xref: /netbsd-src/sys/dev/ic/arcofi.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*	$NetBSD: arcofi.c,v 1.1 2014/08/24 08:17:44 tsutsui Exp $	*/
2 /*	$OpenBSD: arcofi.c,v 1.6 2013/05/15 08:29:24 ratchov Exp $	*/
3 
4 /*
5  * Copyright (c) 2011 Miodrag Vallat.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /*
21  * Driver for the HP ``Audio1'' device, which is a FIFO layer around a
22  * Siemens PSB 2160 ``ARCOFI'' phone quality audio chip.
23  *
24  * It is known to exist in two flavours: on-board the HP9000/425e as a DIO
25  * device, an on-board the HP9000/{705,710,745,747} as a GIO device.
26  *
27  * The FIFO logic buffers up to 128 bytes. When using 8 bit samples and
28  * the logic set to interrupt every half FIFO, the device will interrupt
29  * 125 times per second.
30  */
31 
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/conf.h>
35 #include <sys/device.h>
36 #include <sys/kernel.h>
37 #include <sys/proc.h>
38 #include <sys/mutex.h>
39 #include <sys/condvar.h>
40 #include <sys/bus.h>
41 #include <sys/intr.h>
42 
43 #include <sys/audioio.h>
44 
45 #include <dev/audio_if.h>
46 #include <dev/auconv.h>
47 #include <dev/mulaw.h>
48 
49 #include <dev/ic/arcofivar.h>
50 
51 #include "ioconf.h"
52 
53 #if 0
54 #define	ARCOFI_DEBUG
55 #endif
56 
57 /*
58  * Siemens PSB2160 registers
59  */
60 
61 /* CMDR */
62 #define	CMDR_AD		0x80	/* SP1/PS2 address convention */
63 #define	CMDR_READ	0x40
64 #define	CMDR_WRITE	0x00
65 #define	CMDR_PU		0x20	/* Power Up */
66 #define	CMDR_RCS	0x10	/* Receive and transmit in CH B2 */
67 #define	CMDR_MASK	0x0f
68 
69 	/* command	     length	data */
70 #define	SOP_0	0x00	/*	5	CR4 CR3 CR2 CR1 */
71 #define	COP_1	0x01	/*	5	t1_hi t1_lo f1_hi f1_lo */
72 #define	COP_2	0x02	/*	3	gr1 gr2 */
73 #define	COP_3	0x03	/*	3	t2_hi t2_lo f2_hi f2_lo */
74 #define	SOP_4	0x04	/*	2	CR1 */
75 #define	SOP_5	0x05	/*	2	CR2 */
76 #define	SOP_6	0x06	/*	2	CR3 */
77 #define	SOP_7	0x07	/*	2	CR4 */
78 #define	COP_8	0x08	/*	3	dtmf_hi dtmf_lo */
79 #define	COP_9	0x09	/*	5	gz a3 a2 a1 */
80 #define	COP_A	0x0a	/*	9	fx1 to fx8 */
81 #define	COP_B	0x0b	/*	3	gx1 gx2 */
82 #define	COP_C	0x0c	/*	9	fr1 to fr 8 */
83 #define	COP_D	0x0d	/*	5	fr9 fr10 fx9 fx10 */
84 #define	COP_E	0x0e	/*	5	t3_hi t3_lo f3_hi f3_lo */
85 
86 /* CR1 */
87 #define	CR1_GR		0x80	/* GR gain loaded from CRAM vs 0dB */
88 #define	CR1_GZ		0x40	/* Z gain loaded from CRAM vs -18dB */
89 #define	CR1_FX		0x20	/* X filter loaded from CRAM vs 0dB flat */
90 #define	CR1_FR		0x10	/* R filter loaded from CRAM vs 0dB flat */
91 #define	CR1_GX		0x08	/* GX gain loaded from CRAM vs 0dB */
92 #define	CR1_T_MASK	0x07	/* test mode */
93 #define	CR1_DLP		0x07	/* digital loopback via PCM registers */
94 #define	CR1_DLM		0x06	/* D/A output looped back to A/D input */
95 #define	CR1_DLS		0x05	/* digital loopback via converter registers */
96 #define	CR1_IDR		0x04	/* data RAM initialization */
97 #define	CR1_BYP		0x03	/* bypass analog frontend */
98 #define	CR1_ALM		0x02	/* analog loopback via MUX */
99 #define	CR1_ALS		0x01	/* analog loopback via converter registers */
100 
101 /* CR2 */
102 #define	CR2_SD		0x80	/* SD pin set to input vs output */
103 #define	CR2_SC		0x40	/* SC pin set to input vs output */
104 #define	CR2_SB		0x20	/* SB pin set to input vs output */
105 #define	CR2_SA		0x10	/* SA pin set to input vs output */
106 #define	CR2_ELS		0x08	/* non-input S pins tristate SIP vs sending 0 */
107 #define	CR2_AM		0x04	/* only one device on the SLD bus */
108 #define	CR2_TR		0x02	/* three party conferencing */
109 #define	CR2_EFC		0x01	/* enable feature control */
110 
111 /* CR3 */
112 #define	CR3_MIC_G_MASK	0xe0		/* MIC input analog gain  */
113 #define	CR3_MIC_X_INPUT		0xe0	/* MIC disabled, X input 15.1 dB */
114 #define	CR3_MIC_G_17		0xc0	/* 17 dB */
115 #define	CR3_MIC_G_22		0xa0	/* 22 dB */
116 #define	CR3_MIC_G_28		0x80	/* 28 dB */
117 #define	CR3_MIC_G_34		0x60	/* 34 dB */
118 #define	CR3_MIC_G_40		0x40	/* 40 dB */
119 #define	CR3_MIC_G_46		0x20	/* 46 dB */
120 #define	CR3_MIC_G_52		0x00	/* 52 dB (reset default) */
121 #define	CR3_AFEC_MASK	0x1c
122 #define	CR3_AFEC_MUTE		0x18	/* mute: Hout */
123 #define	CR3_AFEC_HFS		0x14	/* hands free: FHM, LS out */
124 #define	CR3_AFEC_LH3		0x10	/* loud hearing 3: MIC, H out, LS out */
125 #define	CR3_AFEC_LH2		0x0c	/* loud hearing 2: MIC, LS out */
126 #define	CR3_AFEC_LH1		0x08	/* loud hearing 1: LS out */
127 #define	CR3_AFEC_RDY		0x04	/* ready: MIC, H out */
128 #define	CR3_AFEC_POR		0x00	/* power on reset: all off */
129 #define	CR3_OPMODE_MASK	0x03
130 #define	CR3_OPMODE_LINEAR	0x02	/* linear (16 bit) */
131 #define	CR3_OPMODE_MIXED	0x01	/* mixed */
132 #define	CR3_OPMODE_NORMAL	0x00	/* normal (A/u-Law) */
133 
134 /* CR4 */
135 #define	CR4_DHF		0x80	/* TX digital high frequency enable */
136 #define	CR4_DTMF	0x40	/* DTMF generator enable */
137 #define	CR4_TG		0x20	/* tone ring enable */
138 #define	CR4_BT		0x10	/* beat tone generator enable */
139 #define	CR4_TM		0x08	/* incoming voice enable */
140 #define	CR4_BM		0x04	/* beat mode (3 tone vs 2 tone) */
141 #define	CR4_PM		0x02	/* tone sent to piezo vs loudspeaker */
142 #define	CR4_ULAW	0x01	/* u-Law vs A-Law */
143 
144 
145 /*
146  * Glue logic registers
147  * Note the register values here are symbolic, as actual addresses
148  * depend upon the particular bus the device is connected to.
149  */
150 
151 #define	ARCOFI_ID		0	/* id (r) and reset (w) register */
152 
153 #define	ARCOFI_CSR		1	/* status and control register */
154 #define	CSR_INTR_ENABLE			0x80
155 #define	CSR_INTR_REQUEST		0x40	/* unacknowledged interrupt */
156 /* 0x20 and 0x10 used in DIO flavours, to provide IPL */
157 #define	CSR_WIDTH_16			0x08	/* 16-bit samples */
158 #define	CSR_CTRL_FIFO_ENABLE		0x04	/* connect FIFO to CMDR */
159 #define	CSR_DATA_FIFO_ENABLE		0x01	/* connect FIFO to DU/DD */
160 
161 #define	ARCOFI_FIFO_IR		2	/* FIFO interrupt register */
162 #define	FIFO_IR_ENABLE(ev)		((ev) << 4)
163 #define	FIFO_IR_EVENT(ev)		(ev)
164 #define	FIFO_IR_OUT_EMPTY		0x08
165 #define	FIFO_IR_CTRL_EMPTY		0x04
166 #define	FIFO_IR_OUT_HALF_EMPTY		0x02
167 #define	FIFO_IR_IN_HALF_EMPTY		0x01
168 
169 #define	ARCOFI_FIFO_SR		3	/* FIFO status register (ro) */
170 #define	FIFO_SR_CTRL_FULL		0x20
171 #define	FIFO_SR_CTRL_EMPTY		0x10
172 #define	FIFO_SR_OUT_FULL		0x08
173 #define	FIFO_SR_OUT_EMPTY		0x04
174 #define	FIFO_SR_IN_FULL			0x02
175 #define	FIFO_SR_IN_EMPTY		0x01
176 
177 #define	ARCOFI_FIFO_DATA	4	/* data FIFO port */
178 
179 #define	ARCOFI_FIFO_CTRL	5	/* control FIFO port (wo) */
180 
181 #define	ARCOFI_FIFO_SIZE	128
182 
183 #ifdef hp300	/* XXX */
184 #define	arcofi_read(sc, r) \
185 	bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (r))
186 #define	arcofi_write(sc, r, v) \
187 	bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (r), (v))
188 #else
189 #define	arcofi_read(sc, r) \
190 	bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (sc)->sc_reg[(r)])
191 #define	arcofi_write(sc, r, v) \
192 	bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (sc)->sc_reg[(r)], (v))
193 #endif
194 
195 static int	arcofi_cmd(struct arcofi_softc *, uint8_t, const uint8_t *);
196 static int	arcofi_cr3_to_portmask(uint, int);
197 static int	arcofi_gain_to_mi(uint);
198 static uint	arcofi_mi_to_gain(int);
199 static uint	arcofi_portmask_to_cr3(int);
200 
201 static int	arcofi_open(void *, int);
202 static void	arcofi_close(void *);
203 static int	arcofi_drain(void *);
204 static int	arcofi_query_encoding(void *, struct audio_encoding *);
205 static int	arcofi_set_params(void *, int, int,
206 		    struct audio_params *, struct audio_params *,
207 		    stream_filter_list_t *, stream_filter_list_t *);
208 static int	arcofi_round_blocksize(void *, int, int,
209 		    const audio_params_t *);
210 static int	arcofi_commit_settings(void *);
211 static int	arcofi_start_output(void *, void *, int, void (*)(void *),
212 		    void *);
213 static int	arcofi_start_input(void *, void *, int, void (*)(void *),
214 		    void *);
215 static int	arcofi_halt_output(void *);
216 static int	arcofi_halt_input(void *);
217 static int	arcofi_getdev(void *, struct audio_device *);
218 static int	arcofi_set_port(void *, mixer_ctrl_t *);
219 static int	arcofi_get_port(void *, mixer_ctrl_t *);
220 static int	arcofi_query_devinfo(void *, mixer_devinfo_t *);
221 static int	arcofi_get_props(void *);
222 static void	arcofi_get_locks(void *, kmutex_t **, kmutex_t **);
223 
224 static const struct audio_hw_if arcofi_hw_if = {
225 	.open		  = arcofi_open,
226 	.close		  = arcofi_close,
227 	.drain		  = arcofi_drain,
228 	.query_encoding	  = arcofi_query_encoding,
229 	.set_params	  = arcofi_set_params,
230 	.round_blocksize  = arcofi_round_blocksize,
231 	.commit_settings  = arcofi_commit_settings,
232 	.start_output	  = arcofi_start_output,
233 	.start_input	  = arcofi_start_input,
234 	.halt_output	  = arcofi_halt_output,
235 	.halt_input	  = arcofi_halt_input,
236 	.speaker_ctl	  = NULL,
237 	.getdev		  = arcofi_getdev,
238 	.setfd		  = NULL,
239 	.set_port	  = arcofi_set_port,
240 	.get_port	  = arcofi_get_port,
241 	.query_devinfo	  = arcofi_query_devinfo,
242 	.allocm		  = NULL,
243 	.freem		  = NULL,
244 	.round_buffersize = NULL,
245 	.mappage	  = NULL,
246 	.get_props	  = arcofi_get_props,
247 	.trigger_output	  = NULL,
248 	.trigger_input	  = NULL,
249 	.dev_ioctl	  = NULL,
250 	.get_locks	  = arcofi_get_locks,
251 };
252 
253 static const struct audio_format arcofi_formats[] = {
254 	/*
255 	 * 8-bit encodings:
256 	 *  - u-Law and A-Law are native
257 	 *  - linear are converted to 16-bit by auconv
258 	 */
259 	{NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULAW, 8, 8,
260 	 1, AUFMT_MONAURAL, 1, {8000}},
261 	{NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ALAW, 8, 8,
262 	 1, AUFMT_MONAURAL, 1, {8000}},
263 	/*
264 	 * 16-bit encodings:
265 	 *  - slinear big-endian is native
266 	 *  - unsigned or little-endian are converted by auconv
267 	 */
268 	{NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_BE, 16, 16,
269 	 1, AUFMT_MONAURAL, 1, {8000}},
270 };
271 #define ARCOFI_NFORMATS  __arraycount(arcofi_formats)
272 
273 /* mixer items */
274 #define	ARCOFI_PORT_AUDIO_IN_VOLUME	0	/* line in volume (GR) */
275 #define	ARCOFI_PORT_AUDIO_OUT_VOLUME	1	/* line out volume (GX) */
276 #define	ARCOFI_PORT_AUDIO_SPKR_VOLUME	2	/* speaker volume (GX) */
277 #define	ARCOFI_PORT_AUDIO_IN_MUTE	3	/* line in mute (MIC) */
278 #define	ARCOFI_PORT_AUDIO_OUT_MUTE	4	/* line out mute (H out) */
279 #define	ARCOFI_PORT_AUDIO_SPKR_MUTE	5	/* line in mute (LS out) */
280 /* mixer classes */
281 #define	ARCOFI_CLASS_INPUT		6
282 #define	ARCOFI_CLASS_OUTPUT		7
283 
284 /*
285  * Gain programming formulae are a complete mystery to me, and of course
286  * no two chips are compatible - not even the PSB 2163 and PSB 2165
287  * later ARCOFI chips, from the same manufacturer as the PSB 2160!
288  *
289  * Of course, the PSB 2160 datasheet does not give any set of values.
290  * The following table is taken from the HP-UX audio driver (audio_shared.o
291  * private_audio_gain_tab).
292  */
293 
294 #define	NEGATIVE_GAINS	60
295 #define	POSITIVE_GAINS	14
296 static const uint16_t arcofi_gains[1 + NEGATIVE_GAINS + 1 + POSITIVE_GAINS] = {
297 	/* minus infinity */
298 	0x0988,
299 
300 	0xf8b8, 0xf8b8, 0xf8b8, 0xf8b8, 0x099f, 0x099f, 0x099f, 0x099f,
301 	0x09af, 0x09af, 0x09af, 0x09cf, 0x09cf, 0x09cf, 0xf8a9, 0xf83a,
302 	0xf83a, 0xf82b, 0xf82d, 0xf8a3, 0xf8b2, 0xf8a1, 0xe8aa, 0xe84b,
303 	0xe89e, 0xe8d3, 0xe891, 0xe8b1, 0xd8aa, 0xd8cb, 0xd8a6, 0xd8b3,
304 	0xd842, 0xd8b1, 0xc8aa, 0xc8bb, 0xc888, 0xc853, 0xc852, 0xc8b1,
305 	0xb8aa, 0xb8ab, 0xb896, 0xb892, 0xb842, 0xb8b1, 0xa8aa, 0xa8bb,
306 	0x199f, 0x195b, 0x29c1, 0x2923, 0x29aa, 0x392b, 0xf998, 0xb988,
307 	0x1aac, 0x3aa1, 0xbaa1, 0xbb88,
308 
309 	/* 0 */
310 	0x8888,
311 
312 	0xd388, 0x5288, 0xb1a1, 0x31a1, 0x1192, 0x11d0, 0x30c0, 0x2050,
313 	0x1021, 0x1020, 0x1000, 0x0001, 0x0010, 0x0000
314 };
315 
316 static int
317 arcofi_open(void *v, int flags)
318 {
319 	struct arcofi_softc *sc = (struct arcofi_softc *)v;
320 
321 	if (sc->sc_open)
322 		return EBUSY;
323 	sc->sc_open = 1;
324 	KASSERT(sc->sc_mode == 0);
325 
326 	return 0;
327 }
328 
329 static void
330 arcofi_close(void *v)
331 {
332 	struct arcofi_softc *sc = (struct arcofi_softc *)v;
333 
334 	arcofi_halt_input(v);
335 	arcofi_halt_output(v);
336 	sc->sc_open = 0;
337 }
338 
339 static int
340 arcofi_drain(void *v)
341 {
342 	struct arcofi_softc *sc = (struct arcofi_softc *)v;
343 
344 #ifdef ARCOFI_DEBUG
345 	printf("%s: %s, mode %d\n",
346 	    device_xname(sc->sc_dev), __func__, sc->sc_mode);
347 #endif
348 	if ((arcofi_read(sc, ARCOFI_FIFO_SR) & FIFO_SR_OUT_EMPTY) == 0) {
349 		/* enable output FIFO empty interrupt... */
350 		arcofi_write(sc, ARCOFI_FIFO_IR,
351 		    arcofi_read(sc, ARCOFI_FIFO_IR) |
352 		    FIFO_IR_ENABLE(FIFO_IR_OUT_EMPTY));
353 		/* ...and wait for it to fire */
354 		if (cv_timedwait(&sc->sc_cv, &sc->sc_intr_lock,
355 		    ((ARCOFI_FIFO_SIZE * hz) / 8000) + 100) != 0) {
356 			printf("%s: drain did not complete\n",
357 			    device_xname(sc->sc_dev));
358 			arcofi_write(sc, ARCOFI_FIFO_IR,
359 			    arcofi_read(sc, ARCOFI_FIFO_IR) &
360 			    ~FIFO_IR_ENABLE(FIFO_IR_OUT_EMPTY));
361 		}
362 	}
363 	return 0;
364 }
365 
366 static int
367 arcofi_query_encoding(void *v, struct audio_encoding *aep)
368 {
369 	struct arcofi_softc *sc = (struct arcofi_softc *)v;
370 
371 	return auconv_query_encoding(sc->sc_encodings, aep);
372 }
373 
374 /*
375  * Compute proper sample and hardware settings.
376  */
377 static int
378 arcofi_set_params(void *handle, int setmode, int usemode,
379     audio_params_t *play, audio_params_t *rec,
380     stream_filter_list_t *pfil, stream_filter_list_t *rfil)
381 {
382 	struct arcofi_softc *sc;
383 	int i;
384 
385 	sc = handle;
386 	for (i = 0; i < 2; i++) {
387 		int mode;
388 		audio_params_t *p;
389 		stream_filter_list_t *fil;
390 		int ind;
391 
392 		switch (i) {
393 		case 0:
394 			mode = AUMODE_PLAY;
395 			p = play;
396 			fil = pfil;
397 			break;
398 		case 1:
399 			mode = AUMODE_RECORD;
400 			p = rec;
401 			fil = rfil;
402 			break;
403 		default:
404 			return EINVAL;
405 		}
406 
407 		if ((setmode & mode) == 0)
408 			continue;
409 
410 #ifdef ARCOFI_DEBUG
411 		printf("%s: %s, mode %d encoding %d precision %d\n",
412 		    device_xname(sc->sc_dev), __func__,
413 		    mode, p->encoding, p->precision);
414 #endif
415 
416 		ind = auconv_set_converter(arcofi_formats, ARCOFI_NFORMATS,
417 		    mode, p, false, fil);
418 		if (ind < 0)
419 			return EINVAL;
420 		if (fil->req_size > 0)
421 			p = &fil->filters[0].param;
422 		if (p->precision == 8) {
423 			if (p->encoding == AUDIO_ENCODING_ALAW)
424 				sc->sc_shadow.cr4 &= ~CR4_ULAW;
425 			else
426 				sc->sc_shadow.cr4 |= CR4_ULAW;
427 			sc->sc_shadow.cr3 =
428 			    (sc->sc_shadow.cr3 & ~CR3_OPMODE_MASK) |
429 			    CR3_OPMODE_NORMAL;
430 		} else {
431 			sc->sc_shadow.cr3 =
432 			    (sc->sc_shadow.cr3 & ~CR3_OPMODE_MASK) |
433 			    CR3_OPMODE_LINEAR;
434 		}
435 	}
436 
437 	return 0;
438 }
439 
440 static int
441 arcofi_round_blocksize(void *handle, int block, int mode,
442     const audio_params_t *param)
443 {
444 
445 	/*
446 	 * Round the size up to a multiple of half the FIFO, to favour
447 	 * smooth interrupt operation.
448 	 */
449 	return roundup(block, ARCOFI_FIFO_SIZE / 2);
450 }
451 
452 static int
453 arcofi_commit_settings(void *v)
454 {
455 	struct arcofi_softc *sc = (struct arcofi_softc *)v;
456 	int rc;
457 	uint8_t cmd[2], csr, ocsr;
458 
459 #ifdef ARCOFI_DEBUG
460 	printf("%s: %s, gr %04x gx %04x cr3 %02x cr4 %02x mute %d\n",
461 	    device_xname(sc->sc_dev), __func__,
462 	    arcofi_gains[sc->sc_shadow.gr_idx],
463 	    arcofi_gains[sc->sc_shadow.gx_idx],
464 	    sc->sc_shadow.cr3, sc->sc_shadow.cr4, sc->sc_shadow.output_mute);
465 #endif
466 
467 	if (memcmp(&sc->sc_active, &sc->sc_shadow, sizeof(sc->sc_active)) == 0)
468 		return 0;
469 
470 	mutex_spin_enter(&sc->sc_intr_lock);
471 
472 	if (sc->sc_active.gr_idx != sc->sc_shadow.gr_idx) {
473 		cmd[0] = arcofi_gains[sc->sc_shadow.gr_idx] >> 8;
474 		cmd[1] = arcofi_gains[sc->sc_shadow.gr_idx];
475 		if ((rc = arcofi_cmd(sc, COP_2, cmd)) != 0)
476 			goto error;
477 		sc->sc_active.gr_idx = sc->sc_shadow.gr_idx;
478 	}
479 
480 	if (sc->sc_active.gx_idx != sc->sc_shadow.gx_idx ||
481 	    sc->sc_active.output_mute != sc->sc_shadow.output_mute) {
482 		if (sc->sc_shadow.output_mute) {
483 			cmd[0] = arcofi_gains[0] >> 8;
484 			cmd[1] = arcofi_gains[0];
485 		} else {
486 			cmd[0] = arcofi_gains[sc->sc_shadow.gx_idx] >> 8;
487 			cmd[1] = arcofi_gains[sc->sc_shadow.gx_idx];
488 		}
489 		if ((rc = arcofi_cmd(sc, COP_B, cmd)) != 0)
490 			goto error;
491 		sc->sc_active.gx_idx = sc->sc_shadow.gx_idx;
492 		sc->sc_active.output_mute = sc->sc_shadow.output_mute;
493 	}
494 
495 	if (sc->sc_active.cr3 != sc->sc_shadow.cr3) {
496 		cmd[0] = sc->sc_shadow.cr3;
497 		if ((rc = arcofi_cmd(sc, SOP_6, cmd)) != 0)
498 			goto error;
499 		sc->sc_active.cr3 = sc->sc_shadow.cr3;
500 
501 		ocsr = arcofi_read(sc, ARCOFI_CSR);
502 		if ((sc->sc_active.cr3 & CR3_OPMODE_MASK) != CR3_OPMODE_NORMAL)
503 			csr = ocsr | CSR_WIDTH_16;
504 		else
505 			csr = ocsr & ~CSR_WIDTH_16;
506 		if (csr != ocsr)
507 			arcofi_write(sc, ARCOFI_CSR, csr);
508 	}
509 
510 	if (sc->sc_active.cr4 != sc->sc_shadow.cr4) {
511 		cmd[0] = sc->sc_shadow.cr4;
512 		if ((rc = arcofi_cmd(sc, SOP_7, cmd)) != 0)
513 			goto error;
514 		sc->sc_active.cr4 = sc->sc_shadow.cr4;
515 	}
516 
517 	rc = 0;
518  error:
519 	mutex_spin_exit(&sc->sc_intr_lock);
520 	return rc;
521 }
522 
523 static int
524 arcofi_start_input(void *v, void *rbuf, int rsz, void (*cb)(void *),
525     void *cbarg)
526 {
527 	struct arcofi_softc *sc = (struct arcofi_softc *)v;
528 
529 #ifdef ARCOFI_DEBUG
530 	printf("%s: %s, mode %d\n",
531 	    device_xname(sc->sc_dev), __func__, sc->sc_mode);
532 #endif
533 
534 	/* enable data FIFO if becoming active */
535 	if (sc->sc_mode == 0)
536 		arcofi_write(sc, ARCOFI_CSR,
537 		    arcofi_read(sc, ARCOFI_CSR) | CSR_DATA_FIFO_ENABLE);
538 	sc->sc_mode |= AUMODE_RECORD;
539 
540 	sc->sc_recv.buf = (uint8_t *)rbuf;
541 	sc->sc_recv.past = (uint8_t *)rbuf + rsz;
542 	sc->sc_recv.cb = cb;
543 	sc->sc_recv.cbarg = cbarg;
544 
545 	/* enable input FIFO interrupts */
546 	arcofi_write(sc, ARCOFI_FIFO_IR, arcofi_read(sc, ARCOFI_FIFO_IR) |
547 	    FIFO_IR_ENABLE(FIFO_IR_IN_HALF_EMPTY));
548 
549 	return 0;
550 }
551 
552 static int
553 arcofi_start_output(void *v, void *wbuf, int wsz, void (*cb)(void *),
554     void *cbarg)
555 {
556 	struct arcofi_softc *sc = (struct arcofi_softc *)v;
557 
558 #ifdef ARCOFI_DEBUG
559 	printf("%s: %s, mode %d\n",
560 	    device_xname(sc->sc_dev), __func__, sc->sc_mode);
561 #endif
562 
563 	/* enable data FIFO if becoming active */
564 	if (sc->sc_mode == 0)
565 		arcofi_write(sc, ARCOFI_CSR,
566 		    arcofi_read(sc, ARCOFI_CSR) | CSR_DATA_FIFO_ENABLE);
567 	sc->sc_mode |= AUMODE_PLAY;
568 
569 	sc->sc_xmit.buf = (uint8_t *)wbuf;
570 	sc->sc_xmit.past = (uint8_t *)wbuf + wsz;
571 	sc->sc_xmit.cb = cb;
572 	sc->sc_xmit.cbarg = cbarg;
573 
574 	/* enable output FIFO interrupts */
575 	arcofi_write(sc, ARCOFI_FIFO_IR, arcofi_read(sc, ARCOFI_FIFO_IR) |
576 	    FIFO_IR_ENABLE(FIFO_IR_OUT_HALF_EMPTY));
577 
578 	return 0;
579 }
580 
581 static int
582 arcofi_halt_input(void *v)
583 {
584 	struct arcofi_softc *sc = (struct arcofi_softc *)v;
585 
586 #ifdef ARCOFI_DEBUG
587 	printf("%s: %s, mode %d\n",
588 	    device_xname(sc->sc_dev), __func__, sc->sc_mode);
589 #endif
590 
591 	/* disable input FIFO interrupts */
592 	arcofi_write(sc, ARCOFI_FIFO_IR, arcofi_read(sc, ARCOFI_FIFO_IR) &
593 	    ~FIFO_IR_ENABLE(FIFO_IR_IN_HALF_EMPTY));
594 	/* disable data FIFO if becoming idle */
595 	sc->sc_mode &= ~AUMODE_RECORD;
596 	if (sc->sc_mode == 0)
597 		arcofi_write(sc, ARCOFI_CSR,
598 		    arcofi_read(sc, ARCOFI_CSR) & ~CSR_DATA_FIFO_ENABLE);
599 
600 	return 0;
601 }
602 
603 static int
604 arcofi_halt_output(void *v)
605 {
606 	struct arcofi_softc *sc = (struct arcofi_softc *)v;
607 
608 #ifdef ARCOFI_DEBUG
609 	printf("%s: %s, mode %d\n",
610 	    device_xname(sc->sc_dev), __func__, sc->sc_mode);
611 #endif
612 
613 	/* disable output FIFO interrupts */
614 	arcofi_write(sc, ARCOFI_FIFO_IR, arcofi_read(sc, ARCOFI_FIFO_IR) &
615 	    ~FIFO_IR_ENABLE(FIFO_IR_OUT_HALF_EMPTY));
616 	/* disable data FIFO if becoming idle */
617 	sc->sc_mode &= ~AUMODE_PLAY;
618 	if (sc->sc_mode == 0)
619 		arcofi_write(sc, ARCOFI_CSR,
620 		    arcofi_read(sc, ARCOFI_CSR) & ~CSR_DATA_FIFO_ENABLE);
621 
622 	return 0;
623 }
624 
625 static int
626 arcofi_getdev(void *v, struct audio_device *ad)
627 {
628 	struct arcofi_softc *sc = (struct arcofi_softc *)v;
629 
630 	*ad = sc->sc_audio_device;
631 	return 0;
632 }
633 
634 /*
635  * Convert gain table index to AUDIO_MIN_GAIN..AUDIO_MAX_GAIN scale.
636  */
637 static int
638 arcofi_gain_to_mi(uint idx)
639 {
640 
641 	if (idx == 0)
642 		return AUDIO_MIN_GAIN;
643 	if (idx == __arraycount(arcofi_gains) - 1)
644 		return AUDIO_MAX_GAIN;
645 
646 	return ((idx - 1) * (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN)) /
647 	    (__arraycount(arcofi_gains) - 1) + AUDIO_MIN_GAIN + 1;
648 }
649 
650 /*
651  * Convert AUDIO_MIN_GAIN..AUDIO_MAX_GAIN scale to gain table index.
652  */
653 static uint
654 arcofi_mi_to_gain(int lvl)
655 {
656 
657 	if (lvl <= AUDIO_MIN_GAIN)
658 		return 0;
659 	if (lvl >= AUDIO_MAX_GAIN)
660 		return __arraycount(arcofi_gains) - 1;
661 
662 	return ((lvl - AUDIO_MIN_GAIN - 1) * (__arraycount(arcofi_gains) - 1)) /
663 	    (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN);
664 }
665 
666 /*
667  * The following routines rely upon this...
668  */
669 #if (AUDIO_SPEAKER == AUDIO_LINE_IN) || (AUDIO_LINE_OUT == AUDIO_LINE_IN) || \
670     (AUDIO_SPEAKER == AUDIO_LINE_OUT)
671 #error Please rework the cr3 handling logic.
672 #endif
673 
674 /*
675  * The mapping between the available inputs and outputs, and CR3, is as
676  * follows:
677  * - the `line in' connector is the `MIC' input.
678  * - the `line out' connector is the `H out' (heaphones) output.
679  * - the internal `speaker' is the `LS out' (loudspeaker) output.
680  *
681  * Each of these can be enabled or disabled indepently, except for
682  * MIC enabled with H out and LS out disabled, which is not allowed
683  * by the chip (and makes no sense for a chip which was intended to
684  * be used in phones, not voice recorders); we cheat by keeping one
685  * output source enabled, but with the output gain forced to minus
686  * infinity to mute it.
687  *
688  * The truth table is thus:
689  *
690  *	MIC	LS out	H out	AFEC
691  *	off	off	off	POR
692  *	off	off	on	MUTE
693  *	off	on	off	LH1
694  *	off	on	on	LH3, X input enabled
695  *	on	off	off	RDY, GX forced to minus infinity
696  *	on	off	on	RDY
697  *	on	on	off	LH2
698  *	on	on	on	LH3
699  */
700 
701 /*
702  * Convert logical port enable settings to a valid CR3 value.
703  */
704 static uint
705 arcofi_portmask_to_cr3(int mask)
706 {
707 
708 	switch (mask) {
709 	default:
710 	case 0:
711 		return CR3_MIC_G_17 | CR3_AFEC_POR;
712 	case AUDIO_LINE_OUT:
713 		return CR3_MIC_G_17 | CR3_AFEC_MUTE;
714 	case AUDIO_SPEAKER:
715 		return CR3_MIC_G_17 | CR3_AFEC_LH1;
716 	case AUDIO_SPEAKER | AUDIO_LINE_OUT:
717 		return CR3_MIC_X_INPUT | CR3_AFEC_LH3;
718 	case AUDIO_LINE_IN:
719 		/* since we can't do this, just... */
720 		/* FALLTHROUGH */
721 	case AUDIO_LINE_IN | AUDIO_LINE_OUT:
722 		return CR3_MIC_G_17 | CR3_AFEC_RDY;
723 	case AUDIO_LINE_IN | AUDIO_SPEAKER:
724 		return CR3_MIC_G_17 | CR3_AFEC_LH2;
725 	case AUDIO_LINE_IN | AUDIO_SPEAKER | AUDIO_LINE_OUT:
726 		return CR3_MIC_G_17 | CR3_AFEC_LH3;
727 	}
728 }
729 
730 /*
731  * Convert CR3 to an enabled ports mask.
732  */
733 static int
734 arcofi_cr3_to_portmask(uint cr3, int output_mute)
735 {
736 
737 	switch (cr3 & CR3_AFEC_MASK) {
738 	default:
739 	case CR3_AFEC_POR:
740 		return 0;
741 	case CR3_AFEC_RDY:
742 		return output_mute ?
743 		    AUDIO_LINE_IN : AUDIO_LINE_IN | AUDIO_LINE_OUT;
744 	case CR3_AFEC_HFS:
745 	case CR3_AFEC_LH1:
746 		return AUDIO_SPEAKER;
747 	case CR3_AFEC_LH2:
748 		return AUDIO_LINE_IN | AUDIO_SPEAKER;
749 	case CR3_AFEC_LH3:
750 		if ((cr3 & CR3_MIC_G_MASK) == CR3_MIC_X_INPUT)
751 			return AUDIO_SPEAKER | AUDIO_LINE_OUT;
752 		else
753 			return AUDIO_LINE_IN | AUDIO_SPEAKER | AUDIO_LINE_OUT;
754 	case CR3_AFEC_MUTE:
755 		return AUDIO_LINE_OUT;
756 	}
757 }
758 
759 static int
760 arcofi_set_port(void *v, mixer_ctrl_t *mc)
761 {
762 	struct arcofi_softc *sc = (struct arcofi_softc *)v;
763 	int portmask = 0;
764 
765 #ifdef ARCOFI_DEBUG
766 	printf("%s: %s, mode %d\n",
767 	    device_xname(sc->sc_dev), __func__, sc->sc_mode);
768 #endif
769 	/* check for proper type */
770 	switch (mc->dev) {
771 	/* volume settings */
772 	case ARCOFI_PORT_AUDIO_IN_VOLUME:
773 	case ARCOFI_PORT_AUDIO_OUT_VOLUME:
774 	case ARCOFI_PORT_AUDIO_SPKR_VOLUME:
775 		if (mc->un.value.num_channels != 1)
776 			return EINVAL;
777 		break;
778 	/* mute settings */
779 	case ARCOFI_PORT_AUDIO_IN_MUTE:
780 	case ARCOFI_PORT_AUDIO_OUT_MUTE:
781 	case ARCOFI_PORT_AUDIO_SPKR_MUTE:
782 		if (mc->type != AUDIO_MIXER_ENUM)
783 			return EINVAL;
784 		portmask = arcofi_cr3_to_portmask(sc->sc_shadow.cr3,
785 		    sc->sc_shadow.output_mute);
786 #ifdef ARCOFI_DEBUG
787 		printf("%s: %s cr3 %02x -> mask %02x\n",
788 		    device_xname(sc->sc_dev), __func__,
789 		    sc->sc_shadow.cr3, portmask);
790 #endif
791 		break;
792 	default:
793 		return EINVAL;
794 	}
795 
796 	switch (mc->dev) {
797 	/* volume settings */
798 	case ARCOFI_PORT_AUDIO_IN_VOLUME:
799 		sc->sc_shadow.gr_idx =
800 		    arcofi_mi_to_gain(mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
801 		return 0;
802 	case ARCOFI_PORT_AUDIO_OUT_VOLUME:
803 	case ARCOFI_PORT_AUDIO_SPKR_VOLUME:
804 		sc->sc_shadow.gx_idx =
805 		    arcofi_mi_to_gain(mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
806 		return 0;
807 
808 	/* mute settings */
809 	case ARCOFI_PORT_AUDIO_IN_MUTE:
810 		if (mc->un.ord)
811 			portmask &= ~AUDIO_LINE_IN;
812 		else
813 			portmask |= AUDIO_LINE_IN;
814 		break;
815 	case ARCOFI_PORT_AUDIO_OUT_MUTE:
816 		if (mc->un.ord)
817 			portmask &= ~AUDIO_LINE_OUT;
818 		else
819 			portmask |= AUDIO_LINE_OUT;
820 		break;
821 	case ARCOFI_PORT_AUDIO_SPKR_MUTE:
822 		if (mc->un.ord)
823 			portmask &= ~AUDIO_SPEAKER;
824 		else
825 			portmask |= AUDIO_SPEAKER;
826 		break;
827 	}
828 
829 	sc->sc_shadow.cr3 = (sc->sc_shadow.cr3 & CR3_OPMODE_MASK) |
830 	    arcofi_portmask_to_cr3(portmask);
831 	sc->sc_shadow.output_mute = (portmask == AUDIO_LINE_IN);
832 #ifdef ARCOFI_DEBUG
833 	printf("%s: %s mask %02x -> cr3 %02x m %d\n",
834 	    device_xname(sc->sc_dev), __func__,
835 	    portmask, sc->sc_shadow.cr3, sc->sc_shadow.output_mute);
836 #endif
837 
838 	return 0;
839 }
840 
841 static int
842 arcofi_get_port(void *v, mixer_ctrl_t *mc)
843 {
844 	struct arcofi_softc *sc = (struct arcofi_softc *)v;
845 	int portmask = 0;
846 
847 #ifdef ARCOFI_DEBUG
848 	printf("%s: %s, mode %d\n",
849 	    device_xname(sc->sc_dev), __func__, sc->sc_mode);
850 #endif
851 	/* check for proper type */
852 	switch (mc->dev) {
853 	/* volume settings */
854 	case ARCOFI_PORT_AUDIO_IN_VOLUME:
855 	case ARCOFI_PORT_AUDIO_OUT_VOLUME:
856 	case ARCOFI_PORT_AUDIO_SPKR_VOLUME:
857 		if (mc->un.value.num_channels != 1)
858 			return EINVAL;
859 		break;
860 
861 	/* mute settings */
862 	case ARCOFI_PORT_AUDIO_IN_MUTE:
863 	case ARCOFI_PORT_AUDIO_OUT_MUTE:
864 	case ARCOFI_PORT_AUDIO_SPKR_MUTE:
865 		if (mc->type != AUDIO_MIXER_ENUM)
866 			return EINVAL;
867 		portmask = arcofi_cr3_to_portmask(sc->sc_shadow.cr3,
868 		    sc->sc_shadow.output_mute);
869 #ifdef ARCOFI_DEBUG
870 		printf("%s: %s cr3 %02x -> mask %02x\n",
871 		    device_xname(sc->sc_dev), __func__,
872 		    sc->sc_shadow.cr3, portmask);
873 #endif
874 		break;
875 	default:
876 		return EINVAL;
877 	}
878 
879 	switch (mc->dev) {
880 	/* volume settings */
881 	case ARCOFI_PORT_AUDIO_IN_VOLUME:
882 		mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
883 		    arcofi_gain_to_mi(sc->sc_shadow.gr_idx);
884 		break;
885 	case ARCOFI_PORT_AUDIO_OUT_VOLUME:
886 	case ARCOFI_PORT_AUDIO_SPKR_VOLUME:
887 		mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
888 		    arcofi_gain_to_mi(sc->sc_shadow.gx_idx);
889 		break;
890 
891 	/* mute settings */
892 	case ARCOFI_PORT_AUDIO_IN_MUTE:
893 		mc->un.ord = portmask & AUDIO_LINE_IN ? 0 : 1;
894 		break;
895 	case ARCOFI_PORT_AUDIO_OUT_MUTE:
896 		mc->un.ord = portmask & AUDIO_LINE_OUT ? 0 : 1;
897 		break;
898 	case ARCOFI_PORT_AUDIO_SPKR_MUTE:
899 		mc->un.ord = portmask & AUDIO_SPEAKER ? 0 : 1;
900 		break;
901 	}
902 
903 	return 0;
904 }
905 
906 static int
907 arcofi_query_devinfo(void *v, mixer_devinfo_t *md)
908 {
909 
910 	switch (md->index) {
911 	default:
912 		return ENXIO;
913 
914 	/* items */
915 	case ARCOFI_PORT_AUDIO_IN_VOLUME:
916 		md->type = AUDIO_MIXER_VALUE;
917 		md->mixer_class = ARCOFI_CLASS_INPUT;
918 		md->prev = AUDIO_MIXER_LAST;
919 		md->next = ARCOFI_PORT_AUDIO_IN_MUTE;
920 		strlcpy(md->label.name, AudioNline,
921 		    sizeof md->label.name);
922 		goto mono_volume;
923 	case ARCOFI_PORT_AUDIO_OUT_VOLUME:
924 		md->type = AUDIO_MIXER_VALUE;
925 		md->mixer_class = ARCOFI_CLASS_OUTPUT;
926 		md->prev = AUDIO_MIXER_LAST;
927 		md->next = ARCOFI_PORT_AUDIO_OUT_MUTE;
928 		strlcpy(md->label.name, AudioNline,
929 		    sizeof md->label.name);
930 		goto mono_volume;
931 	case ARCOFI_PORT_AUDIO_SPKR_VOLUME:
932 		md->type = AUDIO_MIXER_VALUE;
933 		md->mixer_class = ARCOFI_CLASS_OUTPUT;
934 		md->prev = AUDIO_MIXER_LAST;
935 		md->next = ARCOFI_PORT_AUDIO_SPKR_MUTE;
936 		strlcpy(md->label.name, AudioNspeaker,
937 		    sizeof md->label.name);
938 		/* goto mono_volume; */
939  mono_volume:
940 		md->un.v.num_channels = 1;
941 		strlcpy(md->un.v.units.name, AudioNvolume,
942 		    sizeof md->un.v.units.name);
943 		break;
944 
945 	case ARCOFI_PORT_AUDIO_IN_MUTE:
946 		md->type = AUDIO_MIXER_ENUM;
947 		md->mixer_class = ARCOFI_CLASS_INPUT;
948 		md->prev = ARCOFI_PORT_AUDIO_IN_VOLUME;
949 		md->next = AUDIO_MIXER_LAST;
950 		goto mute;
951 	case ARCOFI_PORT_AUDIO_OUT_MUTE:
952 		md->type = AUDIO_MIXER_ENUM;
953 		md->mixer_class = ARCOFI_CLASS_OUTPUT;
954 		md->prev = ARCOFI_PORT_AUDIO_OUT_VOLUME;
955 		md->next = AUDIO_MIXER_LAST;
956 		goto mute;
957 	case ARCOFI_PORT_AUDIO_SPKR_MUTE:
958 		md->type = AUDIO_MIXER_ENUM;
959 		md->mixer_class = ARCOFI_CLASS_OUTPUT;
960 		md->prev = ARCOFI_PORT_AUDIO_SPKR_VOLUME;
961 		md->next = AUDIO_MIXER_LAST;
962 		/* goto mute; */
963  mute:
964 		strlcpy(md->label.name, AudioNmute, sizeof md->label.name);
965 		md->un.e.num_mem = 2;
966 		strlcpy(md->un.e.member[0].label.name, AudioNoff,
967 		    sizeof md->un.e.member[0].label.name);
968 		md->un.e.member[0].ord = 0;
969 		strlcpy(md->un.e.member[1].label.name, AudioNon,
970 		    sizeof md->un.e.member[1].label.name);
971 		md->un.e.member[1].ord = 1;
972 		break;
973 
974 	/* classes */
975 	case ARCOFI_CLASS_INPUT:
976 		md->type = AUDIO_MIXER_CLASS;
977 		md->mixer_class = ARCOFI_CLASS_INPUT;
978 		md->prev = AUDIO_MIXER_LAST;
979 		md->next = AUDIO_MIXER_LAST;
980 		strlcpy(md->label.name, AudioCinputs,
981 		    sizeof md->label.name);
982 		break;
983 	case ARCOFI_CLASS_OUTPUT:
984 		md->type = AUDIO_MIXER_CLASS;
985 		md->mixer_class = ARCOFI_CLASS_OUTPUT;
986 		md->prev = AUDIO_MIXER_LAST;
987 		md->next = AUDIO_MIXER_LAST;
988 		strlcpy(md->label.name, AudioCoutputs,
989 		    sizeof md->label.name);
990 		break;
991 	}
992 
993 	return 0;
994 }
995 
996 static int
997 arcofi_get_props(void *v)
998 {
999 
1000 	return 0;
1001 }
1002 
1003 static void
1004 arcofi_get_locks(void *v, kmutex_t **intr, kmutex_t **thread)
1005 {
1006 	struct arcofi_softc *sc = (struct arcofi_softc *)v;
1007 
1008 	*intr = &sc->sc_intr_lock;
1009 	*thread = &sc->sc_lock;
1010 }
1011 
1012 int
1013 arcofi_hwintr(void *v)
1014 {
1015 	struct arcofi_softc *sc = (struct arcofi_softc *)v;
1016 	uint8_t *cur, *past;
1017 	uint8_t csr, fir, data;
1018 	int rc = 0;
1019 
1020 	csr = arcofi_read(sc, ARCOFI_CSR);
1021 	if ((csr & CSR_INTR_REQUEST) == 0)
1022 		return 0;
1023 
1024 	fir = arcofi_read(sc, ARCOFI_FIFO_IR);
1025 
1026 	/* receive */
1027 	if (fir & FIFO_IR_EVENT(FIFO_IR_IN_HALF_EMPTY)) {
1028 		rc = 1;
1029 		cur = sc->sc_recv.buf;
1030 		past = sc->sc_recv.past;
1031 
1032 		while ((arcofi_read(sc, ARCOFI_FIFO_SR) &
1033 		    FIFO_SR_IN_EMPTY) == 0) {
1034 			data = arcofi_read(sc, ARCOFI_FIFO_DATA);
1035 			if (cur != NULL && cur != past) {
1036 				*cur++ = data;
1037 				if (cur == past) {
1038 					softint_schedule(sc->sc_sih);
1039 					break;
1040 				}
1041 			}
1042 		}
1043 		sc->sc_recv.buf = cur;
1044 
1045 		if (cur == NULL || cur == past) {
1046 			/* underrun, disable further interrupts */
1047 			arcofi_write(sc, ARCOFI_FIFO_IR,
1048 			    arcofi_read(sc, ARCOFI_FIFO_IR) &
1049 			    ~FIFO_IR_ENABLE(FIFO_IR_IN_HALF_EMPTY));
1050 		}
1051 	}
1052 
1053 	/* xmit */
1054 	if (fir & FIFO_IR_EVENT(FIFO_IR_OUT_HALF_EMPTY)) {
1055 		rc = 1;
1056 		cur = sc->sc_xmit.buf;
1057 		past = sc->sc_xmit.past;
1058 		if (cur != NULL) {
1059 			while ((arcofi_read(sc, ARCOFI_FIFO_SR) &
1060 			    FIFO_SR_OUT_FULL) == 0) {
1061 				if (cur != past)
1062 					arcofi_write(sc, ARCOFI_FIFO_DATA,
1063 					    *cur++);
1064 				if (cur == past) {
1065 					softint_schedule(sc->sc_sih);
1066 					break;
1067 				}
1068 			}
1069 		}
1070 		if (cur == NULL || cur == past) {
1071 			/* disable further interrupts */
1072 			arcofi_write(sc, ARCOFI_FIFO_IR,
1073 			    arcofi_read(sc, ARCOFI_FIFO_IR) &
1074 			    ~FIFO_IR_ENABLE(FIFO_IR_OUT_HALF_EMPTY));
1075 		}
1076 		sc->sc_xmit.buf = cur;
1077 	}
1078 
1079 	/* drain */
1080 	if (fir & FIFO_IR_EVENT(FIFO_IR_OUT_EMPTY)) {
1081 		rc = 1;
1082 		arcofi_write(sc, ARCOFI_FIFO_IR,
1083 		    arcofi_read(sc, ARCOFI_FIFO_IR) &
1084 		    ~FIFO_IR_ENABLE(FIFO_IR_OUT_EMPTY));
1085 		mutex_spin_enter(&sc->sc_intr_lock);
1086 		cv_signal(&sc->sc_cv);
1087 		mutex_spin_exit(&sc->sc_intr_lock);
1088 	}
1089 
1090 #ifdef ARCOFI_DEBUG
1091 	if (rc == 0)
1092 		printf("%s: unclaimed interrupt, csr %02x fir %02x fsr %02x\n",
1093 		    device_xname(sc->sc_dev), csr, fir,
1094 		    arcofi_read(sc, ARCOFI_FIFO_SR));
1095 #endif
1096 
1097 	return rc;
1098 }
1099 
1100 void
1101 arcofi_swintr(void *v)
1102 {
1103 	struct arcofi_softc *sc = (struct arcofi_softc *)v;
1104 	int action;
1105 
1106 	action = 0;
1107 	mutex_spin_enter(&sc->sc_intr_lock);
1108 	if (sc->sc_recv.buf != NULL && sc->sc_recv.buf == sc->sc_recv.past)
1109 		action |= AUMODE_RECORD;
1110 	if (sc->sc_xmit.buf != NULL && sc->sc_xmit.buf == sc->sc_xmit.past)
1111 		action |= AUMODE_PLAY;
1112 
1113 	if (action & AUMODE_RECORD) {
1114 		if (sc->sc_recv.cb)
1115 			sc->sc_recv.cb(sc->sc_recv.cbarg);
1116 	}
1117 	if (action & AUMODE_PLAY) {
1118 		if (sc->sc_xmit.cb)
1119 			sc->sc_xmit.cb(sc->sc_xmit.cbarg);
1120 	}
1121 	mutex_spin_exit(&sc->sc_intr_lock);
1122 }
1123 
1124 static int
1125 arcofi_cmd(struct arcofi_softc *sc, uint8_t cmd, const uint8_t *data)
1126 {
1127 	size_t len;
1128 	uint8_t csr;
1129 	int cnt;
1130 	static const uint8_t cmdlen[] = {
1131 	    [SOP_0] = 4,
1132 	    [COP_1] = 4,
1133 	    [COP_2] = 2,
1134 	    [COP_3] = 2,
1135 	    [SOP_4] = 1,
1136 	    [SOP_5] = 1,
1137 	    [SOP_6] = 1,
1138 	    [SOP_7] = 1,
1139 	    [COP_8] = 2,
1140 	    [COP_9] = 4,
1141 	    [COP_A] = 8,
1142 	    [COP_B] = 2,
1143 	    [COP_C] = 8,
1144 	    [COP_D] = 4,
1145 	    [COP_E] = 4
1146 	};
1147 
1148 	/*
1149 	 * Compute command length.
1150 	 */
1151 	if (cmd >= __arraycount(cmdlen))
1152 		return EINVAL;
1153 	len = cmdlen[cmd];
1154 
1155 	KASSERT(cold || mutex_owned(&sc->sc_intr_lock));
1156 
1157 	/*
1158 	 * Disable all FIFO processing.
1159 	 */
1160 	csr = arcofi_read(sc, ARCOFI_CSR);
1161 	arcofi_write(sc, ARCOFI_CSR,
1162 	    csr & ~(CSR_DATA_FIFO_ENABLE | CSR_CTRL_FIFO_ENABLE));
1163 
1164 	/*
1165 	 * Fill the FIFO with the command bytes.
1166 	 */
1167 	arcofi_write(sc, ARCOFI_FIFO_CTRL, CMDR_PU | CMDR_WRITE | cmd);
1168 	for (; len != 0; len--)
1169 		arcofi_write(sc, ARCOFI_FIFO_CTRL, *data++);
1170 
1171 	/*
1172 	 * Enable command processing.
1173 	 */
1174 	arcofi_write(sc, ARCOFI_CSR,
1175 	    (csr & ~CSR_DATA_FIFO_ENABLE) | CSR_CTRL_FIFO_ENABLE);
1176 
1177 	/*
1178 	 * Wait for the command FIFO to be empty.
1179 	 */
1180 	cnt = 100;
1181 	while ((arcofi_read(sc, ARCOFI_FIFO_SR) & FIFO_SR_CTRL_EMPTY) == 0) {
1182 		if (cnt-- == 0) {
1183 			return EBUSY;
1184 		}
1185 		delay(10);
1186 	}
1187 
1188 	arcofi_write(sc, ARCOFI_CSR, csr);
1189 
1190 	return 0;
1191 }
1192 
1193 void
1194 arcofi_attach(struct arcofi_softc *sc, const char *versionstr)
1195 {
1196 	device_t self;
1197 	int rc;
1198 	uint8_t op, cmd[4];
1199 
1200 	self = sc->sc_dev;
1201 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
1202 	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO);
1203 	cv_init(&sc->sc_cv, device_xname(self));
1204 	rc = auconv_create_encodings(arcofi_formats, ARCOFI_NFORMATS,
1205 	    &sc->sc_encodings);
1206 	if (rc != 0)
1207 		goto out;
1208 
1209 	/*
1210 	 * Reset logic.
1211 	 */
1212 	arcofi_write(sc, ARCOFI_ID, 0);
1213 	delay(100000);
1214 	arcofi_write(sc, ARCOFI_CSR, 0);
1215 
1216 	/*
1217 	 * Initialize the chip to default settings (8 bit, u-Law).
1218 	 */
1219 	sc->sc_active.cr3 =
1220 	    arcofi_portmask_to_cr3(AUDIO_SPEAKER) | CR3_OPMODE_NORMAL;
1221 	sc->sc_active.cr4 = CR4_TM | CR4_ULAW;
1222 	sc->sc_active.gr_idx = sc->sc_active.gx_idx = 1 + NEGATIVE_GAINS;
1223 	sc->sc_active.output_mute = 0;
1224 	memcpy(&sc->sc_shadow, &sc->sc_active, sizeof(sc->sc_active));
1225 
1226 	/* clear CRAM */
1227 	op = SOP_4;
1228 	cmd[0] = CR1_IDR;
1229 	if ((rc = arcofi_cmd(sc, op, cmd)) != 0)
1230 		goto error;
1231 	delay(1000);
1232 
1233 	/* set gain values before enabling them in CR1 */
1234 	op = COP_2;
1235 	cmd[0] = arcofi_gains[sc->sc_active.gr_idx] >> 8;
1236 	cmd[1] = arcofi_gains[sc->sc_active.gr_idx];
1237 	if ((rc = arcofi_cmd(sc, op, cmd)) != 0)
1238 		goto error;
1239 	/* same value for gx... */
1240 	op = COP_B;
1241 	if ((rc = arcofi_cmd(sc, op, cmd)) != 0)
1242 		goto error;
1243 
1244 	/* set all CR registers at once */
1245 	op = SOP_0;
1246 	cmd[0] = sc->sc_active.cr4;
1247 	cmd[1] = sc->sc_active.cr3;
1248 	cmd[2] = CR2_SD | CR2_SC | CR2_SB | CR2_SA | CR2_ELS | CR2_AM | CR2_EFC;
1249 	cmd[3] = CR1_GR | CR1_GX;
1250 	if ((rc = arcofi_cmd(sc, op, cmd)) != 0)
1251 		goto error;
1252 
1253 	arcofi_write(sc, ARCOFI_FIFO_IR, 0);
1254 	arcofi_write(sc, ARCOFI_CSR, CSR_INTR_ENABLE);
1255 
1256 	strlcpy(sc->sc_audio_device.name, arcofi_cd.cd_name,
1257 	    sizeof(sc->sc_audio_device.name));
1258 	strlcpy(sc->sc_audio_device.version, versionstr,
1259 	    sizeof(sc->sc_audio_device.version));
1260 	strlcpy(sc->sc_audio_device.config, device_xname(self),
1261 	    sizeof(sc->sc_audio_device.config));
1262 
1263 	audio_attach_mi(&arcofi_hw_if, sc, self);
1264 	return;
1265 
1266  error:
1267 	arcofi_write(sc, ARCOFI_ID, 0);
1268 	aprint_error("%s: %02x command failed, error %d\n",
1269 	    __func__, op, rc);
1270  out:
1271 	cv_destroy(&sc->sc_cv);
1272 	mutex_destroy(&sc->sc_intr_lock);
1273 	mutex_destroy(&sc->sc_lock);
1274 }
1275