1 /* $OpenBSD: arcofi.c,v 1.17 2016/09/19 22:21:09 kettenis 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_get_port(void *, mixer_ctrl_t *); 199 int arcofi_get_props(void *); 200 int arcofi_halt_input(void *); 201 int arcofi_halt_output(void *); 202 int arcofi_open(void *, int); 203 int arcofi_query_devinfo(void *, mixer_devinfo_t *); 204 int arcofi_round_blocksize(void *, int); 205 int arcofi_set_params(void *, int, int, struct audio_params *, 206 struct audio_params *); 207 int arcofi_set_port(void *, mixer_ctrl_t *); 208 int arcofi_start_input(void *, void *, int, void (*)(void *), void *); 209 int arcofi_start_output(void *, void *, int, void (*)(void *), void *); 210 211 /* const */ struct audio_hw_if arcofi_hw_if = { 212 .open = arcofi_open, 213 .close = arcofi_close, 214 .set_params = arcofi_set_params, 215 .round_blocksize = arcofi_round_blocksize, 216 .commit_settings = arcofi_commit_settings, 217 .start_output = arcofi_start_output, 218 .start_input = arcofi_start_input, 219 .halt_output = arcofi_halt_output, 220 .halt_input = arcofi_halt_input, 221 .set_port = arcofi_set_port, 222 .get_port = arcofi_get_port, 223 .query_devinfo = arcofi_query_devinfo, 224 .get_props = arcofi_get_props, 225 }; 226 227 /* mixer items */ 228 #define ARCOFI_PORT_AUDIO_IN_VOLUME 0 /* line in volume (GR) */ 229 #define ARCOFI_PORT_AUDIO_OUT_VOLUME 1 /* line out volume (GX) */ 230 #define ARCOFI_PORT_AUDIO_SPKR_VOLUME 2 /* speaker volume (GX) */ 231 #define ARCOFI_PORT_AUDIO_IN_MUTE 3 /* line in mute (MIC) */ 232 #define ARCOFI_PORT_AUDIO_OUT_MUTE 4 /* line out mute (H out) */ 233 #define ARCOFI_PORT_AUDIO_SPKR_MUTE 5 /* line in mute (LS out) */ 234 /* mixer classes */ 235 #define ARCOFI_CLASS_INPUT 6 236 #define ARCOFI_CLASS_OUTPUT 7 237 238 /* 239 * Gain programming formulae are a complete mystery to me, and of course 240 * no two chips are compatible - not even the PSB 2163 and PSB 2165 241 * later ARCOFI chips, from the same manufacturer as the PSB 2160! 242 * 243 * Of course, the PSB 2160 datasheet does not give any set of values. 244 * The following table is taken from the HP-UX audio driver (audio_shared.o 245 * private_audio_gain_tab). 246 */ 247 248 #define NEGATIVE_GAINS 60 249 #define POSITIVE_GAINS 14 250 static const uint16_t arcofi_gains[1 + NEGATIVE_GAINS + 1 + POSITIVE_GAINS] = { 251 /* minus infinity */ 252 0x0988, 253 254 0xf8b8, 0xf8b8, 0xf8b8, 0xf8b8, 0x099f, 0x099f, 0x099f, 0x099f, 255 0x09af, 0x09af, 0x09af, 0x09cf, 0x09cf, 0x09cf, 0xf8a9, 0xf83a, 256 0xf83a, 0xf82b, 0xf82d, 0xf8a3, 0xf8b2, 0xf8a1, 0xe8aa, 0xe84b, 257 0xe89e, 0xe8d3, 0xe891, 0xe8b1, 0xd8aa, 0xd8cb, 0xd8a6, 0xd8b3, 258 0xd842, 0xd8b1, 0xc8aa, 0xc8bb, 0xc888, 0xc853, 0xc852, 0xc8b1, 259 0xb8aa, 0xb8ab, 0xb896, 0xb892, 0xb842, 0xb8b1, 0xa8aa, 0xa8bb, 260 0x199f, 0x195b, 0x29c1, 0x2923, 0x29aa, 0x392b, 0xf998, 0xb988, 261 0x1aac, 0x3aa1, 0xbaa1, 0xbb88, 262 263 /* 0 */ 264 0x8888, 265 266 0xd388, 0x5288, 0xb1a1, 0x31a1, 0x1192, 0x11d0, 0x30c0, 0x2050, 267 0x1021, 0x1020, 0x1000, 0x0001, 0x0010, 0x0000 268 }; 269 270 int 271 arcofi_open(void *v, int flags) 272 { 273 struct arcofi_softc *sc = (struct arcofi_softc *)v; 274 275 if (sc->sc_open) 276 return EBUSY; 277 sc->sc_open = 1; 278 KASSERT(sc->sc_mode == 0); 279 280 return 0; 281 } 282 283 void 284 arcofi_close(void *v) 285 { 286 struct arcofi_softc *sc = (struct arcofi_softc *)v; 287 288 arcofi_halt_input(v); 289 arcofi_halt_output(v); 290 sc->sc_open = 0; 291 } 292 293 /* 294 * Compute proper sample and hardware settings. Invoked both for record 295 * and playback, as we don't support independent settings. 296 */ 297 int 298 arcofi_set_param(struct arcofi_softc *sc, int set, int use, int mode, 299 struct audio_params *ap) 300 { 301 if ((set & mode) == 0) 302 return 0; 303 304 #ifdef ARCOFI_DEBUG 305 printf("%s: set_param, mode %d encoding %d precision %d\n", 306 sc->sc_dev.dv_xname, mode, ap->encoding, ap->precision); 307 #endif 308 switch (ap->precision) { 309 case 8: 310 switch (ap->encoding) { 311 case AUDIO_ENCODING_ULAW: 312 sc->sc_shadow.cr4 |= CR4_ULAW; 313 break; 314 case AUDIO_ENCODING_ALAW: 315 sc->sc_shadow.cr4 &= ~CR4_ULAW; 316 break; 317 default: 318 return EINVAL; 319 } 320 sc->sc_shadow.cr3 = (sc->sc_shadow.cr3 & ~CR3_OPMODE_MASK) | 321 CR3_OPMODE_NORMAL; 322 break; 323 case 16: 324 switch (ap->encoding) { 325 case AUDIO_ENCODING_SLINEAR_BE: 326 break; 327 default: 328 return EINVAL; 329 } 330 sc->sc_shadow.cr3 = (sc->sc_shadow.cr3 & ~CR3_OPMODE_MASK) | 331 CR3_OPMODE_LINEAR; 332 break; 333 default: 334 return EINVAL; 335 } 336 337 ap->bps = AUDIO_BPS(ap->precision); 338 ap->msb = 1; 339 ap->channels = 1; 340 ap->sample_rate = 8000; 341 342 return 0; 343 } 344 345 int 346 arcofi_set_params(void *v, int set, int use, struct audio_params *p, 347 struct audio_params *r) 348 { 349 struct arcofi_softc *sc = (struct arcofi_softc *)v; 350 int rc; 351 352 if (r != NULL) { 353 rc = arcofi_set_param(sc, set, use, AUMODE_RECORD, r); 354 if (rc != 0) 355 return rc; 356 } 357 358 if (p != NULL) { 359 rc = arcofi_set_param(sc, set, use, AUMODE_PLAY, p); 360 if (rc != 0) 361 return rc; 362 } 363 364 return 0; 365 } 366 367 int 368 arcofi_round_blocksize(void *v, int blksz) 369 { 370 /* 371 * Round the size up to a multiple of half the FIFO, to favour 372 * smooth interrupt operation. 373 */ 374 return roundup(blksz, ARCOFI_FIFO_SIZE / 2); 375 } 376 377 int 378 arcofi_commit_settings(void *v) 379 { 380 struct arcofi_softc *sc = (struct arcofi_softc *)v; 381 int rc; 382 uint8_t cmd[2], csr, ocsr; 383 384 #ifdef ARCOFI_DEBUG 385 printf("%s: commit_settings, gr %04x gx %04x cr3 %02x cr4 %02x mute %d\n", 386 sc->sc_dev.dv_xname, 387 arcofi_gains[sc->sc_shadow.gr_idx], 388 arcofi_gains[sc->sc_shadow.gx_idx], 389 sc->sc_shadow.cr3, sc->sc_shadow.cr4, sc->sc_shadow.output_mute); 390 #endif 391 392 if (bcmp(&sc->sc_active, &sc->sc_shadow, sizeof(sc->sc_active)) == 0) 393 return 0; 394 395 mtx_enter(&audio_lock); 396 397 if (sc->sc_active.gr_idx != sc->sc_shadow.gr_idx) { 398 cmd[0] = arcofi_gains[sc->sc_shadow.gr_idx] >> 8; 399 cmd[1] = arcofi_gains[sc->sc_shadow.gr_idx]; 400 if ((rc = arcofi_cmd(sc, COP_2, cmd)) != 0) 401 goto error; 402 sc->sc_active.gr_idx = sc->sc_shadow.gr_idx; 403 } 404 405 if (sc->sc_active.gx_idx != sc->sc_shadow.gx_idx || 406 sc->sc_active.output_mute != sc->sc_shadow.output_mute) { 407 if (sc->sc_shadow.output_mute) { 408 cmd[0] = arcofi_gains[0] >> 8; 409 cmd[1] = arcofi_gains[0]; 410 } else { 411 cmd[0] = arcofi_gains[sc->sc_shadow.gx_idx] >> 8; 412 cmd[1] = arcofi_gains[sc->sc_shadow.gx_idx]; 413 } 414 if ((rc = arcofi_cmd(sc, COP_B, cmd)) != 0) 415 goto error; 416 sc->sc_active.gx_idx = sc->sc_shadow.gx_idx; 417 sc->sc_active.output_mute = sc->sc_shadow.output_mute; 418 } 419 420 if (sc->sc_active.cr3 != sc->sc_shadow.cr3) { 421 cmd[0] = sc->sc_shadow.cr3; 422 if ((rc = arcofi_cmd(sc, SOP_6, cmd)) != 0) 423 goto error; 424 sc->sc_active.cr3 = sc->sc_shadow.cr3; 425 426 ocsr = arcofi_read(sc, ARCOFI_CSR); 427 if ((sc->sc_active.cr3 & CR3_OPMODE_MASK) != CR3_OPMODE_NORMAL) 428 csr = ocsr | CSR_WIDTH_16; 429 else 430 csr = ocsr & ~CSR_WIDTH_16; 431 if (csr != ocsr) 432 arcofi_write(sc, ARCOFI_CSR, csr); 433 } 434 435 if (sc->sc_active.cr4 != sc->sc_shadow.cr4) { 436 cmd[0] = sc->sc_shadow.cr4; 437 if ((rc = arcofi_cmd(sc, SOP_7, cmd)) != 0) 438 goto error; 439 sc->sc_active.cr4 = sc->sc_shadow.cr4; 440 } 441 442 rc = 0; 443 error: 444 mtx_leave(&audio_lock); 445 return rc; 446 } 447 448 int 449 arcofi_start_input(void *v, void *rbuf, int rsz, void (*cb)(void *), 450 void *cbarg) 451 { 452 struct arcofi_softc *sc = (struct arcofi_softc *)v; 453 454 #ifdef ARCOFI_DEBUG 455 printf("%s: start_input, mode %d\n", 456 sc->sc_dev.dv_xname, sc->sc_mode); 457 #endif 458 459 /* enable data FIFO if becoming active */ 460 if (sc->sc_mode == 0) 461 arcofi_write(sc, ARCOFI_CSR, 462 arcofi_read(sc, ARCOFI_CSR) | CSR_DATA_FIFO_ENABLE); 463 sc->sc_mode |= AUMODE_RECORD; 464 465 sc->sc_recv.buf = (uint8_t *)rbuf; 466 sc->sc_recv.past = (uint8_t *)rbuf + rsz; 467 sc->sc_recv.cb = cb; 468 sc->sc_recv.cbarg = cbarg; 469 470 /* enable input FIFO interrupts */ 471 arcofi_write(sc, ARCOFI_FIFO_IR, arcofi_read(sc, ARCOFI_FIFO_IR) | 472 FIFO_IR_ENABLE(FIFO_IR_IN_HALF_EMPTY)); 473 474 return 0; 475 } 476 477 int 478 arcofi_start_output(void *v, void *wbuf, int wsz, void (*cb)(void *), 479 void *cbarg) 480 { 481 struct arcofi_softc *sc = (struct arcofi_softc *)v; 482 483 #ifdef ARCOFI_DEBUG 484 printf("%s: start_output, mode %d\n", 485 sc->sc_dev.dv_xname, sc->sc_mode); 486 #endif 487 488 /* enable data FIFO if becoming active */ 489 if (sc->sc_mode == 0) 490 arcofi_write(sc, ARCOFI_CSR, 491 arcofi_read(sc, ARCOFI_CSR) | CSR_DATA_FIFO_ENABLE); 492 sc->sc_mode |= AUMODE_PLAY; 493 494 sc->sc_xmit.buf = (uint8_t *)wbuf; 495 sc->sc_xmit.past = (uint8_t *)wbuf + wsz; 496 sc->sc_xmit.cb = cb; 497 sc->sc_xmit.cbarg = cbarg; 498 499 /* enable output FIFO interrupts */ 500 arcofi_write(sc, ARCOFI_FIFO_IR, arcofi_read(sc, ARCOFI_FIFO_IR) | 501 FIFO_IR_ENABLE(FIFO_IR_OUT_HALF_EMPTY)); 502 503 return 0; 504 } 505 506 int 507 arcofi_halt_input(void *v) 508 { 509 struct arcofi_softc *sc = (struct arcofi_softc *)v; 510 511 mtx_enter(&audio_lock); 512 513 /* disable input FIFO interrupts */ 514 arcofi_write(sc, ARCOFI_FIFO_IR, arcofi_read(sc, ARCOFI_FIFO_IR) & 515 ~FIFO_IR_ENABLE(FIFO_IR_IN_HALF_EMPTY)); 516 /* disable data FIFO if becoming idle */ 517 sc->sc_mode &= ~AUMODE_RECORD; 518 if (sc->sc_mode == 0) 519 arcofi_write(sc, ARCOFI_CSR, 520 arcofi_read(sc, ARCOFI_CSR) & ~CSR_DATA_FIFO_ENABLE); 521 522 mtx_leave(&audio_lock); 523 return 0; 524 } 525 526 int 527 arcofi_halt_output(void *v) 528 { 529 struct arcofi_softc *sc = (struct arcofi_softc *)v; 530 531 mtx_enter(&audio_lock); 532 533 /* disable output FIFO interrupts */ 534 arcofi_write(sc, ARCOFI_FIFO_IR, arcofi_read(sc, ARCOFI_FIFO_IR) & 535 ~FIFO_IR_ENABLE(FIFO_IR_OUT_HALF_EMPTY)); 536 /* disable data FIFO if becoming idle */ 537 sc->sc_mode &= ~AUMODE_PLAY; 538 if (sc->sc_mode == 0) 539 arcofi_write(sc, ARCOFI_CSR, 540 arcofi_read(sc, ARCOFI_CSR) & ~CSR_DATA_FIFO_ENABLE); 541 542 mtx_leave(&audio_lock); 543 return 0; 544 } 545 546 /* 547 * Convert gain table index to AUDIO_MIN_GAIN..AUDIO_MAX_GAIN scale. 548 */ 549 int 550 arcofi_gain_to_mi(uint idx) 551 { 552 if (idx == 0) 553 return AUDIO_MIN_GAIN; 554 if (idx == nitems(arcofi_gains) - 1) 555 return AUDIO_MAX_GAIN; 556 557 return ((idx - 1) * (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN)) / 558 (nitems(arcofi_gains) - 1) + AUDIO_MIN_GAIN + 1; 559 } 560 561 /* 562 * Convert AUDIO_MIN_GAIN..AUDIO_MAX_GAIN scale to gain table index. 563 */ 564 uint 565 arcofi_mi_to_gain(int lvl) 566 { 567 if (lvl <= AUDIO_MIN_GAIN) 568 return 0; 569 if (lvl >= AUDIO_MAX_GAIN) 570 return nitems(arcofi_gains) - 1; 571 572 return ((lvl - AUDIO_MIN_GAIN - 1) * (nitems(arcofi_gains) - 1)) / 573 (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN); 574 } 575 576 /* 577 * Input and output ports definition (used to be in <audioio.h> 578 */ 579 #define AUDIO_SPEAKER 0x01 /* built-in speaker */ 580 #define AUDIO_LINE_IN 0x02 /* line in */ 581 #define AUDIO_LINE_OUT 0x04 /* line out */ 582 583 /* 584 * The mapping between the available inputs and outputs, and CR3, is as 585 * follows: 586 * - the `line in' connector is the `MIC' input. 587 * - the `line out' connector is the `H out' (heaphones) output. 588 * - the internal `speaker' is the `LS out' (loudspeaker) output. 589 * 590 * Each of these can be enabled or disabled independently, except for 591 * MIC enabled with H out and LS out disabled, which is not allowed 592 * by the chip (and makes no sense for a chip which was intended to 593 * be used in phones, not voice recorders); we cheat by keeping one 594 * output source enabled, but with the output gain forced to minus 595 * infinity to mute it. 596 * 597 * The truth table is thus: 598 * 599 * MIC LS out H out AFEC 600 * off off off POR 601 * off off on MUTE 602 * off on off LH1 603 * off on on LH3, X input enabled 604 * on off off RDY, GX forced to minus infinity 605 * on off on RDY 606 * on on off LH2 607 * on on on LH3 608 */ 609 610 /* 611 * Convert logical port enable settings to a valid CR3 value. 612 */ 613 uint 614 arcofi_portmask_to_cr3(int mask) 615 { 616 switch (mask) { 617 default: 618 case 0: 619 return CR3_MIC_G_17 | CR3_AFEC_POR; 620 case AUDIO_LINE_OUT: 621 return CR3_MIC_G_17 | CR3_AFEC_MUTE; 622 case AUDIO_SPEAKER: 623 return CR3_MIC_G_17 | CR3_AFEC_LH1; 624 case AUDIO_SPEAKER | AUDIO_LINE_OUT: 625 return CR3_MIC_X_INPUT | CR3_AFEC_LH3; 626 case AUDIO_LINE_IN: 627 /* since we can't do this, just... */ 628 /* FALLTHROUGH */ 629 case AUDIO_LINE_IN | AUDIO_LINE_OUT: 630 return CR3_MIC_G_17 | CR3_AFEC_RDY; 631 case AUDIO_LINE_IN | AUDIO_SPEAKER: 632 return CR3_MIC_G_17 | CR3_AFEC_LH2; 633 case AUDIO_LINE_IN | AUDIO_SPEAKER | AUDIO_LINE_OUT: 634 return CR3_MIC_G_17 | CR3_AFEC_LH3; 635 } 636 } 637 638 /* 639 * Convert CR3 to an enabled ports mask. 640 */ 641 int 642 arcofi_cr3_to_portmask(uint cr3, int output_mute) 643 { 644 switch (cr3 & CR3_AFEC_MASK) { 645 default: 646 case CR3_AFEC_POR: 647 return 0; 648 case CR3_AFEC_RDY: 649 return output_mute ? 650 AUDIO_LINE_IN : AUDIO_LINE_IN | AUDIO_LINE_OUT; 651 case CR3_AFEC_HFS: 652 case CR3_AFEC_LH1: 653 return AUDIO_SPEAKER; 654 case CR3_AFEC_LH2: 655 return AUDIO_LINE_IN | AUDIO_SPEAKER; 656 case CR3_AFEC_LH3: 657 if ((cr3 & CR3_MIC_G_MASK) == CR3_MIC_X_INPUT) 658 return AUDIO_SPEAKER | AUDIO_LINE_OUT; 659 else 660 return AUDIO_LINE_IN | AUDIO_SPEAKER | AUDIO_LINE_OUT; 661 case CR3_AFEC_MUTE: 662 return AUDIO_LINE_OUT; 663 } 664 } 665 666 int 667 arcofi_set_port(void *v, mixer_ctrl_t *mc) 668 { 669 struct arcofi_softc *sc = (struct arcofi_softc *)v; 670 int portmask; 671 672 /* check for proper type */ 673 switch (mc->dev) { 674 /* volume settings */ 675 case ARCOFI_PORT_AUDIO_IN_VOLUME: 676 case ARCOFI_PORT_AUDIO_OUT_VOLUME: 677 case ARCOFI_PORT_AUDIO_SPKR_VOLUME: 678 if (mc->un.value.num_channels != 1) 679 return EINVAL; 680 break; 681 /* mute settings */ 682 case ARCOFI_PORT_AUDIO_IN_MUTE: 683 case ARCOFI_PORT_AUDIO_OUT_MUTE: 684 case ARCOFI_PORT_AUDIO_SPKR_MUTE: 685 if (mc->type != AUDIO_MIXER_ENUM) 686 return EINVAL; 687 portmask = arcofi_cr3_to_portmask(sc->sc_shadow.cr3, 688 sc->sc_shadow.output_mute); 689 #ifdef ARCOFI_DEBUG 690 printf("%s: set_port cr3 %02x -> mask %02x\n", 691 sc->sc_dev.dv_xname, sc->sc_shadow.cr3, portmask); 692 #endif 693 break; 694 default: 695 return EINVAL; 696 } 697 698 switch (mc->dev) { 699 /* volume settings */ 700 case ARCOFI_PORT_AUDIO_IN_VOLUME: 701 sc->sc_shadow.gr_idx = 702 arcofi_mi_to_gain(mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 703 return 0; 704 case ARCOFI_PORT_AUDIO_OUT_VOLUME: 705 case ARCOFI_PORT_AUDIO_SPKR_VOLUME: 706 sc->sc_shadow.gx_idx = 707 arcofi_mi_to_gain(mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]); 708 return 0; 709 710 /* mute settings */ 711 case ARCOFI_PORT_AUDIO_IN_MUTE: 712 if (mc->un.ord) 713 portmask &= ~AUDIO_LINE_IN; 714 else 715 portmask |= AUDIO_LINE_IN; 716 break; 717 case ARCOFI_PORT_AUDIO_OUT_MUTE: 718 if (mc->un.ord) 719 portmask &= ~AUDIO_LINE_OUT; 720 else 721 portmask |= AUDIO_LINE_OUT; 722 break; 723 case ARCOFI_PORT_AUDIO_SPKR_MUTE: 724 if (mc->un.ord) 725 portmask &= ~AUDIO_SPEAKER; 726 else 727 portmask |= AUDIO_SPEAKER; 728 break; 729 } 730 731 sc->sc_shadow.cr3 = (sc->sc_shadow.cr3 & CR3_OPMODE_MASK) | 732 arcofi_portmask_to_cr3(portmask); 733 sc->sc_shadow.output_mute = (portmask == AUDIO_LINE_IN); 734 #ifdef ARCOFI_DEBUG 735 printf("%s: set_port mask %02x -> cr3 %02x m %d\n", 736 sc->sc_dev.dv_xname, portmask, 737 sc->sc_shadow.cr3, sc->sc_shadow.output_mute); 738 #endif 739 740 return 0; 741 } 742 743 int 744 arcofi_get_port(void *v, mixer_ctrl_t *mc) 745 { 746 struct arcofi_softc *sc = (struct arcofi_softc *)v; 747 int portmask; 748 749 /* check for proper type */ 750 switch (mc->dev) { 751 /* volume settings */ 752 case ARCOFI_PORT_AUDIO_IN_VOLUME: 753 case ARCOFI_PORT_AUDIO_OUT_VOLUME: 754 case ARCOFI_PORT_AUDIO_SPKR_VOLUME: 755 if (mc->un.value.num_channels != 1) 756 return EINVAL; 757 break; 758 759 /* mute settings */ 760 case ARCOFI_PORT_AUDIO_IN_MUTE: 761 case ARCOFI_PORT_AUDIO_OUT_MUTE: 762 case ARCOFI_PORT_AUDIO_SPKR_MUTE: 763 if (mc->type != AUDIO_MIXER_ENUM) 764 return EINVAL; 765 portmask = arcofi_cr3_to_portmask(sc->sc_shadow.cr3, 766 sc->sc_shadow.output_mute); 767 #ifdef ARCOFI_DEBUG 768 printf("%s: get_port cr3 %02x -> mask %02x\n", 769 sc->sc_dev.dv_xname, sc->sc_shadow.cr3, portmask); 770 #endif 771 break; 772 default: 773 return EINVAL; 774 } 775 776 switch (mc->dev) { 777 /* volume settings */ 778 case ARCOFI_PORT_AUDIO_IN_VOLUME: 779 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 780 arcofi_gain_to_mi(sc->sc_shadow.gr_idx); 781 break; 782 case ARCOFI_PORT_AUDIO_OUT_VOLUME: 783 case ARCOFI_PORT_AUDIO_SPKR_VOLUME: 784 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 785 arcofi_gain_to_mi(sc->sc_shadow.gx_idx); 786 break; 787 788 /* mute settings */ 789 case ARCOFI_PORT_AUDIO_IN_MUTE: 790 mc->un.ord = portmask & AUDIO_LINE_IN ? 0 : 1; 791 break; 792 case ARCOFI_PORT_AUDIO_OUT_MUTE: 793 mc->un.ord = portmask & AUDIO_LINE_OUT ? 0 : 1; 794 break; 795 case ARCOFI_PORT_AUDIO_SPKR_MUTE: 796 mc->un.ord = portmask & AUDIO_SPEAKER ? 0 : 1; 797 break; 798 } 799 800 return 0; 801 } 802 803 int 804 arcofi_query_devinfo(void *v, mixer_devinfo_t *md) 805 { 806 switch (md->index) { 807 default: 808 return ENXIO; 809 810 /* items */ 811 case ARCOFI_PORT_AUDIO_IN_VOLUME: 812 md->type = AUDIO_MIXER_VALUE; 813 md->mixer_class = ARCOFI_CLASS_INPUT; 814 md->prev = AUDIO_MIXER_LAST; 815 md->next = ARCOFI_PORT_AUDIO_IN_MUTE; 816 strlcpy(md->label.name, AudioNline, 817 sizeof md->label.name); 818 goto mono_volume; 819 case ARCOFI_PORT_AUDIO_OUT_VOLUME: 820 md->type = AUDIO_MIXER_VALUE; 821 md->mixer_class = ARCOFI_CLASS_OUTPUT; 822 md->prev = AUDIO_MIXER_LAST; 823 md->next = ARCOFI_PORT_AUDIO_OUT_MUTE; 824 strlcpy(md->label.name, AudioNline, 825 sizeof md->label.name); 826 goto mono_volume; 827 case ARCOFI_PORT_AUDIO_SPKR_VOLUME: 828 md->type = AUDIO_MIXER_VALUE; 829 md->mixer_class = ARCOFI_CLASS_OUTPUT; 830 md->prev = AUDIO_MIXER_LAST; 831 md->next = ARCOFI_PORT_AUDIO_SPKR_MUTE; 832 strlcpy(md->label.name, AudioNspeaker, 833 sizeof md->label.name); 834 /* goto mono_volume; */ 835 mono_volume: 836 md->un.v.num_channels = 1; 837 strlcpy(md->un.v.units.name, AudioNvolume, 838 sizeof md->un.v.units.name); 839 break; 840 841 case ARCOFI_PORT_AUDIO_IN_MUTE: 842 md->type = AUDIO_MIXER_ENUM; 843 md->mixer_class = ARCOFI_CLASS_INPUT; 844 md->prev = ARCOFI_PORT_AUDIO_IN_VOLUME; 845 md->next = AUDIO_MIXER_LAST; 846 goto mute; 847 case ARCOFI_PORT_AUDIO_OUT_MUTE: 848 md->type = AUDIO_MIXER_ENUM; 849 md->mixer_class = ARCOFI_CLASS_OUTPUT; 850 md->prev = ARCOFI_PORT_AUDIO_OUT_VOLUME; 851 md->next = AUDIO_MIXER_LAST; 852 goto mute; 853 case ARCOFI_PORT_AUDIO_SPKR_MUTE: 854 md->type = AUDIO_MIXER_ENUM; 855 md->mixer_class = ARCOFI_CLASS_OUTPUT; 856 md->prev = ARCOFI_PORT_AUDIO_SPKR_VOLUME; 857 md->next = AUDIO_MIXER_LAST; 858 /* goto mute; */ 859 mute: 860 strlcpy(md->label.name, AudioNmute, sizeof md->label.name); 861 md->un.e.num_mem = 2; 862 strlcpy(md->un.e.member[0].label.name, AudioNoff, 863 sizeof md->un.e.member[0].label.name); 864 md->un.e.member[0].ord = 0; 865 strlcpy(md->un.e.member[1].label.name, AudioNon, 866 sizeof md->un.e.member[1].label.name); 867 md->un.e.member[1].ord = 1; 868 break; 869 870 /* classes */ 871 case ARCOFI_CLASS_INPUT: 872 md->type = AUDIO_MIXER_CLASS; 873 md->mixer_class = ARCOFI_CLASS_INPUT; 874 md->prev = AUDIO_MIXER_LAST; 875 md->next = AUDIO_MIXER_LAST; 876 strlcpy(md->label.name, AudioCinputs, 877 sizeof md->label.name); 878 break; 879 case ARCOFI_CLASS_OUTPUT: 880 md->type = AUDIO_MIXER_CLASS; 881 md->mixer_class = ARCOFI_CLASS_OUTPUT; 882 md->prev = AUDIO_MIXER_LAST; 883 md->next = AUDIO_MIXER_LAST; 884 strlcpy(md->label.name, AudioCoutputs, 885 sizeof md->label.name); 886 break; 887 } 888 889 return 0; 890 } 891 892 int 893 arcofi_get_props(void *v) 894 { 895 return 0; 896 } 897 898 int 899 arcofi_hwintr(void *v) 900 { 901 struct arcofi_softc *sc = (struct arcofi_softc *)v; 902 uint8_t *cur, *past; 903 uint8_t csr, fir, data; 904 int rc = 0; 905 906 csr = arcofi_read(sc, ARCOFI_CSR); 907 if ((csr & CSR_INTR_REQUEST) == 0) 908 return 0; 909 910 fir = arcofi_read(sc, ARCOFI_FIFO_IR); 911 912 /* receive */ 913 if (fir & FIFO_IR_EVENT(FIFO_IR_IN_HALF_EMPTY)) { 914 rc = 1; 915 cur = sc->sc_recv.buf; 916 past = sc->sc_recv.past; 917 918 while ((arcofi_read(sc, ARCOFI_FIFO_SR) & 919 FIFO_SR_IN_EMPTY) == 0) { 920 data = arcofi_read(sc, ARCOFI_FIFO_DATA); 921 if (cur != NULL && cur != past) { 922 *cur++ = data; 923 if (cur == past) { 924 softintr_schedule(sc->sc_sih); 925 break; 926 } 927 } 928 } 929 sc->sc_recv.buf = cur; 930 931 if (cur == NULL || cur == past) { 932 /* underrun, disable further interrupts */ 933 arcofi_write(sc, ARCOFI_FIFO_IR, 934 arcofi_read(sc, ARCOFI_FIFO_IR) & 935 ~FIFO_IR_ENABLE(FIFO_IR_IN_HALF_EMPTY)); 936 } 937 } 938 939 /* xmit */ 940 if (fir & FIFO_IR_EVENT(FIFO_IR_OUT_HALF_EMPTY)) { 941 rc = 1; 942 cur = sc->sc_xmit.buf; 943 past = sc->sc_xmit.past; 944 if (cur != NULL) { 945 while ((arcofi_read(sc, ARCOFI_FIFO_SR) & 946 FIFO_SR_OUT_FULL) == 0) { 947 if (cur != past) 948 arcofi_write(sc, ARCOFI_FIFO_DATA, 949 *cur++); 950 if (cur == past) { 951 softintr_schedule(sc->sc_sih); 952 break; 953 } 954 } 955 } 956 if (cur == NULL || cur == past) { 957 /* disable further interrupts */ 958 arcofi_write(sc, ARCOFI_FIFO_IR, 959 arcofi_read(sc, ARCOFI_FIFO_IR) & 960 ~FIFO_IR_ENABLE(FIFO_IR_OUT_HALF_EMPTY)); 961 } 962 sc->sc_xmit.buf = cur; 963 } 964 965 /* drain */ 966 if (fir & FIFO_IR_EVENT(FIFO_IR_OUT_EMPTY)) { 967 rc = 1; 968 arcofi_write(sc, ARCOFI_FIFO_IR, 969 arcofi_read(sc, ARCOFI_FIFO_IR) & 970 ~FIFO_IR_ENABLE(FIFO_IR_OUT_EMPTY)); 971 wakeup(&sc->sc_xmit); 972 } 973 974 #ifdef ARCOFI_DEBUG 975 if (rc == 0) 976 printf("%s: unclaimed interrupt, csr %02x fir %02x fsr %02x\n", 977 sc->sc_dev.dv_xname, csr, fir, 978 arcofi_read(sc, ARCOFI_FIFO_SR)); 979 #endif 980 981 return rc; 982 } 983 984 void 985 arcofi_swintr(void *v) 986 { 987 struct arcofi_softc *sc = (struct arcofi_softc *)v; 988 int action; 989 990 action = 0; 991 mtx_enter(&audio_lock); 992 if (sc->sc_recv.buf != NULL && sc->sc_recv.buf == sc->sc_recv.past) 993 action |= AUMODE_RECORD; 994 if (sc->sc_xmit.buf != NULL && sc->sc_xmit.buf == sc->sc_xmit.past) 995 action |= AUMODE_PLAY; 996 997 if (action & AUMODE_RECORD) { 998 if (sc->sc_recv.cb) 999 sc->sc_recv.cb(sc->sc_recv.cbarg); 1000 } 1001 if (action & AUMODE_PLAY) { 1002 if (sc->sc_xmit.cb) 1003 sc->sc_xmit.cb(sc->sc_xmit.cbarg); 1004 } 1005 mtx_leave(&audio_lock); 1006 } 1007 1008 int 1009 arcofi_cmd(struct arcofi_softc *sc, uint8_t cmd, const uint8_t *data) 1010 { 1011 size_t len; 1012 uint8_t csr; 1013 int cnt; 1014 static const uint8_t cmdlen[] = { 1015 [SOP_0] = 4, 1016 [COP_1] = 4, 1017 [COP_2] = 2, 1018 [COP_3] = 2, 1019 [SOP_4] = 1, 1020 [SOP_5] = 1, 1021 [SOP_6] = 1, 1022 [SOP_7] = 1, 1023 [COP_8] = 2, 1024 [COP_9] = 4, 1025 [COP_A] = 8, 1026 [COP_B] = 2, 1027 [COP_C] = 8, 1028 [COP_D] = 4, 1029 [COP_E] = 4 1030 }; 1031 1032 /* 1033 * Compute command length. 1034 */ 1035 if (cmd >= nitems(cmdlen)) 1036 return EINVAL; 1037 len = cmdlen[cmd]; 1038 1039 mtx_enter(&audio_lock); 1040 1041 /* 1042 * Disable all FIFO processing. 1043 */ 1044 csr = arcofi_read(sc, ARCOFI_CSR); 1045 arcofi_write(sc, ARCOFI_CSR, 1046 csr & ~(CSR_DATA_FIFO_ENABLE | CSR_CTRL_FIFO_ENABLE)); 1047 1048 /* 1049 * Fill the FIFO with the command bytes. 1050 */ 1051 arcofi_write(sc, ARCOFI_FIFO_CTRL, CMDR_PU | CMDR_WRITE | cmd); 1052 for (; len != 0; len--) 1053 arcofi_write(sc, ARCOFI_FIFO_CTRL, *data++); 1054 1055 /* 1056 * Enable command processing. 1057 */ 1058 arcofi_write(sc, ARCOFI_CSR, 1059 (csr & ~CSR_DATA_FIFO_ENABLE) | CSR_CTRL_FIFO_ENABLE); 1060 1061 /* 1062 * Wait for the command FIFO to be empty. 1063 */ 1064 cnt = 100; 1065 while ((arcofi_read(sc, ARCOFI_FIFO_SR) & FIFO_SR_CTRL_EMPTY) == 0) { 1066 if (cnt-- == 0) { 1067 mtx_leave(&audio_lock); 1068 return EBUSY; 1069 } 1070 delay(10); 1071 } 1072 1073 arcofi_write(sc, ARCOFI_CSR, csr); 1074 1075 mtx_leave(&audio_lock); 1076 return 0; 1077 } 1078 1079 void 1080 arcofi_attach(struct arcofi_softc *sc, const char *version) 1081 { 1082 int rc; 1083 uint8_t cmd[4]; 1084 1085 /* 1086 * Reset logic. 1087 */ 1088 arcofi_write(sc, ARCOFI_ID, 0); 1089 delay(100000); 1090 arcofi_write(sc, ARCOFI_CSR, 0); 1091 1092 /* 1093 * Initialize the chip to default settings (8 bit, u-Law). 1094 */ 1095 sc->sc_active.cr3 = 1096 arcofi_portmask_to_cr3(AUDIO_SPEAKER) | CR3_OPMODE_NORMAL; 1097 sc->sc_active.cr4 = CR4_TM | CR4_ULAW; 1098 sc->sc_active.gr_idx = sc->sc_active.gx_idx = 1 + NEGATIVE_GAINS; 1099 sc->sc_active.output_mute = 0; 1100 bcopy(&sc->sc_active, &sc->sc_shadow, sizeof(sc->sc_active)); 1101 1102 /* clear CRAM */ 1103 cmd[0] = CR1_IDR; 1104 if ((rc = arcofi_cmd(sc, SOP_4, cmd)) != 0) 1105 goto error; 1106 delay(1000); 1107 1108 /* set gain values before enabling them in CR1 */ 1109 cmd[0] = arcofi_gains[sc->sc_active.gr_idx] >> 8; 1110 cmd[1] = arcofi_gains[sc->sc_active.gr_idx]; 1111 if ((rc = arcofi_cmd(sc, COP_2, cmd)) != 0) 1112 goto error; 1113 /* same value for gx... */ 1114 if ((rc = arcofi_cmd(sc, COP_B, cmd)) != 0) 1115 goto error; 1116 1117 /* set all CR registers at once */ 1118 cmd[0] = sc->sc_active.cr4; 1119 cmd[1] = sc->sc_active.cr3; 1120 cmd[2] = CR2_SD | CR2_SC | CR2_SB | CR2_SA | CR2_ELS | CR2_AM | CR2_EFC; 1121 cmd[3] = CR1_GR | CR1_GX; 1122 if ((rc = arcofi_cmd(sc, SOP_0, cmd)) != 0) 1123 goto error; 1124 1125 arcofi_write(sc, ARCOFI_FIFO_IR, 0); 1126 arcofi_write(sc, ARCOFI_CSR, CSR_INTR_ENABLE); 1127 1128 audio_attach_mi(&arcofi_hw_if, sc, &sc->sc_dev); 1129 return; 1130 1131 error: 1132 arcofi_write(sc, ARCOFI_ID, 0); 1133 printf("%s: command failed, error %d\n", __func__, rc); 1134 } 1135