xref: /freebsd/sys/dev/sound/pci/ich.c (revision 1b6c76a2fe091c74f08427e6c870851025a9cf67)
1 /*
2  * Copyright (c) 2000 Katsurajima Naoto <raven@katsurajima.seya.yokohama.jp>
3  * All rights reserved.
4  *
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  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHERIN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28 
29 #include <dev/sound/pcm/sound.h>
30 #include <dev/sound/pcm/ac97.h>
31 
32 #include <pci/pcireg.h>
33 #include <pci/pcivar.h>
34 
35 
36 /* -------------------------------------------------------------------- */
37 
38 #define ICH_RECPRIMARY 0
39 
40 #define ICH_TIMEOUT 1000 /* semaphore timeout polling count */
41 
42 #define PCIR_NAMBAR 0x10
43 #define PCIR_NABMBAR 0x14
44 
45 /* Native Audio Bus Master Control Registers */
46 #define ICH_REG_PI_BDBAR 0x00
47 #define ICH_REG_PI_CIV   0x04
48 #define ICH_REG_PI_LVI   0x05
49 #define ICH_REG_PI_SR    0x06
50 #define ICH_REG_PI_PICB  0x08
51 #define ICH_REG_PI_PIV   0x0a
52 #define ICH_REG_PI_CR    0x0b
53 #define ICH_REG_PO_BDBAR 0x10
54 #define ICH_REG_PO_CIV   0x14
55 #define ICH_REG_PO_LVI   0x15
56 #define ICH_REG_PO_SR    0x16
57 #define ICH_REG_PO_PICB  0x18
58 #define ICH_REG_PO_PIV   0x1a
59 #define ICH_REG_PO_CR    0x1b
60 #define ICH_REG_MC_BDBAR 0x20
61 #define ICH_REG_MC_CIV   0x24
62 #define ICH_REG_MC_LVI   0x25
63 #define ICH_REG_MC_SR    0x26
64 #define ICH_REG_MC_PICB  0x28
65 #define ICH_REG_MC_PIV   0x2a
66 #define ICH_REG_MC_CR    0x2b
67 #define ICH_REG_GLOB_CNT 0x2c
68 #define ICH_REG_GLOB_STA 0x30
69 #define ICH_REG_ACC_SEMA 0x34
70 /* Status Register Values */
71 #define ICH_X_SR_DCH   0x0001
72 #define ICH_X_SR_CELV  0x0002
73 #define ICH_X_SR_LVBCI 0x0004
74 #define ICH_X_SR_BCIS  0x0008
75 #define ICH_X_SR_FIFOE 0x0010
76 /* Control Register Values */
77 #define ICH_X_CR_RPBM  0x01
78 #define ICH_X_CR_RR    0x02
79 #define ICH_X_CR_LVBIE 0x04
80 #define ICH_X_CR_FEIE  0x08
81 #define ICH_X_CR_IOCE  0x10
82 /* Global Control Register Values */
83 #define ICH_GLOB_CTL_GIE  0x00000001
84 #define ICH_GLOB_CTL_COLD 0x00000002 /* negate */
85 #define ICH_GLOB_CTL_WARM 0x00000004
86 #define ICH_GLOB_CTL_SHUT 0x00000008
87 #define ICH_GLOB_CTL_PRES 0x00000010
88 #define ICH_GLOB_CTL_SRES 0x00000020
89 /* Global Status Register Values */
90 #define ICH_GLOB_STA_GSCI   0x00000001
91 #define ICH_GLOB_STA_MIINT  0x00000002
92 #define ICH_GLOB_STA_MOINT  0x00000004
93 #define ICH_GLOB_STA_PIINT  0x00000020
94 #define ICH_GLOB_STA_POINT  0x00000040
95 #define ICH_GLOB_STA_MINT   0x00000080
96 #define ICH_GLOB_STA_PCR    0x00000100
97 #define ICH_GLOB_STA_SCR    0x00000200
98 #define ICH_GLOB_STA_PRES   0x00000400
99 #define ICH_GLOB_STA_SRES   0x00000800
100 #define ICH_GLOB_STA_SLOT12 0x00007000
101 #define ICH_GLOB_STA_RCODEC 0x00008000
102 #define ICH_GLOB_STA_AD3    0x00010000
103 #define ICH_GLOB_STA_MD3    0x00020000
104 #define ICH_GLOB_STA_IMASK  (ICH_GLOB_STA_MIINT | ICH_GLOB_STA_MOINT | ICH_GLOB_STA_PIINT | ICH_GLOB_STA_POINT | ICH_GLOB_STA_MINT | ICH_GLOB_STA_PRES | ICH_GLOB_STA_SRES)
105 
106 /* AC'97 power/ready functions */
107 #define AC97_POWER_PINPOWER  0x0100
108 #define AC97_POWER_PINREADY  0x0001
109 #define AC97_POWER_POUTPOWER 0x0200
110 #define AC97_POWER_POUTREADY 0x0002
111 
112 /* play/record buffer */
113 #define ICH_FIFOINDEX 32
114 #define ICH_BDC_IOC 0x80000000
115 #define ICH_BDC_BUP 0x40000000
116 #define ICH_DEFAULT_BLOCKSZ 2048
117 /* buffer descriptor */
118 struct ich_desc {
119 	volatile u_int32_t buffer;
120 	volatile u_int32_t length;
121 };
122 
123 struct sc_info;
124 
125 /* channel registers */
126 struct sc_chinfo {
127 	int run, spd, dir, fmt;
128 	struct snd_dbuf *buffer;
129 	struct pcm_channel *channel;
130 	struct sc_info *parent;
131 	struct ich_desc *index;
132 	bus_dmamap_t imap;
133 	u_int32_t lvi;
134 };
135 
136 /* device private data */
137 struct sc_info {
138 	device_t	dev;
139 	u_int32_t 	type, rev;
140 	u_int32_t	cd2id, ctrlbase;
141 
142 	struct resource *nambar, *nabmbar;
143 	int		nambarid, nabmbarid;
144 	bus_space_tag_t nambart, nabmbart;
145 	bus_space_handle_t nambarh, nabmbarh;
146 	bus_dma_tag_t dmat;
147 	struct resource *irq;
148 	int		irqid;
149 	void		*ih;
150 
151 	struct ac97_info *codec;
152 	struct sc_chinfo *pi, *po;
153 };
154 
155 struct {
156 	u_int32_t dev, subdev;
157 	char *name;
158 } ich_devs[] = {
159 	{0x71958086, 0, "Intel 443MX"},
160 	{0x24158086, 0, "Intel 82801AA (ICH)"},
161 	{0x24258086, 0, "Intel 82901AB (ICH)"},
162 	{0x24458086, 0, "Intel 82801BA (ICH2)"},
163 	{0, 0, NULL}
164 };
165 
166 /* variable rate audio */
167 static u_int32_t ich_rate[] = {
168     48000, 44100, 22050, 16000, 11025, 8000, 0
169 };
170 
171 /* -------------------------------------------------------------------- */
172 
173 /*
174  * prototypes
175  */
176 
177 /* channel interface */
178 static void *ichpchan_init(kobj_t, void *, struct snd_dbuf *, struct pcm_channel *, int);
179 static int ichpchan_setformat(kobj_t, void *, u_int32_t);
180 static int ichpchan_setspeed(kobj_t, void *, u_int32_t);
181 static int ichpchan_setblocksize(kobj_t, void *, u_int32_t);
182 static int ichpchan_trigger(kobj_t, void *, int);
183 static int ichpchan_getptr(kobj_t, void *);
184 static struct pcmchan_caps *ichpchan_getcaps(kobj_t, void *);
185 
186 static void *ichrchan_init(kobj_t, void *, struct snd_dbuf *, struct pcm_channel *, int);
187 static int ichrchan_setformat(kobj_t, void *, u_int32_t);
188 static int ichrchan_setspeed(kobj_t, void *, u_int32_t);
189 static int ichrchan_setblocksize(kobj_t, void *, u_int32_t);
190 static int ichrchan_trigger(kobj_t, void *, int);
191 static int ichrchan_getptr(kobj_t, void *);
192 static struct pcmchan_caps *ichrchan_getcaps(kobj_t, void *);
193 
194 /* stuff */
195 static int       ich_init(struct sc_info *);
196 static void      ich_intr(void *);
197 
198 /* -------------------------------------------------------------------- */
199 
200 static u_int32_t ich_recfmt[] = {
201 	AFMT_STEREO | AFMT_S16_LE,
202 	0
203 };
204 static struct pcmchan_caps ich_reccaps = {8000, 48000, ich_recfmt, 0};
205 
206 static u_int32_t ich_playfmt[] = {
207 	AFMT_STEREO | AFMT_S16_LE,
208 	0
209 };
210 static struct pcmchan_caps ich_playcaps = {8000, 48000, ich_playfmt, 0};
211 
212 /* -------------------------------------------------------------------- */
213 /* Hardware */
214 static u_int32_t
215 ich_rd(struct sc_info *sc, int regno, int size)
216 {
217 	switch (size) {
218 	case 1:
219 		return bus_space_read_1(sc->nambart, sc->nambarh, regno);
220 	case 2:
221 		return bus_space_read_2(sc->nambart, sc->nambarh, regno);
222 	case 4:
223 		return bus_space_read_4(sc->nambart, sc->nambarh, regno);
224 	default:
225 		return 0xffffffff;
226 	}
227 }
228 
229 static void
230 ich_wr(struct sc_info *sc, int regno, u_int32_t data, int size)
231 {
232 	switch (size) {
233 	case 1:
234 		bus_space_write_1(sc->nambart, sc->nambarh, regno, data);
235 		break;
236 	case 2:
237 		bus_space_write_2(sc->nambart, sc->nambarh, regno, data);
238 		break;
239 	case 4:
240 		bus_space_write_4(sc->nambart, sc->nambarh, regno, data);
241 		break;
242 	}
243 }
244 
245 /* ac97 codec */
246 static int
247 ich_waitcd(void *devinfo)
248 {
249 	int i;
250 	u_int32_t data;
251 	struct sc_info *sc = (struct sc_info *)devinfo;
252 	for (i = 0;i < ICH_TIMEOUT;i++) {
253 		data = bus_space_read_1(sc->nabmbart, sc->nabmbarh,
254 		    ICH_REG_ACC_SEMA);
255 		if ((data & 0x01) == 0)
256 			return 0;
257 	}
258 	device_printf(sc->dev, "CODEC semaphore timeout\n");
259 	return ETIMEDOUT;
260 }
261 
262 static int
263 ich_rdcd(kobj_t obj, void *devinfo, int regno)
264 {
265 	struct sc_info *sc = (struct sc_info *)devinfo;
266 	regno &= 0xff;
267 	ich_waitcd(sc);
268 	return ich_rd(sc, regno, 2);
269 }
270 
271 static int
272 ich_wrcd(kobj_t obj, void *devinfo, int regno, u_int32_t data)
273 {
274 	struct sc_info *sc = (struct sc_info *)devinfo;
275 	regno &= 0xff;
276 	ich_waitcd(sc);
277 	ich_wr(sc, regno, data, 2);
278 	return 0;
279 }
280 
281 static kobj_method_t ich_ac97_methods[] = {
282 	KOBJMETHOD(ac97_read,		ich_rdcd),
283 	KOBJMETHOD(ac97_write,		ich_wrcd),
284 	{ 0, 0 }
285 };
286 AC97_DECLARE(ich_ac97);
287 
288 /* -------------------------------------------------------------------- */
289 
290 /* channel common routines */
291 static void
292 ichchan_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
293 {
294 	struct sc_chinfo *ch = arg;
295 
296 	if (bootverbose) {
297 		device_printf(ch->parent->dev, "setmap(0x%lx, 0x%lx)\n", (unsigned long)segs->ds_addr, (unsigned long)segs->ds_len);
298 	}
299 }
300 
301 static int
302 ichchan_initbuf(struct sc_chinfo *ch)
303 {
304 	struct sc_info *sc = ch->parent;
305 	int i;
306 
307 	if (sndbuf_alloc(ch->buffer, sc->dmat, ICH_DEFAULT_BLOCKSZ * ICH_FIFOINDEX)) {
308 		return ENOSPC;
309 	}
310 	if (bus_dmamem_alloc(sc->dmat,(void **)&ch->index, BUS_DMA_NOWAIT, &ch->imap)) {
311 		sndbuf_free(ch->buffer);
312 		return ENOSPC;
313 	}
314 	if (bus_dmamap_load(sc->dmat, ch->imap, ch->index,
315 	    sizeof(struct ich_desc) * ICH_FIFOINDEX, ichchan_setmap, ch, 0)) {
316 		bus_dmamem_free(sc->dmat, (void **)&ch->index, ch->imap);
317 		sndbuf_free(ch->buffer);
318 		return ENOSPC;
319 	}
320 	for (i = 0;i < ICH_FIFOINDEX;i++) {
321 		ch->index[i].buffer = vtophys(sndbuf_getbuf(ch->buffer)) +
322 		    ICH_DEFAULT_BLOCKSZ * i;
323 		if (ch->dir == PCMDIR_PLAY)
324 			ch->index[i].length = 0;
325 		else
326 			ch->index[i].length = ICH_BDC_IOC +
327 			    ICH_DEFAULT_BLOCKSZ / 2;
328 	}
329 	return 0;
330 }
331 
332 static void
333 ichchan_free(struct sc_chinfo *ch)
334 {
335 	struct sc_info *sc = ch->parent;
336 
337 	bus_dmamap_unload(sc->dmat, ch->imap);
338 	bus_dmamem_free(sc->dmat, (void **)&ch->index, ch->imap);
339 	sndbuf_free(ch->buffer);
340 }
341 
342 /* play channel interface */
343 static int
344 ichpchan_power(kobj_t obj, struct sc_info *sc, int sw)
345 {
346 	u_int32_t cr;
347 	int i;
348 
349 	cr = ich_rdcd(obj, sc, AC97_REG_POWER);
350 	if (sw) { /* power on */
351 		cr &= ~AC97_POWER_POUTPOWER;
352 		ich_wrcd(obj, sc, AC97_REG_POWER, cr);
353 		for (i = 0;i < ICH_TIMEOUT;i++) {
354 			cr = ich_rdcd(obj, sc, AC97_REG_POWER);
355 			if ((cr & AC97_POWER_POUTREADY) != 0)
356 				break;
357 		}
358 	}
359 	else { /* power off */
360 		cr |= AC97_POWER_POUTPOWER;
361 		ich_wrcd(obj, sc, AC97_REG_POWER, cr);
362 		for (i = 0;i < ICH_TIMEOUT;i++) {
363 			cr = ich_rdcd(obj, sc, AC97_REG_POWER);
364 			if ((cr & AC97_POWER_POUTREADY) == 0)
365 				break;
366 		}
367 	}
368 	if (i == ICH_TIMEOUT)
369 		return -1;
370 	return 0;
371 }
372 
373 static u_int32_t
374 ichpchan_getminspeed(kobj_t obj, void *data)
375 {
376 	struct sc_chinfo *ch = data;
377 	u_int32_t extcap;
378 	u_int32_t minspeed = 48000; /* before AC'97 R2.0 */
379 	int i = 0;
380 
381 	extcap = ac97_getextmode(ch->parent->codec);
382 	if (extcap & AC97_EXTCAP_VRA) {
383 		for (i = 0;ich_rate[i] != 0;i++) {
384 			if (ac97_setrate(ch->parent->codec, AC97_REGEXT_FDACRATE, ich_rate[i]) == ich_rate[i])
385 				minspeed = ich_rate[i];
386 		}
387 	}
388 	return minspeed;
389 }
390 
391 static void *
392 ichpchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
393 {
394 	struct sc_info *sc = devinfo;
395 	struct sc_chinfo *ch;
396 	u_int32_t cr;
397 	int i;
398 
399 	bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_CR, 0);
400 	bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_CR,
401 	    ICH_X_CR_RR);
402 	for (i = 0;i < ICH_TIMEOUT;i++) {
403 		cr = bus_space_read_1(sc->nabmbart, sc->nabmbarh,
404 		    ICH_REG_PO_CR);
405 		if (cr == 0)
406 			break;
407 	}
408 	if (i == ICH_TIMEOUT) {
409 		device_printf(sc->dev, "cannot reset play codec\n");
410 		return NULL;
411 	}
412 	if (ichpchan_power(obj, sc, 1) == -1) {
413 		device_printf(sc->dev, "play DAC not ready\n");
414 		return NULL;
415 	}
416 	ichpchan_power(obj, sc, 0);
417 	if ((ch = malloc(sizeof(*ch), M_DEVBUF, M_NOWAIT)) == NULL) {
418 		device_printf(sc->dev, "cannot allocate channel info area\n");
419 		return NULL;
420 	}
421 	ch->buffer = b;
422 	ch->channel = c;
423 	ch->parent = sc;
424 	ch->dir = PCMDIR_PLAY;
425 	ch->run = 0;
426 	ch->lvi = 0;
427 	if (ichchan_initbuf(ch)) {
428 		device_printf(sc->dev, "cannot allocate channel buffer\n");
429 		free(ch, M_DEVBUF);
430 		return NULL;
431 	}
432 	bus_space_write_4(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_BDBAR,
433 	    (u_int32_t)vtophys(ch->index));
434 	sc->po = ch;
435 	if (bootverbose) {
436 		device_printf(sc->dev,"Play codec support rate(Hz): ");
437 		for (i = 0;ich_rate[i] != 0;i++) {
438 			if (ichpchan_setspeed(obj, ch, ich_rate[i]) == ich_rate[i]) {
439 				printf("%d ", ich_rate[i]);
440 			}
441 		}
442 		printf("\n");
443 	}
444 	ich_playcaps.minspeed = ichpchan_getminspeed(obj, ch);
445 	return ch;
446 }
447 
448 static int
449 ichpchan_free(kobj_t obj, void *data)
450 {
451 	struct sc_chinfo *ch = data;
452 	ichchan_free(ch);
453 	return ichpchan_power(obj, ch->parent, 0);
454 }
455 
456 static int
457 ichpchan_setformat(kobj_t obj, void *data, u_int32_t format)
458 {
459 	struct sc_chinfo *ch = data;
460 
461 	ch->fmt = format;
462 	return 0;
463 }
464 
465 static int
466 ichpchan_setspeed(kobj_t obj, void *data, u_int32_t speed)
467 {
468 	struct sc_chinfo *ch = data;
469 	u_int32_t extcap;
470 
471 	extcap = ac97_getextmode(ch->parent->codec);
472 	if (extcap & AC97_EXTCAP_VRA) {
473 		ch->spd = (u_int32_t)ac97_setrate(ch->parent->codec, AC97_REGEXT_FDACRATE, speed);
474 	}
475 	else {
476 		ch->spd = 48000; /* before AC'97 R2.0 */
477 	}
478 #if(0)
479 	device_printf(ch->parent->dev, "ichpchan_setspeed():ch->spd = %d\n", ch->spd);
480 #endif
481 	return ch->spd;
482 }
483 
484 static int
485 ichpchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
486 {
487 	return blocksize;
488 }
489 
490 /* update index */
491 static void
492 ichpchan_update(struct sc_chinfo *ch)
493 {
494 	struct sc_info *sc = ch->parent;
495 	u_int32_t lvi;
496 	int fp;
497 	int last;
498 	int i;
499 
500 	fp = sndbuf_getfreeptr(ch->buffer);
501 	last = fp - 1;
502 	if (last < 0)
503 		last = ICH_DEFAULT_BLOCKSZ * ICH_FIFOINDEX - 1;
504 	lvi = last / ICH_DEFAULT_BLOCKSZ;
505 	if (lvi >= ch->lvi) {
506 		for (i = ch->lvi;i < lvi;i++)
507 			ch->index[i].length =
508 			    ICH_BDC_IOC + ICH_DEFAULT_BLOCKSZ / 2;
509 		ch->index[i].length = ICH_BDC_IOC + ICH_BDC_BUP
510 		    + (last % ICH_DEFAULT_BLOCKSZ + 1) / 2;
511 	}
512 	else {
513 		for (i = ch->lvi;i < ICH_FIFOINDEX;i++)
514 			ch->index[i].length =
515 			    ICH_BDC_IOC + ICH_DEFAULT_BLOCKSZ / 2;
516 		for (i = 0;i < lvi;i++)
517 			ch->index[i].length =
518 			    ICH_BDC_IOC + ICH_DEFAULT_BLOCKSZ / 2;
519 		ch->index[i].length = ICH_BDC_IOC + ICH_BDC_BUP
520 		    + (last % ICH_DEFAULT_BLOCKSZ + 1) / 2;
521 	}
522 	bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_LVI, lvi);
523 	ch->lvi = lvi;
524 #if(0)
525 	device_printf(ch->parent->dev, "ichpchan_update():fp = %d, lvi = %d\n", fp, lvi);
526 #endif
527 	return;
528 }
529 static void
530 ichpchan_fillblank(struct sc_chinfo *ch)
531 {
532 	struct sc_info *sc = ch->parent;
533 
534 	ch->lvi++;
535 	if (ch->lvi == ICH_FIFOINDEX)
536 		ch->lvi = 0;
537 	ch->index[ch->lvi].length = ICH_BDC_BUP + ICH_DEFAULT_BLOCKSZ / 2;
538 	bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_LVI, ch->lvi);
539 	return;
540 }
541 /* semantic note: must start at beginning of buffer */
542 static int
543 ichpchan_trigger(kobj_t obj, void *data, int go)
544 {
545 	struct sc_chinfo *ch = data;
546 	struct sc_info *sc = ch->parent;
547 	u_int32_t cr;
548 	int i;
549 
550 #if(0)
551 	device_printf(ch->parent->dev, "ichpchan_trigger(0x%08x, %d)\n", data, go);
552 #endif
553 	switch (go) {
554 	case PCMTRIG_START:
555 #if(0)
556 		device_printf(ch->parent->dev, "ichpchan_trigger():PCMTRIG_START\n");
557 #endif
558 		ch->run = 1;
559 		ichpchan_power(obj, sc, 1);
560 		bus_space_write_4(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_BDBAR,
561 		    (u_int32_t)vtophys(ch->index));
562 		ch->lvi = ICH_FIFOINDEX - 1;
563 		ichpchan_update(ch);
564 		bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_CR,
565 		    ICH_X_CR_RPBM | ICH_X_CR_LVBIE | ICH_X_CR_IOCE |
566 		    ICH_X_CR_FEIE);
567 		break;
568 	case PCMTRIG_STOP:
569 #if(0)
570 		device_printf(ch->parent->dev, "ichpchan_trigger():PCMTRIG_STOP\n");
571 #endif
572 		cr = bus_space_read_1(sc->nabmbart, sc->nabmbarh,
573 		    ICH_REG_PO_CR);
574 		bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_CR,
575 		    cr & ~ICH_X_CR_RPBM);
576 		ichpchan_power(obj, sc, 0);
577 		ch->run = 0;
578 		break;
579 	case PCMTRIG_ABORT:
580 #if(0)
581 		device_printf(ch->parent->dev, "ichpchan_trigger():PCMTRIG_ABORT\n");
582 #endif
583 		bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_CR,
584 		    0);
585 		bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_CR,
586 		    ICH_X_CR_RR);
587 		for (i = 0;i < ICH_TIMEOUT;i++) {
588 			cr = bus_space_read_1(sc->nabmbart, sc->nabmbarh,
589 			    ICH_REG_PO_CR);
590 			if (cr == 0)
591 				break;
592 		}
593 		ichpchan_power(obj, sc, 0);
594 		ch->run = 0;
595 		ch->lvi = 0;
596 		break;
597 	default:
598 		break;
599 	}
600 	return 0;
601 }
602 
603 static int
604 ichpchan_getptr(kobj_t obj, void *data)
605 {
606 	struct sc_chinfo *ch = data;
607 	struct sc_info *sc = ch->parent;
608 	u_int32_t ci;
609 
610 #if(0)
611 	device_printf(ch->parent->dev, "ichpchan_getptr(0x%08x)\n", data);
612 #endif
613 	ci = bus_space_read_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_CIV);
614 #if(0)
615 	device_printf(ch->parent->dev, "ichpchan_getptr():ICH_REG_PO_CIV = %d\n", ci);
616 #endif
617 	return ICH_DEFAULT_BLOCKSZ * ci;
618 }
619 
620 static struct pcmchan_caps *
621 ichpchan_getcaps(kobj_t obj, void *data)
622 {
623 	return &ich_playcaps;
624 }
625 
626 static kobj_method_t ichpchan_methods[] = {
627 	KOBJMETHOD(channel_init,		ichpchan_init),
628 	KOBJMETHOD(channel_free,		ichpchan_free),
629 	KOBJMETHOD(channel_setformat,		ichpchan_setformat),
630 	KOBJMETHOD(channel_setspeed,		ichpchan_setspeed),
631 	KOBJMETHOD(channel_setblocksize,	ichpchan_setblocksize),
632 	KOBJMETHOD(channel_trigger,		ichpchan_trigger),
633 	KOBJMETHOD(channel_getptr,		ichpchan_getptr),
634 	KOBJMETHOD(channel_getcaps,		ichpchan_getcaps),
635 	{ 0, 0 }
636 };
637 CHANNEL_DECLARE(ichpchan);
638 
639 /* -------------------------------------------------------------------- */
640 /* record channel interface */
641 static int
642 ichrchan_power(kobj_t obj, struct sc_info *sc, int sw)
643 {
644 	u_int32_t cr;
645 	int i;
646 
647 	cr = ich_rdcd(obj, sc, AC97_REG_POWER);
648 	if (sw) { /* power on */
649 		cr &= ~AC97_POWER_PINPOWER;
650 		ich_wrcd(obj, sc, AC97_REG_POWER, cr);
651 		for (i = 0;i < ICH_TIMEOUT;i++) {
652 			cr = ich_rdcd(obj, sc, AC97_REG_POWER);
653 			if ((cr & AC97_POWER_PINREADY) != 0)
654 				break;
655 		}
656 	}
657 	else { /* power off */
658 		cr |= AC97_POWER_PINPOWER;
659 		ich_wrcd(obj, sc, AC97_REG_POWER, cr);
660 		for (i = 0;i < ICH_TIMEOUT;i++) {
661 			cr = ich_rdcd(obj, sc, AC97_REG_POWER);
662 			if ((cr & AC97_POWER_PINREADY) == 0)
663 				break;
664 		}
665 	}
666 	if (i == ICH_TIMEOUT)
667 		return -1;
668 	return 0;
669 }
670 
671 static u_int32_t
672 ichrchan_getminspeed(kobj_t obj, void *data)
673 {
674 	struct sc_chinfo *ch = data;
675 	u_int32_t extcap;
676 	u_int32_t minspeed = 48000; /* before AC'97 R2.0 */
677 	int i = 0;
678 
679 	extcap = ac97_getextmode(ch->parent->codec);
680 	if (extcap & AC97_EXTCAP_VRM) {
681 		for (i = 0;ich_rate[i] != 0;i++) {
682 			if (ac97_setrate(ch->parent->codec, AC97_REGEXT_LADCRATE, ich_rate[i]) == ich_rate[i])
683 				minspeed = ich_rate[i];
684 		}
685 	}
686 	return minspeed;
687 }
688 
689 static void *
690 ichrchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
691 {
692 	struct sc_info *sc = devinfo;
693 	struct sc_chinfo *ch;
694 	u_int32_t cr;
695 	int i;
696 
697 	/* reset codec */
698 	bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_CR, 0);
699 	bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_CR,
700 	    ICH_X_CR_RR);
701 	for (i = 0;i < ICH_TIMEOUT;i++) {
702 		cr = bus_space_read_1(sc->nabmbart, sc->nabmbarh,
703 		    ICH_REG_PI_CR);
704 		if (cr == 0)
705 			break;
706 	}
707 	if (i == ICH_TIMEOUT) {
708 		device_printf(sc->dev, "cannot reset record codec\n");
709 		return NULL;
710 	}
711 	if (ichrchan_power(obj, sc, 1) == -1) {
712 		device_printf(sc->dev, "record ADC not ready\n");
713 		return NULL;
714 	}
715 	ichrchan_power(obj, sc, 0);
716 	if ((ch = malloc(sizeof(*ch), M_DEVBUF, M_NOWAIT)) == NULL) {
717 		device_printf(sc->dev, "cannot allocate channel info area\n");
718 		return NULL;
719 	}
720 	ch->buffer = b;
721 	ch->channel = c;
722 	ch->parent = sc;
723 	ch->dir = PCMDIR_REC;
724 	ch->run = 0;
725 	ch->lvi = 0;
726 	if (ichchan_initbuf(ch)) {
727 		device_printf(sc->dev, "cannot allocate channel buffer\n");
728 		free(ch, M_DEVBUF);
729 		return NULL;
730 	}
731 	bus_space_write_4(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_BDBAR,
732 	    (u_int32_t)vtophys(ch->index));
733 	sc->pi = ch;
734 	if (bootverbose) {
735 		device_printf(sc->dev,"Record codec support rate(Hz): ");
736 		for (i = 0;ich_rate[i] != 0;i++) {
737 			if (ichrchan_setspeed(obj, ch, ich_rate[i]) == ich_rate[i]) {
738 				printf("%d ", ich_rate[i]);
739 			}
740 		}
741 		printf("\n");
742 	}
743 	ich_reccaps.minspeed = ichrchan_getminspeed(obj, ch);
744 	return ch;
745 }
746 
747 static int
748 ichrchan_free(kobj_t obj, void *data)
749 {
750 	struct sc_chinfo *ch = data;
751 	ichchan_free(ch);
752 	return ichrchan_power(obj, ch->parent, 0);
753 }
754 
755 static int
756 ichrchan_setformat(kobj_t obj, void *data, u_int32_t format)
757 {
758 	struct sc_chinfo *ch = data;
759 
760 	ch->fmt = format;
761 
762 	return 0;
763 }
764 
765 static int
766 ichrchan_setspeed(kobj_t obj, void *data, u_int32_t speed)
767 {
768 	struct sc_chinfo *ch = data;
769 	u_int32_t extcap;
770 
771 	extcap = ac97_getextmode(ch->parent->codec);
772 	if (extcap & AC97_EXTCAP_VRM) {
773 		ch->spd = (u_int32_t)ac97_setrate(ch->parent->codec, AC97_REGEXT_LADCRATE, speed);
774 	}
775 	else {
776 		ch->spd = 48000; /* before AC'97 R2.0 */
777 	}
778 
779 	return ch->spd;
780 }
781 
782 static int
783 ichrchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
784 {
785 	return blocksize;
786 }
787 
788 /* semantic note: must start at beginning of buffer */
789 static int
790 ichrchan_trigger(kobj_t obj, void *data, int go)
791 {
792 	struct sc_chinfo *ch = data;
793 	struct sc_info *sc = ch->parent;
794 	u_int32_t cr;
795 	int i;
796 
797 	switch (go) {
798 	case PCMTRIG_START:
799 		ch->run = 1;
800 		ichrchan_power(obj, sc, 1);
801 		bus_space_write_4(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_BDBAR,
802 		    (u_int32_t)vtophys(ch->index));
803 		ch->lvi = ICH_FIFOINDEX - 1;
804 		bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_LVI,
805 		    ch->lvi);
806 		bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_CR,
807 		    ICH_X_CR_RPBM | ICH_X_CR_LVBIE | ICH_X_CR_IOCE |
808 		    ICH_X_CR_FEIE);
809 		break;
810 	case PCMTRIG_STOP:
811 		cr = bus_space_read_1(sc->nabmbart, sc->nabmbarh,
812 		    ICH_REG_PI_CR);
813 		bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_CR,
814 		    cr & ~ICH_X_CR_RPBM);
815 		ichrchan_power(obj, sc, 0);
816 		ch->run = 0;
817 		break;
818 	case PCMTRIG_ABORT:
819 		bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_CR,
820 		    0);
821 		bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_CR,
822 		    ICH_X_CR_RR);
823 		for (i = 0;i < ICH_TIMEOUT;i++) {
824 			cr = bus_space_read_1(sc->nabmbart, sc->nabmbarh,
825 			    ICH_REG_PI_CR);
826 			if (cr == 0)
827 				break;
828 		}
829 		ichrchan_power(obj, sc, 0);
830 		ch->run = 0;
831 		ch->lvi = 0;
832 		break;
833 	default:
834 		break;
835 	}
836 	return 0;
837 }
838 
839 static int
840 ichrchan_getptr(kobj_t obj, void *data)
841 {
842 	struct sc_chinfo *ch = data;
843 	struct sc_info *sc = ch->parent;
844 	u_int32_t ci;
845 
846 	ci = bus_space_read_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_CIV);
847 	return ci * ICH_DEFAULT_BLOCKSZ;
848 }
849 
850 static struct pcmchan_caps *
851 ichrchan_getcaps(kobj_t obj, void *data)
852 {
853 	return &ich_reccaps;
854 }
855 
856 static kobj_method_t ichrchan_methods[] = {
857 	KOBJMETHOD(channel_init,		ichrchan_init),
858 	KOBJMETHOD(channel_free,		ichrchan_free),
859 	KOBJMETHOD(channel_setformat,		ichrchan_setformat),
860 	KOBJMETHOD(channel_setspeed,		ichrchan_setspeed),
861 	KOBJMETHOD(channel_setblocksize,	ichrchan_setblocksize),
862 	KOBJMETHOD(channel_trigger,		ichrchan_trigger),
863 	KOBJMETHOD(channel_getptr,		ichrchan_getptr),
864 	KOBJMETHOD(channel_getcaps,		ichrchan_getcaps),
865 	{ 0, 0 }
866 };
867 CHANNEL_DECLARE(ichrchan);
868 
869 /* -------------------------------------------------------------------- */
870 /* The interrupt handler */
871 static void
872 ich_intr(void *p)
873 {
874 	struct sc_info *sc = (struct sc_info *)p;
875 	struct sc_chinfo *ch;
876 	u_int32_t cp;
877 	u_int32_t sg;
878 	u_int32_t st;
879 	u_int32_t lvi = 0;
880 
881 #if(0)
882 	device_printf(sc->dev, "ich_intr(0x%08x)\n", p);
883 #endif
884 	/* check interface status */
885 	sg = bus_space_read_4(sc->nabmbart, sc->nabmbarh, ICH_REG_GLOB_STA);
886 #if(0)
887 	device_printf(sc->dev, "ich_intr():REG_GLOB_STA = 0x%08x\n", sg);
888 #endif
889 	if (sg & ICH_GLOB_STA_POINT) {
890 		/* PCM Out INTerrupt */
891 		/* mask interrupt */
892 		cp = bus_space_read_1(sc->nabmbart, sc->nabmbarh,
893 		    ICH_REG_PO_CR);
894 		cp &= ~(ICH_X_CR_LVBIE | ICH_X_CR_IOCE | ICH_X_CR_FEIE);
895 		bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_CR,
896 		    cp);
897 		/* check channel status */
898 		ch = sc->po;
899 		st = bus_space_read_2(sc->nabmbart, sc->nabmbarh,
900 		    ICH_REG_PO_SR);
901 #if(0)
902 		device_printf(sc->dev, "ich_intr():REG_PO_SR = 0x%02x\n", st);
903 #endif
904 		if (st & (ICH_X_SR_BCIS | ICH_X_SR_LVBCI)) {
905 			/* play buffer block complete */
906 			if (st & ICH_X_SR_LVBCI)
907 				lvi = ch->lvi;
908 			/* update buffer */
909 			chn_intr(ch->channel);
910 			ichpchan_update(ch);
911 			if (st & ICH_X_SR_LVBCI) {
912 				/* re-check underflow status */
913 				if (lvi == ch->lvi) {
914 					/* ch->buffer->underflow = 1; */
915 					ichpchan_fillblank(ch);
916 				}
917 			}
918 		}
919 		/* clear status bit */
920 		bus_space_write_2(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_SR,
921 		    st & (ICH_X_SR_FIFOE | ICH_X_SR_BCIS | ICH_X_SR_LVBCI));
922 		/* set interrupt */
923 		cp |= (ICH_X_CR_LVBIE | ICH_X_CR_IOCE | ICH_X_CR_FEIE);
924 		bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PO_CR,
925 		    cp);
926 	}
927 	if (sg & ICH_GLOB_STA_PIINT) {
928 		/* PCM In INTerrupt */
929 		/* mask interrupt */
930 		cp = bus_space_read_1(sc->nabmbart, sc->nabmbarh,
931 		    ICH_REG_PI_CR);
932 		cp &= ~(ICH_X_CR_LVBIE | ICH_X_CR_IOCE | ICH_X_CR_FEIE);
933 		bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_CR,
934 		    cp);
935 		/* check channel status */
936 		ch = sc->pi;
937 		st = bus_space_read_2(sc->nabmbart, sc->nabmbarh,
938 		    ICH_REG_PI_SR);
939 #if(0)
940 		device_printf(sc->dev, "ich_intr():REG_PI_SR = 0x%02x\n", st);
941 #endif
942 		if (st & (ICH_X_SR_BCIS | ICH_X_SR_LVBCI)) {
943 			/* record buffer block filled */
944 			if (st & ICH_X_SR_LVBCI)
945 				lvi = ch->lvi;
946 			/* update space */
947 			chn_intr(ch->channel);
948 			ch->lvi = sndbuf_getreadyptr(ch->buffer) / ICH_DEFAULT_BLOCKSZ - 1;
949 			if (ch->lvi < 0)
950 				ch->lvi = ICH_FIFOINDEX - 1;
951 			bus_space_write_1(sc->nabmbart, sc->nabmbarh,
952 			    ICH_REG_PI_LVI, ch->lvi);
953 			if (st & ICH_X_SR_LVBCI) {
954 				/* re-check underflow status */
955 				if (lvi == ch->lvi) {
956 					ch->lvi++;
957 					if (ch->lvi == ICH_FIFOINDEX)
958 						ch->lvi = 0;
959 					bus_space_write_1(sc->nabmbart,
960 					    sc->nabmbarh, ICH_REG_PI_LVI,
961 					    ch->lvi);
962 				}
963 			}
964 		}
965 		/* clear status bit */
966 		bus_space_write_2(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_SR,
967 		    st & (ICH_X_SR_FIFOE | ICH_X_SR_BCIS | ICH_X_SR_LVBCI));
968 		/* set interrupt */
969 		cp |= (ICH_X_CR_LVBIE | ICH_X_CR_IOCE | ICH_X_CR_FEIE);
970 		bus_space_write_1(sc->nabmbart, sc->nabmbarh, ICH_REG_PI_CR,
971 		    cp);
972 	}
973 }
974 
975 /* -------------------------------------------------------------------- */
976 
977 /*
978  * Probe and attach the card
979  */
980 
981 static int
982 ich_init(struct sc_info *sc)
983 {
984 	u_int32_t stat;
985 	u_int32_t save;
986 
987 	bus_space_write_4(sc->nabmbart, sc->nabmbarh,
988 	    ICH_REG_GLOB_CNT, ICH_GLOB_CTL_COLD);
989 	DELAY(600000);
990 	stat = bus_space_read_4(sc->nabmbart, sc->nabmbarh, ICH_REG_GLOB_STA);
991 	if ((stat & ICH_GLOB_STA_PCR) == 0)
992 		return -1;
993 	bus_space_write_4(sc->nabmbart, sc->nabmbarh,
994 	    ICH_REG_GLOB_CNT, ICH_GLOB_CTL_COLD | ICH_GLOB_CTL_PRES);
995 	save = bus_space_read_2(sc->nambart, sc->nambarh, AC97_MIX_MASTER);
996 	bus_space_write_2(sc->nambart, sc->nambarh, AC97_MIX_MASTER,
997 			  AC97_MUTE);
998 	if (ich_waitcd(sc) == ETIMEDOUT)
999 		return -1;
1000 	DELAY(600); /* it is need for some system */
1001 	stat = bus_space_read_2(sc->nambart, sc->nambarh, AC97_MIX_MASTER);
1002 	if (stat != AC97_MUTE)
1003 		return -1;
1004 	bus_space_write_2(sc->nambart, sc->nambarh, AC97_MIX_MASTER, save);
1005 	return 0;
1006 }
1007 
1008 static int
1009 ich_finddev(u_int32_t dev, u_int32_t subdev)
1010 {
1011 	int i;
1012 
1013 	for (i = 0; ich_devs[i].dev; i++) {
1014 		if (ich_devs[i].dev == dev &&
1015 		    (ich_devs[i].subdev == subdev || ich_devs[i].subdev == 0))
1016 			return i;
1017 	}
1018 	return -1;
1019 }
1020 
1021 static int
1022 ich_pci_probe(device_t dev)
1023 {
1024 	int i;
1025 	u_int32_t subdev;
1026 
1027 	subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev);
1028 	i = ich_finddev(pci_get_devid(dev), subdev);
1029 	if (i >= 0) {
1030 		device_set_desc(dev, ich_devs[i].name);
1031 		return 0;
1032 	} else
1033 		return ENXIO;
1034 }
1035 
1036 static int
1037 ich_pci_attach(device_t dev)
1038 {
1039 	u_int32_t		data;
1040 	u_int32_t		subdev;
1041 	struct sc_info 		*sc;
1042 	char 			status[SND_STATUSLEN];
1043 
1044 	if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) {
1045 		device_printf(dev, "cannot allocate softc\n");
1046 		return ENXIO;
1047 	}
1048 
1049 	bzero(sc, sizeof(*sc));
1050 	sc->dev = dev;
1051 	subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev);
1052 	sc->type = ich_finddev(pci_get_devid(dev), subdev);
1053 	sc->rev = pci_get_revid(dev);
1054 
1055 	data = pci_read_config(dev, PCIR_COMMAND, 2);
1056 	data |= (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
1057 	pci_write_config(dev, PCIR_COMMAND, data, 2);
1058 	data = pci_read_config(dev, PCIR_COMMAND, 2);
1059 
1060 	sc->nambarid = PCIR_NAMBAR;
1061 	sc->nabmbarid = PCIR_NABMBAR;
1062 	sc->nambar = bus_alloc_resource(dev, SYS_RES_IOPORT,
1063 	    &sc->nambarid, 0, ~0, 256, RF_ACTIVE);
1064 	sc->nabmbar = bus_alloc_resource(dev, SYS_RES_IOPORT,
1065 	    &sc->nabmbarid, 0, ~0, 64, RF_ACTIVE);
1066 	if (!sc->nambar || !sc->nabmbar) {
1067 		device_printf(dev, "unable to map IO port space\n");
1068 		goto bad;
1069 	}
1070 	sc->nambart = rman_get_bustag(sc->nambar);
1071 	sc->nambarh = rman_get_bushandle(sc->nambar);
1072 	sc->nabmbart = rman_get_bustag(sc->nabmbar);
1073 	sc->nabmbarh = rman_get_bushandle(sc->nabmbar);
1074 
1075 	if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/4, /*boundary*/0,
1076 	    /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
1077 	    /*highaddr*/BUS_SPACE_MAXADDR,
1078 	    /*filter*/NULL, /*filterarg*/NULL,
1079 	    /*maxsize*/65536, /*nsegments*/1, /*maxsegsz*/0x3ffff,
1080 	    /*flags*/0, &sc->dmat) != 0) {
1081 		device_printf(dev, "unable to create dma tag\n");
1082 		goto bad;
1083 	}
1084 
1085 	if (ich_init(sc) == -1) {
1086 		device_printf(dev, "unable to initialize the card\n");
1087 		goto bad;
1088 	}
1089 
1090 	sc->codec = AC97_CREATE(dev, sc, ich_ac97);
1091 	if (sc->codec == NULL)
1092 		goto bad;
1093 	mixer_init(dev, ac97_getmixerclass(), sc->codec);
1094 	/* check and set VRA function */
1095 	if (ac97_setextmode(sc->codec, AC97_EXTCAP_VRA) == 0) {
1096 		if (bootverbose) {
1097 			device_printf(sc->dev, "set VRA function\n");
1098 		}
1099 	}
1100 	if (ac97_setextmode(sc->codec, AC97_EXTCAP_VRM) == 0) {
1101 		if (bootverbose) {
1102 			device_printf(sc->dev, "set VRM function\n");
1103 		}
1104 	}
1105 
1106 	sc->irqid = 0;
1107 	sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid,
1108 				 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
1109 	if (!sc->irq ||
1110 	    bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, ich_intr, sc, &sc->ih)) {
1111 		device_printf(dev, "unable to map interrupt\n");
1112 		goto bad;
1113 	}
1114 
1115 	snprintf(status, SND_STATUSLEN,
1116 	    "at io 0x%lx-0x%lx, 0x%lx-0x%lx irq %ld",
1117 	    rman_get_start(sc->nambar), rman_get_end(sc->nambar),
1118 	    rman_get_start(sc->nabmbar), rman_get_end(sc->nabmbar),
1119 	    rman_get_start(sc->irq));
1120 
1121 	if (pcm_register(dev, sc, 1, 1))
1122 		goto bad;
1123 	pcm_addchan(dev, PCMDIR_PLAY, &ichpchan_class, sc);
1124 	pcm_addchan(dev, PCMDIR_REC, &ichrchan_class, sc);
1125 	pcm_setstatus(dev, status);
1126 
1127 	return 0;
1128 
1129 bad:
1130 	if (sc->codec)
1131 		ac97_destroy(sc->codec);
1132 	if (sc->nambar)
1133 		bus_release_resource(dev, SYS_RES_IOPORT,
1134 		    sc->nambarid, sc->nambar);
1135 	if (sc->nabmbar)
1136 		bus_release_resource(dev, SYS_RES_IOPORT,
1137 		    sc->nabmbarid, sc->nabmbar);
1138 	if (sc->ih)
1139 		bus_teardown_intr(dev, sc->irq, sc->ih);
1140 	if (sc->irq)
1141 		bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
1142 	free(sc, M_DEVBUF);
1143 	return ENXIO;
1144 }
1145 
1146 static int
1147 ich_pci_detach(device_t dev)
1148 {
1149 	struct sc_info *sc;
1150 	int r;
1151 
1152 	r = pcm_unregister(dev);
1153 	if (r)
1154 		return r;
1155 	sc = pcm_getdevinfo(dev);
1156 
1157 	bus_release_resource(dev, SYS_RES_IOPORT, sc->nambarid, sc->nambar);
1158 	bus_release_resource(dev, SYS_RES_IOPORT, sc->nabmbarid, sc->nabmbar);
1159 	bus_dma_tag_destroy(sc->dmat);
1160 	bus_teardown_intr(dev, sc->irq, sc->ih);
1161 	bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
1162 	free(sc, M_DEVBUF);
1163 	return 0;
1164 }
1165 
1166 static int
1167 ich_pci_resume(device_t dev)
1168 {
1169 	struct sc_info *sc;
1170 
1171 	sc = pcm_getdevinfo(dev);
1172 
1173 	/* Reinit audio device */
1174     	if (ich_init(sc) == -1) {
1175 		device_printf(dev, "unable to reinitialize the card\n");
1176 		return ENXIO;
1177 	}
1178 	/* Reinit mixer */
1179     	if (mixer_reinit(dev) == -1) {
1180 		device_printf(dev, "unable to reinitialize the mixer\n");
1181 		return ENXIO;
1182 	}
1183 	return 0;
1184 }
1185 
1186 static device_method_t ich_methods[] = {
1187 	/* Device interface */
1188 	DEVMETHOD(device_probe,		ich_pci_probe),
1189 	DEVMETHOD(device_attach,	ich_pci_attach),
1190 	DEVMETHOD(device_detach,	ich_pci_detach),
1191 	DEVMETHOD(device_resume,	ich_pci_resume),
1192 	{ 0, 0 }
1193 };
1194 
1195 static driver_t ich_driver = {
1196 	"pcm",
1197 	ich_methods,
1198 	sizeof(struct snddev_info),
1199 };
1200 
1201 DRIVER_MODULE(snd_ich, pci, ich_driver, pcm_devclass, 0, 0);
1202 MODULE_DEPEND(snd_ich, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER);
1203 MODULE_VERSION(snd_ich, 1);
1204