GNU Linux-libre 4.9-gnu1
[releases.git] / sound / soc / sunxi / sun4i-i2s.c
1 /*
2  * Copyright (C) 2015 Andrea Venturi
3  * Andrea Venturi <be17068@iperbole.bo.it>
4  *
5  * Copyright (C) 2016 Maxime Ripard
6  * Maxime Ripard <maxime.ripard@free-electrons.com>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  */
13
14 #include <linux/clk.h>
15 #include <linux/dmaengine.h>
16 #include <linux/module.h>
17 #include <linux/platform_device.h>
18 #include <linux/pm_runtime.h>
19 #include <linux/regmap.h>
20
21 #include <sound/dmaengine_pcm.h>
22 #include <sound/pcm_params.h>
23 #include <sound/soc.h>
24 #include <sound/soc-dai.h>
25
26 #define SUN4I_I2S_CTRL_REG              0x00
27 #define SUN4I_I2S_CTRL_SDO_EN_MASK              GENMASK(11, 8)
28 #define SUN4I_I2S_CTRL_SDO_EN(sdo)                      BIT(8 + (sdo))
29 #define SUN4I_I2S_CTRL_MODE_MASK                BIT(5)
30 #define SUN4I_I2S_CTRL_MODE_SLAVE                       (1 << 5)
31 #define SUN4I_I2S_CTRL_MODE_MASTER                      (0 << 5)
32 #define SUN4I_I2S_CTRL_TX_EN                    BIT(2)
33 #define SUN4I_I2S_CTRL_RX_EN                    BIT(1)
34 #define SUN4I_I2S_CTRL_GL_EN                    BIT(0)
35
36 #define SUN4I_I2S_FMT0_REG              0x04
37 #define SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK      BIT(7)
38 #define SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED          (1 << 7)
39 #define SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL            (0 << 7)
40 #define SUN4I_I2S_FMT0_BCLK_POLARITY_MASK       BIT(6)
41 #define SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED           (1 << 6)
42 #define SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL             (0 << 6)
43 #define SUN4I_I2S_FMT0_SR_MASK                  GENMASK(5, 4)
44 #define SUN4I_I2S_FMT0_SR(sr)                           ((sr) << 4)
45 #define SUN4I_I2S_FMT0_WSS_MASK                 GENMASK(3, 2)
46 #define SUN4I_I2S_FMT0_WSS(wss)                         ((wss) << 2)
47 #define SUN4I_I2S_FMT0_FMT_MASK                 GENMASK(1, 0)
48 #define SUN4I_I2S_FMT0_FMT_RIGHT_J                      (2 << 0)
49 #define SUN4I_I2S_FMT0_FMT_LEFT_J                       (1 << 0)
50 #define SUN4I_I2S_FMT0_FMT_I2S                          (0 << 0)
51
52 #define SUN4I_I2S_FMT1_REG              0x08
53 #define SUN4I_I2S_FIFO_TX_REG           0x0c
54 #define SUN4I_I2S_FIFO_RX_REG           0x10
55
56 #define SUN4I_I2S_FIFO_CTRL_REG         0x14
57 #define SUN4I_I2S_FIFO_CTRL_FLUSH_TX            BIT(25)
58 #define SUN4I_I2S_FIFO_CTRL_FLUSH_RX            BIT(24)
59 #define SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK        BIT(2)
60 #define SUN4I_I2S_FIFO_CTRL_TX_MODE(mode)               ((mode) << 2)
61 #define SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK        GENMASK(1, 0)
62 #define SUN4I_I2S_FIFO_CTRL_RX_MODE(mode)               (mode)
63
64 #define SUN4I_I2S_FIFO_STA_REG          0x18
65
66 #define SUN4I_I2S_DMA_INT_CTRL_REG      0x1c
67 #define SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN        BIT(7)
68 #define SUN4I_I2S_DMA_INT_CTRL_RX_DRQ_EN        BIT(3)
69
70 #define SUN4I_I2S_INT_STA_REG           0x20
71
72 #define SUN4I_I2S_CLK_DIV_REG           0x24
73 #define SUN4I_I2S_CLK_DIV_MCLK_EN               BIT(7)
74 #define SUN4I_I2S_CLK_DIV_BCLK_MASK             GENMASK(6, 4)
75 #define SUN4I_I2S_CLK_DIV_BCLK(bclk)                    ((bclk) << 4)
76 #define SUN4I_I2S_CLK_DIV_MCLK_MASK             GENMASK(3, 0)
77 #define SUN4I_I2S_CLK_DIV_MCLK(mclk)                    ((mclk) << 0)
78
79 #define SUN4I_I2S_RX_CNT_REG            0x28
80 #define SUN4I_I2S_TX_CNT_REG            0x2c
81
82 #define SUN4I_I2S_TX_CHAN_SEL_REG       0x30
83 #define SUN4I_I2S_TX_CHAN_SEL(num_chan)         (((num_chan) - 1) << 0)
84
85 #define SUN4I_I2S_TX_CHAN_MAP_REG       0x34
86 #define SUN4I_I2S_TX_CHAN_MAP(chan, sample)     ((sample) << (chan << 2))
87
88 #define SUN4I_I2S_RX_CHAN_SEL_REG       0x38
89 #define SUN4I_I2S_RX_CHAN_MAP_REG       0x3c
90
91 struct sun4i_i2s {
92         struct clk      *bus_clk;
93         struct clk      *mod_clk;
94         struct regmap   *regmap;
95
96         struct snd_dmaengine_dai_dma_data       playback_dma_data;
97 };
98
99 struct sun4i_i2s_clk_div {
100         u8      div;
101         u8      val;
102 };
103
104 static const struct sun4i_i2s_clk_div sun4i_i2s_bclk_div[] = {
105         { .div = 2, .val = 0 },
106         { .div = 4, .val = 1 },
107         { .div = 6, .val = 2 },
108         { .div = 8, .val = 3 },
109         { .div = 12, .val = 4 },
110         { .div = 16, .val = 5 },
111 };
112
113 static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = {
114         { .div = 1, .val = 0 },
115         { .div = 2, .val = 1 },
116         { .div = 4, .val = 2 },
117         { .div = 6, .val = 3 },
118         { .div = 8, .val = 4 },
119         { .div = 12, .val = 5 },
120         { .div = 16, .val = 6 },
121         { .div = 24, .val = 7 },
122 };
123
124 static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s,
125                                   unsigned int oversample_rate,
126                                   unsigned int word_size)
127 {
128         int div = oversample_rate / word_size / 2;
129         int i;
130
131         for (i = 0; i < ARRAY_SIZE(sun4i_i2s_bclk_div); i++) {
132                 const struct sun4i_i2s_clk_div *bdiv = &sun4i_i2s_bclk_div[i];
133
134                 if (bdiv->div == div)
135                         return bdiv->val;
136         }
137
138         return -EINVAL;
139 }
140
141 static int sun4i_i2s_get_mclk_div(struct sun4i_i2s *i2s,
142                                   unsigned int oversample_rate,
143                                   unsigned int module_rate,
144                                   unsigned int sampling_rate)
145 {
146         int div = module_rate / sampling_rate / oversample_rate;
147         int i;
148
149         for (i = 0; i < ARRAY_SIZE(sun4i_i2s_mclk_div); i++) {
150                 const struct sun4i_i2s_clk_div *mdiv = &sun4i_i2s_mclk_div[i];
151
152                 if (mdiv->div == div)
153                         return mdiv->val;
154         }
155
156         return -EINVAL;
157 }
158
159 static int sun4i_i2s_oversample_rates[] = { 128, 192, 256, 384, 512, 768 };
160
161 static int sun4i_i2s_set_clk_rate(struct sun4i_i2s *i2s,
162                                   unsigned int rate,
163                                   unsigned int word_size)
164 {
165         unsigned int clk_rate;
166         int bclk_div, mclk_div;
167         int ret, i;
168
169         switch (rate) {
170         case 176400:
171         case 88200:
172         case 44100:
173         case 22050:
174         case 11025:
175                 clk_rate = 22579200;
176                 break;
177
178         case 192000:
179         case 128000:
180         case 96000:
181         case 64000:
182         case 48000:
183         case 32000:
184         case 24000:
185         case 16000:
186         case 12000:
187         case 8000:
188                 clk_rate = 24576000;
189                 break;
190
191         default:
192                 return -EINVAL;
193         }
194
195         ret = clk_set_rate(i2s->mod_clk, clk_rate);
196         if (ret)
197                 return ret;
198
199         /* Always favor the highest oversampling rate */
200         for (i = (ARRAY_SIZE(sun4i_i2s_oversample_rates) - 1); i >= 0; i--) {
201                 unsigned int oversample_rate = sun4i_i2s_oversample_rates[i];
202
203                 bclk_div = sun4i_i2s_get_bclk_div(i2s, oversample_rate,
204                                                   word_size);
205                 mclk_div = sun4i_i2s_get_mclk_div(i2s, oversample_rate,
206                                                   clk_rate,
207                                                   rate);
208
209                 if ((bclk_div >= 0) && (mclk_div >= 0))
210                         break;
211         }
212
213         if ((bclk_div < 0) || (mclk_div < 0))
214                 return -EINVAL;
215
216         regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG,
217                      SUN4I_I2S_CLK_DIV_BCLK(bclk_div) |
218                      SUN4I_I2S_CLK_DIV_MCLK(mclk_div) |
219                      SUN4I_I2S_CLK_DIV_MCLK_EN);
220
221         return 0;
222 }
223
224 static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
225                                struct snd_pcm_hw_params *params,
226                                struct snd_soc_dai *dai)
227 {
228         struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
229         int sr, wss;
230         u32 width;
231
232         if (params_channels(params) != 2)
233                 return -EINVAL;
234
235         switch (params_physical_width(params)) {
236         case 16:
237                 width = DMA_SLAVE_BUSWIDTH_2_BYTES;
238                 break;
239         default:
240                 return -EINVAL;
241         }
242         i2s->playback_dma_data.addr_width = width;
243
244         switch (params_width(params)) {
245         case 16:
246                 sr = 0;
247                 wss = 0;
248                 break;
249
250         default:
251                 return -EINVAL;
252         }
253
254         regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
255                            SUN4I_I2S_FMT0_WSS_MASK | SUN4I_I2S_FMT0_SR_MASK,
256                            SUN4I_I2S_FMT0_WSS(wss) | SUN4I_I2S_FMT0_SR(sr));
257
258         return sun4i_i2s_set_clk_rate(i2s, params_rate(params),
259                                       params_width(params));
260 }
261
262 static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
263 {
264         struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
265         u32 val;
266
267         /* DAI Mode */
268         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
269         case SND_SOC_DAIFMT_I2S:
270                 val = SUN4I_I2S_FMT0_FMT_I2S;
271                 break;
272         case SND_SOC_DAIFMT_LEFT_J:
273                 val = SUN4I_I2S_FMT0_FMT_LEFT_J;
274                 break;
275         case SND_SOC_DAIFMT_RIGHT_J:
276                 val = SUN4I_I2S_FMT0_FMT_RIGHT_J;
277                 break;
278         default:
279                 return -EINVAL;
280         }
281
282         regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
283                            SUN4I_I2S_FMT0_FMT_MASK,
284                            val);
285
286         /* DAI clock polarity */
287         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
288         case SND_SOC_DAIFMT_IB_IF:
289                 /* Invert both clocks */
290                 val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED |
291                         SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED;
292                 break;
293         case SND_SOC_DAIFMT_IB_NF:
294                 /* Invert bit clock */
295                 val = SUN4I_I2S_FMT0_BCLK_POLARITY_INVERTED |
296                         SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL;
297                 break;
298         case SND_SOC_DAIFMT_NB_IF:
299                 /* Invert frame clock */
300                 val = SUN4I_I2S_FMT0_LRCLK_POLARITY_INVERTED |
301                         SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL;
302                 break;
303         case SND_SOC_DAIFMT_NB_NF:
304                 /* Nothing to do for both normal cases */
305                 val = SUN4I_I2S_FMT0_BCLK_POLARITY_NORMAL |
306                         SUN4I_I2S_FMT0_LRCLK_POLARITY_NORMAL;
307                 break;
308         default:
309                 return -EINVAL;
310         }
311
312         regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
313                            SUN4I_I2S_FMT0_BCLK_POLARITY_MASK |
314                            SUN4I_I2S_FMT0_LRCLK_POLARITY_MASK,
315                            val);
316
317         /* DAI clock master masks */
318         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
319         case SND_SOC_DAIFMT_CBS_CFS:
320                 /* BCLK and LRCLK master */
321                 val = SUN4I_I2S_CTRL_MODE_MASTER;
322                 break;
323         case SND_SOC_DAIFMT_CBM_CFM:
324                 /* BCLK and LRCLK slave */
325                 val = SUN4I_I2S_CTRL_MODE_SLAVE;
326                 break;
327         default:
328                 return -EINVAL;
329         }
330
331         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
332                            SUN4I_I2S_CTRL_MODE_MASK,
333                            val);
334
335         /* Set significant bits in our FIFOs */
336         regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
337                            SUN4I_I2S_FIFO_CTRL_TX_MODE_MASK |
338                            SUN4I_I2S_FIFO_CTRL_RX_MODE_MASK,
339                            SUN4I_I2S_FIFO_CTRL_TX_MODE(1) |
340                            SUN4I_I2S_FIFO_CTRL_RX_MODE(1));
341         return 0;
342 }
343
344 static void sun4i_i2s_start_playback(struct sun4i_i2s *i2s)
345 {
346         /* Flush TX FIFO */
347         regmap_update_bits(i2s->regmap, SUN4I_I2S_FIFO_CTRL_REG,
348                            SUN4I_I2S_FIFO_CTRL_FLUSH_TX,
349                            SUN4I_I2S_FIFO_CTRL_FLUSH_TX);
350
351         /* Clear TX counter */
352         regmap_write(i2s->regmap, SUN4I_I2S_TX_CNT_REG, 0);
353
354         /* Enable TX Block */
355         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
356                            SUN4I_I2S_CTRL_TX_EN,
357                            SUN4I_I2S_CTRL_TX_EN);
358
359         /* Enable TX DRQ */
360         regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
361                            SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN,
362                            SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN);
363 }
364
365
366 static void sun4i_i2s_stop_playback(struct sun4i_i2s *i2s)
367 {
368         /* Disable TX Block */
369         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
370                            SUN4I_I2S_CTRL_TX_EN,
371                            0);
372
373         /* Disable TX DRQ */
374         regmap_update_bits(i2s->regmap, SUN4I_I2S_DMA_INT_CTRL_REG,
375                            SUN4I_I2S_DMA_INT_CTRL_TX_DRQ_EN,
376                            0);
377 }
378
379 static int sun4i_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
380                              struct snd_soc_dai *dai)
381 {
382         struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
383
384         switch (cmd) {
385         case SNDRV_PCM_TRIGGER_START:
386         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
387         case SNDRV_PCM_TRIGGER_RESUME:
388                 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
389                         sun4i_i2s_start_playback(i2s);
390                 else
391                         return -EINVAL;
392                 break;
393
394         case SNDRV_PCM_TRIGGER_STOP:
395         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
396         case SNDRV_PCM_TRIGGER_SUSPEND:
397                 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
398                         sun4i_i2s_stop_playback(i2s);
399                 else
400                         return -EINVAL;
401                 break;
402
403         default:
404                 return -EINVAL;
405         }
406
407         return 0;
408 }
409
410 static int sun4i_i2s_startup(struct snd_pcm_substream *substream,
411                              struct snd_soc_dai *dai)
412 {
413         struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
414
415         /* Enable the whole hardware block */
416         regmap_write(i2s->regmap, SUN4I_I2S_CTRL_REG,
417                      SUN4I_I2S_CTRL_GL_EN);
418
419         /* Enable the first output line */
420         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
421                            SUN4I_I2S_CTRL_SDO_EN_MASK,
422                            SUN4I_I2S_CTRL_SDO_EN(0));
423
424         /* Enable the first two channels */
425         regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_SEL_REG,
426                      SUN4I_I2S_TX_CHAN_SEL(2));
427
428         /* Map them to the two first samples coming in */
429         regmap_write(i2s->regmap, SUN4I_I2S_TX_CHAN_MAP_REG,
430                      SUN4I_I2S_TX_CHAN_MAP(0, 0) | SUN4I_I2S_TX_CHAN_MAP(1, 1));
431
432         return clk_prepare_enable(i2s->mod_clk);
433 }
434
435 static void sun4i_i2s_shutdown(struct snd_pcm_substream *substream,
436                                struct snd_soc_dai *dai)
437 {
438         struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
439
440         clk_disable_unprepare(i2s->mod_clk);
441
442         /* Disable our output lines */
443         regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG,
444                            SUN4I_I2S_CTRL_SDO_EN_MASK, 0);
445
446         /* Disable the whole hardware block */
447         regmap_write(i2s->regmap, SUN4I_I2S_CTRL_REG, 0);
448 }
449
450 static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
451         .hw_params      = sun4i_i2s_hw_params,
452         .set_fmt        = sun4i_i2s_set_fmt,
453         .shutdown       = sun4i_i2s_shutdown,
454         .startup        = sun4i_i2s_startup,
455         .trigger        = sun4i_i2s_trigger,
456 };
457
458 static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
459 {
460         struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
461
462         snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data, NULL);
463
464         snd_soc_dai_set_drvdata(dai, i2s);
465
466         return 0;
467 }
468
469 static struct snd_soc_dai_driver sun4i_i2s_dai = {
470         .probe = sun4i_i2s_dai_probe,
471         .playback = {
472                 .stream_name = "Playback",
473                 .channels_min = 2,
474                 .channels_max = 2,
475                 .rates = SNDRV_PCM_RATE_8000_192000,
476                 .formats = SNDRV_PCM_FMTBIT_S16_LE,
477         },
478         .ops = &sun4i_i2s_dai_ops,
479         .symmetric_rates = 1,
480 };
481
482 static const struct snd_soc_component_driver sun4i_i2s_component = {
483         .name   = "sun4i-dai",
484 };
485
486 static bool sun4i_i2s_rd_reg(struct device *dev, unsigned int reg)
487 {
488         switch (reg) {
489         case SUN4I_I2S_FIFO_TX_REG:
490                 return false;
491
492         default:
493                 return true;
494         }
495 }
496
497 static bool sun4i_i2s_wr_reg(struct device *dev, unsigned int reg)
498 {
499         switch (reg) {
500         case SUN4I_I2S_FIFO_RX_REG:
501         case SUN4I_I2S_FIFO_STA_REG:
502                 return false;
503
504         default:
505                 return true;
506         }
507 }
508
509 static bool sun4i_i2s_volatile_reg(struct device *dev, unsigned int reg)
510 {
511         switch (reg) {
512         case SUN4I_I2S_FIFO_RX_REG:
513         case SUN4I_I2S_INT_STA_REG:
514         case SUN4I_I2S_RX_CNT_REG:
515         case SUN4I_I2S_TX_CNT_REG:
516                 return true;
517
518         default:
519                 return false;
520         }
521 }
522
523 static const struct reg_default sun4i_i2s_reg_defaults[] = {
524         { SUN4I_I2S_CTRL_REG, 0x00000000 },
525         { SUN4I_I2S_FMT0_REG, 0x0000000c },
526         { SUN4I_I2S_FMT1_REG, 0x00004020 },
527         { SUN4I_I2S_FIFO_CTRL_REG, 0x000400f0 },
528         { SUN4I_I2S_DMA_INT_CTRL_REG, 0x00000000 },
529         { SUN4I_I2S_CLK_DIV_REG, 0x00000000 },
530         { SUN4I_I2S_TX_CHAN_SEL_REG, 0x00000001 },
531         { SUN4I_I2S_TX_CHAN_MAP_REG, 0x76543210 },
532         { SUN4I_I2S_RX_CHAN_SEL_REG, 0x00000001 },
533         { SUN4I_I2S_RX_CHAN_MAP_REG, 0x00003210 },
534 };
535
536 static const struct regmap_config sun4i_i2s_regmap_config = {
537         .reg_bits       = 32,
538         .reg_stride     = 4,
539         .val_bits       = 32,
540         .max_register   = SUN4I_I2S_RX_CHAN_MAP_REG,
541
542         .cache_type     = REGCACHE_FLAT,
543         .reg_defaults   = sun4i_i2s_reg_defaults,
544         .num_reg_defaults       = ARRAY_SIZE(sun4i_i2s_reg_defaults),
545         .writeable_reg  = sun4i_i2s_wr_reg,
546         .readable_reg   = sun4i_i2s_rd_reg,
547         .volatile_reg   = sun4i_i2s_volatile_reg,
548 };
549
550 static int sun4i_i2s_runtime_resume(struct device *dev)
551 {
552         struct sun4i_i2s *i2s = dev_get_drvdata(dev);
553         int ret;
554
555         ret = clk_prepare_enable(i2s->bus_clk);
556         if (ret) {
557                 dev_err(dev, "Failed to enable bus clock\n");
558                 return ret;
559         }
560
561         regcache_cache_only(i2s->regmap, false);
562         regcache_mark_dirty(i2s->regmap);
563
564         ret = regcache_sync(i2s->regmap);
565         if (ret) {
566                 dev_err(dev, "Failed to sync regmap cache\n");
567                 goto err_disable_clk;
568         }
569
570         return 0;
571
572 err_disable_clk:
573         clk_disable_unprepare(i2s->bus_clk);
574         return ret;
575 }
576
577 static int sun4i_i2s_runtime_suspend(struct device *dev)
578 {
579         struct sun4i_i2s *i2s = dev_get_drvdata(dev);
580
581         regcache_cache_only(i2s->regmap, true);
582
583         clk_disable_unprepare(i2s->bus_clk);
584
585         return 0;
586 }
587
588 static int sun4i_i2s_probe(struct platform_device *pdev)
589 {
590         struct sun4i_i2s *i2s;
591         struct resource *res;
592         void __iomem *regs;
593         int irq, ret;
594
595         i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
596         if (!i2s)
597                 return -ENOMEM;
598         platform_set_drvdata(pdev, i2s);
599
600         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
601         regs = devm_ioremap_resource(&pdev->dev, res);
602         if (IS_ERR(regs))
603                 return PTR_ERR(regs);
604
605         irq = platform_get_irq(pdev, 0);
606         if (irq < 0) {
607                 dev_err(&pdev->dev, "Can't retrieve our interrupt\n");
608                 return irq;
609         }
610
611         i2s->bus_clk = devm_clk_get(&pdev->dev, "apb");
612         if (IS_ERR(i2s->bus_clk)) {
613                 dev_err(&pdev->dev, "Can't get our bus clock\n");
614                 return PTR_ERR(i2s->bus_clk);
615         }
616
617         i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
618                                             &sun4i_i2s_regmap_config);
619         if (IS_ERR(i2s->regmap)) {
620                 dev_err(&pdev->dev, "Regmap initialisation failed\n");
621                 return PTR_ERR(i2s->regmap);
622         }
623
624         i2s->mod_clk = devm_clk_get(&pdev->dev, "mod");
625         if (IS_ERR(i2s->mod_clk)) {
626                 dev_err(&pdev->dev, "Can't get our mod clock\n");
627                 return PTR_ERR(i2s->mod_clk);
628         }
629         
630         i2s->playback_dma_data.addr = res->start + SUN4I_I2S_FIFO_TX_REG;
631         i2s->playback_dma_data.maxburst = 4;
632
633         pm_runtime_enable(&pdev->dev);
634         if (!pm_runtime_enabled(&pdev->dev)) {
635                 ret = sun4i_i2s_runtime_resume(&pdev->dev);
636                 if (ret)
637                         goto err_pm_disable;
638         }
639
640         ret = devm_snd_soc_register_component(&pdev->dev,
641                                               &sun4i_i2s_component,
642                                               &sun4i_i2s_dai, 1);
643         if (ret) {
644                 dev_err(&pdev->dev, "Could not register DAI\n");
645                 goto err_suspend;
646         }
647
648         ret = snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
649         if (ret) {
650                 dev_err(&pdev->dev, "Could not register PCM\n");
651                 goto err_suspend;
652         }
653
654         return 0;
655
656 err_suspend:
657         if (!pm_runtime_status_suspended(&pdev->dev))
658                 sun4i_i2s_runtime_suspend(&pdev->dev);
659 err_pm_disable:
660         pm_runtime_disable(&pdev->dev);
661
662         return ret;
663 }
664
665 static int sun4i_i2s_remove(struct platform_device *pdev)
666 {
667         snd_dmaengine_pcm_unregister(&pdev->dev);
668
669         pm_runtime_disable(&pdev->dev);
670         if (!pm_runtime_status_suspended(&pdev->dev))
671                 sun4i_i2s_runtime_suspend(&pdev->dev);
672
673         return 0;
674 }
675
676 static const struct of_device_id sun4i_i2s_match[] = {
677         { .compatible = "allwinner,sun4i-a10-i2s", },
678         {}
679 };
680 MODULE_DEVICE_TABLE(of, sun4i_i2s_match);
681
682 static const struct dev_pm_ops sun4i_i2s_pm_ops = {
683         .runtime_resume         = sun4i_i2s_runtime_resume,
684         .runtime_suspend        = sun4i_i2s_runtime_suspend,
685 };
686
687 static struct platform_driver sun4i_i2s_driver = {
688         .probe  = sun4i_i2s_probe,
689         .remove = sun4i_i2s_remove,
690         .driver = {
691                 .name           = "sun4i-i2s",
692                 .of_match_table = sun4i_i2s_match,
693                 .pm             = &sun4i_i2s_pm_ops,
694         },
695 };
696 module_platform_driver(sun4i_i2s_driver);
697
698 MODULE_AUTHOR("Andrea Venturi <be17068@iperbole.bo.it>");
699 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
700 MODULE_DESCRIPTION("Allwinner A10 I2S driver");
701 MODULE_LICENSE("GPL");