1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright 2014 Emilio López <emilio@elopez.com.ar>
4  * Copyright 2014 Jon Smirl <jonsmirl@gmail.com>
5  * Copyright 2015 Maxime Ripard <maxime.ripard@free-electrons.com>
6  * Copyright 2015 Adam Sampson <ats@offog.org>
7  * Copyright 2016 Chen-Yu Tsai <wens@csie.org>
8  * Copyright 2018 Mesih Kilinc <mesihkilinc@gmail.com>
9  *
10  * Based on the Allwinner SDK driver, released under the GPL.
11  */
12 
13 #include <linux/init.h>
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/platform_device.h>
17 #include <linux/delay.h>
18 #include <linux/slab.h>
19 #include <linux/clk.h>
20 #include <linux/regmap.h>
21 #include <linux/reset.h>
22 #include <linux/gpio/consumer.h>
23 
24 #include <sound/core.h>
25 #include <sound/jack.h>
26 #include <sound/pcm.h>
27 #include <sound/pcm_params.h>
28 #include <sound/soc.h>
29 #include <sound/tlv.h>
30 #include <sound/initval.h>
31 #include <sound/dmaengine_pcm.h>
32 
33 /* Codec DAC digital controls and FIFO registers */
34 #define SUN4I_CODEC_DAC_DPC			(0x00)
35 #define SUN4I_CODEC_DAC_DPC_EN_DA			(31)
36 #define SUN4I_CODEC_DAC_DPC_DVOL			(12)
37 #define SUN4I_CODEC_DAC_FIFOC			(0x04)
38 #define SUN4I_CODEC_DAC_FIFOC_DAC_FS			(29)
39 #define SUN4I_CODEC_DAC_FIFOC_FIR_VERSION		(28)
40 #define SUN4I_CODEC_DAC_FIFOC_SEND_LASAT		(26)
41 #define SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE		(24)
42 #define SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT		(21)
43 #define SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL		(8)
44 #define SUN4I_CODEC_DAC_FIFOC_MONO_EN			(6)
45 #define SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS		(5)
46 #define SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN		(4)
47 #define SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH		(0)
48 #define SUN4I_CODEC_DAC_FIFOS			(0x08)
49 #define SUN4I_CODEC_DAC_TXDATA			(0x0c)
50 
51 /* Codec DAC side analog signal controls */
52 #define SUN4I_CODEC_DAC_ACTL			(0x10)
53 #define SUN4I_CODEC_DAC_ACTL_DACAENR			(31)
54 #define SUN4I_CODEC_DAC_ACTL_DACAENL			(30)
55 #define SUN4I_CODEC_DAC_ACTL_MIXEN			(29)
56 #define SUN4I_CODEC_DAC_ACTL_LNG			(26)
57 #define SUN4I_CODEC_DAC_ACTL_FMG			(23)
58 #define SUN4I_CODEC_DAC_ACTL_MICG			(20)
59 #define SUN4I_CODEC_DAC_ACTL_LLNS			(19)
60 #define SUN4I_CODEC_DAC_ACTL_RLNS			(18)
61 #define SUN4I_CODEC_DAC_ACTL_LFMS			(17)
62 #define SUN4I_CODEC_DAC_ACTL_RFMS			(16)
63 #define SUN4I_CODEC_DAC_ACTL_LDACLMIXS			(15)
64 #define SUN4I_CODEC_DAC_ACTL_RDACRMIXS			(14)
65 #define SUN4I_CODEC_DAC_ACTL_LDACRMIXS			(13)
66 #define SUN4I_CODEC_DAC_ACTL_MIC1LS			(12)
67 #define SUN4I_CODEC_DAC_ACTL_MIC1RS			(11)
68 #define SUN4I_CODEC_DAC_ACTL_MIC2LS			(10)
69 #define SUN4I_CODEC_DAC_ACTL_MIC2RS			(9)
70 #define SUN4I_CODEC_DAC_ACTL_DACPAS			(8)
71 #define SUN4I_CODEC_DAC_ACTL_MIXPAS			(7)
72 #define SUN4I_CODEC_DAC_ACTL_PA_MUTE			(6)
73 #define SUN4I_CODEC_DAC_ACTL_PA_VOL			(0)
74 #define SUN4I_CODEC_DAC_TUNE			(0x14)
75 #define SUN4I_CODEC_DAC_DEBUG			(0x18)
76 
77 /* Codec ADC digital controls and FIFO registers */
78 #define SUN4I_CODEC_ADC_FIFOC			(0x1c)
79 #define SUN4I_CODEC_ADC_FIFOC_ADC_FS			(29)
80 #define SUN4I_CODEC_ADC_FIFOC_EN_AD			(28)
81 #define SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE		(24)
82 #define SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL		(8)
83 #define SUN4I_CODEC_ADC_FIFOC_MONO_EN			(7)
84 #define SUN4I_CODEC_ADC_FIFOC_RX_SAMPLE_BITS		(6)
85 #define SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN		(4)
86 #define SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH		(0)
87 #define SUN4I_CODEC_ADC_FIFOS			(0x20)
88 #define SUN4I_CODEC_ADC_RXDATA			(0x24)
89 
90 /* Codec ADC side analog signal controls */
91 #define SUN4I_CODEC_ADC_ACTL			(0x28)
92 #define SUN4I_CODEC_ADC_ACTL_ADC_R_EN			(31)
93 #define SUN4I_CODEC_ADC_ACTL_ADC_L_EN			(30)
94 #define SUN4I_CODEC_ADC_ACTL_PREG1EN			(29)
95 #define SUN4I_CODEC_ADC_ACTL_PREG2EN			(28)
96 #define SUN4I_CODEC_ADC_ACTL_VMICEN			(27)
97 #define SUN4I_CODEC_ADC_ACTL_PREG1			(25)
98 #define SUN4I_CODEC_ADC_ACTL_PREG2			(23)
99 #define SUN4I_CODEC_ADC_ACTL_VADCG			(20)
100 #define SUN4I_CODEC_ADC_ACTL_ADCIS			(17)
101 #define SUN4I_CODEC_ADC_ACTL_LNPREG			(13)
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 /* H616 specific registers */
232 #define SUN50I_H616_CODEC_DAC_FIFOC		(0x10)
233 
234 #define SUN50I_DAC_FIFO_STA			(0x14)
235 #define SUN50I_DAC_TXE_INT			(3)
236 #define SUN50I_DAC_TXU_INT			(2)
237 #define SUN50I_DAC_TXO_INT			(1)
238 
239 #define SUN50I_DAC_CNT				(0x24)
240 #define SUN50I_DAC_DG_REG			(0x28)
241 #define SUN50I_DAC_DAP_CTL			(0xf0)
242 
243 #define SUN50I_H616_DAC_AC_DAC_REG		(0x310)
244 #define SUN50I_H616_DAC_LEN			(15)
245 #define SUN50I_H616_DAC_REN			(14)
246 #define SUN50I_H616_LINEOUTL_EN			(13)
247 #define SUN50I_H616_LMUTE			(12)
248 #define SUN50I_H616_LINEOUTR_EN			(11)
249 #define SUN50I_H616_RMUTE			(10)
250 #define SUN50I_H616_RSWITCH			(9)
251 #define SUN50I_H616_RAMPEN			(8)
252 #define SUN50I_H616_LINEOUTL_SEL		(6)
253 #define SUN50I_H616_LINEOUTR_SEL		(5)
254 #define SUN50I_H616_LINEOUT_VOL			(0)
255 
256 #define SUN50I_H616_DAC_AC_MIXER_REG		(0x314)
257 #define SUN50I_H616_LMIX_LDAC			(21)
258 #define SUN50I_H616_LMIX_RDAC			(20)
259 #define SUN50I_H616_RMIX_RDAC			(17)
260 #define SUN50I_H616_RMIX_LDAC			(16)
261 #define SUN50I_H616_LMIXEN			(11)
262 #define SUN50I_H616_RMIXEN			(10)
263 
264 #define SUN50I_H616_DAC_AC_RAMP_REG		(0x31c)
265 #define SUN50I_H616_RAMP_STEP			(4)
266 #define SUN50I_H616_RDEN			(0)
267 
268 /* TODO H3 DAP (Digital Audio Processing) bits */
269 
270 #define SUN4I_DMA_MAX_BURST			(8)
271 
272 /* suniv specific registers */
273 
274 #define SUNIV_DMA_MAX_BURST			(4)
275 
276 /* Codec DAC digital controls and FIFO registers */
277 #define SUNIV_CODEC_ADC_FIFOC			(0x10)
278 #define SUNIV_CODEC_ADC_FIFOC_EN_AD		(28)
279 #define SUNIV_CODEC_ADC_FIFOS			(0x14)
280 #define SUNIV_CODEC_ADC_RXDATA			(0x18)
281 
282 /* Output mixer and gain controls */
283 #define SUNIV_CODEC_OM_DACA_CTRL			(0x20)
284 #define SUNIV_CODEC_OM_DACA_CTRL_DACAREN		(31)
285 #define SUNIV_CODEC_OM_DACA_CTRL_DACALEN		(30)
286 #define SUNIV_CODEC_OM_DACA_CTRL_RMIXEN			(29)
287 #define SUNIV_CODEC_OM_DACA_CTRL_LMIXEN			(28)
288 #define SUNIV_CODEC_OM_DACA_CTRL_RHPPAMUTE		(27)
289 #define SUNIV_CODEC_OM_DACA_CTRL_LHPPAMUTE		(26)
290 #define SUNIV_CODEC_OM_DACA_CTRL_RHPIS			(25)
291 #define SUNIV_CODEC_OM_DACA_CTRL_LHPIS			(24)
292 #define SUNIV_CODEC_OM_DACA_CTRL_HPCOM_CTL		(22)
293 #define SUNIV_CODEC_OM_DACA_CTRL_COMPTEN		(21)
294 #define SUNIV_CODEC_OM_DACA_CTRL_RMIXMUTE_MICIN		(20)
295 #define SUNIV_CODEC_OM_DACA_CTRL_RMIXMUTE_LINEIN	(19)
296 #define SUNIV_CODEC_OM_DACA_CTRL_RMIXMUTE_FMIN		(18)
297 #define SUNIV_CODEC_OM_DACA_CTRL_RMIXMUTE_RDAC		(17)
298 #define SUNIV_CODEC_OM_DACA_CTRL_RMIXMUTE_LDAC		(16)
299 #define SUNIV_CODEC_OM_DACA_CTRL_HPPAEN			(15)
300 #define SUNIV_CODEC_OM_DACA_CTRL_LMIXMUTE_MICIN		(12)
301 #define SUNIV_CODEC_OM_DACA_CTRL_LMIXMUTE_LINEIN	(11)
302 #define SUNIV_CODEC_OM_DACA_CTRL_LMIXMUTE_FMIN		(10)
303 #define SUNIV_CODEC_OM_DACA_CTRL_LMIXMUTE_LDAC		(9)
304 #define SUNIV_CODEC_OM_DACA_CTRL_LMIXMUTE_RDAC		(8)
305 #define SUNIV_CODEC_OM_DACA_CTRL_LTLNMUTE		(7)
306 #define SUNIV_CODEC_OM_DACA_CTRL_RTLNMUTE		(6)
307 #define SUNIV_CODEC_OM_DACA_CTRL_HPVOL			(0)
308 
309 /* Analog Input Mixer controls */
310 #define SUNIV_CODEC_ADC_ACTL		(0x24)
311 #define SUNIV_CODEC_ADC_ADCEN		(31)
312 #define SUNIV_CODEC_ADC_MICG		(24)
313 #define SUNIV_CODEC_ADC_LINEINVOL	(21)
314 #define SUNIV_CODEC_ADC_ADCG		(16)
315 #define SUNIV_CODEC_ADC_ADCMIX_MIC	(13)
316 #define SUNIV_CODEC_ADC_ADCMIX_FMINL	(12)
317 #define SUNIV_CODEC_ADC_ADCMIX_FMINR	(11)
318 #define SUNIV_CODEC_ADC_ADCMIX_LINEIN	(10)
319 #define SUNIV_CODEC_ADC_ADCMIX_LOUT	(9)
320 #define SUNIV_CODEC_ADC_ADCMIX_ROUT	(8)
321 #define SUNIV_CODEC_ADC_PASPEEDSELECT	(7)
322 #define SUNIV_CODEC_ADC_FMINVOL		(4)
323 #define SUNIV_CODEC_ADC_MICAMPEN	(3)
324 #define SUNIV_CODEC_ADC_MICBOOST	(0)
325 
326 #define SUNIV_CODEC_ADC_DBG		(0x4c)
327 
328 struct sun4i_codec {
329 	struct device	*dev;
330 	struct regmap	*regmap;
331 	struct clk	*clk_apb;
332 	struct clk	*clk_module;
333 	struct reset_control *rst;
334 	struct gpio_desc *gpio_pa;
335 	struct gpio_desc *gpio_hp;
336 
337 	/* ADC_FIFOC register is at different offset on different SoCs */
338 	struct regmap_field *reg_adc_fifoc;
339 	/* DAC_FIFOC register is at different offset on different SoCs */
340 	struct regmap_field *reg_dac_fifoc;
341 
342 	struct snd_dmaengine_dai_dma_data	capture_dma_data;
343 	struct snd_dmaengine_dai_dma_data	playback_dma_data;
344 };
345 
sun4i_codec_start_playback(struct sun4i_codec * scodec)346 static void sun4i_codec_start_playback(struct sun4i_codec *scodec)
347 {
348 	/* Flush TX FIFO */
349 	regmap_field_set_bits(scodec->reg_dac_fifoc,
350 			      BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH));
351 
352 	/* Enable DAC DRQ */
353 	regmap_field_set_bits(scodec->reg_dac_fifoc,
354 			      BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN));
355 }
356 
sun4i_codec_stop_playback(struct sun4i_codec * scodec)357 static void sun4i_codec_stop_playback(struct sun4i_codec *scodec)
358 {
359 	/* Disable DAC DRQ */
360 	regmap_field_clear_bits(scodec->reg_dac_fifoc,
361 				BIT(SUN4I_CODEC_DAC_FIFOC_DAC_DRQ_EN));
362 }
363 
sun4i_codec_start_capture(struct sun4i_codec * scodec)364 static void sun4i_codec_start_capture(struct sun4i_codec *scodec)
365 {
366 	/* Enable ADC DRQ */
367 	regmap_field_set_bits(scodec->reg_adc_fifoc,
368 			      BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN));
369 }
370 
sun4i_codec_stop_capture(struct sun4i_codec * scodec)371 static void sun4i_codec_stop_capture(struct sun4i_codec *scodec)
372 {
373 	/* Disable ADC DRQ */
374 	regmap_field_clear_bits(scodec->reg_adc_fifoc,
375 				 BIT(SUN4I_CODEC_ADC_FIFOC_ADC_DRQ_EN));
376 }
377 
sun4i_codec_trigger(struct snd_pcm_substream * substream,int cmd,struct snd_soc_dai * dai)378 static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd,
379 			       struct snd_soc_dai *dai)
380 {
381 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
382 	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
383 
384 	switch (cmd) {
385 	case SNDRV_PCM_TRIGGER_START:
386 	case SNDRV_PCM_TRIGGER_RESUME:
387 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
388 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
389 			sun4i_codec_start_playback(scodec);
390 		else
391 			sun4i_codec_start_capture(scodec);
392 		break;
393 
394 	case SNDRV_PCM_TRIGGER_STOP:
395 	case SNDRV_PCM_TRIGGER_SUSPEND:
396 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
397 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
398 			sun4i_codec_stop_playback(scodec);
399 		else
400 			sun4i_codec_stop_capture(scodec);
401 		break;
402 
403 	default:
404 		return -EINVAL;
405 	}
406 
407 	return 0;
408 }
409 
sun4i_codec_prepare_capture(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)410 static int sun4i_codec_prepare_capture(struct snd_pcm_substream *substream,
411 				       struct snd_soc_dai *dai)
412 {
413 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
414 	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
415 
416 
417 	/* Flush RX FIFO */
418 	regmap_field_set_bits(scodec->reg_adc_fifoc,
419 				 BIT(SUN4I_CODEC_ADC_FIFOC_FIFO_FLUSH));
420 
421 
422 	/* Set RX FIFO trigger level */
423 	regmap_field_update_bits(scodec->reg_adc_fifoc,
424 				 0xf << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL,
425 				 0x7 << SUN4I_CODEC_ADC_FIFOC_RX_TRIG_LEVEL);
426 
427 	/*
428 	 * FIXME: Undocumented in the datasheet, but
429 	 *        Allwinner's code mentions that it is
430 	 *        related to microphone gain
431 	 */
432 	if (of_device_is_compatible(scodec->dev->of_node,
433 				    "allwinner,sun4i-a10-codec") ||
434 	    of_device_is_compatible(scodec->dev->of_node,
435 				    "allwinner,sun7i-a20-codec")) {
436 		regmap_update_bits(scodec->regmap, SUN4I_CODEC_ADC_ACTL,
437 				   0x3 << 25,
438 				   0x1 << 25);
439 	}
440 
441 	if (of_device_is_compatible(scodec->dev->of_node,
442 				    "allwinner,sun7i-a20-codec"))
443 		/* FIXME: Undocumented bits */
444 		regmap_update_bits(scodec->regmap, SUN4I_CODEC_DAC_TUNE,
445 				   0x3 << 8,
446 				   0x1 << 8);
447 
448 	return 0;
449 }
450 
sun4i_codec_prepare_playback(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)451 static int sun4i_codec_prepare_playback(struct snd_pcm_substream *substream,
452 					struct snd_soc_dai *dai)
453 {
454 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
455 	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
456 	u32 val;
457 
458 	/* Flush the TX FIFO */
459 	regmap_field_set_bits(scodec->reg_dac_fifoc,
460 			      BIT(SUN4I_CODEC_DAC_FIFOC_FIFO_FLUSH));
461 
462 	/* Set TX FIFO Empty Trigger Level */
463 	regmap_field_update_bits(scodec->reg_dac_fifoc,
464 				 0x3f << SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL,
465 				 0xf << SUN4I_CODEC_DAC_FIFOC_TX_TRIG_LEVEL);
466 
467 	if (substream->runtime->rate > 32000)
468 		/* Use 64 bits FIR filter */
469 		val = 0;
470 	else
471 		/* Use 32 bits FIR filter */
472 		val = BIT(SUN4I_CODEC_DAC_FIFOC_FIR_VERSION);
473 
474 	regmap_field_update_bits(scodec->reg_dac_fifoc,
475 				 BIT(SUN4I_CODEC_DAC_FIFOC_FIR_VERSION),
476 				 val);
477 
478 	/* Send zeros when we have an underrun */
479 	regmap_field_clear_bits(scodec->reg_dac_fifoc,
480 				BIT(SUN4I_CODEC_DAC_FIFOC_SEND_LASAT));
481 
482 	return 0;
483 };
484 
sun4i_codec_prepare(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)485 static int sun4i_codec_prepare(struct snd_pcm_substream *substream,
486 			       struct snd_soc_dai *dai)
487 {
488 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
489 		return sun4i_codec_prepare_playback(substream, dai);
490 
491 	return sun4i_codec_prepare_capture(substream, dai);
492 }
493 
sun4i_codec_get_mod_freq(struct snd_pcm_hw_params * params)494 static unsigned long sun4i_codec_get_mod_freq(struct snd_pcm_hw_params *params)
495 {
496 	unsigned int rate = params_rate(params);
497 
498 	switch (rate) {
499 	case 176400:
500 	case 88200:
501 	case 44100:
502 	case 33075:
503 	case 22050:
504 	case 14700:
505 	case 11025:
506 	case 7350:
507 		return 22579200;
508 
509 	case 192000:
510 	case 96000:
511 	case 48000:
512 	case 32000:
513 	case 24000:
514 	case 16000:
515 	case 12000:
516 	case 8000:
517 		return 24576000;
518 
519 	default:
520 		return 0;
521 	}
522 }
523 
sun4i_codec_get_hw_rate(struct snd_pcm_hw_params * params)524 static int sun4i_codec_get_hw_rate(struct snd_pcm_hw_params *params)
525 {
526 	unsigned int rate = params_rate(params);
527 
528 	switch (rate) {
529 	case 192000:
530 	case 176400:
531 		return 6;
532 
533 	case 96000:
534 	case 88200:
535 		return 7;
536 
537 	case 48000:
538 	case 44100:
539 		return 0;
540 
541 	case 32000:
542 	case 33075:
543 		return 1;
544 
545 	case 24000:
546 	case 22050:
547 		return 2;
548 
549 	case 16000:
550 	case 14700:
551 		return 3;
552 
553 	case 12000:
554 	case 11025:
555 		return 4;
556 
557 	case 8000:
558 	case 7350:
559 		return 5;
560 
561 	default:
562 		return -EINVAL;
563 	}
564 }
565 
sun4i_codec_hw_params_capture(struct sun4i_codec * scodec,struct snd_pcm_hw_params * params,unsigned int hwrate)566 static int sun4i_codec_hw_params_capture(struct sun4i_codec *scodec,
567 					 struct snd_pcm_hw_params *params,
568 					 unsigned int hwrate)
569 {
570 	/* Set ADC sample rate */
571 	regmap_field_update_bits(scodec->reg_adc_fifoc,
572 				 7 << SUN4I_CODEC_ADC_FIFOC_ADC_FS,
573 				 hwrate << SUN4I_CODEC_ADC_FIFOC_ADC_FS);
574 
575 	/* Set the number of channels we want to use */
576 	if (params_channels(params) == 1)
577 		regmap_field_set_bits(scodec->reg_adc_fifoc,
578 					 BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN));
579 	else
580 		regmap_field_clear_bits(scodec->reg_adc_fifoc,
581 					 BIT(SUN4I_CODEC_ADC_FIFOC_MONO_EN));
582 
583 	/* Set the number of sample bits to either 16 or 24 bits */
584 	if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min == 32) {
585 		regmap_field_set_bits(scodec->reg_adc_fifoc,
586 				   BIT(SUN4I_CODEC_ADC_FIFOC_RX_SAMPLE_BITS));
587 
588 		regmap_field_clear_bits(scodec->reg_adc_fifoc,
589 				   BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE));
590 
591 		scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
592 	} else {
593 		regmap_field_clear_bits(scodec->reg_adc_fifoc,
594 				   BIT(SUN4I_CODEC_ADC_FIFOC_RX_SAMPLE_BITS));
595 
596 		/* Fill most significant bits with valid data MSB */
597 		regmap_field_set_bits(scodec->reg_adc_fifoc,
598 				   BIT(SUN4I_CODEC_ADC_FIFOC_RX_FIFO_MODE));
599 
600 		scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
601 	}
602 
603 	return 0;
604 }
605 
sun4i_codec_hw_params_playback(struct sun4i_codec * scodec,struct snd_pcm_hw_params * params,unsigned int hwrate)606 static int sun4i_codec_hw_params_playback(struct sun4i_codec *scodec,
607 					  struct snd_pcm_hw_params *params,
608 					  unsigned int hwrate)
609 {
610 	u32 val;
611 
612 	/* Set DAC sample rate */
613 	regmap_field_update_bits(scodec->reg_dac_fifoc,
614 				 7 << SUN4I_CODEC_DAC_FIFOC_DAC_FS,
615 				 hwrate << SUN4I_CODEC_DAC_FIFOC_DAC_FS);
616 
617 	/* Set the number of channels we want to use */
618 	if (params_channels(params) == 1)
619 		val = BIT(SUN4I_CODEC_DAC_FIFOC_MONO_EN);
620 	else
621 		val = 0;
622 
623 	regmap_field_update_bits(scodec->reg_dac_fifoc,
624 				 BIT(SUN4I_CODEC_DAC_FIFOC_MONO_EN),
625 				 val);
626 
627 	/* Set the number of sample bits to either 16 or 24 bits */
628 	if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min == 32) {
629 		regmap_field_set_bits(scodec->reg_dac_fifoc,
630 				      BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS));
631 
632 		/* Set TX FIFO mode to padding the LSBs with 0 */
633 		regmap_field_clear_bits(scodec->reg_dac_fifoc,
634 					BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE));
635 
636 		scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
637 	} else {
638 		regmap_field_clear_bits(scodec->reg_dac_fifoc,
639 					BIT(SUN4I_CODEC_DAC_FIFOC_TX_SAMPLE_BITS));
640 
641 		/* Set TX FIFO mode to repeat the MSB */
642 		regmap_field_set_bits(scodec->reg_dac_fifoc,
643 				      BIT(SUN4I_CODEC_DAC_FIFOC_TX_FIFO_MODE));
644 
645 		scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
646 	}
647 
648 	return 0;
649 }
650 
sun4i_codec_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)651 static int sun4i_codec_hw_params(struct snd_pcm_substream *substream,
652 				 struct snd_pcm_hw_params *params,
653 				 struct snd_soc_dai *dai)
654 {
655 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
656 	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
657 	unsigned long clk_freq;
658 	int ret, hwrate;
659 
660 	clk_freq = sun4i_codec_get_mod_freq(params);
661 	if (!clk_freq)
662 		return -EINVAL;
663 
664 	ret = clk_set_rate(scodec->clk_module, clk_freq);
665 	if (ret)
666 		return ret;
667 
668 	hwrate = sun4i_codec_get_hw_rate(params);
669 	if (hwrate < 0)
670 		return hwrate;
671 
672 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
673 		return sun4i_codec_hw_params_playback(scodec, params,
674 						      hwrate);
675 
676 	return sun4i_codec_hw_params_capture(scodec, params,
677 					     hwrate);
678 }
679 
sun4i_codec_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)680 static int sun4i_codec_startup(struct snd_pcm_substream *substream,
681 			       struct snd_soc_dai *dai)
682 {
683 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
684 	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
685 
686 	/*
687 	 * Stop issuing DRQ when we have room for less than 16 samples
688 	 * in our TX FIFO
689 	 */
690 	regmap_field_set_bits(scodec->reg_dac_fifoc,
691 			      3 << SUN4I_CODEC_DAC_FIFOC_DRQ_CLR_CNT);
692 
693 	return clk_prepare_enable(scodec->clk_module);
694 }
695 
sun4i_codec_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)696 static void sun4i_codec_shutdown(struct snd_pcm_substream *substream,
697 				 struct snd_soc_dai *dai)
698 {
699 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
700 	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card);
701 
702 	clk_disable_unprepare(scodec->clk_module);
703 }
704 
705 static const struct snd_soc_dai_ops sun4i_codec_dai_ops = {
706 	.startup	= sun4i_codec_startup,
707 	.shutdown	= sun4i_codec_shutdown,
708 	.trigger	= sun4i_codec_trigger,
709 	.hw_params	= sun4i_codec_hw_params,
710 	.prepare	= sun4i_codec_prepare,
711 };
712 
713 #define SUN4I_CODEC_RATES (			\
714 		SNDRV_PCM_RATE_8000_48000 |	\
715 		SNDRV_PCM_RATE_12000 |		\
716 		SNDRV_PCM_RATE_24000 |		\
717 		SNDRV_PCM_RATE_96000 |		\
718 		SNDRV_PCM_RATE_192000)
719 
720 static struct snd_soc_dai_driver sun4i_codec_dai = {
721 	.name	= "Codec",
722 	.ops	= &sun4i_codec_dai_ops,
723 	.playback = {
724 		.stream_name	= "Codec Playback",
725 		.channels_min	= 1,
726 		.channels_max	= 2,
727 		.rate_min	= 8000,
728 		.rate_max	= 192000,
729 		.rates		= SUN4I_CODEC_RATES,
730 		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
731 				  SNDRV_PCM_FMTBIT_S32_LE,
732 		.sig_bits	= 24,
733 	},
734 	.capture = {
735 		.stream_name	= "Codec Capture",
736 		.channels_min	= 1,
737 		.channels_max	= 2,
738 		.rate_min	= 8000,
739 		.rate_max	= 48000,
740 		.rates		= SUN4I_CODEC_RATES,
741 		.formats	= SNDRV_PCM_FMTBIT_S16_LE |
742 				  SNDRV_PCM_FMTBIT_S32_LE,
743 		.sig_bits	= 24,
744 	},
745 };
746 
747 /*** sun4i Codec ***/
748 static const struct snd_kcontrol_new sun4i_codec_pa_mute =
749 	SOC_DAPM_SINGLE("Switch", SUN4I_CODEC_DAC_ACTL,
750 			SUN4I_CODEC_DAC_ACTL_PA_MUTE, 1, 0);
751 
752 static DECLARE_TLV_DB_SCALE(sun4i_codec_pa_volume_scale, -6300, 100, 1);
753 static DECLARE_TLV_DB_SCALE(sun4i_codec_linein_loopback_gain_scale, -150, 150,
754 			    0);
755 static DECLARE_TLV_DB_SCALE(sun4i_codec_linein_preamp_gain_scale, -1200, 300,
756 			    0);
757 static DECLARE_TLV_DB_SCALE(sun4i_codec_fmin_loopback_gain_scale, -450, 150,
758 			    0);
759 static DECLARE_TLV_DB_SCALE(sun4i_codec_micin_loopback_gain_scale, -450, 150,
760 			    0);
761 static DECLARE_TLV_DB_RANGE(sun4i_codec_micin_preamp_gain_scale,
762 			    0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
763 			    1, 7, TLV_DB_SCALE_ITEM(3500, 300, 0));
764 static DECLARE_TLV_DB_RANGE(sun7i_codec_micin_preamp_gain_scale,
765 			    0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
766 			    1, 7, TLV_DB_SCALE_ITEM(2400, 300, 0));
767 
768 static const struct snd_kcontrol_new sun4i_codec_controls[] = {
769 	SOC_SINGLE_TLV("Power Amplifier Volume", SUN4I_CODEC_DAC_ACTL,
770 		       SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0,
771 		       sun4i_codec_pa_volume_scale),
772 	SOC_SINGLE_TLV("Line Playback Volume", SUN4I_CODEC_DAC_ACTL,
773 		       SUN4I_CODEC_DAC_ACTL_LNG, 1, 0,
774 		       sun4i_codec_linein_loopback_gain_scale),
775 	SOC_SINGLE_TLV("Line Boost Volume", SUN4I_CODEC_ADC_ACTL,
776 		       SUN4I_CODEC_ADC_ACTL_LNPREG, 7, 0,
777 		       sun4i_codec_linein_preamp_gain_scale),
778 	SOC_SINGLE_TLV("FM Playback Volume", SUN4I_CODEC_DAC_ACTL,
779 		       SUN4I_CODEC_DAC_ACTL_FMG, 3, 0,
780 		       sun4i_codec_fmin_loopback_gain_scale),
781 	SOC_SINGLE_TLV("Mic Playback Volume", SUN4I_CODEC_DAC_ACTL,
782 		       SUN4I_CODEC_DAC_ACTL_MICG, 7, 0,
783 		       sun4i_codec_micin_loopback_gain_scale),
784 	SOC_SINGLE_TLV("Mic1 Boost Volume", SUN4I_CODEC_ADC_ACTL,
785 		       SUN4I_CODEC_ADC_ACTL_PREG1, 3, 0,
786 		       sun4i_codec_micin_preamp_gain_scale),
787 	SOC_SINGLE_TLV("Mic2 Boost Volume", SUN4I_CODEC_ADC_ACTL,
788 		       SUN4I_CODEC_ADC_ACTL_PREG2, 3, 0,
789 		       sun4i_codec_micin_preamp_gain_scale),
790 };
791 
792 static const struct snd_kcontrol_new sun7i_codec_controls[] = {
793 	SOC_SINGLE_TLV("Power Amplifier Volume", SUN4I_CODEC_DAC_ACTL,
794 		       SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0,
795 		       sun4i_codec_pa_volume_scale),
796 	SOC_SINGLE_TLV("Line Playback Volume", SUN4I_CODEC_DAC_ACTL,
797 		       SUN4I_CODEC_DAC_ACTL_LNG, 1, 0,
798 		       sun4i_codec_linein_loopback_gain_scale),
799 	SOC_SINGLE_TLV("Line Boost Volume", SUN4I_CODEC_ADC_ACTL,
800 		       SUN4I_CODEC_ADC_ACTL_LNPREG, 7, 0,
801 		       sun4i_codec_linein_preamp_gain_scale),
802 	SOC_SINGLE_TLV("FM Playback Volume", SUN4I_CODEC_DAC_ACTL,
803 		       SUN4I_CODEC_DAC_ACTL_FMG, 3, 0,
804 		       sun4i_codec_fmin_loopback_gain_scale),
805 	SOC_SINGLE_TLV("Mic Playback Volume", SUN4I_CODEC_DAC_ACTL,
806 		       SUN4I_CODEC_DAC_ACTL_MICG, 7, 0,
807 		       sun4i_codec_micin_loopback_gain_scale),
808 	SOC_SINGLE_TLV("Mic1 Boost Volume", SUN7I_CODEC_AC_MIC_PHONE_CAL,
809 		       SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG1, 7, 0,
810 		       sun7i_codec_micin_preamp_gain_scale),
811 	SOC_SINGLE_TLV("Mic2 Boost Volume", SUN7I_CODEC_AC_MIC_PHONE_CAL,
812 		       SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG2, 7, 0,
813 		       sun7i_codec_micin_preamp_gain_scale),
814 };
815 
816 static const struct snd_kcontrol_new sun4i_codec_mixer_controls[] = {
817 	SOC_DAPM_SINGLE("Left Mixer Left DAC Playback Switch",
818 			SUN4I_CODEC_DAC_ACTL, SUN4I_CODEC_DAC_ACTL_LDACLMIXS,
819 			1, 0),
820 	SOC_DAPM_SINGLE("Right Mixer Right DAC Playback Switch",
821 			SUN4I_CODEC_DAC_ACTL, SUN4I_CODEC_DAC_ACTL_RDACRMIXS,
822 			1, 0),
823 	SOC_DAPM_SINGLE("Right Mixer Left DAC Playback Switch",
824 			SUN4I_CODEC_DAC_ACTL,
825 			SUN4I_CODEC_DAC_ACTL_LDACRMIXS, 1, 0),
826 	SOC_DAPM_DOUBLE("Line Playback Switch", SUN4I_CODEC_DAC_ACTL,
827 			SUN4I_CODEC_DAC_ACTL_LLNS,
828 			SUN4I_CODEC_DAC_ACTL_RLNS, 1, 0),
829 	SOC_DAPM_DOUBLE("FM Playback Switch", SUN4I_CODEC_DAC_ACTL,
830 			SUN4I_CODEC_DAC_ACTL_LFMS,
831 			SUN4I_CODEC_DAC_ACTL_RFMS, 1, 0),
832 	SOC_DAPM_DOUBLE("Mic1 Playback Switch", SUN4I_CODEC_DAC_ACTL,
833 			SUN4I_CODEC_DAC_ACTL_MIC1LS,
834 			SUN4I_CODEC_DAC_ACTL_MIC1RS, 1, 0),
835 	SOC_DAPM_DOUBLE("Mic2 Playback Switch", SUN4I_CODEC_DAC_ACTL,
836 			SUN4I_CODEC_DAC_ACTL_MIC2LS,
837 			SUN4I_CODEC_DAC_ACTL_MIC2RS, 1, 0),
838 };
839 
840 static const struct snd_kcontrol_new sun4i_codec_pa_mixer_controls[] = {
841 	SOC_DAPM_SINGLE("DAC Playback Switch", SUN4I_CODEC_DAC_ACTL,
842 			SUN4I_CODEC_DAC_ACTL_DACPAS, 1, 0),
843 	SOC_DAPM_SINGLE("Mixer Playback Switch", SUN4I_CODEC_DAC_ACTL,
844 			SUN4I_CODEC_DAC_ACTL_MIXPAS, 1, 0),
845 };
846 
847 static const struct snd_soc_dapm_widget sun4i_codec_codec_dapm_widgets[] = {
848 	/* Digital parts of the ADCs */
849 	SND_SOC_DAPM_SUPPLY("ADC", SUN4I_CODEC_ADC_FIFOC,
850 			    SUN4I_CODEC_ADC_FIFOC_EN_AD, 0,
851 			    NULL, 0),
852 
853 	/* Digital parts of the DACs */
854 	SND_SOC_DAPM_SUPPLY("DAC", SUN4I_CODEC_DAC_DPC,
855 			    SUN4I_CODEC_DAC_DPC_EN_DA, 0,
856 			    NULL, 0),
857 
858 	/* Analog parts of the ADCs */
859 	SND_SOC_DAPM_ADC("Left ADC", "Codec Capture", SUN4I_CODEC_ADC_ACTL,
860 			 SUN4I_CODEC_ADC_ACTL_ADC_L_EN, 0),
861 	SND_SOC_DAPM_ADC("Right ADC", "Codec Capture", SUN4I_CODEC_ADC_ACTL,
862 			 SUN4I_CODEC_ADC_ACTL_ADC_R_EN, 0),
863 
864 	/* Analog parts of the DACs */
865 	SND_SOC_DAPM_DAC("Left DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL,
866 			 SUN4I_CODEC_DAC_ACTL_DACAENL, 0),
867 	SND_SOC_DAPM_DAC("Right DAC", "Codec Playback", SUN4I_CODEC_DAC_ACTL,
868 			 SUN4I_CODEC_DAC_ACTL_DACAENR, 0),
869 
870 	/* Mixers */
871 	SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
872 			   sun4i_codec_mixer_controls,
873 			   ARRAY_SIZE(sun4i_codec_mixer_controls)),
874 	SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
875 			   sun4i_codec_mixer_controls,
876 			   ARRAY_SIZE(sun4i_codec_mixer_controls)),
877 
878 	/* Global Mixer Enable */
879 	SND_SOC_DAPM_SUPPLY("Mixer Enable", SUN4I_CODEC_DAC_ACTL,
880 			    SUN4I_CODEC_DAC_ACTL_MIXEN, 0, NULL, 0),
881 
882 	/* VMIC */
883 	SND_SOC_DAPM_SUPPLY("VMIC", SUN4I_CODEC_ADC_ACTL,
884 			    SUN4I_CODEC_ADC_ACTL_VMICEN, 0, NULL, 0),
885 
886 	/* Mic Pre-Amplifiers */
887 	SND_SOC_DAPM_PGA("MIC1 Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
888 			 SUN4I_CODEC_ADC_ACTL_PREG1EN, 0, NULL, 0),
889 	SND_SOC_DAPM_PGA("MIC2 Pre-Amplifier", SUN4I_CODEC_ADC_ACTL,
890 			 SUN4I_CODEC_ADC_ACTL_PREG2EN, 0, NULL, 0),
891 
892 	/* Power Amplifier */
893 	SND_SOC_DAPM_MIXER("Power Amplifier", SUN4I_CODEC_ADC_ACTL,
894 			   SUN4I_CODEC_ADC_ACTL_PA_EN, 0,
895 			   sun4i_codec_pa_mixer_controls,
896 			   ARRAY_SIZE(sun4i_codec_pa_mixer_controls)),
897 	SND_SOC_DAPM_SWITCH("Power Amplifier Mute", SND_SOC_NOPM, 0, 0,
898 			    &sun4i_codec_pa_mute),
899 
900 	SND_SOC_DAPM_INPUT("Line Right"),
901 	SND_SOC_DAPM_INPUT("Line Left"),
902 	SND_SOC_DAPM_INPUT("FM Right"),
903 	SND_SOC_DAPM_INPUT("FM Left"),
904 	SND_SOC_DAPM_INPUT("Mic1"),
905 	SND_SOC_DAPM_INPUT("Mic2"),
906 
907 	SND_SOC_DAPM_OUTPUT("HP Right"),
908 	SND_SOC_DAPM_OUTPUT("HP Left"),
909 };
910 
911 static const struct snd_soc_dapm_route sun4i_codec_codec_dapm_routes[] = {
912 	/* Left ADC / DAC Routes */
913 	{ "Left ADC", NULL, "ADC" },
914 	{ "Left DAC", NULL, "DAC" },
915 
916 	/* Right ADC / DAC Routes */
917 	{ "Right ADC", NULL, "ADC" },
918 	{ "Right DAC", NULL, "DAC" },
919 
920 	/* Right Mixer Routes */
921 	{ "Right Mixer", NULL, "Mixer Enable" },
922 	{ "Right Mixer", "Right Mixer Left DAC Playback Switch", "Left DAC" },
923 	{ "Right Mixer", "Right Mixer Right DAC Playback Switch", "Right DAC" },
924 	{ "Right Mixer", "Line Playback Switch", "Line Right" },
925 	{ "Right Mixer", "FM Playback Switch", "FM Right" },
926 	{ "Right Mixer", "Mic1 Playback Switch", "MIC1 Pre-Amplifier" },
927 	{ "Right Mixer", "Mic2 Playback Switch", "MIC2 Pre-Amplifier" },
928 
929 	/* Left Mixer Routes */
930 	{ "Left Mixer", NULL, "Mixer Enable" },
931 	{ "Left Mixer", "Left Mixer Left DAC Playback Switch", "Left DAC" },
932 	{ "Left Mixer", "Line Playback Switch", "Line Left" },
933 	{ "Left Mixer", "FM Playback Switch", "FM Left" },
934 	{ "Left Mixer", "Mic1 Playback Switch", "MIC1 Pre-Amplifier" },
935 	{ "Left Mixer", "Mic2 Playback Switch", "MIC2 Pre-Amplifier" },
936 
937 	/* Power Amplifier Routes */
938 	{ "Power Amplifier", "Mixer Playback Switch", "Left Mixer" },
939 	{ "Power Amplifier", "Mixer Playback Switch", "Right Mixer" },
940 	{ "Power Amplifier", "DAC Playback Switch", "Left DAC" },
941 	{ "Power Amplifier", "DAC Playback Switch", "Right DAC" },
942 
943 	/* Headphone Output Routes */
944 	{ "Power Amplifier Mute", "Switch", "Power Amplifier" },
945 	{ "HP Right", NULL, "Power Amplifier Mute" },
946 	{ "HP Left", NULL, "Power Amplifier Mute" },
947 
948 	/* Mic1 Routes */
949 	{ "Left ADC", NULL, "MIC1 Pre-Amplifier" },
950 	{ "Right ADC", NULL, "MIC1 Pre-Amplifier" },
951 	{ "MIC1 Pre-Amplifier", NULL, "Mic1"},
952 	{ "Mic1", NULL, "VMIC" },
953 
954 	/* Mic2 Routes */
955 	{ "Left ADC", NULL, "MIC2 Pre-Amplifier" },
956 	{ "Right ADC", NULL, "MIC2 Pre-Amplifier" },
957 	{ "MIC2 Pre-Amplifier", NULL, "Mic2"},
958 	{ "Mic2", NULL, "VMIC" },
959 };
960 
961 static const struct snd_soc_component_driver sun4i_codec_codec = {
962 	.controls		= sun4i_codec_controls,
963 	.num_controls		= ARRAY_SIZE(sun4i_codec_controls),
964 	.dapm_widgets		= sun4i_codec_codec_dapm_widgets,
965 	.num_dapm_widgets	= ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
966 	.dapm_routes		= sun4i_codec_codec_dapm_routes,
967 	.num_dapm_routes	= ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
968 	.idle_bias_on		= 1,
969 	.use_pmdown_time	= 1,
970 	.endianness		= 1,
971 };
972 
973 static const struct snd_soc_component_driver sun7i_codec_codec = {
974 	.controls		= sun7i_codec_controls,
975 	.num_controls		= ARRAY_SIZE(sun7i_codec_controls),
976 	.dapm_widgets		= sun4i_codec_codec_dapm_widgets,
977 	.num_dapm_widgets	= ARRAY_SIZE(sun4i_codec_codec_dapm_widgets),
978 	.dapm_routes		= sun4i_codec_codec_dapm_routes,
979 	.num_dapm_routes	= ARRAY_SIZE(sun4i_codec_codec_dapm_routes),
980 	.idle_bias_on		= 1,
981 	.use_pmdown_time	= 1,
982 	.endianness		= 1,
983 };
984 
985 /*** sun6i Codec ***/
986 
987 /* mixer controls */
988 static const struct snd_kcontrol_new sun6i_codec_mixer_controls[] = {
989 	SOC_DAPM_DOUBLE("DAC Playback Switch",
990 			SUN6I_CODEC_OM_DACA_CTRL,
991 			SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACL,
992 			SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACR, 1, 0),
993 	SOC_DAPM_DOUBLE("DAC Reversed Playback Switch",
994 			SUN6I_CODEC_OM_DACA_CTRL,
995 			SUN6I_CODEC_OM_DACA_CTRL_LMIX_DACR,
996 			SUN6I_CODEC_OM_DACA_CTRL_RMIX_DACL, 1, 0),
997 	SOC_DAPM_DOUBLE("Line In Playback Switch",
998 			SUN6I_CODEC_OM_DACA_CTRL,
999 			SUN6I_CODEC_OM_DACA_CTRL_LMIX_LINEINL,
1000 			SUN6I_CODEC_OM_DACA_CTRL_RMIX_LINEINR, 1, 0),
1001 	SOC_DAPM_DOUBLE("Mic1 Playback Switch",
1002 			SUN6I_CODEC_OM_DACA_CTRL,
1003 			SUN6I_CODEC_OM_DACA_CTRL_LMIX_MIC1,
1004 			SUN6I_CODEC_OM_DACA_CTRL_RMIX_MIC1, 1, 0),
1005 	SOC_DAPM_DOUBLE("Mic2 Playback Switch",
1006 			SUN6I_CODEC_OM_DACA_CTRL,
1007 			SUN6I_CODEC_OM_DACA_CTRL_LMIX_MIC2,
1008 			SUN6I_CODEC_OM_DACA_CTRL_RMIX_MIC2, 1, 0),
1009 };
1010 
1011 /* ADC mixer controls */
1012 static const struct snd_kcontrol_new sun6i_codec_adc_mixer_controls[] = {
1013 	SOC_DAPM_DOUBLE("Mixer Capture Switch",
1014 			SUN6I_CODEC_ADC_ACTL,
1015 			SUN6I_CODEC_ADC_ACTL_LADCMIX_OMIXL,
1016 			SUN6I_CODEC_ADC_ACTL_RADCMIX_OMIXR, 1, 0),
1017 	SOC_DAPM_DOUBLE("Mixer Reversed Capture Switch",
1018 			SUN6I_CODEC_ADC_ACTL,
1019 			SUN6I_CODEC_ADC_ACTL_LADCMIX_OMIXR,
1020 			SUN6I_CODEC_ADC_ACTL_RADCMIX_OMIXL, 1, 0),
1021 	SOC_DAPM_DOUBLE("Line In Capture Switch",
1022 			SUN6I_CODEC_ADC_ACTL,
1023 			SUN6I_CODEC_ADC_ACTL_LADCMIX_LINEINL,
1024 			SUN6I_CODEC_ADC_ACTL_RADCMIX_LINEINR, 1, 0),
1025 	SOC_DAPM_DOUBLE("Mic1 Capture Switch",
1026 			SUN6I_CODEC_ADC_ACTL,
1027 			SUN6I_CODEC_ADC_ACTL_LADCMIX_MIC1,
1028 			SUN6I_CODEC_ADC_ACTL_RADCMIX_MIC1, 1, 0),
1029 	SOC_DAPM_DOUBLE("Mic2 Capture Switch",
1030 			SUN6I_CODEC_ADC_ACTL,
1031 			SUN6I_CODEC_ADC_ACTL_LADCMIX_MIC2,
1032 			SUN6I_CODEC_ADC_ACTL_RADCMIX_MIC2, 1, 0),
1033 };
1034 
1035 /* headphone controls */
1036 static const char * const sun6i_codec_hp_src_enum_text[] = {
1037 	"DAC", "Mixer",
1038 };
1039 
1040 static SOC_ENUM_DOUBLE_DECL(sun6i_codec_hp_src_enum,
1041 			    SUN6I_CODEC_OM_DACA_CTRL,
1042 			    SUN6I_CODEC_OM_DACA_CTRL_LHPIS,
1043 			    SUN6I_CODEC_OM_DACA_CTRL_RHPIS,
1044 			    sun6i_codec_hp_src_enum_text);
1045 
1046 static const struct snd_kcontrol_new sun6i_codec_hp_src[] = {
1047 	SOC_DAPM_ENUM("Headphone Source Playback Route",
1048 		      sun6i_codec_hp_src_enum),
1049 };
1050 
1051 /* microphone controls */
1052 static const char * const sun6i_codec_mic2_src_enum_text[] = {
1053 	"Mic2", "Mic3",
1054 };
1055 
1056 static SOC_ENUM_SINGLE_DECL(sun6i_codec_mic2_src_enum,
1057 			    SUN6I_CODEC_MIC_CTRL,
1058 			    SUN6I_CODEC_MIC_CTRL_MIC2SLT,
1059 			    sun6i_codec_mic2_src_enum_text);
1060 
1061 static const struct snd_kcontrol_new sun6i_codec_mic2_src[] = {
1062 	SOC_DAPM_ENUM("Mic2 Amplifier Source Route",
1063 		      sun6i_codec_mic2_src_enum),
1064 };
1065 
1066 /* line out controls */
1067 static const char * const sun6i_codec_lineout_src_enum_text[] = {
1068 	"Stereo", "Mono Differential",
1069 };
1070 
1071 static SOC_ENUM_DOUBLE_DECL(sun6i_codec_lineout_src_enum,
1072 			    SUN6I_CODEC_MIC_CTRL,
1073 			    SUN6I_CODEC_MIC_CTRL_LINEOUTLSRC,
1074 			    SUN6I_CODEC_MIC_CTRL_LINEOUTRSRC,
1075 			    sun6i_codec_lineout_src_enum_text);
1076 
1077 static const struct snd_kcontrol_new sun6i_codec_lineout_src[] = {
1078 	SOC_DAPM_ENUM("Line Out Source Playback Route",
1079 		      sun6i_codec_lineout_src_enum),
1080 };
1081 
1082 /* volume / mute controls */
1083 static const DECLARE_TLV_DB_SCALE(sun6i_codec_dvol_scale, -7308, 116, 0);
1084 static const DECLARE_TLV_DB_SCALE(sun6i_codec_hp_vol_scale, -6300, 100, 1);
1085 static const DECLARE_TLV_DB_SCALE(sun6i_codec_out_mixer_pregain_scale,
1086 				  -450, 150, 0);
1087 static const DECLARE_TLV_DB_RANGE(sun6i_codec_lineout_vol_scale,
1088 	0, 1, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
1089 	2, 31, TLV_DB_SCALE_ITEM(-4350, 150, 0),
1090 );
1091 static const DECLARE_TLV_DB_RANGE(sun6i_codec_mic_gain_scale,
1092 	0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
1093 	1, 7, TLV_DB_SCALE_ITEM(2400, 300, 0),
1094 );
1095 
1096 static const struct snd_kcontrol_new sun6i_codec_codec_widgets[] = {
1097 	SOC_SINGLE_TLV("DAC Playback Volume", SUN4I_CODEC_DAC_DPC,
1098 		       SUN4I_CODEC_DAC_DPC_DVOL, 0x3f, 1,
1099 		       sun6i_codec_dvol_scale),
1100 	SOC_SINGLE_TLV("Headphone Playback Volume",
1101 		       SUN6I_CODEC_OM_DACA_CTRL,
1102 		       SUN6I_CODEC_OM_DACA_CTRL_HPVOL, 0x3f, 0,
1103 		       sun6i_codec_hp_vol_scale),
1104 	SOC_SINGLE_TLV("Line Out Playback Volume",
1105 		       SUN6I_CODEC_MIC_CTRL,
1106 		       SUN6I_CODEC_MIC_CTRL_LINEOUTVC, 0x1f, 0,
1107 		       sun6i_codec_lineout_vol_scale),
1108 	SOC_DOUBLE("Headphone Playback Switch",
1109 		   SUN6I_CODEC_OM_DACA_CTRL,
1110 		   SUN6I_CODEC_OM_DACA_CTRL_LHPPAMUTE,
1111 		   SUN6I_CODEC_OM_DACA_CTRL_RHPPAMUTE, 1, 0),
1112 	SOC_DOUBLE("Line Out Playback Switch",
1113 		   SUN6I_CODEC_MIC_CTRL,
1114 		   SUN6I_CODEC_MIC_CTRL_LINEOUTLEN,
1115 		   SUN6I_CODEC_MIC_CTRL_LINEOUTREN, 1, 0),
1116 	/* Mixer pre-gains */
1117 	SOC_SINGLE_TLV("Line In Playback Volume",
1118 		       SUN6I_CODEC_OM_PA_CTRL, SUN6I_CODEC_OM_PA_CTRL_LINEING,
1119 		       0x7, 0, sun6i_codec_out_mixer_pregain_scale),
1120 	SOC_SINGLE_TLV("Mic1 Playback Volume",
1121 		       SUN6I_CODEC_OM_PA_CTRL, SUN6I_CODEC_OM_PA_CTRL_MIC1G,
1122 		       0x7, 0, sun6i_codec_out_mixer_pregain_scale),
1123 	SOC_SINGLE_TLV("Mic2 Playback Volume",
1124 		       SUN6I_CODEC_OM_PA_CTRL, SUN6I_CODEC_OM_PA_CTRL_MIC2G,
1125 		       0x7, 0, sun6i_codec_out_mixer_pregain_scale),
1126 
1127 	/* Microphone Amp boost gains */
1128 	SOC_SINGLE_TLV("Mic1 Boost Volume", SUN6I_CODEC_MIC_CTRL,
1129 		       SUN6I_CODEC_MIC_CTRL_MIC1BOOST, 0x7, 0,
1130 		       sun6i_codec_mic_gain_scale),
1131 	SOC_SINGLE_TLV("Mic2 Boost Volume", SUN6I_CODEC_MIC_CTRL,
1132 		       SUN6I_CODEC_MIC_CTRL_MIC2BOOST, 0x7, 0,
1133 		       sun6i_codec_mic_gain_scale),
1134 	SOC_DOUBLE_TLV("ADC Capture Volume",
1135 		       SUN6I_CODEC_ADC_ACTL, SUN6I_CODEC_ADC_ACTL_ADCLG,
1136 		       SUN6I_CODEC_ADC_ACTL_ADCRG, 0x7, 0,
1137 		       sun6i_codec_out_mixer_pregain_scale),
1138 };
1139 
1140 static const struct snd_soc_dapm_widget sun6i_codec_codec_dapm_widgets[] = {
1141 	/* Microphone inputs */
1142 	SND_SOC_DAPM_INPUT("MIC1"),
1143 	SND_SOC_DAPM_INPUT("MIC2"),
1144 	SND_SOC_DAPM_INPUT("MIC3"),
1145 
1146 	/* Microphone Bias */
1147 	SND_SOC_DAPM_SUPPLY("HBIAS", SUN6I_CODEC_MIC_CTRL,
1148 			    SUN6I_CODEC_MIC_CTRL_HBIASEN, 0, NULL, 0),
1149 	SND_SOC_DAPM_SUPPLY("MBIAS", SUN6I_CODEC_MIC_CTRL,
1150 			    SUN6I_CODEC_MIC_CTRL_MBIASEN, 0, NULL, 0),
1151 
1152 	/* Mic input path */
1153 	SND_SOC_DAPM_MUX("Mic2 Amplifier Source Route",
1154 			 SND_SOC_NOPM, 0, 0, sun6i_codec_mic2_src),
1155 	SND_SOC_DAPM_PGA("Mic1 Amplifier", SUN6I_CODEC_MIC_CTRL,
1156 			 SUN6I_CODEC_MIC_CTRL_MIC1AMPEN, 0, NULL, 0),
1157 	SND_SOC_DAPM_PGA("Mic2 Amplifier", SUN6I_CODEC_MIC_CTRL,
1158 			 SUN6I_CODEC_MIC_CTRL_MIC2AMPEN, 0, NULL, 0),
1159 
1160 	/* Line In */
1161 	SND_SOC_DAPM_INPUT("LINEIN"),
1162 
1163 	/* Digital parts of the ADCs */
1164 	SND_SOC_DAPM_SUPPLY("ADC Enable", SUN6I_CODEC_ADC_FIFOC,
1165 			    SUN6I_CODEC_ADC_FIFOC_EN_AD, 0,
1166 			    NULL, 0),
1167 
1168 	/* Analog parts of the ADCs */
1169 	SND_SOC_DAPM_ADC("Left ADC", "Codec Capture", SUN6I_CODEC_ADC_ACTL,
1170 			 SUN6I_CODEC_ADC_ACTL_ADCLEN, 0),
1171 	SND_SOC_DAPM_ADC("Right ADC", "Codec Capture", SUN6I_CODEC_ADC_ACTL,
1172 			 SUN6I_CODEC_ADC_ACTL_ADCREN, 0),
1173 
1174 	/* ADC Mixers */
1175 	SOC_MIXER_ARRAY("Left ADC Mixer", SND_SOC_NOPM, 0, 0,
1176 			sun6i_codec_adc_mixer_controls),
1177 	SOC_MIXER_ARRAY("Right ADC Mixer", SND_SOC_NOPM, 0, 0,
1178 			sun6i_codec_adc_mixer_controls),
1179 
1180 	/* Digital parts of the DACs */
1181 	SND_SOC_DAPM_SUPPLY("DAC Enable", SUN4I_CODEC_DAC_DPC,
1182 			    SUN4I_CODEC_DAC_DPC_EN_DA, 0,
1183 			    NULL, 0),
1184 
1185 	/* Analog parts of the DACs */
1186 	SND_SOC_DAPM_DAC("Left DAC", "Codec Playback",
1187 			 SUN6I_CODEC_OM_DACA_CTRL,
1188 			 SUN6I_CODEC_OM_DACA_CTRL_DACALEN, 0),
1189 	SND_SOC_DAPM_DAC("Right DAC", "Codec Playback",
1190 			 SUN6I_CODEC_OM_DACA_CTRL,
1191 			 SUN6I_CODEC_OM_DACA_CTRL_DACAREN, 0),
1192 
1193 	/* Mixers */
1194 	SOC_MIXER_ARRAY("Left Mixer", SUN6I_CODEC_OM_DACA_CTRL,
1195 			SUN6I_CODEC_OM_DACA_CTRL_LMIXEN, 0,
1196 			sun6i_codec_mixer_controls),
1197 	SOC_MIXER_ARRAY("Right Mixer", SUN6I_CODEC_OM_DACA_CTRL,
1198 			SUN6I_CODEC_OM_DACA_CTRL_RMIXEN, 0,
1199 			sun6i_codec_mixer_controls),
1200 
1201 	/* Headphone output path */
1202 	SND_SOC_DAPM_MUX("Headphone Source Playback Route",
1203 			 SND_SOC_NOPM, 0, 0, sun6i_codec_hp_src),
1204 	SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUN6I_CODEC_OM_PA_CTRL,
1205 			     SUN6I_CODEC_OM_PA_CTRL_HPPAEN, 0, NULL, 0),
1206 	SND_SOC_DAPM_SUPPLY("HPCOM Protection", SUN6I_CODEC_OM_PA_CTRL,
1207 			    SUN6I_CODEC_OM_PA_CTRL_COMPTEN, 0, NULL, 0),
1208 	SND_SOC_DAPM_REG(snd_soc_dapm_supply, "HPCOM", SUN6I_CODEC_OM_PA_CTRL,
1209 			 SUN6I_CODEC_OM_PA_CTRL_HPCOM_CTL, 0x3, 0x3, 0),
1210 	SND_SOC_DAPM_OUTPUT("HP"),
1211 
1212 	/* Line Out path */
1213 	SND_SOC_DAPM_MUX("Line Out Source Playback Route",
1214 			 SND_SOC_NOPM, 0, 0, sun6i_codec_lineout_src),
1215 	SND_SOC_DAPM_OUTPUT("LINEOUT"),
1216 };
1217 
1218 static const struct snd_soc_dapm_route sun6i_codec_codec_dapm_routes[] = {
1219 	/* DAC Routes */
1220 	{ "Left DAC", NULL, "DAC Enable" },
1221 	{ "Right DAC", NULL, "DAC Enable" },
1222 
1223 	/* Microphone Routes */
1224 	{ "Mic1 Amplifier", NULL, "MIC1"},
1225 	{ "Mic2 Amplifier Source Route", "Mic2", "MIC2" },
1226 	{ "Mic2 Amplifier Source Route", "Mic3", "MIC3" },
1227 	{ "Mic2 Amplifier", NULL, "Mic2 Amplifier Source Route"},
1228 
1229 	/* Left Mixer Routes */
1230 	{ "Left Mixer", "DAC Playback Switch", "Left DAC" },
1231 	{ "Left Mixer", "DAC Reversed Playback Switch", "Right DAC" },
1232 	{ "Left Mixer", "Line In Playback Switch", "LINEIN" },
1233 	{ "Left Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" },
1234 	{ "Left Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
1235 
1236 	/* Right Mixer Routes */
1237 	{ "Right Mixer", "DAC Playback Switch", "Right DAC" },
1238 	{ "Right Mixer", "DAC Reversed Playback Switch", "Left DAC" },
1239 	{ "Right Mixer", "Line In Playback Switch", "LINEIN" },
1240 	{ "Right Mixer", "Mic1 Playback Switch", "Mic1 Amplifier" },
1241 	{ "Right Mixer", "Mic2 Playback Switch", "Mic2 Amplifier" },
1242 
1243 	/* Left ADC Mixer Routes */
1244 	{ "Left ADC Mixer", "Mixer Capture Switch", "Left Mixer" },
1245 	{ "Left ADC Mixer", "Mixer Reversed Capture Switch", "Right Mixer" },
1246 	{ "Left ADC Mixer", "Line In Capture Switch", "LINEIN" },
1247 	{ "Left ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" },
1248 	{ "Left ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
1249 
1250 	/* Right ADC Mixer Routes */
1251 	{ "Right ADC Mixer", "Mixer Capture Switch", "Right Mixer" },
1252 	{ "Right ADC Mixer", "Mixer Reversed Capture Switch", "Left Mixer" },
1253 	{ "Right ADC Mixer", "Line In Capture Switch", "LINEIN" },
1254 	{ "Right ADC Mixer", "Mic1 Capture Switch", "Mic1 Amplifier" },
1255 	{ "Right ADC Mixer", "Mic2 Capture Switch", "Mic2 Amplifier" },
1256 
1257 	/* Headphone Routes */
1258 	{ "Headphone Source Playback Route", "DAC", "Left DAC" },
1259 	{ "Headphone Source Playback Route", "DAC", "Right DAC" },
1260 	{ "Headphone Source Playback Route", "Mixer", "Left Mixer" },
1261 	{ "Headphone Source Playback Route", "Mixer", "Right Mixer" },
1262 	{ "Headphone Amp", NULL, "Headphone Source Playback Route" },
1263 	{ "HP", NULL, "Headphone Amp" },
1264 	{ "HPCOM", NULL, "HPCOM Protection" },
1265 
1266 	/* Line Out Routes */
1267 	{ "Line Out Source Playback Route", "Stereo", "Left Mixer" },
1268 	{ "Line Out Source Playback Route", "Stereo", "Right Mixer" },
1269 	{ "Line Out Source Playback Route", "Mono Differential", "Left Mixer" },
1270 	{ "Line Out Source Playback Route", "Mono Differential", "Right Mixer" },
1271 	{ "LINEOUT", NULL, "Line Out Source Playback Route" },
1272 
1273 	/* ADC Routes */
1274 	{ "Left ADC", NULL, "ADC Enable" },
1275 	{ "Right ADC", NULL, "ADC Enable" },
1276 	{ "Left ADC", NULL, "Left ADC Mixer" },
1277 	{ "Right ADC", NULL, "Right ADC Mixer" },
1278 };
1279 
1280 static const struct snd_soc_component_driver sun6i_codec_codec = {
1281 	.controls		= sun6i_codec_codec_widgets,
1282 	.num_controls		= ARRAY_SIZE(sun6i_codec_codec_widgets),
1283 	.dapm_widgets		= sun6i_codec_codec_dapm_widgets,
1284 	.num_dapm_widgets	= ARRAY_SIZE(sun6i_codec_codec_dapm_widgets),
1285 	.dapm_routes		= sun6i_codec_codec_dapm_routes,
1286 	.num_dapm_routes	= ARRAY_SIZE(sun6i_codec_codec_dapm_routes),
1287 	.idle_bias_on		= 1,
1288 	.use_pmdown_time	= 1,
1289 	.endianness		= 1,
1290 };
1291 
1292 /* sun8i A23 codec */
1293 static const struct snd_kcontrol_new sun8i_a23_codec_codec_controls[] = {
1294 	SOC_SINGLE_TLV("DAC Playback Volume", SUN4I_CODEC_DAC_DPC,
1295 		       SUN4I_CODEC_DAC_DPC_DVOL, 0x3f, 1,
1296 		       sun6i_codec_dvol_scale),
1297 };
1298 
1299 static const struct snd_soc_dapm_widget sun8i_a23_codec_codec_widgets[] = {
1300 	/* Digital parts of the ADCs */
1301 	SND_SOC_DAPM_SUPPLY("ADC Enable", SUN6I_CODEC_ADC_FIFOC,
1302 			    SUN6I_CODEC_ADC_FIFOC_EN_AD, 0, NULL, 0),
1303 	/* Digital parts of the DACs */
1304 	SND_SOC_DAPM_SUPPLY("DAC Enable", SUN4I_CODEC_DAC_DPC,
1305 			    SUN4I_CODEC_DAC_DPC_EN_DA, 0, NULL, 0),
1306 
1307 };
1308 
1309 static const struct snd_soc_component_driver sun8i_a23_codec_codec = {
1310 	.controls		= sun8i_a23_codec_codec_controls,
1311 	.num_controls		= ARRAY_SIZE(sun8i_a23_codec_codec_controls),
1312 	.dapm_widgets		= sun8i_a23_codec_codec_widgets,
1313 	.num_dapm_widgets	= ARRAY_SIZE(sun8i_a23_codec_codec_widgets),
1314 	.idle_bias_on		= 1,
1315 	.use_pmdown_time	= 1,
1316 	.endianness		= 1,
1317 };
1318 
1319 /*suniv F1C100s codec */
1320 
1321 /* headphone controls */
1322 static const char * const suniv_codec_hp_src_enum_text[] = {
1323 	"DAC", "Mixer",
1324 };
1325 
1326 static SOC_ENUM_DOUBLE_DECL(suniv_codec_hp_src_enum,
1327 			    SUNIV_CODEC_OM_DACA_CTRL,
1328 			    SUNIV_CODEC_OM_DACA_CTRL_LHPIS,
1329 			    SUNIV_CODEC_OM_DACA_CTRL_RHPIS,
1330 			    suniv_codec_hp_src_enum_text);
1331 
1332 static const struct snd_kcontrol_new suniv_codec_hp_src[] = {
1333 	SOC_DAPM_ENUM("Headphone Source Playback Route",
1334 		      suniv_codec_hp_src_enum),
1335 };
1336 
1337 /* mixer controls */
1338 static const struct snd_kcontrol_new suniv_codec_adc_mixer_controls[] = {
1339 	SOC_DAPM_SINGLE("Right Out Capture Switch", SUNIV_CODEC_ADC_ACTL,
1340 			SUNIV_CODEC_ADC_ADCMIX_ROUT, 1, 0),
1341 	SOC_DAPM_SINGLE("Left Out Capture Switch", SUNIV_CODEC_ADC_ACTL,
1342 			SUNIV_CODEC_ADC_ADCMIX_LOUT, 1, 0),
1343 	SOC_DAPM_SINGLE("Line In Capture Switch", SUNIV_CODEC_ADC_ACTL,
1344 			SUNIV_CODEC_ADC_ADCMIX_LINEIN, 1, 0),
1345 	SOC_DAPM_SINGLE("Right FM In Capture Switch", SUNIV_CODEC_ADC_ACTL,
1346 			SUNIV_CODEC_ADC_ADCMIX_FMINR, 1, 0),
1347 	SOC_DAPM_SINGLE("Left FM In Capture Switch", SUNIV_CODEC_ADC_ACTL,
1348 			SUNIV_CODEC_ADC_ADCMIX_FMINL, 1, 0),
1349 	SOC_DAPM_SINGLE("Mic Capture Switch", SUNIV_CODEC_ADC_ACTL,
1350 			SUNIV_CODEC_ADC_ADCMIX_MIC, 1, 0),
1351 };
1352 
1353 static const struct snd_kcontrol_new suniv_codec_dac_lmixer_controls[] = {
1354 	SOC_DAPM_SINGLE("Right DAC Playback Switch", SUNIV_CODEC_OM_DACA_CTRL,
1355 			SUNIV_CODEC_OM_DACA_CTRL_LMIXMUTE_RDAC, 1, 0),
1356 	SOC_DAPM_SINGLE("Left DAC Playback Switch", SUNIV_CODEC_OM_DACA_CTRL,
1357 			SUNIV_CODEC_OM_DACA_CTRL_LMIXMUTE_LDAC, 1, 0),
1358 	SOC_DAPM_SINGLE("FM In Playback Switch", SUNIV_CODEC_OM_DACA_CTRL,
1359 			SUNIV_CODEC_OM_DACA_CTRL_LMIXMUTE_FMIN, 1, 0),
1360 	SOC_DAPM_SINGLE("Line In Playback Switch", SUNIV_CODEC_OM_DACA_CTRL,
1361 			SUNIV_CODEC_OM_DACA_CTRL_LMIXMUTE_LINEIN, 1, 0),
1362 	SOC_DAPM_SINGLE("Mic In Playback Switch", SUNIV_CODEC_OM_DACA_CTRL,
1363 			SUNIV_CODEC_OM_DACA_CTRL_LMIXMUTE_MICIN, 1, 0),
1364 };
1365 
1366 static const struct snd_kcontrol_new suniv_codec_dac_rmixer_controls[] = {
1367 	SOC_DAPM_SINGLE("Left DAC Playback Switch", SUNIV_CODEC_OM_DACA_CTRL,
1368 			SUNIV_CODEC_OM_DACA_CTRL_RMIXMUTE_LDAC, 1, 0),
1369 	SOC_DAPM_SINGLE("Right DAC Playback Switch", SUNIV_CODEC_OM_DACA_CTRL,
1370 			SUNIV_CODEC_OM_DACA_CTRL_RMIXMUTE_RDAC, 1, 0),
1371 	SOC_DAPM_SINGLE("FM In Playback Switch", SUNIV_CODEC_OM_DACA_CTRL,
1372 			SUNIV_CODEC_OM_DACA_CTRL_RMIXMUTE_FMIN, 1, 0),
1373 	SOC_DAPM_SINGLE("Line In Playback Switch", SUNIV_CODEC_OM_DACA_CTRL,
1374 			SUNIV_CODEC_OM_DACA_CTRL_RMIXMUTE_LINEIN, 1, 0),
1375 	SOC_DAPM_SINGLE("Mic In Playback Switch", SUNIV_CODEC_OM_DACA_CTRL,
1376 			SUNIV_CODEC_OM_DACA_CTRL_RMIXMUTE_MICIN, 1, 0),
1377 };
1378 
1379 static const DECLARE_TLV_DB_SCALE(suniv_codec_dvol_scale, -7308, 116, 0);
1380 static const DECLARE_TLV_DB_SCALE(suniv_codec_hp_vol_scale, -6300, 100, 1);
1381 static const DECLARE_TLV_DB_SCALE(suniv_codec_out_mixer_pregain_scale,
1382 				  -450, 150, 0);
1383 
1384 static const DECLARE_TLV_DB_RANGE(suniv_codec_mic_gain_scale,
1385 	0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
1386 	1, 7, TLV_DB_SCALE_ITEM(2400, 300, 0),
1387 );
1388 
1389 static const struct snd_kcontrol_new suniv_codec_codec_widgets[] = {
1390 	SOC_SINGLE_TLV("DAC Playback Volume", SUN4I_CODEC_DAC_DPC,
1391 		       SUN4I_CODEC_DAC_DPC_DVOL, 0x3f, 1,
1392 		       suniv_codec_dvol_scale),
1393 	SOC_SINGLE_TLV("Headphone Playback Volume",
1394 		       SUNIV_CODEC_OM_DACA_CTRL,
1395 		       SUNIV_CODEC_OM_DACA_CTRL_HPVOL, 0x3f, 0,
1396 		       suniv_codec_hp_vol_scale),
1397 	SOC_DOUBLE("Headphone Playback Switch",
1398 		   SUNIV_CODEC_OM_DACA_CTRL,
1399 		   SUNIV_CODEC_OM_DACA_CTRL_LHPPAMUTE,
1400 		   SUNIV_CODEC_OM_DACA_CTRL_RHPPAMUTE, 1, 0),
1401 	SOC_SINGLE_TLV("Line In Playback Volume",
1402 		       SUNIV_CODEC_ADC_ACTL, SUNIV_CODEC_ADC_LINEINVOL,
1403 		       0x7, 0, suniv_codec_out_mixer_pregain_scale),
1404 	SOC_SINGLE_TLV("FM In Playback Volume",
1405 		       SUNIV_CODEC_ADC_ACTL, SUNIV_CODEC_ADC_FMINVOL,
1406 		       0x7, 0, suniv_codec_out_mixer_pregain_scale),
1407 	SOC_SINGLE_TLV("Mic In Playback Volume",
1408 		       SUNIV_CODEC_ADC_ACTL, SUNIV_CODEC_ADC_MICG,
1409 		       0x7, 0, suniv_codec_out_mixer_pregain_scale),
1410 
1411 	/* Microphone Amp boost gains */
1412 	SOC_SINGLE_TLV("Mic Boost Volume", SUNIV_CODEC_ADC_ACTL,
1413 		       SUNIV_CODEC_ADC_MICBOOST, 0x7, 0,
1414 		       suniv_codec_mic_gain_scale),
1415 	SOC_SINGLE_TLV("ADC Capture Volume",
1416 		       SUNIV_CODEC_ADC_ACTL, SUNIV_CODEC_ADC_ADCG,
1417 		       0x7, 0, suniv_codec_out_mixer_pregain_scale),
1418 };
1419 
1420 static const struct snd_soc_dapm_widget suniv_codec_codec_dapm_widgets[] = {
1421 	/* Microphone inputs */
1422 	SND_SOC_DAPM_INPUT("MIC"),
1423 
1424 	/* Microphone Bias */
1425 	/* deleted: HBIAS, MBIAS */
1426 
1427 	/* Mic input path */
1428 	SND_SOC_DAPM_PGA("Mic Amplifier", SUNIV_CODEC_ADC_ACTL,
1429 			 SUNIV_CODEC_ADC_MICAMPEN, 0, NULL, 0),
1430 
1431 	/* Line In */
1432 	SND_SOC_DAPM_INPUT("LINEIN"),
1433 
1434 	/* FM In */
1435 	SND_SOC_DAPM_INPUT("FMINR"),
1436 	SND_SOC_DAPM_INPUT("FMINL"),
1437 
1438 	/* Digital parts of the ADCs */
1439 	SND_SOC_DAPM_SUPPLY("ADC Enable", SUNIV_CODEC_ADC_FIFOC,
1440 			    SUNIV_CODEC_ADC_FIFOC_EN_AD, 0,
1441 			    NULL, 0),
1442 
1443 	/* Analog parts of the ADCs */
1444 	SND_SOC_DAPM_ADC("ADC", "Codec Capture", SUNIV_CODEC_ADC_ACTL,
1445 			 SUNIV_CODEC_ADC_ADCEN, 0),
1446 
1447 	/* ADC Mixers */
1448 	SOC_MIXER_ARRAY("ADC Mixer", SUNIV_CODEC_ADC_ACTL,
1449 			SND_SOC_NOPM, 0,
1450 			suniv_codec_adc_mixer_controls),
1451 
1452 	/* Digital parts of the DACs */
1453 	SND_SOC_DAPM_SUPPLY("DAC Enable", SUN4I_CODEC_DAC_DPC,
1454 			    SUN4I_CODEC_DAC_DPC_EN_DA, 0,
1455 			    NULL, 0),
1456 
1457 	/* Analog parts of the DACs */
1458 	SND_SOC_DAPM_DAC("Left DAC", "Codec Playback",
1459 			 SUNIV_CODEC_OM_DACA_CTRL,
1460 			 SUNIV_CODEC_OM_DACA_CTRL_DACALEN, 0),
1461 	SND_SOC_DAPM_DAC("Right DAC", "Codec Playback",
1462 			 SUNIV_CODEC_OM_DACA_CTRL,
1463 			 SUNIV_CODEC_OM_DACA_CTRL_DACAREN, 0),
1464 
1465 	/* Mixers */
1466 	SOC_MIXER_ARRAY("Left Mixer", SUNIV_CODEC_OM_DACA_CTRL,
1467 			SUNIV_CODEC_OM_DACA_CTRL_LMIXEN, 0,
1468 			suniv_codec_dac_lmixer_controls),
1469 	SOC_MIXER_ARRAY("Right Mixer", SUNIV_CODEC_OM_DACA_CTRL,
1470 			SUNIV_CODEC_OM_DACA_CTRL_RMIXEN, 0,
1471 			suniv_codec_dac_rmixer_controls),
1472 
1473 	/* Headphone output path */
1474 	SND_SOC_DAPM_MUX("Headphone Source Playback Route",
1475 			 SND_SOC_NOPM, 0, 0, suniv_codec_hp_src),
1476 	SND_SOC_DAPM_OUT_DRV("Headphone Amp", SUNIV_CODEC_OM_DACA_CTRL,
1477 			     SUNIV_CODEC_OM_DACA_CTRL_HPPAEN, 0, NULL, 0),
1478 	SND_SOC_DAPM_SUPPLY("HPCOM Protection", SUNIV_CODEC_OM_DACA_CTRL,
1479 			    SUNIV_CODEC_OM_DACA_CTRL_COMPTEN, 0, NULL, 0),
1480 	SND_SOC_DAPM_REG(snd_soc_dapm_supply, "HPCOM", SUNIV_CODEC_OM_DACA_CTRL,
1481 			 SUNIV_CODEC_OM_DACA_CTRL_HPCOM_CTL, 0x3, 0x3, 0),
1482 	SND_SOC_DAPM_OUTPUT("HP"),
1483 };
1484 
1485 static const struct snd_soc_dapm_route suniv_codec_codec_dapm_routes[] = {
1486 	/* DAC Routes */
1487 	{ "Left DAC", NULL, "DAC Enable" },
1488 	{ "Right DAC", NULL, "DAC Enable" },
1489 
1490 	/* Microphone Routes */
1491 	{ "Mic Amplifier", NULL, "MIC"},
1492 
1493 	/* Left Mixer Routes */
1494 	{ "Left Mixer", "Right DAC Playback Switch", "Right DAC" },
1495 	{ "Left Mixer", "Left DAC Playback Switch", "Left DAC" },
1496 	{ "Left Mixer", "FM In Playback Switch", "FMINL" },
1497 	{ "Left Mixer", "Line In Playback Switch", "LINEIN" },
1498 	{ "Left Mixer", "Mic In Playback Switch", "Mic Amplifier" },
1499 
1500 	/* Right Mixer Routes */
1501 	{ "Right Mixer", "Left DAC Playback Switch", "Left DAC" },
1502 	{ "Right Mixer", "Right DAC Playback Switch", "Right DAC" },
1503 	{ "Right Mixer", "FM In Playback Switch", "FMINR" },
1504 	{ "Right Mixer", "Line In Playback Switch", "LINEIN" },
1505 	{ "Right Mixer", "Mic In Playback Switch", "Mic Amplifier" },
1506 
1507 	/* ADC Mixer Routes */
1508 	{ "ADC Mixer", "Right Out Capture Switch", "Right Mixer" },
1509 	{ "ADC Mixer", "Left Out Capture Switch", "Left Mixer" },
1510 	{ "ADC Mixer", "Line In Capture Switch", "LINEIN" },
1511 	{ "ADC Mixer", "Right FM In Capture Switch", "FMINR" },
1512 	{ "ADC Mixer", "Left FM In Capture Switch", "FMINL" },
1513 	{ "ADC Mixer", "Mic Capture Switch", "Mic Amplifier" },
1514 
1515 	/* Headphone Routes */
1516 	{ "Headphone Source Playback Route", "DAC", "Left DAC" },
1517 	{ "Headphone Source Playback Route", "DAC", "Right DAC" },
1518 	{ "Headphone Source Playback Route", "Mixer", "Left Mixer" },
1519 	{ "Headphone Source Playback Route", "Mixer", "Right Mixer" },
1520 	{ "Headphone Amp", NULL, "Headphone Source Playback Route" },
1521 	{ "HP", NULL, "Headphone Amp" },
1522 	{ "HPCOM", NULL, "HPCOM Protection" },
1523 
1524 	/* ADC Routes */
1525 	{ "ADC", NULL, "ADC Mixer" },
1526 	{ "ADC", NULL, "ADC Enable" },
1527 };
1528 
1529 static const struct snd_soc_component_driver suniv_codec_codec = {
1530 	.controls		= suniv_codec_codec_widgets,
1531 	.num_controls		= ARRAY_SIZE(suniv_codec_codec_widgets),
1532 	.dapm_widgets		= suniv_codec_codec_dapm_widgets,
1533 	.num_dapm_widgets	= ARRAY_SIZE(suniv_codec_codec_dapm_widgets),
1534 	.dapm_routes		= suniv_codec_codec_dapm_routes,
1535 	.num_dapm_routes	= ARRAY_SIZE(suniv_codec_codec_dapm_routes),
1536 	.idle_bias_on		= 1,
1537 	.use_pmdown_time	= 1,
1538 	.endianness		= 1,
1539 };
1540 
1541 static const struct snd_soc_component_driver sun4i_codec_component = {
1542 	.name			= "sun4i-codec",
1543 	.legacy_dai_naming	= 1,
1544 #ifdef CONFIG_DEBUG_FS
1545 	.debugfs_prefix		= "cpu",
1546 #endif
1547 };
1548 
1549 #define SUN4I_CODEC_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | \
1550 				 SNDRV_PCM_FMTBIT_S32_LE)
1551 
sun4i_codec_dai_probe(struct snd_soc_dai * dai)1552 static int sun4i_codec_dai_probe(struct snd_soc_dai *dai)
1553 {
1554 	struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai);
1555 	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
1556 
1557 	snd_soc_dai_init_dma_data(dai, &scodec->playback_dma_data,
1558 				  &scodec->capture_dma_data);
1559 
1560 	return 0;
1561 }
1562 
1563 static const struct snd_soc_dai_ops dummy_dai_ops = {
1564 	.probe	= sun4i_codec_dai_probe,
1565 };
1566 
1567 static struct snd_soc_dai_driver dummy_cpu_dai = {
1568 	.name	= "sun4i-codec-cpu-dai",
1569 	.playback = {
1570 		.stream_name	= "Playback",
1571 		.channels_min	= 1,
1572 		.channels_max	= 2,
1573 		.rates		= SUN4I_CODEC_RATES,
1574 		.formats	= SUN4I_CODEC_FORMATS,
1575 		.sig_bits	= 24,
1576 	},
1577 	.capture = {
1578 		.stream_name	= "Capture",
1579 		.channels_min	= 1,
1580 		.channels_max	= 2,
1581 		.rates 		= SUN4I_CODEC_RATES,
1582 		.formats 	= SUN4I_CODEC_FORMATS,
1583 		.sig_bits	= 24,
1584 	 },
1585 	.ops = &dummy_dai_ops,
1586 };
1587 
1588 static struct snd_soc_jack sun4i_headphone_jack;
1589 
1590 static struct snd_soc_jack_pin sun4i_headphone_jack_pins[] = {
1591 	{ .pin = "Headphone", .mask = SND_JACK_HEADPHONE },
1592 };
1593 
1594 static struct snd_soc_jack_gpio sun4i_headphone_jack_gpio = {
1595 	.name = "hp-det",
1596 	.report = SND_JACK_HEADPHONE,
1597 	.debounce_time = 150,
1598 };
1599 
sun4i_codec_machine_init(struct snd_soc_pcm_runtime * rtd)1600 static int sun4i_codec_machine_init(struct snd_soc_pcm_runtime *rtd)
1601 {
1602 	struct snd_soc_card *card = rtd->card;
1603 	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card);
1604 	int ret;
1605 
1606 	if (scodec->gpio_hp) {
1607 		ret = snd_soc_card_jack_new_pins(card, "Headphone Jack",
1608 						 SND_JACK_HEADPHONE,
1609 						 &sun4i_headphone_jack,
1610 						 sun4i_headphone_jack_pins,
1611 						 ARRAY_SIZE(sun4i_headphone_jack_pins));
1612 		if (ret) {
1613 			dev_err(rtd->dev,
1614 				"Headphone jack creation failed: %d\n", ret);
1615 			return ret;
1616 		}
1617 
1618 		sun4i_headphone_jack_gpio.desc = scodec->gpio_hp;
1619 		ret = snd_soc_jack_add_gpios(&sun4i_headphone_jack, 1,
1620 					     &sun4i_headphone_jack_gpio);
1621 
1622 		if (ret) {
1623 			dev_err(rtd->dev, "Headphone GPIO not added: %d\n", ret);
1624 			return ret;
1625 		}
1626 	}
1627 
1628 	return 0;
1629 }
1630 
sun4i_codec_create_link(struct device * dev,int * num_links)1631 static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev,
1632 							int *num_links)
1633 {
1634 	struct snd_soc_dai_link *link = devm_kzalloc(dev, sizeof(*link),
1635 						     GFP_KERNEL);
1636 	struct snd_soc_dai_link_component *dlc = devm_kzalloc(dev,
1637 						3 * sizeof(*dlc), GFP_KERNEL);
1638 	if (!link || !dlc)
1639 		return NULL;
1640 
1641 	link->cpus	= &dlc[0];
1642 	link->codecs	= &dlc[1];
1643 	link->platforms	= &dlc[2];
1644 
1645 	link->num_cpus		= 1;
1646 	link->num_codecs	= 1;
1647 	link->num_platforms	= 1;
1648 
1649 	link->name		= "cdc";
1650 	link->stream_name	= "CDC PCM";
1651 	link->codecs->dai_name	= "Codec";
1652 	link->cpus->dai_name	= dev_name(dev);
1653 	link->codecs->name	= dev_name(dev);
1654 	link->platforms->name	= dev_name(dev);
1655 	link->dai_fmt		= SND_SOC_DAIFMT_I2S;
1656 	link->init		= sun4i_codec_machine_init;
1657 
1658 	*num_links = 1;
1659 
1660 	return link;
1661 };
1662 
sun4i_codec_spk_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * k,int event)1663 static int sun4i_codec_spk_event(struct snd_soc_dapm_widget *w,
1664 				 struct snd_kcontrol *k, int event)
1665 {
1666 	struct sun4i_codec *scodec = snd_soc_card_get_drvdata(w->dapm->card);
1667 
1668 	gpiod_set_value_cansleep(scodec->gpio_pa,
1669 				 !!SND_SOC_DAPM_EVENT_ON(event));
1670 
1671 	if (SND_SOC_DAPM_EVENT_ON(event)) {
1672 		/*
1673 		 * Need a delay to wait for DAC to push the data. 700ms seems
1674 		 * to be the best compromise not to feel this delay while
1675 		 * playing a sound.
1676 		 */
1677 		msleep(700);
1678 	}
1679 
1680 	return 0;
1681 }
1682 
1683 static const struct snd_soc_dapm_widget sun4i_codec_card_dapm_widgets[] = {
1684 	SND_SOC_DAPM_SPK("Speaker", sun4i_codec_spk_event),
1685 };
1686 
1687 static const struct snd_soc_dapm_route sun4i_codec_card_dapm_routes[] = {
1688 	{ "Speaker", NULL, "HP Right" },
1689 	{ "Speaker", NULL, "HP Left" },
1690 };
1691 
sun4i_codec_create_card(struct device * dev)1692 static struct snd_soc_card *sun4i_codec_create_card(struct device *dev)
1693 {
1694 	struct snd_soc_card *card;
1695 
1696 	card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
1697 	if (!card)
1698 		return ERR_PTR(-ENOMEM);
1699 
1700 	card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
1701 	if (!card->dai_link)
1702 		return ERR_PTR(-ENOMEM);
1703 
1704 	card->dev		= dev;
1705 	card->owner		= THIS_MODULE;
1706 	card->name		= "sun4i-codec";
1707 	card->dapm_widgets	= sun4i_codec_card_dapm_widgets;
1708 	card->num_dapm_widgets	= ARRAY_SIZE(sun4i_codec_card_dapm_widgets);
1709 	card->dapm_routes	= sun4i_codec_card_dapm_routes;
1710 	card->num_dapm_routes	= ARRAY_SIZE(sun4i_codec_card_dapm_routes);
1711 
1712 	return card;
1713 };
1714 
1715 static const struct snd_soc_dapm_widget sun6i_codec_card_dapm_widgets[] = {
1716 	SND_SOC_DAPM_HP("Headphone", NULL),
1717 	SND_SOC_DAPM_LINE("Line In", NULL),
1718 	SND_SOC_DAPM_LINE("Line Out", NULL),
1719 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
1720 	SND_SOC_DAPM_MIC("Mic", NULL),
1721 	SND_SOC_DAPM_SPK("Speaker", sun4i_codec_spk_event),
1722 };
1723 
sun6i_codec_create_card(struct device * dev)1724 static struct snd_soc_card *sun6i_codec_create_card(struct device *dev)
1725 {
1726 	struct snd_soc_card *card;
1727 	int ret;
1728 
1729 	card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
1730 	if (!card)
1731 		return ERR_PTR(-ENOMEM);
1732 
1733 	card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
1734 	if (!card->dai_link)
1735 		return ERR_PTR(-ENOMEM);
1736 
1737 	card->dev		= dev;
1738 	card->owner		= THIS_MODULE;
1739 	card->name		= "A31 Audio Codec";
1740 	card->dapm_widgets	= sun6i_codec_card_dapm_widgets;
1741 	card->num_dapm_widgets	= ARRAY_SIZE(sun6i_codec_card_dapm_widgets);
1742 	card->fully_routed	= true;
1743 
1744 	ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing");
1745 	if (ret)
1746 		dev_warn(dev, "failed to parse audio-routing: %d\n", ret);
1747 
1748 	return card;
1749 };
1750 
1751 /* Connect digital side enables to analog side widgets */
1752 static const struct snd_soc_dapm_route sun8i_codec_card_routes[] = {
1753 	/* ADC Routes */
1754 	{ "Left ADC", NULL, "ADC Enable" },
1755 	{ "Right ADC", NULL, "ADC Enable" },
1756 	{ "Codec Capture", NULL, "Left ADC" },
1757 	{ "Codec Capture", NULL, "Right ADC" },
1758 
1759 	/* DAC Routes */
1760 	{ "Left DAC", NULL, "DAC Enable" },
1761 	{ "Right DAC", NULL, "DAC Enable" },
1762 	{ "Left DAC", NULL, "Codec Playback" },
1763 	{ "Right DAC", NULL, "Codec Playback" },
1764 };
1765 
1766 static struct snd_soc_aux_dev aux_dev = {
1767 	.dlc = COMP_EMPTY(),
1768 };
1769 
sun8i_a23_codec_create_card(struct device * dev)1770 static struct snd_soc_card *sun8i_a23_codec_create_card(struct device *dev)
1771 {
1772 	struct snd_soc_card *card;
1773 	int ret;
1774 
1775 	card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
1776 	if (!card)
1777 		return ERR_PTR(-ENOMEM);
1778 
1779 	aux_dev.dlc.of_node = of_parse_phandle(dev->of_node,
1780 						 "allwinner,codec-analog-controls",
1781 						 0);
1782 	if (!aux_dev.dlc.of_node) {
1783 		dev_err(dev, "Can't find analog controls for codec.\n");
1784 		return ERR_PTR(-EINVAL);
1785 	}
1786 
1787 	card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
1788 	if (!card->dai_link)
1789 		return ERR_PTR(-ENOMEM);
1790 
1791 	card->dev		= dev;
1792 	card->owner		= THIS_MODULE;
1793 	card->name		= "A23 Audio Codec";
1794 	card->dapm_widgets	= sun6i_codec_card_dapm_widgets;
1795 	card->num_dapm_widgets	= ARRAY_SIZE(sun6i_codec_card_dapm_widgets);
1796 	card->dapm_routes	= sun8i_codec_card_routes;
1797 	card->num_dapm_routes	= ARRAY_SIZE(sun8i_codec_card_routes);
1798 	card->aux_dev		= &aux_dev;
1799 	card->num_aux_devs	= 1;
1800 	card->fully_routed	= true;
1801 
1802 	ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing");
1803 	if (ret)
1804 		dev_warn(dev, "failed to parse audio-routing: %d\n", ret);
1805 
1806 	return card;
1807 };
1808 
sun8i_h3_codec_create_card(struct device * dev)1809 static struct snd_soc_card *sun8i_h3_codec_create_card(struct device *dev)
1810 {
1811 	struct snd_soc_card *card;
1812 	int ret;
1813 
1814 	card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
1815 	if (!card)
1816 		return ERR_PTR(-ENOMEM);
1817 
1818 	aux_dev.dlc.of_node = of_parse_phandle(dev->of_node,
1819 						 "allwinner,codec-analog-controls",
1820 						 0);
1821 	if (!aux_dev.dlc.of_node) {
1822 		dev_err(dev, "Can't find analog controls for codec.\n");
1823 		return ERR_PTR(-EINVAL);
1824 	}
1825 
1826 	card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
1827 	if (!card->dai_link)
1828 		return ERR_PTR(-ENOMEM);
1829 
1830 	card->dev		= dev;
1831 	card->owner		= THIS_MODULE;
1832 	card->name		= "H3 Audio Codec";
1833 	card->dapm_widgets	= sun6i_codec_card_dapm_widgets;
1834 	card->num_dapm_widgets	= ARRAY_SIZE(sun6i_codec_card_dapm_widgets);
1835 	card->dapm_routes	= sun8i_codec_card_routes;
1836 	card->num_dapm_routes	= ARRAY_SIZE(sun8i_codec_card_routes);
1837 	card->aux_dev		= &aux_dev;
1838 	card->num_aux_devs	= 1;
1839 	card->fully_routed	= true;
1840 
1841 	ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing");
1842 	if (ret)
1843 		dev_warn(dev, "failed to parse audio-routing: %d\n", ret);
1844 
1845 	return card;
1846 };
1847 
sun8i_v3s_codec_create_card(struct device * dev)1848 static struct snd_soc_card *sun8i_v3s_codec_create_card(struct device *dev)
1849 {
1850 	struct snd_soc_card *card;
1851 	int ret;
1852 
1853 	card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
1854 	if (!card)
1855 		return ERR_PTR(-ENOMEM);
1856 
1857 	aux_dev.dlc.of_node = of_parse_phandle(dev->of_node,
1858 						 "allwinner,codec-analog-controls",
1859 						 0);
1860 	if (!aux_dev.dlc.of_node) {
1861 		dev_err(dev, "Can't find analog controls for codec.\n");
1862 		return ERR_PTR(-EINVAL);
1863 	}
1864 
1865 	card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
1866 	if (!card->dai_link)
1867 		return ERR_PTR(-ENOMEM);
1868 
1869 	card->dev		= dev;
1870 	card->owner		= THIS_MODULE;
1871 	card->name		= "V3s Audio Codec";
1872 	card->dapm_widgets	= sun6i_codec_card_dapm_widgets;
1873 	card->num_dapm_widgets	= ARRAY_SIZE(sun6i_codec_card_dapm_widgets);
1874 	card->dapm_routes	= sun8i_codec_card_routes;
1875 	card->num_dapm_routes	= ARRAY_SIZE(sun8i_codec_card_routes);
1876 	card->aux_dev		= &aux_dev;
1877 	card->num_aux_devs	= 1;
1878 	card->fully_routed	= true;
1879 
1880 	ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing");
1881 	if (ret)
1882 		dev_warn(dev, "failed to parse audio-routing: %d\n", ret);
1883 
1884 	return card;
1885 };
1886 
1887 static const struct snd_kcontrol_new sun50i_h616_codec_codec_controls[] = {
1888 	SOC_SINGLE_TLV("DAC Playback Volume", SUN4I_CODEC_DAC_DPC,
1889 		       SUN4I_CODEC_DAC_DPC_DVOL, 0x3f, 1,
1890 		       sun6i_codec_dvol_scale),
1891 	SOC_SINGLE_TLV("Line Out Playback Volume",
1892 		       SUN50I_H616_DAC_AC_DAC_REG,
1893 		       SUN50I_H616_LINEOUT_VOL, 0x1f, 0,
1894 		       sun6i_codec_lineout_vol_scale),
1895 	SOC_DOUBLE("Line Out Playback Switch",
1896 		   SUN50I_H616_DAC_AC_DAC_REG,
1897 		   SUN50I_H616_LINEOUTL_EN,
1898 		   SUN50I_H616_LINEOUTR_EN, 1, 0),
1899 };
1900 
1901 static const struct snd_kcontrol_new sun50i_h616_codec_mixer_controls[] = {
1902 	SOC_DAPM_DOUBLE("DAC Playback Switch",
1903 			SUN50I_H616_DAC_AC_MIXER_REG,
1904 			SUN50I_H616_LMIX_LDAC,
1905 			SUN50I_H616_RMIX_RDAC, 1, 0),
1906 	SOC_DAPM_DOUBLE("DAC Reversed Playback Switch",
1907 			SUN50I_H616_DAC_AC_MIXER_REG,
1908 			SUN50I_H616_LMIX_RDAC,
1909 			SUN50I_H616_RMIX_LDAC, 1, 0),
1910 };
1911 
1912 static SOC_ENUM_DOUBLE_DECL(sun50i_h616_codec_lineout_src_enum,
1913 			    SUN50I_H616_DAC_AC_DAC_REG,
1914 			    SUN50I_H616_LINEOUTL_SEL,
1915 			    SUN50I_H616_LINEOUTR_SEL,
1916 			    sun6i_codec_lineout_src_enum_text);
1917 
1918 static const struct snd_kcontrol_new sun50i_h616_codec_lineout_src[] = {
1919 		SOC_DAPM_ENUM("Line Out Source Playback Route",
1920 			      sun50i_h616_codec_lineout_src_enum),
1921 };
1922 
1923 static const struct snd_soc_dapm_widget sun50i_h616_codec_codec_widgets[] = {
1924 	/* Digital parts of the DACs */
1925 	SND_SOC_DAPM_SUPPLY("DAC Enable", SUN4I_CODEC_DAC_DPC,
1926 			    SUN4I_CODEC_DAC_DPC_EN_DA, 0,
1927 			    NULL, 0),
1928 
1929 	/* Analog parts of the DACs */
1930 	SND_SOC_DAPM_DAC("Left DAC", "Codec Playback",
1931 			 SUN50I_H616_DAC_AC_DAC_REG,
1932 			 SUN50I_H616_DAC_LEN, 0),
1933 	SND_SOC_DAPM_DAC("Right DAC", "Codec Playback",
1934 			 SUN50I_H616_DAC_AC_DAC_REG,
1935 			 SUN50I_H616_DAC_REN, 0),
1936 
1937 	/* Mixers */
1938 	SOC_MIXER_ARRAY("Left Mixer", SUN50I_H616_DAC_AC_MIXER_REG,
1939 			SUN50I_H616_LMIXEN, 0,
1940 			sun50i_h616_codec_mixer_controls),
1941 	SOC_MIXER_ARRAY("Right Mixer", SUN50I_H616_DAC_AC_MIXER_REG,
1942 			SUN50I_H616_RMIXEN, 0,
1943 			sun50i_h616_codec_mixer_controls),
1944 
1945 	/* Line Out path */
1946 	SND_SOC_DAPM_MUX("Line Out Source Playback Route",
1947 			 SND_SOC_NOPM, 0, 0, sun50i_h616_codec_lineout_src),
1948 	SND_SOC_DAPM_OUT_DRV("Line Out Ramp Controller",
1949 			     SUN50I_H616_DAC_AC_RAMP_REG,
1950 			     SUN50I_H616_RDEN, 0, NULL, 0),
1951 	SND_SOC_DAPM_OUTPUT("LINEOUT"),
1952 };
1953 
1954 static const struct snd_soc_component_driver sun50i_h616_codec_codec = {
1955 	.controls   = sun50i_h616_codec_codec_controls,
1956 	.num_controls   = ARRAY_SIZE(sun50i_h616_codec_codec_controls),
1957 	.dapm_widgets   = sun50i_h616_codec_codec_widgets,
1958 	.num_dapm_widgets = ARRAY_SIZE(sun50i_h616_codec_codec_widgets),
1959 	.idle_bias_on   = 1,
1960 	.use_pmdown_time  = 1,
1961 	.endianness   = 1,
1962 };
1963 
1964 static const struct snd_kcontrol_new sun50i_h616_card_controls[] = {
1965 	SOC_DAPM_PIN_SWITCH("Speaker"),
1966 };
1967 
1968 static const struct snd_soc_dapm_widget sun50i_h616_codec_card_dapm_widgets[] = {
1969 	SND_SOC_DAPM_HP("Headphone", NULL),
1970 	SND_SOC_DAPM_LINE("Line Out", NULL),
1971 	SND_SOC_DAPM_SPK("Speaker", sun4i_codec_spk_event),
1972 };
1973 
1974 /* Connect digital side enables to analog side widgets */
1975 static const struct snd_soc_dapm_route sun50i_h616_codec_card_routes[] = {
1976 	/* DAC Routes */
1977 	{ "Left DAC", NULL, "DAC Enable" },
1978 	{ "Right DAC", NULL, "DAC Enable" },
1979 
1980 	/* Left Mixer Routes */
1981 	{ "Left Mixer", "DAC Playback Switch", "Left DAC" },
1982 	{ "Left Mixer", "DAC Reversed Playback Switch", "Right DAC" },
1983 
1984 	/* Right Mixer Routes */
1985 	{ "Right Mixer", "DAC Playback Switch", "Right DAC" },
1986 	{ "Right Mixer", "DAC Reversed Playback Switch", "Left DAC" },
1987 
1988 	/* Line Out Routes */
1989 	{ "Line Out Source Playback Route", "Stereo", "Left Mixer" },
1990 	{ "Line Out Source Playback Route", "Stereo", "Right Mixer" },
1991 	{ "Line Out Source Playback Route", "Mono Differential", "Left Mixer" },
1992 	{ "Line Out Source Playback Route", "Mono Differential", "Right Mixer" },
1993 	{ "Line Out Ramp Controller", NULL, "Line Out Source Playback Route" },
1994 	{ "LINEOUT", NULL, "Line Out Ramp Controller" },
1995 };
1996 
sun50i_h616_codec_create_card(struct device * dev)1997 static struct snd_soc_card *sun50i_h616_codec_create_card(struct device *dev)
1998 {
1999 	struct snd_soc_card *card;
2000 	int ret;
2001 
2002 	card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
2003 	if (!card)
2004 		return ERR_PTR(-ENOMEM);
2005 
2006 	card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
2007 	if (!card->dai_link)
2008 		return ERR_PTR(-ENOMEM);
2009 
2010 	card->dai_link->playback_only = true;
2011 	card->dai_link->capture_only = false;
2012 
2013 	card->dev		= dev;
2014 	card->owner		= THIS_MODULE;
2015 	card->name		= "H616 Audio Codec";
2016 	card->long_name		= "h616-audio-codec";
2017 	card->driver_name	= "sun4i-codec";
2018 	card->controls		= sun50i_h616_card_controls;
2019 	card->num_controls	= ARRAY_SIZE(sun50i_h616_card_controls);
2020 	card->dapm_widgets	= sun50i_h616_codec_card_dapm_widgets;
2021 	card->num_dapm_widgets	= ARRAY_SIZE(sun50i_h616_codec_card_dapm_widgets);
2022 	card->dapm_routes	= sun50i_h616_codec_card_routes;
2023 	card->num_dapm_routes	= ARRAY_SIZE(sun50i_h616_codec_card_routes);
2024 	card->fully_routed	= true;
2025 
2026 	ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing");
2027 	if (ret)
2028 		dev_warn(dev, "failed to parse audio-routing: %d\n", ret);
2029 
2030 	return card;
2031 };
2032 
2033 static const struct snd_soc_dapm_widget suniv_codec_card_dapm_widgets[] = {
2034 	SND_SOC_DAPM_HP("Headphone", NULL),
2035 	SND_SOC_DAPM_LINE("Line In", NULL),
2036 	SND_SOC_DAPM_LINE("Right FM In", NULL),
2037 	SND_SOC_DAPM_LINE("Left FM In", NULL),
2038 	SND_SOC_DAPM_MIC("Mic", NULL),
2039 	SND_SOC_DAPM_SPK("Speaker", sun4i_codec_spk_event),
2040 };
2041 
2042 /* Connect digital side enables to analog side widgets */
2043 static const struct snd_soc_dapm_route suniv_codec_card_routes[] = {
2044 	/* ADC Routes */
2045 	{ "ADC", NULL, "ADC Enable" },
2046 	{ "Codec Capture", NULL, "ADC" },
2047 
2048 	/* DAC Routes */
2049 	{ "Left DAC", NULL, "DAC Enable" },
2050 	{ "Right DAC", NULL, "DAC Enable" },
2051 	{ "Left DAC", NULL, "Codec Playback" },
2052 	{ "Right DAC", NULL, "Codec Playback" },
2053 };
2054 
suniv_codec_create_card(struct device * dev)2055 static struct snd_soc_card *suniv_codec_create_card(struct device *dev)
2056 {
2057 	struct snd_soc_card *card;
2058 	int ret;
2059 
2060 	card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
2061 	if (!card)
2062 		return ERR_PTR(-ENOMEM);
2063 
2064 	card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
2065 	if (!card->dai_link)
2066 		return ERR_PTR(-ENOMEM);
2067 
2068 	card->dev		= dev;
2069 	card->name		= "F1C100s Audio Codec";
2070 	card->dapm_widgets	= suniv_codec_card_dapm_widgets;
2071 	card->num_dapm_widgets	= ARRAY_SIZE(suniv_codec_card_dapm_widgets);
2072 	card->dapm_routes	= suniv_codec_card_routes;
2073 	card->num_dapm_routes	= ARRAY_SIZE(suniv_codec_card_routes);
2074 	card->fully_routed	= true;
2075 
2076 	ret = snd_soc_of_parse_audio_routing(card, "allwinner,audio-routing");
2077 	if (ret)
2078 		dev_warn(dev, "failed to parse audio-routing: %d\n", ret);
2079 
2080 	return card;
2081 };
2082 
2083 static const struct regmap_config sun4i_codec_regmap_config = {
2084 	.reg_bits	= 32,
2085 	.reg_stride	= 4,
2086 	.val_bits	= 32,
2087 	.max_register	= SUN4I_CODEC_ADC_RXCNT,
2088 };
2089 
2090 static const struct regmap_config sun6i_codec_regmap_config = {
2091 	.reg_bits	= 32,
2092 	.reg_stride	= 4,
2093 	.val_bits	= 32,
2094 	.max_register	= SUN6I_CODEC_HMIC_DATA,
2095 };
2096 
2097 static const struct regmap_config sun7i_codec_regmap_config = {
2098 	.reg_bits	= 32,
2099 	.reg_stride	= 4,
2100 	.val_bits	= 32,
2101 	.max_register	= SUN7I_CODEC_AC_MIC_PHONE_CAL,
2102 };
2103 
2104 static const struct regmap_config sun8i_a23_codec_regmap_config = {
2105 	.reg_bits	= 32,
2106 	.reg_stride	= 4,
2107 	.val_bits	= 32,
2108 	.max_register	= SUN8I_A23_CODEC_ADC_RXCNT,
2109 };
2110 
2111 static const struct regmap_config sun8i_h3_codec_regmap_config = {
2112 	.reg_bits	= 32,
2113 	.reg_stride	= 4,
2114 	.val_bits	= 32,
2115 	.max_register	= SUN8I_H3_CODEC_ADC_DBG,
2116 };
2117 
2118 static const struct regmap_config sun8i_v3s_codec_regmap_config = {
2119 	.reg_bits	= 32,
2120 	.reg_stride	= 4,
2121 	.val_bits	= 32,
2122 	.max_register	= SUN8I_H3_CODEC_ADC_DBG,
2123 };
2124 
2125 static const struct regmap_config sun50i_h616_codec_regmap_config = {
2126 	.reg_bits	= 32,
2127 	.reg_stride	= 4,
2128 	.val_bits	= 32,
2129 	.max_register	= SUN50I_H616_DAC_AC_RAMP_REG,
2130 	.cache_type	= REGCACHE_NONE,
2131 };
2132 
2133 static const struct regmap_config suniv_codec_regmap_config = {
2134 	.reg_bits	= 32,
2135 	.reg_stride	= 4,
2136 	.val_bits	= 32,
2137 	.max_register	= SUNIV_CODEC_ADC_DBG,
2138 };
2139 
2140 struct sun4i_codec_quirks {
2141 	const struct regmap_config *regmap_config;
2142 	const struct snd_soc_component_driver *codec;
2143 	struct snd_soc_card * (*create_card)(struct device *dev);
2144 	struct reg_field reg_adc_fifoc;	/* used for regmap_field */
2145 	struct reg_field reg_dac_fifoc;	/* used for regmap_field */
2146 	unsigned int reg_dac_txdata;	/* TX FIFO offset for DMA config */
2147 	unsigned int reg_adc_rxdata;	/* RX FIFO offset for DMA config */
2148 	bool has_reset;
2149 	bool playback_only;
2150 	u32 dma_max_burst;
2151 };
2152 
2153 static const struct sun4i_codec_quirks sun4i_codec_quirks = {
2154 	.regmap_config	= &sun4i_codec_regmap_config,
2155 	.codec		= &sun4i_codec_codec,
2156 	.create_card	= sun4i_codec_create_card,
2157 	.reg_adc_fifoc	= REG_FIELD(SUN4I_CODEC_ADC_FIFOC, 0, 31),
2158 	.reg_dac_fifoc	= REG_FIELD(SUN4I_CODEC_DAC_FIFOC, 0, 31),
2159 	.reg_dac_txdata	= SUN4I_CODEC_DAC_TXDATA,
2160 	.reg_adc_rxdata	= SUN4I_CODEC_ADC_RXDATA,
2161 	.dma_max_burst	= SUN4I_DMA_MAX_BURST,
2162 };
2163 
2164 static const struct sun4i_codec_quirks sun6i_a31_codec_quirks = {
2165 	.regmap_config	= &sun6i_codec_regmap_config,
2166 	.codec		= &sun6i_codec_codec,
2167 	.create_card	= sun6i_codec_create_card,
2168 	.reg_adc_fifoc	= REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31),
2169 	.reg_dac_fifoc	= REG_FIELD(SUN4I_CODEC_DAC_FIFOC, 0, 31),
2170 	.reg_dac_txdata	= SUN4I_CODEC_DAC_TXDATA,
2171 	.reg_adc_rxdata	= SUN6I_CODEC_ADC_RXDATA,
2172 	.has_reset	= true,
2173 	.dma_max_burst	= SUN4I_DMA_MAX_BURST,
2174 };
2175 
2176 static const struct sun4i_codec_quirks sun7i_codec_quirks = {
2177 	.regmap_config	= &sun7i_codec_regmap_config,
2178 	.codec		= &sun7i_codec_codec,
2179 	.create_card	= sun4i_codec_create_card,
2180 	.reg_adc_fifoc	= REG_FIELD(SUN4I_CODEC_ADC_FIFOC, 0, 31),
2181 	.reg_dac_fifoc	= REG_FIELD(SUN4I_CODEC_DAC_FIFOC, 0, 31),
2182 	.reg_dac_txdata	= SUN4I_CODEC_DAC_TXDATA,
2183 	.reg_adc_rxdata	= SUN4I_CODEC_ADC_RXDATA,
2184 	.dma_max_burst	= SUN4I_DMA_MAX_BURST,
2185 };
2186 
2187 static const struct sun4i_codec_quirks sun8i_a23_codec_quirks = {
2188 	.regmap_config	= &sun8i_a23_codec_regmap_config,
2189 	.codec		= &sun8i_a23_codec_codec,
2190 	.create_card	= sun8i_a23_codec_create_card,
2191 	.reg_adc_fifoc	= REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31),
2192 	.reg_dac_fifoc	= REG_FIELD(SUN4I_CODEC_DAC_FIFOC, 0, 31),
2193 	.reg_dac_txdata	= SUN4I_CODEC_DAC_TXDATA,
2194 	.reg_adc_rxdata	= SUN6I_CODEC_ADC_RXDATA,
2195 	.has_reset	= true,
2196 	.dma_max_burst	= SUN4I_DMA_MAX_BURST,
2197 };
2198 
2199 static const struct sun4i_codec_quirks sun8i_h3_codec_quirks = {
2200 	.regmap_config	= &sun8i_h3_codec_regmap_config,
2201 	/*
2202 	 * TODO Share the codec structure with A23 for now.
2203 	 * This should be split out when adding digital audio
2204 	 * processing support for the H3.
2205 	 */
2206 	.codec		= &sun8i_a23_codec_codec,
2207 	.create_card	= sun8i_h3_codec_create_card,
2208 	.reg_adc_fifoc	= REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31),
2209 	.reg_dac_fifoc	= REG_FIELD(SUN4I_CODEC_DAC_FIFOC, 0, 31),
2210 	.reg_dac_txdata	= SUN8I_H3_CODEC_DAC_TXDATA,
2211 	.reg_adc_rxdata	= SUN6I_CODEC_ADC_RXDATA,
2212 	.has_reset	= true,
2213 	.dma_max_burst	= SUN4I_DMA_MAX_BURST,
2214 };
2215 
2216 static const struct sun4i_codec_quirks sun8i_v3s_codec_quirks = {
2217 	.regmap_config	= &sun8i_v3s_codec_regmap_config,
2218 	/*
2219 	 * TODO The codec structure should be split out, like
2220 	 * H3, when adding digital audio processing support.
2221 	 */
2222 	.codec		= &sun8i_a23_codec_codec,
2223 	.create_card	= sun8i_v3s_codec_create_card,
2224 	.reg_adc_fifoc	= REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31),
2225 	.reg_dac_fifoc	= REG_FIELD(SUN4I_CODEC_DAC_FIFOC, 0, 31),
2226 	.reg_dac_txdata	= SUN8I_H3_CODEC_DAC_TXDATA,
2227 	.reg_adc_rxdata	= SUN6I_CODEC_ADC_RXDATA,
2228 	.has_reset	= true,
2229 	.dma_max_burst	= SUN4I_DMA_MAX_BURST,
2230 };
2231 
2232 static const struct sun4i_codec_quirks sun50i_h616_codec_quirks = {
2233 	.regmap_config	= &sun50i_h616_codec_regmap_config,
2234 	.codec		= &sun50i_h616_codec_codec,
2235 	.create_card	= sun50i_h616_codec_create_card,
2236 	.reg_dac_fifoc	= REG_FIELD(SUN50I_H616_CODEC_DAC_FIFOC, 0, 31),
2237 	.reg_dac_txdata	= SUN8I_H3_CODEC_DAC_TXDATA,
2238 	.has_reset	= true,
2239 	.dma_max_burst	= SUN4I_DMA_MAX_BURST,
2240 };
2241 
2242 static const struct sun4i_codec_quirks suniv_f1c100s_codec_quirks = {
2243 	.regmap_config	= &suniv_codec_regmap_config,
2244 	.codec		= &suniv_codec_codec,
2245 	.create_card	= suniv_codec_create_card,
2246 	.reg_adc_fifoc	= REG_FIELD(SUNIV_CODEC_ADC_FIFOC, 0, 31),
2247 	.reg_dac_fifoc	= REG_FIELD(SUN4I_CODEC_DAC_FIFOC, 0, 31),
2248 	.reg_dac_txdata	= SUN4I_CODEC_DAC_TXDATA,
2249 	.reg_adc_rxdata	= SUNIV_CODEC_ADC_RXDATA,
2250 	.has_reset	= true,
2251 	.dma_max_burst	= SUNIV_DMA_MAX_BURST,
2252 };
2253 
2254 static const struct of_device_id sun4i_codec_of_match[] = {
2255 	{
2256 		.compatible = "allwinner,sun4i-a10-codec",
2257 		.data = &sun4i_codec_quirks,
2258 	},
2259 	{
2260 		.compatible = "allwinner,sun6i-a31-codec",
2261 		.data = &sun6i_a31_codec_quirks,
2262 	},
2263 	{
2264 		.compatible = "allwinner,sun7i-a20-codec",
2265 		.data = &sun7i_codec_quirks,
2266 	},
2267 	{
2268 		.compatible = "allwinner,sun8i-a23-codec",
2269 		.data = &sun8i_a23_codec_quirks,
2270 	},
2271 	{
2272 		.compatible = "allwinner,sun8i-h3-codec",
2273 		.data = &sun8i_h3_codec_quirks,
2274 	},
2275 	{
2276 		.compatible = "allwinner,sun8i-v3s-codec",
2277 		.data = &sun8i_v3s_codec_quirks,
2278 	},
2279 	{
2280 		.compatible = "allwinner,sun50i-h616-codec",
2281 		.data = &sun50i_h616_codec_quirks,
2282 	},
2283 	{
2284 		.compatible = "allwinner,suniv-f1c100s-codec",
2285 		.data = &suniv_f1c100s_codec_quirks,
2286 	},
2287 	{}
2288 };
2289 MODULE_DEVICE_TABLE(of, sun4i_codec_of_match);
2290 
sun4i_codec_probe(struct platform_device * pdev)2291 static int sun4i_codec_probe(struct platform_device *pdev)
2292 {
2293 	struct snd_soc_card *card;
2294 	struct sun4i_codec *scodec;
2295 	const struct sun4i_codec_quirks *quirks;
2296 	struct resource *res;
2297 	void __iomem *base;
2298 	int ret;
2299 
2300 	scodec = devm_kzalloc(&pdev->dev, sizeof(*scodec), GFP_KERNEL);
2301 	if (!scodec)
2302 		return -ENOMEM;
2303 
2304 	scodec->dev = &pdev->dev;
2305 
2306 	base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
2307 	if (IS_ERR(base))
2308 		return PTR_ERR(base);
2309 
2310 	quirks = of_device_get_match_data(&pdev->dev);
2311 	if (quirks == NULL) {
2312 		dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
2313 		return -ENODEV;
2314 	}
2315 
2316 	scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base,
2317 					       quirks->regmap_config);
2318 	if (IS_ERR(scodec->regmap)) {
2319 		dev_err(&pdev->dev, "Failed to create our regmap\n");
2320 		return PTR_ERR(scodec->regmap);
2321 	}
2322 
2323 	/* Get the clocks from the DT */
2324 	scodec->clk_apb = devm_clk_get_enabled(&pdev->dev, "apb");
2325 	if (IS_ERR(scodec->clk_apb)) {
2326 		dev_err(&pdev->dev, "Failed to get the APB clock\n");
2327 		return PTR_ERR(scodec->clk_apb);
2328 	}
2329 
2330 	scodec->clk_module = devm_clk_get(&pdev->dev, "codec");
2331 	if (IS_ERR(scodec->clk_module)) {
2332 		dev_err(&pdev->dev, "Failed to get the module clock\n");
2333 		return PTR_ERR(scodec->clk_module);
2334 	}
2335 
2336 	if (quirks->has_reset) {
2337 		scodec->rst = devm_reset_control_get_exclusive_deasserted(&pdev->dev, NULL);
2338 		if (IS_ERR(scodec->rst)) {
2339 			dev_err(&pdev->dev, "Failed to get reset control\n");
2340 			return PTR_ERR(scodec->rst);
2341 		}
2342 	}
2343 
2344 	scodec->gpio_pa = devm_gpiod_get_optional(&pdev->dev, "allwinner,pa",
2345 						  GPIOD_OUT_LOW);
2346 	if (IS_ERR(scodec->gpio_pa)) {
2347 		ret = PTR_ERR(scodec->gpio_pa);
2348 		dev_err_probe(&pdev->dev, ret, "Failed to get pa gpio\n");
2349 		return ret;
2350 	}
2351 
2352 	scodec->gpio_hp = devm_gpiod_get_optional(&pdev->dev, "hp-det", GPIOD_IN);
2353 	if (IS_ERR(scodec->gpio_hp)) {
2354 		ret = PTR_ERR(scodec->gpio_hp);
2355 		dev_err_probe(&pdev->dev, ret, "Failed to get hp-det gpio\n");
2356 		return ret;
2357 	}
2358 
2359 	/* reg_field setup */
2360 	scodec->reg_adc_fifoc = devm_regmap_field_alloc(&pdev->dev,
2361 							scodec->regmap,
2362 							quirks->reg_adc_fifoc);
2363 	if (IS_ERR(scodec->reg_adc_fifoc)) {
2364 		ret = PTR_ERR(scodec->reg_adc_fifoc);
2365 		dev_err(&pdev->dev, "Failed to create regmap fields: %d\n",
2366 			ret);
2367 		return ret;
2368 	}
2369 
2370 	scodec->reg_dac_fifoc = devm_regmap_field_alloc(&pdev->dev,
2371 							scodec->regmap,
2372 							quirks->reg_dac_fifoc);
2373 	if (IS_ERR(scodec->reg_dac_fifoc)) {
2374 		ret = PTR_ERR(scodec->reg_dac_fifoc);
2375 		dev_err(&pdev->dev, "Failed to create regmap fields: %d\n",
2376 			ret);
2377 		return ret;
2378 	}
2379 
2380 	/* DMA configuration for TX FIFO */
2381 	scodec->playback_dma_data.addr = res->start + quirks->reg_dac_txdata;
2382 	scodec->playback_dma_data.maxburst = quirks->dma_max_burst;
2383 	scodec->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
2384 
2385 	if (!quirks->playback_only) {
2386 		/* DMA configuration for RX FIFO */
2387 		scodec->capture_dma_data.addr = res->start +
2388 						quirks->reg_adc_rxdata;
2389 		scodec->capture_dma_data.maxburst = quirks->dma_max_burst;
2390 		scodec->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
2391 	}
2392 
2393 	ret = devm_snd_soc_register_component(&pdev->dev, quirks->codec,
2394 				     &sun4i_codec_dai, 1);
2395 	if (ret) {
2396 		dev_err(&pdev->dev, "Failed to register our codec\n");
2397 		return ret;
2398 	}
2399 
2400 	ret = devm_snd_soc_register_component(&pdev->dev,
2401 					      &sun4i_codec_component,
2402 					      &dummy_cpu_dai, 1);
2403 	if (ret) {
2404 		dev_err(&pdev->dev, "Failed to register our DAI\n");
2405 		return ret;
2406 	}
2407 
2408 	ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
2409 	if (ret) {
2410 		dev_err(&pdev->dev, "Failed to register against DMAEngine\n");
2411 		return ret;
2412 	}
2413 
2414 	card = quirks->create_card(&pdev->dev);
2415 	if (IS_ERR(card)) {
2416 		ret = PTR_ERR(card);
2417 		dev_err(&pdev->dev, "Failed to create our card\n");
2418 		return ret;
2419 	}
2420 
2421 	snd_soc_card_set_drvdata(card, scodec);
2422 
2423 	ret = snd_soc_register_card(card);
2424 	if (ret) {
2425 		dev_err_probe(&pdev->dev, ret, "Failed to register our card\n");
2426 		return ret;
2427 	}
2428 
2429 	return 0;
2430 }
2431 
sun4i_codec_remove(struct platform_device * pdev)2432 static void sun4i_codec_remove(struct platform_device *pdev)
2433 {
2434 	struct snd_soc_card *card = platform_get_drvdata(pdev);
2435 
2436 	snd_soc_unregister_card(card);
2437 }
2438 
2439 static struct platform_driver sun4i_codec_driver = {
2440 	.driver = {
2441 		.name = "sun4i-codec",
2442 		.of_match_table = sun4i_codec_of_match,
2443 	},
2444 	.probe = sun4i_codec_probe,
2445 	.remove = sun4i_codec_remove,
2446 };
2447 module_platform_driver(sun4i_codec_driver);
2448 
2449 MODULE_DESCRIPTION("Allwinner A10 codec driver");
2450 MODULE_AUTHOR("Emilio López <emilio@elopez.com.ar>");
2451 MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
2452 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
2453 MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
2454 MODULE_AUTHOR("Ryan Walklin <ryan@testtoast.com");
2455 MODULE_AUTHOR("Mesih Kilinc <mesikilinc@gmail.com>");
2456 MODULE_LICENSE("GPL");
2457