[alsa-devel] [PATCH 0/2] ASoC: pcm3168a: Enable multiple digital port usage
Hi,
On my board the pcm3168a's DIN1/2/3/4 and DOUT1/2/3 is connected to separate McASP serializers. I can run the audio in DIN1/DOUT1 mode (DSP_A, and switching between TDM and normal mode), but I need to run the codec in multi DIN/DOUT mode which was not possible as the driver is hardwired to DIN1/DOUT1 mode.
Use the set_tdm_slots we get information on the number of slots per FS so we can use this to decide if we need to use multiple digital ports in parallel or to use single ones in TDM mode.
The default mode remains DIN1/DOUT1.
Regards, Peter --- Peter Ujfalusi (2): ASoC: pcm3168a: Rename min_frame_size to slot_width ASoC: pcm3168a: Add support for multi DIN/DOUT with TDM slots parameter
sound/soc/codecs/pcm3168a.c | 41 ++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 12 deletions(-)
It represents slot size and not frame.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com --- sound/soc/codecs/pcm3168a.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c index ed0b4317c9ae..861d24cc002e 100644 --- a/sound/soc/codecs/pcm3168a.c +++ b/sound/soc/codecs/pcm3168a.c @@ -432,7 +432,7 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, u32 val, mask, shift, reg; unsigned int rate, fmt, ratio, max_ratio; unsigned int chan; - int i, min_frame_size; + int i, slot_width;
rate = params_rate(params); chan = params_channels(params); @@ -467,11 +467,11 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, }
if (pcm3168a->slot_width) - min_frame_size = pcm3168a->slot_width; + slot_width = pcm3168a->slot_width; else - min_frame_size = params_width(params); + slot_width = params_width(params);
- switch (min_frame_size) { + switch (slot_width) { case 16: if (master_mode || (fmt != PCM3168A_FMT_RIGHT_J)) { dev_err(component->dev, "16-bit slots are supported only for slave mode using right justified\n"); @@ -488,7 +488,7 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, case 32: break; default: - dev_err(component->dev, "unsupported frame size: %d\n", min_frame_size); + dev_err(component->dev, "unsupported frame size: %d\n", slot_width); return -EINVAL; }
The patch
ASoC: pcm3168a: Rename min_frame_size to slot_width
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.3
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From b5d8dffb8cc9792c3bb4310e142932c8bc5c0387 Mon Sep 17 00:00:00 2001
From: Peter Ujfalusi peter.ujfalusi@ti.com Date: Thu, 20 Jun 2019 12:26:55 +0300 Subject: [PATCH] ASoC: pcm3168a: Rename min_frame_size to slot_width
It represents slot size and not frame.
Signed-off-by: Peter Ujfalusi peter.ujfalusi@ti.com Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/codecs/pcm3168a.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c index 9eb24ca09793..e1658947090b 100644 --- a/sound/soc/codecs/pcm3168a.c +++ b/sound/soc/codecs/pcm3168a.c @@ -435,7 +435,7 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, u32 val, mask, shift, reg; unsigned int rate, fmt, ratio, max_ratio; unsigned int chan; - int i, min_frame_size; + int i, slot_width;
rate = params_rate(params); chan = params_channels(params); @@ -470,11 +470,11 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, }
if (pcm3168a->slot_width) - min_frame_size = pcm3168a->slot_width; + slot_width = pcm3168a->slot_width; else - min_frame_size = params_width(params); + slot_width = params_width(params);
- switch (min_frame_size) { + switch (slot_width) { case 16: if (master_mode || (fmt != PCM3168A_FMT_RIGHT_J)) { dev_err(component->dev, "16-bit slots are supported only for slave mode using right justified\n"); @@ -491,7 +491,7 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, case 32: break; default: - dev_err(component->dev, "unsupported frame size: %d\n", min_frame_size); + dev_err(component->dev, "unsupported frame size: %d\n", slot_width); return -EINVAL; }
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: Peter Ujfalusi peter.ujfalusi@ti.com --- sound/soc/codecs/pcm3168a.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-)
diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c index 861d24cc002e..f1104d7d6426 100644 --- a/sound/soc/codecs/pcm3168a.c +++ b/sound/soc/codecs/pcm3168a.c @@ -408,9 +408,11 @@ static int pcm3168a_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, return -EINVAL; }
- pcm3168a->tdm_slots = slots; - pcm3168a->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = tx_mask; - pcm3168a->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = rx_mask; + if (pcm3168a->tdm_slots && pcm3168a->tdm_slots != slots) { + dev_err(component->dev, "Not matching slots %d vs %d\n", + pcm3168a->tdm_slots, slots); + return -EINVAL; + }
if (pcm3168a->slot_width && pcm3168a->slot_width != slot_width) { dev_err(component->dev, "Not matching slot_width %d vs %d\n", @@ -418,7 +420,11 @@ static int pcm3168a_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, return -EINVAL; }
+ pcm3168a->tdm_slots = slots; 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; }
@@ -431,11 +437,10 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, bool tx, master_mode; u32 val, mask, shift, reg; unsigned int rate, fmt, ratio, max_ratio; - unsigned int chan; + unsigned int tdm_slots; int i, slot_width;
rate = params_rate(params); - chan = params_channels(params);
ratio = pcm3168a->sysclk / rate;
@@ -492,8 +497,20 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, return -EINVAL; }
- /* for TDM */ - if (chan > 2) { + if (pcm3168a->tdm_slots) + 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) { case PCM3168A_FMT_I2S: case PCM3168A_FMT_DSP_A:
participants (2)
-
Mark Brown
-
Peter Ujfalusi