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