1 /* $NetBSD: arcofi.c,v 1.4 2022/05/31 08:43:15 andvar 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/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 static int arcofi_recv_data(struct arcofi_softc *); 199 static int arcofi_xmit_data(struct arcofi_softc *); 200 201 static int arcofi_open(void *, int); 202 static int arcofi_query_format(void *, audio_format_query_t *); 203 static int arcofi_set_format(void *, int, 204 const audio_params_t *, const audio_params_t *, 205 audio_filter_reg_t *, audio_filter_reg_t *); 206 static int arcofi_round_blocksize(void *, int, int, 207 const audio_params_t *); 208 static int arcofi_commit_settings(void *); 209 static int arcofi_start_output(void *, void *, int, void (*)(void *), 210 void *); 211 static int arcofi_start_input(void *, void *, int, void (*)(void *), 212 void *); 213 static int arcofi_halt_output(void *); 214 static int arcofi_halt_input(void *); 215 static int arcofi_getdev(void *, struct audio_device *); 216 static int arcofi_set_port(void *, mixer_ctrl_t *); 217 static int arcofi_get_port(void *, mixer_ctrl_t *); 218 static int arcofi_query_devinfo(void *, mixer_devinfo_t *); 219 static int arcofi_get_props(void *); 220 static void arcofi_get_locks(void *, kmutex_t **, kmutex_t **); 221 222 static const struct audio_hw_if arcofi_hw_if = { 223 .open = arcofi_open, 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 .set_port = arcofi_set_port, 235 .get_port = arcofi_get_port, 236 .query_devinfo = arcofi_query_devinfo, 237 .allocm = NULL, 238 .freem = NULL, 239 .round_buffersize = NULL, 240 .get_props = arcofi_get_props, 241 .trigger_output = NULL, 242 .trigger_input = NULL, 243 .dev_ioctl = NULL, 244 .get_locks = arcofi_get_locks, 245 }; 246 247 #define ARCOFI_FORMAT(prio, enc, prec) \ 248 { \ 249 .mode = AUMODE_PLAY | AUMODE_RECORD, \ 250 .priority = (prio), \ 251 .encoding = (enc), \ 252 .validbits = (prec), \ 253 .precision = (prec), \ 254 .channels = 1, \ 255 .channel_mask = AUFMT_MONAURAL, \ 256 .frequency_type = 1, \ 257 .frequency = { 8000 }, \ 258 } 259 static const struct audio_format arcofi_formats[] = { 260 /* 261 * 8-bit u-Law and A-Law are native. 262 */ 263 ARCOFI_FORMAT(1, AUDIO_ENCODING_ULAW, 8), 264 ARCOFI_FORMAT(0, AUDIO_ENCODING_ALAW, 8), 265 /* 266 * 16-bit slinear big-endian is native. 267 * But it's hard to use due to hardware restrictions. 268 */ 269 ARCOFI_FORMAT(0, AUDIO_ENCODING_SLINEAR_BE, 16), 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 __diagused = (struct arcofi_softc *)v; 320 321 KASSERT(sc->sc_mode == 0); 322 323 return 0; 324 } 325 326 static int 327 arcofi_query_format(void *v, audio_format_query_t *afp) 328 { 329 330 return audio_query_format(arcofi_formats, ARCOFI_NFORMATS, afp); 331 } 332 333 static int 334 arcofi_set_format(void *handle, int setmode, 335 const audio_params_t *play, const audio_params_t *rec, 336 audio_filter_reg_t *pfil, audio_filter_reg_t *rfil) 337 { 338 struct arcofi_softc *sc; 339 340 sc = handle; 341 342 if ((setmode & AUMODE_PLAY)) { 343 switch (play->encoding) { 344 case AUDIO_ENCODING_ULAW: 345 pfil->codec = audio_internal_to_mulaw; 346 break; 347 case AUDIO_ENCODING_ALAW: 348 pfil->codec = audio_internal_to_alaw; 349 break; 350 } 351 } 352 if ((setmode & AUMODE_RECORD)) { 353 switch (rec->encoding) { 354 case AUDIO_ENCODING_ULAW: 355 rfil->codec = audio_mulaw_to_internal; 356 break; 357 case AUDIO_ENCODING_ALAW: 358 rfil->codec = audio_alaw_to_internal; 359 break; 360 } 361 } 362 363 /* *play and *rec are identical because !AUDIO_PROP_INDEPENDENT */ 364 365 if (play->precision == 8) { 366 if (play->encoding == AUDIO_ENCODING_ULAW) 367 sc->sc_shadow.cr4 |= CR4_ULAW; 368 else 369 sc->sc_shadow.cr4 &= ~CR4_ULAW; 370 sc->sc_shadow.cr3 = 371 (sc->sc_shadow.cr3 & ~CR3_OPMODE_MASK) | 372 CR3_OPMODE_NORMAL; 373 } else { 374 sc->sc_shadow.cr3 = 375 (sc->sc_shadow.cr3 & ~CR3_OPMODE_MASK) | 376 CR3_OPMODE_LINEAR; 377 } 378 379 return 0; 380 } 381 382 static int 383 arcofi_round_blocksize(void *handle, int block, int mode, 384 const audio_params_t *param) 385 { 386 387 /* 388 * Round the size up to a multiple of half the FIFO, to favour 389 * smooth interrupt operation. 390 */ 391 return roundup(block, ARCOFI_FIFO_SIZE / 2); 392 } 393 394 static int 395 arcofi_commit_settings(void *v) 396 { 397 struct arcofi_softc *sc = (struct arcofi_softc *)v; 398 int rc; 399 uint8_t cmd[2], csr, ocsr; 400 401 #ifdef ARCOFI_DEBUG 402 printf("%s: %s, gr %04x gx %04x cr3 %02x cr4 %02x mute %d\n", 403 device_xname(sc->sc_dev), __func__, 404 arcofi_gains[sc->sc_shadow.gr_idx], 405 arcofi_gains[sc->sc_shadow.gx_idx], 406 sc->sc_shadow.cr3, sc->sc_shadow.cr4, sc->sc_shadow.output_mute); 407 #endif 408 409 if (memcmp(&sc->sc_active, &sc->sc_shadow, sizeof(sc->sc_active)) == 0) 410 return 0; 411 412 mutex_spin_enter(&sc->sc_intr_lock); 413 414 if (sc->sc_active.gr_idx != sc->sc_shadow.gr_idx) { 415 cmd[0] = arcofi_gains[sc->sc_shadow.gr_idx] >> 8; 416 cmd[1] = arcofi_gains[sc->sc_shadow.gr_idx]; 417 if ((rc = arcofi_cmd(sc, COP_2, cmd)) != 0) 418 goto error; 419 sc->sc_active.gr_idx = sc->sc_shadow.gr_idx; 420 } 421 422 if (sc->sc_active.gx_idx != sc->sc_shadow.gx_idx || 423 sc->sc_active.output_mute != sc->sc_shadow.output_mute) { 424 if (sc->sc_shadow.output_mute) { 425 cmd[0] = arcofi_gains[0] >> 8; 426 cmd[1] = arcofi_gains[0]; 427 } else { 428 cmd[0] = arcofi_gains[sc->sc_shadow.gx_idx] >> 8; 429 cmd[1] = arcofi_gains[sc->sc_shadow.gx_idx]; 430 } 431 if ((rc = arcofi_cmd(sc, COP_B, cmd)) != 0) 432 goto error; 433 sc->sc_active.gx_idx = sc->sc_shadow.gx_idx; 434 sc->sc_active.output_mute = sc->sc_shadow.output_mute; 435 } 436 437 if (sc->sc_active.cr3 != sc->sc_shadow.cr3) { 438 cmd[0] = sc->sc_shadow.cr3; 439 if ((rc = arcofi_cmd(sc, SOP_6, cmd)) != 0) 440 goto error; 441 sc->sc_active.cr3 = sc->sc_shadow.cr3; 442 443 ocsr = arcofi_read(sc, ARCOFI_CSR); 444 if ((sc->sc_active.cr3 & CR3_OPMODE_MASK) != CR3_OPMODE_NORMAL) 445 csr = ocsr | CSR_WIDTH_16; 446 else 447 csr = ocsr & ~CSR_WIDTH_16; 448 if (csr != ocsr) 449 arcofi_write(sc, ARCOFI_CSR, csr); 450 } 451 452 if (sc->sc_active.cr4 != sc->sc_shadow.cr4) { 453 cmd[0] = sc->sc_shadow.cr4; 454 if ((rc = arcofi_cmd(sc, SOP_7, cmd)) != 0) 455 goto error; 456 sc->sc_active.cr4 = sc->sc_shadow.cr4; 457 } 458 459 rc = 0; 460 error: 461 mutex_spin_exit(&sc->sc_intr_lock); 462 return rc; 463 } 464 465 /* 466 * Take it out of the queue as much as possible. 467 */ 468 static int 469 arcofi_recv_data(struct arcofi_softc *sc) 470 { 471 uint8_t *cur; 472 uint8_t *past; 473 474 cur = sc->sc_recv.buf; 475 past = sc->sc_recv.past; 476 477 while (cur != past && 478 (arcofi_read(sc, ARCOFI_FIFO_SR) & FIFO_SR_IN_EMPTY) == 0) { 479 *cur++ = arcofi_read(sc, ARCOFI_FIFO_DATA); 480 } 481 sc->sc_recv.buf = cur; 482 483 return past - cur; 484 } 485 486 /* 487 * Fill the queue as much as possible. 488 */ 489 static int 490 arcofi_xmit_data(struct arcofi_softc *sc) 491 { 492 uint8_t *cur; 493 uint8_t *past; 494 495 cur = sc->sc_xmit.buf; 496 past = sc->sc_xmit.past; 497 498 while (cur != past && 499 (arcofi_read(sc, ARCOFI_FIFO_SR) & FIFO_SR_OUT_FULL) == 0) { 500 arcofi_write(sc, ARCOFI_FIFO_DATA, *cur++); 501 } 502 sc->sc_xmit.buf = cur; 503 504 return past - cur; 505 } 506 507 static int 508 arcofi_start_input(void *v, void *rbuf, int rsz, void (*cb)(void *), 509 void *cbarg) 510 { 511 struct arcofi_softc *sc = (struct arcofi_softc *)v; 512 513 #ifdef ARCOFI_DEBUG 514 printf("%s: %s, mode %d\n", 515 device_xname(sc->sc_dev), __func__, sc->sc_mode); 516 #endif 517 518 /* enable data FIFO if becoming active */ 519 if (sc->sc_mode == 0) 520 arcofi_write(sc, ARCOFI_CSR, 521 arcofi_read(sc, ARCOFI_CSR) | CSR_DATA_FIFO_ENABLE); 522 sc->sc_mode |= AUMODE_RECORD; 523 524 sc->sc_recv.buf = (uint8_t *)rbuf; 525 sc->sc_recv.past = (uint8_t *)rbuf + rsz; 526 sc->sc_recv.cb = cb; 527 sc->sc_recv.cbarg = cbarg; 528 529 /* enable input FIFO interrupts */ 530 arcofi_write(sc, ARCOFI_FIFO_IR, arcofi_read(sc, ARCOFI_FIFO_IR) | 531 FIFO_IR_ENABLE(FIFO_IR_IN_HALF_EMPTY)); 532 533 return 0; 534 } 535 536 static int 537 arcofi_start_output(void *v, void *wbuf, int wsz, void (*cb)(void *), 538 void *cbarg) 539 { 540 struct arcofi_softc *sc = (struct arcofi_softc *)v; 541 542 #ifdef ARCOFI_DEBUG 543 printf("%s: %s, mode %d\n", 544 device_xname(sc->sc_dev), __func__, sc->sc_mode); 545 #endif 546 547 /* enable data FIFO if becoming active */ 548 if (sc->sc_mode == 0) 549 arcofi_write(sc, ARCOFI_CSR, 550 arcofi_read(sc, ARCOFI_CSR) | CSR_DATA_FIFO_ENABLE); 551 sc->sc_mode |= AUMODE_PLAY; 552 553 sc->sc_xmit.buf = (uint8_t *)wbuf; 554 sc->sc_xmit.past = (uint8_t *)wbuf + wsz; 555 sc->sc_xmit.cb = cb; 556 sc->sc_xmit.cbarg = cbarg; 557 558 /* Fill FIFO */ 559 arcofi_xmit_data(sc); 560 561 /* enable output FIFO interrupts */ 562 arcofi_write(sc, ARCOFI_FIFO_IR, arcofi_read(sc, ARCOFI_FIFO_IR) | 563 FIFO_IR_ENABLE(FIFO_IR_OUT_HALF_EMPTY)); 564 565 return 0; 566 } 567 568 static int 569 arcofi_halt_input(void *v) 570 { 571 struct arcofi_softc *sc = (struct arcofi_softc *)v; 572 573 #ifdef ARCOFI_DEBUG 574 printf("%s: %s, mode %d\n", 575 device_xname(sc->sc_dev), __func__, sc->sc_mode); 576 #endif 577 578 /* disable input FIFO interrupts */ 579 arcofi_write(sc, ARCOFI_FIFO_IR, arcofi_read(sc, ARCOFI_FIFO_IR) & 580 ~FIFO_IR_ENABLE(FIFO_IR_IN_HALF_EMPTY)); 581 /* disable data FIFO if becoming idle */ 582 sc->sc_mode &= ~AUMODE_RECORD; 583 if (sc->sc_mode == 0) 584 arcofi_write(sc, ARCOFI_CSR, 585 arcofi_read(sc, ARCOFI_CSR) & ~CSR_DATA_FIFO_ENABLE); 586 587 return 0; 588 } 589 590 static int 591 arcofi_halt_output(void *v) 592 { 593 struct arcofi_softc *sc = (struct arcofi_softc *)v; 594 595 #ifdef ARCOFI_DEBUG 596 printf("%s: %s, mode %d\n", 597 device_xname(sc->sc_dev), __func__, sc->sc_mode); 598 #endif 599 600 /* disable output FIFO interrupts */ 601 arcofi_write(sc, ARCOFI_FIFO_IR, arcofi_read(sc, ARCOFI_FIFO_IR) & 602 ~FIFO_IR_ENABLE(FIFO_IR_OUT_HALF_EMPTY)); 603 /* disable data FIFO if becoming idle */ 604 sc->sc_mode &= ~AUMODE_PLAY; 605 if (sc->sc_mode == 0) 606 arcofi_write(sc, ARCOFI_CSR, 607 arcofi_read(sc, ARCOFI_CSR) & ~CSR_DATA_FIFO_ENABLE); 608 609 return 0; 610 } 611 612 static int 613 arcofi_getdev(void *v, struct audio_device *ad) 614 { 615 struct arcofi_softc *sc = (struct arcofi_softc *)v; 616 617 *ad = sc->sc_audio_device; 618 return 0; 619 } 620 621 /* 622 * Convert gain table index to AUDIO_MIN_GAIN..AUDIO_MAX_GAIN scale. 623 */ 624 static int 625 arcofi_gain_to_mi(uint idx) 626 { 627 628 if (idx == 0) 629 return AUDIO_MIN_GAIN; 630 if (idx == __arraycount(arcofi_gains) - 1) 631 return AUDIO_MAX_GAIN; 632 633 return ((idx - 1) * (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN)) / 634 (__arraycount(arcofi_gains) - 1) + AUDIO_MIN_GAIN + 1; 635 } 636 637 /* 638 * Convert AUDIO_MIN_GAIN..AUDIO_MAX_GAIN scale to gain table index. 639 */ 640 static uint 641 arcofi_mi_to_gain(int lvl) 642 { 643 644 if (lvl <= AUDIO_MIN_GAIN) 645 return 0; 646 if (lvl >= AUDIO_MAX_GAIN) 647 return __arraycount(arcofi_gains) - 1; 648 649 return ((lvl - AUDIO_MIN_GAIN - 1) * (__arraycount(arcofi_gains) - 1)) / 650 (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN); 651 } 652 653 /* 654 * The following routines rely upon this... 655 */ 656 #if (AUDIO_SPEAKER == AUDIO_LINE_IN) || (AUDIO_LINE_OUT == AUDIO_LINE_IN) || \ 657 (AUDIO_SPEAKER == AUDIO_LINE_OUT) 658 #error Please rework the cr3 handling logic. 659 #endif 660 661 /* 662 * The mapping between the available inputs and outputs, and CR3, is as 663 * follows: 664 * - the `line in' connector is the `MIC' input. 665 * - the `line out' connector is the `H out' (heaphones) output. 666 * - the internal `speaker' is the `LS out' (loudspeaker) output. 667 * 668 * Each of these can be enabled or disabled independently, except for 669 * MIC enabled with H out and LS out disabled, which is not allowed 670 * by the chip (and makes no sense for a chip which was intended to 671 * be used in phones, not voice recorders); we cheat by keeping one 672 * output source enabled, but with the output gain forced to minus 673 * infinity to mute it. 674 * 675 * The truth table is thus: 676 * 677 * MIC LS out H out AFEC 678 * off off off POR 679 * off off on MUTE 680 * off on off LH1 681 * off on on LH3, X input enabled 682 * on off off RDY, GX forced to minus infinity 683 * on off on RDY 684 * on on off LH2 685 * on on on LH3 686 */ 687 688 /* 689 * Convert logical port enable settings to a valid CR3 value. 690 */ 691 static uint 692 arcofi_portmask_to_cr3(int mask) 693 { 694 695 switch (mask) { 696 default: 697 case 0: 698 return CR3_MIC_G_17 | CR3_AFEC_POR; 699 case AUDIO_LINE_OUT: 700 return CR3_MIC_G_17 | CR3_AFEC_MUTE; 701 case AUDIO_SPEAKER: 702 return CR3_MIC_G_17 | CR3_AFEC_LH1; 703 case AUDIO_SPEAKER | AUDIO_LINE_OUT: 704 return CR3_MIC_X_INPUT | CR3_AFEC_LH3; 705 case AUDIO_LINE_IN: 706 /* since we can't do this, just... */ 707 /* FALLTHROUGH */ 708 case AUDIO_LINE_IN | AUDIO_LINE_OUT: 709 return CR3_MIC_G_17 | CR3_AFEC_RDY; 710 case AUDIO_LINE_IN | AUDIO_SPEAKER: 711 return CR3_MIC_G_17 | CR3_AFEC_LH2; 712 case AUDIO_LINE_IN | AUDIO_SPEAKER | AUDIO_LINE_OUT: 713 return CR3_MIC_G_17 | CR3_AFEC_LH3; 714 } 715 } 716 717 /* 718 * Convert CR3 to an enabled ports mask. 719 */ 720 static int 721 arcofi_cr3_to_portmask(uint cr3, int output_mute) 722 { 723 724 switch (cr3 & CR3_AFEC_MASK) { 725 default: 726 case CR3_AFEC_POR: 727 return 0; 728 case CR3_AFEC_RDY: 729 return output_mute ? 730 AUDIO_LINE_IN : AUDIO_LINE_IN | AUDIO_LINE_OUT; 731 case CR3_AFEC_HFS: 732 case CR3_AFEC_LH1: 733 return AUDIO_SPEAKER; 734 case CR3_AFEC_LH2: 735 return AUDIO_LINE_IN | AUDIO_SPEAKER; 736 case CR3_AFEC_LH3: 737 if ((cr3 & CR3_MIC_G_MASK) == CR3_MIC_X_INPUT) 738 return AUDIO_SPEAKER | AUDIO_LINE_OUT; 739 else 740 return AUDIO_LINE_IN | AUDIO_SPEAKER | AUDIO_LINE_OUT; 741 case CR3_AFEC_MUTE: 742 return AUDIO_LINE_OUT; 743 } 744 } 745 746 static int 747 arcofi_set_port(void *v, mixer_ctrl_t *mc) 748 { 749 struct arcofi_softc *sc = (struct arcofi_softc *)v; 750 int portmask = 0; 751 752 #ifdef ARCOFI_DEBUG 753 printf("%s: %s, mode %d\n", 754 device_xname(sc->sc_dev), __func__, sc->sc_mode); 755 #endif 756 /* check for proper type */ 757 switch (mc->dev) { 758 /* volume settings */ 759 case ARCOFI_PORT_AUDIO_IN_VOLUME: 760 case ARCOFI_PORT_AUDIO_OUT_VOLUME: 761 case ARCOFI_PORT_AUDIO_SPKR_VOLUME: 762 if (mc->un.value.num_channels != 1) 763 return EINVAL; 764 break; 765 /* mute settings */ 766 case ARCOFI_PORT_AUDIO_IN_MUTE: 767 case ARCOFI_PORT_AUDIO_OUT_MUTE: 768 case ARCOFI_PORT_AUDIO_SPKR_MUTE: 769 if (mc->type != AUDIO_MIXER_ENUM) 770 return EINVAL; 771 portmask = arcofi_cr3_to_portmask(sc->sc_shadow.cr3, 772 sc->sc_shadow.output_mute); 773 #ifdef ARCOFI_DEBUG 774 printf("%s: %s cr3 %02x -> mask %02x\n", 775 device_xname(sc->sc_dev), __func__, 776 sc->sc_shadow.cr3, portmask); 777 #endif 778 break; 779 default: 780 return EINVAL; 781 } 782 783 switch (mc->dev) { 784 /* volume settings */ 785 case ARCOFI_PORT_AUDIO_IN_VOLUME: 786 sc->sc_shadow.gr_idx = 787 arcofi_mi_to_gain(mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 788 return 0; 789 case ARCOFI_PORT_AUDIO_OUT_VOLUME: 790 case ARCOFI_PORT_AUDIO_SPKR_VOLUME: 791 sc->sc_shadow.gx_idx = 792 arcofi_mi_to_gain(mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 793 return 0; 794 795 /* mute settings */ 796 case ARCOFI_PORT_AUDIO_IN_MUTE: 797 if (mc->un.ord) 798 portmask &= ~AUDIO_LINE_IN; 799 else 800 portmask |= AUDIO_LINE_IN; 801 break; 802 case ARCOFI_PORT_AUDIO_OUT_MUTE: 803 if (mc->un.ord) 804 portmask &= ~AUDIO_LINE_OUT; 805 else 806 portmask |= AUDIO_LINE_OUT; 807 break; 808 case ARCOFI_PORT_AUDIO_SPKR_MUTE: 809 if (mc->un.ord) 810 portmask &= ~AUDIO_SPEAKER; 811 else 812 portmask |= AUDIO_SPEAKER; 813 break; 814 } 815 816 sc->sc_shadow.cr3 = (sc->sc_shadow.cr3 & CR3_OPMODE_MASK) | 817 arcofi_portmask_to_cr3(portmask); 818 sc->sc_shadow.output_mute = (portmask == AUDIO_LINE_IN); 819 #ifdef ARCOFI_DEBUG 820 printf("%s: %s mask %02x -> cr3 %02x m %d\n", 821 device_xname(sc->sc_dev), __func__, 822 portmask, sc->sc_shadow.cr3, sc->sc_shadow.output_mute); 823 #endif 824 825 return 0; 826 } 827 828 static int 829 arcofi_get_port(void *v, mixer_ctrl_t *mc) 830 { 831 struct arcofi_softc *sc = (struct arcofi_softc *)v; 832 int portmask = 0; 833 834 #ifdef ARCOFI_DEBUG 835 printf("%s: %s, mode %d\n", 836 device_xname(sc->sc_dev), __func__, sc->sc_mode); 837 #endif 838 /* check for proper type */ 839 switch (mc->dev) { 840 /* volume settings */ 841 case ARCOFI_PORT_AUDIO_IN_VOLUME: 842 case ARCOFI_PORT_AUDIO_OUT_VOLUME: 843 case ARCOFI_PORT_AUDIO_SPKR_VOLUME: 844 if (mc->un.value.num_channels != 1) 845 return EINVAL; 846 break; 847 848 /* mute settings */ 849 case ARCOFI_PORT_AUDIO_IN_MUTE: 850 case ARCOFI_PORT_AUDIO_OUT_MUTE: 851 case ARCOFI_PORT_AUDIO_SPKR_MUTE: 852 if (mc->type != AUDIO_MIXER_ENUM) 853 return EINVAL; 854 portmask = arcofi_cr3_to_portmask(sc->sc_shadow.cr3, 855 sc->sc_shadow.output_mute); 856 #ifdef ARCOFI_DEBUG 857 printf("%s: %s cr3 %02x -> mask %02x\n", 858 device_xname(sc->sc_dev), __func__, 859 sc->sc_shadow.cr3, portmask); 860 #endif 861 break; 862 default: 863 return EINVAL; 864 } 865 866 switch (mc->dev) { 867 /* volume settings */ 868 case ARCOFI_PORT_AUDIO_IN_VOLUME: 869 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 870 arcofi_gain_to_mi(sc->sc_shadow.gr_idx); 871 break; 872 case ARCOFI_PORT_AUDIO_OUT_VOLUME: 873 case ARCOFI_PORT_AUDIO_SPKR_VOLUME: 874 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 875 arcofi_gain_to_mi(sc->sc_shadow.gx_idx); 876 break; 877 878 /* mute settings */ 879 case ARCOFI_PORT_AUDIO_IN_MUTE: 880 mc->un.ord = portmask & AUDIO_LINE_IN ? 0 : 1; 881 break; 882 case ARCOFI_PORT_AUDIO_OUT_MUTE: 883 mc->un.ord = portmask & AUDIO_LINE_OUT ? 0 : 1; 884 break; 885 case ARCOFI_PORT_AUDIO_SPKR_MUTE: 886 mc->un.ord = portmask & AUDIO_SPEAKER ? 0 : 1; 887 break; 888 } 889 890 return 0; 891 } 892 893 static int 894 arcofi_query_devinfo(void *v, mixer_devinfo_t *md) 895 { 896 897 switch (md->index) { 898 default: 899 return ENXIO; 900 901 /* items */ 902 case ARCOFI_PORT_AUDIO_IN_VOLUME: 903 md->type = AUDIO_MIXER_VALUE; 904 md->mixer_class = ARCOFI_CLASS_INPUT; 905 md->prev = AUDIO_MIXER_LAST; 906 md->next = ARCOFI_PORT_AUDIO_IN_MUTE; 907 strlcpy(md->label.name, AudioNline, 908 sizeof md->label.name); 909 goto mono_volume; 910 case ARCOFI_PORT_AUDIO_OUT_VOLUME: 911 md->type = AUDIO_MIXER_VALUE; 912 md->mixer_class = ARCOFI_CLASS_OUTPUT; 913 md->prev = AUDIO_MIXER_LAST; 914 md->next = ARCOFI_PORT_AUDIO_OUT_MUTE; 915 strlcpy(md->label.name, AudioNline, 916 sizeof md->label.name); 917 goto mono_volume; 918 case ARCOFI_PORT_AUDIO_SPKR_VOLUME: 919 md->type = AUDIO_MIXER_VALUE; 920 md->mixer_class = ARCOFI_CLASS_OUTPUT; 921 md->prev = AUDIO_MIXER_LAST; 922 md->next = ARCOFI_PORT_AUDIO_SPKR_MUTE; 923 strlcpy(md->label.name, AudioNspeaker, 924 sizeof md->label.name); 925 /* goto mono_volume; */ 926 mono_volume: 927 md->un.v.num_channels = 1; 928 strlcpy(md->un.v.units.name, AudioNvolume, 929 sizeof md->un.v.units.name); 930 break; 931 932 case ARCOFI_PORT_AUDIO_IN_MUTE: 933 md->type = AUDIO_MIXER_ENUM; 934 md->mixer_class = ARCOFI_CLASS_INPUT; 935 md->prev = ARCOFI_PORT_AUDIO_IN_VOLUME; 936 md->next = AUDIO_MIXER_LAST; 937 goto mute; 938 case ARCOFI_PORT_AUDIO_OUT_MUTE: 939 md->type = AUDIO_MIXER_ENUM; 940 md->mixer_class = ARCOFI_CLASS_OUTPUT; 941 md->prev = ARCOFI_PORT_AUDIO_OUT_VOLUME; 942 md->next = AUDIO_MIXER_LAST; 943 goto mute; 944 case ARCOFI_PORT_AUDIO_SPKR_MUTE: 945 md->type = AUDIO_MIXER_ENUM; 946 md->mixer_class = ARCOFI_CLASS_OUTPUT; 947 md->prev = ARCOFI_PORT_AUDIO_SPKR_VOLUME; 948 md->next = AUDIO_MIXER_LAST; 949 /* goto mute; */ 950 mute: 951 strlcpy(md->label.name, AudioNmute, sizeof md->label.name); 952 md->un.e.num_mem = 2; 953 strlcpy(md->un.e.member[0].label.name, AudioNoff, 954 sizeof md->un.e.member[0].label.name); 955 md->un.e.member[0].ord = 0; 956 strlcpy(md->un.e.member[1].label.name, AudioNon, 957 sizeof md->un.e.member[1].label.name); 958 md->un.e.member[1].ord = 1; 959 break; 960 961 /* classes */ 962 case ARCOFI_CLASS_INPUT: 963 md->type = AUDIO_MIXER_CLASS; 964 md->mixer_class = ARCOFI_CLASS_INPUT; 965 md->prev = AUDIO_MIXER_LAST; 966 md->next = AUDIO_MIXER_LAST; 967 strlcpy(md->label.name, AudioCinputs, 968 sizeof md->label.name); 969 break; 970 case ARCOFI_CLASS_OUTPUT: 971 md->type = AUDIO_MIXER_CLASS; 972 md->mixer_class = ARCOFI_CLASS_OUTPUT; 973 md->prev = AUDIO_MIXER_LAST; 974 md->next = AUDIO_MIXER_LAST; 975 strlcpy(md->label.name, AudioCoutputs, 976 sizeof md->label.name); 977 break; 978 } 979 980 return 0; 981 } 982 983 static int 984 arcofi_get_props(void *v) 985 { 986 987 return AUDIO_PROP_PLAYBACK | AUDIO_PROP_CAPTURE; 988 } 989 990 static void 991 arcofi_get_locks(void *v, kmutex_t **intr, kmutex_t **thread) 992 { 993 struct arcofi_softc *sc = (struct arcofi_softc *)v; 994 995 *intr = &sc->sc_intr_lock; 996 *thread = &sc->sc_lock; 997 } 998 999 int 1000 arcofi_hwintr(void *v) 1001 { 1002 struct arcofi_softc *sc = (struct arcofi_softc *)v; 1003 uint8_t csr, fir; 1004 int rc = 0; 1005 1006 csr = arcofi_read(sc, ARCOFI_CSR); 1007 if ((csr & CSR_INTR_REQUEST) == 0) 1008 return 0; 1009 1010 fir = arcofi_read(sc, ARCOFI_FIFO_IR); 1011 1012 /* receive */ 1013 if ((sc->sc_mode & AUMODE_RECORD) && 1014 (fir & FIFO_IR_EVENT(FIFO_IR_IN_HALF_EMPTY))) { 1015 rc = 1; 1016 1017 if (arcofi_recv_data(sc) == 0) { 1018 /* disable further interrupts */ 1019 arcofi_write(sc, ARCOFI_FIFO_IR, 1020 arcofi_read(sc, ARCOFI_FIFO_IR) & 1021 ~FIFO_IR_ENABLE(FIFO_IR_IN_HALF_EMPTY)); 1022 1023 /* callback */ 1024 sc->sc_recv.cb(sc->sc_recv.cbarg); 1025 } 1026 } 1027 1028 /* xmit */ 1029 if ((sc->sc_mode & AUMODE_PLAY) && 1030 (fir & FIFO_IR_EVENT(FIFO_IR_OUT_HALF_EMPTY))) { 1031 rc = 1; 1032 1033 if (arcofi_xmit_data(sc) == 0) { 1034 /* disable further interrupts */ 1035 arcofi_write(sc, ARCOFI_FIFO_IR, 1036 arcofi_read(sc, ARCOFI_FIFO_IR) & 1037 ~FIFO_IR_ENABLE(FIFO_IR_OUT_HALF_EMPTY)); 1038 1039 /* callback */ 1040 sc->sc_xmit.cb(sc->sc_xmit.cbarg); 1041 } 1042 } 1043 1044 #ifdef ARCOFI_DEBUG 1045 if (rc == 0) 1046 printf("%s: unclaimed interrupt, csr %02x fir %02x fsr %02x\n", 1047 device_xname(sc->sc_dev), csr, fir, 1048 arcofi_read(sc, ARCOFI_FIFO_SR)); 1049 #endif 1050 1051 return rc; 1052 } 1053 1054 static int 1055 arcofi_cmd(struct arcofi_softc *sc, uint8_t cmd, const uint8_t *data) 1056 { 1057 size_t len; 1058 uint8_t csr; 1059 int cnt; 1060 static const uint8_t cmdlen[] = { 1061 [SOP_0] = 4, 1062 [COP_1] = 4, 1063 [COP_2] = 2, 1064 [COP_3] = 2, 1065 [SOP_4] = 1, 1066 [SOP_5] = 1, 1067 [SOP_6] = 1, 1068 [SOP_7] = 1, 1069 [COP_8] = 2, 1070 [COP_9] = 4, 1071 [COP_A] = 8, 1072 [COP_B] = 2, 1073 [COP_C] = 8, 1074 [COP_D] = 4, 1075 [COP_E] = 4 1076 }; 1077 1078 /* 1079 * Compute command length. 1080 */ 1081 if (cmd >= __arraycount(cmdlen)) 1082 return EINVAL; 1083 len = cmdlen[cmd]; 1084 1085 KASSERT(cold || mutex_owned(&sc->sc_intr_lock)); 1086 1087 /* 1088 * Disable all FIFO processing. 1089 */ 1090 csr = arcofi_read(sc, ARCOFI_CSR); 1091 arcofi_write(sc, ARCOFI_CSR, 1092 csr & ~(CSR_DATA_FIFO_ENABLE | CSR_CTRL_FIFO_ENABLE)); 1093 1094 /* 1095 * Fill the FIFO with the command bytes. 1096 */ 1097 arcofi_write(sc, ARCOFI_FIFO_CTRL, CMDR_PU | CMDR_WRITE | cmd); 1098 for (; len != 0; len--) 1099 arcofi_write(sc, ARCOFI_FIFO_CTRL, *data++); 1100 1101 /* 1102 * Enable command processing. 1103 */ 1104 arcofi_write(sc, ARCOFI_CSR, 1105 (csr & ~CSR_DATA_FIFO_ENABLE) | CSR_CTRL_FIFO_ENABLE); 1106 1107 /* 1108 * Wait for the command FIFO to be empty. 1109 */ 1110 cnt = 100; 1111 while ((arcofi_read(sc, ARCOFI_FIFO_SR) & FIFO_SR_CTRL_EMPTY) == 0) { 1112 if (cnt-- == 0) { 1113 return EBUSY; 1114 } 1115 delay(10); 1116 } 1117 1118 arcofi_write(sc, ARCOFI_CSR, csr); 1119 1120 return 0; 1121 } 1122 1123 void 1124 arcofi_attach(struct arcofi_softc *sc, const char *versionstr) 1125 { 1126 device_t self; 1127 int rc; 1128 uint8_t op, cmd[4]; 1129 1130 self = sc->sc_dev; 1131 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 1132 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO); 1133 1134 /* 1135 * Reset logic. 1136 */ 1137 arcofi_write(sc, ARCOFI_ID, 0); 1138 delay(100000); 1139 arcofi_write(sc, ARCOFI_CSR, 0); 1140 1141 /* 1142 * Initialize the chip to default settings (8 bit, u-Law). 1143 */ 1144 sc->sc_active.cr3 = 1145 arcofi_portmask_to_cr3(AUDIO_SPEAKER) | CR3_OPMODE_NORMAL; 1146 sc->sc_active.cr4 = CR4_TM | CR4_ULAW; 1147 sc->sc_active.gr_idx = sc->sc_active.gx_idx = 1 + NEGATIVE_GAINS; 1148 sc->sc_active.output_mute = 0; 1149 memcpy(&sc->sc_shadow, &sc->sc_active, sizeof(sc->sc_active)); 1150 1151 /* clear CRAM */ 1152 op = SOP_4; 1153 cmd[0] = CR1_IDR; 1154 if ((rc = arcofi_cmd(sc, op, cmd)) != 0) 1155 goto error; 1156 delay(1000); 1157 1158 /* set gain values before enabling them in CR1 */ 1159 op = COP_2; 1160 cmd[0] = arcofi_gains[sc->sc_active.gr_idx] >> 8; 1161 cmd[1] = arcofi_gains[sc->sc_active.gr_idx]; 1162 if ((rc = arcofi_cmd(sc, op, cmd)) != 0) 1163 goto error; 1164 /* same value for gx... */ 1165 op = COP_B; 1166 if ((rc = arcofi_cmd(sc, op, cmd)) != 0) 1167 goto error; 1168 1169 /* set all CR registers at once */ 1170 op = SOP_0; 1171 cmd[0] = sc->sc_active.cr4; 1172 cmd[1] = sc->sc_active.cr3; 1173 cmd[2] = CR2_SD | CR2_SC | CR2_SB | CR2_SA | CR2_ELS | CR2_AM | CR2_EFC; 1174 cmd[3] = CR1_GR | CR1_GX; 1175 if ((rc = arcofi_cmd(sc, op, cmd)) != 0) 1176 goto error; 1177 1178 arcofi_write(sc, ARCOFI_FIFO_IR, 0); 1179 arcofi_write(sc, ARCOFI_CSR, CSR_INTR_ENABLE); 1180 1181 strlcpy(sc->sc_audio_device.name, arcofi_cd.cd_name, 1182 sizeof(sc->sc_audio_device.name)); 1183 strlcpy(sc->sc_audio_device.version, versionstr, 1184 sizeof(sc->sc_audio_device.version)); 1185 strlcpy(sc->sc_audio_device.config, device_xname(self), 1186 sizeof(sc->sc_audio_device.config)); 1187 1188 audio_attach_mi(&arcofi_hw_if, sc, self); 1189 return; 1190 1191 error: 1192 arcofi_write(sc, ARCOFI_ID, 0); 1193 aprint_error("%s: %02x command failed, error %d\n", 1194 __func__, op, rc); 1195 mutex_destroy(&sc->sc_intr_lock); 1196 mutex_destroy(&sc->sc_lock); 1197 } 1198