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