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