]> asedeno.scripts.mit.edu Git - linux.git/blob - sound/soc/sunxi/sun4i-codec.c
ASoC: sun4i-codec: Add FM Playback Volume, FM Left, FM Right, FM Playback Switch
[linux.git] / sound / soc / sunxi / sun4i-codec.c
1 /*
2  * Copyright 2014 Emilio López <emilio@elopez.com.ar>
3  * Copyright 2014 Jon Smirl <jonsmirl@gmail.com>
4  * Copyright 2015 Maxime Ripard <maxime.ripard@free-electrons.com>
5  * Copyright 2015 Adam Sampson <ats@offog.org>
6  * Copyright 2016 Chen-Yu Tsai <wens@csie.org>
7  *
8  * Based on the Allwinner SDK driver, released under the GPL.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  */
20
21 #include <linux/init.h>
22 #include <linux/kernel.h>
23 #include <linux/module.h>
24 #include <linux/platform_device.h>
25 #include <linux/delay.h>
26 #include <linux/slab.h>
27 #include <linux/of.h>
28 #include <linux/of_address.h>
29 #include <linux/of_device.h>
30 #include <linux/of_platform.h>
31 #include <linux/clk.h>
32 #include <linux/regmap.h>
33 #include <linux/reset.h>
34 #include <linux/gpio/consumer.h>
35
36 #include <sound/core.h>
37 #include <sound/pcm.h>
38 #include <sound/pcm_params.h>
39 #include <sound/soc.h>
40 #include <sound/tlv.h>
41 #include <sound/initval.h>
42 #include <sound/dmaengine_pcm.h>
43
44 /* Codec DAC digital controls and FIFO registers */
45 #define SUN4I_CODEC_DAC_DPC                     (0x00)
46 #define SUN4I_CODEC_DAC_DPC_EN_DA                       (31)
47 #define SUN4I_CODEC_DAC_DPC_DVOL                        (12)
48 #define SUN4I_CODEC_DAC_FIFOC                   (0x04)
49 #define SUN4I_CODEC_DAC_FIFOC_DAC_FS                    (29)
50 #define SUN4I_CODEC_DAC_FIFOC_FIR_VERSION               (28)
51 #define SUN4I_CODEC_DAC_FIFOC_SEND_LASAT                (26)
52 #define SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE              (24)
53 #define SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT               (21)
54 #define SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL             (8)
55 #define SUN4I_CODEC_DAC_FIFOC_MONO_EN                   (6)
56 #define SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS            (5)
57 #define SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN                (4)
58 #define SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH                (0)
59 #define SUN4I_CODEC_DAC_FIFOS                   (0x08)
60 #define SUN4I_CODEC_DAC_TXDATA                  (0x0c)
61
62 /* Codec DAC side analog signal controls */
63 #define SUN4I_CODEC_DAC_ACTL                    (0x10)
64 #define SUN4I_CODEC_DAC_ACTL_DACAENR                    (31)
65 #define SUN4I_CODEC_DAC_ACTL_DACAENL                    (30)
66 #define SUN4I_CODEC_DAC_ACTL_MIXEN                      (29)
67 #define SUN4I_CODEC_DAC_ACTL_FMG                        (23)
68 #define SUN4I_CODEC_DAC_ACTL_MICG                       (20)
69 #define SUN4I_CODEC_DAC_ACTL_LFMS                       (17)
70 #define SUN4I_CODEC_DAC_ACTL_RFMS                       (16)
71 #define SUN4I_CODEC_DAC_ACTL_LDACLMIXS                  (15)
72 #define SUN4I_CODEC_DAC_ACTL_RDACRMIXS                  (14)
73 #define SUN4I_CODEC_DAC_ACTL_LDACRMIXS                  (13)
74 #define SUN4I_CODEC_DAC_ACTL_MIC1LS                     (12)
75 #define SUN4I_CODEC_DAC_ACTL_MIC1RS                     (11)
76 #define SUN4I_CODEC_DAC_ACTL_MIC2LS                     (10)
77 #define SUN4I_CODEC_DAC_ACTL_MIC2RS                     (9)
78 #define SUN4I_CODEC_DAC_ACTL_DACPAS                     (8)
79 #define SUN4I_CODEC_DAC_ACTL_MIXPAS                     (7)
80 #define SUN4I_CODEC_DAC_ACTL_PA_MUTE                    (6)
81 #define SUN4I_CODEC_DAC_ACTL_PA_VOL                     (0)
82 #define SUN4I_CODEC_DAC_TUNE                    (0x14)
83 #define SUN4I_CODEC_DAC_DEBUG                   (0x18)
84
85 /* Codec ADC digital controls and FIFO registers */
86 #define SUN4I_CODEC_ADC_FIFOC                   (0x1c)
87 #define SUN4I_CODEC_ADC_FIFOC_ADC_FS                    (29)
88 #define SUN4I_CODEC_ADC_FIFOC_EN_AD                     (28)
89 #define SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE              (24)
90 #define SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL             (8)
91 #define SUN4I_CODEC_ADC_FIFOC_MONO_EN                   (7)
92 #define SUN4I_CODEC_ADC_FIFOC_RX_SAMPLE_BITS            (6)
93 #define SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN                (4)
94 #define SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH                (0)
95 #define SUN4I_CODEC_ADC_FIFOS                   (0x20)
96 #define SUN4I_CODEC_ADC_RXDATA                  (0x24)
97
98 /* Codec ADC side analog signal controls */
99 #define SUN4I_CODEC_ADC_ACTL                    (0x28)
100 #define SUN4I_CODEC_ADC_ACTL_ADC_R_EN                   (31)
101 #define SUN4I_CODEC_ADC_ACTL_ADC_L_EN                   (30)
102 #define SUN4I_CODEC_ADC_ACTL_PREG1EN                    (29)
103 #define SUN4I_CODEC_ADC_ACTL_PREG2EN                    (28)
104 #define SUN4I_CODEC_ADC_ACTL_VMICEN                     (27)
105 #define SUN4I_CODEC_ADC_ACTL_PREG1                      (25)
106 #define SUN4I_CODEC_ADC_ACTL_PREG2                      (23)
107 #define SUN4I_CODEC_ADC_ACTL_VADCG                      (20)
108 #define SUN4I_CODEC_ADC_ACTL_ADCIS                      (17)
109 #define SUN4I_CODEC_ADC_ACTL_PA_EN                      (4)
110 #define SUN4I_CODEC_ADC_ACTL_DDE                        (3)
111 #define SUN4I_CODEC_ADC_DEBUG                   (0x2c)
112
113 /* FIFO counters */
114 #define SUN4I_CODEC_DAC_TXCNT                   (0x30)
115 #define SUN4I_CODEC_ADC_RXCNT                   (0x34)
116
117 /* Calibration register (sun7i only) */
118 #define SUN7I_CODEC_AC_DAC_CAL                  (0x38)
119
120 /* Microphone controls (sun7i only) */
121 #define SUN7I_CODEC_AC_MIC_PHONE_CAL            (0x3c)
122
123 #define SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG1              (29)
124 #define SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG2              (26)
125
126 /*
127  * sun6i specific registers
128  *
129  * sun6i shares the same digital control and FIFO registers as sun4i,
130  * but only the DAC digital controls are at the same offset. The others
131  * have been moved around to accommodate extra analog controls.
132  */
133
134 /* Codec DAC digital controls and FIFO registers */
135 #define SUN6I_CODEC_ADC_FIFOC                   (0x10)
136 #define SUN6I_CODEC_ADC_FIFOC_EN_AD                     (28)
137 #define SUN6I_CODEC_ADC_FIFOS                   (0x14)
138 #define SUN6I_CODEC_ADC_RXDATA                  (0x18)
139
140 /* Output mixer and gain controls */
141 #define SUN6I_CODEC_OM_DACA_CTRL                (0x20)
142 #define SUN6I_CODEC_OM_DACA_CTRL_DACAREN                (31)
143 #define SUN6I_CODEC_OM_DACA_CTRL_DACALEN                (30)
144 #define SUN6I_CODEC_OM_DACA_CTRL_RMIXEN                 (29)
145 #define SUN6I_CODEC_OM_DACA_CTRL_LMIXEN                 (28)
146 #define SUN6I_CODEC_OM_DACA_CTRL_RMIX_MIC1              (23)
147 #define SUN6I_CODEC_OM_DACA_CTRL_RMIX_MIC2              (22)
148 #define SUN6I_CODEC_OM_DACA_CTRL_RMIX_PHONE             (21)
149 #define SUN6I_CODEC_OM_DACA_CTRL_RMIX_PHONEP            (20)
150 #define SUN6I_CODEC_OM_DACA_CTRL_RMIX_LINEINR           (19)
151 #define SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACR              (18)
152 #define SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACL              (17)
153 #define SUN6I_CODEC_OM_DACA_CTRL_LMIX_MIC1              (16)
154 #define SUN6I_CODEC_OM_DACA_CTRL_LMIX_MIC2              (15)
155 #define SUN6I_CODEC_OM_DACA_CTRL_LMIX_PHONE             (14)
156 #define SUN6I_CODEC_OM_DACA_CTRL_LMIX_PHONEN            (13)
157 #define SUN6I_CODEC_OM_DACA_CTRL_LMIX_LINEINL           (12)
158 #define SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACL              (11)
159 #define SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACR              (10)
160 #define SUN6I_CODEC_OM_DACA_CTRL_RHPIS                  (9)
161 #define SUN6I_CODEC_OM_DACA_CTRL_LHPIS                  (8)
162 #define SUN6I_CODEC_OM_DACA_CTRL_RHPPAMUTE              (7)
163 #define SUN6I_CODEC_OM_DACA_CTRL_LHPPAMUTE              (6)
164 #define SUN6I_CODEC_OM_DACA_CTRL_HPVOL                  (0)
165 #define SUN6I_CODEC_OM_PA_CTRL                  (0x24)
166 #define SUN6I_CODEC_OM_PA_CTRL_HPPAEN                   (31)
167 #define SUN6I_CODEC_OM_PA_CTRL_HPCOM_CTL                (29)
168 #define SUN6I_CODEC_OM_PA_CTRL_COMPTEN                  (28)
169 #define SUN6I_CODEC_OM_PA_CTRL_MIC1G                    (15)
170 #define SUN6I_CODEC_OM_PA_CTRL_MIC2G                    (12)
171 #define SUN6I_CODEC_OM_PA_CTRL_LINEING                  (9)
172 #define SUN6I_CODEC_OM_PA_CTRL_PHONEG                   (6)
173 #define SUN6I_CODEC_OM_PA_CTRL_PHONEPG                  (3)
174 #define SUN6I_CODEC_OM_PA_CTRL_PHONENG                  (0)
175
176 /* Microphone, line out and phone out controls */
177 #define SUN6I_CODEC_MIC_CTRL                    (0x28)
178 #define SUN6I_CODEC_MIC_CTRL_HBIASEN                    (31)
179 #define SUN6I_CODEC_MIC_CTRL_MBIASEN                    (30)
180 #define SUN6I_CODEC_MIC_CTRL_MIC1AMPEN                  (28)
181 #define SUN6I_CODEC_MIC_CTRL_MIC1BOOST                  (25)
182 #define SUN6I_CODEC_MIC_CTRL_MIC2AMPEN                  (24)
183 #define SUN6I_CODEC_MIC_CTRL_MIC2BOOST                  (21)
184 #define SUN6I_CODEC_MIC_CTRL_MIC2SLT                    (20)
185 #define SUN6I_CODEC_MIC_CTRL_LINEOUTLEN                 (19)
186 #define SUN6I_CODEC_MIC_CTRL_LINEOUTREN                 (18)
187 #define SUN6I_CODEC_MIC_CTRL_LINEOUTLSRC                (17)
188 #define SUN6I_CODEC_MIC_CTRL_LINEOUTRSRC                (16)
189 #define SUN6I_CODEC_MIC_CTRL_LINEOUTVC                  (11)
190 #define SUN6I_CODEC_MIC_CTRL_PHONEPREG                  (8)
191
192 /* ADC mixer controls */
193 #define SUN6I_CODEC_ADC_ACTL                    (0x2c)
194 #define SUN6I_CODEC_ADC_ACTL_ADCREN                     (31)
195 #define SUN6I_CODEC_ADC_ACTL_ADCLEN                     (30)
196 #define SUN6I_CODEC_ADC_ACTL_ADCRG                      (27)
197 #define SUN6I_CODEC_ADC_ACTL_ADCLG                      (24)
198 #define SUN6I_CODEC_ADC_ACTL_RADCMIX_MIC1               (13)
199 #define SUN6I_CODEC_ADC_ACTL_RADCMIX_MIC2               (12)
200 #define SUN6I_CODEC_ADC_ACTL_RADCMIX_PHONE              (11)
201 #define SUN6I_CODEC_ADC_ACTL_RADCMIX_PHONEP             (10)
202 #define SUN6I_CODEC_ADC_ACTL_RADCMIX_LINEINR            (9)
203 #define SUN6I_CODEC_ADC_ACTL_RADCMIX_OMIXR              (8)
204 #define SUN6I_CODEC_ADC_ACTL_RADCMIX_OMIXL              (7)
205 #define SUN6I_CODEC_ADC_ACTL_LADCMIX_MIC1               (6)
206 #define SUN6I_CODEC_ADC_ACTL_LADCMIX_MIC2               (5)
207 #define SUN6I_CODEC_ADC_ACTL_LADCMIX_PHONE              (4)
208 #define SUN6I_CODEC_ADC_ACTL_LADCMIX_PHONEN             (3)
209 #define SUN6I_CODEC_ADC_ACTL_LADCMIX_LINEINL            (2)
210 #define SUN6I_CODEC_ADC_ACTL_LADCMIX_OMIXL              (1)
211 #define SUN6I_CODEC_ADC_ACTL_LADCMIX_OMIXR              (0)
212
213 /* Analog performance tuning controls */
214 #define SUN6I_CODEC_ADDA_TUNE                   (0x30)
215
216 /* Calibration controls */
217 #define SUN6I_CODEC_CALIBRATION                 (0x34)
218
219 /* FIFO counters */
220 #define SUN6I_CODEC_DAC_TXCNT                   (0x40)
221 #define SUN6I_CODEC_ADC_RXCNT                   (0x44)
222
223 /* headset jack detection and button support registers */
224 #define SUN6I_CODEC_HMIC_CTL                    (0x50)
225 #define SUN6I_CODEC_HMIC_DATA                   (0x54)
226
227 /* TODO sun6i DAP (Digital Audio Processing) bits */
228
229 /* FIFO counters moved on A23 */
230 #define SUN8I_A23_CODEC_DAC_TXCNT               (0x1c)
231 #define SUN8I_A23_CODEC_ADC_RXCNT               (0x20)
232
233 /* TX FIFO moved on H3 */
234 #define SUN8I_H3_CODEC_DAC_TXDATA               (0x20)
235 #define SUN8I_H3_CODEC_DAC_DBG                  (0x48)
236 #define SUN8I_H3_CODEC_ADC_DBG                  (0x4c)
237
238 /* TODO H3 DAP (Digital Audio Processing) bits */
239
240 struct sun4i_codec {
241         struct device   *dev;
242         struct regmap   *regmap;
243         struct clk      *clk_apb;
244         struct clk      *clk_module;
245         struct reset_control *rst;
246         struct gpio_desc *gpio_pa;
247
248         /* ADC_FIFOC register is at different offset on different SoCs */
249         struct regmap_field *reg_adc_fifoc;
250
251         struct snd_dmaengine_dai_dma_data       capture_dma_data;
252         struct snd_dmaengine_dai_dma_data       playback_dma_data;
253 };
254
255 static void sun4i_codec_start_playback(struct sun4i_codec *scodec)
256 {
257         /* Flush TX FIFO */
258         regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
259                            BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH),
260                            BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH));
261
262         /* Enable DAC DRQ */
263         regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
264                            BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN),
265                            BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN));
266 }
267
268 static void sun4i_codec_stop_playback(struct sun4i_codec *scodec)
269 {
270         /* Disable DAC DRQ */
271         regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
272                            BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN),
273                            0);
274 }
275
276 static void sun4i_codec_start_capture(struct sun4i_codec *scodec)
277 {
278         /* Enable ADC DRQ */
279         regmap_field_update_bits(scodec->reg_adc_fifoc,
280                                  BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN),
281                                  BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN));
282 }
283
284 static void sun4i_codec_stop_capture(struct sun4i_codec *scodec)
285 {
286         /* Disable ADC DRQ */
287         regmap_field_update_bits(scodec->reg_adc_fifoc,
288                                  BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN), 0);
289 }
290
291 static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd,
292                                struct snd_soc_dai *dai)
293 {
294         struct snd_soc_pcm_runtime *rtd = substream->private_data;
295         struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
296
297         switch (cmd) {
298         case SNDRV_PCM_TRIGGER_START:
299         case SNDRV_PCM_TRIGGER_RESUME:
300         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
301                 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
302                         sun4i_codec_start_playback(scodec);
303                 else
304                         sun4i_codec_start_capture(scodec);
305                 break;
306
307         case SNDRV_PCM_TRIGGER_STOP:
308         case SNDRV_PCM_TRIGGER_SUSPEND:
309         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
310                 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
311                         sun4i_codec_stop_playback(scodec);
312                 else
313                         sun4i_codec_stop_capture(scodec);
314                 break;
315
316         default:
317                 return -EINVAL;
318         }
319
320         return 0;
321 }
322
323 static int sun4i_codec_prepare_capture(struct snd_pcm_substream *substream,
324                                        struct snd_soc_dai *dai)
325 {
326         struct snd_soc_pcm_runtime *rtd = substream->private_data;
327         struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
328
329
330         /* Flush RX FIFO */
331         regmap_field_update_bits(scodec->reg_adc_fifoc,
332                                  BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH),
333                                  BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH));
334
335
336         /* Set RX FIFO trigger level */
337         regmap_field_update_bits(scodec->reg_adc_fifoc,
338                                  0xf << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL,
339                                  0x7 << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL);
340
341         /*
342          * FIXME: Undocumented in the datasheet, but
343          *        Allwinner's code mentions that it is related
344          *        related to microphone gain
345          */
346         if (of_device_is_compatible(scodec->dev->of_node,
347                                     "allwinner,sun4i-a10-codec") ||
348             of_device_is_compatible(scodec->dev->of_node,
349                                     "allwinner,sun7i-a20-codec")) {
350                 regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_ACTL,
351                                    0x3 << 25,
352                                    0x1 << 25);
353         }
354
355         if (of_device_is_compatible(scodec->dev->of_node,
356                                     "allwinner,sun7i-a20-codec"))
357                 /* FIXME: Undocumented bits */
358                 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_TUNE,
359                                    0x3 << 8,
360                                    0x1 << 8);
361
362         return 0;
363 }
364
365 static int sun4i_codec_prepare_playback(struct snd_pcm_substream *substream,
366                                         struct snd_soc_dai *dai)
367 {
368         struct snd_soc_pcm_runtime *rtd = substream->private_data;
369         struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
370         u32 val;
371
372         /* Flush the TX FIFO */
373         regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
374                            BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH),
375                            BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH));
376
377         /* Set TX FIFO Empty Trigger Level */
378         regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
379                            0x3f << SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL,
380                            0xf << SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL);
381
382         if (substream->runtime->rate > 32000)
383                 /* Use 64 bits FIR filter */
384                 val = 0;
385         else
386                 /* Use 32 bits FIR filter */
387                 val = BIT(SUN4I_CODEC_DAC_FIFOC_FIR_VERSION);
388
389         regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
390                            BIT(SUN4I_CODEC_DAC_FIFOC_FIR_VERSION),
391                            val);
392
393         /* Send zeros when we have an underrun */
394         regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
395                            BIT(SUN4I_CODEC_DAC_FIFOC_SEND_LASAT),
396                            0);
397
398         return 0;
399 };
400
401 static int sun4i_codec_prepare(struct snd_pcm_substream *substream,
402                                struct snd_soc_dai *dai)
403 {
404         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
405                 return sun4i_codec_prepare_playback(substream, dai);
406
407         return sun4i_codec_prepare_capture(substream, dai);
408 }
409
410 static unsigned long sun4i_codec_get_mod_freq(struct snd_pcm_hw_params *params)
411 {
412         unsigned int rate = params_rate(params);
413
414         switch (rate) {
415         case 176400:
416         case 88200:
417         case 44100:
418         case 33075:
419         case 22050:
420         case 14700:
421         case 11025:
422         case 7350:
423                 return 22579200;
424
425         case 192000:
426         case 96000:
427         case 48000:
428         case 32000:
429         case 24000:
430         case 16000:
431         case 12000:
432         case 8000:
433                 return 24576000;
434
435         default:
436                 return 0;
437         }
438 }
439
440 static int sun4i_codec_get_hw_rate(struct snd_pcm_hw_params *params)
441 {
442         unsigned int rate = params_rate(params);
443
444         switch (rate) {
445         case 192000:
446         case 176400:
447                 return 6;
448
449         case 96000:
450         case 88200:
451                 return 7;
452
453         case 48000:
454         case 44100:
455                 return 0;
456
457         case 32000:
458         case 33075:
459                 return 1;
460
461         case 24000:
462         case 22050:
463                 return 2;
464
465         case 16000:
466         case 14700:
467                 return 3;
468
469         case 12000:
470         case 11025:
471                 return 4;
472
473         case 8000:
474         case 7350:
475                 return 5;
476
477         default:
478                 return -EINVAL;
479         }
480 }
481
482 static int sun4i_codec_hw_params_capture(struct sun4i_codec *scodec,
483                                          struct snd_pcm_hw_params *params,
484                                          unsigned int hwrate)
485 {
486         /* Set ADC sample rate */
487         regmap_field_update_bits(scodec->reg_adc_fifoc,
488                                  7 << SUN4I_CODEC_ADC_FIFOC_ADC_FS,
489                                  hwrate << SUN4I_CODEC_ADC_FIFOC_ADC_FS);
490
491         /* Set the number of channels we want to use */
492         if (params_channels(params) == 1)
493                 regmap_field_update_bits(scodec->reg_adc_fifoc,
494                                          BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN),
495                                          BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN));
496         else
497                 regmap_field_update_bits(scodec->reg_adc_fifoc,
498                                          BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN),
499                                          0);
500
501         /* Set the number of sample bits to either 16 or 24 bits */
502         if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min == 32) {
503                 regmap_field_update_bits(scodec->reg_adc_fifoc,
504                                    BIT(SUN4I_CODEC_ADC_FIFOC_RX_SAMPLE_BITS),
505                                    BIT(SUN4I_CODEC_ADC_FIFOC_RX_SAMPLE_BITS));
506
507                 regmap_field_update_bits(scodec->reg_adc_fifoc,
508                                    BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE),
509                                    0);
510
511                 scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
512         } else {
513                 regmap_field_update_bits(scodec->reg_adc_fifoc,
514                                    BIT(SUN4I_CODEC_ADC_FIFOC_RX_SAMPLE_BITS),
515                                    0);
516
517                 /* Fill most significant bits with valid data MSB */
518                 regmap_field_update_bits(scodec->reg_adc_fifoc,
519                                    BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE),
520                                    BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE));
521
522                 scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
523         }
524
525         return 0;
526 }
527
528 static int sun4i_codec_hw_params_playback(struct sun4i_codec *scodec,
529                                           struct snd_pcm_hw_params *params,
530                                           unsigned int hwrate)
531 {
532         u32 val;
533
534         /* Set DAC sample rate */
535         regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
536                            7 << SUN4I_CODEC_DAC_FIFOC_DAC_FS,
537                            hwrate << SUN4I_CODEC_DAC_FIFOC_DAC_FS);
538
539         /* Set the number of channels we want to use */
540         if (params_channels(params) == 1)
541                 val = BIT(SUN4I_CODEC_DAC_FIFOC_MONO_EN);
542         else
543                 val = 0;
544
545         regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
546                            BIT(SUN4I_CODEC_DAC_FIFOC_MONO_EN),
547                            val);
548
549         /* Set the number of sample bits to either 16 or 24 bits */
550         if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min == 32) {
551                 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
552                                    BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS),
553                                    BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS));
554
555                 /* Set TX FIFO mode to padding the LSBs with 0 */
556                 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
557                                    BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE),
558                                    0);
559
560                 scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
561         } else {
562                 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
563                                    BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS),
564                                    0);
565
566                 /* Set TX FIFO mode to repeat the MSB */
567                 regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
568                                    BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE),
569                                    BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE));
570
571                 scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
572         }
573
574         return 0;
575 }
576
577 static int sun4i_codec_hw_params(struct snd_pcm_substream *substream,
578                                  struct snd_pcm_hw_params *params,
579                                  struct snd_soc_dai *dai)
580 {
581         struct snd_soc_pcm_runtime *rtd = substream->private_data;
582         struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
583         unsigned long clk_freq;
584         int ret, hwrate;
585
586         clk_freq = sun4i_codec_get_mod_freq(params);
587         if (!clk_freq)
588                 return -EINVAL;
589
590         ret = clk_set_rate(scodec->clk_module, clk_freq);
591         if (ret)
592                 return ret;
593
594         hwrate = sun4i_codec_get_hw_rate(params);
595         if (hwrate < 0)
596                 return hwrate;
597
598         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
599                 return sun4i_codec_hw_params_playback(scodec, params,
600                                                       hwrate);
601
602         return sun4i_codec_hw_params_capture(scodec, params,
603                                              hwrate);
604 }
605
606
607 static unsigned int sun4i_codec_src_rates[] = {
608         8000, 11025, 12000, 16000, 22050, 24000, 32000,
609         44100, 48000, 96000, 192000
610 };
611
612
613 static struct snd_pcm_hw_constraint_list sun4i_codec_constraints = {
614         .count  = ARRAY_SIZE(sun4i_codec_src_rates),
615         .list   = sun4i_codec_src_rates,
616 };
617
618
619 static int sun4i_codec_startup(struct snd_pcm_substream *substream,
620                                struct snd_soc_dai *dai)
621 {
622         struct snd_soc_pcm_runtime *rtd = substream->private_data;
623         struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
624
625         snd_pcm_hw_constraint_list(substream->runtime, 0,
626                                 SNDRV_PCM_HW_PARAM_RATE, &sun4i_codec_constraints);
627
628         /*
629          * Stop issuing DRQ when we have room for less than 16 samples
630          * in our TX FIFO
631          */
632         regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_FIFOC,
633                            3 << SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT,
634                            3 << SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT);
635
636         return clk_prepare_enable(scodec->clk_module);
637 }
638
639 static void sun4i_codec_shutdown(struct snd_pcm_substream *substream,
640                                  struct snd_soc_dai *dai)
641 {
642         struct snd_soc_pcm_runtime *rtd = substream->private_data;
643         struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
644
645         clk_disable_unprepare(scodec->clk_module);
646 }
647
648 static const struct snd_soc_dai_ops sun4i_codec_dai_ops = {
649         .startup        = sun4i_codec_startup,
650         .shutdown       = sun4i_codec_shutdown,
651         .trigger        = sun4i_codec_trigger,
652         .hw_params      = sun4i_codec_hw_params,
653         .prepare        = sun4i_codec_prepare,
654 };
655
656 static struct snd_soc_dai_driver sun4i_codec_dai = {
657         .name   = "Codec",
658         .ops    = &sun4i_codec_dai_ops,
659         .playback = {
660                 .stream_name    = "Codec Playback",
661                 .channels_min   = 1,
662                 .channels_max   = 2,
663                 .rate_min       = 8000,
664                 .rate_max       = 192000,
665                 .rates          = SNDRV_PCM_RATE_CONTINUOUS,
666                 .formats        = SNDRV_PCM_FMTBIT_S16_LE |
667                                   SNDRV_PCM_FMTBIT_S32_LE,
668                 .sig_bits       = 24,
669         },
670         .capture = {
671                 .stream_name    = "Codec Capture",
672                 .channels_min   = 1,
673                 .channels_max   = 2,
674                 .rate_min       = 8000,
675                 .rate_max       = 48000,
676                 .rates          = SNDRV_PCM_RATE_CONTINUOUS,
677                 .formats        = SNDRV_PCM_FMTBIT_S16_LE |
678                                   SNDRV_PCM_FMTBIT_S32_LE,
679                 .sig_bits       = 24,
680         },
681 };
682
683 /*** sun4i Codec ***/
684 static const struct snd_kcontrol_new sun4i_codec_pa_mute =
685         SOC_DAPM_SINGLE("Switch", SUN4I_CODEC_DAC_ACTL,
686                         SUN4I_CODEC_DAC_ACTL_PA_MUTE, 1, 0);
687
688 static DECLARE_TLV_DB_SCALE(sun4i_codec_pa_volume_scale, -6300, 100, 1);
689 static DECLARE_TLV_DB_SCALE(sun4i_codec_fmin_loopback_gain_scale, -450, 150,
690                             0);
691 static DECLARE_TLV_DB_SCALE(sun4i_codec_micin_loopback_gain_scale, -450, 150,
692                             0);
693 static DECLARE_TLV_DB_RANGE(sun4i_codec_micin_preamp_gain_scale,
694                             0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
695                             1, 7, TLV_DB_SCALE_ITEM(3500, 300, 0));
696 static DECLARE_TLV_DB_RANGE(sun7i_codec_micin_preamp_gain_scale,
697                             0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
698                             1, 7, TLV_DB_SCALE_ITEM(2400, 300, 0));
699
700 static const struct snd_kcontrol_new sun4i_codec_controls[] = {
701         SOC_SINGLE_TLV("Power Amplifier Volume", SUN4I_CODEC_DAC_ACTL,
702                        SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0,
703                        sun4i_codec_pa_volume_scale),
704         SOC_SINGLE_TLV("FM Playback Volume", SUN4I_CODEC_DAC_ACTL,
705                        SUN4I_CODEC_DAC_ACTL_FMG, 3, 0,
706                        sun4i_codec_fmin_loopback_gain_scale),
707         SOC_SINGLE_TLV("Mic Playback Volume", SUN4I_CODEC_DAC_ACTL,
708                        SUN4I_CODEC_DAC_ACTL_MICG, 7, 0,
709                        sun4i_codec_micin_loopback_gain_scale),
710         SOC_SINGLE_TLV("Mic1 Boost Volume", SUN4I_CODEC_ADC_ACTL,
711                        SUN4I_CODEC_ADC_ACTL_PREG1, 3, 0,
712                        sun4i_codec_micin_preamp_gain_scale),
713         SOC_SINGLE_TLV("Mic2 Boost Volume", SUN4I_CODEC_ADC_ACTL,
714                        SUN4I_CODEC_ADC_ACTL_PREG2, 3, 0,
715                        sun4i_codec_micin_preamp_gain_scale),
716 };
717
718 static const struct snd_kcontrol_new sun7i_codec_controls[] = {
719         SOC_SINGLE_TLV("Power Amplifier Volume", SUN4I_CODEC_DAC_ACTL,
720                        SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0,
721                        sun4i_codec_pa_volume_scale),
722         SOC_SINGLE_TLV("FM Playback Volume", SUN4I_CODEC_DAC_ACTL,
723                        SUN4I_CODEC_DAC_ACTL_FMG, 3, 0,
724                        sun4i_codec_fmin_loopback_gain_scale),
725         SOC_SINGLE_TLV("Mic Playback Volume", SUN4I_CODEC_DAC_ACTL,
726                        SUN4I_CODEC_DAC_ACTL_MICG, 7, 0,
727                        sun4i_codec_micin_loopback_gain_scale),
728         SOC_SINGLE_TLV("Mic1 Boost Volume", SUN7I_CODEC_AC_MIC_PHONE_CAL,
729                        SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG1, 7, 0,
730                        sun7i_codec_micin_preamp_gain_scale),
731         SOC_SINGLE_TLV("Mic2 Boost Volume", SUN7I_CODEC_AC_MIC_PHONE_CAL,
732                        SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG2, 7, 0,
733                        sun7i_codec_micin_preamp_gain_scale),
734 };
735
736 static const struct snd_kcontrol_new sun4i_codec_mixer_controls[] = {
737         SOC_DAPM_SINGLE("Left Mixer Left DAC Playback Switch",
738                         SUN4I_CODEC_DAC_ACTL, SUN4I_CODEC_DAC_ACTL_LDACLMIXS,
739                         1, 0),
740         SOC_DAPM_SINGLE("Right Mixer Right DAC Playback Switch",
741                         SUN4I_CODEC_DAC_ACTL, SUN4I_CODEC_DAC_ACTL_RDACRMIXS,
742                         1, 0),
743         SOC_DAPM_SINGLE("Right Mixer Left DAC Playback Switch",
744                         SUN4I_CODEC_DAC_ACTL,
745                         SUN4I_CODEC_DAC_ACTL_LDACRMIXS, 1, 0),
746         SOC_DAPM_DOUBLE("FM Playback Switch", SUN4I_CODEC_DAC_ACTL,
747                         SUN4I_CODEC_DAC_ACTL_LFMS,
748                         SUN4I_CODEC_DAC_ACTL_RFMS, 1, 0),
749         SOC_DAPM_DOUBLE("Mic1 Playback Switch", SUN4I_CODEC_DAC_ACTL,
750                         SUN4I_CODEC_DAC_ACTL_MIC1LS,
751                         SUN4I_CODEC_DAC_ACTL_MIC1RS, 1, 0),
752         SOC_DAPM_DOUBLE("Mic2 Playback Switch", SUN4I_CODEC_DAC_ACTL,
753                         SUN4I_CODEC_DAC_ACTL_MIC2LS,
754                         SUN4I_CODEC_DAC_ACTL_MIC2RS, 1, 0),
755 };
756
757 static const struct snd_kcontrol_new sun4i_codec_pa_mixer_controls[] = {
758         SOC_DAPM_SINGLE("DAC Playback Switch", SUN4I_CODEC_DAC_ACTL,
759                         SUN4I_CODEC_DAC_ACTL_DACPAS, 1, 0),
760         SOC_DAPM_SINGLE("Mixer Playback Switch", SUN4I_CODEC_DAC_ACTL,
761                         SUN4I_CODEC_DAC_ACTL_MIXPAS, 1, 0),
762 };
763
764 static const struct snd_soc_dapm_widget sun4i_codec_codec_dapm_widgets[] = {
765         /* Digital parts of the ADCs */
766         SND_SOC_DAPM_SUPPLY("ADC", SUN4I_CODEC_ADC_FIFOC,
767                             SUN4I_CODEC_ADC_FIFOC_EN_AD, 0,
768                             NULL, 0),
769
770         /* Digital parts of the DACs */
771         SND_SOC_DAPM_SUPPLY("DAC", SUN4I_CODEC_DAC_DPC,
772                             SUN4I_CODEC_DAC_DPC_EN_DA, 0,
773                             NULL, 0),
774
775         /* Analog parts of the ADCs */
776         SND_SOC_DAPM_ADC("Left ADC", "Codec Capture", SUN4I_CODEC_ADC_ACTL,
777                          SUN4I_CODEC_ADC_ACTL_ADC_L_EN, 0),
778         SND_SOC_DAPM_ADC("Right ADC", "Codec Capture", SUN4I_CODEC_ADC_ACTL,
779                          SUN4I_CODEC_ADC_ACTL_ADC_R_EN, 0),
780
781         /* Analog parts of the DACs */
782         SND_SOC_DAPM_DAC("Left DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL,
783                          SUN4I_CODEC_DAC_ACTL_DACAENL, 0),
784         SND_SOC_DAPM_DAC("Right DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL,
785                          SUN4I_CODEC_DAC_ACTL_DACAENR, 0),
786
787         /* Mixers */
788         SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
789                            sun4i_codec_mixer_controls,
790                            ARRAY_SIZE(sun4i_codec_mixer_controls)),
791         SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
792                            sun4i_codec_mixer_controls,
793                            ARRAY_SIZE(sun4i_codec_mixer_controls)),
794
795         /* Global Mixer Enable */
796         SND_SOC_DAPM_SUPPLY("Mixer Enable", SUN4I_CODEC_DAC_ACTL,
797                             SUN4I_CODEC_DAC_ACTL_MIXEN, 0, NULL, 0),
798
799         /* VMIC */
800         SND_SOC_DAPM_SUPPLY("VMIC", SUN4I_CODEC_ADC_ACTL,
801                             SUN4I_CODEC_ADC_ACTL_VMICEN, 0, NULL, 0),
802
803         /* Mic Pre-Amplifiers */
804         SND_SOC_DAPM_PGA("MIC1 Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
805                          SUN4I_CODEC_ADC_ACTL_PREG1EN, 0, NULL, 0),
806         SND_SOC_DAPM_PGA("MIC2 Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
807                          SUN4I_CODEC_ADC_ACTL_PREG2EN, 0, NULL, 0),
808
809         /* Power Amplifier */
810         SND_SOC_DAPM_MIXER("Power Amplifier", SUN4I_CODEC_ADC_ACTL,
811                            SUN4I_CODEC_ADC_ACTL_PA_EN, 0,
812                            sun4i_codec_pa_mixer_controls,
813                            ARRAY_SIZE(sun4i_codec_pa_mixer_controls)),
814         SND_SOC_DAPM_SWITCH("Power Amplifier Mute", SND_SOC_NOPM, 0, 0,
815                             &sun4i_codec_pa_mute),
816
817         SND_SOC_DAPM_INPUT("FM Right"),
818         SND_SOC_DAPM_INPUT("FM Left"),
819         SND_SOC_DAPM_INPUT("Mic1"),
820         SND_SOC_DAPM_INPUT("Mic2"),
821
822         SND_SOC_DAPM_OUTPUT("HP Right"),
823         SND_SOC_DAPM_OUTPUT("HP Left"),
824 };
825
826 static const struct snd_soc_dapm_route sun4i_codec_codec_dapm_routes[] = {
827         /* Left ADC / DAC Routes */
828         { "Left ADC", NULL, "ADC" },
829         { "Left DAC", NULL, "DAC" },
830
831         /* Right ADC / DAC Routes */
832         { "Right ADC", NULL, "ADC" },
833         { "Right DAC", NULL, "DAC" },
834
835         /* Right Mixer Routes */
836         { "Right Mixer", NULL, "Mixer Enable" },
837         { "Right Mixer", "Right Mixer Left DAC Playback Switch", "Left DAC" },
838         { "Right Mixer", "Right Mixer Right DAC Playback Switch", "Right DAC" },
839         { "Right Mixer", "FM Playback Switch", "FM Right" },
840         { "Right Mixer", "Mic1 Playback Switch", "MIC1 Pre-Amplifier" },
841         { "Right Mixer", "Mic2 Playback Switch", "MIC2 Pre-Amplifier" },
842
843         /* Left Mixer Routes */
844         { "Left Mixer", NULL, "Mixer Enable" },
845         { "Left Mixer", "Left Mixer Left DAC Playback Switch", "Left DAC" },
846         { "Left Mixer", "FM Playback Switch", "FM Left" },
847         { "Left Mixer", "Mic1 Playback Switch", "MIC1 Pre-Amplifier" },
848         { "Left Mixer", "Mic2 Playback Switch", "MIC2 Pre-Amplifier" },
849
850         /* Power Amplifier Routes */
851         { "Power Amplifier", "Mixer Playback Switch", "Left Mixer" },
852         { "Power Amplifier", "Mixer Playback Switch", "Right Mixer" },
853         { "Power Amplifier", "DAC Playback Switch", "Left DAC" },
854         { "Power Amplifier", "DAC Playback Switch", "Right DAC" },
855
856         /* Headphone Output Routes */
857         { "Power Amplifier Mute", "Switch", "Power Amplifier" },
858         { "HP Right", NULL, "Power Amplifier Mute" },
859         { "HP Left", NULL, "Power Amplifier Mute" },
860
861         /* Mic1 Routes */
862         { "Left ADC", NULL, "MIC1 Pre-Amplifier" },
863         { "Right ADC", NULL, "MIC1 Pre-Amplifier" },
864         { "MIC1 Pre-Amplifier", NULL, "Mic1"},
865         { "Mic1", NULL, "VMIC" },
866
867         /* Mic2 Routes */
868         { "Left ADC", NULL, "MIC2 Pre-Amplifier" },
869         { "Right ADC", NULL, "MIC2 Pre-Amplifier" },
870         { "MIC2 Pre-Amplifier", NULL, "Mic2"},
871         { "Mic2", NULL, "VMIC" },
872 };
873
874 static const struct snd_soc_component_driver sun4i_codec_codec = {
875         .controls               = sun4i_codec_controls,
876         .num_controls           = ARRAY_SIZE(sun4i_codec_controls),
877         .dapm_widgets           = sun4i_codec_codec_dapm_widgets,
878         .num_dapm_widgets       = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
879         .dapm_routes            = sun4i_codec_codec_dapm_routes,
880         .num_dapm_routes        = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
881         .idle_bias_on           = 1,
882         .use_pmdown_time        = 1,
883         .endianness             = 1,
884         .non_legacy_dai_naming  = 1,
885 };
886
887 static const struct snd_soc_component_driver sun7i_codec_codec = {
888         .controls               = sun7i_codec_controls,
889         .num_controls           = ARRAY_SIZE(sun7i_codec_controls),
890         .dapm_widgets           = sun4i_codec_codec_dapm_widgets,
891         .num_dapm_widgets       = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
892         .dapm_routes            = sun4i_codec_codec_dapm_routes,
893         .num_dapm_routes        = ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
894         .idle_bias_on           = 1,
895         .use_pmdown_time        = 1,
896         .endianness             = 1,
897         .non_legacy_dai_naming  = 1,
898 };
899
900 /*** sun6i Codec ***/
901
902 /* mixer controls */
903 static const struct snd_kcontrol_new sun6i_codec_mixer_controls[] = {
904         SOC_DAPM_DOUBLE("DAC Playback Switch",
905                         SUN6I_CODEC_OM_DACA_CTRL,
906                         SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACL,
907                         SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACR, 1, 0),
908         SOC_DAPM_DOUBLE("DAC Reversed Playback Switch",
909                         SUN6I_CODEC_OM_DACA_CTRL,
910                         SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACR,
911                         SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACL, 1, 0),
912         SOC_DAPM_DOUBLE("Line In Playback Switch",
913                         SUN6I_CODEC_OM_DACA_CTRL,
914                         SUN6I_CODEC_OM_DACA_CTRL_LMIX_LINEINL,
915                         SUN6I_CODEC_OM_DACA_CTRL_RMIX_LINEINR, 1, 0),
916         SOC_DAPM_DOUBLE("Mic1 Playback Switch",
917                         SUN6I_CODEC_OM_DACA_CTRL,
918                         SUN6I_CODEC_OM_DACA_CTRL_LMIX_MIC1,
919                         SUN6I_CODEC_OM_DACA_CTRL_RMIX_MIC1, 1, 0),
920         SOC_DAPM_DOUBLE("Mic2 Playback Switch",
921                         SUN6I_CODEC_OM_DACA_CTRL,
922                         SUN6I_CODEC_OM_DACA_CTRL_LMIX_MIC2,
923                         SUN6I_CODEC_OM_DACA_CTRL_RMIX_MIC2, 1, 0),
924 };
925
926 /* ADC mixer controls */
927 static const struct snd_kcontrol_new sun6i_codec_adc_mixer_controls[] = {
928         SOC_DAPM_DOUBLE("Mixer Capture Switch",
929                         SUN6I_CODEC_ADC_ACTL,
930                         SUN6I_CODEC_ADC_ACTL_LADCMIX_OMIXL,
931                         SUN6I_CODEC_ADC_ACTL_RADCMIX_OMIXR, 1, 0),
932         SOC_DAPM_DOUBLE("Mixer Reversed Capture Switch",
933                         SUN6I_CODEC_ADC_ACTL,
934                         SUN6I_CODEC_ADC_ACTL_LADCMIX_OMIXR,
935                         SUN6I_CODEC_ADC_ACTL_RADCMIX_OMIXL, 1, 0),
936         SOC_DAPM_DOUBLE("Line In Capture Switch",
937                         SUN6I_CODEC_ADC_ACTL,
938                         SUN6I_CODEC_ADC_ACTL_LADCMIX_LINEINL,
939                         SUN6I_CODEC_ADC_ACTL_RADCMIX_LINEINR, 1, 0),
940         SOC_DAPM_DOUBLE("Mic1 Capture Switch",
941                         SUN6I_CODEC_ADC_ACTL,
942                         SUN6I_CODEC_ADC_ACTL_LADCMIX_MIC1,
943                         SUN6I_CODEC_ADC_ACTL_RADCMIX_MIC1, 1, 0),
944         SOC_DAPM_DOUBLE("Mic2 Capture Switch",
945                         SUN6I_CODEC_ADC_ACTL,
946                         SUN6I_CODEC_ADC_ACTL_LADCMIX_MIC2,
947                         SUN6I_CODEC_ADC_ACTL_RADCMIX_MIC2, 1, 0),
948 };
949
950 /* headphone controls */
951 static const char * const sun6i_codec_hp_src_enum_text[] = {
952         "DAC", "Mixer",
953 };
954
955 static SOC_ENUM_DOUBLE_DECL(sun6i_codec_hp_src_enum,
956                             SUN6I_CODEC_OM_DACA_CTRL,
957                             SUN6I_CODEC_OM_DACA_CTRL_LHPIS,
958                             SUN6I_CODEC_OM_DACA_CTRL_RHPIS,
959                             sun6i_codec_hp_src_enum_text);
960
961 static const struct snd_kcontrol_new sun6i_codec_hp_src[] = {
962         SOC_DAPM_ENUM("Headphone Source Playback Route",
963                       sun6i_codec_hp_src_enum),
964 };
965
966 /* microphone controls */
967 static const char * const sun6i_codec_mic2_src_enum_text[] = {
968         "Mic2", "Mic3",
969 };
970
971 static SOC_ENUM_SINGLE_DECL(sun6i_codec_mic2_src_enum,
972                             SUN6I_CODEC_MIC_CTRL,
973                             SUN6I_CODEC_MIC_CTRL_MIC2SLT,
974                             sun6i_codec_mic2_src_enum_text);
975
976 static const struct snd_kcontrol_new sun6i_codec_mic2_src[] = {
977         SOC_DAPM_ENUM("Mic2 Amplifier Source Route",
978                       sun6i_codec_mic2_src_enum),
979 };
980
981 /* line out controls */
982 static const char * const sun6i_codec_lineout_src_enum_text[] = {
983         "Stereo", "Mono Differential",
984 };
985
986 static SOC_ENUM_DOUBLE_DECL(sun6i_codec_lineout_src_enum,
987                             SUN6I_CODEC_MIC_CTRL,
988                             SUN6I_CODEC_MIC_CTRL_LINEOUTLSRC,
989                             SUN6I_CODEC_MIC_CTRL_LINEOUTRSRC,
990                             sun6i_codec_lineout_src_enum_text);
991
992 static const struct snd_kcontrol_new sun6i_codec_lineout_src[] = {
993         SOC_DAPM_ENUM("Line Out Source Playback Route",
994                       sun6i_codec_lineout_src_enum),
995 };
996
997 /* volume / mute controls */
998 static const DECLARE_TLV_DB_SCALE(sun6i_codec_dvol_scale, -7308, 116, 0);
999 static const DECLARE_TLV_DB_SCALE(sun6i_codec_hp_vol_scale, -6300, 100, 1);
1000 static const DECLARE_TLV_DB_SCALE(sun6i_codec_out_mixer_pregain_scale,
1001                                   -450, 150, 0);
1002 static const DECLARE_TLV_DB_RANGE(sun6i_codec_lineout_vol_scale,
1003         0, 1, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
1004         2, 31, TLV_DB_SCALE_ITEM(-4350, 150, 0),
1005 );
1006 static const DECLARE_TLV_DB_RANGE(sun6i_codec_mic_gain_scale,
1007         0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
1008         1, 7, TLV_DB_SCALE_ITEM(2400, 300, 0),
1009 );
1010
1011 static const struct snd_kcontrol_new sun6i_codec_codec_widgets[] = {
1012         SOC_SINGLE_TLV("DAC Playback Volume", SUN4I_CODEC_DAC_DPC,
1013                        SUN4I_CODEC_DAC_DPC_DVOL, 0x3f, 1,
1014                        sun6i_codec_dvol_scale),
1015         SOC_SINGLE_TLV("Headphone Playback Volume",
1016                        SUN6I_CODEC_OM_DACA_CTRL,
1017                        SUN6I_CODEC_OM_DACA_CTRL_HPVOL, 0x3f, 0,
1018                        sun6i_codec_hp_vol_scale),
1019         SOC_SINGLE_TLV("Line Out Playback Volume",
1020                        SUN6I_CODEC_MIC_CTRL,
1021                        SUN6I_CODEC_MIC_CTRL_LINEOUTVC, 0x1f, 0,
1022                        sun6i_codec_lineout_vol_scale),
1023         SOC_DOUBLE("Headphone Playback Switch",
1024                    SUN6I_CODEC_OM_DACA_CTRL,
1025                    SUN6I_CODEC_OM_DACA_CTRL_LHPPAMUTE,
1026                    SUN6I_CODEC_OM_DACA_CTRL_RHPPAMUTE, 1, 0),
1027         SOC_DOUBLE("Line Out Playback Switch",
1028                    SUN6I_CODEC_MIC_CTRL,
1029                    SUN6I_CODEC_MIC_CTRL_LINEOUTLEN,
1030                    SUN6I_CODEC_MIC_CTRL_LINEOUTREN, 1, 0),
1031         /* Mixer pre-gains */
1032         SOC_SINGLE_TLV("Line In Playback Volume",
1033                        SUN6I_CODEC_OM_PA_CTRL, SUN6I_CODEC_OM_PA_CTRL_LINEING,
1034                        0x7, 0, sun6i_codec_out_mixer_pregain_scale),
1035         SOC_SINGLE_TLV("Mic1 Playback Volume",
1036                        SUN6I_CODEC_OM_PA_CTRL, SUN6I_CODEC_OM_PA_CTRL_MIC1G,
1037                        0x7, 0, sun6i_codec_out_mixer_pregain_scale),
1038         SOC_SINGLE_TLV("Mic2 Playback Volume",
1039                        SUN6I_CODEC_OM_PA_CTRL, SUN6I_CODEC_OM_PA_CTRL_MIC2G,
1040                        0x7, 0, sun6i_codec_out_mixer_pregain_scale),
1041
1042         /* Microphone Amp boost gains */
1043         SOC_SINGLE_TLV("Mic1 Boost Volume", SUN6I_CODEC_MIC_CTRL,
1044                        SUN6I_CODEC_MIC_CTRL_MIC1BOOST, 0x7, 0,
1045                        sun6i_codec_mic_gain_scale),
1046         SOC_SINGLE_TLV("Mic2 Boost Volume", SUN6I_CODEC_MIC_CTRL,
1047                        SUN6I_CODEC_MIC_CTRL_MIC2BOOST, 0x7, 0,
1048                        sun6i_codec_mic_gain_scale),
1049         SOC_DOUBLE_TLV("ADC Capture Volume",
1050                        SUN6I_CODEC_ADC_ACTL, SUN6I_CODEC_ADC_ACTL_ADCLG,
1051                        SUN6I_CODEC_ADC_ACTL_ADCRG, 0x7, 0,
1052                        sun6i_codec_out_mixer_pregain_scale),
1053 };
1054
1055 static const struct snd_soc_dapm_widget sun6i_codec_codec_dapm_widgets[] = {
1056         /* Microphone inputs */
1057         SND_SOC_DAPM_INPUT("MIC1"),
1058         SND_SOC_DAPM_INPUT("MIC2"),
1059         SND_SOC_DAPM_INPUT("MIC3"),
1060
1061         /* Microphone Bias */
1062         SND_SOC_DAPM_SUPPLY("HBIAS", SUN6I_CODEC_MIC_CTRL,
1063                             SUN6I_CODEC_MIC_CTRL_HBIASEN, 0, NULL, 0),
1064         SND_SOC_DAPM_SUPPLY("MBIAS", SUN6I_CODEC_MIC_CTRL,
1065                             SUN6I_CODEC_MIC_CTRL_MBIASEN, 0, NULL, 0),
1066
1067         /* Mic input path */
1068         SND_SOC_DAPM_MUX("Mic2 Amplifier Source Route",
1069                          SND_SOC_NOPM, 0, 0, sun6i_codec_mic2_src),
1070         SND_SOC_DAPM_PGA("Mic1 Amplifier", SUN6I_CODEC_MIC_CTRL,
1071                          SUN6I_CODEC_MIC_CTRL_MIC1AMPEN, 0, NULL, 0),
1072         SND_SOC_DAPM_PGA("Mic2 Amplifier", SUN6I_CODEC_MIC_CTRL,
1073                          SUN6I_CODEC_MIC_CTRL_MIC2AMPEN, 0, NULL, 0),
1074
1075         /* Line In */
1076         SND_SOC_DAPM_INPUT("LINEIN"),
1077
1078         /* Digital parts of the ADCs */
1079         SND_SOC_DAPM_SUPPLY("ADC Enable", SUN6I_CODEC_ADC_FIFOC,
1080                             SUN6I_CODEC_ADC_FIFOC_EN_AD, 0,
1081                             NULL, 0),
1082
1083         /* Analog parts of the ADCs */
1084         SND_SOC_DAPM_ADC("Left ADC", "Codec Capture", SUN6I_CODEC_ADC_ACTL,
1085                          SUN6I_CODEC_ADC_ACTL_ADCLEN, 0),
1086         SND_SOC_DAPM_ADC("Right ADC", "Codec Capture", SUN6I_CODEC_ADC_ACTL,
1087                          SUN6I_CODEC_ADC_ACTL_ADCREN, 0),
1088
1089         /* ADC Mixers */
1090         SOC_MIXER_ARRAY("Left ADC Mixer", SND_SOC_NOPM, 0, 0,
1091                         sun6i_codec_adc_mixer_controls),
1092         SOC_MIXER_ARRAY("Right ADC Mixer", SND_SOC_NOPM, 0, 0,
1093                         sun6i_codec_adc_mixer_controls),
1094
1095         /* Digital parts of the DACs */
1096         SND_SOC_DAPM_SUPPLY("DAC Enable", SUN4I_CODEC_DAC_DPC,
1097                             SUN4I_CODEC_DAC_DPC_EN_DA, 0,
1098                             NULL, 0),
1099
1100         /* Analog parts of the DACs */
1101         SND_SOC_DAPM_DAC("Left DAC", "Codec Playback",
1102                          SUN6I_CODEC_OM_DACA_CTRL,
1103                          SUN6I_CODEC_OM_DACA_CTRL_DACALEN, 0),
1104         SND_SOC_DAPM_DAC("Right DAC", "Codec Playback",
1105                          SUN6I_CODEC_OM_DACA_CTRL,
1106                          SUN6I_CODEC_OM_DACA_CTRL_DACAREN, 0),
1107
1108         /* Mixers */
1109         SOC_MIXER_ARRAY("Left Mixer", SUN6I_CODEC_OM_DACA_CTRL,
1110                         SUN6I_CODEC_OM_DACA_CTRL_LMIXEN, 0,
1111                         sun6i_codec_mixer_controls),
1112         SOC_MIXER_ARRAY("Right Mixer", SUN6I_CODEC_OM_DACA_CTRL,
1113                         SUN6I_CODEC_OM_DACA_CTRL_RMIXEN, 0,
1114                         sun6i_codec_mixer_controls),
1115
1116         /* Headphone output path */
1117         SND_SOC_DAPM_MUX("Headphone Source Playback Route",
1118                          SND_SOC_NOPM, 0, 0, sun6i_codec_hp_src),
1119         SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN6I_CODEC_OM_PA_CTRL,
1120                              SUN6I_CODEC_OM_PA_CTRL_HPPAEN, 0, NULL, 0),
1121         SND_SOC_DAPM_SUPPLY("HPCOM Protection", SUN6I_CODEC_OM_PA_CTRL,
1122                             SUN6I_CODEC_OM_PA_CTRL_COMPTEN, 0, NULL, 0),
1123         SND_SOC_DAPM_REG(snd_soc_dapm_supply, "HPCOM", SUN6I_CODEC_OM_PA_CTRL,
1124                          SUN6I_CODEC_OM_PA_CTRL_HPCOM_CTL, 0x3, 0x3, 0),
1125         SND_SOC_DAPM_OUTPUT("HP"),
1126
1127         /* Line Out path */
1128         SND_SOC_DAPM_MUX("Line Out Source Playback Route",
1129                          SND_SOC_NOPM, 0, 0, sun6i_codec_lineout_src),
1130         SND_SOC_DAPM_OUTPUT("LINEOUT"),
1131 };
1132
1133 static const struct snd_soc_dapm_route sun6i_codec_codec_dapm_routes[] = {
1134         /* DAC Routes */
1135         { "Left DAC", NULL, "DAC Enable" },
1136         { "Right DAC", NULL, "DAC Enable" },
1137
1138         /* Microphone Routes */
1139         { "Mic1 Amplifier", NULL, "MIC1"},
1140         { "Mic2 Amplifier Source Route", "Mic2", "MIC2" },
1141         { "Mic2 Amplifier Source Route", "Mic3", "MIC3" },
1142         { "Mic2 Amplifier", NULL, "Mic2 Amplifier Source Route"},
1143
1144         /* Left Mixer Routes */
1145         { "Left Mixer", "DAC Playback Switch", "Left DAC" },
1146         { "Left Mixer", "DAC Reversed Playback Switch", "Right DAC" },
1147         { "Left Mixer", "Line In Playback Switch", "LINEIN" },
1148         { "Left Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" },
1149         { "Left Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
1150
1151         /* Right Mixer Routes */
1152         { "Right Mixer", "DAC Playback Switch", "Right DAC" },
1153         { "Right Mixer", "DAC Reversed Playback Switch", "Left DAC" },
1154         { "Right Mixer", "Line In Playback Switch", "LINEIN" },
1155         { "Right Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" },
1156         { "Right Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
1157
1158         /* Left ADC Mixer Routes */
1159         { "Left ADC Mixer", "Mixer Capture Switch", "Left Mixer" },
1160         { "Left ADC Mixer", "Mixer Reversed Capture Switch", "Right Mixer" },
1161         { "Left ADC Mixer", "Line In Capture Switch", "LINEIN" },
1162         { "Left ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" },
1163         { "Left ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
1164
1165         /* Right ADC Mixer Routes */
1166         { "Right ADC Mixer", "Mixer Capture Switch", "Right Mixer" },
1167         { "Right ADC Mixer", "Mixer Reversed Capture Switch", "Left Mixer" },
1168         { "Right ADC Mixer", "Line In Capture Switch", "LINEIN" },
1169         { "Right ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" },
1170         { "Right ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
1171
1172         /* Headphone Routes */
1173         { "Headphone Source Playback Route", "DAC", "Left DAC" },
1174         { "Headphone Source Playback Route", "DAC", "Right DAC" },
1175         { "Headphone Source Playback Route", "Mixer", "Left Mixer" },
1176         { "Headphone Source Playback Route", "Mixer", "Right Mixer" },
1177         { "Headphone Amp", NULL, "Headphone Source Playback Route" },
1178         { "HP", NULL, "Headphone Amp" },
1179         { "HPCOM", NULL, "HPCOM Protection" },
1180
1181         /* Line Out Routes */
1182         { "Line Out Source Playback Route", "Stereo", "Left Mixer" },
1183         { "Line Out Source Playback Route", "Stereo", "Right Mixer" },
1184         { "Line Out Source Playback Route", "Mono Differential", "Left Mixer" },
1185         { "Line Out Source Playback Route", "Mono Differential", "Right Mixer" },
1186         { "LINEOUT", NULL, "Line Out Source Playback Route" },
1187
1188         /* ADC Routes */
1189         { "Left ADC", NULL, "ADC Enable" },
1190         { "Right ADC", NULL, "ADC Enable" },
1191         { "Left ADC", NULL, "Left ADC Mixer" },
1192         { "Right ADC", NULL, "Right ADC Mixer" },
1193 };
1194
1195 static const struct snd_soc_component_driver sun6i_codec_codec = {
1196         .controls               = sun6i_codec_codec_widgets,
1197         .num_controls           = ARRAY_SIZE(sun6i_codec_codec_widgets),
1198         .dapm_widgets           = sun6i_codec_codec_dapm_widgets,
1199         .num_dapm_widgets       = ARRAY_SIZE(sun6i_codec_codec_dapm_widgets),
1200         .dapm_routes            = sun6i_codec_codec_dapm_routes,
1201         .num_dapm_routes        = ARRAY_SIZE(sun6i_codec_codec_dapm_routes),
1202         .idle_bias_on           = 1,
1203         .use_pmdown_time        = 1,
1204         .endianness             = 1,
1205         .non_legacy_dai_naming  = 1,
1206 };
1207
1208 /* sun8i A23 codec */
1209 static const struct snd_kcontrol_new sun8i_a23_codec_codec_controls[] = {
1210         SOC_SINGLE_TLV("DAC Playback Volume", SUN4I_CODEC_DAC_DPC,
1211                        SUN4I_CODEC_DAC_DPC_DVOL, 0x3f, 1,
1212                        sun6i_codec_dvol_scale),
1213 };
1214
1215 static const struct snd_soc_dapm_widget sun8i_a23_codec_codec_widgets[] = {
1216         /* Digital parts of the ADCs */
1217         SND_SOC_DAPM_SUPPLY("ADC Enable", SUN6I_CODEC_ADC_FIFOC,
1218                             SUN6I_CODEC_ADC_FIFOC_EN_AD, 0, NULL, 0),
1219         /* Digital parts of the DACs */
1220         SND_SOC_DAPM_SUPPLY("DAC Enable", SUN4I_CODEC_DAC_DPC,
1221                             SUN4I_CODEC_DAC_DPC_EN_DA, 0, NULL, 0),
1222
1223 };
1224
1225 static const struct snd_soc_component_driver sun8i_a23_codec_codec = {
1226         .controls               = sun8i_a23_codec_codec_controls,
1227         .num_controls           = ARRAY_SIZE(sun8i_a23_codec_codec_controls),
1228         .dapm_widgets           = sun8i_a23_codec_codec_widgets,
1229         .num_dapm_widgets       = ARRAY_SIZE(sun8i_a23_codec_codec_widgets),
1230         .idle_bias_on           = 1,
1231         .use_pmdown_time        = 1,
1232         .endianness             = 1,
1233         .non_legacy_dai_naming  = 1,
1234 };
1235
1236 static const struct snd_soc_component_driver sun4i_codec_component = {
1237         .name = "sun4i-codec",
1238 };
1239
1240 #define SUN4I_CODEC_RATES       SNDRV_PCM_RATE_CONTINUOUS
1241 #define SUN4I_CODEC_FORMATS     (SNDRV_PCM_FMTBIT_S16_LE | \
1242                                  SNDRV_PCM_FMTBIT_S32_LE)
1243
1244 static int sun4i_codec_dai_probe(struct snd_soc_dai *dai)
1245 {
1246         struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai);
1247         struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
1248
1249         snd_soc_dai_init_dma_data(dai, &scodec->playback_dma_data,
1250                                   &scodec->capture_dma_data);
1251
1252         return 0;
1253 }
1254
1255 static struct snd_soc_dai_driver dummy_cpu_dai = {
1256         .name   = "sun4i-codec-cpu-dai",
1257         .probe  = sun4i_codec_dai_probe,
1258         .playback = {
1259                 .stream_name    = "Playback",
1260                 .channels_min   = 1,
1261                 .channels_max   = 2,
1262                 .rates          = SUN4I_CODEC_RATES,
1263                 .formats        = SUN4I_CODEC_FORMATS,
1264                 .sig_bits       = 24,
1265         },
1266         .capture = {
1267                 .stream_name    = "Capture",
1268                 .channels_min   = 1,
1269                 .channels_max   = 2,
1270                 .rates          = SUN4I_CODEC_RATES,
1271                 .formats        = SUN4I_CODEC_FORMATS,
1272                 .sig_bits       = 24,
1273          },
1274 };
1275
1276 static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev,
1277                                                         int *num_links)
1278 {
1279         struct snd_soc_dai_link *link = devm_kzalloc(dev, sizeof(*link),
1280                                                      GFP_KERNEL);
1281         if (!link)
1282                 return NULL;
1283
1284         link->name              = "cdc";
1285         link->stream_name       = "CDC PCM";
1286         link->codec_dai_name    = "Codec";
1287         link->cpu_dai_name      = dev_name(dev);
1288         link->codec_name        = dev_name(dev);
1289         link->platform_name     = dev_name(dev);
1290         link->dai_fmt           = SND_SOC_DAIFMT_I2S;
1291
1292         *num_links = 1;
1293
1294         return link;
1295 };
1296
1297 static int sun4i_codec_spk_event(struct snd_soc_dapm_widget *w,
1298                                  struct snd_kcontrol *k, int event)
1299 {
1300         struct sun4i_codec *scodec = snd_soc_card_get_drvdata(w->dapm->card);
1301
1302         gpiod_set_value_cansleep(scodec->gpio_pa,
1303                                  !!SND_SOC_DAPM_EVENT_ON(event));
1304
1305         return 0;
1306 }
1307
1308 static const struct snd_soc_dapm_widget sun4i_codec_card_dapm_widgets[] = {
1309         SND_SOC_DAPM_SPK("Speaker", sun4i_codec_spk_event),
1310 };
1311
1312 static const struct snd_soc_dapm_route sun4i_codec_card_dapm_routes[] = {
1313         { "Speaker", NULL, "HP Right" },
1314         { "Speaker", NULL, "HP Left" },
1315 };
1316
1317 static struct snd_soc_card *sun4i_codec_create_card(struct device *dev)
1318 {
1319         struct snd_soc_card *card;
1320
1321         card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
1322         if (!card)
1323                 return ERR_PTR(-ENOMEM);
1324
1325         card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
1326         if (!card->dai_link)
1327                 return ERR_PTR(-ENOMEM);
1328
1329         card->dev               = dev;
1330         card->name              = "sun4i-codec";
1331         card->dapm_widgets      = sun4i_codec_card_dapm_widgets;
1332         card->num_dapm_widgets  = ARRAY_SIZE(sun4i_codec_card_dapm_widgets);
1333         card->dapm_routes       = sun4i_codec_card_dapm_routes;
1334         card->num_dapm_routes   = ARRAY_SIZE(sun4i_codec_card_dapm_routes);
1335
1336         return card;
1337 };
1338
1339 static const struct snd_soc_dapm_widget sun6i_codec_card_dapm_widgets[] = {
1340         SND_SOC_DAPM_HP("Headphone", NULL),
1341         SND_SOC_DAPM_LINE("Line In", NULL),
1342         SND_SOC_DAPM_LINE("Line Out", NULL),
1343         SND_SOC_DAPM_MIC("Headset Mic", NULL),
1344         SND_SOC_DAPM_MIC("Mic", NULL),
1345         SND_SOC_DAPM_SPK("Speaker", sun4i_codec_spk_event),
1346 };
1347
1348 static struct snd_soc_card *sun6i_codec_create_card(struct device *dev)
1349 {
1350         struct snd_soc_card *card;
1351         int ret;
1352
1353         card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
1354         if (!card)
1355                 return ERR_PTR(-ENOMEM);
1356
1357         card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
1358         if (!card->dai_link)
1359                 return ERR_PTR(-ENOMEM);
1360
1361         card->dev               = dev;
1362         card->name              = "A31 Audio Codec";
1363         card->dapm_widgets      = sun6i_codec_card_dapm_widgets;
1364         card->num_dapm_widgets  = ARRAY_SIZE(sun6i_codec_card_dapm_widgets);
1365         card->fully_routed      = true;
1366
1367         ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing");
1368         if (ret)
1369                 dev_warn(dev, "failed to parse audio-routing: %d\n", ret);
1370
1371         return card;
1372 };
1373
1374 /* Connect digital side enables to analog side widgets */
1375 static const struct snd_soc_dapm_route sun8i_codec_card_routes[] = {
1376         /* ADC Routes */
1377         { "Left ADC", NULL, "ADC Enable" },
1378         { "Right ADC", NULL, "ADC Enable" },
1379         { "Codec Capture", NULL, "Left ADC" },
1380         { "Codec Capture", NULL, "Right ADC" },
1381
1382         /* DAC Routes */
1383         { "Left DAC", NULL, "DAC Enable" },
1384         { "Right DAC", NULL, "DAC Enable" },
1385         { "Left DAC", NULL, "Codec Playback" },
1386         { "Right DAC", NULL, "Codec Playback" },
1387 };
1388
1389 static struct snd_soc_aux_dev aux_dev = {
1390         .name = "Codec Analog Controls",
1391 };
1392
1393 static struct snd_soc_card *sun8i_a23_codec_create_card(struct device *dev)
1394 {
1395         struct snd_soc_card *card;
1396         int ret;
1397
1398         card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
1399         if (!card)
1400                 return ERR_PTR(-ENOMEM);
1401
1402         aux_dev.codec_of_node = of_parse_phandle(dev->of_node,
1403                                                  "allwinner,codec-analog-controls",
1404                                                  0);
1405         if (!aux_dev.codec_of_node) {
1406                 dev_err(dev, "Can't find analog controls for codec.\n");
1407                 return ERR_PTR(-EINVAL);
1408         };
1409
1410         card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
1411         if (!card->dai_link)
1412                 return ERR_PTR(-ENOMEM);
1413
1414         card->dev               = dev;
1415         card->name              = "A23 Audio Codec";
1416         card->dapm_widgets      = sun6i_codec_card_dapm_widgets;
1417         card->num_dapm_widgets  = ARRAY_SIZE(sun6i_codec_card_dapm_widgets);
1418         card->dapm_routes       = sun8i_codec_card_routes;
1419         card->num_dapm_routes   = ARRAY_SIZE(sun8i_codec_card_routes);
1420         card->aux_dev           = &aux_dev;
1421         card->num_aux_devs      = 1;
1422         card->fully_routed      = true;
1423
1424         ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing");
1425         if (ret)
1426                 dev_warn(dev, "failed to parse audio-routing: %d\n", ret);
1427
1428         return card;
1429 };
1430
1431 static struct snd_soc_card *sun8i_h3_codec_create_card(struct device *dev)
1432 {
1433         struct snd_soc_card *card;
1434         int ret;
1435
1436         card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
1437         if (!card)
1438                 return ERR_PTR(-ENOMEM);
1439
1440         aux_dev.codec_of_node = of_parse_phandle(dev->of_node,
1441                                                  "allwinner,codec-analog-controls",
1442                                                  0);
1443         if (!aux_dev.codec_of_node) {
1444                 dev_err(dev, "Can't find analog controls for codec.\n");
1445                 return ERR_PTR(-EINVAL);
1446         };
1447
1448         card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
1449         if (!card->dai_link)
1450                 return ERR_PTR(-ENOMEM);
1451
1452         card->dev               = dev;
1453         card->name              = "H3 Audio Codec";
1454         card->dapm_widgets      = sun6i_codec_card_dapm_widgets;
1455         card->num_dapm_widgets  = ARRAY_SIZE(sun6i_codec_card_dapm_widgets);
1456         card->dapm_routes       = sun8i_codec_card_routes;
1457         card->num_dapm_routes   = ARRAY_SIZE(sun8i_codec_card_routes);
1458         card->aux_dev           = &aux_dev;
1459         card->num_aux_devs      = 1;
1460         card->fully_routed      = true;
1461
1462         ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing");
1463         if (ret)
1464                 dev_warn(dev, "failed to parse audio-routing: %d\n", ret);
1465
1466         return card;
1467 };
1468
1469 static struct snd_soc_card *sun8i_v3s_codec_create_card(struct device *dev)
1470 {
1471         struct snd_soc_card *card;
1472         int ret;
1473
1474         card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
1475         if (!card)
1476                 return ERR_PTR(-ENOMEM);
1477
1478         aux_dev.codec_of_node = of_parse_phandle(dev->of_node,
1479                                                  "allwinner,codec-analog-controls",
1480                                                  0);
1481         if (!aux_dev.codec_of_node) {
1482                 dev_err(dev, "Can't find analog controls for codec.\n");
1483                 return ERR_PTR(-EINVAL);
1484         };
1485
1486         card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
1487         if (!card->dai_link)
1488                 return ERR_PTR(-ENOMEM);
1489
1490         card->dev               = dev;
1491         card->name              = "V3s Audio Codec";
1492         card->dapm_widgets      = sun6i_codec_card_dapm_widgets;
1493         card->num_dapm_widgets  = ARRAY_SIZE(sun6i_codec_card_dapm_widgets);
1494         card->dapm_routes       = sun8i_codec_card_routes;
1495         card->num_dapm_routes   = ARRAY_SIZE(sun8i_codec_card_routes);
1496         card->aux_dev           = &aux_dev;
1497         card->num_aux_devs      = 1;
1498         card->fully_routed      = true;
1499
1500         ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing");
1501         if (ret)
1502                 dev_warn(dev, "failed to parse audio-routing: %d\n", ret);
1503
1504         return card;
1505 };
1506
1507 static const struct regmap_config sun4i_codec_regmap_config = {
1508         .reg_bits       = 32,
1509         .reg_stride     = 4,
1510         .val_bits       = 32,
1511         .max_register   = SUN4I_CODEC_ADC_RXCNT,
1512 };
1513
1514 static const struct regmap_config sun6i_codec_regmap_config = {
1515         .reg_bits       = 32,
1516         .reg_stride     = 4,
1517         .val_bits       = 32,
1518         .max_register   = SUN6I_CODEC_HMIC_DATA,
1519 };
1520
1521 static const struct regmap_config sun7i_codec_regmap_config = {
1522         .reg_bits       = 32,
1523         .reg_stride     = 4,
1524         .val_bits       = 32,
1525         .max_register   = SUN7I_CODEC_AC_MIC_PHONE_CAL,
1526 };
1527
1528 static const struct regmap_config sun8i_a23_codec_regmap_config = {
1529         .reg_bits       = 32,
1530         .reg_stride     = 4,
1531         .val_bits       = 32,
1532         .max_register   = SUN8I_A23_CODEC_ADC_RXCNT,
1533 };
1534
1535 static const struct regmap_config sun8i_h3_codec_regmap_config = {
1536         .reg_bits       = 32,
1537         .reg_stride     = 4,
1538         .val_bits       = 32,
1539         .max_register   = SUN8I_H3_CODEC_ADC_DBG,
1540 };
1541
1542 static const struct regmap_config sun8i_v3s_codec_regmap_config = {
1543         .reg_bits       = 32,
1544         .reg_stride     = 4,
1545         .val_bits       = 32,
1546         .max_register   = SUN8I_H3_CODEC_ADC_DBG,
1547 };
1548
1549 struct sun4i_codec_quirks {
1550         const struct regmap_config *regmap_config;
1551         const struct snd_soc_component_driver *codec;
1552         struct snd_soc_card * (*create_card)(struct device *dev);
1553         struct reg_field reg_adc_fifoc; /* used for regmap_field */
1554         unsigned int reg_dac_txdata;    /* TX FIFO offset for DMA config */
1555         unsigned int reg_adc_rxdata;    /* RX FIFO offset for DMA config */
1556         bool has_reset;
1557 };
1558
1559 static const struct sun4i_codec_quirks sun4i_codec_quirks = {
1560         .regmap_config  = &sun4i_codec_regmap_config,
1561         .codec          = &sun4i_codec_codec,
1562         .create_card    = sun4i_codec_create_card,
1563         .reg_adc_fifoc  = REG_FIELD(SUN4I_CODEC_ADC_FIFOC, 0, 31),
1564         .reg_dac_txdata = SUN4I_CODEC_DAC_TXDATA,
1565         .reg_adc_rxdata = SUN4I_CODEC_ADC_RXDATA,
1566 };
1567
1568 static const struct sun4i_codec_quirks sun6i_a31_codec_quirks = {
1569         .regmap_config  = &sun6i_codec_regmap_config,
1570         .codec          = &sun6i_codec_codec,
1571         .create_card    = sun6i_codec_create_card,
1572         .reg_adc_fifoc  = REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31),
1573         .reg_dac_txdata = SUN4I_CODEC_DAC_TXDATA,
1574         .reg_adc_rxdata = SUN6I_CODEC_ADC_RXDATA,
1575         .has_reset      = true,
1576 };
1577
1578 static const struct sun4i_codec_quirks sun7i_codec_quirks = {
1579         .regmap_config  = &sun7i_codec_regmap_config,
1580         .codec          = &sun7i_codec_codec,
1581         .create_card    = sun4i_codec_create_card,
1582         .reg_adc_fifoc  = REG_FIELD(SUN4I_CODEC_ADC_FIFOC, 0, 31),
1583         .reg_dac_txdata = SUN4I_CODEC_DAC_TXDATA,
1584         .reg_adc_rxdata = SUN4I_CODEC_ADC_RXDATA,
1585 };
1586
1587 static const struct sun4i_codec_quirks sun8i_a23_codec_quirks = {
1588         .regmap_config  = &sun8i_a23_codec_regmap_config,
1589         .codec          = &sun8i_a23_codec_codec,
1590         .create_card    = sun8i_a23_codec_create_card,
1591         .reg_adc_fifoc  = REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31),
1592         .reg_dac_txdata = SUN4I_CODEC_DAC_TXDATA,
1593         .reg_adc_rxdata = SUN6I_CODEC_ADC_RXDATA,
1594         .has_reset      = true,
1595 };
1596
1597 static const struct sun4i_codec_quirks sun8i_h3_codec_quirks = {
1598         .regmap_config  = &sun8i_h3_codec_regmap_config,
1599         /*
1600          * TODO Share the codec structure with A23 for now.
1601          * This should be split out when adding digital audio
1602          * processing support for the H3.
1603          */
1604         .codec          = &sun8i_a23_codec_codec,
1605         .create_card    = sun8i_h3_codec_create_card,
1606         .reg_adc_fifoc  = REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31),
1607         .reg_dac_txdata = SUN8I_H3_CODEC_DAC_TXDATA,
1608         .reg_adc_rxdata = SUN6I_CODEC_ADC_RXDATA,
1609         .has_reset      = true,
1610 };
1611
1612 static const struct sun4i_codec_quirks sun8i_v3s_codec_quirks = {
1613         .regmap_config  = &sun8i_v3s_codec_regmap_config,
1614         /*
1615          * TODO The codec structure should be split out, like
1616          * H3, when adding digital audio processing support.
1617          */
1618         .codec          = &sun8i_a23_codec_codec,
1619         .create_card    = sun8i_v3s_codec_create_card,
1620         .reg_adc_fifoc  = REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31),
1621         .reg_dac_txdata = SUN8I_H3_CODEC_DAC_TXDATA,
1622         .reg_adc_rxdata = SUN6I_CODEC_ADC_RXDATA,
1623         .has_reset      = true,
1624 };
1625
1626 static const struct of_device_id sun4i_codec_of_match[] = {
1627         {
1628                 .compatible = "allwinner,sun4i-a10-codec",
1629                 .data = &sun4i_codec_quirks,
1630         },
1631         {
1632                 .compatible = "allwinner,sun6i-a31-codec",
1633                 .data = &sun6i_a31_codec_quirks,
1634         },
1635         {
1636                 .compatible = "allwinner,sun7i-a20-codec",
1637                 .data = &sun7i_codec_quirks,
1638         },
1639         {
1640                 .compatible = "allwinner,sun8i-a23-codec",
1641                 .data = &sun8i_a23_codec_quirks,
1642         },
1643         {
1644                 .compatible = "allwinner,sun8i-h3-codec",
1645                 .data = &sun8i_h3_codec_quirks,
1646         },
1647         {
1648                 .compatible = "allwinner,sun8i-v3s-codec",
1649                 .data = &sun8i_v3s_codec_quirks,
1650         },
1651         {}
1652 };
1653 MODULE_DEVICE_TABLE(of, sun4i_codec_of_match);
1654
1655 static int sun4i_codec_probe(struct platform_device *pdev)
1656 {
1657         struct snd_soc_card *card;
1658         struct sun4i_codec *scodec;
1659         const struct sun4i_codec_quirks *quirks;
1660         struct resource *res;
1661         void __iomem *base;
1662         int ret;
1663
1664         scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL);
1665         if (!scodec)
1666                 return -ENOMEM;
1667
1668         scodec->dev = &pdev->dev;
1669
1670         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1671         base = devm_ioremap_resource(&pdev->dev, res);
1672         if (IS_ERR(base)) {
1673                 dev_err(&pdev->dev, "Failed to map the registers\n");
1674                 return PTR_ERR(base);
1675         }
1676
1677         quirks = of_device_get_match_data(&pdev->dev);
1678         if (quirks == NULL) {
1679                 dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
1680                 return -ENODEV;
1681         }
1682
1683         scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
1684                                                quirks->regmap_config);
1685         if (IS_ERR(scodec->regmap)) {
1686                 dev_err(&pdev->dev, "Failed to create our regmap\n");
1687                 return PTR_ERR(scodec->regmap);
1688         }
1689
1690         /* Get the clocks from the DT */
1691         scodec->clk_apb = devm_clk_get(&pdev->dev, "apb");
1692         if (IS_ERR(scodec->clk_apb)) {
1693                 dev_err(&pdev->dev, "Failed to get the APB clock\n");
1694                 return PTR_ERR(scodec->clk_apb);
1695         }
1696
1697         scodec->clk_module = devm_clk_get(&pdev->dev, "codec");
1698         if (IS_ERR(scodec->clk_module)) {
1699                 dev_err(&pdev->dev, "Failed to get the module clock\n");
1700                 return PTR_ERR(scodec->clk_module);
1701         }
1702
1703         if (quirks->has_reset) {
1704                 scodec->rst = devm_reset_control_get_exclusive(&pdev->dev,
1705                                                                NULL);
1706                 if (IS_ERR(scodec->rst)) {
1707                         dev_err(&pdev->dev, "Failed to get reset control\n");
1708                         return PTR_ERR(scodec->rst);
1709                 }
1710         }
1711
1712         scodec->gpio_pa = devm_gpiod_get_optional(&pdev->dev, "allwinner,pa",
1713                                                   GPIOD_OUT_LOW);
1714         if (IS_ERR(scodec->gpio_pa)) {
1715                 ret = PTR_ERR(scodec->gpio_pa);
1716                 if (ret != -EPROBE_DEFER)
1717                         dev_err(&pdev->dev, "Failed to get pa gpio: %d\n", ret);
1718                 return ret;
1719         }
1720
1721         /* reg_field setup */
1722         scodec->reg_adc_fifoc = devm_regmap_field_alloc(&pdev->dev,
1723                                                         scodec->regmap,
1724                                                         quirks->reg_adc_fifoc);
1725         if (IS_ERR(scodec->reg_adc_fifoc)) {
1726                 ret = PTR_ERR(scodec->reg_adc_fifoc);
1727                 dev_err(&pdev->dev, "Failed to create regmap fields: %d\n",
1728                         ret);
1729                 return ret;
1730         }
1731
1732         /* Enable the bus clock */
1733         if (clk_prepare_enable(scodec->clk_apb)) {
1734                 dev_err(&pdev->dev, "Failed to enable the APB clock\n");
1735                 return -EINVAL;
1736         }
1737
1738         /* Deassert the reset control */
1739         if (scodec->rst) {
1740                 ret = reset_control_deassert(scodec->rst);
1741                 if (ret) {
1742                         dev_err(&pdev->dev,
1743                                 "Failed to deassert the reset control\n");
1744                         goto err_clk_disable;
1745                 }
1746         }
1747
1748         /* DMA configuration for TX FIFO */
1749         scodec->playback_dma_data.addr = res->start + quirks->reg_dac_txdata;
1750         scodec->playback_dma_data.maxburst = 8;
1751         scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
1752
1753         /* DMA configuration for RX FIFO */
1754         scodec->capture_dma_data.addr = res->start + quirks->reg_adc_rxdata;
1755         scodec->capture_dma_data.maxburst = 8;
1756         scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
1757
1758         ret = devm_snd_soc_register_component(&pdev->dev, quirks->codec,
1759                                      &sun4i_codec_dai, 1);
1760         if (ret) {
1761                 dev_err(&pdev->dev, "Failed to register our codec\n");
1762                 goto err_assert_reset;
1763         }
1764
1765         ret = devm_snd_soc_register_component(&pdev->dev,
1766                                               &sun4i_codec_component,
1767                                               &dummy_cpu_dai, 1);
1768         if (ret) {
1769                 dev_err(&pdev->dev, "Failed to register our DAI\n");
1770                 goto err_assert_reset;
1771         }
1772
1773         ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
1774         if (ret) {
1775                 dev_err(&pdev->dev, "Failed to register against DMAEngine\n");
1776                 goto err_assert_reset;
1777         }
1778
1779         card = quirks->create_card(&pdev->dev);
1780         if (IS_ERR(card)) {
1781                 ret = PTR_ERR(card);
1782                 dev_err(&pdev->dev, "Failed to create our card\n");
1783                 goto err_assert_reset;
1784         }
1785
1786         snd_soc_card_set_drvdata(card, scodec);
1787
1788         ret = snd_soc_register_card(card);
1789         if (ret) {
1790                 dev_err(&pdev->dev, "Failed to register our card\n");
1791                 goto err_assert_reset;
1792         }
1793
1794         return 0;
1795
1796 err_assert_reset:
1797         if (scodec->rst)
1798                 reset_control_assert(scodec->rst);
1799 err_clk_disable:
1800         clk_disable_unprepare(scodec->clk_apb);
1801         return ret;
1802 }
1803
1804 static int sun4i_codec_remove(struct platform_device *pdev)
1805 {
1806         struct snd_soc_card *card = platform_get_drvdata(pdev);
1807         struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
1808
1809         snd_soc_unregister_card(card);
1810         if (scodec->rst)
1811                 reset_control_assert(scodec->rst);
1812         clk_disable_unprepare(scodec->clk_apb);
1813
1814         return 0;
1815 }
1816
1817 static struct platform_driver sun4i_codec_driver = {
1818         .driver = {
1819                 .name = "sun4i-codec",
1820                 .of_match_table = sun4i_codec_of_match,
1821         },
1822         .probe = sun4i_codec_probe,
1823         .remove = sun4i_codec_remove,
1824 };
1825 module_platform_driver(sun4i_codec_driver);
1826
1827 MODULE_DESCRIPTION("Allwinner A10 codec driver");
1828 MODULE_AUTHOR("Emilio López <emilio@elopez.com.ar>");
1829 MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
1830 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
1831 MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
1832 MODULE_LICENSE("GPL");