Message ID | 20190603174735.21002-9-codekipper@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | ASoC: sun4i-i2s: Updates to the driver | expand |
On Mon, Jun 03, 2019 at 07:47:34PM +0200, codekipper@gmail.com wrote: > From: Marcus Cooper <codekipper@gmail.com> > > Extend the functionality of the driver to include support of 20 and > 24 bits per sample for the earlier SoCs. > > Newer SoCs can also handle 32bit samples. > > Signed-off-by: Marcus Cooper <codekipper@gmail.com> > --- > sound/soc/sunxi/sun4i-i2s.c | 34 +++++++++++++++++++++++++++++++--- > 1 file changed, 31 insertions(+), 3 deletions(-) > > diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c > index 3549a87ed9e9..351b8021173b 100644 > --- a/sound/soc/sunxi/sun4i-i2s.c > +++ b/sound/soc/sunxi/sun4i-i2s.c > @@ -428,6 +428,11 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, > case 16: > width = DMA_SLAVE_BUSWIDTH_2_BYTES; > break; > + case 20: > + case 24: > + case 32: > + width = DMA_SLAVE_BUSWIDTH_4_BYTES; > + break; Doesn't this test the physical width? If so, then I'm not sure that 20 even exists, and that we can support 24. > default: > dev_err(dai->dev, "Unsupported physical sample width: %d\n", > params_physical_width(params)); > @@ -440,7 +445,18 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, > sr = 0; > wss = 0; > break; > - > + case 20: > + sr = 1; > + wss = 1; > + break; > + case 24: > + sr = 2; > + wss = 2; > + break; > + case 32: > + sr = 4; > + wss = 4; > + break; This doesn't really works, wss being the slot size, and you can have a different slot size and sample size. I have a patch that reworks this, I'll send it. Maxime -- Maxime Ripard, Bootlin Embedded Linux and Kernel engineering https://bootlin.com
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c index 3549a87ed9e9..351b8021173b 100644 --- a/sound/soc/sunxi/sun4i-i2s.c +++ b/sound/soc/sunxi/sun4i-i2s.c @@ -428,6 +428,11 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, case 16: width = DMA_SLAVE_BUSWIDTH_2_BYTES; break; + case 20: + case 24: + case 32: + width = DMA_SLAVE_BUSWIDTH_4_BYTES; + break; default: dev_err(dai->dev, "Unsupported physical sample width: %d\n", params_physical_width(params)); @@ -440,7 +445,18 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, sr = 0; wss = 0; break; - + case 20: + sr = 1; + wss = 1; + break; + case 24: + sr = 2; + wss = 2; + break; + case 32: + sr = 4; + wss = 4; + break; default: dev_err(dai->dev, "Unsupported sample width: %d\n", params_width(params)); @@ -722,6 +738,13 @@ static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai) return 0; } +#define SUN4I_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S20_LE | \ + SNDRV_PCM_FMTBIT_S24_LE) + +#define SUN8I_FORMATS (SUN4I_FORMATS | \ + SNDRV_PCM_FMTBIT_S32_LE) + static struct snd_soc_dai_driver sun4i_i2s_dai = { .probe = sun4i_i2s_dai_probe, .capture = { @@ -729,14 +752,14 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = { .channels_min = 2, .channels_max = 2, .rates = SNDRV_PCM_RATE_8000_192000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .formats = SUN4I_FORMATS, }, .playback = { .stream_name = "Playback", .channels_min = 2, .channels_max = 2, .rates = SNDRV_PCM_RATE_8000_192000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, + .formats = SUN4I_FORMATS, }, .ops = &sun4i_i2s_dai_ops, .symmetric_rates = 1, @@ -1161,6 +1184,11 @@ static int sun4i_i2s_probe(struct platform_device *pdev) goto err_pm_disable; } + if (i2s->variant->is_h3_i2s_based) { + soc_dai->playback.formats = SUN8I_FORMATS; + soc_dai->capture.formats = SUN8I_FORMATS; + } + if (!of_property_read_u32(pdev->dev.of_node, "allwinner,playback-channels", &val)) { if (val >= 2 && val <= 8)