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