Remove ASR_MEASURE_PERFORMANCE, it doesn't work anyway.
[dragonfly.git] / sys / dev / sound / pci / ich.c
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  * $FreeBSD: src/sys/dev/sound/pci/ich.c,v 1.3.2.12 2003/01/20 03:59:42 orion Exp $
28  * $DragonFly: src/sys/dev/sound/pci/ich.c,v 1.6 2004/04/08 15:16:50 joerg Exp $
29  */
30
31 #include <dev/sound/pcm/sound.h>
32 #include <dev/sound/pcm/ac97.h>
33 #include <dev/sound/pci/ich.h>
34
35 #include <bus/pci/pcireg.h>
36 #include <bus/pci/pcivar.h>
37
38 SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pci/ich.c,v 1.6 2004/04/08 15:16:50 joerg Exp $");
39
40 /* -------------------------------------------------------------------- */
41
42 #define ICH_TIMEOUT 1000 /* semaphore timeout polling count */
43 #define ICH_DTBL_LENGTH 32
44 #define ICH_DEFAULT_BUFSZ 16384
45 #define ICH_MAX_BUFSZ 65536
46
47 #define SIS7012ID       0x70121039      /* SiS 7012 needs special handling */
48 #define ICH4ID          0x24c58086      /* ICH4 needs special handling too */
49 #define ICH5ID          0x24d58086      /* ICH5 needs to be treated as ICH4 */
50
51 /* buffer descriptor */
52 struct ich_desc {
53         volatile u_int32_t buffer;
54         volatile u_int32_t length;
55 };
56
57 struct sc_info;
58
59 /* channel registers */
60 struct sc_chinfo {
61         u_int32_t num:8, run:1, run_save:1;
62         u_int32_t blksz, blkcnt, spd;
63         u_int32_t regbase, spdreg;
64         u_int32_t imask;
65         u_int32_t civ;
66
67         struct snd_dbuf *buffer;
68         struct pcm_channel *channel;
69         struct sc_info *parent;
70
71         struct ich_desc *dtbl;
72 };
73
74 /* device private data */
75 struct sc_info {
76         device_t dev;
77         int hasvra, hasvrm, hasmic;
78         unsigned int chnum, bufsz;
79         int sample_size, swap_reg;
80
81         struct resource *nambar, *nabmbar, *irq;
82         int regtype, nambarid, nabmbarid, irqid;
83         bus_space_tag_t nambart, nabmbart;
84         bus_space_handle_t nambarh, nabmbarh;
85         bus_dma_tag_t dmat;
86         bus_dmamap_t dtmap;
87         void *ih;
88
89         struct ac97_info *codec;
90         struct sc_chinfo ch[3];
91         int ac97rate;
92         struct ich_desc *dtbl;
93         struct intr_config_hook intrhook;
94         int use_intrhook;
95 };
96
97 /* -------------------------------------------------------------------- */
98
99 static u_int32_t ich_fmt[] = {
100         AFMT_STEREO | AFMT_S16_LE,
101         0
102 };
103 static struct pcmchan_caps ich_vrcaps = {8000, 48000, ich_fmt, 0};
104 static struct pcmchan_caps ich_caps = {48000, 48000, ich_fmt, 0};
105
106 /* -------------------------------------------------------------------- */
107 /* Hardware */
108 static u_int32_t
109 ich_rd(struct sc_info *sc, int regno, int size)
110 {
111         switch (size) {
112         case 1:
113                 return bus_space_read_1(sc->nabmbart, sc->nabmbarh, regno);
114         case 2:
115                 return bus_space_read_2(sc->nabmbart, sc->nabmbarh, regno);
116         case 4:
117                 return bus_space_read_4(sc->nabmbart, sc->nabmbarh, regno);
118         default:
119                 return 0xffffffff;
120         }
121 }
122
123 static void
124 ich_wr(struct sc_info *sc, int regno, u_int32_t data, int size)
125 {
126         switch (size) {
127         case 1:
128                 bus_space_write_1(sc->nabmbart, sc->nabmbarh, regno, data);
129                 break;
130         case 2:
131                 bus_space_write_2(sc->nabmbart, sc->nabmbarh, regno, data);
132                 break;
133         case 4:
134                 bus_space_write_4(sc->nabmbart, sc->nabmbarh, regno, data);
135                 break;
136         }
137 }
138
139 /* ac97 codec */
140 static int
141 ich_waitcd(void *devinfo)
142 {
143         int i;
144         u_int32_t data;
145         struct sc_info *sc = (struct sc_info *)devinfo;
146
147         for (i = 0; i < ICH_TIMEOUT; i++) {
148                 data = ich_rd(sc, ICH_REG_ACC_SEMA, 1);
149                 if ((data & 0x01) == 0)
150                         return 0;
151         }
152         device_printf(sc->dev, "CODEC semaphore timeout\n");
153         return ETIMEDOUT;
154 }
155
156 static int
157 ich_rdcd(kobj_t obj, void *devinfo, int regno)
158 {
159         struct sc_info *sc = (struct sc_info *)devinfo;
160
161         regno &= 0xff;
162         ich_waitcd(sc);
163
164         return bus_space_read_2(sc->nambart, sc->nambarh, regno);
165 }
166
167 static int
168 ich_wrcd(kobj_t obj, void *devinfo, int regno, u_int16_t data)
169 {
170         struct sc_info *sc = (struct sc_info *)devinfo;
171
172         regno &= 0xff;
173         ich_waitcd(sc);
174         bus_space_write_2(sc->nambart, sc->nambarh, regno, data);
175
176         return 0;
177 }
178
179 static kobj_method_t ich_ac97_methods[] = {
180         KOBJMETHOD(ac97_read,           ich_rdcd),
181         KOBJMETHOD(ac97_write,          ich_wrcd),
182         { 0, 0 }
183 };
184 AC97_DECLARE(ich_ac97);
185
186 /* -------------------------------------------------------------------- */
187 /* common routines */
188
189 static void
190 ich_filldtbl(struct sc_chinfo *ch)
191 {
192         u_int32_t base;
193         int i;
194
195         base = vtophys(sndbuf_getbuf(ch->buffer));
196         ch->blkcnt = sndbuf_getsize(ch->buffer) / ch->blksz;
197         if (ch->blkcnt != 2 && ch->blkcnt != 4 && ch->blkcnt != 8 && ch->blkcnt != 16 && ch->blkcnt != 32) {
198                 ch->blkcnt = 2;
199                 ch->blksz = sndbuf_getsize(ch->buffer) / ch->blkcnt;
200         }
201
202         for (i = 0; i < ICH_DTBL_LENGTH; i++) {
203                 ch->dtbl[i].buffer = base + (ch->blksz * (i % ch->blkcnt));
204                 ch->dtbl[i].length = ICH_BDC_IOC
205                                    | (ch->blksz / ch->parent->sample_size);
206         }
207 }
208
209 static int
210 ich_resetchan(struct sc_info *sc, int num)
211 {
212         int i, cr, regbase;
213
214         if (num == 0)
215                 regbase = ICH_REG_PO_BASE;
216         else if (num == 1)
217                 regbase = ICH_REG_PI_BASE;
218         else if (num == 2)
219                 regbase = ICH_REG_MC_BASE;
220         else
221                 return ENXIO;
222
223         ich_wr(sc, regbase + ICH_REG_X_CR, 0, 1);
224         DELAY(100);
225         ich_wr(sc, regbase + ICH_REG_X_CR, ICH_X_CR_RR, 1);
226         for (i = 0; i < ICH_TIMEOUT; i++) {
227                 cr = ich_rd(sc, regbase + ICH_REG_X_CR, 1);
228                 if (cr == 0)
229                         return 0;
230         }
231
232         device_printf(sc->dev, "cannot reset channel %d\n", num);
233         return ENXIO;
234 }
235
236 /* -------------------------------------------------------------------- */
237 /* channel interface */
238
239 static void *
240 ichchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
241 {
242         struct sc_info *sc = devinfo;
243         struct sc_chinfo *ch;
244         unsigned int num;
245
246         num = sc->chnum++;
247         ch = &sc->ch[num];
248         ch->num = num;
249         ch->buffer = b;
250         ch->channel = c;
251         ch->parent = sc;
252         ch->run = 0;
253         ch->dtbl = sc->dtbl + (ch->num * ICH_DTBL_LENGTH);
254         ch->blkcnt = 2;
255         ch->blksz = sc->bufsz / ch->blkcnt;
256
257         switch(ch->num) {
258         case 0: /* play */
259                 KASSERT(dir == PCMDIR_PLAY, ("wrong direction"));
260                 ch->regbase = ICH_REG_PO_BASE;
261                 ch->spdreg = sc->hasvra? AC97_REGEXT_FDACRATE : 0;
262                 ch->imask = ICH_GLOB_STA_POINT;
263                 break;
264
265         case 1: /* record */
266                 KASSERT(dir == PCMDIR_REC, ("wrong direction"));
267                 ch->regbase = ICH_REG_PI_BASE;
268                 ch->spdreg = sc->hasvra? AC97_REGEXT_LADCRATE : 0;
269                 ch->imask = ICH_GLOB_STA_PIINT;
270                 break;
271
272         case 2: /* mic */
273                 KASSERT(dir == PCMDIR_REC, ("wrong direction"));
274                 ch->regbase = ICH_REG_MC_BASE;
275                 ch->spdreg = sc->hasvrm? AC97_REGEXT_MADCRATE : 0;
276                 ch->imask = ICH_GLOB_STA_MINT;
277                 break;
278
279         default:
280                 return NULL;
281         }
282
283         if (sndbuf_alloc(ch->buffer, sc->dmat, sc->bufsz))
284                 return NULL;
285
286         ich_wr(sc, ch->regbase + ICH_REG_X_BDBAR, (u_int32_t)vtophys(ch->dtbl), 4);
287
288         return ch;
289 }
290
291 static int
292 ichchan_setformat(kobj_t obj, void *data, u_int32_t format)
293 {
294         return 0;
295 }
296
297 static int
298 ichchan_setspeed(kobj_t obj, void *data, u_int32_t speed)
299 {
300         struct sc_chinfo *ch = data;
301         struct sc_info *sc = ch->parent;
302
303         if (ch->spdreg) {
304                 int r;
305                 if (sc->ac97rate <= 32000 || sc->ac97rate >= 64000)
306                         sc->ac97rate = 48000;
307                 r = (speed * 48000) / sc->ac97rate;
308                 /*
309                  * Cast the return value of ac97_setrate() to u_int so that
310                  * the math don't overflow into the negative range.
311                  */
312                 ch->spd = ((u_int)ac97_setrate(sc->codec, ch->spdreg, r) *
313                     sc->ac97rate) / 48000;
314         } else {
315                 ch->spd = 48000;
316         }
317         return ch->spd;
318 }
319
320 static int
321 ichchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
322 {
323         struct sc_chinfo *ch = data;
324         struct sc_info *sc = ch->parent;
325
326         ch->blksz = blocksize;
327         ich_filldtbl(ch);
328         ich_wr(sc, ch->regbase + ICH_REG_X_LVI, ch->blkcnt - 1, 1);
329
330         return ch->blksz;
331 }
332
333 static int
334 ichchan_trigger(kobj_t obj, void *data, int go)
335 {
336         struct sc_chinfo *ch = data;
337         struct sc_info *sc = ch->parent;
338
339         switch (go) {
340         case PCMTRIG_START:
341                 ch->run = 1;
342                 ich_wr(sc, ch->regbase + ICH_REG_X_BDBAR, (u_int32_t)vtophys(ch->dtbl), 4);
343                 ich_wr(sc, ch->regbase + ICH_REG_X_CR, ICH_X_CR_RPBM | ICH_X_CR_LVBIE | ICH_X_CR_IOCE, 1);
344                 break;
345
346         case PCMTRIG_ABORT:
347                 ich_resetchan(sc, ch->num);
348                 ch->run = 0;
349                 break;
350         }
351         return 0;
352 }
353
354 static int
355 ichchan_getptr(kobj_t obj, void *data)
356 {
357         struct sc_chinfo *ch = data;
358         struct sc_info *sc = ch->parent;
359         u_int32_t pos;
360
361         ch->civ = ich_rd(sc, ch->regbase + ICH_REG_X_CIV, 1) % ch->blkcnt;
362
363         pos = ch->civ * ch->blksz;
364
365         return pos;
366 }
367
368 static struct pcmchan_caps *
369 ichchan_getcaps(kobj_t obj, void *data)
370 {
371         struct sc_chinfo *ch = data;
372
373         return ch->spdreg? &ich_vrcaps : &ich_caps;
374 }
375
376 static kobj_method_t ichchan_methods[] = {
377         KOBJMETHOD(channel_init,                ichchan_init),
378         KOBJMETHOD(channel_setformat,           ichchan_setformat),
379         KOBJMETHOD(channel_setspeed,            ichchan_setspeed),
380         KOBJMETHOD(channel_setblocksize,        ichchan_setblocksize),
381         KOBJMETHOD(channel_trigger,             ichchan_trigger),
382         KOBJMETHOD(channel_getptr,              ichchan_getptr),
383         KOBJMETHOD(channel_getcaps,             ichchan_getcaps),
384         { 0, 0 }
385 };
386 CHANNEL_DECLARE(ichchan);
387
388 /* -------------------------------------------------------------------- */
389 /* The interrupt handler */
390
391 static void
392 ich_intr(void *p)
393 {
394         struct sc_info *sc = (struct sc_info *)p;
395         struct sc_chinfo *ch;
396         u_int32_t cbi, lbi, lvi, st, gs;
397         int i;
398
399         gs = ich_rd(sc, ICH_REG_GLOB_STA, 4) & ICH_GLOB_STA_IMASK;
400         if (gs & (ICH_GLOB_STA_PRES | ICH_GLOB_STA_SRES)) {
401                 /* Clear resume interrupt(s) - nothing doing with them */
402                 ich_wr(sc, ICH_REG_GLOB_STA, gs, 4);
403         }
404         gs &= ~(ICH_GLOB_STA_PRES | ICH_GLOB_STA_SRES);
405
406         for (i = 0; i < 3; i++) {
407                 ch = &sc->ch[i];
408                 if ((ch->imask & gs) == 0)
409                         continue;
410                 gs &= ~ch->imask;
411                 st = ich_rd(sc, ch->regbase +
412                                 (sc->swap_reg ? ICH_REG_X_PICB : ICH_REG_X_SR),
413                             2);
414                 st &= ICH_X_SR_FIFOE | ICH_X_SR_BCIS | ICH_X_SR_LVBCI;
415                 if (st & (ICH_X_SR_BCIS | ICH_X_SR_LVBCI)) {
416                                 /* block complete - update buffer */
417                         if (ch->run)
418                                 chn_intr(ch->channel);
419                         lvi = ich_rd(sc, ch->regbase + ICH_REG_X_LVI, 1);
420                         cbi = ch->civ % ch->blkcnt;
421                         if (cbi == 0)
422                                 cbi = ch->blkcnt - 1;
423                         else
424                                 cbi--;
425                         lbi = lvi % ch->blkcnt;
426                         if (cbi >= lbi)
427                                 lvi += cbi - lbi;
428                         else
429                                 lvi += cbi + ch->blkcnt - lbi;
430                         lvi %= ICH_DTBL_LENGTH;
431                         ich_wr(sc, ch->regbase + ICH_REG_X_LVI, lvi, 1);
432
433                 }
434                 /* clear status bit */
435                 ich_wr(sc, ch->regbase +
436                            (sc->swap_reg ? ICH_REG_X_PICB : ICH_REG_X_SR),
437                        st, 2);
438         }
439         if (gs != 0) {
440                 device_printf(sc->dev,
441                               "Unhandled interrupt, gs_intr = %x\n", gs);
442         }
443 }
444
445 /* ------------------------------------------------------------------------- */
446 /*
447  * Sysctl to control ac97 speed (some boards appear to end up using
448  * XTAL_IN rather than BIT_CLK for link timing).
449  */
450
451
452 static int
453 ich_initsys(struct sc_info* sc)
454 {
455 #ifdef SND_DYNSYSCTL
456         SYSCTL_ADD_INT(snd_sysctl_tree(sc->dev),
457                        SYSCTL_CHILDREN(snd_sysctl_tree_top(sc->dev)),
458                        OID_AUTO, "ac97rate", CTLFLAG_RW,
459                        &sc->ac97rate, 48000,
460                        "AC97 link rate (default = 48000)");
461 #endif /* SND_DYNSYSCTL */
462         return 0;
463 }
464
465 /* -------------------------------------------------------------------- */
466 /* Calibrate card to determine the clock source.  The source maybe a
467  * function of the ac97 codec initialization code (to be investigated).
468  */
469
470 static
471 void ich_calibrate(void *arg)
472 {
473         struct sc_info *sc;
474         struct sc_chinfo *ch;
475         struct timeval t1, t2;
476         u_int8_t ociv, nciv;
477         u_int32_t wait_us, actual_48k_rate, bytes;
478
479         sc = (struct sc_info *)arg;
480         ch = &sc->ch[1];
481
482         if (sc->use_intrhook)
483                 config_intrhook_disestablish(&sc->intrhook);
484
485         /*
486          * Grab audio from input for fixed interval and compare how
487          * much we actually get with what we expect.  Interval needs
488          * to be sufficiently short that no interrupts are
489          * generated.
490          */
491
492         KASSERT(ch->regbase == ICH_REG_PI_BASE, ("wrong direction"));
493
494         bytes = sndbuf_getsize(ch->buffer) / 2;
495         ichchan_setblocksize(0, ch, bytes);
496
497         /*
498          * our data format is stereo, 16 bit so each sample is 4 bytes.
499          * assuming we get 48000 samples per second, we get 192000 bytes/sec.
500          * we're going to start recording with interrupts disabled and measure
501          * the time taken for one block to complete.  we know the block size,
502          * we know the time in microseconds, we calculate the sample rate:
503          *
504          * actual_rate [bps] = bytes / (time [s] * 4)
505          * actual_rate [bps] = (bytes * 1000000) / (time [us] * 4)
506          * actual_rate [Hz] = (bytes * 250000) / time [us]
507          */
508
509         /* prepare */
510         ociv = ich_rd(sc, ch->regbase + ICH_REG_X_CIV, 1);
511         nciv = ociv;
512         ich_wr(sc, ch->regbase + ICH_REG_X_BDBAR, (u_int32_t)vtophys(ch->dtbl), 4);
513
514         /* start */
515         microtime(&t1);
516         ich_wr(sc, ch->regbase + ICH_REG_X_CR, ICH_X_CR_RPBM, 1);
517
518         /* wait */
519         while (nciv == ociv) {
520                 microtime(&t2);
521                 if (t2.tv_sec - t1.tv_sec > 1)
522                         break;
523                 nciv = ich_rd(sc, ch->regbase + ICH_REG_X_CIV, 1);
524         }
525         microtime(&t2);
526
527         /* stop */
528         ich_wr(sc, ch->regbase + ICH_REG_X_CR, 0, 1);
529
530         /* reset */
531         DELAY(100);
532         ich_wr(sc, ch->regbase + ICH_REG_X_CR, ICH_X_CR_RR, 1);
533
534         /* turn time delta into us */
535         wait_us = ((t2.tv_sec - t1.tv_sec) * 1000000) + t2.tv_usec - t1.tv_usec;
536
537         if (nciv == ociv) {
538                 device_printf(sc->dev, "ac97 link rate calibration timed out after %d us\n", wait_us);
539                 return;
540         }
541
542         actual_48k_rate = (bytes * 250000) / wait_us;
543
544         if (actual_48k_rate < 47500 || actual_48k_rate > 48500) {
545                 sc->ac97rate = actual_48k_rate;
546         } else {
547                 sc->ac97rate = 48000;
548         }
549
550         if (bootverbose || sc->ac97rate != 48000) {
551                 device_printf(sc->dev, "measured ac97 link rate at %d Hz", actual_48k_rate);
552                 if (sc->ac97rate != actual_48k_rate)
553                         printf(", will use %d Hz", sc->ac97rate);
554                 printf("\n");
555         }
556         return;
557 }
558
559 /* -------------------------------------------------------------------- */
560 /* Probe and attach the card */
561
562 static void
563 ich_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
564 {
565         return;
566 }
567
568 static int
569 ich_init(struct sc_info *sc)
570 {
571         u_int32_t stat;
572         int sz;
573
574         ich_wr(sc, ICH_REG_GLOB_CNT, ICH_GLOB_CTL_COLD, 4);
575         DELAY(600000);
576         stat = ich_rd(sc, ICH_REG_GLOB_STA, 4);
577
578         if ((stat & ICH_GLOB_STA_PCR) == 0) {
579                 /* ICH4/ICH5 may fail when busmastering is enabled. Continue */
580                 if ((pci_get_devid(sc->dev) != ICH4ID) &&
581                     (pci_get_devid(sc->dev) != ICH5ID)) {
582                         return ENXIO;
583                 }
584         }
585
586         ich_wr(sc, ICH_REG_GLOB_CNT, ICH_GLOB_CTL_COLD | ICH_GLOB_CTL_PRES, 4);
587
588         if (ich_resetchan(sc, 0) || ich_resetchan(sc, 1))
589                 return ENXIO;
590         if (sc->hasmic && ich_resetchan(sc, 2))
591                 return ENXIO;
592
593         if (bus_dmamem_alloc(sc->dmat, (void **)&sc->dtbl, BUS_DMA_NOWAIT, &sc->dtmap))
594                 return ENOSPC;
595
596         sz = sizeof(struct ich_desc) * ICH_DTBL_LENGTH * 3;
597         if (bus_dmamap_load(sc->dmat, sc->dtmap, sc->dtbl, sz, ich_setmap, NULL, 0)) {
598                 bus_dmamem_free(sc->dmat, (void **)&sc->dtbl, sc->dtmap);
599                 return ENOSPC;
600         }
601
602         return 0;
603 }
604
605 static int
606 ich_pci_probe(device_t dev)
607 {
608         switch(pci_get_devid(dev)) {
609         case 0x71958086:
610                 device_set_desc(dev, "Intel 443MX");
611                 return 0;
612
613         case 0x24158086:
614                 device_set_desc(dev, "Intel ICH (82801AA)");
615                 return 0;
616
617         case 0x24258086:
618                 device_set_desc(dev, "Intel ICH (82801AB)");
619                 return 0;
620
621         case 0x24458086:
622                 device_set_desc(dev, "Intel ICH2 (82801BA)");
623                 return 0;
624
625         case 0x24858086:
626                 device_set_desc(dev, "Intel ICH3 (82801CA)");
627                 return 0;
628
629         case ICH4ID:
630                 device_set_desc(dev, "Intel ICH4 (82801DB)");
631                 return -1000;   /* allow a better driver to override us */
632
633         case ICH5ID:
634                 device_set_desc(dev, "Intel ICH5 (82801EB)");
635                 return -1000;   /* allow a better driver to override us */
636
637         case SIS7012ID:
638                 device_set_desc(dev, "SiS 7012");
639                 return 0;
640
641         case 0x01b110de:
642                 device_set_desc(dev, "Nvidia nForce");
643                 return 0;
644
645         case 0x006a10de:
646                 device_set_desc(dev, "Nvidia nForce2");
647                 return 0;
648
649         case 0x74451022:
650                 device_set_desc(dev, "AMD-768");
651                 return 0;
652
653         case 0x746d1022:
654                 device_set_desc(dev, "AMD-8111");
655                 return 0;
656
657         default:
658                 return ENXIO;
659         }
660 }
661
662 static int
663 ich_pci_attach(device_t dev)
664 {
665         u_int16_t               extcaps;
666         struct sc_info          *sc;
667         char                    status[SND_STATUSLEN];
668
669         if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) {
670                 device_printf(dev, "cannot allocate softc\n");
671                 return ENXIO;
672         }
673
674         bzero(sc, sizeof(*sc));
675         sc->dev = dev;
676
677         /*
678          * The SiS 7012 register set isn't quite like the standard ich.
679          * There really should be a general "quirks" mechanism.
680          */
681         if (pci_get_devid(dev) == SIS7012ID) {
682                 sc->swap_reg = 1;
683                 sc->sample_size = 1;
684         } else {
685                 sc->swap_reg = 0;
686                 sc->sample_size = 2;
687         }
688
689         /*
690          * Enable bus master. On ich4/5 this may prevent the detection of
691          * the primary codec becoming ready in ich_init().
692          */
693         pci_enable_busmaster(dev);
694
695         if ((pci_get_devid(dev) == ICH4ID) || (pci_get_devid(dev) == ICH5ID)) {
696                 sc->nambarid = PCIR_MMBAR;
697                 sc->nabmbarid = PCIR_MBBAR;
698                 sc->regtype = SYS_RES_MEMORY;
699                 pci_enable_io(dev, SYS_RES_MEMORY);
700         } else {
701                 sc->nambarid = PCIR_NAMBAR;
702                 sc->nabmbarid = PCIR_NABMBAR;
703                 sc->regtype = SYS_RES_IOPORT;
704                 pci_enable_io(dev, SYS_RES_IOPORT);
705         }
706
707         sc->nambar = bus_alloc_resource(dev, sc->regtype, &sc->nambarid, 0, ~0, 1, RF_ACTIVE);
708         sc->nabmbar = bus_alloc_resource(dev, sc->regtype, &sc->nabmbarid, 0, ~0, 1, RF_ACTIVE);
709
710         if (!sc->nambar || !sc->nabmbar) {
711                 device_printf(dev, "unable to map IO port space\n");
712                 goto bad;
713         }
714
715         sc->nambart = rman_get_bustag(sc->nambar);
716         sc->nambarh = rman_get_bushandle(sc->nambar);
717         sc->nabmbart = rman_get_bustag(sc->nabmbar);
718         sc->nabmbarh = rman_get_bushandle(sc->nabmbar);
719
720         sc->bufsz = pcm_getbuffersize(dev, 4096, ICH_DEFAULT_BUFSZ, ICH_MAX_BUFSZ);
721         if (bus_dma_tag_create(NULL, 8, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
722                                NULL, NULL, sc->bufsz, 1, 0x3ffff, 0, &sc->dmat) != 0) {
723                 device_printf(dev, "unable to create dma tag\n");
724                 goto bad;
725         }
726
727         sc->irqid = 0;
728         sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
729         if (!sc->irq || snd_setup_intr(dev, sc->irq, INTR_MPSAFE, ich_intr, sc, &sc->ih)) {
730                 device_printf(dev, "unable to map interrupt\n");
731                 goto bad;
732         }
733
734         if (ich_init(sc)) {
735                 device_printf(dev, "unable to initialize the card\n");
736                 goto bad;
737         }
738
739         sc->codec = AC97_CREATE(dev, sc, ich_ac97);
740         if (sc->codec == NULL)
741                 goto bad;
742         mixer_init(dev, ac97_getmixerclass(), sc->codec);
743
744         /* check and set VRA function */
745         extcaps = ac97_getextcaps(sc->codec);
746         sc->hasvra = extcaps & AC97_EXTCAP_VRA;
747         sc->hasvrm = extcaps & AC97_EXTCAP_VRM;
748         sc->hasmic = ac97_getcaps(sc->codec) & AC97_CAP_MICCHANNEL;
749         ac97_setextmode(sc->codec, sc->hasvra | sc->hasvrm);
750
751         if (pcm_register(dev, sc, 1, sc->hasmic? 2 : 1))
752                 goto bad;
753
754         pcm_addchan(dev, PCMDIR_PLAY, &ichchan_class, sc);              /* play */
755         pcm_addchan(dev, PCMDIR_REC, &ichchan_class, sc);               /* record */
756         if (sc->hasmic)
757                 pcm_addchan(dev, PCMDIR_REC, &ichchan_class, sc);       /* record mic */
758
759         snprintf(status, SND_STATUSLEN, "at io 0x%lx, 0x%lx irq %ld bufsz %u",
760                  rman_get_start(sc->nambar), rman_get_start(sc->nabmbar), rman_get_start(sc->irq), sc->bufsz);
761
762         pcm_setstatus(dev, status);
763
764         ich_initsys(sc);
765
766         sc->intrhook.ich_func = ich_calibrate;
767         sc->intrhook.ich_arg = sc;
768         sc->use_intrhook = 1;
769         if (config_intrhook_establish(&sc->intrhook) != 0) {
770                 device_printf(dev, "Cannot establish calibration hook, will calibrate now\n");
771                 sc->use_intrhook = 0;
772                 ich_calibrate(sc);
773         }
774
775         return 0;
776
777 bad:
778         if (sc->codec)
779                 ac97_destroy(sc->codec);
780         if (sc->ih)
781                 bus_teardown_intr(dev, sc->irq, sc->ih);
782         if (sc->irq)
783                 bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
784         if (sc->nambar)
785                 bus_release_resource(dev, sc->regtype,
786                     sc->nambarid, sc->nambar);
787         if (sc->nabmbar)
788                 bus_release_resource(dev, sc->regtype,
789                     sc->nabmbarid, sc->nabmbar);
790         free(sc, M_DEVBUF);
791         return ENXIO;
792 }
793
794 static int
795 ich_pci_detach(device_t dev)
796 {
797         struct sc_info *sc;
798         int r;
799
800         r = pcm_unregister(dev);
801         if (r)
802                 return r;
803         sc = pcm_getdevinfo(dev);
804
805         bus_teardown_intr(dev, sc->irq, sc->ih);
806         bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
807         bus_release_resource(dev, sc->regtype, sc->nambarid, sc->nambar);
808         bus_release_resource(dev, sc->regtype, sc->nabmbarid, sc->nabmbar);
809         bus_dma_tag_destroy(sc->dmat);
810         free(sc, M_DEVBUF);
811         return 0;
812 }
813
814 static int
815 ich_pci_suspend(device_t dev)
816 {
817         struct sc_info *sc;
818         int i;
819
820         sc = pcm_getdevinfo(dev);
821         for (i = 0 ; i < 3; i++) {
822                 sc->ch[i].run_save = sc->ch[i].run;
823                 if (sc->ch[i].run) {
824                         ichchan_trigger(0, &sc->ch[i], PCMTRIG_ABORT);
825                 }
826         }
827         return 0;
828 }
829
830 static int
831 ich_pci_resume(device_t dev)
832 {
833         struct sc_info *sc;
834         int i;
835
836         sc = pcm_getdevinfo(dev);
837
838         /* Reinit audio device */
839         if (ich_init(sc) == -1) {
840                 device_printf(dev, "unable to reinitialize the card\n");
841                 return ENXIO;
842         }
843         /* Reinit mixer */
844         if (mixer_reinit(dev) == -1) {
845                 device_printf(dev, "unable to reinitialize the mixer\n");
846                 return ENXIO;
847         }
848         /* Re-start DMA engines */
849         for (i = 0 ; i < 3; i++) {
850                 struct sc_chinfo *ch = &sc->ch[i];
851                 if (sc->ch[i].run_save) {
852                         ichchan_setblocksize(0, ch, ch->blksz);
853                         ichchan_setspeed(0, ch, ch->spd);
854                         ichchan_trigger(0, ch, PCMTRIG_START);
855                 }
856         }
857         return 0;
858 }
859
860 static device_method_t ich_methods[] = {
861         /* Device interface */
862         DEVMETHOD(device_probe,         ich_pci_probe),
863         DEVMETHOD(device_attach,        ich_pci_attach),
864         DEVMETHOD(device_detach,        ich_pci_detach),
865         DEVMETHOD(device_suspend,       ich_pci_suspend),
866         DEVMETHOD(device_resume,        ich_pci_resume),
867         { 0, 0 }
868 };
869
870 static driver_t ich_driver = {
871         "pcm",
872         ich_methods,
873         PCM_SOFTC_SIZE,
874 };
875
876 DRIVER_MODULE(snd_ich, pci, ich_driver, pcm_devclass, 0, 0);
877 MODULE_DEPEND(snd_ich, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER);
878 MODULE_VERSION(snd_ich, 1);