xref: /netbsd-src/sys/arch/zaurus/dev/wm8731_zaudio.c (revision e622eac459adf11c2e710d7a4de0f05510bbbe61)
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
wm8731_write(struct zaudio_softc * sc,int reg,int val)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
wm8731_match(device_t parent,cfdata_t cf,struct i2c_attach_args * ia)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
wm8731_attach(device_t parent,device_t self,struct i2c_attach_args * ia)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
wm8731_finalize(device_t dv)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
wm8731_suspend(device_t dv,const pmf_qual_t * qual)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
wm8731_resume(device_t dv,const pmf_qual_t * qual)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
vol_sadd(int vol,int stride)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
wm8731_volume_up(device_t dv)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
vol_ssub(int vol,int stride)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
wm8731_volume_down(device_t dv)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
wm8731_volume_toggle(device_t dv)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
wm8731_init(struct zaudio_softc * sc)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
wm8731_jack_intr(void * v)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
wm8731_jack(void * v)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
wm8731_standby(struct zaudio_softc * sc)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
wm8731_update_volume(struct zaudio_softc * sc,int output)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
wm8731_update_mutes(struct zaudio_softc * sc,int mask)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
wm8731_play_setup(struct zaudio_softc * sc)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
wm8731_record_setup(struct zaudio_softc * sc)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
wm8731_halt_output(void * hdl)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
wm8731_halt_input(void * hdl)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
wm8731_getdev(void * hdl,struct audio_device * ret)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
wm8731_set_port(void * hdl,struct mixer_ctrl * mc)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
wm8731_get_port(void * hdl,struct mixer_ctrl * mc)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
wm8731_query_devinfo(void * hdl,struct mixer_devinfo * di)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
wm8731_start_output(void * hdl,void * block,int bsize,void (* intr)(void *),void * intrarg)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
wm8731_start_input(void * hdl,void * block,int bsize,void (* intr)(void *),void * intrarg)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