]> asedeno.scripts.mit.edu Git - linux.git/blob - sound/soc/sunxi/sun4i-i2s.c
ASoC: sun4i-i2s: Fix the LRCK polarity
[linux.git] / sound / soc / sunxi / sun4i-i2s.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2015 Andrea Venturi
4  * Andrea Venturi <be17068@iperbole.bo.it>
5  *
6  * Copyright (C) 2016 Maxime Ripard
7  * Maxime Ripard <maxime.ripard@free-electrons.com>
8  */
9
10 #include <linux/clk.h>
11 #include <linux/dmaengine.h>
12 #include <linux/module.h>
13 #include <linux/of_device.h>
14 #include <linux/platform_device.h>
15 #include <linux/pm_runtime.h>
16 #include <linux/regmap.h>
17 #include <linux/reset.h>
18
19 #include <sound/dmaengine_pcm.h>
20 #include <sound/pcm_params.h>
21 #include <sound/soc.h>
22 #include <sound/soc-dai.h>
23
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)
33
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)
49
50 #define SUN4I_I2S_FMT1_REG              0x08
51 #define SUN4I_I2S_FIFO_TX_REG           0x0c
52 #define SUN4I_I2S_FIFO_RX_REG           0x10
53
54 #define SUN4I_I2S_FIFO_CTRL_REG         0x14
55 #define SUN4I_I2S_FIFO_CTRL_FLUSH_TX            BIT(25)
56 #define SUN4I_I2S_FIFO_CTRL_FLUSH_RX            BIT(24)
57 #define SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK        BIT(2)
58 #define SUN4I_I2S_FIFO_CTRL_TX_MODE(mode)               ((mode) << 2)
59 #define SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK        GENMASK(1, 0)
60 #define SUN4I_I2S_FIFO_CTRL_RX_MODE(mode)               (mode)
61
62 #define SUN4I_I2S_FIFO_STA_REG          0x18
63
64 #define SUN4I_I2S_DMA_INT_CTRL_REG      0x1c
65 #define SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN        BIT(7)
66 #define SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN        BIT(3)
67
68 #define SUN4I_I2S_INT_STA_REG           0x20
69
70 #define SUN4I_I2S_CLK_DIV_REG           0x24
71 #define SUN4I_I2S_CLK_DIV_MCLK_EN               BIT(7)
72 #define SUN4I_I2S_CLK_DIV_BCLK_MASK             GENMASK(6, 4)
73 #define SUN4I_I2S_CLK_DIV_BCLK(bclk)                    ((bclk) << 4)
74 #define SUN4I_I2S_CLK_DIV_MCLK_MASK             GENMASK(3, 0)
75 #define SUN4I_I2S_CLK_DIV_MCLK(mclk)                    ((mclk) << 0)
76
77 #define SUN4I_I2S_TX_CNT_REG            0x28
78 #define SUN4I_I2S_RX_CNT_REG            0x2c
79
80 #define SUN4I_I2S_TX_CHAN_SEL_REG       0x30
81 #define SUN4I_I2S_CHAN_SEL_MASK                 GENMASK(2, 0)
82 #define SUN4I_I2S_CHAN_SEL(num_chan)            (((num_chan) - 1) << 0)
83
84 #define SUN4I_I2S_TX_CHAN_MAP_REG       0x34
85 #define SUN4I_I2S_TX_CHAN_MAP(chan, sample)     ((sample) << (chan << 2))
86
87 #define SUN4I_I2S_RX_CHAN_SEL_REG       0x38
88 #define SUN4I_I2S_RX_CHAN_MAP_REG       0x3c
89
90 /* Defines required for sun8i-h3 support */
91 #define SUN8I_I2S_CTRL_BCLK_OUT                 BIT(18)
92 #define SUN8I_I2S_CTRL_LRCK_OUT                 BIT(17)
93
94 #define SUN8I_I2S_CTRL_MODE_MASK                GENMASK(5, 4)
95 #define SUN8I_I2S_CTRL_MODE_RIGHT               (2 << 4)
96 #define SUN8I_I2S_CTRL_MODE_LEFT                (1 << 4)
97 #define SUN8I_I2S_CTRL_MODE_PCM                 (0 << 4)
98
99 #define SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK      BIT(19)
100 #define SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED          (1 << 19)
101 #define SUN8I_I2S_FMT0_LRCLK_POLARITY_NORMAL            (0 << 19)
102 #define SUN8I_I2S_FMT0_LRCK_PERIOD_MASK         GENMASK(17, 8)
103 #define SUN8I_I2S_FMT0_LRCK_PERIOD(period)      ((period - 1) << 8)
104 #define SUN8I_I2S_FMT0_BCLK_POLARITY_MASK       BIT(7)
105 #define SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED           (1 << 7)
106 #define SUN8I_I2S_FMT0_BCLK_POLARITY_NORMAL             (0 << 7)
107
108 #define SUN8I_I2S_INT_STA_REG           0x0c
109 #define SUN8I_I2S_FIFO_TX_REG           0x20
110
111 #define SUN8I_I2S_CHAN_CFG_REG          0x30
112 #define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK     GENMASK(6, 4)
113 #define SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(chan)    ((chan - 1) << 4)
114 #define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK     GENMASK(2, 0)
115 #define SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(chan)    (chan - 1)
116
117 #define SUN8I_I2S_TX_CHAN_MAP_REG       0x44
118 #define SUN8I_I2S_TX_CHAN_SEL_REG       0x34
119 #define SUN8I_I2S_TX_CHAN_OFFSET_MASK           GENMASK(13, 12)
120 #define SUN8I_I2S_TX_CHAN_OFFSET(offset)        (offset << 12)
121 #define SUN8I_I2S_TX_CHAN_EN_MASK               GENMASK(11, 4)
122 #define SUN8I_I2S_TX_CHAN_EN(num_chan)          (((1 << num_chan) - 1) << 4)
123
124 #define SUN8I_I2S_RX_CHAN_SEL_REG       0x54
125 #define SUN8I_I2S_RX_CHAN_MAP_REG       0x58
126
127 struct sun4i_i2s;
128
129 /**
130  * struct sun4i_i2s_quirks - Differences between SoC variants.
131  *
132  * @has_reset: SoC needs reset deasserted.
133  * @has_fmt_set_lrck_period: SoC requires lrclk period to be set.
134  * @reg_offset_txdata: offset of the tx fifo.
135  * @sun4i_i2s_regmap: regmap config to use.
136  * @field_clkdiv_mclk_en: regmap field to enable mclk output.
137  * @field_fmt_wss: regmap field to set word select size.
138  * @field_fmt_sr: regmap field to set sample resolution.
139  */
140 struct sun4i_i2s_quirks {
141         bool                            has_reset;
142         bool                            has_fmt_set_lrck_period;
143         unsigned int                    reg_offset_txdata;      /* TX FIFO */
144         const struct regmap_config      *sun4i_i2s_regmap;
145
146         /* Register fields for i2s */
147         struct reg_field                field_clkdiv_mclk_en;
148         struct reg_field                field_fmt_wss;
149         struct reg_field                field_fmt_sr;
150
151         const struct sun4i_i2s_clk_div  *bclk_dividers;
152         unsigned int                    num_bclk_dividers;
153         const struct sun4i_i2s_clk_div  *mclk_dividers;
154         unsigned int                    num_mclk_dividers;
155
156         unsigned long (*get_bclk_parent_rate)(const struct sun4i_i2s *);
157         s8      (*get_sr)(const struct sun4i_i2s *, int);
158         s8      (*get_wss)(const struct sun4i_i2s *, int);
159         int     (*set_chan_cfg)(const struct sun4i_i2s *,
160                                 const struct snd_pcm_hw_params *);
161         int     (*set_fmt)(const struct sun4i_i2s *, unsigned int);
162 };
163
164 struct sun4i_i2s {
165         struct clk      *bus_clk;
166         struct clk      *mod_clk;
167         struct regmap   *regmap;
168         struct reset_control *rst;
169
170         unsigned int    mclk_freq;
171
172         struct snd_dmaengine_dai_dma_data       capture_dma_data;
173         struct snd_dmaengine_dai_dma_data       playback_dma_data;
174
175         /* Register fields for i2s */
176         struct regmap_field     *field_clkdiv_mclk_en;
177         struct regmap_field     *field_fmt_wss;
178         struct regmap_field     *field_fmt_sr;
179
180         const struct sun4i_i2s_quirks   *variant;
181 };
182
183 struct sun4i_i2s_clk_div {
184         u8      div;
185         u8      val;
186 };
187
188 static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
189         { .div = 2, .val = 0 },
190         { .div = 4, .val = 1 },
191         { .div = 6, .val = 2 },
192         { .div = 8, .val = 3 },
193         { .div = 12, .val = 4 },
194         { .div = 16, .val = 5 },
195         /* TODO - extend divide ratio supported by newer SoCs */
196 };
197
198 static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = {
199         { .div = 1, .val = 0 },
200         { .div = 2, .val = 1 },
201         { .div = 4, .val = 2 },
202         { .div = 6, .val = 3 },
203         { .div = 8, .val = 4 },
204         { .div = 12, .val = 5 },
205         { .div = 16, .val = 6 },
206         { .div = 24, .val = 7 },
207         /* TODO - extend divide ratio supported by newer SoCs */
208 };
209
210 static const struct sun4i_i2s_clk_div sun8i_i2s_clk_div[] = {
211         { .div = 1, .val = 1 },
212         { .div = 2, .val = 2 },
213         { .div = 4, .val = 3 },
214         { .div = 6, .val = 4 },
215         { .div = 8, .val = 5 },
216         { .div = 12, .val = 6 },
217         { .div = 16, .val = 7 },
218         { .div = 24, .val = 8 },
219         { .div = 32, .val = 9 },
220         { .div = 48, .val = 10 },
221         { .div = 64, .val = 11 },
222         { .div = 96, .val = 12 },
223         { .div = 128, .val = 13 },
224         { .div = 176, .val = 14 },
225         { .div = 192, .val = 15 },
226 };
227
228 static unsigned long sun4i_i2s_get_bclk_parent_rate(const struct sun4i_i2s *i2s)
229 {
230         return i2s->mclk_freq;
231 }
232
233 static unsigned long sun8i_i2s_get_bclk_parent_rate(const struct sun4i_i2s *i2s)
234 {
235         return clk_get_rate(i2s->mod_clk);
236 }
237
238 static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s,
239                                   unsigned long parent_rate,
240                                   unsigned int sampling_rate,
241                                   unsigned int word_size)
242 {
243         const struct sun4i_i2s_clk_div *dividers = i2s->variant->bclk_dividers;
244         int div = parent_rate / sampling_rate / word_size / 2;
245         int i;
246
247         for (i = 0; i < i2s->variant->num_bclk_dividers; i++) {
248                 const struct sun4i_i2s_clk_div *bdiv = &dividers[i];
249
250                 if (bdiv->div == div)
251                         return bdiv->val;
252         }
253
254         return -EINVAL;
255 }
256
257 static int sun4i_i2s_get_mclk_div(struct sun4i_i2s *i2s,
258                                   unsigned long parent_rate,
259                                   unsigned long mclk_rate)
260 {
261         const struct sun4i_i2s_clk_div *dividers = i2s->variant->mclk_dividers;
262         int div = parent_rate / mclk_rate;
263         int i;
264
265         for (i = 0; i < i2s->variant->num_mclk_dividers; i++) {
266                 const struct sun4i_i2s_clk_div *mdiv = &dividers[i];
267
268                 if (mdiv->div == div)
269                         return mdiv->val;
270         }
271
272         return -EINVAL;
273 }
274
275 static int sun4i_i2s_oversample_rates[] = { 128, 192, 256, 384, 512, 768 };
276 static bool sun4i_i2s_oversample_is_valid(unsigned int oversample)
277 {
278         int i;
279
280         for (i = 0; i < ARRAY_SIZE(sun4i_i2s_oversample_rates); i++)
281                 if (sun4i_i2s_oversample_rates[i] == oversample)
282                         return true;
283
284         return false;
285 }
286
287 static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
288                                   unsigned int rate,
289                                   unsigned int word_size)
290 {
291         struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
292         unsigned int oversample_rate, clk_rate, bclk_parent_rate;
293         int bclk_div, mclk_div;
294         int ret;
295
296         switch (rate) {
297         case 176400:
298         case 88200:
299         case 44100:
300         case 22050:
301         case 11025:
302                 clk_rate = 22579200;
303                 break;
304
305         case 192000:
306         case 128000:
307         case 96000:
308         case 64000:
309         case 48000:
310         case 32000:
311         case 24000:
312         case 16000:
313         case 12000:
314         case 8000:
315                 clk_rate = 24576000;
316                 break;
317
318         default:
319                 dev_err(dai->dev, "Unsupported sample rate: %u\n", rate);
320                 return -EINVAL;
321         }
322
323         ret = clk_set_rate(i2s->mod_clk, clk_rate);
324         if (ret)
325                 return ret;
326
327         oversample_rate = i2s->mclk_freq / rate;
328         if (!sun4i_i2s_oversample_is_valid(oversample_rate)) {
329                 dev_err(dai->dev, "Unsupported oversample rate: %d\n",
330                         oversample_rate);
331                 return -EINVAL;
332         }
333
334         bclk_parent_rate = i2s->variant->get_bclk_parent_rate(i2s);
335         bclk_div = sun4i_i2s_get_bclk_div(i2s, bclk_parent_rate,
336                                           rate, word_size);
337         if (bclk_div < 0) {
338                 dev_err(dai->dev, "Unsupported BCLK divider: %d\n", bclk_div);
339                 return -EINVAL;
340         }
341
342         mclk_div = sun4i_i2s_get_mclk_div(i2s, clk_rate, i2s->mclk_freq);
343         if (mclk_div < 0) {
344                 dev_err(dai->dev, "Unsupported MCLK divider: %d\n", mclk_div);
345                 return -EINVAL;
346         }
347
348         regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG,
349                      SUN4I_I2S_CLK_DIV_BCLK(bclk_div) |
350                      SUN4I_I2S_CLK_DIV_MCLK(mclk_div));
351
352         regmap_field_write(i2s->field_clkdiv_mclk_en, 1);
353
354         /* Set sync period */
355         if (i2s->variant->has_fmt_set_lrck_period)
356                 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
357                                    SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
358                                    SUN8I_I2S_FMT0_LRCK_PERIOD(32));
359
360         return 0;
361 }
362
363 static s8 sun4i_i2s_get_sr(const struct sun4i_i2s *i2s, int width)
364 {
365         if (width < 16 || width > 24)
366                 return -EINVAL;
367
368         if (width % 4)
369                 return -EINVAL;
370
371         return (width - 16) / 4;
372 }
373
374 static s8 sun4i_i2s_get_wss(const struct sun4i_i2s *i2s, int width)
375 {
376         if (width < 16 || width > 32)
377                 return -EINVAL;
378
379         if (width % 4)
380                 return -EINVAL;
381
382         return (width - 16) / 4;
383 }
384
385 static s8 sun8i_i2s_get_sr_wss(const struct sun4i_i2s *i2s, int width)
386 {
387         if (width % 4)
388                 return -EINVAL;
389
390         if (width < 8 || width > 32)
391                 return -EINVAL;
392
393         return (width - 8) / 4 + 1;
394 }
395
396 static int sun4i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
397                                   const struct snd_pcm_hw_params *params)
398 {
399         unsigned int channels = params_channels(params);
400
401         if (channels != 2)
402                 return -EINVAL;
403
404         /* Map the channels for playback and capture */
405         regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210);
406         regmap_write(i2s->regmap, SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210);
407
408         /* Configure the channels */
409         regmap_update_bits(i2s->regmap, SUN4I_I2S_TX_CHAN_SEL_REG,
410                            SUN4I_I2S_CHAN_SEL_MASK,
411                            SUN4I_I2S_CHAN_SEL(channels));
412         regmap_update_bits(i2s->regmap, SUN4I_I2S_RX_CHAN_SEL_REG,
413                            SUN4I_I2S_CHAN_SEL_MASK,
414                            SUN4I_I2S_CHAN_SEL(channels));
415
416         return 0;
417 }
418
419 static int sun8i_i2s_set_chan_cfg(const struct sun4i_i2s *i2s,
420                                   const struct snd_pcm_hw_params *params)
421 {
422         unsigned int channels = params_channels(params);
423
424         if (channels != 2)
425                 return -EINVAL;
426
427         /* Map the channels for playback and capture */
428         regmap_write(i2s->regmap, SUN8I_I2S_TX_CHAN_MAP_REG, 0x76543210);
429         regmap_write(i2s->regmap, SUN8I_I2S_RX_CHAN_MAP_REG, 0x76543210);
430
431         /* Configure the channels */
432         regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
433                            SUN4I_I2S_CHAN_SEL_MASK,
434                            SUN4I_I2S_CHAN_SEL(channels));
435
436         regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
437                            SUN4I_I2S_CHAN_SEL_MASK,
438                            SUN4I_I2S_CHAN_SEL(channels));
439
440         regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
441                            SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM_MASK,
442                            SUN8I_I2S_CHAN_CFG_TX_SLOT_NUM(channels));
443         regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG,
444                            SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM_MASK,
445                            SUN8I_I2S_CHAN_CFG_RX_SLOT_NUM(channels));
446
447         regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
448                            SUN8I_I2S_TX_CHAN_EN_MASK,
449                            SUN8I_I2S_TX_CHAN_EN(channels));
450
451         return 0;
452 }
453
454 static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
455                                struct snd_pcm_hw_params *params,
456                                struct snd_soc_dai *dai)
457 {
458         struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
459         int ret, sr, wss;
460         u32 width;
461
462         ret = i2s->variant->set_chan_cfg(i2s, params);
463         if (ret < 0) {
464                 dev_err(dai->dev, "Invalid channel configuration\n");
465                 return ret;
466         }
467
468         switch (params_physical_width(params)) {
469         case 16:
470                 width = DMA_SLAVE_BUSWIDTH_2_BYTES;
471                 break;
472         default:
473                 dev_err(dai->dev, "Unsupported physical sample width: %d\n",
474                         params_physical_width(params));
475                 return -EINVAL;
476         }
477         i2s->playback_dma_data.addr_width = width;
478
479         sr = i2s->variant->get_sr(i2s, params_width(params));
480         if (sr < 0)
481                 return -EINVAL;
482
483         wss = i2s->variant->get_wss(i2s, params_width(params));
484         if (wss < 0)
485                 return -EINVAL;
486
487         regmap_field_write(i2s->field_fmt_wss, wss);
488         regmap_field_write(i2s->field_fmt_sr, sr);
489
490         return sun4i_i2s_set_clk_rate(dai, params_rate(params),
491                                       params_width(params));
492 }
493
494 static int sun4i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
495                                  unsigned int fmt)
496 {
497         u32 val;
498
499         /* DAI clock polarity */
500         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
501         case SND_SOC_DAIFMT_IB_IF:
502                 /* Invert both clocks */
503                 val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED |
504                       SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
505                 break;
506         case SND_SOC_DAIFMT_IB_NF:
507                 /* Invert bit clock */
508                 val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED;
509                 break;
510         case SND_SOC_DAIFMT_NB_IF:
511                 /* Invert frame clock */
512                 val = SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
513                 break;
514         case SND_SOC_DAIFMT_NB_NF:
515                 val = 0;
516                 break;
517         default:
518                 return -EINVAL;
519         }
520
521         regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
522                            SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK |
523                            SUN4I_I2S_FMT0_BCLK_POLARITY_MASK,
524                            val);
525
526         /* DAI Mode */
527         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
528         case SND_SOC_DAIFMT_I2S:
529                 val = SUN4I_I2S_FMT0_FMT_I2S;
530                 break;
531
532         case SND_SOC_DAIFMT_LEFT_J:
533                 val = SUN4I_I2S_FMT0_FMT_LEFT_J;
534                 break;
535
536         case SND_SOC_DAIFMT_RIGHT_J:
537                 val = SUN4I_I2S_FMT0_FMT_RIGHT_J;
538                 break;
539
540         default:
541                 return -EINVAL;
542         }
543
544         regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
545                            SUN4I_I2S_FMT0_FMT_MASK, val);
546
547         /* DAI clock master masks */
548         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
549         case SND_SOC_DAIFMT_CBS_CFS:
550                 /* BCLK and LRCLK master */
551                 val = SUN4I_I2S_CTRL_MODE_MASTER;
552                 break;
553
554         case SND_SOC_DAIFMT_CBM_CFM:
555                 /* BCLK and LRCLK slave */
556                 val = SUN4I_I2S_CTRL_MODE_SLAVE;
557                 break;
558
559         default:
560                 return -EINVAL;
561         }
562         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
563                            SUN4I_I2S_CTRL_MODE_MASK, val);
564         return 0;
565 }
566
567 static int sun8i_i2s_set_soc_fmt(const struct sun4i_i2s *i2s,
568                                  unsigned int fmt)
569 {
570         u32 mode, val;
571         u8 offset;
572
573         /*
574          * DAI clock polarity
575          *
576          * The setup for LRCK contradicts the datasheet, but under a
577          * scope it's clear that the LRCK polarity is reversed
578          * compared to the expected polarity on the bus.
579          */
580         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
581         case SND_SOC_DAIFMT_IB_IF:
582                 /* Invert both clocks */
583                 val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED;
584                 break;
585         case SND_SOC_DAIFMT_IB_NF:
586                 /* Invert bit clock */
587                 val = SUN8I_I2S_FMT0_BCLK_POLARITY_INVERTED |
588                       SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
589                 break;
590         case SND_SOC_DAIFMT_NB_IF:
591                 /* Invert frame clock */
592                 val = 0;
593                 break;
594         case SND_SOC_DAIFMT_NB_NF:
595                 val = SUN8I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
596                 break;
597         default:
598                 return -EINVAL;
599         }
600
601         regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
602                            SUN8I_I2S_FMT0_LRCLK_POLARITY_MASK |
603                            SUN8I_I2S_FMT0_BCLK_POLARITY_MASK,
604                            val);
605
606         /* DAI Mode */
607         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
608         case SND_SOC_DAIFMT_I2S:
609                 mode = SUN8I_I2S_CTRL_MODE_LEFT;
610                 offset = 1;
611                 break;
612
613         case SND_SOC_DAIFMT_LEFT_J:
614                 mode = SUN8I_I2S_CTRL_MODE_LEFT;
615                 offset = 0;
616                 break;
617
618         case SND_SOC_DAIFMT_RIGHT_J:
619                 mode = SUN8I_I2S_CTRL_MODE_RIGHT;
620                 offset = 0;
621                 break;
622
623         default:
624                 return -EINVAL;
625         }
626
627         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
628                            SUN8I_I2S_CTRL_MODE_MASK, mode);
629         regmap_update_bits(i2s->regmap, SUN8I_I2S_TX_CHAN_SEL_REG,
630                            SUN8I_I2S_TX_CHAN_OFFSET_MASK,
631                            SUN8I_I2S_TX_CHAN_OFFSET(offset));
632         regmap_update_bits(i2s->regmap, SUN8I_I2S_RX_CHAN_SEL_REG,
633                            SUN8I_I2S_TX_CHAN_OFFSET_MASK,
634                            SUN8I_I2S_TX_CHAN_OFFSET(offset));
635
636         /* DAI clock master masks */
637         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
638         case SND_SOC_DAIFMT_CBS_CFS:
639                 /* BCLK and LRCLK master */
640                 val = SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT;
641                 break;
642
643         case SND_SOC_DAIFMT_CBM_CFM:
644                 /* BCLK and LRCLK slave */
645                 val = 0;
646                 break;
647
648         default:
649                 return -EINVAL;
650         }
651
652         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
653                            SUN8I_I2S_CTRL_BCLK_OUT | SUN8I_I2S_CTRL_LRCK_OUT,
654                            val);
655
656         return 0;
657 }
658
659 static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
660 {
661         struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
662         int ret;
663
664         ret = i2s->variant->set_fmt(i2s, fmt);
665         if (ret) {
666                 dev_err(dai->dev, "Unsupported format configuration\n");
667                 return ret;
668         }
669
670         /* Set significant bits in our FIFOs */
671         regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
672                            SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK |
673                            SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK,
674                            SUN4I_I2S_FIFO_CTRL_TX_MODE(1) |
675                            SUN4I_I2S_FIFO_CTRL_RX_MODE(1));
676         return 0;
677 }
678
679 static void sun4i_i2s_start_capture(struct sun4i_i2s *i2s)
680 {
681         /* Flush RX FIFO */
682         regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
683                            SUN4I_I2S_FIFO_CTRL_FLUSH_RX,
684                            SUN4I_I2S_FIFO_CTRL_FLUSH_RX);
685
686         /* Clear RX counter */
687         regmap_write(i2s->regmap, SUN4I_I2S_RX_CNT_REG, 0);
688
689         /* Enable RX Block */
690         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
691                            SUN4I_I2S_CTRL_RX_EN,
692                            SUN4I_I2S_CTRL_RX_EN);
693
694         /* Enable RX DRQ */
695         regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
696                            SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN,
697                            SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN);
698 }
699
700 static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s)
701 {
702         /* Flush TX FIFO */
703         regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
704                            SUN4I_I2S_FIFO_CTRL_FLUSH_TX,
705                            SUN4I_I2S_FIFO_CTRL_FLUSH_TX);
706
707         /* Clear TX counter */
708         regmap_write(i2s->regmap, SUN4I_I2S_TX_CNT_REG, 0);
709
710         /* Enable TX Block */
711         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
712                            SUN4I_I2S_CTRL_TX_EN,
713                            SUN4I_I2S_CTRL_TX_EN);
714
715         /* Enable TX DRQ */
716         regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
717                            SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN,
718                            SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN);
719 }
720
721 static void sun4i_i2s_stop_capture(struct sun4i_i2s *i2s)
722 {
723         /* Disable RX Block */
724         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
725                            SUN4I_I2S_CTRL_RX_EN,
726                            0);
727
728         /* Disable RX DRQ */
729         regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
730                            SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN,
731                            0);
732 }
733
734 static void sun4i_i2s_stop_playback(struct sun4i_i2s *i2s)
735 {
736         /* Disable TX Block */
737         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
738                            SUN4I_I2S_CTRL_TX_EN,
739                            0);
740
741         /* Disable TX DRQ */
742         regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
743                            SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN,
744                            0);
745 }
746
747 static int sun4i_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
748                              struct snd_soc_dai *dai)
749 {
750         struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
751
752         switch (cmd) {
753         case SNDRV_PCM_TRIGGER_START:
754         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
755         case SNDRV_PCM_TRIGGER_RESUME:
756                 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
757                         sun4i_i2s_start_playback(i2s);
758                 else
759                         sun4i_i2s_start_capture(i2s);
760                 break;
761
762         case SNDRV_PCM_TRIGGER_STOP:
763         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
764         case SNDRV_PCM_TRIGGER_SUSPEND:
765                 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
766                         sun4i_i2s_stop_playback(i2s);
767                 else
768                         sun4i_i2s_stop_capture(i2s);
769                 break;
770
771         default:
772                 return -EINVAL;
773         }
774
775         return 0;
776 }
777
778 static int sun4i_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
779                                 unsigned int freq, int dir)
780 {
781         struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
782
783         if (clk_id != 0)
784                 return -EINVAL;
785
786         i2s->mclk_freq = freq;
787
788         return 0;
789 }
790
791 static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
792         .hw_params      = sun4i_i2s_hw_params,
793         .set_fmt        = sun4i_i2s_set_fmt,
794         .set_sysclk     = sun4i_i2s_set_sysclk,
795         .trigger        = sun4i_i2s_trigger,
796 };
797
798 static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
799 {
800         struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
801
802         snd_soc_dai_init_dma_data(dai,
803                                   &i2s->playback_dma_data,
804                                   &i2s->capture_dma_data);
805
806         snd_soc_dai_set_drvdata(dai, i2s);
807
808         return 0;
809 }
810
811 static struct snd_soc_dai_driver sun4i_i2s_dai = {
812         .probe = sun4i_i2s_dai_probe,
813         .capture = {
814                 .stream_name = "Capture",
815                 .channels_min = 2,
816                 .channels_max = 2,
817                 .rates = SNDRV_PCM_RATE_8000_192000,
818                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
819         },
820         .playback = {
821                 .stream_name = "Playback",
822                 .channels_min = 2,
823                 .channels_max = 2,
824                 .rates = SNDRV_PCM_RATE_8000_192000,
825                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
826         },
827         .ops = &sun4i_i2s_dai_ops,
828         .symmetric_rates = 1,
829 };
830
831 static const struct snd_soc_component_driver sun4i_i2s_component = {
832         .name   = "sun4i-dai",
833 };
834
835 static bool sun4i_i2s_rd_reg(struct device *dev, unsigned int reg)
836 {
837         switch (reg) {
838         case SUN4I_I2S_FIFO_TX_REG:
839                 return false;
840
841         default:
842                 return true;
843         }
844 }
845
846 static bool sun4i_i2s_wr_reg(struct device *dev, unsigned int reg)
847 {
848         switch (reg) {
849         case SUN4I_I2S_FIFO_RX_REG:
850         case SUN4I_I2S_FIFO_STA_REG:
851                 return false;
852
853         default:
854                 return true;
855         }
856 }
857
858 static bool sun4i_i2s_volatile_reg(struct device *dev, unsigned int reg)
859 {
860         switch (reg) {
861         case SUN4I_I2S_FIFO_RX_REG:
862         case SUN4I_I2S_INT_STA_REG:
863         case SUN4I_I2S_RX_CNT_REG:
864         case SUN4I_I2S_TX_CNT_REG:
865                 return true;
866
867         default:
868                 return false;
869         }
870 }
871
872 static bool sun8i_i2s_rd_reg(struct device *dev, unsigned int reg)
873 {
874         switch (reg) {
875         case SUN8I_I2S_FIFO_TX_REG:
876                 return false;
877
878         default:
879                 return true;
880         }
881 }
882
883 static bool sun8i_i2s_volatile_reg(struct device *dev, unsigned int reg)
884 {
885         if (reg == SUN8I_I2S_INT_STA_REG)
886                 return true;
887         if (reg == SUN8I_I2S_FIFO_TX_REG)
888                 return false;
889
890         return sun4i_i2s_volatile_reg(dev, reg);
891 }
892
893 static const struct reg_default sun4i_i2s_reg_defaults[] = {
894         { SUN4I_I2S_CTRL_REG, 0x00000000 },
895         { SUN4I_I2S_FMT0_REG, 0x0000000c },
896         { SUN4I_I2S_FMT1_REG, 0x00004020 },
897         { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
898         { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
899         { SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
900         { SUN4I_I2S_TX_CHAN_SEL_REG, 0x00000001 },
901         { SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210 },
902         { SUN4I_I2S_RX_CHAN_SEL_REG, 0x00000001 },
903         { SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210 },
904 };
905
906 static const struct reg_default sun8i_i2s_reg_defaults[] = {
907         { SUN4I_I2S_CTRL_REG, 0x00060000 },
908         { SUN4I_I2S_FMT0_REG, 0x00000033 },
909         { SUN4I_I2S_FMT1_REG, 0x00000030 },
910         { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
911         { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
912         { SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
913         { SUN8I_I2S_CHAN_CFG_REG, 0x00000000 },
914         { SUN8I_I2S_TX_CHAN_SEL_REG, 0x00000000 },
915         { SUN8I_I2S_TX_CHAN_MAP_REG, 0x00000000 },
916         { SUN8I_I2S_RX_CHAN_SEL_REG, 0x00000000 },
917         { SUN8I_I2S_RX_CHAN_MAP_REG, 0x00000000 },
918 };
919
920 static const struct regmap_config sun4i_i2s_regmap_config = {
921         .reg_bits       = 32,
922         .reg_stride     = 4,
923         .val_bits       = 32,
924         .max_register   = SUN4I_I2S_RX_CHAN_MAP_REG,
925
926         .cache_type     = REGCACHE_FLAT,
927         .reg_defaults   = sun4i_i2s_reg_defaults,
928         .num_reg_defaults       = ARRAY_SIZE(sun4i_i2s_reg_defaults),
929         .writeable_reg  = sun4i_i2s_wr_reg,
930         .readable_reg   = sun4i_i2s_rd_reg,
931         .volatile_reg   = sun4i_i2s_volatile_reg,
932 };
933
934 static const struct regmap_config sun8i_i2s_regmap_config = {
935         .reg_bits       = 32,
936         .reg_stride     = 4,
937         .val_bits       = 32,
938         .max_register   = SUN8I_I2S_RX_CHAN_MAP_REG,
939         .cache_type     = REGCACHE_FLAT,
940         .reg_defaults   = sun8i_i2s_reg_defaults,
941         .num_reg_defaults       = ARRAY_SIZE(sun8i_i2s_reg_defaults),
942         .writeable_reg  = sun4i_i2s_wr_reg,
943         .readable_reg   = sun8i_i2s_rd_reg,
944         .volatile_reg   = sun8i_i2s_volatile_reg,
945 };
946
947 static int sun4i_i2s_runtime_resume(struct device *dev)
948 {
949         struct sun4i_i2s *i2s = dev_get_drvdata(dev);
950         int ret;
951
952         ret = clk_prepare_enable(i2s->bus_clk);
953         if (ret) {
954                 dev_err(dev, "Failed to enable bus clock\n");
955                 return ret;
956         }
957
958         regcache_cache_only(i2s->regmap, false);
959         regcache_mark_dirty(i2s->regmap);
960
961         ret = regcache_sync(i2s->regmap);
962         if (ret) {
963                 dev_err(dev, "Failed to sync regmap cache\n");
964                 goto err_disable_clk;
965         }
966
967         /* Enable the whole hardware block */
968         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
969                            SUN4I_I2S_CTRL_GL_EN, SUN4I_I2S_CTRL_GL_EN);
970
971         /* Enable the first output line */
972         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
973                            SUN4I_I2S_CTRL_SDO_EN_MASK,
974                            SUN4I_I2S_CTRL_SDO_EN(0));
975
976         ret = clk_prepare_enable(i2s->mod_clk);
977         if (ret) {
978                 dev_err(dev, "Failed to enable module clock\n");
979                 goto err_disable_clk;
980         }
981
982         return 0;
983
984 err_disable_clk:
985         clk_disable_unprepare(i2s->bus_clk);
986         return ret;
987 }
988
989 static int sun4i_i2s_runtime_suspend(struct device *dev)
990 {
991         struct sun4i_i2s *i2s = dev_get_drvdata(dev);
992
993         clk_disable_unprepare(i2s->mod_clk);
994
995         /* Disable our output lines */
996         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
997                            SUN4I_I2S_CTRL_SDO_EN_MASK, 0);
998
999         /* Disable the whole hardware block */
1000         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
1001                            SUN4I_I2S_CTRL_GL_EN, 0);
1002
1003         regcache_cache_only(i2s->regmap, true);
1004
1005         clk_disable_unprepare(i2s->bus_clk);
1006
1007         return 0;
1008 }
1009
1010 static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = {
1011         .has_reset              = false,
1012         .reg_offset_txdata      = SUN4I_I2S_FIFO_TX_REG,
1013         .sun4i_i2s_regmap       = &sun4i_i2s_regmap_config,
1014         .field_clkdiv_mclk_en   = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
1015         .field_fmt_wss          = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
1016         .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
1017         .bclk_dividers          = sun4i_i2s_bclk_div,
1018         .num_bclk_dividers      = ARRAY_SIZE(sun4i_i2s_bclk_div),
1019         .mclk_dividers          = sun4i_i2s_mclk_div,
1020         .num_mclk_dividers      = ARRAY_SIZE(sun4i_i2s_mclk_div),
1021         .get_bclk_parent_rate   = sun4i_i2s_get_bclk_parent_rate,
1022         .get_sr                 = sun4i_i2s_get_sr,
1023         .get_wss                = sun4i_i2s_get_wss,
1024         .set_chan_cfg           = sun4i_i2s_set_chan_cfg,
1025         .set_fmt                = sun4i_i2s_set_soc_fmt,
1026 };
1027
1028 static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = {
1029         .has_reset              = true,
1030         .reg_offset_txdata      = SUN4I_I2S_FIFO_TX_REG,
1031         .sun4i_i2s_regmap       = &sun4i_i2s_regmap_config,
1032         .field_clkdiv_mclk_en   = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
1033         .field_fmt_wss          = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
1034         .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
1035         .bclk_dividers          = sun4i_i2s_bclk_div,
1036         .num_bclk_dividers      = ARRAY_SIZE(sun4i_i2s_bclk_div),
1037         .mclk_dividers          = sun4i_i2s_mclk_div,
1038         .num_mclk_dividers      = ARRAY_SIZE(sun4i_i2s_mclk_div),
1039         .get_bclk_parent_rate   = sun4i_i2s_get_bclk_parent_rate,
1040         .get_sr                 = sun4i_i2s_get_sr,
1041         .get_wss                = sun4i_i2s_get_wss,
1042         .set_chan_cfg           = sun4i_i2s_set_chan_cfg,
1043         .set_fmt                = sun4i_i2s_set_soc_fmt,
1044 };
1045
1046 static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = {
1047         .has_reset              = true,
1048         .reg_offset_txdata      = SUN8I_I2S_FIFO_TX_REG,
1049         .sun4i_i2s_regmap       = &sun4i_i2s_regmap_config,
1050         .field_clkdiv_mclk_en   = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
1051         .field_fmt_wss          = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
1052         .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
1053         .bclk_dividers          = sun8i_i2s_clk_div,
1054         .num_bclk_dividers      = ARRAY_SIZE(sun8i_i2s_clk_div),
1055         .mclk_dividers          = sun8i_i2s_clk_div,
1056         .num_mclk_dividers      = ARRAY_SIZE(sun8i_i2s_clk_div),
1057         .get_bclk_parent_rate   = sun8i_i2s_get_bclk_parent_rate,
1058         .get_sr                 = sun8i_i2s_get_sr_wss,
1059         .get_wss                = sun8i_i2s_get_sr_wss,
1060         .set_chan_cfg           = sun8i_i2s_set_chan_cfg,
1061         .set_fmt                = sun8i_i2s_set_soc_fmt,
1062 };
1063
1064 static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = {
1065         .has_reset              = true,
1066         .reg_offset_txdata      = SUN8I_I2S_FIFO_TX_REG,
1067         .sun4i_i2s_regmap       = &sun8i_i2s_regmap_config,
1068         .has_fmt_set_lrck_period = true,
1069         .field_clkdiv_mclk_en   = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8),
1070         .field_fmt_wss          = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2),
1071         .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6),
1072         .bclk_dividers          = sun8i_i2s_clk_div,
1073         .num_bclk_dividers      = ARRAY_SIZE(sun8i_i2s_clk_div),
1074         .mclk_dividers          = sun8i_i2s_clk_div,
1075         .num_mclk_dividers      = ARRAY_SIZE(sun8i_i2s_clk_div),
1076         .get_bclk_parent_rate   = sun8i_i2s_get_bclk_parent_rate,
1077         .get_sr                 = sun8i_i2s_get_sr_wss,
1078         .get_wss                = sun8i_i2s_get_sr_wss,
1079         .set_chan_cfg           = sun8i_i2s_set_chan_cfg,
1080         .set_fmt                = sun8i_i2s_set_soc_fmt,
1081 };
1082
1083 static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
1084         .has_reset              = true,
1085         .reg_offset_txdata      = SUN8I_I2S_FIFO_TX_REG,
1086         .sun4i_i2s_regmap       = &sun4i_i2s_regmap_config,
1087         .field_clkdiv_mclk_en   = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7),
1088         .field_fmt_wss          = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3),
1089         .field_fmt_sr           = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5),
1090         .bclk_dividers          = sun4i_i2s_bclk_div,
1091         .num_bclk_dividers      = ARRAY_SIZE(sun4i_i2s_bclk_div),
1092         .mclk_dividers          = sun4i_i2s_mclk_div,
1093         .num_mclk_dividers      = ARRAY_SIZE(sun4i_i2s_mclk_div),
1094         .get_bclk_parent_rate   = sun4i_i2s_get_bclk_parent_rate,
1095         .get_sr                 = sun4i_i2s_get_sr,
1096         .get_wss                = sun4i_i2s_get_wss,
1097         .set_chan_cfg           = sun4i_i2s_set_chan_cfg,
1098         .set_fmt                = sun4i_i2s_set_soc_fmt,
1099 };
1100
1101 static int sun4i_i2s_init_regmap_fields(struct device *dev,
1102                                         struct sun4i_i2s *i2s)
1103 {
1104         i2s->field_clkdiv_mclk_en =
1105                 devm_regmap_field_alloc(dev, i2s->regmap,
1106                                         i2s->variant->field_clkdiv_mclk_en);
1107         if (IS_ERR(i2s->field_clkdiv_mclk_en))
1108                 return PTR_ERR(i2s->field_clkdiv_mclk_en);
1109
1110         i2s->field_fmt_wss =
1111                         devm_regmap_field_alloc(dev, i2s->regmap,
1112                                                 i2s->variant->field_fmt_wss);
1113         if (IS_ERR(i2s->field_fmt_wss))
1114                 return PTR_ERR(i2s->field_fmt_wss);
1115
1116         i2s->field_fmt_sr =
1117                         devm_regmap_field_alloc(dev, i2s->regmap,
1118                                                 i2s->variant->field_fmt_sr);
1119         if (IS_ERR(i2s->field_fmt_sr))
1120                 return PTR_ERR(i2s->field_fmt_sr);
1121
1122         return 0;
1123 }
1124
1125 static int sun4i_i2s_probe(struct platform_device *pdev)
1126 {
1127         struct sun4i_i2s *i2s;
1128         struct resource *res;
1129         void __iomem *regs;
1130         int irq, ret;
1131
1132         i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
1133         if (!i2s)
1134                 return -ENOMEM;
1135         platform_set_drvdata(pdev, i2s);
1136
1137         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1138         regs = devm_ioremap_resource(&pdev->dev, res);
1139         if (IS_ERR(regs))
1140                 return PTR_ERR(regs);
1141
1142         irq = platform_get_irq(pdev, 0);
1143         if (irq < 0)
1144                 return irq;
1145
1146         i2s->variant = of_device_get_match_data(&pdev->dev);
1147         if (!i2s->variant) {
1148                 dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
1149                 return -ENODEV;
1150         }
1151
1152         i2s->bus_clk = devm_clk_get(&pdev->dev, "apb");
1153         if (IS_ERR(i2s->bus_clk)) {
1154                 dev_err(&pdev->dev, "Can't get our bus clock\n");
1155                 return PTR_ERR(i2s->bus_clk);
1156         }
1157
1158         i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
1159                                             i2s->variant->sun4i_i2s_regmap);
1160         if (IS_ERR(i2s->regmap)) {
1161                 dev_err(&pdev->dev, "Regmap initialisation failed\n");
1162                 return PTR_ERR(i2s->regmap);
1163         }
1164
1165         i2s->mod_clk = devm_clk_get(&pdev->dev, "mod");
1166         if (IS_ERR(i2s->mod_clk)) {
1167                 dev_err(&pdev->dev, "Can't get our mod clock\n");
1168                 return PTR_ERR(i2s->mod_clk);
1169         }
1170
1171         if (i2s->variant->has_reset) {
1172                 i2s->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL);
1173                 if (IS_ERR(i2s->rst)) {
1174                         dev_err(&pdev->dev, "Failed to get reset control\n");
1175                         return PTR_ERR(i2s->rst);
1176                 }
1177         }
1178
1179         if (!IS_ERR(i2s->rst)) {
1180                 ret = reset_control_deassert(i2s->rst);
1181                 if (ret) {
1182                         dev_err(&pdev->dev,
1183                                 "Failed to deassert the reset control\n");
1184                         return -EINVAL;
1185                 }
1186         }
1187
1188         i2s->playback_dma_data.addr = res->start +
1189                                         i2s->variant->reg_offset_txdata;
1190         i2s->playback_dma_data.maxburst = 8;
1191
1192         i2s->capture_dma_data.addr = res->start + SUN4I_I2S_FIFO_RX_REG;
1193         i2s->capture_dma_data.maxburst = 8;
1194
1195         pm_runtime_enable(&pdev->dev);
1196         if (!pm_runtime_enabled(&pdev->dev)) {
1197                 ret = sun4i_i2s_runtime_resume(&pdev->dev);
1198                 if (ret)
1199                         goto err_pm_disable;
1200         }
1201
1202         ret = sun4i_i2s_init_regmap_fields(&pdev->dev, i2s);
1203         if (ret) {
1204                 dev_err(&pdev->dev, "Could not initialise regmap fields\n");
1205                 goto err_suspend;
1206         }
1207
1208         ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
1209         if (ret) {
1210                 dev_err(&pdev->dev, "Could not register PCM\n");
1211                 goto err_suspend;
1212         }
1213
1214         ret = devm_snd_soc_register_component(&pdev->dev,
1215                                               &sun4i_i2s_component,
1216                                               &sun4i_i2s_dai, 1);
1217         if (ret) {
1218                 dev_err(&pdev->dev, "Could not register DAI\n");
1219                 goto err_suspend;
1220         }
1221
1222         return 0;
1223
1224 err_suspend:
1225         if (!pm_runtime_status_suspended(&pdev->dev))
1226                 sun4i_i2s_runtime_suspend(&pdev->dev);
1227 err_pm_disable:
1228         pm_runtime_disable(&pdev->dev);
1229         if (!IS_ERR(i2s->rst))
1230                 reset_control_assert(i2s->rst);
1231
1232         return ret;
1233 }
1234
1235 static int sun4i_i2s_remove(struct platform_device *pdev)
1236 {
1237         struct sun4i_i2s *i2s = dev_get_drvdata(&pdev->dev);
1238
1239         pm_runtime_disable(&pdev->dev);
1240         if (!pm_runtime_status_suspended(&pdev->dev))
1241                 sun4i_i2s_runtime_suspend(&pdev->dev);
1242
1243         if (!IS_ERR(i2s->rst))
1244                 reset_control_assert(i2s->rst);
1245
1246         return 0;
1247 }
1248
1249 static const struct of_device_id sun4i_i2s_match[] = {
1250         {
1251                 .compatible = "allwinner,sun4i-a10-i2s",
1252                 .data = &sun4i_a10_i2s_quirks,
1253         },
1254         {
1255                 .compatible = "allwinner,sun6i-a31-i2s",
1256                 .data = &sun6i_a31_i2s_quirks,
1257         },
1258         {
1259                 .compatible = "allwinner,sun8i-a83t-i2s",
1260                 .data = &sun8i_a83t_i2s_quirks,
1261         },
1262         {
1263                 .compatible = "allwinner,sun8i-h3-i2s",
1264                 .data = &sun8i_h3_i2s_quirks,
1265         },
1266         {
1267                 .compatible = "allwinner,sun50i-a64-codec-i2s",
1268                 .data = &sun50i_a64_codec_i2s_quirks,
1269         },
1270         {}
1271 };
1272 MODULE_DEVICE_TABLE(of, sun4i_i2s_match);
1273
1274 static const struct dev_pm_ops sun4i_i2s_pm_ops = {
1275         .runtime_resume         = sun4i_i2s_runtime_resume,
1276         .runtime_suspend        = sun4i_i2s_runtime_suspend,
1277 };
1278
1279 static struct platform_driver sun4i_i2s_driver = {
1280         .probe  = sun4i_i2s_probe,
1281         .remove = sun4i_i2s_remove,
1282         .driver = {
1283                 .name           = "sun4i-i2s",
1284                 .of_match_table = sun4i_i2s_match,
1285                 .pm             = &sun4i_i2s_pm_ops,
1286         },
1287 };
1288 module_platform_driver(sun4i_i2s_driver);
1289
1290 MODULE_AUTHOR("Andrea Venturi <be17068@iperbole.bo.it>");
1291 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
1292 MODULE_DESCRIPTION("Allwinner A10 I2S driver");
1293 MODULE_LICENSE("GPL");