]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/mips/ingenic/jz4780_aic.c
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r304149, and update
[FreeBSD/FreeBSD.git] / sys / mips / ingenic / jz4780_aic.c
1 /*-
2  * Copyright (c) 2016 Ruslan Bukin <br@bsdpad.com>
3  * All rights reserved.
4  *
5  * This software was developed by SRI International and the University of
6  * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
7  * ("CTSRD"), as part of the DARPA CRASH research programme.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30
31 /* Ingenic JZ4780 Audio Interface Controller (AIC). */
32
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/conf.h>
39 #include <sys/bus.h>
40 #include <sys/kernel.h>
41 #include <sys/module.h>
42 #include <sys/lock.h>
43 #include <sys/mutex.h>
44 #include <sys/resource.h>
45 #include <sys/rman.h>
46
47 #include <machine/bus.h>
48
49 #include <dev/fdt/fdt_common.h>
50 #include <dev/ofw/ofw_bus.h>
51 #include <dev/ofw/ofw_bus_subr.h>
52
53 #include <dev/sound/pcm/sound.h>
54 #include <dev/sound/chip.h>
55 #include <mixer_if.h>
56
57 #include <dev/extres/clk/clk.h>
58 #include <dev/xdma/xdma.h>
59
60 #include <mips/ingenic/jz4780_common.h>
61 #include <mips/ingenic/jz4780_aic.h>
62
63 #define AIC_NCHANNELS           1
64
65 struct aic_softc {
66         device_t                dev;
67         struct resource         *res[1];
68         bus_space_tag_t         bst;
69         bus_space_handle_t      bsh;
70         struct mtx              *lock;
71         int                     pos;
72         bus_dma_tag_t           dma_tag;
73         bus_dmamap_t            dma_map;
74         bus_addr_t              buf_base_phys;
75         uint32_t                *buf_base;
76         uintptr_t               aic_fifo_paddr;
77         int                     dma_size;
78         clk_t                   clk_aic;
79         clk_t                   clk_i2s;
80         struct aic_rate         *sr;
81         void                    *ih;
82         struct xdma_channel     *xchan;
83         xdma_controller_t       *xdma_tx;
84         int                     internal_codec;
85 };
86
87 /* Channel registers */
88 struct sc_chinfo {
89         struct snd_dbuf         *buffer;
90         struct pcm_channel      *channel;
91         struct sc_pcminfo       *parent;
92
93         /* Channel information */
94         uint32_t        dir;
95         uint32_t        format;
96
97         /* Flags */
98         uint32_t        run;
99 };
100
101 /* PCM device private data */
102 struct sc_pcminfo {
103         device_t                dev;
104         uint32_t                chnum;
105         struct sc_chinfo        chan[AIC_NCHANNELS];
106         struct aic_softc        *sc;
107 };
108
109 static struct resource_spec aic_spec[] = {
110         { SYS_RES_MEMORY,       0,      RF_ACTIVE },
111         { -1, 0 }
112 };
113
114 static int aic_probe(device_t dev);
115 static int aic_attach(device_t dev);
116 static int aic_detach(device_t dev);
117 static int setup_xdma(struct sc_pcminfo *scp);
118
119 struct aic_rate {
120         uint32_t speed;
121 };
122
123 static struct aic_rate rate_map[] = {
124         { 48000 },
125         /* TODO: add more frequences */
126         { 0 },
127 };
128
129 /*
130  * Mixer interface.
131  */
132 static int
133 aicmixer_init(struct snd_mixer *m)
134 {
135         struct sc_pcminfo *scp;
136         struct aic_softc *sc;
137         int mask;
138
139         scp = mix_getdevinfo(m);
140         sc = scp->sc;
141
142         if (sc == NULL)
143                 return -1;
144
145         mask = SOUND_MASK_PCM;
146
147         snd_mtxlock(sc->lock);
148         pcm_setflags(scp->dev, pcm_getflags(scp->dev) | SD_F_SOFTPCMVOL);
149         mix_setdevs(m, mask);
150         snd_mtxunlock(sc->lock);
151
152         return (0);
153 }
154
155 static int
156 aicmixer_set(struct snd_mixer *m, unsigned dev,
157     unsigned left, unsigned right)
158 {
159         struct sc_pcminfo *scp;
160
161         scp = mix_getdevinfo(m);
162
163         /* Here we can configure hardware volume on our DAC */
164
165         return (0);
166 }
167
168 static kobj_method_t aicmixer_methods[] = {
169         KOBJMETHOD(mixer_init,      aicmixer_init),
170         KOBJMETHOD(mixer_set,       aicmixer_set),
171         KOBJMETHOD_END
172 };
173 MIXER_DECLARE(aicmixer);
174
175 /*
176  * Channel interface.
177  */
178 static void *
179 aicchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
180     struct pcm_channel *c, int dir)
181 {
182         struct sc_pcminfo *scp;
183         struct sc_chinfo *ch;
184         struct aic_softc *sc;
185
186         scp = (struct sc_pcminfo *)devinfo;
187         sc = scp->sc;
188
189         snd_mtxlock(sc->lock);
190         ch = &scp->chan[0];
191         ch->dir = dir;
192         ch->run = 0;
193         ch->buffer = b;
194         ch->channel = c;
195         ch->parent = scp;
196         snd_mtxunlock(sc->lock);
197
198         if (sndbuf_setup(ch->buffer, sc->buf_base, sc->dma_size) != 0) {
199                 device_printf(scp->dev, "Can't setup sndbuf.\n");
200                 return NULL;
201         }
202
203         return (ch);
204 }
205
206 static int
207 aicchan_free(kobj_t obj, void *data)
208 {
209         struct sc_chinfo *ch = data;
210         struct sc_pcminfo *scp = ch->parent;
211         struct aic_softc *sc = scp->sc;
212
213         snd_mtxlock(sc->lock);
214         /* TODO: free channel buffer */
215         snd_mtxunlock(sc->lock);
216
217         return (0);
218 }
219
220 static int
221 aicchan_setformat(kobj_t obj, void *data, uint32_t format)
222 {
223         struct sc_pcminfo *scp;
224         struct sc_chinfo *ch;
225
226         ch = data;
227         scp = ch->parent;
228
229         ch->format = format;
230
231         return (0);
232 }
233
234 static uint32_t
235 aicchan_setspeed(kobj_t obj, void *data, uint32_t speed)
236 {
237         struct sc_pcminfo *scp;
238         struct sc_chinfo *ch;
239         struct aic_rate *sr;
240         struct aic_softc *sc;
241         int threshold;
242         int i;
243
244         ch = data;
245         scp = ch->parent;
246         sc = scp->sc;
247
248         sr = NULL;
249
250         /* First look for equal frequency. */
251         for (i = 0; rate_map[i].speed != 0; i++) {
252                 if (rate_map[i].speed == speed)
253                         sr = &rate_map[i];
254         }
255
256         /* If no match, just find nearest. */
257         if (sr == NULL) {
258                 for (i = 0; rate_map[i].speed != 0; i++) {
259                         sr = &rate_map[i];
260                         threshold = sr->speed + ((rate_map[i + 1].speed != 0) ?
261                             ((rate_map[i + 1].speed - sr->speed) >> 1) : 0);
262                         if (speed < threshold)
263                                 break;
264                 }
265         }
266
267         sc->sr = sr;
268
269         /* Clocks can be reconfigured here. */
270
271         return (sr->speed);
272 }
273
274 static uint32_t
275 aicchan_setblocksize(kobj_t obj, void *data, uint32_t blocksize)
276 {
277         struct sc_pcminfo *scp;
278         struct sc_chinfo *ch;
279         struct aic_softc *sc;
280
281         ch = data;
282         scp = ch->parent;
283         sc = scp->sc;
284
285         sndbuf_resize(ch->buffer, sc->dma_size / blocksize, blocksize);
286
287         return (sndbuf_getblksz(ch->buffer));
288 }
289
290 static int
291 aic_intr(void *arg)
292 {
293         struct sc_pcminfo *scp;
294         xdma_channel_t *xchan;
295         struct sc_chinfo *ch;
296         struct aic_softc *sc;
297         xdma_config_t *conf;
298         int bufsize;
299
300         scp = arg;
301         sc = scp->sc;
302         ch = &scp->chan[0];
303
304         xchan = sc->xchan;
305         conf = &xchan->conf;
306
307         bufsize = sndbuf_getsize(ch->buffer);
308
309         sc->pos += conf->block_len;
310         if (sc->pos >= bufsize)
311                 sc->pos -= bufsize;
312
313         if (ch->run)
314                 chn_intr(ch->channel);
315
316         return (0);
317 }
318
319 static int
320 setup_xdma(struct sc_pcminfo *scp)
321 {
322         struct aic_softc *sc;
323         struct sc_chinfo *ch;
324         int fmt;
325         int err;
326
327         ch = &scp->chan[0];
328         sc = scp->sc;
329
330         fmt = sndbuf_getfmt(ch->buffer);
331
332         KASSERT(fmt & AFMT_16BIT, ("16-bit audio supported only."));
333
334         err = xdma_prep_cyclic(sc->xchan,
335             XDMA_MEM_TO_DEV,                    /* direction */
336             sc->buf_base_phys,                  /* src addr */
337             sc->aic_fifo_paddr,                 /* dst addr */
338             sndbuf_getblksz(ch->buffer),        /* block len */
339             sndbuf_getblkcnt(ch->buffer),       /* block num */
340             2,                                  /* src port width */
341             2);                                 /* dst port width */
342         if (err != 0) {
343                 device_printf(sc->dev, "Can't configure virtual channel\n");
344                 return (-1);
345         }
346
347         xdma_begin(sc->xchan);
348
349         return (0);
350 }
351
352 static int
353 aic_start(struct sc_pcminfo *scp)
354 {
355         struct aic_softc *sc;
356         int reg;
357
358         sc = scp->sc;
359
360         /* Ensure clock enabled. */
361         reg = READ4(sc, I2SCR);
362         reg |= (I2SCR_ESCLK);
363         WRITE4(sc, I2SCR, reg);
364
365         setup_xdma(scp);
366
367         reg = (AICCR_OSS_16 | AICCR_ISS_16);
368         reg |= (AICCR_CHANNEL_2);
369         reg |= (AICCR_TDMS);
370         reg |= (AICCR_ERPL);
371         WRITE4(sc, AICCR, reg);
372
373         return (0);
374 }
375
376 static int
377 aic_stop(struct sc_pcminfo *scp)
378 {
379         struct aic_softc *sc;
380         int reg;
381
382         sc = scp->sc;
383
384         reg = READ4(sc, AICCR);
385         reg &= ~(AICCR_TDMS | AICCR_ERPL);
386         WRITE4(sc, AICCR, reg);
387
388         xdma_terminate(sc->xchan);
389
390         return (0);
391 }
392
393 static int
394 aicchan_trigger(kobj_t obj, void *data, int go)
395 {
396         struct sc_pcminfo *scp;
397         struct sc_chinfo *ch;
398         struct aic_softc *sc;
399
400         ch = data;
401         scp = ch->parent;
402         sc = scp->sc;
403
404         snd_mtxlock(sc->lock);
405
406         switch (go) {
407         case PCMTRIG_START:
408                 ch->run = 1;
409
410                 sc->pos = 0;
411
412                 aic_start(scp);
413
414                 break;
415
416         case PCMTRIG_STOP:
417         case PCMTRIG_ABORT:
418                 ch->run = 0;
419
420                 aic_stop(scp);
421
422                 sc->pos = 0;
423
424                 bzero(sc->buf_base, sc->dma_size);
425
426                 break;
427         }
428
429         snd_mtxunlock(sc->lock);
430
431         return (0);
432 }
433
434 static uint32_t
435 aicchan_getptr(kobj_t obj, void *data)
436 {
437         struct sc_pcminfo *scp;
438         struct sc_chinfo *ch;
439         struct aic_softc *sc;
440
441         ch = data;
442         scp = ch->parent;
443         sc = scp->sc;
444
445         return (sc->pos);
446 }
447
448 static uint32_t aic_pfmt[] = {
449         SND_FORMAT(AFMT_S16_LE, 2, 0),
450         0
451 };
452
453 static struct pcmchan_caps aic_pcaps = {48000, 48000, aic_pfmt, 0};
454
455 static struct pcmchan_caps *
456 aicchan_getcaps(kobj_t obj, void *data)
457 {
458
459         return (&aic_pcaps);
460 }
461
462 static kobj_method_t aicchan_methods[] = {
463         KOBJMETHOD(channel_init,         aicchan_init),
464         KOBJMETHOD(channel_free,         aicchan_free),
465         KOBJMETHOD(channel_setformat,    aicchan_setformat),
466         KOBJMETHOD(channel_setspeed,     aicchan_setspeed),
467         KOBJMETHOD(channel_setblocksize, aicchan_setblocksize),
468         KOBJMETHOD(channel_trigger,      aicchan_trigger),
469         KOBJMETHOD(channel_getptr,       aicchan_getptr),
470         KOBJMETHOD(channel_getcaps,      aicchan_getcaps),
471         KOBJMETHOD_END
472 };
473 CHANNEL_DECLARE(aicchan);
474
475 static void
476 aic_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
477 {
478         bus_addr_t *addr;
479
480         if (err)
481                 return;
482
483         addr = (bus_addr_t*)arg;
484         *addr = segs[0].ds_addr;
485 }
486
487 static int
488 aic_dma_setup(struct aic_softc *sc)
489 {
490         device_t dev;
491         int err;
492
493         dev = sc->dev;
494
495         /* DMA buffer size. */
496         sc->dma_size = 131072;
497
498         /*
499          * Must use dma_size boundary as modulo feature required.
500          * Modulo feature allows setup circular buffer.
501          */
502         err = bus_dma_tag_create(
503             bus_get_dma_tag(sc->dev),
504             4, sc->dma_size,            /* alignment, boundary */
505             BUS_SPACE_MAXADDR_32BIT,    /* lowaddr */
506             BUS_SPACE_MAXADDR,          /* highaddr */
507             NULL, NULL,                 /* filter, filterarg */
508             sc->dma_size, 1,            /* maxsize, nsegments */
509             sc->dma_size, 0,            /* maxsegsize, flags */
510             NULL, NULL,                 /* lockfunc, lockarg */
511             &sc->dma_tag);
512         if (err) {
513                 device_printf(dev, "cannot create bus dma tag\n");
514                 return (-1);
515         }
516
517         err = bus_dmamem_alloc(sc->dma_tag, (void **)&sc->buf_base,
518             BUS_DMA_WAITOK | BUS_DMA_COHERENT, &sc->dma_map);
519         if (err) {
520                 device_printf(dev, "cannot allocate memory\n");
521                 return (-1);
522         }
523
524         err = bus_dmamap_load(sc->dma_tag, sc->dma_map, sc->buf_base,
525             sc->dma_size, aic_dmamap_cb, &sc->buf_base_phys, BUS_DMA_WAITOK);
526         if (err) {
527                 device_printf(dev, "cannot load DMA map\n");
528                 return (-1);
529         }
530
531         bzero(sc->buf_base, sc->dma_size);
532
533         return (0);
534 }
535
536 static int
537 aic_configure_clocks(struct aic_softc *sc)
538 {
539         uint64_t aic_freq;
540         uint64_t i2s_freq;
541         device_t dev;
542         int err;
543
544         dev = sc->dev;
545
546         err = clk_get_by_ofw_name(sc->dev, 0, "aic", &sc->clk_aic);
547         if (err != 0) {
548                 device_printf(dev, "Can't find aic clock.\n");
549                 return (-1);
550         }
551
552         err = clk_enable(sc->clk_aic);
553         if (err != 0) {
554                 device_printf(dev, "Can't enable aic clock.\n");
555                 return (-1);
556         }
557
558         err = clk_get_by_ofw_name(sc->dev, 0, "i2s", &sc->clk_i2s);
559         if (err != 0) {
560                 device_printf(dev, "Can't find i2s clock.\n");
561                 return (-1);
562         }
563
564         err = clk_enable(sc->clk_i2s);
565         if (err != 0) {
566                 device_printf(dev, "Can't enable i2s clock.\n");
567                 return (-1);
568         }
569
570         err = clk_set_freq(sc->clk_i2s, 12000000, 0);
571         if (err != 0) {
572                 device_printf(dev, "Can't set i2s frequency.\n");
573                 return (-1);
574         }
575
576         clk_get_freq(sc->clk_aic, &aic_freq);
577         clk_get_freq(sc->clk_i2s, &i2s_freq);
578
579         device_printf(dev, "Frequency aic %d i2s %d\n",
580             (uint32_t)aic_freq, (uint32_t)i2s_freq);
581
582         return (0);
583 }
584
585 static int
586 aic_configure(struct aic_softc *sc)
587 {
588         int reg;
589
590         WRITE4(sc, AICFR, AICFR_RST);
591
592         /* Configure AIC */
593         reg = 0;
594         if (sc->internal_codec) {
595                 reg |= (AICFR_ICDC);
596         } else {
597                 reg |= (AICFR_SYNCD | AICFR_BCKD);
598         }
599         reg |= (AICFR_AUSEL);   /* I2S/MSB-justified format. */
600         reg |= (AICFR_TFTH(8)); /* Transmit FIFO threshold */
601         reg |= (AICFR_RFTH(7)); /* Receive FIFO threshold */
602         WRITE4(sc, AICFR, reg);
603
604         reg = READ4(sc, AICFR);
605         reg |= (AICFR_ENB);     /* Enable the controller. */
606         WRITE4(sc, AICFR, reg);
607
608         return (0);
609 }
610
611 static int
612 sysctl_hw_pcm_internal_codec(SYSCTL_HANDLER_ARGS)
613 {
614         struct sc_pcminfo *scp;
615         struct sc_chinfo *ch;
616         struct aic_softc *sc;
617         int error, val;
618
619         if (arg1 == NULL)
620                 return (EINVAL);
621
622         scp = arg1;
623         sc = scp->sc;
624         ch = &scp->chan[0];
625
626         snd_mtxlock(sc->lock);
627
628         val = sc->internal_codec;
629         error = sysctl_handle_int(oidp, &val, 0, req);
630         if (error || req->newptr == NULL) {
631                 snd_mtxunlock(sc->lock);
632                 return (error);
633         }
634         if (val < 0 || val > 1) {
635                 snd_mtxunlock(sc->lock);
636                 return (EINVAL);
637         }
638
639         if (sc->internal_codec != val) {
640                 sc->internal_codec = val;
641                 if (ch->run)
642                         aic_stop(scp);
643                 aic_configure(sc);
644                 if (ch->run)
645                         aic_start(scp);
646         }
647
648         snd_mtxunlock(sc->lock);
649
650         return (0);
651 }
652
653 static int
654 aic_probe(device_t dev)
655 {
656
657         if (!ofw_bus_status_okay(dev))
658                 return (ENXIO);
659
660         if (!ofw_bus_is_compatible(dev, "ingenic,jz4780-i2s"))
661                 return (ENXIO);
662
663         device_set_desc(dev, "Audio Interface Controller");
664
665         return (BUS_PROBE_DEFAULT);
666 }
667
668 static int
669 aic_attach(device_t dev)
670 {
671         char status[SND_STATUSLEN];
672         struct sc_pcminfo *scp;
673         struct aic_softc *sc;
674         int err;
675
676         sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
677         sc->dev = dev;
678         sc->pos = 0;
679         sc->internal_codec = 1;
680
681         /* Get xDMA controller */
682         sc->xdma_tx = xdma_ofw_get(sc->dev, "tx");
683         if (sc->xdma_tx == NULL) {
684                 device_printf(dev, "Can't find DMA controller.\n");
685                 return (ENXIO);
686         }
687
688         /* Alloc xDMA virtual channel. */
689         sc->xchan = xdma_channel_alloc(sc->xdma_tx);
690         if (sc->xchan == NULL) {
691                 device_printf(dev, "Can't alloc virtual DMA channel.\n");
692                 return (ENXIO);
693         }
694
695         /* Setup sound subsystem */
696         sc->lock = snd_mtxcreate(device_get_nameunit(dev), "aic softc");
697         if (sc->lock == NULL) {
698                 device_printf(dev, "Can't create mtx.\n");
699                 return (ENXIO);
700         }
701
702         if (bus_alloc_resources(dev, aic_spec, sc->res)) {
703                 device_printf(dev,
704                     "could not allocate resources for device\n");
705                 return (ENXIO);
706         }
707
708         /* Memory interface */
709         sc->bst = rman_get_bustag(sc->res[0]);
710         sc->bsh = rman_get_bushandle(sc->res[0]);
711         sc->aic_fifo_paddr = rman_get_start(sc->res[0]) + AICDR;
712
713         /* Setup PCM. */
714         scp = malloc(sizeof(struct sc_pcminfo), M_DEVBUF, M_WAITOK | M_ZERO);
715         scp->sc = sc;
716         scp->dev = dev;
717
718         /* Setup audio buffer. */
719         err = aic_dma_setup(sc);
720         if (err != 0) {
721                 device_printf(dev, "Can't setup sound buffer.\n");
722                 return (ENXIO);
723         }
724
725         /* Setup clocks. */
726         err = aic_configure_clocks(sc);
727         if (err != 0) {
728                 device_printf(dev, "Can't configure clocks.\n");
729                 return (ENXIO);
730         }
731
732         err = aic_configure(sc);
733         if (err != 0) {
734                 device_printf(dev, "Can't configure AIC.\n");
735                 return (ENXIO);
736         }
737
738         pcm_setflags(dev, pcm_getflags(dev) | SD_F_MPSAFE);
739
740         /* Setup interrupt handler. */
741         err = xdma_setup_intr(sc->xchan, aic_intr, scp, &sc->ih);
742         if (err) {
743                 device_printf(sc->dev,
744                     "Can't setup xDMA interrupt handler.\n");
745                 return (ENXIO);
746         }
747
748         err = pcm_register(dev, scp, 1, 0);
749         if (err) {
750                 device_printf(dev, "Can't register pcm.\n");
751                 return (ENXIO);
752         }
753
754         scp->chnum = 0;
755         pcm_addchan(dev, PCMDIR_PLAY, &aicchan_class, scp);
756         scp->chnum++;
757
758         snprintf(status, SND_STATUSLEN, "at %s", ofw_bus_get_name(dev));
759         pcm_setstatus(dev, status);
760
761         mixer_init(dev, &aicmixer_class, scp);
762
763         /* Create device sysctl node. */
764         SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
765             SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
766             OID_AUTO, "internal_codec", CTLTYPE_INT | CTLFLAG_RW,
767             scp, 0, sysctl_hw_pcm_internal_codec, "I",
768             "use internal audio codec");
769
770         return (0);
771 }
772
773 static int
774 aic_detach(device_t dev)
775 {
776         struct aic_softc *sc;
777
778         sc = device_get_softc(dev);
779
780         xdma_channel_free(sc->xchan);
781
782         bus_release_resources(dev, aic_spec, sc->res);
783
784         return (0);
785 }
786
787 static device_method_t aic_pcm_methods[] = {
788         /* Device interface */
789         DEVMETHOD(device_probe,         aic_probe),
790         DEVMETHOD(device_attach,        aic_attach),
791         DEVMETHOD(device_detach,        aic_detach),
792         DEVMETHOD_END
793 };
794
795 static driver_t aic_pcm_driver = {
796         "pcm",
797         aic_pcm_methods,
798         PCM_SOFTC_SIZE,
799 };
800
801 DRIVER_MODULE(aic, simplebus, aic_pcm_driver, pcm_devclass, 0, 0);
802 MODULE_DEPEND(aic, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
803 MODULE_VERSION(aic, 1);