diff options
author | Marcus Cooper <codekipper@gmail.com> | 2017-08-19 08:48:33 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2017-08-21 12:15:50 -0400 |
commit | 771647159125e93547f15daa14131a30a26f9b60 (patch) | |
tree | e7ff99b02ce628ba705aefc3168eea3f6b7a432d | |
parent | 6eb4f27419d9250ac632df15d9dcf916d84b9944 (diff) |
ASoC: sun4i-i2s: Add regfields for word size select and sample resolution
On newer SoCs the location of the slot width select and sample
resolution are different and also there is a bigger range of
support.
For the current supported rates then an offset is required.
Signed-off-by: Marcus Cooper <codekipper@gmail.com>
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | sound/soc/sunxi/sun4i-i2s.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c index 87feb5a14cff..563de785d639 100644 --- a/sound/soc/sunxi/sun4i-i2s.c +++ b/sound/soc/sunxi/sun4i-i2s.c | |||
@@ -98,6 +98,9 @@ | |||
98 | * @sun4i_i2s_regmap: regmap config to use. | 98 | * @sun4i_i2s_regmap: regmap config to use. |
99 | * @mclk_offset: Value by which mclkdiv needs to be adjusted. | 99 | * @mclk_offset: Value by which mclkdiv needs to be adjusted. |
100 | * @bclk_offset: Value by which bclkdiv needs to be adjusted. | 100 | * @bclk_offset: Value by which bclkdiv needs to be adjusted. |
101 | * @fmt_offset: Value by which wss and sr needs to be adjusted. | ||
102 | * @field_fmt_wss: regmap field to set word select size. | ||
103 | * @field_fmt_sr: regmap field to set sample resolution. | ||
101 | * @field_txchanmap: location of the tx channel mapping register. | 104 | * @field_txchanmap: location of the tx channel mapping register. |
102 | * @field_rxchanmap: location of the rx channel mapping register. | 105 | * @field_rxchanmap: location of the rx channel mapping register. |
103 | * @field_txchansel: location of the tx channel select bit fields. | 106 | * @field_txchansel: location of the tx channel select bit fields. |
@@ -109,8 +112,11 @@ struct sun4i_i2s_quirks { | |||
109 | const struct regmap_config *sun4i_i2s_regmap; | 112 | const struct regmap_config *sun4i_i2s_regmap; |
110 | unsigned int mclk_offset; | 113 | unsigned int mclk_offset; |
111 | unsigned int bclk_offset; | 114 | unsigned int bclk_offset; |
115 | unsigned int fmt_offset; | ||
112 | 116 | ||
113 | /* Register fields for i2s */ | 117 | /* Register fields for i2s */ |
118 | struct reg_field field_fmt_wss; | ||
119 | struct reg_field field_fmt_sr; | ||
114 | struct reg_field field_txchanmap; | 120 | struct reg_field field_txchanmap; |
115 | struct reg_field field_rxchanmap; | 121 | struct reg_field field_rxchanmap; |
116 | struct reg_field field_txchansel; | 122 | struct reg_field field_txchansel; |
@@ -129,6 +135,8 @@ struct sun4i_i2s { | |||
129 | struct snd_dmaengine_dai_dma_data playback_dma_data; | 135 | struct snd_dmaengine_dai_dma_data playback_dma_data; |
130 | 136 | ||
131 | /* Register fields for i2s */ | 137 | /* Register fields for i2s */ |
138 | struct regmap_field *field_fmt_wss; | ||
139 | struct regmap_field *field_fmt_sr; | ||
132 | struct regmap_field *field_txchanmap; | 140 | struct regmap_field *field_txchanmap; |
133 | struct regmap_field *field_rxchanmap; | 141 | struct regmap_field *field_rxchanmap; |
134 | struct regmap_field *field_txchansel; | 142 | struct regmap_field *field_txchansel; |
@@ -314,9 +322,10 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, | |||
314 | return -EINVAL; | 322 | return -EINVAL; |
315 | } | 323 | } |
316 | 324 | ||
317 | regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, | 325 | regmap_field_write(i2s->field_fmt_wss, |
318 | SUN4I_I2S_FMT0_WSS_MASK | SUN4I_I2S_FMT0_SR_MASK, | 326 | wss + i2s->variant->fmt_offset); |
319 | SUN4I_I2S_FMT0_WSS(wss) | SUN4I_I2S_FMT0_SR(sr)); | 327 | regmap_field_write(i2s->field_fmt_sr, |
328 | sr + i2s->variant->fmt_offset); | ||
320 | 329 | ||
321 | return sun4i_i2s_set_clk_rate(i2s, params_rate(params), | 330 | return sun4i_i2s_set_clk_rate(i2s, params_rate(params), |
322 | params_width(params)); | 331 | params_width(params)); |
@@ -701,6 +710,8 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { | |||
701 | .has_reset = false, | 710 | .has_reset = false, |
702 | .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG, | 711 | .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG, |
703 | .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, | 712 | .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, |
713 | .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), | ||
714 | .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), | ||
704 | .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), | 715 | .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), |
705 | .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), | 716 | .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), |
706 | .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), | 717 | .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), |
@@ -711,6 +722,8 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { | |||
711 | .has_reset = true, | 722 | .has_reset = true, |
712 | .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG, | 723 | .reg_offset_txdata = SUN4I_I2S_FIFO_TX_REG, |
713 | .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, | 724 | .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, |
725 | .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), | ||
726 | .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), | ||
714 | .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), | 727 | .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), |
715 | .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), | 728 | .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), |
716 | .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), | 729 | .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), |
@@ -720,6 +733,18 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { | |||
720 | static int sun4i_i2s_init_regmap_fields(struct device *dev, | 733 | static int sun4i_i2s_init_regmap_fields(struct device *dev, |
721 | struct sun4i_i2s *i2s) | 734 | struct sun4i_i2s *i2s) |
722 | { | 735 | { |
736 | i2s->field_fmt_wss = | ||
737 | devm_regmap_field_alloc(dev, i2s->regmap, | ||
738 | i2s->variant->field_fmt_wss); | ||
739 | if (IS_ERR(i2s->field_fmt_wss)) | ||
740 | return PTR_ERR(i2s->field_fmt_wss); | ||
741 | |||
742 | i2s->field_fmt_sr = | ||
743 | devm_regmap_field_alloc(dev, i2s->regmap, | ||
744 | i2s->variant->field_fmt_sr); | ||
745 | if (IS_ERR(i2s->field_fmt_sr)) | ||
746 | return PTR_ERR(i2s->field_fmt_sr); | ||
747 | |||
723 | i2s->field_txchanmap = | 748 | i2s->field_txchanmap = |
724 | devm_regmap_field_alloc(dev, i2s->regmap, | 749 | devm_regmap_field_alloc(dev, i2s->regmap, |
725 | i2s->variant->field_txchanmap); | 750 | i2s->variant->field_txchanmap); |