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