asoc: codecs: Add unified SWR Tx mapping support

Add dynamic port enablement for wcd938x and
wcd937x targets to support unified swr tx port
mapping added as part of SWR 1.6 updates.

Change-Id: If0cf823dc51028fd5bd95f5a49ffe05998526be6
Signed-off-by: Ramlal Karra <rkarra@codeaurora.org>
Bu işleme şunda yer alıyor:
Ramlal Karra
2020-01-27 21:59:36 +05:30
işlemeyi yapan: Gerrit - the friendly Code Review server
ebeveyn 669089fdbd
işleme 3e2c37d273
8 değiştirilmiş dosya ile 616 ekleme ve 268 silme

Dosyayı Görüntüle

@@ -21,9 +21,9 @@
#include <asoc/msm-cdc-supply.h>
#include <dt-bindings/sound/audio-codec-port-types.h>
#include "internal.h"
#include "wcd938x-registers.h"
#include "wcd938x.h"
#include "internal.h"
#define WCD938X_DRV_NAME "wcd938x_codec"
@@ -362,25 +362,32 @@ static int wcd938x_tx_connect_port(struct snd_soc_component *component,
u8 slv_port_type, u8 enable)
{
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
u8 port_id, num_ch, ch_mask, port_type;
u8 port_id, num_ch, ch_mask, ch_type;
u32 ch_rate;
int slave_ch_idx;
u8 num_port = 1;
int ret = 0;
ret = wcd938x_set_port_params(component, slv_port_type, &port_id,
&num_ch, &ch_mask, &ch_rate,
&port_type, CODEC_TX);
&ch_type, CODEC_TX);
if (ret)
return ret;
slave_ch_idx = wcd938x_slave_get_slave_ch_val(slv_port_type);
if (slave_ch_idx != -EINVAL)
ch_type = wcd938x_slave_get_master_ch_val(slave_ch_idx);
dev_dbg(component->dev, "%s slv_ch_idx: %d, mstr_ch_type: %d\n",
__func__, slave_ch_idx, ch_type);
if (enable)
ret = swr_connect_port(wcd938x->tx_swr_dev, &port_id,
num_port, &ch_mask, &ch_rate,
&num_ch, &port_type);
&num_ch, &ch_type);
else
ret = swr_disconnect_port(wcd938x->tx_swr_dev, &port_id,
num_port, &ch_mask, &port_type);
num_port, &ch_mask, &ch_type);
return ret;
}
@@ -2326,6 +2333,96 @@ static int wcd938x_ldoh_put(struct snd_kcontrol *kcontrol,
return 0;
}
const char * const tx_master_ch_text[] = {
"ZERO", "SWRM_TX1_CH1", "SWRM_TX1_CH2", "SWRM_TX1_CH3", "SWRM_TX1_CH4",
"SWRM_TX2_CH1", "SWRM_TX2_CH2", "SWRM_TX2_CH3", "SWRM_TX2_CH4",
"SWRM_TX3_CH1", "SWRM_TX3_CH2", "SWRM_TX3_CH3", "SWRM_TX3_CH4",
"SWRM_PCM_IN",
};
const struct soc_enum tx_master_ch_enum =
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tx_master_ch_text),
tx_master_ch_text);
static void wcd938x_tx_get_slave_ch_type_idx(const char *wname, int *ch_idx)
{
u8 ch_type = 0;
if (strnstr(wname, "ADC1", sizeof("ADC1")))
ch_type = ADC1;
else if (strnstr(wname, "ADC2", sizeof("ADC2")))
ch_type = ADC2;
else if (strnstr(wname, "ADC3", sizeof("ADC3")))
ch_type = ADC3;
else if (strnstr(wname, "ADC4", sizeof("ADC4")))
ch_type = ADC4;
else if (strnstr(wname, "DMIC0", sizeof("DMIC0")))
ch_type = DMIC0;
else if (strnstr(wname, "DMIC1", sizeof("DMIC1")))
ch_type = DMIC1;
else if (strnstr(wname, "MBHC", sizeof("MBHC")))
ch_type = MBHC;
else if (strnstr(wname, "DMIC2", sizeof("DMIC2")))
ch_type = DMIC2;
else if (strnstr(wname, "DMIC3", sizeof("DMIC3")))
ch_type = DMIC3;
else if (strnstr(wname, "DMIC4", sizeof("DMIC4")))
ch_type = DMIC4;
else if (strnstr(wname, "DMIC5", sizeof("DMIC5")))
ch_type = DMIC5;
else if (strnstr(wname, "DMIC6", sizeof("DMIC6")))
ch_type = DMIC6;
else if (strnstr(wname, "DMIC7", sizeof("DMIC7")))
ch_type = DMIC7;
else
pr_err("%s: port name: %s is not listed\n", __func__, wname);
if (ch_type)
*ch_idx = wcd938x_slave_get_slave_ch_val(ch_type);
else
*ch_idx = -EINVAL;
}
static int wcd938x_tx_master_ch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component =
snd_soc_kcontrol_component(kcontrol);
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
int slave_ch_idx;
wcd938x_tx_get_slave_ch_type_idx(kcontrol->id.name, &slave_ch_idx);
if (slave_ch_idx != -EINVAL)
ucontrol->value.integer.value[0] =
wcd938x_slave_get_master_ch_val(
wcd938x->tx_master_ch_map[slave_ch_idx]);
return 0;
}
static int wcd938x_tx_master_ch_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component =
snd_soc_kcontrol_component(kcontrol);
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
int slave_ch_idx;
wcd938x_tx_get_slave_ch_type_idx(kcontrol->id.name, &slave_ch_idx);
dev_dbg(component->dev, "%s: slave_ch_idx: %d", __func__, slave_ch_idx);
dev_dbg(component->dev, "%s: ucontrol->value.enumerated.item[0] = %ld\n",
__func__, ucontrol->value.enumerated.item[0]);
if (slave_ch_idx != -EINVAL)
wcd938x->tx_master_ch_map[slave_ch_idx] =
wcd938x_slave_get_master_ch(
ucontrol->value.enumerated.item[0]);
return 0;
}
static const char * const tx_mode_mux_text_wcd9380[] = {
"ADC_INVALID", "ADC_HIFI", "ADC_LO_HIF", "ADC_NORMAL", "ADC_LP",
};
@@ -2423,6 +2520,33 @@ static const struct snd_kcontrol_new wcd938x_snd_controls[] = {
analog_gain),
SOC_SINGLE_TLV("ADC4 Volume", WCD938X_ANA_TX_CH4, 0, 20, 0,
analog_gain),
SOC_ENUM_EXT("ADC1 ChMap", tx_master_ch_enum,
wcd938x_tx_master_ch_get, wcd938x_tx_master_ch_put),
SOC_ENUM_EXT("ADC2 ChMap", tx_master_ch_enum,
wcd938x_tx_master_ch_get, wcd938x_tx_master_ch_put),
SOC_ENUM_EXT("ADC3 ChMap", tx_master_ch_enum,
wcd938x_tx_master_ch_get, wcd938x_tx_master_ch_put),
SOC_ENUM_EXT("ADC4 ChMap", tx_master_ch_enum,
wcd938x_tx_master_ch_get, wcd938x_tx_master_ch_put),
SOC_ENUM_EXT("DMIC0 ChMap", tx_master_ch_enum,
wcd938x_tx_master_ch_get, wcd938x_tx_master_ch_put),
SOC_ENUM_EXT("DMIC1 ChMap", tx_master_ch_enum,
wcd938x_tx_master_ch_get, wcd938x_tx_master_ch_put),
SOC_ENUM_EXT("MBHC ChMap", tx_master_ch_enum,
wcd938x_tx_master_ch_get, wcd938x_tx_master_ch_put),
SOC_ENUM_EXT("DMIC2 ChMap", tx_master_ch_enum,
wcd938x_tx_master_ch_get, wcd938x_tx_master_ch_put),
SOC_ENUM_EXT("DMIC3 ChMap", tx_master_ch_enum,
wcd938x_tx_master_ch_get, wcd938x_tx_master_ch_put),
SOC_ENUM_EXT("DMIC4 ChMap", tx_master_ch_enum,
wcd938x_tx_master_ch_get, wcd938x_tx_master_ch_put),
SOC_ENUM_EXT("DMIC5 ChMap", tx_master_ch_enum,
wcd938x_tx_master_ch_get, wcd938x_tx_master_ch_put),
SOC_ENUM_EXT("DMIC6 ChMap", tx_master_ch_enum,
wcd938x_tx_master_ch_get, wcd938x_tx_master_ch_put),
SOC_ENUM_EXT("DMIC7 ChMap", tx_master_ch_enum,
wcd938x_tx_master_ch_get, wcd938x_tx_master_ch_put),
};
static const struct snd_kcontrol_new adc1_switch[] = {
@@ -2771,18 +2895,7 @@ static const struct snd_soc_dapm_widget wcd938x_dapm_widgets[] = {
hphr_rdac_switch, ARRAY_SIZE(hphr_rdac_switch)),
/*output widgets tx*/
SND_SOC_DAPM_OUTPUT("ADC1_OUTPUT"),
SND_SOC_DAPM_OUTPUT("ADC2_OUTPUT"),
SND_SOC_DAPM_OUTPUT("ADC3_OUTPUT"),
SND_SOC_DAPM_OUTPUT("ADC4_OUTPUT"),
SND_SOC_DAPM_OUTPUT("DMIC1_OUTPUT"),
SND_SOC_DAPM_OUTPUT("DMIC2_OUTPUT"),
SND_SOC_DAPM_OUTPUT("DMIC3_OUTPUT"),
SND_SOC_DAPM_OUTPUT("DMIC4_OUTPUT"),
SND_SOC_DAPM_OUTPUT("DMIC5_OUTPUT"),
SND_SOC_DAPM_OUTPUT("DMIC6_OUTPUT"),
SND_SOC_DAPM_OUTPUT("DMIC7_OUTPUT"),
SND_SOC_DAPM_OUTPUT("DMIC8_OUTPUT"),
SND_SOC_DAPM_OUTPUT("WCD_TX_OUTPUT"),
/*output widgets rx*/
SND_SOC_DAPM_OUTPUT("EAR"),
@@ -2811,12 +2924,12 @@ static const struct snd_soc_dapm_widget wcd938x_dapm_widgets[] = {
static const struct snd_soc_dapm_route wcd938x_audio_map[] = {
{"ADC1_OUTPUT", NULL, "ADC1_MIXER"},
{"WCD_TX_OUTPUT", NULL, "ADC1_MIXER"},
{"ADC1_MIXER", "Switch", "ADC1 REQ"},
{"ADC1 REQ", NULL, "ADC1"},
{"ADC1", NULL, "AMIC1"},
{"ADC2_OUTPUT", NULL, "ADC2_MIXER"},
{"WCD_TX_OUTPUT", NULL, "ADC2_MIXER"},
{"ADC2_MIXER", "Switch", "ADC2 REQ"},
{"ADC2 REQ", NULL, "ADC2"},
{"ADC2", NULL, "HDR12 MUX"},
@@ -2825,7 +2938,7 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = {
{"ADC2 MUX", "INP3", "AMIC3"},
{"ADC2 MUX", "INP2", "AMIC2"},
{"ADC3_OUTPUT", NULL, "ADC3_MIXER"},
{"WCD_TX_OUTPUT", NULL, "ADC3_MIXER"},
{"ADC3_MIXER", "Switch", "ADC3 REQ"},
{"ADC3 REQ", NULL, "ADC3"},
{"ADC3", NULL, "HDR34 MUX"},
@@ -2834,35 +2947,35 @@ static const struct snd_soc_dapm_route wcd938x_audio_map[] = {
{"ADC3 MUX", "INP4", "AMIC4"},
{"ADC3 MUX", "INP6", "AMIC6"},
{"ADC4_OUTPUT", NULL, "ADC4_MIXER"},
{"WCD_TX_OUTPUT", NULL, "ADC4_MIXER"},
{"ADC4_MIXER", "Switch", "ADC4 REQ"},
{"ADC4 REQ", NULL, "ADC4"},
{"ADC4", NULL, "ADC4 MUX"},
{"ADC4 MUX", "INP5", "AMIC5"},
{"ADC4 MUX", "INP7", "AMIC7"},
{"DMIC1_OUTPUT", NULL, "DMIC1_MIXER"},
{"WCD_TX_OUTPUT", NULL, "DMIC1_MIXER"},
{"DMIC1_MIXER", "Switch", "DMIC1"},
{"DMIC2_OUTPUT", NULL, "DMIC2_MIXER"},
{"WCD_TX_OUTPUT", NULL, "DMIC2_MIXER"},
{"DMIC2_MIXER", "Switch", "DMIC2"},
{"DMIC3_OUTPUT", NULL, "DMIC3_MIXER"},
{"WCD_TX_OUTPUT", NULL, "DMIC3_MIXER"},
{"DMIC3_MIXER", "Switch", "DMIC3"},
{"DMIC4_OUTPUT", NULL, "DMIC4_MIXER"},
{"WCD_TX_OUTPUT", NULL, "DMIC4_MIXER"},
{"DMIC4_MIXER", "Switch", "DMIC4"},
{"DMIC5_OUTPUT", NULL, "DMIC5_MIXER"},
{"WCD_TX_OUTPUT", NULL, "DMIC5_MIXER"},
{"DMIC5_MIXER", "Switch", "DMIC5"},
{"DMIC6_OUTPUT", NULL, "DMIC6_MIXER"},
{"WCD_TX_OUTPUT", NULL, "DMIC6_MIXER"},
{"DMIC6_MIXER", "Switch", "DMIC6"},
{"DMIC7_OUTPUT", NULL, "DMIC7_MIXER"},
{"WCD_TX_OUTPUT", NULL, "DMIC7_MIXER"},
{"DMIC7_MIXER", "Switch", "DMIC7"},
{"DMIC8_OUTPUT", NULL, "DMIC8_MIXER"},
{"WCD_TX_OUTPUT", NULL, "DMIC8_MIXER"},
{"DMIC8_MIXER", "Switch", "DMIC8"},
{"IN1_HPHL", NULL, "CLS_H_PORT"},
@@ -3160,18 +3273,7 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component)
snd_soc_dapm_ignore_suspend(dapm, "AMIC5");
snd_soc_dapm_ignore_suspend(dapm, "AMIC6");
snd_soc_dapm_ignore_suspend(dapm, "AMIC7");
snd_soc_dapm_ignore_suspend(dapm, "DMIC1_OUTPUT");
snd_soc_dapm_ignore_suspend(dapm, "DMIC2_OUTPUT");
snd_soc_dapm_ignore_suspend(dapm, "DMIC3_OUTPUT");
snd_soc_dapm_ignore_suspend(dapm, "DMIC4_OUTPUT");
snd_soc_dapm_ignore_suspend(dapm, "DMIC5_OUTPUT");
snd_soc_dapm_ignore_suspend(dapm, "DMIC6_OUTPUT");
snd_soc_dapm_ignore_suspend(dapm, "DMIC7_OUTPUT");
snd_soc_dapm_ignore_suspend(dapm, "DMIC8_OUTPUT");
snd_soc_dapm_ignore_suspend(dapm, "ADC1_OUTPUT");
snd_soc_dapm_ignore_suspend(dapm, "ADC2_OUTPUT");
snd_soc_dapm_ignore_suspend(dapm, "ADC3_OUTPUT");
snd_soc_dapm_ignore_suspend(dapm, "ADC4_OUTPUT");
snd_soc_dapm_ignore_suspend(dapm, "WCD_TX_OUTPUT");
snd_soc_dapm_ignore_suspend(dapm, "IN1_HPHL");
snd_soc_dapm_ignore_suspend(dapm, "IN2_HPHR");
snd_soc_dapm_ignore_suspend(dapm, "IN3_AUX");
@@ -3526,7 +3628,7 @@ static int wcd938x_bind(struct device *dev)
wcd_disable_irq(&wcd938x->irq_info, WCD938X_IRQ_AUX_PDM_WD_INT);
ret = snd_soc_register_component(dev, &soc_codec_dev_wcd938x,
NULL, 0);
NULL, 0);
if (ret) {
dev_err(dev, "%s: Codec registration failed\n",
__func__);