2018-11-24 11:11:00

by Cheng-Yi Chiang

[permalink] [raw]
Subject: [PATCH 1/4] ASoC: qcom: sdm845: Add board specific dapm widgets

Add board specific dapm widgets so these widgets can be used
in the route.

Signed-off-by: Rohit kumar <[email protected]>
Signed-off-by: Cheng-Yi Chiang <[email protected]>
---
sound/soc/qcom/sdm845.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c
index 58593db2ab151..95d8d4422dae0 100644
--- a/sound/soc/qcom/sdm845.c
+++ b/sound/soc/qcom/sdm845.c
@@ -212,6 +212,14 @@ static int sdm845_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
return 0;
}

+static const struct snd_soc_dapm_widget sdm845_snd_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_SPK("Left Spk", NULL),
+ SND_SOC_DAPM_SPK("Right Spk", NULL),
+ SND_SOC_DAPM_MIC("Int Mic", NULL),
+};
+
static void sdm845_add_be_ops(struct snd_soc_card *card)
{
struct snd_soc_dai_link *link;
@@ -243,6 +251,8 @@ static int sdm845_snd_platform_probe(struct platform_device *pdev)
goto data_alloc_fail;
}

+ card->dapm_widgets = sdm845_snd_widgets;
+ card->num_dapm_widgets = ARRAY_SIZE(sdm845_snd_widgets);
card->dev = dev;
dev_set_drvdata(dev, card);
ret = qcom_snd_parse_of(card);
--
2.20.0.rc0.387.gc7a69e6b6c-goog



2018-11-24 11:11:09

by Cheng-Yi Chiang

[permalink] [raw]
Subject: [PATCH 2/4] ASoC: qcom: sdm845: Create and setup jack in init callback

Add a callback for init ops on dai_link to create and setup jack.

Signed-off-by: Rohit kumar <[email protected]>
Signed-off-by: Cheng-Yi Chiang <[email protected]>
---
sound/soc/qcom/sdm845.c | 57 +++++++++++++++++++++++++++++++++++++++--
1 file changed, 55 insertions(+), 2 deletions(-)

diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c
index 95d8d4422dae0..43c03f8e8cdc2 100644
--- a/sound/soc/qcom/sdm845.c
+++ b/sound/soc/qcom/sdm845.c
@@ -8,6 +8,8 @@
#include <linux/of_device.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
+#include <sound/jack.h>
+#include <uapi/linux/input-event-codes.h>
#include "common.h"
#include "qdsp6/q6afe.h"

@@ -17,6 +19,8 @@
#define MI2S_BCLK_RATE 1536000

struct sdm845_snd_data {
+ struct snd_soc_jack jack;
+ bool jack_setup;
struct snd_soc_card *card;
uint32_t pri_mi2s_clk_count;
uint32_t sec_mi2s_clk_count;
@@ -100,6 +104,54 @@ static int sdm845_snd_hw_params(struct snd_pcm_substream *substream,
return ret;
}

+static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_component *component;
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
+ struct snd_soc_card *card = rtd->card;
+ struct sdm845_snd_data *pdata = snd_soc_card_get_drvdata(card);
+ int i, rval;
+
+ if (!pdata->jack_setup) {
+ struct snd_jack *jack;
+
+ rval = snd_soc_card_jack_new(card, "Headset Jack",
+ SND_JACK_HEADSET |
+ SND_JACK_HEADPHONE |
+ SND_JACK_BTN_0 | SND_JACK_BTN_1 |
+ SND_JACK_BTN_2 | SND_JACK_BTN_3,
+ &pdata->jack, NULL, 0);
+
+ if (rval < 0) {
+ dev_err(card->dev, "Unable to add Headphone Jack\n");
+ return rval;
+ }
+
+ jack = pdata->jack.jack;
+
+ snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
+ snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
+ snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
+ snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
+ pdata->jack_setup = true;
+ }
+
+ for (i = 0 ; i < dai_link->num_codecs; i++) {
+ struct snd_soc_dai *dai = rtd->codec_dais[i];
+
+ component = dai->component;
+ rval = snd_soc_component_set_jack(
+ component, &pdata->jack, NULL);
+ if (rval != 0 && rval != -ENOTSUPP) {
+ dev_warn(card->dev, "Failed to set jack: %d\n", rval);
+ return rval;
+ }
+ }
+
+ return 0;
+}
+
+
static int sdm845_snd_startup(struct snd_pcm_substream *substream)
{
unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
@@ -220,7 +272,7 @@ static const struct snd_soc_dapm_widget sdm845_snd_widgets[] = {
SND_SOC_DAPM_MIC("Int Mic", NULL),
};

-static void sdm845_add_be_ops(struct snd_soc_card *card)
+static void sdm845_add_ops(struct snd_soc_card *card)
{
struct snd_soc_dai_link *link;
int i;
@@ -230,6 +282,7 @@ static void sdm845_add_be_ops(struct snd_soc_card *card)
link->ops = &sdm845_be_ops;
link->be_hw_params_fixup = sdm845_be_hw_params_fixup;
}
+ link->init = sdm845_dai_init;
}
}

