]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/dev/sound/pci/maestro.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / dev / sound / pci / maestro.c
1 /*-
2  * Copyright (c) 2000-2004 Taku YAMAMOTO <taku@tackymt.homeip.net>
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, WHETHER IN 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 THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  *      maestro.c,v 1.23.2.1 2003/10/03 18:21:38 taku Exp
27  */
28
29 /*
30  * Credits:
31  *
32  * Part of this code (especially in many magic numbers) was heavily inspired
33  * by the Linux driver originally written by
34  * Alan Cox <alan.cox@linux.org>, modified heavily by
35  * Zach Brown <zab@zabbo.net>.
36  *
37  * busdma()-ize and buffer size reduction were suggested by
38  * Cameron Grant <cg@freebsd.org>.
39  * Also he showed me the way to use busdma() suite.
40  *
41  * Internal speaker problems on NEC VersaPro's and Dell Inspiron 7500
42  * were looked at by
43  * Munehiro Matsuda <haro@tk.kubota.co.jp>,
44  * who brought patches based on the Linux driver with some simplification.
45  *
46  * Hardware volume controller was implemented by
47  * John Baldwin <jhb@freebsd.org>.
48  */
49
50 #ifdef HAVE_KERNEL_OPTION_HEADERS
51 #include "opt_snd.h"
52 #endif
53
54 #include <dev/sound/pcm/sound.h>
55 #include <dev/sound/pcm/ac97.h>
56 #include <dev/pci/pcireg.h>
57 #include <dev/pci/pcivar.h>
58
59 #include <dev/sound/pci/maestro_reg.h>
60
61 SND_DECLARE_FILE("$FreeBSD$");
62
63 /*
64  * PCI IDs of supported chips:
65  *
66  * MAESTRO-1    0x01001285
67  * MAESTRO-2    0x1968125d
68  * MAESTRO-2E   0x1978125d
69  */
70
71 #define MAESTRO_1_PCI_ID        0x01001285
72 #define MAESTRO_2_PCI_ID        0x1968125d
73 #define MAESTRO_2E_PCI_ID       0x1978125d
74
75 #define NEC_SUBID1      0x80581033      /* Taken from Linux driver */
76 #define NEC_SUBID2      0x803c1033      /* NEC VersaProNX VA26D    */
77
78 #ifdef AGG_MAXPLAYCH
79 # if AGG_MAXPLAYCH > 4
80 #  undef AGG_MAXPLAYCH
81 #  define AGG_MAXPLAYCH 4
82 # endif
83 #else
84 # define AGG_MAXPLAYCH  4
85 #endif
86
87 #define AGG_DEFAULT_BUFSZ       0x4000 /* 0x1000, but gets underflows */
88
89
90 /* compatibility */
91 #if __FreeBSD_version < 500000
92 # define critical_enter()       disable_intr()
93 # define critical_exit()        enable_intr()
94 #endif
95
96 #ifndef PCIR_BAR
97 #define PCIR_BAR(x)     (PCIR_MAPS + (x) * 4)
98 #endif
99
100
101 /* -----------------------------
102  * Data structures.
103  */
104 struct agg_chinfo {
105         /* parent softc */
106         struct agg_info         *parent;
107
108         /* FreeBSD newpcm related */
109         struct pcm_channel      *channel;
110         struct snd_dbuf         *buffer;
111
112         /* OS independent */
113         bus_addr_t              phys;   /* channel buffer physical address */
114         bus_addr_t              base;   /* channel buffer segment base */
115         u_int32_t               blklen; /* DMA block length in WORDs */
116         u_int32_t               buflen; /* channel buffer length in WORDs */
117         u_int32_t               speed;
118         unsigned                num     : 3;
119         unsigned                stereo  : 1;
120         unsigned                qs16    : 1;    /* quantum size is 16bit */
121         unsigned                us      : 1;    /* in unsigned format */
122 };
123
124 struct agg_rchinfo {
125         /* parent softc */
126         struct agg_info         *parent;
127
128         /* FreeBSD newpcm related */
129         struct pcm_channel      *channel;
130         struct snd_dbuf         *buffer;
131
132         /* OS independent */
133         bus_addr_t              phys;   /* channel buffer physical address */
134         bus_addr_t              base;   /* channel buffer segment base */
135         u_int32_t               blklen; /* DMA block length in WORDs */
136         u_int32_t               buflen; /* channel buffer length in WORDs */
137         u_int32_t               speed;
138         unsigned                        : 3;
139         unsigned                stereo  : 1;
140         bus_addr_t              srcphys;
141         int16_t                 *src;   /* stereo peer buffer */
142         int16_t                 *sink;  /* channel buffer pointer */
143         volatile u_int32_t      hwptr;  /* ready point in 16bit sample */
144 };
145
146 struct agg_info {
147         /* FreeBSD newbus related */
148         device_t                dev;
149
150         /* I wonder whether bus_space_* are in common in *BSD... */
151         struct resource         *reg;
152         int                     regid;
153         bus_space_tag_t         st;
154         bus_space_handle_t      sh;
155
156         struct resource         *irq;
157         int                     irqid;
158         void                    *ih;
159
160         bus_dma_tag_t           buf_dmat;
161         bus_dma_tag_t           stat_dmat;
162
163         /* FreeBSD SMPng related */
164         struct mtx              lock;   /* mutual exclusion */
165         /* FreeBSD newpcm related */
166         struct ac97_info        *codec;
167
168         /* OS independent */
169         u_int8_t                *stat;  /* status buffer pointer */
170         bus_addr_t              phys;   /* status buffer physical address */
171         unsigned int            bufsz;  /* channel buffer size in bytes */
172         u_int                   playchns;
173         volatile u_int          active;
174         struct agg_chinfo       pch[AGG_MAXPLAYCH];
175         struct agg_rchinfo      rch;
176         volatile u_int8_t       curpwr; /* current power status: D[0-3] */
177 };
178
179
180 /* -----------------------------
181  * Sysctls for debug.
182  */
183 static unsigned int powerstate_active = PCI_POWERSTATE_D1;
184 #ifdef MAESTRO_AGGRESSIVE_POWERSAVE
185 static unsigned int powerstate_idle   = PCI_POWERSTATE_D2;
186 #else
187 static unsigned int powerstate_idle   = PCI_POWERSTATE_D1;
188 #endif
189 static unsigned int powerstate_init   = PCI_POWERSTATE_D2;
190
191 /* XXX: this should move to a device specific sysctl dev.pcm.X.debug.Y via
192    device_get_sysctl_*() as discussed on multimedia@ in msg-id
193    <861wujij2q.fsf@xps.des.no> */
194 static SYSCTL_NODE(_debug, OID_AUTO, maestro, CTLFLAG_RD, 0, "");
195 SYSCTL_UINT(_debug_maestro, OID_AUTO, powerstate_active, CTLFLAG_RW,
196             &powerstate_active, 0, "The Dx power state when active (0-1)");
197 SYSCTL_UINT(_debug_maestro, OID_AUTO, powerstate_idle, CTLFLAG_RW,
198             &powerstate_idle, 0, "The Dx power state when idle (0-2)");
199 SYSCTL_UINT(_debug_maestro, OID_AUTO, powerstate_init, CTLFLAG_RW,
200             &powerstate_init, 0,
201             "The Dx power state prior to the first use (0-2)");
202
203
204 /* -----------------------------
205  * Prototypes
206  */
207
208 static void     agg_sleep(struct agg_info*, const char *wmesg, int msec);
209
210 static __inline u_int32_t       agg_rd(struct agg_info*, int, int size);
211 static __inline void            agg_wr(struct agg_info*, int, u_int32_t data,
212                                                                 int size);
213 static int      agg_rdcodec(struct agg_info*, int);
214 static int      agg_wrcodec(struct agg_info*, int, u_int32_t);
215
216 static void     ringbus_setdest(struct agg_info*, int, int);
217
218 static u_int16_t        wp_rdreg(struct agg_info*, u_int16_t);
219 static void             wp_wrreg(struct agg_info*, u_int16_t, u_int16_t);
220 static u_int16_t        wp_rdapu(struct agg_info*, unsigned, u_int16_t);
221 static void     wp_wrapu(struct agg_info*, unsigned, u_int16_t, u_int16_t);
222 static void     wp_settimer(struct agg_info*, u_int);
223 static void     wp_starttimer(struct agg_info*);
224 static void     wp_stoptimer(struct agg_info*);
225
226 #if 0
227 static u_int16_t        wc_rdreg(struct agg_info*, u_int16_t);
228 #endif
229 static void             wc_wrreg(struct agg_info*, u_int16_t, u_int16_t);
230 #if 0
231 static u_int16_t        wc_rdchctl(struct agg_info*, int);
232 #endif
233 static void             wc_wrchctl(struct agg_info*, int, u_int16_t);
234
235 static void     agg_stopclock(struct agg_info*, int part, int st);
236
237 static void     agg_initcodec(struct agg_info*);
238 static void     agg_init(struct agg_info*);
239 static void     agg_power(struct agg_info*, int);
240
241 static void     aggch_start_dac(struct agg_chinfo*);
242 static void     aggch_stop_dac(struct agg_chinfo*);
243 static void     aggch_start_adc(struct agg_rchinfo*);
244 static void     aggch_stop_adc(struct agg_rchinfo*);
245 static void     aggch_feed_adc_stereo(struct agg_rchinfo*);
246 static void     aggch_feed_adc_mono(struct agg_rchinfo*);
247
248 #ifdef AGG_JITTER_CORRECTION
249 static void     suppress_jitter(struct agg_chinfo*);
250 static void     suppress_rec_jitter(struct agg_rchinfo*);
251 #endif
252
253 static void     set_timer(struct agg_info*);
254
255 static void     agg_intr(void *);
256 static int      agg_probe(device_t);
257 static int      agg_attach(device_t);
258 static int      agg_detach(device_t);
259 static int      agg_suspend(device_t);
260 static int      agg_resume(device_t);
261 static int      agg_shutdown(device_t);
262
263 static void     *dma_malloc(bus_dma_tag_t, u_int32_t, bus_addr_t*);
264 static void     dma_free(bus_dma_tag_t, void *);
265
266
267 /* -----------------------------
268  * Subsystems.
269  */
270
271 /* locking */
272 #define agg_lock(sc)    snd_mtxlock(&((sc)->lock))
273 #define agg_unlock(sc)  snd_mtxunlock(&((sc)->lock))
274
275 static void
276 agg_sleep(struct agg_info *sc, const char *wmesg, int msec)
277 {
278         int timo;
279
280         timo = msec * hz / 1000;
281         if (timo == 0)
282                 timo = 1;
283         msleep(sc, &sc->lock, PWAIT, wmesg, timo);
284 }
285
286
287 /* I/O port */
288
289 static __inline u_int32_t
290 agg_rd(struct agg_info *sc, int regno, int size)
291 {
292         switch (size) {
293         case 1:
294                 return bus_space_read_1(sc->st, sc->sh, regno);
295         case 2:
296                 return bus_space_read_2(sc->st, sc->sh, regno);
297         case 4:
298                 return bus_space_read_4(sc->st, sc->sh, regno);
299         default:
300                 return ~(u_int32_t)0;
301         }
302 }
303
304 #define AGG_RD(sc, regno, size)           \
305         bus_space_read_##size(            \
306             ((struct agg_info*)(sc))->st, \
307             ((struct agg_info*)(sc))->sh, (regno))
308
309 static __inline void
310 agg_wr(struct agg_info *sc, int regno, u_int32_t data, int size)
311 {
312         switch (size) {
313         case 1:
314                 bus_space_write_1(sc->st, sc->sh, regno, data);
315                 break;
316         case 2:
317                 bus_space_write_2(sc->st, sc->sh, regno, data);
318                 break;
319         case 4:
320                 bus_space_write_4(sc->st, sc->sh, regno, data);
321                 break;
322         }
323 }
324
325 #define AGG_WR(sc, regno, data, size)     \
326         bus_space_write_##size(           \
327             ((struct agg_info*)(sc))->st, \
328             ((struct agg_info*)(sc))->sh, (regno), (data))
329
330 /* -------------------------------------------------------------------- */
331
332 /* Codec/Ringbus */
333
334 static int
335 agg_codec_wait4idle(struct agg_info *ess)
336 {
337         unsigned t = 26;
338
339         while (AGG_RD(ess, PORT_CODEC_STAT, 1) & CODEC_STAT_MASK) {
340                 if (--t == 0)
341                         return EBUSY;
342                 DELAY(2);       /* 20.8us / 13 */
343         }
344         return 0;
345 }
346
347
348 static int
349 agg_rdcodec(struct agg_info *ess, int regno)
350 {
351         int ret;
352
353         /* We have to wait for a SAFE time to write addr/data */
354         if (agg_codec_wait4idle(ess)) {
355                 /* Timed out. No read performed. */
356                 device_printf(ess->dev, "agg_rdcodec() PROGLESS timed out.\n");
357                 return -1;
358         }
359
360         AGG_WR(ess, PORT_CODEC_CMD, CODEC_CMD_READ | regno, 1);
361         /*DELAY(21);    * AC97 cycle = 20.8usec */
362
363         /* Wait for data retrieve */
364         if (!agg_codec_wait4idle(ess)) {
365                 ret = AGG_RD(ess, PORT_CODEC_REG, 2);
366         } else {
367                 /* Timed out. No read performed. */
368                 device_printf(ess->dev, "agg_rdcodec() RW_DONE timed out.\n");
369                 ret = -1;
370         }
371
372         return ret;
373 }
374
375 static int
376 agg_wrcodec(struct agg_info *ess, int regno, u_int32_t data)
377 {
378         /* We have to wait for a SAFE time to write addr/data */
379         if (agg_codec_wait4idle(ess)) {
380                 /* Timed out. Abort writing. */
381                 device_printf(ess->dev, "agg_wrcodec() PROGLESS timed out.\n");
382                 return -1;
383         }
384
385         AGG_WR(ess, PORT_CODEC_REG, data, 2);
386         AGG_WR(ess, PORT_CODEC_CMD, CODEC_CMD_WRITE | regno, 1);
387
388         /* Wait for write completion */
389         if (agg_codec_wait4idle(ess)) {
390                 /* Timed out. */
391                 device_printf(ess->dev, "agg_wrcodec() RW_DONE timed out.\n");
392                 return -1;
393         }
394
395         return 0;
396 }
397
398 static void
399 ringbus_setdest(struct agg_info *ess, int src, int dest)
400 {
401         u_int32_t       data;
402
403         data = AGG_RD(ess, PORT_RINGBUS_CTRL, 4);
404         data &= ~(0xfU << src);
405         data |= (0xfU & dest) << src;
406         AGG_WR(ess, PORT_RINGBUS_CTRL, data, 4);
407 }
408
409 /* -------------------------------------------------------------------- */
410
411 /* Wave Processor */
412
413 static u_int16_t
414 wp_rdreg(struct agg_info *ess, u_int16_t reg)
415 {
416         AGG_WR(ess, PORT_DSP_INDEX, reg, 2);
417         return AGG_RD(ess, PORT_DSP_DATA, 2);
418 }
419
420 static void
421 wp_wrreg(struct agg_info *ess, u_int16_t reg, u_int16_t data)
422 {
423         AGG_WR(ess, PORT_DSP_INDEX, reg, 2);
424         AGG_WR(ess, PORT_DSP_DATA, data, 2);
425 }
426
427 static int
428 wp_wait_data(struct agg_info *ess, u_int16_t data)
429 {
430         unsigned t = 0;
431
432         while (AGG_RD(ess, PORT_DSP_DATA, 2) != data) {
433                 if (++t == 1000) {
434                         return EAGAIN;
435                 }
436                 AGG_WR(ess, PORT_DSP_DATA, data, 2);
437         }
438
439         return 0;
440 }
441
442 static u_int16_t
443 wp_rdapu(struct agg_info *ess, unsigned ch, u_int16_t reg)
444 {
445         wp_wrreg(ess, WPREG_CRAM_PTR, reg | (ch << 4));
446         if (wp_wait_data(ess, reg | (ch << 4)) != 0)
447                 device_printf(ess->dev, "wp_rdapu() indexing timed out.\n");
448         return wp_rdreg(ess, WPREG_DATA_PORT);
449 }
450
451 static void
452 wp_wrapu(struct agg_info *ess, unsigned ch, u_int16_t reg, u_int16_t data)
453 {
454         wp_wrreg(ess, WPREG_CRAM_PTR, reg | (ch << 4));
455         if (wp_wait_data(ess, reg | (ch << 4)) == 0) {
456                 wp_wrreg(ess, WPREG_DATA_PORT, data);
457                 if (wp_wait_data(ess, data) != 0)
458                         device_printf(ess->dev,
459                             "wp_wrapu() write timed out.\n");
460         } else {
461                 device_printf(ess->dev, "wp_wrapu() indexing timed out.\n");
462         }
463 }
464
465 static void
466 apu_setparam(struct agg_info *ess, int apuch,
467     u_int32_t wpwa, u_int16_t size, int16_t pan, u_int dv)
468 {
469         wp_wrapu(ess, apuch, APUREG_WAVESPACE, (wpwa >> 8) & APU_64KPAGE_MASK);
470         wp_wrapu(ess, apuch, APUREG_CURPTR, wpwa);
471         wp_wrapu(ess, apuch, APUREG_ENDPTR, wpwa + size);
472         wp_wrapu(ess, apuch, APUREG_LOOPLEN, size);
473         wp_wrapu(ess, apuch, APUREG_ROUTING, 0);
474         wp_wrapu(ess, apuch, APUREG_AMPLITUDE, 0xf000);
475         wp_wrapu(ess, apuch, APUREG_POSITION, 0x8f00
476             | (APU_RADIUS_MASK & (RADIUS_CENTERCIRCLE << APU_RADIUS_SHIFT))
477             | (APU_PAN_MASK & ((pan + PAN_FRONT) << APU_PAN_SHIFT)));
478         wp_wrapu(ess, apuch, APUREG_FREQ_LOBYTE,
479             APU_plus6dB | ((dv & 0xff) << APU_FREQ_LOBYTE_SHIFT));
480         wp_wrapu(ess, apuch, APUREG_FREQ_HIWORD, dv >> 8);
481 }
482
483 static void
484 wp_settimer(struct agg_info *ess, u_int divide)
485 {
486         u_int prescale = 0;
487
488         RANGE(divide, 2, 32 << 7);
489
490         for (; divide > 32; divide >>= 1) {
491                 prescale++;
492                 divide++;
493         }
494
495         for (; prescale < 7 && divide > 2 && !(divide & 1); divide >>= 1)
496                 prescale++;
497
498         wp_wrreg(ess, WPREG_TIMER_ENABLE, 0);
499         wp_wrreg(ess, WPREG_TIMER_FREQ, 0x9000 |
500             (prescale << WP_TIMER_FREQ_PRESCALE_SHIFT) | (divide - 1));
501         wp_wrreg(ess, WPREG_TIMER_ENABLE, 1);
502 }
503
504 static void
505 wp_starttimer(struct agg_info *ess)
506 {
507         AGG_WR(ess, PORT_INT_STAT, 1, 2);
508         AGG_WR(ess, PORT_HOSTINT_CTRL, HOSTINT_CTRL_DSOUND_INT_ENABLED
509                | AGG_RD(ess, PORT_HOSTINT_CTRL, 2), 2);
510         wp_wrreg(ess, WPREG_TIMER_START, 1);
511 }
512
513 static void
514 wp_stoptimer(struct agg_info *ess)
515 {
516         AGG_WR(ess, PORT_HOSTINT_CTRL, ~HOSTINT_CTRL_DSOUND_INT_ENABLED
517                & AGG_RD(ess, PORT_HOSTINT_CTRL, 2), 2);
518         AGG_WR(ess, PORT_INT_STAT, 1, 2);
519         wp_wrreg(ess, WPREG_TIMER_START, 0);
520 }
521
522 /* -------------------------------------------------------------------- */
523
524 /* WaveCache */
525
526 #if 0
527 static u_int16_t
528 wc_rdreg(struct agg_info *ess, u_int16_t reg)
529 {
530         AGG_WR(ess, PORT_WAVCACHE_INDEX, reg, 2);
531         return AGG_RD(ess, PORT_WAVCACHE_DATA, 2);
532 }
533 #endif
534
535 static void
536 wc_wrreg(struct agg_info *ess, u_int16_t reg, u_int16_t data)
537 {
538         AGG_WR(ess, PORT_WAVCACHE_INDEX, reg, 2);
539         AGG_WR(ess, PORT_WAVCACHE_DATA, data, 2);
540 }
541
542 #if 0
543 static u_int16_t
544 wc_rdchctl(struct agg_info *ess, int ch)
545 {
546         return wc_rdreg(ess, ch << 3);
547 }
548 #endif
549
550 static void
551 wc_wrchctl(struct agg_info *ess, int ch, u_int16_t data)
552 {
553         wc_wrreg(ess, ch << 3, data);
554 }
555
556 /* -------------------------------------------------------------------- */
557
558 /* Power management */
559 static void
560 agg_stopclock(struct agg_info *ess, int part, int st)
561 {
562         u_int32_t data;
563
564         data = pci_read_config(ess->dev, CONF_ACPI_STOPCLOCK, 4);
565         if (part < 16) {
566                 if (st == PCI_POWERSTATE_D1)
567                         data &= ~(1 << part);
568                 else
569                         data |= (1 << part);
570                 if (st == PCI_POWERSTATE_D1 || st == PCI_POWERSTATE_D2)
571                         data |= (0x10000 << part);
572                 else
573                         data &= ~(0x10000 << part);
574                 pci_write_config(ess->dev, CONF_ACPI_STOPCLOCK, data, 4);
575         }
576 }
577
578
579 /* -----------------------------
580  * Controller.
581  */
582
583 static void
584 agg_initcodec(struct agg_info* ess)
585 {
586         u_int16_t data;
587
588         if (AGG_RD(ess, PORT_RINGBUS_CTRL, 4) & RINGBUS_CTRL_ACLINK_ENABLED) {
589                 AGG_WR(ess, PORT_RINGBUS_CTRL, 0, 4);
590                 DELAY(104);     /* 20.8us * (4 + 1) */
591         }
592         /* XXX - 2nd codec should be looked at. */
593         AGG_WR(ess, PORT_RINGBUS_CTRL, RINGBUS_CTRL_AC97_SWRESET, 4);
594         DELAY(2);
595         AGG_WR(ess, PORT_RINGBUS_CTRL, RINGBUS_CTRL_ACLINK_ENABLED, 4);
596         DELAY(50);
597
598         if (agg_rdcodec(ess, 0) < 0) {
599                 AGG_WR(ess, PORT_RINGBUS_CTRL, 0, 4);
600                 DELAY(21);
601
602                 /* Try cold reset. */
603                 device_printf(ess->dev, "will perform cold reset.\n");
604                 data = AGG_RD(ess, PORT_GPIO_DIR, 2);
605                 if (pci_read_config(ess->dev, 0x58, 2) & 1)
606                         data |= 0x10;
607                 data |= 0x009 & ~AGG_RD(ess, PORT_GPIO_DATA, 2);
608                 AGG_WR(ess, PORT_GPIO_MASK, 0xff6, 2);
609                 AGG_WR(ess, PORT_GPIO_DIR, data | 0x009, 2);
610                 AGG_WR(ess, PORT_GPIO_DATA, 0x000, 2);
611                 DELAY(2);
612                 AGG_WR(ess, PORT_GPIO_DATA, 0x001, 2);
613                 DELAY(1);
614                 AGG_WR(ess, PORT_GPIO_DATA, 0x009, 2);
615                 agg_sleep(ess, "agginicd", 500);
616                 AGG_WR(ess, PORT_GPIO_DIR, data, 2);
617                 DELAY(84);      /* 20.8us * 4 */
618                 AGG_WR(ess, PORT_RINGBUS_CTRL, RINGBUS_CTRL_ACLINK_ENABLED, 4);
619                 DELAY(50);
620         }
621 }
622
623 static void
624 agg_init(struct agg_info* ess)
625 {
626         u_int32_t data;
627
628         /* Setup PCI config registers. */
629
630         /* Disable all legacy emulations. */
631         data = pci_read_config(ess->dev, CONF_LEGACY, 2);
632         data |= LEGACY_DISABLED;
633         pci_write_config(ess->dev, CONF_LEGACY, data, 2);
634
635         /* Disconnect from CHI. (Makes Dell inspiron 7500 work?)
636          * Enable posted write.
637          * Prefer PCI timing rather than that of ISA.
638          * Don't swap L/R. */
639         data = pci_read_config(ess->dev, CONF_MAESTRO, 4);
640         data |= MAESTRO_PMC;
641         data |= MAESTRO_CHIBUS | MAESTRO_POSTEDWRITE | MAESTRO_DMA_PCITIMING;
642         data &= ~MAESTRO_SWAP_LR;
643         pci_write_config(ess->dev, CONF_MAESTRO, data, 4);
644
645         /* Turn off unused parts if necessary. */
646         /* consult CONF_MAESTRO. */
647         if (data & MAESTRO_SPDIF)
648                 agg_stopclock(ess, ACPI_PART_SPDIF,     PCI_POWERSTATE_D2);
649         else
650                 agg_stopclock(ess, ACPI_PART_SPDIF,     PCI_POWERSTATE_D1);
651         if (data & MAESTRO_HWVOL)
652                 agg_stopclock(ess, ACPI_PART_HW_VOL,    PCI_POWERSTATE_D3);
653         else
654                 agg_stopclock(ess, ACPI_PART_HW_VOL,    PCI_POWERSTATE_D1);
655
656         /* parts that never be used */
657         agg_stopclock(ess, ACPI_PART_978,       PCI_POWERSTATE_D1);
658         agg_stopclock(ess, ACPI_PART_DAA,       PCI_POWERSTATE_D1);
659         agg_stopclock(ess, ACPI_PART_GPIO,      PCI_POWERSTATE_D1);
660         agg_stopclock(ess, ACPI_PART_SB,        PCI_POWERSTATE_D1);
661         agg_stopclock(ess, ACPI_PART_FM,        PCI_POWERSTATE_D1);
662         agg_stopclock(ess, ACPI_PART_MIDI,      PCI_POWERSTATE_D1);
663         agg_stopclock(ess, ACPI_PART_GAME_PORT, PCI_POWERSTATE_D1);
664
665         /* parts that will be used only when play/recording */
666         agg_stopclock(ess, ACPI_PART_WP,        PCI_POWERSTATE_D2);
667
668         /* parts that should always be turned on */
669         agg_stopclock(ess, ACPI_PART_CODEC_CLOCK, PCI_POWERSTATE_D3);
670         agg_stopclock(ess, ACPI_PART_GLUE,      PCI_POWERSTATE_D3);
671         agg_stopclock(ess, ACPI_PART_PCI_IF,    PCI_POWERSTATE_D3);
672         agg_stopclock(ess, ACPI_PART_RINGBUS,   PCI_POWERSTATE_D3);
673
674         /* Reset direct sound. */
675         AGG_WR(ess, PORT_HOSTINT_CTRL, HOSTINT_CTRL_SOFT_RESET, 2);
676         DELAY(100);
677         AGG_WR(ess, PORT_HOSTINT_CTRL, 0, 2);
678         DELAY(100);
679         AGG_WR(ess, PORT_HOSTINT_CTRL, HOSTINT_CTRL_DSOUND_RESET, 2);
680         DELAY(100);
681         AGG_WR(ess, PORT_HOSTINT_CTRL, 0, 2);
682         DELAY(100);
683
684         /* Enable hardware volume control interruption. */
685         if (data & MAESTRO_HWVOL)       /* XXX - why not use device flags? */
686                 AGG_WR(ess, PORT_HOSTINT_CTRL,HOSTINT_CTRL_HWVOL_ENABLED, 2);
687
688         /* Setup Wave Processor. */
689
690         /* Enable WaveCache, set DMA base address. */
691         wp_wrreg(ess, WPREG_WAVE_ROMRAM,
692             WP_WAVE_VIRTUAL_ENABLED | WP_WAVE_DRAM_ENABLED);
693         wp_wrreg(ess, WPREG_CRAM_DATA, 0);
694
695         AGG_WR(ess, PORT_WAVCACHE_CTRL,
696                WAVCACHE_ENABLED | WAVCACHE_WTSIZE_2MB | WAVCACHE_SGC_32_47, 2);
697
698         for (data = WAVCACHE_PCMBAR; data < WAVCACHE_PCMBAR + 4; data++)
699                 wc_wrreg(ess, data, ess->phys >> WAVCACHE_BASEADDR_SHIFT);
700
701         /* Setup Codec/Ringbus. */
702         agg_initcodec(ess);
703         AGG_WR(ess, PORT_RINGBUS_CTRL,
704                RINGBUS_CTRL_RINGBUS_ENABLED | RINGBUS_CTRL_ACLINK_ENABLED, 4);
705
706         wp_wrreg(ess, 0x08, 0xB004);
707         wp_wrreg(ess, 0x09, 0x001B);
708         wp_wrreg(ess, 0x0A, 0x8000);
709         wp_wrreg(ess, 0x0B, 0x3F37);
710         wp_wrreg(ess, WPREG_BASE, 0x8598);      /* Parallel I/O */
711         wp_wrreg(ess, WPREG_BASE + 1, 0x7632);
712         ringbus_setdest(ess, RINGBUS_SRC_ADC,
713             RINGBUS_DEST_STEREO | RINGBUS_DEST_DSOUND_IN);
714         ringbus_setdest(ess, RINGBUS_SRC_DSOUND,
715             RINGBUS_DEST_STEREO | RINGBUS_DEST_DAC);
716
717         /* Enable S/PDIF if necessary. */
718         if (pci_read_config(ess->dev, CONF_MAESTRO, 4) & MAESTRO_SPDIF)
719                 /* XXX - why not use device flags? */
720                 AGG_WR(ess, PORT_RINGBUS_CTRL_B, RINGBUS_CTRL_SPDIF |
721                        AGG_RD(ess, PORT_RINGBUS_CTRL_B, 1), 1);
722
723         /* Setup ASSP. Needed for Dell Inspiron 7500? */
724         AGG_WR(ess, PORT_ASSP_CTRL_B, 0x00, 1);
725         AGG_WR(ess, PORT_ASSP_CTRL_A, 0x03, 1);
726         AGG_WR(ess, PORT_ASSP_CTRL_C, 0x00, 1);
727
728         /*
729          * Setup GPIO.
730          * There seems to be speciality with NEC systems.
731          */
732         switch (pci_get_subvendor(ess->dev)
733             | (pci_get_subdevice(ess->dev) << 16)) {
734         case NEC_SUBID1:
735         case NEC_SUBID2:
736                 /* Matthew Braithwaite <matt@braithwaite.net> reported that
737                  * NEC Versa LX doesn't need GPIO operation. */
738                 AGG_WR(ess, PORT_GPIO_MASK, 0x9ff, 2);
739                 AGG_WR(ess, PORT_GPIO_DIR,
740                        AGG_RD(ess, PORT_GPIO_DIR, 2) | 0x600, 2);
741                 AGG_WR(ess, PORT_GPIO_DATA, 0x200, 2);
742                 break;
743         }
744 }
745
746 /* Deals power state transition. Must be called with softc->lock held. */
747 static void
748 agg_power(struct agg_info *ess, int status)
749 {
750         u_int8_t lastpwr;
751
752         lastpwr = ess->curpwr;
753         if (lastpwr == status)
754                 return;
755
756         switch (status) {
757         case PCI_POWERSTATE_D0:
758         case PCI_POWERSTATE_D1:
759                 switch (lastpwr) {
760                 case PCI_POWERSTATE_D2:
761                         pci_set_powerstate(ess->dev, status);
762                         /* Turn on PCM-related parts. */
763                         agg_wrcodec(ess, AC97_REG_POWER, 0);
764                         DELAY(100);
765 #if 0
766                         if ((agg_rdcodec(ess, AC97_REG_POWER) & 3) != 3)
767                                 device_printf(ess->dev,
768                                     "warning: codec not ready.\n");
769 #endif
770                         AGG_WR(ess, PORT_RINGBUS_CTRL,
771                                (AGG_RD(ess, PORT_RINGBUS_CTRL, 4)
772                                 & ~RINGBUS_CTRL_ACLINK_ENABLED)
773                                | RINGBUS_CTRL_RINGBUS_ENABLED, 4);
774                         DELAY(50);
775                         AGG_WR(ess, PORT_RINGBUS_CTRL,
776                                AGG_RD(ess, PORT_RINGBUS_CTRL, 4)
777                                | RINGBUS_CTRL_ACLINK_ENABLED, 4);
778                         break;
779                 case PCI_POWERSTATE_D3:
780                         /* Initialize. */
781                         pci_set_powerstate(ess->dev, PCI_POWERSTATE_D0);
782                         DELAY(100);
783                         agg_init(ess);
784                         /* FALLTHROUGH */
785                 case PCI_POWERSTATE_D0:
786                 case PCI_POWERSTATE_D1:
787                         pci_set_powerstate(ess->dev, status);
788                         break;
789                 }
790                 break;
791         case PCI_POWERSTATE_D2:
792                 switch (lastpwr) {
793                 case PCI_POWERSTATE_D3:
794                         /* Initialize. */
795                         pci_set_powerstate(ess->dev, PCI_POWERSTATE_D0);
796                         DELAY(100);
797                         agg_init(ess);
798                         /* FALLTHROUGH */
799                 case PCI_POWERSTATE_D0:
800                 case PCI_POWERSTATE_D1:
801                         /* Turn off PCM-related parts. */
802                         AGG_WR(ess, PORT_RINGBUS_CTRL,
803                                AGG_RD(ess, PORT_RINGBUS_CTRL, 4)
804                                & ~RINGBUS_CTRL_RINGBUS_ENABLED, 4);
805                         DELAY(100);
806                         agg_wrcodec(ess, AC97_REG_POWER, 0x300);
807                         DELAY(100);
808                         break;
809                 }
810                 pci_set_powerstate(ess->dev, status);
811                 break;
812         case PCI_POWERSTATE_D3:
813                 /* Entirely power down. */
814                 agg_wrcodec(ess, AC97_REG_POWER, 0xdf00);
815                 DELAY(100);
816                 AGG_WR(ess, PORT_RINGBUS_CTRL, 0, 4);
817                 /*DELAY(1);*/
818                 if (lastpwr != PCI_POWERSTATE_D2)
819                         wp_stoptimer(ess);
820                 AGG_WR(ess, PORT_HOSTINT_CTRL, 0, 2);
821                 AGG_WR(ess, PORT_HOSTINT_STAT, 0xff, 1);
822                 pci_set_powerstate(ess->dev, status);
823                 break;
824         default:
825                 /* Invalid power state; let it ignored. */
826                 status = lastpwr;
827                 break;
828         }
829
830         ess->curpwr = status;
831 }
832
833 /* -------------------------------------------------------------------- */
834
835 /* Channel controller. */
836
837 static void
838 aggch_start_dac(struct agg_chinfo *ch)
839 {
840         bus_addr_t      wpwa;
841         u_int32_t       speed;
842         u_int16_t       size, apuch, wtbar, wcreg, aputype;
843         u_int           dv;
844         int             pan;
845
846         speed = ch->speed;
847         wpwa = (ch->phys - ch->base) >> 1;
848         wtbar = 0xc & (wpwa >> WPWA_WTBAR_SHIFT(2));
849         wcreg = (ch->phys - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK;
850         size  = ch->buflen;
851         apuch = (ch->num << 1) | 32;
852         pan = PAN_RIGHT - PAN_FRONT;
853
854         if (ch->stereo) {
855                 wcreg |= WAVCACHE_CHCTL_STEREO;
856                 if (ch->qs16) {
857                         aputype = APUTYPE_16BITSTEREO;
858                         wpwa >>= 1;
859                         size >>= 1;
860                         pan = -pan;
861                 } else
862                         aputype = APUTYPE_8BITSTEREO;
863         } else {
864                 pan = 0;
865                 if (ch->qs16)
866                         aputype = APUTYPE_16BITLINEAR;
867                 else {
868                         aputype = APUTYPE_8BITLINEAR;
869                         speed >>= 1;
870                 }
871         }
872         if (ch->us)
873                 wcreg |= WAVCACHE_CHCTL_U8;
874
875         if (wtbar > 8)
876                 wtbar = (wtbar >> 1) + 4;
877
878         dv = (((speed % 48000) << 16) + 24000) / 48000
879             + ((speed / 48000) << 16);
880
881         agg_lock(ch->parent);
882         agg_power(ch->parent, powerstate_active);
883
884         wc_wrreg(ch->parent, WAVCACHE_WTBAR + wtbar,
885             ch->base >> WAVCACHE_BASEADDR_SHIFT);
886         wc_wrreg(ch->parent, WAVCACHE_WTBAR + wtbar + 1,
887             ch->base >> WAVCACHE_BASEADDR_SHIFT);
888         if (wtbar < 8) {
889                 wc_wrreg(ch->parent, WAVCACHE_WTBAR + wtbar + 2,
890                     ch->base >> WAVCACHE_BASEADDR_SHIFT);
891                 wc_wrreg(ch->parent, WAVCACHE_WTBAR + wtbar + 3,
892                     ch->base >> WAVCACHE_BASEADDR_SHIFT);
893         }
894         wc_wrchctl(ch->parent, apuch, wcreg);
895         wc_wrchctl(ch->parent, apuch + 1, wcreg);
896
897         apu_setparam(ch->parent, apuch, wpwa, size, pan, dv);
898         if (ch->stereo) {
899                 if (ch->qs16)
900                         wpwa |= (WPWA_STEREO >> 1);
901                 apu_setparam(ch->parent, apuch + 1, wpwa, size, -pan, dv);
902
903                 critical_enter();
904                 wp_wrapu(ch->parent, apuch, APUREG_APUTYPE,
905                     (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf);
906                 wp_wrapu(ch->parent, apuch + 1, APUREG_APUTYPE,
907                     (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf);
908                 critical_exit();
909         } else {
910                 wp_wrapu(ch->parent, apuch, APUREG_APUTYPE,
911                     (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf);
912         }
913
914         /* to mark that this channel is ready for intr. */
915         ch->parent->active |= (1 << ch->num);
916
917         set_timer(ch->parent);
918         wp_starttimer(ch->parent);
919         agg_unlock(ch->parent);
920 }
921
922 static void
923 aggch_stop_dac(struct agg_chinfo *ch)
924 {
925         agg_lock(ch->parent);
926
927         /* to mark that this channel no longer needs further intrs. */
928         ch->parent->active &= ~(1 << ch->num);
929
930         wp_wrapu(ch->parent, (ch->num << 1) | 32, APUREG_APUTYPE,
931             APUTYPE_INACTIVE << APU_APUTYPE_SHIFT);
932         wp_wrapu(ch->parent, (ch->num << 1) | 33, APUREG_APUTYPE,
933             APUTYPE_INACTIVE << APU_APUTYPE_SHIFT);
934
935         if (ch->parent->active) {
936                 set_timer(ch->parent);
937                 wp_starttimer(ch->parent);
938         } else {
939                 wp_stoptimer(ch->parent);
940                 agg_power(ch->parent, powerstate_idle);
941         }
942         agg_unlock(ch->parent);
943 }
944
945 static void
946 aggch_start_adc(struct agg_rchinfo *ch)
947 {
948         bus_addr_t      wpwa, wpwa2;
949         u_int16_t       wcreg, wcreg2;
950         u_int   dv;
951         int     pan;
952
953         /* speed > 48000 not cared */
954         dv = ((ch->speed << 16) + 24000) / 48000;
955
956         /* RATECONV doesn't seem to like dv == 0x10000. */
957         if (dv == 0x10000)
958                 dv--;
959
960         if (ch->stereo) {
961                 wpwa = (ch->srcphys - ch->base) >> 1;
962                 wpwa2 = (ch->srcphys + ch->parent->bufsz/2 - ch->base) >> 1;
963                 wcreg = (ch->srcphys - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK;
964                 wcreg2 = (ch->base - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK;
965                 pan = PAN_LEFT - PAN_FRONT;
966         } else {
967                 wpwa = (ch->phys - ch->base) >> 1;
968                 wpwa2 = (ch->srcphys - ch->base) >> 1;
969                 wcreg = (ch->phys - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK;
970                 wcreg2 = (ch->base - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK;
971                 pan = 0;
972         }
973
974         agg_lock(ch->parent);
975
976         ch->hwptr = 0;
977         agg_power(ch->parent, powerstate_active);
978
979         /* Invalidate WaveCache. */
980         wc_wrchctl(ch->parent, 0, wcreg | WAVCACHE_CHCTL_STEREO);
981         wc_wrchctl(ch->parent, 1, wcreg | WAVCACHE_CHCTL_STEREO);
982         wc_wrchctl(ch->parent, 2, wcreg2 | WAVCACHE_CHCTL_STEREO);
983         wc_wrchctl(ch->parent, 3, wcreg2 | WAVCACHE_CHCTL_STEREO);
984
985         /* Load APU registers. */
986         /* APU #0 : Sample rate converter for left/center. */
987         apu_setparam(ch->parent, 0, WPWA_USE_SYSMEM | wpwa,
988                      ch->buflen >> ch->stereo, 0, dv);
989         wp_wrapu(ch->parent, 0, APUREG_AMPLITUDE, 0);
990         wp_wrapu(ch->parent, 0, APUREG_ROUTING, 2 << APU_DATASRC_A_SHIFT);
991
992         /* APU #1 : Sample rate converter for right. */
993         apu_setparam(ch->parent, 1, WPWA_USE_SYSMEM | wpwa2,
994                      ch->buflen >> ch->stereo, 0, dv);
995         wp_wrapu(ch->parent, 1, APUREG_AMPLITUDE, 0);
996         wp_wrapu(ch->parent, 1, APUREG_ROUTING, 3 << APU_DATASRC_A_SHIFT);
997
998         /* APU #2 : Input mixer for left. */
999         apu_setparam(ch->parent, 2, WPWA_USE_SYSMEM | 0,
1000                      ch->parent->bufsz >> 2, pan, 0x10000);
1001         wp_wrapu(ch->parent, 2, APUREG_AMPLITUDE, 0);
1002         wp_wrapu(ch->parent, 2, APUREG_EFFECT_GAIN, 0xf0);
1003         wp_wrapu(ch->parent, 2, APUREG_ROUTING, 0x15 << APU_DATASRC_A_SHIFT);
1004
1005         /* APU #3 : Input mixer for right. */
1006         apu_setparam(ch->parent, 3, WPWA_USE_SYSMEM | (ch->parent->bufsz >> 2),
1007                      ch->parent->bufsz >> 2, -pan, 0x10000);
1008         wp_wrapu(ch->parent, 3, APUREG_AMPLITUDE, 0);
1009         wp_wrapu(ch->parent, 3, APUREG_EFFECT_GAIN, 0xf0);
1010         wp_wrapu(ch->parent, 3, APUREG_ROUTING, 0x14 << APU_DATASRC_A_SHIFT);
1011
1012         /* to mark this channel ready for intr. */
1013         ch->parent->active |= (1 << ch->parent->playchns);
1014
1015         /* start adc */
1016         critical_enter();
1017         wp_wrapu(ch->parent, 0, APUREG_APUTYPE,
1018             (APUTYPE_RATECONV << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf);
1019         wp_wrapu(ch->parent, 1, APUREG_APUTYPE,
1020             (APUTYPE_RATECONV << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf);
1021         wp_wrapu(ch->parent, 2, APUREG_APUTYPE,
1022             (APUTYPE_INPUTMIXER << APU_APUTYPE_SHIFT) | 0xf);
1023         wp_wrapu(ch->parent, 3, APUREG_APUTYPE,
1024             (APUTYPE_INPUTMIXER << APU_APUTYPE_SHIFT) | 0xf);
1025         critical_exit();
1026
1027         set_timer(ch->parent);
1028         wp_starttimer(ch->parent);
1029         agg_unlock(ch->parent);
1030 }
1031
1032 static void
1033 aggch_stop_adc(struct agg_rchinfo *ch)
1034 {
1035         int apuch;
1036
1037         agg_lock(ch->parent);
1038
1039         /* to mark that this channel no longer needs further intrs. */
1040         ch->parent->active &= ~(1 << ch->parent->playchns);
1041
1042         for (apuch = 0; apuch < 4; apuch++)
1043                 wp_wrapu(ch->parent, apuch, APUREG_APUTYPE,
1044                     APUTYPE_INACTIVE << APU_APUTYPE_SHIFT);
1045
1046         if (ch->parent->active) {
1047                 set_timer(ch->parent);
1048                 wp_starttimer(ch->parent);
1049         } else {
1050                 wp_stoptimer(ch->parent);
1051                 agg_power(ch->parent, powerstate_idle);
1052         }
1053         agg_unlock(ch->parent);
1054 }
1055
1056 /*
1057  * Feed from L/R channel of ADC to destination with stereo interleaving.
1058  * This function expects n not overwrapping the buffer boundary.
1059  * Note that n is measured in sample unit.
1060  *
1061  * XXX - this function works in 16bit stereo format only.
1062  */
1063 static void
1064 interleave(int16_t *l, int16_t *r, int16_t *p, unsigned n)
1065 {
1066         int16_t *end;
1067
1068         for (end = l + n; l < end; ) {
1069                 *p++ = *l++;
1070                 *p++ = *r++;
1071         }
1072 }
1073
1074 static void
1075 aggch_feed_adc_stereo(struct agg_rchinfo *ch)
1076 {
1077         unsigned cur, last;
1078         int16_t *src2;
1079
1080         agg_lock(ch->parent);
1081         cur = wp_rdapu(ch->parent, 0, APUREG_CURPTR);
1082         agg_unlock(ch->parent);
1083         cur -= 0xffff & ((ch->srcphys - ch->base) >> 1);
1084         last = ch->hwptr;
1085         src2 = ch->src + ch->parent->bufsz/4;
1086
1087         if (cur < last) {
1088                 interleave(ch->src + last, src2 + last,
1089                            ch->sink + 2*last, ch->buflen/2 - last);
1090                 interleave(ch->src, src2,
1091                            ch->sink, cur);
1092         } else if (cur > last)
1093                 interleave(ch->src + last, src2 + last,
1094                            ch->sink + 2*last, cur - last);
1095         ch->hwptr = cur;
1096 }
1097
1098 /*
1099  * Feed from R channel of ADC and mixdown to destination L/center.
1100  * This function expects n not overwrapping the buffer boundary.
1101  * Note that n is measured in sample unit.
1102  *
1103  * XXX - this function works in 16bit monoral format only.
1104  */
1105 static void
1106 mixdown(int16_t *src, int16_t *dest, unsigned n)
1107 {
1108         int16_t *end;
1109
1110         for (end = dest + n; dest < end; dest++)
1111                 *dest = (int16_t)(((int)*dest - (int)*src++) / 2);
1112 }
1113
1114 static void
1115 aggch_feed_adc_mono(struct agg_rchinfo *ch)
1116 {
1117         unsigned cur, last;
1118
1119         agg_lock(ch->parent);
1120         cur = wp_rdapu(ch->parent, 0, APUREG_CURPTR);
1121         agg_unlock(ch->parent);
1122         cur -= 0xffff & ((ch->phys - ch->base) >> 1);
1123         last = ch->hwptr;
1124
1125         if (cur < last) {
1126                 mixdown(ch->src + last, ch->sink + last, ch->buflen - last);
1127                 mixdown(ch->src, ch->sink, cur);
1128         } else if (cur > last)
1129                 mixdown(ch->src + last, ch->sink + last, cur - last);
1130         ch->hwptr = cur;
1131 }
1132
1133 #ifdef AGG_JITTER_CORRECTION
1134 /*
1135  * Stereo jitter suppressor.
1136  * Sometimes playback pointers differ in stereo-paired channels.
1137  * Calling this routine within intr fixes the problem.
1138  */
1139 static void
1140 suppress_jitter(struct agg_chinfo *ch)
1141 {
1142         if (ch->stereo) {
1143                 int cp1, cp2, diff /*, halfsize*/ ;
1144
1145                 /*halfsize = (ch->qs16? ch->buflen >> 2 : ch->buflen >> 1);*/
1146                 cp1 = wp_rdapu(ch->parent, (ch->num << 1) | 32, APUREG_CURPTR);
1147                 cp2 = wp_rdapu(ch->parent, (ch->num << 1) | 33, APUREG_CURPTR);
1148                 if (cp1 != cp2) {
1149                         diff = (cp1 > cp2 ? cp1 - cp2 : cp2 - cp1);
1150                         if (diff > 1 /* && diff < halfsize*/ )
1151                                 AGG_WR(ch->parent, PORT_DSP_DATA, cp1, 2);
1152                 }
1153         }
1154 }
1155
1156 static void
1157 suppress_rec_jitter(struct agg_rchinfo *ch)
1158 {
1159         int cp1, cp2, diff /*, halfsize*/ ;
1160
1161         /*halfsize = (ch->stereo? ch->buflen >> 2 : ch->buflen >> 1);*/
1162         cp1 = (ch->stereo? ch->parent->bufsz >> 2 : ch->parent->bufsz >> 1)
1163                 + wp_rdapu(ch->parent, 0, APUREG_CURPTR);
1164         cp2 = wp_rdapu(ch->parent, 1, APUREG_CURPTR);
1165         if (cp1 != cp2) {
1166                 diff = (cp1 > cp2 ? cp1 - cp2 : cp2 - cp1);
1167                 if (diff > 1 /* && diff < halfsize*/ )
1168                         AGG_WR(ch->parent, PORT_DSP_DATA, cp1, 2);
1169         }
1170 }
1171 #endif
1172
1173 static u_int
1174 calc_timer_div(struct agg_chinfo *ch)
1175 {
1176         u_int speed;
1177
1178         speed = ch->speed;
1179 #ifdef INVARIANTS
1180         if (speed == 0) {
1181                 printf("snd_maestro: pch[%d].speed == 0, which shouldn't\n",
1182                        ch->num);
1183                 speed = 1;
1184         }
1185 #endif
1186         return (48000 * (ch->blklen << (!ch->qs16 + !ch->stereo))
1187                 + speed - 1) / speed;
1188 }
1189
1190 static u_int
1191 calc_timer_div_rch(struct agg_rchinfo *ch)
1192 {
1193         u_int speed;
1194
1195         speed = ch->speed;
1196 #ifdef INVARIANTS
1197         if (speed == 0) {
1198                 printf("snd_maestro: rch.speed == 0, which shouldn't\n");
1199                 speed = 1;
1200         }
1201 #endif
1202         return (48000 * (ch->blklen << (!ch->stereo))
1203                 + speed - 1) / speed;
1204 }
1205
1206 static void
1207 set_timer(struct agg_info *ess)
1208 {
1209         int i;
1210         u_int   dv = 32 << 7, newdv;
1211
1212         for (i = 0; i < ess->playchns; i++)
1213                 if ((ess->active & (1 << i)) &&
1214                     (dv > (newdv = calc_timer_div(ess->pch + i))))
1215                         dv = newdv;
1216         if ((ess->active & (1 << i)) &&
1217             (dv > (newdv = calc_timer_div_rch(&ess->rch))))
1218                 dv = newdv;
1219
1220         wp_settimer(ess, dv);
1221 }
1222
1223
1224 /* -----------------------------
1225  * Newpcm glue.
1226  */
1227
1228 /* AC97 mixer interface. */
1229
1230 static u_int32_t
1231 agg_ac97_init(kobj_t obj, void *sc)
1232 {
1233         struct agg_info *ess = sc;
1234
1235         return (AGG_RD(ess, PORT_CODEC_STAT, 1) & CODEC_STAT_MASK)? 0 : 1;
1236 }
1237
1238 static int
1239 agg_ac97_read(kobj_t obj, void *sc, int regno)
1240 {
1241         struct agg_info *ess = sc;
1242         int ret;
1243
1244         /* XXX sound locking violation: agg_lock(ess); */
1245         ret = agg_rdcodec(ess, regno);
1246         /* agg_unlock(ess); */
1247         return ret;
1248 }
1249
1250 static int
1251 agg_ac97_write(kobj_t obj, void *sc, int regno, u_int32_t data)
1252 {
1253         struct agg_info *ess = sc;
1254         int ret;
1255
1256         /* XXX sound locking violation: agg_lock(ess); */
1257         ret = agg_wrcodec(ess, regno, data);
1258         /* agg_unlock(ess); */
1259         return ret;
1260 }
1261
1262
1263 static kobj_method_t agg_ac97_methods[] = {
1264         KOBJMETHOD(ac97_init,           agg_ac97_init),
1265         KOBJMETHOD(ac97_read,           agg_ac97_read),
1266         KOBJMETHOD(ac97_write,          agg_ac97_write),
1267         KOBJMETHOD_END
1268 };
1269 AC97_DECLARE(agg_ac97);
1270
1271
1272 /* -------------------------------------------------------------------- */
1273
1274 /* Playback channel. */
1275
1276 static void *
1277 aggpch_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
1278                                                 struct pcm_channel *c, int dir)
1279 {
1280         struct agg_info *ess = devinfo;
1281         struct agg_chinfo *ch;
1282         bus_addr_t physaddr;
1283         void *p;
1284
1285         KASSERT((dir == PCMDIR_PLAY),
1286             ("aggpch_init() called for RECORDING channel!"));
1287         ch = ess->pch + ess->playchns;
1288
1289         ch->parent = ess;
1290         ch->channel = c;
1291         ch->buffer = b;
1292         ch->num = ess->playchns;
1293
1294         p = dma_malloc(ess->buf_dmat, ess->bufsz, &physaddr);
1295         if (p == NULL)
1296                 return NULL;
1297         ch->phys = physaddr;
1298         ch->base = physaddr & ((~(bus_addr_t)0) << WAVCACHE_BASEADDR_SHIFT);
1299
1300         sndbuf_setup(b, p, ess->bufsz);
1301         ch->blklen = sndbuf_getblksz(b) / 2;
1302         ch->buflen = sndbuf_getsize(b) / 2;
1303         ess->playchns++;
1304
1305         return ch;
1306 }
1307
1308 static void
1309 adjust_pchbase(struct agg_chinfo *chans, u_int n, u_int size)
1310 {
1311         struct agg_chinfo *pchs[AGG_MAXPLAYCH];
1312         u_int i, j, k;
1313         bus_addr_t base;
1314
1315         /* sort pchs by phys address */
1316         for (i = 0; i < n; i++) {
1317                 for (j = 0; j < i; j++)
1318                         if (chans[i].phys < pchs[j]->phys) {
1319                                 for (k = i; k > j; k--)
1320                                         pchs[k] = pchs[k - 1];
1321                                 break;
1322                         }
1323                 pchs[j] = chans + i;
1324         }
1325
1326         /* use new base register if next buffer can not be addressed
1327            via current base. */
1328 #define BASE_SHIFT (WPWA_WTBAR_SHIFT(2) + 2 + 1)
1329         base = pchs[0]->base;
1330         for (k = 1, i = 1; i < n; i++) {
1331                 if (pchs[i]->phys + size - base >= 1 << BASE_SHIFT)
1332                         /* not addressable: assign new base */
1333                         base = (pchs[i]->base -= k++ << BASE_SHIFT);
1334                 else
1335                         pchs[i]->base = base;
1336         }
1337 #undef BASE_SHIFT
1338
1339         if (bootverbose) {
1340                 printf("Total of %d bases are assigned.\n", k);
1341                 for (i = 0; i < n; i++) {
1342                         printf("ch.%d: phys 0x%llx, wpwa 0x%llx\n",
1343                                i, (long long)chans[i].phys,
1344                                (long long)(chans[i].phys -
1345                                            chans[i].base) >> 1);
1346                 }
1347         }
1348 }
1349
1350 static int
1351 aggpch_free(kobj_t obj, void *data)
1352 {
1353         struct agg_chinfo *ch = data;
1354         struct agg_info *ess = ch->parent;
1355
1356         /* free up buffer - called after channel stopped */
1357         dma_free(ess->buf_dmat, sndbuf_getbuf(ch->buffer));
1358
1359         /* return 0 if ok */
1360         return 0;
1361 }
1362
1363 static int
1364 aggpch_setformat(kobj_t obj, void *data, u_int32_t format)
1365 {
1366         struct agg_chinfo *ch = data;
1367
1368         if (format & AFMT_BIGENDIAN || format & AFMT_U16_LE)
1369                 return EINVAL;
1370         ch->stereo = ch->qs16 = ch->us = 0;
1371         if (AFMT_CHANNEL(format) > 1)
1372                 ch->stereo = 1;
1373
1374         if (format & AFMT_U8 || format & AFMT_S8) {
1375                 if (format & AFMT_U8)
1376                         ch->us = 1;
1377         } else
1378                 ch->qs16 = 1;
1379         return 0;
1380 }
1381
1382 static u_int32_t
1383 aggpch_setspeed(kobj_t obj, void *data, u_int32_t speed)
1384 {
1385
1386         ((struct agg_chinfo*)data)->speed = speed;
1387
1388         return (speed);
1389 }
1390
1391 static u_int32_t
1392 aggpch_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
1393 {
1394         struct agg_chinfo *ch = data;
1395         int blkcnt;
1396
1397         /* try to keep at least 20msec DMA space */
1398         blkcnt = (ch->speed << (ch->stereo + ch->qs16)) / (50 * blocksize);
1399         RANGE(blkcnt, 2, ch->parent->bufsz / blocksize);
1400
1401         if (sndbuf_getsize(ch->buffer) != blkcnt * blocksize) {
1402                 sndbuf_resize(ch->buffer, blkcnt, blocksize);
1403                 blkcnt = sndbuf_getblkcnt(ch->buffer);
1404                 blocksize = sndbuf_getblksz(ch->buffer);
1405         } else {
1406                 sndbuf_setblkcnt(ch->buffer, blkcnt);
1407                 sndbuf_setblksz(ch->buffer, blocksize);
1408         }
1409
1410         ch->blklen = blocksize / 2;
1411         ch->buflen = blkcnt * blocksize / 2;
1412         return blocksize;
1413 }
1414
1415 static int
1416 aggpch_trigger(kobj_t obj, void *data, int go)
1417 {
1418         struct agg_chinfo *ch = data;
1419
1420         switch (go) {
1421         case PCMTRIG_EMLDMAWR:
1422                 break;
1423         case PCMTRIG_START:
1424                 aggch_start_dac(ch);
1425                 break;
1426         case PCMTRIG_ABORT:
1427         case PCMTRIG_STOP:
1428                 aggch_stop_dac(ch);
1429                 break;
1430         }
1431         return 0;
1432 }
1433
1434 static u_int32_t
1435 aggpch_getptr(kobj_t obj, void *data)
1436 {
1437         struct agg_chinfo *ch = data;
1438         u_int32_t cp;
1439
1440         agg_lock(ch->parent);
1441         cp = wp_rdapu(ch->parent, (ch->num << 1) | 32, APUREG_CURPTR);
1442         agg_unlock(ch->parent);
1443
1444         return ch->qs16 && ch->stereo
1445                 ? (cp << 2) - ((0xffff << 2) & (ch->phys - ch->base))
1446                 : (cp << 1) - ((0xffff << 1) & (ch->phys - ch->base));
1447 }
1448
1449 static struct pcmchan_caps *
1450 aggpch_getcaps(kobj_t obj, void *data)
1451 {
1452         static u_int32_t playfmt[] = {
1453                 SND_FORMAT(AFMT_U8, 1, 0),
1454                 SND_FORMAT(AFMT_U8, 2, 0),
1455                 SND_FORMAT(AFMT_S8, 1, 0),
1456                 SND_FORMAT(AFMT_S8, 2, 0),
1457                 SND_FORMAT(AFMT_S16_LE, 1, 0),
1458                 SND_FORMAT(AFMT_S16_LE, 2, 0),
1459                 0
1460         };
1461         static struct pcmchan_caps playcaps = {8000, 48000, playfmt, 0};
1462
1463         return &playcaps;
1464 }
1465
1466
1467 static kobj_method_t aggpch_methods[] = {
1468         KOBJMETHOD(channel_init,                aggpch_init),
1469         KOBJMETHOD(channel_free,                aggpch_free),
1470         KOBJMETHOD(channel_setformat,           aggpch_setformat),
1471         KOBJMETHOD(channel_setspeed,            aggpch_setspeed),
1472         KOBJMETHOD(channel_setblocksize,        aggpch_setblocksize),
1473         KOBJMETHOD(channel_trigger,             aggpch_trigger),
1474         KOBJMETHOD(channel_getptr,              aggpch_getptr),
1475         KOBJMETHOD(channel_getcaps,             aggpch_getcaps),
1476         KOBJMETHOD_END
1477 };
1478 CHANNEL_DECLARE(aggpch);
1479
1480
1481 /* -------------------------------------------------------------------- */
1482
1483 /* Recording channel. */
1484
1485 static void *
1486 aggrch_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
1487                                                 struct pcm_channel *c, int dir)
1488 {
1489         struct agg_info *ess = devinfo;
1490         struct agg_rchinfo *ch;
1491         u_int8_t *p;
1492
1493         KASSERT((dir == PCMDIR_REC),
1494             ("aggrch_init() called for PLAYBACK channel!"));
1495         ch = &ess->rch;
1496
1497         ch->parent = ess;
1498         ch->channel = c;
1499         ch->buffer = b;
1500
1501         /* Uses the bottom-half of the status buffer. */
1502         p        = ess->stat + ess->bufsz;
1503         ch->phys = ess->phys + ess->bufsz;
1504         ch->base = ess->phys;
1505         ch->src  = (int16_t *)(p + ess->bufsz);
1506         ch->srcphys = ch->phys + ess->bufsz;
1507         ch->sink = (int16_t *)p;
1508
1509         sndbuf_setup(b, p, ess->bufsz);
1510         ch->blklen = sndbuf_getblksz(b) / 2;
1511         ch->buflen = sndbuf_getsize(b) / 2;
1512
1513         return ch;
1514 }
1515
1516 static int
1517 aggrch_setformat(kobj_t obj, void *data, u_int32_t format)
1518 {
1519         struct agg_rchinfo *ch = data;
1520
1521         if (!(format & AFMT_S16_LE))
1522                 return EINVAL;
1523         if (AFMT_CHANNEL(format) > 1)
1524                 ch->stereo = 1;
1525         else
1526                 ch->stereo = 0;
1527         return 0;
1528 }
1529
1530 static u_int32_t
1531 aggrch_setspeed(kobj_t obj, void *data, u_int32_t speed)
1532 {
1533
1534         ((struct agg_rchinfo*)data)->speed = speed;
1535
1536         return (speed);
1537 }
1538
1539 static u_int32_t
1540 aggrch_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
1541 {
1542         struct agg_rchinfo *ch = data;
1543         int blkcnt;
1544
1545         /* try to keep at least 20msec DMA space */
1546         blkcnt = (ch->speed << ch->stereo) / (25 * blocksize);
1547         RANGE(blkcnt, 2, ch->parent->bufsz / blocksize);
1548
1549         if (sndbuf_getsize(ch->buffer) != blkcnt * blocksize) {
1550                 sndbuf_resize(ch->buffer, blkcnt, blocksize);
1551                 blkcnt = sndbuf_getblkcnt(ch->buffer);
1552                 blocksize = sndbuf_getblksz(ch->buffer);
1553         } else {
1554                 sndbuf_setblkcnt(ch->buffer, blkcnt);
1555                 sndbuf_setblksz(ch->buffer, blocksize);
1556         }
1557
1558         ch->blklen = blocksize / 2;
1559         ch->buflen = blkcnt * blocksize / 2;
1560         return blocksize;
1561 }
1562
1563 static int
1564 aggrch_trigger(kobj_t obj, void *sc, int go)
1565 {
1566         struct agg_rchinfo *ch = sc;
1567
1568         switch (go) {
1569         case PCMTRIG_EMLDMARD:
1570                 if (ch->stereo)
1571                         aggch_feed_adc_stereo(ch);
1572                 else
1573                         aggch_feed_adc_mono(ch);
1574                 break;
1575         case PCMTRIG_START:
1576                 aggch_start_adc(ch);
1577                 break;
1578         case PCMTRIG_ABORT:
1579         case PCMTRIG_STOP:
1580                 aggch_stop_adc(ch);
1581                 break;
1582         }
1583         return 0;
1584 }
1585
1586 static u_int32_t
1587 aggrch_getptr(kobj_t obj, void *sc)
1588 {
1589         struct agg_rchinfo *ch = sc;
1590
1591         return ch->stereo? ch->hwptr << 2 : ch->hwptr << 1;
1592 }
1593
1594 static struct pcmchan_caps *
1595 aggrch_getcaps(kobj_t obj, void *sc)
1596 {
1597         static u_int32_t recfmt[] = {
1598                 SND_FORMAT(AFMT_S16_LE, 1, 0),
1599                 SND_FORMAT(AFMT_S16_LE, 2, 0),
1600                 0
1601         };
1602         static struct pcmchan_caps reccaps = {8000, 48000, recfmt, 0};
1603
1604         return &reccaps;
1605 }
1606
1607 static kobj_method_t aggrch_methods[] = {
1608         KOBJMETHOD(channel_init,                aggrch_init),
1609         /* channel_free: no-op */
1610         KOBJMETHOD(channel_setformat,           aggrch_setformat),
1611         KOBJMETHOD(channel_setspeed,            aggrch_setspeed),
1612         KOBJMETHOD(channel_setblocksize,        aggrch_setblocksize),
1613         KOBJMETHOD(channel_trigger,             aggrch_trigger),
1614         KOBJMETHOD(channel_getptr,              aggrch_getptr),
1615         KOBJMETHOD(channel_getcaps,             aggrch_getcaps),
1616         KOBJMETHOD_END
1617 };
1618 CHANNEL_DECLARE(aggrch);
1619
1620
1621 /* -----------------------------
1622  * Bus space.
1623  */
1624
1625 static void
1626 agg_intr(void *sc)
1627 {
1628         struct agg_info* ess = sc;
1629         register u_int8_t status;
1630         int i;
1631         u_int m;
1632
1633         status = AGG_RD(ess, PORT_HOSTINT_STAT, 1);
1634         if (!status)
1635                 return;
1636
1637         /* Acknowledge intr. */
1638         AGG_WR(ess, PORT_HOSTINT_STAT, status, 1);
1639
1640         if (status & HOSTINT_STAT_DSOUND) {
1641 #ifdef AGG_JITTER_CORRECTION
1642                 agg_lock(ess);
1643 #endif
1644                 if (ess->curpwr <= PCI_POWERSTATE_D1) {
1645                         AGG_WR(ess, PORT_INT_STAT, 1, 2);
1646 #ifdef AGG_JITTER_CORRECTION
1647                         for (i = 0, m = 1; i < ess->playchns; i++, m <<= 1) {
1648                                 if (ess->active & m)
1649                                         suppress_jitter(ess->pch + i);
1650                         }
1651                         if (ess->active & m)
1652                                 suppress_rec_jitter(&ess->rch);
1653                         agg_unlock(ess);
1654 #endif
1655                         for (i = 0, m = 1; i < ess->playchns; i++, m <<= 1) {
1656                                 if (ess->active & m) {
1657                                         if (ess->curpwr <= PCI_POWERSTATE_D1)
1658                                                 chn_intr(ess->pch[i].channel);
1659                                         else {
1660                                                 m = 0;
1661                                                 break;
1662                                         }
1663                                 }
1664                         }
1665                         if ((ess->active & m)
1666                             && ess->curpwr <= PCI_POWERSTATE_D1)
1667                                 chn_intr(ess->rch.channel);
1668                 }
1669 #ifdef AGG_JITTER_CORRECTION
1670                 else
1671                         agg_unlock(ess);
1672 #endif
1673         }
1674
1675         if (status & HOSTINT_STAT_HWVOL) {
1676                 register u_int8_t event;
1677
1678                 agg_lock(ess);
1679                 event = AGG_RD(ess, PORT_HWVOL_MASTER, 1);
1680                 AGG_WR(ess, PORT_HWVOL_MASTER, HWVOL_NOP, 1);
1681                 agg_unlock(ess);
1682
1683                 switch (event) {
1684                 case HWVOL_UP:
1685                         mixer_hwvol_step(ess->dev, 1, 1);
1686                         break;
1687                 case HWVOL_DOWN:
1688                         mixer_hwvol_step(ess->dev, -1, -1);
1689                         break;
1690                 case HWVOL_NOP:
1691                         break;
1692                 default:
1693                         if (event & HWVOL_MUTE) {
1694                                 mixer_hwvol_mute(ess->dev);
1695                                 break;
1696                         }
1697                         device_printf(ess->dev,
1698                                       "%s: unknown HWVOL event 0x%x\n",
1699                                       device_get_nameunit(ess->dev), event);
1700                 }
1701         }
1702 }
1703
1704 static void
1705 setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1706 {
1707         bus_addr_t *phys = arg;
1708
1709         *phys = error? 0 : segs->ds_addr;
1710
1711         if (bootverbose) {
1712                 printf("setmap (%lx, %lx), nseg=%d, error=%d\n",
1713                     (unsigned long)segs->ds_addr, (unsigned long)segs->ds_len,
1714                     nseg, error);
1715         }
1716 }
1717
1718 static void *
1719 dma_malloc(bus_dma_tag_t dmat, u_int32_t sz, bus_addr_t *phys)
1720 {
1721         void *buf;
1722         bus_dmamap_t map;
1723
1724         if (bus_dmamem_alloc(dmat, &buf, BUS_DMA_NOWAIT, &map))
1725                 return NULL;
1726         if (bus_dmamap_load(dmat, map, buf, sz, setmap, phys, 0)
1727             || !*phys || map) {
1728                 bus_dmamem_free(dmat, buf, map);
1729                 return NULL;
1730         }
1731         return buf;
1732 }
1733
1734 static void
1735 dma_free(bus_dma_tag_t dmat, void *buf)
1736 {
1737         bus_dmamem_free(dmat, buf, NULL);
1738 }
1739
1740 static int
1741 agg_probe(device_t dev)
1742 {
1743         char *s = NULL;
1744
1745         switch (pci_get_devid(dev)) {
1746         case MAESTRO_1_PCI_ID:
1747                 s = "ESS Technology Maestro-1";
1748                 break;
1749
1750         case MAESTRO_2_PCI_ID:
1751                 s = "ESS Technology Maestro-2";
1752                 break;
1753
1754         case MAESTRO_2E_PCI_ID:
1755                 s = "ESS Technology Maestro-2E";
1756                 break;
1757         }
1758
1759         if (s != NULL && pci_get_class(dev) == PCIC_MULTIMEDIA) {
1760                 device_set_desc(dev, s);
1761                 return BUS_PROBE_DEFAULT;
1762         }
1763         return ENXIO;
1764 }
1765
1766 static int
1767 agg_attach(device_t dev)
1768 {
1769         struct agg_info *ess = NULL;
1770         u_int32_t       data;
1771         int     regid = PCIR_BAR(0);
1772         struct resource *reg = NULL;
1773         struct ac97_info        *codec = NULL;
1774         int     irqid = 0;
1775         struct resource *irq = NULL;
1776         void    *ih = NULL;
1777         char    status[SND_STATUSLEN];
1778         int     dacn, ret = 0;
1779
1780         ess = malloc(sizeof(*ess), M_DEVBUF, M_WAITOK | M_ZERO);
1781         ess->dev = dev;
1782
1783         mtx_init(&ess->lock, device_get_desc(dev), "snd_maestro softc",
1784                  MTX_DEF | MTX_RECURSE);
1785         if (!mtx_initialized(&ess->lock)) {
1786                 device_printf(dev, "failed to create a mutex.\n");
1787                 ret = ENOMEM;
1788                 goto bad;
1789         }
1790
1791         if (resource_int_value(device_get_name(dev), device_get_unit(dev),
1792             "dac", &dacn) == 0) {
1793                 if (dacn < 1)
1794                         dacn = 1;
1795                 else if (dacn > AGG_MAXPLAYCH)
1796                         dacn = AGG_MAXPLAYCH;
1797         } else
1798                 dacn = AGG_MAXPLAYCH;
1799
1800         ess->bufsz = pcm_getbuffersize(dev, 4096, AGG_DEFAULT_BUFSZ, 65536);
1801         if (bus_dma_tag_create(/*parent*/ bus_get_dma_tag(dev),
1802                                /*align */ 4, 1 << (16+1),
1803                                /*limit */ MAESTRO_MAXADDR, BUS_SPACE_MAXADDR,
1804                                /*filter*/ NULL, NULL,
1805                                /*size  */ ess->bufsz, 1, 0x3ffff,
1806                                /*flags */ 0,
1807 #if __FreeBSD_version >= 501102
1808                                /*lock  */ busdma_lock_mutex, &Giant,
1809 #endif
1810                                &ess->buf_dmat) != 0) {
1811                 device_printf(dev, "unable to create dma tag\n");
1812                 ret = ENOMEM;
1813                 goto bad;
1814         }
1815
1816         if (bus_dma_tag_create(/*parent*/ bus_get_dma_tag(dev),
1817                                /*align */ 1 << WAVCACHE_BASEADDR_SHIFT,
1818                                           1 << (16+1),
1819                                /*limit */ MAESTRO_MAXADDR, BUS_SPACE_MAXADDR,
1820                                /*filter*/ NULL, NULL,
1821                                /*size  */ 3*ess->bufsz, 1, 0x3ffff,
1822                                /*flags */ 0,
1823 #if __FreeBSD_version >= 501102
1824                                /*lock  */ busdma_lock_mutex, &Giant,
1825 #endif
1826                                &ess->stat_dmat) != 0) {
1827                 device_printf(dev, "unable to create dma tag\n");
1828                 ret = ENOMEM;
1829                 goto bad;
1830         }
1831
1832         /* Allocate the room for brain-damaging status buffer. */
1833         ess->stat = dma_malloc(ess->stat_dmat, 3*ess->bufsz, &ess->phys);
1834         if (ess->stat == NULL) {
1835                 device_printf(dev, "cannot allocate status buffer\n");
1836                 ret = ENOMEM;
1837                 goto bad;
1838         }
1839         if (bootverbose)
1840                 device_printf(dev, "Maestro status/record buffer: %#llx\n",
1841                     (long long)ess->phys);
1842
1843         /* State D0-uninitialized. */
1844         ess->curpwr = PCI_POWERSTATE_D3;
1845         pci_set_powerstate(dev, PCI_POWERSTATE_D0);
1846
1847         pci_enable_busmaster(dev);
1848
1849         /* Allocate resources. */
1850         reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &regid, RF_ACTIVE);
1851         if (reg != NULL) {
1852                 ess->reg = reg;
1853                 ess->regid = regid;
1854                 ess->st = rman_get_bustag(reg);
1855                 ess->sh = rman_get_bushandle(reg);
1856         } else {
1857                 device_printf(dev, "unable to map register space\n");
1858                 ret = ENXIO;
1859                 goto bad;
1860         }
1861         irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &irqid,
1862             RF_ACTIVE | RF_SHAREABLE);
1863         if (irq != NULL) {
1864                 ess->irq = irq;
1865                 ess->irqid = irqid;
1866         } else {
1867                 device_printf(dev, "unable to map interrupt\n");
1868                 ret = ENXIO;
1869                 goto bad;
1870         }
1871
1872         /* Setup resources. */
1873         if (snd_setup_intr(dev, irq, INTR_MPSAFE, agg_intr, ess, &ih)) {
1874                 device_printf(dev, "unable to setup interrupt\n");
1875                 ret = ENXIO;
1876                 goto bad;
1877         } else
1878                 ess->ih = ih;
1879
1880         /* Transition from D0-uninitialized to D0. */
1881         agg_lock(ess);
1882         agg_power(ess, PCI_POWERSTATE_D0);
1883         if (agg_rdcodec(ess, 0) == 0x80) {
1884                 /* XXX - TODO: PT101 */
1885                 agg_unlock(ess);
1886                 device_printf(dev, "PT101 codec detected!\n");
1887                 ret = ENXIO;
1888                 goto bad;
1889         }
1890         agg_unlock(ess);
1891         codec = AC97_CREATE(dev, ess, agg_ac97);
1892         if (codec == NULL) {
1893                 device_printf(dev, "failed to create AC97 codec softc!\n");
1894                 ret = ENOMEM;
1895                 goto bad;
1896         }
1897         if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) {
1898                 device_printf(dev, "mixer initialization failed!\n");
1899                 ret = ENXIO;
1900                 goto bad;
1901         }
1902         ess->codec = codec;
1903
1904         ret = pcm_register(dev, ess, dacn, 1);
1905         if (ret)
1906                 goto bad;
1907
1908         mixer_hwvol_init(dev);
1909         agg_lock(ess);
1910         agg_power(ess, powerstate_init);
1911         agg_unlock(ess);
1912         for (data = 0; data < dacn; data++)
1913                 pcm_addchan(dev, PCMDIR_PLAY, &aggpch_class, ess);
1914         pcm_addchan(dev, PCMDIR_REC, &aggrch_class, ess);
1915         adjust_pchbase(ess->pch, ess->playchns, ess->bufsz);
1916
1917         snprintf(status, SND_STATUSLEN,
1918             "port 0x%lx-0x%lx irq %ld at device %d.%d on pci%d",
1919             rman_get_start(reg), rman_get_end(reg), rman_get_start(irq),
1920             pci_get_slot(dev), pci_get_function(dev), pci_get_bus(dev));
1921         pcm_setstatus(dev, status);
1922
1923         return 0;
1924
1925  bad:
1926         if (codec != NULL)
1927                 ac97_destroy(codec);
1928         if (ih != NULL)
1929                 bus_teardown_intr(dev, irq, ih);
1930         if (irq != NULL)
1931                 bus_release_resource(dev, SYS_RES_IRQ, irqid, irq);
1932         if (reg != NULL)
1933                 bus_release_resource(dev, SYS_RES_IOPORT, regid, reg);
1934         if (ess != NULL) {
1935                 if (ess->stat != NULL)
1936                         dma_free(ess->stat_dmat, ess->stat);
1937                 if (ess->stat_dmat != NULL)
1938                         bus_dma_tag_destroy(ess->stat_dmat);
1939                 if (ess->buf_dmat != NULL)
1940                         bus_dma_tag_destroy(ess->buf_dmat);
1941                 if (mtx_initialized(&ess->lock))
1942                         mtx_destroy(&ess->lock);
1943                 free(ess, M_DEVBUF);
1944         }
1945
1946         return ret;
1947 }
1948
1949 static int
1950 agg_detach(device_t dev)
1951 {
1952         struct agg_info *ess = pcm_getdevinfo(dev);
1953         int r;
1954         u_int16_t icr;
1955
1956         icr = AGG_RD(ess, PORT_HOSTINT_CTRL, 2);
1957         AGG_WR(ess, PORT_HOSTINT_CTRL, 0, 2);
1958
1959         agg_lock(ess);
1960         if (ess->active) {
1961                 AGG_WR(ess, PORT_HOSTINT_CTRL, icr, 2);
1962                 agg_unlock(ess);
1963                 return EBUSY;
1964         }
1965         agg_unlock(ess);
1966
1967         r = pcm_unregister(dev);
1968         if (r) {
1969                 AGG_WR(ess, PORT_HOSTINT_CTRL, icr, 2);
1970                 return r;
1971         }
1972
1973         agg_lock(ess);
1974         agg_power(ess, PCI_POWERSTATE_D3);
1975         agg_unlock(ess);
1976
1977         bus_teardown_intr(dev, ess->irq, ess->ih);
1978         bus_release_resource(dev, SYS_RES_IRQ, ess->irqid, ess->irq);
1979         bus_release_resource(dev, SYS_RES_IOPORT, ess->regid, ess->reg);
1980         dma_free(ess->stat_dmat, ess->stat);
1981         bus_dma_tag_destroy(ess->stat_dmat);
1982         bus_dma_tag_destroy(ess->buf_dmat);
1983         mtx_destroy(&ess->lock);
1984         free(ess, M_DEVBUF);
1985         return 0;
1986 }
1987
1988 static int
1989 agg_suspend(device_t dev)
1990 {
1991         struct agg_info *ess = pcm_getdevinfo(dev);
1992
1993         AGG_WR(ess, PORT_HOSTINT_CTRL, 0, 2);
1994         agg_lock(ess);
1995         agg_power(ess, PCI_POWERSTATE_D3);
1996         agg_unlock(ess);
1997
1998         return 0;
1999 }
2000
2001 static int
2002 agg_resume(device_t dev)
2003 {
2004         int i;
2005         struct agg_info *ess = pcm_getdevinfo(dev);
2006
2007         for (i = 0; i < ess->playchns; i++)
2008                 if (ess->active & (1 << i))
2009                         aggch_start_dac(ess->pch + i);
2010         if (ess->active & (1 << i))
2011                 aggch_start_adc(&ess->rch);
2012
2013         agg_lock(ess);
2014         if (!ess->active)
2015                 agg_power(ess, powerstate_init);
2016         agg_unlock(ess);
2017
2018         if (mixer_reinit(dev)) {
2019                 device_printf(dev, "unable to reinitialize the mixer\n");
2020                 return ENXIO;
2021         }
2022
2023         return 0;
2024 }
2025
2026 static int
2027 agg_shutdown(device_t dev)
2028 {
2029         struct agg_info *ess = pcm_getdevinfo(dev);
2030
2031         agg_lock(ess);
2032         agg_power(ess, PCI_POWERSTATE_D3);
2033         agg_unlock(ess);
2034
2035         return 0;
2036 }
2037
2038
2039 static device_method_t agg_methods[] = {
2040     DEVMETHOD(device_probe,     agg_probe),
2041     DEVMETHOD(device_attach,    agg_attach),
2042     DEVMETHOD(device_detach,    agg_detach),
2043     DEVMETHOD(device_suspend,   agg_suspend),
2044     DEVMETHOD(device_resume,    agg_resume),
2045     DEVMETHOD(device_shutdown,  agg_shutdown),
2046
2047     { 0, 0 }
2048 };
2049
2050 static driver_t agg_driver = {
2051     "pcm",
2052     agg_methods,
2053     PCM_SOFTC_SIZE,
2054 };
2055
2056 /*static devclass_t pcm_devclass;*/
2057
2058 DRIVER_MODULE(snd_maestro, pci, agg_driver, pcm_devclass, 0, 0);
2059 MODULE_DEPEND(snd_maestro, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
2060 MODULE_VERSION(snd_maestro, 1);