diff mbox series

[v2] ASoC: sunxi: sun4i-i2s: Support 32-bit audio formats

Message ID 20240403-sunxi_s32-v2-1-29ebf6ad590a@jookia.org (mailing list archive)
State Accepted
Commit 863f94ac5f4481a7c5665e8152d551701ac71bf3
Headers show
Series [v2] ASoC: sunxi: sun4i-i2s: Support 32-bit audio formats | expand

Commit Message

John Watts April 3, 2024, 3:47 a.m. UTC
The I2S cores used in the H3 onwards support 32-bit sample rates.
Support these by adding a per-variant PCM format list.

Signed-off-by: John Watts <contact@jookia.org>
---
This patch enables support for 32-bit audio in the sunxi I2S driver.

I have only tested this on the Allwinner T113 but I'm fairly
certain it will work on older boards.
---
Changes in v2:
- Specify PCM formats for each variant instead of failing in hw_params
- Link to v1: https://lore.kernel.org/r/20240326-sunxi_s32-v1-1-899f71dcb1e6@jookia.org
---
 sound/soc/sunxi/sun4i-i2s.c | 33 ++++++++++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 5 deletions(-)


---
base-commit: 13227c2baa6b345451128828c9c2b0ec3868bd0d
change-id: 20240326-sunxi_s32-f2ab25b8e688

Best regards,

Comments

Jernej Škrabec April 14, 2024, 10:48 a.m. UTC | #1
Dne sreda, 3. april 2024 ob 05:47:35 CEST je John Watts napisal(a):
> The I2S cores used in the H3 onwards support 32-bit sample rates.
> Support these by adding a per-variant PCM format list.
> 
> Signed-off-by: John Watts <contact@jookia.org>

Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>

Best regards,
Jernej