@@ -264,7 +317,7 @@ static int sdm845_snd_platform_probe(struct platform_device *pdev)
data->card = card;
snd_soc_card_set_drvdata(card, data);

- sdm845_add_be_ops(card);
+ sdm845_add_ops(card);
ret = snd_soc_register_card(card);
if (ret) {
dev_err(dev, "Sound card registration failed\n");
--
2.20.0.rc0.387.gc7a69e6b6c-goog


2018-11-24 11:11:27

by Cheng-Yi Chiang

[permalink] [raw]
Subject: [PATCH 3/4] ASoC: qcom: sdm845: Add codec related configuration for sdm845

Set TDM time slots and DAI format for speaker codec.
Set DAI format and clock for headset.

Signed-off-by: Rohit kumar <[email protected]>
Signed-off-by: Cheng-Yi Chiang <[email protected]>
---
sound/soc/qcom/sdm845.c | 82 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 81 insertions(+), 1 deletion(-)

diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c
index 43c03f8e8cdc2..d815040e98dc9 100644
--- a/sound/soc/qcom/sdm845.c
+++ b/sound/soc/qcom/sdm845.c
@@ -6,12 +6,15 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
+#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/jack.h>
+#include <sound/soc.h>
#include <uapi/linux/input-event-codes.h>
#include "common.h"
#include "qdsp6/q6afe.h"
+#include "../codecs/rt5663.h"

#define DEFAULT_SAMPLE_RATE_48K 48000
#define DEFAULT_MCLK_RATE 24576000
@@ -34,7 +37,7 @@ static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- int ret = 0;
+ int ret = 0, j;
int channels, slot_width;

switch (params_format(params)) {
@@ -81,6 +84,31 @@ static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream,
goto end;
}
}
+
+ for (j = 0; j < rtd->num_codecs; j++) {
+ struct snd_soc_dai *codec_dai = rtd->codec_dais[j];
+
+ if (!strcmp(codec_dai->component->name_prefix, "Left")) {
+ ret = snd_soc_dai_set_tdm_slot(
+ codec_dai, 0x30, 0x3, 8, slot_width);
+ if (ret < 0) {
+ dev_err(rtd->dev,
+ "DEV0 TDM slot err:%d\n", ret);
+ return ret;
+ }
+ }
+
+ if (!strcmp(codec_dai->component->name_prefix, "Right")) {
+ ret = snd_soc_dai_set_tdm_slot(
+ codec_dai, 0xC0, 0x3, 8, slot_width);
+ if (ret < 0) {
+ dev_err(rtd->dev,
+ "DEV1 TDM slot err:%d\n", ret);
+ return ret;
+ }
+ }
+ }
+
end:
return ret;
}
@@ -90,9 +118,26 @@ static int sdm845_snd_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
int ret = 0;

