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