zaudio.c revision 1.1 1 /* $NetBSD: zaudio.c,v 1.1 2006/12/16 05:21:04 ober 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 struct audio_device wm8750_device = {
107 "WM8750",
108 "1.0",
109 "wm"
110 };
111
112 void zaudio_init(struct zaudio_softc *);
113 int zaudio_jack_intr(void *);
114 void zaudio_jack(void *);
115 void zaudio_standby(struct zaudio_softc *);
116 void zaudio_update_volume(struct zaudio_softc *, int);
117 void zaudio_update_mutes(struct zaudio_softc *);
118 void zaudio_play_setup(struct zaudio_softc *);
119 int zaudio_open(void *, int);
120 void zaudio_close(void *);
121 int zaudio_query_encoding(void *, struct audio_encoding *);
122 int zaudio_set_params(void *, int, int, struct audio_params *,
123 struct audio_params *);
124 int zaudio_halt_output(void *);
125 int zaudio_halt_input(void *);
126 int zaudio_getdev(void *, struct audio_device *);
127 int zaudio_set_port(void *, struct mixer_ctrl *);
128 int zaudio_get_port(void *, struct mixer_ctrl *);
129 int zaudio_query_devinfo(void *, struct mixer_devinfo *);
130 int zaudio_get_props(void *);
131 int zaudio_start_output(void *, void *, int, void (*)(void *), void *);
132 int zaudio_start_input(void *, void *, int, void (*)(void *), void *);
133
134 struct audio_hw_if wm8750_hw_if = {
135 zaudio_open,
136 zaudio_close,
137 NULL /* zaudio_drain */,
138 zaudio_query_encoding,
139 zaudio_set_params,
140 pxa2x0_i2s_round_blocksize,
141 NULL /* zaudio_commit_settings */,
142 NULL /* zaudio_init_output */,
143 NULL /* zaudio_init_input */,
144 zaudio_start_output,
145 zaudio_start_input,
146 zaudio_halt_output,
147 zaudio_halt_input,
148 NULL /* zaudio_speaker_ctl */,
149 zaudio_getdev,
150 NULL /* zaudio_setfd */,
151 zaudio_set_port,
152 zaudio_get_port,
153 zaudio_query_devinfo,
154 pxa2x0_i2s_allocm,
155 pxa2x0_i2s_freem,
156 pxa2x0_i2s_round_buffersize,
157 pxa2x0_i2s_mappage,
158 zaudio_get_props,
159 NULL /* zaudio_trigger_output */,
160 NULL /* zaudio_trigger_input */
161 };
162
163 static const unsigned short playback_registers[][2] = {
164 /* Unmute DAC */
165 { ADCDACCTL_REG, 0x000 },
166
167 /* 16 bit audio words */
168 { AUDINT_REG, AUDINT_SET_FORMAT(2) },
169
170 /* Enable thermal protection, power */
171 { ADCTL1_REG, ADCTL1_TSDEN | ADCTL1_SET_VSEL(3) },
172
173 /* Enable speaker driver, DAC oversampling */
174 { ADCTL2_REG, ADCTL2_ROUT2INV | ADCTL2_DACOSR },
175
176 /* Set DAC voltage references */
177 { PWRMGMT1_REG, PWRMGMT1_SET_VMIDSEL(1) | PWRMGMT1_VREF },
178
179 /* Direct DACs to output mixers */
180 { LOUTMIX1_REG, LOUTMIX1_LD2LO },
181 { ROUTMIX2_REG, ROUTMIX2_RD2RO },
182
183 /* End of list */
184 { 0xffff, 0xffff }
185 };
186
187 static int
188 zaudio_match(struct device *parent, struct cfdata *cf, void *aux)
189 {
190
191 return 1;
192 }
193
194 static void
195 zaudio_attach(struct device *parent, struct device *self, void *aux)
196 {
197 struct zaudio_softc *sc = (struct zaudio_softc *)self;
198 struct pxaip_attach_args *pxa = aux;
199 int err;
200
201 sc->sc_powerhook = powerhook_establish(zaudio_power, sc);
202 if (sc->sc_powerhook == NULL) {
203 printf(": unable to establish powerhook\n");
204 return;
205 }
206
207 sc->sc_i2s.sc_iot = pxa->pxa_iot;
208 sc->sc_i2s.sc_dmat = pxa->pxa_dmat;
209 sc->sc_i2s.sc_size = PXA2X0_I2S_SIZE;
210 if (pxa2x0_i2s_attach_sub(&sc->sc_i2s)) {
211 printf(": unable to attach I2S\n");
212 goto fail_i2s;
213 }
214
215 sc->sc_i2c.sc_iot = pxa->pxa_iot;
216 sc->sc_i2c.sc_size = PXA2X0_I2C_SIZE;
217 if (pxa2x0_i2c_attach_sub(&sc->sc_i2c)) {
218 printf(": unable to attach I2C\n");
219 goto fail_i2c;
220 }
221
222 /* Check for an I2C response from the wm8750 */
223 pxa2x0_i2c_open(&sc->sc_i2c);
224 err = wm8750_write(sc, RESET_REG, 0);
225 pxa2x0_i2c_close(&sc->sc_i2c);
226
227 if (err) {
228 printf(": codec failed to respond\n");
229 goto fail_probe;
230 }
231 delay(100);
232
233 /* Speaker on, headphones off by default. */
234 sc->sc_volume[ZAUDIO_OP_SPKR].left = 240;
235 sc->sc_unmute[ZAUDIO_OP_SPKR] = 1;
236 sc->sc_volume[ZAUDIO_OP_HP].left = 180;
237 sc->sc_volume[ZAUDIO_OP_HP].right = 180;
238 sc->sc_unmute[ZAUDIO_OP_HP] = 0;
239
240 /* Configure headphone jack state change handling. */
241 callout_init(&sc->sc_to);
242 callout_setfunc(&sc->sc_to, zaudio_jack, sc);
243 pxa2x0_gpio_set_function(GPIO_HP_IN_C3000, GPIO_IN);
244 (void)pxa2x0_gpio_intr_establish(GPIO_HP_IN_C3000,
245 IST_EDGE_BOTH, IPL_BIO, zaudio_jack_intr, sc, "hpjk");
246
247 zaudio_init(sc);
248
249 printf(": I2C, I2S, WM8750 Audio\n");
250
251 audio_attach_mi(&wm8750_hw_if, sc, &sc->sc_dev);
252
253 return;
254
255 fail_probe:
256 pxa2x0_i2c_detach_sub(&sc->sc_i2c);
257 fail_i2c:
258 pxa2x0_i2s_detach_sub(&sc->sc_i2s);
259 fail_i2s:
260 powerhook_disestablish(sc->sc_powerhook);
261 }
262
263 int
264 zaudio_detach(struct device *self, int flags)
265 {
266 struct zaudio_softc *sc = (struct zaudio_softc *)self;
267
268 if (sc->sc_powerhook != NULL) {
269 powerhook_disestablish(sc->sc_powerhook);
270 sc->sc_powerhook = NULL;
271 }
272
273 pxa2x0_i2c_detach_sub(&sc->sc_i2c);
274 pxa2x0_i2s_detach_sub(&sc->sc_i2s);
275
276 return 0;
277 }
278
279 static void
280 zaudio_power(int why, void *arg)
281 {
282 struct zaudio_softc *sc = arg;
283
284 switch (why) {
285 case PWR_STANDBY:
286 case PWR_SUSPEND:
287 callout_stop(&sc->sc_to);
288 zaudio_standby(sc);
289 break;
290
291 case PWR_RESUME:
292 pxa2x0_i2s_init(&sc->sc_i2s);
293 pxa2x0_i2c_init(&sc->sc_i2c);
294 zaudio_init(sc);
295 break;
296 }
297 }
298
299 void
300 zaudio_init(struct zaudio_softc *sc)
301 {
302 pxa2x0_i2c_open(&sc->sc_i2c);
303
304 /* Reset the codec */
305 wm8750_write(sc, RESET_REG, 0);
306 delay(100);
307
308 /* Switch to standby power only */
309 wm8750_write(sc, PWRMGMT1_REG, PWRMGMT1_SET_VMIDSEL(2));
310 wm8750_write(sc, PWRMGMT2_REG, 0);
311
312 /* Configure digital interface for I2S */
313 wm8750_write(sc, AUDINT_REG, AUDINT_SET_FORMAT(2));
314
315 /* Initialise volume levels */
316 zaudio_update_volume(sc, ZAUDIO_OP_SPKR);
317 zaudio_update_volume(sc, ZAUDIO_OP_HP);
318 scoop_set_headphone(0);
319
320 pxa2x0_i2c_close(&sc->sc_i2c);
321
322 /* Assume that the jack state has changed. */
323 zaudio_jack(sc);
324
325 }
326
327 int
328 zaudio_jack_intr(void *v)
329 {
330 struct zaudio_softc *sc = v;
331
332 if (!callout_active(&sc->sc_to))
333 zaudio_jack(sc);
334
335 return (1);
336 }
337
338 void
339 zaudio_jack(void *v)
340 {
341 struct zaudio_softc *sc = v;
342
343 switch (sc->sc_state) {
344 case ZAUDIO_JACK_STATE_OUT:
345 if (pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) {
346 sc->sc_state = ZAUDIO_JACK_STATE_INS;
347 sc->sc_icount = 0;
348 }
349 break;
350 case ZAUDIO_JACK_STATE_INS:
351 if (sc->sc_icount++ > 2) {
352 if (pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) {
353 sc->sc_state = ZAUDIO_JACK_STATE_IN;
354 sc->sc_unmute[ZAUDIO_OP_SPKR] = 0;
355 sc->sc_unmute[ZAUDIO_OP_HP] = 1;
356 goto update_mutes;
357 } else
358 sc->sc_state = ZAUDIO_JACK_STATE_OUT;
359 }
360 break;
361 case ZAUDIO_JACK_STATE_IN:
362 if (!pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) {
363 sc->sc_state = ZAUDIO_JACK_STATE_REM;
364 sc->sc_icount = 0;
365 }
366 break;
367 case ZAUDIO_JACK_STATE_REM:
368 if (sc->sc_icount++ > 2) {
369 if (!pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) {
370 sc->sc_state = ZAUDIO_JACK_STATE_OUT;
371 sc->sc_unmute[ZAUDIO_OP_SPKR] = 1;
372 sc->sc_unmute[ZAUDIO_OP_HP] = 0;
373 goto update_mutes;
374 } else
375 sc->sc_state = ZAUDIO_JACK_STATE_IN;
376 }
377 break;
378 }
379
380 callout_schedule(&sc->sc_to, hz/4);
381 return;
382
383 update_mutes:
384 callout_stop(&sc->sc_to);
385
386 if (sc->sc_playing) {
387 pxa2x0_i2c_open(&sc->sc_i2c);
388 zaudio_update_mutes(sc);
389 pxa2x0_i2c_close(&sc->sc_i2c);
390 }
391 }
392
393 void
394 zaudio_standby(struct zaudio_softc *sc)
395 {
396 pxa2x0_i2c_open(&sc->sc_i2c);
397
398 /* Switch codec to standby power only */
399 wm8750_write(sc, PWRMGMT1_REG, PWRMGMT1_SET_VMIDSEL(2));
400 wm8750_write(sc, PWRMGMT2_REG, 0);
401
402 scoop_set_headphone(0);
403
404 pxa2x0_i2c_close(&sc->sc_i2c);
405 }
406
407 void
408 zaudio_update_volume(struct zaudio_softc *sc, int output)
409 {
410 switch(output) {
411 case ZAUDIO_OP_SPKR:
412 wm8750_write(sc, LOUT2VOL_REG, LOUT2VOL_LO2VU | LOUT2VOL_LO2ZC |
413 LOUT2VOL_SET_LOUT2VOL(sc->sc_volume[ZAUDIO_OP_SPKR
414 ].left >> 1));
415 wm8750_write(sc, ROUT2VOL_REG, ROUT2VOL_RO2VU | ROUT2VOL_RO2ZC |
416 ROUT2VOL_SET_ROUT2VOL(sc->sc_volume[ZAUDIO_OP_SPKR
417 ].left >> 1));
418 break;
419 case ZAUDIO_OP_HP:
420 wm8750_write(sc, LOUT1VOL_REG, LOUT1VOL_LO1VU | LOUT1VOL_LO1ZC |
421 LOUT1VOL_SET_LOUT1VOL(sc->sc_volume[ZAUDIO_OP_HP
422 ].left >> 1));
423 wm8750_write(sc, ROUT1VOL_REG, ROUT1VOL_RO1VU | ROUT1VOL_RO1ZC |
424 ROUT1VOL_SET_ROUT1VOL(sc->sc_volume[ZAUDIO_OP_HP
425 ].right >> 1));
426 break;
427 }
428 }
429
430 void
431 zaudio_update_mutes(struct zaudio_softc *sc)
432 {
433 unsigned short val;
434
435 val = PWRMGMT2_DACL | PWRMGMT2_DACR;
436
437 if (sc->sc_unmute[ZAUDIO_OP_SPKR])
438 val |= PWRMGMT2_LOUT2 | PWRMGMT2_ROUT2;
439
440 if (sc->sc_unmute[ZAUDIO_OP_HP])
441 val |= PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1;
442
443 wm8750_write(sc, PWRMGMT2_REG, val);
444
445 scoop_set_headphone(sc->sc_unmute[ZAUDIO_OP_HP]);
446 }
447
448 void
449 zaudio_play_setup(struct zaudio_softc *sc)
450 {
451 int i = 0;
452
453 pxa2x0_i2c_open(&sc->sc_i2c);
454
455 /* Program the codec with playback settings */
456 while (playback_registers[i][0] != 0xffff) {
457 wm8750_write(sc, playback_registers[i][0],
458 playback_registers[i][1]);
459 i++;
460 }
461 zaudio_update_mutes(sc);
462
463 pxa2x0_i2c_close(&sc->sc_i2c);
464 }
465
466 int
467 zaudio_open(void *hdl, int flags)
468 {
469 struct zaudio_softc *sc = hdl;
470
471 /* Power on the I2S bus and codec */
472 pxa2x0_i2s_open(&sc->sc_i2s);
473
474 return 0;
475 }
476
477 void
478 zaudio_close(void *hdl)
479 {
480 struct zaudio_softc *sc = hdl;
481
482 /* Power off the I2S bus and codec */
483 pxa2x0_i2s_close(&sc->sc_i2s);
484 }
485
486 int
487 zaudio_query_encoding(void *hdl, struct audio_encoding *aep)
488 {
489 switch (aep->index) {
490 case 0:
491 strlcpy(aep->name, AudioEulinear, sizeof(aep->name));
492 aep->encoding = AUDIO_ENCODING_ULINEAR;
493 aep->precision = 8;
494 aep->flags = 0;
495 return (0);
496 case 1:
497 strlcpy(aep->name, AudioEmulaw, sizeof(aep->name));
498 aep->encoding = AUDIO_ENCODING_ULAW;
499 aep->precision = 8;
500 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
501 return (0);
502 case 2:
503 strlcpy(aep->name, AudioEalaw, sizeof(aep->name));
504 aep->encoding = AUDIO_ENCODING_ALAW;
505 aep->precision = 8;
506 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
507 return (0);
508 case 3:
509 strlcpy(aep->name, AudioEslinear, sizeof(aep->name));
510 aep->encoding = AUDIO_ENCODING_SLINEAR;
511 aep->precision = 8;
512 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
513 return (0);
514 case 4:
515 strlcpy(aep->name, AudioEslinear_le, sizeof(aep->name));
516 aep->encoding = AUDIO_ENCODING_SLINEAR_LE;
517 aep->precision = 16;
518 aep->flags = 0;
519 return (0);
520 case 5:
521 strlcpy(aep->name, AudioEulinear_le, sizeof(aep->name));
522 aep->encoding = AUDIO_ENCODING_ULINEAR_LE;
523 aep->precision = 16;
524 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
525 return (0);
526 case 6:
527 strlcpy(aep->name, AudioEslinear_be, sizeof(aep->name));
528 aep->encoding = AUDIO_ENCODING_SLINEAR_BE;
529 aep->precision = 16;
530 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
531 return (0);
532 case 7:
533 strlcpy(aep->name, AudioEulinear_be, sizeof(aep->name));
534 aep->encoding = AUDIO_ENCODING_ULINEAR_BE;
535 aep->precision = 16;
536 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
537 return (0);
538 default:
539 return (EINVAL);
540 }
541 }
542
543 int
544 zaudio_set_params(void *hdl, int setmode, int usemode,
545 struct audio_params *play, struct audio_params *rec)
546 {
547 struct zaudio_softc *sc = hdl;
548
549 if (setmode & AUMODE_PLAY) {
550 play->factor = 1;
551 play->sw_code = NULL;
552 switch(play->encoding) {
553 case AUDIO_ENCODING_ULAW:
554 switch (play->channels) {
555 case 1:
556 play->factor = 4;
557 play->sw_code = mulaw_to_slinear16_mts;
558 break;
559 case 2:
560 play->factor = 2;
561 play->sw_code = mulaw_to_slinear16;
562 break;
563 default:
564 return (EINVAL);
565 }
566 break;
567 case AUDIO_ENCODING_SLINEAR_LE:
568 switch (play->precision) {
569 case 8:
570 switch (play->channels) {
571 case 1:
572 play->factor = 4;
573 play->sw_code = linear8_to_linear16_mts;
574 break;
575 case 2:
576 play->factor = 2;
577 play->sw_code = linear8_to_linear16;
578 break;
579 default:
580 return (EINVAL);
581 }
582 break;
583 case 16:
584 switch (play->channels) {
585 case 1:
586 play->factor = 2;
587 play->sw_code = noswap_bytes_mts;
588 break;
589 case 2:
590 break;
591 default:
592 return (EINVAL);
593 }
594 break;
595 default:
596 return (EINVAL);
597 }
598 break;
599 case AUDIO_ENCODING_ULINEAR_LE:
600 switch (play->precision) {
601 case 8:
602 switch (play->channels) {
603 case 1:
604 play->factor = 4;
605 play->sw_code =
606 ulinear8_to_linear16_mts;
607 break;
608 case 2:
609 play->factor = 2;
610 play->sw_code = ulinear8_to_linear16;
611 break;
612 default:
613 return (EINVAL);
614 }
615 break;
616 case 16:
617 switch (play->channels) {
618 case 1:
619 play->factor = 2;
620 play->sw_code = change_sign16_mts;
621 break;
622 case 2:
623 play->sw_code = change_sign16;
624 break;
625 default:
626 return (EINVAL);
627 }
628 break;
629 default:
630 return (EINVAL);
631 }
632 break;
633 case AUDIO_ENCODING_ALAW:
634 switch (play->channels) {
635 case 1:
636 play->factor = 4;
637 play->sw_code = alaw_to_slinear16_mts;
638 case 2:
639 play->factor = 2;
640 play->sw_code = alaw_to_slinear16;
641 default:
642 return (EINVAL);
643 }
644 break;
645 case AUDIO_ENCODING_SLINEAR_BE:
646 switch (play->precision) {
647 case 8:
648 switch (play->channels) {
649 case 1:
650 play->factor = 4;
651 play->sw_code =
652 linear8_to_linear16_mts;
653 break;
654 case 2:
655 play->factor = 2;
656 play->sw_code = linear8_to_linear16;
657 break;
658 default:
659 return (EINVAL);
660 }
661 break;
662 case 16:
663 switch (play->channels) {
664 case 1:
665 play->factor = 2;
666 play->sw_code = swap_bytes_mts;
667 break;
668 case 2:
669 play->sw_code = swap_bytes;
670 break;
671 default:
672 return (EINVAL);
673 }
674 break;
675 default:
676 return (EINVAL);
677 }
678 break;
679 case AUDIO_ENCODING_ULINEAR_BE:
680 switch (play->precision) {
681 case 8:
682 switch (play->channels) {
683 case 1:
684 play->factor = 4;
685 play->sw_code =
686 ulinear8_to_linear16_mts;
687 break;
688 case 2:
689 play->factor = 2;
690 play->sw_code = ulinear8_to_linear16;
691 break;
692 default:
693 return (EINVAL);
694 }
695 break;
696 case 16:
697 switch (play->channels) {
698 case 1:
699 play->factor = 2;
700 play->sw_code =
701 change_sign16_swap_bytes_mts;
702 break;
703 case 2:
704 play->sw_code =
705 change_sign16_swap_bytes;
706 break;
707 default:
708 return (EINVAL);
709 }
710 break;
711 default:
712 return (EINVAL);
713 }
714 break;
715 default:
716 return (EINVAL);
717 }
718
719 pxa2x0_i2s_setspeed(&sc->sc_i2s, &play->sample_rate);
720 }
721
722 #if RECORD_XXX_NOT_YET
723 if (setmode & AUMODE_RECORD) {
724 rec->factor = 1;
725 rec->sw_code = NULL;
726 switch(rec->encoding) {
727 case AUDIO_ENCODING_ULAW:
728 rec->sw_code = ulinear8_to_mulaw;
729 break;
730 case AUDIO_ENCODING_SLINEAR_LE:
731 if (rec->precision == 8)
732 rec->sw_code = change_sign8;
733 break;
734 case AUDIO_ENCODING_ULINEAR_LE:
735 if (rec->precision == 16)
736 rec->sw_code = change_sign16;
737 break;
738 case AUDIO_ENCODING_ALAW:
739 rec->sw_code = ulinear8_to_alaw;
740 break;
741 case AUDIO_ENCODING_SLINEAR_BE:
742 if (rec->precision == 16)
743 rec->sw_code = swap_bytes;
744 else
745 rec->sw_code = change_sign8;
746 break;
747 case AUDIO_ENCODING_ULINEAR_BE:
748 if (rec->precision == 16)
749 rec->sw_code = swap_bytes_change_sign16;
750 break;
751 default:
752 return (EINVAL);
753 }
754
755 pxa2x0_i2s_setspeed(sc, &rec->sample_rate);
756 }
757 #endif
758
759 return (0);
760 }
761
762 int
763 zaudio_halt_output(void *hdl)
764 {
765 struct zaudio_softc *sc = hdl;
766
767 /* XXX forcibly stop output DMA? */
768
769 zaudio_standby(sc);
770 sc->sc_playing = 0;
771
772 return 0;
773 }
774
775 int
776 zaudio_halt_input(void *hdl)
777 {
778 /* struct zaudio_softc *sc = hdl; */
779
780 return 0;
781 }
782
783 int
784 zaudio_getdev(void *hdl, struct audio_device *ret)
785 {
786 /* struct zaudio_softc *sc = hdl; */
787
788 *ret = wm8750_device;
789 return 0;
790 }
791
792 #define ZAUDIO_SPKR_LVL 0
793 #define ZAUDIO_SPKR_MUTE 1
794 #define ZAUDIO_HP_LVL 2
795 #define ZAUDIO_HP_MUTE 3
796 #define ZAUDIO_OUTPUT_CLASS 4
797
798 int
799 zaudio_set_port(void *hdl, struct mixer_ctrl *mc)
800 {
801 struct zaudio_softc *sc = hdl;
802 int error = EINVAL, s;
803
804 s = splbio();
805 pxa2x0_i2c_open(&sc->sc_i2c);
806
807 switch (mc->dev) {
808 case ZAUDIO_SPKR_LVL:
809 if (mc->type != AUDIO_MIXER_VALUE)
810 break;
811 if (mc->un.value.num_channels == 1)
812 sc->sc_volume[ZAUDIO_OP_SPKR].left =
813 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
814 else
815 break;
816 zaudio_update_volume(sc, ZAUDIO_OP_SPKR);
817 error = 0;
818 break;
819 case ZAUDIO_SPKR_MUTE:
820 if (mc->type != AUDIO_MIXER_ENUM)
821 break;
822 sc->sc_unmute[ZAUDIO_OP_SPKR] = mc->un.ord ? 1 : 0;
823 zaudio_update_mutes(sc);
824 error = 0;
825 break;
826 case ZAUDIO_HP_LVL:
827 if (mc->type != AUDIO_MIXER_VALUE)
828 break;
829 if (mc->un.value.num_channels == 1) {
830 sc->sc_volume[ZAUDIO_OP_HP].left =
831 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
832 sc->sc_volume[ZAUDIO_OP_HP].right =
833 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
834 } else if (mc->un.value.num_channels == 2) {
835 sc->sc_volume[ZAUDIO_OP_HP].left =
836 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
837 sc->sc_volume[ZAUDIO_OP_HP].right =
838 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
839 }
840 else
841 break;
842 zaudio_update_volume(sc, ZAUDIO_OP_HP);
843 error = 0;
844 break;
845 case ZAUDIO_HP_MUTE:
846 if (mc->type != AUDIO_MIXER_ENUM)
847 break;
848 sc->sc_unmute[ZAUDIO_OP_HP] = mc->un.ord ? 1 : 0;
849 zaudio_update_mutes(sc);
850 error = 0;
851 break;
852 }
853
854 pxa2x0_i2c_close(&sc->sc_i2c);
855 splx(s);
856
857 return error;
858 }
859
860 int
861 zaudio_get_port(void *hdl, struct mixer_ctrl *mc)
862 {
863 struct zaudio_softc *sc = hdl;
864 int error = EINVAL;
865
866 switch (mc->dev) {
867 case ZAUDIO_SPKR_LVL:
868 if (mc->type != AUDIO_MIXER_VALUE)
869 break;
870 if (mc->un.value.num_channels == 1)
871 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
872 sc->sc_volume[ZAUDIO_OP_SPKR].left;
873 else
874 break;
875 error = 0;
876 break;
877 case ZAUDIO_SPKR_MUTE:
878 if (mc->type != AUDIO_MIXER_ENUM)
879 break;
880 mc->un.ord = sc->sc_unmute[ZAUDIO_OP_SPKR] ? 1 : 0;
881 error = 0;
882 break;
883 case ZAUDIO_HP_LVL:
884 if (mc->type != AUDIO_MIXER_VALUE)
885 break;
886 if (mc->un.value.num_channels == 1)
887 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
888 sc->sc_volume[ZAUDIO_OP_HP].left;
889 else if (mc->un.value.num_channels == 2) {
890 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
891 sc->sc_volume[ZAUDIO_OP_HP].left;
892 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
893 sc->sc_volume[ZAUDIO_OP_HP].right;
894 }
895 else
896 break;
897 error = 0;
898 break;
899 case ZAUDIO_HP_MUTE:
900 if (mc->type != AUDIO_MIXER_ENUM)
901 break;
902 mc->un.ord = sc->sc_unmute[ZAUDIO_OP_HP] ? 1 : 0;
903 error = 0;
904 break;
905 }
906
907 return error;
908 }
909
910 int
911 zaudio_query_devinfo(void *hdl, struct mixer_devinfo *di)
912 {
913 /* struct zaudio_softc *sc = hdl; */
914
915 switch (di->index) {
916 case ZAUDIO_SPKR_LVL:
917 di->type = AUDIO_MIXER_VALUE;
918 di->mixer_class = ZAUDIO_OUTPUT_CLASS;
919 di->prev = AUDIO_MIXER_LAST;
920 di->next = ZAUDIO_SPKR_MUTE;
921 strlcpy(di->label.name, AudioNspeaker,
922 sizeof(di->label.name));
923 strlcpy(di->un.v.units.name, AudioNvolume,
924 sizeof(di->un.v.units.name));
925 di->un.v.num_channels = 1;
926 break;
927 case ZAUDIO_SPKR_MUTE:
928 di->type = AUDIO_MIXER_ENUM;
929 di->mixer_class = ZAUDIO_OUTPUT_CLASS;
930 di->prev = ZAUDIO_SPKR_LVL;
931 di->next = AUDIO_MIXER_LAST;
932 goto mute;
933 case ZAUDIO_HP_LVL:
934 di->type = AUDIO_MIXER_VALUE;
935 di->mixer_class = ZAUDIO_OUTPUT_CLASS;
936 di->prev = AUDIO_MIXER_LAST;
937 di->next = ZAUDIO_HP_MUTE;
938 strlcpy(di->label.name, AudioNheadphone,
939 sizeof(di->label.name));
940 di->un.v.num_channels = 1;
941 strlcpy(di->un.v.units.name, AudioNvolume,
942 sizeof(di->un.v.units.name));
943 break;
944 case ZAUDIO_HP_MUTE:
945 di->type = AUDIO_MIXER_ENUM;
946 di->mixer_class = ZAUDIO_OUTPUT_CLASS;
947 di->prev = ZAUDIO_HP_LVL;
948 di->next = AUDIO_MIXER_LAST;
949 mute:
950 strlcpy(di->label.name, AudioNmute, sizeof(di->label.name));
951 di->un.e.num_mem = 2;
952 strlcpy(di->un.e.member[0].label.name, AudioNon,
953 sizeof(di->un.e.member[0].label.name));
954 di->un.e.member[0].ord = 0;
955 strlcpy(di->un.e.member[1].label.name, AudioNoff,
956 sizeof(di->un.e.member[1].label.name));
957 di->un.e.member[1].ord = 1;
958 break;
959 case ZAUDIO_OUTPUT_CLASS:
960 di->type = AUDIO_MIXER_CLASS;
961 di->mixer_class = ZAUDIO_OUTPUT_CLASS;
962 di->prev = AUDIO_MIXER_LAST;
963 di->next = AUDIO_MIXER_LAST;
964 strlcpy(di->label.name, AudioCoutputs,
965 sizeof(di->label.name));
966 break;
967 default:
968 return ENXIO;
969 }
970
971 return 0;
972 }
973
974 int
975 zaudio_get_props(void *hdl)
976 {
977 return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX;
978 }
979
980 int
981 zaudio_start_output(void *hdl, void *block, int bsize, void (*intr)(void *),
982 void *intrarg)
983 {
984 struct zaudio_softc *sc = hdl;
985 int err;
986
987 /* Power up codec if we are not already playing. */
988 if (!sc->sc_playing) {
989 sc->sc_playing = 1;
990 zaudio_play_setup(sc);
991 }
992
993 /* Start DMA via I2S */
994 err = pxa2x0_i2s_start_output(&sc->sc_i2s, block, bsize, intr, intrarg);
995 if (err) {
996 zaudio_standby(sc);
997 sc->sc_playing = 0;
998 }
999 return err;
1000 }
1001
1002 int
1003 zaudio_start_input(void *hdl, void *block, int bsize, void (*intr)(void *),
1004 void *intrarg)
1005 {
1006 return ENXIO;
1007 }
1008