xref: /freebsd/sys/arm/allwinner/a10_codec.c (revision d0b2dbfa0ecf2bbc9709efc5e20baf8e4b44bbbf)
1 /*-
2  * Copyright (c) 2014-2016 Jared D. McNeill <jmcneill@invisible.ca>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
21  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 /*
28  * Allwinner A10/A20 and H3 Audio Codec
29  */
30 
31 #include <sys/cdefs.h>
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/bus.h>
35 #include <sys/rman.h>
36 #include <sys/condvar.h>
37 #include <sys/kernel.h>
38 #include <sys/module.h>
39 #include <sys/gpio.h>
40 
41 #include <machine/bus.h>
42 
43 #include <dev/sound/pcm/sound.h>
44 #include <dev/sound/chip.h>
45 
46 #include <dev/ofw/ofw_bus.h>
47 #include <dev/ofw/ofw_bus_subr.h>
48 
49 #include <dev/gpio/gpiobusvar.h>
50 
51 #include <dev/extres/clk/clk.h>
52 #include <dev/extres/hwreset/hwreset.h>
53 
54 #include "sunxi_dma_if.h"
55 #include "mixer_if.h"
56 
57 struct a10codec_info;
58 
59 struct a10codec_config {
60 	/* mixer class */
61 	struct kobj_class *mixer_class;
62 
63 	/* toggle DAC/ADC mute */
64 	void		(*mute)(struct a10codec_info *, int, int);
65 
66 	/* DRQ types */
67 	u_int		drqtype_codec;
68 	u_int		drqtype_sdram;
69 
70 	/* register map */
71 	bus_size_t	DPC,
72 			DAC_FIFOC,
73 			DAC_FIFOS,
74 			DAC_TXDATA,
75 			ADC_FIFOC,
76 			ADC_FIFOS,
77 			ADC_RXDATA,
78 			DAC_CNT,
79 			ADC_CNT;
80 };
81 
82 #define	TX_TRIG_LEVEL	0xf
83 #define	RX_TRIG_LEVEL	0x7
84 #define	DRQ_CLR_CNT	0x3
85 
86 #define	AC_DAC_DPC(_sc)		((_sc)->cfg->DPC)
87 #define	 DAC_DPC_EN_DA			0x80000000
88 #define	AC_DAC_FIFOC(_sc)	((_sc)->cfg->DAC_FIFOC)
89 #define	 DAC_FIFOC_FS_SHIFT		29
90 #define	 DAC_FIFOC_FS_MASK		(7U << DAC_FIFOC_FS_SHIFT)
91 #define	  DAC_FS_48KHZ			0
92 #define	  DAC_FS_32KHZ			1
93 #define	  DAC_FS_24KHZ			2
94 #define	  DAC_FS_16KHZ			3
95 #define	  DAC_FS_12KHZ			4
96 #define	  DAC_FS_8KHZ			5
97 #define	  DAC_FS_192KHZ			6
98 #define	  DAC_FS_96KHZ			7
99 #define	 DAC_FIFOC_FIFO_MODE_SHIFT	24
100 #define	 DAC_FIFOC_FIFO_MODE_MASK	(3U << DAC_FIFOC_FIFO_MODE_SHIFT)
101 #define	  FIFO_MODE_24_31_8		0
102 #define	  FIFO_MODE_16_31_16		0
103 #define	  FIFO_MODE_16_15_0		1
104 #define	 DAC_FIFOC_DRQ_CLR_CNT_SHIFT	21
105 #define	 DAC_FIFOC_DRQ_CLR_CNT_MASK	(3U << DAC_FIFOC_DRQ_CLR_CNT_SHIFT)
106 #define	 DAC_FIFOC_TX_TRIG_LEVEL_SHIFT	8
107 #define	 DAC_FIFOC_TX_TRIG_LEVEL_MASK	(0x7f << DAC_FIFOC_TX_TRIG_LEVEL_SHIFT)
108 #define	 DAC_FIFOC_MONO_EN		(1U << 6)
109 #define	 DAC_FIFOC_TX_BITS		(1U << 5)
110 #define	 DAC_FIFOC_DRQ_EN		(1U << 4)
111 #define	 DAC_FIFOC_FIFO_FLUSH		(1U << 0)
112 #define	AC_DAC_FIFOS(_sc)	((_sc)->cfg->DAC_FIFOS)
113 #define	AC_DAC_TXDATA(_sc)	((_sc)->cfg->DAC_TXDATA)
114 #define	AC_ADC_FIFOC(_sc)	((_sc)->cfg->ADC_FIFOC)
115 #define	 ADC_FIFOC_FS_SHIFT		29
116 #define	 ADC_FIFOC_FS_MASK		(7U << ADC_FIFOC_FS_SHIFT)
117 #define	  ADC_FS_48KHZ		0
118 #define	 ADC_FIFOC_EN_AD		(1U << 28)
119 #define	 ADC_FIFOC_RX_FIFO_MODE		(1U << 24)
120 #define	 ADC_FIFOC_RX_TRIG_LEVEL_SHIFT	8
121 #define	 ADC_FIFOC_RX_TRIG_LEVEL_MASK	(0x1f << ADC_FIFOC_RX_TRIG_LEVEL_SHIFT)
122 #define	 ADC_FIFOC_MONO_EN		(1U << 7)
123 #define	 ADC_FIFOC_RX_BITS		(1U << 6)
124 #define	 ADC_FIFOC_DRQ_EN		(1U << 4)
125 #define	 ADC_FIFOC_FIFO_FLUSH		(1U << 1)
126 #define	AC_ADC_FIFOS(_sc)	((_sc)->cfg->ADC_FIFOS)
127 #define	AC_ADC_RXDATA(_sc)	((_sc)->cfg->ADC_RXDATA)
128 #define	AC_DAC_CNT(_sc)		((_sc)->cfg->DAC_CNT)
129 #define	AC_ADC_CNT(_sc)		((_sc)->cfg->ADC_CNT)
130 
131 static uint32_t a10codec_fmt[] = {
132 	SND_FORMAT(AFMT_S16_LE, 1, 0),
133 	SND_FORMAT(AFMT_S16_LE, 2, 0),
134 	0
135 };
136 
137 static struct pcmchan_caps a10codec_pcaps = { 8000, 192000, a10codec_fmt, 0 };
138 static struct pcmchan_caps a10codec_rcaps = { 8000, 48000, a10codec_fmt, 0 };
139 
140 struct a10codec_info;
141 
142 struct a10codec_chinfo {
143 	struct snd_dbuf		*buffer;
144 	struct pcm_channel	*channel;
145 	struct a10codec_info	*parent;
146 	bus_dmamap_t		dmamap;
147 	void			*dmaaddr;
148 	bus_addr_t		physaddr;
149 	bus_size_t		fifo;
150 	device_t		dmac;
151 	void			*dmachan;
152 
153 	int			dir;
154 	int			run;
155 	uint32_t		pos;
156 	uint32_t		format;
157 	uint32_t		blocksize;
158 	uint32_t		speed;
159 };
160 
161 struct a10codec_info {
162 	device_t		dev;
163 	struct resource		*res[2];
164 	struct mtx		*lock;
165 	bus_dma_tag_t		dmat;
166 	unsigned		dmasize;
167 	void			*ih;
168 
169 	struct a10codec_config	*cfg;
170 
171 	struct a10codec_chinfo	play;
172 	struct a10codec_chinfo	rec;
173 };
174 
175 static struct resource_spec a10codec_spec[] = {
176 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },
177 	{ -1, 0 }
178 };
179 
180 #define	CODEC_ANALOG_READ(sc, reg)		bus_read_4((sc)->res[1], (reg))
181 #define	CODEC_ANALOG_WRITE(sc, reg, val)	bus_write_4((sc)->res[1], (reg), (val))
182 
183 #define	CODEC_READ(sc, reg)		bus_read_4((sc)->res[0], (reg))
184 #define	CODEC_WRITE(sc, reg, val)	bus_write_4((sc)->res[0], (reg), (val))
185 
186 /*
187  * A10/A20 mixer interface
188  */
189 
190 #define	A10_DAC_ACTL	0x10
191 #define	 A10_DACAREN			(1U << 31)
192 #define	 A10_DACALEN			(1U << 30)
193 #define	 A10_MIXEN			(1U << 29)
194 #define	 A10_DACPAS			(1U << 8)
195 #define	 A10_PAMUTE			(1U << 6)
196 #define	 A10_PAVOL_SHIFT		0
197 #define	 A10_PAVOL_MASK			(0x3f << A10_PAVOL_SHIFT)
198 #define	A10_ADC_ACTL	0x28
199 #define	 A10_ADCREN			(1U << 31)
200 #define	 A10_ADCLEN			(1U << 30)
201 #define	 A10_PREG1EN			(1U << 29)
202 #define	 A10_PREG2EN			(1U << 28)
203 #define	 A10_VMICEN			(1U << 27)
204 #define	 A10_ADCG_SHIFT			20
205 #define	 A10_ADCG_MASK			(7U << A10_ADCG_SHIFT)
206 #define	 A10_ADCIS_SHIFT		17
207 #define	 A10_ADCIS_MASK			(7U << A10_ADCIS_SHIFT)
208 #define	  A10_ADC_IS_LINEIN			0
209 #define	  A10_ADC_IS_FMIN			1
210 #define	  A10_ADC_IS_MIC1			2
211 #define	  A10_ADC_IS_MIC2			3
212 #define	  A10_ADC_IS_MIC1_L_MIC2_R		4
213 #define	  A10_ADC_IS_MIC1_LR_MIC2_LR		5
214 #define	  A10_ADC_IS_OMIX			6
215 #define	  A10_ADC_IS_LINEIN_L_MIC1_R		7
216 #define	 A10_LNRDF			(1U << 16)
217 #define	 A10_LNPREG_SHIFT		13
218 #define	 A10_LNPREG_MASK		(7U << A10_LNPREG_SHIFT)
219 #define	 A10_PA_EN			(1U << 4)
220 #define	 A10_DDE			(1U << 3)
221 
222 static int
223 a10_mixer_init(struct snd_mixer *m)
224 {
225 	struct a10codec_info *sc = mix_getdevinfo(m);
226 	uint32_t val;
227 
228 	mix_setdevs(m, SOUND_MASK_VOLUME | SOUND_MASK_LINE | SOUND_MASK_RECLEV);
229 	mix_setrecdevs(m, SOUND_MASK_LINE | SOUND_MASK_LINE1 | SOUND_MASK_MIC);
230 
231 	/* Unmute input source to PA */
232 	val = CODEC_READ(sc, A10_DAC_ACTL);
233 	val |= A10_PAMUTE;
234 	CODEC_WRITE(sc, A10_DAC_ACTL, val);
235 
236 	/* Enable PA */
237 	val = CODEC_READ(sc, A10_ADC_ACTL);
238 	val |= A10_PA_EN;
239 	CODEC_WRITE(sc, A10_ADC_ACTL, val);
240 
241 	return (0);
242 }
243 
244 static const struct a10_mixer {
245 	unsigned reg;
246 	unsigned mask;
247 	unsigned shift;
248 } a10_mixers[SOUND_MIXER_NRDEVICES] = {
249 	[SOUND_MIXER_VOLUME]	= { A10_DAC_ACTL, A10_PAVOL_MASK,
250 				    A10_PAVOL_SHIFT },
251 	[SOUND_MIXER_LINE]	= { A10_ADC_ACTL, A10_LNPREG_MASK,
252 				    A10_LNPREG_SHIFT },
253 	[SOUND_MIXER_RECLEV]	= { A10_ADC_ACTL, A10_ADCG_MASK,
254 				    A10_ADCG_SHIFT },
255 };
256 
257 static int
258 a10_mixer_set(struct snd_mixer *m, unsigned dev, unsigned left,
259     unsigned right)
260 {
261 	struct a10codec_info *sc = mix_getdevinfo(m);
262 	uint32_t val;
263 	unsigned nvol, max;
264 
265 	max = a10_mixers[dev].mask >> a10_mixers[dev].shift;
266 	nvol = (left * max) / 100;
267 
268 	val = CODEC_READ(sc, a10_mixers[dev].reg);
269 	val &= ~a10_mixers[dev].mask;
270 	val |= (nvol << a10_mixers[dev].shift);
271 	CODEC_WRITE(sc, a10_mixers[dev].reg, val);
272 
273 	left = right = (left * 100) / max;
274 	return (left | (right << 8));
275 }
276 
277 static uint32_t
278 a10_mixer_setrecsrc(struct snd_mixer *m, uint32_t src)
279 {
280 	struct a10codec_info *sc = mix_getdevinfo(m);
281 	uint32_t val;
282 
283 	val = CODEC_READ(sc, A10_ADC_ACTL);
284 
285 	switch (src) {
286 	case SOUND_MASK_LINE:	/* line-in */
287 		val &= ~A10_ADCIS_MASK;
288 		val |= (A10_ADC_IS_LINEIN << A10_ADCIS_SHIFT);
289 		break;
290 	case SOUND_MASK_MIC:	/* MIC1 */
291 		val &= ~A10_ADCIS_MASK;
292 		val |= (A10_ADC_IS_MIC1 << A10_ADCIS_SHIFT);
293 		break;
294 	case SOUND_MASK_LINE1:	/* MIC2 */
295 		val &= ~A10_ADCIS_MASK;
296 		val |= (A10_ADC_IS_MIC2 << A10_ADCIS_SHIFT);
297 		break;
298 	default:
299 		break;
300 	}
301 
302 	CODEC_WRITE(sc, A10_ADC_ACTL, val);
303 
304 	switch ((val & A10_ADCIS_MASK) >> A10_ADCIS_SHIFT) {
305 	case A10_ADC_IS_LINEIN:
306 		return (SOUND_MASK_LINE);
307 	case A10_ADC_IS_MIC1:
308 		return (SOUND_MASK_MIC);
309 	case A10_ADC_IS_MIC2:
310 		return (SOUND_MASK_LINE1);
311 	default:
312 		return (0);
313 	}
314 }
315 
316 static void
317 a10_mute(struct a10codec_info *sc, int mute, int dir)
318 {
319 	uint32_t val;
320 
321 	if (dir == PCMDIR_PLAY) {
322 		val = CODEC_READ(sc, A10_DAC_ACTL);
323 		if (mute) {
324 			/* Disable DAC analog l/r channels and output mixer */
325 			val &= ~A10_DACAREN;
326 			val &= ~A10_DACALEN;
327 			val &= ~A10_DACPAS;
328 		} else {
329 			/* Enable DAC analog l/r channels and output mixer */
330 			val |= A10_DACAREN;
331 			val |= A10_DACALEN;
332 			val |= A10_DACPAS;
333 		}
334 		CODEC_WRITE(sc, A10_DAC_ACTL, val);
335 	} else {
336 		val = CODEC_READ(sc, A10_ADC_ACTL);
337 		if (mute) {
338 			/* Disable ADC analog l/r channels, MIC1 preamp,
339 			 * and VMIC pin voltage
340 			 */
341 			val &= ~A10_ADCREN;
342 			val &= ~A10_ADCLEN;
343 			val &= ~A10_PREG1EN;
344 			val &= ~A10_VMICEN;
345 		} else {
346 			/* Enable ADC analog l/r channels, MIC1 preamp,
347 			 * and VMIC pin voltage
348 			 */
349 			val |= A10_ADCREN;
350 			val |= A10_ADCLEN;
351 			val |= A10_PREG1EN;
352 			val |= A10_VMICEN;
353 		}
354 		CODEC_WRITE(sc, A10_ADC_ACTL, val);
355 	}
356 }
357 
358 static kobj_method_t a10_mixer_methods[] = {
359 	KOBJMETHOD(mixer_init,		a10_mixer_init),
360 	KOBJMETHOD(mixer_set,		a10_mixer_set),
361 	KOBJMETHOD(mixer_setrecsrc,	a10_mixer_setrecsrc),
362 	KOBJMETHOD_END
363 };
364 MIXER_DECLARE(a10_mixer);
365 
366 /*
367  * H3 mixer interface
368  */
369 
370 #define	H3_PR_CFG		0x00
371 #define	 H3_AC_PR_RST		(1 << 28)
372 #define	 H3_AC_PR_RW		(1 << 24)
373 #define	 H3_AC_PR_ADDR_SHIFT	16
374 #define	 H3_AC_PR_ADDR_MASK	(0x1f << H3_AC_PR_ADDR_SHIFT)
375 #define	 H3_ACDA_PR_WDAT_SHIFT	8
376 #define	 H3_ACDA_PR_WDAT_MASK	(0xff << H3_ACDA_PR_WDAT_SHIFT)
377 #define	 H3_ACDA_PR_RDAT_SHIFT	0
378 #define	 H3_ACDA_PR_RDAT_MASK	(0xff << H3_ACDA_PR_RDAT_SHIFT)
379 
380 #define	H3_LOMIXSC		0x01
381 #define	 H3_LOMIXSC_LDAC	(1 << 1)
382 #define	H3_ROMIXSC		0x02
383 #define	 H3_ROMIXSC_RDAC	(1 << 1)
384 #define	H3_DAC_PA_SRC		0x03
385 #define	 H3_DACAREN		(1 << 7)
386 #define	 H3_DACALEN		(1 << 6)
387 #define	 H3_RMIXEN		(1 << 5)
388 #define	 H3_LMIXEN		(1 << 4)
389 #define	H3_LINEIN_GCTR		0x05
390 #define	 H3_LINEING_SHIFT	4
391 #define	 H3_LINEING_MASK	(0x7 << H3_LINEING_SHIFT)
392 #define	H3_MIC_GCTR		0x06
393 #define	 H3_MIC1_GAIN_SHIFT	4
394 #define	 H3_MIC1_GAIN_MASK	(0x7 << H3_MIC1_GAIN_SHIFT)
395 #define	 H3_MIC2_GAIN_SHIFT	0
396 #define	 H3_MIC2_GAIN_MASK	(0x7 << H3_MIC2_GAIN_SHIFT)
397 #define	H3_PAEN_CTR		0x07
398 #define	 H3_LINEOUTEN		(1 << 7)
399 #define	H3_LINEOUT_VOLC		0x09
400 #define	 H3_LINEOUTVOL_SHIFT	3
401 #define	 H3_LINEOUTVOL_MASK	(0x1f << H3_LINEOUTVOL_SHIFT)
402 #define	H3_MIC2G_LINEOUT_CTR	0x0a
403 #define	 H3_LINEOUT_LSEL	(1 << 3)
404 #define	 H3_LINEOUT_RSEL	(1 << 2)
405 #define	H3_LADCMIXSC		0x0c
406 #define	H3_RADCMIXSC		0x0d
407 #define	 H3_ADCMIXSC_MIC1	(1 << 6)
408 #define	 H3_ADCMIXSC_MIC2	(1 << 5)
409 #define	 H3_ADCMIXSC_LINEIN	(1 << 2)
410 #define	 H3_ADCMIXSC_OMIXER	(3 << 0)
411 #define	H3_ADC_AP_EN		0x0f
412 #define	 H3_ADCREN		(1 << 7)
413 #define	 H3_ADCLEN		(1 << 6)
414 #define	 H3_ADCG_SHIFT		0
415 #define	 H3_ADCG_MASK		(0x7 << H3_ADCG_SHIFT)
416 
417 static u_int
418 h3_pr_read(struct a10codec_info *sc, u_int addr)
419 {
420 	uint32_t val;
421 
422 	/* Read current value */
423 	val = CODEC_ANALOG_READ(sc, H3_PR_CFG);
424 
425 	/* De-assert reset */
426 	val |= H3_AC_PR_RST;
427 	CODEC_ANALOG_WRITE(sc, H3_PR_CFG, val);
428 
429 	/* Read mode */
430 	val &= ~H3_AC_PR_RW;
431 	CODEC_ANALOG_WRITE(sc, H3_PR_CFG, val);
432 
433 	/* Set address */
434 	val &= ~H3_AC_PR_ADDR_MASK;
435 	val |= (addr << H3_AC_PR_ADDR_SHIFT);
436 	CODEC_ANALOG_WRITE(sc, H3_PR_CFG, val);
437 
438 	/* Read data */
439 	return (CODEC_ANALOG_READ(sc , H3_PR_CFG) & H3_ACDA_PR_RDAT_MASK);
440 }
441 
442 static void
443 h3_pr_write(struct a10codec_info *sc, u_int addr, u_int data)
444 {
445 	uint32_t val;
446 
447 	/* Read current value */
448 	val = CODEC_ANALOG_READ(sc, H3_PR_CFG);
449 
450 	/* De-assert reset */
451 	val |= H3_AC_PR_RST;
452 	CODEC_ANALOG_WRITE(sc, H3_PR_CFG, val);
453 
454 	/* Set address */
455 	val &= ~H3_AC_PR_ADDR_MASK;
456 	val |= (addr << H3_AC_PR_ADDR_SHIFT);
457 	CODEC_ANALOG_WRITE(sc, H3_PR_CFG, val);
458 
459 	/* Write data */
460 	val &= ~H3_ACDA_PR_WDAT_MASK;
461 	val |= (data << H3_ACDA_PR_WDAT_SHIFT);
462 	CODEC_ANALOG_WRITE(sc, H3_PR_CFG, val);
463 
464 	/* Write mode */
465 	val |= H3_AC_PR_RW;
466 	CODEC_ANALOG_WRITE(sc, H3_PR_CFG, val);
467 }
468 
469 static void
470 h3_pr_set_clear(struct a10codec_info *sc, u_int addr, u_int set, u_int clr)
471 {
472 	u_int old, new;
473 
474 	old = h3_pr_read(sc, addr);
475 	new = set | (old & ~clr);
476 	h3_pr_write(sc, addr, new);
477 }
478 
479 static int
480 h3_mixer_init(struct snd_mixer *m)
481 {
482 	int rid=1;
483 	pcell_t reg[2];
484 	phandle_t analogref;
485 	struct a10codec_info *sc = mix_getdevinfo(m);
486 
487 	if (OF_getencprop(ofw_bus_get_node(sc->dev), "allwinner,codec-analog-controls",
488 	    &analogref, sizeof(analogref)) <= 0) {
489 		return (ENXIO);
490 	}
491 
492 	if (OF_getencprop(OF_node_from_xref(analogref), "reg",
493 	    reg, sizeof(reg)) <= 0) {
494 		return (ENXIO);
495 	}
496 
497 	sc->res[1] = bus_alloc_resource(sc->dev, SYS_RES_MEMORY, &rid, reg[0],
498 	    reg[0]+reg[1], reg[1], RF_ACTIVE );
499 
500 	if (sc->res[1] == NULL) {
501 		return (ENXIO);
502 	}
503 
504 	mix_setdevs(m, SOUND_MASK_PCM | SOUND_MASK_VOLUME | SOUND_MASK_RECLEV |
505 	    SOUND_MASK_MIC | SOUND_MASK_LINE | SOUND_MASK_LINE1);
506 	mix_setrecdevs(m, SOUND_MASK_MIC | SOUND_MASK_LINE | SOUND_MASK_LINE1 |
507 	    SOUND_MASK_IMIX);
508 
509 	pcm_setflags(sc->dev, pcm_getflags(sc->dev) | SD_F_SOFTPCMVOL);
510 
511 	/* Right & Left LINEOUT enable */
512 	h3_pr_set_clear(sc, H3_PAEN_CTR, H3_LINEOUTEN, 0);
513 	h3_pr_set_clear(sc, H3_MIC2G_LINEOUT_CTR,
514 	    H3_LINEOUT_LSEL | H3_LINEOUT_RSEL, 0);
515 
516 	return (0);
517 }
518 
519 static const struct h3_mixer {
520 	unsigned reg;
521 	unsigned mask;
522 	unsigned shift;
523 } h3_mixers[SOUND_MIXER_NRDEVICES] = {
524 	[SOUND_MIXER_VOLUME]	= { H3_LINEOUT_VOLC, H3_LINEOUTVOL_MASK,
525 				    H3_LINEOUTVOL_SHIFT },
526 	[SOUND_MIXER_RECLEV]	= { H3_ADC_AP_EN, H3_ADCG_MASK,
527 				    H3_ADCG_SHIFT },
528 	[SOUND_MIXER_LINE]	= { H3_LINEIN_GCTR, H3_LINEING_MASK,
529 				    H3_LINEING_SHIFT },
530 	[SOUND_MIXER_MIC]	= { H3_MIC_GCTR, H3_MIC1_GAIN_MASK,
531 				    H3_MIC1_GAIN_SHIFT },
532 	[SOUND_MIXER_LINE1]	= { H3_MIC_GCTR, H3_MIC2_GAIN_MASK,
533 				    H3_MIC2_GAIN_SHIFT },
534 };
535 
536 static int
537 h3_mixer_set(struct snd_mixer *m, unsigned dev, unsigned left,
538     unsigned right)
539 {
540 	struct a10codec_info *sc = mix_getdevinfo(m);
541 	unsigned nvol, max;
542 
543 	max = h3_mixers[dev].mask >> h3_mixers[dev].shift;
544 	nvol = (left * max) / 100;
545 
546 	h3_pr_set_clear(sc, h3_mixers[dev].reg,
547 	    nvol << h3_mixers[dev].shift, h3_mixers[dev].mask);
548 
549 	left = right = (left * 100) / max;
550 	return (left | (right << 8));
551 }
552 
553 static uint32_t
554 h3_mixer_setrecsrc(struct snd_mixer *m, uint32_t src)
555 {
556 	struct a10codec_info *sc = mix_getdevinfo(m);
557 	uint32_t val;
558 
559 	val = 0;
560 	src &= (SOUND_MASK_LINE | SOUND_MASK_MIC |
561 	    SOUND_MASK_LINE1 | SOUND_MASK_IMIX);
562 
563 	if ((src & SOUND_MASK_LINE) != 0)	/* line-in */
564 		val |= H3_ADCMIXSC_LINEIN;
565 	if ((src & SOUND_MASK_MIC) != 0)	/* MIC1 */
566 		val |= H3_ADCMIXSC_MIC1;
567 	if ((src & SOUND_MASK_LINE1) != 0)	/* MIC2 */
568 		val |= H3_ADCMIXSC_MIC2;
569 	if ((src & SOUND_MASK_IMIX) != 0)	/* l/r output mixer */
570 		val |= H3_ADCMIXSC_OMIXER;
571 
572 	h3_pr_write(sc, H3_LADCMIXSC, val);
573 	h3_pr_write(sc, H3_RADCMIXSC, val);
574 
575 	return (src);
576 }
577 
578 static void
579 h3_mute(struct a10codec_info *sc, int mute, int dir)
580 {
581 	if (dir == PCMDIR_PLAY) {
582 		if (mute) {
583 			/* Mute DAC l/r channels to output mixer */
584 			h3_pr_set_clear(sc, H3_LOMIXSC, 0, H3_LOMIXSC_LDAC);
585 			h3_pr_set_clear(sc, H3_ROMIXSC, 0, H3_ROMIXSC_RDAC);
586 			/* Disable DAC analog l/r channels and output mixer */
587 			h3_pr_set_clear(sc, H3_DAC_PA_SRC,
588 			    0, H3_DACAREN | H3_DACALEN | H3_RMIXEN | H3_LMIXEN);
589 		} else {
590 			/* Enable DAC analog l/r channels and output mixer */
591 			h3_pr_set_clear(sc, H3_DAC_PA_SRC,
592 			    H3_DACAREN | H3_DACALEN | H3_RMIXEN | H3_LMIXEN, 0);
593 			/* Unmute DAC l/r channels to output mixer */
594 			h3_pr_set_clear(sc, H3_LOMIXSC, H3_LOMIXSC_LDAC, 0);
595 			h3_pr_set_clear(sc, H3_ROMIXSC, H3_ROMIXSC_RDAC, 0);
596 		}
597 	} else {
598 		if (mute) {
599 			/* Disable ADC analog l/r channels */
600 			h3_pr_set_clear(sc, H3_ADC_AP_EN,
601 			    0, H3_ADCREN | H3_ADCLEN);
602 		} else {
603 			/* Enable ADC analog l/r channels */
604 			h3_pr_set_clear(sc, H3_ADC_AP_EN,
605 			    H3_ADCREN | H3_ADCLEN, 0);
606 		}
607 	}
608 }
609 
610 static kobj_method_t h3_mixer_methods[] = {
611 	KOBJMETHOD(mixer_init,		h3_mixer_init),
612 	KOBJMETHOD(mixer_set,		h3_mixer_set),
613 	KOBJMETHOD(mixer_setrecsrc,	h3_mixer_setrecsrc),
614 	KOBJMETHOD_END
615 };
616 MIXER_DECLARE(h3_mixer);
617 
618 /*
619  * Channel interface
620  */
621 
622 static void
623 a10codec_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
624 {
625 	struct a10codec_chinfo *ch = arg;
626 
627 	if (error != 0)
628 		return;
629 
630 	ch->physaddr = segs[0].ds_addr;
631 }
632 
633 static void
634 a10codec_transfer(struct a10codec_chinfo *ch)
635 {
636 	bus_addr_t src, dst;
637 	int error;
638 
639 	if (ch->dir == PCMDIR_PLAY) {
640 		src = ch->physaddr + ch->pos;
641 		dst = ch->fifo;
642 	} else {
643 		src = ch->fifo;
644 		dst = ch->physaddr + ch->pos;
645 	}
646 
647 	error = SUNXI_DMA_TRANSFER(ch->dmac, ch->dmachan, src, dst,
648 	    ch->blocksize);
649 	if (error) {
650 		ch->run = 0;
651 		device_printf(ch->parent->dev, "DMA transfer failed: %d\n",
652 		    error);
653 	}
654 }
655 
656 static void
657 a10codec_dmaconfig(struct a10codec_chinfo *ch)
658 {
659 	struct a10codec_info *sc = ch->parent;
660 	struct sunxi_dma_config conf;
661 
662 	memset(&conf, 0, sizeof(conf));
663 	conf.src_width = conf.dst_width = 16;
664 	conf.src_burst_len = conf.dst_burst_len = 4;
665 
666 	if (ch->dir == PCMDIR_PLAY) {
667 		conf.dst_noincr = true;
668 		conf.src_drqtype = sc->cfg->drqtype_sdram;
669 		conf.dst_drqtype = sc->cfg->drqtype_codec;
670 	} else {
671 		conf.src_noincr = true;
672 		conf.src_drqtype = sc->cfg->drqtype_codec;
673 		conf.dst_drqtype = sc->cfg->drqtype_sdram;
674 	}
675 
676 	SUNXI_DMA_SET_CONFIG(ch->dmac, ch->dmachan, &conf);
677 }
678 
679 static void
680 a10codec_dmaintr(void *priv)
681 {
682 	struct a10codec_chinfo *ch = priv;
683 	unsigned bufsize;
684 
685 	bufsize = sndbuf_getsize(ch->buffer);
686 
687 	ch->pos += ch->blocksize;
688 	if (ch->pos >= bufsize)
689 		ch->pos -= bufsize;
690 
691 	if (ch->run) {
692 		chn_intr(ch->channel);
693 		a10codec_transfer(ch);
694 	}
695 }
696 
697 static unsigned
698 a10codec_fs(struct a10codec_chinfo *ch)
699 {
700 	switch (ch->speed) {
701 	case 48000:
702 		return (DAC_FS_48KHZ);
703 	case 24000:
704 		return (DAC_FS_24KHZ);
705 	case 12000:
706 		return (DAC_FS_12KHZ);
707 	case 192000:
708 		return (DAC_FS_192KHZ);
709 	case 32000:
710 		return (DAC_FS_32KHZ);
711 	case 16000:
712 		return (DAC_FS_16KHZ);
713 	case 8000:
714 		return (DAC_FS_8KHZ);
715 	case 96000:
716 		return (DAC_FS_96KHZ);
717 	default:
718 		return (DAC_FS_48KHZ);
719 	}
720 }
721 
722 static void
723 a10codec_start(struct a10codec_chinfo *ch)
724 {
725 	struct a10codec_info *sc = ch->parent;
726 	uint32_t val;
727 
728 	ch->pos = 0;
729 
730 	if (ch->dir == PCMDIR_PLAY) {
731 		/* Flush DAC FIFO */
732 		CODEC_WRITE(sc, AC_DAC_FIFOC(sc), DAC_FIFOC_FIFO_FLUSH);
733 
734 		/* Clear DAC FIFO status */
735 		CODEC_WRITE(sc, AC_DAC_FIFOS(sc),
736 		    CODEC_READ(sc, AC_DAC_FIFOS(sc)));
737 
738 		/* Unmute output */
739 		sc->cfg->mute(sc, 0, ch->dir);
740 
741 		/* Configure DAC DMA channel */
742 		a10codec_dmaconfig(ch);
743 
744 		/* Configure DAC FIFO */
745 		CODEC_WRITE(sc, AC_DAC_FIFOC(sc),
746 		    (AFMT_CHANNEL(ch->format) == 1 ? DAC_FIFOC_MONO_EN : 0) |
747 		    (a10codec_fs(ch) << DAC_FIFOC_FS_SHIFT) |
748 		    (FIFO_MODE_16_15_0 << DAC_FIFOC_FIFO_MODE_SHIFT) |
749 		    (DRQ_CLR_CNT << DAC_FIFOC_DRQ_CLR_CNT_SHIFT) |
750 		    (TX_TRIG_LEVEL << DAC_FIFOC_TX_TRIG_LEVEL_SHIFT));
751 
752 		/* Enable DAC DRQ */
753 		val = CODEC_READ(sc, AC_DAC_FIFOC(sc));
754 		val |= DAC_FIFOC_DRQ_EN;
755 		CODEC_WRITE(sc, AC_DAC_FIFOC(sc), val);
756 	} else {
757 		/* Flush ADC FIFO */
758 		CODEC_WRITE(sc, AC_ADC_FIFOC(sc), ADC_FIFOC_FIFO_FLUSH);
759 
760 		/* Clear ADC FIFO status */
761 		CODEC_WRITE(sc, AC_ADC_FIFOS(sc),
762 		    CODEC_READ(sc, AC_ADC_FIFOS(sc)));
763 
764 		/* Unmute input */
765 		sc->cfg->mute(sc, 0, ch->dir);
766 
767 		/* Configure ADC DMA channel */
768 		a10codec_dmaconfig(ch);
769 
770 		/* Configure ADC FIFO */
771 		CODEC_WRITE(sc, AC_ADC_FIFOC(sc),
772 		    ADC_FIFOC_EN_AD |
773 		    ADC_FIFOC_RX_FIFO_MODE |
774 		    (AFMT_CHANNEL(ch->format) == 1 ? ADC_FIFOC_MONO_EN : 0) |
775 		    (a10codec_fs(ch) << ADC_FIFOC_FS_SHIFT) |
776 		    (RX_TRIG_LEVEL << ADC_FIFOC_RX_TRIG_LEVEL_SHIFT));
777 
778 		/* Enable ADC DRQ */
779 		val = CODEC_READ(sc, AC_ADC_FIFOC(sc));
780 		val |= ADC_FIFOC_DRQ_EN;
781 		CODEC_WRITE(sc, AC_ADC_FIFOC(sc), val);
782 	}
783 
784 	/* Start DMA transfer */
785 	a10codec_transfer(ch);
786 }
787 
788 static void
789 a10codec_stop(struct a10codec_chinfo *ch)
790 {
791 	struct a10codec_info *sc = ch->parent;
792 
793 	/* Disable DMA channel */
794 	SUNXI_DMA_HALT(ch->dmac, ch->dmachan);
795 
796 	sc->cfg->mute(sc, 1, ch->dir);
797 
798 	if (ch->dir == PCMDIR_PLAY) {
799 		/* Disable DAC DRQ */
800 		CODEC_WRITE(sc, AC_DAC_FIFOC(sc), 0);
801 	} else {
802 		/* Disable ADC DRQ */
803 		CODEC_WRITE(sc, AC_ADC_FIFOC(sc), 0);
804 	}
805 }
806 
807 static void *
808 a10codec_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
809     struct pcm_channel *c, int dir)
810 {
811 	struct a10codec_info *sc = devinfo;
812 	struct a10codec_chinfo *ch = dir == PCMDIR_PLAY ? &sc->play : &sc->rec;
813 	phandle_t xref;
814 	pcell_t *cells;
815 	int ncells, error;
816 
817 	error = ofw_bus_parse_xref_list_alloc(ofw_bus_get_node(sc->dev),
818 	    "dmas", "#dma-cells", dir == PCMDIR_PLAY ? 1 : 0,
819 	    &xref, &ncells, &cells);
820 	if (error != 0) {
821 		device_printf(sc->dev, "cannot parse 'dmas' property\n");
822 		return (NULL);
823 	}
824 	OF_prop_free(cells);
825 
826 	ch->parent = sc;
827 	ch->channel = c;
828 	ch->buffer = b;
829 	ch->dir = dir;
830 	ch->fifo = rman_get_start(sc->res[0]) +
831 	    (dir == PCMDIR_REC ? AC_ADC_RXDATA(sc) : AC_DAC_TXDATA(sc));
832 
833 	ch->dmac = OF_device_from_xref(xref);
834 	if (ch->dmac == NULL) {
835 		device_printf(sc->dev, "cannot find DMA controller\n");
836 		device_printf(sc->dev, "xref = 0x%x\n", (u_int)xref);
837 		return (NULL);
838 	}
839 	ch->dmachan = SUNXI_DMA_ALLOC(ch->dmac, false, a10codec_dmaintr, ch);
840 	if (ch->dmachan == NULL) {
841 		device_printf(sc->dev, "cannot allocate DMA channel\n");
842 		return (NULL);
843 	}
844 
845 	error = bus_dmamem_alloc(sc->dmat, &ch->dmaaddr,
846 	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &ch->dmamap);
847 	if (error != 0) {
848 		device_printf(sc->dev, "cannot allocate channel buffer\n");
849 		return (NULL);
850 	}
851 	error = bus_dmamap_load(sc->dmat, ch->dmamap, ch->dmaaddr,
852 	    sc->dmasize, a10codec_dmamap_cb, ch, BUS_DMA_NOWAIT);
853 	if (error != 0) {
854 		device_printf(sc->dev, "cannot load DMA map\n");
855 		return (NULL);
856 	}
857 	memset(ch->dmaaddr, 0, sc->dmasize);
858 
859 	if (sndbuf_setup(ch->buffer, ch->dmaaddr, sc->dmasize) != 0) {
860 		device_printf(sc->dev, "cannot setup sndbuf\n");
861 		return (NULL);
862 	}
863 
864 	return (ch);
865 }
866 
867 static int
868 a10codec_chan_free(kobj_t obj, void *data)
869 {
870 	struct a10codec_chinfo *ch = data;
871 	struct a10codec_info *sc = ch->parent;
872 
873 	SUNXI_DMA_FREE(ch->dmac, ch->dmachan);
874 	bus_dmamap_unload(sc->dmat, ch->dmamap);
875 	bus_dmamem_free(sc->dmat, ch->dmaaddr, ch->dmamap);
876 
877 	return (0);
878 }
879 
880 static int
881 a10codec_chan_setformat(kobj_t obj, void *data, uint32_t format)
882 {
883 	struct a10codec_chinfo *ch = data;
884 
885 	ch->format = format;
886 
887 	return (0);
888 }
889 
890 static uint32_t
891 a10codec_chan_setspeed(kobj_t obj, void *data, uint32_t speed)
892 {
893 	struct a10codec_chinfo *ch = data;
894 
895 	/*
896 	 * The codec supports full duplex operation but both DAC and ADC
897 	 * use the same source clock (PLL2). Limit the available speeds to
898 	 * those supported by a 24576000 Hz input.
899 	 */
900 	switch (speed) {
901 	case 8000:
902 	case 12000:
903 	case 16000:
904 	case 24000:
905 	case 32000:
906 	case 48000:
907 		ch->speed = speed;
908 		break;
909 	case 96000:
910 	case 192000:
911 		/* 96 KHz / 192 KHz mode only supported for playback */
912 		if (ch->dir == PCMDIR_PLAY) {
913 			ch->speed = speed;
914 		} else {
915 			ch->speed = 48000;
916 		}
917 		break;
918 	case 44100:
919 		ch->speed = 48000;
920 		break;
921 	case 22050:
922 		ch->speed = 24000;
923 		break;
924 	case 11025:
925 		ch->speed = 12000;
926 		break;
927 	default:
928 		ch->speed = 48000;
929 		break;
930 	}
931 
932 	return (ch->speed);
933 }
934 
935 static uint32_t
936 a10codec_chan_setblocksize(kobj_t obj, void *data, uint32_t blocksize)
937 {
938 	struct a10codec_chinfo *ch = data;
939 
940 	ch->blocksize = blocksize & ~3;
941 
942 	return (ch->blocksize);
943 }
944 
945 static int
946 a10codec_chan_trigger(kobj_t obj, void *data, int go)
947 {
948 	struct a10codec_chinfo *ch = data;
949 	struct a10codec_info *sc = ch->parent;
950 
951 	if (!PCMTRIG_COMMON(go))
952 		return (0);
953 
954 	snd_mtxlock(sc->lock);
955 	switch (go) {
956 	case PCMTRIG_START:
957 		ch->run = 1;
958 		a10codec_stop(ch);
959 		a10codec_start(ch);
960 		break;
961 	case PCMTRIG_STOP:
962 	case PCMTRIG_ABORT:
963 		ch->run = 0;
964 		a10codec_stop(ch);
965 		break;
966 	default:
967 		break;
968 	}
969 	snd_mtxunlock(sc->lock);
970 
971 	return (0);
972 }
973 
974 static uint32_t
975 a10codec_chan_getptr(kobj_t obj, void *data)
976 {
977 	struct a10codec_chinfo *ch = data;
978 
979 	return (ch->pos);
980 }
981 
982 static struct pcmchan_caps *
983 a10codec_chan_getcaps(kobj_t obj, void *data)
984 {
985 	struct a10codec_chinfo *ch = data;
986 
987 	if (ch->dir == PCMDIR_PLAY) {
988 		return (&a10codec_pcaps);
989 	} else {
990 		return (&a10codec_rcaps);
991 	}
992 }
993 
994 static kobj_method_t a10codec_chan_methods[] = {
995 	KOBJMETHOD(channel_init,		a10codec_chan_init),
996 	KOBJMETHOD(channel_free,		a10codec_chan_free),
997 	KOBJMETHOD(channel_setformat,		a10codec_chan_setformat),
998 	KOBJMETHOD(channel_setspeed,		a10codec_chan_setspeed),
999 	KOBJMETHOD(channel_setblocksize,	a10codec_chan_setblocksize),
1000 	KOBJMETHOD(channel_trigger,		a10codec_chan_trigger),
1001 	KOBJMETHOD(channel_getptr,		a10codec_chan_getptr),
1002 	KOBJMETHOD(channel_getcaps,		a10codec_chan_getcaps),
1003 	KOBJMETHOD_END
1004 };
1005 CHANNEL_DECLARE(a10codec_chan);
1006 
1007 /*
1008  * Device interface
1009  */
1010 
1011 static const struct a10codec_config a10_config = {
1012 	.mixer_class	= &a10_mixer_class,
1013 	.mute		= a10_mute,
1014 	.drqtype_codec	= 19,
1015 	.drqtype_sdram	= 22,
1016 	.DPC		= 0x00,
1017 	.DAC_FIFOC	= 0x04,
1018 	.DAC_FIFOS	= 0x08,
1019 	.DAC_TXDATA	= 0x0c,
1020 	.ADC_FIFOC	= 0x1c,
1021 	.ADC_FIFOS	= 0x20,
1022 	.ADC_RXDATA	= 0x24,
1023 	.DAC_CNT	= 0x30,
1024 	.ADC_CNT	= 0x34,
1025 };
1026 
1027 static const struct a10codec_config h3_config = {
1028 	.mixer_class	= &h3_mixer_class,
1029 	.mute		= h3_mute,
1030 	.drqtype_codec	= 15,
1031 	.drqtype_sdram	= 1,
1032 	.DPC		= 0x00,
1033 	.DAC_FIFOC	= 0x04,
1034 	.DAC_FIFOS	= 0x08,
1035 	.DAC_TXDATA	= 0x20,
1036 	.ADC_FIFOC	= 0x10,
1037 	.ADC_FIFOS	= 0x14,
1038 	.ADC_RXDATA	= 0x18,
1039 	.DAC_CNT	= 0x40,
1040 	.ADC_CNT	= 0x44,
1041 };
1042 
1043 static struct ofw_compat_data compat_data[] = {
1044 	{ "allwinner,sun4i-a10-codec",	(uintptr_t)&a10_config },
1045 	{ "allwinner,sun7i-a20-codec",	(uintptr_t)&a10_config },
1046 	{ "allwinner,sun8i-h3-codec",	(uintptr_t)&h3_config },
1047 	{ NULL, 0 }
1048 };
1049 
1050 static int
1051 a10codec_probe(device_t dev)
1052 {
1053 	if (!ofw_bus_status_okay(dev))
1054 		return (ENXIO);
1055 
1056 	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
1057 		return (ENXIO);
1058 
1059 	device_set_desc(dev, "Allwinner Audio Codec");
1060 	return (BUS_PROBE_DEFAULT);
1061 }
1062 
1063 static int
1064 a10codec_attach(device_t dev)
1065 {
1066 	struct a10codec_info *sc;
1067 	char status[SND_STATUSLEN];
1068 	struct gpiobus_pin *pa_pin;
1069 	phandle_t node;
1070 	clk_t clk_bus, clk_codec;
1071 	hwreset_t rst;
1072 	uint32_t val;
1073 	int error;
1074 
1075 	node = ofw_bus_get_node(dev);
1076 
1077 	sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
1078 	sc->cfg = (void *)ofw_bus_search_compatible(dev, compat_data)->ocd_data;
1079 	sc->dev = dev;
1080 	sc->lock = snd_mtxcreate(device_get_nameunit(dev), "a10codec softc");
1081 
1082 	if (bus_alloc_resources(dev, a10codec_spec, sc->res)) {
1083 		device_printf(dev, "cannot allocate resources for device\n");
1084 		error = ENXIO;
1085 		goto fail;
1086 	}
1087 
1088 	sc->dmasize = 131072;
1089 	error = bus_dma_tag_create(
1090 	    bus_get_dma_tag(dev),
1091 	    4, sc->dmasize,		/* alignment, boundary */
1092 	    BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
1093 	    BUS_SPACE_MAXADDR,		/* highaddr */
1094 	    NULL, NULL,			/* filter, filterarg */
1095 	    sc->dmasize, 1,		/* maxsize, nsegs */
1096 	    sc->dmasize, 0,		/* maxsegsize, flags */
1097 	    NULL, NULL,			/* lockfunc, lockarg */
1098 	    &sc->dmat);
1099 	if (error != 0) {
1100 		device_printf(dev, "cannot create DMA tag\n");
1101 		goto fail;
1102 	}
1103 
1104 	/* Get clocks */
1105 	if (clk_get_by_ofw_name(dev, 0, "apb", &clk_bus) != 0 &&
1106 	    clk_get_by_ofw_name(dev, 0, "ahb", &clk_bus) != 0) {
1107 		device_printf(dev, "cannot find bus clock\n");
1108 		goto fail;
1109 	}
1110 	if (clk_get_by_ofw_name(dev, 0, "codec", &clk_codec) != 0) {
1111 		device_printf(dev, "cannot find codec clock\n");
1112 		goto fail;
1113 	}
1114 
1115 	/* Gating bus clock for codec */
1116 	if (clk_enable(clk_bus) != 0) {
1117 		device_printf(dev, "cannot enable bus clock\n");
1118 		goto fail;
1119 	}
1120 	/* Activate audio codec clock. According to the A10 and A20 user
1121 	 * manuals, Audio_pll can be either 24.576MHz or 22.5792MHz. Most
1122 	 * audio sampling rates require an 24.576MHz input clock with the
1123 	 * exception of 44.1kHz, 22.05kHz, and 11.025kHz. Unfortunately,
1124 	 * both capture and playback use the same clock source so to
1125 	 * safely support independent full duplex operation, we use a fixed
1126 	 * 24.576MHz clock source and don't advertise native support for
1127 	 * the three sampling rates that require a 22.5792MHz input.
1128 	 */
1129 	error = clk_set_freq(clk_codec, 24576000, CLK_SET_ROUND_DOWN);
1130 	if (error != 0) {
1131 		device_printf(dev, "cannot set codec clock frequency\n");
1132 		goto fail;
1133 	}
1134 	/* Enable audio codec clock */
1135 	error = clk_enable(clk_codec);
1136 	if (error != 0) {
1137 		device_printf(dev, "cannot enable codec clock\n");
1138 		goto fail;
1139 	}
1140 
1141 	/* De-assert hwreset */
1142 	if (hwreset_get_by_ofw_idx(dev, 0, 0, &rst) == 0) {
1143 		error = hwreset_deassert(rst);
1144 		if (error != 0) {
1145 			device_printf(dev, "cannot de-assert reset\n");
1146 			goto fail;
1147 		}
1148 	}
1149 
1150 	/* Enable DAC */
1151 	val = CODEC_READ(sc, AC_DAC_DPC(sc));
1152 	val |= DAC_DPC_EN_DA;
1153 	CODEC_WRITE(sc, AC_DAC_DPC(sc), val);
1154 
1155 	if (mixer_init(dev, sc->cfg->mixer_class, sc)) {
1156 		device_printf(dev, "mixer_init failed\n");
1157 		goto fail;
1158 	}
1159 
1160 	/* Unmute PA */
1161 	if (gpio_pin_get_by_ofw_property(dev, node, "allwinner,pa-gpios",
1162 	    &pa_pin) == 0) {
1163 		error = gpio_pin_set_active(pa_pin, 1);
1164 		if (error != 0)
1165 			device_printf(dev, "failed to unmute PA\n");
1166 	}
1167 
1168 	pcm_setflags(dev, pcm_getflags(dev) | SD_F_MPSAFE);
1169 
1170 	if (pcm_register(dev, sc, 1, 1)) {
1171 		device_printf(dev, "pcm_register failed\n");
1172 		goto fail;
1173 	}
1174 
1175 	pcm_addchan(dev, PCMDIR_PLAY, &a10codec_chan_class, sc);
1176 	pcm_addchan(dev, PCMDIR_REC, &a10codec_chan_class, sc);
1177 
1178 	snprintf(status, SND_STATUSLEN, "at %s", ofw_bus_get_name(dev));
1179 	pcm_setstatus(dev, status);
1180 
1181 	return (0);
1182 
1183 fail:
1184 	bus_release_resources(dev, a10codec_spec, sc->res);
1185 	snd_mtxfree(sc->lock);
1186 	free(sc, M_DEVBUF);
1187 
1188 	return (ENXIO);
1189 }
1190 
1191 static device_method_t a10codec_pcm_methods[] = {
1192 	/* Device interface */
1193 	DEVMETHOD(device_probe,		a10codec_probe),
1194 	DEVMETHOD(device_attach,	a10codec_attach),
1195 
1196 	DEVMETHOD_END
1197 };
1198 
1199 static driver_t a10codec_pcm_driver = {
1200 	"pcm",
1201 	a10codec_pcm_methods,
1202 	PCM_SOFTC_SIZE,
1203 };
1204 
1205 DRIVER_MODULE(a10codec, simplebus, a10codec_pcm_driver, 0, 0);
1206 MODULE_DEPEND(a10codec, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
1207 MODULE_VERSION(a10codec, 1);
1208