asoc: codecs: Add parent child relation for bolero and tanggu
In bolero and tanggu combination, make bolero parent of tanggu. Bolero and tanggu can communicate mutually using notifier and plat_data callback APIs. Change-Id: Iecd119df7f0ad1ba225c0427f3f42f217146b092 Signed-off-by: Laxminath Kasam <lkasam@codeaurora.org>
This commit is contained in:
@@ -75,6 +75,107 @@ static const struct snd_kcontrol_new name##_mux = \
|
||||
#define RX_MACRO_RX_PATH_OFFSET 0x80
|
||||
#define RX_MACRO_COMP_OFFSET 0x40
|
||||
|
||||
#define MAX_IMPED_PARAMS 6
|
||||
|
||||
struct wcd_imped_val {
|
||||
u32 imped_val;
|
||||
u8 index;
|
||||
};
|
||||
|
||||
static const struct wcd_imped_val imped_index[] = {
|
||||
{4, 0},
|
||||
{5, 1},
|
||||
{6, 2},
|
||||
{7, 3},
|
||||
{8, 4},
|
||||
{9, 5},
|
||||
{10, 6},
|
||||
{11, 7},
|
||||
{12, 8},
|
||||
{13, 9},
|
||||
};
|
||||
|
||||
struct rx_macro_reg_mask_val {
|
||||
u16 reg;
|
||||
u8 mask;
|
||||
u8 val;
|
||||
};
|
||||
|
||||
static const struct rx_macro_reg_mask_val imped_table[][MAX_IMPED_PARAMS] = {
|
||||
{
|
||||
{BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf2},
|
||||
{BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf2},
|
||||
{BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
|
||||
{BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf2},
|
||||
{BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf2},
|
||||
{BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
|
||||
},
|
||||
{
|
||||
{BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf4},
|
||||
{BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf4},
|
||||
{BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
|
||||
{BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf4},
|
||||
{BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf4},
|
||||
{BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
|
||||
},
|
||||
{
|
||||
{BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf7},
|
||||
{BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf7},
|
||||
{BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x01},
|
||||
{BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf7},
|
||||
{BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf7},
|
||||
{BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x01},
|
||||
},
|
||||
{
|
||||
{BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xf9},
|
||||
{BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xf9},
|
||||
{BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
|
||||
{BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xf9},
|
||||
{BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xf9},
|
||||
{BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
|
||||
},
|
||||
{
|
||||
{BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfa},
|
||||
{BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfa},
|
||||
{BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
|
||||
{BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfa},
|
||||
{BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfa},
|
||||
{BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
|
||||
},
|
||||
{
|
||||
{BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfb},
|
||||
{BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfb},
|
||||
{BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
|
||||
{BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfb},
|
||||
{BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfb},
|
||||
{BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
|
||||
},
|
||||
{
|
||||
{BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfc},
|
||||
{BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfc},
|
||||
{BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
|
||||
{BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfc},
|
||||
{BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfc},
|
||||
{BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
|
||||
},
|
||||
{
|
||||
{BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfd},
|
||||
{BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfd},
|
||||
{BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x00},
|
||||
{BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfd},
|
||||
{BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd},
|
||||
{BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x00},
|
||||
},
|
||||
{
|
||||
{BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0xff, 0xfd},
|
||||
{BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0xff, 0xfd},
|
||||
{BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x01, 0x01},
|
||||
{BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0xff, 0xfd},
|
||||
{BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd},
|
||||
{BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x01, 0x01},
|
||||
},
|
||||
};
|
||||
|
||||
enum {
|
||||
INTERP_HPHL,
|
||||
INTERP_HPHR,
|
||||
@@ -494,6 +595,80 @@ static struct snd_soc_dai_driver rx_macro_dai[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static int get_impedance_index(int imped)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (imped < imped_index[i].imped_val) {
|
||||
pr_debug("%s, detected impedance is less than %d Ohm\n",
|
||||
__func__, imped_index[i].imped_val);
|
||||
i = 0;
|
||||
goto ret;
|
||||
}
|
||||
if (imped >= imped_index[ARRAY_SIZE(imped_index) - 1].imped_val) {
|
||||
pr_debug("%s, detected impedance is greater than %d Ohm\n",
|
||||
__func__,
|
||||
imped_index[ARRAY_SIZE(imped_index) - 1].imped_val);
|
||||
i = ARRAY_SIZE(imped_index) - 1;
|
||||
goto ret;
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(imped_index) - 1; i++) {
|
||||
if (imped >= imped_index[i].imped_val &&
|
||||
imped < imped_index[i + 1].imped_val)
|
||||
break;
|
||||
}
|
||||
ret:
|
||||
pr_debug("%s: selected impedance index = %d\n",
|
||||
__func__, imped_index[i].index);
|
||||
return imped_index[i].index;
|
||||
}
|
||||
|
||||
/*
|
||||
* rx_macro_wcd_clsh_imped_config -
|
||||
* This function updates HPHL and HPHR gain settings
|
||||
* according to the impedance value.
|
||||
*
|
||||
* @codec: codec pointer handle
|
||||
* @imped: impedance value of HPHL/R
|
||||
* @reset: bool variable to reset registers when teardown
|
||||
*/
|
||||
static void rx_macro_wcd_clsh_imped_config(struct snd_soc_codec *codec,
|
||||
int imped, bool reset)
|
||||
{
|
||||
int i;
|
||||
int index = 0;
|
||||
int table_size;
|
||||
|
||||
static const struct rx_macro_reg_mask_val
|
||||
(*imped_table_ptr)[MAX_IMPED_PARAMS];
|
||||
|
||||
table_size = ARRAY_SIZE(imped_table);
|
||||
imped_table_ptr = imped_table;
|
||||
/* reset = 1, which means request is to reset the register values */
|
||||
if (reset) {
|
||||
for (i = 0; i < MAX_IMPED_PARAMS; i++)
|
||||
snd_soc_update_bits(codec,
|
||||
imped_table_ptr[index][i].reg,
|
||||
imped_table_ptr[index][i].mask, 0);
|
||||
return;
|
||||
}
|
||||
index = get_impedance_index(imped);
|
||||
if (index >= (ARRAY_SIZE(imped_index) - 1)) {
|
||||
pr_debug("%s, impedance not in range = %d\n", __func__, imped);
|
||||
return;
|
||||
}
|
||||
if (index >= table_size) {
|
||||
pr_debug("%s, impedance index not in range = %d\n", __func__,
|
||||
index);
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < MAX_IMPED_PARAMS; i++)
|
||||
snd_soc_update_bits(codec,
|
||||
imped_table_ptr[index][i].reg,
|
||||
imped_table_ptr[index][i].mask,
|
||||
imped_table_ptr[index][i].val);
|
||||
}
|
||||
|
||||
static bool rx_macro_get_data(struct snd_soc_codec *codec,
|
||||
struct device **rx_dev,
|
||||
struct rx_macro_priv **rx_priv,
|
||||
@@ -928,6 +1103,37 @@ static int rx_macro_mclk_ctrl(struct device *dev, bool enable)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rx_macro_event_handler(struct snd_soc_codec *codec, u16 event,
|
||||
u32 data)
|
||||
{
|
||||
u16 reg = 0, reg_mix = 0, rx_idx = 0, mute = 0x0;
|
||||
struct device *rx_dev = NULL;
|
||||
struct rx_macro_priv *rx_priv = NULL;
|
||||
|
||||
if (!rx_macro_get_data(codec, &rx_dev, &rx_priv, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
switch (event) {
|
||||
case BOLERO_MACRO_EVT_RX_MUTE:
|
||||
rx_idx = data >> 0x10;
|
||||
mute = data & 0xffff;
|
||||
reg = BOLERO_CDC_RX_RX0_RX_PATH_CTL + (rx_idx *
|
||||
RX_MACRO_RX_PATH_OFFSET);
|
||||
reg_mix = BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL + (rx_idx *
|
||||
RX_MACRO_RX_PATH_OFFSET);
|
||||
snd_soc_update_bits(codec, reg, 0x10, mute << 0x10);
|
||||
snd_soc_update_bits(codec, reg_mix, 0x10, mute << 0x10);
|
||||
break;
|
||||
case BOLERO_MACRO_EVT_IMPED_TRUE:
|
||||
rx_macro_wcd_clsh_imped_config(codec, data, true);
|
||||
break;
|
||||
case BOLERO_MACRO_EVT_IMPED_FALSE:
|
||||
rx_macro_wcd_clsh_imped_config(codec, data, false);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rx_macro_find_playback_dai_id_for_port(int port_id,
|
||||
struct rx_macro_priv *rx_priv)
|
||||
{
|
||||
@@ -1078,7 +1284,6 @@ static int rx_macro_enable_mix_path(struct snd_soc_dapm_widget *w,
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
snd_soc_write(codec, gain_reg,
|
||||
snd_soc_read(codec, gain_reg));
|
||||
snd_soc_update_bits(codec, mix_reg, 0x10, 0x00);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
/* Clk Disable */
|
||||
@@ -1128,7 +1333,6 @@ static int rx_macro_enable_main_path(struct snd_soc_dapm_widget *w,
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
snd_soc_write(codec, gain_reg,
|
||||
snd_soc_read(codec, gain_reg));
|
||||
snd_soc_update_bits(codec, reg, 0x10, 0x00);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
rx_macro_enable_interp_clk(codec, event, w->shift);
|
||||
@@ -2955,6 +3159,7 @@ static void rx_macro_init_ops(struct macro_ops *ops, char __iomem *rx_io_base)
|
||||
ops->dai_ptr = rx_macro_dai;
|
||||
ops->num_dais = ARRAY_SIZE(rx_macro_dai);
|
||||
ops->mclk_fn = rx_macro_mclk_ctrl;
|
||||
ops->event_handler = rx_macro_event_handler;
|
||||
}
|
||||
|
||||
static int rx_macro_probe(struct platform_device *pdev)
|
||||
|
Reference in New Issue
Block a user