> ---
> This patch enables support for 32-bit audio in the sunxi I2S driver.
> 
> I have only tested this on the Allwinner T113 but I'm fairly
> certain it will work on older boards.
> ---
> Changes in v2:
> - Specify PCM formats for each variant instead of failing in hw_params
> - Link to v1: https://lore.kernel.org/r/20240326-sunxi_s32-v1-1-899f71dcb1e6@jookia.org
> ---
>  sound/soc/sunxi/sun4i-i2s.c | 33 ++++++++++++++++++++++++++++-----
>  1 file changed, 28 insertions(+), 5 deletions(-)
> 
> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> index a736f632bf0b..59830f2a0d30 100644
> --- a/sound/soc/sunxi/sun4i-i2s.c
> +++ b/sound/soc/sunxi/sun4i-i2s.c
> @@ -156,6 +156,7 @@ struct sun4i_i2s;
>  /**
>   * struct sun4i_i2s_quirks - Differences between SoC variants.
>   * @has_reset: SoC needs reset deasserted.
> + * @pcm_formats: available PCM formats
>   * @reg_offset_txdata: offset of the tx fifo.
>   * @sun4i_i2s_regmap: regmap config to use.
>   * @field_clkdiv_mclk_en: regmap field to enable mclk output.
> @@ -175,6 +176,7 @@ struct sun4i_i2s;
>   */
>  struct sun4i_i2s_quirks {
>  	bool				has_reset;
> +	snd_pcm_format_t		pcm_formats;
>  	unsigned int			reg_offset_txdata;	/* TX FIFO */
>  	const struct regmap_config	*sun4i_i2s_regmap;
>  
> @@ -1092,8 +1094,18 @@ static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
>  	return 0;
>  }
>  
> +static int sun4i_i2s_dai_startup(struct snd_pcm_substream *sub, struct snd_soc_dai *dai)
> +{
> +	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
> +	struct snd_pcm_runtime *runtime = sub->runtime;
> +
> +	return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT,
> +					    i2s->variant->pcm_formats);
> +}
> +
>  static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
>  	.probe		= sun4i_i2s_dai_probe,
> +	.startup	= sun4i_i2s_dai_startup,
>  	.hw_params	= sun4i_i2s_hw_params,
>  	.set_fmt	= sun4i_i2s_set_fmt,
>  	.set_sysclk	= sun4i_i2s_set_sysclk,
> @@ -1101,9 +1113,10 @@ static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
>  	.trigger	= sun4i_i2s_trigger,
>  };
>  
> -#define SUN4I_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | \
> -			 SNDRV_PCM_FMTBIT_S20_LE | \
> -			 SNDRV_PCM_FMTBIT_S24_LE)
> +#define SUN4I_FORMATS_ALL (SNDRV_PCM_FMTBIT_S16_LE | \
> +			   SNDRV_PCM_FMTBIT_S20_LE | \
> +			   SNDRV_PCM_FMTBIT_S24_LE | \
> +			   SNDRV_PCM_FMTBIT_S32_LE)
>  
>  static struct snd_soc_dai_driver sun4i_i2s_dai = {
>  	.capture = {
> @@ -1111,14 +1124,14 @@ static struct snd_soc_dai_driver sun4i_i2s_dai = {
>  		.channels_min = 1,
>  		.channels_max = 8,
>  		.rates = SNDRV_PCM_RATE_8000_192000,
> -		.formats = SUN4I_FORMATS,
> +		.formats = SUN4I_FORMATS_ALL,
>  	},
>  	.playback = {
>  		.stream_name = "Playback",
>  		.channels_min = 1,
>  		.channels_max = 8,
>  		.rates = SNDRV_PCM_RATE_8000_192000,
> -		.formats = SUN4I_FORMATS,
> +		.formats = SUN4I_FORMATS_ALL,
>  	},
>  	.ops = &sun4i_i2s_dai_ops,
>  	.symmetric_rate = 1,
> @@ -1340,8 +1353,12 @@ static int sun4i_i2s_runtime_suspend(struct device *dev)
>  	return 0;
>  }
>  
> +#define SUN4I_FORMATS_A10 (SUN4I_FORMATS_ALL & ~SNDRV_PCM_FMTBIT_S32_LE)
> +#define SUN4I_FORMATS_H3 SUN4I_FORMATS_ALL
> +
>  static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
>  	.has_reset		= false,
> +	.pcm_formats		= SUN4I_FORMATS_A10,
>  	.reg_offset_txdata	= SUN4I_I2S_FIFO_TX_REG,
>  	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
>  	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
> @@ -1360,6 +1377,7 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
>  
>  static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
>  	.has_reset		= true,
> +	.pcm_formats		= SUN4I_FORMATS_A10,
>  	.reg_offset_txdata	= SUN4I_I2S_FIFO_TX_REG,
>  	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
>  	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
> @@ -1383,6 +1401,7 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
>   */
>  static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
>  	.has_reset		= true,
> +	.pcm_formats		= SUN4I_FORMATS_A10,
>  	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
>  	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
>  	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
> @@ -1401,6 +1420,7 @@ static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
>  
>  static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
>  	.has_reset		= true,
> +	.pcm_formats		= SUN4I_FORMATS_H3,
>  	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
>  	.sun4i_i2s_regmap	= &sun8i_i2s_regmap_config,
>  	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
> @@ -1419,6 +1439,7 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
>  
>  static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
>  	.has_reset		= true,
> +	.pcm_formats		= SUN4I_FORMATS_H3,
>  	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
>  	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
>  	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
> @@ -1437,6 +1458,7 @@ static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
>  
>  static const struct sun4i_i2s_quirks sun50i_h6_i2s_quirks = {
>  	.has_reset		= true,
> +	.pcm_formats		= SUN4I_FORMATS_H3,
>  	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
>  	.sun4i_i2s_regmap	= &sun50i_h6_i2s_regmap_config,
>  	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
> @@ -1455,6 +1477,7 @@ static const struct sun4i_i2s_quirks sun50i_h6_i2s_quirks = {
>  
>  static const struct sun4i_i2s_quirks sun50i_r329_i2s_quirks = {
>  	.has_reset		= true,
> +	.pcm_formats		= SUN4I_FORMATS_H3,
>  	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
>  	.sun4i_i2s_regmap	= &sun50i_h6_i2s_regmap_config,
>  	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
> 
> ---
> base-commit: 13227c2baa6b345451128828c9c2b0ec3868bd0d
> change-id: 20240326-sunxi_s32-f2ab25b8e688
> 
> Best regards,
>
Mark Brown April 15, 2024, 11:43 p.m. UTC | #2
On Wed, 03 Apr 2024 14:47:35 +1100, John Watts wrote:
> The I2S cores used in the H3 onwards support 32-bit sample rates.
> Support these by adding a per-variant PCM format list.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/1] ASoC: sunxi: sun4i-i2s: Support 32-bit audio formats
      commit: 863f94ac5f4481a7c5665e8152d551701ac71bf3

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
diff mbox series

Patch

diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index a736f632bf0b..59830f2a0d30 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -156,6 +156,7 @@  struct sun4i_i2s;
 /**
  * struct sun4i_i2s_quirks - Differences between SoC variants.
  * @has_reset: SoC needs reset deasserted.
+ * @pcm_formats: available PCM formats
  * @reg_offset_txdata: offset of the tx fifo.
  * @sun4i_i2s_regmap: regmap config to use.
  * @field_clkdiv_mclk_en: regmap field to enable mclk output.
@@ -175,6 +176,7 @@  struct sun4i_i2s;
  */
 struct sun4i_i2s_quirks {
 	bool				has_reset;
+	snd_pcm_format_t		pcm_formats;
 	unsigned int			reg_offset_txdata;	/* TX FIFO */
 	const struct regmap_config	*sun4i_i2s_regmap;
 
@@ -1092,8 +1094,18 @@  static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
 	return 0;
 }
 
+static int sun4i_i2s_dai_startup(struct snd_pcm_substream *sub, struct snd_soc_dai *dai)
+{
+	struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+	struct snd_pcm_runtime *runtime = sub->runtime;
+
+	return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT,
+					    i2s->variant->pcm_formats);
+}
+
 static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
 	.probe		= sun4i_i2s_dai_probe,
+	.startup	= sun4i_i2s_dai_startup,
 	.hw_params	= sun4i_i2s_hw_params,
 	.set_fmt	= sun4i_i2s_set_fmt,
 	.set_sysclk	= sun4i_i2s_set_sysclk,
@@ -1101,9 +1113,10 @@  static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
 	.trigger	= sun4i_i2s_trigger,
 };
 
-#define SUN4I_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | \
-			 SNDRV_PCM_FMTBIT_S20_LE | \
-			 SNDRV_PCM_FMTBIT_S24_LE)
+#define SUN4I_FORMATS_ALL (SNDRV_PCM_FMTBIT_S16_LE | \
+			   SNDRV_PCM_FMTBIT_S20_LE | \
+			   SNDRV_PCM_FMTBIT_S24_LE | \
+			   SNDRV_PCM_FMTBIT_S32_LE)
 
 static struct snd_soc_dai_driver sun4i_i2s_dai = {
 	.capture = {
@@ -1111,14 +1124,14 @@  static struct snd_soc_dai_driver sun4i_i2s_dai = {
 		.channels_min = 1,
 		.channels_max = 8,
 		.rates = SNDRV_PCM_RATE_8000_192000,
-		.formats = SUN4I_FORMATS,
+		.formats = SUN4I_FORMATS_ALL,
 	},
 	.playback = {
 		.stream_name = "Playback",
 		.channels_min = 1,
 		.channels_max = 8,
 		.rates = SNDRV_PCM_RATE_8000_192000,
-		.formats = SUN4I_FORMATS,
+		.formats = SUN4I_FORMATS_ALL,
 	},
 	.ops = &sun4i_i2s_dai_ops,
 	.symmetric_rate = 1,
@@ -1340,8 +1353,12 @@  static int sun4i_i2s_runtime_suspend(struct device *dev)
 	return 0;
 }
 
+#define SUN4I_FORMATS_A10 (SUN4I_FORMATS_ALL & ~SNDRV_PCM_FMTBIT_S32_LE)
+#define SUN4I_FORMATS_H3 SUN4I_FORMATS_ALL
+
 static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
 	.has_reset		= false,
+	.pcm_formats		= SUN4I_FORMATS_A10,
 	.reg_offset_txdata	= SUN4I_I2S_FIFO_TX_REG,
 	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
 	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
@@ -1360,6 +1377,7 @@  static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
 
 static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
 	.has_reset		= true,
+	.pcm_formats		= SUN4I_FORMATS_A10,
 	.reg_offset_txdata	= SUN4I_I2S_FIFO_TX_REG,
 	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
 	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
@@ -1383,6 +1401,7 @@  static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
  */
 static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
 	.has_reset		= true,
+	.pcm_formats		= SUN4I_FORMATS_A10,
 	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
 	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
 	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
@@ -1401,6 +1420,7 @@  static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
 
 static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
 	.has_reset		= true,
+	.pcm_formats		= SUN4I_FORMATS_H3,
 	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
 	.sun4i_i2s_regmap	= &sun8i_i2s_regmap_config,
 	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
@@ -1419,6 +1439,7 @@  static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
 
 static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
 	.has_reset		= true,
+	.pcm_formats		= SUN4I_FORMATS_H3,
 	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
 	.sun4i_i2s_regmap	= &sun4i_i2s_regmap_config,
 	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
@@ -1437,6 +1458,7 @@  static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
 
 static const struct sun4i_i2s_quirks sun50i_h6_i2s_quirks = {
 	.has_reset		= true,
+	.pcm_formats		= SUN4I_FORMATS_H3,
 	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
 	.sun4i_i2s_regmap	= &sun50i_h6_i2s_regmap_config,
 	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
@@ -1455,6 +1477,7 @@  static const struct sun4i_i2s_quirks sun50i_h6_i2s_quirks = {
 
 static const struct sun4i_i2s_quirks sun50i_r329_i2s_quirks = {
 	.has_reset		= true,
+	.pcm_formats		= SUN4I_FORMATS_H3,
 	.reg_offset_txdata	= SUN8I_I2S_FIFO_TX_REG,
 	.sun4i_i2s_regmap	= &sun50i_h6_i2s_regmap_config,
 	.field_clkdiv_mclk_en	= REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),