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