summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/qcom,msm8916-wcd-digital-codec.yaml8
-rw-r--r--Documentation/devicetree/bindings/sound/qcom,pm8916-wcd-analog-codec.yaml11
-rw-r--r--Documentation/devicetree/bindings/sound/qcom,q6dsp-lpass-ports.yaml4
-rw-r--r--Documentation/devicetree/bindings/sound/qcom,sm8250.yaml1
-rw-r--r--include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h4
-rw-r--r--sound/soc/codecs/msm8916-wcd-analog.c144
-rw-r--r--sound/soc/qcom/common.c1
-rw-r--r--sound/soc/qcom/common.h2
-rw-r--r--sound/soc/qcom/qdsp6/q6afe-dai.c48
-rw-r--r--sound/soc/qcom/qdsp6/q6afe.c56
-rw-r--r--sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c5
-rw-r--r--sound/soc/qcom/qdsp6/q6routing.c78
-rw-r--r--sound/soc/qcom/sm8250.c17
13 files changed, 367 insertions, 12 deletions
diff --git a/Documentation/devicetree/bindings/sound/qcom,msm8916-wcd-digital-codec.yaml b/Documentation/devicetree/bindings/sound/qcom,msm8916-wcd-digital-codec.yaml
index a899c4e7c1c9..33bc23b6176a 100644
--- a/Documentation/devicetree/bindings/sound/qcom,msm8916-wcd-digital-codec.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,msm8916-wcd-digital-codec.yaml
@@ -14,7 +14,13 @@ description:
properties:
compatible:
- const: qcom,msm8916-wcd-digital-codec
+ oneOf:
+ - items:
+ - enum:
+ - qcom,sdm660-wcd-digital-codec
+ - const: qcom,msm8916-wcd-digital-codec
+
+ - const: qcom,msm8916-wcd-digital-codec
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/sound/qcom,pm8916-wcd-analog-codec.yaml b/Documentation/devicetree/bindings/sound/qcom,pm8916-wcd-analog-codec.yaml
index 94e7a1860977..be47dbdb2e92 100644
--- a/Documentation/devicetree/bindings/sound/qcom,pm8916-wcd-analog-codec.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,pm8916-wcd-analog-codec.yaml
@@ -14,7 +14,16 @@ description:
properties:
compatible:
- const: qcom,pm8916-wcd-analog-codec
+ oneOf:
+ - items:
+ - enum:
+ - qcom,pm660l-wcd-analog-codec
+ - const: qcom,pm8953-wcd-analog-codec
+
+ - enum:
+ - qcom,pm8916-wcd-analog-codec
+ - qcom,pm8950-wcd-analog-codec
+ - qcom,pm8953-wcd-analog-codec
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/sound/qcom,q6dsp-lpass-ports.yaml b/Documentation/devicetree/bindings/sound/qcom,q6dsp-lpass-ports.yaml
index 2b27d6c8f58f..3b03e2acd67e 100644
--- a/Documentation/devicetree/bindings/sound/qcom,q6dsp-lpass-ports.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,q6dsp-lpass-ports.yaml
@@ -127,7 +127,7 @@ patternProperties:
contains:
# MI2S DAI ID range PRIMARY_MI2S_RX - QUATERNARY_MI2S_TX and
# QUINARY_MI2S_RX - QUINARY_MI2S_TX and
- # LPI_MI2S_RX_0 - SENARY_MI2S_TX
+ # LPI_MI2S_RX_0 - LPI_MI2S_TX_6
items:
oneOf:
- minimum: 16
@@ -135,7 +135,7 @@ patternProperties:
- minimum: 127
maximum: 128
- minimum: 137
- maximum: 148
+ maximum: 152
then:
required:
- qcom,sd-lines
diff --git a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
index 486780ed553c..c1bd19299763 100644
--- a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
@@ -48,6 +48,7 @@ properties:
- qcom,qrb5165-rb5-sndcard
- qcom,sc7180-qdsp6-sndcard
- qcom,sc8280xp-sndcard
+ - qcom,sdm660-sndcard
- qcom,sdm845-sndcard
- qcom,sm8250-sndcard
- qcom,sm8450-sndcard
diff --git a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
index 8e04106d48be..ca84952c3884 100644
--- a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
+++ b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h
@@ -152,6 +152,10 @@
#define LPI_MI2S_TX_4 146
#define SENARY_MI2S_RX 147
#define SENARY_MI2S_TX 148
+#define LPI_MI2S_RX_5 149
+#define LPI_MI2S_TX_5 150
+#define LPI_MI2S_RX_6 151
+#define LPI_MI2S_TX_6 152
#define LPASS_CLK_ID_PRI_MI2S_IBIT 1
#define LPASS_CLK_ID_PRI_MI2S_EBIT 2
diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c
index 9ca381812975..87f8a47cc293 100644
--- a/sound/soc/codecs/msm8916-wcd-analog.c
+++ b/sound/soc/codecs/msm8916-wcd-analog.c
@@ -217,9 +217,11 @@
#define CDC_A_RX_HPH_BIAS_LDO_OCP (0xf195)
#define CDC_A_RX_HPH_BIAS_CNP (0xf196)
#define CDC_A_RX_HPH_CNP_EN (0xf197)
+#define CDC_A_RX_HPH_L_TEST (0xf19A)
#define CDC_A_RX_HPH_L_PA_DAC_CTL (0xf19B)
#define RX_HPA_L_PA_DAC_CTL_DATA_RESET_MASK BIT(1)
#define RX_HPA_L_PA_DAC_CTL_DATA_RESET_RESET BIT(1)
+#define CDC_A_RX_HPH_R_TEST (0xf19C)
#define CDC_A_RX_HPH_R_PA_DAC_CTL (0xf19D)
#define RX_HPH_R_PA_DAC_CTL_DATA_RESET BIT(1)
#define RX_HPH_R_PA_DAC_CTL_DATA_RESET_MASK BIT(1)
@@ -232,6 +234,8 @@
#define RX_EAR_CTL_PA_SEL_MASK BIT(7)
#define RX_EAR_CTL_PA_SEL BIT(7)
+#define CDC_A_RX_EAR_STATUS (0xf1A1)
+
#define CDC_A_SPKR_DAC_CTL (0xf1B0)
#define SPKR_DAC_CTL_DAC_RESET_MASK BIT(4)
#define SPKR_DAC_CTL_DAC_RESET_NORMAL 0
@@ -250,6 +254,7 @@
SPKR_DRV_CAL_EN | SPKR_DRV_SETTLE_EN | \
SPKR_DRV_FW_EN | SPKR_DRV_BOOST_SET | \
SPKR_DRV_CMFB_SET | SPKR_DRV_GAIN_SET)
+#define CDC_A_SPKR_ANA_BIAS_SET (0xf1B3)
#define CDC_A_SPKR_OCP_CTL (0xf1B4)
#define CDC_A_SPKR_PWRSTG_CTL (0xf1B5)
#define SPKR_PWRSTG_CTL_DAC_EN_MASK BIT(0)
@@ -264,6 +269,7 @@
#define CDC_A_SPKR_DRV_DBG (0xf1B7)
#define CDC_A_CURRENT_LIMIT (0xf1C0)
+#define CDC_A_BYPASS_MODE (0xf1C2)
#define CDC_A_BOOST_EN_CTL (0xf1C3)
#define CDC_A_SLOPE_COMP_IP_ZERO (0xf1C4)
#define CDC_A_SEC_ACCESS (0xf1D0)
@@ -286,6 +292,11 @@ static const char * const supply_names[] = {
#define MBHC_MAX_BUTTONS (5)
+struct wcd_reg_seq {
+ const struct reg_default *seq;
+ int seq_size;
+};
+
struct pm8916_wcd_analog_priv {
u16 pmic_rev;
u16 codec_version;
@@ -696,6 +707,59 @@ static int pm8916_wcd_analog_enable_ear_pa(struct snd_soc_dapm_widget *w,
return 0;
}
+static int pm8916_wcd_analog_enable_hphl_pa(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+ struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(component->dev);
+
+ /* This quirk is not required for revisions prior to CAJON_2_0 */
+ if (priv->codec_version < 4)
+ return 0;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ usleep_range(7000, 7100);
+ snd_soc_component_update_bits(component, CDC_A_RX_HPH_L_TEST,
+ 0x04, 0x04);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ /* wait 20 ms after the digital codec has powered down */
+ msleep(20);
+ snd_soc_component_update_bits(component, CDC_A_RX_HPH_L_TEST,
+ 0x04, 0x00);
+ break;
+ }
+ return 0;
+}
+
+static int pm8916_wcd_analog_enable_hphr_pa(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
+ struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(component->dev);
+
+ /* This quirk is not required for revisions prior to CAJON_2_0 */
+ if (priv->codec_version < 4)
+ return 0;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ usleep_range(7000, 7100);
+ snd_soc_component_update_bits(component, CDC_A_RX_HPH_R_TEST,
+ 0x04, 0x04);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ msleep(20);
+ snd_soc_component_update_bits(component, CDC_A_RX_HPH_R_TEST,
+ 0x04, 0x00);
+ break;
+ }
+ return 0;
+}
+
static const struct reg_default wcd_reg_defaults_2_0[] = {
{CDC_A_RX_COM_OCP_CTL, 0xD1},
{CDC_A_RX_COM_OCP_COUNT, 0xFF},
@@ -715,9 +779,69 @@ static const struct reg_default wcd_reg_defaults_2_0[] = {
{CDC_A_MASTER_BIAS_CTL, 0x30},
};
+static const struct wcd_reg_seq pm8916_data = {
+ .seq = wcd_reg_defaults_2_0,
+ .seq_size = ARRAY_SIZE(wcd_reg_defaults_2_0),
+};
+
+static const struct reg_default wcd_reg_defaults_pm8950[] = {
+ {CDC_A_RX_COM_OCP_CTL, 0xd1},
+ {CDC_A_RX_COM_OCP_COUNT, 0xff},
+ {CDC_D_SEC_ACCESS, 0xa5},
+ {CDC_D_PERPH_RESET_CTL3, 0x0f},
+ {CDC_A_TX_1_2_OPAMP_BIAS, 0x4c},
+ {CDC_A_NCP_FBCTRL, 0xa8},
+ {CDC_A_NCP_VCTRL, 0xa4},
+ {CDC_A_SPKR_DRV_CTL, 0x69},
+ {CDC_A_SPKR_DRV_DBG, 0x01},
+ {CDC_A_SEC_ACCESS, 0xa5},
+ {CDC_A_PERPH_RESET_CTL3, 0x0f},
+ {CDC_A_CURRENT_LIMIT, 0x82},
+ {CDC_A_SPKR_ANA_BIAS_SET, 0x41},
+ {CDC_A_SPKR_DAC_CTL, 0x03},
+ {CDC_A_SPKR_OCP_CTL, 0xe1},
+ {CDC_A_RX_HPH_BIAS_PA, 0xfa},
+ {CDC_A_MASTER_BIAS_CTL, 0x30},
+ {CDC_A_MICB_1_INT_RBIAS, 0x00},
+};
+
+static const struct wcd_reg_seq pm8950_data = {
+ .seq = wcd_reg_defaults_pm8950,
+ .seq_size = ARRAY_SIZE(wcd_reg_defaults_pm8950),
+};
+
+static const struct reg_default wcd_reg_defaults_pm8953[] = {
+ {CDC_A_RX_COM_OCP_CTL, 0xd1},
+ {CDC_A_RX_COM_OCP_COUNT, 0xff},
+ {CDC_D_SEC_ACCESS, 0xa5},
+ {CDC_D_PERPH_RESET_CTL3, 0x0f},
+ {CDC_A_TX_1_2_OPAMP_BIAS, 0x4c},
+ {CDC_A_NCP_FBCTRL, 0xa8},
+ {CDC_A_NCP_VCTRL, 0xa4},
+ {CDC_A_SPKR_DRV_CTL, 0x69},
+ {CDC_A_SPKR_DRV_DBG, 0x01},
+ {CDC_A_SEC_ACCESS, 0xa5},
+ {CDC_A_PERPH_RESET_CTL3, 0x0f},
+ {CDC_A_CURRENT_LIMIT, 0xa2},
+ {CDC_A_BYPASS_MODE, 0x18},
+ {CDC_A_SPKR_ANA_BIAS_SET, 0x41},
+ {CDC_A_SPKR_DAC_CTL, 0x03},
+ {CDC_A_SPKR_OCP_CTL, 0xe1},
+ {CDC_A_RX_HPH_BIAS_PA, 0xfa},
+ {CDC_A_RX_EAR_STATUS, 0x10},
+ {CDC_A_MASTER_BIAS_CTL, 0x30},
+ {CDC_A_MICB_1_INT_RBIAS, 0x00},
+};
+
+static const struct wcd_reg_seq pm8953_data = {
+ .seq = wcd_reg_defaults_pm8953,
+ .seq_size = ARRAY_SIZE(wcd_reg_defaults_pm8953),
+};
+
static int pm8916_wcd_analog_probe(struct snd_soc_component *component)
{
struct pm8916_wcd_analog_priv *priv = dev_get_drvdata(component->dev);
+ const struct wcd_reg_seq *wcd_reg_init_data;
int err, reg;
err = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies);
@@ -738,9 +862,11 @@ static int pm8916_wcd_analog_probe(struct snd_soc_component *component)
snd_soc_component_write(component, CDC_D_PERPH_RESET_CTL4, 0x01);
snd_soc_component_write(component, CDC_A_PERPH_RESET_CTL4, 0x01);
- for (reg = 0; reg < ARRAY_SIZE(wcd_reg_defaults_2_0); reg++)
- snd_soc_component_write(component, wcd_reg_defaults_2_0[reg].reg,
- wcd_reg_defaults_2_0[reg].def);
+ wcd_reg_init_data = of_device_get_match_data(component->dev);
+
+ for (reg = 0; reg < wcd_reg_init_data->seq_size; reg++)
+ snd_soc_component_write(component, wcd_reg_init_data->seq[reg].reg,
+ wcd_reg_init_data->seq[reg].def);
priv->component = component;
@@ -883,11 +1009,15 @@ static const struct snd_soc_dapm_widget pm8916_wcd_analog_dapm_widgets[] = {
SND_SOC_DAPM_MUX("EAR_S", SND_SOC_NOPM, 0, 0, &ear_mux),
SND_SOC_DAPM_SUPPLY("EAR CP", CDC_A_NCP_EN, 4, 0, NULL, 0),
- SND_SOC_DAPM_PGA("HPHL PA", CDC_A_RX_HPH_CNP_EN, 5, 0, NULL, 0),
+ SND_SOC_DAPM_PGA_E("HPHL PA", CDC_A_RX_HPH_CNP_EN, 5, 0, NULL, 0,
+ pm8916_wcd_analog_enable_hphl_pa,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MUX("HPHL", SND_SOC_NOPM, 0, 0, &hphl_mux),
SND_SOC_DAPM_MIXER("HPHL DAC", CDC_A_RX_HPH_L_PA_DAC_CTL, 3, 0, NULL,
0),
- SND_SOC_DAPM_PGA("HPHR PA", CDC_A_RX_HPH_CNP_EN, 4, 0, NULL, 0),
+ SND_SOC_DAPM_PGA_E("HPHR PA", CDC_A_RX_HPH_CNP_EN, 4, 0, NULL, 0,
+ pm8916_wcd_analog_enable_hphr_pa,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MUX("HPHR", SND_SOC_NOPM, 0, 0, &hphr_mux),
SND_SOC_DAPM_MIXER("HPHR DAC", CDC_A_RX_HPH_R_PA_DAC_CTL, 3, 0, NULL,
0),
@@ -1259,7 +1389,9 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
}
static const struct of_device_id pm8916_wcd_analog_spmi_match_table[] = {
- { .compatible = "qcom,pm8916-wcd-analog-codec", },
+ { .compatible = "qcom,pm8916-wcd-analog-codec", .data = &pm8916_data },
+ { .compatible = "qcom,pm8950-wcd-analog-codec", .data = &pm8950_data },
+ { .compatible = "qcom,pm8953-wcd-analog-codec", .data = &pm8953_data },
{ }
};
diff --git a/sound/soc/qcom/common.c b/sound/soc/qcom/common.c
index e4ff247ea47f..f8782e5cfaae 100644
--- a/sound/soc/qcom/common.c
+++ b/sound/soc/qcom/common.c
@@ -215,6 +215,7 @@ int qcom_snd_wcd_jack_setup(struct snd_soc_pcm_runtime *rtd,
}
switch (cpu_dai->id) {
+ case LPI_MI2S_RX_0:
case TX_CODEC_DMA_TX_0:
case TX_CODEC_DMA_TX_1:
case TX_CODEC_DMA_TX_2:
diff --git a/sound/soc/qcom/common.h b/sound/soc/qcom/common.h
index ee6662885593..48b114eb46a5 100644
--- a/sound/soc/qcom/common.h
+++ b/sound/soc/qcom/common.h
@@ -7,7 +7,7 @@
#include <dt-bindings/sound/qcom,q6afe.h>
#include <sound/soc.h>
-#define LPASS_MAX_PORT (SENARY_MI2S_TX + 1)
+#define LPASS_MAX_PORT (LPI_MI2S_TX_6 + 1)
int qcom_snd_parse_of(struct snd_soc_card *card);
int qcom_snd_wcd_jack_setup(struct snd_soc_pcm_runtime *rtd,
diff --git a/sound/soc/qcom/qdsp6/q6afe-dai.c b/sound/soc/qcom/qdsp6/q6afe-dai.c
index a0d21034a626..920345609d2c 100644
--- a/sound/soc/qcom/qdsp6/q6afe-dai.c
+++ b/sound/soc/qcom/qdsp6/q6afe-dai.c
@@ -412,6 +412,8 @@ static int q6afe_dai_prepare(struct snd_pcm_substream *substream,
case SENARY_MI2S_RX ... SENARY_MI2S_TX:
case QUINARY_MI2S_RX ... QUINARY_MI2S_TX:
case PRIMARY_MI2S_RX ... QUATERNARY_MI2S_TX:
+ case LPI_MI2S_RX_0 ... LPI_MI2S_TX_4:
+ case LPI_MI2S_RX_5 ... LPI_MI2S_TX_6:
rc = q6afe_i2s_port_prepare(dai_data->port[dai->id],
&dai_data->port_config[dai->id].i2s_cfg);
if (rc < 0) {
@@ -665,6 +667,21 @@ static const struct snd_soc_dapm_route q6afe_dapm_routes[] = {
/* USB playback AFE port receives data for playback, hence use the RX port */
{"USB Playback", NULL, "USB_RX"},
+
+ {"LPI RX0 MI2S Playback", NULL, "LPI_MI2S_RX_0"},
+ {"LPI_MI2S_TX_0", NULL, "LPI TX0 MI2S Capture"},
+ {"LPI RX1 MI2S Playback", NULL, "LPI_MI2S_RX_1"},
+ {"LPI_MI2S_TX_1", NULL, "LPI TX1 MI2S Capture"},
+ {"LPI RX2 MI2S Playback", NULL, "LPI_MI2S_RX_2"},
+ {"LPI_MI2S_TX_2", NULL, "LPI TX2 MI2S Capture"},
+ {"LPI RX3 MI2S Playback", NULL, "LPI_MI2S_RX_3"},
+ {"LPI_MI2S_TX_3", NULL, "LPI TX3 MI2S Capture"},
+ {"LPI RX4 MI2S Playback", NULL, "LPI_MI2S_RX_4"},
+ {"LPI_MI2S_TX_4", NULL, "LPI TX4 MI2S Capture"},
+ {"LPI RX5 MI2S Playback", NULL, "LPI_MI2S_RX_5"},
+ {"LPI_MI2S_TX_5", NULL, "LPI TX5 MI2S Capture"},
+ {"LPI RX6 MI2S Playback", NULL, "LPI_MI2S_RX_6"},
+ {"LPI_MI2S_TX_6", NULL, "LPI TX6 MI2S Capture"},
};
static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai)
@@ -1011,6 +1028,35 @@ static const struct snd_soc_dapm_widget q6afe_dai_widgets[] = {
0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_IN("USB_RX", NULL, 0, SND_SOC_NOPM, 0, 0),
+
+ SND_SOC_DAPM_AIF_IN("LPI_MI2S_RX_0", NULL,
+ 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("LPI_MI2S_TX_0", NULL,
+ 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("LPI_MI2S_RX_1", NULL,
+ 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("LPI_MI2S_TX_1", NULL,
+ 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("LPI_MI2S_RX_2", NULL,
+ 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("LPI_MI2S_TX_2", NULL,
+ 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("LPI_MI2S_RX_3", NULL,
+ 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("LPI_MI2S_TX_3", NULL,
+ 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("LPI_MI2S_RX_4", NULL,
+ 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("LPI_MI2S_TX_4", NULL,
+ 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("LPI_MI2S_RX_5", NULL,
+ 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("LPI_MI2S_TX_5", NULL,
+ 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN("LPI_MI2S_RX_6", NULL,
+ 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("LPI_MI2S_TX_6", NULL,
+ 0, SND_SOC_NOPM, 0, 0),
};
static const struct snd_soc_component_driver q6afe_dai_component = {
@@ -1045,6 +1091,8 @@ static void of_q6afe_parse_dai_data(struct device *dev,
case SENARY_MI2S_RX ... SENARY_MI2S_TX:
case QUINARY_MI2S_RX ... QUINARY_MI2S_TX:
case PRIMARY_MI2S_RX ... QUATERNARY_MI2S_TX:
+ case LPI_MI2S_RX_0 ... LPI_MI2S_TX_4:
+ case LPI_MI2S_RX_5 ... LPI_MI2S_TX_6:
priv = &data->priv[id];
ret = of_property_read_variable_u32_array(node,
"qcom,sd-lines",
diff --git a/sound/soc/qcom/qdsp6/q6afe.c b/sound/soc/qcom/qdsp6/q6afe.c
index 40237267fda0..1d68a80e8e0c 100644
--- a/sound/soc/qcom/qdsp6/q6afe.c
+++ b/sound/soc/qcom/qdsp6/q6afe.c
@@ -132,6 +132,20 @@
#define AFE_PORT_ID_QUINARY_MI2S_TX 0x1017
#define AFE_PORT_ID_SENARY_MI2S_RX 0x1018
#define AFE_PORT_ID_SENARY_MI2S_TX 0x1019
+#define AFE_PORT_ID_INT0_MI2S_RX 0x102e
+#define AFE_PORT_ID_INT0_MI2S_TX 0x102f
+#define AFE_PORT_ID_INT1_MI2S_RX 0x1030
+#define AFE_PORT_ID_INT1_MI2S_TX 0x1031
+#define AFE_PORT_ID_INT2_MI2S_RX 0x1032
+#define AFE_PORT_ID_INT2_MI2S_TX 0x1033
+#define AFE_PORT_ID_INT3_MI2S_RX 0x1034
+#define AFE_PORT_ID_INT3_MI2S_TX 0x1035
+#define AFE_PORT_ID_INT4_MI2S_RX 0x1036
+#define AFE_PORT_ID_INT4_MI2S_TX 0x1037
+#define AFE_PORT_ID_INT5_MI2S_RX 0x1038
+#define AFE_PORT_ID_INT5_MI2S_TX 0x1039
+#define AFE_PORT_ID_INT6_MI2S_RX 0x103a
+#define AFE_PORT_ID_INT6_MI2S_TX 0x103b
/* Start of the range of port IDs for TDM devices. */
#define AFE_PORT_ID_TDM_PORT_RANGE_START 0x9000
@@ -931,6 +945,34 @@ static struct afe_port_map port_maps[AFE_PORT_MAX] = {
[RX_CODEC_DMA_RX_7] = { AFE_PORT_ID_RX_CODEC_DMA_RX_7,
RX_CODEC_DMA_RX_7, 1, 1},
[USB_RX] = { AFE_PORT_ID_USB_RX, USB_RX, 1, 1},
+ [LPI_MI2S_RX_0] = { AFE_PORT_ID_INT0_MI2S_RX,
+ LPI_MI2S_RX_0, 1, 1},
+ [LPI_MI2S_TX_0] = { AFE_PORT_ID_INT0_MI2S_TX,
+ LPI_MI2S_TX_0, 0, 1},
+ [LPI_MI2S_RX_1] = { AFE_PORT_ID_INT1_MI2S_RX,
+ LPI_MI2S_RX_1, 1, 1},
+ [LPI_MI2S_TX_1] = { AFE_PORT_ID_INT1_MI2S_TX,
+ LPI_MI2S_TX_1, 0, 1},
+ [LPI_MI2S_RX_2] = { AFE_PORT_ID_INT2_MI2S_RX,
+ LPI_MI2S_RX_2, 1, 1},
+ [LPI_MI2S_TX_2] = { AFE_PORT_ID_INT2_MI2S_TX,
+ LPI_MI2S_TX_2, 0, 1},
+ [LPI_MI2S_RX_3] = { AFE_PORT_ID_INT3_MI2S_RX,
+ LPI_MI2S_RX_3, 1, 1},
+ [LPI_MI2S_TX_3] = { AFE_PORT_ID_INT3_MI2S_TX,
+ LPI_MI2S_TX_3, 0, 1},
+ [LPI_MI2S_RX_4] = { AFE_PORT_ID_INT4_MI2S_RX,
+ LPI_MI2S_RX_4, 1, 1},
+ [LPI_MI2S_TX_4] = { AFE_PORT_ID_INT4_MI2S_TX,
+ LPI_MI2S_TX_4, 0, 1},
+ [LPI_MI2S_RX_5] = { AFE_PORT_ID_INT5_MI2S_RX,
+ LPI_MI2S_RX_5, 1, 1},
+ [LPI_MI2S_TX_5] = { AFE_PORT_ID_INT5_MI2S_TX,
+ LPI_MI2S_TX_5, 0, 1},
+ [LPI_MI2S_RX_6] = { AFE_PORT_ID_INT6_MI2S_RX,
+ LPI_MI2S_RX_6, 1, 1},
+ [LPI_MI2S_TX_6] = { AFE_PORT_ID_INT6_MI2S_TX,
+ LPI_MI2S_TX_6, 0, 1},
};
static void q6afe_port_free(struct kref *ref)
@@ -1785,6 +1827,20 @@ struct q6afe_port *q6afe_port_get_from_id(struct device *dev, int id)
case AFE_PORT_ID_QUINARY_MI2S_TX:
case AFE_PORT_ID_SENARY_MI2S_RX:
case AFE_PORT_ID_SENARY_MI2S_TX:
+ case AFE_PORT_ID_INT0_MI2S_RX:
+ case AFE_PORT_ID_INT0_MI2S_TX:
+ case AFE_PORT_ID_INT1_MI2S_RX:
+ case AFE_PORT_ID_INT1_MI2S_TX:
+ case AFE_PORT_ID_INT2_MI2S_RX:
+ case AFE_PORT_ID_INT2_MI2S_TX:
+ case AFE_PORT_ID_INT3_MI2S_RX:
+ case AFE_PORT_ID_INT3_MI2S_TX:
+ case AFE_PORT_ID_INT4_MI2S_RX:
+ case AFE_PORT_ID_INT4_MI2S_TX:
+ case AFE_PORT_ID_INT5_MI2S_RX:
+ case AFE_PORT_ID_INT5_MI2S_TX:
+ case AFE_PORT_ID_INT6_MI2S_RX:
+ case AFE_PORT_ID_INT6_MI2S_TX:
cfg_type = AFE_PARAM_ID_I2S_CONFIG;
break;
case AFE_PORT_ID_PRIMARY_TDM_RX ... AFE_PORT_ID_QUINARY_TDM_TX_7:
diff --git a/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c b/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c
index e5cd82f77b55..c3d8116ad503 100644
--- a/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c
+++ b/sound/soc/qcom/qdsp6/q6dsp-lpass-ports.c
@@ -553,11 +553,15 @@ static struct snd_soc_dai_driver q6dsp_audio_fe_dais[] = {
Q6AFE_MI2S_RX_DAI("LPI RX2", LPI_MI2S_RX_2),
Q6AFE_MI2S_RX_DAI("LPI RX3", LPI_MI2S_RX_3),
Q6AFE_MI2S_RX_DAI("LPI RX4", LPI_MI2S_RX_4),
+ Q6AFE_MI2S_RX_DAI("LPI RX5", LPI_MI2S_RX_5),
+ Q6AFE_MI2S_RX_DAI("LPI RX6", LPI_MI2S_RX_6),
Q6AFE_MI2S_TX_DAI("LPI TX0", LPI_MI2S_TX_0),
Q6AFE_MI2S_TX_DAI("LPI TX1", LPI_MI2S_TX_1),
Q6AFE_MI2S_TX_DAI("LPI TX2", LPI_MI2S_TX_2),
Q6AFE_MI2S_TX_DAI("LPI TX3", LPI_MI2S_TX_3),
Q6AFE_MI2S_TX_DAI("LPI TX4", LPI_MI2S_TX_4),
+ Q6AFE_MI2S_TX_DAI("LPI TX5", LPI_MI2S_TX_5),
+ Q6AFE_MI2S_TX_DAI("LPI TX6", LPI_MI2S_TX_6),
Q6AFE_TDM_PB_DAI("Primary", 0, PRIMARY_TDM_RX_0),
Q6AFE_TDM_PB_DAI("Primary", 1, PRIMARY_TDM_RX_1),
Q6AFE_TDM_PB_DAI("Primary", 2, PRIMARY_TDM_RX_2),
@@ -712,6 +716,7 @@ struct snd_soc_dai_driver *q6dsp_audio_ports_set_config(struct device *dev,
case QUINARY_MI2S_RX ... QUINARY_MI2S_TX:
case PRIMARY_MI2S_RX ... QUATERNARY_MI2S_TX:
case LPI_MI2S_RX_0 ... LPI_MI2S_TX_4:
+ case LPI_MI2S_RX_5 ... LPI_MI2S_TX_6:
q6dsp_audio_fe_dais[i].ops = cfg->q6i2s_ops;
break;
case PRIMARY_TDM_RX_0 ... QUINARY_TDM_TX_7:
diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c
index 7386226046fa..d076c99f197f 100644
--- a/sound/soc/qcom/qdsp6/q6routing.c
+++ b/sound/soc/qcom/qdsp6/q6routing.c
@@ -127,7 +127,14 @@
{ mix_name, "TX_CODEC_DMA_TX_2", "TX_CODEC_DMA_TX_2"}, \
{ mix_name, "TX_CODEC_DMA_TX_3", "TX_CODEC_DMA_TX_3"}, \
{ mix_name, "TX_CODEC_DMA_TX_4", "TX_CODEC_DMA_TX_4"}, \
- { mix_name, "TX_CODEC_DMA_TX_5", "TX_CODEC_DMA_TX_5"}
+ { mix_name, "TX_CODEC_DMA_TX_5", "TX_CODEC_DMA_TX_5"}, \
+ { mix_name, "LPI_MI2S_TX_0", "LPI_MI2S_TX_0" }, \
+ { mix_name, "LPI_MI2S_TX_1", "LPI_MI2S_TX_1" }, \
+ { mix_name, "LPI_MI2S_TX_2", "LPI_MI2S_TX_2" }, \
+ { mix_name, "LPI_MI2S_TX_3", "LPI_MI2S_TX_3" }, \
+ { mix_name, "LPI_MI2S_TX_4", "LPI_MI2S_TX_4" }, \
+ { mix_name, "LPI_MI2S_TX_5", "LPI_MI2S_TX_5" }, \
+ { mix_name, "LPI_MI2S_TX_6", "LPI_MI2S_TX_6" }
#define Q6ROUTING_TX_MIXERS(id) \
SOC_SINGLE_EXT("PRI_MI2S_TX", PRIMARY_MI2S_TX, \
@@ -321,6 +328,27 @@
msm_routing_put_audio_mixer), \
SOC_SINGLE_EXT("TX_CODEC_DMA_TX_5", TX_CODEC_DMA_TX_5, \
id, 1, 0, msm_routing_get_audio_mixer, \
+ msm_routing_put_audio_mixer), \
+ SOC_SINGLE_EXT("LPI_MI2S_TX_0", LPI_MI2S_TX_0, \
+ id, 1, 0, msm_routing_get_audio_mixer, \
+ msm_routing_put_audio_mixer), \
+ SOC_SINGLE_EXT("LPI_MI2S_TX_1", LPI_MI2S_TX_1, \
+ id, 1, 0, msm_routing_get_audio_mixer, \
+ msm_routing_put_audio_mixer), \
+ SOC_SINGLE_EXT("LPI_MI2S_TX_2", LPI_MI2S_TX_2, \
+ id, 1, 0, msm_routing_get_audio_mixer, \
+ msm_routing_put_audio_mixer), \
+ SOC_SINGLE_EXT("LPI_MI2S_TX_3", LPI_MI2S_TX_3, \
+ id, 1, 0, msm_routing_get_audio_mixer, \
+ msm_routing_put_audio_mixer), \
+ SOC_SINGLE_EXT("LPI_MI2S_TX_4", LPI_MI2S_TX_4, \
+ id, 1, 0, msm_routing_get_audio_mixer, \
+ msm_routing_put_audio_mixer), \
+ SOC_SINGLE_EXT("LPI_MI2S_TX_5", LPI_MI2S_TX_5, \
+ id, 1, 0, msm_routing_get_audio_mixer, \
+ msm_routing_put_audio_mixer), \
+ SOC_SINGLE_EXT("LPI_MI2S_TX_6", LPI_MI2S_TX_6, \
+ id, 1, 0, msm_routing_get_audio_mixer, \
msm_routing_put_audio_mixer),
struct session_data {
@@ -709,6 +737,26 @@ static const struct snd_kcontrol_new rxcodec_dma_rx_6_mixer_controls[] = {
static const struct snd_kcontrol_new rx_codec_dma_rx_7_mixer_controls[] = {
Q6ROUTING_RX_MIXERS(RX_CODEC_DMA_RX_7) };
+static const struct snd_kcontrol_new lpi_mi2s_rx_0_mixer_controls[] = {
+ Q6ROUTING_RX_MIXERS(LPI_MI2S_RX_0) };
+
+static const struct snd_kcontrol_new lpi_mi2s_rx_1_mixer_controls[] = {
+ Q6ROUTING_RX_MIXERS(LPI_MI2S_RX_1) };
+
+static const struct snd_kcontrol_new lpi_mi2s_rx_2_mixer_controls[] = {
+ Q6ROUTING_RX_MIXERS(LPI_MI2S_RX_2) };
+
+static const struct snd_kcontrol_new lpi_mi2s_rx_3_mixer_controls[] = {
+ Q6ROUTING_RX_MIXERS(LPI_MI2S_RX_3) };
+
+static const struct snd_kcontrol_new lpi_mi2s_rx_4_mixer_controls[] = {
+ Q6ROUTING_RX_MIXERS(LPI_MI2S_RX_4) };
+
+static const struct snd_kcontrol_new lpi_mi2s_rx_5_mixer_controls[] = {
+ Q6ROUTING_RX_MIXERS(LPI_MI2S_RX_5) };
+
+static const struct snd_kcontrol_new lpi_mi2s_rx_6_mixer_controls[] = {
+ Q6ROUTING_RX_MIXERS(LPI_MI2S_RX_6) };
static const struct snd_kcontrol_new mmul1_mixer_controls[] = {
Q6ROUTING_TX_MIXERS(MSM_FRONTEND_DAI_MULTIMEDIA1) };
@@ -938,6 +986,27 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
SND_SOC_DAPM_MIXER("USB_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
usb_rx_mixer_controls,
ARRAY_SIZE(usb_rx_mixer_controls)),
+ SND_SOC_DAPM_MIXER("LPI_MI2S_RX_0 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ lpi_mi2s_rx_0_mixer_controls,
+ ARRAY_SIZE(lpi_mi2s_rx_0_mixer_controls)),
+ SND_SOC_DAPM_MIXER("LPI_MI2S_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ lpi_mi2s_rx_1_mixer_controls,
+ ARRAY_SIZE(lpi_mi2s_rx_1_mixer_controls)),
+ SND_SOC_DAPM_MIXER("LPI_MI2S_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ lpi_mi2s_rx_2_mixer_controls,
+ ARRAY_SIZE(lpi_mi2s_rx_2_mixer_controls)),
+ SND_SOC_DAPM_MIXER("LPI_MI2S_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ lpi_mi2s_rx_3_mixer_controls,
+ ARRAY_SIZE(lpi_mi2s_rx_3_mixer_controls)),
+ SND_SOC_DAPM_MIXER("LPI_MI2S_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ lpi_mi2s_rx_4_mixer_controls,
+ ARRAY_SIZE(lpi_mi2s_rx_4_mixer_controls)),
+ SND_SOC_DAPM_MIXER("LPI_MI2S_RX_5 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ lpi_mi2s_rx_5_mixer_controls,
+ ARRAY_SIZE(lpi_mi2s_rx_5_mixer_controls)),
+ SND_SOC_DAPM_MIXER("LPI_MI2S_RX_6 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ lpi_mi2s_rx_6_mixer_controls,
+ ARRAY_SIZE(lpi_mi2s_rx_6_mixer_controls)),
SND_SOC_DAPM_MIXER("MultiMedia1 Mixer", SND_SOC_NOPM, 0, 0,
mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)),
SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0,
@@ -1031,6 +1100,13 @@ static const struct snd_soc_dapm_route intercon[] = {
Q6ROUTING_RX_DAPM_ROUTE("RX_CODEC_DMA_RX_6 Audio Mixer", "RX_CODEC_DMA_RX_6"),
Q6ROUTING_RX_DAPM_ROUTE("RX_CODEC_DMA_RX_7 Audio Mixer", "RX_CODEC_DMA_RX_7"),
Q6ROUTING_RX_DAPM_ROUTE("USB_RX Audio Mixer", "USB_RX"),
+ Q6ROUTING_RX_DAPM_ROUTE("LPI_MI2S_RX_0 Audio Mixer", "LPI_MI2S_RX_0"),
+ Q6ROUTING_RX_DAPM_ROUTE("LPI_MI2S_RX_1 Audio Mixer", "LPI_MI2S_RX_1"),
+ Q6ROUTING_RX_DAPM_ROUTE("LPI_MI2S_RX_2 Audio Mixer", "LPI_MI2S_RX_2"),
+ Q6ROUTING_RX_DAPM_ROUTE("LPI_MI2S_RX_3 Audio Mixer", "LPI_MI2S_RX_3"),
+ Q6ROUTING_RX_DAPM_ROUTE("LPI_MI2S_RX_4 Audio Mixer", "LPI_MI2S_RX_4"),
+ Q6ROUTING_RX_DAPM_ROUTE("LPI_MI2S_RX_5 Audio Mixer", "LPI_MI2S_RX_5"),
+ Q6ROUTING_RX_DAPM_ROUTE("LPI_MI2S_RX_6 Audio Mixer", "LPI_MI2S_RX_6"),
Q6ROUTING_TX_DAPM_ROUTE("MultiMedia1 Mixer"),
Q6ROUTING_TX_DAPM_ROUTE("MultiMedia2 Mixer"),
Q6ROUTING_TX_DAPM_ROUTE("MultiMedia3 Mixer"),
diff --git a/sound/soc/qcom/sm8250.c b/sound/soc/qcom/sm8250.c
index f193d0ba63d0..76dc3a3f4a31 100644
--- a/sound/soc/qcom/sm8250.c
+++ b/sound/soc/qcom/sm8250.c
@@ -112,6 +112,22 @@ static int sm8250_snd_startup(struct snd_pcm_substream *substream)
snd_soc_dai_set_fmt(cpu_dai, fmt);
snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
break;
+ case LPI_MI2S_RX_0:
+ codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S;
+ snd_soc_dai_set_sysclk(cpu_dai,
+ Q6AFE_LPASS_CLK_ID_INT0_MI2S_IBIT,
+ MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
+ snd_soc_dai_set_fmt(cpu_dai, fmt);
+ snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
+ break;
+ case LPI_MI2S_TX_3:
+ codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S;
+ snd_soc_dai_set_sysclk(cpu_dai,
+ Q6AFE_LPASS_CLK_ID_INT3_MI2S_IBIT,
+ MI2S_BCLK_RATE, SNDRV_PCM_STREAM_CAPTURE);
+ snd_soc_dai_set_fmt(cpu_dai, fmt);
+ snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt);
+ break;
default:
break;
}
@@ -194,6 +210,7 @@ static const struct of_device_id snd_sm8250_dt_match[] = {
{ .compatible = "qcom,qrb2210-sndcard", .data = "qcm2290" },
{ .compatible = "qcom,qrb4210-rb2-sndcard", .data = "sm4250" },
{ .compatible = "qcom,qrb5165-rb5-sndcard", .data = "sm8250" },
+ { .compatible = "qcom,sdm660-sndcard", .data = "sdm660" },
{ .compatible = "qcom,sm8250-sndcard", .data = "sm8250" },
{}
};