Commit 97000221 authored by Peter Ujfalusi's avatar Peter Ujfalusi Committed by Mark Brown

ASoC: pcm3168a: Add support for multi DIN/DOUT with TDM slots parameter

The driver was wired to be only usable in DIN1/DOUT1 mode, switching
between TDM and non TDM modes based on the number of channels.

While keeping this functionality for compatibility add support for using
all DIN1/2/3/4 and DOUT1/2/3 if it is needed by setting the TDM slots to
2.
Signed-off-by: default avatarPeter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent b5d8dffb
...@@ -411,9 +411,11 @@ static int pcm3168a_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, ...@@ -411,9 +411,11 @@ static int pcm3168a_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
return -EINVAL; return -EINVAL;
} }
pcm3168a->tdm_slots = slots; if (pcm3168a->tdm_slots && pcm3168a->tdm_slots != slots) {
pcm3168a->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = tx_mask; dev_err(component->dev, "Not matching slots %d vs %d\n",
pcm3168a->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = rx_mask; pcm3168a->tdm_slots, slots);
return -EINVAL;
}
if (pcm3168a->slot_width && pcm3168a->slot_width != slot_width) { if (pcm3168a->slot_width && pcm3168a->slot_width != slot_width) {
dev_err(component->dev, "Not matching slot_width %d vs %d\n", dev_err(component->dev, "Not matching slot_width %d vs %d\n",
...@@ -421,7 +423,11 @@ static int pcm3168a_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, ...@@ -421,7 +423,11 @@ static int pcm3168a_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
return -EINVAL; return -EINVAL;
} }
pcm3168a->tdm_slots = slots;
pcm3168a->slot_width = slot_width; pcm3168a->slot_width = slot_width;
pcm3168a->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = tx_mask;
pcm3168a->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = rx_mask;
return 0; return 0;
} }
...@@ -434,11 +440,10 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, ...@@ -434,11 +440,10 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
bool tx, master_mode; bool tx, master_mode;
u32 val, mask, shift, reg; u32 val, mask, shift, reg;
unsigned int rate, fmt, ratio, max_ratio; unsigned int rate, fmt, ratio, max_ratio;
unsigned int chan; unsigned int tdm_slots;
int i, slot_width; int i, slot_width;
rate = params_rate(params); rate = params_rate(params);
chan = params_channels(params);
ratio = pcm3168a->sysclk / rate; ratio = pcm3168a->sysclk / rate;
...@@ -495,8 +500,20 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, ...@@ -495,8 +500,20 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
return -EINVAL; return -EINVAL;
} }
/* for TDM */ if (pcm3168a->tdm_slots)
if (chan > 2) { tdm_slots = pcm3168a->tdm_slots;
else
tdm_slots = params_channels(params);
/*
* Switch the codec to TDM mode when more than 2 TDM slots are needed
* for the stream.
* If pcm3168a->tdm_slots is not set or set to more than 2 (8/6 usually)
* then DIN1/DOUT1 is used in TDM mode.
* If pcm3168a->tdm_slots is set to 2 then DIN1/2/3/4 and DOUT1/2/3 is
* used in normal mode, no need to switch to TDM modes.
*/
if (tdm_slots > 2) {
switch (fmt) { switch (fmt) {
case PCM3168A_FMT_I2S: case PCM3168A_FMT_I2S:
case PCM3168A_FMT_DSP_A: case PCM3168A_FMT_DSP_A:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment