@@ -156,6 +156,7 @@ struct sun4i_i2s;
156156/**
157157 * struct sun4i_i2s_quirks - Differences between SoC variants.
158158 * @has_reset: SoC needs reset deasserted.
159+ * @pcm_formats: available PCM formats
159160 * @reg_offset_txdata: offset of the tx fifo.
160161 * @sun4i_i2s_regmap: regmap config to use.
161162 * @field_clkdiv_mclk_en: regmap field to enable mclk output.
@@ -175,6 +176,7 @@ struct sun4i_i2s;
175176 */
176177struct sun4i_i2s_quirks {
177178 bool has_reset ;
179+ snd_pcm_format_t pcm_formats ;
178180 unsigned int reg_offset_txdata ; /* TX FIFO */
179181 const struct regmap_config * sun4i_i2s_regmap ;
180182
@@ -1092,33 +1094,44 @@ static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
10921094 return 0 ;
10931095}
10941096
1097+ static int sun4i_i2s_dai_startup (struct snd_pcm_substream * sub , struct snd_soc_dai * dai )
1098+ {
1099+ struct sun4i_i2s * i2s = snd_soc_dai_get_drvdata (dai );
1100+ struct snd_pcm_runtime * runtime = sub -> runtime ;
1101+
1102+ return snd_pcm_hw_constraint_mask64 (runtime , SNDRV_PCM_HW_PARAM_FORMAT ,
1103+ i2s -> variant -> pcm_formats );
1104+ }
1105+
10951106static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
10961107 .probe = sun4i_i2s_dai_probe ,
1108+ .startup = sun4i_i2s_dai_startup ,
10971109 .hw_params = sun4i_i2s_hw_params ,
10981110 .set_fmt = sun4i_i2s_set_fmt ,
10991111 .set_sysclk = sun4i_i2s_set_sysclk ,
11001112 .set_tdm_slot = sun4i_i2s_set_tdm_slot ,
11011113 .trigger = sun4i_i2s_trigger ,
11021114};
11031115
1104- #define SUN4I_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
1105- SNDRV_PCM_FMTBIT_S20_LE | \
1106- SNDRV_PCM_FMTBIT_S24_LE)
1116+ #define SUN4I_FORMATS_ALL (SNDRV_PCM_FMTBIT_S16_LE | \
1117+ SNDRV_PCM_FMTBIT_S20_LE | \
1118+ SNDRV_PCM_FMTBIT_S24_LE | \
1119+ SNDRV_PCM_FMTBIT_S32_LE)
11071120
11081121static struct snd_soc_dai_driver sun4i_i2s_dai = {
11091122 .capture = {
11101123 .stream_name = "Capture" ,
11111124 .channels_min = 1 ,
11121125 .channels_max = 8 ,
11131126 .rates = SNDRV_PCM_RATE_8000_192000 ,
1114- .formats = SUN4I_FORMATS ,
1127+ .formats = SUN4I_FORMATS_ALL ,
11151128 },
11161129 .playback = {
11171130 .stream_name = "Playback" ,
11181131 .channels_min = 1 ,
11191132 .channels_max = 8 ,
11201133 .rates = SNDRV_PCM_RATE_8000_192000 ,
1121- .formats = SUN4I_FORMATS ,
1134+ .formats = SUN4I_FORMATS_ALL ,
11221135 },
11231136 .ops = & sun4i_i2s_dai_ops ,
11241137 .symmetric_rate = 1 ,
@@ -1340,8 +1353,12 @@ static int sun4i_i2s_runtime_suspend(struct device *dev)
13401353 return 0 ;
13411354}
13421355
1356+ #define SUN4I_FORMATS_A10 (SUN4I_FORMATS_ALL & ~SNDRV_PCM_FMTBIT_S32_LE)
1357+ #define SUN4I_FORMATS_H3 SUN4I_FORMATS_ALL
1358+
13431359static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
13441360 .has_reset = false,
1361+ .pcm_formats = SUN4I_FORMATS_A10 ,
13451362 .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG ,
13461363 .sun4i_i2s_regmap = & sun4i_i2s_regmap_config ,
13471364 .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 = {
13601377
13611378static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
13621379 .has_reset = true,
1380+ .pcm_formats = SUN4I_FORMATS_A10 ,
13631381 .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG ,
13641382 .sun4i_i2s_regmap = & sun4i_i2s_regmap_config ,
13651383 .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 = {
13831401 */
13841402static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
13851403 .has_reset = true,
1404+ .pcm_formats = SUN4I_FORMATS_A10 ,
13861405 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG ,
13871406 .sun4i_i2s_regmap = & sun4i_i2s_regmap_config ,
13881407 .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 = {
14011420
14021421static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
14031422 .has_reset = true,
1423+ .pcm_formats = SUN4I_FORMATS_H3 ,
14041424 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG ,
14051425 .sun4i_i2s_regmap = & sun8i_i2s_regmap_config ,
14061426 .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 = {
14191439
14201440static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
14211441 .has_reset = true,
1442+ .pcm_formats = SUN4I_FORMATS_H3 ,
14221443 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG ,
14231444 .sun4i_i2s_regmap = & sun4i_i2s_regmap_config ,
14241445 .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 = {
14371458
14381459static const struct sun4i_i2s_quirks sun50i_h6_i2s_quirks = {
14391460 .has_reset = true,
1461+ .pcm_formats = SUN4I_FORMATS_H3 ,
14401462 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG ,
14411463 .sun4i_i2s_regmap = & sun50i_h6_i2s_regmap_config ,
14421464 .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 = {
14551477
14561478static const struct sun4i_i2s_quirks sun50i_r329_i2s_quirks = {
14571479 .has_reset = true,
1480+ .pcm_formats = SUN4I_FORMATS_H3 ,
14581481 .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG ,
14591482 .sun4i_i2s_regmap = & sun50i_h6_i2s_regmap_config ,
14601483 .field_clkdiv_mclk_en = REG_FIELD (SUN4I_I2S_CLK_DIV_REG , 8 , 8 ),
0 commit comments