2322 lines
74 KiB
C
Executable file
2322 lines
74 KiB
C
Executable file
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* ALSA SoC - Samsung Abox Audio Tuning Block driver
|
|
*
|
|
* Copyright (c) 2020 Samsung Electronics Co. Ltd.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*/
|
|
|
|
#include <sound/tlv.h>
|
|
|
|
#include "abox_soc.h"
|
|
#include "abox.h"
|
|
#include "abox_cmpnt.h"
|
|
#include "abox_dma.h"
|
|
#include "abox_atune.h"
|
|
#include "abox_memlog.h"
|
|
|
|
#define VERBOSE 1
|
|
#undef GAIN_CONTROL
|
|
#define COUNT_CH 8
|
|
#define COUNT_EQ 5
|
|
|
|
#ifdef GAIN_CONTROL
|
|
struct atune_gain_control {
|
|
unsigned int base;
|
|
unsigned int count;
|
|
unsigned int min;
|
|
unsigned int max;
|
|
};
|
|
|
|
static int atune_gain_info(struct snd_kcontrol *kcontrol,
|
|
struct snd_ctl_elem_info *uinfo)
|
|
{
|
|
struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
|
|
struct device *dev = cmpnt->dev;
|
|
struct atune_gain_control *params = (void *)kcontrol->private_value;
|
|
|
|
abox_dbg(dev, "%s: %s\n", __func__, kcontrol->id.name);
|
|
|
|
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
|
uinfo->count = params->count;
|
|
uinfo->value.integer.min = params->min;
|
|
uinfo->value.integer.max = params->max;
|
|
return 0;
|
|
}
|
|
|
|
static int atune_gain_get(struct snd_kcontrol *kcontrol,
|
|
struct snd_ctl_elem_value *ucontrol)
|
|
{
|
|
struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
|
|
struct device *dev = cmpnt->dev;
|
|
struct atune_gain_control *params = (void *)kcontrol->private_value;
|
|
unsigned int i;
|
|
int ret = 0;
|
|
|
|
abox_dbg(dev, "%s: %s\n", __func__, kcontrol->id.name);
|
|
|
|
for (i = 0; i < params->count; i++) {
|
|
unsigned int reg, val;
|
|
int index, shift, db;
|
|
|
|
reg = params->base + (i / ATUNE_FLD_PER_SFR(CH_GAIN));
|
|
val = snd_soc_component_read(cmpnt, reg);
|
|
if (ret < 0) {
|
|
abox_err(dev, "reading fail at %#x\n", reg);
|
|
break;
|
|
}
|
|
shift = (int)(val & ATUNE_CH_GAIN_SHIFT_MASK(i)) >>
|
|
ATUNE_CH_GAIN_SHIFT_L(i);
|
|
index = (int)(val & ATUNE_CH_GAIN_INDEX_MASK(i)) >>
|
|
ATUNE_CH_GAIN_INDEX_L(i);
|
|
db = shift * 6 + (index ? (index - 6) : 0);
|
|
if (VERBOSE)
|
|
abox_dbg(dev, "%s: shift:%d, index:%d, db:%d\n",
|
|
__func__, shift, index, db);
|
|
ucontrol->value.integer.value[i] = db;
|
|
abox_dbg(dev, "%s: %#x => %#x\n", kcontrol->id.name, reg, val);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int atune_gain_put(struct snd_kcontrol *kcontrol,
|
|
struct snd_ctl_elem_value *ucontrol)
|
|
{
|
|
struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
|
|
struct device *dev = cmpnt->dev;
|
|
struct atune_gain_control *params = (void *)kcontrol->private_value;
|
|
unsigned int i;
|
|
|
|
abox_dbg(dev, "%s: %s\n", __func__, kcontrol->id.name);
|
|
|
|
for (i = 0; i < params->count; i++) {
|
|
unsigned int reg, val;
|
|
int index, shift, db;
|
|
|
|
db = (int)ucontrol->value.integer.value[i];
|
|
shift = db / 6;
|
|
index = db - (shift * 6);
|
|
index = index ? (index + 6) : 0;
|
|
if (VERBOSE)
|
|
abox_dbg(dev, "%s: shift:%d, index:%d, db:%d\n",
|
|
__func__, shift, index, db);
|
|
reg = params->base + (i / ATUNE_FLD_PER_SFR(CH_GAIN));
|
|
val = (shift << ATUNE_CH_GAIN_SHIFT_L(i)) |
|
|
(index << ATUNE_CH_GAIN_INDEX_L(i));
|
|
snd_soc_component_write(cmpnt, reg, val);
|
|
abox_dbg(dev, "%s: %#x <= %#x\n", kcontrol->id.name, reg, val);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#define ATUNE_GAIN_CONTROL(xname, xbase, xcount, xmin, xmax) \
|
|
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
|
|
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
|
|
.info = atune_gain_info, .get = atune_gain_get, \
|
|
.put = atune_gain_put, .private_value = \
|
|
((unsigned long)&(struct atune_gain_control) \
|
|
{.base = xbase, .count = xcount, \
|
|
.min = xmin, .max = xmax}) }
|
|
#endif
|
|
|
|
#define SOC_SINGLE_S_TLV(xname, reg, xshift, xmin, xmax, xsign_bit, \
|
|
xinvert, tlv_array) \
|
|
SOC_DOUBLE_R_S_TLV(xname, reg, reg, xshift, xmin, xmax, xsign_bit, \
|
|
xinvert, tlv_array)
|
|
|
|
static const char * const gain_func_texts[] = {
|
|
"MUTE", "NORMAL", "FADE IN", "FADE OUT",
|
|
};
|
|
|
|
static SOC_ENUM_SINGLE_DECL(spus0_pregain_func_enum, ATUNE_SPUS_USGAIN_CTRL(0),
|
|
ATUNE_FUNC_L, gain_func_texts);
|
|
static SOC_ENUM_SINGLE_DECL(spus1_pregain_func_enum, ATUNE_SPUS_USGAIN_CTRL(1),
|
|
ATUNE_FUNC_L, gain_func_texts);
|
|
static SOC_ENUM_SINGLE_DECL(spus0_postgain_func_enum, ATUNE_SPUS_DSGAIN_CTRL(0),
|
|
ATUNE_FUNC_L, gain_func_texts);
|
|
static SOC_ENUM_SINGLE_DECL(spus1_postgain_func_enum, ATUNE_SPUS_DSGAIN_CTRL(1),
|
|
ATUNE_FUNC_L, gain_func_texts);
|
|
static SOC_ENUM_SINGLE_DECL(spum0_pregain_func_enum, ATUNE_SPUM_USGAIN_CTRL(0),
|
|
ATUNE_FUNC_L, gain_func_texts);
|
|
static SOC_ENUM_SINGLE_DECL(spum1_pregain_func_enum, ATUNE_SPUM_USGAIN_CTRL(1),
|
|
ATUNE_FUNC_L, gain_func_texts);
|
|
static SOC_ENUM_SINGLE_DECL(spum0_postgain_func_enum, ATUNE_SPUM_DSGAIN_CTRL(0),
|
|
ATUNE_FUNC_L, gain_func_texts);
|
|
static SOC_ENUM_SINGLE_DECL(spum1_postgain_func_enum, ATUNE_SPUM_DSGAIN_CTRL(1),
|
|
ATUNE_FUNC_L, gain_func_texts);
|
|
|
|
static const DECLARE_TLV_DB_SCALE(atune_gain_shift_tlv, -19200, 600, 0);
|
|
static const DECLARE_TLV_DB_RANGE(atune_gain_index_tlv,
|
|
0x0, 0x0, TLV_DB_SCALE_ITEM(0, 0, 0),
|
|
0x1, 0x5, TLV_DB_SCALE_ITEM(-500, 100, 0),
|
|
);
|
|
|
|
#define ATUNE_SPUS_PREGAIN_CH_CONTROLS(x, ch) \
|
|
SOC_SINGLE_S_TLV("SPUS"#x" PREGAIN CH"#ch" Main Volume", \
|
|
ATUNE_SPUS_USGAIN_GAIN_CH(x, ch), \
|
|
ATUNE_CH_GAIN_SHIFT_L(ch), \
|
|
-32, 20, 5, 0, atune_gain_shift_tlv), \
|
|
SOC_SINGLE_S_TLV("SPUS"#x" PREGAIN CH"#ch" Fine Volume", \
|
|
ATUNE_SPUS_USGAIN_GAIN_CH(x, ch), \
|
|
ATUNE_CH_GAIN_INDEX_L(ch), \
|
|
0, 5, 2, 0, atune_gain_index_tlv)
|
|
|
|
#define ATUNE_SPUS_PREGAIN_CONTROLS(x) \
|
|
ATUNE_SPUS_PREGAIN_CH_CONTROLS(x, 0), \
|
|
ATUNE_SPUS_PREGAIN_CH_CONTROLS(x, 1), \
|
|
ATUNE_SPUS_PREGAIN_CH_CONTROLS(x, 2), \
|
|
ATUNE_SPUS_PREGAIN_CH_CONTROLS(x, 3)
|
|
|
|
#define ATUNE_SPUS_POSTGAIN_CH_CONTROLS(x, ch) \
|
|
SOC_SINGLE_S_TLV("SPUS"#x" POSTGAIN CH"#ch" Main Volume", \
|
|
ATUNE_SPUS_DSGAIN_GAIN_CH(x, ch), \
|
|
ATUNE_CH_GAIN_SHIFT_L(ch), \
|
|
-32, 20, 5, 0, atune_gain_shift_tlv), \
|
|
SOC_SINGLE_S_TLV("SPUS"#x" POSTGAIN CH"#ch" Fine Volume", \
|
|
ATUNE_SPUS_DSGAIN_GAIN_CH(x, ch), \
|
|
ATUNE_CH_GAIN_INDEX_L(ch), \
|
|
0, 5, 2, 0, atune_gain_index_tlv)
|
|
|
|
#define ATUNE_SPUS_POSTGAIN_CONTROLS(x) \
|
|
ATUNE_SPUS_POSTGAIN_CH_CONTROLS(x, 0), \
|
|
ATUNE_SPUS_POSTGAIN_CH_CONTROLS(x, 1), \
|
|
ATUNE_SPUS_POSTGAIN_CH_CONTROLS(x, 2), \
|
|
ATUNE_SPUS_POSTGAIN_CH_CONTROLS(x, 3)
|
|
|
|
static const char * const dither_type_texts[] = {
|
|
"OFF", "RPDF", "TPDF",
|
|
};
|
|
|
|
static SOC_ENUM_SINGLE_DECL(spus0_postgain_dither_type_enum,
|
|
ATUNE_SPUS_DSGAIN_BIT_CTRL(0), ATUNE_DITHER_TYPE_L,
|
|
dither_type_texts);
|
|
static SOC_ENUM_SINGLE_DECL(spus1_postgain_dither_type_enum,
|
|
ATUNE_SPUS_DSGAIN_BIT_CTRL(1), ATUNE_DITHER_TYPE_L,
|
|
dither_type_texts);
|
|
static SOC_ENUM_SINGLE_DECL(spum0_postgain_dither_type_enum,
|
|
ATUNE_SPUM_DSGAIN_BIT_CTRL(0), ATUNE_DITHER_TYPE_L,
|
|
dither_type_texts);
|
|
static SOC_ENUM_SINGLE_DECL(spum1_postgain_dither_type_enum,
|
|
ATUNE_SPUM_DSGAIN_BIT_CTRL(1), ATUNE_DITHER_TYPE_L,
|
|
dither_type_texts);
|
|
|
|
#define ATUNE_SPUM_PREGAIN_CH_CONTROLS(x, ch) \
|
|
SOC_SINGLE_S_TLV("SPUM"#x" PREGAIN CH"#ch" Main Volume", \
|
|
ATUNE_SPUM_USGAIN_GAIN_CH(x, ch), \
|
|
ATUNE_CH_GAIN_SHIFT_L(ch), \
|
|
-32, 20, 5, 0, atune_gain_shift_tlv), \
|
|
SOC_SINGLE_S_TLV("SPUM"#x" PREGAIN CH"#ch" Fine Volume", \
|
|
ATUNE_SPUM_USGAIN_GAIN_CH(x, ch), \
|
|
ATUNE_CH_GAIN_INDEX_L(ch), \
|
|
0, 5, 2, 0, atune_gain_index_tlv)
|
|
|
|
#define ATUNE_SPUM_PREGAIN_CONTROLS(x) \
|
|
ATUNE_SPUM_PREGAIN_CH_CONTROLS(x, 0), \
|
|
ATUNE_SPUM_PREGAIN_CH_CONTROLS(x, 1), \
|
|
ATUNE_SPUM_PREGAIN_CH_CONTROLS(x, 2), \
|
|
ATUNE_SPUM_PREGAIN_CH_CONTROLS(x, 3)
|
|
|
|
#define ATUNE_SPUM_POSTGAIN_CH_CONTROLS(x, ch) \
|
|
SOC_SINGLE_S_TLV("SPUM"#x" POSTGAIN CH"#ch" Main Volume", \
|
|
ATUNE_SPUM_DSGAIN_GAIN_CH(x, ch), \
|
|
ATUNE_CH_GAIN_SHIFT_L(ch), \
|
|
-32, 20, 5, 0, atune_gain_shift_tlv), \
|
|
SOC_SINGLE_S_TLV("SPUM"#x" POSTGAIN CH"#ch" Fine Volume", \
|
|
ATUNE_SPUM_DSGAIN_GAIN_CH(x, ch), \
|
|
ATUNE_CH_GAIN_INDEX_L(ch), \
|
|
0, 5, 2, 0, atune_gain_index_tlv)
|
|
|
|
#define ATUNE_SPUM_POSTGAIN_CONTROLS(x) \
|
|
ATUNE_SPUM_POSTGAIN_CH_CONTROLS(x, 0), \
|
|
ATUNE_SPUM_POSTGAIN_CH_CONTROLS(x, 1), \
|
|
ATUNE_SPUM_POSTGAIN_CH_CONTROLS(x, 2), \
|
|
ATUNE_SPUM_POSTGAIN_CH_CONTROLS(x, 3)
|
|
|
|
static int atune_param_update_get(struct snd_kcontrol *kcontrol,
|
|
struct snd_ctl_elem_value *ucontrol)
|
|
{
|
|
ucontrol->value.integer.value[0] = 0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int atune_param_update_put(struct snd_kcontrol *kcontrol,
|
|
struct snd_ctl_elem_value *ucontrol)
|
|
{
|
|
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
|
struct soc_mixer_control *mc =
|
|
(struct soc_mixer_control *)kcontrol->private_value;
|
|
unsigned int reg = mc->reg;
|
|
unsigned int shift = mc->shift;
|
|
int max = mc->max;
|
|
unsigned int mask = (1 << fls(max)) - 1;
|
|
unsigned int val, val_mask;
|
|
int err;
|
|
|
|
val = (ucontrol->value.integer.value[0] & mask) << shift;
|
|
val_mask = mask << shift;
|
|
|
|
/* param_update field is write only but r/w field is in same SFR.
|
|
* To ensure write, write 0 first and then write requested value.
|
|
*/
|
|
err = snd_soc_component_update_bits(component, reg, val_mask, 0);
|
|
if (err < 0 || val == 0)
|
|
return err;
|
|
|
|
return snd_soc_component_update_bits(component, reg, val_mask, val);
|
|
}
|
|
|
|
static const unsigned int headroom_mask = ATUNE_HEADROOM_HPF_MASK >>
|
|
ATUNE_HEADROOM_HPF_L;
|
|
|
|
static const char * const headroom_texts[] = {
|
|
"6dB", "12dB", "18dB", "24dB",
|
|
};
|
|
|
|
static const unsigned int headroom_values[] = {
|
|
2, 3, 4, 5,
|
|
};
|
|
|
|
static const unsigned int headroom_items = ARRAY_SIZE(headroom_texts);
|
|
|
|
#define ATUNE_SPUS_BQF_CH_HPF_HEADROOM_ENUM(x, ch) \
|
|
SOC_VALUE_ENUM_SINGLE(ATUNE_SPUS_BQF_CH##ch##_HEADROOM(x), \
|
|
ATUNE_HEADROOM_HPF_L, headroom_mask, \
|
|
headroom_items, headroom_texts, headroom_values)
|
|
|
|
static const struct soc_enum spus_bqf_ch_hpf_headroom[][COUNT_CH] = {
|
|
/* SPUS BQF0 */
|
|
{
|
|
ATUNE_SPUS_BQF_CH_HPF_HEADROOM_ENUM(0, 0),
|
|
ATUNE_SPUS_BQF_CH_HPF_HEADROOM_ENUM(0, 1),
|
|
ATUNE_SPUS_BQF_CH_HPF_HEADROOM_ENUM(0, 2),
|
|
ATUNE_SPUS_BQF_CH_HPF_HEADROOM_ENUM(0, 3),
|
|
},
|
|
/* SPUS BQF1 */
|
|
{
|
|
ATUNE_SPUS_BQF_CH_HPF_HEADROOM_ENUM(0, 0),
|
|
ATUNE_SPUS_BQF_CH_HPF_HEADROOM_ENUM(0, 1),
|
|
ATUNE_SPUS_BQF_CH_HPF_HEADROOM_ENUM(0, 2),
|
|
ATUNE_SPUS_BQF_CH_HPF_HEADROOM_ENUM(0, 3),
|
|
},
|
|
};
|
|
|
|
#define ATUNE_SPUS_BQF_CH_EQ_HEADROOM_ENUM(x, ch, eq) \
|
|
SOC_VALUE_ENUM_SINGLE(ATUNE_SPUS_BQF_CH##ch##_HEADROOM(x), \
|
|
ATUNE_HEADROOM_EQ_L(eq), headroom_mask, \
|
|
headroom_items, headroom_texts, headroom_values)
|
|
|
|
#define ATUNE_SPUS_BQF_CH_HEADROOM_ENUM(x, ch) \
|
|
ATUNE_SPUS_BQF_CH_EQ_HEADROOM_ENUM(x, ch, 0), \
|
|
ATUNE_SPUS_BQF_CH_EQ_HEADROOM_ENUM(x, ch, 1), \
|
|
ATUNE_SPUS_BQF_CH_EQ_HEADROOM_ENUM(x, ch, 2), \
|
|
ATUNE_SPUS_BQF_CH_EQ_HEADROOM_ENUM(x, ch, 3), \
|
|
ATUNE_SPUS_BQF_CH_EQ_HEADROOM_ENUM(x, ch, 4)
|
|
|
|
static const struct soc_enum spus_bqf_ch_eq_headroom[][COUNT_CH][COUNT_EQ] = {
|
|
/* SPUS0 */
|
|
{
|
|
{ ATUNE_SPUS_BQF_CH_HEADROOM_ENUM(0, 0) },
|
|
{ ATUNE_SPUS_BQF_CH_HEADROOM_ENUM(0, 1) },
|
|
{ ATUNE_SPUS_BQF_CH_HEADROOM_ENUM(0, 2) },
|
|
{ ATUNE_SPUS_BQF_CH_HEADROOM_ENUM(0, 3) },
|
|
},
|
|
/* SPUS1 */
|
|
{
|
|
{ ATUNE_SPUS_BQF_CH_HEADROOM_ENUM(1, 0) },
|
|
{ ATUNE_SPUS_BQF_CH_HEADROOM_ENUM(1, 1) },
|
|
{ ATUNE_SPUS_BQF_CH_HEADROOM_ENUM(1, 2) },
|
|
{ ATUNE_SPUS_BQF_CH_HEADROOM_ENUM(1, 3) },
|
|
},
|
|
};
|
|
|
|
#define ATUNE_SPUM_BQF_CH_HPF_HEADROOM_ENUM(x, ch) \
|
|
SOC_VALUE_ENUM_SINGLE(ATUNE_SPUM_BQF_CH##ch##_HEADROOM(x), \
|
|
ATUNE_HEADROOM_HPF_L, headroom_mask, \
|
|
headroom_items, headroom_texts, headroom_values)
|
|
|
|
static const struct soc_enum spum_bqf_ch_hpf_headroom[][COUNT_CH] = {
|
|
/* SPUM0 */
|
|
{
|
|
ATUNE_SPUM_BQF_CH_HPF_HEADROOM_ENUM(0, 0),
|
|
ATUNE_SPUM_BQF_CH_HPF_HEADROOM_ENUM(0, 1),
|
|
ATUNE_SPUM_BQF_CH_HPF_HEADROOM_ENUM(0, 2),
|
|
ATUNE_SPUM_BQF_CH_HPF_HEADROOM_ENUM(0, 3),
|
|
},
|
|
/* SPUM1 */
|
|
{
|
|
ATUNE_SPUM_BQF_CH_HPF_HEADROOM_ENUM(0, 0),
|
|
ATUNE_SPUM_BQF_CH_HPF_HEADROOM_ENUM(0, 1),
|
|
ATUNE_SPUM_BQF_CH_HPF_HEADROOM_ENUM(0, 2),
|
|
ATUNE_SPUM_BQF_CH_HPF_HEADROOM_ENUM(0, 3),
|
|
},
|
|
};
|
|
|
|
#define ATUNE_SPUM_BQF_CH_EQ_HEADROOM_ENUM(x, ch, eq) \
|
|
SOC_VALUE_ENUM_SINGLE(ATUNE_SPUM_BQF_CH##ch##_HEADROOM(x), \
|
|
ATUNE_HEADROOM_EQ_L(eq), headroom_mask, \
|
|
headroom_items, headroom_texts, headroom_values)
|
|
|
|
#define ATUNE_SPUM_BQF_CH_HEADROOM_ENUM(x, ch) \
|
|
ATUNE_SPUM_BQF_CH_EQ_HEADROOM_ENUM(x, ch, 0), \
|
|
ATUNE_SPUM_BQF_CH_EQ_HEADROOM_ENUM(x, ch, 1), \
|
|
ATUNE_SPUM_BQF_CH_EQ_HEADROOM_ENUM(x, ch, 2), \
|
|
ATUNE_SPUM_BQF_CH_EQ_HEADROOM_ENUM(x, ch, 3), \
|
|
ATUNE_SPUM_BQF_CH_EQ_HEADROOM_ENUM(x, ch, 4)
|
|
|
|
static const struct soc_enum spum_bqf_ch_eq_headroom[][COUNT_CH][COUNT_EQ] = {
|
|
/* SPUM0 */
|
|
{
|
|
{ ATUNE_SPUM_BQF_CH_HEADROOM_ENUM(0, 0) },
|
|
{ ATUNE_SPUM_BQF_CH_HEADROOM_ENUM(0, 1) },
|
|
{ ATUNE_SPUM_BQF_CH_HEADROOM_ENUM(0, 2) },
|
|
{ ATUNE_SPUM_BQF_CH_HEADROOM_ENUM(0, 3) },
|
|
},
|
|
/* SPUM1 */
|
|
{
|
|
{ ATUNE_SPUM_BQF_CH_HEADROOM_ENUM(1, 0) },
|
|
{ ATUNE_SPUM_BQF_CH_HEADROOM_ENUM(1, 1) },
|
|
{ ATUNE_SPUM_BQF_CH_HEADROOM_ENUM(1, 2) },
|
|
{ ATUNE_SPUM_BQF_CH_HEADROOM_ENUM(1, 3) },
|
|
},
|
|
};
|
|
|
|
#define ATUNE_SPUS_BQF_CH_HEADROOM_CONTROLS(x, ch) \
|
|
SOC_ENUM("SPUS"#x" CH"#ch" HEADROOM HPF", \
|
|
spus_bqf_ch_hpf_headroom[x][ch]), \
|
|
SOC_ENUM("SPUS"#x" CH"#ch" HEADROOM EQ0", \
|
|
spus_bqf_ch_eq_headroom[x][ch][0]), \
|
|
SOC_ENUM("SPUS"#x" CH"#ch" HEADROOM EQ1", \
|
|
spus_bqf_ch_eq_headroom[x][ch][1]), \
|
|
SOC_ENUM("SPUS"#x" CH"#ch" HEADROOM EQ2", \
|
|
spus_bqf_ch_eq_headroom[x][ch][2]), \
|
|
SOC_ENUM("SPUS"#x" CH"#ch" HEADROOM EQ3", \
|
|
spus_bqf_ch_eq_headroom[x][ch][3]), \
|
|
SOC_ENUM("SPUS"#x" CH"#ch" HEADROOM EQ4", \
|
|
spus_bqf_ch_eq_headroom[x][ch][4])
|
|
|
|
#define ATUNE_SPUS_BQF_HEADROOM_CONTROLS(x) \
|
|
ATUNE_SPUS_BQF_CH_HEADROOM_CONTROLS(x, 0), \
|
|
ATUNE_SPUS_BQF_CH_HEADROOM_CONTROLS(x, 1), \
|
|
ATUNE_SPUS_BQF_CH_HEADROOM_CONTROLS(x, 2), \
|
|
ATUNE_SPUS_BQF_CH_HEADROOM_CONTROLS(x, 3)
|
|
|
|
#define ATUNE_SPUM_BQF_CH_HEADROOM_CONTROLS(x, ch) \
|
|
SOC_ENUM("SPUM"#x" CH"#ch" HEADROOM HPF", \
|
|
spum_bqf_ch_hpf_headroom[x][ch]), \
|
|
SOC_ENUM("SPUM"#x" CH"#ch" HEADROOM EQ0", \
|
|
spum_bqf_ch_eq_headroom[x][ch][0]), \
|
|
SOC_ENUM("SPUM"#x" CH"#ch" HEADROOM EQ1", \
|
|
spum_bqf_ch_eq_headroom[x][ch][1]), \
|
|
SOC_ENUM("SPUM"#x" CH"#ch" HEADROOM EQ2", \
|
|
spum_bqf_ch_eq_headroom[x][ch][2]), \
|
|
SOC_ENUM("SPUM"#x" CH"#ch" HEADROOM EQ3", \
|
|
spum_bqf_ch_eq_headroom[x][ch][3]), \
|
|
SOC_ENUM("SPUM"#x" CH"#ch" HEADROOM EQ4", \
|
|
spum_bqf_ch_eq_headroom[x][ch][4])
|
|
|
|
#define ATUNE_SPUM_BQF_HEADROOM_CONTROLS(x) \
|
|
ATUNE_SPUM_BQF_CH_HEADROOM_CONTROLS(x, 0), \
|
|
ATUNE_SPUM_BQF_CH_HEADROOM_CONTROLS(x, 1), \
|
|
ATUNE_SPUM_BQF_CH_HEADROOM_CONTROLS(x, 2), \
|
|
ATUNE_SPUM_BQF_CH_HEADROOM_CONTROLS(x, 3)
|
|
|
|
#define ATUNE_SPUS_BQF_CH_POSTAMP_CONTROLS(x, ch) \
|
|
SOC_SINGLE("SPUS"#x" CH"#ch" POSTAMP HPF", \
|
|
ATUNE_SPUS_BQF_CH##ch##_POSTAMP(x), \
|
|
ATUNE_POSTAMP_HPF_L, 3, 0), \
|
|
SOC_SINGLE("SPUS"#x" CH"#ch" POSTAMP EQ0", \
|
|
ATUNE_SPUS_BQF_CH##ch##_POSTAMP(x), \
|
|
ATUNE_POSTAMP_EQ_L(0), 3, 0), \
|
|
SOC_SINGLE("SPUS"#x" CH"#ch" POSTAMP EQ1", \
|
|
ATUNE_SPUS_BQF_CH##ch##_POSTAMP(x), \
|
|
ATUNE_POSTAMP_EQ_L(1), 3, 0), \
|
|
SOC_SINGLE("SPUS"#x" CH"#ch" POSTAMP EQ2", \
|
|
ATUNE_SPUS_BQF_CH##ch##_POSTAMP(x), \
|
|
ATUNE_POSTAMP_EQ_L(2), 3, 0), \
|
|
SOC_SINGLE("SPUS"#x" CH"#ch" POSTAMP EQ3", \
|
|
ATUNE_SPUS_BQF_CH##ch##_POSTAMP(x), \
|
|
ATUNE_POSTAMP_EQ_L(3), 3, 0), \
|
|
SOC_SINGLE("SPUS"#x" CH"#ch" POSTAMP EQ4", \
|
|
ATUNE_SPUS_BQF_CH##ch##_POSTAMP(x), \
|
|
ATUNE_POSTAMP_EQ_L(4), 3, 0)
|
|
|
|
#define ATUNE_SPUS_BQF_POSTAMP_CONTROLS(x) \
|
|
ATUNE_SPUS_BQF_CH_POSTAMP_CONTROLS(x, 0), \
|
|
ATUNE_SPUS_BQF_CH_POSTAMP_CONTROLS(x, 1), \
|
|
ATUNE_SPUS_BQF_CH_POSTAMP_CONTROLS(x, 2), \
|
|
ATUNE_SPUS_BQF_CH_POSTAMP_CONTROLS(x, 3)
|
|
|
|
#define ATUNE_SPUM_BQF_CH_POSTAMP_CONTROLS(x, ch) \
|
|
SOC_SINGLE("SPUM"#x" CH"#ch" POSTAMP HPF", \
|
|
ATUNE_SPUM_BQF_CH##ch##_POSTAMP(x), \
|
|
ATUNE_POSTAMP_HPF_L, 3, 0), \
|
|
SOC_SINGLE("SPUM"#x" CH"#ch" POSTAMP EQ0", \
|
|
ATUNE_SPUM_BQF_CH##ch##_POSTAMP(x), \
|
|
ATUNE_POSTAMP_EQ_L(0), 3, 0), \
|
|
SOC_SINGLE("SPUM"#x" CH"#ch" POSTAMP EQ1", \
|
|
ATUNE_SPUM_BQF_CH##ch##_POSTAMP(x), \
|
|
ATUNE_POSTAMP_EQ_L(1), 3, 0), \
|
|
SOC_SINGLE("SPUM"#x" CH"#ch" POSTAMP EQ2", \
|
|
ATUNE_SPUM_BQF_CH##ch##_POSTAMP(x), \
|
|
ATUNE_POSTAMP_EQ_L(2), 3, 0), \
|
|
SOC_SINGLE("SPUM"#x" CH"#ch" POSTAMP EQ3", \
|
|
ATUNE_SPUM_BQF_CH##ch##_POSTAMP(x), \
|
|
ATUNE_POSTAMP_EQ_L(3), 3, 0), \
|
|
SOC_SINGLE("SPUM"#x" CH"#ch" POSTAMP EQ4", \
|
|
ATUNE_SPUM_BQF_CH##ch##_POSTAMP(x), \
|
|
ATUNE_POSTAMP_EQ_L(4), 3, 0)
|
|
|
|
#define ATUNE_SPUM_BQF_POSTAMP_CONTROLS(x) \
|
|
ATUNE_SPUM_BQF_CH_POSTAMP_CONTROLS(x, 0), \
|
|
ATUNE_SPUM_BQF_CH_POSTAMP_CONTROLS(x, 1), \
|
|
ATUNE_SPUM_BQF_CH_POSTAMP_CONTROLS(x, 2), \
|
|
ATUNE_SPUM_BQF_CH_POSTAMP_CONTROLS(x, 3)
|
|
|
|
struct atune_multi_control {
|
|
int min, max;
|
|
int regs[8];
|
|
unsigned int shifts[8];
|
|
unsigned int count;
|
|
unsigned int sign_bit;
|
|
unsigned int invert:1;
|
|
unsigned int autodisable:1;
|
|
struct snd_soc_dobj dobj;
|
|
};
|
|
|
|
/* revisit snd_soc_read_signed() in ASoC */
|
|
static int cmpnt_read_signed(struct snd_soc_component *component,
|
|
unsigned int reg, unsigned int mask, unsigned int shift,
|
|
unsigned int sign_bit, int *signed_val)
|
|
{
|
|
unsigned int val;
|
|
|
|
val = snd_soc_component_read(component, reg);
|
|
val = (val >> shift) & mask;
|
|
|
|
if (!sign_bit || !(val & BIT(sign_bit)))
|
|
*signed_val = val;
|
|
else
|
|
*signed_val = (int)val | ~((int)(BIT(sign_bit) - 1));
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int atune_info_multi(struct snd_kcontrol *kcontrol,
|
|
struct snd_ctl_elem_info *uinfo)
|
|
{
|
|
struct atune_multi_control *amc =
|
|
(struct atune_multi_control *)kcontrol->private_value;
|
|
|
|
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
|
|
uinfo->count = amc->count;
|
|
uinfo->value.integer.min = amc->min;
|
|
uinfo->value.integer.max = amc->max;
|
|
return 0;
|
|
}
|
|
|
|
static int __maybe_unused atune_get_multi(struct snd_kcontrol *kcontrol,
|
|
struct snd_ctl_elem_value *ucontrol)
|
|
{
|
|
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
|
struct atune_multi_control *amc =
|
|
(struct atune_multi_control *)kcontrol->private_value;
|
|
unsigned int *reg = amc->regs;
|
|
unsigned int *shift = amc->shifts;
|
|
unsigned int i, count = amc->count;
|
|
int max = amc->max;
|
|
int sign_bit = amc->sign_bit;
|
|
unsigned int mask = (1 << fls(max)) - 1;
|
|
unsigned int invert = amc->invert;
|
|
int val;
|
|
int ret;
|
|
|
|
if (sign_bit)
|
|
mask = BIT(sign_bit + 1) - 1;
|
|
|
|
for (i = count - 1; i; i--) {
|
|
ret = cmpnt_read_signed(component, reg[i], mask, shift[i],
|
|
sign_bit, &val);
|
|
if (ret)
|
|
return ret;
|
|
|
|
ucontrol->value.integer.value[i] = invert ? (max - val): val;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int __maybe_unused atune_put_multi(struct snd_kcontrol *kcontrol,
|
|
struct snd_ctl_elem_value *ucontrol)
|
|
{
|
|
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
|
struct atune_multi_control *amc =
|
|
(struct atune_multi_control *)kcontrol->private_value;
|
|
unsigned int *reg = amc->regs;
|
|
unsigned int *shift = amc->shifts;
|
|
unsigned int i, count = amc->count;
|
|
int max = amc->max;
|
|
unsigned int sign_bit = amc->sign_bit;
|
|
unsigned int mask = (1 << fls(max)) - 1;
|
|
unsigned int invert = amc->invert;
|
|
int err;
|
|
unsigned int val, val_mask;
|
|
|
|
if (sign_bit)
|
|
mask = BIT(sign_bit + 1) - 1;
|
|
|
|
for (i = count - 1; i; i--) {
|
|
val = ((ucontrol->value.integer.value[i]) & mask);
|
|
if (invert)
|
|
val = max - val;
|
|
val_mask = mask << shift[i];
|
|
val = val << shift[i];
|
|
err = snd_soc_component_update_bits(component, reg[i],
|
|
val_mask, val);
|
|
if (err < 0)
|
|
break;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
static int atune_get_multi_linear(struct snd_kcontrol *kcontrol,
|
|
struct snd_ctl_elem_value *ucontrol)
|
|
{
|
|
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
|
struct atune_multi_control *amc =
|
|
(struct atune_multi_control *)kcontrol->private_value;
|
|
unsigned int reg = amc->regs[0];
|
|
unsigned int shift = amc->shifts[0];
|
|
unsigned int offset;
|
|
unsigned int i, count = amc->count;
|
|
int max = amc->max;
|
|
int sign_bit = amc->sign_bit;
|
|
unsigned int mask = (1 << fls(max)) - 1;
|
|
unsigned int invert = amc->invert;
|
|
int val;
|
|
int ret;
|
|
|
|
if (sign_bit)
|
|
mask = BIT(sign_bit + 1) - 1;
|
|
|
|
for (i = 0, offset = 0; i < count; i++, offset += SFR_STRIDE) {
|
|
ret = cmpnt_read_signed(component, reg + offset, mask, shift,
|
|
sign_bit, &val);
|
|
if (ret)
|
|
return ret;
|
|
|
|
ucontrol->value.integer.value[i] = invert ? (max - val): val;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int atune_put_multi_linear(struct snd_kcontrol *kcontrol,
|
|
struct snd_ctl_elem_value *ucontrol)
|
|
{
|
|
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
|
|
struct atune_multi_control *amc =
|
|
(struct atune_multi_control *)kcontrol->private_value;
|
|
unsigned int reg = amc->regs[0];
|
|
unsigned int shift = amc->shifts[0];
|
|
unsigned int offset;
|
|
unsigned int i, count = amc->count;
|
|
int max = amc->max;
|
|
unsigned int sign_bit = amc->sign_bit;
|
|
unsigned int mask = (1 << fls(max)) - 1;
|
|
unsigned int invert = amc->invert;
|
|
int err;
|
|
unsigned int val, val_mask;
|
|
|
|
if (sign_bit)
|
|
mask = BIT(sign_bit + 1) - 1;
|
|
|
|
for (i = 0, offset = 0; i < count; i++, offset += SFR_STRIDE) {
|
|
val = ((ucontrol->value.integer.value[i]) & mask);
|
|
if (invert)
|
|
val = max - val;
|
|
val_mask = mask << shift;
|
|
val = val << shift;
|
|
err = snd_soc_component_update_bits(component, reg + offset,
|
|
val_mask, val);
|
|
if (err < 0)
|
|
break;
|
|
}
|
|
|
|
return err;
|
|
}
|
|
|
|
#define ATUNE_MULTI_VALUE(xregs, xshifts, xcount, xmin, xmax, \
|
|
xsign_bit, xinvert) \
|
|
((unsigned long)&(struct atune_multi_control) \
|
|
{.regs = xregs, .shifts = xshifts, .count = xcount, .min = xmin, \
|
|
.max = xmax, .sign_bit = xsign_bit, .invert = xinvert,})
|
|
|
|
#define ATUNE_MULTI(xname, regs, shifts, min, max, sign_bit, invert) \
|
|
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
|
.info = atune_info_multi, .get = atune_get_multi,\
|
|
.put = atune_put_multi, \
|
|
.private_value = ATUNE_MULTI_VALUE(regs, shifts, \
|
|
ARRAY_SIZE(regs), min, max, sign_bit, invert) }
|
|
|
|
#define ATUNE_MULTI_LINEAR(xname, regbase, shift, count, min, max, \
|
|
sign_bit, invert) \
|
|
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
|
|
.info = atune_info_multi, .get = atune_get_multi_linear,\
|
|
.put = atune_put_multi_linear, \
|
|
.private_value = ATUNE_MULTI_VALUE({ regbase }, { shift }, \
|
|
count, min, max, sign_bit, invert) }
|
|
|
|
#define ATUNE_SPUS_BQF_CH_COEF_CONTROLS(x, ch) \
|
|
ATUNE_MULTI_LINEAR("SPUS"#x" CH"#ch" HPF COEF", \
|
|
ATUNE_SPUS_BQF_CH##ch##_HPF_COEF0(x), \
|
|
ATUNE_COEF_L, 5, INT_MIN, INT_MAX, 31, 0), \
|
|
ATUNE_MULTI_LINEAR("SPUS"#x" CH"#ch" EQ0 COEF", \
|
|
ATUNE_SPUS_BQF_CH##ch##_EQ0_COEF0(x), \
|
|
ATUNE_COEF_L, 5, INT_MIN, INT_MAX, 31, 0), \
|
|
ATUNE_MULTI_LINEAR("SPUS"#x" CH"#ch" EQ1 COEF", \
|
|
ATUNE_SPUS_BQF_CH##ch##_EQ1_COEF0(x), \
|
|
ATUNE_COEF_L, 5, INT_MIN, INT_MAX, 31, 0), \
|
|
ATUNE_MULTI_LINEAR("SPUS"#x" CH"#ch" EQ2 COEF", \
|
|
ATUNE_SPUS_BQF_CH##ch##_EQ2_COEF0(x), \
|
|
ATUNE_COEF_L, 5, INT_MIN, INT_MAX, 31, 0), \
|
|
ATUNE_MULTI_LINEAR("SPUS"#x" CH"#ch" EQ3 COEF", \
|
|
ATUNE_SPUS_BQF_CH##ch##_EQ3_COEF0(x), \
|
|
ATUNE_COEF_L, 5, INT_MIN, INT_MAX, 31, 0), \
|
|
ATUNE_MULTI_LINEAR("SPUS"#x" CH"#ch" EQ4 COEF", \
|
|
ATUNE_SPUS_BQF_CH##ch##_EQ4_COEF0(x), \
|
|
ATUNE_COEF_L, 5, INT_MIN, INT_MAX, 31, 0)
|
|
|
|
#define ATUNE_SPUS_BQF_COEF_CONTROLS(x) \
|
|
ATUNE_SPUS_BQF_CH_COEF_CONTROLS(x, 0), \
|
|
ATUNE_SPUS_BQF_CH_COEF_CONTROLS(x, 1), \
|
|
ATUNE_SPUS_BQF_CH_COEF_CONTROLS(x, 2), \
|
|
ATUNE_SPUS_BQF_CH_COEF_CONTROLS(x, 3)
|
|
|
|
#define ATUNE_SPUM_BQF_CH_COEF_CONTROLS(x, ch) \
|
|
ATUNE_MULTI_LINEAR("SPUM"#x" CH"#ch" HPF COEF", \
|
|
ATUNE_SPUM_BQF_CH##ch##_HPF_COEF0(x), \
|
|
ATUNE_COEF_L, 5, INT_MIN, INT_MAX, 31, 0), \
|
|
ATUNE_MULTI_LINEAR("SPUM"#x" CH"#ch" EQ0 COEF", \
|
|
ATUNE_SPUM_BQF_CH##ch##_EQ0_COEF0(x), \
|
|
ATUNE_COEF_L, 5, INT_MIN, INT_MAX, 31, 0), \
|
|
ATUNE_MULTI_LINEAR("SPUM"#x" CH"#ch" EQ1 COEF", \
|
|
ATUNE_SPUM_BQF_CH##ch##_EQ1_COEF0(x), \
|
|
ATUNE_COEF_L, 5, INT_MIN, INT_MAX, 31, 0), \
|
|
ATUNE_MULTI_LINEAR("SPUM"#x" CH"#ch" EQ2 COEF", \
|
|
ATUNE_SPUM_BQF_CH##ch##_EQ2_COEF0(x), \
|
|
ATUNE_COEF_L, 5, INT_MIN, INT_MAX, 31, 0), \
|
|
ATUNE_MULTI_LINEAR("SPUM"#x" CH"#ch" EQ3 COEF", \
|
|
ATUNE_SPUM_BQF_CH##ch##_EQ3_COEF0(x), \
|
|
ATUNE_COEF_L, 5, INT_MIN, INT_MAX, 31, 0), \
|
|
ATUNE_MULTI_LINEAR("SPUM"#x" CH"#ch" EQ4 COEF", \
|
|
ATUNE_SPUM_BQF_CH##ch##_EQ4_COEF0(x), \
|
|
ATUNE_COEF_L, 5, INT_MIN, INT_MAX, 31, 0)
|
|
|
|
#define ATUNE_SPUM_BQF_COEF_CONTROLS(x) \
|
|
ATUNE_SPUM_BQF_CH_COEF_CONTROLS(x, 0), \
|
|
ATUNE_SPUM_BQF_CH_COEF_CONTROLS(x, 1), \
|
|
ATUNE_SPUM_BQF_CH_COEF_CONTROLS(x, 2), \
|
|
ATUNE_SPUM_BQF_CH_COEF_CONTROLS(x, 3)
|
|
|
|
static const DECLARE_TLV_DB_SCALE(atune_ng_threshold_tlv, -9600, 100, 0);
|
|
static const DECLARE_TLV_DB_MINMAX(atune_drc_makeup_gain_tlv, 0, 3000);
|
|
static const DECLARE_TLV_DB_SCALE(atune_drc_threshold_tlv, -8000, 100, 0);
|
|
|
|
#define ATUNE_SPUS_DRC_BAND_CONTROLS(x, band) \
|
|
SOC_SINGLE_S_TLV("SPUS"#x" DRC "#band" MAKEUP GAIN", \
|
|
ATUNE_SPUS_DRC_COMP_##band##0(x), \
|
|
ATUNE_MAKEUP_GAIN_L, 0x0400, 0x7FFF, \
|
|
15, 0, atune_drc_makeup_gain_tlv), \
|
|
SOC_SINGLE_S_TLV("SPUS"#x" DRC "#band" THRESHOLD", \
|
|
ATUNE_SPUS_DRC_COMP_##band##0(x), \
|
|
ATUNE_THRS_L, -80, 0, 7, 0, \
|
|
atune_drc_threshold_tlv), \
|
|
SOC_SINGLE("SPUS"#x" DRC "#band" RATIO", \
|
|
ATUNE_SPUS_DRC_COMP_##band##0(x), \
|
|
ATUNE_RATIO_L, 0xf, 0), \
|
|
SOC_SINGLE("SPUS"#x" DRC "#band" RMS", \
|
|
ATUNE_SPUS_DRC_COMP_##band##0(x), \
|
|
ATUNE_RMS_ENABLE_L, 1, 0), \
|
|
SOC_SINGLE("SPUS"#x" DRC "#band" MUTE", \
|
|
ATUNE_SPUS_DRC_COMP_##band##0(x), \
|
|
ATUNE_MUTE_ENABLE_L, 1, 0), \
|
|
SOC_SINGLE("SPUS"#x" DRC "#band" ATTACK", \
|
|
ATUNE_SPUS_DRC_COMP_##band##1(x), \
|
|
ATUNE_ATTACK_TIME_L, INT_MAX, 0), \
|
|
SOC_SINGLE("SPUS"#x" DRC "#band" RELEASE", \
|
|
ATUNE_SPUS_DRC_COMP_##band##2(x), \
|
|
ATUNE_RELEASE_TIME_L, INT_MAX, 0)
|
|
|
|
#define ATUNE_SPUS_DRC_CONTROLS(x) \
|
|
ATUNE_SPUS_DRC_BAND_CONTROLS(x, LB), \
|
|
ATUNE_SPUS_DRC_BAND_CONTROLS(x, MB), \
|
|
ATUNE_SPUS_DRC_BAND_CONTROLS(x, HB)
|
|
|
|
#define ATUNE_SPUM_DRC_BAND_CONTROLS(x, band) \
|
|
SOC_SINGLE_S_TLV("SPUM"#x" DRC "#band" MAKEUP GAIN", \
|
|
ATUNE_SPUM_DRC_COMP_##band##0(x), \
|
|
ATUNE_MAKEUP_GAIN_L, 0x0400, 0x7FFF, \
|
|
15, 0, atune_drc_makeup_gain_tlv), \
|
|
SOC_SINGLE_S_TLV("SPUM"#x" DRC "#band" THRESHOLD", \
|
|
ATUNE_SPUM_DRC_COMP_##band##0(x), \
|
|
ATUNE_THRS_L, -80, 0, 7, 0, \
|
|
atune_drc_threshold_tlv), \
|
|
SOC_SINGLE("SPUM"#x" DRC "#band" RATIO", \
|
|
ATUNE_SPUM_DRC_COMP_##band##0(x), \
|
|
ATUNE_RATIO_L, 0xf, 0), \
|
|
SOC_SINGLE("SPUM"#x" DRC "#band" RMS", \
|
|
ATUNE_SPUM_DRC_COMP_##band##0(x), \
|
|
ATUNE_RMS_ENABLE_L, 1, 0), \
|
|
SOC_SINGLE("SPUM"#x" DRC "#band" MUTE", \
|
|
ATUNE_SPUM_DRC_COMP_##band##0(x), \
|
|
ATUNE_MUTE_ENABLE_L, 1, 0), \
|
|
SOC_SINGLE("SPUM"#x" DRC "#band" ATTACK", \
|
|
ATUNE_SPUM_DRC_COMP_##band##1(x), \
|
|
ATUNE_ATTACK_TIME_L, INT_MAX, 0), \
|
|
SOC_SINGLE("SPUM"#x" DRC "#band" RELEASE", \
|
|
ATUNE_SPUM_DRC_COMP_##band##2(x), \
|
|
ATUNE_RELEASE_TIME_L, INT_MAX, 0)
|
|
|
|
#define ATUNE_SPUM_DRC_CONTROLS(x) \
|
|
ATUNE_SPUM_DRC_BAND_CONTROLS(x, LB), \
|
|
ATUNE_SPUM_DRC_BAND_CONTROLS(x, MB), \
|
|
ATUNE_SPUM_DRC_BAND_CONTROLS(x, HB)
|
|
|
|
static const struct snd_kcontrol_new atune_controls[] = {
|
|
SOC_ENUM("SPUS0 PREGAIN FUNC", spus0_pregain_func_enum),
|
|
SOC_SINGLE("SPUS0 PREGAIN EN", ATUNE_SPUS_USGAIN_CTRL(0),
|
|
ATUNE_ENABLE_L, 1, 0),
|
|
SOC_SINGLE_XR_SX("SPUS0 PREGAIN VOL CHANGE FADE IN",
|
|
ATUNE_SPUS_USGAIN_VOL_CHANGE_FIN(0),
|
|
1, 32, 0, INT_MAX, 0),
|
|
SOC_SINGLE_XR_SX("SPUS0 PREGAIN VOL CHANGE FADE OUT",
|
|
ATUNE_SPUS_USGAIN_VOL_CHANGE_FOUT(0),
|
|
1, 32, INT_MIN, 0, 0),
|
|
ATUNE_SPUS_PREGAIN_CONTROLS(0),
|
|
SOC_SINGLE("SPUS0 EQ EN", ATUNE_SPUS_BQF_CTRL(0),
|
|
ATUNE_EQ_ENABLE_L, 1, 0),
|
|
SOC_SINGLE("SPUS0 HPF EN", ATUNE_SPUS_BQF_CTRL(0),
|
|
ATUNE_HPF_ENABLE_L, 1, 0),
|
|
SOC_SINGLE("SPUS0 CASCADE EN", ATUNE_SPUS_BQF_CTRL(0),
|
|
ATUNE_CASCADE_EN_L, 1, 0),
|
|
SOC_SINGLE_EXT("SPUS0 PARAM UPDATE", ATUNE_SPUS_BQF_CTRL(0),
|
|
ATUNE_PARAM_UPDATE_L, 1, 0,
|
|
atune_param_update_get, atune_param_update_put),
|
|
ATUNE_SPUS_BQF_HEADROOM_CONTROLS(0),
|
|
ATUNE_SPUS_BQF_POSTAMP_CONTROLS(0),
|
|
ATUNE_SPUS_BQF_COEF_CONTROLS(0),
|
|
SOC_SINGLE("SPUS0 LIMITER WINDOW", ATUNE_SPUS_DRC_CTRL(0),
|
|
ATUNE_LIMIT_WINDOW_SIZE_L, 0xff, 0),
|
|
SOC_SINGLE_S_TLV("SPUS0 DRC NG THRESHOLD", ATUNE_SPUS_DRC_CTRL(0),
|
|
ATUNE_NOISE_THRS_L, -108, -12, 7, 0,
|
|
atune_ng_threshold_tlv),
|
|
SOC_SINGLE("SPUS0 DRC NG HB EN", ATUNE_SPUS_DRC_CTRL(0),
|
|
ATUNE_DRC_NG_ENABLE_HB_L, 1, 0),
|
|
SOC_SINGLE("SPUS0 DRC NG MB EN", ATUNE_SPUS_DRC_CTRL(0),
|
|
ATUNE_DRC_NG_ENABLE_MB_L, 1, 0),
|
|
SOC_SINGLE("SPUS0 DRC NG LB EN", ATUNE_SPUS_DRC_CTRL(0),
|
|
ATUNE_DRC_NG_ENABLE_LB_L, 1, 0),
|
|
SOC_SINGLE("SPUS0 DRC HB EN", ATUNE_SPUS_DRC_CTRL(0),
|
|
ATUNE_DRC_ENABLE_HB_L, 1, 0),
|
|
SOC_SINGLE("SPUS0 DRC MB EN", ATUNE_SPUS_DRC_CTRL(0),
|
|
ATUNE_DRC_ENABLE_MB_L, 1, 0),
|
|
SOC_SINGLE("SPUS0 DRC LB EN", ATUNE_SPUS_DRC_CTRL(0),
|
|
ATUNE_DRC_ENABLE_LB_L, 1, 0),
|
|
SOC_SINGLE("SPUS0 LIMITER EN", ATUNE_SPUS_DRC_CTRL(0),
|
|
ATUNE_LIMIT_ENABLE_L, 1, 0),
|
|
SOC_SINGLE("SPUS0 DRC EN", ATUNE_SPUS_DRC_CTRL(0),
|
|
ATUNE_DRC_ENABLE_L, 1, 0),
|
|
ATUNE_SPUS_DRC_CONTROLS(0),
|
|
SOC_SINGLE("SPUS0 LIMITER THRESHOLD", ATUNE_SPUS_DRC_LMT_CTRL0(0),
|
|
ATUNE_THRESHOLD_L, INT_MAX, 0),
|
|
SOC_SINGLE("SPUS0 LIMITER ATTACK", ATUNE_SPUS_DRC_LMT_CTRL1(0),
|
|
ATUNE_ATTACK_TIME_L, INT_MAX, 0),
|
|
ATUNE_MULTI_LINEAR("SPUS0 DRC XPF0 COEF", ATUNE_SPUS_DRC_xPF0_COEF0(0),
|
|
ATUNE_COEF_L, 4, INT_MIN, INT_MAX, 31, 0),
|
|
ATUNE_MULTI_LINEAR("SPUS0 DRC XPF1 COEF", ATUNE_SPUS_DRC_xPF1_COEF0(0),
|
|
ATUNE_COEF_L, 4, INT_MIN, INT_MAX, 31, 0),
|
|
SOC_ENUM("SPUS0 POSTGAIN FUNC", spus0_postgain_func_enum),
|
|
SOC_SINGLE("SPUS0 POSTGAIN EN", ATUNE_SPUS_DSGAIN_CTRL(0),
|
|
ATUNE_ENABLE_L, 1, 0),
|
|
SOC_SINGLE_XR_SX("SPUS0 POSTGAIN VOL CHANGE FADE IN",
|
|
ATUNE_SPUS_DSGAIN_VOL_CHANGE_FIN(0),
|
|
1, 32, 0, INT_MAX, 0),
|
|
SOC_SINGLE_XR_SX("SPUS0 POSTGAIN VOL CHANGE FADE OUT",
|
|
ATUNE_SPUS_DSGAIN_VOL_CHANGE_FOUT(0),
|
|
1, 32, INT_MIN, 0, 0),
|
|
ATUNE_SPUS_POSTGAIN_CONTROLS(0),
|
|
SOC_ENUM("SPUS0 POSTGAIN Dither Type", spus0_postgain_dither_type_enum),
|
|
|
|
SOC_ENUM("SPUM0 PREGAIN FUNC", spum0_pregain_func_enum),
|
|
SOC_SINGLE("SPUM0 PREGAIN EN", ATUNE_SPUM_USGAIN_CTRL(0),
|
|
ATUNE_ENABLE_L, 1, 0),
|
|
SOC_SINGLE_XR_SX("SPUM0 PREGAIN VOL CHANGE FADE IN",
|
|
ATUNE_SPUM_USGAIN_VOL_CHANGE_FIN(0),
|
|
1, 32, 0, INT_MAX, 0),
|
|
SOC_SINGLE_XR_SX("SPUM0 PREGAIN VOL CHANGE FADE OUT",
|
|
ATUNE_SPUM_USGAIN_VOL_CHANGE_FOUT(0),
|
|
1, 32, INT_MIN, 0, 0),
|
|
ATUNE_SPUM_PREGAIN_CONTROLS(0),
|
|
SOC_SINGLE("SPUM0 EQ EN", ATUNE_SPUM_BQF_CTRL(0),
|
|
ATUNE_EQ_ENABLE_L, 1, 0),
|
|
SOC_SINGLE("SPUM0 HPF EN", ATUNE_SPUM_BQF_CTRL(0),
|
|
ATUNE_HPF_ENABLE_L, 1, 0),
|
|
SOC_SINGLE("SPUM0 CASCADE EN", ATUNE_SPUM_BQF_CTRL(0),
|
|
ATUNE_CASCADE_EN_L, 1, 0),
|
|
SOC_SINGLE_EXT("SPUM0 PARAM UPDATE", ATUNE_SPUM_BQF_CTRL(0),
|
|
ATUNE_PARAM_UPDATE_L, 1, 0,
|
|
atune_param_update_get, atune_param_update_put),
|
|
ATUNE_SPUM_BQF_HEADROOM_CONTROLS(0),
|
|
ATUNE_SPUM_BQF_POSTAMP_CONTROLS(0),
|
|
ATUNE_SPUM_BQF_COEF_CONTROLS(0),
|
|
SOC_SINGLE("SPUM0 LIMITER WINDOW", ATUNE_SPUM_DRC_CTRL(0),
|
|
ATUNE_LIMIT_WINDOW_SIZE_L, 0xff, 0),
|
|
SOC_SINGLE_S_TLV("SPUM0 DRC NG THRESHOLD", ATUNE_SPUM_DRC_CTRL(0),
|
|
ATUNE_NOISE_THRS_L, -108, -12, 7, 0,
|
|
atune_ng_threshold_tlv),
|
|
SOC_SINGLE("SPUM0 DRC NG HB EN", ATUNE_SPUM_DRC_CTRL(0),
|
|
ATUNE_DRC_NG_ENABLE_HB_L, 1, 0),
|
|
SOC_SINGLE("SPUM0 DRC NG MB EN", ATUNE_SPUM_DRC_CTRL(0),
|
|
ATUNE_DRC_NG_ENABLE_MB_L, 1, 0),
|
|
SOC_SINGLE("SPUM0 DRC NG LB EN", ATUNE_SPUM_DRC_CTRL(0),
|
|
ATUNE_DRC_NG_ENABLE_LB_L, 1, 0),
|
|
SOC_SINGLE("SPUM0 DRC HB EN", ATUNE_SPUM_DRC_CTRL(0),
|
|
ATUNE_DRC_ENABLE_HB_L, 1, 0),
|
|
SOC_SINGLE("SPUM0 DRC MB EN", ATUNE_SPUM_DRC_CTRL(0),
|
|
ATUNE_DRC_ENABLE_MB_L, 1, 0),
|
|
SOC_SINGLE("SPUM0 DRC LB EN", ATUNE_SPUM_DRC_CTRL(0),
|
|
ATUNE_DRC_ENABLE_LB_L, 1, 0),
|
|
SOC_SINGLE("SPUM0 LIMITER EN", ATUNE_SPUM_DRC_CTRL(0),
|
|
ATUNE_LIMIT_ENABLE_L, 1, 0),
|
|
SOC_SINGLE("SPUM0 DRC EN", ATUNE_SPUM_DRC_CTRL(0),
|
|
ATUNE_DRC_ENABLE_L, 1, 0),
|
|
ATUNE_SPUM_DRC_CONTROLS(0),
|
|
SOC_SINGLE("SPUM0 LIMITER THRESHOLD", ATUNE_SPUM_DRC_LMT_CTRL0(0),
|
|
ATUNE_THRESHOLD_L, INT_MAX, 0),
|
|
SOC_SINGLE("SPUM0 LIMITER ATTACK", ATUNE_SPUM_DRC_LMT_CTRL1(0),
|
|
ATUNE_ATTACK_TIME_L, INT_MAX, 0),
|
|
ATUNE_MULTI_LINEAR("SPUM0 DRC XPF0 COEF", ATUNE_SPUM_DRC_xPF0_COEF0(0),
|
|
ATUNE_COEF_L, 4, INT_MIN, INT_MAX, 31, 0),
|
|
ATUNE_MULTI_LINEAR("SPUM0 DRC XPF1 COEF", ATUNE_SPUM_DRC_xPF1_COEF0(0),
|
|
ATUNE_COEF_L, 4, INT_MIN, INT_MAX, 31, 0),
|
|
SOC_ENUM("SPUM0 POSTGAIN FUNC", spum0_postgain_func_enum),
|
|
SOC_SINGLE("SPUM0 POSTGAIN EN", ATUNE_SPUM_DSGAIN_CTRL(0),
|
|
ATUNE_ENABLE_L, 1, 0),
|
|
SOC_SINGLE_XR_SX("SPUM0 POSTGAIN VOL CHANGE FADE IN",
|
|
ATUNE_SPUM_DSGAIN_VOL_CHANGE_FIN(0),
|
|
1, 32, 0, INT_MAX, 0),
|
|
SOC_SINGLE_XR_SX("SPUM0 POSTGAIN VOL CHANGE FADE OUT",
|
|
ATUNE_SPUM_DSGAIN_VOL_CHANGE_FOUT(0),
|
|
1, 32, INT_MIN, 0, 0),
|
|
ATUNE_SPUM_POSTGAIN_CONTROLS(0),
|
|
SOC_ENUM("SPUM0 POSTGAIN Dither Type", spum0_postgain_dither_type_enum),
|
|
};
|
|
|
|
static const struct snd_kcontrol_new atune1_controls[] = {
|
|
SOC_ENUM("SPUS1 PREGAIN FUNC", spus1_pregain_func_enum),
|
|
SOC_SINGLE("SPUS1 PREGAIN EN", ATUNE_SPUS_USGAIN_CTRL(1),
|
|
ATUNE_ENABLE_L, 1, 0),
|
|
SOC_SINGLE_XR_SX("SPUS1 PREGAIN VOL CHANGE FADE IN",
|
|
ATUNE_SPUS_USGAIN_VOL_CHANGE_FIN(1),
|
|
1, 32, 0, INT_MAX, 0),
|
|
SOC_SINGLE_XR_SX("SPUS1 PREGAIN VOL CHANGE FADE OUT",
|
|
ATUNE_SPUS_USGAIN_VOL_CHANGE_FOUT(1),
|
|
1, 32, INT_MIN, 0, 0),
|
|
ATUNE_SPUS_PREGAIN_CONTROLS(1),
|
|
SOC_SINGLE("SPUS1 EQ EN", ATUNE_SPUS_BQF_CTRL(1),
|
|
ATUNE_EQ_ENABLE_L, 1, 0),
|
|
SOC_SINGLE("SPUS1 HPF EN", ATUNE_SPUS_BQF_CTRL(1),
|
|
ATUNE_HPF_ENABLE_L, 1, 0),
|
|
SOC_SINGLE("SPUS1 CASCADE EN", ATUNE_SPUS_BQF_CTRL(1),
|
|
ATUNE_CASCADE_EN_L, 1, 0),
|
|
SOC_SINGLE_EXT("SPUS1 PARAM UPDATE", ATUNE_SPUS_BQF_CTRL(1),
|
|
ATUNE_PARAM_UPDATE_L, 1, 0,
|
|
atune_param_update_get, atune_param_update_put),
|
|
ATUNE_SPUS_BQF_HEADROOM_CONTROLS(1),
|
|
ATUNE_SPUS_BQF_POSTAMP_CONTROLS(1),
|
|
ATUNE_SPUS_BQF_COEF_CONTROLS(1),
|
|
SOC_SINGLE("SPUS1 LIMITER WINDOW", ATUNE_SPUS_DRC_CTRL(1),
|
|
ATUNE_LIMIT_WINDOW_SIZE_L, 0xff, 0),
|
|
SOC_SINGLE_S_TLV("SPUS1 DRC NG THRESHOLD", ATUNE_SPUS_DRC_CTRL(1),
|
|
ATUNE_NOISE_THRS_L, -108, -12, 7, 0,
|
|
atune_ng_threshold_tlv),
|
|
SOC_SINGLE("SPUS1 DRC NG HB EN", ATUNE_SPUS_DRC_CTRL(1),
|
|
ATUNE_DRC_NG_ENABLE_HB_L, 1, 0),
|
|
SOC_SINGLE("SPUS1 DRC NG MB EN", ATUNE_SPUS_DRC_CTRL(1),
|
|
ATUNE_DRC_NG_ENABLE_MB_L, 1, 0),
|
|
SOC_SINGLE("SPUS1 DRC NG LB EN", ATUNE_SPUS_DRC_CTRL(1),
|
|
ATUNE_DRC_NG_ENABLE_LB_L, 1, 0),
|
|
SOC_SINGLE("SPUS1 DRC HB EN", ATUNE_SPUS_DRC_CTRL(1),
|
|
ATUNE_DRC_ENABLE_HB_L, 1, 0),
|
|
SOC_SINGLE("SPUS1 DRC MB EN", ATUNE_SPUS_DRC_CTRL(1),
|
|
ATUNE_DRC_ENABLE_MB_L, 1, 0),
|
|
SOC_SINGLE("SPUS1 DRC LB EN", ATUNE_SPUS_DRC_CTRL(1),
|
|
ATUNE_DRC_ENABLE_LB_L, 1, 0),
|
|
SOC_SINGLE("SPUS1 LIMITER EN", ATUNE_SPUS_DRC_CTRL(1),
|
|
ATUNE_LIMIT_ENABLE_L, 1, 0),
|
|
SOC_SINGLE("SPUS1 DRC EN", ATUNE_SPUS_DRC_CTRL(1),
|
|
ATUNE_DRC_ENABLE_L, 1, 0),
|
|
ATUNE_SPUS_DRC_CONTROLS(1),
|
|
SOC_SINGLE("SPUS1 LIMITER THRESHOLD", ATUNE_SPUS_DRC_LMT_CTRL0(1),
|
|
ATUNE_THRESHOLD_L, INT_MAX, 0),
|
|
SOC_SINGLE("SPUS1 LIMITER ATTACK", ATUNE_SPUS_DRC_LMT_CTRL1(1),
|
|
ATUNE_ATTACK_TIME_L, INT_MAX, 0),
|
|
ATUNE_MULTI_LINEAR("SPUS1 DRC XPF0 COEF", ATUNE_SPUS_DRC_xPF0_COEF0(1),
|
|
ATUNE_COEF_L, 4, INT_MIN, INT_MAX, 31, 0),
|
|
ATUNE_MULTI_LINEAR("SPUS1 DRC XPF1 COEF", ATUNE_SPUS_DRC_xPF1_COEF0(1),
|
|
ATUNE_COEF_L, 4, INT_MIN, INT_MAX, 31, 0),
|
|
SOC_ENUM("SPUS1 POSTGAIN FUNC", spus1_postgain_func_enum),
|
|
SOC_SINGLE("SPUS1 POSTGAIN EN", ATUNE_SPUS_DSGAIN_CTRL(1),
|
|
ATUNE_ENABLE_L, 1, 0),
|
|
SOC_SINGLE_XR_SX("SPUS1 POSTGAIN VOL CHANGE FADE IN",
|
|
ATUNE_SPUS_DSGAIN_VOL_CHANGE_FIN(1),
|
|
1, 32, 0, INT_MAX, 0),
|
|
SOC_SINGLE_XR_SX("SPUS1 POSTGAIN VOL CHANGE FADE OUT",
|
|
ATUNE_SPUS_DSGAIN_VOL_CHANGE_FOUT(1),
|
|
1, 32, INT_MIN, 0, 0),
|
|
ATUNE_SPUS_POSTGAIN_CONTROLS(1),
|
|
SOC_ENUM("SPUS1 POSTGAIN Dither Type", spus1_postgain_dither_type_enum),
|
|
|
|
SOC_ENUM("SPUM1 PREGAIN FUNC", spum1_pregain_func_enum),
|
|
SOC_SINGLE("SPUM1 PREGAIN EN", ATUNE_SPUM_USGAIN_CTRL(1),
|
|
ATUNE_ENABLE_L, 1, 0),
|
|
SOC_SINGLE_XR_SX("SPUM1 PREGAIN VOL CHANGE FADE IN",
|
|
ATUNE_SPUM_USGAIN_VOL_CHANGE_FIN(1),
|
|
1, 32, 0, INT_MAX, 0),
|
|
SOC_SINGLE_XR_SX("SPUM1 PREGAIN VOL CHANGE FADE OUT",
|
|
ATUNE_SPUM_USGAIN_VOL_CHANGE_FOUT(1),
|
|
1, 32, INT_MIN, 0, 0),
|
|
ATUNE_SPUM_PREGAIN_CONTROLS(1),
|
|
SOC_SINGLE("SPUM1 EQ EN", ATUNE_SPUM_BQF_CTRL(1),
|
|
ATUNE_EQ_ENABLE_L, 1, 0),
|
|
SOC_SINGLE("SPUM1 HPF EN", ATUNE_SPUM_BQF_CTRL(1),
|
|
ATUNE_HPF_ENABLE_L, 1, 0),
|
|
SOC_SINGLE("SPUM1 CASCADE EN", ATUNE_SPUM_BQF_CTRL(1),
|
|
ATUNE_CASCADE_EN_L, 1, 0),
|
|
SOC_SINGLE_EXT("SPUM1 PARAM UPDATE", ATUNE_SPUM_BQF_CTRL(1),
|
|
ATUNE_PARAM_UPDATE_L, 1, 0,
|
|
atune_param_update_get, atune_param_update_put),
|
|
ATUNE_SPUM_BQF_HEADROOM_CONTROLS(1),
|
|
ATUNE_SPUM_BQF_POSTAMP_CONTROLS(1),
|
|
ATUNE_SPUM_BQF_COEF_CONTROLS(1),
|
|
SOC_SINGLE("SPUM1 LIMITER WINDOW", ATUNE_SPUM_DRC_CTRL(1),
|
|
ATUNE_LIMIT_WINDOW_SIZE_L, 0xff, 0),
|
|
SOC_SINGLE_S_TLV("SPUM1 DRC NG THRESHOLD", ATUNE_SPUM_DRC_CTRL(1),
|
|
ATUNE_NOISE_THRS_L, -108, -12, 7, 0,
|
|
atune_ng_threshold_tlv),
|
|
SOC_SINGLE("SPUM1 DRC NG HB EN", ATUNE_SPUM_DRC_CTRL(1),
|
|
ATUNE_DRC_NG_ENABLE_HB_L, 1, 0),
|
|
SOC_SINGLE("SPUM1 DRC NG MB EN", ATUNE_SPUM_DRC_CTRL(1),
|
|
ATUNE_DRC_NG_ENABLE_MB_L, 1, 0),
|
|
SOC_SINGLE("SPUM1 DRC NG LB EN", ATUNE_SPUM_DRC_CTRL(1),
|
|
ATUNE_DRC_NG_ENABLE_LB_L, 1, 0),
|
|
SOC_SINGLE("SPUM1 DRC HB EN", ATUNE_SPUM_DRC_CTRL(1),
|
|
ATUNE_DRC_ENABLE_HB_L, 1, 0),
|
|
SOC_SINGLE("SPUM1 DRC MB EN", ATUNE_SPUM_DRC_CTRL(1),
|
|
ATUNE_DRC_ENABLE_MB_L, 1, 0),
|
|
SOC_SINGLE("SPUM1 DRC LB EN", ATUNE_SPUM_DRC_CTRL(1),
|
|
ATUNE_DRC_ENABLE_LB_L, 1, 0),
|
|
SOC_SINGLE("SPUM1 LIMITER EN", ATUNE_SPUM_DRC_CTRL(1),
|
|
ATUNE_LIMIT_ENABLE_L, 1, 0),
|
|
SOC_SINGLE("SPUM1 DRC EN", ATUNE_SPUM_DRC_CTRL(1),
|
|
ATUNE_DRC_ENABLE_L, 1, 0),
|
|
ATUNE_SPUM_DRC_CONTROLS(1),
|
|
SOC_SINGLE("SPUM1 LIMITER THRESHOLD", ATUNE_SPUM_DRC_LMT_CTRL0(1),
|
|
ATUNE_THRESHOLD_L, INT_MAX, 0),
|
|
SOC_SINGLE("SPUM1 LIMITER ATTACK", ATUNE_SPUM_DRC_LMT_CTRL1(1),
|
|
ATUNE_ATTACK_TIME_L, INT_MAX, 0),
|
|
ATUNE_MULTI_LINEAR("SPUM1 DRC XPF0 COEF", ATUNE_SPUM_DRC_xPF0_COEF0(1),
|
|
ATUNE_COEF_L, 4, INT_MIN, INT_MAX, 31, 0),
|
|
ATUNE_MULTI_LINEAR("SPUM1 DRC XPF1 COEF", ATUNE_SPUM_DRC_xPF1_COEF0(1),
|
|
ATUNE_COEF_L, 4, INT_MIN, INT_MAX, 31, 0),
|
|
SOC_ENUM("SPUM1 POSTGAIN FUNC", spum1_postgain_func_enum),
|
|
SOC_SINGLE("SPUM1 POSTGAIN EN", ATUNE_SPUM_DSGAIN_CTRL(1),
|
|
ATUNE_ENABLE_L, 1, 0),
|
|
SOC_SINGLE_XR_SX("SPUM1 POSTGAIN VOL CHANGE FADE IN",
|
|
ATUNE_SPUM_DSGAIN_VOL_CHANGE_FIN(1),
|
|
1, 32, 0, INT_MAX, 0),
|
|
SOC_SINGLE_XR_SX("SPUM1 POSTGAIN VOL CHANGE FADE OUT",
|
|
ATUNE_SPUM_DSGAIN_VOL_CHANGE_FOUT(1),
|
|
1, 32, INT_MIN, 0, 0),
|
|
ATUNE_SPUM_POSTGAIN_CONTROLS(1),
|
|
SOC_ENUM("SPUM1 POSTGAIN Dither Type", spum1_postgain_dither_type_enum),
|
|
};
|
|
|
|
static const unsigned int spus_pre_tune_mask =
|
|
ABOX_PRE_TUNE_SEL_MASK(0) >> ABOX_PRE_TUNE_SEL_L(0);
|
|
static const char * const spus_pre_tune_texts[] = {
|
|
"SPUS0", "SPUS1", "SPUS2", "SPUS3",
|
|
"SPUS4", "SPUS5", "SPUS6", "SPUS7",
|
|
"SPUS8", "SPUS9", "SPUS10", "SPUS11",
|
|
"RESERVED",
|
|
};
|
|
static const unsigned int spus_pre_tune_values[] = {
|
|
0x0, 0x1, 0x2, 0x3,
|
|
0x4, 0x5, 0x6, 0x7,
|
|
0x8, 0x9, 0xa, 0xb,
|
|
0xf,
|
|
};
|
|
static SOC_VALUE_ENUM_SINGLE_DECL(spus_pre_tune0_enum,
|
|
ABOX_SPUS_CTRL_TUNE_SEL, ABOX_PRE_TUNE_SEL_L(0),
|
|
spus_pre_tune_mask, spus_pre_tune_texts, spus_pre_tune_values);
|
|
static const struct snd_kcontrol_new spus_pre_tune0_controls[] = {
|
|
SOC_DAPM_ENUM("SPUS PRETUNE0 SEL", spus_pre_tune0_enum),
|
|
};
|
|
static SOC_VALUE_ENUM_SINGLE_DECL(spus_pre_tune1_enum,
|
|
ABOX_SPUS_CTRL_TUNE_SEL, ABOX_PRE_TUNE_SEL_L(1),
|
|
spus_pre_tune_mask, spus_pre_tune_texts, spus_pre_tune_values);
|
|
static const struct snd_kcontrol_new spus_pre_tune1_controls[] = {
|
|
SOC_DAPM_ENUM("SPUS PRETUNE1 SEL", spus_pre_tune1_enum),
|
|
};
|
|
|
|
static int atune_find_spus(struct snd_soc_component *cmpnt, int aid)
|
|
{
|
|
unsigned int val;
|
|
int ret;
|
|
|
|
val = snd_soc_component_read(cmpnt, ABOX_SPUS_CTRL_TUNE_SEL);
|
|
ret = (val & ABOX_PRE_TUNE_SEL_MASK(aid)) >> ABOX_PRE_TUNE_SEL_L(aid);
|
|
if (ret > 0xb)
|
|
ret = -EPIPE;
|
|
|
|
return ret;
|
|
}
|
|
|
|
static const unsigned int spus_post_tune_mask =
|
|
ABOX_POST_TUNE_SEL_MASK(0) >> ABOX_POST_TUNE_SEL_L(0);
|
|
static const char * const spus_post_tune_texts[] = {
|
|
"SIFS0", "SIFS1", "SIFS2", "SIFS3",
|
|
"SIFS4", "SIFS5", "SIFS6", "RESERVED",
|
|
};
|
|
static const unsigned int spus_post_tune_values[] = {
|
|
0x0, 0x1, 0x2, 0x3,
|
|
0x4, 0x5, 0x6, 0xf,
|
|
};
|
|
static SOC_VALUE_ENUM_SINGLE_DECL(spus_post_tune0_enum,
|
|
ABOX_SPUS_CTRL_TUNE_SEL, ABOX_POST_TUNE_SEL_L(0),
|
|
spus_post_tune_mask, spus_post_tune_texts,
|
|
spus_post_tune_values);
|
|
static const struct snd_kcontrol_new spus_post_tune0_controls[] = {
|
|
SOC_DAPM_ENUM("SPUS POSTTUNE0 SEL", spus_post_tune0_enum),
|
|
};
|
|
static SOC_VALUE_ENUM_SINGLE_DECL(spus_post_tune1_enum,
|
|
ABOX_SPUS_CTRL_TUNE_SEL, ABOX_POST_TUNE_SEL_L(1),
|
|
spus_post_tune_mask, spus_post_tune_texts,
|
|
spus_post_tune_values);
|
|
static const struct snd_kcontrol_new spus_post_tune1_controls[] = {
|
|
SOC_DAPM_ENUM("SPUS POSTTUNE1 SEL", spus_post_tune1_enum),
|
|
};
|
|
|
|
static int atune_find_sifs(struct snd_soc_component *cmpnt, int aid)
|
|
{
|
|
unsigned int val;
|
|
int ret;
|
|
|
|
val = snd_soc_component_read(cmpnt, ABOX_SPUS_CTRL_TUNE_SEL);
|
|
ret = (val & ABOX_POST_TUNE_SEL_MASK(aid)) >> ABOX_POST_TUNE_SEL_L(aid);
|
|
if (ret > 0x6)
|
|
ret = -EPIPE;
|
|
|
|
return ret;
|
|
}
|
|
|
|
static const unsigned int spum_tune_mask =
|
|
ABOX_PRE_TUNE_SEL_MASK(0) >> ABOX_PRE_TUNE_SEL_L(0);
|
|
static const char * const spum_tune_texts[] = {
|
|
"SIFM0", "SIFM1", "SIFM2", "SIFM3",
|
|
"SIFM4", "SIFM5", "SIFM6", "SIFM7",
|
|
"SIFM8", "SIFM9", "SIFM10", "SIFM11",
|
|
"RESERVED",
|
|
};
|
|
static const unsigned int spum_tune_values[] = {
|
|
0x0, 0x1, 0x2, 0x3,
|
|
0x4, 0x5, 0x6, 0x7,
|
|
0x8, 0x9, 0xa, 0xb,
|
|
0xf,
|
|
};
|
|
static SOC_VALUE_ENUM_SINGLE_DECL(spum_pre_tune0_enum,
|
|
ABOX_SPUM_CTRL_TUNE_SEL, ABOX_PRE_TUNE_SEL_L(0),
|
|
spum_tune_mask, spum_tune_texts, spum_tune_values);
|
|
static const struct snd_kcontrol_new spum_pre_tune0_controls[] = {
|
|
SOC_DAPM_ENUM("SPUM PRETUNE0 SEL", spum_pre_tune0_enum),
|
|
};
|
|
static SOC_VALUE_ENUM_SINGLE_DECL(spum_pre_tune1_enum,
|
|
ABOX_SPUM_CTRL_TUNE_SEL, ABOX_PRE_TUNE_SEL_L(1),
|
|
spum_tune_mask, spum_tune_texts, spum_tune_values);
|
|
static const struct snd_kcontrol_new spum_pre_tune1_controls[] = {
|
|
SOC_DAPM_ENUM("SPUM PRETUNE1 SEL", spum_pre_tune1_enum),
|
|
};
|
|
static SOC_VALUE_ENUM_SINGLE_DECL(spum_post_tune0_enum,
|
|
ABOX_SPUM_CTRL_TUNE_SEL, ABOX_POST_TUNE_SEL_L(0),
|
|
spum_tune_mask, spum_tune_texts, spum_tune_values);
|
|
static const struct snd_kcontrol_new spum_post_tune0_controls[] = {
|
|
SOC_DAPM_ENUM("SPUM POSTTUNE0 SEL", spum_post_tune0_enum),
|
|
};
|
|
static SOC_VALUE_ENUM_SINGLE_DECL(spum_post_tune1_enum,
|
|
ABOX_SPUM_CTRL_TUNE_SEL, ABOX_POST_TUNE_SEL_L(1),
|
|
spum_tune_mask, spum_tune_texts, spum_tune_values);
|
|
static const struct snd_kcontrol_new spum_post_tune1_controls[] = {
|
|
SOC_DAPM_ENUM("SPUM POSTTUNE1 SEL", spum_post_tune1_enum),
|
|
};
|
|
|
|
static int atune_find_nsrc(struct snd_soc_component *cmpnt, int aid)
|
|
{
|
|
unsigned int val;
|
|
int ret;
|
|
|
|
val = snd_soc_component_read(cmpnt, ABOX_SPUM_CTRL_TUNE_SEL);
|
|
ret = (val & ABOX_PRE_TUNE_SEL_MASK(aid)) >> ABOX_PRE_TUNE_SEL_L(aid);
|
|
if (ret > 0x7)
|
|
ret = -EPIPE;
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int atune_find_sifm(struct snd_soc_component *cmpnt, int aid)
|
|
{
|
|
unsigned int val;
|
|
int ret;
|
|
|
|
val = snd_soc_component_read(cmpnt, ABOX_SPUM_CTRL_TUNE_SEL);
|
|
ret = (val & ABOX_POST_TUNE_SEL_MASK(aid)) >> ABOX_POST_TUNE_SEL_L(aid);
|
|
if (ret > 0x7)
|
|
ret = -EPIPE;
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int sifs_from_spus(struct abox_data *data, int sid)
|
|
{
|
|
return abox_cmpnt_spus_get_sifs(data, sid);
|
|
}
|
|
|
|
static int pretune_id_from_spus(struct abox_data *data, int sid)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
int aid, ret = -EPIPE;
|
|
|
|
for (aid = 0; aid < COUNT_ATUNE; aid++) {
|
|
ret = atune_find_spus(cmpnt, aid);
|
|
if (ret == sid)
|
|
return aid;
|
|
}
|
|
|
|
return -EPIPE;
|
|
}
|
|
|
|
static int posttune_id_from_sifs(struct abox_data *data, int sid)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
int aid, ret = -EPIPE;
|
|
|
|
for (aid = 0; aid < COUNT_ATUNE; aid++) {
|
|
ret = atune_find_sifs(cmpnt, aid);
|
|
if (ret == sid)
|
|
return aid;
|
|
}
|
|
|
|
return -EPIPE;
|
|
}
|
|
|
|
static int posttune_id_from_spus(struct abox_data *data, int sid)
|
|
{
|
|
int sifs = sifs_from_spus(data, sid);
|
|
|
|
if (sifs < 0)
|
|
return sifs;
|
|
else
|
|
return posttune_id_from_sifs(data, sifs);
|
|
}
|
|
|
|
static int pretune_id_from_nsrc(struct abox_data *data, int sid)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
int aid, ret = -EPIPE;
|
|
|
|
for (aid = 0; aid < COUNT_ATUNE; aid++) {
|
|
ret = atune_find_nsrc(cmpnt, aid);
|
|
if (ret == sid)
|
|
return aid;
|
|
}
|
|
|
|
return -EPIPE;
|
|
}
|
|
|
|
static int posttune_id_from_sifm(struct abox_data *data, int sid)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
int aid, ret = -EPIPE;
|
|
|
|
for (aid = 0; aid < COUNT_ATUNE; aid++) {
|
|
ret = atune_find_sifm(cmpnt, aid);
|
|
if (ret == sid)
|
|
return aid;
|
|
}
|
|
|
|
return -EPIPE;
|
|
}
|
|
|
|
static int posttune_id_from_nsrc(struct abox_data *data, int sid)
|
|
{
|
|
/* nsrc and sifm is matched by one to one */
|
|
return posttune_id_from_sifm(data, sid);
|
|
}
|
|
|
|
static int spus_pregain_enabled(struct abox_data *data, int aid)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
unsigned int val;
|
|
|
|
val = snd_soc_component_read(cmpnt, ATUNE_SPUS_USGAIN_CTRL(aid));
|
|
|
|
return !!(val & ATUNE_ENABLE_MASK);
|
|
}
|
|
|
|
static int spus_bqf_enabled(struct abox_data *data, int aid)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
unsigned int val;
|
|
|
|
val = snd_soc_component_read(cmpnt, ATUNE_SPUS_BQF_CTRL(aid));
|
|
|
|
return !!(val & (ATUNE_EQ_ENABLE_MASK | ATUNE_HPF_ENABLE_MASK));
|
|
}
|
|
|
|
static int spus_drc_enabled(struct abox_data *data, int aid)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
unsigned int val;
|
|
|
|
val = snd_soc_component_read(cmpnt, ATUNE_SPUS_DRC_CTRL(aid));
|
|
|
|
return !!(val & (ATUNE_DRC_ENABLE_MASK | ATUNE_LIMIT_ENABLE_MASK));
|
|
}
|
|
|
|
static int spus_postgain_enabled(struct abox_data *data, int aid)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
unsigned int val;
|
|
|
|
val = snd_soc_component_read(cmpnt, ATUNE_SPUS_DSGAIN_CTRL(aid));
|
|
|
|
return !!(val & ATUNE_ENABLE_MASK);
|
|
}
|
|
|
|
static int spum_pregain_enabled(struct abox_data *data, int aid)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
unsigned int val;
|
|
|
|
val = snd_soc_component_read(cmpnt, ATUNE_SPUM_USGAIN_CTRL(aid));
|
|
|
|
return !!(val & ATUNE_ENABLE_MASK);
|
|
}
|
|
|
|
static int spum_bqf_enabled(struct abox_data *data, int aid)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
unsigned int val;
|
|
|
|
val = snd_soc_component_read(cmpnt, ATUNE_SPUM_BQF_CTRL(aid));
|
|
|
|
return !!(val & (ATUNE_EQ_ENABLE_MASK | ATUNE_HPF_ENABLE_MASK));
|
|
}
|
|
|
|
static int spum_drc_enabled(struct abox_data *data, int aid)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
unsigned int val;
|
|
|
|
val = snd_soc_component_read(cmpnt, ATUNE_SPUM_DRC_CTRL(aid));
|
|
|
|
return !!(val & (ATUNE_DRC_ENABLE_MASK | ATUNE_LIMIT_ENABLE_MASK));
|
|
}
|
|
|
|
static int spum_postgain_enabled(struct abox_data *data, int aid)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
unsigned int val;
|
|
|
|
val = snd_soc_component_read(cmpnt, ATUNE_SPUM_DSGAIN_CTRL(aid));
|
|
|
|
return !!(val & ATUNE_ENABLE_MASK);
|
|
}
|
|
|
|
static int spus_posttune_enabled(struct abox_data *data, int sid)
|
|
{
|
|
int aid = posttune_id_from_spus(data, sid);
|
|
|
|
if (aid < 0)
|
|
return 0;
|
|
|
|
return spus_bqf_enabled(data, aid) || spus_drc_enabled(data, aid)
|
|
|| spus_postgain_enabled(data, aid);
|
|
}
|
|
|
|
static int spum_pretune_enabled(struct abox_data *data, int sid)
|
|
{
|
|
int aid = pretune_id_from_nsrc(data, sid);
|
|
|
|
if (aid < 0)
|
|
return 0;
|
|
|
|
return spum_pregain_enabled(data, aid) || spum_bqf_enabled(data, aid);
|
|
}
|
|
|
|
static int spus_pregain_event(struct abox_data *data, int e, int aid, int sid)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
struct device *dev_dma;
|
|
unsigned int shift, mask, val, width, channels;
|
|
int ret = 0;
|
|
struct snd_pcm_hw_params params;
|
|
|
|
if (aid < 0 || sid < 0)
|
|
return 0;
|
|
|
|
abox_dbg(data->dev, "%s(%d, %d, %d)\n", __func__, e, aid, sid);
|
|
|
|
if (SND_SOC_DAPM_EVENT_ON(e)) {
|
|
/* sync function chain */
|
|
val = spus_pregain_enabled(data, aid);
|
|
shift = ABOX_FUNC_CHAIN_SRC_USG_L(sid);
|
|
mask = ABOX_FUNC_CHAIN_SRC_USG_MASK(sid);
|
|
ret = snd_soc_component_update_bits(cmpnt,
|
|
ABOX_SPUS_CTRL_FC_SRC(sid),
|
|
mask, val << shift);
|
|
if (ret < 0) {
|
|
abox_err(data->dev, "%s: function chain set fail: %d\n",
|
|
__func__, ret);
|
|
goto out;
|
|
}
|
|
|
|
abox_dbg(data->dev, "%s(%d, %d, %d): %s\n", __func__,
|
|
e, aid, sid, val ? "connected" : "disconnected");
|
|
|
|
if (!spus_posttune_enabled(data, sid)) {
|
|
/* if pretune only is enabled,
|
|
* enable ASRC for bit conversion
|
|
*/
|
|
abox_cmpnt_asrc_enable(data, SNDRV_PCM_STREAM_PLAYBACK,
|
|
sid);
|
|
}
|
|
|
|
/* sync format */
|
|
dev_dma = data->dev_rdma[sid];
|
|
ret = abox_dma_hw_params_fixup(dev_dma, ¶ms);
|
|
if (ret < 0) {
|
|
abox_err(data->dev, "%s: hw params get failed: %d\n",
|
|
__func__, ret);
|
|
goto out;
|
|
}
|
|
width = abox_dma_get_dst_bit_width(dev_dma);
|
|
channels = params_channels(¶ms);
|
|
val = abox_get_format(width, channels);
|
|
shift = ATUNE_FORMAT_L;
|
|
mask = ATUNE_FORMAT_MASK;
|
|
ret = snd_soc_component_update_bits(cmpnt,
|
|
ATUNE_SPUS_USGAIN_CTRL(aid),
|
|
mask, val << shift);
|
|
abox_dbg(data->dev, "%s(%d, %d): input format=%#x\n", __func__,
|
|
aid, sid, val);
|
|
}
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static int spus_pregain0_event(struct snd_soc_dapm_widget *w,
|
|
struct snd_kcontrol *k, int e)
|
|
{
|
|
return spus_pregain_event(NULL, e, 0, 0);
|
|
}
|
|
|
|
static int spus_pregain1_event(struct snd_soc_dapm_widget *w,
|
|
struct snd_kcontrol *k, int e)
|
|
{
|
|
return spus_pregain_event(NULL, e, 1, 0);
|
|
}
|
|
|
|
static int spus_bqf_event(struct abox_data *data, int e, int aid, int sid)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
unsigned int shift, mask, val;
|
|
int ret = 0;
|
|
|
|
if (aid < 0 || sid < 0)
|
|
return 0;
|
|
|
|
abox_dbg(data->dev, "%s(%d, %d, %d)\n", __func__, e, aid, sid);
|
|
|
|
if (SND_SOC_DAPM_EVENT_ON(e)) {
|
|
/* sync function chain */
|
|
val = spus_bqf_enabled(data, aid);
|
|
shift = ABOX_FUNC_CHAIN_SRC_BQF_L(sid);
|
|
mask = ABOX_FUNC_CHAIN_SRC_BQF_MASK(sid);
|
|
ret = snd_soc_component_update_bits(cmpnt,
|
|
ABOX_SPUS_CTRL_FC_SRC(sid),
|
|
mask, val << shift);
|
|
if (ret < 0) {
|
|
abox_err(data->dev, "%s: function chain set fail: %d\n",
|
|
__func__, ret);
|
|
goto out;
|
|
}
|
|
|
|
abox_dbg(data->dev, "%s(%d, %d, %d): %s\n", __func__,
|
|
e, aid, sid, val ? "connected" : "disconnected");
|
|
|
|
/* atune can process 32bit only */
|
|
if (val)
|
|
abox_dma_set_dst_bit_width(data->dev_rdma[sid], 32);
|
|
}
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static int spus_bqf0_event(struct snd_soc_dapm_widget *w,
|
|
struct snd_kcontrol *k, int e)
|
|
{
|
|
/* later use */
|
|
return 0;
|
|
}
|
|
|
|
static int spus_bqf1_event(struct snd_soc_dapm_widget *w,
|
|
struct snd_kcontrol *k, int e)
|
|
{
|
|
/* later use */
|
|
return 0;
|
|
}
|
|
|
|
static int spus_drc_event(struct abox_data *data, int e, int aid, int sid)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
unsigned int shift, mask, val;
|
|
int ret = 0;
|
|
|
|
if (aid < 0 || sid < 0)
|
|
return 0;
|
|
|
|
abox_dbg(data->dev, "%s(%d, %d, %d)\n", __func__, e, aid, sid);
|
|
|
|
if (SND_SOC_DAPM_EVENT_ON(e)) {
|
|
/* sync function chain */
|
|
val = spus_drc_enabled(data, aid);
|
|
shift = ABOX_FUNC_CHAIN_SRC_DRC_L(sid);
|
|
mask = ABOX_FUNC_CHAIN_SRC_DRC_MASK(sid);
|
|
ret = snd_soc_component_update_bits(cmpnt,
|
|
ABOX_SPUS_CTRL_FC_SRC(sid),
|
|
mask, val << shift);
|
|
if (ret < 0) {
|
|
abox_err(data->dev, "%s: function chain set fail: %d\n",
|
|
__func__, ret);
|
|
goto out;
|
|
}
|
|
|
|
abox_dbg(data->dev, "%s(%d, %d, %d): %s\n", __func__,
|
|
e, aid, sid, val ? "connected" : "disconnected");
|
|
|
|
/* atune can process 32bit only */
|
|
if (val)
|
|
abox_dma_set_dst_bit_width(data->dev_rdma[sid], 32);
|
|
}
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static int spus_drc0_event(struct snd_soc_dapm_widget *w,
|
|
struct snd_kcontrol *k, int e)
|
|
{
|
|
/* later use */
|
|
return 0;
|
|
}
|
|
|
|
static int spus_drc1_event(struct snd_soc_dapm_widget *w,
|
|
struct snd_kcontrol *k, int e)
|
|
{
|
|
/* later use */
|
|
return 0;
|
|
}
|
|
|
|
static int spus_postgain_event(struct abox_data *data, int e, int aid, int sid)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
unsigned int shift, mask, val, rate, format;
|
|
int sifs_id, ret = 0;
|
|
|
|
if (aid < 0 || sid < 0)
|
|
return 0;
|
|
|
|
abox_dbg(data->dev, "%s(%d, %d, %d)\n", __func__, e, aid, sid);
|
|
|
|
if (SND_SOC_DAPM_EVENT_ON(e)) {
|
|
/* sync function chain */
|
|
val = spus_postgain_enabled(data, aid);
|
|
shift = ABOX_FUNC_CHAIN_SRC_DSG_L(sid);
|
|
mask = ABOX_FUNC_CHAIN_SRC_DSG_MASK(sid);
|
|
ret = snd_soc_component_update_bits(cmpnt,
|
|
ABOX_SPUS_CTRL_FC_SRC(sid),
|
|
mask, val << shift);
|
|
if (ret < 0) {
|
|
abox_err(data->dev, "%s: function chain set fail: %d\n",
|
|
__func__, ret);
|
|
goto out;
|
|
}
|
|
|
|
abox_dbg(data->dev, "%s(%d, %d, %d): %s\n", __func__,
|
|
e, aid, sid, val ? "connected" : "disconnected");
|
|
|
|
/* atune can process 32bit only */
|
|
if (val)
|
|
abox_dma_set_dst_bit_width(data->dev_rdma[sid], 32);
|
|
|
|
/* get sifs id */
|
|
sifs_id = sifs_from_spus(data, sid);
|
|
if (sifs_id < 0) {
|
|
abox_err(data->dev, "%s: invalid sifs: %d\n",
|
|
__func__, sifs_id);
|
|
goto out;
|
|
}
|
|
|
|
/* get rate */
|
|
rate = abox_cmpnt_sif_get_dst_rate(data,
|
|
SNDRV_PCM_STREAM_PLAYBACK, sifs_id);
|
|
|
|
/* sync rate */
|
|
val = ilog2((rate / 48000));
|
|
shift = ATUNE_SAMPLE_RATE_L;
|
|
mask = ATUNE_SAMPLE_RATE_MASK;
|
|
ret = snd_soc_component_update_bits(cmpnt,
|
|
ATUNE_SPUS_DSGAIN_CTRL(aid),
|
|
mask, val << shift);
|
|
abox_dbg(data->dev, "%s(%d, %d): rate=%#x\n", __func__,
|
|
aid, sid, val);
|
|
|
|
/* get format */
|
|
format = abox_cmpnt_sif_get_dst_format(data,
|
|
SNDRV_PCM_STREAM_PLAYBACK, sifs_id);
|
|
|
|
/* sync input format */
|
|
val = format | (0x3 << 3); /* 32bit fixed */
|
|
shift = ATUNE_FORMAT_L;
|
|
mask = ATUNE_FORMAT_MASK;
|
|
ret = snd_soc_component_update_bits(cmpnt,
|
|
ATUNE_SPUS_DSGAIN_CTRL(aid),
|
|
mask, val << shift);
|
|
abox_dbg(data->dev, "%s(%d, %d): input format=%#x\n", __func__,
|
|
aid, sid, val);
|
|
|
|
/* sync output format */
|
|
val = format >> 0x3;
|
|
shift = ATUNE_DITHER_OUTPUT_BIT_L;
|
|
mask = ATUNE_DITHER_OUTPUT_BIT_MASK;
|
|
ret = snd_soc_component_update_bits(cmpnt,
|
|
ATUNE_SPUS_DSGAIN_BIT_CTRL(aid),
|
|
mask, val << shift);
|
|
abox_dbg(data->dev, "%s(%d, %d): output format=%#x\n", __func__,
|
|
aid, sid, val);
|
|
}
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static int spus_postgain0_event(struct snd_soc_dapm_widget *w,
|
|
struct snd_kcontrol *k, int e)
|
|
{
|
|
/* later use */
|
|
return 0;
|
|
}
|
|
|
|
static int spus_postgain1_event(struct snd_soc_dapm_widget *w,
|
|
struct snd_kcontrol *k, int e)
|
|
{
|
|
/* later use */
|
|
return 0;
|
|
}
|
|
|
|
static int spum_pregain_event(struct abox_data *data, int e, int aid, int sid)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
unsigned int shift, mask, val;
|
|
int ret = 0;
|
|
|
|
if (aid < 0 || sid < 0)
|
|
return 0;
|
|
|
|
abox_dbg(data->dev, "%s(%d, %d, %d)\n", __func__, e, aid, sid);
|
|
|
|
if (SND_SOC_DAPM_EVENT_ON(e)) {
|
|
/* sync function chain */
|
|
val = spum_pregain_enabled(data, aid);
|
|
shift = ABOX_FUNC_CHAIN_NSRC_USG_L(sid);
|
|
mask = ABOX_FUNC_CHAIN_NSRC_USG_MASK(sid);
|
|
ret = snd_soc_component_update_bits(cmpnt,
|
|
ABOX_SPUM_CTRL_FC_NSRC(sid),
|
|
mask, val << shift);
|
|
if (ret < 0) {
|
|
abox_err(data->dev, "%s: function chain set fail: %d\n",
|
|
__func__, ret);
|
|
goto out;
|
|
}
|
|
|
|
abox_dbg(data->dev, "%s(%d, %d, %d): %s\n", __func__,
|
|
e, aid, sid, val ? "connected" : "disconnected");
|
|
|
|
/* atune can process 32bit only */
|
|
if (val)
|
|
abox_dma_set_dst_bit_width(data->dev_wdma[sid], 32);
|
|
|
|
/* sync format */
|
|
val = abox_cmpnt_sif_get_dst_format(data,
|
|
SNDRV_PCM_STREAM_CAPTURE, sid);
|
|
shift = ATUNE_FORMAT_L;
|
|
mask = ATUNE_FORMAT_MASK;
|
|
ret = snd_soc_component_update_bits(cmpnt,
|
|
ATUNE_SPUM_USGAIN_CTRL(aid),
|
|
mask, val << shift);
|
|
abox_dbg(data->dev, "%s(%d, %d): input format=%#x\n", __func__,
|
|
aid, sid, val);
|
|
}
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static int spum_pregain0_event(struct snd_soc_dapm_widget *w,
|
|
struct snd_kcontrol *k, int e)
|
|
{
|
|
/* later use */
|
|
return 0;
|
|
}
|
|
|
|
static int spum_pregain1_event(struct snd_soc_dapm_widget *w,
|
|
struct snd_kcontrol *k, int e)
|
|
{
|
|
/* later use */
|
|
return 0;
|
|
}
|
|
|
|
static int spum_bqf_event(struct abox_data *data, int e, int aid, int sid)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
unsigned int shift, mask, val;
|
|
int ret = 0;
|
|
|
|
if (aid < 0 || sid < 0)
|
|
return 0;
|
|
|
|
abox_dbg(data->dev, "%s(%d, %d, %d)\n", __func__, e, aid, sid);
|
|
|
|
if (SND_SOC_DAPM_EVENT_ON(e)) {
|
|
/* sync function chain */
|
|
val = spum_bqf_enabled(data, aid);
|
|
shift = ABOX_FUNC_CHAIN_NSRC_BQF_L(sid);
|
|
mask = ABOX_FUNC_CHAIN_NSRC_BQF_MASK(sid);
|
|
ret = snd_soc_component_update_bits(cmpnt,
|
|
ABOX_SPUM_CTRL_FC_NSRC(sid),
|
|
mask, val << shift);
|
|
if (ret < 0) {
|
|
abox_err(data->dev, "%s: function chain set fail: %d\n",
|
|
__func__, ret);
|
|
goto out;
|
|
}
|
|
|
|
abox_dbg(data->dev, "%s(%d, %d, %d): %s\n", __func__,
|
|
e, aid, sid, val ? "connected" : "disconnected");
|
|
|
|
/* atune can process 32bit only */
|
|
if (val)
|
|
abox_dma_set_dst_bit_width(data->dev_wdma[sid], 32);
|
|
}
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static int spum_bqf0_event(struct snd_soc_dapm_widget *w,
|
|
struct snd_kcontrol *k, int e)
|
|
{
|
|
/* later use */
|
|
return 0;
|
|
}
|
|
|
|
static int spum_bqf1_event(struct snd_soc_dapm_widget *w,
|
|
struct snd_kcontrol *k, int e)
|
|
{
|
|
/* later use */
|
|
return 0;
|
|
}
|
|
|
|
static int spum_drc_event(struct abox_data *data, int e, int aid, int sid)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
unsigned int shift, mask, val;
|
|
int ret = 0;
|
|
|
|
if (aid < 0 || sid < 0)
|
|
return 0;
|
|
|
|
abox_dbg(data->dev, "%s(%d, %d, %d)\n", __func__, e, aid, sid);
|
|
|
|
if (SND_SOC_DAPM_EVENT_ON(e)) {
|
|
/* sync function chain */
|
|
val = spum_drc_enabled(data, aid);
|
|
shift = ABOX_FUNC_CHAIN_NSRC_DRC_L(sid);
|
|
mask = ABOX_FUNC_CHAIN_NSRC_DRC_MASK(sid);
|
|
ret = snd_soc_component_update_bits(cmpnt,
|
|
ABOX_SPUM_CTRL_FC_NSRC(sid),
|
|
mask, val << shift);
|
|
if (ret < 0) {
|
|
abox_err(data->dev, "%s: function chain set fail: %d\n",
|
|
__func__, ret);
|
|
goto out;
|
|
}
|
|
|
|
abox_dbg(data->dev, "%s(%d, %d, %d): %s\n", __func__,
|
|
e, aid, sid, val ? "connected" : "disconnected");
|
|
|
|
if (!spum_pretune_enabled(data, sid)) {
|
|
/* if posttune only is enabled,
|
|
* enable ASRC for bit conversion
|
|
*/
|
|
abox_cmpnt_asrc_enable(data, SNDRV_PCM_STREAM_CAPTURE,
|
|
sid);
|
|
}
|
|
}
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static int spum_drc0_event(struct snd_soc_dapm_widget *w,
|
|
struct snd_kcontrol *k, int e)
|
|
{
|
|
/* later use */
|
|
return 0;
|
|
}
|
|
|
|
static int spum_drc1_event(struct snd_soc_dapm_widget *w,
|
|
struct snd_kcontrol *k, int e)
|
|
{
|
|
/* later use */
|
|
return 0;
|
|
}
|
|
|
|
static int spum_postgain_event(struct abox_data *data, int e, int aid, int sid)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
struct device *dev_dma;
|
|
unsigned int shift, mask, val, width, channels, rate;
|
|
int ret = 0;
|
|
struct snd_pcm_hw_params params;
|
|
|
|
if (aid < 0 || sid < 0)
|
|
return 0;
|
|
|
|
abox_dbg(data->dev, "%s(%d, %d, %d)\n", __func__, e, aid, sid);
|
|
|
|
if (SND_SOC_DAPM_EVENT_ON(e)) {
|
|
/* sync function chain */
|
|
val = spum_postgain_enabled(data, aid);
|
|
shift = ABOX_FUNC_CHAIN_NSRC_DSG_L(sid);
|
|
mask = ABOX_FUNC_CHAIN_NSRC_DSG_MASK(sid);
|
|
ret = snd_soc_component_update_bits(cmpnt,
|
|
ABOX_SPUM_CTRL_FC_NSRC(sid),
|
|
mask, val << shift);
|
|
if (ret < 0) {
|
|
abox_err(data->dev, "%s: function chain set fail: %d\n",
|
|
__func__, ret);
|
|
goto out;
|
|
}
|
|
|
|
abox_dbg(data->dev, "%s(%d, %d, %d): %s\n", __func__,
|
|
e, aid, sid, val ? "connected" : "disconnected");
|
|
|
|
if (!spum_pretune_enabled(data, sid)) {
|
|
/* if posttune only is enabled,
|
|
* enable ASRC for bit conversion
|
|
*/
|
|
abox_cmpnt_asrc_enable(data, SNDRV_PCM_STREAM_CAPTURE,
|
|
sid);
|
|
}
|
|
|
|
/* get format */
|
|
dev_dma = data->dev_wdma[sid];
|
|
ret = abox_dma_hw_params_fixup(dev_dma, ¶ms);
|
|
if (ret < 0) {
|
|
abox_err(dev_dma, "%s: hw params get failed: %d\n",
|
|
__func__, ret);
|
|
goto out;
|
|
}
|
|
rate = params_rate(¶ms);
|
|
channels = params_channels(¶ms);
|
|
width = abox_dma_get_dst_bit_width(dev_dma);
|
|
|
|
/* sync rate */
|
|
val = ilog2((rate / 48000));
|
|
shift = ATUNE_SAMPLE_RATE_L;
|
|
mask = ATUNE_SAMPLE_RATE_MASK;
|
|
ret = snd_soc_component_update_bits(cmpnt,
|
|
ATUNE_SPUM_DSGAIN_CTRL(aid),
|
|
mask, val << shift);
|
|
abox_dbg(data->dev, "%s(%d, %d): rate=%#x\n", __func__,
|
|
aid, sid, val);
|
|
|
|
/* sync input format */
|
|
val = abox_get_format(32, channels); /* 32bit fixed */
|
|
shift = ATUNE_FORMAT_L;
|
|
mask = ATUNE_FORMAT_MASK;
|
|
ret = snd_soc_component_update_bits(cmpnt,
|
|
ATUNE_SPUM_DSGAIN_CTRL(aid),
|
|
mask, val << shift);
|
|
abox_dbg(data->dev, "%s(%d, %d): input format=%#x\n", __func__,
|
|
aid, sid, val);
|
|
|
|
/* sync output format */
|
|
val = (width / 8) - 1;
|
|
shift = ATUNE_DITHER_OUTPUT_BIT_L;
|
|
mask = ATUNE_DITHER_OUTPUT_BIT_MASK;
|
|
ret = snd_soc_component_update_bits(cmpnt,
|
|
ATUNE_SPUM_DSGAIN_BIT_CTRL(aid),
|
|
mask, val << shift);
|
|
abox_dbg(data->dev, "%s(%d, %d): output format=%#x\n", __func__,
|
|
aid, sid, val);
|
|
}
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static int spum_postgain0_event(struct snd_soc_dapm_widget *w,
|
|
struct snd_kcontrol *k, int e)
|
|
{
|
|
/* later use */
|
|
return 0;
|
|
}
|
|
|
|
static int spum_postgain1_event(struct snd_soc_dapm_widget *w,
|
|
struct snd_kcontrol *k, int e)
|
|
{
|
|
/* later use */
|
|
return 0;
|
|
}
|
|
|
|
/* later use */
|
|
#define ATUNE_EVENT_FLAGS 0
|
|
|
|
static const struct snd_soc_dapm_widget atune_widgets[] = {
|
|
SND_SOC_DAPM_MUX("SPUS PRETUNE0 IN", SND_SOC_NOPM, 0, 0,
|
|
spus_pre_tune0_controls),
|
|
SND_SOC_DAPM_DEMUX("SPUS PRETUNE0 OUT", SND_SOC_NOPM, 0, 0,
|
|
spus_pre_tune0_controls),
|
|
SND_SOC_DAPM_MUX("SPUS POSTTUNE0 IN", SND_SOC_NOPM, 0, 0,
|
|
spus_post_tune0_controls),
|
|
SND_SOC_DAPM_DEMUX("SPUS POSTTUNE0 OUT", SND_SOC_NOPM, 0, 0,
|
|
spus_post_tune0_controls),
|
|
SND_SOC_DAPM_PGA_E("SPUS PREGAIN0", SND_SOC_NOPM, 0, 0, NULL, 0,
|
|
spus_pregain0_event, ATUNE_EVENT_FLAGS),
|
|
SND_SOC_DAPM_PGA_E("SPUS BQF0", SND_SOC_NOPM, 0, 0, NULL, 0,
|
|
spus_bqf0_event, ATUNE_EVENT_FLAGS),
|
|
SND_SOC_DAPM_PGA_E("SPUS DRC0", SND_SOC_NOPM, 0, 0, NULL, 0,
|
|
spus_drc0_event, ATUNE_EVENT_FLAGS),
|
|
SND_SOC_DAPM_PGA_E("SPUS POSTGAIN0", SND_SOC_NOPM, 0, 0, NULL, 0,
|
|
spus_postgain0_event, ATUNE_EVENT_FLAGS),
|
|
|
|
SND_SOC_DAPM_MUX("SPUM PRETUNE0 IN", SND_SOC_NOPM, 0, 0,
|
|
spum_pre_tune0_controls),
|
|
SND_SOC_DAPM_DEMUX("SPUM PRETUNE0 OUT", SND_SOC_NOPM, 0, 0,
|
|
spum_pre_tune0_controls),
|
|
SND_SOC_DAPM_MUX("SPUM POSTTUNE0 IN", SND_SOC_NOPM, 0, 0,
|
|
spum_post_tune0_controls),
|
|
SND_SOC_DAPM_DEMUX("SPUM POSTTUNE0 OUT", SND_SOC_NOPM, 0, 0,
|
|
spum_post_tune0_controls),
|
|
SND_SOC_DAPM_PGA_E("SPUM PREGAIN0", SND_SOC_NOPM, 0, 0, NULL, 0,
|
|
spum_pregain0_event, ATUNE_EVENT_FLAGS),
|
|
SND_SOC_DAPM_PGA_E("SPUM BQF0", SND_SOC_NOPM, 0, 0, NULL, 0,
|
|
spum_bqf0_event, ATUNE_EVENT_FLAGS),
|
|
SND_SOC_DAPM_PGA_E("SPUM DRC0", SND_SOC_NOPM, 0, 0, NULL, 0,
|
|
spum_drc0_event, ATUNE_EVENT_FLAGS),
|
|
SND_SOC_DAPM_PGA_E("SPUM POSTGAIN0", SND_SOC_NOPM, 0, 0, NULL, 0,
|
|
spum_postgain0_event, ATUNE_EVENT_FLAGS),
|
|
};
|
|
|
|
static const struct snd_soc_dapm_widget atune1_widgets[] = {
|
|
SND_SOC_DAPM_MUX("SPUS PRETUNE1 IN", SND_SOC_NOPM, 0, 0,
|
|
spus_pre_tune1_controls),
|
|
SND_SOC_DAPM_DEMUX("SPUS PRETUNE1 OUT", SND_SOC_NOPM, 0, 0,
|
|
spus_pre_tune1_controls),
|
|
SND_SOC_DAPM_MUX("SPUS POSTTUNE1 IN", SND_SOC_NOPM, 0, 0,
|
|
spus_post_tune1_controls),
|
|
SND_SOC_DAPM_DEMUX("SPUS POSTTUNE1 OUT", SND_SOC_NOPM, 0, 0,
|
|
spus_post_tune1_controls),
|
|
SND_SOC_DAPM_PGA_E("SPUS PREGAIN1", SND_SOC_NOPM, 0, 0, NULL, 0,
|
|
spus_pregain1_event, ATUNE_EVENT_FLAGS),
|
|
SND_SOC_DAPM_PGA_E("SPUS BQF1", SND_SOC_NOPM, 0, 0, NULL, 0,
|
|
spus_bqf1_event, ATUNE_EVENT_FLAGS),
|
|
SND_SOC_DAPM_PGA_E("SPUS DRC1", SND_SOC_NOPM, 0, 0, NULL, 0,
|
|
spus_drc1_event, ATUNE_EVENT_FLAGS),
|
|
SND_SOC_DAPM_PGA_E("SPUS POSTGAIN1", SND_SOC_NOPM, 0, 0, NULL, 0,
|
|
spus_postgain1_event, ATUNE_EVENT_FLAGS),
|
|
|
|
SND_SOC_DAPM_MUX("SPUM PRETUNE1 IN", SND_SOC_NOPM, 0, 0,
|
|
spum_pre_tune1_controls),
|
|
SND_SOC_DAPM_DEMUX("SPUM PRETUNE1 OUT", SND_SOC_NOPM, 0, 0,
|
|
spum_pre_tune1_controls),
|
|
SND_SOC_DAPM_MUX("SPUM POSTTUNE1 IN", SND_SOC_NOPM, 0, 0,
|
|
spum_post_tune1_controls),
|
|
SND_SOC_DAPM_DEMUX("SPUM POSTTUNE1 OUT", SND_SOC_NOPM, 0, 0,
|
|
spum_post_tune1_controls),
|
|
SND_SOC_DAPM_PGA_E("SPUM PREGAIN1", SND_SOC_NOPM, 0, 0, NULL, 0,
|
|
spum_pregain1_event, ATUNE_EVENT_FLAGS),
|
|
SND_SOC_DAPM_PGA_E("SPUM BQF1", SND_SOC_NOPM, 0, 0, NULL, 0,
|
|
spum_bqf1_event, ATUNE_EVENT_FLAGS),
|
|
SND_SOC_DAPM_PGA_E("SPUM DRC1", SND_SOC_NOPM, 0, 0, NULL, 0,
|
|
spum_drc1_event, ATUNE_EVENT_FLAGS),
|
|
SND_SOC_DAPM_PGA_E("SPUM POSTGAIN1", SND_SOC_NOPM, 0, 0, NULL, 0,
|
|
spum_postgain1_event, ATUNE_EVENT_FLAGS),
|
|
};
|
|
|
|
static const struct snd_soc_dapm_route atune_routes[] = {
|
|
/* sink, control, source */
|
|
{"SPUS PRETUNE0 IN", "SPUS0", "SPUS IN0"},
|
|
{"SPUS PRETUNE0 IN", "SPUS1", "SPUS IN1"},
|
|
{"SPUS PRETUNE0 IN", "SPUS2", "SPUS IN2"},
|
|
{"SPUS PRETUNE0 IN", "SPUS3", "SPUS IN3"},
|
|
{"SPUS PRETUNE0 IN", "SPUS4", "SPUS IN4"},
|
|
{"SPUS PRETUNE0 IN", "SPUS5", "SPUS IN5"},
|
|
{"SPUS PRETUNE0 IN", "SPUS6", "SPUS IN6"},
|
|
{"SPUS PRETUNE0 IN", "SPUS7", "SPUS IN7"},
|
|
{"SPUS PRETUNE0 IN", "SPUS8", "SPUS IN8"},
|
|
{"SPUS PRETUNE0 IN", "SPUS9", "SPUS IN9"},
|
|
{"SPUS PRETUNE0 IN", "SPUS10", "SPUS IN10"},
|
|
{"SPUS PRETUNE0 IN", "SPUS11", "SPUS IN11"},
|
|
{"SPUS PREGAIN0", NULL, "SPUS PRETUNE0 IN"},
|
|
{"SPUS PRETUNE0 OUT", NULL, "SPUS PREGAIN0"},
|
|
{"SPUS PGA0", "SPUS0", "SPUS PRETUNE0 OUT"},
|
|
{"SPUS PGA1", "SPUS1", "SPUS PRETUNE0 OUT"},
|
|
{"SPUS PGA2", "SPUS2", "SPUS PRETUNE0 OUT"},
|
|
{"SPUS PGA3", "SPUS3", "SPUS PRETUNE0 OUT"},
|
|
{"SPUS PGA4", "SPUS4", "SPUS PRETUNE0 OUT"},
|
|
{"SPUS PGA5", "SPUS5", "SPUS PRETUNE0 OUT"},
|
|
{"SPUS PGA6", "SPUS6", "SPUS PRETUNE0 OUT"},
|
|
{"SPUS PGA7", "SPUS7", "SPUS PRETUNE0 OUT"},
|
|
{"SPUS PGA8", "SPUS8", "SPUS PRETUNE0 OUT"},
|
|
{"SPUS PGA9", "SPUS9", "SPUS PRETUNE0 OUT"},
|
|
{"SPUS PGA10", "SPUS10", "SPUS PRETUNE0 OUT"},
|
|
{"SPUS PGA11", "SPUS11", "SPUS PRETUNE0 OUT"},
|
|
|
|
{"SPUS POSTTUNE0 IN", "SIFS0", "SIFS0"},
|
|
{"SPUS POSTTUNE0 IN", "SIFS1", "SIFS1"},
|
|
{"SPUS POSTTUNE0 IN", "SIFS2", "SIFS2"},
|
|
{"SPUS POSTTUNE0 IN", "SIFS3", "SIFS3"},
|
|
{"SPUS POSTTUNE0 IN", "SIFS4", "SIFS4"},
|
|
{"SPUS POSTTUNE0 IN", "SIFS5", "SIFS5"},
|
|
{"SPUS POSTTUNE0 IN", "SIFS6", "SIFS6"},
|
|
{"SPUS BQF0", NULL, "SPUS POSTTUNE0 IN"},
|
|
{"SPUS DRC0", NULL, "SPUS BQF0"},
|
|
{"SPUS POSTGAIN0", NULL, "SPUS DRC0"},
|
|
{"SPUS POSTTUNE0 OUT", NULL, "SPUS POSTGAIN0"},
|
|
{"SIFS0 PGA", "SIFS0", "SPUS POSTTUNE0 OUT"},
|
|
{"SIFS1 PGA", "SIFS1", "SPUS POSTTUNE0 OUT"},
|
|
{"SIFS2 PGA", "SIFS2", "SPUS POSTTUNE0 OUT"},
|
|
{"SIFS3 PGA", "SIFS3", "SPUS POSTTUNE0 OUT"},
|
|
{"SIFS4 PGA", "SIFS4", "SPUS POSTTUNE0 OUT"},
|
|
{"SIFS5 PGA", "SIFS5", "SPUS POSTTUNE0 OUT"},
|
|
{"SIFS6 PGA", "SIFS6", "SPUS POSTTUNE0 OUT"},
|
|
|
|
{"SPUM PRETUNE0 IN", "SIFM0", "NSRC0 In"},
|
|
{"SPUM PRETUNE0 IN", "SIFM1", "NSRC1 In"},
|
|
{"SPUM PRETUNE0 IN", "SIFM2", "NSRC2 In"},
|
|
{"SPUM PRETUNE0 IN", "SIFM3", "NSRC3 In"},
|
|
{"SPUM PRETUNE0 IN", "SIFM4", "NSRC4 In"},
|
|
{"SPUM PRETUNE0 IN", "SIFM5", "NSRC5 In"},
|
|
{"SPUM PRETUNE0 IN", "SIFM6", "NSRC6 In"},
|
|
{"SPUM PRETUNE0 IN", "SIFM7", "NSRC7 In"},
|
|
{"SPUM PRETUNE0 IN", "SIFM8", "NSRC8 In"},
|
|
{"SPUM PRETUNE0 IN", "SIFM9", "NSRC9 In"},
|
|
{"SPUM PRETUNE0 IN", "SIFM10", "NSRC10 In"},
|
|
{"SPUM PRETUNE0 IN", "SIFM11", "NSRC11 In"},
|
|
{"SPUM PREGAIN0", NULL, "SPUM PRETUNE0 IN"},
|
|
{"SPUM BQF0", NULL, "SPUM PREGAIN0"},
|
|
{"SPUM PRETUNE0 OUT", NULL, "SPUM BQF0"},
|
|
{"NSRC0 PGA", "SIFM0", "SPUM PRETUNE0 OUT"},
|
|
{"NSRC1 PGA", "SIFM1", "SPUM PRETUNE0 OUT"},
|
|
{"NSRC2 PGA", "SIFM2", "SPUM PRETUNE0 OUT"},
|
|
{"NSRC3 PGA", "SIFM3", "SPUM PRETUNE0 OUT"},
|
|
{"NSRC4 PGA", "SIFM4", "SPUM PRETUNE0 OUT"},
|
|
{"NSRC5 PGA", "SIFM5", "SPUM PRETUNE0 OUT"},
|
|
{"NSRC6 PGA", "SIFM6", "SPUM PRETUNE0 OUT"},
|
|
{"NSRC7 PGA", "SIFM7", "SPUM PRETUNE0 OUT"},
|
|
{"NSRC8 PGA", "SIFM8", "SPUM PRETUNE0 OUT"},
|
|
{"NSRC9 PGA", "SIFM9", "SPUM PRETUNE0 OUT"},
|
|
{"NSRC10 PGA", "SIFM10", "SPUM PRETUNE0 OUT"},
|
|
{"NSRC11 PGA", "SIFM11", "SPUM PRETUNE0 OUT"},
|
|
|
|
{"SPUM POSTTUNE0 IN", "SIFM0", "SPUM ASRC0"},
|
|
{"SPUM POSTTUNE0 IN", "SIFM1", "SPUM ASRC1"},
|
|
{"SPUM POSTTUNE0 IN", "SIFM2", "SPUM ASRC2"},
|
|
{"SPUM POSTTUNE0 IN", "SIFM3", "SPUM ASRC3"},
|
|
{"SPUM POSTTUNE0 IN", "SIFM4", "SPUM ASRC4"},
|
|
{"SPUM POSTTUNE0 IN", "SIFM5", "SPUM ASRC5"},
|
|
{"SPUM POSTTUNE0 IN", "SIFM6", "SPUM ASRC6"},
|
|
{"SPUM POSTTUNE0 IN", "SIFM7", "SPUM ASRC7"},
|
|
{"SPUM POSTTUNE0 IN", "SIFM8", "SPUM ASRC8"},
|
|
{"SPUM POSTTUNE0 IN", "SIFM9", "SPUM ASRC9"},
|
|
{"SPUM POSTTUNE0 IN", "SIFM10", "SPUM ASRC10"},
|
|
{"SPUM POSTTUNE0 IN", "SIFM11", "SPUM ASRC11"},
|
|
{"SPUM DRC0", NULL, "SPUM POSTTUNE0 IN"},
|
|
{"SPUM POSTGAIN0", NULL, "SPUM DRC0"},
|
|
{"SPUM POSTTUNE0 OUT", NULL, "SPUM POSTGAIN0"},
|
|
{"SPUM PGA0", "SIFM0", "SPUM POSTTUNE0 OUT"},
|
|
{"SPUM PGA1", "SIFM1", "SPUM POSTTUNE0 OUT"},
|
|
{"SPUM PGA2", "SIFM2", "SPUM POSTTUNE0 OUT"},
|
|
{"SPUM PGA3", "SIFM3", "SPUM POSTTUNE0 OUT"},
|
|
{"SPUM PGA4", "SIFM4", "SPUM POSTTUNE0 OUT"},
|
|
{"SPUM PGA5", "SIFM5", "SPUM POSTTUNE0 OUT"},
|
|
{"SPUM PGA6", "SIFM6", "SPUM POSTTUNE0 OUT"},
|
|
{"SPUM PGA7", "SIFM7", "SPUM POSTTUNE0 OUT"},
|
|
{"SPUM PGA8", "SIFM8", "SPUM POSTTUNE0 OUT"},
|
|
{"SPUM PGA9", "SIFM9", "SPUM POSTTUNE0 OUT"},
|
|
{"SPUM PGA10", "SIFM10", "SPUM POSTTUNE0 OUT"},
|
|
{"SPUM PGA11", "SIFM11", "SPUM POSTTUNE0 OUT"},
|
|
};
|
|
|
|
static const struct snd_soc_dapm_route atune1_routes[] = {
|
|
/* sink, control, source */
|
|
{"SPUS PRETUNE1 IN", "SPUS0", "SPUS IN0"},
|
|
{"SPUS PRETUNE1 IN", "SPUS1", "SPUS IN1"},
|
|
{"SPUS PRETUNE1 IN", "SPUS2", "SPUS IN2"},
|
|
{"SPUS PRETUNE1 IN", "SPUS3", "SPUS IN3"},
|
|
{"SPUS PRETUNE1 IN", "SPUS4", "SPUS IN4"},
|
|
{"SPUS PRETUNE1 IN", "SPUS5", "SPUS IN5"},
|
|
{"SPUS PRETUNE1 IN", "SPUS6", "SPUS IN6"},
|
|
{"SPUS PRETUNE1 IN", "SPUS7", "SPUS IN7"},
|
|
{"SPUS PRETUNE1 IN", "SPUS8", "SPUS IN8"},
|
|
{"SPUS PRETUNE1 IN", "SPUS9", "SPUS IN9"},
|
|
{"SPUS PRETUNE1 IN", "SPUS10", "SPUS IN10"},
|
|
{"SPUS PRETUNE1 IN", "SPUS11", "SPUS IN11"},
|
|
{"SPUS PREGAIN1", NULL, "SPUS PRETUNE1 IN"},
|
|
{"SPUS PRETUNE1 OUT", NULL, "SPUS PREGAIN1"},
|
|
{"SPUS PGA0", "SPUS0", "SPUS PRETUNE1 OUT"},
|
|
{"SPUS PGA1", "SPUS1", "SPUS PRETUNE1 OUT"},
|
|
{"SPUS PGA2", "SPUS2", "SPUS PRETUNE1 OUT"},
|
|
{"SPUS PGA3", "SPUS3", "SPUS PRETUNE1 OUT"},
|
|
{"SPUS PGA4", "SPUS4", "SPUS PRETUNE1 OUT"},
|
|
{"SPUS PGA5", "SPUS5", "SPUS PRETUNE1 OUT"},
|
|
{"SPUS PGA6", "SPUS6", "SPUS PRETUNE1 OUT"},
|
|
{"SPUS PGA7", "SPUS7", "SPUS PRETUNE1 OUT"},
|
|
{"SPUS PGA8", "SPUS8", "SPUS PRETUNE1 OUT"},
|
|
{"SPUS PGA9", "SPUS9", "SPUS PRETUNE1 OUT"},
|
|
{"SPUS PGA10", "SPUS10", "SPUS PRETUNE1 OUT"},
|
|
{"SPUS PGA11", "SPUS11", "SPUS PRETUNE1 OUT"},
|
|
|
|
{"SPUS POSTTUNE1 IN", "SIFS0", "SIFS0"},
|
|
{"SPUS POSTTUNE1 IN", "SIFS1", "SIFS1"},
|
|
{"SPUS POSTTUNE1 IN", "SIFS2", "SIFS2"},
|
|
{"SPUS POSTTUNE1 IN", "SIFS3", "SIFS3"},
|
|
{"SPUS POSTTUNE1 IN", "SIFS4", "SIFS4"},
|
|
{"SPUS POSTTUNE1 IN", "SIFS5", "SIFS5"},
|
|
{"SPUS POSTTUNE1 IN", "SIFS6", "SIFS6"},
|
|
{"SPUS BQF1", NULL, "SPUS POSTTUNE1 IN"},
|
|
{"SPUS DRC1", NULL, "SPUS BQF1"},
|
|
{"SPUS POSTGAIN1", NULL, "SPUS DRC1"},
|
|
{"SPUS POSTTUNE1 OUT", NULL, "SPUS POSTGAIN1"},
|
|
{"SIFS0 PGA", "SIFS0", "SPUS POSTTUNE1 OUT"},
|
|
{"SIFS1 PGA", "SIFS1", "SPUS POSTTUNE1 OUT"},
|
|
{"SIFS2 PGA", "SIFS2", "SPUS POSTTUNE1 OUT"},
|
|
{"SIFS3 PGA", "SIFS3", "SPUS POSTTUNE1 OUT"},
|
|
{"SIFS4 PGA", "SIFS4", "SPUS POSTTUNE1 OUT"},
|
|
{"SIFS5 PGA", "SIFS5", "SPUS POSTTUNE1 OUT"},
|
|
{"SIFS6 PGA", "SIFS6", "SPUS POSTTUNE1 OUT"},
|
|
|
|
{"SPUM PRETUNE1 IN", "SIFM0", "NSRC0 In"},
|
|
{"SPUM PRETUNE1 IN", "SIFM1", "NSRC1 In"},
|
|
{"SPUM PRETUNE1 IN", "SIFM2", "NSRC2 In"},
|
|
{"SPUM PRETUNE1 IN", "SIFM3", "NSRC3 In"},
|
|
{"SPUM PRETUNE1 IN", "SIFM4", "NSRC4 In"},
|
|
{"SPUM PRETUNE1 IN", "SIFM5", "NSRC5 In"},
|
|
{"SPUM PRETUNE1 IN", "SIFM6", "NSRC6 In"},
|
|
{"SPUM PRETUNE1 IN", "SIFM7", "NSRC7 In"},
|
|
{"SPUM PRETUNE1 IN", "SIFM8", "NSRC8 In"},
|
|
{"SPUM PRETUNE1 IN", "SIFM9", "NSRC9 In"},
|
|
{"SPUM PRETUNE1 IN", "SIFM10", "NSRC10 In"},
|
|
{"SPUM PRETUNE1 IN", "SIFM11", "NSRC11 In"},
|
|
{"SPUM PREGAIN1", NULL, "SPUM PRETUNE1 IN"},
|
|
{"SPUM BQF1", NULL, "SPUM PREGAIN1"},
|
|
{"SPUM PRETUNE1 OUT", NULL, "SPUM BQF1"},
|
|
{"NSRC0 PGA", "SIFM0", "SPUM PRETUNE1 OUT"},
|
|
{"NSRC1 PGA", "SIFM1", "SPUM PRETUNE1 OUT"},
|
|
{"NSRC2 PGA", "SIFM2", "SPUM PRETUNE1 OUT"},
|
|
{"NSRC3 PGA", "SIFM3", "SPUM PRETUNE1 OUT"},
|
|
{"NSRC4 PGA", "SIFM4", "SPUM PRETUNE1 OUT"},
|
|
{"NSRC5 PGA", "SIFM5", "SPUM PRETUNE1 OUT"},
|
|
{"NSRC6 PGA", "SIFM6", "SPUM PRETUNE1 OUT"},
|
|
{"NSRC7 PGA", "SIFM7", "SPUM PRETUNE1 OUT"},
|
|
{"NSRC8 PGA", "SIFM8", "SPUM PRETUNE1 OUT"},
|
|
{"NSRC9 PGA", "SIFM9", "SPUM PRETUNE1 OUT"},
|
|
{"NSRC10 PGA", "SIFM10", "SPUM PRETUNE1 OUT"},
|
|
{"NSRC11 PGA", "SIFM11", "SPUM PRETUNE1 OUT"},
|
|
|
|
{"SPUM POSTTUNE1 IN", "SIFM0", "SPUM ASRC0"},
|
|
{"SPUM POSTTUNE1 IN", "SIFM1", "SPUM ASRC1"},
|
|
{"SPUM POSTTUNE1 IN", "SIFM2", "SPUM ASRC2"},
|
|
{"SPUM POSTTUNE1 IN", "SIFM3", "SPUM ASRC3"},
|
|
{"SPUM POSTTUNE1 IN", "SIFM4", "SPUM ASRC4"},
|
|
{"SPUM POSTTUNE1 IN", "SIFM5", "SPUM ASRC5"},
|
|
{"SPUM POSTTUNE1 IN", "SIFM6", "SPUM ASRC6"},
|
|
{"SPUM POSTTUNE1 IN", "SIFM7", "SPUM ASRC7"},
|
|
{"SPUM POSTTUNE1 IN", "SIFM8", "SPUM ASRC8"},
|
|
{"SPUM POSTTUNE1 IN", "SIFM9", "SPUM ASRC9"},
|
|
{"SPUM POSTTUNE1 IN", "SIFM10", "SPUM ASRC10"},
|
|
{"SPUM POSTTUNE1 IN", "SIFM11", "SPUM ASRC11"},
|
|
{"SPUM DRC1", NULL, "SPUM POSTTUNE1 IN"},
|
|
{"SPUM POSTGAIN1", NULL, "SPUM DRC1"},
|
|
{"SPUM POSTTUNE1 OUT", NULL, "SPUM POSTGAIN1"},
|
|
{"SPUM PGA0", "SIFM0", "SPUM POSTTUNE1 OUT"},
|
|
{"SPUM PGA1", "SIFM1", "SPUM POSTTUNE1 OUT"},
|
|
{"SPUM PGA2", "SIFM2", "SPUM POSTTUNE1 OUT"},
|
|
{"SPUM PGA3", "SIFM3", "SPUM POSTTUNE1 OUT"},
|
|
{"SPUM PGA4", "SIFM4", "SPUM POSTTUNE1 OUT"},
|
|
{"SPUM PGA5", "SIFM5", "SPUM POSTTUNE1 OUT"},
|
|
{"SPUM PGA6", "SIFM6", "SPUM POSTTUNE1 OUT"},
|
|
{"SPUM PGA7", "SIFM7", "SPUM POSTTUNE1 OUT"},
|
|
{"SPUM PGA8", "SIFM8", "SPUM POSTTUNE1 OUT"},
|
|
{"SPUM PGA9", "SIFM9", "SPUM POSTTUNE1 OUT"},
|
|
{"SPUM PGA10", "SIFM10", "SPUM POSTTUNE1 OUT"},
|
|
{"SPUM PGA11", "SIFM11", "SPUM POSTTUNE1 OUT"},
|
|
};
|
|
|
|
int abox_atune_probe(struct abox_data *data, int count)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(cmpnt);
|
|
int ret;
|
|
|
|
if (!cmpnt)
|
|
return -EAGAIN;
|
|
|
|
if (count < 1)
|
|
goto out;
|
|
|
|
ret = snd_soc_add_component_controls(cmpnt, atune_controls,
|
|
ARRAY_SIZE(atune_controls));
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
ret = snd_soc_dapm_new_controls(dapm, atune_widgets,
|
|
ARRAY_SIZE(atune_widgets));
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
ret = snd_soc_dapm_add_routes(dapm, atune_routes,
|
|
ARRAY_SIZE(atune_routes));
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
if (count < 2)
|
|
goto out;
|
|
|
|
ret = snd_soc_add_component_controls(cmpnt, atune1_controls,
|
|
ARRAY_SIZE(atune1_controls));
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
ret = snd_soc_dapm_new_controls(dapm, atune1_widgets,
|
|
ARRAY_SIZE(atune1_widgets));
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
ret = snd_soc_dapm_add_routes(dapm, atune1_routes,
|
|
ARRAY_SIZE(atune1_routes));
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
out:
|
|
abox_info(cmpnt->dev, "atune probed\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
int abox_atune_remove(struct abox_data *data)
|
|
{
|
|
/* widgets and controls would be removed with component */
|
|
return 0;
|
|
}
|
|
|
|
bool abox_atune_spus_posttune_connected(struct abox_data *data, int id)
|
|
{
|
|
return spus_posttune_enabled(data, id);
|
|
}
|
|
|
|
bool abox_atune_spum_pretune_connected(struct abox_data *data, int id)
|
|
{
|
|
return spum_pretune_enabled(data, id);
|
|
}
|
|
|
|
int abox_atune_dapm_event(struct abox_data *data, int e, int stream, int sid)
|
|
{
|
|
struct snd_soc_component *cmpnt = data->cmpnt;
|
|
unsigned int mask;
|
|
int aid, ret = 0;
|
|
|
|
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
|
/* clear atune connection to function chain */
|
|
mask = ABOX_FUNC_CHAIN_SRC_USG_MASK(sid) |
|
|
ABOX_FUNC_CHAIN_SRC_BQF_MASK(sid) |
|
|
ABOX_FUNC_CHAIN_SRC_DRC_MASK(sid) |
|
|
ABOX_FUNC_CHAIN_SRC_DSG_MASK(sid);
|
|
snd_soc_component_update_bits(cmpnt,
|
|
ABOX_SPUS_CTRL_FC_SRC(sid), mask, 0x0);
|
|
|
|
aid = posttune_id_from_spus(data, sid);
|
|
if (aid >= 0) {
|
|
ret = spus_bqf_event(data, e, aid, sid);
|
|
if (ret < 0)
|
|
goto err;
|
|
ret = spus_drc_event(data, e, aid, sid);
|
|
if (ret < 0)
|
|
goto err;
|
|
ret = spus_postgain_event(data, e, aid, sid);
|
|
if (ret < 0)
|
|
goto err;
|
|
}
|
|
|
|
aid = pretune_id_from_spus(data, sid);
|
|
if (aid >= 0) {
|
|
ret = spus_pregain_event(data, e, aid, sid);
|
|
if (ret < 0)
|
|
goto err;
|
|
}
|
|
} else {
|
|
/* clear atune connection to function chain */
|
|
mask = ABOX_FUNC_CHAIN_NSRC_USG_MASK(sid) |
|
|
ABOX_FUNC_CHAIN_NSRC_BQF_MASK(sid) |
|
|
ABOX_FUNC_CHAIN_NSRC_DRC_MASK(sid) |
|
|
ABOX_FUNC_CHAIN_NSRC_DSG_MASK(sid);
|
|
snd_soc_component_update_bits(cmpnt,
|
|
ABOX_SPUM_CTRL_FC_NSRC(sid), mask, 0x0);
|
|
|
|
aid = pretune_id_from_nsrc(data, sid);
|
|
if (aid >= 0) {
|
|
ret = spum_pregain_event(data, e, aid, sid);
|
|
if (ret < 0)
|
|
goto err;
|
|
ret = spum_bqf_event(data, e, aid, sid);
|
|
if (ret < 0)
|
|
goto err;
|
|
}
|
|
|
|
aid = posttune_id_from_nsrc(data, sid);
|
|
if (aid >= 0) {
|
|
ret = spum_drc_event(data, e, aid, sid);
|
|
if (ret < 0)
|
|
goto err;
|
|
ret = spum_postgain_event(data, e, aid, sid);
|
|
if (ret < 0)
|
|
goto err;
|
|
}
|
|
}
|
|
err:
|
|
return ret;
|
|
}
|