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