xref: /freebsd/sys/dev/sound/pci/ich.c (revision 6990ffd8a95caaba6858ad44ff1b3157d1efba8f)
1 /*
2  * Copyright (c) 2000 Katsurajima Naoto <raven@katsurajima.seya.yokohama.jp>
3  * Copyright (c) 2001 Cameron Grant <cg@freebsd.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
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  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHERIN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <dev/sound/pcm/sound.h>
29 #include <dev/sound/pcm/ac97.h>
30 #include <dev/sound/pci/ich.h>
31 
32 #include <pci/pcireg.h>
33 #include <pci/pcivar.h>
34 
35 SND_DECLARE_FILE("$FreeBSD$");
36 
37 /* -------------------------------------------------------------------- */
38 
39 #define ICH_TIMEOUT 1000 /* semaphore timeout polling count */
40 #define ICH_DTBL_LENGTH 32
41 #define ICH_DEFAULT_BUFSZ 16384
42 
43 /* buffer descriptor */
44 struct ich_desc {
45 	volatile u_int32_t buffer;
46 	volatile u_int32_t length;
47 };
48 
49 struct sc_info;
50 
51 /* channel registers */
52 struct sc_chinfo {
53 	u_int32_t num, run;
54 	u_int32_t blksz, blkcnt;
55 	u_int32_t regbase, spdreg;
56 	u_int32_t civ;
57 
58 	struct snd_dbuf *buffer;
59 	struct pcm_channel *channel;
60 	struct sc_info *parent;
61 
62 	struct ich_desc *dtbl;
63 };
64 
65 /* device private data */
66 struct sc_info {
67 	device_t dev;
68 	int hasvra, hasvrm;
69 	int chnum;
70 
71 	struct resource *nambar, *nabmbar, *irq;
72 	int nambarid, nabmbarid, irqid;
73 	bus_space_tag_t nambart, nabmbart;
74 	bus_space_handle_t nambarh, nabmbarh;
75 	bus_dma_tag_t dmat;
76 	bus_dmamap_t dtmap;
77 	void *ih;
78 
79 	struct ac97_info *codec;
80 	struct sc_chinfo ch[3];
81 	struct ich_desc *dtbl;
82 };
83 
84 /* -------------------------------------------------------------------- */
85 
86 static u_int32_t ich_fmt[] = {
87 	AFMT_STEREO | AFMT_S16_LE,
88 	0
89 };
90 static struct pcmchan_caps ich_vrcaps = {8000, 48000, ich_fmt, 0};
91 static struct pcmchan_caps ich_caps = {48000, 48000, ich_fmt, 0};
92 
93 /* -------------------------------------------------------------------- */
94 /* Hardware */
95 static u_int32_t
96 ich_rd(struct sc_info *sc, int regno, int size)
97 {
98 	switch (size) {
99 	case 1:
100 		return bus_space_read_1(sc->nabmbart, sc->nabmbarh, regno);
101 	case 2:
102 		return bus_space_read_2(sc->nabmbart, sc->nabmbarh, regno);
103 	case 4:
104 		return bus_space_read_4(sc->nabmbart, sc->nabmbarh, regno);
105 	default:
106 		return 0xffffffff;
107 	}
108 }
109 
110 static void
111 ich_wr(struct sc_info *sc, int regno, u_int32_t data, int size)
112 {
113 	switch (size) {
114 	case 1:
115 		bus_space_write_1(sc->nabmbart, sc->nabmbarh, regno, data);
116 		break;
117 	case 2:
118 		bus_space_write_2(sc->nabmbart, sc->nabmbarh, regno, data);
119 		break;
120 	case 4:
121 		bus_space_write_4(sc->nabmbart, sc->nabmbarh, regno, data);
122 		break;
123 	}
124 }
125 
126 /* ac97 codec */
127 static int
128 ich_waitcd(void *devinfo)
129 {
130 	int i;
131 	u_int32_t data;
132 	struct sc_info *sc = (struct sc_info *)devinfo;
133 
134 	for (i = 0; i < ICH_TIMEOUT; i++) {
135 		data = ich_rd(sc, ICH_REG_ACC_SEMA, 1);
136 		if ((data & 0x01) == 0)
137 			return 0;
138 	}
139 	device_printf(sc->dev, "CODEC semaphore timeout\n");
140 	return ETIMEDOUT;
141 }
142 
143 static int
144 ich_rdcd(kobj_t obj, void *devinfo, int regno)
145 {
146 	struct sc_info *sc = (struct sc_info *)devinfo;
147 
148 	regno &= 0xff;
149 	ich_waitcd(sc);
150 
151 	return bus_space_read_2(sc->nambart, sc->nambarh, regno);
152 }
153 
154 static int
155 ich_wrcd(kobj_t obj, void *devinfo, int regno, u_int16_t data)
156 {
157 	struct sc_info *sc = (struct sc_info *)devinfo;
158 
159 	regno &= 0xff;
160 	ich_waitcd(sc);
161 	bus_space_write_2(sc->nambart, sc->nambarh, regno, data);
162 
163 	return 0;
164 }
165 
166 static kobj_method_t ich_ac97_methods[] = {
167 	KOBJMETHOD(ac97_read,		ich_rdcd),
168 	KOBJMETHOD(ac97_write,		ich_wrcd),
169 	{ 0, 0 }
170 };
171 AC97_DECLARE(ich_ac97);
172 
173 /* -------------------------------------------------------------------- */
174 /* common routines */
175 
176 static void
177 ich_filldtbl(struct sc_chinfo *ch)
178 {
179 	u_int32_t base;
180 	int i;
181 
182 	base = vtophys(sndbuf_getbuf(ch->buffer));
183 	ch->blkcnt = sndbuf_getsize(ch->buffer) / ch->blksz;
184 	if (ch->blkcnt != 2 && ch->blkcnt != 4 && ch->blkcnt != 8 && ch->blkcnt != 16 && ch->blkcnt != 32) {
185 		ch->blkcnt = 2;
186 		ch->blksz = sndbuf_getsize(ch->buffer) / ch->blkcnt;
187 	}
188 
189 	for (i = 0; i < ICH_DTBL_LENGTH; i++) {
190 		ch->dtbl[i].buffer = base + (ch->blksz * (i % ch->blkcnt));
191 		ch->dtbl[i].length = ICH_BDC_IOC | (ch->blksz / 2);
192 	}
193 }
194 
195 static int
196 ich_resetchan(struct sc_info *sc, int num)
197 {
198 	int i, cr, regbase;
199 
200 	if (num == 0)
201 		regbase = ICH_REG_PO_BASE;
202 	else if (num == 1)
203 		regbase = ICH_REG_PI_BASE;
204 	else if (num == 2)
205 		regbase = ICH_REG_MC_BASE;
206 	else
207 		return ENXIO;
208 
209 	ich_wr(sc, regbase + ICH_REG_X_CR, 0, 1);
210 	DELAY(100);
211 	ich_wr(sc, regbase + ICH_REG_X_CR, ICH_X_CR_RR, 1);
212 	for (i = 0; i < ICH_TIMEOUT; i++) {
213 		cr = ich_rd(sc, regbase + ICH_REG_X_CR, 1);
214 		if (cr == 0)
215 			return 0;
216 	}
217 
218 	device_printf(sc->dev, "cannot reset channel %d\n", num);
219 	return ENXIO;
220 }
221 
222 /* -------------------------------------------------------------------- */
223 /* channel interface */
224 
225 static void *
226 ichchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
227 {
228 	struct sc_info *sc = devinfo;
229 	struct sc_chinfo *ch;
230 	int num;
231 
232 	num = sc->chnum++;
233 	ch = &sc->ch[num];
234 	ch->num = num;
235 	ch->buffer = b;
236 	ch->channel = c;
237 	ch->parent = sc;
238 	ch->run = 0;
239 	ch->dtbl = sc->dtbl + (ch->num * ICH_DTBL_LENGTH);
240 	ch->blkcnt = 2;
241 	ch->blksz = ICH_DEFAULT_BUFSZ / ch->blkcnt;
242 
243 	switch(ch->num) {
244 	case 0: /* play */
245 		KASSERT(dir == PCMDIR_PLAY, ("wrong direction"));
246 		ch->regbase = ICH_REG_PO_BASE;
247 		ch->spdreg = sc->hasvra? AC97_REGEXT_FDACRATE : 0;
248 		break;
249 
250 	case 1: /* record */
251 		KASSERT(dir == PCMDIR_REC, ("wrong direction"));
252 		ch->regbase = ICH_REG_PI_BASE;
253 		ch->spdreg = sc->hasvra? AC97_REGEXT_LADCRATE : 0;
254 		break;
255 
256 	case 2: /* mic */
257 		KASSERT(dir == PCMDIR_REC, ("wrong direction"));
258 		ch->regbase = ICH_REG_MC_BASE;
259 		ch->spdreg = sc->hasvrm? AC97_REGEXT_MADCRATE : 0;
260 		break;
261 
262 	default:
263 		return NULL;
264 	}
265 
266 	if (sndbuf_alloc(ch->buffer, sc->dmat, ICH_DEFAULT_BUFSZ))
267 		return NULL;
268 
269 	ich_wr(sc, ch->regbase + ICH_REG_X_BDBAR, (u_int32_t)vtophys(ch->dtbl), 4);
270 
271 	return ch;
272 }
273 
274 static int
275 ichchan_setformat(kobj_t obj, void *data, u_int32_t format)
276 {
277 	return 0;
278 }
279 
280 static int
281 ichchan_setspeed(kobj_t obj, void *data, u_int32_t speed)
282 {
283 	struct sc_chinfo *ch = data;
284 	struct sc_info *sc = ch->parent;
285 
286 	if (ch->spdreg)
287 		return ac97_setrate(sc->codec, ch->spdreg, speed);
288 	else
289 		return 48000;
290 }
291 
292 static int
293 ichchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
294 {
295 	struct sc_chinfo *ch = data;
296 	struct sc_info *sc = ch->parent;
297 
298 	ch->blksz = blocksize;
299 	ich_filldtbl(ch);
300 	ich_wr(sc, ch->regbase + ICH_REG_X_LVI, ch->blkcnt - 1, 1);
301 
302 	return ch->blksz;
303 }
304 
305 static int
306 ichchan_trigger(kobj_t obj, void *data, int go)
307 {
308 	struct sc_chinfo *ch = data;
309 	struct sc_info *sc = ch->parent;
310 
311 	switch (go) {
312 	case PCMTRIG_START:
313 		ch->run = 1;
314 		ich_wr(sc, ch->regbase + ICH_REG_X_BDBAR, (u_int32_t)vtophys(ch->dtbl), 4);
315 		ich_wr(sc, ch->regbase + ICH_REG_X_CR, ICH_X_CR_RPBM | ICH_X_CR_LVBIE | ICH_X_CR_IOCE | ICH_X_CR_FEIE, 1);
316 		break;
317 
318 	case PCMTRIG_ABORT:
319 		ich_resetchan(sc, ch->num);
320 		ch->run = 0;
321 		break;
322 	}
323 	return 0;
324 }
325 
326 static int
327 ichchan_getptr(kobj_t obj, void *data)
328 {
329 	struct sc_chinfo *ch = data;
330 	struct sc_info *sc = ch->parent;
331       	u_int32_t pos;
332 
333 	ch->civ = ich_rd(sc, ch->regbase + ICH_REG_X_CIV, 1) % ch->blkcnt;
334 
335 	pos = ch->civ * ch->blksz;
336 
337 	return pos;
338 }
339 
340 static struct pcmchan_caps *
341 ichchan_getcaps(kobj_t obj, void *data)
342 {
343 	struct sc_chinfo *ch = data;
344 
345 	return ch->spdreg? &ich_vrcaps : &ich_caps;
346 }
347 
348 static kobj_method_t ichchan_methods[] = {
349 	KOBJMETHOD(channel_init,		ichchan_init),
350 	KOBJMETHOD(channel_setformat,		ichchan_setformat),
351 	KOBJMETHOD(channel_setspeed,		ichchan_setspeed),
352 	KOBJMETHOD(channel_setblocksize,	ichchan_setblocksize),
353 	KOBJMETHOD(channel_trigger,		ichchan_trigger),
354 	KOBJMETHOD(channel_getptr,		ichchan_getptr),
355 	KOBJMETHOD(channel_getcaps,		ichchan_getcaps),
356 	{ 0, 0 }
357 };
358 CHANNEL_DECLARE(ichchan);
359 
360 /* -------------------------------------------------------------------- */
361 /* The interrupt handler */
362 
363 static void
364 ich_intr(void *p)
365 {
366 	struct sc_info *sc = (struct sc_info *)p;
367 	struct sc_chinfo *ch;
368 	u_int32_t cbi, lbi, lvi, st;
369 	int i;
370 
371 	for (i = 0; i < 3; i++) {
372 		ch = &sc->ch[i];
373 		/* check channel status */
374 		st = ich_rd(sc, ch->regbase + ICH_REG_X_SR, 2);
375 		st &= ICH_X_SR_FIFOE | ICH_X_SR_BCIS | ICH_X_SR_LVBCI;
376 		if (st != 0) {
377 			if (st & (ICH_X_SR_BCIS | ICH_X_SR_LVBCI)) {
378 				/* block complete - update buffer */
379 				if (ch->run)
380 					chn_intr(ch->channel);
381 				lvi = ich_rd(sc, ch->regbase + ICH_REG_X_LVI, 1);
382 				cbi = ch->civ % ch->blkcnt;
383 				if (cbi == 0)
384 					cbi = ch->blkcnt - 1;
385 				else
386 					cbi--;
387 				lbi = lvi % ch->blkcnt;
388 				if (cbi >= lbi)
389 					lvi += cbi - lbi;
390 				else
391 					lvi += cbi + ch->blkcnt - lbi;
392 				lvi %= ICH_DTBL_LENGTH;
393 				ich_wr(sc, ch->regbase + ICH_REG_X_LVI, lvi, 1);
394 			}
395 			/* clear status bit */
396 			ich_wr(sc, ch->regbase + ICH_REG_X_SR, st, 2);
397 		}
398 	}
399 }
400 
401 /* -------------------------------------------------------------------- */
402 /* Probe and attach the card */
403 
404 static void
405 ich_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
406 {
407 	return;
408 }
409 
410 static int
411 ich_init(struct sc_info *sc)
412 {
413 	u_int32_t stat;
414 	int sz;
415 
416 	ich_wr(sc, ICH_REG_GLOB_CNT, ICH_GLOB_CTL_COLD, 4);
417 	DELAY(600000);
418 	stat = ich_rd(sc, ICH_REG_GLOB_STA, 4);
419 
420 	if ((stat & ICH_GLOB_STA_PCR) == 0)
421 		return ENXIO;
422 
423 	ich_wr(sc, ICH_REG_GLOB_CNT, ICH_GLOB_CTL_COLD | ICH_GLOB_CTL_PRES, 4);
424 
425 	if (ich_resetchan(sc, 0) || ich_resetchan(sc, 1) || ich_resetchan(sc, 2))
426 		return ENXIO;
427 
428 	if (bus_dmamem_alloc(sc->dmat, (void **)&sc->dtbl, BUS_DMA_NOWAIT, &sc->dtmap))
429 		return ENOSPC;
430 
431 	sz = sizeof(struct ich_desc) * ICH_DTBL_LENGTH * 3;
432 	if (bus_dmamap_load(sc->dmat, sc->dtmap, sc->dtbl, sz, ich_setmap, NULL, 0)) {
433 		bus_dmamem_free(sc->dmat, (void **)&sc->dtbl, sc->dtmap);
434 		return ENOSPC;
435 	}
436 
437 	return 0;
438 }
439 
440 static int
441 ich_pci_probe(device_t dev)
442 {
443 	switch(pci_get_devid(dev)) {
444 	case 0x71958086:
445 		device_set_desc(dev, "Intel 443MX");
446 		return 0;
447 
448 	case 0x24158086:
449 		device_set_desc(dev, "Intel 82801AA (ICH)");
450 		return 0;
451 
452 	case 0x24258086:
453 		device_set_desc(dev, "Intel 82901AB (ICH)");
454 		return 0;
455 
456 	case 0x24458086:
457 		device_set_desc(dev, "Intel 82801BA (ICH2)");
458 		return 0;
459 
460 	default:
461 		return ENXIO;
462 	}
463 }
464 
465 static int
466 ich_pci_attach(device_t dev)
467 {
468 	u_int32_t		data;
469 	struct sc_info 		*sc;
470 	char 			status[SND_STATUSLEN];
471 
472 	if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) {
473 		device_printf(dev, "cannot allocate softc\n");
474 		return ENXIO;
475 	}
476 
477 	bzero(sc, sizeof(*sc));
478 	sc->dev = dev;
479 
480 	data = pci_read_config(dev, PCIR_COMMAND, 2);
481 	data |= (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
482 	pci_write_config(dev, PCIR_COMMAND, data, 2);
483 	data = pci_read_config(dev, PCIR_COMMAND, 2);
484 
485 	sc->nambarid = PCIR_NAMBAR;
486 	sc->nabmbarid = PCIR_NABMBAR;
487 	sc->nambar = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->nambarid, 0, ~0, 1, RF_ACTIVE);
488 	sc->nabmbar = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->nabmbarid, 0, ~0, 1, RF_ACTIVE);
489 
490 	if (!sc->nambar || !sc->nabmbar) {
491 		device_printf(dev, "unable to map IO port space\n");
492 		goto bad;
493 	}
494 
495 	sc->nambart = rman_get_bustag(sc->nambar);
496 	sc->nambarh = rman_get_bushandle(sc->nambar);
497 	sc->nabmbart = rman_get_bustag(sc->nabmbar);
498 	sc->nabmbarh = rman_get_bushandle(sc->nabmbar);
499 
500 	if (bus_dma_tag_create(NULL, 8, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
501 			       NULL, NULL, ICH_DEFAULT_BUFSZ, 1, 0x3ffff, 0, &sc->dmat) != 0) {
502 		device_printf(dev, "unable to create dma tag\n");
503 		goto bad;
504 	}
505 
506 	if (ich_init(sc)) {
507 		device_printf(dev, "unable to initialize the card\n");
508 		goto bad;
509 	}
510 
511 	sc->codec = AC97_CREATE(dev, sc, ich_ac97);
512 	if (sc->codec == NULL)
513 		goto bad;
514 	mixer_init(dev, ac97_getmixerclass(), sc->codec);
515 
516 	/* check and set VRA function */
517 	if (ac97_setextmode(sc->codec, AC97_EXTCAP_VRA) == 0)
518 		sc->hasvra = 1;
519 	if (ac97_setextmode(sc->codec, AC97_EXTCAP_VRM) == 0)
520 		sc->hasvrm = 1;
521 
522 	sc->irqid = 0;
523 	sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
524 	if (!sc->irq || snd_setup_intr(dev, sc->irq, INTR_MPSAFE, ich_intr, sc, &sc->ih)) {
525 		device_printf(dev, "unable to map interrupt\n");
526 		goto bad;
527 	}
528 
529 	if (pcm_register(dev, sc, 1, 2))
530 		goto bad;
531 
532 	pcm_addchan(dev, PCMDIR_PLAY, &ichchan_class, sc);
533 	pcm_addchan(dev, PCMDIR_REC, &ichchan_class, sc);
534 	pcm_addchan(dev, PCMDIR_REC, &ichchan_class, sc);
535 
536 	snprintf(status, SND_STATUSLEN, "at io 0x%lx, 0x%lx irq %ld",
537 		 rman_get_start(sc->nambar), rman_get_start(sc->nabmbar), rman_get_start(sc->irq));
538 
539 	pcm_setstatus(dev, status);
540 
541 	return 0;
542 
543 bad:
544 	if (sc->codec)
545 		ac97_destroy(sc->codec);
546 	if (sc->nambar)
547 		bus_release_resource(dev, SYS_RES_IOPORT,
548 		    sc->nambarid, sc->nambar);
549 	if (sc->nabmbar)
550 		bus_release_resource(dev, SYS_RES_IOPORT,
551 		    sc->nabmbarid, sc->nabmbar);
552 	if (sc->ih)
553 		bus_teardown_intr(dev, sc->irq, sc->ih);
554 	if (sc->irq)
555 		bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
556 	free(sc, M_DEVBUF);
557 	return ENXIO;
558 }
559 
560 static int
561 ich_pci_detach(device_t dev)
562 {
563 	struct sc_info *sc;
564 	int r;
565 
566 	r = pcm_unregister(dev);
567 	if (r)
568 		return r;
569 	sc = pcm_getdevinfo(dev);
570 
571 	bus_teardown_intr(dev, sc->irq, sc->ih);
572 	bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
573 	bus_release_resource(dev, SYS_RES_IOPORT, sc->nambarid, sc->nambar);
574 	bus_release_resource(dev, SYS_RES_IOPORT, sc->nabmbarid, sc->nabmbar);
575 	bus_dma_tag_destroy(sc->dmat);
576 	free(sc, M_DEVBUF);
577 	return 0;
578 }
579 
580 static int
581 ich_pci_resume(device_t dev)
582 {
583 	struct sc_info *sc;
584 
585 	sc = pcm_getdevinfo(dev);
586 
587 	/* Reinit audio device */
588     	if (ich_init(sc) == -1) {
589 		device_printf(dev, "unable to reinitialize the card\n");
590 		return ENXIO;
591 	}
592 	/* Reinit mixer */
593     	if (mixer_reinit(dev) == -1) {
594 		device_printf(dev, "unable to reinitialize the mixer\n");
595 		return ENXIO;
596 	}
597 	return 0;
598 }
599 
600 static device_method_t ich_methods[] = {
601 	/* Device interface */
602 	DEVMETHOD(device_probe,		ich_pci_probe),
603 	DEVMETHOD(device_attach,	ich_pci_attach),
604 	DEVMETHOD(device_detach,	ich_pci_detach),
605 	DEVMETHOD(device_resume,	ich_pci_resume),
606 	{ 0, 0 }
607 };
608 
609 static driver_t ich_driver = {
610 	"pcm",
611 	ich_methods,
612 	PCM_SOFTC_SIZE,
613 };
614 
615 DRIVER_MODULE(snd_ich, pci, ich_driver, pcm_devclass, 0, 0);
616 MODULE_DEPEND(snd_ich, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER);
617 MODULE_VERSION(snd_ich, 1);
618