switch (cpu_dai->id) {
+ case PRIMARY_MI2S_RX:
+ case PRIMARY_MI2S_TX:
+ /*
+ * Use ASRC for internal clocks, as PLL rate isn't multiple
+ * of BCLK.
+ */
+ rt5663_sel_asrc_clk_src(
+ codec_dai->component,
+ RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER,
+ RT5663_CLK_SEL_I2S1_ASRC);
+ ret = snd_soc_dai_set_sysclk(codec_dai,
+ RT5663_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN);
+ if (ret < 0)
+ dev_err(rtd->dev,
+ "snd_soc_dai_set_sysclk err = %d\n", ret);
+ break;
case QUATERNARY_TDM_RX_0:
case QUATERNARY_TDM_TX_0:
ret = sdm845_tdm_snd_hw_params(substream, params);
@@ -155,14 +200,20 @@ static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd)
static int sdm845_snd_startup(struct snd_pcm_substream *substream)
{
unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
+ unsigned int codec_dai_fmt = SND_SOC_DAIFMT_CBS_CFS;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_card *card = rtd->card;
struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card);
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+
+ int j;
+ int ret;

switch (cpu_dai->id) {
case PRIMARY_MI2S_RX:
case PRIMARY_MI2S_TX:
+ codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF;
if (++(data->pri_mi2s_clk_count) == 1) {
snd_soc_dai_set_sysclk(cpu_dai,
Q6AFE_LPASS_CLK_ID_MCLK_1,
@@ -172,6 +223,7 @@ static int sdm845_snd_startup(struct snd_pcm_substream *substream)
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 SECONDARY_MI2S_TX:
@@ -190,6 +242,34 @@ static int sdm845_snd_startup(struct snd_pcm_substream *substream)
Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT,
TDM_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
}
+
+ codec_dai_fmt |= SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_DSP_B;
+
+ for (j = 0; j < rtd->num_codecs; j++) {
+ codec_dai = rtd->codec_dais[j];
+
+ if (!strcmp(codec_dai->component->name_prefix,
+ "Left")) {
+ ret = snd_soc_dai_set_fmt(
+ codec_dai, codec_dai_fmt);
+ if (ret < 0) {
+ dev_err(rtd->dev,
+ "Left TDM fmt err:%d\n", ret);
+ return ret;
+ }
+ }
+
+ if (!strcmp(codec_dai->component->name_prefix,
+ "Right")) {
+ ret = snd_soc_dai_set_fmt(
+ codec_dai, codec_dai_fmt);
+ if (ret < 0) {
+ dev_err(rtd->dev,
+ "Right TDM slot err:%d\n", ret);
+ return ret;
+ }
+ }
+ }
break;

default:
--
2.20.0.rc0.387.gc7a69e6b6c-goog


2018-11-24 11:12:17

by Cheng-Yi Chiang

[permalink] [raw]
Subject: [PATCH 4/4] ASoC: qcom: Kconfig: select config for codec

Select SND_SOC_RT5663 and SND_SOC_MAX98927 for SND_SOC_SDM845.

Signed-off-by: Rohit kumar <[email protected]>
Signed-off-by: Cheng-Yi Chiang <[email protected]>
---
sound/soc/qcom/Kconfig | 2 ++
1 file changed, 2 insertions(+)

diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
index 2a4c912d1e484..3528c4279cbae 100644
--- a/sound/soc/qcom/Kconfig
+++ b/sound/soc/qcom/Kconfig
@@ -100,6 +100,8 @@ config SND_SOC_SDM845
depends on QCOM_APR
select SND_SOC_QDSP6
select SND_SOC_QCOM_COMMON
+ select SND_SOC_RT5663
+ select SND_SOC_MAX98927
help
To add support for audio on Qualcomm Technologies Inc.
SDM845 SoC-based systems.
--
2.20.0.rc0.387.gc7a69e6b6c-goog


2018-11-27 09:18:23

by Srinivas Kandagatla

[permalink] [raw]
Subject: Re: [alsa-devel] [PATCH 1/4] ASoC: qcom: sdm845: Add board specific dapm widgets



On 24/11/18 11:09, Cheng-Yi Chiang wrote:
> Add board specific dapm widgets so these widgets can be used
> in the route.
>
> Signed-off-by: Rohit kumar <[email protected]>
> Signed-off-by: Cheng-Yi Chiang <[email protected]>

Acked-by: Srinivas Kandagatla <[email protected]>

> ---
> sound/soc/qcom/sdm845.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c
> index 58593db2ab151..95d8d4422dae0 100644
> --- a/sound/soc/qcom/sdm845.c
> +++ b/sound/soc/qcom/sdm845.c
> @@ -212,6 +212,14 @@ static int sdm845_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
> return 0;
> }
>
> +static const struct snd_soc_dapm_widget sdm845_snd_widgets[] = {
> + SND_SOC_DAPM_HP("Headphone Jack", NULL),
> + SND_SOC_DAPM_MIC("Headset Mic", NULL),
> + SND_SOC_DAPM_SPK("Left Spk", NULL),
> + SND_SOC_DAPM_SPK("Right Spk", NULL),
> + SND_SOC_DAPM_MIC("Int Mic", NULL),
> +};
> +
> static void sdm845_add_be_ops(struct snd_soc_card *card)
> {
> struct snd_soc_dai_link *link;
> @@ -243,6 +251,8 @@ static int sdm845_snd_platform_probe(struct platform_device *pdev)
> goto data_alloc_fail;
> }
>
> + card->dapm_widgets = sdm845_snd_widgets;
> + card->num_dapm_widgets = ARRAY_SIZE(sdm845_snd_widgets);
> card->dev = dev;
> dev_set_drvdata(dev, card);
> ret = qcom_snd_parse_of(card);
>

2018-11-27 09:19:05

by Srinivas Kandagatla

[permalink] [raw]
Subject: Re: [alsa-devel] [PATCH 4/4] ASoC: qcom: Kconfig: select config for codec



On 24/11/18 11:09, Cheng-Yi Chiang wrote:
> Select SND_SOC_RT5663 and SND_SOC_MAX98927 for SND_SOC_SDM845.
>
> Signed-off-by: Rohit kumar <[email protected]>
> Signed-off-by: Cheng-Yi Chiang <[email protected]>

Acked-by: Srinivas Kandagatla <[email protected]>

> ---
> sound/soc/qcom/Kconfig | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
> index 2a4c912d1e484..3528c4279cbae 100644
> --- a/sound/soc/qcom/Kconfig
> +++ b/sound/soc/qcom/Kconfig
> @@ -100,6 +100,8 @@ config SND_SOC_SDM845
> depends on QCOM_APR
> select SND_SOC_QDSP6
> select SND_SOC_QCOM_COMMON
> + select SND_SOC_RT5663
> + select SND_SOC_MAX98927
> help
> To add support for audio on Qualcomm Technologies Inc.
> SDM845 SoC-based systems.
>

2018-11-27 09:20:03

by Srinivas Kandagatla

[permalink] [raw]
Subject: Re: [alsa-devel] [PATCH 2/4] ASoC: qcom: sdm845: Create and setup jack in init callback



On 24/11/18 11:09, Cheng-Yi Chiang wrote:
> Add a callback for init ops on dai_link to create and setup jack.
>
> Signed-off-by: Rohit kumar <[email protected]>
> Signed-off-by: Cheng-Yi Chiang <[email protected]>

Acked-by: Srinivas Kandagatla <[email protected]>

> ---
> sound/soc/qcom/sdm845.c | 57 +++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 55 insertions(+), 2 deletions(-)
>
> diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c
> index 95d8d4422dae0..43c03f8e8cdc2 100644
> --- a/sound/soc/qcom/sdm845.c
> +++ b/sound/soc/qcom/sdm845.c
> @@ -8,6 +8,8 @@
> #include <linux/of_device.h>
> #include <sound/pcm.h>
> #include <sound/pcm_params.h>
> +#include <sound/jack.h>
> +#include <uapi/linux/input-event-codes.h>
> #include "common.h"
> #include "qdsp6/q6afe.h"
>
> @@ -17,6 +19,8 @@
> #define MI2S_BCLK_RATE 1536000
>
> struct sdm845_snd_data {
> + struct snd_soc_jack jack;
> + bool jack_setup;
> struct snd_soc_card *card;
> uint32_t pri_mi2s_clk_count;
> uint32_t sec_mi2s_clk_count;
> @@ -100,6 +104,54 @@ static int sdm845_snd_hw_params(struct snd_pcm_substream *substream,
> return ret;
> }
>
> +static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd)
> +{
> + struct snd_soc_component *component;
> + struct snd_soc_dai_link *dai_link = rtd->dai_link;
> + struct snd_soc_card *card = rtd->card;
> + struct sdm845_snd_data *pdata = snd_soc_card_get_drvdata(card);
> + int i, rval;
> +
> + if (!pdata->jack_setup) {
> + struct snd_jack *jack;
> +
> + rval = snd_soc_card_jack_new(card, "Headset Jack",
> + SND_JACK_HEADSET |
> + SND_JACK_HEADPHONE |
> + SND_JACK_BTN_0 | SND_JACK_BTN_1 |
> + SND_JACK_BTN_2 | SND_JACK_BTN_3,
> + &pdata->jack, NULL, 0);
> +
> + if (rval < 0) {
> + dev_err(card->dev, "Unable to add Headphone Jack\n");
> + return rval;
> + }
> +
> + jack = pdata->jack.jack;
> +
> + snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
> + snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
> + snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
> + snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
> + pdata->jack_setup = true;
> + }
> +
> + for (i = 0 ; i < dai_link->num_codecs; i++) {
> + struct snd_soc_dai *dai = rtd->codec_dais[i];
> +
> + component = dai->component;
> + rval = snd_soc_component_set_jack(
> + component, &pdata->jack, NULL);
> + if (rval != 0 && rval != -ENOTSUPP) {
> + dev_warn(card->dev, "Failed to set jack: %d\n", rval);
> + return rval;
> + }
> + }
> +
> + return 0;
> +}
> +
> +
> static int sdm845_snd_startup(struct snd_pcm_substream *substream)
> {
> unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
> @@ -220,7 +272,7 @@ static const struct snd_soc_dapm_widget sdm845_snd_widgets[] = {
> SND_SOC_DAPM_MIC("Int Mic", NULL),
> };
>
> -static void sdm845_add_be_ops(struct snd_soc_card *card)
> +static void sdm845_add_ops(struct snd_soc_card *card)
> {
> struct snd_soc_dai_link *link;
> int i;
> @@ -230,6 +282,7 @@ static void sdm845_add_be_ops(struct snd_soc_card *card)
> link->ops = &sdm845_be_ops;
> link->be_hw_params_fixup = sdm845_be_hw_params_fixup;
> }
> + link->init = sdm845_dai_init;
> }
> }
>
> @@ -264,7 +317,7 @@ static int sdm845_snd_platform_probe(struct platform_device *pdev)
> data->card = card;
> snd_soc_card_set_drvdata(card, data);
>
> - sdm845_add_be_ops(card);
> + sdm845_add_ops(card);
> ret = snd_soc_register_card(card);
> if (ret) {
> dev_err(dev, "Sound card registration failed\n");
>

2018-11-27 09:34:09

by Srinivas Kandagatla

[permalink] [raw]
Subject: Re: [alsa-devel] [PATCH 3/4] ASoC: qcom: sdm845: Add codec related configuration for sdm845

Thanks for the patch Jimmy,

On 24/11/18 11:09, Cheng-Yi Chiang wrote:
> Set TDM time slots and DAI format for speaker codec.
> Set DAI format and clock for headset. >
> Signed-off-by: Rohit kumar <[email protected]>
> Signed-off-by: Cheng-Yi Chiang <[email protected]>

Overall the patch looks good for me, but this needs to be split into two
patches + few more minor nits!
> ---
> sound/soc/qcom/sdm845.c | 82 ++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 81 insertions(+), 1 deletion(-)
>
> diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c
> index 43c03f8e8cdc2..d815040e98dc9 100644
> --- a/sound/soc/qcom/sdm845.c
> +++ b/sound/soc/qcom/sdm845.c
> @@ -6,12 +6,15 @@
> #include <linux/module.h>
> #include <linux/platform_device.h>
> #include <linux/of_device.h>
> +#include <sound/core.h>
> #include <sound/pcm.h>
> #include <sound/pcm_params.h>
> #include <sound/jack.h>
> +#include <sound/soc.h>
> #include <uapi/linux/input-event-codes.h>
> #include "common.h"
> #include "qdsp6/q6afe.h"
> +#include "../codecs/rt5663.h"
>
> #define DEFAULT_SAMPLE_RATE_48K 48000
> #define DEFAULT_MCLK_RATE 24576000
> @@ -34,7 +37,7 @@ static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream,
> {
> struct snd_soc_pcm_runtime *rtd = substream->private_data;
> struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
> - int ret = 0;
> + int ret = 0, j;
> int channels, slot_width;
>
> switch (params_format(params)) {
> @@ -81,6 +84,31 @@ static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream,
> goto end;
> }
> }
> +
> + for (j = 0; j < rtd->num_codecs; j++) {
> + struct snd_soc_dai *codec_dai = rtd->codec_dais[j];
> +
> + if (!strcmp(codec_dai->component->name_prefix, "Left")) {
> + ret = snd_soc_dai_set_tdm_slot(
> + codec_dai, 0x30, 0x3, 8, slot_width);

These constants needs some kind of defines to make the code more readable!

> + if (ret < 0) {
> + dev_err(rtd->dev,
> + "DEV0 TDM slot err:%d\n", ret);
> + return ret;
> + }
> + }
> +
> + if (!strcmp(codec_dai->component->name_prefix, "Right")) {
> + ret = snd_soc_dai_set_tdm_slot(
> + codec_dai, 0xC0, 0x3, 8, slot_width);
> + if (ret < 0) {
> + dev_err(rtd->dev,
> + "DEV1 TDM slot err:%d\n", ret);
> + return ret;
> + }
> + }
> + }
> +
> end:
> return ret;
> }
> @@ -90,9 +118,26 @@ static int sdm845_snd_hw_params(struct snd_pcm_substream *substream,
> {
> struct snd_soc_pcm_runtime *rtd = substream->private_data;
> struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
> + struct snd_soc_dai *codec_dai = rtd->codec_dai;
> int ret = 0;
>
> switch (cpu_dai->id) {
> + case PRIMARY_MI2S_RX:
> + case PRIMARY_MI2S_TX:
> + /*
> + * Use ASRC for internal clocks, as PLL rate isn't multiple
> + * of BCLK.
> + */
> + rt5663_sel_asrc_clk_src(
> + codec_dai->component,
> + RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER,
> + RT5663_CLK_SEL_I2S1_ASRC);
> + ret = snd_soc_dai_set_sysclk(codec_dai,
> + RT5663_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN);

Use DEFAULT_MCLK_RATE here.


> + if (ret < 0)
> + dev_err(rtd->dev,
> + "snd_soc_dai_set_sysclk err = %d\n", ret);
> + break;
> case QUATERNARY_TDM_RX_0:
> case QUATERNARY_TDM_TX_0:
> ret = sdm845_tdm_snd_hw_params(substream, params);
> @@ -155,14 +200,20 @@ static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd)
> static int sdm845_snd_startup(struct snd_pcm_substream *substream)
> {
> unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
> + unsigned int codec_dai_fmt = SND_SOC_DAIFMT_CBS_CFS;
> struct snd_soc_pcm_runtime *rtd = substream->private_data;
> struct snd_soc_card *card = rtd->card;
> struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card);
> struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
> + struct snd_soc_dai *codec_dai = rtd->codec_dai;
> +
Unnecessary New line here.

> + int j;
> + int ret;
>
> switch (cpu_dai->id) {
> case PRIMARY_MI2S_RX:
> case PRIMARY_MI2S_TX:
> + codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF;
> if (++(data->pri_mi2s_clk_count) == 1) {
> snd_soc_dai_set_sysclk(cpu_dai,
> Q6AFE_LPASS_CLK_ID_MCLK_1,
> @@ -172,6 +223,7 @@ static int sdm845_snd_startup(struct snd_pcm_substream *substream)
> 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 SECONDARY_MI2S_TX:
> @@ -190,6 +242,34 @@ static int sdm845_snd_startup(struct snd_pcm_substream *substream)
> Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT,
> TDM_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
> }
> +
> + codec_dai_fmt |= SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_DSP_B;
> +
> + for (j = 0; j < rtd->num_codecs; j++) {
> + codec_dai = rtd->codec_dais[j];
> +
> + if (!strcmp(codec_dai->component->name_prefix,
> + "Left")) {
> + ret = snd_soc_dai_set_fmt(
> + codec_dai, codec_dai_fmt);
> + if (ret < 0) {
> + dev_err(rtd->dev,
> + "Left TDM fmt err:%d\n", ret);
> + return ret;
> + }
> + }
> +
> + if (!strcmp(codec_dai->component->name_prefix,
> + "Right")) {
> + ret = snd_soc_dai_set_fmt(
> + codec_dai, codec_dai_fmt);
> + if (ret < 0) {
> + dev_err(rtd->dev,
> + "Right TDM slot err:%d\n", ret);
> + return ret;
> + }
> + }
> + }
> break;
>
> default:
>

2018-11-28 11:02:29

by Cheng-Yi Chiang

[permalink] [raw]
Subject: Re: [alsa-devel] [PATCH 3/4] ASoC: qcom: sdm845: Add codec related configuration for sdm845

On Tue, Nov 27, 2018 at 5:32 PM Srinivas Kandagatla
<[email protected]> wrote:
>
> Thanks for the patch Jimmy,
>
Hi Srini,
Thanks for the review!
I have updated the patch series in v2.

> On 24/11/18 11:09, Cheng-Yi Chiang wrote:
> > Set TDM time slots and DAI format for speaker codec.
> > Set DAI format and clock for headset. >
> > Signed-off-by: Rohit kumar <[email protected]>
> > Signed-off-by: Cheng-Yi Chiang <[email protected]>
>
> Overall the patch looks good for me, but this needs to be split into two
> patches + few more minor nits!
Separated for speaker and headset in v2.
> > ---
> > sound/soc/qcom/sdm845.c | 82 ++++++++++++++++++++++++++++++++++++++++-
> > 1 file changed, 81 insertions(+), 1 deletion(-)
> >
> > diff --git a/sound/soc/qcom/sdm845.c b/sound/soc/qcom/sdm845.c
> > index 43c03f8e8cdc2..d815040e98dc9 100644
> > --- a/sound/soc/qcom/sdm845.c
> > +++ b/sound/soc/qcom/sdm845.c
> > @@ -6,12 +6,15 @@
> > #include <linux/module.h>
> > #include <linux/platform_device.h>
> > #include <linux/of_device.h>
> > +#include <sound/core.h>
> > #include <sound/pcm.h>
> > #include <sound/pcm_params.h>
> > #include <sound/jack.h>
> > +#include <sound/soc.h>
> > #include <uapi/linux/input-event-codes.h>
> > #include "common.h"
> > #include "qdsp6/q6afe.h"
> > +#include "../codecs/rt5663.h"
> >
> > #define DEFAULT_SAMPLE_RATE_48K 48000
> > #define DEFAULT_MCLK_RATE 24576000
> > @@ -34,7 +37,7 @@ static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream,
> > {
> > struct snd_soc_pcm_runtime *rtd = substream->private_data;
> > struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
> > - int ret = 0;
> > + int ret = 0, j;
> > int channels, slot_width;
> >
> > switch (params_format(params)) {
> > @@ -81,6 +84,31 @@ static int sdm845_tdm_snd_hw_params(struct snd_pcm_substream *substream,
> > goto end;
> > }
> > }
> > +
> > + for (j = 0; j < rtd->num_codecs; j++) {
> > + struct snd_soc_dai *codec_dai = rtd->codec_dais[j];
> > +
> > + if (!strcmp(codec_dai->component->name_prefix, "Left")) {
> > + ret = snd_soc_dai_set_tdm_slot(
> > + codec_dai, 0x30, 0x3, 8, slot_width);
>
> These constants needs some kind of defines to make the code more readable!
Fixed in v2.
>
> > + if (ret < 0) {
> > + dev_err(rtd->dev,
> > + "DEV0 TDM slot err:%d\n", ret);
> > + return ret;
> > + }
> > + }
> > +
> > + if (!strcmp(codec_dai->component->name_prefix, "Right")) {
> > + ret = snd_soc_dai_set_tdm_slot(
> > + codec_dai, 0xC0, 0x3, 8, slot_width);
> > + if (ret < 0) {
> > + dev_err(rtd->dev,
> > + "DEV1 TDM slot err:%d\n", ret);
> > + return ret;
> > + }
> > + }
> > + }
> > +
> > end:
> > return ret;
> > }
> > @@ -90,9 +118,26 @@ static int sdm845_snd_hw_params(struct snd_pcm_substream *substream,
> > {
> > struct snd_soc_pcm_runtime *rtd = substream->private_data;
> > struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
> > + struct snd_soc_dai *codec_dai = rtd->codec_dai;
> > int ret = 0;
> >
> > switch (cpu_dai->id) {
> > + case PRIMARY_MI2S_RX:
> > + case PRIMARY_MI2S_TX:
> > + /*
> > + * Use ASRC for internal clocks, as PLL rate isn't multiple
> > + * of BCLK.
> > + */
> > + rt5663_sel_asrc_clk_src(
> > + codec_dai->component,
> > + RT5663_DA_STEREO_FILTER | RT5663_AD_STEREO_FILTER,
> > + RT5663_CLK_SEL_I2S1_ASRC);
> > + ret = snd_soc_dai_set_sysclk(codec_dai,
> > + RT5663_SCLK_S_MCLK, 24576000, SND_SOC_CLOCK_IN);
>
> Use DEFAULT_MCLK_RATE here.
Fixed in v2.
>
>
> > + if (ret < 0)
> > + dev_err(rtd->dev,
> > + "snd_soc_dai_set_sysclk err = %d\n", ret);
> > + break;
> > case QUATERNARY_TDM_RX_0:
> > case QUATERNARY_TDM_TX_0:
> > ret = sdm845_tdm_snd_hw_params(substream, params);
> > @@ -155,14 +200,20 @@ static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd)
> > static int sdm845_snd_startup(struct snd_pcm_substream *substream)
> > {
> > unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
> > + unsigned int codec_dai_fmt = SND_SOC_DAIFMT_CBS_CFS;
> > struct snd_soc_pcm_runtime *rtd = substream->private_data;
> > struct snd_soc_card *card = rtd->card;
> > struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card);
> > struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
> > + struct snd_soc_dai *codec_dai = rtd->codec_dai;
> > +
> Unnecessary New line here.
Fixed in v2.
>
> > + int j;
> > + int ret;
> >
> > switch (cpu_dai->id) {
> > case PRIMARY_MI2S_RX:
> > case PRIMARY_MI2S_TX:
> > + codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF;
> > if (++(data->pri_mi2s_clk_count) == 1) {
> > snd_soc_dai_set_sysclk(cpu_dai,
> > Q6AFE_LPASS_CLK_ID_MCLK_1,
> > @@ -172,6 +223,7 @@ static int sdm845_snd_startup(struct snd_pcm_substream *substream)
> > 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 SECONDARY_MI2S_TX:
> > @@ -190,6 +242,34 @@ static int sdm845_snd_startup(struct snd_pcm_substream *substream)
> > Q6AFE_LPASS_CLK_ID_QUAD_TDM_IBIT,
> > TDM_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK);
> > }
> > +
> > + codec_dai_fmt |= SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_DSP_B;
> > +
> > + for (j = 0; j < rtd->num_codecs; j++) {
> > + codec_dai = rtd->codec_dais[j];
> > +
> > + if (!strcmp(codec_dai->component->name_prefix,
> > + "Left")) {
> > + ret = snd_soc_dai_set_fmt(
> > + codec_dai, codec_dai_fmt);
> > + if (ret < 0) {
> > + dev_err(rtd->dev,
> > + "Left TDM fmt err:%d\n", ret);
> > + return ret;
> > + }
> > + }
> > +
> > + if (!strcmp(codec_dai->component->name_prefix,
> > + "Right")) {
> > + ret = snd_soc_dai_set_fmt(
> > + codec_dai, codec_dai_fmt);
> > + if (ret < 0) {
> > + dev_err(rtd->dev,
> > + "Right TDM slot err:%d\n", ret);
> > + return ret;
> > + }
> > + }
> > + }
> > break;
> >
> > default:
> >