zaudio.c revision 1.6 1 /* $NetBSD: zaudio.c,v 1.6 2009/01/29 12:28:15 nonaka 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(device_t, cfdata_t, void *);
62 static void zaudio_attach(device_t, device_t, void *);
63 static int zaudio_detach(device_t, 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 device_t 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_NEW(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(device_t parent, cfdata_t cf, void *aux)
207 {
208
209 return 1;
210 }
211
212 static void
213 zaudio_attach(device_t parent, device_t self, void *aux)
214 {
215 struct zaudio_softc *sc = device_private(self);
216 struct pxaip_attach_args *pxa = aux;
217 int rv;
218
219 sc->sc_dev = self;
220
221 aprint_normal(": I2C, I2S, WM8750 Audio\n");
222 aprint_naive("\n");
223
224 sc->sc_powerhook = powerhook_establish(device_xname(sc->sc_dev),
225 zaudio_power, sc);
226 if (sc->sc_powerhook == NULL) {
227 aprint_error_dev(sc->sc_dev, "unable to establish powerhook\n");
228 return;
229 }
230
231 sc->sc_i2s.sc_iot = pxa->pxa_iot;
232 sc->sc_i2s.sc_dmat = pxa->pxa_dmat;
233 sc->sc_i2s.sc_size = PXA2X0_I2S_SIZE;
234 if (pxa2x0_i2s_attach_sub(&sc->sc_i2s)) {
235 aprint_error_dev(sc->sc_dev, "unable to attach I2S\n");
236 goto fail_i2s;
237 }
238
239 sc->sc_i2c.sc_iot = pxa->pxa_iot;
240 sc->sc_i2c.sc_size = PXA2X0_I2C_SIZE;
241 if (pxa2x0_i2c_attach_sub(&sc->sc_i2c)) {
242 aprint_error_dev(sc->sc_dev, "unable to attach I2C\n");
243 goto fail_i2c;
244 }
245
246 /* Check for an I2C response from the wm8750 */
247 pxa2x0_i2c_open(&sc->sc_i2c);
248 rv = wm8750_write(sc, RESET_REG, 0);
249 pxa2x0_i2c_close(&sc->sc_i2c);
250
251 if (rv) {
252 aprint_error_dev(sc->sc_dev, "codec failed to respond\n");
253 goto fail_probe;
254 }
255 delay(100);
256
257 /* Speaker on, headphones off by default. */
258 sc->sc_volume[ZAUDIO_OP_SPKR].left = 240;
259 sc->sc_unmute[ZAUDIO_OP_SPKR] = 1;
260 sc->sc_volume[ZAUDIO_OP_HP].left = 180;
261 sc->sc_volume[ZAUDIO_OP_HP].right = 180;
262 sc->sc_unmute[ZAUDIO_OP_HP] = 0;
263
264 /* Configure headphone jack state change handling. */
265 callout_init(&sc->sc_to, 0);
266 callout_setfunc(&sc->sc_to, zaudio_jack, sc);
267 pxa2x0_gpio_set_function(GPIO_HP_IN_C3000, GPIO_IN);
268 (void)pxa2x0_gpio_intr_establish(GPIO_HP_IN_C3000,
269 IST_EDGE_BOTH, IPL_BIO, zaudio_jack_intr, sc);
270
271 zaudio_init(sc);
272
273 audio_attach_mi(&wm8750_hw_if, sc, sc->sc_dev);
274
275 return;
276
277 fail_probe:
278 pxa2x0_i2c_detach_sub(&sc->sc_i2c);
279 fail_i2c:
280 pxa2x0_i2s_detach_sub(&sc->sc_i2s);
281 fail_i2s:
282 powerhook_disestablish(sc->sc_powerhook);
283 }
284
285 static int
286 zaudio_detach(device_t self, int flags)
287 {
288 struct zaudio_softc *sc = device_private(self);
289
290 if (sc->sc_powerhook != NULL) {
291 powerhook_disestablish(sc->sc_powerhook);
292 sc->sc_powerhook = NULL;
293 }
294
295 pxa2x0_i2c_detach_sub(&sc->sc_i2c);
296 pxa2x0_i2s_detach_sub(&sc->sc_i2s);
297
298 return 0;
299 }
300
301 static void
302 zaudio_power(int why, void *arg)
303 {
304 struct zaudio_softc *sc = arg;
305
306 switch (why) {
307 case PWR_STANDBY:
308 case PWR_SUSPEND:
309 callout_stop(&sc->sc_to);
310 zaudio_standby(sc);
311 break;
312
313 case PWR_RESUME:
314 pxa2x0_i2s_init(&sc->sc_i2s);
315 pxa2x0_i2c_init(&sc->sc_i2c);
316 zaudio_init(sc);
317 break;
318 }
319 }
320
321 void
322 zaudio_init(struct zaudio_softc *sc)
323 {
324
325 pxa2x0_i2c_open(&sc->sc_i2c);
326
327 /* Reset the codec */
328 wm8750_write(sc, RESET_REG, 0);
329 delay(100);
330
331 /* Switch to standby power only */
332 wm8750_write(sc, PWRMGMT1_REG, PWRMGMT1_SET_VMIDSEL(2));
333 wm8750_write(sc, PWRMGMT2_REG, 0);
334
335 /* Configure digital interface for I2S */
336 wm8750_write(sc, AUDINT_REG, AUDINT_SET_FORMAT(2));
337
338 /* Initialise volume levels */
339 zaudio_update_volume(sc, ZAUDIO_OP_SPKR);
340 zaudio_update_volume(sc, ZAUDIO_OP_HP);
341
342 pxa2x0_i2c_close(&sc->sc_i2c);
343
344 scoop_set_headphone(0);
345
346 /* Assume that the jack state has changed. */
347 zaudio_jack(sc);
348
349 }
350
351 static int
352 zaudio_jack_intr(void *v)
353 {
354 struct zaudio_softc *sc = v;
355
356 if (!callout_active(&sc->sc_to))
357 zaudio_jack(sc);
358
359 return 1;
360 }
361
362 void
363 zaudio_jack(void *v)
364 {
365 struct zaudio_softc *sc = v;
366
367 switch (sc->sc_state) {
368 case ZAUDIO_JACK_STATE_OUT:
369 if (pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) {
370 sc->sc_state = ZAUDIO_JACK_STATE_INS;
371 sc->sc_icount = 0;
372 }
373 break;
374
375 case ZAUDIO_JACK_STATE_INS:
376 if (sc->sc_icount++ > 2) {
377 if (pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) {
378 sc->sc_state = ZAUDIO_JACK_STATE_IN;
379 sc->sc_unmute[ZAUDIO_OP_SPKR] = 0;
380 sc->sc_unmute[ZAUDIO_OP_HP] = 1;
381 goto update_mutes;
382 } else
383 sc->sc_state = ZAUDIO_JACK_STATE_OUT;
384 }
385 break;
386
387 case ZAUDIO_JACK_STATE_IN:
388 if (!pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) {
389 sc->sc_state = ZAUDIO_JACK_STATE_REM;
390 sc->sc_icount = 0;
391 }
392 break;
393
394 case ZAUDIO_JACK_STATE_REM:
395 if (sc->sc_icount++ > 2) {
396 if (!pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) {
397 sc->sc_state = ZAUDIO_JACK_STATE_OUT;
398 sc->sc_unmute[ZAUDIO_OP_SPKR] = 1;
399 sc->sc_unmute[ZAUDIO_OP_HP] = 0;
400 goto update_mutes;
401 } else
402 sc->sc_state = ZAUDIO_JACK_STATE_IN;
403 }
404 break;
405 }
406
407 callout_schedule(&sc->sc_to, hz/4);
408
409 return;
410
411 update_mutes:
412 callout_stop(&sc->sc_to);
413
414 if (sc->sc_playing) {
415 pxa2x0_i2c_open(&sc->sc_i2c);
416 zaudio_update_mutes(sc);
417 pxa2x0_i2c_close(&sc->sc_i2c);
418 }
419 }
420
421 void
422 zaudio_standby(struct zaudio_softc *sc)
423 {
424
425 pxa2x0_i2c_open(&sc->sc_i2c);
426
427 /* Switch codec to standby power only */
428 wm8750_write(sc, PWRMGMT1_REG, PWRMGMT1_SET_VMIDSEL(2));
429 wm8750_write(sc, PWRMGMT2_REG, 0);
430
431 pxa2x0_i2c_close(&sc->sc_i2c);
432
433 scoop_set_headphone(0);
434 }
435
436 void
437 zaudio_update_volume(struct zaudio_softc *sc, int output)
438 {
439
440 switch (output) {
441 case ZAUDIO_OP_SPKR:
442 wm8750_write(sc, LOUT2VOL_REG, LOUT2VOL_LO2VU | LOUT2VOL_LO2ZC |
443 LOUT2VOL_SET_LOUT2VOL(sc->sc_volume[ZAUDIO_OP_SPKR
444 ].left >> 1));
445 wm8750_write(sc, ROUT2VOL_REG, ROUT2VOL_RO2VU | ROUT2VOL_RO2ZC |
446 ROUT2VOL_SET_ROUT2VOL(sc->sc_volume[ZAUDIO_OP_SPKR
447 ].left >> 1));
448 break;
449
450 case ZAUDIO_OP_HP:
451 wm8750_write(sc, LOUT1VOL_REG, LOUT1VOL_LO1VU | LOUT1VOL_LO1ZC |
452 LOUT1VOL_SET_LOUT1VOL(sc->sc_volume[ZAUDIO_OP_HP
453 ].left >> 1));
454 wm8750_write(sc, ROUT1VOL_REG, ROUT1VOL_RO1VU | ROUT1VOL_RO1ZC |
455 ROUT1VOL_SET_ROUT1VOL(sc->sc_volume[ZAUDIO_OP_HP
456 ].right >> 1));
457 break;
458 }
459 }
460
461 void
462 zaudio_update_mutes(struct zaudio_softc *sc)
463 {
464 uint16_t val;
465
466 val = PWRMGMT2_DACL | PWRMGMT2_DACR;
467
468 if (sc->sc_unmute[ZAUDIO_OP_SPKR])
469 val |= PWRMGMT2_LOUT2 | PWRMGMT2_ROUT2;
470
471 if (sc->sc_unmute[ZAUDIO_OP_HP])
472 val |= PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1;
473
474 wm8750_write(sc, PWRMGMT2_REG, val);
475
476 scoop_set_headphone(sc->sc_unmute[ZAUDIO_OP_HP]);
477 }
478
479 void
480 zaudio_play_setup(struct zaudio_softc *sc)
481 {
482 int i;
483
484 pxa2x0_i2c_open(&sc->sc_i2c);
485
486 /* Program the codec with playback settings */
487 for (i = 0; playback_registers[i][0] != 0xffff; i++) {
488 wm8750_write(sc, playback_registers[i][0],
489 playback_registers[i][1]);
490 }
491 zaudio_update_mutes(sc);
492
493 pxa2x0_i2c_close(&sc->sc_i2c);
494 }
495
496 /*
497 * audio operation functions.
498 */
499 static int
500 zaudio_open(void *hdl, int flags)
501 {
502 struct zaudio_softc *sc = hdl;
503
504 /* Power on the I2S bus and codec */
505 pxa2x0_i2s_open(&sc->sc_i2s);
506
507 return 0;
508 }
509
510 static void
511 zaudio_close(void *hdl)
512 {
513 struct zaudio_softc *sc = hdl;
514
515 /* Power off the I2S bus and codec */
516 pxa2x0_i2s_close(&sc->sc_i2s);
517 }
518
519 static int
520 zaudio_query_encoding(void *hdl, struct audio_encoding *aep)
521 {
522
523 switch (aep->index) {
524 case 0:
525 strlcpy(aep->name, AudioEulinear, sizeof(aep->name));
526 aep->encoding = AUDIO_ENCODING_ULINEAR;
527 aep->precision = 8;
528 aep->flags = 0;
529 break;
530
531 case 1:
532 strlcpy(aep->name, AudioEmulaw, sizeof(aep->name));
533 aep->encoding = AUDIO_ENCODING_ULAW;
534 aep->precision = 8;
535 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
536 break;
537
538 case 2:
539 strlcpy(aep->name, AudioEalaw, sizeof(aep->name));
540 aep->encoding = AUDIO_ENCODING_ALAW;
541 aep->precision = 8;
542 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
543 break;
544
545 case 3:
546 strlcpy(aep->name, AudioEslinear, sizeof(aep->name));
547 aep->encoding = AUDIO_ENCODING_SLINEAR;
548 aep->precision = 8;
549 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
550 break;
551
552 case 4:
553 strlcpy(aep->name, AudioEslinear_le, sizeof(aep->name));
554 aep->encoding = AUDIO_ENCODING_SLINEAR_LE;
555 aep->precision = 16;
556 aep->flags = 0;
557 break;
558
559 case 5:
560 strlcpy(aep->name, AudioEulinear_le, sizeof(aep->name));
561 aep->encoding = AUDIO_ENCODING_ULINEAR_LE;
562 aep->precision = 16;
563 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
564 break;
565
566 case 6:
567 strlcpy(aep->name, AudioEslinear_be, sizeof(aep->name));
568 aep->encoding = AUDIO_ENCODING_SLINEAR_BE;
569 aep->precision = 16;
570 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
571 break;
572
573 case 7:
574 strlcpy(aep->name, AudioEulinear_be, sizeof(aep->name));
575 aep->encoding = AUDIO_ENCODING_ULINEAR_BE;
576 aep->precision = 16;
577 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
578 break;
579
580 default:
581 return EINVAL;
582 }
583
584 return 0;
585 }
586
587 static int
588 zaudio_set_params(void *hdl, int setmode, int usemode,
589 audio_params_t *play, audio_params_t *rec,
590 stream_filter_list_t *pfil, stream_filter_list_t *rfil)
591 {
592 struct zaudio_softc *sc = hdl;
593 struct audio_params *p;
594 stream_filter_list_t *fil;
595 int mode, i;
596
597 if (play->sample_rate != rec->sample_rate &&
598 usemode == (AUMODE_PLAY | AUMODE_RECORD)) {
599 if (setmode == AUMODE_PLAY) {
600 rec->sample_rate = play->sample_rate;
601 setmode |= AUMODE_RECORD;
602 } else if (setmode == AUMODE_RECORD) {
603 play->sample_rate = rec->sample_rate;
604 setmode |= AUMODE_PLAY;
605 } else
606 return EINVAL;
607 }
608
609 for (mode = AUMODE_RECORD; mode != -1;
610 mode = (mode == AUMODE_RECORD) ? AUMODE_PLAY : -1) {
611 if ((setmode & mode) == 0)
612 continue;
613
614 p = (mode == AUMODE_PLAY) ? play : rec;
615
616 if (p->sample_rate < 4000 || p->sample_rate > 48000 ||
617 (p->precision != 8 && p->precision != 16) ||
618 (p->channels != 1 && p->channels != 2))
619 return EINVAL;
620
621 fil = (mode == AUMODE_PLAY) ? pfil : rfil;
622 i = auconv_set_converter(zaudio_formats, ZAUDIO_NFORMATS,
623 mode, p, false, fil);
624 if (i < 0)
625 return EINVAL;
626 }
627
628 if (setmode == AUMODE_RECORD)
629 pxa2x0_i2s_setspeed(&sc->sc_i2s, &rec->sample_rate);
630 else
631 pxa2x0_i2s_setspeed(&sc->sc_i2s, &play->sample_rate);
632
633 return 0;
634 }
635
636 static int
637 zaudio_round_blocksize(void *hdl, int bs, int mode, const audio_params_t *param)
638 {
639 struct zaudio_softc *sc = hdl;
640
641 return pxa2x0_i2s_round_blocksize(&sc->sc_i2s, bs, mode, param);
642 }
643
644
645 static int
646 zaudio_halt_output(void *hdl)
647 {
648 struct zaudio_softc *sc = hdl;
649 int rv;
650
651 rv = pxa2x0_i2s_halt_output(&sc->sc_i2s);
652 zaudio_standby(sc);
653 sc->sc_playing = 0;
654
655 return rv;
656 }
657
658 static int
659 zaudio_halt_input(void *hdl)
660 {
661 struct zaudio_softc *sc = hdl;
662 int rv;
663
664 rv = pxa2x0_i2s_halt_input(&sc->sc_i2s);
665
666 return rv;
667 }
668
669 static int
670 zaudio_getdev(void *hdl, struct audio_device *ret)
671 {
672 /* struct zaudio_softc *sc = hdl; */
673
674 *ret = wm8750_device;
675 return 0;
676 }
677
678 #define ZAUDIO_SPKR_LVL 0
679 #define ZAUDIO_SPKR_MUTE 1
680 #define ZAUDIO_HP_LVL 2
681 #define ZAUDIO_HP_MUTE 3
682 #define ZAUDIO_OUTPUT_CLASS 4
683
684 static int
685 zaudio_set_port(void *hdl, struct mixer_ctrl *mc)
686 {
687 struct zaudio_softc *sc = hdl;
688 int error = EINVAL;
689 int s;
690
691 s = splbio();
692 pxa2x0_i2c_open(&sc->sc_i2c);
693
694 switch (mc->dev) {
695 case ZAUDIO_SPKR_LVL:
696 if (mc->type != AUDIO_MIXER_VALUE)
697 break;
698 if (mc->un.value.num_channels == 1)
699 sc->sc_volume[ZAUDIO_OP_SPKR].left =
700 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
701 else
702 break;
703 zaudio_update_volume(sc, ZAUDIO_OP_SPKR);
704 error = 0;
705 break;
706
707 case ZAUDIO_SPKR_MUTE:
708 if (mc->type != AUDIO_MIXER_ENUM)
709 break;
710 sc->sc_unmute[ZAUDIO_OP_SPKR] = mc->un.ord ? 1 : 0;
711 zaudio_update_mutes(sc);
712 error = 0;
713 break;
714
715 case ZAUDIO_HP_LVL:
716 if (mc->type != AUDIO_MIXER_VALUE)
717 break;
718 if (mc->un.value.num_channels == 1) {
719 sc->sc_volume[ZAUDIO_OP_HP].left =
720 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
721 sc->sc_volume[ZAUDIO_OP_HP].right =
722 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
723 } else if (mc->un.value.num_channels == 2) {
724 sc->sc_volume[ZAUDIO_OP_HP].left =
725 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
726 sc->sc_volume[ZAUDIO_OP_HP].right =
727 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
728 }
729 else
730 break;
731 zaudio_update_volume(sc, ZAUDIO_OP_HP);
732 error = 0;
733 break;
734
735 case ZAUDIO_HP_MUTE:
736 if (mc->type != AUDIO_MIXER_ENUM)
737 break;
738 sc->sc_unmute[ZAUDIO_OP_HP] = mc->un.ord ? 1 : 0;
739 zaudio_update_mutes(sc);
740 error = 0;
741 break;
742 }
743
744 pxa2x0_i2c_close(&sc->sc_i2c);
745 splx(s);
746
747 return error;
748 }
749
750 static int
751 zaudio_get_port(void *hdl, struct mixer_ctrl *mc)
752 {
753 struct zaudio_softc *sc = hdl;
754 int error = EINVAL;
755
756 switch (mc->dev) {
757 case ZAUDIO_SPKR_LVL:
758 if (mc->type != AUDIO_MIXER_VALUE)
759 break;
760 if (mc->un.value.num_channels == 1)
761 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
762 sc->sc_volume[ZAUDIO_OP_SPKR].left;
763 else
764 break;
765 error = 0;
766 break;
767
768 case ZAUDIO_SPKR_MUTE:
769 if (mc->type != AUDIO_MIXER_ENUM)
770 break;
771 mc->un.ord = sc->sc_unmute[ZAUDIO_OP_SPKR] ? 1 : 0;
772 error = 0;
773 break;
774
775 case ZAUDIO_HP_LVL:
776 if (mc->type != AUDIO_MIXER_VALUE)
777 break;
778 if (mc->un.value.num_channels == 1)
779 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
780 sc->sc_volume[ZAUDIO_OP_HP].left;
781 else if (mc->un.value.num_channels == 2) {
782 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
783 sc->sc_volume[ZAUDIO_OP_HP].left;
784 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
785 sc->sc_volume[ZAUDIO_OP_HP].right;
786 }
787 else
788 break;
789 error = 0;
790 break;
791
792 case ZAUDIO_HP_MUTE:
793 if (mc->type != AUDIO_MIXER_ENUM)
794 break;
795 mc->un.ord = sc->sc_unmute[ZAUDIO_OP_HP] ? 1 : 0;
796 error = 0;
797 break;
798 }
799
800 return error;
801 }
802
803 static int
804 zaudio_query_devinfo(void *hdl, struct mixer_devinfo *di)
805 {
806 /* struct zaudio_softc *sc = hdl; */
807
808 switch (di->index) {
809 case ZAUDIO_SPKR_LVL:
810 di->type = AUDIO_MIXER_VALUE;
811 di->mixer_class = ZAUDIO_OUTPUT_CLASS;
812 di->prev = AUDIO_MIXER_LAST;
813 di->next = ZAUDIO_SPKR_MUTE;
814 strlcpy(di->label.name, AudioNspeaker,
815 sizeof(di->label.name));
816 strlcpy(di->un.v.units.name, AudioNvolume,
817 sizeof(di->un.v.units.name));
818 di->un.v.num_channels = 1;
819 break;
820
821 case ZAUDIO_SPKR_MUTE:
822 di->type = AUDIO_MIXER_ENUM;
823 di->mixer_class = ZAUDIO_OUTPUT_CLASS;
824 di->prev = ZAUDIO_SPKR_LVL;
825 di->next = AUDIO_MIXER_LAST;
826 goto mute;
827
828 case ZAUDIO_HP_LVL:
829 di->type = AUDIO_MIXER_VALUE;
830 di->mixer_class = ZAUDIO_OUTPUT_CLASS;
831 di->prev = AUDIO_MIXER_LAST;
832 di->next = ZAUDIO_HP_MUTE;
833 strlcpy(di->label.name, AudioNheadphone,
834 sizeof(di->label.name));
835 di->un.v.num_channels = 1;
836 strlcpy(di->un.v.units.name, AudioNvolume,
837 sizeof(di->un.v.units.name));
838 break;
839
840 case ZAUDIO_HP_MUTE:
841 di->type = AUDIO_MIXER_ENUM;
842 di->mixer_class = ZAUDIO_OUTPUT_CLASS;
843 di->prev = ZAUDIO_HP_LVL;
844 di->next = AUDIO_MIXER_LAST;
845 mute:
846 strlcpy(di->label.name, AudioNmute, sizeof(di->label.name));
847 di->un.e.num_mem = 2;
848 strlcpy(di->un.e.member[0].label.name, AudioNon,
849 sizeof(di->un.e.member[0].label.name));
850 di->un.e.member[0].ord = 0;
851 strlcpy(di->un.e.member[1].label.name, AudioNoff,
852 sizeof(di->un.e.member[1].label.name));
853 di->un.e.member[1].ord = 1;
854 break;
855
856 case ZAUDIO_OUTPUT_CLASS:
857 di->type = AUDIO_MIXER_CLASS;
858 di->mixer_class = ZAUDIO_OUTPUT_CLASS;
859 di->prev = AUDIO_MIXER_LAST;
860 di->next = AUDIO_MIXER_LAST;
861 strlcpy(di->label.name, AudioCoutputs,
862 sizeof(di->label.name));
863 break;
864
865 default:
866 return ENXIO;
867 }
868
869 return 0;
870 }
871
872 static void *
873 zaudio_allocm(void *hdl, int direction, size_t size,
874 struct malloc_type *type, int flags)
875 {
876 struct zaudio_softc *sc = hdl;
877
878 return pxa2x0_i2s_allocm(&sc->sc_i2s, direction, size, type, flags);
879 }
880
881 static void
882 zaudio_freem(void *hdl, void *ptr, struct malloc_type *type)
883 {
884 struct zaudio_softc *sc = hdl;
885
886 return pxa2x0_i2s_freem(&sc->sc_i2s, ptr, type);
887 }
888
889 static size_t
890 zaudio_round_buffersize(void *hdl, int direction, size_t bufsize)
891 {
892 struct zaudio_softc *sc = hdl;
893
894 return pxa2x0_i2s_round_buffersize(&sc->sc_i2s, direction, bufsize);
895 }
896
897 static paddr_t
898 zaudio_mappage(void *hdl, void *mem, off_t off, int prot)
899 {
900 struct zaudio_softc *sc = hdl;
901
902 return pxa2x0_i2s_mappage(&sc->sc_i2s, mem, off, prot);
903 }
904
905 static int
906 zaudio_get_props(void *hdl)
907 {
908
909 return AUDIO_PROP_MMAP|AUDIO_PROP_INDEPENDENT|AUDIO_PROP_FULLDUPLEX;
910 }
911
912 static int
913 zaudio_start_output(void *hdl, void *block, int bsize, void (*intr)(void *),
914 void *intrarg)
915 {
916 struct zaudio_softc *sc = hdl;
917 int rv;
918
919 /* Power up codec if we are not already playing. */
920 if (!sc->sc_playing) {
921 sc->sc_playing = 1;
922 zaudio_play_setup(sc);
923 }
924
925 /* Start DMA via I2S */
926 rv = pxa2x0_i2s_start_output(&sc->sc_i2s, block, bsize, intr, intrarg);
927 if (rv) {
928 zaudio_standby(sc);
929 sc->sc_playing = 0;
930 }
931 return rv;
932 }
933
934 static int
935 zaudio_start_input(void *hdl, void *block, int bsize, void (*intr)(void *),
936 void *intrarg)
937 {
938
939 return ENXIO;
940 }
941