Skip to content

Commit fb18028

Browse files
fidomaxbroonie
authored andcommitted
ASoC: codecs: max98090: Allow dsp_a mode
TDM mode for max98090 is dsp_a compatible with such limitations: 1) Up to four timeslots supported. 2) Only 16 bits timeslots supported. 3) Only 2 active timeslots (L/R) supported. We want to setup TDM mode only when dsp_a mode is selected. So move M98090_REG_TDM_FORMAT/M98090_REG_TDM_CONTROL registers setup from max98090_set_tdm_slot() to the max98090_dai_set_fmt(). Also extend max98090_set_tdm_slot() with all TDM limitations check. Signed-off-by: Maxim Kochetkov <fido_max@inbox.ru> Link: https://lore.kernel.org/r/Message-Id: <20230622142038.63388-1-fido_max@inbox.ru> Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 82f76ac commit fb18028

2 files changed

Lines changed: 30 additions & 26 deletions

File tree

sound/soc/codecs/max98090.c

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,7 +1581,7 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
15811581
struct snd_soc_component *component = codec_dai->component;
15821582
struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
15831583
struct max98090_cdata *cdata;
1584-
u8 regval;
1584+
u8 regval, tdm_regval;
15851585

15861586
max98090->dai_fmt = fmt;
15871587
cdata = &max98090->dai[0];
@@ -1590,6 +1590,7 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
15901590
cdata->fmt = fmt;
15911591

15921592
regval = 0;
1593+
tdm_regval = 0;
15931594
switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
15941595
case SND_SOC_DAIFMT_CBC_CFC:
15951596
/* Set to consumer mode PLL - MAS mode off */
@@ -1635,7 +1636,8 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
16351636
regval |= M98090_RJ_MASK;
16361637
break;
16371638
case SND_SOC_DAIFMT_DSP_A:
1638-
/* Not supported mode */
1639+
tdm_regval |= M98090_TDM_MASK;
1640+
break;
16391641
default:
16401642
dev_err(component->dev, "DAI format unsupported");
16411643
return -EINVAL;
@@ -1664,11 +1666,20 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
16641666
* seen for the case of TDM mode. The remaining cases have
16651667
* normal logic.
16661668
*/
1667-
if (max98090->tdm_slots > 1)
1669+
if (tdm_regval)
16681670
regval ^= M98090_BCI_MASK;
16691671

16701672
snd_soc_component_write(component,
16711673
M98090_REG_INTERFACE_FORMAT, regval);
1674+
1675+
regval = 0;
1676+
if (tdm_regval)
1677+
regval = max98090->tdm_lslot << M98090_TDM_SLOTL_SHIFT |
1678+
max98090->tdm_rslot << M98090_TDM_SLOTR_SHIFT |
1679+
0 << M98090_TDM_SLOTDLY_SHIFT;
1680+
1681+
snd_soc_component_write(component, M98090_REG_TDM_FORMAT, regval);
1682+
snd_soc_component_write(component, M98090_REG_TDM_CONTROL, tdm_regval);
16721683
}
16731684

16741685
return 0;
@@ -1679,33 +1690,22 @@ static int max98090_set_tdm_slot(struct snd_soc_dai *codec_dai,
16791690
{
16801691
struct snd_soc_component *component = codec_dai->component;
16811692
struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
1682-
struct max98090_cdata *cdata;
1683-
cdata = &max98090->dai[0];
16841693

16851694
if (slots < 0 || slots > 4)
16861695
return -EINVAL;
16871696

1688-
max98090->tdm_slots = slots;
1689-
max98090->tdm_width = slot_width;
1690-
1691-
if (max98090->tdm_slots > 1) {
1692-
/* SLOTL SLOTR SLOTDLY */
1693-
snd_soc_component_write(component, M98090_REG_TDM_FORMAT,
1694-
0 << M98090_TDM_SLOTL_SHIFT |
1695-
1 << M98090_TDM_SLOTR_SHIFT |
1696-
0 << M98090_TDM_SLOTDLY_SHIFT);
1697-
1698-
/* FSW TDM */
1699-
snd_soc_component_update_bits(component, M98090_REG_TDM_CONTROL,
1700-
M98090_TDM_MASK,
1701-
M98090_TDM_MASK);
1702-
}
1697+
if (slot_width != 16)
1698+
return -EINVAL;
17031699

1704-
/*
1705-
* Normally advisable to set TDM first, but this permits either order
1706-
*/
1707-
cdata->fmt = 0;
1708-
max98090_dai_set_fmt(codec_dai, max98090->dai_fmt);
1700+
if (rx_mask != tx_mask)
1701+
return -EINVAL;
1702+
1703+
if (!rx_mask)
1704+
return -EINVAL;
1705+
1706+
max98090->tdm_slots = slots;
1707+
max98090->tdm_lslot = ffs(rx_mask) - 1;
1708+
max98090->tdm_rslot = fls(rx_mask) - 1;
17091709

17101710
return 0;
17111711
}
@@ -2408,6 +2408,9 @@ static int max98090_probe(struct snd_soc_component *component)
24082408
max98090->pa1en = 0;
24092409
max98090->pa2en = 0;
24102410

2411+
max98090->tdm_lslot = 0;
2412+
max98090->tdm_rslot = 1;
2413+
24112414
ret = snd_soc_component_read(component, M98090_REG_REVISION_ID);
24122415
if (ret < 0) {
24132416
dev_err(component->dev, "Failed to read device revision: %d\n",

sound/soc/codecs/max98090.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1533,7 +1533,8 @@ struct max98090_priv {
15331533
struct snd_soc_jack *jack;
15341534
unsigned int dai_fmt;
15351535
int tdm_slots;
1536-
int tdm_width;
1536+
int tdm_lslot;
1537+
int tdm_rslot;
15371538
u8 lin_state;
15381539
unsigned int pa1en;
15391540
unsigned int pa2en;

0 commit comments

Comments
 (0)