1 /* $NetBSD: wm8750_zaudio.c,v 1.4 2024/05/01 19:11:45 andvar 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 (at) 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 * Copyright (C) 2009 NONAKA Kimihiro <nonaka (at) netbsd.org> 22 * All rights reserved. 23 * 24 * Redistribution and use in source and binary forms, with or without 25 * modification, are permitted provided that the following conditions 26 * are met: 27 * 1. Redistributions of source code must retain the above copyright 28 * notice, this list of conditions and the following disclaimer. 29 * 2. Redistributions in binary form must reproduce the above copyright 30 * notice, this list of conditions and the following disclaimer in the 31 * documentation and/or other materials provided with the distribution. 32 * 33 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 34 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 35 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 36 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 37 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 38 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 39 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 40 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 41 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 42 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 43 */ 44 45 /* 46 * TODO: 47 * - powerhooks (currently only works until first suspend) 48 */ 49 50 #include "opt_cputypes.h" 51 #include "opt_zaudio.h" 52 53 #include <sys/cdefs.h> 54 __KERNEL_RCSID(0, "$NetBSD: wm8750_zaudio.c,v 1.4 2024/05/01 19:11:45 andvar Exp $"); 55 56 #include <sys/param.h> 57 #include <sys/systm.h> 58 #include <sys/callout.h> 59 #include <sys/device.h> 60 #include <sys/kmem.h> 61 #include <sys/kernel.h> 62 #include <sys/audioio.h> 63 #include <sys/mutex.h> 64 #include <sys/intr.h> 65 #include <sys/bus.h> 66 67 #include <dev/audio/audio_if.h> 68 69 #include <dev/i2c/i2cvar.h> 70 71 #include <arm/xscale/pxa2x0reg.h> 72 #include <arm/xscale/pxa2x0var.h> 73 #include <arm/xscale/pxa2x0_i2c.h> 74 #include <arm/xscale/pxa2x0_i2s.h> 75 #include <arm/xscale/pxa2x0_dmac.h> 76 #include <arm/xscale/pxa2x0_gpio.h> 77 78 #include <zaurus/zaurus/zaurus_var.h> 79 #include <zaurus/dev/zaudiovar.h> 80 #include <zaurus/dev/wm8750reg.h> 81 #include <zaurus/dev/wm8750var.h> 82 #include <zaurus/dev/scoopvar.h> 83 #include <zaurus/dev/ioexpvar.h> 84 85 #define WM8750_ADDRESS 0x1B 86 87 /* GPIO pins */ 88 #define GPIO_HP_IN_C3000 116 89 90 #define WM8750_OP_SPKR 0 91 #define WM8750_OP_HP 1 92 #define WM8750_OP_MIC 2 93 #define WM8750_OP_NUM 3 94 95 #define ZAUDIO_JACK_STATE_OUT 0 96 #define ZAUDIO_JACK_STATE_IN 1 97 #define ZAUDIO_JACK_STATE_INS 2 98 #define ZAUDIO_JACK_STATE_REM 3 99 100 static int wm8750_finalize(device_t); 101 static bool wm8750_suspend(device_t, const pmf_qual_t *); 102 static bool wm8750_resume(device_t, const pmf_qual_t *); 103 static void wm8750_volume_up(device_t); 104 static void wm8750_volume_down(device_t); 105 static void wm8750_volume_toggle(device_t); 106 107 static struct audio_device wm8750_device = { 108 "WM8750", 109 "1.0", 110 "wm" 111 }; 112 113 static void wm8750_init(struct zaudio_softc *); 114 static int wm8750_jack_intr(void *); 115 static void wm8750_jack(void *); 116 static void wm8750_standby(struct zaudio_softc *); 117 static void wm8750_update_volume(struct zaudio_softc *, int); 118 static void wm8750_update_mutes(struct zaudio_softc *, int); 119 static void wm8750_play_setup(struct zaudio_softc *); 120 /*static*/ void wm8750_record_setup(struct zaudio_softc *); 121 static int wm8750_start_output(void *, void *, int, void (*)(void *), void *); 122 static int wm8750_start_input(void *, void *, int, void (*)(void *), void *); 123 static int wm8750_halt_output(void *); 124 static int wm8750_halt_input(void *); 125 static int wm8750_getdev(void *, struct audio_device *); 126 static int wm8750_set_port(void *, struct mixer_ctrl *); 127 static int wm8750_get_port(void *, struct mixer_ctrl *); 128 static int wm8750_query_devinfo(void *, struct mixer_devinfo *); 129 130 static struct audio_hw_if wm8750_hw_if = { 131 .open = zaudio_open, 132 .close = zaudio_close, 133 .query_format = zaudio_query_format, 134 .set_format = zaudio_set_format, 135 .round_blocksize = zaudio_round_blocksize, 136 .commit_settings = NULL, 137 .init_output = NULL, 138 .init_input = NULL, 139 .start_output = wm8750_start_output, 140 .start_input = wm8750_start_input, 141 .halt_output = wm8750_halt_output, 142 .halt_input = wm8750_halt_input, 143 .speaker_ctl = NULL, 144 .getdev = wm8750_getdev, 145 .set_port = wm8750_set_port, 146 .get_port = wm8750_get_port, 147 .query_devinfo = wm8750_query_devinfo, 148 .allocm = zaudio_allocm, 149 .freem = zaudio_freem, 150 .round_buffersize = zaudio_round_buffersize, 151 .get_props = zaudio_get_props, 152 .trigger_output = NULL, 153 .trigger_input = NULL, 154 .dev_ioctl = NULL, 155 .get_locks = zaudio_get_locks, 156 }; 157 158 static const uint16_t playback_regs[][2] = { 159 /* Unmute DAC */ 160 { ADCDACCTL_REG, 0x000 }, 161 162 /* 16 bit audio words */ 163 { AUDINT_REG, AUDINT_SET_FORMAT(2) }, 164 165 /* Enable thermal protection, power */ 166 { ADCTL1_REG, ADCTL1_TSDEN | ADCTL1_SET_VSEL(3) }, 167 168 /* Enable speaker driver, DAC oversampling */ 169 { ADCTL2_REG, ADCTL2_ROUT2INV | ADCTL2_DACOSR }, 170 171 /* Set DAC voltage references */ 172 { PWRMGMT1_REG, PWRMGMT1_SET_VMIDSEL(1) | PWRMGMT1_VREF }, 173 174 /* Direct DACs to output mixers */ 175 { LOUTMIX1_REG, LOUTMIX1_LD2LO }, 176 { LOUTMIX2_REG, 0x000 }, 177 { ROUTMIX1_REG, 0x000 }, 178 { ROUTMIX2_REG, ROUTMIX2_RD2RO }, 179 180 /* End of list */ 181 { 0xffff, 0xffff } 182 }; 183 184 static const uint16_t record_regs[][2] = { 185 /* Unmute DAC */ 186 { ADCDACCTL_REG, 0x000 }, 187 188 /* 16 bit audio words */ 189 { AUDINT_REG, AUDINT_SET_FORMAT(2) }, 190 191 /* Enable thermal protection, power, left DAC for both channel */ 192 { ADCTL1_REG, ADCTL1_TSDEN | ADCTL1_SET_VSEL(3) 193 | ADCTL1_SET_DATSEL(1) }, 194 195 /* Differential input select: LINPUT1-RINPUT1, stereo */ 196 { ADCINPMODE_REG, 0x000 }, 197 198 /* L-R differential, micboost 20dB */ 199 { ADCLSPATH_REG, ADCLSPATH_SET_LINSEL(3) | ADCLSPATH_SET_LMICBOOST(2) }, 200 { ADCRSPATH_REG, ADCRSPATH_SET_RINSEL(3) | ADCRSPATH_SET_RMICBOOST(2) }, 201 202 /* End of list */ 203 { 0xffff, 0xffff } 204 }; 205 206 static __inline int 207 wm8750_write(struct zaudio_softc *sc, int reg, int val) 208 { 209 uint16_t tmp; 210 uint8_t cmd; 211 uint8_t data; 212 213 tmp = (reg << 9) | (val & 0x1ff); 214 cmd = tmp >> 8; 215 data = tmp; 216 return iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, WM8750_ADDRESS, 217 &cmd, 1, &data, 1, 0); 218 } 219 220 int 221 wm8750_match(device_t parent, cfdata_t cf, struct i2c_attach_args *ia) 222 { 223 int match_result; 224 225 if (ZAURUS_ISC860) 226 return 0; 227 228 if (iic_use_direct_match(ia, cf, NULL, &match_result)) 229 return match_result; 230 231 /* indirect config - check typical address */ 232 if (ia->ia_addr == WM8750_ADDRESS) 233 return I2C_MATCH_ADDRESS_ONLY; 234 235 return 0; 236 } 237 238 void 239 wm8750_attach(device_t parent, device_t self, struct i2c_attach_args *ia) 240 { 241 struct zaudio_softc *sc = device_private(self); 242 int error; 243 244 aprint_normal(": I2S, WM8750 Audio\n"); 245 aprint_naive("\n"); 246 247 /* Check for an I2C response from the wm8750 */ 248 iic_acquire_bus(sc->sc_i2c, 0); 249 error = wm8750_write(sc, RESET_REG, 0); 250 iic_release_bus(sc->sc_i2c, 0); 251 if (error) { 252 aprint_error_dev(self, "codec failed to respond\n"); 253 goto fail_i2c; 254 } 255 delay(100); 256 257 /* Allocate memory for volume & mute operations */ 258 sc->sc_volume = kmem_zalloc(sizeof(*sc->sc_volume) * WM8750_OP_NUM, 259 KM_SLEEP); 260 sc->sc_unmute = kmem_zalloc(sizeof(*sc->sc_unmute) * WM8750_OP_NUM, 261 KM_SLEEP); 262 sc->sc_unmute_toggle = kmem_zalloc( 263 sizeof(*sc->sc_unmute_toggle) * WM8750_OP_NUM, KM_SLEEP); 264 265 /* Speaker on, headphones off by default. */ 266 sc->sc_volume[WM8750_OP_SPKR].left = 180; 267 sc->sc_jack = FALSE; 268 UNMUTE(sc, WM8750_OP_SPKR, 1); 269 sc->sc_volume[WM8750_OP_HP].left = 180; 270 sc->sc_volume[WM8750_OP_HP].right = 180; 271 UNMUTE(sc, WM8750_OP_HP, 0); 272 sc->sc_volume[WM8750_OP_MIC].left = 180; 273 UNMUTE(sc, WM8750_OP_MIC, 0); 274 275 /* Configure headphone jack state change handling. */ 276 callout_setfunc(&sc->sc_to, wm8750_jack, sc); 277 pxa2x0_gpio_set_function(GPIO_HP_IN_C3000, GPIO_IN); 278 (void) pxa2x0_gpio_intr_establish(GPIO_HP_IN_C3000, IST_EDGE_BOTH, 279 IPL_BIO, wm8750_jack_intr, sc); 280 281 /* wm8750_init() implicitly depends on ioexp or scoop */ 282 config_finalize_register(self, wm8750_finalize); 283 284 audio_attach_mi(&wm8750_hw_if, sc, self); 285 286 if (!pmf_device_register(self, wm8750_suspend, wm8750_resume)) 287 aprint_error_dev(self, "couldn't establish power handler\n"); 288 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_UP, 289 wm8750_volume_up, true)) 290 aprint_error_dev(self, "couldn't register event handler\n"); 291 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_DOWN, 292 wm8750_volume_down, true)) 293 aprint_error_dev(self, "couldn't register event handler\n"); 294 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_TOGGLE, 295 wm8750_volume_toggle, true)) 296 aprint_error_dev(self, "couldn't register event handler\n"); 297 298 return; 299 300 fail_i2c: 301 pxa2x0_i2s_detach_sub(&sc->sc_i2s); 302 } 303 304 static int 305 wm8750_finalize(device_t dv) 306 { 307 struct zaudio_softc *sc = device_private(dv); 308 309 wm8750_init(sc); 310 return 0; 311 } 312 313 static bool 314 wm8750_suspend(device_t dv, const pmf_qual_t *qual) 315 { 316 struct zaudio_softc *sc = device_private(dv); 317 318 callout_stop(&sc->sc_to); 319 wm8750_standby(sc); 320 321 return true; 322 } 323 324 static bool 325 wm8750_resume(device_t dv, const pmf_qual_t *qual) 326 { 327 struct zaudio_softc *sc = device_private(dv); 328 329 pxa2x0_i2s_init(&sc->sc_i2s); 330 wm8750_init(sc); 331 332 return true; 333 } 334 335 static __inline uint8_t 336 vol_sadd(int vol, int stride) 337 { 338 339 vol += stride; 340 if (vol > 255) 341 return 255; 342 return (uint8_t)vol; 343 } 344 345 #ifndef ZAUDIO_VOLUME_STRIDE 346 #define ZAUDIO_VOLUME_STRIDE 8 347 #endif 348 349 static void 350 wm8750_volume_up(device_t dv) 351 { 352 struct zaudio_softc *sc = device_private(dv); 353 int s; 354 355 s = splbio(); 356 iic_acquire_bus(sc->sc_i2c, 0); 357 358 sc->sc_volume[WM8750_OP_SPKR].left = 359 vol_sadd(sc->sc_volume[WM8750_OP_SPKR].left, ZAUDIO_VOLUME_STRIDE); 360 sc->sc_volume[WM8750_OP_HP].left = 361 vol_sadd(sc->sc_volume[WM8750_OP_HP].left, ZAUDIO_VOLUME_STRIDE); 362 sc->sc_volume[WM8750_OP_HP].right = 363 vol_sadd(sc->sc_volume[WM8750_OP_HP].right, ZAUDIO_VOLUME_STRIDE); 364 365 wm8750_update_volume(sc, WM8750_OP_SPKR); 366 wm8750_update_volume(sc, WM8750_OP_HP); 367 368 iic_release_bus(sc->sc_i2c, 0); 369 splx(s); 370 } 371 372 static __inline uint8_t 373 vol_ssub(int vol, int stride) 374 { 375 376 vol -= stride; 377 if (vol < 0) 378 return 0; 379 return (uint8_t)vol; 380 } 381 382 static void 383 wm8750_volume_down(device_t dv) 384 { 385 struct zaudio_softc *sc = device_private(dv); 386 int s; 387 388 s = splbio(); 389 iic_acquire_bus(sc->sc_i2c, 0); 390 391 sc->sc_volume[WM8750_OP_SPKR].left = 392 vol_ssub(sc->sc_volume[WM8750_OP_SPKR].left, ZAUDIO_VOLUME_STRIDE); 393 sc->sc_volume[WM8750_OP_HP].left = 394 vol_ssub(sc->sc_volume[WM8750_OP_HP].left, ZAUDIO_VOLUME_STRIDE); 395 sc->sc_volume[WM8750_OP_HP].right = 396 vol_ssub(sc->sc_volume[WM8750_OP_HP].right, ZAUDIO_VOLUME_STRIDE); 397 398 wm8750_update_volume(sc, WM8750_OP_SPKR); 399 wm8750_update_volume(sc, WM8750_OP_HP); 400 401 iic_release_bus(sc->sc_i2c, 0); 402 splx(s); 403 } 404 405 static void 406 wm8750_volume_toggle(device_t dv) 407 { 408 struct zaudio_softc *sc = device_private(dv); 409 int s; 410 411 s = splbio(); 412 iic_acquire_bus(sc->sc_i2c, 0); 413 414 if (!sc->sc_unmute[WM8750_OP_SPKR] && !sc->sc_unmute[WM8750_OP_HP]) { 415 sc->sc_unmute[WM8750_OP_SPKR] = 416 sc->sc_unmute_toggle[WM8750_OP_SPKR]; 417 sc->sc_unmute[WM8750_OP_HP] = 418 sc->sc_unmute_toggle[WM8750_OP_HP]; 419 } else { 420 sc->sc_unmute[WM8750_OP_SPKR] = 0; 421 sc->sc_unmute[WM8750_OP_HP] = 0; 422 } 423 wm8750_update_mutes(sc, 1); 424 425 iic_release_bus(sc->sc_i2c, 0); 426 splx(s); 427 } 428 429 static void 430 wm8750_init(struct zaudio_softc *sc) 431 { 432 433 iic_acquire_bus(sc->sc_i2c, 0); 434 435 /* Reset the codec */ 436 wm8750_write(sc, RESET_REG, 0); 437 delay(100); 438 439 /* Switch to standby power only */ 440 wm8750_write(sc, PWRMGMT1_REG, PWRMGMT1_SET_VMIDSEL(2)); 441 wm8750_write(sc, PWRMGMT2_REG, 0); 442 443 /* Configure digital interface for I2S */ 444 wm8750_write(sc, AUDINT_REG, AUDINT_SET_FORMAT(2)); 445 446 /* Initialise volume levels */ 447 wm8750_update_volume(sc, WM8750_OP_SPKR); 448 wm8750_update_volume(sc, WM8750_OP_HP); 449 wm8750_update_volume(sc, WM8750_OP_MIC); 450 451 scoop_set_headphone(0); 452 if (ZAURUS_ISC1000) 453 ioexp_set_mic_bias(0); 454 else 455 scoop_set_mic_bias(0); 456 457 iic_release_bus(sc->sc_i2c, 0); 458 459 /* Assume that the jack state has changed. */ 460 wm8750_jack(sc); 461 } 462 463 static int 464 wm8750_jack_intr(void *v) 465 { 466 struct zaudio_softc *sc = v; 467 468 if (!callout_active(&sc->sc_to)) 469 wm8750_jack(sc); 470 471 return 1; 472 } 473 474 static void 475 wm8750_jack(void *v) 476 { 477 struct zaudio_softc *sc = v; 478 479 switch (sc->sc_state) { 480 case ZAUDIO_JACK_STATE_OUT: 481 if (pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) { 482 sc->sc_state = ZAUDIO_JACK_STATE_INS; 483 sc->sc_icount = 0; 484 } 485 break; 486 487 case ZAUDIO_JACK_STATE_INS: 488 if (sc->sc_icount++ > 2) { 489 if (pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) { 490 sc->sc_state = ZAUDIO_JACK_STATE_IN; 491 sc->sc_jack = TRUE; 492 UNMUTE(sc, WM8750_OP_SPKR, 0); 493 UNMUTE(sc, WM8750_OP_HP, 1); 494 UNMUTE(sc, WM8750_OP_MIC, 1); 495 goto update_mutes; 496 } else 497 sc->sc_state = ZAUDIO_JACK_STATE_OUT; 498 } 499 break; 500 501 case ZAUDIO_JACK_STATE_IN: 502 if (!pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) { 503 sc->sc_state = ZAUDIO_JACK_STATE_REM; 504 sc->sc_icount = 0; 505 } 506 break; 507 508 case ZAUDIO_JACK_STATE_REM: 509 if (sc->sc_icount++ > 2) { 510 if (!pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) { 511 sc->sc_state = ZAUDIO_JACK_STATE_OUT; 512 sc->sc_jack = FALSE; 513 UNMUTE(sc, WM8750_OP_SPKR, 1); 514 UNMUTE(sc, WM8750_OP_HP, 0); 515 UNMUTE(sc, WM8750_OP_MIC, 0); 516 goto update_mutes; 517 } else 518 sc->sc_state = ZAUDIO_JACK_STATE_IN; 519 } 520 break; 521 } 522 523 callout_schedule(&sc->sc_to, hz/4); 524 525 return; 526 527 update_mutes: 528 callout_stop(&sc->sc_to); 529 530 if (sc->sc_playing || sc->sc_recording) { 531 iic_acquire_bus(sc->sc_i2c, 0); 532 if (sc->sc_playing) 533 wm8750_update_mutes(sc, 1); 534 if (sc->sc_recording) 535 wm8750_update_mutes(sc, 2); 536 iic_release_bus(sc->sc_i2c, 0); 537 } 538 } 539 540 static void 541 wm8750_standby(struct zaudio_softc *sc) 542 { 543 544 iic_acquire_bus(sc->sc_i2c, 0); 545 546 /* Switch codec to standby power only */ 547 wm8750_write(sc, PWRMGMT1_REG, PWRMGMT1_SET_VMIDSEL(2)); 548 wm8750_write(sc, PWRMGMT2_REG, 0); 549 550 scoop_set_headphone(0); 551 if (ZAURUS_ISC1000) 552 ioexp_set_mic_bias(0); 553 else 554 scoop_set_mic_bias(0); 555 556 iic_release_bus(sc->sc_i2c, 0); 557 } 558 559 static void 560 wm8750_update_volume(struct zaudio_softc *sc, int output) 561 { 562 563 switch (output) { 564 case WM8750_OP_SPKR: 565 wm8750_write(sc, LOUT2VOL_REG, LOUT2VOL_LO2VU | LOUT2VOL_LO2ZC | 566 LOUT2VOL_SET_LOUT2VOL(sc->sc_volume[WM8750_OP_SPKR].left >> 1)); 567 wm8750_write(sc, ROUT2VOL_REG, ROUT2VOL_RO2VU | ROUT2VOL_RO2ZC | 568 ROUT2VOL_SET_ROUT2VOL(sc->sc_volume[WM8750_OP_SPKR].left >> 1)); 569 break; 570 571 case WM8750_OP_HP: 572 wm8750_write(sc, LOUT1VOL_REG, LOUT1VOL_LO1VU | LOUT1VOL_LO1ZC | 573 LOUT1VOL_SET_LOUT1VOL(sc->sc_volume[WM8750_OP_HP].left >> 1)); 574 wm8750_write(sc, ROUT1VOL_REG, ROUT1VOL_RO1VU | ROUT1VOL_RO1ZC | 575 ROUT1VOL_SET_ROUT1VOL(sc->sc_volume[WM8750_OP_HP].right >> 1)); 576 break; 577 578 case WM8750_OP_MIC: 579 wm8750_write(sc, LINVOL_REG, LINVOL_LIVU | 580 LINVOL_SET_LINVOL(sc->sc_volume[WM8750_OP_MIC].left >> 2)); 581 wm8750_write(sc, RINVOL_REG, RINVOL_RIVU | 582 RINVOL_SET_RINVOL(sc->sc_volume[WM8750_OP_MIC].left >> 2)); 583 break; 584 } 585 } 586 587 static void 588 wm8750_update_mutes(struct zaudio_softc *sc, int mask) 589 { 590 uint16_t val; 591 592 /* playback */ 593 if (mask & 1) { 594 val = PWRMGMT2_DACL | PWRMGMT2_DACR; 595 if (sc->sc_unmute[WM8750_OP_SPKR]) 596 val |= PWRMGMT2_LOUT2 | PWRMGMT2_ROUT2; 597 if (sc->sc_unmute[WM8750_OP_HP]) 598 val |= PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1; 599 wm8750_write(sc, PWRMGMT2_REG, val); 600 scoop_set_headphone(sc->sc_unmute[WM8750_OP_HP]); 601 } 602 603 /* record */ 604 if (mask & 2) { 605 val = PWRMGMT1_SET_VMIDSEL(1) | PWRMGMT1_VREF; 606 if (sc->sc_unmute[WM8750_OP_MIC]) { 607 val |= PWRMGMT1_AINL | PWRMGMT1_AINR 608 | PWRMGMT1_ADCL | PWRMGMT1_ADCR | PWRMGMT1_MICB; 609 } 610 wm8750_write(sc, PWRMGMT1_REG, val); 611 if (ZAURUS_ISC1000) 612 ioexp_set_mic_bias(sc->sc_unmute[WM8750_OP_MIC]); 613 else 614 scoop_set_mic_bias(sc->sc_unmute[WM8750_OP_MIC]); 615 } 616 } 617 618 static void 619 wm8750_play_setup(struct zaudio_softc *sc) 620 { 621 int i; 622 623 iic_acquire_bus(sc->sc_i2c, 0); 624 625 /* Program the codec with playback settings */ 626 for (i = 0; playback_regs[i][0] != 0xffff; i++) { 627 wm8750_write(sc, playback_regs[i][0], playback_regs[i][1]); 628 } 629 wm8750_update_mutes(sc, 1); 630 631 iic_release_bus(sc->sc_i2c, 0); 632 } 633 634 /*static*/ void 635 wm8750_record_setup(struct zaudio_softc *sc) 636 { 637 int i; 638 639 iic_acquire_bus(sc->sc_i2c, 0); 640 641 /* Program the codec with playback settings */ 642 for (i = 0; record_regs[i][0] != 0xffff; i++) { 643 wm8750_write(sc, record_regs[i][0], record_regs[i][1]); 644 } 645 wm8750_update_mutes(sc, 2); 646 647 iic_release_bus(sc->sc_i2c, 0); 648 } 649 650 static int 651 wm8750_halt_output(void *hdl) 652 { 653 struct zaudio_softc *sc = hdl; 654 int rv; 655 656 rv = pxa2x0_i2s_halt_output(&sc->sc_i2s); 657 if (!sc->sc_recording) 658 wm8750_standby(sc); 659 sc->sc_playing = 0; 660 661 return rv; 662 } 663 664 static int 665 wm8750_halt_input(void *hdl) 666 { 667 struct zaudio_softc *sc = hdl; 668 int rv; 669 670 rv = pxa2x0_i2s_halt_input(&sc->sc_i2s); 671 if (!sc->sc_playing) 672 wm8750_standby(sc); 673 sc->sc_recording = 0; 674 675 return rv; 676 } 677 678 static int 679 wm8750_getdev(void *hdl, struct audio_device *ret) 680 { 681 682 *ret = wm8750_device; 683 return 0; 684 } 685 686 #define WM8750_SPKR_LVL 0 687 #define WM8750_SPKR_MUTE 1 688 #define WM8750_HP_LVL 2 689 #define WM8750_HP_MUTE 3 690 #define WM8750_MIC_LVL 4 691 #define WM8750_MIC_MUTE 5 692 #define WM8750_RECORD_SOURCE 6 693 #define WM8750_OUTPUT_CLASS 7 694 #define WM8750_INPUT_CLASS 8 695 #define WM8750_RECORD_CLASS 9 696 697 static int 698 wm8750_set_port(void *hdl, struct mixer_ctrl *mc) 699 { 700 struct zaudio_softc *sc = hdl; 701 int error = EINVAL; 702 int s; 703 704 s = splbio(); 705 iic_acquire_bus(sc->sc_i2c, 0); 706 707 switch (mc->dev) { 708 case WM8750_SPKR_LVL: 709 if (mc->type != AUDIO_MIXER_VALUE) 710 break; 711 if (mc->un.value.num_channels == 1) 712 sc->sc_volume[WM8750_OP_SPKR].left = 713 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 714 else 715 break; 716 wm8750_update_volume(sc, WM8750_OP_SPKR); 717 error = 0; 718 break; 719 720 case WM8750_SPKR_MUTE: 721 if (mc->type != AUDIO_MIXER_ENUM) 722 break; 723 UNMUTE(sc, WM8750_OP_SPKR, mc->un.ord ? 1 : 0); 724 wm8750_update_mutes(sc, 1); 725 error = 0; 726 break; 727 728 case WM8750_HP_LVL: 729 if (mc->type != AUDIO_MIXER_VALUE) 730 break; 731 if (mc->un.value.num_channels == 1) { 732 sc->sc_volume[WM8750_OP_HP].left = 733 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 734 sc->sc_volume[WM8750_OP_HP].right = 735 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 736 } else if (mc->un.value.num_channels == 2) { 737 sc->sc_volume[WM8750_OP_HP].left = 738 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; 739 sc->sc_volume[WM8750_OP_HP].right = 740 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; 741 } 742 else 743 break; 744 wm8750_update_volume(sc, WM8750_OP_HP); 745 error = 0; 746 break; 747 748 case WM8750_HP_MUTE: 749 if (mc->type != AUDIO_MIXER_ENUM) 750 break; 751 UNMUTE(sc, WM8750_OP_HP, mc->un.ord ? 1 : 0); 752 wm8750_update_mutes(sc, 1); 753 error = 0; 754 break; 755 756 case WM8750_MIC_LVL: 757 if (mc->type != AUDIO_MIXER_VALUE) 758 break; 759 if (mc->un.value.num_channels == 1) 760 sc->sc_volume[WM8750_OP_MIC].left = 761 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 762 else 763 break; 764 wm8750_update_volume(sc, WM8750_OP_MIC); 765 error = 0; 766 break; 767 768 case WM8750_MIC_MUTE: 769 if (mc->type != AUDIO_MIXER_ENUM) 770 break; 771 UNMUTE(sc, WM8750_OP_MIC, mc->un.ord ? 1 : 0); 772 wm8750_update_mutes(sc, 2); 773 error = 0; 774 break; 775 776 case WM8750_RECORD_SOURCE: 777 if (mc->type != AUDIO_MIXER_ENUM) 778 break; 779 if (mc->un.ord != 0) 780 break; 781 /* MIC only */ 782 error = 0; 783 break; 784 } 785 786 iic_release_bus(sc->sc_i2c, 0); 787 splx(s); 788 789 return error; 790 } 791 792 static int 793 wm8750_get_port(void *hdl, struct mixer_ctrl *mc) 794 { 795 struct zaudio_softc *sc = hdl; 796 int error = EINVAL; 797 798 switch (mc->dev) { 799 case WM8750_SPKR_LVL: 800 if (mc->type != AUDIO_MIXER_VALUE) 801 break; 802 if (mc->un.value.num_channels == 1) 803 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 804 sc->sc_volume[WM8750_OP_SPKR].left; 805 else 806 break; 807 error = 0; 808 break; 809 810 case WM8750_SPKR_MUTE: 811 if (mc->type != AUDIO_MIXER_ENUM) 812 break; 813 mc->un.ord = sc->sc_unmute[WM8750_OP_SPKR] ? 1 : 0; 814 error = 0; 815 break; 816 817 case WM8750_HP_LVL: 818 if (mc->type != AUDIO_MIXER_VALUE) 819 break; 820 if (mc->un.value.num_channels == 1) 821 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 822 sc->sc_volume[WM8750_OP_HP].left; 823 else if (mc->un.value.num_channels == 2) { 824 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 825 sc->sc_volume[WM8750_OP_HP].left; 826 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 827 sc->sc_volume[WM8750_OP_HP].right; 828 } 829 else 830 break; 831 error = 0; 832 break; 833 834 case WM8750_HP_MUTE: 835 if (mc->type != AUDIO_MIXER_ENUM) 836 break; 837 mc->un.ord = sc->sc_unmute[WM8750_OP_HP] ? 1 : 0; 838 error = 0; 839 break; 840 841 case WM8750_MIC_LVL: 842 if (mc->type != AUDIO_MIXER_VALUE) 843 break; 844 if (mc->un.value.num_channels == 1) 845 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = 846 sc->sc_volume[WM8750_OP_MIC].left; 847 else 848 break; 849 error = 0; 850 break; 851 852 case WM8750_MIC_MUTE: 853 if (mc->type != AUDIO_MIXER_ENUM) 854 break; 855 mc->un.ord = sc->sc_unmute[WM8750_OP_MIC] ? 1 : 0; 856 error = 0; 857 break; 858 859 case WM8750_RECORD_SOURCE: 860 if (mc->type != AUDIO_MIXER_ENUM) 861 break; 862 mc->un.ord = 0; /* MIC only */ 863 error = 0; 864 break; 865 } 866 867 return error; 868 } 869 870 /*ARGSUSED*/ 871 static int 872 wm8750_query_devinfo(void *hdl, struct mixer_devinfo *di) 873 { 874 875 switch (di->index) { 876 case WM8750_SPKR_LVL: 877 di->type = AUDIO_MIXER_VALUE; 878 di->mixer_class = WM8750_OUTPUT_CLASS; 879 di->prev = AUDIO_MIXER_LAST; 880 di->next = WM8750_SPKR_MUTE; 881 strlcpy(di->label.name, AudioNspeaker, sizeof(di->label.name)); 882 strlcpy(di->un.v.units.name, AudioNvolume, 883 sizeof(di->un.v.units.name)); 884 di->un.v.num_channels = 1; 885 break; 886 887 case WM8750_SPKR_MUTE: 888 di->type = AUDIO_MIXER_ENUM; 889 di->mixer_class = WM8750_OUTPUT_CLASS; 890 di->prev = WM8750_SPKR_LVL; 891 di->next = AUDIO_MIXER_LAST; 892 goto mute; 893 894 case WM8750_HP_LVL: 895 di->type = AUDIO_MIXER_VALUE; 896 di->mixer_class = WM8750_OUTPUT_CLASS; 897 di->prev = AUDIO_MIXER_LAST; 898 di->next = WM8750_HP_MUTE; 899 strlcpy(di->label.name, AudioNheadphone, 900 sizeof(di->label.name)); 901 di->un.v.num_channels = 1; 902 strlcpy(di->un.v.units.name, AudioNvolume, 903 sizeof(di->un.v.units.name)); 904 break; 905 906 case WM8750_HP_MUTE: 907 di->type = AUDIO_MIXER_ENUM; 908 di->mixer_class = WM8750_OUTPUT_CLASS; 909 di->prev = WM8750_HP_LVL; 910 di->next = AUDIO_MIXER_LAST; 911 mute: 912 strlcpy(di->label.name, AudioNmute, sizeof(di->label.name)); 913 di->un.e.num_mem = 2; 914 strlcpy(di->un.e.member[0].label.name, AudioNon, 915 sizeof(di->un.e.member[0].label.name)); 916 di->un.e.member[0].ord = 0; 917 strlcpy(di->un.e.member[1].label.name, AudioNoff, 918 sizeof(di->un.e.member[1].label.name)); 919 di->un.e.member[1].ord = 1; 920 break; 921 922 case WM8750_MIC_LVL: 923 di->type = AUDIO_MIXER_VALUE; 924 di->mixer_class = WM8750_INPUT_CLASS; 925 di->prev = AUDIO_MIXER_LAST; 926 di->next = WM8750_MIC_MUTE; 927 strlcpy(di->label.name, AudioNmicrophone, 928 sizeof(di->label.name)); 929 strlcpy(di->un.v.units.name, AudioNvolume, 930 sizeof(di->un.v.units.name)); 931 di->un.v.num_channels = 1; 932 break; 933 934 case WM8750_MIC_MUTE: 935 di->type = AUDIO_MIXER_ENUM; 936 di->mixer_class = WM8750_INPUT_CLASS; 937 di->prev = WM8750_MIC_LVL; 938 di->next = AUDIO_MIXER_LAST; 939 goto mute; 940 941 case WM8750_RECORD_SOURCE: 942 di->type = AUDIO_MIXER_ENUM; 943 di->mixer_class = WM8750_RECORD_CLASS; 944 di->prev = AUDIO_MIXER_LAST; 945 di->next = AUDIO_MIXER_LAST; 946 strlcpy(di->label.name, AudioNsource, sizeof(di->label.name)); 947 di->un.e.num_mem = 1; 948 strlcpy(di->un.e.member[0].label.name, AudioNmicrophone, 949 sizeof(di->un.e.member[0].label.name)); 950 di->un.e.member[0].ord = 0; 951 break; 952 953 case WM8750_OUTPUT_CLASS: 954 di->type = AUDIO_MIXER_CLASS; 955 di->mixer_class = WM8750_OUTPUT_CLASS; 956 di->prev = AUDIO_MIXER_LAST; 957 di->next = AUDIO_MIXER_LAST; 958 strlcpy(di->label.name, AudioCoutputs, sizeof(di->label.name)); 959 break; 960 961 case WM8750_INPUT_CLASS: 962 di->type = AUDIO_MIXER_CLASS; 963 di->mixer_class = WM8750_INPUT_CLASS; 964 di->prev = AUDIO_MIXER_LAST; 965 di->next = AUDIO_MIXER_LAST; 966 strlcpy(di->label.name, AudioCinputs, sizeof(di->label.name)); 967 break; 968 969 case WM8750_RECORD_CLASS: 970 di->type = AUDIO_MIXER_CLASS; 971 di->mixer_class = WM8750_RECORD_CLASS; 972 di->prev = AUDIO_MIXER_LAST; 973 di->next = AUDIO_MIXER_LAST; 974 strlcpy(di->label.name, AudioCinputs, sizeof(di->label.name)); 975 break; 976 977 default: 978 return ENXIO; 979 } 980 981 return 0; 982 } 983 984 static int 985 wm8750_start_output(void *hdl, void *block, int bsize, void (*intr)(void *), 986 void *intrarg) 987 { 988 struct zaudio_softc *sc = hdl; 989 int rv; 990 991 /* Power up codec if we are not already playing. */ 992 if (!sc->sc_playing) { 993 sc->sc_playing = 1; 994 wm8750_play_setup(sc); 995 } 996 997 /* Start DMA via I2S */ 998 rv = pxa2x0_i2s_start_output(&sc->sc_i2s, block, bsize, intr, intrarg); 999 if (rv) { 1000 if (!sc->sc_recording) 1001 wm8750_standby(sc); 1002 sc->sc_playing = 0; 1003 } 1004 1005 return rv; 1006 } 1007 1008 static int 1009 wm8750_start_input(void *hdl, void *block, int bsize, void (*intr)(void *), 1010 void *intrarg) 1011 { 1012 struct zaudio_softc *sc = hdl; 1013 int rv; 1014 1015 /* Power up codec if we are not already recording. */ 1016 if (!sc->sc_recording) { 1017 sc->sc_recording = 1; 1018 wm8750_record_setup(sc); 1019 } 1020 1021 /* Start DMA via I2S */ 1022 rv = pxa2x0_i2s_start_input(&sc->sc_i2s, block, bsize, intr, intrarg); 1023 if (rv) { 1024 if (!sc->sc_playing) 1025 wm8750_standby(sc); 1026 sc->sc_recording = 0; 1027 } 1028 return rv; 1029 } 1030