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 * $FreeBSD$
27 */
28
29 /*
30 * Allwinner A10/A20 Audio Codec
31 */
32
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/bus.h>
39 #include <sys/rman.h>
40 #include <sys/condvar.h>
41 #include <sys/kernel.h>
42 #include <sys/module.h>
43 #include <sys/gpio.h>
44
45 #include <machine/bus.h>
46
47 #include <dev/sound/pcm/sound.h>
48 #include <dev/sound/chip.h>
49
50 #include <dev/ofw/ofw_bus.h>
51 #include <dev/ofw/ofw_bus_subr.h>
52
53 #include <dev/extres/clk/clk.h>
54
55 #include "sunxi_dma_if.h"
56 #include "mixer_if.h"
57 #include "gpio_if.h"
58
59 #define TX_TRIG_LEVEL 0xf
60 #define RX_TRIG_LEVEL 0x7
61 #define DRQ_CLR_CNT 0x3
62
63 #define AC_DAC_DPC 0x00
64 #define DAC_DPC_EN_DA 0x80000000
65 #define AC_DAC_FIFOC 0x04
66 #define DAC_FIFOC_FS_SHIFT 29
67 #define DAC_FIFOC_FS_MASK (7U << DAC_FIFOC_FS_SHIFT)
68 #define DAC_FS_48KHZ 0
69 #define DAC_FS_32KHZ 1
70 #define DAC_FS_24KHZ 2
71 #define DAC_FS_16KHZ 3
72 #define DAC_FS_12KHZ 4
73 #define DAC_FS_8KHZ 5
74 #define DAC_FS_192KHZ 6
75 #define DAC_FS_96KHZ 7
76 #define DAC_FIFOC_FIFO_MODE_SHIFT 24
77 #define DAC_FIFOC_FIFO_MODE_MASK (3U << DAC_FIFOC_FIFO_MODE_SHIFT)
78 #define FIFO_MODE_24_31_8 0
79 #define FIFO_MODE_16_31_16 0
80 #define FIFO_MODE_16_15_0 1
81 #define DAC_FIFOC_DRQ_CLR_CNT_SHIFT 21
82 #define DAC_FIFOC_DRQ_CLR_CNT_MASK (3U << DAC_FIFOC_DRQ_CLR_CNT_SHIFT)
83 #define DAC_FIFOC_TX_TRIG_LEVEL_SHIFT 8
84 #define DAC_FIFOC_TX_TRIG_LEVEL_MASK (0x7f << DAC_FIFOC_TX_TRIG_LEVEL_SHIFT)
85 #define DAC_FIFOC_MONO_EN (1U << 6)
86 #define DAC_FIFOC_TX_BITS (1U << 5)
87 #define DAC_FIFOC_DRQ_EN (1U << 4)
88 #define DAC_FIFOC_FIFO_FLUSH (1U << 0)
89 #define AC_DAC_FIFOS 0x08
90 #define AC_DAC_TXDATA 0x0c
91 #define AC_DAC_ACTL 0x10
92 #define DAC_ACTL_DACAREN (1U << 31)
93 #define DAC_ACTL_DACALEN (1U << 30)
94 #define DAC_ACTL_MIXEN (1U << 29)
95 #define DAC_ACTL_DACPAS (1U << 8)
96 #define DAC_ACTL_PAMUTE (1U << 6)
97 #define DAC_ACTL_PAVOL_SHIFT 0
98 #define DAC_ACTL_PAVOL_MASK (0x3f << DAC_ACTL_PAVOL_SHIFT)
99 #define AC_ADC_FIFOC 0x1c
100 #define ADC_FIFOC_FS_SHIFT 29
101 #define ADC_FIFOC_FS_MASK (7U << ADC_FIFOC_FS_SHIFT)
102 #define ADC_FS_48KHZ 0
103 #define ADC_FIFOC_EN_AD (1U << 28)
104 #define ADC_FIFOC_RX_FIFO_MODE (1U << 24)
105 #define ADC_FIFOC_RX_TRIG_LEVEL_SHIFT 8
106 #define ADC_FIFOC_RX_TRIG_LEVEL_MASK (0x1f << ADC_FIFOC_RX_TRIG_LEVEL_SHIFT)
107 #define ADC_FIFOC_MONO_EN (1U << 7)
108 #define ADC_FIFOC_RX_BITS (1U << 6)
109 #define ADC_FIFOC_DRQ_EN (1U << 4)
110 #define ADC_FIFOC_FIFO_FLUSH (1U << 1)
111 #define AC_ADC_FIFOS 0x20
112 #define AC_ADC_RXDATA 0x24
113 #define AC_ADC_ACTL 0x28
114 #define ADC_ACTL_ADCREN (1U << 31)
115 #define ADC_ACTL_ADCLEN (1U << 30)
116 #define ADC_ACTL_PREG1EN (1U << 29)
117 #define ADC_ACTL_PREG2EN (1U << 28)
118 #define ADC_ACTL_VMICEN (1U << 27)
119 #define ADC_ACTL_ADCG_SHIFT 20
120 #define ADC_ACTL_ADCG_MASK (7U << ADC_ACTL_ADCG_SHIFT)
121 #define ADC_ACTL_ADCIS_SHIFT 17
122 #define ADC_ACTL_ADCIS_MASK (7U << ADC_ACTL_ADCIS_SHIFT)
123 #define ADC_IS_LINEIN 0
124 #define ADC_IS_FMIN 1
125 #define ADC_IS_MIC1 2
126 #define ADC_IS_MIC2 3
127 #define ADC_IS_MIC1_L_MIC2_R 4
128 #define ADC_IS_MIC1_LR_MIC2_LR 5
129 #define ADC_IS_OMIX 6
130 #define ADC_IS_LINEIN_L_MIC1_R 7
131 #define ADC_ACTL_LNRDF (1U << 16)
132 #define ADC_ACTL_LNPREG_SHIFT 13
133 #define ADC_ACTL_LNPREG_MASK (7U << ADC_ACTL_LNPREG_SHIFT)
134 #define ADC_ACTL_PA_EN (1U << 4)
135 #define ADC_ACTL_DDE (1U << 3)
136 #define AC_DAC_CNT 0x30
137 #define AC_ADC_CNT 0x34
138
139 static uint32_t a10codec_fmt[] = {
140 SND_FORMAT(AFMT_S16_LE, 1, 0),
141 SND_FORMAT(AFMT_S16_LE, 2, 0),
142 0
143 };
144
145 static struct pcmchan_caps a10codec_pcaps = { 8000, 192000, a10codec_fmt, 0 };
146 static struct pcmchan_caps a10codec_rcaps = { 8000, 48000, a10codec_fmt, 0 };
147
148 struct a10codec_info;
149
150 struct a10codec_chinfo {
151 struct snd_dbuf *buffer;
152 struct pcm_channel *channel;
153 struct a10codec_info *parent;
154 bus_dmamap_t dmamap;
155 void *dmaaddr;
156 bus_addr_t physaddr;
157 bus_size_t fifo;
158 device_t dmac;
159 void *dmachan;
160
161 int dir;
162 int run;
163 uint32_t pos;
164 uint32_t format;
165 uint32_t blocksize;
166 uint32_t speed;
167 };
168
169 struct a10codec_info {
170 device_t dev;
171 struct resource *res[2];
172 struct mtx *lock;
173 bus_dma_tag_t dmat;
174 unsigned dmasize;
175 void *ih;
176
177 unsigned drqtype_codec;
178 unsigned drqtype_sdram;
179
180 struct a10codec_chinfo play;
181 struct a10codec_chinfo rec;
182 };
183
184 static struct resource_spec a10codec_spec[] = {
185 { SYS_RES_MEMORY, 0, RF_ACTIVE },
186 { SYS_RES_IRQ, 0, RF_ACTIVE },
187 { -1, 0 }
188 };
189
190 #define CODEC_READ(sc, reg) bus_read_4((sc)->res[0], (reg))
191 #define CODEC_WRITE(sc, reg, val) bus_write_4((sc)->res[0], (reg), (val))
192
193 /*
194 * Mixer interface
195 */
196
197 static int
a10codec_mixer_init(struct snd_mixer * m)198 a10codec_mixer_init(struct snd_mixer *m)
199 {
200 struct a10codec_info *sc = mix_getdevinfo(m);
201 pcell_t prop[4];
202 phandle_t node;
203 device_t gpio;
204 uint32_t val;
205 ssize_t len;
206 int pin;
207
208 mix_setdevs(m, SOUND_MASK_VOLUME | SOUND_MASK_LINE | SOUND_MASK_RECLEV);
209 mix_setrecdevs(m, SOUND_MASK_LINE | SOUND_MASK_LINE1 | SOUND_MASK_MIC);
210
211 /* Unmute input source to PA */
212 val = CODEC_READ(sc, AC_DAC_ACTL);
213 val |= DAC_ACTL_PAMUTE;
214 CODEC_WRITE(sc, AC_DAC_ACTL, val);
215
216 /* Enable PA */
217 val = CODEC_READ(sc, AC_ADC_ACTL);
218 val |= ADC_ACTL_PA_EN;
219 CODEC_WRITE(sc, AC_ADC_ACTL, val);
220
221 /* Unmute PA */
222 node = ofw_bus_get_node(sc->dev);
223 len = OF_getencprop(node, "allwinner,pa-gpios", prop, sizeof(prop));
224 if (len > 0 && (len / sizeof(prop[0])) == 4) {
225 gpio = OF_device_from_xref(prop[0]);
226 if (gpio != NULL) {
227 pin = prop[1] * 32 + prop[2];
228 GPIO_PIN_SETFLAGS(gpio, pin, GPIO_PIN_OUTPUT);
229 GPIO_PIN_SET(gpio, pin, GPIO_PIN_LOW);
230 }
231 }
232
233 return (0);
234 }
235
236 static const struct a10codec_mixer {
237 unsigned reg;
238 unsigned mask;
239 unsigned shift;
240 } a10codec_mixers[SOUND_MIXER_NRDEVICES] = {
241 [SOUND_MIXER_VOLUME] = { AC_DAC_ACTL, DAC_ACTL_PAVOL_MASK,
242 DAC_ACTL_PAVOL_SHIFT },
243 [SOUND_MIXER_LINE] = { AC_ADC_ACTL, ADC_ACTL_LNPREG_MASK,
244 ADC_ACTL_LNPREG_SHIFT },
245 [SOUND_MIXER_RECLEV] = { AC_ADC_ACTL, ADC_ACTL_ADCG_MASK,
246 ADC_ACTL_ADCG_SHIFT },
247 };
248
249 static int
a10codec_mixer_set(struct snd_mixer * m,unsigned dev,unsigned left,unsigned right)250 a10codec_mixer_set(struct snd_mixer *m, unsigned dev, unsigned left,
251 unsigned right)
252 {
253 struct a10codec_info *sc = mix_getdevinfo(m);
254 uint32_t val;
255 unsigned nvol, max;
256
257 max = a10codec_mixers[dev].mask >> a10codec_mixers[dev].shift;
258 nvol = (left * max) / 100;
259
260 val = CODEC_READ(sc, a10codec_mixers[dev].reg);
261 val &= ~a10codec_mixers[dev].mask;
262 val |= (nvol << a10codec_mixers[dev].shift);
263 CODEC_WRITE(sc, a10codec_mixers[dev].reg, val);
264
265 left = right = (left * 100) / max;
266 return (left | (right << 8));
267 }
268
269 static uint32_t
a10codec_mixer_setrecsrc(struct snd_mixer * m,uint32_t src)270 a10codec_mixer_setrecsrc(struct snd_mixer *m, uint32_t src)
271 {
272 struct a10codec_info *sc = mix_getdevinfo(m);
273 uint32_t val;
274
275 val = CODEC_READ(sc, AC_ADC_ACTL);
276
277 switch (src) {
278 case SOUND_MASK_LINE: /* line-in */
279 val &= ~ADC_ACTL_ADCIS_MASK;
280 val |= (ADC_IS_LINEIN << ADC_ACTL_ADCIS_SHIFT);
281 break;
282 case SOUND_MASK_MIC: /* MIC1 */
283 val &= ~ADC_ACTL_ADCIS_MASK;
284 val |= (ADC_IS_MIC1 << ADC_ACTL_ADCIS_SHIFT);
285 break;
286 case SOUND_MASK_LINE1: /* MIC2 */
287 val &= ~ADC_ACTL_ADCIS_MASK;
288 val |= (ADC_IS_MIC2 << ADC_ACTL_ADCIS_SHIFT);
289 break;
290 default:
291 break;
292 }
293
294 CODEC_WRITE(sc, AC_ADC_ACTL, val);
295
296 switch ((val & ADC_ACTL_ADCIS_MASK) >> ADC_ACTL_ADCIS_SHIFT) {
297 case ADC_IS_LINEIN:
298 return (SOUND_MASK_LINE);
299 case ADC_IS_MIC1:
300 return (SOUND_MASK_MIC);
301 case ADC_IS_MIC2:
302 return (SOUND_MASK_LINE1);
303 default:
304 return (0);
305 }
306 }
307
308 static kobj_method_t a10codec_mixer_methods[] = {
309 KOBJMETHOD(mixer_init, a10codec_mixer_init),
310 KOBJMETHOD(mixer_set, a10codec_mixer_set),
311 KOBJMETHOD(mixer_setrecsrc, a10codec_mixer_setrecsrc),
312 KOBJMETHOD_END
313 };
314 MIXER_DECLARE(a10codec_mixer);
315
316
317 /*
318 * Channel interface
319 */
320
321 static void
a10codec_dmamap_cb(void * arg,bus_dma_segment_t * segs,int nseg,int error)322 a10codec_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
323 {
324 struct a10codec_chinfo *ch = arg;
325
326 if (error != 0)
327 return;
328
329 ch->physaddr = segs[0].ds_addr;
330 }
331
332 static void
a10codec_transfer(struct a10codec_chinfo * ch)333 a10codec_transfer(struct a10codec_chinfo *ch)
334 {
335 bus_addr_t src, dst;
336 int error;
337
338 if (ch->dir == PCMDIR_PLAY) {
339 src = ch->physaddr + ch->pos;
340 dst = ch->fifo;
341 } else {
342 src = ch->fifo;
343 dst = ch->physaddr + ch->pos;
344 }
345
346 error = SUNXI_DMA_TRANSFER(ch->dmac, ch->dmachan, src, dst,
347 ch->blocksize);
348 if (error) {
349 ch->run = 0;
350 device_printf(ch->parent->dev, "DMA transfer failed: %d\n",
351 error);
352 }
353 }
354
355 static void
a10codec_dmaconfig(struct a10codec_chinfo * ch)356 a10codec_dmaconfig(struct a10codec_chinfo *ch)
357 {
358 struct a10codec_info *sc = ch->parent;
359 struct sunxi_dma_config conf;
360
361 memset(&conf, 0, sizeof(conf));
362 conf.src_width = conf.dst_width = 16;
363 conf.src_burst_len = conf.dst_burst_len = 4;
364
365 if (ch->dir == PCMDIR_PLAY) {
366 conf.dst_noincr = true;
367 conf.src_drqtype = sc->drqtype_sdram;
368 conf.dst_drqtype = sc->drqtype_codec;
369 } else {
370 conf.src_noincr = true;
371 conf.src_drqtype = sc->drqtype_codec;
372 conf.dst_drqtype = sc->drqtype_sdram;
373 }
374
375 SUNXI_DMA_SET_CONFIG(ch->dmac, ch->dmachan, &conf);
376 }
377
378 static void
a10codec_dmaintr(void * priv)379 a10codec_dmaintr(void *priv)
380 {
381 struct a10codec_chinfo *ch = priv;
382 unsigned bufsize;
383
384 bufsize = sndbuf_getsize(ch->buffer);
385
386 ch->pos += ch->blocksize;
387 if (ch->pos >= bufsize)
388 ch->pos -= bufsize;
389
390 if (ch->run) {
391 chn_intr(ch->channel);
392 a10codec_transfer(ch);
393 }
394 }
395
396 static unsigned
a10codec_fs(struct a10codec_chinfo * ch)397 a10codec_fs(struct a10codec_chinfo *ch)
398 {
399 switch (ch->speed) {
400 case 48000:
401 return (DAC_FS_48KHZ);
402 case 24000:
403 return (DAC_FS_24KHZ);
404 case 12000:
405 return (DAC_FS_12KHZ);
406 case 192000:
407 return (DAC_FS_192KHZ);
408 case 32000:
409 return (DAC_FS_32KHZ);
410 case 16000:
411 return (DAC_FS_16KHZ);
412 case 8000:
413 return (DAC_FS_8KHZ);
414 case 96000:
415 return (DAC_FS_96KHZ);
416 default:
417 return (DAC_FS_48KHZ);
418 }
419 }
420
421 static void
a10codec_start(struct a10codec_chinfo * ch)422 a10codec_start(struct a10codec_chinfo *ch)
423 {
424 struct a10codec_info *sc = ch->parent;
425 uint32_t val;
426
427 ch->pos = 0;
428
429 if (ch->dir == PCMDIR_PLAY) {
430 /* Flush DAC FIFO */
431 CODEC_WRITE(sc, AC_DAC_FIFOC, DAC_FIFOC_FIFO_FLUSH);
432
433 /* Clear DAC FIFO status */
434 CODEC_WRITE(sc, AC_DAC_FIFOS, CODEC_READ(sc, AC_DAC_FIFOS));
435
436 /* Enable DAC analog left/right channels and output mixer */
437 val = CODEC_READ(sc, AC_DAC_ACTL);
438 val |= DAC_ACTL_DACAREN;
439 val |= DAC_ACTL_DACALEN;
440 val |= DAC_ACTL_DACPAS;
441 CODEC_WRITE(sc, AC_DAC_ACTL, val);
442
443 /* Configure DAC DMA channel */
444 a10codec_dmaconfig(ch);
445
446 /* Configure DAC FIFO */
447 CODEC_WRITE(sc, AC_DAC_FIFOC,
448 (AFMT_CHANNEL(ch->format) == 1 ? DAC_FIFOC_MONO_EN : 0) |
449 (a10codec_fs(ch) << DAC_FIFOC_FS_SHIFT) |
450 (FIFO_MODE_16_15_0 << DAC_FIFOC_FIFO_MODE_SHIFT) |
451 (DRQ_CLR_CNT << DAC_FIFOC_DRQ_CLR_CNT_SHIFT) |
452 (TX_TRIG_LEVEL << DAC_FIFOC_TX_TRIG_LEVEL_SHIFT));
453
454 /* Enable DAC DRQ */
455 val = CODEC_READ(sc, AC_DAC_FIFOC);
456 val |= DAC_FIFOC_DRQ_EN;
457 CODEC_WRITE(sc, AC_DAC_FIFOC, val);
458 } else {
459 /* Flush ADC FIFO */
460 CODEC_WRITE(sc, AC_ADC_FIFOC, ADC_FIFOC_FIFO_FLUSH);
461
462 /* Clear ADC FIFO status */
463 CODEC_WRITE(sc, AC_ADC_FIFOS, CODEC_READ(sc, AC_ADC_FIFOS));
464
465 /* Enable ADC analog left/right channels, MIC1 preamp,
466 * and VMIC pin voltage
467 */
468 val = CODEC_READ(sc, AC_ADC_ACTL);
469 val |= ADC_ACTL_ADCREN;
470 val |= ADC_ACTL_ADCLEN;
471 val |= ADC_ACTL_PREG1EN;
472 val |= ADC_ACTL_VMICEN;
473 CODEC_WRITE(sc, AC_ADC_ACTL, val);
474
475 /* Configure ADC DMA channel */
476 a10codec_dmaconfig(ch);
477
478 /* Configure ADC FIFO */
479 CODEC_WRITE(sc, AC_ADC_FIFOC,
480 ADC_FIFOC_EN_AD |
481 ADC_FIFOC_RX_FIFO_MODE |
482 (AFMT_CHANNEL(ch->format) == 1 ? ADC_FIFOC_MONO_EN : 0) |
483 (a10codec_fs(ch) << ADC_FIFOC_FS_SHIFT) |
484 (RX_TRIG_LEVEL << ADC_FIFOC_RX_TRIG_LEVEL_SHIFT));
485
486 /* Enable ADC DRQ */
487 val = CODEC_READ(sc, AC_ADC_FIFOC);
488 val |= ADC_FIFOC_DRQ_EN;
489 CODEC_WRITE(sc, AC_ADC_FIFOC, val);
490 }
491
492 /* Start DMA transfer */
493 a10codec_transfer(ch);
494 }
495
496 static void
a10codec_stop(struct a10codec_chinfo * ch)497 a10codec_stop(struct a10codec_chinfo *ch)
498 {
499 struct a10codec_info *sc = ch->parent;
500 uint32_t val;
501
502 /* Disable DMA channel */
503 SUNXI_DMA_HALT(ch->dmac, ch->dmachan);
504
505 if (ch->dir == PCMDIR_PLAY) {
506 /* Disable DAC analog left/right channels and output mixer */
507 val = CODEC_READ(sc, AC_DAC_ACTL);
508 val &= ~DAC_ACTL_DACAREN;
509 val &= ~DAC_ACTL_DACALEN;
510 val &= ~DAC_ACTL_DACPAS;
511 CODEC_WRITE(sc, AC_DAC_ACTL, val);
512
513 /* Disable DAC DRQ */
514 CODEC_WRITE(sc, AC_DAC_FIFOC, 0);
515 } else {
516 /* Disable ADC analog left/right channels, MIC1 preamp,
517 * and VMIC pin voltage
518 */
519 val = CODEC_READ(sc, AC_ADC_ACTL);
520 val &= ~ADC_ACTL_ADCREN;
521 val &= ~ADC_ACTL_ADCLEN;
522 val &= ~ADC_ACTL_PREG1EN;
523 val &= ~ADC_ACTL_VMICEN;
524 CODEC_WRITE(sc, AC_ADC_ACTL, val);
525
526 /* Disable ADC DRQ */
527 CODEC_WRITE(sc, AC_ADC_FIFOC, 0);
528 }
529 }
530
531 static void *
a10codec_chan_init(kobj_t obj,void * devinfo,struct snd_dbuf * b,struct pcm_channel * c,int dir)532 a10codec_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
533 struct pcm_channel *c, int dir)
534 {
535 struct a10codec_info *sc = devinfo;
536 struct a10codec_chinfo *ch = dir == PCMDIR_PLAY ? &sc->play : &sc->rec;
537 int error;
538
539 ch->parent = sc;
540 ch->channel = c;
541 ch->buffer = b;
542 ch->dir = dir;
543 ch->fifo = rman_get_start(sc->res[0]) +
544 (dir == PCMDIR_REC ? AC_ADC_RXDATA : AC_DAC_TXDATA);
545
546 ch->dmac = devclass_get_device(devclass_find("a10dmac"), 0);
547 if (ch->dmac == NULL) {
548 device_printf(sc->dev, "cannot find DMA controller\n");
549 return (NULL);
550 }
551 ch->dmachan = SUNXI_DMA_ALLOC(ch->dmac, false, a10codec_dmaintr, ch);
552 if (ch->dmachan == NULL) {
553 device_printf(sc->dev, "cannot allocate DMA channel\n");
554 return (NULL);
555 }
556
557 error = bus_dmamem_alloc(sc->dmat, &ch->dmaaddr,
558 BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &ch->dmamap);
559 if (error != 0) {
560 device_printf(sc->dev, "cannot allocate channel buffer\n");
561 return (NULL);
562 }
563 error = bus_dmamap_load(sc->dmat, ch->dmamap, ch->dmaaddr,
564 sc->dmasize, a10codec_dmamap_cb, ch, BUS_DMA_NOWAIT);
565 if (error != 0) {
566 device_printf(sc->dev, "cannot load DMA map\n");
567 return (NULL);
568 }
569 memset(ch->dmaaddr, 0, sc->dmasize);
570
571 if (sndbuf_setup(ch->buffer, ch->dmaaddr, sc->dmasize) != 0) {
572 device_printf(sc->dev, "cannot setup sndbuf\n");
573 return (NULL);
574 }
575
576 return (ch);
577 }
578
579 static int
a10codec_chan_free(kobj_t obj,void * data)580 a10codec_chan_free(kobj_t obj, void *data)
581 {
582 struct a10codec_chinfo *ch = data;
583 struct a10codec_info *sc = ch->parent;
584
585 SUNXI_DMA_FREE(ch->dmac, ch->dmachan);
586 bus_dmamap_unload(sc->dmat, ch->dmamap);
587 bus_dmamem_free(sc->dmat, ch->dmaaddr, ch->dmamap);
588
589 return (0);
590 }
591
592 static int
a10codec_chan_setformat(kobj_t obj,void * data,uint32_t format)593 a10codec_chan_setformat(kobj_t obj, void *data, uint32_t format)
594 {
595 struct a10codec_chinfo *ch = data;
596
597 ch->format = format;
598
599 return (0);
600 }
601
602 static uint32_t
a10codec_chan_setspeed(kobj_t obj,void * data,uint32_t speed)603 a10codec_chan_setspeed(kobj_t obj, void *data, uint32_t speed)
604 {
605 struct a10codec_chinfo *ch = data;
606
607 /*
608 * The codec supports full duplex operation but both DAC and ADC
609 * use the same source clock (PLL2). Limit the available speeds to
610 * those supported by a 24576000 Hz input.
611 */
612 switch (speed) {
613 case 8000:
614 case 12000:
615 case 16000:
616 case 24000:
617 case 32000:
618 case 48000:
619 ch->speed = speed;
620 break;
621 case 96000:
622 case 192000:
623 /* 96 KHz / 192 KHz mode only supported for playback */
624 if (ch->dir == PCMDIR_PLAY) {
625 ch->speed = speed;
626 } else {
627 ch->speed = 48000;
628 }
629 break;
630 case 44100:
631 ch->speed = 48000;
632 break;
633 case 22050:
634 ch->speed = 24000;
635 break;
636 case 11025:
637 ch->speed = 12000;
638 break;
639 default:
640 ch->speed = 48000;
641 break;
642 }
643
644 return (ch->speed);
645 }
646
647 static uint32_t
a10codec_chan_setblocksize(kobj_t obj,void * data,uint32_t blocksize)648 a10codec_chan_setblocksize(kobj_t obj, void *data, uint32_t blocksize)
649 {
650 struct a10codec_chinfo *ch = data;
651
652 ch->blocksize = blocksize & ~3;
653
654 return (ch->blocksize);
655 }
656
657 static int
a10codec_chan_trigger(kobj_t obj,void * data,int go)658 a10codec_chan_trigger(kobj_t obj, void *data, int go)
659 {
660 struct a10codec_chinfo *ch = data;
661 struct a10codec_info *sc = ch->parent;
662
663 if (!PCMTRIG_COMMON(go))
664 return (0);
665
666 snd_mtxlock(sc->lock);
667 switch (go) {
668 case PCMTRIG_START:
669 ch->run = 1;
670 a10codec_start(ch);
671 break;
672 case PCMTRIG_STOP:
673 case PCMTRIG_ABORT:
674 ch->run = 0;
675 a10codec_stop(ch);
676 break;
677 default:
678 break;
679 }
680 snd_mtxunlock(sc->lock);
681
682 return (0);
683 }
684
685 static uint32_t
a10codec_chan_getptr(kobj_t obj,void * data)686 a10codec_chan_getptr(kobj_t obj, void *data)
687 {
688 struct a10codec_chinfo *ch = data;
689
690 return (ch->pos);
691 }
692
693 static struct pcmchan_caps *
a10codec_chan_getcaps(kobj_t obj,void * data)694 a10codec_chan_getcaps(kobj_t obj, void *data)
695 {
696 struct a10codec_chinfo *ch = data;
697
698 if (ch->dir == PCMDIR_PLAY) {
699 return (&a10codec_pcaps);
700 } else {
701 return (&a10codec_rcaps);
702 }
703 }
704
705 static kobj_method_t a10codec_chan_methods[] = {
706 KOBJMETHOD(channel_init, a10codec_chan_init),
707 KOBJMETHOD(channel_free, a10codec_chan_free),
708 KOBJMETHOD(channel_setformat, a10codec_chan_setformat),
709 KOBJMETHOD(channel_setspeed, a10codec_chan_setspeed),
710 KOBJMETHOD(channel_setblocksize, a10codec_chan_setblocksize),
711 KOBJMETHOD(channel_trigger, a10codec_chan_trigger),
712 KOBJMETHOD(channel_getptr, a10codec_chan_getptr),
713 KOBJMETHOD(channel_getcaps, a10codec_chan_getcaps),
714 KOBJMETHOD_END
715 };
716 CHANNEL_DECLARE(a10codec_chan);
717
718
719 /*
720 * Device interface
721 */
722
723 static struct ofw_compat_data compat_data[] = {
724 {"allwinner,sun4i-a10-codec", 1},
725 {"allwinner,sun7i-a20-codec", 1},
726 {NULL, 0},
727 };
728
729 static int
a10codec_probe(device_t dev)730 a10codec_probe(device_t dev)
731 {
732 if (!ofw_bus_status_okay(dev))
733 return (ENXIO);
734
735 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
736 return (ENXIO);
737
738 device_set_desc(dev, "Allwinner Audio Codec");
739 return (BUS_PROBE_DEFAULT);
740 }
741
742 static int
a10codec_attach(device_t dev)743 a10codec_attach(device_t dev)
744 {
745 struct a10codec_info *sc;
746 char status[SND_STATUSLEN];
747 clk_t clk_apb, clk_codec;
748 uint32_t val;
749 int error;
750
751 sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
752 sc->dev = dev;
753 sc->lock = snd_mtxcreate(device_get_nameunit(dev), "a10codec softc");
754
755 if (bus_alloc_resources(dev, a10codec_spec, sc->res)) {
756 device_printf(dev, "cannot allocate resources for device\n");
757 error = ENXIO;
758 goto fail;
759 }
760
761 /* XXX DRQ types should come from FDT, but how? */
762 if (ofw_bus_is_compatible(dev, "allwinner,sun4i-a10-codec") ||
763 ofw_bus_is_compatible(dev, "allwinner,sun7i-a20-codec")) {
764 sc->drqtype_codec = 19;
765 sc->drqtype_sdram = 22;
766 } else {
767 device_printf(dev, "DRQ types not known for this SoC\n");
768 error = ENXIO;
769 goto fail;
770 }
771
772 sc->dmasize = 131072;
773 error = bus_dma_tag_create(
774 bus_get_dma_tag(dev),
775 4, sc->dmasize, /* alignment, boundary */
776 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
777 BUS_SPACE_MAXADDR, /* highaddr */
778 NULL, NULL, /* filter, filterarg */
779 sc->dmasize, 1, /* maxsize, nsegs */
780 sc->dmasize, 0, /* maxsegsize, flags */
781 NULL, NULL, /* lockfunc, lockarg */
782 &sc->dmat);
783 if (error != 0) {
784 device_printf(dev, "cannot create DMA tag\n");
785 goto fail;
786 }
787
788 /* Get clocks */
789 error = clk_get_by_ofw_name(dev, 0, "apb", &clk_apb);
790 if (error != 0) {
791 device_printf(dev, "cannot find apb clock\n");
792 goto fail;
793 }
794 error = clk_get_by_ofw_name(dev, 0, "codec", &clk_codec);
795 if (error != 0) {
796 device_printf(dev, "cannot find codec clock\n");
797 goto fail;
798 }
799
800 /* Gating APB clock for codec */
801 error = clk_enable(clk_apb);
802 if (error != 0) {
803 device_printf(dev, "cannot enable apb clock\n");
804 goto fail;
805 }
806 /* Activate audio codec clock. According to the A10 and A20 user
807 * manuals, Audio_pll can be either 24.576MHz or 22.5792MHz. Most
808 * audio sampling rates require an 24.576MHz input clock with the
809 * exception of 44.1kHz, 22.05kHz, and 11.025kHz. Unfortunately,
810 * both capture and playback use the same clock source so to
811 * safely support independent full duplex operation, we use a fixed
812 * 24.576MHz clock source and don't advertise native support for
813 * the three sampling rates that require a 22.5792MHz input.
814 */
815 error = clk_set_freq(clk_codec, 24576000, CLK_SET_ROUND_DOWN);
816 if (error != 0) {
817 device_printf(dev, "cannot set codec clock frequency\n");
818 goto fail;
819 }
820 /* Enable audio codec clock */
821 error = clk_enable(clk_codec);
822 if (error != 0) {
823 device_printf(dev, "cannot enable codec clock\n");
824 goto fail;
825 }
826
827 /* Enable DAC */
828 val = CODEC_READ(sc, AC_DAC_DPC);
829 val |= DAC_DPC_EN_DA;
830 CODEC_WRITE(sc, AC_DAC_DPC, val);
831
832 #ifdef notdef
833 error = snd_setup_intr(dev, sc->irq, INTR_MPSAFE, a10codec_intr, sc,
834 &sc->ih);
835 if (error != 0) {
836 device_printf(dev, "could not setup interrupt handler\n");
837 goto fail;
838 }
839 #endif
840
841 if (mixer_init(dev, &a10codec_mixer_class, sc)) {
842 device_printf(dev, "mixer_init failed\n");
843 goto fail;
844 }
845
846 pcm_setflags(dev, pcm_getflags(dev) | SD_F_MPSAFE);
847
848 if (pcm_register(dev, sc, 1, 1)) {
849 device_printf(dev, "pcm_register failed\n");
850 goto fail;
851 }
852
853 pcm_addchan(dev, PCMDIR_PLAY, &a10codec_chan_class, sc);
854 pcm_addchan(dev, PCMDIR_REC, &a10codec_chan_class, sc);
855
856 snprintf(status, SND_STATUSLEN, "at %s", ofw_bus_get_name(dev));
857 pcm_setstatus(dev, status);
858
859 return (0);
860
861 fail:
862 bus_release_resources(dev, a10codec_spec, sc->res);
863 snd_mtxfree(sc->lock);
864 free(sc, M_DEVBUF);
865
866 return (error);
867 }
868
869 static device_method_t a10codec_pcm_methods[] = {
870 /* Device interface */
871 DEVMETHOD(device_probe, a10codec_probe),
872 DEVMETHOD(device_attach, a10codec_attach),
873
874 DEVMETHOD_END
875 };
876
877 static driver_t a10codec_pcm_driver = {
878 "pcm",
879 a10codec_pcm_methods,
880 PCM_SOFTC_SIZE,
881 };
882
883 DRIVER_MODULE(a10codec, simplebus, a10codec_pcm_driver, pcm_devclass, 0, 0);
884 MODULE_DEPEND(a10codec, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
885 MODULE_VERSION(a10codec, 1);
886