diff options
author | Maxime Ripard <maxime.ripard@bootlin.com> | 2019-08-19 15:25:11 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2019-08-20 13:30:00 -0400 |
commit | d70be625f25af7a2bc91b7d17d205f6071f08f2f (patch) | |
tree | 9434180c9d68075a60375b1ff80f744b28da49d0 /sound | |
parent | dd28d54c248fa37794dfa3d23a24ff99a1d3b6ac (diff) |
ASoC: sun4i-i2s: Move the channel configuration to a callback
The two main generations of our I2S controller require a slightly different
channel configuration, mostly because of a quite different register layout
and some additional registers being needed on the newer generation.
This used to be controlled through a bunch of booleans, however this proved
to be quite impractical, especially since a bunch of SoCs forgot to set
those parameters and therefore were broken from that point of view.
Fixes: 21faaea1343f ("ASoC: sun4i-i2s: Add support for A83T")
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
Link: https://lore.kernel.org/r/6414463de69584e8227fa495b13aa5f4798e1f0e.1566242458.git-series.maxime.ripard@bootlin.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/sunxi/sun4i-i2s.c | 156 |
1 files changed, 69 insertions, 87 deletions
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c index 2c909c6cafa9..42e45c9a947a 100644 --- a/sound/soc/sunxi/sun4i-i2s.c +++ b/sound/soc/sunxi/sun4i-i2s.c | |||
@@ -80,6 +80,7 @@ | |||
80 | #define SUN4I_I2S_TX_CNT_REG 0x2c | 80 | #define SUN4I_I2S_TX_CNT_REG 0x2c |
81 | 81 | ||
82 | #define SUN4I_I2S_TX_CHAN_SEL_REG 0x30 | 82 | #define SUN4I_I2S_TX_CHAN_SEL_REG 0x30 |
83 | #define SUN4I_I2S_CHAN_SEL_MASK GENMASK(2, 0) | ||
83 | #define SUN4I_I2S_CHAN_SEL(num_chan) (((num_chan) - 1) << 0) | 84 | #define SUN4I_I2S_CHAN_SEL(num_chan) (((num_chan) - 1) << 0) |
84 | 85 | ||
85 | #define SUN4I_I2S_TX_CHAN_MAP_REG 0x34 | 86 | #define SUN4I_I2S_TX_CHAN_MAP_REG 0x34 |
@@ -122,8 +123,6 @@ struct sun4i_i2s; | |||
122 | * @has_reset: SoC needs reset deasserted. | 123 | * @has_reset: SoC needs reset deasserted. |
123 | * @has_slave_select_bit: SoC has a bit to enable slave mode. | 124 | * @has_slave_select_bit: SoC has a bit to enable slave mode. |
124 | * @has_fmt_set_lrck_period: SoC requires lrclk period to be set. | 125 | * @has_fmt_set_lrck_period: SoC requires lrclk period to be set. |
125 | * @has_chcfg: tx and rx slot number need to be set. | ||
126 | * @has_chsel_tx_chen: SoC requires that the tx channels are enabled. | ||
127 | * @has_chsel_offset: SoC uses offset for selecting dai operational mode. | 126 | * @has_chsel_offset: SoC uses offset for selecting dai operational mode. |
128 | * @reg_offset_txdata: offset of the tx fifo. | 127 | * @reg_offset_txdata: offset of the tx fifo. |
129 | * @sun4i_i2s_regmap: regmap config to use. | 128 | * @sun4i_i2s_regmap: regmap config to use. |
@@ -135,17 +134,11 @@ struct sun4i_i2s; | |||
135 | * @field_fmt_bclk: regmap field to set clk polarity. | 134 | * @field_fmt_bclk: regmap field to set clk polarity. |
136 | * @field_fmt_lrclk: regmap field to set frame polarity. | 135 | * @field_fmt_lrclk: regmap field to set frame polarity. |
137 | * @field_fmt_mode: regmap field to set the operational mode. | 136 | * @field_fmt_mode: regmap field to set the operational mode. |
138 | * @field_txchanmap: location of the tx channel mapping register. | ||
139 | * @field_rxchanmap: location of the rx channel mapping register. | ||
140 | * @field_txchansel: location of the tx channel select bit fields. | ||
141 | * @field_rxchansel: location of the rx channel select bit fields. | ||
142 | */ | 137 | */ |
143 | struct sun4i_i2s_quirks { | 138 | struct sun4i_i2s_quirks { |
144 | bool has_reset; | 139 | bool has_reset; |
145 | bool has_slave_select_bit; | 140 | bool has_slave_select_bit; |
146 | bool has_fmt_set_lrck_period; | 141 | bool has_fmt_set_lrck_period; |
147 | bool has_chcfg; | ||
148 | bool has_chsel_tx_chen; | ||
149 | bool has_chsel_offset; | 142 | bool has_chsel_offset; |
150 | unsigned int reg_offset_txdata; /* TX FIFO */ | 143 | unsigned int reg_offset_txdata; /* TX FIFO */ |
151 | const struct regmap_config *sun4i_i2s_regmap; | 144 | const struct regmap_config *sun4i_i2s_regmap; |
@@ -159,13 +152,11 @@ struct sun4i_i2s_quirks { | |||
159 | struct reg_field field_fmt_bclk; | 152 | struct reg_field field_fmt_bclk; |
160 | struct reg_field field_fmt_lrclk; | 153 | struct reg_field field_fmt_lrclk; |
161 | struct reg_field field_fmt_mode; | 154 | struct reg_field field_fmt_mode; |
162 | struct reg_field field_txchanmap; | ||
163 | struct reg_field field_rxchanmap; | ||
164 | struct reg_field field_txchansel; | ||
165 | struct reg_field field_rxchansel; | ||
166 | 155 | ||
167 | s8 (*get_sr)(const struct sun4i_i2s *, int); | 156 | s8 (*get_sr)(const struct sun4i_i2s *, int); |
168 | s8 (*get_wss)(const struct sun4i_i2s *, int); | 157 | s8 (*get_wss)(const struct sun4i_i2s *, int); |
158 | int (*set_chan_cfg)(const struct sun4i_i2s *, | ||
159 | const struct snd_pcm_hw_params *); | ||
169 | }; | 160 | }; |
170 | 161 | ||
171 | struct sun4i_i2s { | 162 | struct sun4i_i2s { |
@@ -186,10 +177,6 @@ struct sun4i_i2s { | |||
186 | struct regmap_field *field_fmt_bclk; | 177 | struct regmap_field *field_fmt_bclk; |
187 | struct regmap_field *field_fmt_lrclk; | 178 | struct regmap_field *field_fmt_lrclk; |
188 | struct regmap_field *field_fmt_mode; | 179 | struct regmap_field *field_fmt_mode; |
189 | struct regmap_field *field_txchanmap; | ||
190 | struct regmap_field *field_rxchanmap; | ||
191 | struct regmap_field *field_txchansel; | ||
192 | struct regmap_field *field_rxchansel; | ||
193 | 180 | ||
194 | const struct sun4i_i2s_quirks *variant; | 181 | const struct sun4i_i2s_quirks *variant; |
195 | }; | 182 | }; |
@@ -380,44 +367,77 @@ static s8 sun8i_i2s_get_sr_wss(const struct sun4i_i2s *i2s, int width) | |||
380 | return (width - 8) / 4 + 1; | 367 | return (width - 8) / 4 + 1; |
381 | } | 368 | } |
382 | 369 | ||
383 | static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, | 370 | static int sun4i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s, |
384 | struct snd_pcm_hw_params *params, | 371 | const struct snd_pcm_hw_params *params) |
385 | struct snd_soc_dai *dai) | ||
386 | { | 372 | { |
387 | struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); | 373 | unsigned int channels = params_channels(params); |
388 | int sr, wss, channels; | ||
389 | u32 width; | ||
390 | 374 | ||
391 | channels = params_channels(params); | 375 | if (channels != 2) |
392 | if (channels != 2) { | ||
393 | dev_err(dai->dev, "Unsupported number of channels: %d\n", | ||
394 | channels); | ||
395 | return -EINVAL; | 376 | return -EINVAL; |
396 | } | ||
397 | 377 | ||
398 | if (i2s->variant->has_chcfg) { | 378 | /* Map the channels for playback and capture */ |
399 | regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG, | 379 | regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210); |
400 | SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK, | 380 | regmap_write(i2s->regmap, SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210); |
401 | SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels)); | 381 | |
402 | regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG, | 382 | /* Configure the channels */ |
403 | SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK, | 383 | regmap_update_bits(i2s->regmap, SUN4I_I2S_TX_CHAN_SEL_REG, |
404 | SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels)); | 384 | SUN4I_I2S_CHAN_SEL_MASK, |
405 | } | 385 | SUN4I_I2S_CHAN_SEL(channels)); |
386 | regmap_update_bits(i2s->regmap, SUN4I_I2S_RX_CHAN_SEL_REG, | ||
387 | SUN4I_I2S_CHAN_SEL_MASK, | ||
388 | SUN4I_I2S_CHAN_SEL(channels)); | ||
389 | |||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s, | ||
394 | const struct snd_pcm_hw_params *params) | ||
395 | { | ||
396 | unsigned int channels = params_channels(params); | ||
397 | |||
398 | if (channels != 2) | ||
399 | return -EINVAL; | ||
406 | 400 | ||
407 | /* Map the channels for playback and capture */ | 401 | /* Map the channels for playback and capture */ |
408 | regmap_field_write(i2s->field_txchanmap, 0x76543210); | 402 | regmap_write(i2s->regmap, SUN8I_I2S_TX_CHAN_MAP_REG, 0x76543210); |
409 | regmap_field_write(i2s->field_rxchanmap, 0x00003210); | 403 | regmap_write(i2s->regmap, SUN8I_I2S_RX_CHAN_MAP_REG, 0x76543210); |
410 | 404 | ||
411 | /* Configure the channels */ | 405 | /* Configure the channels */ |
412 | regmap_field_write(i2s->field_txchansel, | 406 | regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG, |
407 | SUN4I_I2S_CHAN_SEL_MASK, | ||
413 | SUN4I_I2S_CHAN_SEL(channels)); | 408 | SUN4I_I2S_CHAN_SEL(channels)); |
414 | regmap_field_write(i2s->field_rxchansel, | 409 | |
410 | regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG, | ||
411 | SUN4I_I2S_CHAN_SEL_MASK, | ||
415 | SUN4I_I2S_CHAN_SEL(channels)); | 412 | SUN4I_I2S_CHAN_SEL(channels)); |
416 | 413 | ||
417 | if (i2s->variant->has_chsel_tx_chen) | 414 | regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG, |
418 | regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG, | 415 | SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK, |
419 | SUN8I_I2S_TX_CHAN_EN_MASK, | 416 | SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels)); |
420 | SUN8I_I2S_TX_CHAN_EN(channels)); | 417 | regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG, |
418 | SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK, | ||
419 | SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels)); | ||
420 | |||
421 | regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG, | ||
422 | SUN8I_I2S_TX_CHAN_EN_MASK, | ||
423 | SUN8I_I2S_TX_CHAN_EN(channels)); | ||
424 | |||
425 | return 0; | ||
426 | } | ||
427 | |||
428 | static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, | ||
429 | struct snd_pcm_hw_params *params, | ||
430 | struct snd_soc_dai *dai) | ||
431 | { | ||
432 | struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); | ||
433 | int ret, sr, wss; | ||
434 | u32 width; | ||
435 | |||
436 | ret = i2s->variant->set_chan_cfg(i2s, params); | ||
437 | if (ret < 0) { | ||
438 | dev_err(dai->dev, "Invalid channel configuration\n"); | ||
439 | return ret; | ||
440 | } | ||
421 | 441 | ||
422 | switch (params_physical_width(params)) { | 442 | switch (params_physical_width(params)) { |
423 | case 16: | 443 | case 16: |
@@ -915,12 +935,9 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { | |||
915 | .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), | 935 | .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), |
916 | .has_slave_select_bit = true, | 936 | .has_slave_select_bit = true, |
917 | .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), | 937 | .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), |
918 | .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), | ||
919 | .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), | ||
920 | .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), | ||
921 | .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2), | ||
922 | .get_sr = sun4i_i2s_get_sr, | 938 | .get_sr = sun4i_i2s_get_sr, |
923 | .get_wss = sun4i_i2s_get_wss, | 939 | .get_wss = sun4i_i2s_get_wss, |
940 | .set_chan_cfg = sun4i_i2s_set_chan_cfg, | ||
924 | }; | 941 | }; |
925 | 942 | ||
926 | static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { | 943 | static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { |
@@ -934,12 +951,9 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { | |||
934 | .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), | 951 | .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), |
935 | .has_slave_select_bit = true, | 952 | .has_slave_select_bit = true, |
936 | .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), | 953 | .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), |
937 | .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), | ||
938 | .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), | ||
939 | .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), | ||
940 | .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2), | ||
941 | .get_sr = sun4i_i2s_get_sr, | 954 | .get_sr = sun4i_i2s_get_sr, |
942 | .get_wss = sun4i_i2s_get_wss, | 955 | .get_wss = sun4i_i2s_get_wss, |
956 | .set_chan_cfg = sun4i_i2s_set_chan_cfg, | ||
943 | }; | 957 | }; |
944 | 958 | ||
945 | static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = { | 959 | static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = { |
@@ -953,12 +967,9 @@ static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = { | |||
953 | .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), | 967 | .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), |
954 | .has_slave_select_bit = true, | 968 | .has_slave_select_bit = true, |
955 | .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), | 969 | .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), |
956 | .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), | ||
957 | .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), | ||
958 | .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), | ||
959 | .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2), | ||
960 | .get_sr = sun8i_i2s_get_sr_wss, | 970 | .get_sr = sun8i_i2s_get_sr_wss, |
961 | .get_wss = sun8i_i2s_get_sr_wss, | 971 | .get_wss = sun8i_i2s_get_sr_wss, |
972 | .set_chan_cfg = sun8i_i2s_set_chan_cfg, | ||
962 | }; | 973 | }; |
963 | 974 | ||
964 | static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = { | 975 | static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = { |
@@ -968,8 +979,6 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = { | |||
968 | .mclk_offset = 1, | 979 | .mclk_offset = 1, |
969 | .bclk_offset = 2, | 980 | .bclk_offset = 2, |
970 | .has_fmt_set_lrck_period = true, | 981 | .has_fmt_set_lrck_period = true, |
971 | .has_chcfg = true, | ||
972 | .has_chsel_tx_chen = true, | ||
973 | .has_chsel_offset = true, | 982 | .has_chsel_offset = true, |
974 | .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8), | 983 | .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8), |
975 | .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2), | 984 | .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2), |
@@ -977,12 +986,9 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = { | |||
977 | .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), | 986 | .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), |
978 | .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 19, 19), | 987 | .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 19, 19), |
979 | .field_fmt_mode = REG_FIELD(SUN4I_I2S_CTRL_REG, 4, 5), | 988 | .field_fmt_mode = REG_FIELD(SUN4I_I2S_CTRL_REG, 4, 5), |
980 | .field_txchanmap = REG_FIELD(SUN8I_I2S_TX_CHAN_MAP_REG, 0, 31), | ||
981 | .field_rxchanmap = REG_FIELD(SUN8I_I2S_RX_CHAN_MAP_REG, 0, 31), | ||
982 | .field_txchansel = REG_FIELD(SUN8I_I2S_TX_CHAN_SEL_REG, 0, 2), | ||
983 | .field_rxchansel = REG_FIELD(SUN8I_I2S_RX_CHAN_SEL_REG, 0, 2), | ||
984 | .get_sr = sun8i_i2s_get_sr_wss, | 989 | .get_sr = sun8i_i2s_get_sr_wss, |
985 | .get_wss = sun8i_i2s_get_sr_wss, | 990 | .get_wss = sun8i_i2s_get_sr_wss, |
991 | .set_chan_cfg = sun8i_i2s_set_chan_cfg, | ||
986 | }; | 992 | }; |
987 | 993 | ||
988 | static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = { | 994 | static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = { |
@@ -996,12 +1002,9 @@ static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = { | |||
996 | .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), | 1002 | .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), |
997 | .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), | 1003 | .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), |
998 | .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), | 1004 | .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), |
999 | .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), | ||
1000 | .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), | ||
1001 | .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), | ||
1002 | .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2), | ||
1003 | .get_sr = sun4i_i2s_get_sr, | 1005 | .get_sr = sun4i_i2s_get_sr, |
1004 | .get_wss = sun4i_i2s_get_wss, | 1006 | .get_wss = sun4i_i2s_get_wss, |
1007 | .set_chan_cfg = sun4i_i2s_set_chan_cfg, | ||
1005 | }; | 1008 | }; |
1006 | 1009 | ||
1007 | static int sun4i_i2s_init_regmap_fields(struct device *dev, | 1010 | static int sun4i_i2s_init_regmap_fields(struct device *dev, |
@@ -1043,28 +1046,7 @@ static int sun4i_i2s_init_regmap_fields(struct device *dev, | |||
1043 | if (IS_ERR(i2s->field_fmt_mode)) | 1046 | if (IS_ERR(i2s->field_fmt_mode)) |
1044 | return PTR_ERR(i2s->field_fmt_mode); | 1047 | return PTR_ERR(i2s->field_fmt_mode); |
1045 | 1048 | ||
1046 | i2s->field_txchanmap = | 1049 | return 0; |
1047 | devm_regmap_field_alloc(dev, i2s->regmap, | ||
1048 | i2s->variant->field_txchanmap); | ||
1049 | if (IS_ERR(i2s->field_txchanmap)) | ||
1050 | return PTR_ERR(i2s->field_txchanmap); | ||
1051 | |||
1052 | i2s->field_rxchanmap = | ||
1053 | devm_regmap_field_alloc(dev, i2s->regmap, | ||
1054 | i2s->variant->field_rxchanmap); | ||
1055 | if (IS_ERR(i2s->field_rxchanmap)) | ||
1056 | return PTR_ERR(i2s->field_rxchanmap); | ||
1057 | |||
1058 | i2s->field_txchansel = | ||
1059 | devm_regmap_field_alloc(dev, i2s->regmap, | ||
1060 | i2s->variant->field_txchansel); | ||
1061 | if (IS_ERR(i2s->field_txchansel)) | ||
1062 | return PTR_ERR(i2s->field_txchansel); | ||
1063 | |||
1064 | i2s->field_rxchansel = | ||
1065 | devm_regmap_field_alloc(dev, i2s->regmap, | ||
1066 | i2s->variant->field_rxchansel); | ||
1067 | return PTR_ERR_OR_ZERO(i2s->field_rxchansel); | ||
1068 | } | 1050 | } |
1069 | 1051 | ||
1070 | static int sun4i_i2s_probe(struct platform_device *pdev) | 1052 | static int sun4i_i2s_probe(struct platform_device *pdev) |