1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2015 Andrea Venturi
4 * Andrea Venturi <be17068@iperbole.bo.it>
6 * Copyright (C) 2016 Maxime Ripard
7 * Maxime Ripard <maxime.ripard@free-electrons.com>
10 #include <linux/clk.h>
11 #include <linux/dmaengine.h>
12 #include <linux/module.h>
14 #include <linux/platform_device.h>
15 #include <linux/pm_runtime.h>
16 #include <linux/regmap.h>
17 #include <linux/reset.h>
19 #include <sound/dmaengine_pcm.h>
20 #include <sound/pcm_params.h>
21 #include <sound/soc.h>
22 #include <sound/soc-dai.h>
24 #define SUN4I_I2S_CTRL_REG 0x00
25 #define SUN4I_I2S_CTRL_SDO_EN_MASK GENMASK(11, 8)
26 #define SUN4I_I2S_CTRL_SDO_EN(sdo) BIT(8 + (sdo))
27 #define SUN4I_I2S_CTRL_MODE_MASK BIT(5)
28 #define SUN4I_I2S_CTRL_MODE_SLAVE (1 << 5)
29 #define SUN4I_I2S_CTRL_MODE_MASTER (0 << 5)
30 #define SUN4I_I2S_CTRL_TX_EN BIT(2)
31 #define SUN4I_I2S_CTRL_RX_EN BIT(1)
32 #define SUN4I_I2S_CTRL_GL_EN BIT(0)
34 #define SUN4I_I2S_FMT0_REG 0x04
35 #define SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK BIT(7)
36 #define SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED (1 << 7)
37 #define SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL (0 << 7)
38 #define SUN4I_I2S_FMT0_BCLK_POLARITY_MASK BIT(6)
39 #define SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED (1 << 6)
40 #define SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL (0 << 6)
41 #define SUN4I_I2S_FMT0_SR_MASK GENMASK(5, 4)
42 #define SUN4I_I2S_FMT0_SR(sr) ((sr) << 4)
43 #define SUN4I_I2S_FMT0_WSS_MASK GENMASK(3, 2)
44 #define SUN4I_I2S_FMT0_WSS(wss) ((wss) << 2)
45 #define SUN4I_I2S_FMT0_FMT_MASK GENMASK(1, 0)
46 #define SUN4I_I2S_FMT0_FMT_RIGHT_J (2 << 0)
47 #define SUN4I_I2S_FMT0_FMT_LEFT_J (1 << 0)
48 #define SUN4I_I2S_FMT0_FMT_I2S (0 << 0)
50 #define SUN4I_I2S_FMT1_REG 0x08
51 #define SUN4I_I2S_FMT1_REG_SEXT_MASK BIT(8)
52 #define SUN4I_I2S_FMT1_REG_SEXT(sext) ((sext) << 8)
54 #define SUN4I_I2S_FIFO_TX_REG 0x0c
55 #define SUN4I_I2S_FIFO_RX_REG 0x10
57 #define SUN4I_I2S_FIFO_CTRL_REG 0x14
58 #define SUN4I_I2S_FIFO_CTRL_FLUSH_TX BIT(25)
59 #define SUN4I_I2S_FIFO_CTRL_FLUSH_RX BIT(24)
60 #define SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK BIT(2)
61 #define SUN4I_I2S_FIFO_CTRL_TX_MODE(mode) ((mode) << 2)
62 #define SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK GENMASK(1, 0)
63 #define SUN4I_I2S_FIFO_CTRL_RX_MODE(mode) (mode)
65 #define SUN4I_I2S_FIFO_STA_REG 0x18
67 #define SUN4I_I2S_DMA_INT_CTRL_REG 0x1c
68 #define SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN BIT(7)
69 #define SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN BIT(3)
71 #define SUN4I_I2S_INT_STA_REG 0x20
73 #define SUN4I_I2S_CLK_DIV_REG 0x24
74 #define SUN4I_I2S_CLK_DIV_MCLK_EN BIT(7)
75 #define SUN4I_I2S_CLK_DIV_BCLK_MASK GENMASK(6, 4)
76 #define SUN4I_I2S_CLK_DIV_BCLK(bclk) ((bclk) << 4)
77 #define SUN4I_I2S_CLK_DIV_MCLK_MASK GENMASK(3, 0)
78 #define SUN4I_I2S_CLK_DIV_MCLK(mclk) ((mclk) << 0)
80 #define SUN4I_I2S_TX_CNT_REG 0x28
81 #define SUN4I_I2S_RX_CNT_REG 0x2c
83 #define SUN4I_I2S_TX_CHAN_SEL_REG 0x30
84 #define SUN4I_I2S_CHAN_SEL_MASK GENMASK(2, 0)
85 #define SUN4I_I2S_CHAN_SEL(num_chan) (((num_chan) - 1) << 0)
87 #define SUN4I_I2S_TX_CHAN_MAP_REG 0x34
88 #define SUN4I_I2S_TX_CHAN_MAP(chan, sample) ((sample) << (chan << 2))
90 #define SUN4I_I2S_RX_CHAN_SEL_REG 0x38
91 #define SUN4I_I2S_RX_CHAN_MAP_REG 0x3c
93 /* Defines required for sun8i-h3 support */
94 #define SUN8I_I2S_CTRL_BCLK_OUT BIT(18)
95 #define SUN8I_I2S_CTRL_LRCK_OUT BIT(17)
97 #define SUN8I_I2S_CTRL_MODE_MASK GENMASK(5, 4)
98 #define SUN8I_I2S_CTRL_MODE_RIGHT (2 << 4)
99 #define SUN8I_I2S_CTRL_MODE_LEFT (1 << 4)
100 #define SUN8I_I2S_CTRL_MODE_PCM (0 << 4)
102 #define SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK BIT(19)
103 #define SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH (1 << 19)
104 #define SUN8I_I2S_FMT0_LRCLK_POLARITY_START_LOW (0 << 19)
105 #define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK GENMASK(17, 8)
106 #define SUN8I_I2S_FMT0_LRCK_PERIOD(period) ((period - 1) << 8)
107 #define SUN8I_I2S_FMT0_BCLK_POLARITY_MASK BIT(7)
108 #define SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED (1 << 7)
109 #define SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL (0 << 7)
111 #define SUN8I_I2S_FMT1_REG_SEXT_MASK GENMASK(5, 4)
112 #define SUN8I_I2S_FMT1_REG_SEXT(sext) ((sext) << 4)
114 #define SUN8I_I2S_INT_STA_REG 0x0c
115 #define SUN8I_I2S_FIFO_TX_REG 0x20
117 #define SUN8I_I2S_CHAN_CFG_REG 0x30
118 #define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK GENMASK(7, 4)
119 #define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(chan) ((chan - 1) << 4)
120 #define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK GENMASK(3, 0)
121 #define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(chan) (chan - 1)
123 #define SUN8I_I2S_TX_CHAN_MAP_REG 0x44
124 #define SUN8I_I2S_TX_CHAN_SEL_REG 0x34
125 #define SUN8I_I2S_TX_CHAN_OFFSET_MASK GENMASK(13, 12)
126 #define SUN8I_I2S_TX_CHAN_OFFSET(offset) (offset << 12)
127 #define SUN8I_I2S_TX_CHAN_EN_MASK GENMASK(11, 4)
128 #define SUN8I_I2S_TX_CHAN_EN(num_chan) (((1 << num_chan) - 1) << 4)
130 #define SUN8I_I2S_RX_CHAN_SEL_REG 0x54
131 #define SUN8I_I2S_RX_CHAN_MAP_REG 0x58
133 /* Defines required for sun50i-h6 support */
134 #define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK GENMASK(21, 20)
135 #define SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset) ((offset) << 20)
136 #define SUN50I_H6_I2S_TX_CHAN_SEL_MASK GENMASK(19, 16)
137 #define SUN50I_H6_I2S_TX_CHAN_SEL(chan) ((chan - 1) << 16)
138 #define SUN50I_H6_I2S_TX_CHAN_EN_MASK GENMASK(15, 0)
139 #define SUN50I_H6_I2S_TX_CHAN_EN(num_chan) (((1 << num_chan) - 1))
141 #define SUN50I_H6_I2S_TX_CHAN_SEL_REG(pin) (0x34 + 4 * (pin))
142 #define SUN50I_H6_I2S_TX_CHAN_MAP0_REG(pin) (0x44 + 8 * (pin))
143 #define SUN50I_H6_I2S_TX_CHAN_MAP1_REG(pin) (0x48 + 8 * (pin))
145 #define SUN50I_H6_I2S_RX_CHAN_SEL_REG 0x64
146 #define SUN50I_H6_I2S_RX_CHAN_MAP0_REG 0x68
147 #define SUN50I_H6_I2S_RX_CHAN_MAP1_REG 0x6C
149 #define SUN50I_R329_I2S_RX_CHAN_MAP0_REG 0x68
150 #define SUN50I_R329_I2S_RX_CHAN_MAP1_REG 0x6c
151 #define SUN50I_R329_I2S_RX_CHAN_MAP2_REG 0x70
152 #define SUN50I_R329_I2S_RX_CHAN_MAP3_REG 0x74
157 * struct sun4i_i2s_quirks - Differences between SoC variants.
158 * @has_reset: SoC needs reset deasserted.
159 * @pcm_formats: available PCM formats.
160 * @reg_offset_txdata: offset of the tx fifo.
161 * @sun4i_i2s_regmap: regmap config to use.
162 * @field_clkdiv_mclk_en: regmap field to enable mclk output.
163 * @field_fmt_wss: regmap field to set word select size.
164 * @field_fmt_sr: regmap field to set sample resolution.
165 * @num_din_pins: input pins
166 * @num_dout_pins: output pins (currently set but unused)
167 * @bclk_dividers: bit clock dividers array
168 * @num_bclk_dividers: number of bit clock dividers
169 * @mclk_dividers: mclk dividers array
170 * @num_mclk_dividers: number of mclk dividers
171 * @get_bclk_parent_rate: callback to get bclk parent rate
172 * @get_sr: callback to get sample resolution
173 * @get_wss: callback to get word select size
174 * @set_chan_cfg: callback to set channel configuration
175 * @set_fmt: callback to set format
177 struct sun4i_i2s_quirks
{
180 unsigned int reg_offset_txdata
; /* TX FIFO */
181 const struct regmap_config
*sun4i_i2s_regmap
;
183 /* Register fields for i2s */
184 struct reg_field field_clkdiv_mclk_en
;
185 struct reg_field field_fmt_wss
;
186 struct reg_field field_fmt_sr
;
188 unsigned int num_din_pins
;
189 unsigned int num_dout_pins
;
191 const struct sun4i_i2s_clk_div
*bclk_dividers
;
192 unsigned int num_bclk_dividers
;
193 const struct sun4i_i2s_clk_div
*mclk_dividers
;
194 unsigned int num_mclk_dividers
;
196 unsigned long (*get_bclk_parent_rate
)(const struct sun4i_i2s
*i2s
);
197 int (*get_sr
)(unsigned int width
);
198 int (*get_wss
)(unsigned int width
);
201 * In the set_chan_cfg() function pointer:
202 * @slots: channels per frame + padding slots, regardless of format
203 * @slot_width: bits per sample + padding bits, regardless of format
205 int (*set_chan_cfg
)(const struct sun4i_i2s
*i2s
,
206 unsigned int channels
, unsigned int slots
,
207 unsigned int slot_width
);
208 int (*set_fmt
)(const struct sun4i_i2s
*i2s
, unsigned int fmt
);
214 struct regmap
*regmap
;
215 struct reset_control
*rst
;
218 unsigned int mclk_freq
;
220 unsigned int slot_width
;
222 struct snd_dmaengine_dai_dma_data capture_dma_data
;
223 struct snd_dmaengine_dai_dma_data playback_dma_data
;
225 /* Register fields for i2s */
226 struct regmap_field
*field_clkdiv_mclk_en
;
227 struct regmap_field
*field_fmt_wss
;
228 struct regmap_field
*field_fmt_sr
;
230 const struct sun4i_i2s_quirks
*variant
;
233 struct sun4i_i2s_clk_div
{
238 static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div
[] = {
239 { .div
= 2, .val
= 0 },
240 { .div
= 4, .val
= 1 },
241 { .div
= 6, .val
= 2 },
242 { .div
= 8, .val
= 3 },
243 { .div
= 12, .val
= 4 },
244 { .div
= 16, .val
= 5 },
245 /* TODO - extend divide ratio supported by newer SoCs */
248 static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div
[] = {
249 { .div
= 1, .val
= 0 },
250 { .div
= 2, .val
= 1 },
251 { .div
= 4, .val
= 2 },
252 { .div
= 6, .val
= 3 },
253 { .div
= 8, .val
= 4 },
254 { .div
= 12, .val
= 5 },
255 { .div
= 16, .val
= 6 },
256 { .div
= 24, .val
= 7 },
257 /* TODO - extend divide ratio supported by newer SoCs */
260 static const struct sun4i_i2s_clk_div sun8i_i2s_clk_div
[] = {
261 { .div
= 1, .val
= 1 },
262 { .div
= 2, .val
= 2 },
263 { .div
= 4, .val
= 3 },
264 { .div
= 6, .val
= 4 },
265 { .div
= 8, .val
= 5 },
266 { .div
= 12, .val
= 6 },
267 { .div
= 16, .val
= 7 },
268 { .div
= 24, .val
= 8 },
269 { .div
= 32, .val
= 9 },
270 { .div
= 48, .val
= 10 },
271 { .div
= 64, .val
= 11 },
272 { .div
= 96, .val
= 12 },
273 { .div
= 128, .val
= 13 },
274 { .div
= 176, .val
= 14 },
275 { .div
= 192, .val
= 15 },
278 static unsigned long sun4i_i2s_get_bclk_parent_rate(const struct sun4i_i2s
*i2s
)
280 return i2s
->mclk_freq
;
283 static unsigned long sun8i_i2s_get_bclk_parent_rate(const struct sun4i_i2s
*i2s
)
285 return clk_get_rate(i2s
->mod_clk
);
288 static int sun4i_i2s_get_bclk_div(struct sun4i_i2s
*i2s
,
289 unsigned long parent_rate
,
290 unsigned int sampling_rate
,
291 unsigned int channels
,
292 unsigned int word_size
)
294 const struct sun4i_i2s_clk_div
*dividers
= i2s
->variant
->bclk_dividers
;
295 int div
= parent_rate
/ sampling_rate
/ word_size
/ channels
;
298 for (i
= 0; i
< i2s
->variant
->num_bclk_dividers
; i
++) {
299 const struct sun4i_i2s_clk_div
*bdiv
= ÷rs
[i
];
301 if (bdiv
->div
== div
)
308 static int sun4i_i2s_get_mclk_div(struct sun4i_i2s
*i2s
,
309 unsigned long parent_rate
,
310 unsigned long mclk_rate
)
312 const struct sun4i_i2s_clk_div
*dividers
= i2s
->variant
->mclk_dividers
;
313 int div
= parent_rate
/ mclk_rate
;
316 for (i
= 0; i
< i2s
->variant
->num_mclk_dividers
; i
++) {
317 const struct sun4i_i2s_clk_div
*mdiv
= ÷rs
[i
];
319 if (mdiv
->div
== div
)
326 static int sun4i_i2s_oversample_rates
[] = { 128, 192, 256, 384, 512, 768 };
327 static bool sun4i_i2s_oversample_is_valid(unsigned int oversample
)
331 for (i
= 0; i
< ARRAY_SIZE(sun4i_i2s_oversample_rates
); i
++)
332 if (sun4i_i2s_oversample_rates
[i
] == oversample
)
338 static int sun4i_i2s_set_clk_rate(struct snd_soc_dai
*dai
,
341 unsigned int slot_width
)
343 struct sun4i_i2s
*i2s
= snd_soc_dai_get_drvdata(dai
);
344 unsigned int oversample_rate
, clk_rate
, bclk_parent_rate
;
345 int bclk_div
, mclk_div
;
371 dev_err(dai
->dev
, "Unsupported sample rate: %u\n", rate
);
375 ret
= clk_set_rate(i2s
->mod_clk
, clk_rate
);
379 oversample_rate
= i2s
->mclk_freq
/ rate
;
380 if (!sun4i_i2s_oversample_is_valid(oversample_rate
)) {
381 dev_err(dai
->dev
, "Unsupported oversample rate: %d\n",
386 bclk_parent_rate
= i2s
->variant
->get_bclk_parent_rate(i2s
);
387 bclk_div
= sun4i_i2s_get_bclk_div(i2s
, bclk_parent_rate
,
388 rate
, slots
, slot_width
);
390 dev_err(dai
->dev
, "Unsupported BCLK divider: %d\n", bclk_div
);
394 mclk_div
= sun4i_i2s_get_mclk_div(i2s
, clk_rate
, i2s
->mclk_freq
);
396 dev_err(dai
->dev
, "Unsupported MCLK divider: %d\n", mclk_div
);
400 regmap_write(i2s
->regmap
, SUN4I_I2S_CLK_DIV_REG
,
401 SUN4I_I2S_CLK_DIV_BCLK(bclk_div
) |
402 SUN4I_I2S_CLK_DIV_MCLK(mclk_div
));
404 regmap_field_write(i2s
->field_clkdiv_mclk_en
, 1);
409 static int sun4i_i2s_get_sr(unsigned int width
)
423 static int sun4i_i2s_get_wss(unsigned int width
)
439 static int sun8i_i2s_get_sr_wss(unsigned int width
)
461 static int sun4i_i2s_set_chan_cfg(const struct sun4i_i2s
*i2s
,
462 unsigned int channels
, unsigned int slots
,
463 unsigned int slot_width
)
465 /* Map the channels for playback and capture */
466 regmap_write(i2s
->regmap
, SUN4I_I2S_TX_CHAN_MAP_REG
, 0x76543210);
467 regmap_write(i2s
->regmap
, SUN4I_I2S_RX_CHAN_MAP_REG
, 0x00003210);
469 /* Configure the channels */
470 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_TX_CHAN_SEL_REG
,
471 SUN4I_I2S_CHAN_SEL_MASK
,
472 SUN4I_I2S_CHAN_SEL(channels
));
473 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_RX_CHAN_SEL_REG
,
474 SUN4I_I2S_CHAN_SEL_MASK
,
475 SUN4I_I2S_CHAN_SEL(channels
));
480 static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s
*i2s
,
481 unsigned int channels
, unsigned int slots
,
482 unsigned int slot_width
)
484 unsigned int lrck_period
;
486 /* Map the channels for playback and capture */
487 regmap_write(i2s
->regmap
, SUN8I_I2S_TX_CHAN_MAP_REG
, 0x76543210);
488 regmap_write(i2s
->regmap
, SUN8I_I2S_RX_CHAN_MAP_REG
, 0x76543210);
490 /* Configure the channels */
491 regmap_update_bits(i2s
->regmap
, SUN8I_I2S_TX_CHAN_SEL_REG
,
492 SUN4I_I2S_CHAN_SEL_MASK
,
493 SUN4I_I2S_CHAN_SEL(channels
));
494 regmap_update_bits(i2s
->regmap
, SUN8I_I2S_RX_CHAN_SEL_REG
,
495 SUN4I_I2S_CHAN_SEL_MASK
,
496 SUN4I_I2S_CHAN_SEL(channels
));
498 regmap_update_bits(i2s
->regmap
, SUN8I_I2S_CHAN_CFG_REG
,
499 SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK
,
500 SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels
));
501 regmap_update_bits(i2s
->regmap
, SUN8I_I2S_CHAN_CFG_REG
,
502 SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK
,
503 SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels
));
505 switch (i2s
->format
& SND_SOC_DAIFMT_FORMAT_MASK
) {
506 case SND_SOC_DAIFMT_DSP_A
:
507 case SND_SOC_DAIFMT_DSP_B
:
508 lrck_period
= slot_width
* slots
;
511 case SND_SOC_DAIFMT_LEFT_J
:
512 case SND_SOC_DAIFMT_RIGHT_J
:
513 case SND_SOC_DAIFMT_I2S
:
514 lrck_period
= slot_width
;
521 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_FMT0_REG
,
522 SUN8I_I2S_FMT0_LRCK_PERIOD_MASK
,
523 SUN8I_I2S_FMT0_LRCK_PERIOD(lrck_period
));
525 regmap_update_bits(i2s
->regmap
, SUN8I_I2S_TX_CHAN_SEL_REG
,
526 SUN8I_I2S_TX_CHAN_EN_MASK
,
527 SUN8I_I2S_TX_CHAN_EN(channels
));
532 static int sun50i_h6_i2s_set_chan_cfg(const struct sun4i_i2s
*i2s
,
533 unsigned int channels
, unsigned int slots
,
534 unsigned int slot_width
)
536 unsigned int lrck_period
;
538 /* Map the channels for playback and capture */
539 regmap_write(i2s
->regmap
, SUN50I_H6_I2S_TX_CHAN_MAP0_REG(0), 0xFEDCBA98);
540 regmap_write(i2s
->regmap
, SUN50I_H6_I2S_TX_CHAN_MAP1_REG(0), 0x76543210);
541 if (i2s
->variant
->num_din_pins
> 1) {
542 regmap_write(i2s
->regmap
, SUN50I_R329_I2S_RX_CHAN_MAP0_REG
, 0x0F0E0D0C);
543 regmap_write(i2s
->regmap
, SUN50I_R329_I2S_RX_CHAN_MAP1_REG
, 0x0B0A0908);
544 regmap_write(i2s
->regmap
, SUN50I_R329_I2S_RX_CHAN_MAP2_REG
, 0x07060504);
545 regmap_write(i2s
->regmap
, SUN50I_R329_I2S_RX_CHAN_MAP3_REG
, 0x03020100);
547 regmap_write(i2s
->regmap
, SUN50I_H6_I2S_RX_CHAN_MAP0_REG
, 0xFEDCBA98);
548 regmap_write(i2s
->regmap
, SUN50I_H6_I2S_RX_CHAN_MAP1_REG
, 0x76543210);
551 /* Configure the channels */
552 regmap_update_bits(i2s
->regmap
, SUN50I_H6_I2S_TX_CHAN_SEL_REG(0),
553 SUN50I_H6_I2S_TX_CHAN_SEL_MASK
,
554 SUN50I_H6_I2S_TX_CHAN_SEL(channels
));
555 regmap_update_bits(i2s
->regmap
, SUN50I_H6_I2S_RX_CHAN_SEL_REG
,
556 SUN50I_H6_I2S_TX_CHAN_SEL_MASK
,
557 SUN50I_H6_I2S_TX_CHAN_SEL(channels
));
559 regmap_update_bits(i2s
->regmap
, SUN8I_I2S_CHAN_CFG_REG
,
560 SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK
,
561 SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels
));
562 regmap_update_bits(i2s
->regmap
, SUN8I_I2S_CHAN_CFG_REG
,
563 SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK
,
564 SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels
));
566 switch (i2s
->format
& SND_SOC_DAIFMT_FORMAT_MASK
) {
567 case SND_SOC_DAIFMT_DSP_A
:
568 case SND_SOC_DAIFMT_DSP_B
:
569 lrck_period
= slot_width
* slots
;
572 case SND_SOC_DAIFMT_LEFT_J
:
573 case SND_SOC_DAIFMT_RIGHT_J
:
574 case SND_SOC_DAIFMT_I2S
:
575 lrck_period
= slot_width
;
582 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_FMT0_REG
,
583 SUN8I_I2S_FMT0_LRCK_PERIOD_MASK
,
584 SUN8I_I2S_FMT0_LRCK_PERIOD(lrck_period
));
586 regmap_update_bits(i2s
->regmap
, SUN50I_H6_I2S_TX_CHAN_SEL_REG(0),
587 SUN50I_H6_I2S_TX_CHAN_EN_MASK
,
588 SUN50I_H6_I2S_TX_CHAN_EN(channels
));
593 static int sun4i_i2s_hw_params(struct snd_pcm_substream
*substream
,
594 struct snd_pcm_hw_params
*params
,
595 struct snd_soc_dai
*dai
)
597 struct sun4i_i2s
*i2s
= snd_soc_dai_get_drvdata(dai
);
598 unsigned int word_size
= params_width(params
);
599 unsigned int slot_width
= params_physical_width(params
);
600 unsigned int channels
= params_channels(params
);
602 unsigned int slots
= channels
;
611 slot_width
= i2s
->slot_width
;
613 ret
= i2s
->variant
->set_chan_cfg(i2s
, channels
, slots
, slot_width
);
615 dev_err(dai
->dev
, "Invalid channel configuration\n");
619 /* Set significant bits in our FIFOs */
620 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_FIFO_CTRL_REG
,
621 SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK
|
622 SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK
,
623 SUN4I_I2S_FIFO_CTRL_TX_MODE(1) |
624 SUN4I_I2S_FIFO_CTRL_RX_MODE(1));
626 switch (params_physical_width(params
)) {
628 width
= DMA_SLAVE_BUSWIDTH_2_BYTES
;
631 width
= DMA_SLAVE_BUSWIDTH_4_BYTES
;
634 dev_err(dai
->dev
, "Unsupported physical sample width: %d\n",
635 params_physical_width(params
));
638 i2s
->playback_dma_data
.addr_width
= width
;
640 sr
= i2s
->variant
->get_sr(word_size
);
644 wss
= i2s
->variant
->get_wss(slot_width
);
648 regmap_field_write(i2s
->field_fmt_wss
, wss
);
649 regmap_field_write(i2s
->field_fmt_sr
, sr
);
651 return sun4i_i2s_set_clk_rate(dai
, params_rate(params
),
655 static int sun4i_i2s_set_soc_fmt(const struct sun4i_i2s
*i2s
,
660 /* DAI clock polarity */
661 switch (fmt
& SND_SOC_DAIFMT_INV_MASK
) {
662 case SND_SOC_DAIFMT_IB_IF
:
663 /* Invert both clocks */
664 val
= SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED
|
665 SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED
;
667 case SND_SOC_DAIFMT_IB_NF
:
668 /* Invert bit clock */
669 val
= SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED
;
671 case SND_SOC_DAIFMT_NB_IF
:
672 /* Invert frame clock */
673 val
= SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED
;
675 case SND_SOC_DAIFMT_NB_NF
:
682 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_FMT0_REG
,
683 SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK
|
684 SUN4I_I2S_FMT0_BCLK_POLARITY_MASK
,
688 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
689 case SND_SOC_DAIFMT_I2S
:
690 val
= SUN4I_I2S_FMT0_FMT_I2S
;
693 case SND_SOC_DAIFMT_LEFT_J
:
694 val
= SUN4I_I2S_FMT0_FMT_LEFT_J
;
697 case SND_SOC_DAIFMT_RIGHT_J
:
698 val
= SUN4I_I2S_FMT0_FMT_RIGHT_J
;
705 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_FMT0_REG
,
706 SUN4I_I2S_FMT0_FMT_MASK
, val
);
708 /* DAI clock master masks */
709 switch (fmt
& SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK
) {
710 case SND_SOC_DAIFMT_BP_FP
:
711 /* BCLK and LRCLK master */
712 val
= SUN4I_I2S_CTRL_MODE_MASTER
;
715 case SND_SOC_DAIFMT_BC_FC
:
716 /* BCLK and LRCLK slave */
717 val
= SUN4I_I2S_CTRL_MODE_SLAVE
;
723 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_CTRL_REG
,
724 SUN4I_I2S_CTRL_MODE_MASK
, val
);
729 static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s
*i2s
,
732 u32 mode
, lrclk_pol
, bclk_pol
, val
;
736 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
737 case SND_SOC_DAIFMT_DSP_A
:
738 lrclk_pol
= SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH
;
739 mode
= SUN8I_I2S_CTRL_MODE_PCM
;
743 case SND_SOC_DAIFMT_DSP_B
:
744 lrclk_pol
= SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH
;
745 mode
= SUN8I_I2S_CTRL_MODE_PCM
;
749 case SND_SOC_DAIFMT_I2S
:
750 lrclk_pol
= SUN8I_I2S_FMT0_LRCLK_POLARITY_START_LOW
;
751 mode
= SUN8I_I2S_CTRL_MODE_LEFT
;
755 case SND_SOC_DAIFMT_LEFT_J
:
756 lrclk_pol
= SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH
;
757 mode
= SUN8I_I2S_CTRL_MODE_LEFT
;
761 case SND_SOC_DAIFMT_RIGHT_J
:
762 lrclk_pol
= SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH
;
763 mode
= SUN8I_I2S_CTRL_MODE_RIGHT
;
771 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_CTRL_REG
,
772 SUN8I_I2S_CTRL_MODE_MASK
, mode
);
773 regmap_update_bits(i2s
->regmap
, SUN8I_I2S_TX_CHAN_SEL_REG
,
774 SUN8I_I2S_TX_CHAN_OFFSET_MASK
,
775 SUN8I_I2S_TX_CHAN_OFFSET(offset
));
776 regmap_update_bits(i2s
->regmap
, SUN8I_I2S_RX_CHAN_SEL_REG
,
777 SUN8I_I2S_TX_CHAN_OFFSET_MASK
,
778 SUN8I_I2S_TX_CHAN_OFFSET(offset
));
780 /* DAI clock polarity */
781 bclk_pol
= SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL
;
783 switch (fmt
& SND_SOC_DAIFMT_INV_MASK
) {
784 case SND_SOC_DAIFMT_IB_IF
:
785 /* Invert both clocks */
786 lrclk_pol
^= SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK
;
787 bclk_pol
= SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED
;
789 case SND_SOC_DAIFMT_IB_NF
:
790 /* Invert bit clock */
791 bclk_pol
= SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED
;
793 case SND_SOC_DAIFMT_NB_IF
:
794 /* Invert frame clock */
795 lrclk_pol
^= SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK
;
797 case SND_SOC_DAIFMT_NB_NF
:
804 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_FMT0_REG
,
805 SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK
|
806 SUN8I_I2S_FMT0_BCLK_POLARITY_MASK
,
807 lrclk_pol
| bclk_pol
);
809 /* DAI clock master masks */
810 switch (fmt
& SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK
) {
811 case SND_SOC_DAIFMT_BP_FP
:
812 /* BCLK and LRCLK master */
813 val
= SUN8I_I2S_CTRL_BCLK_OUT
| SUN8I_I2S_CTRL_LRCK_OUT
;
816 case SND_SOC_DAIFMT_BC_FC
:
817 /* BCLK and LRCLK slave */
825 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_CTRL_REG
,
826 SUN8I_I2S_CTRL_BCLK_OUT
| SUN8I_I2S_CTRL_LRCK_OUT
,
829 /* Set sign extension to pad out LSB with 0 */
830 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_FMT1_REG
,
831 SUN8I_I2S_FMT1_REG_SEXT_MASK
,
832 SUN8I_I2S_FMT1_REG_SEXT(0));
837 static int sun50i_h6_i2s_set_soc_fmt(const struct sun4i_i2s
*i2s
,
840 u32 mode
, lrclk_pol
, bclk_pol
, val
;
844 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
845 case SND_SOC_DAIFMT_DSP_A
:
846 lrclk_pol
= SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH
;
847 mode
= SUN8I_I2S_CTRL_MODE_PCM
;
851 case SND_SOC_DAIFMT_DSP_B
:
852 lrclk_pol
= SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH
;
853 mode
= SUN8I_I2S_CTRL_MODE_PCM
;
857 case SND_SOC_DAIFMT_I2S
:
858 lrclk_pol
= SUN8I_I2S_FMT0_LRCLK_POLARITY_START_LOW
;
859 mode
= SUN8I_I2S_CTRL_MODE_LEFT
;
863 case SND_SOC_DAIFMT_LEFT_J
:
864 lrclk_pol
= SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH
;
865 mode
= SUN8I_I2S_CTRL_MODE_LEFT
;
869 case SND_SOC_DAIFMT_RIGHT_J
:
870 lrclk_pol
= SUN8I_I2S_FMT0_LRCLK_POLARITY_START_HIGH
;
871 mode
= SUN8I_I2S_CTRL_MODE_RIGHT
;
879 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_CTRL_REG
,
880 SUN8I_I2S_CTRL_MODE_MASK
, mode
);
881 regmap_update_bits(i2s
->regmap
, SUN8I_I2S_TX_CHAN_SEL_REG
,
882 SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK
,
883 SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset
));
884 regmap_update_bits(i2s
->regmap
, SUN50I_H6_I2S_RX_CHAN_SEL_REG
,
885 SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET_MASK
,
886 SUN50I_H6_I2S_TX_CHAN_SEL_OFFSET(offset
));
888 /* DAI clock polarity */
889 bclk_pol
= SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL
;
891 switch (fmt
& SND_SOC_DAIFMT_INV_MASK
) {
892 case SND_SOC_DAIFMT_IB_IF
:
893 /* Invert both clocks */
894 lrclk_pol
^= SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK
;
895 bclk_pol
= SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED
;
897 case SND_SOC_DAIFMT_IB_NF
:
898 /* Invert bit clock */
899 bclk_pol
= SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED
;
901 case SND_SOC_DAIFMT_NB_IF
:
902 /* Invert frame clock */
903 lrclk_pol
^= SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK
;
905 case SND_SOC_DAIFMT_NB_NF
:
912 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_FMT0_REG
,
913 SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK
|
914 SUN8I_I2S_FMT0_BCLK_POLARITY_MASK
,
915 lrclk_pol
| bclk_pol
);
918 /* DAI clock master masks */
919 switch (fmt
& SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK
) {
920 case SND_SOC_DAIFMT_BP_FP
:
921 /* BCLK and LRCLK master */
922 val
= SUN8I_I2S_CTRL_BCLK_OUT
| SUN8I_I2S_CTRL_LRCK_OUT
;
925 case SND_SOC_DAIFMT_BC_FC
:
926 /* BCLK and LRCLK slave */
934 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_CTRL_REG
,
935 SUN8I_I2S_CTRL_BCLK_OUT
| SUN8I_I2S_CTRL_LRCK_OUT
,
938 /* Set sign extension to pad out LSB with 0 */
939 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_FMT1_REG
,
940 SUN8I_I2S_FMT1_REG_SEXT_MASK
,
941 SUN8I_I2S_FMT1_REG_SEXT(0));
946 static int sun4i_i2s_set_fmt(struct snd_soc_dai
*dai
, unsigned int fmt
)
948 struct sun4i_i2s
*i2s
= snd_soc_dai_get_drvdata(dai
);
951 ret
= i2s
->variant
->set_fmt(i2s
, fmt
);
953 dev_err(dai
->dev
, "Unsupported format configuration\n");
962 static void sun4i_i2s_start_capture(struct sun4i_i2s
*i2s
)
965 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_FIFO_CTRL_REG
,
966 SUN4I_I2S_FIFO_CTRL_FLUSH_RX
,
967 SUN4I_I2S_FIFO_CTRL_FLUSH_RX
);
969 /* Clear RX counter */
970 regmap_write(i2s
->regmap
, SUN4I_I2S_RX_CNT_REG
, 0);
972 /* Enable RX Block */
973 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_CTRL_REG
,
974 SUN4I_I2S_CTRL_RX_EN
,
975 SUN4I_I2S_CTRL_RX_EN
);
978 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_DMA_INT_CTRL_REG
,
979 SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN
,
980 SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN
);
983 static void sun4i_i2s_start_playback(struct sun4i_i2s
*i2s
)
986 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_FIFO_CTRL_REG
,
987 SUN4I_I2S_FIFO_CTRL_FLUSH_TX
,
988 SUN4I_I2S_FIFO_CTRL_FLUSH_TX
);
990 /* Clear TX counter */
991 regmap_write(i2s
->regmap
, SUN4I_I2S_TX_CNT_REG
, 0);
993 /* Enable TX Block */
994 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_CTRL_REG
,
995 SUN4I_I2S_CTRL_TX_EN
,
996 SUN4I_I2S_CTRL_TX_EN
);
999 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_DMA_INT_CTRL_REG
,
1000 SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN
,
1001 SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN
);
1004 static void sun4i_i2s_stop_capture(struct sun4i_i2s
*i2s
)
1006 /* Disable RX Block */
1007 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_CTRL_REG
,
1008 SUN4I_I2S_CTRL_RX_EN
,
1011 /* Disable RX DRQ */
1012 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_DMA_INT_CTRL_REG
,
1013 SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN
,
1017 static void sun4i_i2s_stop_playback(struct sun4i_i2s
*i2s
)
1019 /* Disable TX Block */
1020 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_CTRL_REG
,
1021 SUN4I_I2S_CTRL_TX_EN
,
1024 /* Disable TX DRQ */
1025 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_DMA_INT_CTRL_REG
,
1026 SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN
,
1030 static int sun4i_i2s_trigger(struct snd_pcm_substream
*substream
, int cmd
,
1031 struct snd_soc_dai
*dai
)
1033 struct sun4i_i2s
*i2s
= snd_soc_dai_get_drvdata(dai
);
1036 case SNDRV_PCM_TRIGGER_START
:
1037 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
1038 case SNDRV_PCM_TRIGGER_RESUME
:
1039 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
1040 sun4i_i2s_start_playback(i2s
);
1042 sun4i_i2s_start_capture(i2s
);
1045 case SNDRV_PCM_TRIGGER_STOP
:
1046 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
1047 case SNDRV_PCM_TRIGGER_SUSPEND
:
1048 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
1049 sun4i_i2s_stop_playback(i2s
);
1051 sun4i_i2s_stop_capture(i2s
);
1061 static int sun4i_i2s_set_sysclk(struct snd_soc_dai
*dai
, int clk_id
,
1062 unsigned int freq
, int dir
)
1064 struct sun4i_i2s
*i2s
= snd_soc_dai_get_drvdata(dai
);
1069 i2s
->mclk_freq
= freq
;
1074 static int sun4i_i2s_set_tdm_slot(struct snd_soc_dai
*dai
,
1075 unsigned int tx_mask
, unsigned int rx_mask
,
1076 int slots
, int slot_width
)
1078 struct sun4i_i2s
*i2s
= snd_soc_dai_get_drvdata(dai
);
1084 i2s
->slot_width
= slot_width
;
1089 static int sun4i_i2s_dai_probe(struct snd_soc_dai
*dai
)
1091 struct sun4i_i2s
*i2s
= snd_soc_dai_get_drvdata(dai
);
1093 snd_soc_dai_init_dma_data(dai
,
1094 &i2s
->playback_dma_data
,
1095 &i2s
->capture_dma_data
);
1100 static int sun4i_i2s_dai_startup(struct snd_pcm_substream
*sub
, struct snd_soc_dai
*dai
)
1102 struct sun4i_i2s
*i2s
= snd_soc_dai_get_drvdata(dai
);
1103 struct snd_pcm_runtime
*runtime
= sub
->runtime
;
1105 return snd_pcm_hw_constraint_mask64(runtime
, SNDRV_PCM_HW_PARAM_FORMAT
,
1106 i2s
->variant
->pcm_formats
);
1109 static const struct snd_soc_dai_ops sun4i_i2s_dai_ops
= {
1110 .probe
= sun4i_i2s_dai_probe
,
1111 .startup
= sun4i_i2s_dai_startup
,
1112 .hw_params
= sun4i_i2s_hw_params
,
1113 .set_fmt
= sun4i_i2s_set_fmt
,
1114 .set_sysclk
= sun4i_i2s_set_sysclk
,
1115 .set_tdm_slot
= sun4i_i2s_set_tdm_slot
,
1116 .trigger
= sun4i_i2s_trigger
,
1119 #define SUN4I_FORMATS_ALL (SNDRV_PCM_FMTBIT_S16_LE | \
1120 SNDRV_PCM_FMTBIT_S20_LE | \
1121 SNDRV_PCM_FMTBIT_S24_LE | \
1122 SNDRV_PCM_FMTBIT_S32_LE)
1124 static struct snd_soc_dai_driver sun4i_i2s_dai
= {
1126 .stream_name
= "Capture",
1129 .rates
= SNDRV_PCM_RATE_8000_192000
,
1130 .formats
= SUN4I_FORMATS_ALL
,
1133 .stream_name
= "Playback",
1136 .rates
= SNDRV_PCM_RATE_8000_192000
,
1137 .formats
= SUN4I_FORMATS_ALL
,
1139 .ops
= &sun4i_i2s_dai_ops
,
1140 .symmetric_rate
= 1,
1143 static const struct snd_soc_component_driver sun4i_i2s_component
= {
1144 .name
= "sun4i-dai",
1145 .legacy_dai_naming
= 1,
1148 static bool sun4i_i2s_rd_reg(struct device
*dev
, unsigned int reg
)
1151 case SUN4I_I2S_FIFO_TX_REG
:
1159 static bool sun4i_i2s_wr_reg(struct device
*dev
, unsigned int reg
)
1162 case SUN4I_I2S_FIFO_RX_REG
:
1163 case SUN4I_I2S_FIFO_STA_REG
:
1171 static bool sun4i_i2s_volatile_reg(struct device
*dev
, unsigned int reg
)
1174 case SUN4I_I2S_FIFO_RX_REG
:
1175 case SUN4I_I2S_INT_STA_REG
:
1176 case SUN4I_I2S_RX_CNT_REG
:
1177 case SUN4I_I2S_TX_CNT_REG
:
1185 static bool sun8i_i2s_rd_reg(struct device
*dev
, unsigned int reg
)
1188 case SUN8I_I2S_FIFO_TX_REG
:
1196 static bool sun8i_i2s_volatile_reg(struct device
*dev
, unsigned int reg
)
1199 case SUN4I_I2S_FIFO_CTRL_REG
:
1200 case SUN4I_I2S_FIFO_RX_REG
:
1201 case SUN4I_I2S_FIFO_STA_REG
:
1202 case SUN4I_I2S_RX_CNT_REG
:
1203 case SUN4I_I2S_TX_CNT_REG
:
1204 case SUN8I_I2S_FIFO_TX_REG
:
1205 case SUN8I_I2S_INT_STA_REG
:
1213 static const struct reg_default sun4i_i2s_reg_defaults
[] = {
1214 { SUN4I_I2S_CTRL_REG
, 0x00000000 },
1215 { SUN4I_I2S_FMT0_REG
, 0x0000000c },
1216 { SUN4I_I2S_FMT1_REG
, 0x00004020 },
1217 { SUN4I_I2S_FIFO_CTRL_REG
, 0x000400f0 },
1218 { SUN4I_I2S_DMA_INT_CTRL_REG
, 0x00000000 },
1219 { SUN4I_I2S_CLK_DIV_REG
, 0x00000000 },
1220 { SUN4I_I2S_TX_CHAN_SEL_REG
, 0x00000001 },
1221 { SUN4I_I2S_TX_CHAN_MAP_REG
, 0x76543210 },
1222 { SUN4I_I2S_RX_CHAN_SEL_REG
, 0x00000001 },
1223 { SUN4I_I2S_RX_CHAN_MAP_REG
, 0x00003210 },
1226 static const struct reg_default sun8i_i2s_reg_defaults
[] = {
1227 { SUN4I_I2S_CTRL_REG
, 0x00060000 },
1228 { SUN4I_I2S_FMT0_REG
, 0x00000033 },
1229 { SUN4I_I2S_FMT1_REG
, 0x00000030 },
1230 { SUN4I_I2S_FIFO_CTRL_REG
, 0x000400f0 },
1231 { SUN4I_I2S_DMA_INT_CTRL_REG
, 0x00000000 },
1232 { SUN4I_I2S_CLK_DIV_REG
, 0x00000000 },
1233 { SUN8I_I2S_CHAN_CFG_REG
, 0x00000000 },
1234 { SUN8I_I2S_TX_CHAN_SEL_REG
, 0x00000000 },
1235 { SUN8I_I2S_TX_CHAN_MAP_REG
, 0x00000000 },
1236 { SUN8I_I2S_RX_CHAN_SEL_REG
, 0x00000000 },
1237 { SUN8I_I2S_RX_CHAN_MAP_REG
, 0x00000000 },
1240 static const struct reg_default sun50i_h6_i2s_reg_defaults
[] = {
1241 { SUN4I_I2S_CTRL_REG
, 0x00060000 },
1242 { SUN4I_I2S_FMT0_REG
, 0x00000033 },
1243 { SUN4I_I2S_FMT1_REG
, 0x00000030 },
1244 { SUN4I_I2S_FIFO_CTRL_REG
, 0x000400f0 },
1245 { SUN4I_I2S_DMA_INT_CTRL_REG
, 0x00000000 },
1246 { SUN4I_I2S_CLK_DIV_REG
, 0x00000000 },
1247 { SUN8I_I2S_CHAN_CFG_REG
, 0x00000000 },
1248 { SUN50I_H6_I2S_TX_CHAN_SEL_REG(0), 0x00000000 },
1249 { SUN50I_H6_I2S_TX_CHAN_MAP0_REG(0), 0x00000000 },
1250 { SUN50I_H6_I2S_TX_CHAN_MAP1_REG(0), 0x00000000 },
1251 { SUN50I_H6_I2S_RX_CHAN_SEL_REG
, 0x00000000 },
1252 { SUN50I_H6_I2S_RX_CHAN_MAP0_REG
, 0x00000000 },
1253 { SUN50I_H6_I2S_RX_CHAN_MAP1_REG
, 0x00000000 },
1256 static const struct regmap_config sun4i_i2s_regmap_config
= {
1260 .max_register
= SUN4I_I2S_RX_CHAN_MAP_REG
,
1262 .cache_type
= REGCACHE_FLAT
,
1263 .reg_defaults
= sun4i_i2s_reg_defaults
,
1264 .num_reg_defaults
= ARRAY_SIZE(sun4i_i2s_reg_defaults
),
1265 .writeable_reg
= sun4i_i2s_wr_reg
,
1266 .readable_reg
= sun4i_i2s_rd_reg
,
1267 .volatile_reg
= sun4i_i2s_volatile_reg
,
1270 static const struct regmap_config sun8i_i2s_regmap_config
= {
1274 .max_register
= SUN8I_I2S_RX_CHAN_MAP_REG
,
1275 .cache_type
= REGCACHE_FLAT
,
1276 .reg_defaults
= sun8i_i2s_reg_defaults
,
1277 .num_reg_defaults
= ARRAY_SIZE(sun8i_i2s_reg_defaults
),
1278 .writeable_reg
= sun4i_i2s_wr_reg
,
1279 .readable_reg
= sun8i_i2s_rd_reg
,
1280 .volatile_reg
= sun8i_i2s_volatile_reg
,
1283 static const struct regmap_config sun50i_h6_i2s_regmap_config
= {
1287 .max_register
= SUN50I_R329_I2S_RX_CHAN_MAP3_REG
,
1288 .cache_type
= REGCACHE_FLAT
,
1289 .reg_defaults
= sun50i_h6_i2s_reg_defaults
,
1290 .num_reg_defaults
= ARRAY_SIZE(sun50i_h6_i2s_reg_defaults
),
1291 .writeable_reg
= sun4i_i2s_wr_reg
,
1292 .readable_reg
= sun8i_i2s_rd_reg
,
1293 .volatile_reg
= sun8i_i2s_volatile_reg
,
1296 static int sun4i_i2s_runtime_resume(struct device
*dev
)
1298 struct sun4i_i2s
*i2s
= dev_get_drvdata(dev
);
1301 ret
= clk_prepare_enable(i2s
->bus_clk
);
1303 dev_err(dev
, "Failed to enable bus clock\n");
1307 regcache_cache_only(i2s
->regmap
, false);
1308 regcache_mark_dirty(i2s
->regmap
);
1310 ret
= regcache_sync(i2s
->regmap
);
1312 dev_err(dev
, "Failed to sync regmap cache\n");
1313 goto err_disable_clk
;
1316 /* Enable the whole hardware block */
1317 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_CTRL_REG
,
1318 SUN4I_I2S_CTRL_GL_EN
, SUN4I_I2S_CTRL_GL_EN
);
1320 /* Enable the first output line */
1321 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_CTRL_REG
,
1322 SUN4I_I2S_CTRL_SDO_EN_MASK
,
1323 SUN4I_I2S_CTRL_SDO_EN(0));
1325 ret
= clk_prepare_enable(i2s
->mod_clk
);
1327 dev_err(dev
, "Failed to enable module clock\n");
1328 goto err_disable_clk
;
1334 clk_disable_unprepare(i2s
->bus_clk
);
1338 static int sun4i_i2s_runtime_suspend(struct device
*dev
)
1340 struct sun4i_i2s
*i2s
= dev_get_drvdata(dev
);
1342 clk_disable_unprepare(i2s
->mod_clk
);
1344 /* Disable our output lines */
1345 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_CTRL_REG
,
1346 SUN4I_I2S_CTRL_SDO_EN_MASK
, 0);
1348 /* Disable the whole hardware block */
1349 regmap_update_bits(i2s
->regmap
, SUN4I_I2S_CTRL_REG
,
1350 SUN4I_I2S_CTRL_GL_EN
, 0);
1352 regcache_cache_only(i2s
->regmap
, true);
1354 clk_disable_unprepare(i2s
->bus_clk
);
1359 #define SUN4I_FORMATS_A10 (SUN4I_FORMATS_ALL & ~SNDRV_PCM_FMTBIT_S32_LE)
1360 #define SUN4I_FORMATS_H3 SUN4I_FORMATS_ALL
1362 static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks
= {
1364 .pcm_formats
= SUN4I_FORMATS_A10
,
1365 .reg_offset_txdata
= SUN4I_I2S_FIFO_TX_REG
,
1366 .sun4i_i2s_regmap
= &sun4i_i2s_regmap_config
,
1367 .field_clkdiv_mclk_en
= REG_FIELD(SUN4I_I2S_CLK_DIV_REG
, 7, 7),
1368 .field_fmt_wss
= REG_FIELD(SUN4I_I2S_FMT0_REG
, 2, 3),
1369 .field_fmt_sr
= REG_FIELD(SUN4I_I2S_FMT0_REG
, 4, 5),
1370 .bclk_dividers
= sun4i_i2s_bclk_div
,
1371 .num_bclk_dividers
= ARRAY_SIZE(sun4i_i2s_bclk_div
),
1372 .mclk_dividers
= sun4i_i2s_mclk_div
,
1373 .num_mclk_dividers
= ARRAY_SIZE(sun4i_i2s_mclk_div
),
1374 .get_bclk_parent_rate
= sun4i_i2s_get_bclk_parent_rate
,
1375 .get_sr
= sun4i_i2s_get_sr
,
1376 .get_wss
= sun4i_i2s_get_wss
,
1377 .set_chan_cfg
= sun4i_i2s_set_chan_cfg
,
1378 .set_fmt
= sun4i_i2s_set_soc_fmt
,
1381 static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks
= {
1383 .pcm_formats
= SUN4I_FORMATS_A10
,
1384 .reg_offset_txdata
= SUN4I_I2S_FIFO_TX_REG
,
1385 .sun4i_i2s_regmap
= &sun4i_i2s_regmap_config
,
1386 .field_clkdiv_mclk_en
= REG_FIELD(SUN4I_I2S_CLK_DIV_REG
, 7, 7),
1387 .field_fmt_wss
= REG_FIELD(SUN4I_I2S_FMT0_REG
, 2, 3),
1388 .field_fmt_sr
= REG_FIELD(SUN4I_I2S_FMT0_REG
, 4, 5),
1389 .bclk_dividers
= sun4i_i2s_bclk_div
,
1390 .num_bclk_dividers
= ARRAY_SIZE(sun4i_i2s_bclk_div
),
1391 .mclk_dividers
= sun4i_i2s_mclk_div
,
1392 .num_mclk_dividers
= ARRAY_SIZE(sun4i_i2s_mclk_div
),
1393 .get_bclk_parent_rate
= sun4i_i2s_get_bclk_parent_rate
,
1394 .get_sr
= sun4i_i2s_get_sr
,
1395 .get_wss
= sun4i_i2s_get_wss
,
1396 .set_chan_cfg
= sun4i_i2s_set_chan_cfg
,
1397 .set_fmt
= sun4i_i2s_set_soc_fmt
,
1401 * This doesn't describe the TDM controller documented in the A83t
1402 * datasheet, but the three undocumented I2S controller that use the
1405 static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks
= {
1407 .pcm_formats
= SUN4I_FORMATS_A10
,
1408 .reg_offset_txdata
= SUN8I_I2S_FIFO_TX_REG
,
1409 .sun4i_i2s_regmap
= &sun4i_i2s_regmap_config
,
1410 .field_clkdiv_mclk_en
= REG_FIELD(SUN4I_I2S_CLK_DIV_REG
, 7, 7),
1411 .field_fmt_wss
= REG_FIELD(SUN4I_I2S_FMT0_REG
, 2, 3),
1412 .field_fmt_sr
= REG_FIELD(SUN4I_I2S_FMT0_REG
, 4, 5),
1413 .bclk_dividers
= sun4i_i2s_bclk_div
,
1414 .num_bclk_dividers
= ARRAY_SIZE(sun4i_i2s_bclk_div
),
1415 .mclk_dividers
= sun4i_i2s_mclk_div
,
1416 .num_mclk_dividers
= ARRAY_SIZE(sun4i_i2s_mclk_div
),
1417 .get_bclk_parent_rate
= sun4i_i2s_get_bclk_parent_rate
,
1418 .get_sr
= sun4i_i2s_get_sr
,
1419 .get_wss
= sun4i_i2s_get_wss
,
1420 .set_chan_cfg
= sun4i_i2s_set_chan_cfg
,
1421 .set_fmt
= sun4i_i2s_set_soc_fmt
,
1424 static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks
= {
1426 .pcm_formats
= SUN4I_FORMATS_H3
,
1427 .reg_offset_txdata
= SUN8I_I2S_FIFO_TX_REG
,
1428 .sun4i_i2s_regmap
= &sun8i_i2s_regmap_config
,
1429 .field_clkdiv_mclk_en
= REG_FIELD(SUN4I_I2S_CLK_DIV_REG
, 8, 8),
1430 .field_fmt_wss
= REG_FIELD(SUN4I_I2S_FMT0_REG
, 0, 2),
1431 .field_fmt_sr
= REG_FIELD(SUN4I_I2S_FMT0_REG
, 4, 6),
1432 .bclk_dividers
= sun8i_i2s_clk_div
,
1433 .num_bclk_dividers
= ARRAY_SIZE(sun8i_i2s_clk_div
),
1434 .mclk_dividers
= sun8i_i2s_clk_div
,
1435 .num_mclk_dividers
= ARRAY_SIZE(sun8i_i2s_clk_div
),
1436 .get_bclk_parent_rate
= sun8i_i2s_get_bclk_parent_rate
,
1437 .get_sr
= sun8i_i2s_get_sr_wss
,
1438 .get_wss
= sun8i_i2s_get_sr_wss
,
1439 .set_chan_cfg
= sun8i_i2s_set_chan_cfg
,
1440 .set_fmt
= sun8i_i2s_set_soc_fmt
,
1443 static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks
= {
1445 .pcm_formats
= SUN4I_FORMATS_H3
,
1446 .reg_offset_txdata
= SUN8I_I2S_FIFO_TX_REG
,
1447 .sun4i_i2s_regmap
= &sun4i_i2s_regmap_config
,
1448 .field_clkdiv_mclk_en
= REG_FIELD(SUN4I_I2S_CLK_DIV_REG
, 7, 7),
1449 .field_fmt_wss
= REG_FIELD(SUN4I_I2S_FMT0_REG
, 2, 3),
1450 .field_fmt_sr
= REG_FIELD(SUN4I_I2S_FMT0_REG
, 4, 5),
1451 .bclk_dividers
= sun4i_i2s_bclk_div
,
1452 .num_bclk_dividers
= ARRAY_SIZE(sun4i_i2s_bclk_div
),
1453 .mclk_dividers
= sun4i_i2s_mclk_div
,
1454 .num_mclk_dividers
= ARRAY_SIZE(sun4i_i2s_mclk_div
),
1455 .get_bclk_parent_rate
= sun4i_i2s_get_bclk_parent_rate
,
1456 .get_sr
= sun4i_i2s_get_sr
,
1457 .get_wss
= sun4i_i2s_get_wss
,
1458 .set_chan_cfg
= sun4i_i2s_set_chan_cfg
,
1459 .set_fmt
= sun4i_i2s_set_soc_fmt
,
1462 static const struct sun4i_i2s_quirks sun50i_h6_i2s_quirks
= {
1464 .pcm_formats
= SUN4I_FORMATS_H3
,
1465 .reg_offset_txdata
= SUN8I_I2S_FIFO_TX_REG
,
1466 .sun4i_i2s_regmap
= &sun50i_h6_i2s_regmap_config
,
1467 .field_clkdiv_mclk_en
= REG_FIELD(SUN4I_I2S_CLK_DIV_REG
, 8, 8),
1468 .field_fmt_wss
= REG_FIELD(SUN4I_I2S_FMT0_REG
, 0, 2),
1469 .field_fmt_sr
= REG_FIELD(SUN4I_I2S_FMT0_REG
, 4, 6),
1470 .bclk_dividers
= sun8i_i2s_clk_div
,
1471 .num_bclk_dividers
= ARRAY_SIZE(sun8i_i2s_clk_div
),
1472 .mclk_dividers
= sun8i_i2s_clk_div
,
1473 .num_mclk_dividers
= ARRAY_SIZE(sun8i_i2s_clk_div
),
1474 .get_bclk_parent_rate
= sun8i_i2s_get_bclk_parent_rate
,
1475 .get_sr
= sun8i_i2s_get_sr_wss
,
1476 .get_wss
= sun8i_i2s_get_sr_wss
,
1477 .set_chan_cfg
= sun50i_h6_i2s_set_chan_cfg
,
1478 .set_fmt
= sun50i_h6_i2s_set_soc_fmt
,
1481 static const struct sun4i_i2s_quirks sun50i_r329_i2s_quirks
= {
1483 .pcm_formats
= SUN4I_FORMATS_H3
,
1484 .reg_offset_txdata
= SUN8I_I2S_FIFO_TX_REG
,
1485 .sun4i_i2s_regmap
= &sun50i_h6_i2s_regmap_config
,
1486 .field_clkdiv_mclk_en
= REG_FIELD(SUN4I_I2S_CLK_DIV_REG
, 8, 8),
1487 .field_fmt_wss
= REG_FIELD(SUN4I_I2S_FMT0_REG
, 0, 2),
1488 .field_fmt_sr
= REG_FIELD(SUN4I_I2S_FMT0_REG
, 4, 6),
1491 .bclk_dividers
= sun8i_i2s_clk_div
,
1492 .num_bclk_dividers
= ARRAY_SIZE(sun8i_i2s_clk_div
),
1493 .mclk_dividers
= sun8i_i2s_clk_div
,
1494 .num_mclk_dividers
= ARRAY_SIZE(sun8i_i2s_clk_div
),
1495 .get_bclk_parent_rate
= sun8i_i2s_get_bclk_parent_rate
,
1496 .get_sr
= sun8i_i2s_get_sr_wss
,
1497 .get_wss
= sun8i_i2s_get_sr_wss
,
1498 .set_chan_cfg
= sun50i_h6_i2s_set_chan_cfg
,
1499 .set_fmt
= sun50i_h6_i2s_set_soc_fmt
,
1502 static int sun4i_i2s_init_regmap_fields(struct device
*dev
,
1503 struct sun4i_i2s
*i2s
)
1505 i2s
->field_clkdiv_mclk_en
=
1506 devm_regmap_field_alloc(dev
, i2s
->regmap
,
1507 i2s
->variant
->field_clkdiv_mclk_en
);
1508 if (IS_ERR(i2s
->field_clkdiv_mclk_en
))
1509 return PTR_ERR(i2s
->field_clkdiv_mclk_en
);
1511 i2s
->field_fmt_wss
=
1512 devm_regmap_field_alloc(dev
, i2s
->regmap
,
1513 i2s
->variant
->field_fmt_wss
);
1514 if (IS_ERR(i2s
->field_fmt_wss
))
1515 return PTR_ERR(i2s
->field_fmt_wss
);
1518 devm_regmap_field_alloc(dev
, i2s
->regmap
,
1519 i2s
->variant
->field_fmt_sr
);
1520 if (IS_ERR(i2s
->field_fmt_sr
))
1521 return PTR_ERR(i2s
->field_fmt_sr
);
1526 static int sun4i_i2s_probe(struct platform_device
*pdev
)
1528 struct sun4i_i2s
*i2s
;
1529 struct resource
*res
;
1533 i2s
= devm_kzalloc(&pdev
->dev
, sizeof(*i2s
), GFP_KERNEL
);
1536 platform_set_drvdata(pdev
, i2s
);
1538 regs
= devm_platform_get_and_ioremap_resource(pdev
, 0, &res
);
1540 return PTR_ERR(regs
);
1542 irq
= platform_get_irq(pdev
, 0);
1546 i2s
->variant
= of_device_get_match_data(&pdev
->dev
);
1547 if (!i2s
->variant
) {
1548 dev_err(&pdev
->dev
, "Failed to determine the quirks to use\n");
1552 i2s
->bus_clk
= devm_clk_get(&pdev
->dev
, "apb");
1553 if (IS_ERR(i2s
->bus_clk
)) {
1554 dev_err(&pdev
->dev
, "Can't get our bus clock\n");
1555 return PTR_ERR(i2s
->bus_clk
);
1558 i2s
->regmap
= devm_regmap_init_mmio(&pdev
->dev
, regs
,
1559 i2s
->variant
->sun4i_i2s_regmap
);
1560 if (IS_ERR(i2s
->regmap
)) {
1561 dev_err(&pdev
->dev
, "Regmap initialisation failed\n");
1562 return PTR_ERR(i2s
->regmap
);
1565 i2s
->mod_clk
= devm_clk_get(&pdev
->dev
, "mod");
1566 if (IS_ERR(i2s
->mod_clk
)) {
1567 dev_err(&pdev
->dev
, "Can't get our mod clock\n");
1568 return PTR_ERR(i2s
->mod_clk
);
1571 if (i2s
->variant
->has_reset
) {
1572 i2s
->rst
= devm_reset_control_get_exclusive(&pdev
->dev
, NULL
);
1573 if (IS_ERR(i2s
->rst
)) {
1574 dev_err(&pdev
->dev
, "Failed to get reset control\n");
1575 return PTR_ERR(i2s
->rst
);
1579 if (!IS_ERR(i2s
->rst
)) {
1580 ret
= reset_control_deassert(i2s
->rst
);
1583 "Failed to deassert the reset control\n");
1588 i2s
->playback_dma_data
.addr
= res
->start
+
1589 i2s
->variant
->reg_offset_txdata
;
1590 i2s
->playback_dma_data
.maxburst
= 8;
1592 i2s
->capture_dma_data
.addr
= res
->start
+ SUN4I_I2S_FIFO_RX_REG
;
1593 i2s
->capture_dma_data
.maxburst
= 8;
1595 pm_runtime_enable(&pdev
->dev
);
1596 if (!pm_runtime_enabled(&pdev
->dev
)) {
1597 ret
= sun4i_i2s_runtime_resume(&pdev
->dev
);
1599 goto err_pm_disable
;
1602 ret
= sun4i_i2s_init_regmap_fields(&pdev
->dev
, i2s
);
1604 dev_err(&pdev
->dev
, "Could not initialise regmap fields\n");
1608 ret
= devm_snd_dmaengine_pcm_register(&pdev
->dev
, NULL
, 0);
1610 dev_err(&pdev
->dev
, "Could not register PCM\n");
1614 ret
= devm_snd_soc_register_component(&pdev
->dev
,
1615 &sun4i_i2s_component
,
1618 dev_err(&pdev
->dev
, "Could not register DAI\n");
1625 if (!pm_runtime_status_suspended(&pdev
->dev
))
1626 sun4i_i2s_runtime_suspend(&pdev
->dev
);
1628 pm_runtime_disable(&pdev
->dev
);
1629 if (!IS_ERR(i2s
->rst
))
1630 reset_control_assert(i2s
->rst
);
1635 static void sun4i_i2s_remove(struct platform_device
*pdev
)
1637 struct sun4i_i2s
*i2s
= dev_get_drvdata(&pdev
->dev
);
1639 pm_runtime_disable(&pdev
->dev
);
1640 if (!pm_runtime_status_suspended(&pdev
->dev
))
1641 sun4i_i2s_runtime_suspend(&pdev
->dev
);
1643 if (!IS_ERR(i2s
->rst
))
1644 reset_control_assert(i2s
->rst
);
1647 static const struct of_device_id sun4i_i2s_match
[] = {
1649 .compatible
= "allwinner,sun4i-a10-i2s",
1650 .data
= &sun4i_a10_i2s_quirks
,
1653 .compatible
= "allwinner,sun6i-a31-i2s",
1654 .data
= &sun6i_a31_i2s_quirks
,
1657 .compatible
= "allwinner,sun8i-a83t-i2s",
1658 .data
= &sun8i_a83t_i2s_quirks
,
1661 .compatible
= "allwinner,sun8i-h3-i2s",
1662 .data
= &sun8i_h3_i2s_quirks
,
1665 .compatible
= "allwinner,sun50i-a64-codec-i2s",
1666 .data
= &sun50i_a64_codec_i2s_quirks
,
1669 .compatible
= "allwinner,sun50i-h6-i2s",
1670 .data
= &sun50i_h6_i2s_quirks
,
1673 .compatible
= "allwinner,sun50i-r329-i2s",
1674 .data
= &sun50i_r329_i2s_quirks
,
1678 MODULE_DEVICE_TABLE(of
, sun4i_i2s_match
);
1680 static const struct dev_pm_ops sun4i_i2s_pm_ops
= {
1681 .runtime_resume
= sun4i_i2s_runtime_resume
,
1682 .runtime_suspend
= sun4i_i2s_runtime_suspend
,
1685 static struct platform_driver sun4i_i2s_driver
= {
1686 .probe
= sun4i_i2s_probe
,
1687 .remove
= sun4i_i2s_remove
,
1689 .name
= "sun4i-i2s",
1690 .of_match_table
= sun4i_i2s_match
,
1691 .pm
= &sun4i_i2s_pm_ops
,
1694 module_platform_driver(sun4i_i2s_driver
);
1696 MODULE_AUTHOR("Andrea Venturi <be17068@iperbole.bo.it>");
1697 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
1698 MODULE_DESCRIPTION("Allwinner A10 I2S driver");
1699 MODULE_LICENSE("GPL");