Skip to content

Commit 242b5bf

Browse files
ChiYuan Huanggregkh
authored andcommitted
ASoC: codecs: rtq9128: Fix TDM enable and DAI format control flow
[ Upstream commit 415d10c ] To enable TDM mode, the current control flow limits the function calling order should be 'set_tdm_slot->set_dai_fmt'. But not all platform sound card like as simeple card to follow this design. To bypass this limit, adjust the DAI format setting in runtime 'hw_param' callback. Signed-off-by: ChiYuan Huang <[email protected]> Link: https://msgid.link/r/c4c8df00d8d179b8b5b39a8521de3a85325c57e8.1703813842.git.cy_huang@richtek.com Signed-off-by: Mark Brown <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 2c272ff commit 242b5bf

File tree

1 file changed

+36
-31
lines changed

1 file changed

+36
-31
lines changed

sound/soc/codecs/rtq9128.c

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959

6060
struct rtq9128_data {
6161
struct gpio_desc *enable;
62+
unsigned int daifmt;
6263
int tdm_slots;
6364
int tdm_slot_width;
6465
bool tdm_input_data2_select;
@@ -441,10 +442,7 @@ static const struct snd_soc_component_driver rtq9128_comp_driver = {
441442
static int rtq9128_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
442443
{
443444
struct rtq9128_data *data = snd_soc_dai_get_drvdata(dai);
444-
struct snd_soc_component *comp = dai->component;
445445
struct device *dev = dai->dev;
446-
unsigned int audfmt, fmtval;
447-
int ret;
448446

449447
dev_dbg(dev, "%s: fmt 0x%8x\n", __func__, fmt);
450448

@@ -454,35 +452,10 @@ static int rtq9128_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
454452
return -EINVAL;
455453
}
456454

457-
fmtval = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
458-
if (data->tdm_slots && fmtval != SND_SOC_DAIFMT_DSP_A && fmtval != SND_SOC_DAIFMT_DSP_B) {
459-
dev_err(dev, "TDM is used, format only support DSP_A or DSP_B\n");
460-
return -EINVAL;
461-
}
455+
/* Store here and will be used in runtime hw_params for DAI format setting */
456+
data->daifmt = fmt;
462457

463-
switch (fmtval) {
464-
case SND_SOC_DAIFMT_I2S:
465-
audfmt = 8;
466-
break;
467-
case SND_SOC_DAIFMT_LEFT_J:
468-
audfmt = 9;
469-
break;
470-
case SND_SOC_DAIFMT_RIGHT_J:
471-
audfmt = 10;
472-
break;
473-
case SND_SOC_DAIFMT_DSP_A:
474-
audfmt = data->tdm_slots ? 12 : 11;
475-
break;
476-
case SND_SOC_DAIFMT_DSP_B:
477-
audfmt = data->tdm_slots ? 4 : 3;
478-
break;
479-
default:
480-
dev_err(dev, "Unsupported format 0x%8x\n", fmt);
481-
return -EINVAL;
482-
}
483-
484-
ret = snd_soc_component_write_field(comp, RTQ9128_REG_I2S_OPT, RTQ9128_AUDFMT_MASK, audfmt);
485-
return ret < 0 ? ret : 0;
458+
return 0;
486459
}
487460

488461
static int rtq9128_dai_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
@@ -558,10 +531,38 @@ static int rtq9128_dai_hw_params(struct snd_pcm_substream *stream, struct snd_pc
558531
unsigned int width, slot_width, bitrate, audbit, dolen;
559532
struct snd_soc_component *comp = dai->component;
560533
struct device *dev = dai->dev;
534+
unsigned int fmtval, audfmt;
561535
int ret;
562536

563537
dev_dbg(dev, "%s: width %d\n", __func__, params_width(param));
564538

539+
fmtval = FIELD_GET(SND_SOC_DAIFMT_FORMAT_MASK, data->daifmt);
540+
if (data->tdm_slots && fmtval != SND_SOC_DAIFMT_DSP_A && fmtval != SND_SOC_DAIFMT_DSP_B) {
541+
dev_err(dev, "TDM is used, format only support DSP_A or DSP_B\n");
542+
return -EINVAL;
543+
}
544+
545+
switch (fmtval) {
546+
case SND_SOC_DAIFMT_I2S:
547+
audfmt = 8;
548+
break;
549+
case SND_SOC_DAIFMT_LEFT_J:
550+
audfmt = 9;
551+
break;
552+
case SND_SOC_DAIFMT_RIGHT_J:
553+
audfmt = 10;
554+
break;
555+
case SND_SOC_DAIFMT_DSP_A:
556+
audfmt = data->tdm_slots ? 12 : 11;
557+
break;
558+
case SND_SOC_DAIFMT_DSP_B:
559+
audfmt = data->tdm_slots ? 4 : 3;
560+
break;
561+
default:
562+
dev_err(dev, "Unsupported format 0x%8x\n", fmtval);
563+
return -EINVAL;
564+
}
565+
565566
switch (width = params_width(param)) {
566567
case 16:
567568
audbit = 0;
@@ -615,6 +616,10 @@ static int rtq9128_dai_hw_params(struct snd_pcm_substream *stream, struct snd_pc
615616
return -EINVAL;
616617
}
617618

619+
ret = snd_soc_component_write_field(comp, RTQ9128_REG_I2S_OPT, RTQ9128_AUDFMT_MASK, audfmt);
620+
if (ret < 0)
621+
return ret;
622+
618623
ret = snd_soc_component_write_field(comp, RTQ9128_REG_I2S_OPT, RTQ9128_AUDBIT_MASK, audbit);
619624
if (ret < 0)
620625
return ret;

0 commit comments

Comments
 (0)