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