xref: /openbsd-src/sys/dev/pci/auich.c (revision 850e275390052b330d93020bf619a739a3c277ac)
1 /*	$OpenBSD: auich.c,v 1.74 2008/09/15 22:40:50 jakemsr Exp $	*/
2 
3 /*
4  * Copyright (c) 2000,2001 Michael Shalayeff
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22  * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26  * THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /* #define	AUICH_DEBUG */
30 /*
31  * AC'97 audio found on Intel 810/815/820/440MX chipsets.
32  *	http://developer.intel.com/design/chipsets/datashts/290655.htm
33  *	http://developer.intel.com/design/chipsets/manuals/298028.htm
34  *	http://www.intel.com/design/chipsets/datashts/290716.htm
35  *	http://www.intel.com/design/chipsets/datashts/290744.htm
36  */
37 
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/kernel.h>
41 #include <sys/malloc.h>
42 #include <sys/device.h>
43 
44 #include <dev/pci/pcidevs.h>
45 #include <dev/pci/pcivar.h>
46 
47 #include <sys/audioio.h>
48 #include <dev/audio_if.h>
49 #include <dev/mulaw.h>
50 #include <dev/auconv.h>
51 
52 #include <machine/bus.h>
53 
54 #include <dev/ic/ac97.h>
55 
56 /* 12.1.10 NAMBAR - native audio mixer base address register */
57 #define	AUICH_NAMBAR	0x10
58 /* 12.1.11 NABMBAR - native audio bus mastering base address register */
59 #define	AUICH_NABMBAR	0x14
60 #define	AUICH_CFG	0x41
61 #define	AUICH_CFG_IOSE	0x01
62 /* ICH4/ICH5/ICH6/ICH7 native audio mixer BAR */
63 #define	AUICH_MMBAR	0x18
64 /* ICH4/ICH5/ICH6/ICH7 native bus mastering BAR */
65 #define	AUICH_MBBAR	0x1c
66 #define	AUICH_S2CR	0x10000000	/* tertiary codec ready */
67 
68 /* table 12-3. native audio bus master control registers */
69 #define	AUICH_BDBAR	0x00	/* 8-byte aligned address */
70 #define	AUICH_CIV		0x04	/* 5 bits current index value */
71 #define	AUICH_LVI		0x05	/* 5 bits last valid index value */
72 #define		AUICH_LVI_MASK	0x1f
73 #define	AUICH_STS		0x06	/* 16 bits status */
74 #define		AUICH_FIFOE	0x10	/* fifo error */
75 #define		AUICH_BCIS	0x08	/* r- buf cmplt int sts; wr ack */
76 #define		AUICH_LVBCI	0x04	/* r- last valid bci, wr ack */
77 #define		AUICH_CELV	0x02	/* current equals last valid */
78 #define		AUICH_DCH		0x01	/* dma halted */
79 #define		AUICH_ISTS_BITS	"\020\01dch\02celv\03lvbci\04bcis\05fifoe"
80 #define	AUICH_PICB	0x08	/* 16 bits */
81 #define	AUICH_PIV		0x0a	/* 5 bits prefetched index value */
82 #define	AUICH_CTRL	0x0b	/* control */
83 #define		AUICH_IOCE	0x10	/* int on completion enable */
84 #define		AUICH_FEIE	0x08	/* fifo error int enable */
85 #define		AUICH_LVBIE	0x04	/* last valid buf int enable */
86 #define		AUICH_RR		0x02	/* 1 - reset regs */
87 #define		AUICH_RPBM	0x01	/* 1 - run, 0 - pause */
88 
89 #define	AUICH_PCMI	0x00
90 #define	AUICH_PCMO	0x10
91 #define	AUICH_MICI	0x20
92 
93 #define	AUICH_GCTRL	0x2c
94 #define		AUICH_SSM_78	0x40000000	/* S/PDIF slots 7 and 8 */
95 #define		AUICH_SSM_69	0x80000000	/* S/PDIF slots 6 and 9 */
96 #define		AUICH_SSM_1011	0xc0000000	/* S/PDIF slots 10 and 11 */
97 #define		AUICH_POM16	0x000000	/* PCM out precision 16bit */
98 #define		AUICH_POM20	0x400000	/* PCM out precision 20bit */
99 #define		AUICH_PCM246_MASK 0x300000
100 #define		AUICH_PCM2	0x000000	/* 2ch output */
101 #define		AUICH_PCM4	0x100000	/* 4ch output */
102 #define		AUICH_PCM6	0x200000	/* 6ch output */
103 #define		AUICH_S2RIE	0x40	/* int when tertiary codec resume */
104 #define		AUICH_SRIE	0x20	/* int when 2ndary codec resume */
105 #define		AUICH_PRIE	0x10	/* int when primary codec resume */
106 #define		AUICH_ACLSO	0x08	/* aclink shut off */
107 #define		AUICH_WRESET	0x04	/* warm reset */
108 #define		AUICH_CRESET	0x02	/* cold reset */
109 #define		AUICH_GIE		0x01	/* gpi int enable */
110 #define	AUICH_GSTS	0x30
111 #define		AUICH_MD3		0x20000	/* pwr-dn semaphore for modem */
112 #define		AUICH_AD3		0x10000	/* pwr-dn semaphore for audio */
113 #define		AUICH_RCS		0x08000	/* read completion status */
114 #define		AUICH_B3S12	0x04000	/* bit 3 of slot 12 */
115 #define		AUICH_B2S12	0x02000	/* bit 2 of slot 12 */
116 #define		AUICH_B1S12	0x01000	/* bit 1 of slot 12 */
117 #define		AUICH_SRI		0x00800	/* secondary resume int */
118 #define		AUICH_PRI		0x00400	/* primary resume int */
119 #define		AUICH_SCR		0x00200	/* secondary codec ready */
120 #define		AUICH_PCR		0x00100	/* primary codec ready */
121 #define		AUICH_MINT	0x00080	/* mic in int */
122 #define		AUICH_POINT	0x00040	/* pcm out int */
123 #define		AUICH_PIINT	0x00020	/* pcm in int */
124 #define		AUICH_MOINT	0x00004	/* modem out int */
125 #define		AUICH_MIINT	0x00002	/* modem in int */
126 #define		AUICH_GSCI	0x00001	/* gpi status change */
127 #define		AUICH_GSTS_BITS	"\020\01gsci\02miict\03moint\06piint\07point\010mint\011pcr\012scr\013pri\014sri\015b1s12\016b2s12\017b3s12\020rcs\021ad3\022md3"
128 #define	AUICH_CAS		0x34	/* 1/8 bit */
129 #define	AUICH_SEMATIMO		1000	/* us */
130 #define	AUICH_RESETIMO		500000	/* us */
131 
132 #define	ICH_SIS_NV_CTL	0x4c	/* some SiS/NVIDIA register.  From Linux */
133 #define		ICH_SIS_CTL_UNMUTE	0x01	/* un-mute the output */
134 
135 /*
136  * There are 32 buffer descriptors.  Each can reference up to 2^16 16-bit
137  * samples.
138  */
139 #define	AUICH_DMALIST_MAX	32
140 #define	AUICH_DMASEG_MAX	(65536*2)
141 struct auich_dmalist {
142 	u_int32_t	base;
143 	u_int32_t	len;
144 #define	AUICH_DMAF_IOC	0x80000000	/* 1-int on complete */
145 #define	AUICH_DMAF_BUP	0x40000000	/* 0-retrans last, 1-transmit 0 */
146 };
147 
148 #define	AUICH_FIXED_RATE 48000
149 
150 #ifndef BUS_DMA_NOCACHE
151 #define BUS_DMA_NOCACHE 0
152 #endif
153 
154 struct auich_dma {
155 	bus_dmamap_t map;
156 	caddr_t addr;
157 	bus_dma_segment_t segs[1];
158 	int nsegs;
159 	size_t size;
160 };
161 
162 struct auich_cdata {
163 	struct auich_dmalist ic_dmalist_pcmo[AUICH_DMALIST_MAX];
164 	struct auich_dmalist ic_dmalist_pcmi[AUICH_DMALIST_MAX];
165 	struct auich_dmalist ic_dmalist_mici[AUICH_DMALIST_MAX];
166 };
167 
168 #define	AUICH_CDOFF(x)		offsetof(struct auich_cdata, x)
169 #define	AUICH_PCMO_OFF(x)	AUICH_CDOFF(ic_dmalist_pcmo[(x)])
170 #define	AUICH_PCMI_OFF(x)	AUICH_CDOFF(ic_dmalist_pcmi[(x)])
171 #define	AUICH_MICI_OFF(x)	AUICH_CDOFF(ic_dmalist_mici[(x)])
172 
173 struct auich_softc {
174 	struct device sc_dev;
175 	void *sc_ih;
176 
177 	audio_device_t sc_audev;
178 
179 	bus_space_tag_t iot;
180 	bus_space_tag_t iot_mix;
181 	bus_space_handle_t mix_ioh;
182 	bus_space_handle_t aud_ioh;
183 	bus_dma_tag_t dmat;
184 
185 	struct ac97_codec_if *codec_if;
186 	struct ac97_host_if host_if;
187 
188 	/* dma scatter-gather buffer lists */
189 
190 	bus_dmamap_t sc_cddmamap;
191 #define	sc_cddma	sc_cddmamap->dm_segs[0].ds_addr
192 
193 	struct auich_cdata *sc_cdata;
194 
195 	struct auich_ring {
196 		int qptr;
197 		struct auich_dmalist *dmalist;
198 
199 		uint32_t start, p, end;
200 		int blksize;
201 
202 		void (*intr)(void *);
203 		void *arg;
204 	} pcmo, pcmi, mici;
205 
206 	struct auich_dma *sc_pdma;	/* play */
207 	struct auich_dma *sc_rdma;	/* record */
208 	struct auich_dma *sc_cdma;	/* calibrate */
209 
210 #ifdef AUICH_DEBUG
211 	int pcmi_fifoe;
212 	int pcmo_fifoe;
213 #endif
214 
215 	void *powerhook;
216 	int suspend;
217 	u_int16_t ext_ctrl;
218 	int sc_sample_size;
219 	int sc_sts_reg;
220 	int sc_dmamap_flags;
221 	int sc_ignore_codecready;
222 	int flags;
223 	int sc_ac97rate;
224 };
225 
226 #ifdef AUICH_DEBUG
227 #define	DPRINTF(l,x)	do { if (auich_debug & (l)) printf x; } while(0)
228 int auich_debug = 0xfffe;
229 #define	AUICH_DEBUG_CODECIO	0x0001
230 #define	AUICH_DEBUG_DMA		0x0002
231 #define	AUICH_DEBUG_INTR	0x0004
232 #else
233 #define	DPRINTF(x,y)	/* nothing */
234 #endif
235 
236 struct cfdriver	auich_cd = {
237 	NULL, "auich", DV_DULL
238 };
239 
240 int  auich_match(struct device *, void *, void *);
241 void auich_attach(struct device *, struct device *, void *);
242 int  auich_intr(void *);
243 
244 struct cfattach auich_ca = {
245 	sizeof(struct auich_softc), auich_match, auich_attach
246 };
247 
248 static const struct auich_devtype {
249 	int	vendor;
250 	int	product;
251 	int	options;
252 	char	name[8];
253 } auich_devices[] = {
254 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_6300ESB_ACA,	0, "ESB" },
255 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_6321ESB_ACA,	0, "ESB2" },
256 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801AA_ACA,	0, "ICH" },
257 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801AB_ACA,	0, "ICH0" },
258 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801BA_ACA,	0, "ICH2" },
259 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801CA_ACA,	0, "ICH3" },
260 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801DB_ACA,	0, "ICH4" },
261 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801EB_ACA,	0, "ICH5" },
262 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801FB_ACA,	0, "ICH6" },
263 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82801GB_ACA,	0, "ICH7" },
264 	{ PCI_VENDOR_INTEL,	PCI_PRODUCT_INTEL_82440MX_ACA,	0, "440MX" },
265 	{ PCI_VENDOR_SIS,	PCI_PRODUCT_SIS_7012_ACA,	0, "SiS7012" },
266 	{ PCI_VENDOR_NVIDIA,	PCI_PRODUCT_NVIDIA_NFORCE_ACA,	0, "nForce" },
267 	{ PCI_VENDOR_NVIDIA,	PCI_PRODUCT_NVIDIA_NFORCE2_ACA,	0, "nForce2" },
268 	{ PCI_VENDOR_NVIDIA,	PCI_PRODUCT_NVIDIA_NFORCE2_400_ACA,
269 	    0, "nForce2" },
270 	{ PCI_VENDOR_NVIDIA,	PCI_PRODUCT_NVIDIA_NFORCE3_ACA,	0, "nForce3" },
271 	{ PCI_VENDOR_NVIDIA,	PCI_PRODUCT_NVIDIA_NFORCE3_250_ACA,
272 	    0, "nForce3" },
273 	{ PCI_VENDOR_NVIDIA,	PCI_PRODUCT_NVIDIA_NFORCE4_AC,	0, "nForce4" },
274 	{ PCI_VENDOR_NVIDIA,	PCI_PRODUCT_NVIDIA_MCP04_AC97,	0, "MCP04" },
275 	{ PCI_VENDOR_NVIDIA,	PCI_PRODUCT_NVIDIA_MCP51_ACA,	0, "MCP51" },
276 	{ PCI_VENDOR_AMD,	PCI_PRODUCT_AMD_PBC768_ACA,	0, "AMD768" },
277 	{ PCI_VENDOR_AMD,	PCI_PRODUCT_AMD_8111_ACA,	0, "AMD8111" },
278 };
279 
280 int auich_open(void *, int);
281 void auich_close(void *);
282 int auich_query_encoding(void *, struct audio_encoding *);
283 int auich_set_params(void *, int, int, struct audio_params *,
284     struct audio_params *);
285 int auich_round_blocksize(void *, int);
286 void auich_halt_pipe(struct auich_softc *, int);
287 int auich_halt_output(void *);
288 int auich_halt_input(void *);
289 int auich_getdev(void *, struct audio_device *);
290 int auich_set_port(void *, mixer_ctrl_t *);
291 int auich_get_port(void *, mixer_ctrl_t *);
292 int auich_query_devinfo(void *, mixer_devinfo_t *);
293 void *auich_allocm(void *, int, size_t, int, int);
294 void auich_freem(void *, void *, int);
295 size_t auich_round_buffersize(void *, int, size_t);
296 paddr_t auich_mappage(void *, void *, off_t, int);
297 int auich_get_props(void *);
298 void auich_trigger_pipe(struct auich_softc *, int, struct auich_ring *);
299 void auich_intr_pipe(struct auich_softc *, int, struct auich_ring *);
300 int auich_trigger_output(void *, void *, void *, int, void (*)(void *),
301     void *, struct audio_params *);
302 int auich_trigger_input(void *, void *, void *, int, void (*)(void *),
303     void *, struct audio_params *);
304 int auich_alloc_cdata(struct auich_softc *);
305 int auich_allocmem(struct auich_softc *, size_t, size_t, struct auich_dma *);
306 int auich_freemem(struct auich_softc *, struct auich_dma *);
307 void auich_get_default_params(void *, int, struct audio_params *);
308 
309 void auich_powerhook(int, void *);
310 
311 struct audio_hw_if auich_hw_if = {
312 	auich_open,
313 	auich_close,
314 	NULL,			/* drain */
315 	auich_query_encoding,
316 	auich_set_params,
317 	auich_round_blocksize,
318 	NULL,			/* commit_setting */
319 	NULL,			/* init_output */
320 	NULL,			/* init_input */
321 	NULL,			/* start_output */
322 	NULL,			/* start_input */
323 	auich_halt_output,
324 	auich_halt_input,
325 	NULL,			/* speaker_ctl */
326 	auich_getdev,
327 	NULL,			/* getfd */
328 	auich_set_port,
329 	auich_get_port,
330 	auich_query_devinfo,
331 	auich_allocm,
332 	auich_freem,
333 	auich_round_buffersize,
334 	auich_mappage,
335 	auich_get_props,
336 	auich_trigger_output,
337 	auich_trigger_input,
338 	auich_get_default_params
339 };
340 
341 int  auich_attach_codec(void *, struct ac97_codec_if *);
342 int  auich_read_codec(void *, u_int8_t, u_int16_t *);
343 int  auich_write_codec(void *, u_int8_t, u_int16_t);
344 void auich_reset_codec(void *);
345 enum ac97_host_flags auich_flags_codec(void *);
346 unsigned int auich_calibrate(struct auich_softc *);
347 
348 int
349 auich_match(parent, match, aux)
350 	struct device *parent;
351 	void *match;
352 	void *aux;
353 {
354 	struct pci_attach_args *pa = aux;
355 	int i;
356 
357 	for (i = sizeof(auich_devices)/sizeof(auich_devices[0]); i--;)
358 		if (PCI_VENDOR(pa->pa_id) == auich_devices[i].vendor &&
359 		    PCI_PRODUCT(pa->pa_id) == auich_devices[i].product)
360 			return 1;
361 
362 	return 0;
363 }
364 
365 void
366 auich_attach(parent, self, aux)
367 	struct device *parent, *self;
368 	void *aux;
369 {
370 	struct auich_softc *sc = (struct auich_softc *)self;
371 	struct pci_attach_args *pa = aux;
372 	pci_intr_handle_t ih;
373 	bus_size_t mix_size, aud_size;
374 	pcireg_t csr;
375 	const char *intrstr;
376 	u_int32_t status;
377 	int i;
378 
379 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL &&
380 	    (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801DB_ACA ||
381 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801EB_ACA ||
382 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801FB_ACA ||
383 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801GB_ACA)) {
384 		/*
385 		 * Use native mode for ICH4/ICH5/ICH6/ICH7
386 		 */
387 		if (pci_mapreg_map(pa, AUICH_MMBAR, PCI_MAPREG_TYPE_MEM, 0,
388 		    &sc->iot_mix, &sc->mix_ioh, NULL, &mix_size, 0)) {
389 			csr = pci_conf_read(pa->pa_pc, pa->pa_tag, AUICH_CFG);
390 			pci_conf_write(pa->pa_pc, pa->pa_tag, AUICH_CFG,
391 			    csr | AUICH_CFG_IOSE);
392 			if (pci_mapreg_map(pa, AUICH_NAMBAR, PCI_MAPREG_TYPE_IO,
393 			    0, &sc->iot_mix, &sc->mix_ioh, NULL, &mix_size, 0)) {
394 				printf(": can't map codec mem/io space\n");
395 				return;
396 			}
397 		}
398 
399 		if (pci_mapreg_map(pa, AUICH_MBBAR, PCI_MAPREG_TYPE_MEM, 0,
400 		    &sc->iot, &sc->aud_ioh, NULL, &aud_size, 0)) {
401 			csr = pci_conf_read(pa->pa_pc, pa->pa_tag, AUICH_CFG);
402 			pci_conf_write(pa->pa_pc, pa->pa_tag, AUICH_CFG,
403 			    csr | AUICH_CFG_IOSE);
404 			if (pci_mapreg_map(pa, AUICH_NABMBAR,
405 			    PCI_MAPREG_TYPE_IO, 0, &sc->iot,
406 			    &sc->aud_ioh, NULL, &aud_size, 0)) {
407 				printf(": can't map device mem/io space\n");
408 				bus_space_unmap(sc->iot_mix, sc->mix_ioh, mix_size);
409 				return;
410 			}
411 		}
412 	} else {
413 		if (pci_mapreg_map(pa, AUICH_NAMBAR, PCI_MAPREG_TYPE_IO,
414 		    0, &sc->iot_mix, &sc->mix_ioh, NULL, &mix_size, 0)) {
415 			printf(": can't map codec i/o space\n");
416 			return;
417 		}
418 
419 		if (pci_mapreg_map(pa, AUICH_NABMBAR, PCI_MAPREG_TYPE_IO,
420 		    0, &sc->iot, &sc->aud_ioh, NULL, &aud_size, 0)) {
421 			printf(": can't map device i/o space\n");
422 			bus_space_unmap(sc->iot_mix, sc->mix_ioh, mix_size);
423 			return;
424 		}
425 	}
426 	sc->dmat = pa->pa_dmat;
427 
428 	if (pci_intr_map(pa, &ih)) {
429 		bus_space_unmap(sc->iot, sc->aud_ioh, aud_size);
430 		bus_space_unmap(sc->iot_mix, sc->mix_ioh, mix_size);
431 		return;
432 	}
433 	intrstr = pci_intr_string(pa->pa_pc, ih);
434 	sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, auich_intr,
435 				       sc, sc->sc_dev.dv_xname);
436 	if (!sc->sc_ih) {
437 		printf(": can't establish interrupt");
438 		if (intrstr)
439 			printf(" at %s", intrstr);
440 		printf("\n");
441 		bus_space_unmap(sc->iot, sc->aud_ioh, aud_size);
442 		bus_space_unmap(sc->iot_mix, sc->mix_ioh, mix_size);
443 		return;
444 	}
445 
446 	for (i = sizeof(auich_devices)/sizeof(auich_devices[0]); i--;)
447 		if (PCI_PRODUCT(pa->pa_id) == auich_devices[i].product)
448 			break;
449 
450 	snprintf(sc->sc_audev.name, sizeof sc->sc_audev.name, "%s AC97",
451 		 auich_devices[i].name);
452 	snprintf(sc->sc_audev.version, sizeof sc->sc_audev.version, "0x%02x",
453 		 PCI_REVISION(pa->pa_class));
454 	strlcpy(sc->sc_audev.config, sc->sc_dev.dv_xname,
455 		sizeof sc->sc_audev.config);
456 
457 	printf(": %s, %s\n", intrstr, sc->sc_audev.name);
458 
459 	/* SiS 7012 needs special handling */
460 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SIS &&
461 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SIS_7012_ACA) {
462 		sc->sc_sts_reg = AUICH_PICB;
463 		sc->sc_sample_size = 1;
464 		/* un-mute output */
465 		bus_space_write_4(sc->iot, sc->aud_ioh, ICH_SIS_NV_CTL,
466 		    bus_space_read_4(sc->iot, sc->aud_ioh, ICH_SIS_NV_CTL) |
467 		    ICH_SIS_CTL_UNMUTE);
468 	} else {
469 		sc->sc_sts_reg = AUICH_STS;
470 		sc->sc_sample_size = 2;
471 	}
472 
473 	/* Workaround for a 440MX B-stepping erratum */
474 	sc->sc_dmamap_flags = BUS_DMA_COHERENT;
475 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL &&
476 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82440MX_ACA) {
477 		sc->sc_dmamap_flags |= BUS_DMA_NOCACHE;
478 		printf("%s: DMA bug workaround enabled\n", sc->sc_dev.dv_xname);
479 	}
480 
481 	/* Set up DMA lists. */
482 	sc->pcmo.qptr = sc->pcmi.qptr = sc->mici.qptr = 0;
483 	auich_alloc_cdata(sc);
484 
485 	DPRINTF(AUICH_DEBUG_DMA, ("auich_attach: lists %p %p %p\n",
486 	    sc->pcmo.dmalist, sc->pcmi.dmalist, sc->mici.dmalist));
487 
488 	/* Reset codec and AC'97 */
489 	auich_reset_codec(sc);
490 	status = bus_space_read_4(sc->iot, sc->aud_ioh, AUICH_GSTS);
491 	if (!(status & AUICH_PCR)) {	/* reset failure */
492 		if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL &&
493 		    (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801DB_ACA ||
494 		     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801EB_ACA ||
495 		     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801FB_ACA ||
496 		     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801GB_ACA)) {
497 			/* MSI 845G Max never return AUICH_PCR */
498 			sc->sc_ignore_codecready = 1;
499 		} else {
500 			printf("%s: reset failed!\n", sc->sc_dev.dv_xname);
501 			return;
502 		}
503 	}
504 
505 	sc->host_if.arg = sc;
506 	sc->host_if.attach = auich_attach_codec;
507 	sc->host_if.read = auich_read_codec;
508 	sc->host_if.write = auich_write_codec;
509 	sc->host_if.reset = auich_reset_codec;
510 	sc->host_if.flags = auich_flags_codec;
511 	if (sc->sc_dev.dv_cfdata->cf_flags & 0x0001)
512 		sc->flags = AC97_HOST_SWAPPED_CHANNELS;
513 
514 	if (ac97_attach(&sc->host_if) != 0) {
515 		pci_intr_disestablish(pa->pa_pc, sc->sc_ih);
516 		bus_space_unmap(sc->iot, sc->aud_ioh, aud_size);
517 		bus_space_unmap(sc->iot_mix, sc->mix_ioh, mix_size);
518 		return;
519 	}
520 
521 	audio_attach_mi(&auich_hw_if, sc, &sc->sc_dev);
522 
523 	/* Watch for power changes */
524 	sc->suspend = PWR_RESUME;
525 	sc->powerhook = powerhook_establish(auich_powerhook, sc);
526 
527 	sc->sc_ac97rate = -1;
528 }
529 
530 int
531 auich_read_codec(v, reg, val)
532 	void *v;
533 	u_int8_t reg;
534 	u_int16_t *val;
535 {
536 	struct auich_softc *sc = v;
537 	int i;
538 
539 	/* wait for an access semaphore */
540 	for (i = AUICH_SEMATIMO; i-- &&
541 	    bus_space_read_1(sc->iot, sc->aud_ioh, AUICH_CAS) & 1; DELAY(1));
542 
543 	if (!sc->sc_ignore_codecready && i < 0) {
544 		DPRINTF(AUICH_DEBUG_CODECIO,
545 		    ("%s: read_codec timeout\n", sc->sc_dev.dv_xname));
546 		return (-1);
547 	}
548 
549 	*val = bus_space_read_2(sc->iot_mix, sc->mix_ioh, reg);
550 	DPRINTF(AUICH_DEBUG_CODECIO, ("%s: read_codec(%x, %x)\n",
551 	    sc->sc_dev.dv_xname, reg, *val));
552 	return (0);
553 }
554 
555 int
556 auich_write_codec(v, reg, val)
557 	void *v;
558 	u_int8_t reg;
559 	u_int16_t val;
560 {
561 	struct auich_softc *sc = v;
562 	int i;
563 
564 	/* wait for an access semaphore */
565 	for (i = AUICH_SEMATIMO; i-- &&
566 	    bus_space_read_1(sc->iot, sc->aud_ioh, AUICH_CAS) & 1; DELAY(1));
567 
568 	if (sc->sc_ignore_codecready || i >= 0) {
569 		DPRINTF(AUICH_DEBUG_CODECIO, ("%s: write_codec(%x, %x)\n",
570 		    sc->sc_dev.dv_xname, reg, val));
571 		bus_space_write_2(sc->iot_mix, sc->mix_ioh, reg, val);
572 		return (0);
573 	} else {
574 		DPRINTF(AUICH_DEBUG_CODECIO,
575 		    ("%s: write_codec timeout\n", sc->sc_dev.dv_xname));
576 		return (-1);
577 	}
578 }
579 
580 int
581 auich_attach_codec(v, cif)
582 	void *v;
583 	struct ac97_codec_if *cif;
584 {
585 	struct auich_softc *sc = v;
586 
587 	sc->codec_if = cif;
588 	return 0;
589 }
590 
591 void
592 auich_reset_codec(v)
593 	void *v;
594 {
595 	struct auich_softc *sc = v;
596 	u_int32_t control;
597 	int i;
598 
599 	control = bus_space_read_4(sc->iot, sc->aud_ioh, AUICH_GCTRL);
600 	control &= ~(AUICH_ACLSO | AUICH_PCM246_MASK);
601 	control |= (control & AUICH_CRESET) ? AUICH_WRESET : AUICH_CRESET;
602 	bus_space_write_4(sc->iot, sc->aud_ioh, AUICH_GCTRL, control);
603 
604 	for (i = AUICH_RESETIMO; i-- &&
605 	    !(bus_space_read_4(sc->iot, sc->aud_ioh, AUICH_GSTS) & AUICH_PCR);
606 	    DELAY(1));
607 
608 	if (i < 0)
609 		DPRINTF(AUICH_DEBUG_CODECIO,
610 		    ("%s: reset_codec timeout\n", sc->sc_dev.dv_xname));
611 }
612 
613 enum ac97_host_flags
614 auich_flags_codec(void *v)
615 {
616 	struct auich_softc *sc = v;
617 
618 	return (sc->flags);
619 }
620 
621 int
622 auich_open(v, flags)
623 	void *v;
624 	int flags;
625 {
626 	struct auich_softc *sc = v;
627 
628 	if (sc->sc_ac97rate == -1)
629 		sc->sc_ac97rate = auich_calibrate(sc);
630 	return 0;
631 }
632 
633 void
634 auich_close(v)
635 	void *v;
636 {
637 }
638 
639 void
640 auich_get_default_params(void *addr, int mode, struct audio_params *params)
641 {
642 	ac97_get_default_params(params);
643 }
644 
645 int
646 auich_query_encoding(v, aep)
647 	void *v;
648 	struct audio_encoding *aep;
649 {
650 	switch (aep->index) {
651 	case 0:
652 		strlcpy(aep->name, AudioEulinear, sizeof aep->name);
653 		aep->encoding = AUDIO_ENCODING_ULINEAR;
654 		aep->precision = 8;
655 		aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
656 		return (0);
657 	case 1:
658 		strlcpy(aep->name, AudioEmulaw, sizeof aep->name);
659 		aep->encoding = AUDIO_ENCODING_ULAW;
660 		aep->precision = 8;
661 		aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
662 		return (0);
663 	case 2:
664 		strlcpy(aep->name, AudioEalaw, sizeof aep->name);
665 		aep->encoding = AUDIO_ENCODING_ALAW;
666 		aep->precision = 8;
667 		aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
668 		return (0);
669 	case 3:
670 		strlcpy(aep->name, AudioEslinear, sizeof aep->name);
671 		aep->encoding = AUDIO_ENCODING_SLINEAR;
672 		aep->precision = 8;
673 		aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
674 		return (0);
675 	case 4:
676 		strlcpy(aep->name, AudioEslinear_le, sizeof aep->name);
677 		aep->encoding = AUDIO_ENCODING_SLINEAR_LE;
678 		aep->precision = 16;
679 		aep->flags = 0;
680 		return (0);
681 	case 5:
682 		strlcpy(aep->name, AudioEulinear_le, sizeof aep->name);
683 		aep->encoding = AUDIO_ENCODING_ULINEAR_LE;
684 		aep->precision = 16;
685 		aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
686 		return (0);
687 	case 6:
688 		strlcpy(aep->name, AudioEslinear_be, sizeof aep->name);
689 		aep->encoding = AUDIO_ENCODING_SLINEAR_BE;
690 		aep->precision = 16;
691 		aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
692 		return (0);
693 	case 7:
694 		strlcpy(aep->name, AudioEulinear_be, sizeof aep->name);
695 		aep->encoding = AUDIO_ENCODING_ULINEAR_BE;
696 		aep->precision = 16;
697 		aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
698 		return (0);
699 	default:
700 		return (EINVAL);
701 	}
702 }
703 
704 int
705 auich_set_params(v, setmode, usemode, play, rec)
706 	void *v;
707 	int setmode, usemode;
708 	struct audio_params *play, *rec;
709 {
710 	struct auich_softc *sc = v;
711 	int error;
712 	u_int orate;
713 	u_int adj_rate;
714 
715 	if (setmode & AUMODE_PLAY) {
716 		play->factor = 1;
717 		play->sw_code = NULL;
718 		switch(play->encoding) {
719 		case AUDIO_ENCODING_ULAW:
720 			switch (play->channels) {
721 			case 1:
722 				play->factor = 4;
723 				play->sw_code = mulaw_to_slinear16_le_mts;
724 				break;
725 			case 2:
726 				play->factor = 2;
727 				play->sw_code = mulaw_to_slinear16_le;
728 				break;
729 			default:
730 				return (EINVAL);
731 			}
732 			break;
733 		case AUDIO_ENCODING_SLINEAR_LE:
734 			switch (play->precision) {
735 			case 8:
736 				switch (play->channels) {
737 				case 1:
738 					play->factor = 4;
739 					play->sw_code = linear8_to_linear16_le_mts;
740 					break;
741 				case 2:
742 					play->factor = 2;
743 					play->sw_code = linear8_to_linear16_le;
744 					break;
745 				default:
746 					return (EINVAL);
747 				}
748 				break;
749 			case 16:
750 				switch (play->channels) {
751 				case 1:
752 					play->factor = 2;
753 					play->sw_code = noswap_bytes_mts;
754 					break;
755 				case 2:
756 					break;
757 				default:
758 					return (EINVAL);
759 				}
760 				break;
761 			default:
762 				return (EINVAL);
763 			}
764 			break;
765 		case AUDIO_ENCODING_ULINEAR_LE:
766 			switch (play->precision) {
767 			case 8:
768 				switch (play->channels) {
769 				case 1:
770 					play->factor = 4;
771 					play->sw_code = ulinear8_to_linear16_le_mts;
772 					break;
773 				case 2:
774 					play->factor = 2;
775 					play->sw_code = ulinear8_to_linear16_le;
776 					break;
777 				default:
778 					return (EINVAL);
779 				}
780 				break;
781 			case 16:
782 				switch (play->channels) {
783 				case 1:
784 					play->factor = 2;
785 					play->sw_code = change_sign16_le_mts;
786 					break;
787 				case 2:
788 					play->sw_code = change_sign16_le;
789 					break;
790 				default:
791 					return (EINVAL);
792 				}
793 				break;
794 			default:
795 				return (EINVAL);
796 			}
797 			break;
798 		case AUDIO_ENCODING_ALAW:
799 			switch (play->channels) {
800 			case 1:
801 				play->factor = 4;
802 				play->sw_code = alaw_to_slinear16_le_mts;
803 				break;
804 			case 2:
805 				play->factor = 2;
806 				play->sw_code = alaw_to_slinear16_le;
807 				break;
808 			default:
809 				return (EINVAL);
810 			}
811 			break;
812 		case AUDIO_ENCODING_SLINEAR_BE:
813 			switch (play->precision) {
814 			case 8:
815 				switch (play->channels) {
816 				case 1:
817 					play->factor = 4;
818 					play->sw_code = linear8_to_linear16_le_mts;
819 					break;
820 				case 2:
821 					play->factor = 2;
822 					play->sw_code = linear8_to_linear16_le;
823 					break;
824 				default:
825 					return (EINVAL);
826 				}
827 				break;
828 			case 16:
829 				switch (play->channels) {
830 				case 1:
831 					play->factor = 2;
832 					play->sw_code = swap_bytes_mts;
833 					break;
834 				case 2:
835 					play->sw_code = swap_bytes;
836 					break;
837 				default:
838 					return (EINVAL);
839 				}
840 				break;
841 			default:
842 				return (EINVAL);
843 			}
844 			break;
845 		case AUDIO_ENCODING_ULINEAR_BE:
846 			switch (play->precision) {
847 			case 8:
848 				switch (play->channels) {
849 				case 1:
850 					play->factor = 4;
851 					play->sw_code = ulinear8_to_linear16_le_mts;
852 					break;
853 				case 2:
854 					play->factor = 2;
855 					play->sw_code = ulinear8_to_linear16_le;
856 					break;
857 				default:
858 					return (EINVAL);
859 				}
860 				break;
861 			case 16:
862 				switch (play->channels) {
863 				case 1:
864 					play->factor = 2;
865 					play->sw_code = swap_bytes_change_sign16_le_mts;
866 					break;
867 				case 2:
868 					play->sw_code = swap_bytes_change_sign16_le;
869 					break;
870 				default:
871 					return (EINVAL);
872 				}
873 				break;
874 			default:
875 				return (EINVAL);
876 			}
877 			break;
878 		default:
879 			return (EINVAL);
880 		}
881 
882 		orate = adj_rate = play->sample_rate;
883 		if (sc->sc_ac97rate != 0)
884 			adj_rate = orate * AUICH_FIXED_RATE / sc->sc_ac97rate;
885 
886 		play->sample_rate = adj_rate;
887 		error = ac97_set_rate(sc->codec_if,
888 		    AC97_REG_PCM_LFE_DAC_RATE, &play->sample_rate);
889 		if (error)
890 			return (error);
891 
892 		play->sample_rate = adj_rate;
893 		error = ac97_set_rate(sc->codec_if,
894 		    AC97_REG_PCM_SURR_DAC_RATE, &play->sample_rate);
895 		if (error)
896 			return (error);
897 
898 		play->sample_rate = adj_rate;
899 		error = ac97_set_rate(sc->codec_if,
900 		    AC97_REG_PCM_FRONT_DAC_RATE, &play->sample_rate);
901 		if (error)
902 			return (error);
903 
904 		if (play->sample_rate == adj_rate)
905 			play->sample_rate = orate;
906 	}
907 
908 	if (setmode & AUMODE_RECORD) {
909 		rec->factor = 1;
910 		rec->sw_code = 0;
911 		switch(rec->encoding) {
912 		case AUDIO_ENCODING_ULAW:
913 			switch (rec->channels) {
914 			case 1:
915 				rec->sw_code = slinear16_to_mulaw_le_stm;
916 				rec->factor = 4;
917 				break;
918 			case 2:
919 				rec->sw_code = slinear16_to_mulaw_le;
920 				rec->factor = 2;
921 				break;
922 			}
923 			break;
924 		case AUDIO_ENCODING_ALAW:
925 			switch (rec->channels) {
926 			case 1:
927 				rec->sw_code = slinear16_to_alaw_le_stm;
928 				rec->factor = 4;
929 				break;
930 			case 2:
931 				rec->sw_code = slinear16_to_alaw_le;
932 				rec->factor = 2;
933 				break;
934 			}
935 			break;
936 		case AUDIO_ENCODING_SLINEAR_LE:
937 			switch (rec->precision) {
938 			case 8:
939 				switch (rec->channels) {
940 				case 1:
941 					rec->sw_code = linear16_to_linear8_le_stm;
942 					rec->factor = 4;
943 					break;
944 				case 2:
945 					rec->sw_code = linear16_to_linear8_le;
946 					rec->factor = 2;
947 					break;
948 				}
949 				break;
950 			case 16:
951 				switch (rec->channels) {
952 				case 1:
953 					rec->sw_code = linear16_decimator;
954 					rec->factor = 2;
955 					break;
956 				case 2:
957 					break;
958 				}
959 				break;
960 			default:
961 				return (EINVAL);
962 			}
963 			break;
964 		case AUDIO_ENCODING_ULINEAR_LE:
965 			switch (rec->precision) {
966 			case 8:
967 				switch (rec->channels) {
968 				case 1:
969 					rec->sw_code = linear16_to_ulinear8_le_stm;
970 					rec->factor = 4;
971 					break;
972 				case 2:
973 					rec->sw_code = linear16_to_ulinear8_le;
974 					rec->factor = 2;
975 					break;
976 				}
977 				break;
978 			case 16:
979 				switch (rec->channels) {
980 				case 1:
981 					rec->sw_code = change_sign16_le_stm;
982 					rec->factor = 2;
983 					break;
984 				case 2:
985 					rec->sw_code = change_sign16_le;
986 					break;
987 				}
988 				break;
989 			default:
990 				return (EINVAL);
991 			}
992 			break;
993 		case AUDIO_ENCODING_SLINEAR_BE:
994 			switch (rec->precision) {
995 			case 8:
996 				switch (rec->channels) {
997 				case 1:
998 					rec->sw_code = linear16_to_linear8_le_stm;
999 					rec->factor = 4;
1000 					break;
1001 				case 2:
1002 					rec->sw_code = linear16_to_linear8_le;
1003 					rec->factor = 2;
1004 					break;
1005 				}
1006 				break;
1007 			case 16:
1008 				switch (rec->channels) {
1009 				case 1:
1010 					rec->sw_code = swap_bytes_stm;
1011 					rec->factor = 2;
1012 					break;
1013 				case 2:
1014 					rec->sw_code = swap_bytes;
1015 					break;
1016 				}
1017 				break;
1018 			default:
1019 				return (EINVAL);
1020 			}
1021 			break;
1022 		case AUDIO_ENCODING_ULINEAR_BE:
1023 			switch (rec->precision) {
1024 			case 8:
1025 				switch (rec->channels) {
1026 				case 1:
1027 					rec->sw_code = linear16_to_ulinear8_le_stm;
1028 					rec->factor = 4;
1029 					break;
1030 				case 2:
1031 					rec->sw_code = linear16_to_ulinear8_le;
1032 					rec->factor = 2;
1033 					break;
1034 				}
1035 				break;
1036 			case 16:
1037 				switch (rec->channels) {
1038 				case 1:
1039 					rec->sw_code = change_sign16_swap_bytes_le_stm;
1040 					rec->factor = 2;
1041 					break;
1042 				case 2:
1043 					rec->sw_code = change_sign16_swap_bytes_le;
1044 					break;
1045 				}
1046 				break;
1047 			default:
1048 				return (EINVAL);
1049 			}
1050 			break;
1051 		default:
1052 			return (EINVAL);
1053 		}
1054 
1055 		orate = rec->sample_rate;
1056 		if (sc->sc_ac97rate != 0)
1057 			rec->sample_rate = orate * AUICH_FIXED_RATE /
1058 			    sc->sc_ac97rate;
1059 		error = ac97_set_rate(sc->codec_if, AC97_REG_PCM_LR_ADC_RATE,
1060 		    &rec->sample_rate);
1061 		if (error)
1062 			return (error);
1063 		rec->sample_rate = orate;
1064 	}
1065 
1066 	return (0);
1067 }
1068 
1069 int
1070 auich_round_blocksize(v, blk)
1071 	void *v;
1072 	int blk;
1073 {
1074 	return (blk + 0x3f) & ~0x3f;
1075 }
1076 
1077 
1078 void
1079 auich_halt_pipe(struct auich_softc *sc, int pipe)
1080 {
1081 	int i;
1082 	uint32_t status;
1083 
1084 	bus_space_write_1(sc->iot, sc->aud_ioh, pipe + AUICH_CTRL, 0);
1085 	for (i = 0; i < 100; i++) {
1086 		status = bus_space_read_4(sc->iot, sc->aud_ioh, pipe + AUICH_STS);
1087 		if (status & AUICH_DCH)
1088 			break;
1089 		DELAY(1);
1090 	}
1091 	bus_space_write_1(sc->iot, sc->aud_ioh, pipe + AUICH_CTRL, AUICH_RR);
1092 
1093 	if (i > 0)
1094 		DPRINTF(AUICH_DEBUG_DMA,
1095 		    ("auich_halt_pipe: halt took %d cycles\n", i));
1096 }
1097 
1098 
1099 int
1100 auich_halt_output(v)
1101 	void *v;
1102 {
1103 	struct auich_softc *sc = v;
1104 
1105 	DPRINTF(AUICH_DEBUG_DMA, ("%s: halt_output\n", sc->sc_dev.dv_xname));
1106 
1107 	bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMO + AUICH_CTRL, AUICH_RR);
1108 	sc->pcmo.intr = NULL;
1109 
1110 	return 0;
1111 }
1112 
1113 int
1114 auich_halt_input(v)
1115 	void *v;
1116 {
1117 	struct auich_softc *sc = v;
1118 
1119 	DPRINTF(AUICH_DEBUG_DMA,
1120 	    ("%s: halt_input\n", sc->sc_dev.dv_xname));
1121 
1122 	/* XXX halt both unless known otherwise */
1123 
1124 	bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_CTRL, AUICH_RR);
1125 	bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_MICI + AUICH_CTRL, AUICH_RR);
1126 	sc->pcmi.intr = NULL;
1127 
1128 	return 0;
1129 }
1130 
1131 int
1132 auich_getdev(v, adp)
1133 	void *v;
1134 	struct audio_device *adp;
1135 {
1136 	struct auich_softc *sc = v;
1137 	*adp = sc->sc_audev;
1138 	return 0;
1139 }
1140 
1141 int
1142 auich_set_port(v, cp)
1143 	void *v;
1144 	mixer_ctrl_t *cp;
1145 {
1146 	struct auich_softc *sc = v;
1147 	return sc->codec_if->vtbl->mixer_set_port(sc->codec_if, cp);
1148 }
1149 
1150 int
1151 auich_get_port(v, cp)
1152 	void *v;
1153 	mixer_ctrl_t *cp;
1154 {
1155 	struct auich_softc *sc = v;
1156 	return sc->codec_if->vtbl->mixer_get_port(sc->codec_if, cp);
1157 }
1158 
1159 int
1160 auich_query_devinfo(v, dp)
1161 	void *v;
1162 	mixer_devinfo_t *dp;
1163 {
1164 	struct auich_softc *sc = v;
1165 	return sc->codec_if->vtbl->query_devinfo(sc->codec_if, dp);
1166 }
1167 
1168 void *
1169 auich_allocm(v, direction, size, pool, flags)
1170 	void *v;
1171 	int direction;
1172 	size_t size;
1173 	int pool, flags;
1174 {
1175 	struct auich_softc *sc = v;
1176 	struct auich_dma *p;
1177 	int error;
1178 
1179 	/* can only use 1 segment */
1180 	if (size > AUICH_DMASEG_MAX) {
1181 		DPRINTF(AUICH_DEBUG_DMA,
1182 		    ("%s: requested buffer size too large: %d", \
1183 		    sc->sc_dev.dv_xname, size));
1184 		return NULL;
1185 	}
1186 
1187 	p = malloc(sizeof(*p), pool, flags | M_ZERO);
1188 	if (!p)
1189 		return NULL;
1190 
1191 	error = auich_allocmem(sc, size, PAGE_SIZE, p);
1192 	if (error) {
1193 		free(p, pool);
1194 		return NULL;
1195 	}
1196 
1197 	if (direction == AUMODE_PLAY)
1198 		sc->sc_pdma = p;
1199 	else if (direction == AUMODE_RECORD)
1200 		sc->sc_rdma = p;
1201 	else
1202 		sc->sc_cdma = p;
1203 
1204 	return p->addr;
1205 }
1206 
1207 void
1208 auich_freem(void *v, void *ptr, int pool)
1209 {
1210 	struct auich_softc *sc;
1211 	struct auich_dma *p;
1212 
1213 	sc = v;
1214 	if (sc->sc_pdma != NULL && sc->sc_pdma->addr == ptr)
1215 		p = sc->sc_pdma;
1216 	else if (sc->sc_rdma != NULL && sc->sc_rdma->addr == ptr)
1217 		p = sc->sc_rdma;
1218 	else if (sc->sc_cdma != NULL && sc->sc_cdma->addr == ptr)
1219 		p = sc->sc_cdma;
1220 	else
1221 		return;
1222 
1223 	auich_freemem(sc, p);
1224 	free(p, pool);
1225 }
1226 
1227 size_t
1228 auich_round_buffersize(v, direction, size)
1229 	void *v;
1230 	int direction;
1231 	size_t size;
1232 {
1233 	if (size > AUICH_DMALIST_MAX * AUICH_DMASEG_MAX)
1234 		size = AUICH_DMALIST_MAX * AUICH_DMASEG_MAX;
1235 
1236 	return size;
1237 }
1238 
1239 paddr_t
1240 auich_mappage(v, mem, off, prot)
1241 	void *v;
1242 	void *mem;
1243 	off_t off;
1244 	int prot;
1245 {
1246 	struct auich_softc *sc = v;
1247 	struct auich_dma *p;
1248 
1249 	if (off < 0)
1250 		return -1;
1251 
1252 	p = NULL;
1253 	if (sc->sc_pdma != NULL && sc->sc_pdma->addr == mem)
1254 		p = sc->sc_pdma;
1255 	else if (sc->sc_rdma != NULL && sc->sc_rdma->addr == mem)
1256 		p = sc->sc_rdma;
1257 	else
1258 		return -1;
1259 
1260 	return bus_dmamem_mmap(sc->dmat, p->segs, p->nsegs,
1261 	    off, prot, BUS_DMA_WAITOK);
1262 }
1263 
1264 int
1265 auich_get_props(v)
1266 	void *v;
1267 {
1268 	return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX;
1269 }
1270 
1271 int
1272 auich_intr(v)
1273 	void *v;
1274 {
1275 	struct auich_softc *sc = v;
1276 	int ret = 0, sts, gsts;
1277 
1278 	gsts = bus_space_read_4(sc->iot, sc->aud_ioh, AUICH_GSTS);
1279 	DPRINTF(AUICH_DEBUG_INTR, ("auich_intr: gsts=%b\n", gsts, AUICH_GSTS_BITS));
1280 
1281 	if (gsts & AUICH_POINT) {
1282 		sts = bus_space_read_2(sc->iot, sc->aud_ioh,
1283 		    AUICH_PCMO + sc->sc_sts_reg);
1284 		DPRINTF(AUICH_DEBUG_INTR,
1285 		    ("auich_intr: osts=%b\n", sts, AUICH_ISTS_BITS));
1286 
1287 #ifdef AUICH_DEBUG
1288 		if (sts & AUICH_FIFOE) {
1289 			printf("%s: fifo underrun # %u\n",
1290 			    sc->sc_dev.dv_xname, ++sc->pcmo_fifoe);
1291 		}
1292 #endif
1293 
1294 		if (sts & AUICH_BCIS)
1295 			auich_intr_pipe(sc, AUICH_PCMO, &sc->pcmo);
1296 
1297 		/* int ack */
1298 		bus_space_write_2(sc->iot, sc->aud_ioh,
1299 		    AUICH_PCMO + sc->sc_sts_reg, sts &
1300 		    (AUICH_BCIS | AUICH_FIFOE));
1301 		bus_space_write_4(sc->iot, sc->aud_ioh, AUICH_GSTS, AUICH_POINT);
1302 		ret++;
1303 	}
1304 
1305 	if (gsts & AUICH_PIINT) {
1306 		sts = bus_space_read_2(sc->iot, sc->aud_ioh,
1307 		    AUICH_PCMI + sc->sc_sts_reg);
1308 		DPRINTF(AUICH_DEBUG_INTR,
1309 		    ("auich_intr: ists=%b\n", sts, AUICH_ISTS_BITS));
1310 
1311 #ifdef AUICH_DEBUG
1312 		if (sts & AUICH_FIFOE) {
1313 			printf("%s: in fifo overrun # %u\n",
1314 			    sc->sc_dev.dv_xname, ++sc->pcmi_fifoe);
1315 		}
1316 #endif
1317 
1318 		if (sts & AUICH_BCIS)
1319 			auich_intr_pipe(sc, AUICH_PCMI, &sc->pcmi);
1320 
1321 		/* int ack */
1322 		bus_space_write_2(sc->iot, sc->aud_ioh,
1323 		    AUICH_PCMI + sc->sc_sts_reg, sts &
1324 		    (AUICH_BCIS | AUICH_FIFOE));
1325 		bus_space_write_4(sc->iot, sc->aud_ioh, AUICH_GSTS, AUICH_PIINT);
1326 		ret++;
1327 	}
1328 
1329 	if (gsts & AUICH_MINT) {
1330 		sts = bus_space_read_2(sc->iot, sc->aud_ioh,
1331 		    AUICH_MICI + sc->sc_sts_reg);
1332 		DPRINTF(AUICH_DEBUG_INTR,
1333 		    ("auich_intr: ists=%b\n", sts, AUICH_ISTS_BITS));
1334 #ifdef AUICH_DEBUG
1335 		if (sts & AUICH_FIFOE)
1336 			printf("%s: mic fifo overrun\n", sc->sc_dev.dv_xname);
1337 #endif
1338 
1339 		if (sts & AUICH_BCIS)
1340 			auich_intr_pipe(sc, AUICH_MICI, &sc->mici);
1341 
1342 		/* int ack */
1343 		bus_space_write_2(sc->iot, sc->aud_ioh,
1344 		    AUICH_MICI + sc->sc_sts_reg,
1345 		    sts + (AUICH_BCIS | AUICH_FIFOE));
1346 
1347 		bus_space_write_4(sc->iot, sc->aud_ioh, AUICH_GSTS, AUICH_MINT);
1348 		ret++;
1349 	}
1350 
1351 	return ret;
1352 }
1353 
1354 
1355 void
1356 auich_trigger_pipe(struct auich_softc *sc, int pipe, struct auich_ring *ring)
1357 {
1358 	int blksize, qptr;
1359 	struct auich_dmalist *q;
1360 
1361 	blksize = ring->blksize;
1362 
1363 	for (qptr = 0; qptr < AUICH_DMALIST_MAX; qptr++) {
1364 		q = &ring->dmalist[qptr];
1365 		q->base = ring->p;
1366 		q->len = (blksize / sc->sc_sample_size) | AUICH_DMAF_IOC;
1367 
1368 		ring->p += blksize;
1369 		if (ring->p >= ring->end)
1370 			ring->p = ring->start;
1371 	}
1372 	ring->qptr = 0;
1373 
1374 	bus_space_write_1(sc->iot, sc->aud_ioh, pipe + AUICH_LVI,
1375 	    (qptr - 1) & AUICH_LVI_MASK);
1376 	bus_space_write_1(sc->iot, sc->aud_ioh, pipe + AUICH_CTRL,
1377 	    AUICH_IOCE | AUICH_FEIE | AUICH_RPBM);
1378 }
1379 
1380 void
1381 auich_intr_pipe(struct auich_softc *sc, int pipe, struct auich_ring *ring)
1382 {
1383 	int blksize, qptr, nqptr;
1384 	struct auich_dmalist *q;
1385 
1386 	blksize = ring->blksize;
1387 	qptr = ring->qptr;
1388 	nqptr = bus_space_read_1(sc->iot, sc->aud_ioh, pipe + AUICH_CIV);
1389 
1390 	while (qptr != nqptr) {
1391 		q = &ring->dmalist[qptr];
1392 		q->base = ring->p;
1393 		q->len = (blksize / sc->sc_sample_size) | AUICH_DMAF_IOC;
1394 
1395 		DPRINTF(AUICH_DEBUG_INTR,
1396 		    ("auich_intr: %p, %p = %x @ 0x%x\n",
1397 		    &ring->dmalist[qptr], q, q->len, q->base));
1398 
1399 		ring->p += blksize;
1400 		if (ring->p >= ring->end)
1401 			ring->p = ring->start;
1402 
1403 		qptr = (qptr + 1) & AUICH_LVI_MASK;
1404 		if (ring->intr)
1405 			ring->intr(ring->arg);
1406 	}
1407 	ring->qptr = qptr;
1408 
1409 	bus_space_write_1(sc->iot, sc->aud_ioh, pipe + AUICH_LVI,
1410 	    (qptr - 1) & AUICH_LVI_MASK);
1411 }
1412 
1413 
1414 int
1415 auich_trigger_output(v, start, end, blksize, intr, arg, param)
1416 	void *v;
1417 	void *start, *end;
1418 	int blksize;
1419 	void (*intr)(void *);
1420 	void *arg;
1421 	struct audio_params *param;
1422 {
1423 	struct auich_softc *sc = v;
1424 	struct auich_dma *p;
1425 	size_t size;
1426 
1427 	DPRINTF(AUICH_DEBUG_DMA,
1428 	    ("auich_trigger_output(%x, %x, %d, %p, %p, %p)\n",
1429 	    start, end, blksize, intr, arg, param));
1430 
1431 	if (sc->sc_pdma->addr == start)
1432 		p = sc->sc_pdma;
1433 	else
1434 		return -1;
1435 
1436 	size = (size_t)((caddr_t)end - (caddr_t)start);
1437 
1438 	sc->pcmo.intr = intr;
1439 	sc->pcmo.arg = arg;
1440 
1441 	/*
1442 	 * The logic behind this is:
1443 	 * setup one buffer to play, then LVI dump out the rest
1444 	 * to the scatter-gather chain.
1445 	 */
1446 	sc->pcmo.start = p->segs->ds_addr;
1447 	sc->pcmo.p = sc->pcmo.start;
1448 	sc->pcmo.end = sc->pcmo.start + size;
1449 	sc->pcmo.blksize = blksize;
1450 
1451 	bus_space_write_4(sc->iot, sc->aud_ioh, AUICH_PCMO + AUICH_BDBAR,
1452 	    sc->sc_cddma + AUICH_PCMO_OFF(0));
1453 	auich_trigger_pipe(sc, AUICH_PCMO, &sc->pcmo);
1454 
1455 	return 0;
1456 }
1457 
1458 int
1459 auich_trigger_input(v, start, end, blksize, intr, arg, param)
1460 	void *v;
1461 	void *start, *end;
1462 	int blksize;
1463 	void (*intr)(void *);
1464 	void *arg;
1465 	struct audio_params *param;
1466 {
1467 	struct auich_softc *sc = v;
1468 	struct auich_dma *p;
1469 	size_t size;
1470 
1471 	DPRINTF(AUICH_DEBUG_DMA,
1472 	    ("auich_trigger_input(%x, %x, %d, %p, %p, %p)\n",
1473 	    start, end, blksize, intr, arg, param));
1474 
1475 	if (sc->sc_rdma->addr == start)
1476 		p = sc->sc_rdma;
1477 	else
1478 		return -1;
1479 
1480 	size = (size_t)((caddr_t)end - (caddr_t)start);
1481 
1482 	sc->pcmi.intr = intr;
1483 	sc->pcmi.arg = arg;
1484 
1485 	/*
1486 	 * The logic behind this is:
1487 	 * setup one buffer to play, then LVI dump out the rest
1488 	 * to the scatter-gather chain.
1489 	 */
1490 	sc->pcmi.start = p->segs->ds_addr;
1491 	sc->pcmi.p = sc->pcmi.start;
1492 	sc->pcmi.end = sc->pcmi.start + size;
1493 	sc->pcmi.blksize = blksize;
1494 
1495 	bus_space_write_4(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_BDBAR,
1496 	    sc->sc_cddma + AUICH_PCMI_OFF(0));
1497 	auich_trigger_pipe(sc, AUICH_PCMI, &sc->pcmi);
1498 
1499 	return 0;
1500 }
1501 
1502 
1503 int
1504 auich_allocmem(struct auich_softc *sc, size_t size, size_t align,
1505     struct auich_dma *p)
1506 {
1507 	int error;
1508 
1509 	p->size = size;
1510 	error = bus_dmamem_alloc(sc->dmat, p->size, align, 0, p->segs, 1,
1511 	    &p->nsegs, BUS_DMA_NOWAIT);
1512 	if (error) {
1513 		DPRINTF(AUICH_DEBUG_DMA,
1514 		    ("%s: bus_dmamem_alloc failed: error %d\n",
1515 		    sc->sc_dev.dv_xname, error));
1516 		return error;
1517 	}
1518 
1519 	error = bus_dmamem_map(sc->dmat, p->segs, 1, p->size, &p->addr,
1520 	    BUS_DMA_NOWAIT | sc->sc_dmamap_flags);
1521 	if (error) {
1522 		DPRINTF(AUICH_DEBUG_DMA,
1523 		    ("%s: bus_dmamem_map failed: error %d\n",
1524 		    sc->sc_dev.dv_xname, error));
1525 		goto free;
1526 	}
1527 
1528 	error = bus_dmamap_create(sc->dmat, p->size, 1, p->size, 0,
1529 	    BUS_DMA_NOWAIT, &p->map);
1530 	if (error) {
1531 		DPRINTF(AUICH_DEBUG_DMA,
1532 		    ("%s: bus_dmamap_create failed: error %d\n",
1533 		    sc->sc_dev.dv_xname, error));
1534 		goto unmap;
1535 	}
1536 
1537 	error = bus_dmamap_load(sc->dmat, p->map, p->addr, p->size, NULL,
1538 	    BUS_DMA_NOWAIT);
1539 	if (error) {
1540 		DPRINTF(AUICH_DEBUG_DMA,
1541 		    ("%s: bus_dmamap_load failed: error %d\n",
1542 		    sc->sc_dev.dv_xname, error));
1543 		goto destroy;
1544 	}
1545 	return 0;
1546 
1547  destroy:
1548 	bus_dmamap_destroy(sc->dmat, p->map);
1549  unmap:
1550 	bus_dmamem_unmap(sc->dmat, p->addr, p->size);
1551  free:
1552 	bus_dmamem_free(sc->dmat, p->segs, p->nsegs);
1553 	return error;
1554 }
1555 
1556 
1557 int
1558 auich_freemem(struct auich_softc *sc, struct auich_dma *p)
1559 {
1560 	bus_dmamap_unload(sc->dmat, p->map);
1561 	bus_dmamap_destroy(sc->dmat, p->map);
1562 	bus_dmamem_unmap(sc->dmat, p->addr, p->size);
1563 	bus_dmamem_free(sc->dmat, p->segs, p->nsegs);
1564 	return 0;
1565 }
1566 
1567 
1568 
1569 int
1570 auich_alloc_cdata(struct auich_softc *sc)
1571 {
1572 	bus_dma_segment_t seg;
1573 	int error, rseg;
1574 
1575 	/*
1576 	 * Allocate the control data structure, and create and load the
1577 	 * DMA map for it.
1578 	 */
1579 	if ((error = bus_dmamem_alloc(sc->dmat, sizeof(struct auich_cdata),
1580 	    PAGE_SIZE, 0, &seg, 1, &rseg, 0)) != 0) {
1581 		printf("%s: unable to allocate control data, error = %d\n",
1582 		    sc->sc_dev.dv_xname, error);
1583 		goto fail_0;
1584 	}
1585 
1586 	if ((error = bus_dmamem_map(sc->dmat, &seg, 1,
1587 	    sizeof(struct auich_cdata), (caddr_t *) &sc->sc_cdata,
1588 	    sc->sc_dmamap_flags)) != 0) {
1589 		printf("%s: unable to map control data, error = %d\n",
1590 		    sc->sc_dev.dv_xname, error);
1591 		goto fail_1;
1592 	}
1593 
1594 	if ((error = bus_dmamap_create(sc->dmat, sizeof(struct auich_cdata), 1,
1595 	    sizeof(struct auich_cdata), 0, 0, &sc->sc_cddmamap)) != 0) {
1596 		printf("%s: unable to create control data DMA map, "
1597 		    "error = %d\n", sc->sc_dev.dv_xname, error);
1598 		goto fail_2;
1599 	}
1600 
1601 	if ((error = bus_dmamap_load(sc->dmat, sc->sc_cddmamap, sc->sc_cdata,
1602 	    sizeof(struct auich_cdata), NULL, 0)) != 0) {
1603 		printf("%s: unable tp load control data DMA map, "
1604 		    "error = %d\n", sc->sc_dev.dv_xname, error);
1605 		goto fail_3;
1606 	}
1607 
1608 	sc->pcmo.dmalist = sc->sc_cdata->ic_dmalist_pcmo;
1609 	sc->pcmi.dmalist = sc->sc_cdata->ic_dmalist_pcmi;
1610 	sc->mici.dmalist = sc->sc_cdata->ic_dmalist_mici;
1611 
1612 	return 0;
1613 
1614  fail_3:
1615 	bus_dmamap_destroy(sc->dmat, sc->sc_cddmamap);
1616  fail_2:
1617 	bus_dmamem_unmap(sc->dmat, (caddr_t) sc->sc_cdata,
1618 	    sizeof(struct auich_cdata));
1619  fail_1:
1620 	bus_dmamem_free(sc->dmat, &seg, rseg);
1621  fail_0:
1622 	return error;
1623 }
1624 
1625 
1626 void
1627 auich_powerhook(why, self)
1628 	int why;
1629 	void *self;
1630 {
1631 	struct auich_softc *sc = (struct auich_softc *)self;
1632 
1633 	if (why != PWR_RESUME) {
1634 		/* Power down */
1635 		DPRINTF(1, ("auich: power down\n"));
1636 		sc->suspend = why;
1637 		auich_read_codec(sc, AC97_REG_EXT_AUDIO_CTRL, &sc->ext_ctrl);
1638 
1639 	} else {
1640 		/* Wake up */
1641 		DPRINTF(1, ("auich: power resume\n"));
1642 		if (sc->suspend == PWR_RESUME) {
1643 			printf("%s: resume without suspend?\n",
1644 			    sc->sc_dev.dv_xname);
1645 			sc->suspend = why;
1646 			return;
1647 		}
1648 		sc->suspend = why;
1649 		auich_reset_codec(sc);
1650 		DELAY(1000);
1651 		(sc->codec_if->vtbl->restore_ports)(sc->codec_if);
1652 		auich_write_codec(sc, AC97_REG_EXT_AUDIO_CTRL, sc->ext_ctrl);
1653 	}
1654 }
1655 
1656 
1657 /* -------------------------------------------------------------------- */
1658 /* Calibrate card (some boards are overclocked and need scaling) */
1659 
1660 unsigned int
1661 auich_calibrate(struct auich_softc *sc)
1662 {
1663 	struct timeval t1, t2;
1664 	u_int8_t ociv, nciv;
1665 	u_int32_t wait_us, actual_48k_rate, bytes, ac97rate;
1666 	void *temp_buffer;
1667 	struct auich_dma *p;
1668 
1669 	ac97rate = AUICH_FIXED_RATE;
1670 	/*
1671 	 * Grab audio from input for fixed interval and compare how
1672 	 * much we actually get with what we expect.  Interval needs
1673 	 * to be sufficiently short that no interrupts are
1674 	 * generated.
1675 	 */
1676 
1677 	/* Setup a buffer */
1678 	bytes = 16000;
1679 	temp_buffer = auich_allocm(sc, 0, bytes, M_DEVBUF, M_NOWAIT);
1680 	if (temp_buffer == NULL)
1681 		return (ac97rate);
1682 	if (sc->sc_cdma->addr == temp_buffer) {
1683 		p = sc->sc_cdma;
1684 	} else {
1685 		printf("auich_calibrate: bad address %p\n", temp_buffer);
1686 		return (ac97rate);
1687 	}
1688 
1689 	sc->pcmi.dmalist[0].base = p->map->dm_segs[0].ds_addr;
1690 	sc->pcmi.dmalist[0].len = bytes / sc->sc_sample_size;
1691 
1692 
1693 	/*
1694 	 * our data format is stereo, 16 bit so each sample is 4 bytes.
1695 	 * assuming we get 48000 samples per second, we get 192000 bytes/sec.
1696 	 * we're going to start recording with interrupts disabled and measure
1697 	 * the time taken for one block to complete.  we know the block size,
1698 	 * we know the time in microseconds, we calculate the sample rate:
1699 	 *
1700 	 * actual_rate [bps] = bytes / (time [s] * 4)
1701 	 * actual_rate [bps] = (bytes * 1000000) / (time [us] * 4)
1702 	 * actual_rate [Hz] = (bytes * 250000) / time [us]
1703 	 */
1704 
1705 	/* prepare */
1706 	ociv = bus_space_read_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_CIV);
1707 	nciv = ociv;
1708 	bus_space_write_4(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_BDBAR,
1709 	    sc->sc_cddma + AUICH_PCMI_OFF(0));
1710 	bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_LVI,
1711 			  (0 - 1) & AUICH_LVI_MASK);
1712 
1713 	/* start */
1714 	microuptime(&t1);
1715 	bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_CTRL,
1716 	    AUICH_RPBM);
1717 
1718 	/* wait */
1719 	while (nciv == ociv) {
1720 		microuptime(&t2);
1721 		if (t2.tv_sec - t1.tv_sec > 1)
1722 			break;
1723 		nciv = bus_space_read_1(sc->iot, sc->aud_ioh,
1724 					AUICH_PCMI + AUICH_CIV);
1725 	}
1726 	microuptime(&t2);
1727 
1728 	/* reset */
1729 	bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_PCMI + AUICH_CTRL, AUICH_RR);
1730 	bus_space_write_1(sc->iot, sc->aud_ioh, AUICH_MICI + AUICH_CTRL, AUICH_RR);
1731 	DELAY(100);
1732 
1733 	/* turn time delta into us */
1734 	wait_us = ((t2.tv_sec - t1.tv_sec) * 1000000) + t2.tv_usec - t1.tv_usec;
1735 
1736 	auich_freem(sc, temp_buffer, M_DEVBUF);
1737 
1738 	if (nciv == ociv) {
1739 		printf("%s: ac97 link rate calibration timed out after %d us\n",
1740 		       sc->sc_dev.dv_xname, wait_us);
1741 		return (ac97rate);
1742 	}
1743 
1744 	actual_48k_rate = (bytes * 250000) / wait_us;
1745 
1746 	if (actual_48k_rate <= 48500)
1747 		ac97rate = AUICH_FIXED_RATE;
1748 	else
1749 		ac97rate = actual_48k_rate;
1750 
1751 	printf("%s: measured ac97 link rate at %d Hz",
1752 	       sc->sc_dev.dv_xname, actual_48k_rate);
1753 	if (ac97rate != actual_48k_rate)
1754 		printf(", will use %d Hz", ac97rate);
1755 	printf("\n");
1756 
1757 	return (ac97rate);
1758 }
1759