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