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