Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: sunxi: sun4i-i2s: Support 32-bit audio formats

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>
Link: https://lore.kernel.org/r/20240403-sunxi_s32-v2-1-29ebf6ad590a@jookia.org
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

John Watts and committed by
Mark Brown
863f94ac dd8c3473

+28 -5
+28 -5
sound/soc/sunxi/sun4i-i2s.c
··· 156 156 /** 157 157 * struct sun4i_i2s_quirks - Differences between SoC variants. 158 158 * @has_reset: SoC needs reset deasserted. 159 + * @pcm_formats: available PCM formats 159 160 * @reg_offset_txdata: offset of the tx fifo. 160 161 * @sun4i_i2s_regmap: regmap config to use. 161 162 * @field_clkdiv_mclk_en: regmap field to enable mclk output. ··· 176 175 */ 177 176 struct sun4i_i2s_quirks { 178 177 bool has_reset; 178 + snd_pcm_format_t pcm_formats; 179 179 unsigned int reg_offset_txdata; /* TX FIFO */ 180 180 const struct regmap_config *sun4i_i2s_regmap; 181 181 ··· 1094 1092 return 0; 1095 1093 } 1096 1094 1095 + static int sun4i_i2s_dai_startup(struct snd_pcm_substream *sub, struct snd_soc_dai *dai) 1096 + { 1097 + struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); 1098 + struct snd_pcm_runtime *runtime = sub->runtime; 1099 + 1100 + return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT, 1101 + i2s->variant->pcm_formats); 1102 + } 1103 + 1097 1104 static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = { 1098 1105 .probe = sun4i_i2s_dai_probe, 1106 + .startup = sun4i_i2s_dai_startup, 1099 1107 .hw_params = sun4i_i2s_hw_params, 1100 1108 .set_fmt = sun4i_i2s_set_fmt, 1101 1109 .set_sysclk = sun4i_i2s_set_sysclk, ··· 1113 1101 .trigger = sun4i_i2s_trigger, 1114 1102 }; 1115 1103 1116 - #define SUN4I_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ 1117 - SNDRV_PCM_FMTBIT_S20_LE | \ 1118 - SNDRV_PCM_FMTBIT_S24_LE) 1104 + #define SUN4I_FORMATS_ALL (SNDRV_PCM_FMTBIT_S16_LE | \ 1105 + SNDRV_PCM_FMTBIT_S20_LE | \ 1106 + SNDRV_PCM_FMTBIT_S24_LE | \ 1107 + SNDRV_PCM_FMTBIT_S32_LE) 1119 1108 1120 1109 static struct snd_soc_dai_driver sun4i_i2s_dai = { 1121 1110 .capture = { ··· 1124 1111 .channels_min = 1, 1125 1112 .channels_max = 8, 1126 1113 .rates = SNDRV_PCM_RATE_8000_192000, 1127 - .formats = SUN4I_FORMATS, 1114 + .formats = SUN4I_FORMATS_ALL, 1128 1115 }, 1129 1116 .playback = { 1130 1117 .stream_name = "Playback", 1131 1118 .channels_min = 1, 1132 1119 .channels_max = 8, 1133 1120 .rates = SNDRV_PCM_RATE_8000_192000, 1134 - .formats = SUN4I_FORMATS, 1121 + .formats = SUN4I_FORMATS_ALL, 1135 1122 }, 1136 1123 .ops = &sun4i_i2s_dai_ops, 1137 1124 .symmetric_rate = 1, ··· 1353 1340 return 0; 1354 1341 } 1355 1342 1343 + #define SUN4I_FORMATS_A10 (SUN4I_FORMATS_ALL & ~SNDRV_PCM_FMTBIT_S32_LE) 1344 + #define SUN4I_FORMATS_H3 SUN4I_FORMATS_ALL 1345 + 1356 1346 static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { 1357 1347 .has_reset = false, 1348 + .pcm_formats = SUN4I_FORMATS_A10, 1358 1349 .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG, 1359 1350 .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, 1360 1351 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), ··· 1377 1360 1378 1361 static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { 1379 1362 .has_reset = true, 1363 + .pcm_formats = SUN4I_FORMATS_A10, 1380 1364 .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG, 1381 1365 .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, 1382 1366 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), ··· 1401 1383 */ 1402 1384 static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = { 1403 1385 .has_reset = true, 1386 + .pcm_formats = SUN4I_FORMATS_A10, 1404 1387 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG, 1405 1388 .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, 1406 1389 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), ··· 1420 1401 1421 1402 static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = { 1422 1403 .has_reset = true, 1404 + .pcm_formats = SUN4I_FORMATS_H3, 1423 1405 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG, 1424 1406 .sun4i_i2s_regmap = &sun8i_i2s_regmap_config, 1425 1407 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8), ··· 1439 1419 1440 1420 static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = { 1441 1421 .has_reset = true, 1422 + .pcm_formats = SUN4I_FORMATS_H3, 1442 1423 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG, 1443 1424 .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, 1444 1425 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), ··· 1458 1437 1459 1438 static const struct sun4i_i2s_quirks sun50i_h6_i2s_quirks = { 1460 1439 .has_reset = true, 1440 + .pcm_formats = SUN4I_FORMATS_H3, 1461 1441 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG, 1462 1442 .sun4i_i2s_regmap = &sun50i_h6_i2s_regmap_config, 1463 1443 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8), ··· 1477 1455 1478 1456 static const struct sun4i_i2s_quirks sun50i_r329_i2s_quirks = { 1479 1457 .has_reset = true, 1458 + .pcm_formats = SUN4I_FORMATS_H3, 1480 1459 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG, 1481 1460 .sun4i_i2s_regmap = &sun50i_h6_i2s_regmap_config, 1482 1461 .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),