mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 12:43:29 +02:00
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>
This commit is contained in:
committed by
Mark Brown
parent
82f76ac26c
commit
fb180283c0
@@ -1581,7 +1581,7 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
|
|||||||
struct snd_soc_component *component = codec_dai->component;
|
struct snd_soc_component *component = codec_dai->component;
|
||||||
struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
|
struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
|
||||||
struct max98090_cdata *cdata;
|
struct max98090_cdata *cdata;
|
||||||
u8 regval;
|
u8 regval, tdm_regval;
|
||||||
|
|
||||||
max98090->dai_fmt = fmt;
|
max98090->dai_fmt = fmt;
|
||||||
cdata = &max98090->dai[0];
|
cdata = &max98090->dai[0];
|
||||||
@@ -1590,6 +1590,7 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
|
|||||||
cdata->fmt = fmt;
|
cdata->fmt = fmt;
|
||||||
|
|
||||||
regval = 0;
|
regval = 0;
|
||||||
|
tdm_regval = 0;
|
||||||
switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
|
switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
|
||||||
case SND_SOC_DAIFMT_CBC_CFC:
|
case SND_SOC_DAIFMT_CBC_CFC:
|
||||||
/* Set to consumer mode PLL - MAS mode off */
|
/* Set to consumer mode PLL - MAS mode off */
|
||||||
@@ -1635,7 +1636,8 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
|
|||||||
regval |= M98090_RJ_MASK;
|
regval |= M98090_RJ_MASK;
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAIFMT_DSP_A:
|
case SND_SOC_DAIFMT_DSP_A:
|
||||||
/* Not supported mode */
|
tdm_regval |= M98090_TDM_MASK;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(component->dev, "DAI format unsupported");
|
dev_err(component->dev, "DAI format unsupported");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -1664,11 +1666,20 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
|
|||||||
* seen for the case of TDM mode. The remaining cases have
|
* seen for the case of TDM mode. The remaining cases have
|
||||||
* normal logic.
|
* normal logic.
|
||||||
*/
|
*/
|
||||||
if (max98090->tdm_slots > 1)
|
if (tdm_regval)
|
||||||
regval ^= M98090_BCI_MASK;
|
regval ^= M98090_BCI_MASK;
|
||||||
|
|
||||||
snd_soc_component_write(component,
|
snd_soc_component_write(component,
|
||||||
M98090_REG_INTERFACE_FORMAT, regval);
|
M98090_REG_INTERFACE_FORMAT, regval);
|
||||||
|
|
||||||
|
regval = 0;
|
||||||
|
if (tdm_regval)
|
||||||
|
regval = max98090->tdm_lslot << M98090_TDM_SLOTL_SHIFT |
|
||||||
|
max98090->tdm_rslot << M98090_TDM_SLOTR_SHIFT |
|
||||||
|
0 << M98090_TDM_SLOTDLY_SHIFT;
|
||||||
|
|
||||||
|
snd_soc_component_write(component, M98090_REG_TDM_FORMAT, regval);
|
||||||
|
snd_soc_component_write(component, M98090_REG_TDM_CONTROL, tdm_regval);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1679,33 +1690,22 @@ static int max98090_set_tdm_slot(struct snd_soc_dai *codec_dai,
|
|||||||
{
|
{
|
||||||
struct snd_soc_component *component = codec_dai->component;
|
struct snd_soc_component *component = codec_dai->component;
|
||||||
struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
|
struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
|
||||||
struct max98090_cdata *cdata;
|
|
||||||
cdata = &max98090->dai[0];
|
|
||||||
|
|
||||||
if (slots < 0 || slots > 4)
|
if (slots < 0 || slots > 4)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (slot_width != 16)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (rx_mask != tx_mask)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!rx_mask)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
max98090->tdm_slots = slots;
|
max98090->tdm_slots = slots;
|
||||||
max98090->tdm_width = slot_width;
|
max98090->tdm_lslot = ffs(rx_mask) - 1;
|
||||||
|
max98090->tdm_rslot = fls(rx_mask) - 1;
|
||||||
if (max98090->tdm_slots > 1) {
|
|
||||||
/* SLOTL SLOTR SLOTDLY */
|
|
||||||
snd_soc_component_write(component, M98090_REG_TDM_FORMAT,
|
|
||||||
0 << M98090_TDM_SLOTL_SHIFT |
|
|
||||||
1 << M98090_TDM_SLOTR_SHIFT |
|
|
||||||
0 << M98090_TDM_SLOTDLY_SHIFT);
|
|
||||||
|
|
||||||
/* FSW TDM */
|
|
||||||
snd_soc_component_update_bits(component, M98090_REG_TDM_CONTROL,
|
|
||||||
M98090_TDM_MASK,
|
|
||||||
M98090_TDM_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Normally advisable to set TDM first, but this permits either order
|
|
||||||
*/
|
|
||||||
cdata->fmt = 0;
|
|
||||||
max98090_dai_set_fmt(codec_dai, max98090->dai_fmt);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -2408,6 +2408,9 @@ static int max98090_probe(struct snd_soc_component *component)
|
|||||||
max98090->pa1en = 0;
|
max98090->pa1en = 0;
|
||||||
max98090->pa2en = 0;
|
max98090->pa2en = 0;
|
||||||
|
|
||||||
|
max98090->tdm_lslot = 0;
|
||||||
|
max98090->tdm_rslot = 1;
|
||||||
|
|
||||||
ret = snd_soc_component_read(component, M98090_REG_REVISION_ID);
|
ret = snd_soc_component_read(component, M98090_REG_REVISION_ID);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(component->dev, "Failed to read device revision: %d\n",
|
dev_err(component->dev, "Failed to read device revision: %d\n",
|
||||||
|
@@ -1533,7 +1533,8 @@ struct max98090_priv {
|
|||||||
struct snd_soc_jack *jack;
|
struct snd_soc_jack *jack;
|
||||||
unsigned int dai_fmt;
|
unsigned int dai_fmt;
|
||||||
int tdm_slots;
|
int tdm_slots;
|
||||||
int tdm_width;
|
int tdm_lslot;
|
||||||
|
int tdm_rslot;
|
||||||
u8 lin_state;
|
u8 lin_state;
|
||||||
unsigned int pa1en;
|
unsigned int pa1en;
|
||||||
unsigned int pa2en;
|
unsigned int pa2en;
|
||||||
|
Reference in New Issue
Block a user