1 /* $NetBSD: zaudio.c,v 1.5 2007/10/17 19:58:34 garbled Exp $ */ 2 /* $OpenBSD: zaurus_audio.c,v 1.8 2005/08/18 13:23:02 robert Exp $ */ 3 4 /* 5 * Copyright (c) 2005 Christopher Pascoe <pascoe@openbsd.org> 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 * TODO: 22 * - powerhooks (currently only works until first suspend) 23 * - record support 24 */ 25 26 #include <sys/cdefs.h> 27 __KERNEL_RCSID(0, "$NetBSD"); 28 29 #include <sys/param.h> 30 #include <sys/systm.h> 31 #include <sys/callout.h> 32 #include <sys/device.h> 33 #include <sys/malloc.h> 34 #include <sys/kernel.h> 35 #include <sys/audioio.h> 36 37 #include <machine/intr.h> 38 #include <machine/bus.h> 39 40 #include <arm/xscale/pxa2x0reg.h> 41 #include <arm/xscale/pxa2x0var.h> 42 #include <arm/xscale/pxa2x0_i2c.h> 43 #include <arm/xscale/pxa2x0_i2s.h> 44 #include <arm/xscale/pxa2x0_dmac.h> 45 #include <arm/xscale/pxa2x0_gpio.h> 46 47 #include <dev/audio_if.h> 48 #include <dev/mulaw.h> 49 #include <dev/auconv.h> 50 51 #include <zaurus/dev/wm8750reg.h> 52 #include <zaurus/dev/scoopvar.h> 53 54 #define WM8750_ADDRESS 0x1B 55 #define SPKR_VOLUME 112 56 57 #define wm8750_write(sc, reg, val) \ 58 pxa2x0_i2c_write_2(&sc->sc_i2c, WM8750_ADDRESS, \ 59 (((reg) << 9) | ((val) & 0x1ff))) 60 61 static int zaudio_match(struct device *, struct cfdata *, void *); 62 static void zaudio_attach(struct device *, struct device *, void *); 63 static int zaudio_detach(struct device *, int); 64 static void zaudio_power(int, void *); 65 66 #define ZAUDIO_OP_SPKR 0 67 #define ZAUDIO_OP_HP 1 68 69 #define ZAUDIO_JACK_STATE_OUT 0 70 #define ZAUDIO_JACK_STATE_IN 1 71 #define ZAUDIO_JACK_STATE_INS 2 72 #define ZAUDIO_JACK_STATE_REM 3 73 74 /* GPIO pins */ 75 #define GPIO_HP_IN_C3000 116 76 77 struct zaudio_volume { 78 u_int8_t left; 79 u_int8_t right; 80 }; 81 82 struct zaudio_softc { 83 struct device sc_dev; 84 85 /* i2s device softc */ 86 /* NB: pxa2x0_i2s requires this to be the second struct member */ 87 struct pxa2x0_i2s_softc sc_i2s; 88 89 /* i2c device softc */ 90 struct pxa2x0_i2c_softc sc_i2c; 91 92 void *sc_powerhook; 93 int sc_playing; 94 95 struct zaudio_volume sc_volume[2]; 96 char sc_unmute[2]; 97 98 int sc_state; 99 int sc_icount; 100 struct callout sc_to; 101 }; 102 103 CFATTACH_DECL(zaudio, sizeof(struct zaudio_softc), 104 zaudio_match, zaudio_attach, zaudio_detach, NULL); 105 106 static struct audio_device wm8750_device = { 107 "WM8750", 108 "1.0", 109 "wm" 110 }; 111 112 #define ZAUDIO_NFORMATS 4 113 static const struct audio_format zaudio_formats[ZAUDIO_NFORMATS] = { 114 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_LE, 16, 16, 115 2, AUFMT_STEREO, 0, {4000, 48000}}, 116 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_LE, 16, 16, 117 1, AUFMT_MONAURAL, 0, {4000, 48000}}, 118 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULINEAR_LE, 8, 8, 119 2, AUFMT_STEREO, 0, {4000, 48000}}, 120 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULINEAR_LE, 8, 8, 121 1, AUFMT_MONAURAL, 0, {4000, 48000}}, 122 }; 123 124 void zaudio_init(struct zaudio_softc *); 125 static int zaudio_jack_intr(void *); 126 void zaudio_jack(void *); 127 void zaudio_standby(struct zaudio_softc *); 128 void zaudio_update_volume(struct zaudio_softc *, int); 129 void zaudio_update_mutes(struct zaudio_softc *); 130 void zaudio_play_setup(struct zaudio_softc *); 131 static int zaudio_open(void *, int); 132 static void zaudio_close(void *); 133 static int zaudio_query_encoding(void *, struct audio_encoding *); 134 static int zaudio_set_params(void *, int, int, audio_params_t *, 135 audio_params_t *, stream_filter_list_t *, stream_filter_list_t *); 136 static int zaudio_round_blocksize(void *, int, int, const audio_params_t *); 137 static int zaudio_start_output(void *, void *, int, void (*)(void *), void *); 138 static int zaudio_start_input(void *, void *, int, void (*)(void *), void *); 139 static int zaudio_halt_output(void *); 140 static int zaudio_halt_input(void *); 141 static int zaudio_getdev(void *, struct audio_device *); 142 static int zaudio_set_port(void *, struct mixer_ctrl *); 143 static int zaudio_get_port(void *, struct mixer_ctrl *); 144 static int zaudio_query_devinfo(void *, struct mixer_devinfo *); 145 static void *zaudio_allocm(void *, int, size_t, struct malloc_type *, int); 146 static void zaudio_freem(void *, void *, struct malloc_type *); 147 static size_t zaudio_round_buffersize(void *, int, size_t); 148 static paddr_t zaudio_mappage(void *, void *, off_t, int); 149 static int zaudio_get_props(void *); 150 151 struct audio_hw_if wm8750_hw_if = { 152 zaudio_open, 153 zaudio_close, 154 NULL, 155 zaudio_query_encoding, 156 zaudio_set_params, 157 zaudio_round_blocksize, 158 NULL, 159 NULL, 160 NULL, 161 zaudio_start_output, 162 zaudio_start_input, 163 zaudio_halt_output, 164 zaudio_halt_input, 165 NULL, 166 zaudio_getdev, 167 NULL, 168 zaudio_set_port, 169 zaudio_get_port, 170 zaudio_query_devinfo, 171 zaudio_allocm, 172 zaudio_freem, 173 zaudio_round_buffersize, 174 zaudio_mappage, 175 zaudio_get_props, 176 NULL, 177 NULL, 178 NULL, 179 }; 180 181 static const uint16_t playback_registers[][2] = { 182 /* Unmute DAC */ 183 { ADCDACCTL_REG, 0x000 }, 184 185 /* 16 bit audio words */ 186 { AUDINT_REG, AUDINT_SET_FORMAT(2) }, 187 188 /* Enable thermal protection, power */ 189 { ADCTL1_REG, ADCTL1_TSDEN | ADCTL1_SET_VSEL(3) }, 190 191 /* Enable speaker driver, DAC oversampling */ 192 { ADCTL2_REG, ADCTL2_ROUT2INV | ADCTL2_DACOSR }, 193 194 /* Set DAC voltage references */ 195 { PWRMGMT1_REG, PWRMGMT1_SET_VMIDSEL(1) | PWRMGMT1_VREF }, 196 197 /* Direct DACs to output mixers */ 198 { LOUTMIX1_REG, LOUTMIX1_LD2LO }, 199 { ROUTMIX2_REG, ROUTMIX2_RD2RO }, 200 201 /* End of list */ 202 { 0xffff, 0xffff } 203 }; 204 205 static int 206 zaudio_match(struct device *parent, struct cfdata *cf, void *aux) 207 { 208 209 return 1; 210 } 211 212 static void 213 zaudio_attach(struct device *parent, struct device *self, void *aux) 214 { 215 struct zaudio_softc *sc = (struct zaudio_softc *)self; 216 struct pxaip_attach_args *pxa = aux; 217 int rv; 218 219 sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname, 220 zaudio_power, sc); 221 if (sc->sc_powerhook == NULL) { 222 printf(": unable to establish powerhook\n"); 223 return; 224 } 225 226 sc->sc_i2s.sc_iot = pxa->pxa_iot; 227 sc->sc_i2s.sc_dmat = pxa->pxa_dmat; 228 sc->sc_i2s.sc_size = PXA2X0_I2S_SIZE; 229 if (pxa2x0_i2s_attach_sub(&sc->sc_i2s)) { 230 printf(": unable to attach I2S\n"); 231 goto fail_i2s; 232 } 233 234 sc->sc_i2c.sc_iot = pxa->pxa_iot; 235 sc->sc_i2c.sc_size = PXA2X0_I2C_SIZE; 236 if (pxa2x0_i2c_attach_sub(&sc->sc_i2c)) { 237 printf(": unable to attach I2C\n"); 238 goto fail_i2c; 239 } 240 241 /* Check for an I2C response from the wm8750 */ 242 pxa2x0_i2c_open(&sc->sc_i2c); 243 rv = wm8750_write(sc, RESET_REG, 0); 244 pxa2x0_i2c_close(&sc->sc_i2c); 245 246 if (rv) { 247 printf(": codec failed to respond\n"); 248 goto fail_probe; 249 } 250 delay(100); 251 252 /* Speaker on, headphones off by default. */ 253 sc->sc_volume[ZAUDIO_OP_SPKR].left = 240; 254 sc->sc_unmute[ZAUDIO_OP_SPKR] = 1; 255 sc->sc_volume[ZAUDIO_OP_HP].left = 180; 256 sc->sc_volume[ZAUDIO_OP_HP].right = 180; 257 sc->sc_unmute[ZAUDIO_OP_HP] = 0; 258 259 /* Configure headphone jack state change handling. */ 260 callout_init(&sc->sc_to, 0); 261 callout_setfunc(&sc->sc_to, zaudio_jack, sc); 262 pxa2x0_gpio_set_function(GPIO_HP_IN_C3000, GPIO_IN); 263 (void)pxa2x0_gpio_intr_establish(GPIO_HP_IN_C3000, 264 IST_EDGE_BOTH, IPL_BIO, zaudio_jack_intr, sc); 265 266 zaudio_init(sc); 267 268 printf(": I2C, I2S, WM8750 Audio\n"); 269 270 audio_attach_mi(&wm8750_hw_if, sc, &sc->sc_dev); 271 272 return; 273 274 fail_probe: 275 pxa2x0_i2c_detach_sub(&sc->sc_i2c); 276 fail_i2c: 277 pxa2x0_i2s_detach_sub(&sc->sc_i2s); 278 fail_i2s: 279 powerhook_disestablish(sc->sc_powerhook); 280 } 281 282 static int 283 zaudio_detach(struct device *self, int flags) 284 { 285 struct zaudio_softc *sc = (struct zaudio_softc *)self; 286 287 if (sc->sc_powerhook != NULL) { 288 powerhook_disestablish(sc->sc_powerhook); 289 sc->sc_powerhook = NULL; 290 } 291 292 pxa2x0_i2c_detach_sub(&sc->sc_i2c); 293 pxa2x0_i2s_detach_sub(&sc->sc_i2s); 294 295 return 0; 296 } 297 298 static void 299 zaudio_power(int why, void *arg) 300 { 301 struct zaudio_softc *sc = arg; 302 303 switch (why) { 304 case PWR_STANDBY: 305 case PWR_SUSPEND: 306 callout_stop(&sc->sc_to); 307 zaudio_standby(sc); 308 break; 309 310 case PWR_RESUME: 311 pxa2x0_i2s_init(&sc->sc_i2s); 312 pxa2x0_i2c_init(&sc->sc_i2c); 313 zaudio_init(sc); 314 break; 315 } 316 } 317 318 void 319 zaudio_init(struct zaudio_softc *sc) 320 { 321 322 pxa2x0_i2c_open(&sc->sc_i2c); 323 324 /* Reset the codec */ 325 wm8750_write(sc, RESET_REG, 0); 326 delay(100); 327 328 /* Switch to standby power only */ 329 wm8750_write(sc, PWRMGMT1_REG, PWRMGMT1_SET_VMIDSEL(2)); 330 wm8750_write(sc, PWRMGMT2_REG, 0); 331 332 /* Configure digital interface for I2S */ 333 wm8750_write(sc, AUDINT_REG, AUDINT_SET_FORMAT(2)); 334 335 /* Initialise volume levels */ 336 zaudio_update_volume(sc, ZAUDIO_OP_SPKR); 337 zaudio_update_volume(sc, ZAUDIO_OP_HP); 338 339 pxa2x0_i2c_close(&sc->sc_i2c); 340 341 scoop_set_headphone(0); 342 343 /* Assume that the jack state has changed. */ 344 zaudio_jack(sc); 345 346 } 347 348 static int 349 zaudio_jack_intr(void *v) 350 { 351 struct zaudio_softc *sc = v; 352 353 if (!callout_active(&sc->sc_to)) 354 zaudio_jack(sc); 355 356 return 1; 357 } 358 359 void 360 zaudio_jack(void *v) 361 { 362 struct zaudio_softc *sc = v; 363 364 switch (sc->sc_state) { 365 case ZAUDIO_JACK_STATE_OUT: 366 if (pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) { 367 sc->sc_state = ZAUDIO_JACK_STATE_INS; 368 sc->sc_icount = 0; 369 } 370 break; 371 372 case ZAUDIO_JACK_STATE_INS: 373 if (sc->sc_icount++ > 2) { 374 if (pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) { 375 sc->sc_state = ZAUDIO_JACK_STATE_IN; 376 sc->sc_unmute[ZAUDIO_OP_SPKR] = 0; 377 sc->sc_unmute[ZAUDIO_OP_HP] = 1; 378 goto update_mutes; 379 } else 380 sc->sc_state = ZAUDIO_JACK_STATE_OUT; 381 } 382 break; 383 384 case ZAUDIO_JACK_STATE_IN: 385 if (!pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) { 386 sc->sc_state = ZAUDIO_JACK_STATE_REM; 387 sc->sc_icount = 0; 388 } 389 break; 390 391 case ZAUDIO_JACK_STATE_REM: 392 if (sc->sc_icount++ > 2) { 393 if (!pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) { 394 sc->sc_state = ZAUDIO_JACK_STATE_OUT; 395 sc->sc_unmute[ZAUDIO_OP_SPKR] = 1; 396 sc->sc_unmute[ZAUDIO_OP_HP] = 0; 397 goto update_mutes; 398 } else 399 sc->sc_state = ZAUDIO_JACK_STATE_IN; 400 } 401 break; 402 } 403 404 callout_schedule(&sc->sc_to, hz/4); 405 406 return; 407 408 update_mutes: 409 callout_stop(&sc->sc_to); 410 411 if (sc->sc_playing) { 412 pxa2x0_i2c_open(&sc->sc_i2c); 413 zaudio_update_mutes(sc); 414 pxa2x0_i2c_close(&sc->sc_i2c); 415 } 416 } 417 418 void 419 zaudio_standby(struct zaudio_softc *sc) 420 { 421 422 pxa2x0_i2c_open(&sc->sc_i2c); 423 424 /* Switch codec to standby power only */ 425 wm8750_write(sc, PWRMGMT1_REG, PWRMGMT1_SET_VMIDSEL(2)); 426 wm8750_write(sc, PWRMGMT2_REG, 0); 427 428 pxa2x0_i2c_close(&sc->sc_i2c); 429 430 scoop_set_headphone(0); 431 } 432 433 void 434 zaudio_update_volume(struct zaudio_softc *sc, int output) 435 { 436 437 switch (output) { 438 case ZAUDIO_OP_SPKR: 439 wm8750_write(sc, LOUT2VOL_REG, LOUT2VOL_LO2VU | LOUT2VOL_LO2ZC | 440 LOUT2VOL_SET_LOUT2VOL(sc->sc_volume[ZAUDIO_OP_SPKR 441 ].left >> 1)); 442 wm8750_write(sc, ROUT2VOL_REG, ROUT2VOL_RO2VU | ROUT2VOL_RO2ZC | 443 ROUT2VOL_SET_ROUT2VOL(sc->sc_volume[ZAUDIO_OP_SPKR 444 ].left >> 1)); 445 break; 446 447 case ZAUDIO_OP_HP: 448 wm8750_write(sc, LOUT1VOL_REG, LOUT1VOL_LO1VU | LOUT1VOL_LO1ZC | 449 LOUT1VOL_SET_LOUT1VOL(sc->sc_volume[ZAUDIO_OP_HP 450 ].left >> 1)); 451 wm8750_write(sc, ROUT1VOL_REG, ROUT1VOL_RO1VU | ROUT1VOL_RO1ZC | 452 ROUT1VOL_SET_ROUT1VOL(sc->sc_volume[ZAUDIO_OP_HP 453 ].right >> 1)); 454 break; 455 } 456 } 457 458 void 459 zaudio_update_mutes(struct zaudio_softc *sc) 460 { 461 uint16_t val; 462 463 val = PWRMGMT2_DACL | PWRMGMT2_DACR; 464 465 if (sc->sc_unmute[ZAUDIO_OP_SPKR]) 466 val |= PWRMGMT2_LOUT2 | PWRMGMT2_ROUT2; 467 468 if (sc->sc_unmute[ZAUDIO_OP_HP]) 469 val |= PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1; 470 471 wm8750_write(sc, PWRMGMT2_REG, val); 472 473 scoop_set_headphone(sc->sc_unmute[ZAUDIO_OP_HP]); 474 } 475 476 void 477 zaudio_play_setup(struct zaudio_softc *sc) 478 { 479 int i; 480 481 pxa2x0_i2c_open(&sc->sc_i2c); 482 483 /* Program the codec with playback settings */ 484 for (i = 0; playback_registers[i][0] != 0xffff; i++) { 485 wm8750_write(sc, playback_registers[i][0], 486 playback_registers[i][1]); 487 } 488 zaudio_update_mutes(sc); 489 490 pxa2x0_i2c_close(&sc->sc_i2c); 491 } 492 493 /* 494 * audio operation functions. 495 */ 496 static int 497 zaudio_open(void *hdl, int flags) 498 { 499 struct zaudio_softc *sc = hdl; 500 501 /* Power on the I2S bus and codec */ 502 pxa2x0_i2s_open(&sc->sc_i2s); 503 504 return 0; 505 } 506 507 static void 508 zaudio_close(void *hdl) 509 { 510 struct zaudio_softc *sc = hdl; 511 512 /* Power off the I2S bus and codec */ 513 pxa2x0_i2s_close(&sc->sc_i2s); 514 } 515 516 static int 517 zaudio_query_encoding(void *hdl, struct audio_encoding *aep) 518 { 519 520 switch (aep->index) { 521 case 0: 522 strlcpy(aep->name, AudioEulinear, sizeof(aep->name)); 523 aep->encoding = AUDIO_ENCODING_ULINEAR; 524 aep->precision = 8; 525 aep->flags = 0; 526 break; 527 528 case 1: 529 strlcpy(aep->name, AudioEmulaw, sizeof(aep->name)); 530 aep->encoding = AUDIO_ENCODING_ULAW; 531 aep->precision = 8; 532 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 533 break; 534 535 case 2: 536 strlcpy(aep->name, AudioEalaw, sizeof(aep->name)); 537 aep->encoding = AUDIO_ENCODING_ALAW; 538 aep->precision = 8; 539 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 540 break; 541 542 case 3: 543 strlcpy(aep->name, AudioEslinear, sizeof(aep->name)); 544 aep->encoding = AUDIO_ENCODING_SLINEAR; 545 aep->precision = 8; 546 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 547 break; 548 549 case 4: 550 strlcpy(aep->name, AudioEslinear_le, sizeof(aep->name)); 551 aep->encoding = AUDIO_ENCODING_SLINEAR_LE; 552 aep->precision = 16; 553 aep->flags = 0; 554 break; 555 556 case 5: 557 strlcpy(aep->name, AudioEulinear_le, sizeof(aep->name)); 558 aep->encoding = AUDIO_ENCODING_ULINEAR_LE; 559 aep->precision = 16; 560 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 561 break; 562 563 case 6: 564 strlcpy(aep->name, AudioEslinear_be, sizeof(aep->name)); 565 aep->encoding = AUDIO_ENCODING_SLINEAR_BE; 566 aep->precision = 16; 567 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 568 break; 569 570 case 7: 571 strlcpy(aep->name, AudioEulinear_be, sizeof(aep->name)); 572 aep->encoding = AUDIO_ENCODING_ULINEAR_BE; 573 aep->precision = 16; 574 aep->flags = AUDIO_ENCODINGFLAG_EMULATED; 575 break; 576 577 default: 578 return EINVAL; 579 } 580 581 return 0; 582 } 583 584 static int 585 zaudio_set_params(void *hdl, int setmode, int usemode, 586 audio_params_t *play, audio_params_t *rec, 587 stream_filter_list_t *pfil, stream_filter_list_t *rfil) 588 { 589 struct zaudio_softc *sc = hdl; 590 struct audio_params *p; 591 stream_filter_list_t *fil; 592 int mode, i; 593 594 if (play->sample_rate != rec->sample_rate && 595 usemode == (AUMODE_PLAY | AUMODE_RECORD)) { 596 if (setmode == AUMODE_PLAY) { 597 rec->sample_rate = play->sample_rate; 598 setmode |= AUMODE_RECORD; 599 } else if (setmode == AUMODE_RECORD) { 600 play->sample_rate = rec->sample_rate; 601 setmode |= AUMODE_PLAY; 602 } else 603 return EINVAL; 604 } 605 606 for (mode = AUMODE_RECORD; mode != -1; 607 mode = (mode == AUMODE_RECORD) ? AUMODE_PLAY : -1) { 608 if ((setmode & mode) == 0) 609 continue; 610 611 p = (mode == AUMODE_PLAY) ? play : rec; 612 613 if (p->sample_rate < 4000 || p->sample_rate > 48000 || 614 (p->precision != 8 && p->precision != 16) || 615 (p->channels != 1 && p->channels != 2)) 616 return EINVAL; 617 618 fil = (mode == AUMODE_PLAY) ? pfil : rfil; 619 i = auconv_set_converter(zaudio_formats, ZAUDIO_NFORMATS, 620 mode, p, false, fil); 621 if (i < 0) 622 return EINVAL; 623 } 624 625 if (setmode == AUMODE_RECORD) 626 pxa2x0_i2s_setspeed(&sc->sc_i2s, &rec->sample_rate); 627 else 628 pxa2x0_i2s_setspeed(&sc->sc_i2s, &play->sample_rate); 629 630 return 0; 631 } 632 633 static int 634 zaudio_round_blocksize(void *hdl, int bs, int mode, const audio_params_t *param) 635 { 636 struct zaudio_softc *sc = hdl; 637 638 return pxa2x0_i2s_round_blocksize(&sc->sc_i2s, bs, mode, param); 639 } 640 641 642 static int 643 zaudio_halt_output(void *hdl) 644 { 645 struct zaudio_softc *sc = hdl; 646 int rv; 647 648 rv = pxa2x0_i2s_halt_output(&sc->sc_i2s); 649 zaudio_standby(sc); 650 sc->sc_playing = 0; 651 652 return rv; 653 } 654 655 static int 656 zaudio_halt_input(void *hdl) 657 { 658 struct zaudio_softc *sc = hdl; 659 int rv; 660 661 rv = pxa2x0_i2s_halt_input(&sc->sc_i2s); 662 663 return rv; 664 } 665 666 static int 667 zaudio_getdev(void *hdl, struct audio_device *ret) 668 { 669 /* struct zaudio_softc *sc = hdl; */ 670 671 *ret = wm8750_device; 672 return 0; 673 } 674 675 #define ZAUDIO_SPKR_LVL 0 676 #define ZAUDIO_SPKR_MUTE 1 677 #define ZAUDIO_HP_LVL 2 678 #define ZAUDIO_HP_MUTE 3 679 #define ZAUDIO_OUTPUT_CLASS 4 680 681 static int 682 zaudio_set_port(void *hdl, struct mixer_ctrl *mc) 683 { 684 struct zaudio_softc *sc = hdl; 685 int error = EINVAL; 686 int s; 687 688 s = splbio(); 689 pxa2x0_i2c_open(&sc->sc_i2c); 690 691 switch (mc->dev) { 692 case ZAUDIO_SPKR_LVL: 693 if (mc->type != AUDIO_MIXER_VALUE) 694 break; 695 if (mc->un.value.num_channels == 1) 696 sc->sc_volume[ZAUDIO_OP_SPKR].left = 697 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 698 else 699 break; 700 zaudio_update_volume(sc, ZAUDIO_OP_SPKR); 701 error = 0; 702 break; 703 704 case ZAUDIO_SPKR_MUTE: 705 if (mc->type != AUDIO_MIXER_ENUM) 706 break; 707 sc->sc_unmute[ZAUDIO_OP_SPKR] = mc->un.ord ? 1 : 0; 708 zaudio_update_mutes(sc); 709 error = 0; 710 break; 711 712 case ZAUDIO_HP_LVL: 713 if (mc->type != AUDIO_MIXER_VALUE) 714 break; 715 if (mc->un.value.num_channels == 1) { 716 sc->sc_volume[ZAUDIO_OP_HP].left = 717 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 718 sc->sc_volume[ZAUDIO_OP_HP].right = 719 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 720 } else if (mc->un.value.num_channels == 2) { 721 sc->sc_volume[ZAUDIO_OP_HP].left = 722 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; 723 sc->sc_volume[ZAUDIO_OP_HP].right = 724 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; 725 } 726 else 727 break; 728 zaudio_update_volume(sc, ZAUDIO_OP_HP); 729 error = 0; 730 break; 731 732 case ZAUDIO_HP_MUTE: 733 if (mc->type != AUDIO_MIXER_ENUM) 734 break; 735 sc->sc_unmute[ZAUDIO_OP_HP] = mc->un.ord ? 1 : 0; 736 zaudio_update_mutes(sc); 737 error = 0; 738 break; 739 } 740 741 pxa2x0_i2c_close(&sc->sc_i2c); 742 splx(s); 743 744 return error; 745 } 746 747 static int 748 zaudio_get_port(void *hdl, struct mixer_ctrl *mc) 749 { 750 struct zaudio_softc *sc = hdl; 751 int error = EINVAL; 752 753 switch (mc->dev) { 754 case ZAUDIO_SPKR_LVL: 755 if (mc->type != AUDIO_MIXER_VALUE) 756 break; 757 if (mc->un.value.num_channels == 1) 758 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 759 sc->sc_volume[ZAUDIO_OP_SPKR].left; 760 else 761 break; 762 error = 0; 763 break; 764 765 case ZAUDIO_SPKR_MUTE: 766 if (mc->type != AUDIO_MIXER_ENUM) 767 break; 768 mc->un.ord = sc->sc_unmute[ZAUDIO_OP_SPKR] ? 1 : 0; 769 error = 0; 770 break; 771 772 case ZAUDIO_HP_LVL: 773 if (mc->type != AUDIO_MIXER_VALUE) 774 break; 775 if (mc->un.value.num_channels == 1) 776 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 777 sc->sc_volume[ZAUDIO_OP_HP].left; 778 else if (mc->un.value.num_channels == 2) { 779 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 780 sc->sc_volume[ZAUDIO_OP_HP].left; 781 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 782 sc->sc_volume[ZAUDIO_OP_HP].right; 783 } 784 else 785 break; 786 error = 0; 787 break; 788 789 case ZAUDIO_HP_MUTE: 790 if (mc->type != AUDIO_MIXER_ENUM) 791 break; 792 mc->un.ord = sc->sc_unmute[ZAUDIO_OP_HP] ? 1 : 0; 793 error = 0; 794 break; 795 } 796 797 return error; 798 } 799 800 static int 801 zaudio_query_devinfo(void *hdl, struct mixer_devinfo *di) 802 { 803 /* struct zaudio_softc *sc = hdl; */ 804 805 switch (di->index) { 806 case ZAUDIO_SPKR_LVL: 807 di->type = AUDIO_MIXER_VALUE; 808 di->mixer_class = ZAUDIO_OUTPUT_CLASS; 809 di->prev = AUDIO_MIXER_LAST; 810 di->next = ZAUDIO_SPKR_MUTE; 811 strlcpy(di->label.name, AudioNspeaker, 812 sizeof(di->label.name)); 813 strlcpy(di->un.v.units.name, AudioNvolume, 814 sizeof(di->un.v.units.name)); 815 di->un.v.num_channels = 1; 816 break; 817 818 case ZAUDIO_SPKR_MUTE: 819 di->type = AUDIO_MIXER_ENUM; 820 di->mixer_class = ZAUDIO_OUTPUT_CLASS; 821 di->prev = ZAUDIO_SPKR_LVL; 822 di->next = AUDIO_MIXER_LAST; 823 goto mute; 824 825 case ZAUDIO_HP_LVL: 826 di->type = AUDIO_MIXER_VALUE; 827 di->mixer_class = ZAUDIO_OUTPUT_CLASS; 828 di->prev = AUDIO_MIXER_LAST; 829 di->next = ZAUDIO_HP_MUTE; 830 strlcpy(di->label.name, AudioNheadphone, 831 sizeof(di->label.name)); 832 di->un.v.num_channels = 1; 833 strlcpy(di->un.v.units.name, AudioNvolume, 834 sizeof(di->un.v.units.name)); 835 break; 836 837 case ZAUDIO_HP_MUTE: 838 di->type = AUDIO_MIXER_ENUM; 839 di->mixer_class = ZAUDIO_OUTPUT_CLASS; 840 di->prev = ZAUDIO_HP_LVL; 841 di->next = AUDIO_MIXER_LAST; 842 mute: 843 strlcpy(di->label.name, AudioNmute, sizeof(di->label.name)); 844 di->un.e.num_mem = 2; 845 strlcpy(di->un.e.member[0].label.name, AudioNon, 846 sizeof(di->un.e.member[0].label.name)); 847 di->un.e.member[0].ord = 0; 848 strlcpy(di->un.e.member[1].label.name, AudioNoff, 849 sizeof(di->un.e.member[1].label.name)); 850 di->un.e.member[1].ord = 1; 851 break; 852 853 case ZAUDIO_OUTPUT_CLASS: 854 di->type = AUDIO_MIXER_CLASS; 855 di->mixer_class = ZAUDIO_OUTPUT_CLASS; 856 di->prev = AUDIO_MIXER_LAST; 857 di->next = AUDIO_MIXER_LAST; 858 strlcpy(di->label.name, AudioCoutputs, 859 sizeof(di->label.name)); 860 break; 861 862 default: 863 return ENXIO; 864 } 865 866 return 0; 867 } 868 869 static void * 870 zaudio_allocm(void *hdl, int direction, size_t size, 871 struct malloc_type *type, int flags) 872 { 873 struct zaudio_softc *sc = hdl; 874 875 return pxa2x0_i2s_allocm(&sc->sc_i2s, direction, size, type, flags); 876 } 877 878 static void 879 zaudio_freem(void *hdl, void *ptr, struct malloc_type *type) 880 { 881 struct zaudio_softc *sc = hdl; 882 883 return pxa2x0_i2s_freem(&sc->sc_i2s, ptr, type); 884 } 885 886 static size_t 887 zaudio_round_buffersize(void *hdl, int direction, size_t bufsize) 888 { 889 struct zaudio_softc *sc = hdl; 890 891 return pxa2x0_i2s_round_buffersize(&sc->sc_i2s, direction, bufsize); 892 } 893 894 static paddr_t 895 zaudio_mappage(void *hdl, void *mem, off_t off, int prot) 896 { 897 struct zaudio_softc *sc = hdl; 898 899 return pxa2x0_i2s_mappage(&sc->sc_i2s, mem, off, prot); 900 } 901 902 static int 903 zaudio_get_props(void *hdl) 904 { 905 906 return AUDIO_PROP_MMAP|AUDIO_PROP_INDEPENDENT|AUDIO_PROP_FULLDUPLEX; 907 } 908 909 static int 910 zaudio_start_output(void *hdl, void *block, int bsize, void (*intr)(void *), 911 void *intrarg) 912 { 913 struct zaudio_softc *sc = hdl; 914 int rv; 915 916 /* Power up codec if we are not already playing. */ 917 if (!sc->sc_playing) { 918 sc->sc_playing = 1; 919 zaudio_play_setup(sc); 920 } 921 922 /* Start DMA via I2S */ 923 rv = pxa2x0_i2s_start_output(&sc->sc_i2s, block, bsize, intr, intrarg); 924 if (rv) { 925 zaudio_standby(sc); 926 sc->sc_playing = 0; 927 } 928 return rv; 929 } 930 931 static int 932 zaudio_start_input(void *hdl, void *block, int bsize, void (*intr)(void *), 933 void *intrarg) 934 { 935 936 return ENXIO; 937 } 938