- Add codec id for Realtek ALC268.
[dragonfly.git] / sys / dev / sound / pci / au88x0.c
blob2ca4ce8fab30a1983fd60cdd5a85739060c181c0
1 /*-
2 * Copyright (c) 2003 Dag-Erling Coïdan Smørgrav
3 * All rights reserved.
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 * in this position and unchanged.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * $FreeBSD: src/sys/dev/sound/pci/au88x0.c,v 1.10 2005/03/01 08:58:05 imp Exp $
29 * $DragonFly: src/sys/dev/sound/pci/au88x0.c,v 1.1 2007/01/04 21:47:02 corecode Exp $
32 #include <dev/sound/pcm/sound.h>
33 #include <dev/sound/pcm/ac97.h>
34 #include <dev/sound/pci/au88x0.h>
36 #include <sys/bus.h>
38 #include <bus/pci/pcireg.h>
39 #include <bus/pci/pcivar.h>
42 /***************************************************************************\
43 * *
44 * SUPPORTED CHIPSETS *
45 * *
46 \***************************************************************************/
48 static struct au88x0_chipset au88x0_chipsets[] = {
50 .auc_name = "Aureal Vortex (8820)",
51 .auc_pci_id = 0x000112eb,
53 .auc_control = 0x1280c,
55 .auc_irq_source = 0x12800,
56 .auc_irq_mask = 0x12804,
57 .auc_irq_control = 0x12808,
58 .auc_irq_status = 0x1199c,
60 .auc_dma_control = 0x1060c,
62 .auc_fifo_size = 0x20,
63 .auc_wt_fifos = 32,
64 .auc_wt_fifo_base = 0x0e800,
65 .auc_wt_fifo_ctl = 0x0f800,
66 .auc_wt_dma_ctl = 0x10500,
67 .auc_adb_fifos = 16,
68 .auc_adb_fifo_base = 0x0e000,
69 .auc_adb_fifo_ctl = 0x0f840,
70 .auc_adb_dma_ctl = 0x10580,
72 .auc_adb_route_base = 0x10800,
73 .auc_adb_route_bits = 7,
74 .auc_adb_codec_in = 0x48,
75 .auc_adb_codec_out = 0x58,
78 .auc_name = "Aureal Vortex 2 (8830)",
79 .auc_pci_id = 0x000212eb,
81 .auc_control = 0x2a00c,
83 .auc_irq_source = 0x2a000,
84 .auc_irq_mask = 0x2a004,
85 .auc_irq_control = 0x2a008,
86 .auc_irq_status = 0x2919c,
88 .auc_dma_control = 0x27ae8,
90 .auc_fifo_size = 0x40,
91 .auc_wt_fifos = 64,
92 .auc_wt_fifo_base = 0x10000,
93 .auc_wt_fifo_ctl = 0x16000,
94 .auc_wt_dma_ctl = 0x27900,
95 .auc_adb_fifos = 32,
96 .auc_adb_fifo_base = 0x14000,
97 .auc_adb_fifo_ctl = 0x16100,
98 .auc_adb_dma_ctl = 0x27a00,
100 .auc_adb_route_base = 0x28000,
101 .auc_adb_route_bits = 8,
102 .auc_adb_codec_in = 0x70,
103 .auc_adb_codec_out = 0x88,
106 .auc_name = "Aureal Vortex Advantage (8810)",
107 .auc_pci_id = 0x000312eb,
109 .auc_control = 0x2a00c,
111 .auc_irq_source = 0x2a000,
112 .auc_irq_mask = 0x2a004,
113 .auc_irq_control = 0x2a008,
114 .auc_irq_status = 0x2919c,
116 .auc_dma_control = 0x27ae8,
118 .auc_fifo_size = 0x20,
119 .auc_wt_fifos = 32,
120 .auc_wt_fifo_base = 0x10000,
121 .auc_wt_fifo_ctl = 0x16000,
122 .auc_wt_dma_ctl = 0x27fd8,
123 .auc_adb_fifos = 16,
124 .auc_adb_fifo_base = 0x14000,
125 .auc_adb_fifo_ctl = 0x16100,
126 .auc_adb_dma_ctl = 0x27180,
128 .auc_adb_route_base = 0x28000,
129 .auc_adb_route_bits = 8,
130 .auc_adb_codec_in = 0x70,
131 .auc_adb_codec_out = 0x88,
134 .auc_pci_id = 0,
139 /***************************************************************************\
141 * FORMATS AND CAPABILITIES *
143 \***************************************************************************/
145 static u_int32_t au88x0_formats[] = {
146 AFMT_U8,
147 AFMT_STEREO | AFMT_U8,
148 AFMT_S16_LE,
149 AFMT_STEREO | AFMT_S16_LE,
153 static struct pcmchan_caps au88x0_capabilities = {
154 4000, /* minimum sample rate */
155 48000, /* maximum sample rate */
156 au88x0_formats, /* supported formats */
157 0 /* no particular capabilities */
161 /***************************************************************************\
163 * CODEC INTERFACE *
165 \***************************************************************************/
168 * Read from the au88x0 register space
170 #if 1
171 /* all our writes are 32-bit */
172 #define au88x0_read(aui, reg, n) \
173 bus_space_read_4((aui)->aui_spct, (aui)->aui_spch, (reg))
174 #define au88x0_write(aui, reg, data, n) \
175 bus_space_write_4((aui)->aui_spct, (aui)->aui_spch, (reg), (data))
176 #else
177 static uint32_t
178 au88x0_read(struct au88x0_info *aui, int reg, int size)
180 uint32_t data;
182 switch (size) {
183 case 1:
184 data = bus_space_read_1(aui->aui_spct, aui->aui_spch, reg);
185 break;
186 case 2:
187 data = bus_space_read_2(aui->aui_spct, aui->aui_spch, reg);
188 break;
189 case 4:
190 data = bus_space_read_4(aui->aui_spct, aui->aui_spch, reg);
191 break;
192 default:
193 panic("unsupported read size %d", size);
195 return (data);
199 * Write to the au88x0 register space
201 static void
202 au88x0_write(struct au88x0_info *aui, int reg, uint32_t data, int size)
205 switch (size) {
206 case 1:
207 bus_space_write_1(aui->aui_spct, aui->aui_spch, reg, data);
208 break;
209 case 2:
210 bus_space_write_2(aui->aui_spct, aui->aui_spch, reg, data);
211 break;
212 case 4:
213 bus_space_write_4(aui->aui_spct, aui->aui_spch, reg, data);
214 break;
215 default:
216 panic("unsupported write size %d", size);
219 #endif
222 * Reset and initialize the codec
224 static void
225 au88x0_codec_init(struct au88x0_info *aui)
227 uint32_t data;
228 int i;
230 /* wave that chicken */
231 au88x0_write(aui, AU88X0_CODEC_CONTROL, 0x8068, 4);
232 DELAY(AU88X0_SETTLE_DELAY);
233 au88x0_write(aui, AU88X0_CODEC_CONTROL, 0x00e8, 4);
234 DELAY(1000);
235 for (i = 0; i < 32; ++i) {
236 au88x0_write(aui, AU88X0_CODEC_CHANNEL + i * 4, 0, 4);
237 DELAY(AU88X0_SETTLE_DELAY);
239 au88x0_write(aui, AU88X0_CODEC_CONTROL, 0x00e8, 4);
240 DELAY(AU88X0_SETTLE_DELAY);
242 /* enable both codec channels */
243 data = au88x0_read(aui, AU88X0_CODEC_ENABLE, 4);
244 data |= (1 << (8 + 0)) | (1 << (8 + 1));
245 au88x0_write(aui, AU88X0_CODEC_ENABLE, data, 4);
246 DELAY(AU88X0_SETTLE_DELAY);
250 * Wait for the codec to get ready to accept a register write
251 * Should be called at spltty
253 static int
254 au88x0_codec_wait(struct au88x0_info *aui)
256 uint32_t data;
257 int i;
259 for (i = 0; i < AU88X0_RETRY_COUNT; ++i) {
260 data = au88x0_read(aui, AU88X0_CODEC_CONTROL, 4);
261 if (data & AU88X0_CDCTL_WROK)
262 return (0);
263 DELAY(AU88X0_SETTLE_DELAY);
265 device_printf(aui->aui_dev, "timeout while waiting for codec\n");
266 return (-1);
270 * Read from the ac97 codec
272 static int
273 au88x0_codec_read(kobj_t obj, void *arg, int reg)
275 struct au88x0_info *aui = arg;
276 uint32_t data;
277 int sl;
279 sl = spltty();
280 au88x0_codec_wait(aui);
281 au88x0_write(aui, AU88X0_CODEC_IO, AU88X0_CDIO_READ(reg), 4);
282 DELAY(1000);
283 data = au88x0_read(aui, AU88X0_CODEC_IO, 4);
284 splx(sl);
285 data &= AU88X0_CDIO_DATA_MASK;
286 data >>= AU88X0_CDIO_DATA_SHIFT;
287 return (data);
291 * Write to the ac97 codec
293 static int
294 au88x0_codec_write(kobj_t obj, void *arg, int reg, uint32_t data)
296 struct au88x0_info *aui = arg;
297 int sl;
299 sl = spltty();
300 au88x0_codec_wait(aui);
301 au88x0_write(aui, AU88X0_CODEC_IO, AU88X0_CDIO_WRITE(reg, data), 4);
302 splx(sl);
303 return 0;
307 * Codec interface glue
309 static kobj_method_t au88x0_ac97_methods[] = {
310 KOBJMETHOD(ac97_read, au88x0_codec_read),
311 KOBJMETHOD(ac97_write, au88x0_codec_write),
312 { 0, 0 }
314 AC97_DECLARE(au88x0_ac97);
316 #define au88x0_channel(aui, dir) \
317 &(aui)->aui_chan[((dir) == PCMDIR_PLAY) ? 0 : 1]
320 /***************************************************************************\
322 * CHANNEL INTERFACE *
324 \***************************************************************************/
327 * Initialize a PCM channel
329 static void *
330 au88x0_chan_init(kobj_t obj, void *arg,
331 struct snd_dbuf *buf, struct pcm_channel *chan, int dir)
333 struct au88x0_info *aui = arg;
334 struct au88x0_chan_info *auci = au88x0_channel(aui, dir);
336 if (sndbuf_alloc(buf, aui->aui_dmat, aui->aui_bufsize) != 0)
337 return (NULL);
338 auci->auci_aui = aui;
339 auci->auci_pcmchan = chan;
340 auci->auci_buf = buf;
341 auci->auci_dir = dir;
342 return (auci);
346 * Set the data format for a PCM channel
348 static int
349 au88x0_chan_setformat(kobj_t obj, void *arg, u_int32_t format)
352 /* XXX */
353 return (ENXIO);
357 * Set the sample rate for a PCM channel
359 static int
360 au88x0_chan_setspeed(kobj_t obj, void *arg, u_int32_t speed)
363 /* XXX */
364 return (speed);
368 * Set the block size for a PCM channel
370 static int
371 au88x0_chan_setblocksize(kobj_t obj, void *arg, u_int32_t blocksize)
374 /* XXX */
375 return (blocksize);
379 * Initiate a data transfer
381 static int
382 au88x0_chan_trigger(kobj_t obj, void *arg, int trigger)
384 struct au88x0_chan_info *auci = arg;
386 (void)auci;
387 switch (trigger) {
388 case PCMTRIG_START:
389 break;
390 case PCMTRIG_STOP:
391 case PCMTRIG_ABORT:
392 break;
394 return (0);
400 static int
401 au88x0_chan_getptr(kobj_t obj, void *arg)
404 /* XXX */
405 return (0);
409 * Return the capabilities of a PCM channel
411 static struct pcmchan_caps *
412 au88x0_chan_getcaps(kobj_t obj, void *arg)
415 return (&au88x0_capabilities);
419 * Channel interface glue
421 static kobj_method_t au88x0_chan_methods[] = {
422 KOBJMETHOD(channel_init, au88x0_chan_init),
423 KOBJMETHOD(channel_setformat, au88x0_chan_setformat),
424 KOBJMETHOD(channel_setspeed, au88x0_chan_setspeed),
425 KOBJMETHOD(channel_setblocksize, au88x0_chan_setblocksize),
426 KOBJMETHOD(channel_trigger, au88x0_chan_trigger),
427 KOBJMETHOD(channel_getptr, au88x0_chan_getptr),
428 KOBJMETHOD(channel_getcaps, au88x0_chan_getcaps),
429 { 0, 0 }
431 CHANNEL_DECLARE(au88x0_chan);
434 /***************************************************************************\
436 * INTERRUPT HANDLER *
438 \***************************************************************************/
440 static void
441 au88x0_intr(void *arg)
443 struct au88x0_info *aui = arg;
444 struct au88x0_chipset *auc = aui->aui_chipset;
445 int pending, source;
447 pending = au88x0_read(aui, auc->auc_irq_control, 4);
448 if ((pending & AU88X0_IRQ_PENDING_BIT) == 0)
449 return;
450 source = au88x0_read(aui, auc->auc_irq_source, 4);
451 if (source & AU88X0_IRQ_FATAL_ERR)
452 device_printf(aui->aui_dev,
453 "fatal error interrupt received\n");
454 if (source & AU88X0_IRQ_PARITY_ERR)
455 device_printf(aui->aui_dev,
456 "parity error interrupt received\n");
457 /* XXX handle the others... */
459 /* acknowledge the interrupts we just handled */
460 au88x0_write(aui, auc->auc_irq_source, source, 4);
461 au88x0_read(aui, auc->auc_irq_source, 4);
465 /***************************************************************************\
467 * INITIALIZATION *
469 \***************************************************************************/
472 * Reset and initialize the ADB and WT FIFOs
474 * - need to find out what the magic values 0x42000 and 0x2000 mean.
476 static void
477 au88x0_fifo_init(struct au88x0_info *aui)
479 struct au88x0_chipset *auc = aui->aui_chipset;
480 int i;
482 /* reset, then clear the ADB FIFOs */
483 for (i = 0; i < auc->auc_adb_fifos; ++i)
484 au88x0_write(aui, auc->auc_adb_fifo_ctl + i * 4, 0x42000, 4);
485 for (i = 0; i < auc->auc_adb_fifos * auc->auc_fifo_size; ++i)
486 au88x0_write(aui, auc->auc_adb_fifo_base + i * 4, 0, 4);
488 /* reset, then clear the WT FIFOs */
489 for (i = 0; i < auc->auc_wt_fifos; ++i)
490 au88x0_write(aui, auc->auc_wt_fifo_ctl + i * 4, 0x42000, 4);
491 for (i = 0; i < auc->auc_wt_fifos * auc->auc_fifo_size; ++i)
492 au88x0_write(aui, auc->auc_wt_fifo_base + i * 4, 0, 4);
496 * Hardware initialization
498 static void
499 au88x0_init(struct au88x0_info *aui)
501 struct au88x0_chipset *auc = aui->aui_chipset;
503 /* reset the chip */
504 au88x0_write(aui, auc->auc_control, 0xffffffff, 4);
505 DELAY(10000);
507 /* clear all interrupts */
508 au88x0_write(aui, auc->auc_irq_source, 0xffffffff, 4);
509 au88x0_read(aui, auc->auc_irq_source, 4);
510 au88x0_read(aui, auc->auc_irq_status, 4);
512 /* initialize the codec */
513 au88x0_codec_init(aui);
515 /* initialize the fifos */
516 au88x0_fifo_init(aui);
518 /* initialize the DMA engine */
519 /* XXX chicken-waving! */
520 au88x0_write(aui, auc->auc_dma_control, 0x1380000, 4);
524 * Construct and set status string
526 static void
527 au88x0_set_status(device_t dev)
529 char status[SND_STATUSLEN];
530 struct au88x0_info *aui;
532 aui = pcm_getdevinfo(dev);
533 snprintf(status, sizeof status, "at %s 0x%lx irq %ld %s",
534 (aui->aui_regtype == SYS_RES_IOPORT)? "io" : "memory",
535 rman_get_start(aui->aui_reg), rman_get_start(aui->aui_irq),PCM_KLDSTRING(snd_au88x0));
536 pcm_setstatus(dev, status);
540 /***************************************************************************\
542 * PCI INTERFACE *
544 \***************************************************************************/
547 * Probe
549 static int
550 au88x0_pci_probe(device_t dev)
552 struct au88x0_chipset *auc;
553 uint32_t pci_id;
555 pci_id = pci_get_devid(dev);
556 for (auc = au88x0_chipsets; auc->auc_pci_id; ++auc) {
557 if (auc->auc_pci_id == pci_id) {
558 device_set_desc(dev, auc->auc_name);
559 return BUS_PROBE_DEFAULT;
562 return (ENXIO);
566 * Attach
568 static int
569 au88x0_pci_attach(device_t dev)
571 struct au88x0_chipset *auc;
572 struct au88x0_info *aui = NULL;
573 uint32_t config;
574 int error;
576 if ((aui = kmalloc(sizeof *aui, M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL) {
577 device_printf(dev, "failed to allocate softc\n");
578 return (ENXIO);
580 aui->aui_dev = dev;
582 /* Model-specific parameters */
583 aui->aui_model = pci_get_devid(dev);
584 for (auc = au88x0_chipsets; auc->auc_pci_id; ++auc)
585 if (auc->auc_pci_id == aui->aui_model)
586 aui->aui_chipset = auc;
587 if (aui->aui_chipset == NULL)
588 panic("%s() called for non-au88x0 device", __func__);
590 /* enable pio, mmio, bus-mastering dma */
591 config = pci_read_config(dev, PCIR_COMMAND, 2);
592 config |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
593 pci_write_config(dev, PCIR_COMMAND, config, 2);
595 /* register mapping */
596 config = pci_read_config(dev, PCIR_COMMAND, 2);
597 if (config & PCIM_CMD_MEMEN) {
598 /* try memory-mapped I/O */
599 aui->aui_regid = PCIR_BAR(0);
600 aui->aui_regtype = SYS_RES_MEMORY;
601 aui->aui_reg = bus_alloc_resource_any(dev, aui->aui_regtype,
602 &aui->aui_regid, RF_ACTIVE);
604 if (aui->aui_reg == NULL && (config & PCIM_CMD_PORTEN)) {
605 /* fall back on port I/O */
606 aui->aui_regid = PCIR_BAR(0);
607 aui->aui_regtype = SYS_RES_IOPORT;
608 aui->aui_reg = bus_alloc_resource_any(dev, aui->aui_regtype,
609 &aui->aui_regid, RF_ACTIVE);
611 if (aui->aui_reg == NULL) {
612 /* both mmio and pio failed... */
613 device_printf(dev, "failed to map registers\n");
614 goto failed;
616 aui->aui_spct = rman_get_bustag(aui->aui_reg);
617 aui->aui_spch = rman_get_bushandle(aui->aui_reg);
619 /* IRQ mapping */
620 aui->aui_irqid = 0;
621 aui->aui_irqtype = SYS_RES_IRQ;
622 aui->aui_irq = bus_alloc_resource_any(dev, aui->aui_irqtype,
623 &aui->aui_irqid, RF_ACTIVE | RF_SHAREABLE);
624 if (aui->aui_irq == 0) {
625 device_printf(dev, "failed to map IRQ\n");
626 goto failed;
629 /* install interrupt handler */
630 error = snd_setup_intr(dev, aui->aui_irq, 0, au88x0_intr,
631 aui, &aui->aui_irqh);
632 if (error != 0) {
633 device_printf(dev, "failed to install interrupt handler\n");
634 goto failed;
637 /* DMA mapping */
638 aui->aui_bufsize = pcm_getbuffersize(dev, AU88X0_BUFSIZE_MIN,
639 AU88X0_BUFSIZE_DFLT, AU88X0_BUFSIZE_MAX);
640 error = bus_dma_tag_create(NULL,
641 2, 0, /* 16-bit alignment, no boundary */
642 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, /* restrict to 4GB */
643 NULL, NULL, /* no filter */
644 aui->aui_bufsize, 1, aui->aui_bufsize,
645 0, busdma_lock_mutex, &Giant, &aui->aui_dmat);
646 if (error != 0) {
647 device_printf(dev, "failed to create DMA tag\n");
648 goto failed;
651 /* initialize the hardware */
652 au88x0_init(aui);
654 /* initialize the ac97 codec and mixer */
655 if ((aui->aui_ac97i = AC97_CREATE(dev, aui, au88x0_ac97)) == NULL) {
656 device_printf(dev, "failed to initialize ac97 codec\n");
657 goto failed;
659 if (mixer_init(dev, ac97_getmixerclass(), aui->aui_ac97i) != 0) {
660 device_printf(dev, "failed to initialize ac97 mixer\n");
661 goto failed;
664 /* register with the pcm driver */
665 if (pcm_register(dev, aui, 0, 0))
666 goto failed;
667 pcm_addchan(dev, PCMDIR_PLAY, &au88x0_chan_class, aui);
668 #if 0
669 pcm_addchan(dev, PCMDIR_REC, &au88x0_chan_class, aui);
670 #endif
671 au88x0_set_status(dev);
673 return (0);
674 failed:
675 if (aui->aui_ac97i != NULL)
676 ac97_destroy(aui->aui_ac97i);
677 if (aui->aui_dmat)
678 bus_dma_tag_destroy(aui->aui_dmat);
679 if (aui->aui_irqh != NULL)
680 bus_teardown_intr(dev, aui->aui_irq, aui->aui_irqh);
681 if (aui->aui_irq)
682 bus_release_resource(dev, aui->aui_irqtype,
683 aui->aui_irqid, aui->aui_irq);
684 if (aui->aui_reg)
685 bus_release_resource(dev, aui->aui_regtype,
686 aui->aui_regid, aui->aui_reg);
687 kfree(aui, M_DEVBUF);
688 return (ENXIO);
692 * Detach
694 static int
695 au88x0_pci_detach(device_t dev)
697 struct au88x0_info *aui;
698 int error;
700 aui = pcm_getdevinfo(dev);
701 if ((error = pcm_unregister(dev)) != 0)
702 return (error);
704 /* release resources in reverse order */
705 bus_dma_tag_destroy(aui->aui_dmat);
706 bus_teardown_intr(dev, aui->aui_irq, aui->aui_irqh);
707 bus_release_resource(dev, aui->aui_irqtype,
708 aui->aui_irqid, aui->aui_irq);
709 bus_release_resource(dev, aui->aui_regtype,
710 aui->aui_regid, aui->aui_reg);
711 kfree(aui, M_DEVBUF);
713 return (0);
717 * Driver glue
719 static device_method_t au88x0_methods[] = {
720 DEVMETHOD(device_probe, au88x0_pci_probe),
721 DEVMETHOD(device_attach, au88x0_pci_attach),
722 DEVMETHOD(device_detach, au88x0_pci_detach),
723 { 0, 0 }
726 static driver_t au88x0_driver = {
727 "pcm",
728 au88x0_methods,
729 PCM_SOFTC_SIZE,
732 DRIVER_MODULE(snd_au88x0, pci, au88x0_driver, pcm_devclass, 0, 0);
733 MODULE_DEPEND(snd_au88x0, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
734 MODULE_VERSION(snd_au88x0, 1);