Home | History | Annotate | Line # | Download | only in dev
      1 /*	$NetBSD: wm8731_zaudio.c,v 1.3 2019/05/08 13:40:17 isaki Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2013 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by TOYOKURA Atsushi.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 /*
     33  * TODO:
     34  *	- powerhooks (currently only works until first suspend)
     35  */
     36 
     37 #include "opt_cputypes.h"
     38 #include "opt_zaudio.h"
     39 
     40 #include <sys/cdefs.h>
     41 __KERNEL_RCSID(0, "$NetBSD: wm8731_zaudio.c,v 1.3 2019/05/08 13:40:17 isaki Exp $");
     42 
     43 #include <sys/param.h>
     44 #include <sys/systm.h>
     45 #include <sys/callout.h>
     46 #include <sys/device.h>
     47 #include <sys/kmem.h>
     48 #include <sys/kernel.h>
     49 #include <sys/audioio.h>
     50 #include <sys/mutex.h>
     51 #include <sys/intr.h>
     52 #include <sys/bus.h>
     53 
     54 #include <dev/audio/audio_if.h>
     55 
     56 #include <dev/i2c/i2cvar.h>
     57 
     58 #include <arm/xscale/pxa2x0reg.h>
     59 #include <arm/xscale/pxa2x0var.h>
     60 #include <arm/xscale/pxa2x0_i2c.h>
     61 #include <arm/xscale/pxa2x0_i2s.h>
     62 #include <arm/xscale/pxa2x0_dmac.h>
     63 #include <arm/xscale/pxa2x0_gpio.h>
     64 
     65 #include <zaurus/zaurus/zaurus_var.h>
     66 #include <zaurus/dev/zaudiovar.h>
     67 #include <zaurus/dev/wm8731reg.h>
     68 #include <zaurus/dev/wm8731var.h>
     69 #include <zaurus/dev/scoopvar.h>
     70 
     71 #define WM8731_ADDRESS  0x1B
     72 
     73 /* GPIO pins */
     74 #define GPIO_HP_IN_C860	4
     75 
     76 #define WM8731_OP_SPKR	0
     77 #define WM8731_OP_MIC	1
     78 #define WM8731_OP_NUM	2
     79 
     80 static int	wm8731_finalize(device_t);
     81 static bool	wm8731_suspend(device_t, const pmf_qual_t *);
     82 static bool	wm8731_resume(device_t, const pmf_qual_t *);
     83 static void	wm8731_volume_up(device_t);
     84 static void	wm8731_volume_down(device_t);
     85 static void	wm8731_volume_toggle(device_t);
     86 
     87 static struct audio_device wm8731_device = {
     88 	"WM8731",
     89 	"1.0",
     90 	"wm"
     91 };
     92 
     93 static void wm8731_init(struct zaudio_softc *);
     94 static int wm8731_jack_intr(void *);
     95 static void wm8731_jack(void *);
     96 static void wm8731_standby(struct zaudio_softc *);
     97 static void wm8731_update_volume(struct zaudio_softc *, int);
     98 static void wm8731_update_mutes(struct zaudio_softc *, int);
     99 static void wm8731_play_setup(struct zaudio_softc *);
    100 /*static*/ void wm8731_record_setup(struct zaudio_softc *);
    101 static int wm8731_start_output(void *, void *, int, void (*)(void *), void *);
    102 static int wm8731_start_input(void *, void *, int, void (*)(void *), void *);
    103 static int wm8731_halt_output(void *);
    104 static int wm8731_halt_input(void *);
    105 static int wm8731_getdev(void *, struct audio_device *);
    106 static int wm8731_set_port(void *, struct mixer_ctrl *);
    107 static int wm8731_get_port(void *, struct mixer_ctrl *);
    108 static int wm8731_query_devinfo(void *, struct mixer_devinfo *);
    109 
    110 static struct audio_hw_if wm8731_hw_if = {
    111 	.open			= zaudio_open,
    112 	.close			= zaudio_close,
    113 	.query_format		= zaudio_query_format,
    114 	.set_format		= zaudio_set_format,
    115 	.round_blocksize	= zaudio_round_blocksize,
    116 	.commit_settings	= NULL,
    117 	.init_output		= NULL,
    118 	.init_input		= NULL,
    119 	.start_output		= wm8731_start_output,
    120 	.start_input		= wm8731_start_input,
    121 	.halt_output		= wm8731_halt_output,
    122 	.halt_input		= wm8731_halt_input,
    123 	.speaker_ctl		= NULL,
    124 	.getdev			= wm8731_getdev,
    125 	.set_port		= wm8731_set_port,
    126 	.get_port		= wm8731_get_port,
    127 	.query_devinfo		= wm8731_query_devinfo,
    128 	.allocm			= zaudio_allocm,
    129 	.freem			= zaudio_freem,
    130 	.round_buffersize	= zaudio_round_buffersize,
    131 	.get_props		= zaudio_get_props,
    132 	.trigger_output		= NULL,
    133 	.trigger_input		= NULL,
    134 	.dev_ioctl		= NULL,
    135 	.get_locks		= zaudio_get_locks,
    136 };
    137 
    138 static const uint16_t playback_regs[][2] = {
    139 	/* Power Down Control */
    140 	{ WM8731_PD_REG, WM8731_CLKOUTPD | WM8731_OSCPD | WM8731_OUTPD
    141 	    | WM8731_ADCPD | WM8731_MICPD | WM8731_LINEINPD },
    142 
    143 	/* Digital Audio Path Control */
    144 	{ WM8731_DAP_REG, 0 },
    145 
    146 	/* Analogue Audio Path Control */
    147 	{ WM8731_AAP_REG, WM8731_DACSEL | WM8731_MUTEMIC },
    148 
    149 	/* Activating DSP and DAI */
    150 	{ WM8731_AC_REG, WM8731_ACTIVE },
    151 
    152 	/* End of list */
    153 	{ 0xffff, 0xffff }
    154 };
    155 
    156 static const uint16_t record_regs[][2] = {
    157 	/* Power Down Control */
    158 	{ WM8731_PD_REG, WM8731_CLKOUTPD | WM8731_OSCPD | WM8731_DACPD
    159 	    | WM8731_LINEINPD },
    160 
    161 	/* Digital Audio Path Control */
    162 	{ WM8731_DAP_REG, 0 },
    163 
    164 	/* Analogue Audio Path Control */
    165 	{ WM8731_AAP_REG, WM8731_INSEL | WM8731_MICBOOST },
    166 
    167 	/* Activating DSP and DAI */
    168 	{ WM8731_AC_REG, WM8731_ACTIVE },
    169 
    170 	/* End of list */
    171 	{ 0xffff, 0xffff }
    172 };
    173 
    174 static __inline int
    175 wm8731_write(struct zaudio_softc *sc, int reg, int val)
    176 {
    177 	uint16_t tmp;
    178 	uint8_t cmd;
    179 	uint8_t data;
    180 
    181 	tmp = (reg << 9) | (val & 0x1ff);
    182 	cmd = tmp >> 8;
    183 	data = tmp;
    184 	return iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, WM8731_ADDRESS,
    185 	    &cmd, 1, &data, 1, 0);
    186 }
    187 
    188 int
    189 wm8731_match(device_t parent, cfdata_t cf, struct i2c_attach_args *ia)
    190 {
    191 	int match_result;
    192 
    193 	if (ZAURUS_ISC1000 || ZAURUS_ISC3000)
    194 		return 0;
    195 
    196 	if (iic_use_direct_match(ia, cf, NULL, &match_result))
    197 		return match_result;
    198 
    199 	/* indirect config - check typical address */
    200 	if (ia->ia_addr == WM8731_ADDRESS)
    201 		return I2C_MATCH_ADDRESS_ONLY;
    202 
    203 	return 0;
    204 }
    205 
    206 void
    207 wm8731_attach(device_t parent, device_t self, struct i2c_attach_args *ia)
    208 {
    209 	struct zaudio_softc *sc = device_private(self);
    210 	int error;
    211 
    212 	aprint_normal(": I2S, WM8731 Audio\n");
    213 	aprint_naive("\n");
    214 
    215 	/* Check for an I2C response from the wm8731 */
    216 	iic_acquire_bus(sc->sc_i2c, 0);
    217 	error = wm8731_write(sc, WM8731_RESET_REG, 0);
    218 	iic_release_bus(sc->sc_i2c, 0);
    219 	if (error) {
    220 		aprint_error_dev(self, "codec failed to respond\n");
    221 		goto fail_i2c;
    222 	}
    223 	delay(100);
    224 
    225 	/* Allocate memory for volume & mute operations */
    226 	sc->sc_volume = kmem_zalloc(sizeof(*sc->sc_volume) * WM8731_OP_NUM,
    227 	    KM_SLEEP);
    228 	sc->sc_unmute = kmem_zalloc(sizeof(*sc->sc_unmute) * WM8731_OP_NUM,
    229 	    KM_SLEEP);
    230 	sc->sc_unmute_toggle = kmem_zalloc(
    231 	    sizeof(*sc->sc_unmute_toggle) * WM8731_OP_NUM, KM_SLEEP);
    232 
    233 	/* Speaker On by default. */
    234 	sc->sc_volume[WM8731_OP_SPKR].left = 180;
    235 	sc->sc_volume[WM8731_OP_SPKR].right = 180;
    236 	sc->sc_jack = FALSE;
    237 	UNMUTE(sc, WM8731_OP_SPKR, 1);
    238 	sc->sc_volume[WM8731_OP_MIC].left = 180;
    239 	UNMUTE(sc, WM8731_OP_MIC, 0);
    240 
    241 	/* Configure headphone jack state change handling. */
    242 	callout_setfunc(&sc->sc_to, wm8731_jack, sc);
    243 	pxa2x0_gpio_set_function(GPIO_HP_IN_C860, GPIO_IN);
    244 	(void) pxa2x0_gpio_intr_establish(GPIO_HP_IN_C860, IST_EDGE_BOTH,
    245 	    IPL_BIO, wm8731_jack_intr, sc);
    246 
    247 	/* wm8731_init() implicitly depends on ioexp or scoop */
    248 	config_finalize_register(self, wm8731_finalize);
    249 
    250 	audio_attach_mi(&wm8731_hw_if, sc, self);
    251 
    252 	if (!pmf_device_register(self, wm8731_suspend, wm8731_resume))
    253 		aprint_error_dev(self, "couldn't establish power handler\n");
    254 	if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_UP,
    255 	    wm8731_volume_up, true))
    256 		aprint_error_dev(self, "couldn't register event handler\n");
    257 	if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_DOWN,
    258 	    wm8731_volume_down, true))
    259 		aprint_error_dev(self, "couldn't register event handler\n");
    260 	if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_TOGGLE,
    261 	    wm8731_volume_toggle, true))
    262 		aprint_error_dev(self, "couldn't register event handler\n");
    263 
    264 	return;
    265 
    266 fail_i2c:
    267 	pxa2x0_i2s_detach_sub(&sc->sc_i2s);
    268 }
    269 
    270 static int
    271 wm8731_finalize(device_t dv)
    272 {
    273 	struct zaudio_softc *sc = device_private(dv);
    274 
    275 	wm8731_init(sc);
    276 	return 0;
    277 }
    278 
    279 static bool
    280 wm8731_suspend(device_t dv, const pmf_qual_t *qual)
    281 {
    282 	struct zaudio_softc *sc = device_private(dv);
    283 
    284 	callout_stop(&sc->sc_to);
    285 	wm8731_standby(sc);
    286 
    287 	return true;
    288 }
    289 
    290 static bool
    291 wm8731_resume(device_t dv, const pmf_qual_t *qual)
    292 {
    293 	struct zaudio_softc *sc = device_private(dv);
    294 
    295 	pxa2x0_i2s_init(&sc->sc_i2s);
    296 	wm8731_init(sc);
    297 
    298 	return true;
    299 }
    300 
    301 static __inline uint8_t
    302 vol_sadd(int vol, int stride)
    303 {
    304 
    305 	vol += stride;
    306 	if (vol > 255)
    307 		return 255;
    308 	return (uint8_t)vol;
    309 }
    310 
    311 #ifndef	ZAUDIO_VOLUME_STRIDE
    312 #define	ZAUDIO_VOLUME_STRIDE	8
    313 #endif
    314 
    315 static void
    316 wm8731_volume_up(device_t dv)
    317 {
    318 	struct zaudio_softc *sc = device_private(dv);
    319 	int s;
    320 
    321 	s = splbio();
    322 	iic_acquire_bus(sc->sc_i2c, 0);
    323 
    324 	sc->sc_volume[WM8731_OP_SPKR].left =
    325 	    vol_sadd(sc->sc_volume[WM8731_OP_SPKR].left, ZAUDIO_VOLUME_STRIDE);
    326 	sc->sc_volume[WM8731_OP_SPKR].right =
    327 	    vol_sadd(sc->sc_volume[WM8731_OP_SPKR].right, ZAUDIO_VOLUME_STRIDE);
    328 
    329 	wm8731_update_volume(sc, WM8731_OP_SPKR);
    330 
    331 	iic_release_bus(sc->sc_i2c, 0);
    332 	splx(s);
    333 }
    334 
    335 static __inline uint8_t
    336 vol_ssub(int vol, int stride)
    337 {
    338 
    339 	vol -= stride;
    340 	if (vol < 0)
    341 		return 0;
    342 	return (uint8_t)vol;
    343 }
    344 
    345 static void
    346 wm8731_volume_down(device_t dv)
    347 {
    348 	struct zaudio_softc *sc = device_private(dv);
    349 	int s;
    350 
    351 	s = splbio();
    352 	iic_acquire_bus(sc->sc_i2c, 0);
    353 
    354 	sc->sc_volume[WM8731_OP_SPKR].left =
    355 	    vol_ssub(sc->sc_volume[WM8731_OP_SPKR].left, ZAUDIO_VOLUME_STRIDE);
    356 	sc->sc_volume[WM8731_OP_SPKR].right =
    357 	    vol_ssub(sc->sc_volume[WM8731_OP_SPKR].right, ZAUDIO_VOLUME_STRIDE);
    358 
    359 	wm8731_update_volume(sc, WM8731_OP_SPKR);
    360 
    361 	iic_release_bus(sc->sc_i2c, 0);
    362 	splx(s);
    363 }
    364 
    365 static void
    366 wm8731_volume_toggle(device_t dv)
    367 {
    368 	struct zaudio_softc *sc = device_private(dv);
    369 	int s;
    370 
    371 	s = splbio();
    372 	iic_acquire_bus(sc->sc_i2c, 0);
    373 
    374 	if (!sc->sc_unmute[WM8731_OP_SPKR]) {
    375 		sc->sc_unmute[WM8731_OP_SPKR] =
    376 		    sc->sc_unmute_toggle[WM8731_OP_SPKR];
    377 	} else {
    378 		sc->sc_unmute[WM8731_OP_SPKR] = 0;
    379 	}
    380 	wm8731_update_mutes(sc, 1);
    381 
    382 	iic_release_bus(sc->sc_i2c, 0);
    383 	splx(s);
    384 }
    385 
    386 static void
    387 wm8731_init(struct zaudio_softc *sc)
    388 {
    389 
    390 	iic_acquire_bus(sc->sc_i2c, 0);
    391 
    392 	/* Reset the codec */
    393 	wm8731_write(sc, WM8731_RESET_REG, 0);
    394 	delay(100);
    395 
    396 	/* Switch to standby power only */
    397 	wm8731_write(sc, WM8731_PD_REG, WM8731_CLKOUTPD | WM8731_OSCPD |
    398 	      WM8731_OUTPD | WM8731_DACPD | WM8731_ADCPD | WM8731_MICPD |
    399 	      WM8731_LINEINPD);
    400 
    401 	/* Configure digital interface for I2S */
    402 	wm8731_write(sc, WM8731_DAI_REG, WM8731_SET_IWL(2) | WM8731_SET_FORMAT(2));
    403 
    404 	/* Initialise volume levels */
    405 	wm8731_update_volume(sc, WM8731_OP_SPKR);
    406 	wm8731_update_volume(sc, WM8731_OP_MIC);
    407 
    408 	scoop_set_headphone(0);
    409 	scoop_set_speaker(0);
    410 	scoop_set_mic_bias(0);
    411 
    412 	iic_release_bus(sc->sc_i2c, 0);
    413 
    414 	/* Assume that the jack state has changed. */
    415 	wm8731_jack(sc);
    416 }
    417 
    418 static int
    419 wm8731_jack_intr(void *v)
    420 {
    421 	struct zaudio_softc *sc = v;
    422 
    423 	if (!callout_active(&sc->sc_to))
    424 		wm8731_jack(sc);
    425 
    426 	return 1;
    427 }
    428 
    429 static void
    430 wm8731_jack(void *v)
    431 {
    432 	struct zaudio_softc *sc = v;
    433 
    434 	switch (sc->sc_state) {
    435 	case ZAUDIO_JACK_STATE_OUT:
    436 		if (pxa2x0_gpio_get_bit(GPIO_HP_IN_C860)) {
    437 			sc->sc_state = ZAUDIO_JACK_STATE_INS;
    438 			sc->sc_icount = 0;
    439 		}
    440 		break;
    441 
    442 	case ZAUDIO_JACK_STATE_INS:
    443 		if (sc->sc_icount++ > 2) {
    444 			if (pxa2x0_gpio_get_bit(GPIO_HP_IN_C860)) {
    445 				sc->sc_state = ZAUDIO_JACK_STATE_IN;
    446 				sc->sc_jack = TRUE;
    447 				UNMUTE(sc, WM8731_OP_MIC, 1);
    448 				goto update_mutes;
    449 			} else
    450 				sc->sc_state = ZAUDIO_JACK_STATE_OUT;
    451 		}
    452 		break;
    453 
    454 	case ZAUDIO_JACK_STATE_IN:
    455 		if (!pxa2x0_gpio_get_bit(GPIO_HP_IN_C860)) {
    456 			sc->sc_state = ZAUDIO_JACK_STATE_REM;
    457 			sc->sc_icount = 0;
    458 		}
    459 		break;
    460 
    461 	case ZAUDIO_JACK_STATE_REM:
    462 		if (sc->sc_icount++ > 2) {
    463 			if (!pxa2x0_gpio_get_bit(GPIO_HP_IN_C860)) {
    464 				sc->sc_state = ZAUDIO_JACK_STATE_OUT;
    465 				sc->sc_jack = FALSE;
    466 				UNMUTE(sc, WM8731_OP_MIC, 0);
    467 				goto update_mutes;
    468 			} else
    469 				sc->sc_state = ZAUDIO_JACK_STATE_IN;
    470 		}
    471 		break;
    472 	}
    473 
    474 	callout_schedule(&sc->sc_to, hz/4);
    475 
    476 	return;
    477 
    478 update_mutes:
    479 	callout_stop(&sc->sc_to);
    480 
    481 	if (sc->sc_playing || sc->sc_recording) {
    482 		iic_acquire_bus(sc->sc_i2c, 0);
    483 		if (sc->sc_playing)
    484 			wm8731_update_mutes(sc, 1);
    485 		if (sc->sc_recording)
    486 			wm8731_update_mutes(sc, 2);
    487 		iic_release_bus(sc->sc_i2c, 0);
    488 	}
    489 }
    490 
    491 static void
    492 wm8731_standby(struct zaudio_softc *sc)
    493 {
    494 
    495 	iic_acquire_bus(sc->sc_i2c, 0);
    496 
    497 	/* Switch to standby power only */
    498 	wm8731_write(sc, WM8731_PD_REG, WM8731_CLKOUTPD | WM8731_OSCPD |
    499 	      WM8731_OUTPD | WM8731_DACPD | WM8731_ADCPD | WM8731_MICPD |
    500 	      WM8731_LINEINPD);
    501 
    502 	scoop_set_headphone(0);
    503 	scoop_set_speaker(0);
    504 	scoop_set_mic_bias(0);
    505 
    506 	/* Activating DSP and DAI */
    507 	wm8731_write(sc, WM8731_AC_REG, 0);
    508 
    509 	iic_release_bus(sc->sc_i2c, 0);
    510 }
    511 
    512 static void
    513 wm8731_update_volume(struct zaudio_softc *sc, int output)
    514 {
    515 	struct zaudio_volume *volume;
    516 
    517 	switch (output) {
    518 	case WM8731_OP_SPKR:
    519 		volume = &sc->sc_volume[WM8731_OP_SPKR];
    520 		wm8731_write(sc, WM8731_LHP_REG,
    521 		       WM8731_SET_LHPVOL(volume->left >> 1));
    522 		wm8731_write(sc, WM8731_RHP_REG,
    523 		       WM8731_SET_RHPVOL(volume->right >> 1));
    524 		break;
    525 
    526 	case WM8731_OP_MIC:
    527 		volume = &sc->sc_volume[WM8731_OP_MIC];
    528 		wm8731_write(sc, WM8731_LIN_REG, WM8731_LRINBOTH |
    529 		    WM8731_SET_LINVOL(volume->left >> 3));
    530 		break;
    531 	}
    532 }
    533 
    534 static void
    535 wm8731_update_mutes(struct zaudio_softc *sc, int mask)
    536 {
    537 	uint16_t val = WM8731_CLKOUTPD | WM8731_OSCPD | WM8731_LINEINPD;
    538 
    539 	/* playback */
    540 	if (mask & 1) {
    541 		val |= WM8731_ADCPD | WM8731_MICPD;
    542 		if (!sc->sc_unmute[WM8731_OP_SPKR]) {
    543 			val |= WM8731_OUTPD | WM8731_DACPD;
    544 		}
    545 		wm8731_write(sc, WM8731_PD_REG, val);
    546 		scoop_set_headphone(sc->sc_unmute[WM8731_OP_SPKR] & sc->sc_jack);
    547 		scoop_set_speaker(sc->sc_unmute[WM8731_OP_SPKR] & !sc->sc_jack);
    548 	}
    549 
    550 	/* record */
    551 	if (mask & 2) {
    552 		val = WM8731_OUTPD | WM8731_DACPD;
    553 		if (!sc->sc_unmute[WM8731_OP_MIC]) {
    554 			val |= WM8731_ADCPD | WM8731_MICPD;
    555 		}
    556 		wm8731_write(sc, WM8731_PD_REG, val);
    557 		scoop_set_mic_bias(sc->sc_unmute[WM8731_OP_MIC]);
    558 	}
    559 }
    560 
    561 static void
    562 wm8731_play_setup(struct zaudio_softc *sc)
    563 {
    564 	int i;
    565 
    566 	iic_acquire_bus(sc->sc_i2c, 0);
    567 
    568 	/* Program the codec with playback settings */
    569 	for (i = 0; playback_regs[i][0] != 0xffff; i++) {
    570 		wm8731_write(sc, playback_regs[i][0], playback_regs[i][1]);
    571 	}
    572 	wm8731_update_mutes(sc, 1);
    573 
    574 	iic_release_bus(sc->sc_i2c, 0);
    575 }
    576 
    577 /*static*/ void
    578 wm8731_record_setup(struct zaudio_softc *sc)
    579 {
    580 	int i;
    581 
    582 	iic_acquire_bus(sc->sc_i2c, 0);
    583 
    584 	/* Program the codec with playback settings */
    585 	for (i = 0; record_regs[i][0] != 0xffff; i++) {
    586 		wm8731_write(sc, record_regs[i][0], record_regs[i][1]);
    587 	}
    588 	wm8731_update_mutes(sc, 2);
    589 
    590 	iic_release_bus(sc->sc_i2c, 0);
    591 }
    592 
    593 static int
    594 wm8731_halt_output(void *hdl)
    595 {
    596 	struct zaudio_softc *sc = hdl;
    597 	int rv;
    598 
    599 	rv = pxa2x0_i2s_halt_output(&sc->sc_i2s);
    600 	if (!sc->sc_recording)
    601 		wm8731_standby(sc);
    602 	sc->sc_playing = 0;
    603 
    604 	return rv;
    605 }
    606 
    607 static int
    608 wm8731_halt_input(void *hdl)
    609 {
    610 	struct zaudio_softc *sc = hdl;
    611 	int rv;
    612 
    613 	rv = pxa2x0_i2s_halt_input(&sc->sc_i2s);
    614 	if (!sc->sc_playing)
    615 		wm8731_standby(sc);
    616 	sc->sc_recording = 0;
    617 
    618 	return rv;
    619 }
    620 
    621 static int
    622 wm8731_getdev(void *hdl, struct audio_device *ret)
    623 {
    624 
    625 	*ret = wm8731_device;
    626 	return 0;
    627 }
    628 
    629 #define WM8731_SPKR_LVL		0
    630 #define WM8731_SPKR_MUTE	1
    631 #define WM8731_MIC_LVL		2
    632 #define WM8731_MIC_MUTE		3
    633 #define WM8731_RECORD_SOURCE	4
    634 #define WM8731_OUTPUT_CLASS	5
    635 #define WM8731_INPUT_CLASS	6
    636 #define WM8731_RECORD_CLASS	7
    637 
    638 static int
    639 wm8731_set_port(void *hdl, struct mixer_ctrl *mc)
    640 {
    641 	struct zaudio_softc *sc = hdl;
    642 	int error = EINVAL;
    643 	int s;
    644 
    645 	s = splbio();
    646 	iic_acquire_bus(sc->sc_i2c, 0);
    647 
    648 	switch (mc->dev) {
    649 	case WM8731_SPKR_LVL:
    650 		if (mc->type != AUDIO_MIXER_VALUE)
    651 			break;
    652 		if (mc->un.value.num_channels == 1) {
    653 			sc->sc_volume[WM8731_OP_SPKR].left =
    654 			    mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
    655 			sc->sc_volume[WM8731_OP_SPKR].right =
    656 			    mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
    657 		} else if (mc->un.value.num_channels == 2) {
    658 			sc->sc_volume[WM8731_OP_SPKR].left =
    659 			    mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
    660 			sc->sc_volume[WM8731_OP_SPKR].right =
    661 			    mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
    662 		}
    663 		else
    664 			break;
    665 		wm8731_update_volume(sc, WM8731_OP_SPKR);
    666 		error = 0;
    667 		break;
    668 
    669 	case WM8731_SPKR_MUTE:
    670 		if (mc->type != AUDIO_MIXER_ENUM)
    671 			break;
    672 		UNMUTE(sc, WM8731_OP_SPKR, mc->un.ord ? 1 : 0);
    673 		wm8731_update_mutes(sc, 1);
    674 		error = 0;
    675 		break;
    676 
    677 	case WM8731_MIC_LVL:
    678 		if (mc->type != AUDIO_MIXER_VALUE)
    679 			break;
    680 		if (mc->un.value.num_channels == 1)
    681 			sc->sc_volume[WM8731_OP_MIC].left =
    682 			    mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
    683 		else
    684 			break;
    685 		wm8731_update_volume(sc, WM8731_OP_MIC);
    686 		error = 0;
    687 		break;
    688 
    689 	case WM8731_MIC_MUTE:
    690 		if (mc->type != AUDIO_MIXER_ENUM)
    691 			break;
    692 		UNMUTE(sc, WM8731_OP_MIC, mc->un.ord ? 1 : 0);
    693 		wm8731_update_mutes(sc, 2);
    694 		error = 0;
    695 		break;
    696 
    697 	case WM8731_RECORD_SOURCE:
    698 		if (mc->type != AUDIO_MIXER_ENUM)
    699 			break;
    700 		if (mc->un.ord != 0)
    701 			break;
    702 		/* MIC only */
    703 		error = 0;
    704 		break;
    705 	}
    706 
    707 	iic_release_bus(sc->sc_i2c, 0);
    708 	splx(s);
    709 
    710 	return error;
    711 }
    712 
    713 static int
    714 wm8731_get_port(void *hdl, struct mixer_ctrl *mc)
    715 {
    716 	struct zaudio_softc *sc = hdl;
    717 	int error = EINVAL;
    718 
    719 	switch (mc->dev) {
    720 	case WM8731_SPKR_LVL:
    721 		if (mc->type != AUDIO_MIXER_VALUE)
    722 			break;
    723 		if (mc->un.value.num_channels == 1)
    724 			mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
    725 			    sc->sc_volume[WM8731_OP_SPKR].left;
    726 		else if (mc->un.value.num_channels == 2) {
    727 			mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
    728 			    sc->sc_volume[WM8731_OP_SPKR].left;
    729 			mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
    730 			    sc->sc_volume[WM8731_OP_SPKR].right;
    731 		}
    732 		else
    733 			break;
    734 		error = 0;
    735 		break;
    736 
    737 	case WM8731_SPKR_MUTE:
    738 		if (mc->type != AUDIO_MIXER_ENUM)
    739 			break;
    740 		mc->un.ord = sc->sc_unmute[WM8731_OP_SPKR] ? 1 : 0;
    741 		error = 0;
    742 		break;
    743 
    744 	case WM8731_MIC_LVL:
    745 		if (mc->type != AUDIO_MIXER_VALUE)
    746 			break;
    747 		if (mc->un.value.num_channels == 1)
    748 			mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
    749 			    sc->sc_volume[WM8731_OP_MIC].left;
    750 		else
    751 			break;
    752 		error = 0;
    753 		break;
    754 
    755 	case WM8731_MIC_MUTE:
    756 		if (mc->type != AUDIO_MIXER_ENUM)
    757 			break;
    758 		mc->un.ord = sc->sc_unmute[WM8731_OP_MIC] ? 1 : 0;
    759 		error = 0;
    760 		break;
    761 
    762 	case WM8731_RECORD_SOURCE:
    763 		if (mc->type != AUDIO_MIXER_ENUM)
    764 			break;
    765 		mc->un.ord = 0; /* MIC only */
    766 		error = 0;
    767 		break;
    768 	}
    769 
    770 	return error;
    771 }
    772 
    773 /*ARGSUSED*/
    774 static int
    775 wm8731_query_devinfo(void *hdl, struct mixer_devinfo *di)
    776 {
    777 
    778 	switch (di->index) {
    779 	case WM8731_SPKR_LVL:
    780 		di->type = AUDIO_MIXER_VALUE;
    781 		di->mixer_class = WM8731_OUTPUT_CLASS;
    782 		di->prev = AUDIO_MIXER_LAST;
    783 		di->next = WM8731_SPKR_MUTE;
    784 		strlcpy(di->label.name, AudioNspeaker,
    785 		    sizeof(di->label.name));
    786 		di->un.v.num_channels = 1;
    787 		strlcpy(di->un.v.units.name, AudioNvolume,
    788 		    sizeof(di->un.v.units.name));
    789 		break;
    790 
    791 	case WM8731_SPKR_MUTE:
    792 		di->type = AUDIO_MIXER_ENUM;
    793 		di->mixer_class = WM8731_OUTPUT_CLASS;
    794 		di->prev = WM8731_SPKR_LVL;
    795 		di->next = AUDIO_MIXER_LAST;
    796 mute:
    797 		strlcpy(di->label.name, AudioNmute, sizeof(di->label.name));
    798 		di->un.e.num_mem = 2;
    799 		strlcpy(di->un.e.member[0].label.name, AudioNon,
    800 		    sizeof(di->un.e.member[0].label.name));
    801 		di->un.e.member[0].ord = 0;
    802 		strlcpy(di->un.e.member[1].label.name, AudioNoff,
    803 		    sizeof(di->un.e.member[1].label.name));
    804 		di->un.e.member[1].ord = 1;
    805 		break;
    806 
    807 	case WM8731_MIC_LVL:
    808 		di->type = AUDIO_MIXER_VALUE;
    809 		di->mixer_class = WM8731_INPUT_CLASS;
    810 		di->prev = AUDIO_MIXER_LAST;
    811 		di->next = WM8731_MIC_MUTE;
    812 		strlcpy(di->label.name, AudioNmicrophone,
    813 		    sizeof(di->label.name));
    814 		strlcpy(di->un.v.units.name, AudioNvolume,
    815 		    sizeof(di->un.v.units.name));
    816 		di->un.v.num_channels = 1;
    817 		break;
    818 
    819 	case WM8731_MIC_MUTE:
    820 		di->type = AUDIO_MIXER_ENUM;
    821 		di->mixer_class = WM8731_INPUT_CLASS;
    822 		di->prev = WM8731_MIC_LVL;
    823 		di->next = AUDIO_MIXER_LAST;
    824 		goto mute;
    825 
    826 	case WM8731_RECORD_SOURCE:
    827 		di->type = AUDIO_MIXER_ENUM;
    828 		di->mixer_class = WM8731_RECORD_CLASS;
    829 		di->prev = AUDIO_MIXER_LAST;
    830 		di->next = AUDIO_MIXER_LAST;
    831 		strlcpy(di->label.name, AudioNsource, sizeof(di->label.name));
    832 		di->un.e.num_mem = 1;
    833 		strlcpy(di->un.e.member[0].label.name, AudioNmicrophone,
    834 		    sizeof(di->un.e.member[0].label.name));
    835 		di->un.e.member[0].ord = 0;
    836 		break;
    837 
    838 	case WM8731_OUTPUT_CLASS:
    839 		di->type = AUDIO_MIXER_CLASS;
    840 		di->mixer_class = WM8731_OUTPUT_CLASS;
    841 		di->prev = AUDIO_MIXER_LAST;
    842 		di->next = AUDIO_MIXER_LAST;
    843 		strlcpy(di->label.name, AudioCoutputs, sizeof(di->label.name));
    844 		break;
    845 
    846 	case WM8731_INPUT_CLASS:
    847 		di->type = AUDIO_MIXER_CLASS;
    848 		di->mixer_class = WM8731_INPUT_CLASS;
    849 		di->prev = AUDIO_MIXER_LAST;
    850 		di->next = AUDIO_MIXER_LAST;
    851 		strlcpy(di->label.name, AudioCinputs, sizeof(di->label.name));
    852 		break;
    853 
    854 	case WM8731_RECORD_CLASS:
    855 		di->type = AUDIO_MIXER_CLASS;
    856 		di->mixer_class = WM8731_RECORD_CLASS;
    857 		di->prev = AUDIO_MIXER_LAST;
    858 		di->next = AUDIO_MIXER_LAST;
    859 		strlcpy(di->label.name, AudioCinputs, sizeof(di->label.name));
    860 		break;
    861 
    862 	default:
    863 		return ENXIO;
    864 	}
    865 
    866 	return 0;
    867 }
    868 
    869 static int
    870 wm8731_start_output(void *hdl, void *block, int bsize, void (*intr)(void *),
    871     void *intrarg)
    872 {
    873 	struct zaudio_softc *sc = hdl;
    874 	int rv;
    875 
    876 	/* Power up codec if we are not already playing. */
    877 	if (!sc->sc_playing) {
    878 		sc->sc_playing = 1;
    879 		wm8731_play_setup(sc);
    880 	}
    881 
    882 	/* Start DMA via I2S */
    883 	rv = pxa2x0_i2s_start_output(&sc->sc_i2s, block, bsize, intr, intrarg);
    884 	if (rv) {
    885 		if (!sc->sc_recording)
    886 			wm8731_standby(sc);
    887 		sc->sc_playing = 0;
    888 	}
    889 
    890 	return rv;
    891 }
    892 
    893 static int
    894 wm8731_start_input(void *hdl, void *block, int bsize, void (*intr)(void *),
    895     void *intrarg)
    896 {
    897 	struct zaudio_softc *sc = hdl;
    898 	int rv;
    899 
    900 	/* Power up codec if we are not already recording. */
    901 	if (!sc->sc_recording) {
    902 		sc->sc_recording = 1;
    903 		wm8731_record_setup(sc);
    904 	}
    905 
    906 	/* Start DMA via I2S */
    907 	rv = pxa2x0_i2s_start_input(&sc->sc_i2s, block, bsize, intr, intrarg);
    908 	if (rv) {
    909 		if (!sc->sc_playing)
    910 			wm8731_standby(sc);
    911 		sc->sc_recording = 0;
    912 	}
    913 	return rv;
    914 }
    915