zaudio.c revision 1.3 1 /* $NetBSD: zaudio.c,v 1.3 2007/02/22 06:47:16 thorpej Exp $ */
2 /* $OpenBSD: zaurus_audio.c,v 1.8 2005/08/18 13:23:02 robert Exp $ */
3
4 /*
5 * Copyright (c) 2005 Christopher Pascoe <pascoe (at) openbsd.org>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 /*
21 * TODO:
22 * - powerhooks (currently only works until first suspend)
23 * - record support
24 */
25
26 #include <sys/cdefs.h>
27 __KERNEL_RCSID(0, "$NetBSD");
28
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/callout.h>
32 #include <sys/device.h>
33 #include <sys/malloc.h>
34 #include <sys/kernel.h>
35 #include <sys/audioio.h>
36
37 #include <machine/intr.h>
38 #include <machine/bus.h>
39
40 #include <arm/xscale/pxa2x0reg.h>
41 #include <arm/xscale/pxa2x0var.h>
42 #include <arm/xscale/pxa2x0_i2c.h>
43 #include <arm/xscale/pxa2x0_i2s.h>
44 #include <arm/xscale/pxa2x0_dmac.h>
45 #include <arm/xscale/pxa2x0_gpio.h>
46
47 #include <dev/audio_if.h>
48 #include <dev/mulaw.h>
49 #include <dev/auconv.h>
50
51 #include <zaurus/dev/wm8750reg.h>
52 #include <zaurus/dev/scoopvar.h>
53
54 #define WM8750_ADDRESS 0x1B
55 #define SPKR_VOLUME 112
56
57 #define wm8750_write(sc, reg, val) \
58 pxa2x0_i2c_write_2(&sc->sc_i2c, WM8750_ADDRESS, \
59 (((reg) << 9) | ((val) & 0x1ff)))
60
61 static int zaudio_match(struct device *, struct cfdata *, void *);
62 static void zaudio_attach(struct device *, struct device *, void *);
63 static int zaudio_detach(struct device *, int);
64 static void zaudio_power(int, void *);
65
66 #define ZAUDIO_OP_SPKR 0
67 #define ZAUDIO_OP_HP 1
68
69 #define ZAUDIO_JACK_STATE_OUT 0
70 #define ZAUDIO_JACK_STATE_IN 1
71 #define ZAUDIO_JACK_STATE_INS 2
72 #define ZAUDIO_JACK_STATE_REM 3
73
74 /* GPIO pins */
75 #define GPIO_HP_IN_C3000 116
76
77 struct zaudio_volume {
78 u_int8_t left;
79 u_int8_t right;
80 };
81
82 struct zaudio_softc {
83 struct device sc_dev;
84
85 /* i2s device softc */
86 /* NB: pxa2x0_i2s requires this to be the second struct member */
87 struct pxa2x0_i2s_softc sc_i2s;
88
89 /* i2c device softc */
90 struct pxa2x0_i2c_softc sc_i2c;
91
92 void *sc_powerhook;
93 int sc_playing;
94
95 struct zaudio_volume sc_volume[2];
96 char sc_unmute[2];
97
98 int sc_state;
99 int sc_icount;
100 struct callout sc_to;
101 };
102
103 CFATTACH_DECL(zaudio, sizeof(struct zaudio_softc),
104 zaudio_match, zaudio_attach, zaudio_detach, NULL);
105
106 static struct audio_device wm8750_device = {
107 "WM8750",
108 "1.0",
109 "wm"
110 };
111
112 #define ZAUDIO_NFORMATS 4
113 static const struct audio_format zaudio_formats[ZAUDIO_NFORMATS] = {
114 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_LE, 16, 16,
115 2, AUFMT_STEREO, 0, {4000, 48000}},
116 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_LE, 16, 16,
117 1, AUFMT_MONAURAL, 0, {4000, 48000}},
118 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULINEAR_LE, 8, 8,
119 2, AUFMT_STEREO, 0, {4000, 48000}},
120 {NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULINEAR_LE, 8, 8,
121 1, AUFMT_MONAURAL, 0, {4000, 48000}},
122 };
123
124 void zaudio_init(struct zaudio_softc *);
125 static int zaudio_jack_intr(void *);
126 void zaudio_jack(void *);
127 void zaudio_standby(struct zaudio_softc *);
128 void zaudio_update_volume(struct zaudio_softc *, int);
129 void zaudio_update_mutes(struct zaudio_softc *);
130 void zaudio_play_setup(struct zaudio_softc *);
131 static int zaudio_open(void *, int);
132 static void zaudio_close(void *);
133 static int zaudio_query_encoding(void *, struct audio_encoding *);
134 static int zaudio_set_params(void *, int, int, audio_params_t *,
135 audio_params_t *, stream_filter_list_t *, stream_filter_list_t *);
136 static int zaudio_round_blocksize(void *, int, int, const audio_params_t *);
137 static int zaudio_start_output(void *, void *, int, void (*)(void *), void *);
138 static int zaudio_start_input(void *, void *, int, void (*)(void *), void *);
139 static int zaudio_halt_output(void *);
140 static int zaudio_halt_input(void *);
141 static int zaudio_getdev(void *, struct audio_device *);
142 static int zaudio_set_port(void *, struct mixer_ctrl *);
143 static int zaudio_get_port(void *, struct mixer_ctrl *);
144 static int zaudio_query_devinfo(void *, struct mixer_devinfo *);
145 static void *zaudio_allocm(void *, int, size_t, struct malloc_type *, int);
146 static void zaudio_freem(void *, void *, struct malloc_type *);
147 static size_t zaudio_round_buffersize(void *, int, size_t);
148 static paddr_t zaudio_mappage(void *, void *, off_t, int);
149 static int zaudio_get_props(void *);
150
151 struct audio_hw_if wm8750_hw_if = {
152 zaudio_open,
153 zaudio_close,
154 NULL,
155 zaudio_query_encoding,
156 zaudio_set_params,
157 zaudio_round_blocksize,
158 NULL,
159 NULL,
160 NULL,
161 zaudio_start_output,
162 zaudio_start_input,
163 zaudio_halt_output,
164 zaudio_halt_input,
165 NULL,
166 zaudio_getdev,
167 NULL,
168 zaudio_set_port,
169 zaudio_get_port,
170 zaudio_query_devinfo,
171 zaudio_allocm,
172 zaudio_freem,
173 zaudio_round_buffersize,
174 zaudio_mappage,
175 zaudio_get_props,
176 NULL,
177 NULL,
178 NULL,
179 };
180
181 static const uint16_t playback_registers[][2] = {
182 /* Unmute DAC */
183 { ADCDACCTL_REG, 0x000 },
184
185 /* 16 bit audio words */
186 { AUDINT_REG, AUDINT_SET_FORMAT(2) },
187
188 /* Enable thermal protection, power */
189 { ADCTL1_REG, ADCTL1_TSDEN | ADCTL1_SET_VSEL(3) },
190
191 /* Enable speaker driver, DAC oversampling */
192 { ADCTL2_REG, ADCTL2_ROUT2INV | ADCTL2_DACOSR },
193
194 /* Set DAC voltage references */
195 { PWRMGMT1_REG, PWRMGMT1_SET_VMIDSEL(1) | PWRMGMT1_VREF },
196
197 /* Direct DACs to output mixers */
198 { LOUTMIX1_REG, LOUTMIX1_LD2LO },
199 { ROUTMIX2_REG, ROUTMIX2_RD2RO },
200
201 /* End of list */
202 { 0xffff, 0xffff }
203 };
204
205 static int
206 zaudio_match(struct device *parent, struct cfdata *cf, void *aux)
207 {
208
209 return 1;
210 }
211
212 static void
213 zaudio_attach(struct device *parent, struct device *self, void *aux)
214 {
215 struct zaudio_softc *sc = (struct zaudio_softc *)self;
216 struct pxaip_attach_args *pxa = aux;
217 int rv;
218
219 sc->sc_powerhook = powerhook_establish(sc->sc_dev.dv_xname,
220 zaudio_power, sc);
221 if (sc->sc_powerhook == NULL) {
222 printf(": unable to establish powerhook\n");
223 return;
224 }
225
226 sc->sc_i2s.sc_iot = pxa->pxa_iot;
227 sc->sc_i2s.sc_dmat = pxa->pxa_dmat;
228 sc->sc_i2s.sc_size = PXA2X0_I2S_SIZE;
229 if (pxa2x0_i2s_attach_sub(&sc->sc_i2s)) {
230 printf(": unable to attach I2S\n");
231 goto fail_i2s;
232 }
233
234 sc->sc_i2c.sc_iot = pxa->pxa_iot;
235 sc->sc_i2c.sc_size = PXA2X0_I2C_SIZE;
236 if (pxa2x0_i2c_attach_sub(&sc->sc_i2c)) {
237 printf(": unable to attach I2C\n");
238 goto fail_i2c;
239 }
240
241 /* Check for an I2C response from the wm8750 */
242 pxa2x0_i2c_open(&sc->sc_i2c);
243 rv = wm8750_write(sc, RESET_REG, 0);
244 pxa2x0_i2c_close(&sc->sc_i2c);
245
246 if (rv) {
247 printf(": codec failed to respond\n");
248 goto fail_probe;
249 }
250 delay(100);
251
252 /* Speaker on, headphones off by default. */
253 sc->sc_volume[ZAUDIO_OP_SPKR].left = 240;
254 sc->sc_unmute[ZAUDIO_OP_SPKR] = 1;
255 sc->sc_volume[ZAUDIO_OP_HP].left = 180;
256 sc->sc_volume[ZAUDIO_OP_HP].right = 180;
257 sc->sc_unmute[ZAUDIO_OP_HP] = 0;
258
259 /* Configure headphone jack state change handling. */
260 callout_init(&sc->sc_to);
261 callout_setfunc(&sc->sc_to, zaudio_jack, sc);
262 pxa2x0_gpio_set_function(GPIO_HP_IN_C3000, GPIO_IN);
263 (void)pxa2x0_gpio_intr_establish(GPIO_HP_IN_C3000,
264 IST_EDGE_BOTH, IPL_BIO, zaudio_jack_intr, sc);
265
266 zaudio_init(sc);
267
268 printf(": I2C, I2S, WM8750 Audio\n");
269
270 audio_attach_mi(&wm8750_hw_if, sc, &sc->sc_dev);
271
272 return;
273
274 fail_probe:
275 pxa2x0_i2c_detach_sub(&sc->sc_i2c);
276 fail_i2c:
277 pxa2x0_i2s_detach_sub(&sc->sc_i2s);
278 fail_i2s:
279 powerhook_disestablish(sc->sc_powerhook);
280 }
281
282 static int
283 zaudio_detach(struct device *self, int flags)
284 {
285 struct zaudio_softc *sc = (struct zaudio_softc *)self;
286
287 if (sc->sc_powerhook != NULL) {
288 powerhook_disestablish(sc->sc_powerhook);
289 sc->sc_powerhook = NULL;
290 }
291
292 pxa2x0_i2c_detach_sub(&sc->sc_i2c);
293 pxa2x0_i2s_detach_sub(&sc->sc_i2s);
294
295 return 0;
296 }
297
298 static void
299 zaudio_power(int why, void *arg)
300 {
301 struct zaudio_softc *sc = arg;
302
303 switch (why) {
304 case PWR_STANDBY:
305 case PWR_SUSPEND:
306 callout_stop(&sc->sc_to);
307 zaudio_standby(sc);
308 break;
309
310 case PWR_RESUME:
311 pxa2x0_i2s_init(&sc->sc_i2s);
312 pxa2x0_i2c_init(&sc->sc_i2c);
313 zaudio_init(sc);
314 break;
315 }
316 }
317
318 void
319 zaudio_init(struct zaudio_softc *sc)
320 {
321
322 pxa2x0_i2c_open(&sc->sc_i2c);
323
324 /* Reset the codec */
325 wm8750_write(sc, RESET_REG, 0);
326 delay(100);
327
328 /* Switch to standby power only */
329 wm8750_write(sc, PWRMGMT1_REG, PWRMGMT1_SET_VMIDSEL(2));
330 wm8750_write(sc, PWRMGMT2_REG, 0);
331
332 /* Configure digital interface for I2S */
333 wm8750_write(sc, AUDINT_REG, AUDINT_SET_FORMAT(2));
334
335 /* Initialise volume levels */
336 zaudio_update_volume(sc, ZAUDIO_OP_SPKR);
337 zaudio_update_volume(sc, ZAUDIO_OP_HP);
338
339 pxa2x0_i2c_close(&sc->sc_i2c);
340
341 scoop_set_headphone(0);
342
343 /* Assume that the jack state has changed. */
344 zaudio_jack(sc);
345
346 }
347
348 static int
349 zaudio_jack_intr(void *v)
350 {
351 struct zaudio_softc *sc = v;
352
353 if (!callout_active(&sc->sc_to))
354 zaudio_jack(sc);
355
356 return 1;
357 }
358
359 void
360 zaudio_jack(void *v)
361 {
362 struct zaudio_softc *sc = v;
363
364 switch (sc->sc_state) {
365 case ZAUDIO_JACK_STATE_OUT:
366 if (pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) {
367 sc->sc_state = ZAUDIO_JACK_STATE_INS;
368 sc->sc_icount = 0;
369 }
370 break;
371
372 case ZAUDIO_JACK_STATE_INS:
373 if (sc->sc_icount++ > 2) {
374 if (pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) {
375 sc->sc_state = ZAUDIO_JACK_STATE_IN;
376 sc->sc_unmute[ZAUDIO_OP_SPKR] = 0;
377 sc->sc_unmute[ZAUDIO_OP_HP] = 1;
378 goto update_mutes;
379 } else
380 sc->sc_state = ZAUDIO_JACK_STATE_OUT;
381 }
382 break;
383
384 case ZAUDIO_JACK_STATE_IN:
385 if (!pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) {
386 sc->sc_state = ZAUDIO_JACK_STATE_REM;
387 sc->sc_icount = 0;
388 }
389 break;
390
391 case ZAUDIO_JACK_STATE_REM:
392 if (sc->sc_icount++ > 2) {
393 if (!pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) {
394 sc->sc_state = ZAUDIO_JACK_STATE_OUT;
395 sc->sc_unmute[ZAUDIO_OP_SPKR] = 1;
396 sc->sc_unmute[ZAUDIO_OP_HP] = 0;
397 goto update_mutes;
398 } else
399 sc->sc_state = ZAUDIO_JACK_STATE_IN;
400 }
401 break;
402 }
403
404 callout_schedule(&sc->sc_to, hz/4);
405
406 return;
407
408 update_mutes:
409 callout_stop(&sc->sc_to);
410
411 if (sc->sc_playing) {
412 pxa2x0_i2c_open(&sc->sc_i2c);
413 zaudio_update_mutes(sc);
414 pxa2x0_i2c_close(&sc->sc_i2c);
415 }
416 }
417
418 void
419 zaudio_standby(struct zaudio_softc *sc)
420 {
421
422 pxa2x0_i2c_open(&sc->sc_i2c);
423
424 /* Switch codec to standby power only */
425 wm8750_write(sc, PWRMGMT1_REG, PWRMGMT1_SET_VMIDSEL(2));
426 wm8750_write(sc, PWRMGMT2_REG, 0);
427
428 pxa2x0_i2c_close(&sc->sc_i2c);
429
430 scoop_set_headphone(0);
431 }
432
433 void
434 zaudio_update_volume(struct zaudio_softc *sc, int output)
435 {
436
437 switch (output) {
438 case ZAUDIO_OP_SPKR:
439 wm8750_write(sc, LOUT2VOL_REG, LOUT2VOL_LO2VU | LOUT2VOL_LO2ZC |
440 LOUT2VOL_SET_LOUT2VOL(sc->sc_volume[ZAUDIO_OP_SPKR
441 ].left >> 1));
442 wm8750_write(sc, ROUT2VOL_REG, ROUT2VOL_RO2VU | ROUT2VOL_RO2ZC |
443 ROUT2VOL_SET_ROUT2VOL(sc->sc_volume[ZAUDIO_OP_SPKR
444 ].left >> 1));
445 break;
446
447 case ZAUDIO_OP_HP:
448 wm8750_write(sc, LOUT1VOL_REG, LOUT1VOL_LO1VU | LOUT1VOL_LO1ZC |
449 LOUT1VOL_SET_LOUT1VOL(sc->sc_volume[ZAUDIO_OP_HP
450 ].left >> 1));
451 wm8750_write(sc, ROUT1VOL_REG, ROUT1VOL_RO1VU | ROUT1VOL_RO1ZC |
452 ROUT1VOL_SET_ROUT1VOL(sc->sc_volume[ZAUDIO_OP_HP
453 ].right >> 1));
454 break;
455 }
456 }
457
458 void
459 zaudio_update_mutes(struct zaudio_softc *sc)
460 {
461 uint16_t val;
462
463 val = PWRMGMT2_DACL | PWRMGMT2_DACR;
464
465 if (sc->sc_unmute[ZAUDIO_OP_SPKR])
466 val |= PWRMGMT2_LOUT2 | PWRMGMT2_ROUT2;
467
468 if (sc->sc_unmute[ZAUDIO_OP_HP])
469 val |= PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1;
470
471 wm8750_write(sc, PWRMGMT2_REG, val);
472
473 scoop_set_headphone(sc->sc_unmute[ZAUDIO_OP_HP]);
474 }
475
476 void
477 zaudio_play_setup(struct zaudio_softc *sc)
478 {
479 int i;
480
481 pxa2x0_i2c_open(&sc->sc_i2c);
482
483 /* Program the codec with playback settings */
484 for (i = 0; playback_registers[i][0] != 0xffff; i++) {
485 wm8750_write(sc, playback_registers[i][0],
486 playback_registers[i][1]);
487 }
488 zaudio_update_mutes(sc);
489
490 pxa2x0_i2c_close(&sc->sc_i2c);
491 }
492
493 /*
494 * audio operation functions.
495 */
496 static int
497 zaudio_open(void *hdl, int flags)
498 {
499 struct zaudio_softc *sc = hdl;
500
501 /* Power on the I2S bus and codec */
502 pxa2x0_i2s_open(&sc->sc_i2s);
503
504 return 0;
505 }
506
507 static void
508 zaudio_close(void *hdl)
509 {
510 struct zaudio_softc *sc = hdl;
511
512 /* Power off the I2S bus and codec */
513 pxa2x0_i2s_close(&sc->sc_i2s);
514 }
515
516 static int
517 zaudio_query_encoding(void *hdl, struct audio_encoding *aep)
518 {
519
520 switch (aep->index) {
521 case 0:
522 strlcpy(aep->name, AudioEulinear, sizeof(aep->name));
523 aep->encoding = AUDIO_ENCODING_ULINEAR;
524 aep->precision = 8;
525 aep->flags = 0;
526 break;
527
528 case 1:
529 strlcpy(aep->name, AudioEmulaw, sizeof(aep->name));
530 aep->encoding = AUDIO_ENCODING_ULAW;
531 aep->precision = 8;
532 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
533 break;
534
535 case 2:
536 strlcpy(aep->name, AudioEalaw, sizeof(aep->name));
537 aep->encoding = AUDIO_ENCODING_ALAW;
538 aep->precision = 8;
539 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
540 break;
541
542 case 3:
543 strlcpy(aep->name, AudioEslinear, sizeof(aep->name));
544 aep->encoding = AUDIO_ENCODING_SLINEAR;
545 aep->precision = 8;
546 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
547 break;
548
549 case 4:
550 strlcpy(aep->name, AudioEslinear_le, sizeof(aep->name));
551 aep->encoding = AUDIO_ENCODING_SLINEAR_LE;
552 aep->precision = 16;
553 aep->flags = 0;
554 break;
555
556 case 5:
557 strlcpy(aep->name, AudioEulinear_le, sizeof(aep->name));
558 aep->encoding = AUDIO_ENCODING_ULINEAR_LE;
559 aep->precision = 16;
560 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
561 break;
562
563 case 6:
564 strlcpy(aep->name, AudioEslinear_be, sizeof(aep->name));
565 aep->encoding = AUDIO_ENCODING_SLINEAR_BE;
566 aep->precision = 16;
567 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
568 break;
569
570 case 7:
571 strlcpy(aep->name, AudioEulinear_be, sizeof(aep->name));
572 aep->encoding = AUDIO_ENCODING_ULINEAR_BE;
573 aep->precision = 16;
574 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
575 break;
576
577 default:
578 return EINVAL;
579 }
580
581 return 0;
582 }
583
584 static int
585 zaudio_set_params(void *hdl, int setmode, int usemode,
586 audio_params_t *play, audio_params_t *rec,
587 stream_filter_list_t *pfil, stream_filter_list_t *rfil)
588 {
589 struct zaudio_softc *sc = hdl;
590 struct audio_params *p;
591 stream_filter_list_t *fil;
592 int mode, i;
593
594 if (play->sample_rate != rec->sample_rate &&
595 usemode == (AUMODE_PLAY | AUMODE_RECORD)) {
596 if (setmode == AUMODE_PLAY) {
597 rec->sample_rate = play->sample_rate;
598 setmode |= AUMODE_RECORD;
599 } else if (setmode == AUMODE_RECORD) {
600 play->sample_rate = rec->sample_rate;
601 setmode |= AUMODE_PLAY;
602 } else
603 return EINVAL;
604 }
605
606 for (mode = AUMODE_RECORD; mode != -1;
607 mode = (mode == AUMODE_RECORD) ? AUMODE_PLAY : -1) {
608 if ((setmode & mode) == 0)
609 continue;
610
611 p = (mode == AUMODE_PLAY) ? play : rec;
612
613 if (p->sample_rate < 4000 || p->sample_rate > 48000 ||
614 (p->precision != 8 && p->precision != 16) ||
615 (p->channels != 1 && p->channels != 2))
616 return EINVAL;
617
618 fil = (mode == AUMODE_PLAY) ? pfil : rfil;
619 i = auconv_set_converter(zaudio_formats, ZAUDIO_NFORMATS,
620 mode, p, false, fil);
621 if (i < 0)
622 return EINVAL;
623 }
624
625 if (setmode == AUMODE_RECORD)
626 pxa2x0_i2s_setspeed(&sc->sc_i2s, &rec->sample_rate);
627 else
628 pxa2x0_i2s_setspeed(&sc->sc_i2s, &play->sample_rate);
629
630 return 0;
631 }
632
633 static int
634 zaudio_round_blocksize(void *hdl, int bs, int mode, const audio_params_t *param)
635 {
636 struct zaudio_softc *sc = hdl;
637
638 return pxa2x0_i2s_round_blocksize(&sc->sc_i2s, bs, mode, param);
639 }
640
641
642 static int
643 zaudio_halt_output(void *hdl)
644 {
645 struct zaudio_softc *sc = hdl;
646 int rv;
647
648 rv = pxa2x0_i2s_halt_output(&sc->sc_i2s);
649 zaudio_standby(sc);
650 sc->sc_playing = 0;
651
652 return rv;
653 }
654
655 static int
656 zaudio_halt_input(void *hdl)
657 {
658 struct zaudio_softc *sc = hdl;
659 int rv;
660
661 rv = pxa2x0_i2s_halt_input(&sc->sc_i2s);
662
663 return rv;
664 }
665
666 static int
667 zaudio_getdev(void *hdl, struct audio_device *ret)
668 {
669 /* struct zaudio_softc *sc = hdl; */
670
671 *ret = wm8750_device;
672 return 0;
673 }
674
675 #define ZAUDIO_SPKR_LVL 0
676 #define ZAUDIO_SPKR_MUTE 1
677 #define ZAUDIO_HP_LVL 2
678 #define ZAUDIO_HP_MUTE 3
679 #define ZAUDIO_OUTPUT_CLASS 4
680
681 static int
682 zaudio_set_port(void *hdl, struct mixer_ctrl *mc)
683 {
684 struct zaudio_softc *sc = hdl;
685 int error = EINVAL;
686 int s;
687
688 s = splbio();
689 pxa2x0_i2c_open(&sc->sc_i2c);
690
691 switch (mc->dev) {
692 case ZAUDIO_SPKR_LVL:
693 if (mc->type != AUDIO_MIXER_VALUE)
694 break;
695 if (mc->un.value.num_channels == 1)
696 sc->sc_volume[ZAUDIO_OP_SPKR].left =
697 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
698 else
699 break;
700 zaudio_update_volume(sc, ZAUDIO_OP_SPKR);
701 error = 0;
702 break;
703
704 case ZAUDIO_SPKR_MUTE:
705 if (mc->type != AUDIO_MIXER_ENUM)
706 break;
707 sc->sc_unmute[ZAUDIO_OP_SPKR] = mc->un.ord ? 1 : 0;
708 zaudio_update_mutes(sc);
709 error = 0;
710 break;
711
712 case ZAUDIO_HP_LVL:
713 if (mc->type != AUDIO_MIXER_VALUE)
714 break;
715 if (mc->un.value.num_channels == 1) {
716 sc->sc_volume[ZAUDIO_OP_HP].left =
717 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
718 sc->sc_volume[ZAUDIO_OP_HP].right =
719 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
720 } else if (mc->un.value.num_channels == 2) {
721 sc->sc_volume[ZAUDIO_OP_HP].left =
722 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
723 sc->sc_volume[ZAUDIO_OP_HP].right =
724 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
725 }
726 else
727 break;
728 zaudio_update_volume(sc, ZAUDIO_OP_HP);
729 error = 0;
730 break;
731
732 case ZAUDIO_HP_MUTE:
733 if (mc->type != AUDIO_MIXER_ENUM)
734 break;
735 sc->sc_unmute[ZAUDIO_OP_HP] = mc->un.ord ? 1 : 0;
736 zaudio_update_mutes(sc);
737 error = 0;
738 break;
739 }
740
741 pxa2x0_i2c_close(&sc->sc_i2c);
742 splx(s);
743
744 return error;
745 }
746
747 static int
748 zaudio_get_port(void *hdl, struct mixer_ctrl *mc)
749 {
750 struct zaudio_softc *sc = hdl;
751 int error = EINVAL;
752
753 switch (mc->dev) {
754 case ZAUDIO_SPKR_LVL:
755 if (mc->type != AUDIO_MIXER_VALUE)
756 break;
757 if (mc->un.value.num_channels == 1)
758 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
759 sc->sc_volume[ZAUDIO_OP_SPKR].left;
760 else
761 break;
762 error = 0;
763 break;
764
765 case ZAUDIO_SPKR_MUTE:
766 if (mc->type != AUDIO_MIXER_ENUM)
767 break;
768 mc->un.ord = sc->sc_unmute[ZAUDIO_OP_SPKR] ? 1 : 0;
769 error = 0;
770 break;
771
772 case ZAUDIO_HP_LVL:
773 if (mc->type != AUDIO_MIXER_VALUE)
774 break;
775 if (mc->un.value.num_channels == 1)
776 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
777 sc->sc_volume[ZAUDIO_OP_HP].left;
778 else if (mc->un.value.num_channels == 2) {
779 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
780 sc->sc_volume[ZAUDIO_OP_HP].left;
781 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
782 sc->sc_volume[ZAUDIO_OP_HP].right;
783 }
784 else
785 break;
786 error = 0;
787 break;
788
789 case ZAUDIO_HP_MUTE:
790 if (mc->type != AUDIO_MIXER_ENUM)
791 break;
792 mc->un.ord = sc->sc_unmute[ZAUDIO_OP_HP] ? 1 : 0;
793 error = 0;
794 break;
795 }
796
797 return error;
798 }
799
800 static int
801 zaudio_query_devinfo(void *hdl, struct mixer_devinfo *di)
802 {
803 /* struct zaudio_softc *sc = hdl; */
804
805 switch (di->index) {
806 case ZAUDIO_SPKR_LVL:
807 di->type = AUDIO_MIXER_VALUE;
808 di->mixer_class = ZAUDIO_OUTPUT_CLASS;
809 di->prev = AUDIO_MIXER_LAST;
810 di->next = ZAUDIO_SPKR_MUTE;
811 strlcpy(di->label.name, AudioNspeaker,
812 sizeof(di->label.name));
813 strlcpy(di->un.v.units.name, AudioNvolume,
814 sizeof(di->un.v.units.name));
815 di->un.v.num_channels = 1;
816 break;
817
818 case ZAUDIO_SPKR_MUTE:
819 di->type = AUDIO_MIXER_ENUM;
820 di->mixer_class = ZAUDIO_OUTPUT_CLASS;
821 di->prev = ZAUDIO_SPKR_LVL;
822 di->next = AUDIO_MIXER_LAST;
823 goto mute;
824
825 case ZAUDIO_HP_LVL:
826 di->type = AUDIO_MIXER_VALUE;
827 di->mixer_class = ZAUDIO_OUTPUT_CLASS;
828 di->prev = AUDIO_MIXER_LAST;
829 di->next = ZAUDIO_HP_MUTE;
830 strlcpy(di->label.name, AudioNheadphone,
831 sizeof(di->label.name));
832 di->un.v.num_channels = 1;
833 strlcpy(di->un.v.units.name, AudioNvolume,
834 sizeof(di->un.v.units.name));
835 break;
836
837 case ZAUDIO_HP_MUTE:
838 di->type = AUDIO_MIXER_ENUM;
839 di->mixer_class = ZAUDIO_OUTPUT_CLASS;
840 di->prev = ZAUDIO_HP_LVL;
841 di->next = AUDIO_MIXER_LAST;
842 mute:
843 strlcpy(di->label.name, AudioNmute, sizeof(di->label.name));
844 di->un.e.num_mem = 2;
845 strlcpy(di->un.e.member[0].label.name, AudioNon,
846 sizeof(di->un.e.member[0].label.name));
847 di->un.e.member[0].ord = 0;
848 strlcpy(di->un.e.member[1].label.name, AudioNoff,
849 sizeof(di->un.e.member[1].label.name));
850 di->un.e.member[1].ord = 1;
851 break;
852
853 case ZAUDIO_OUTPUT_CLASS:
854 di->type = AUDIO_MIXER_CLASS;
855 di->mixer_class = ZAUDIO_OUTPUT_CLASS;
856 di->prev = AUDIO_MIXER_LAST;
857 di->next = AUDIO_MIXER_LAST;
858 strlcpy(di->label.name, AudioCoutputs,
859 sizeof(di->label.name));
860 break;
861
862 default:
863 return ENXIO;
864 }
865
866 return 0;
867 }
868
869 static void *
870 zaudio_allocm(void *hdl, int direction, size_t size,
871 struct malloc_type *type, int flags)
872 {
873 struct zaudio_softc *sc = hdl;
874
875 return pxa2x0_i2s_allocm(&sc->sc_i2s, direction, size, type, flags);
876 }
877
878 static void
879 zaudio_freem(void *hdl, void *ptr, struct malloc_type *type)
880 {
881 struct zaudio_softc *sc = hdl;
882
883 return pxa2x0_i2s_freem(&sc->sc_i2s, ptr, type);
884 }
885
886 static size_t
887 zaudio_round_buffersize(void *hdl, int direction, size_t bufsize)
888 {
889 struct zaudio_softc *sc = hdl;
890
891 return pxa2x0_i2s_round_buffersize(&sc->sc_i2s, direction, bufsize);
892 }
893
894 static paddr_t
895 zaudio_mappage(void *hdl, void *mem, off_t off, int prot)
896 {
897 struct zaudio_softc *sc = hdl;
898
899 return pxa2x0_i2s_mappage(&sc->sc_i2s, mem, off, prot);
900 }
901
902 static int
903 zaudio_get_props(void *hdl)
904 {
905
906 return AUDIO_PROP_MMAP|AUDIO_PROP_INDEPENDENT|AUDIO_PROP_FULLDUPLEX;
907 }
908
909 static int
910 zaudio_start_output(void *hdl, void *block, int bsize, void (*intr)(void *),
911 void *intrarg)
912 {
913 struct zaudio_softc *sc = hdl;
914 int rv;
915
916 /* Power up codec if we are not already playing. */
917 if (!sc->sc_playing) {
918 sc->sc_playing = 1;
919 zaudio_play_setup(sc);
920 }
921
922 /* Start DMA via I2S */
923 rv = pxa2x0_i2s_start_output(&sc->sc_i2s, block, bsize, intr, intrarg);
924 if (rv) {
925 zaudio_standby(sc);
926 sc->sc_playing = 0;
927 }
928 return rv;
929 }
930
931 static int
932 zaudio_start_input(void *hdl, void *block, int bsize, void (*intr)(void *),
933 void *intrarg)
934 {
935
936 return ENXIO;
937 }
938