Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / arch / zaurus / dev / zaudio.c
blobb1ad5e0b09a3a7f662c4af4f488efeefe9948453
1 /* $NetBSD: zaudio.c,v 1.10 2009/04/18 05:20:21 nonaka Exp $ */
2 /* $OpenBSD: zaurus_audio.c,v 1.8 2005/08/18 13:23:02 robert Exp $ */
4 /*
5 * Copyright (c) 2005 Christopher Pascoe <pascoe@openbsd.org>
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 /*-
21 * Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org>
22 * All rights reserved.
24 * Redistribution and use in source and binary forms, with or without
25 * modification, are permitted provided that the following conditions
26 * are met:
27 * 1. Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the following disclaimer.
29 * 2. Redistributions in binary form must reproduce the above copyright
30 * notice, this list of conditions and the following disclaimer in the
31 * documentation and/or other materials provided with the distribution.
33 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
34 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
37 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 * SUCH DAMAGE.
47 * TODO:
48 * - powerhooks (currently only works until first suspend)
51 #include <sys/cdefs.h>
52 __KERNEL_RCSID(0, "$NetBSD: zaudio.c,v 1.10 2009/04/18 05:20:21 nonaka Exp $");
54 #include <sys/param.h>
55 #include <sys/systm.h>
56 #include <sys/callout.h>
57 #include <sys/device.h>
58 #include <sys/malloc.h>
59 #include <sys/kernel.h>
60 #include <sys/audioio.h>
62 #include <machine/intr.h>
63 #include <machine/bus.h>
65 #include <arm/xscale/pxa2x0reg.h>
66 #include <arm/xscale/pxa2x0var.h>
67 #include <arm/xscale/pxa2x0_i2c.h>
68 #include <arm/xscale/pxa2x0_i2s.h>
69 #include <arm/xscale/pxa2x0_dmac.h>
70 #include <arm/xscale/pxa2x0_gpio.h>
72 #include <dev/audio_if.h>
73 #include <dev/mulaw.h>
74 #include <dev/auconv.h>
76 #include <zaurus/dev/wm8750reg.h>
77 #include <zaurus/dev/scoopvar.h>
79 #define WM8750_ADDRESS 0x1B
81 #define wm8750_write(sc, reg, val) \
82 pxa2x0_i2c_write_2(&sc->sc_i2c, WM8750_ADDRESS, \
83 (((reg) << 9) | ((val) & 0x1ff)))
85 static int zaudio_match(device_t, cfdata_t, void *);
86 static void zaudio_attach(device_t, device_t, void *);
87 static bool zaudio_suspend(device_t dv, pmf_qual_t);
88 static bool zaudio_resume(device_t dv, pmf_qual_t);
90 #define ZAUDIO_OP_SPKR 0
91 #define ZAUDIO_OP_HP 1
92 #define ZAUDIO_OP_MIC 2
93 #define ZAUDIO_OP_NUM 3
95 #define ZAUDIO_JACK_STATE_OUT 0
96 #define ZAUDIO_JACK_STATE_IN 1
97 #define ZAUDIO_JACK_STATE_INS 2
98 #define ZAUDIO_JACK_STATE_REM 3
100 /* GPIO pins */
101 #define GPIO_HP_IN_C3000 116
103 struct zaudio_volume {
104 u_int8_t left;
105 u_int8_t right;
108 struct zaudio_softc {
109 device_t sc_dev;
111 /* i2s device softc */
112 /* NB: pxa2x0_i2s requires this to be the second struct member */
113 struct pxa2x0_i2s_softc sc_i2s;
115 /* i2c device softc */
116 struct pxa2x0_i2c_softc sc_i2c;
118 int sc_playing;
119 int sc_recording;
121 struct zaudio_volume sc_volume[ZAUDIO_OP_NUM];
122 char sc_unmute[ZAUDIO_OP_NUM];
124 int sc_state;
125 int sc_icount;
126 struct callout sc_to;
129 CFATTACH_DECL_NEW(zaudio, sizeof(struct zaudio_softc),
130 zaudio_match, zaudio_attach, NULL, NULL);
132 static struct audio_device wm8750_device = {
133 "WM8750",
134 "1.0",
135 "wm"
138 static const struct audio_format zaudio_formats[] = {
140 .driver_data = NULL,
141 .mode = AUMODE_PLAY | AUMODE_RECORD,
142 .encoding = AUDIO_ENCODING_SLINEAR_LE,
143 .validbits = 16,
144 .precision = 16,
145 .channels = 2,
146 .channel_mask = AUFMT_STEREO,
147 .frequency_type = 0,
148 .frequency = { 4000, 48000 }
151 .driver_data = NULL,
152 .mode = AUMODE_PLAY | AUMODE_RECORD,
153 .encoding = AUDIO_ENCODING_SLINEAR_LE,
154 .validbits = 16,
155 .precision = 16,
156 .channels = 1,
157 .channel_mask = AUFMT_MONAURAL,
158 .frequency_type = 0,
159 .frequency = { 4000, 48000 }
162 .driver_data = NULL,
163 .mode = AUMODE_PLAY | AUMODE_RECORD,
164 .encoding = AUDIO_ENCODING_ULINEAR_LE,
165 .validbits = 8,
166 .precision = 8,
167 .channels = 2,
168 .channel_mask = AUFMT_STEREO,
169 .frequency_type = 0,
170 .frequency = { 4000, 48000 }
173 .driver_data = NULL,
174 .mode = AUMODE_PLAY | AUMODE_RECORD,
175 .encoding = AUDIO_ENCODING_ULINEAR_LE,
176 .validbits = 8,
177 .precision = 8,
178 .channels = 1,
179 .channel_mask = AUFMT_MONAURAL,
180 .frequency_type = 0,
181 .frequency = { 4000, 48000 }
184 static const int zaudio_nformats = (int)__arraycount(zaudio_formats);
186 static void zaudio_init(struct zaudio_softc *);
187 static int zaudio_jack_intr(void *);
188 static void zaudio_jack(void *);
189 static void zaudio_standby(struct zaudio_softc *);
190 static void zaudio_update_volume(struct zaudio_softc *, int);
191 static void zaudio_update_mutes(struct zaudio_softc *, int);
192 static void zaudio_play_setup(struct zaudio_softc *);
193 /*static*/ void zaudio_record_setup(struct zaudio_softc *);
194 static int zaudio_open(void *, int);
195 static void zaudio_close(void *);
196 static int zaudio_query_encoding(void *, struct audio_encoding *);
197 static int zaudio_set_params(void *, int, int, audio_params_t *,
198 audio_params_t *, stream_filter_list_t *, stream_filter_list_t *);
199 static int zaudio_round_blocksize(void *, int, int, const audio_params_t *);
200 static int zaudio_start_output(void *, void *, int, void (*)(void *), void *);
201 static int zaudio_start_input(void *, void *, int, void (*)(void *), void *);
202 static int zaudio_halt_output(void *);
203 static int zaudio_halt_input(void *);
204 static int zaudio_getdev(void *, struct audio_device *);
205 static int zaudio_set_port(void *, struct mixer_ctrl *);
206 static int zaudio_get_port(void *, struct mixer_ctrl *);
207 static int zaudio_query_devinfo(void *, struct mixer_devinfo *);
208 static void *zaudio_allocm(void *, int, size_t, struct malloc_type *, int);
209 static void zaudio_freem(void *, void *, struct malloc_type *);
210 static size_t zaudio_round_buffersize(void *, int, size_t);
211 static paddr_t zaudio_mappage(void *, void *, off_t, int);
212 static int zaudio_get_props(void *);
214 struct audio_hw_if wm8750_hw_if = {
215 .open = zaudio_open,
216 .close = zaudio_close,
217 .drain = NULL,
218 .query_encoding = zaudio_query_encoding,
219 .set_params = zaudio_set_params,
220 .round_blocksize = zaudio_round_blocksize,
221 .commit_settings = NULL,
222 .init_output = NULL,
223 .init_input = NULL,
224 .start_output = zaudio_start_output,
225 .start_input = zaudio_start_input,
226 .halt_output = zaudio_halt_output,
227 .halt_input = zaudio_halt_input,
228 .speaker_ctl = NULL,
229 .getdev = zaudio_getdev,
230 .setfd = NULL,
231 .set_port = zaudio_set_port,
232 .get_port = zaudio_get_port,
233 .query_devinfo = zaudio_query_devinfo,
234 .allocm = zaudio_allocm,
235 .freem = zaudio_freem,
236 .round_buffersize = zaudio_round_buffersize,
237 .mappage = zaudio_mappage,
238 .get_props = zaudio_get_props,
239 .trigger_output = NULL,
240 .trigger_input = NULL,
241 .dev_ioctl = NULL,
242 .powerstate = NULL,
245 static const uint16_t playback_regs[][2] = {
246 /* Unmute DAC */
247 { ADCDACCTL_REG, 0x000 },
249 /* 16 bit audio words */
250 { AUDINT_REG, AUDINT_SET_FORMAT(2) },
252 /* Enable thermal protection, power */
253 { ADCTL1_REG, ADCTL1_TSDEN | ADCTL1_SET_VSEL(3) },
255 /* Enable speaker driver, DAC oversampling */
256 { ADCTL2_REG, ADCTL2_ROUT2INV | ADCTL2_DACOSR },
258 /* Set DAC voltage references */
259 { PWRMGMT1_REG, PWRMGMT1_SET_VMIDSEL(1) | PWRMGMT1_VREF },
261 /* Direct DACs to output mixers */
262 { LOUTMIX1_REG, LOUTMIX1_LD2LO },
263 { LOUTMIX2_REG, 0x000 },
264 { ROUTMIX1_REG, 0x000 },
265 { ROUTMIX2_REG, ROUTMIX2_RD2RO },
267 /* End of list */
268 { 0xffff, 0xffff }
271 static const uint16_t record_regs[][2] = {
272 /* Unmute DAC */
273 { ADCDACCTL_REG, 0x000 },
275 /* 16 bit audio words */
276 { AUDINT_REG, AUDINT_SET_FORMAT(2) },
278 /* Enable thermal protection, power, left DAC for both channel */
279 { ADCTL1_REG, ADCTL1_TSDEN | ADCTL1_SET_VSEL(3)
280 | ADCTL1_SET_DATSEL(1) },
282 /* Diffrential input select: LINPUT1-RINPUT1, stereo */
283 { ADCINPMODE_REG, 0x000 },
285 /* L-R differential, micboost 20dB */
286 { ADCLSPATH_REG, ADCLSPATH_SET_LINSEL(3) | ADCLSPATH_SET_LMICBOOST(2) },
287 { ADCRSPATH_REG, ADCRSPATH_SET_RINSEL(3) | ADCRSPATH_SET_RMICBOOST(2) },
289 /* End of list */
290 { 0xffff, 0xffff }
293 static int
294 zaudio_match(device_t parent, cfdata_t cf, void *aux)
297 return 1;
300 static void
301 zaudio_attach(device_t parent, device_t self, void *aux)
303 struct zaudio_softc *sc = device_private(self);
304 struct pxaip_attach_args *pxa = aux;
305 int rv;
307 sc->sc_dev = self;
309 aprint_normal(": I2C, I2S, WM8750 Audio\n");
310 aprint_naive("\n");
312 if (!pmf_device_register(sc->sc_dev, zaudio_suspend, zaudio_resume))
313 aprint_error_dev(sc->sc_dev,
314 "couldn't establish power handler\n");
316 sc->sc_i2s.sc_iot = pxa->pxa_iot;
317 sc->sc_i2s.sc_dmat = pxa->pxa_dmat;
318 sc->sc_i2s.sc_size = PXA2X0_I2S_SIZE;
319 if (pxa2x0_i2s_attach_sub(&sc->sc_i2s)) {
320 aprint_error_dev(sc->sc_dev, "unable to attach I2S\n");
321 goto fail_i2s;
324 sc->sc_i2c.sc_iot = pxa->pxa_iot;
325 sc->sc_i2c.sc_size = PXA2X0_I2C_SIZE;
326 if (pxa2x0_i2c_attach_sub(&sc->sc_i2c)) {
327 aprint_error_dev(sc->sc_dev, "unable to attach I2C\n");
328 goto fail_i2c;
331 /* Check for an I2C response from the wm8750 */
332 pxa2x0_i2c_open(&sc->sc_i2c);
333 rv = wm8750_write(sc, RESET_REG, 0);
334 pxa2x0_i2c_close(&sc->sc_i2c);
335 if (rv) {
336 aprint_error_dev(sc->sc_dev, "codec failed to respond\n");
337 goto fail_probe;
339 delay(100);
341 /* Speaker on, headphones off by default. */
342 sc->sc_volume[ZAUDIO_OP_SPKR].left = 240;
343 sc->sc_unmute[ZAUDIO_OP_SPKR] = 1;
344 sc->sc_volume[ZAUDIO_OP_HP].left = 180;
345 sc->sc_volume[ZAUDIO_OP_HP].right = 180;
346 sc->sc_unmute[ZAUDIO_OP_HP] = 0;
347 sc->sc_volume[ZAUDIO_OP_MIC].left = 240;
348 sc->sc_unmute[ZAUDIO_OP_MIC] = 0;
350 /* Configure headphone jack state change handling. */
351 callout_init(&sc->sc_to, 0);
352 callout_setfunc(&sc->sc_to, zaudio_jack, sc);
353 pxa2x0_gpio_set_function(GPIO_HP_IN_C3000, GPIO_IN);
354 (void) pxa2x0_gpio_intr_establish(GPIO_HP_IN_C3000, IST_EDGE_BOTH,
355 IPL_BIO, zaudio_jack_intr, sc);
357 zaudio_init(sc);
359 audio_attach_mi(&wm8750_hw_if, sc, sc->sc_dev);
361 return;
363 fail_probe:
364 pxa2x0_i2c_detach_sub(&sc->sc_i2c);
365 fail_i2c:
366 pxa2x0_i2s_detach_sub(&sc->sc_i2s);
367 fail_i2s:
368 pmf_device_deregister(self);
371 static bool
372 zaudio_suspend(device_t dv, pmf_qual_t qual)
374 struct zaudio_softc *sc = device_private(dv);
376 callout_stop(&sc->sc_to);
377 zaudio_standby(sc);
379 return true;
382 static bool
383 zaudio_resume(device_t dv, pmf_qual_t qual)
385 struct zaudio_softc *sc = device_private(dv);
387 pxa2x0_i2s_init(&sc->sc_i2s);
388 pxa2x0_i2c_init(&sc->sc_i2c);
389 zaudio_init(sc);
391 return true;
394 static void
395 zaudio_init(struct zaudio_softc *sc)
398 pxa2x0_i2c_open(&sc->sc_i2c);
400 /* Reset the codec */
401 wm8750_write(sc, RESET_REG, 0);
402 delay(100);
404 /* Switch to standby power only */
405 wm8750_write(sc, PWRMGMT1_REG, PWRMGMT1_SET_VMIDSEL(2));
406 wm8750_write(sc, PWRMGMT2_REG, 0);
408 /* Configure digital interface for I2S */
409 wm8750_write(sc, AUDINT_REG, AUDINT_SET_FORMAT(2));
411 /* Initialise volume levels */
412 zaudio_update_volume(sc, ZAUDIO_OP_SPKR);
413 zaudio_update_volume(sc, ZAUDIO_OP_HP);
414 zaudio_update_volume(sc, ZAUDIO_OP_MIC);
416 pxa2x0_i2c_close(&sc->sc_i2c);
418 scoop_set_headphone(0);
419 scoop_set_mic_bias(0);
421 /* Assume that the jack state has changed. */
422 zaudio_jack(sc);
425 static int
426 zaudio_jack_intr(void *v)
428 struct zaudio_softc *sc = v;
430 if (!callout_active(&sc->sc_to))
431 zaudio_jack(sc);
433 return 1;
436 static void
437 zaudio_jack(void *v)
439 struct zaudio_softc *sc = v;
441 switch (sc->sc_state) {
442 case ZAUDIO_JACK_STATE_OUT:
443 if (pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) {
444 sc->sc_state = ZAUDIO_JACK_STATE_INS;
445 sc->sc_icount = 0;
447 break;
449 case ZAUDIO_JACK_STATE_INS:
450 if (sc->sc_icount++ > 2) {
451 if (pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) {
452 sc->sc_state = ZAUDIO_JACK_STATE_IN;
453 sc->sc_unmute[ZAUDIO_OP_SPKR] = 0;
454 sc->sc_unmute[ZAUDIO_OP_HP] = 1;
455 sc->sc_unmute[ZAUDIO_OP_MIC] = 1;
456 goto update_mutes;
457 } else
458 sc->sc_state = ZAUDIO_JACK_STATE_OUT;
460 break;
462 case ZAUDIO_JACK_STATE_IN:
463 if (!pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) {
464 sc->sc_state = ZAUDIO_JACK_STATE_REM;
465 sc->sc_icount = 0;
467 break;
469 case ZAUDIO_JACK_STATE_REM:
470 if (sc->sc_icount++ > 2) {
471 if (!pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) {
472 sc->sc_state = ZAUDIO_JACK_STATE_OUT;
473 sc->sc_unmute[ZAUDIO_OP_SPKR] = 1;
474 sc->sc_unmute[ZAUDIO_OP_HP] = 0;
475 sc->sc_unmute[ZAUDIO_OP_MIC] = 0;
476 goto update_mutes;
477 } else
478 sc->sc_state = ZAUDIO_JACK_STATE_IN;
480 break;
483 callout_schedule(&sc->sc_to, hz/4);
485 return;
487 update_mutes:
488 callout_stop(&sc->sc_to);
490 if (sc->sc_playing || sc->sc_recording) {
491 pxa2x0_i2c_open(&sc->sc_i2c);
492 if (sc->sc_playing)
493 zaudio_update_mutes(sc, 1);
494 if (sc->sc_recording)
495 zaudio_update_mutes(sc, 2);
496 pxa2x0_i2c_close(&sc->sc_i2c);
500 static void
501 zaudio_standby(struct zaudio_softc *sc)
504 pxa2x0_i2c_open(&sc->sc_i2c);
506 /* Switch codec to standby power only */
507 wm8750_write(sc, PWRMGMT1_REG, PWRMGMT1_SET_VMIDSEL(2));
508 wm8750_write(sc, PWRMGMT2_REG, 0);
510 pxa2x0_i2c_close(&sc->sc_i2c);
512 scoop_set_headphone(0);
513 scoop_set_mic_bias(0);
516 static void
517 zaudio_update_volume(struct zaudio_softc *sc, int output)
520 switch (output) {
521 case ZAUDIO_OP_SPKR:
522 wm8750_write(sc, LOUT2VOL_REG, LOUT2VOL_LO2VU | LOUT2VOL_LO2ZC |
523 LOUT2VOL_SET_LOUT2VOL(sc->sc_volume[ZAUDIO_OP_SPKR].left >> 1));
524 wm8750_write(sc, ROUT2VOL_REG, ROUT2VOL_RO2VU | ROUT2VOL_RO2ZC |
525 ROUT2VOL_SET_ROUT2VOL(sc->sc_volume[ZAUDIO_OP_SPKR].left >> 1));
526 break;
528 case ZAUDIO_OP_HP:
529 wm8750_write(sc, LOUT1VOL_REG, LOUT1VOL_LO1VU | LOUT1VOL_LO1ZC |
530 LOUT1VOL_SET_LOUT1VOL(sc->sc_volume[ZAUDIO_OP_HP].left >> 1));
531 wm8750_write(sc, ROUT1VOL_REG, ROUT1VOL_RO1VU | ROUT1VOL_RO1ZC |
532 ROUT1VOL_SET_ROUT1VOL(sc->sc_volume[ZAUDIO_OP_HP].right >> 1));
533 break;
535 case ZAUDIO_OP_MIC:
536 wm8750_write(sc, LINVOL_REG, LINVOL_LIVU |
537 LINVOL_SET_LINVOL(sc->sc_volume[ZAUDIO_OP_MIC].left >> 2));
538 wm8750_write(sc, RINVOL_REG, RINVOL_RIVU |
539 RINVOL_SET_RINVOL(sc->sc_volume[ZAUDIO_OP_MIC].left >> 2));
540 break;
544 static void
545 zaudio_update_mutes(struct zaudio_softc *sc, int mask)
547 uint16_t val;
549 /* playback */
550 if (mask & 1) {
551 val = PWRMGMT2_DACL | PWRMGMT2_DACR;
552 if (sc->sc_unmute[ZAUDIO_OP_SPKR])
553 val |= PWRMGMT2_LOUT2 | PWRMGMT2_ROUT2;
554 if (sc->sc_unmute[ZAUDIO_OP_HP])
555 val |= PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1;
556 wm8750_write(sc, PWRMGMT2_REG, val);
557 scoop_set_headphone(sc->sc_unmute[ZAUDIO_OP_HP]);
560 /* record */
561 if (mask & 2) {
562 val = PWRMGMT1_SET_VMIDSEL(1) | PWRMGMT1_VREF;
563 if (sc->sc_unmute[ZAUDIO_OP_MIC]) {
564 val |= PWRMGMT1_AINL | PWRMGMT1_AINR
565 | PWRMGMT1_ADCL | PWRMGMT1_ADCR | PWRMGMT1_MICB;
567 wm8750_write(sc, PWRMGMT1_REG, val);
568 scoop_set_mic_bias(sc->sc_unmute[ZAUDIO_OP_MIC]);
572 static void
573 zaudio_play_setup(struct zaudio_softc *sc)
575 int i;
577 pxa2x0_i2c_open(&sc->sc_i2c);
579 /* Program the codec with playback settings */
580 for (i = 0; playback_regs[i][0] != 0xffff; i++) {
581 wm8750_write(sc, playback_regs[i][0], playback_regs[i][1]);
583 zaudio_update_mutes(sc, 1);
585 pxa2x0_i2c_close(&sc->sc_i2c);
588 /*static*/ void
589 zaudio_record_setup(struct zaudio_softc *sc)
591 int i;
593 pxa2x0_i2c_open(&sc->sc_i2c);
595 /* Program the codec with playback settings */
596 for (i = 0; record_regs[i][0] != 0xffff; i++) {
597 wm8750_write(sc, record_regs[i][0], record_regs[i][1]);
600 zaudio_update_mutes(sc, 2);
602 pxa2x0_i2c_close(&sc->sc_i2c);
606 * audio operation functions.
608 static int
609 zaudio_open(void *hdl, int flags)
611 struct zaudio_softc *sc = hdl;
613 /* Power on the I2S bus and codec */
614 pxa2x0_i2s_open(&sc->sc_i2s);
616 return 0;
619 static void
620 zaudio_close(void *hdl)
622 struct zaudio_softc *sc = hdl;
624 /* Power off the I2S bus and codec */
625 pxa2x0_i2s_close(&sc->sc_i2s);
628 static int
629 zaudio_query_encoding(void *hdl, struct audio_encoding *aep)
632 switch (aep->index) {
633 case 0:
634 strlcpy(aep->name, AudioEulinear, sizeof(aep->name));
635 aep->encoding = AUDIO_ENCODING_ULINEAR;
636 aep->precision = 8;
637 aep->flags = 0;
638 break;
640 case 1:
641 strlcpy(aep->name, AudioEmulaw, sizeof(aep->name));
642 aep->encoding = AUDIO_ENCODING_ULAW;
643 aep->precision = 8;
644 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
645 break;
647 case 2:
648 strlcpy(aep->name, AudioEalaw, sizeof(aep->name));
649 aep->encoding = AUDIO_ENCODING_ALAW;
650 aep->precision = 8;
651 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
652 break;
654 case 3:
655 strlcpy(aep->name, AudioEslinear, sizeof(aep->name));
656 aep->encoding = AUDIO_ENCODING_SLINEAR;
657 aep->precision = 8;
658 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
659 break;
661 case 4:
662 strlcpy(aep->name, AudioEslinear_le, sizeof(aep->name));
663 aep->encoding = AUDIO_ENCODING_SLINEAR_LE;
664 aep->precision = 16;
665 aep->flags = 0;
666 break;
668 case 5:
669 strlcpy(aep->name, AudioEulinear_le, sizeof(aep->name));
670 aep->encoding = AUDIO_ENCODING_ULINEAR_LE;
671 aep->precision = 16;
672 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
673 break;
675 case 6:
676 strlcpy(aep->name, AudioEslinear_be, sizeof(aep->name));
677 aep->encoding = AUDIO_ENCODING_SLINEAR_BE;
678 aep->precision = 16;
679 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
680 break;
682 case 7:
683 strlcpy(aep->name, AudioEulinear_be, sizeof(aep->name));
684 aep->encoding = AUDIO_ENCODING_ULINEAR_BE;
685 aep->precision = 16;
686 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
687 break;
689 default:
690 return EINVAL;
693 return 0;
696 static int
697 zaudio_set_params(void *hdl, int setmode, int usemode,
698 audio_params_t *play, audio_params_t *rec,
699 stream_filter_list_t *pfil, stream_filter_list_t *rfil)
701 struct zaudio_softc *sc = hdl;
702 struct audio_params *p;
703 stream_filter_list_t *fil;
704 int mode, i;
706 if (play->sample_rate != rec->sample_rate &&
707 usemode == (AUMODE_PLAY | AUMODE_RECORD)) {
708 if (setmode == AUMODE_PLAY) {
709 rec->sample_rate = play->sample_rate;
710 setmode |= AUMODE_RECORD;
711 } else if (setmode == AUMODE_RECORD) {
712 play->sample_rate = rec->sample_rate;
713 setmode |= AUMODE_PLAY;
714 } else
715 return EINVAL;
718 for (mode = AUMODE_RECORD; mode != -1;
719 mode = (mode == AUMODE_RECORD) ? AUMODE_PLAY : -1) {
720 if ((setmode & mode) == 0)
721 continue;
723 p = (mode == AUMODE_PLAY) ? play : rec;
725 if (p->sample_rate < 4000 || p->sample_rate > 48000 ||
726 (p->precision != 8 && p->precision != 16) ||
727 (p->channels != 1 && p->channels != 2))
728 return EINVAL;
730 fil = (mode == AUMODE_PLAY) ? pfil : rfil;
731 i = auconv_set_converter(zaudio_formats, zaudio_nformats,
732 mode, p, false, fil);
733 if (i < 0)
734 return EINVAL;
737 if (setmode == AUMODE_RECORD)
738 pxa2x0_i2s_setspeed(&sc->sc_i2s, &rec->sample_rate);
739 else
740 pxa2x0_i2s_setspeed(&sc->sc_i2s, &play->sample_rate);
742 return 0;
745 static int
746 zaudio_round_blocksize(void *hdl, int bs, int mode, const audio_params_t *param)
748 struct zaudio_softc *sc = hdl;
750 return pxa2x0_i2s_round_blocksize(&sc->sc_i2s, bs, mode, param);
754 static int
755 zaudio_halt_output(void *hdl)
757 struct zaudio_softc *sc = hdl;
758 int rv;
760 rv = pxa2x0_i2s_halt_output(&sc->sc_i2s);
761 if (!sc->sc_recording)
762 zaudio_standby(sc);
763 sc->sc_playing = 0;
765 return rv;
768 static int
769 zaudio_halt_input(void *hdl)
771 struct zaudio_softc *sc = hdl;
772 int rv;
774 rv = pxa2x0_i2s_halt_input(&sc->sc_i2s);
775 if (!sc->sc_playing)
776 zaudio_standby(sc);
777 sc->sc_recording = 0;
779 return rv;
782 static int
783 zaudio_getdev(void *hdl, struct audio_device *ret)
786 *ret = wm8750_device;
787 return 0;
790 #define ZAUDIO_SPKR_LVL 0
791 #define ZAUDIO_SPKR_MUTE 1
792 #define ZAUDIO_HP_LVL 2
793 #define ZAUDIO_HP_MUTE 3
794 #define ZAUDIO_MIC_LVL 4
795 #define ZAUDIO_MIC_MUTE 5
796 #define ZAUDIO_RECORD_SOURCE 6
797 #define ZAUDIO_OUTPUT_CLASS 7
798 #define ZAUDIO_INPUT_CLASS 8
799 #define ZAUDIO_RECORD_CLASS 9
801 static int
802 zaudio_set_port(void *hdl, struct mixer_ctrl *mc)
804 struct zaudio_softc *sc = hdl;
805 int error = EINVAL;
806 int s;
808 s = splbio();
809 pxa2x0_i2c_open(&sc->sc_i2c);
811 switch (mc->dev) {
812 case ZAUDIO_SPKR_LVL:
813 if (mc->type != AUDIO_MIXER_VALUE)
814 break;
815 if (mc->un.value.num_channels == 1)
816 sc->sc_volume[ZAUDIO_OP_SPKR].left =
817 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
818 else
819 break;
820 zaudio_update_volume(sc, ZAUDIO_OP_SPKR);
821 error = 0;
822 break;
824 case ZAUDIO_SPKR_MUTE:
825 if (mc->type != AUDIO_MIXER_ENUM)
826 break;
827 sc->sc_unmute[ZAUDIO_OP_SPKR] = mc->un.ord ? 1 : 0;
828 zaudio_update_mutes(sc, 1);
829 error = 0;
830 break;
832 case ZAUDIO_HP_LVL:
833 if (mc->type != AUDIO_MIXER_VALUE)
834 break;
835 if (mc->un.value.num_channels == 1) {
836 sc->sc_volume[ZAUDIO_OP_HP].left =
837 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
838 sc->sc_volume[ZAUDIO_OP_HP].right =
839 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
840 } else if (mc->un.value.num_channels == 2) {
841 sc->sc_volume[ZAUDIO_OP_HP].left =
842 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
843 sc->sc_volume[ZAUDIO_OP_HP].right =
844 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
846 else
847 break;
848 zaudio_update_volume(sc, ZAUDIO_OP_HP);
849 error = 0;
850 break;
852 case ZAUDIO_HP_MUTE:
853 if (mc->type != AUDIO_MIXER_ENUM)
854 break;
855 sc->sc_unmute[ZAUDIO_OP_HP] = mc->un.ord ? 1 : 0;
856 zaudio_update_mutes(sc, 1);
857 error = 0;
858 break;
860 case ZAUDIO_MIC_LVL:
861 if (mc->type != AUDIO_MIXER_VALUE)
862 break;
863 if (mc->un.value.num_channels == 1)
864 sc->sc_volume[ZAUDIO_OP_MIC].left =
865 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
866 else
867 break;
868 zaudio_update_volume(sc, ZAUDIO_OP_MIC);
869 error = 0;
870 break;
872 case ZAUDIO_MIC_MUTE:
873 if (mc->type != AUDIO_MIXER_ENUM)
874 break;
875 sc->sc_unmute[ZAUDIO_OP_MIC] = mc->un.ord ? 1 : 0;
876 zaudio_update_mutes(sc, 2);
877 error = 0;
878 break;
880 case ZAUDIO_RECORD_SOURCE:
881 if (mc->type != AUDIO_MIXER_ENUM)
882 break;
883 if (mc->un.ord != 0)
884 break;
885 /* MIC only */
886 error = 0;
887 break;
890 pxa2x0_i2c_close(&sc->sc_i2c);
891 splx(s);
893 return error;
896 static int
897 zaudio_get_port(void *hdl, struct mixer_ctrl *mc)
899 struct zaudio_softc *sc = hdl;
900 int error = EINVAL;
902 switch (mc->dev) {
903 case ZAUDIO_SPKR_LVL:
904 if (mc->type != AUDIO_MIXER_VALUE)
905 break;
906 if (mc->un.value.num_channels == 1)
907 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
908 sc->sc_volume[ZAUDIO_OP_SPKR].left;
909 else
910 break;
911 error = 0;
912 break;
914 case ZAUDIO_SPKR_MUTE:
915 if (mc->type != AUDIO_MIXER_ENUM)
916 break;
917 mc->un.ord = sc->sc_unmute[ZAUDIO_OP_SPKR] ? 1 : 0;
918 error = 0;
919 break;
921 case ZAUDIO_HP_LVL:
922 if (mc->type != AUDIO_MIXER_VALUE)
923 break;
924 if (mc->un.value.num_channels == 1)
925 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
926 sc->sc_volume[ZAUDIO_OP_HP].left;
927 else if (mc->un.value.num_channels == 2) {
928 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
929 sc->sc_volume[ZAUDIO_OP_HP].left;
930 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
931 sc->sc_volume[ZAUDIO_OP_HP].right;
933 else
934 break;
935 error = 0;
936 break;
938 case ZAUDIO_HP_MUTE:
939 if (mc->type != AUDIO_MIXER_ENUM)
940 break;
941 mc->un.ord = sc->sc_unmute[ZAUDIO_OP_HP] ? 1 : 0;
942 error = 0;
943 break;
945 case ZAUDIO_MIC_LVL:
946 if (mc->type != AUDIO_MIXER_VALUE)
947 break;
948 if (mc->un.value.num_channels == 1)
949 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
950 sc->sc_volume[ZAUDIO_OP_MIC].left;
951 else
952 break;
953 error = 0;
954 break;
956 case ZAUDIO_MIC_MUTE:
957 if (mc->type != AUDIO_MIXER_ENUM)
958 break;
959 mc->un.ord = sc->sc_unmute[ZAUDIO_OP_MIC] ? 1 : 0;
960 error = 0;
961 break;
963 case ZAUDIO_RECORD_SOURCE:
964 if (mc->type != AUDIO_MIXER_ENUM)
965 break;
966 mc->un.ord = 0; /* MIC only */
967 error = 0;
968 break;
971 return error;
974 /*ARGSUSED*/
975 static int
976 zaudio_query_devinfo(void *hdl, struct mixer_devinfo *di)
979 switch (di->index) {
980 case ZAUDIO_SPKR_LVL:
981 di->type = AUDIO_MIXER_VALUE;
982 di->mixer_class = ZAUDIO_OUTPUT_CLASS;
983 di->prev = AUDIO_MIXER_LAST;
984 di->next = ZAUDIO_SPKR_MUTE;
985 strlcpy(di->label.name, AudioNspeaker, sizeof(di->label.name));
986 strlcpy(di->un.v.units.name, AudioNvolume,
987 sizeof(di->un.v.units.name));
988 di->un.v.num_channels = 1;
989 break;
991 case ZAUDIO_SPKR_MUTE:
992 di->type = AUDIO_MIXER_ENUM;
993 di->mixer_class = ZAUDIO_OUTPUT_CLASS;
994 di->prev = ZAUDIO_SPKR_LVL;
995 di->next = AUDIO_MIXER_LAST;
996 goto mute;
998 case ZAUDIO_HP_LVL:
999 di->type = AUDIO_MIXER_VALUE;
1000 di->mixer_class = ZAUDIO_OUTPUT_CLASS;
1001 di->prev = AUDIO_MIXER_LAST;
1002 di->next = ZAUDIO_HP_MUTE;
1003 strlcpy(di->label.name, AudioNheadphone,
1004 sizeof(di->label.name));
1005 di->un.v.num_channels = 1;
1006 strlcpy(di->un.v.units.name, AudioNvolume,
1007 sizeof(di->un.v.units.name));
1008 break;
1010 case ZAUDIO_HP_MUTE:
1011 di->type = AUDIO_MIXER_ENUM;
1012 di->mixer_class = ZAUDIO_OUTPUT_CLASS;
1013 di->prev = ZAUDIO_HP_LVL;
1014 di->next = AUDIO_MIXER_LAST;
1015 mute:
1016 strlcpy(di->label.name, AudioNmute, sizeof(di->label.name));
1017 di->un.e.num_mem = 2;
1018 strlcpy(di->un.e.member[0].label.name, AudioNon,
1019 sizeof(di->un.e.member[0].label.name));
1020 di->un.e.member[0].ord = 0;
1021 strlcpy(di->un.e.member[1].label.name, AudioNoff,
1022 sizeof(di->un.e.member[1].label.name));
1023 di->un.e.member[1].ord = 1;
1024 break;
1026 case ZAUDIO_MIC_LVL:
1027 di->type = AUDIO_MIXER_VALUE;
1028 di->mixer_class = ZAUDIO_INPUT_CLASS;
1029 di->prev = AUDIO_MIXER_LAST;
1030 di->next = ZAUDIO_MIC_MUTE;
1031 strlcpy(di->label.name, AudioNmicrophone,
1032 sizeof(di->label.name));
1033 strlcpy(di->un.v.units.name, AudioNvolume,
1034 sizeof(di->un.v.units.name));
1035 di->un.v.num_channels = 1;
1036 break;
1038 case ZAUDIO_MIC_MUTE:
1039 di->type = AUDIO_MIXER_ENUM;
1040 di->mixer_class = ZAUDIO_INPUT_CLASS;
1041 di->prev = ZAUDIO_MIC_LVL;
1042 di->next = AUDIO_MIXER_LAST;
1043 goto mute;
1045 case ZAUDIO_RECORD_SOURCE:
1046 di->type = AUDIO_MIXER_ENUM;
1047 di->mixer_class = ZAUDIO_RECORD_CLASS;
1048 di->prev = AUDIO_MIXER_LAST;
1049 di->next = AUDIO_MIXER_LAST;
1050 strlcpy(di->label.name, AudioNsource, sizeof(di->label.name));
1051 di->un.e.num_mem = 1;
1052 strlcpy(di->un.e.member[0].label.name, AudioNmicrophone,
1053 sizeof(di->un.e.member[0].label.name));
1054 di->un.e.member[0].ord = 0;
1055 break;
1057 case ZAUDIO_OUTPUT_CLASS:
1058 di->type = AUDIO_MIXER_CLASS;
1059 di->mixer_class = ZAUDIO_OUTPUT_CLASS;
1060 di->prev = AUDIO_MIXER_LAST;
1061 di->next = AUDIO_MIXER_LAST;
1062 strlcpy(di->label.name, AudioCoutputs, sizeof(di->label.name));
1063 break;
1065 case ZAUDIO_INPUT_CLASS:
1066 di->type = AUDIO_MIXER_CLASS;
1067 di->mixer_class = ZAUDIO_INPUT_CLASS;
1068 di->prev = AUDIO_MIXER_LAST;
1069 di->next = AUDIO_MIXER_LAST;
1070 strlcpy(di->label.name, AudioCinputs, sizeof(di->label.name));
1071 break;
1073 case ZAUDIO_RECORD_CLASS:
1074 di->type = AUDIO_MIXER_CLASS;
1075 di->mixer_class = ZAUDIO_RECORD_CLASS;
1076 di->prev = AUDIO_MIXER_LAST;
1077 di->next = AUDIO_MIXER_LAST;
1078 strlcpy(di->label.name, AudioCinputs, sizeof(di->label.name));
1079 break;
1081 default:
1082 return ENXIO;
1085 return 0;
1088 static void *
1089 zaudio_allocm(void *hdl, int direction, size_t size, struct malloc_type *type,
1090 int flags)
1092 struct zaudio_softc *sc = hdl;
1094 return pxa2x0_i2s_allocm(&sc->sc_i2s, direction, size, type, flags);
1097 static void
1098 zaudio_freem(void *hdl, void *ptr, struct malloc_type *type)
1100 struct zaudio_softc *sc = hdl;
1102 return pxa2x0_i2s_freem(&sc->sc_i2s, ptr, type);
1105 static size_t
1106 zaudio_round_buffersize(void *hdl, int direction, size_t bufsize)
1108 struct zaudio_softc *sc = hdl;
1110 return pxa2x0_i2s_round_buffersize(&sc->sc_i2s, direction, bufsize);
1113 static paddr_t
1114 zaudio_mappage(void *hdl, void *mem, off_t off, int prot)
1116 struct zaudio_softc *sc = hdl;
1118 return pxa2x0_i2s_mappage(&sc->sc_i2s, mem, off, prot);
1121 static int
1122 zaudio_get_props(void *hdl)
1125 return AUDIO_PROP_MMAP|AUDIO_PROP_INDEPENDENT;
1128 static int
1129 zaudio_start_output(void *hdl, void *block, int bsize, void (*intr)(void *),
1130 void *intrarg)
1132 struct zaudio_softc *sc = hdl;
1133 int rv;
1135 /* Power up codec if we are not already playing. */
1136 if (!sc->sc_playing) {
1137 sc->sc_playing = 1;
1138 zaudio_play_setup(sc);
1141 /* Start DMA via I2S */
1142 rv = pxa2x0_i2s_start_output(&sc->sc_i2s, block, bsize, intr, intrarg);
1143 if (rv) {
1144 if (!sc->sc_recording)
1145 zaudio_standby(sc);
1146 sc->sc_playing = 0;
1148 return rv;
1151 static int
1152 zaudio_start_input(void *hdl, void *block, int bsize, void (*intr)(void *),
1153 void *intrarg)
1155 struct zaudio_softc *sc = hdl;
1156 int rv;
1158 /* Power up codec if we are not already recording. */
1159 if (!sc->sc_recording) {
1160 sc->sc_recording = 1;
1161 zaudio_record_setup(sc);
1164 /* Start DMA via I2S */
1165 rv = pxa2x0_i2s_start_input(&sc->sc_i2s, block, bsize, intr, intrarg);
1166 if (rv) {
1167 if (!sc->sc_playing)
1168 zaudio_standby(sc);
1169 sc->sc_recording = 0;
1171 return rv;