diff options
author | Maxime Ripard <maxime.ripard@bootlin.com> | 2019-08-19 15:25:12 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2019-08-20 13:30:18 -0400 |
commit | 71137bcd0a9a778f9407a3bee46c62fcccee4f83 (patch) | |
tree | 7e7b6ab867b6ac8fa9714c9fa009d5645f58e9fd /sound | |
parent | d70be625f25af7a2bc91b7d17d205f6071f08f2f (diff) |
ASoC: sun4i-i2s: Move the format configuration to a callback
The two main generations of our I2S controller require a slightly different
format 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/dc818644c3e40734e7a97247c994b1fca1c3c047.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 | 199 |
1 files changed, 106 insertions, 93 deletions
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c index 42e45c9a947a..93ea627e2f1f 100644 --- a/sound/soc/sunxi/sun4i-i2s.c +++ b/sound/soc/sunxi/sun4i-i2s.c | |||
@@ -93,6 +93,11 @@ | |||
93 | #define SUN8I_I2S_CTRL_BCLK_OUT BIT(18) | 93 | #define SUN8I_I2S_CTRL_BCLK_OUT BIT(18) |
94 | #define SUN8I_I2S_CTRL_LRCK_OUT BIT(17) | 94 | #define SUN8I_I2S_CTRL_LRCK_OUT BIT(17) |
95 | 95 | ||
96 | #define SUN8I_I2S_CTRL_MODE_MASK GENMASK(5, 4) | ||
97 | #define SUN8I_I2S_CTRL_MODE_RIGHT (2 << 4) | ||
98 | #define SUN8I_I2S_CTRL_MODE_LEFT (1 << 4) | ||
99 | #define SUN8I_I2S_CTRL_MODE_PCM (0 << 4) | ||
100 | |||
96 | #define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK GENMASK(17, 8) | 101 | #define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK GENMASK(17, 8) |
97 | #define SUN8I_I2S_FMT0_LRCK_PERIOD(period) ((period - 1) << 8) | 102 | #define SUN8I_I2S_FMT0_LRCK_PERIOD(period) ((period - 1) << 8) |
98 | 103 | ||
@@ -121,9 +126,7 @@ struct sun4i_i2s; | |||
121 | * struct sun4i_i2s_quirks - Differences between SoC variants. | 126 | * struct sun4i_i2s_quirks - Differences between SoC variants. |
122 | * | 127 | * |
123 | * @has_reset: SoC needs reset deasserted. | 128 | * @has_reset: SoC needs reset deasserted. |
124 | * @has_slave_select_bit: SoC has a bit to enable slave mode. | ||
125 | * @has_fmt_set_lrck_period: SoC requires lrclk period to be set. | 129 | * @has_fmt_set_lrck_period: SoC requires lrclk period to be set. |
126 | * @has_chsel_offset: SoC uses offset for selecting dai operational mode. | ||
127 | * @reg_offset_txdata: offset of the tx fifo. | 130 | * @reg_offset_txdata: offset of the tx fifo. |
128 | * @sun4i_i2s_regmap: regmap config to use. | 131 | * @sun4i_i2s_regmap: regmap config to use. |
129 | * @mclk_offset: Value by which mclkdiv needs to be adjusted. | 132 | * @mclk_offset: Value by which mclkdiv needs to be adjusted. |
@@ -133,13 +136,10 @@ struct sun4i_i2s; | |||
133 | * @field_fmt_sr: regmap field to set sample resolution. | 136 | * @field_fmt_sr: regmap field to set sample resolution. |
134 | * @field_fmt_bclk: regmap field to set clk polarity. | 137 | * @field_fmt_bclk: regmap field to set clk polarity. |
135 | * @field_fmt_lrclk: regmap field to set frame polarity. | 138 | * @field_fmt_lrclk: regmap field to set frame polarity. |
136 | * @field_fmt_mode: regmap field to set the operational mode. | ||
137 | */ | 139 | */ |
138 | struct sun4i_i2s_quirks { | 140 | struct sun4i_i2s_quirks { |
139 | bool has_reset; | 141 | bool has_reset; |
140 | bool has_slave_select_bit; | ||
141 | bool has_fmt_set_lrck_period; | 142 | bool has_fmt_set_lrck_period; |
142 | bool has_chsel_offset; | ||
143 | unsigned int reg_offset_txdata; /* TX FIFO */ | 143 | unsigned int reg_offset_txdata; /* TX FIFO */ |
144 | const struct regmap_config *sun4i_i2s_regmap; | 144 | const struct regmap_config *sun4i_i2s_regmap; |
145 | unsigned int mclk_offset; | 145 | unsigned int mclk_offset; |
@@ -151,12 +151,12 @@ struct sun4i_i2s_quirks { | |||
151 | struct reg_field field_fmt_sr; | 151 | struct reg_field field_fmt_sr; |
152 | struct reg_field field_fmt_bclk; | 152 | struct reg_field field_fmt_bclk; |
153 | struct reg_field field_fmt_lrclk; | 153 | struct reg_field field_fmt_lrclk; |
154 | struct reg_field field_fmt_mode; | ||
155 | 154 | ||
156 | s8 (*get_sr)(const struct sun4i_i2s *, int); | 155 | s8 (*get_sr)(const struct sun4i_i2s *, int); |
157 | s8 (*get_wss)(const struct sun4i_i2s *, int); | 156 | s8 (*get_wss)(const struct sun4i_i2s *, int); |
158 | int (*set_chan_cfg)(const struct sun4i_i2s *, | 157 | int (*set_chan_cfg)(const struct sun4i_i2s *, |
159 | const struct snd_pcm_hw_params *); | 158 | const struct snd_pcm_hw_params *); |
159 | int (*set_fmt)(const struct sun4i_i2s *, unsigned int); | ||
160 | }; | 160 | }; |
161 | 161 | ||
162 | struct sun4i_i2s { | 162 | struct sun4i_i2s { |
@@ -176,7 +176,6 @@ struct sun4i_i2s { | |||
176 | struct regmap_field *field_fmt_sr; | 176 | struct regmap_field *field_fmt_sr; |
177 | struct regmap_field *field_fmt_bclk; | 177 | struct regmap_field *field_fmt_bclk; |
178 | struct regmap_field *field_fmt_lrclk; | 178 | struct regmap_field *field_fmt_lrclk; |
179 | struct regmap_field *field_fmt_mode; | ||
180 | 179 | ||
181 | const struct sun4i_i2s_quirks *variant; | 180 | const struct sun4i_i2s_quirks *variant; |
182 | }; | 181 | }; |
@@ -465,52 +464,117 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, | |||
465 | params_width(params)); | 464 | params_width(params)); |
466 | } | 465 | } |
467 | 466 | ||
468 | static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | 467 | static int sun4i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, |
468 | unsigned int fmt) | ||
469 | { | 469 | { |
470 | struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); | ||
471 | u32 val; | 470 | u32 val; |
472 | u32 offset = 0; | ||
473 | u32 bclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL; | ||
474 | u32 lrclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL; | ||
475 | 471 | ||
476 | /* DAI Mode */ | 472 | /* DAI Mode */ |
477 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 473 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
478 | case SND_SOC_DAIFMT_I2S: | 474 | case SND_SOC_DAIFMT_I2S: |
479 | val = SUN4I_I2S_FMT0_FMT_I2S; | 475 | val = SUN4I_I2S_FMT0_FMT_I2S; |
480 | offset = 1; | ||
481 | break; | 476 | break; |
477 | |||
482 | case SND_SOC_DAIFMT_LEFT_J: | 478 | case SND_SOC_DAIFMT_LEFT_J: |
483 | val = SUN4I_I2S_FMT0_FMT_LEFT_J; | 479 | val = SUN4I_I2S_FMT0_FMT_LEFT_J; |
484 | break; | 480 | break; |
481 | |||
485 | case SND_SOC_DAIFMT_RIGHT_J: | 482 | case SND_SOC_DAIFMT_RIGHT_J: |
486 | val = SUN4I_I2S_FMT0_FMT_RIGHT_J; | 483 | val = SUN4I_I2S_FMT0_FMT_RIGHT_J; |
487 | break; | 484 | break; |
485 | |||
488 | default: | 486 | default: |
489 | dev_err(dai->dev, "Unsupported format: %d\n", | ||
490 | fmt & SND_SOC_DAIFMT_FORMAT_MASK); | ||
491 | return -EINVAL; | 487 | return -EINVAL; |
492 | } | 488 | } |
493 | 489 | ||
494 | if (i2s->variant->has_chsel_offset) { | 490 | regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG, |
495 | /* | 491 | SUN4I_I2S_FMT0_FMT_MASK, val); |
496 | * offset being set indicates that we're connected to an i2s | 492 | |
497 | * device, however offset is only used on the sun8i block and | 493 | /* DAI clock master masks */ |
498 | * i2s shares the same setting with the LJ format. Increment | 494 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
499 | * val so that the bit to value to write is correct. | 495 | case SND_SOC_DAIFMT_CBS_CFS: |
500 | */ | 496 | /* BCLK and LRCLK master */ |
501 | if (offset > 0) | 497 | val = SUN4I_I2S_CTRL_MODE_MASTER; |
502 | val++; | 498 | break; |
503 | /* blck offset determines whether i2s or LJ */ | 499 | |
504 | regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG, | 500 | case SND_SOC_DAIFMT_CBM_CFM: |
505 | SUN8I_I2S_TX_CHAN_OFFSET_MASK, | 501 | /* BCLK and LRCLK slave */ |
506 | SUN8I_I2S_TX_CHAN_OFFSET(offset)); | 502 | val = SUN4I_I2S_CTRL_MODE_SLAVE; |
507 | 503 | break; | |
508 | regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG, | 504 | |
509 | SUN8I_I2S_TX_CHAN_OFFSET_MASK, | 505 | default: |
510 | SUN8I_I2S_TX_CHAN_OFFSET(offset)); | 506 | return -EINVAL; |
511 | } | 507 | } |
508 | regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, | ||
509 | SUN4I_I2S_CTRL_MODE_MASK, val); | ||
510 | return 0; | ||
511 | } | ||
512 | 512 | ||
513 | regmap_field_write(i2s->field_fmt_mode, val); | 513 | static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s, |
514 | unsigned int fmt) | ||
515 | { | ||
516 | u32 mode, val; | ||
517 | u8 offset; | ||
518 | |||
519 | /* DAI Mode */ | ||
520 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
521 | case SND_SOC_DAIFMT_I2S: | ||
522 | mode = SUN8I_I2S_CTRL_MODE_LEFT; | ||
523 | offset = 1; | ||
524 | break; | ||
525 | |||
526 | case SND_SOC_DAIFMT_LEFT_J: | ||
527 | mode = SUN8I_I2S_CTRL_MODE_LEFT; | ||
528 | offset = 0; | ||
529 | break; | ||
530 | |||
531 | case SND_SOC_DAIFMT_RIGHT_J: | ||
532 | mode = SUN8I_I2S_CTRL_MODE_RIGHT; | ||
533 | offset = 0; | ||
534 | break; | ||
535 | |||
536 | default: | ||
537 | return -EINVAL; | ||
538 | } | ||
539 | |||
540 | regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, | ||
541 | SUN8I_I2S_CTRL_MODE_MASK, mode); | ||
542 | regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG, | ||
543 | SUN8I_I2S_TX_CHAN_OFFSET_MASK, | ||
544 | SUN8I_I2S_TX_CHAN_OFFSET(offset)); | ||
545 | regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG, | ||
546 | SUN8I_I2S_TX_CHAN_OFFSET_MASK, | ||
547 | SUN8I_I2S_TX_CHAN_OFFSET(offset)); | ||
548 | |||
549 | /* DAI clock master masks */ | ||
550 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
551 | case SND_SOC_DAIFMT_CBS_CFS: | ||
552 | /* BCLK and LRCLK master */ | ||
553 | val = SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT; | ||
554 | break; | ||
555 | |||
556 | case SND_SOC_DAIFMT_CBM_CFM: | ||
557 | /* BCLK and LRCLK slave */ | ||
558 | val = 0; | ||
559 | break; | ||
560 | |||
561 | default: | ||
562 | return -EINVAL; | ||
563 | } | ||
564 | |||
565 | regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, | ||
566 | SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT, | ||
567 | val); | ||
568 | |||
569 | return 0; | ||
570 | } | ||
571 | |||
572 | static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | ||
573 | { | ||
574 | struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); | ||
575 | u32 bclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL; | ||
576 | u32 lrclk_polarity = SUN4I_I2S_FMT0_POLARITY_NORMAL; | ||
577 | int ret; | ||
514 | 578 | ||
515 | /* DAI clock polarity */ | 579 | /* DAI clock polarity */ |
516 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | 580 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
@@ -538,50 +602,10 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
538 | regmap_field_write(i2s->field_fmt_bclk, bclk_polarity); | 602 | regmap_field_write(i2s->field_fmt_bclk, bclk_polarity); |
539 | regmap_field_write(i2s->field_fmt_lrclk, lrclk_polarity); | 603 | regmap_field_write(i2s->field_fmt_lrclk, lrclk_polarity); |
540 | 604 | ||
541 | if (i2s->variant->has_slave_select_bit) { | 605 | ret = i2s->variant->set_fmt(i2s, fmt); |
542 | /* DAI clock master masks */ | 606 | if (ret) { |
543 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 607 | dev_err(dai->dev, "Unsupported format configuration\n"); |
544 | case SND_SOC_DAIFMT_CBS_CFS: | 608 | return ret; |
545 | /* BCLK and LRCLK master */ | ||
546 | val = SUN4I_I2S_CTRL_MODE_MASTER; | ||
547 | break; | ||
548 | case SND_SOC_DAIFMT_CBM_CFM: | ||
549 | /* BCLK and LRCLK slave */ | ||
550 | val = SUN4I_I2S_CTRL_MODE_SLAVE; | ||
551 | break; | ||
552 | default: | ||
553 | dev_err(dai->dev, "Unsupported slave setting: %d\n", | ||
554 | fmt & SND_SOC_DAIFMT_MASTER_MASK); | ||
555 | return -EINVAL; | ||
556 | } | ||
557 | regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, | ||
558 | SUN4I_I2S_CTRL_MODE_MASK, | ||
559 | val); | ||
560 | } else { | ||
561 | /* | ||
562 | * The newer i2s block does not have a slave select bit, | ||
563 | * instead the clk pins are configured as inputs. | ||
564 | */ | ||
565 | /* DAI clock master masks */ | ||
566 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
567 | case SND_SOC_DAIFMT_CBS_CFS: | ||
568 | /* BCLK and LRCLK master */ | ||
569 | val = SUN8I_I2S_CTRL_BCLK_OUT | | ||
570 | SUN8I_I2S_CTRL_LRCK_OUT; | ||
571 | break; | ||
572 | case SND_SOC_DAIFMT_CBM_CFM: | ||
573 | /* BCLK and LRCLK slave */ | ||
574 | val = 0; | ||
575 | break; | ||
576 | default: | ||
577 | dev_err(dai->dev, "Unsupported slave setting: %d\n", | ||
578 | fmt & SND_SOC_DAIFMT_MASTER_MASK); | ||
579 | return -EINVAL; | ||
580 | } | ||
581 | regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, | ||
582 | SUN8I_I2S_CTRL_BCLK_OUT | | ||
583 | SUN8I_I2S_CTRL_LRCK_OUT, | ||
584 | val); | ||
585 | } | 609 | } |
586 | 610 | ||
587 | /* Set significant bits in our FIFOs */ | 611 | /* Set significant bits in our FIFOs */ |
@@ -933,11 +957,10 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { | |||
933 | .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), | 957 | .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), |
934 | .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), | 958 | .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), |
935 | .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), | 959 | .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), |
936 | .has_slave_select_bit = true, | ||
937 | .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), | ||
938 | .get_sr = sun4i_i2s_get_sr, | 960 | .get_sr = sun4i_i2s_get_sr, |
939 | .get_wss = sun4i_i2s_get_wss, | 961 | .get_wss = sun4i_i2s_get_wss, |
940 | .set_chan_cfg = sun4i_i2s_set_chan_cfg, | 962 | .set_chan_cfg = sun4i_i2s_set_chan_cfg, |
963 | .set_fmt = sun4i_i2s_set_soc_fmt, | ||
941 | }; | 964 | }; |
942 | 965 | ||
943 | static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { | 966 | static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { |
@@ -949,11 +972,10 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { | |||
949 | .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), | 972 | .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), |
950 | .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), | 973 | .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), |
951 | .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), | 974 | .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), |
952 | .has_slave_select_bit = true, | ||
953 | .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), | ||
954 | .get_sr = sun4i_i2s_get_sr, | 975 | .get_sr = sun4i_i2s_get_sr, |
955 | .get_wss = sun4i_i2s_get_wss, | 976 | .get_wss = sun4i_i2s_get_wss, |
956 | .set_chan_cfg = sun4i_i2s_set_chan_cfg, | 977 | .set_chan_cfg = sun4i_i2s_set_chan_cfg, |
978 | .set_fmt = sun4i_i2s_set_soc_fmt, | ||
957 | }; | 979 | }; |
958 | 980 | ||
959 | static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = { | 981 | static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = { |
@@ -965,11 +987,10 @@ static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = { | |||
965 | .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), | 987 | .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), |
966 | .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), | 988 | .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), |
967 | .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), | 989 | .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), |
968 | .has_slave_select_bit = true, | ||
969 | .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), | ||
970 | .get_sr = sun8i_i2s_get_sr_wss, | 990 | .get_sr = sun8i_i2s_get_sr_wss, |
971 | .get_wss = sun8i_i2s_get_sr_wss, | 991 | .get_wss = sun8i_i2s_get_sr_wss, |
972 | .set_chan_cfg = sun8i_i2s_set_chan_cfg, | 992 | .set_chan_cfg = sun8i_i2s_set_chan_cfg, |
993 | .set_fmt = sun8i_i2s_set_soc_fmt, | ||
973 | }; | 994 | }; |
974 | 995 | ||
975 | static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = { | 996 | static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = { |
@@ -979,32 +1000,30 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = { | |||
979 | .mclk_offset = 1, | 1000 | .mclk_offset = 1, |
980 | .bclk_offset = 2, | 1001 | .bclk_offset = 2, |
981 | .has_fmt_set_lrck_period = true, | 1002 | .has_fmt_set_lrck_period = true, |
982 | .has_chsel_offset = true, | ||
983 | .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8), | 1003 | .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8), |
984 | .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2), | 1004 | .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2), |
985 | .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6), | 1005 | .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6), |
986 | .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), | 1006 | .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), |
987 | .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 19, 19), | 1007 | .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 19, 19), |
988 | .field_fmt_mode = REG_FIELD(SUN4I_I2S_CTRL_REG, 4, 5), | ||
989 | .get_sr = sun8i_i2s_get_sr_wss, | 1008 | .get_sr = sun8i_i2s_get_sr_wss, |
990 | .get_wss = sun8i_i2s_get_sr_wss, | 1009 | .get_wss = sun8i_i2s_get_sr_wss, |
991 | .set_chan_cfg = sun8i_i2s_set_chan_cfg, | 1010 | .set_chan_cfg = sun8i_i2s_set_chan_cfg, |
1011 | .set_fmt = sun8i_i2s_set_soc_fmt, | ||
992 | }; | 1012 | }; |
993 | 1013 | ||
994 | static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = { | 1014 | static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = { |
995 | .has_reset = true, | 1015 | .has_reset = true, |
996 | .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG, | 1016 | .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG, |
997 | .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, | 1017 | .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, |
998 | .has_slave_select_bit = true, | ||
999 | .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), | 1018 | .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), |
1000 | .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), | 1019 | .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), |
1001 | .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), | 1020 | .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), |
1002 | .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), | 1021 | .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), |
1003 | .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), | 1022 | .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), |
1004 | .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), | ||
1005 | .get_sr = sun4i_i2s_get_sr, | 1023 | .get_sr = sun4i_i2s_get_sr, |
1006 | .get_wss = sun4i_i2s_get_wss, | 1024 | .get_wss = sun4i_i2s_get_wss, |
1007 | .set_chan_cfg = sun4i_i2s_set_chan_cfg, | 1025 | .set_chan_cfg = sun4i_i2s_set_chan_cfg, |
1026 | .set_fmt = sun4i_i2s_set_soc_fmt, | ||
1008 | }; | 1027 | }; |
1009 | 1028 | ||
1010 | static int sun4i_i2s_init_regmap_fields(struct device *dev, | 1029 | static int sun4i_i2s_init_regmap_fields(struct device *dev, |
@@ -1040,12 +1059,6 @@ static int sun4i_i2s_init_regmap_fields(struct device *dev, | |||
1040 | if (IS_ERR(i2s->field_fmt_lrclk)) | 1059 | if (IS_ERR(i2s->field_fmt_lrclk)) |
1041 | return PTR_ERR(i2s->field_fmt_lrclk); | 1060 | return PTR_ERR(i2s->field_fmt_lrclk); |
1042 | 1061 | ||
1043 | i2s->field_fmt_mode = | ||
1044 | devm_regmap_field_alloc(dev, i2s->regmap, | ||
1045 | i2s->variant->field_fmt_mode); | ||
1046 | if (IS_ERR(i2s->field_fmt_mode)) | ||
1047 | return PTR_ERR(i2s->field_fmt_mode); | ||
1048 | |||
1049 | return 0; | 1062 | return 0; |
1050 | } | 1063 | } |
1051 | 1064 | ||