wm8750_zaudio.c revision 1.2 1 /* $NetBSD: wm8750_zaudio.c,v 1.2 2018/06/16 21:22:13 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 * Copyright (C) 2009 NONAKA Kimihiro <nonaka (at) netbsd.org>
22 * All rights reserved.
23 *
24 * Redistribution and use in source and binary forms, with or without
25 * modification, are permitted provided that the following conditions
26 * are met:
27 * 1. Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the following disclaimer.
29 * 2. Redistributions in binary form must reproduce the above copyright
30 * notice, this list of conditions and the following disclaimer in the
31 * documentation and/or other materials provided with the distribution.
32 *
33 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
34 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
35 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
36 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
37 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
38 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
39 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
40 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
42 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 */
44
45 /*
46 * TODO:
47 * - powerhooks (currently only works until first suspend)
48 */
49
50 #include "opt_cputypes.h"
51 #include "opt_zaudio.h"
52
53 #include <sys/cdefs.h>
54 __KERNEL_RCSID(0, "$NetBSD: wm8750_zaudio.c,v 1.2 2018/06/16 21:22:13 thorpej Exp $");
55
56 #include <sys/param.h>
57 #include <sys/systm.h>
58 #include <sys/callout.h>
59 #include <sys/device.h>
60 #include <sys/kmem.h>
61 #include <sys/kernel.h>
62 #include <sys/audioio.h>
63 #include <sys/mutex.h>
64 #include <sys/intr.h>
65 #include <sys/bus.h>
66
67 #include <dev/audio_if.h>
68 #include <dev/mulaw.h>
69 #include <dev/auconv.h>
70
71 #include <dev/i2c/i2cvar.h>
72
73 #include <arm/xscale/pxa2x0reg.h>
74 #include <arm/xscale/pxa2x0var.h>
75 #include <arm/xscale/pxa2x0_i2c.h>
76 #include <arm/xscale/pxa2x0_i2s.h>
77 #include <arm/xscale/pxa2x0_dmac.h>
78 #include <arm/xscale/pxa2x0_gpio.h>
79
80 #include <zaurus/zaurus/zaurus_var.h>
81 #include <zaurus/dev/zaudiovar.h>
82 #include <zaurus/dev/wm8750reg.h>
83 #include <zaurus/dev/wm8750var.h>
84 #include <zaurus/dev/scoopvar.h>
85 #include <zaurus/dev/ioexpvar.h>
86
87 #define WM8750_ADDRESS 0x1B
88
89 /* GPIO pins */
90 #define GPIO_HP_IN_C3000 116
91
92 #define WM8750_OP_SPKR 0
93 #define WM8750_OP_HP 1
94 #define WM8750_OP_MIC 2
95 #define WM8750_OP_NUM 3
96
97 #define ZAUDIO_JACK_STATE_OUT 0
98 #define ZAUDIO_JACK_STATE_IN 1
99 #define ZAUDIO_JACK_STATE_INS 2
100 #define ZAUDIO_JACK_STATE_REM 3
101
102 static int wm8750_finalize(device_t);
103 static bool wm8750_suspend(device_t, const pmf_qual_t *);
104 static bool wm8750_resume(device_t, const pmf_qual_t *);
105 static void wm8750_volume_up(device_t);
106 static void wm8750_volume_down(device_t);
107 static void wm8750_volume_toggle(device_t);
108
109 static struct audio_device wm8750_device = {
110 "WM8750",
111 "1.0",
112 "wm"
113 };
114
115 static const struct audio_format wm8750_formats[] = {
116 {
117 .driver_data = NULL,
118 .mode = AUMODE_PLAY | AUMODE_RECORD,
119 .encoding = AUDIO_ENCODING_SLINEAR_LE,
120 .validbits = 16,
121 .precision = 16,
122 .channels = 2,
123 .channel_mask = AUFMT_STEREO,
124 .frequency_type = 0,
125 .frequency = { 4000, 48000 }
126 },
127 {
128 .driver_data = NULL,
129 .mode = AUMODE_PLAY | AUMODE_RECORD,
130 .encoding = AUDIO_ENCODING_SLINEAR_LE,
131 .validbits = 16,
132 .precision = 16,
133 .channels = 1,
134 .channel_mask = AUFMT_MONAURAL,
135 .frequency_type = 0,
136 .frequency = { 4000, 48000 }
137 },
138 {
139 .driver_data = NULL,
140 .mode = AUMODE_PLAY | AUMODE_RECORD,
141 .encoding = AUDIO_ENCODING_ULINEAR_LE,
142 .validbits = 8,
143 .precision = 8,
144 .channels = 2,
145 .channel_mask = AUFMT_STEREO,
146 .frequency_type = 0,
147 .frequency = { 4000, 48000 }
148 },
149 {
150 .driver_data = NULL,
151 .mode = AUMODE_PLAY | AUMODE_RECORD,
152 .encoding = AUDIO_ENCODING_ULINEAR_LE,
153 .validbits = 8,
154 .precision = 8,
155 .channels = 1,
156 .channel_mask = AUFMT_MONAURAL,
157 .frequency_type = 0,
158 .frequency = { 4000, 48000 }
159 },
160 };
161 static const int wm8750_nformats = (int)__arraycount(wm8750_formats);
162
163 static void wm8750_init(struct zaudio_softc *);
164 static int wm8750_jack_intr(void *);
165 static void wm8750_jack(void *);
166 static void wm8750_standby(struct zaudio_softc *);
167 static void wm8750_update_volume(struct zaudio_softc *, int);
168 static void wm8750_update_mutes(struct zaudio_softc *, int);
169 static void wm8750_play_setup(struct zaudio_softc *);
170 /*static*/ void wm8750_record_setup(struct zaudio_softc *);
171 static int wm8750_query_encoding(void *, struct audio_encoding *);
172 static int wm8750_set_params(void *, int, int, audio_params_t *,
173 audio_params_t *, stream_filter_list_t *, stream_filter_list_t *);
174 static int wm8750_start_output(void *, void *, int, void (*)(void *), void *);
175 static int wm8750_start_input(void *, void *, int, void (*)(void *), void *);
176 static int wm8750_halt_output(void *);
177 static int wm8750_halt_input(void *);
178 static int wm8750_getdev(void *, struct audio_device *);
179 static int wm8750_set_port(void *, struct mixer_ctrl *);
180 static int wm8750_get_port(void *, struct mixer_ctrl *);
181 static int wm8750_query_devinfo(void *, struct mixer_devinfo *);
182
183 static struct audio_hw_if wm8750_hw_if = {
184 .open = zaudio_open,
185 .close = zaudio_close,
186 .drain = NULL,
187 .query_encoding = wm8750_query_encoding,
188 .set_params = wm8750_set_params,
189 .round_blocksize = zaudio_round_blocksize,
190 .commit_settings = NULL,
191 .init_output = NULL,
192 .init_input = NULL,
193 .start_output = wm8750_start_output,
194 .start_input = wm8750_start_input,
195 .halt_output = wm8750_halt_output,
196 .halt_input = wm8750_halt_input,
197 .speaker_ctl = NULL,
198 .getdev = wm8750_getdev,
199 .setfd = NULL,
200 .set_port = wm8750_set_port,
201 .get_port = wm8750_get_port,
202 .query_devinfo = wm8750_query_devinfo,
203 .allocm = zaudio_allocm,
204 .freem = zaudio_freem,
205 .round_buffersize = zaudio_round_buffersize,
206 .mappage = zaudio_mappage,
207 .get_props = zaudio_get_props,
208 .trigger_output = NULL,
209 .trigger_input = NULL,
210 .dev_ioctl = NULL,
211 .get_locks = zaudio_get_locks,
212 };
213
214 static const uint16_t playback_regs[][2] = {
215 /* Unmute DAC */
216 { ADCDACCTL_REG, 0x000 },
217
218 /* 16 bit audio words */
219 { AUDINT_REG, AUDINT_SET_FORMAT(2) },
220
221 /* Enable thermal protection, power */
222 { ADCTL1_REG, ADCTL1_TSDEN | ADCTL1_SET_VSEL(3) },
223
224 /* Enable speaker driver, DAC oversampling */
225 { ADCTL2_REG, ADCTL2_ROUT2INV | ADCTL2_DACOSR },
226
227 /* Set DAC voltage references */
228 { PWRMGMT1_REG, PWRMGMT1_SET_VMIDSEL(1) | PWRMGMT1_VREF },
229
230 /* Direct DACs to output mixers */
231 { LOUTMIX1_REG, LOUTMIX1_LD2LO },
232 { LOUTMIX2_REG, 0x000 },
233 { ROUTMIX1_REG, 0x000 },
234 { ROUTMIX2_REG, ROUTMIX2_RD2RO },
235
236 /* End of list */
237 { 0xffff, 0xffff }
238 };
239
240 static const uint16_t record_regs[][2] = {
241 /* Unmute DAC */
242 { ADCDACCTL_REG, 0x000 },
243
244 /* 16 bit audio words */
245 { AUDINT_REG, AUDINT_SET_FORMAT(2) },
246
247 /* Enable thermal protection, power, left DAC for both channel */
248 { ADCTL1_REG, ADCTL1_TSDEN | ADCTL1_SET_VSEL(3)
249 | ADCTL1_SET_DATSEL(1) },
250
251 /* Diffrential input select: LINPUT1-RINPUT1, stereo */
252 { ADCINPMODE_REG, 0x000 },
253
254 /* L-R differential, micboost 20dB */
255 { ADCLSPATH_REG, ADCLSPATH_SET_LINSEL(3) | ADCLSPATH_SET_LMICBOOST(2) },
256 { ADCRSPATH_REG, ADCRSPATH_SET_RINSEL(3) | ADCRSPATH_SET_RMICBOOST(2) },
257
258 /* End of list */
259 { 0xffff, 0xffff }
260 };
261
262 static __inline int
263 wm8750_write(struct zaudio_softc *sc, int reg, int val)
264 {
265 uint16_t tmp;
266 uint8_t cmd;
267 uint8_t data;
268
269 tmp = (reg << 9) | (val & 0x1ff);
270 cmd = tmp >> 8;
271 data = tmp;
272 return iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, WM8750_ADDRESS,
273 &cmd, 1, &data, 1, 0);
274 }
275
276 int
277 wm8750_match(device_t parent, cfdata_t cf, struct i2c_attach_args *ia)
278 {
279 int match_result;
280
281 if (ZAURUS_ISC860)
282 return 0;
283
284 if (iic_use_direct_match(ia, cf, NULL, &match_result))
285 return match_result;
286
287 /* indirect config - check typical address */
288 if (ia->ia_addr == WM8750_ADDRESS)
289 return I2C_MATCH_ADDRESS_ONLY;
290
291 return 0;
292 }
293
294 void
295 wm8750_attach(device_t parent, device_t self, struct i2c_attach_args *ia)
296 {
297 struct zaudio_softc *sc = device_private(self);
298 int error;
299
300 aprint_normal(": I2S, WM8750 Audio\n");
301 aprint_naive("\n");
302
303 /* Check for an I2C response from the wm8750 */
304 iic_acquire_bus(sc->sc_i2c, 0);
305 error = wm8750_write(sc, RESET_REG, 0);
306 iic_release_bus(sc->sc_i2c, 0);
307 if (error) {
308 aprint_error_dev(self, "codec failed to respond\n");
309 goto fail_i2c;
310 }
311 delay(100);
312
313 /* Allocate memory for volume & mute operations */
314 sc->sc_volume = kmem_zalloc(sizeof(*sc->sc_volume) * WM8750_OP_NUM,
315 KM_SLEEP);
316 sc->sc_unmute = kmem_zalloc(sizeof(*sc->sc_unmute) * WM8750_OP_NUM,
317 KM_SLEEP);
318 sc->sc_unmute_toggle = kmem_zalloc(
319 sizeof(*sc->sc_unmute_toggle) * WM8750_OP_NUM, KM_SLEEP);
320
321 /* Speaker on, headphones off by default. */
322 sc->sc_volume[WM8750_OP_SPKR].left = 180;
323 sc->sc_jack = FALSE;
324 UNMUTE(sc, WM8750_OP_SPKR, 1);
325 sc->sc_volume[WM8750_OP_HP].left = 180;
326 sc->sc_volume[WM8750_OP_HP].right = 180;
327 UNMUTE(sc, WM8750_OP_HP, 0);
328 sc->sc_volume[WM8750_OP_MIC].left = 180;
329 UNMUTE(sc, WM8750_OP_MIC, 0);
330
331 /* Configure headphone jack state change handling. */
332 callout_setfunc(&sc->sc_to, wm8750_jack, sc);
333 pxa2x0_gpio_set_function(GPIO_HP_IN_C3000, GPIO_IN);
334 (void) pxa2x0_gpio_intr_establish(GPIO_HP_IN_C3000, IST_EDGE_BOTH,
335 IPL_BIO, wm8750_jack_intr, sc);
336
337 /* wm8750_init() implicitly depends on ioexp or scoop */
338 config_finalize_register(self, wm8750_finalize);
339
340 audio_attach_mi(&wm8750_hw_if, sc, self);
341
342 if (!pmf_device_register(self, wm8750_suspend, wm8750_resume))
343 aprint_error_dev(self, "couldn't establish power handler\n");
344 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_UP,
345 wm8750_volume_up, true))
346 aprint_error_dev(self, "couldn't register event handler\n");
347 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_DOWN,
348 wm8750_volume_down, true))
349 aprint_error_dev(self, "couldn't register event handler\n");
350 if (!pmf_event_register(self, PMFE_AUDIO_VOLUME_TOGGLE,
351 wm8750_volume_toggle, true))
352 aprint_error_dev(self, "couldn't register event handler\n");
353
354 return;
355
356 fail_i2c:
357 pxa2x0_i2s_detach_sub(&sc->sc_i2s);
358 }
359
360 static int
361 wm8750_finalize(device_t dv)
362 {
363 struct zaudio_softc *sc = device_private(dv);
364
365 wm8750_init(sc);
366 return 0;
367 }
368
369 static bool
370 wm8750_suspend(device_t dv, const pmf_qual_t *qual)
371 {
372 struct zaudio_softc *sc = device_private(dv);
373
374 callout_stop(&sc->sc_to);
375 wm8750_standby(sc);
376
377 return true;
378 }
379
380 static bool
381 wm8750_resume(device_t dv, const pmf_qual_t *qual)
382 {
383 struct zaudio_softc *sc = device_private(dv);
384
385 pxa2x0_i2s_init(&sc->sc_i2s);
386 wm8750_init(sc);
387
388 return true;
389 }
390
391 static __inline uint8_t
392 vol_sadd(int vol, int stride)
393 {
394
395 vol += stride;
396 if (vol > 255)
397 return 255;
398 return (uint8_t)vol;
399 }
400
401 #ifndef ZAUDIO_VOLUME_STRIDE
402 #define ZAUDIO_VOLUME_STRIDE 8
403 #endif
404
405 static void
406 wm8750_volume_up(device_t dv)
407 {
408 struct zaudio_softc *sc = device_private(dv);
409 int s;
410
411 s = splbio();
412 iic_acquire_bus(sc->sc_i2c, 0);
413
414 sc->sc_volume[WM8750_OP_SPKR].left =
415 vol_sadd(sc->sc_volume[WM8750_OP_SPKR].left, ZAUDIO_VOLUME_STRIDE);
416 sc->sc_volume[WM8750_OP_HP].left =
417 vol_sadd(sc->sc_volume[WM8750_OP_HP].left, ZAUDIO_VOLUME_STRIDE);
418 sc->sc_volume[WM8750_OP_HP].right =
419 vol_sadd(sc->sc_volume[WM8750_OP_HP].right, ZAUDIO_VOLUME_STRIDE);
420
421 wm8750_update_volume(sc, WM8750_OP_SPKR);
422 wm8750_update_volume(sc, WM8750_OP_HP);
423
424 iic_release_bus(sc->sc_i2c, 0);
425 splx(s);
426 }
427
428 static __inline uint8_t
429 vol_ssub(int vol, int stride)
430 {
431
432 vol -= stride;
433 if (vol < 0)
434 return 0;
435 return (uint8_t)vol;
436 }
437
438 static void
439 wm8750_volume_down(device_t dv)
440 {
441 struct zaudio_softc *sc = device_private(dv);
442 int s;
443
444 s = splbio();
445 iic_acquire_bus(sc->sc_i2c, 0);
446
447 sc->sc_volume[WM8750_OP_SPKR].left =
448 vol_ssub(sc->sc_volume[WM8750_OP_SPKR].left, ZAUDIO_VOLUME_STRIDE);
449 sc->sc_volume[WM8750_OP_HP].left =
450 vol_ssub(sc->sc_volume[WM8750_OP_HP].left, ZAUDIO_VOLUME_STRIDE);
451 sc->sc_volume[WM8750_OP_HP].right =
452 vol_ssub(sc->sc_volume[WM8750_OP_HP].right, ZAUDIO_VOLUME_STRIDE);
453
454 wm8750_update_volume(sc, WM8750_OP_SPKR);
455 wm8750_update_volume(sc, WM8750_OP_HP);
456
457 iic_release_bus(sc->sc_i2c, 0);
458 splx(s);
459 }
460
461 static void
462 wm8750_volume_toggle(device_t dv)
463 {
464 struct zaudio_softc *sc = device_private(dv);
465 int s;
466
467 s = splbio();
468 iic_acquire_bus(sc->sc_i2c, 0);
469
470 if (!sc->sc_unmute[WM8750_OP_SPKR] && !sc->sc_unmute[WM8750_OP_HP]) {
471 sc->sc_unmute[WM8750_OP_SPKR] =
472 sc->sc_unmute_toggle[WM8750_OP_SPKR];
473 sc->sc_unmute[WM8750_OP_HP] =
474 sc->sc_unmute_toggle[WM8750_OP_HP];
475 } else {
476 sc->sc_unmute[WM8750_OP_SPKR] = 0;
477 sc->sc_unmute[WM8750_OP_HP] = 0;
478 }
479 wm8750_update_mutes(sc, 1);
480
481 iic_release_bus(sc->sc_i2c, 0);
482 splx(s);
483 }
484
485 static void
486 wm8750_init(struct zaudio_softc *sc)
487 {
488
489 iic_acquire_bus(sc->sc_i2c, 0);
490
491 /* Reset the codec */
492 wm8750_write(sc, RESET_REG, 0);
493 delay(100);
494
495 /* Switch to standby power only */
496 wm8750_write(sc, PWRMGMT1_REG, PWRMGMT1_SET_VMIDSEL(2));
497 wm8750_write(sc, PWRMGMT2_REG, 0);
498
499 /* Configure digital interface for I2S */
500 wm8750_write(sc, AUDINT_REG, AUDINT_SET_FORMAT(2));
501
502 /* Initialise volume levels */
503 wm8750_update_volume(sc, WM8750_OP_SPKR);
504 wm8750_update_volume(sc, WM8750_OP_HP);
505 wm8750_update_volume(sc, WM8750_OP_MIC);
506
507 scoop_set_headphone(0);
508 if (ZAURUS_ISC1000)
509 ioexp_set_mic_bias(0);
510 else
511 scoop_set_mic_bias(0);
512
513 iic_release_bus(sc->sc_i2c, 0);
514
515 /* Assume that the jack state has changed. */
516 wm8750_jack(sc);
517 }
518
519 static int
520 wm8750_jack_intr(void *v)
521 {
522 struct zaudio_softc *sc = v;
523
524 if (!callout_active(&sc->sc_to))
525 wm8750_jack(sc);
526
527 return 1;
528 }
529
530 static void
531 wm8750_jack(void *v)
532 {
533 struct zaudio_softc *sc = v;
534
535 switch (sc->sc_state) {
536 case ZAUDIO_JACK_STATE_OUT:
537 if (pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) {
538 sc->sc_state = ZAUDIO_JACK_STATE_INS;
539 sc->sc_icount = 0;
540 }
541 break;
542
543 case ZAUDIO_JACK_STATE_INS:
544 if (sc->sc_icount++ > 2) {
545 if (pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) {
546 sc->sc_state = ZAUDIO_JACK_STATE_IN;
547 sc->sc_jack = TRUE;
548 UNMUTE(sc, WM8750_OP_SPKR, 0);
549 UNMUTE(sc, WM8750_OP_HP, 1);
550 UNMUTE(sc, WM8750_OP_MIC, 1);
551 goto update_mutes;
552 } else
553 sc->sc_state = ZAUDIO_JACK_STATE_OUT;
554 }
555 break;
556
557 case ZAUDIO_JACK_STATE_IN:
558 if (!pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) {
559 sc->sc_state = ZAUDIO_JACK_STATE_REM;
560 sc->sc_icount = 0;
561 }
562 break;
563
564 case ZAUDIO_JACK_STATE_REM:
565 if (sc->sc_icount++ > 2) {
566 if (!pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000)) {
567 sc->sc_state = ZAUDIO_JACK_STATE_OUT;
568 sc->sc_jack = FALSE;
569 UNMUTE(sc, WM8750_OP_SPKR, 1);
570 UNMUTE(sc, WM8750_OP_HP, 0);
571 UNMUTE(sc, WM8750_OP_MIC, 0);
572 goto update_mutes;
573 } else
574 sc->sc_state = ZAUDIO_JACK_STATE_IN;
575 }
576 break;
577 }
578
579 callout_schedule(&sc->sc_to, hz/4);
580
581 return;
582
583 update_mutes:
584 callout_stop(&sc->sc_to);
585
586 if (sc->sc_playing || sc->sc_recording) {
587 iic_acquire_bus(sc->sc_i2c, 0);
588 if (sc->sc_playing)
589 wm8750_update_mutes(sc, 1);
590 if (sc->sc_recording)
591 wm8750_update_mutes(sc, 2);
592 iic_release_bus(sc->sc_i2c, 0);
593 }
594 }
595
596 static void
597 wm8750_standby(struct zaudio_softc *sc)
598 {
599
600 iic_acquire_bus(sc->sc_i2c, 0);
601
602 /* Switch codec to standby power only */
603 wm8750_write(sc, PWRMGMT1_REG, PWRMGMT1_SET_VMIDSEL(2));
604 wm8750_write(sc, PWRMGMT2_REG, 0);
605
606 scoop_set_headphone(0);
607 if (ZAURUS_ISC1000)
608 ioexp_set_mic_bias(0);
609 else
610 scoop_set_mic_bias(0);
611
612 iic_release_bus(sc->sc_i2c, 0);
613 }
614
615 static void
616 wm8750_update_volume(struct zaudio_softc *sc, int output)
617 {
618
619 switch (output) {
620 case WM8750_OP_SPKR:
621 wm8750_write(sc, LOUT2VOL_REG, LOUT2VOL_LO2VU | LOUT2VOL_LO2ZC |
622 LOUT2VOL_SET_LOUT2VOL(sc->sc_volume[WM8750_OP_SPKR].left >> 1));
623 wm8750_write(sc, ROUT2VOL_REG, ROUT2VOL_RO2VU | ROUT2VOL_RO2ZC |
624 ROUT2VOL_SET_ROUT2VOL(sc->sc_volume[WM8750_OP_SPKR].left >> 1));
625 break;
626
627 case WM8750_OP_HP:
628 wm8750_write(sc, LOUT1VOL_REG, LOUT1VOL_LO1VU | LOUT1VOL_LO1ZC |
629 LOUT1VOL_SET_LOUT1VOL(sc->sc_volume[WM8750_OP_HP].left >> 1));
630 wm8750_write(sc, ROUT1VOL_REG, ROUT1VOL_RO1VU | ROUT1VOL_RO1ZC |
631 ROUT1VOL_SET_ROUT1VOL(sc->sc_volume[WM8750_OP_HP].right >> 1));
632 break;
633
634 case WM8750_OP_MIC:
635 wm8750_write(sc, LINVOL_REG, LINVOL_LIVU |
636 LINVOL_SET_LINVOL(sc->sc_volume[WM8750_OP_MIC].left >> 2));
637 wm8750_write(sc, RINVOL_REG, RINVOL_RIVU |
638 RINVOL_SET_RINVOL(sc->sc_volume[WM8750_OP_MIC].left >> 2));
639 break;
640 }
641 }
642
643 static void
644 wm8750_update_mutes(struct zaudio_softc *sc, int mask)
645 {
646 uint16_t val;
647
648 /* playback */
649 if (mask & 1) {
650 val = PWRMGMT2_DACL | PWRMGMT2_DACR;
651 if (sc->sc_unmute[WM8750_OP_SPKR])
652 val |= PWRMGMT2_LOUT2 | PWRMGMT2_ROUT2;
653 if (sc->sc_unmute[WM8750_OP_HP])
654 val |= PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1;
655 wm8750_write(sc, PWRMGMT2_REG, val);
656 scoop_set_headphone(sc->sc_unmute[WM8750_OP_HP]);
657 }
658
659 /* record */
660 if (mask & 2) {
661 val = PWRMGMT1_SET_VMIDSEL(1) | PWRMGMT1_VREF;
662 if (sc->sc_unmute[WM8750_OP_MIC]) {
663 val |= PWRMGMT1_AINL | PWRMGMT1_AINR
664 | PWRMGMT1_ADCL | PWRMGMT1_ADCR | PWRMGMT1_MICB;
665 }
666 wm8750_write(sc, PWRMGMT1_REG, val);
667 if (ZAURUS_ISC1000)
668 ioexp_set_mic_bias(sc->sc_unmute[WM8750_OP_MIC]);
669 else
670 scoop_set_mic_bias(sc->sc_unmute[WM8750_OP_MIC]);
671 }
672 }
673
674 static void
675 wm8750_play_setup(struct zaudio_softc *sc)
676 {
677 int i;
678
679 iic_acquire_bus(sc->sc_i2c, 0);
680
681 /* Program the codec with playback settings */
682 for (i = 0; playback_regs[i][0] != 0xffff; i++) {
683 wm8750_write(sc, playback_regs[i][0], playback_regs[i][1]);
684 }
685 wm8750_update_mutes(sc, 1);
686
687 iic_release_bus(sc->sc_i2c, 0);
688 }
689
690 /*static*/ void
691 wm8750_record_setup(struct zaudio_softc *sc)
692 {
693 int i;
694
695 iic_acquire_bus(sc->sc_i2c, 0);
696
697 /* Program the codec with playback settings */
698 for (i = 0; record_regs[i][0] != 0xffff; i++) {
699 wm8750_write(sc, record_regs[i][0], record_regs[i][1]);
700 }
701 wm8750_update_mutes(sc, 2);
702
703 iic_release_bus(sc->sc_i2c, 0);
704 }
705
706 static int
707 wm8750_query_encoding(void *hdl, struct audio_encoding *aep)
708 {
709
710 switch (aep->index) {
711 case 0:
712 strlcpy(aep->name, AudioEulinear, sizeof(aep->name));
713 aep->encoding = AUDIO_ENCODING_ULINEAR;
714 aep->precision = 8;
715 aep->flags = 0;
716 break;
717
718 case 1:
719 strlcpy(aep->name, AudioEmulaw, sizeof(aep->name));
720 aep->encoding = AUDIO_ENCODING_ULAW;
721 aep->precision = 8;
722 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
723 break;
724
725 case 2:
726 strlcpy(aep->name, AudioEalaw, sizeof(aep->name));
727 aep->encoding = AUDIO_ENCODING_ALAW;
728 aep->precision = 8;
729 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
730 break;
731
732 case 3:
733 strlcpy(aep->name, AudioEslinear, sizeof(aep->name));
734 aep->encoding = AUDIO_ENCODING_SLINEAR;
735 aep->precision = 8;
736 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
737 break;
738
739 case 4:
740 strlcpy(aep->name, AudioEslinear_le, sizeof(aep->name));
741 aep->encoding = AUDIO_ENCODING_SLINEAR_LE;
742 aep->precision = 16;
743 aep->flags = 0;
744 break;
745
746 case 5:
747 strlcpy(aep->name, AudioEulinear_le, sizeof(aep->name));
748 aep->encoding = AUDIO_ENCODING_ULINEAR_LE;
749 aep->precision = 16;
750 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
751 break;
752
753 case 6:
754 strlcpy(aep->name, AudioEslinear_be, sizeof(aep->name));
755 aep->encoding = AUDIO_ENCODING_SLINEAR_BE;
756 aep->precision = 16;
757 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
758 break;
759
760 case 7:
761 strlcpy(aep->name, AudioEulinear_be, sizeof(aep->name));
762 aep->encoding = AUDIO_ENCODING_ULINEAR_BE;
763 aep->precision = 16;
764 aep->flags = AUDIO_ENCODINGFLAG_EMULATED;
765 break;
766
767 default:
768 return EINVAL;
769 }
770
771 return 0;
772 }
773
774 static int
775 wm8750_set_params(void *hdl, int setmode, int usemode, audio_params_t *play,
776 audio_params_t *rec, stream_filter_list_t *pfil, stream_filter_list_t *rfil)
777 {
778 struct zaudio_softc *sc = hdl;
779 struct audio_params *p;
780 stream_filter_list_t *fil;
781 int mode, i;
782
783 if (play->sample_rate != rec->sample_rate &&
784 usemode == (AUMODE_PLAY | AUMODE_RECORD)) {
785 if (setmode == AUMODE_PLAY) {
786 rec->sample_rate = play->sample_rate;
787 setmode |= AUMODE_RECORD;
788 } else if (setmode == AUMODE_RECORD) {
789 play->sample_rate = rec->sample_rate;
790 setmode |= AUMODE_PLAY;
791 } else
792 return EINVAL;
793 }
794
795 for (mode = AUMODE_RECORD; mode != -1;
796 mode = (mode == AUMODE_RECORD) ? AUMODE_PLAY : -1) {
797 if ((setmode & mode) == 0)
798 continue;
799
800 p = (mode == AUMODE_PLAY) ? play : rec;
801
802 if (p->sample_rate < 4000 || p->sample_rate > 48000 ||
803 (p->precision != 8 && p->precision != 16) ||
804 (p->channels != 1 && p->channels != 2))
805 return EINVAL;
806
807 fil = (mode == AUMODE_PLAY) ? pfil : rfil;
808 i = auconv_set_converter(wm8750_formats, wm8750_nformats,
809 mode, p, false, fil);
810 if (i < 0)
811 return EINVAL;
812 }
813
814 if (setmode == AUMODE_RECORD)
815 pxa2x0_i2s_setspeed(&sc->sc_i2s, &rec->sample_rate);
816 else
817 pxa2x0_i2s_setspeed(&sc->sc_i2s, &play->sample_rate);
818
819 return 0;
820 }
821
822 static int
823 wm8750_halt_output(void *hdl)
824 {
825 struct zaudio_softc *sc = hdl;
826 int rv;
827
828 rv = pxa2x0_i2s_halt_output(&sc->sc_i2s);
829 if (!sc->sc_recording)
830 wm8750_standby(sc);
831 sc->sc_playing = 0;
832
833 return rv;
834 }
835
836 static int
837 wm8750_halt_input(void *hdl)
838 {
839 struct zaudio_softc *sc = hdl;
840 int rv;
841
842 rv = pxa2x0_i2s_halt_input(&sc->sc_i2s);
843 if (!sc->sc_playing)
844 wm8750_standby(sc);
845 sc->sc_recording = 0;
846
847 return rv;
848 }
849
850 static int
851 wm8750_getdev(void *hdl, struct audio_device *ret)
852 {
853
854 *ret = wm8750_device;
855 return 0;
856 }
857
858 #define WM8750_SPKR_LVL 0
859 #define WM8750_SPKR_MUTE 1
860 #define WM8750_HP_LVL 2
861 #define WM8750_HP_MUTE 3
862 #define WM8750_MIC_LVL 4
863 #define WM8750_MIC_MUTE 5
864 #define WM8750_RECORD_SOURCE 6
865 #define WM8750_OUTPUT_CLASS 7
866 #define WM8750_INPUT_CLASS 8
867 #define WM8750_RECORD_CLASS 9
868
869 static int
870 wm8750_set_port(void *hdl, struct mixer_ctrl *mc)
871 {
872 struct zaudio_softc *sc = hdl;
873 int error = EINVAL;
874 int s;
875
876 s = splbio();
877 iic_acquire_bus(sc->sc_i2c, 0);
878
879 switch (mc->dev) {
880 case WM8750_SPKR_LVL:
881 if (mc->type != AUDIO_MIXER_VALUE)
882 break;
883 if (mc->un.value.num_channels == 1)
884 sc->sc_volume[WM8750_OP_SPKR].left =
885 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
886 else
887 break;
888 wm8750_update_volume(sc, WM8750_OP_SPKR);
889 error = 0;
890 break;
891
892 case WM8750_SPKR_MUTE:
893 if (mc->type != AUDIO_MIXER_ENUM)
894 break;
895 UNMUTE(sc, WM8750_OP_SPKR, mc->un.ord ? 1 : 0);
896 wm8750_update_mutes(sc, 1);
897 error = 0;
898 break;
899
900 case WM8750_HP_LVL:
901 if (mc->type != AUDIO_MIXER_VALUE)
902 break;
903 if (mc->un.value.num_channels == 1) {
904 sc->sc_volume[WM8750_OP_HP].left =
905 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
906 sc->sc_volume[WM8750_OP_HP].right =
907 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
908 } else if (mc->un.value.num_channels == 2) {
909 sc->sc_volume[WM8750_OP_HP].left =
910 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
911 sc->sc_volume[WM8750_OP_HP].right =
912 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
913 }
914 else
915 break;
916 wm8750_update_volume(sc, WM8750_OP_HP);
917 error = 0;
918 break;
919
920 case WM8750_HP_MUTE:
921 if (mc->type != AUDIO_MIXER_ENUM)
922 break;
923 UNMUTE(sc, WM8750_OP_HP, mc->un.ord ? 1 : 0);
924 wm8750_update_mutes(sc, 1);
925 error = 0;
926 break;
927
928 case WM8750_MIC_LVL:
929 if (mc->type != AUDIO_MIXER_VALUE)
930 break;
931 if (mc->un.value.num_channels == 1)
932 sc->sc_volume[WM8750_OP_MIC].left =
933 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
934 else
935 break;
936 wm8750_update_volume(sc, WM8750_OP_MIC);
937 error = 0;
938 break;
939
940 case WM8750_MIC_MUTE:
941 if (mc->type != AUDIO_MIXER_ENUM)
942 break;
943 UNMUTE(sc, WM8750_OP_MIC, mc->un.ord ? 1 : 0);
944 wm8750_update_mutes(sc, 2);
945 error = 0;
946 break;
947
948 case WM8750_RECORD_SOURCE:
949 if (mc->type != AUDIO_MIXER_ENUM)
950 break;
951 if (mc->un.ord != 0)
952 break;
953 /* MIC only */
954 error = 0;
955 break;
956 }
957
958 iic_release_bus(sc->sc_i2c, 0);
959 splx(s);
960
961 return error;
962 }
963
964 static int
965 wm8750_get_port(void *hdl, struct mixer_ctrl *mc)
966 {
967 struct zaudio_softc *sc = hdl;
968 int error = EINVAL;
969
970 switch (mc->dev) {
971 case WM8750_SPKR_LVL:
972 if (mc->type != AUDIO_MIXER_VALUE)
973 break;
974 if (mc->un.value.num_channels == 1)
975 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
976 sc->sc_volume[WM8750_OP_SPKR].left;
977 else
978 break;
979 error = 0;
980 break;
981
982 case WM8750_SPKR_MUTE:
983 if (mc->type != AUDIO_MIXER_ENUM)
984 break;
985 mc->un.ord = sc->sc_unmute[WM8750_OP_SPKR] ? 1 : 0;
986 error = 0;
987 break;
988
989 case WM8750_HP_LVL:
990 if (mc->type != AUDIO_MIXER_VALUE)
991 break;
992 if (mc->un.value.num_channels == 1)
993 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
994 sc->sc_volume[WM8750_OP_HP].left;
995 else if (mc->un.value.num_channels == 2) {
996 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
997 sc->sc_volume[WM8750_OP_HP].left;
998 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
999 sc->sc_volume[WM8750_OP_HP].right;
1000 }
1001 else
1002 break;
1003 error = 0;
1004 break;
1005
1006 case WM8750_HP_MUTE:
1007 if (mc->type != AUDIO_MIXER_ENUM)
1008 break;
1009 mc->un.ord = sc->sc_unmute[WM8750_OP_HP] ? 1 : 0;
1010 error = 0;
1011 break;
1012
1013 case WM8750_MIC_LVL:
1014 if (mc->type != AUDIO_MIXER_VALUE)
1015 break;
1016 if (mc->un.value.num_channels == 1)
1017 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
1018 sc->sc_volume[WM8750_OP_MIC].left;
1019 else
1020 break;
1021 error = 0;
1022 break;
1023
1024 case WM8750_MIC_MUTE:
1025 if (mc->type != AUDIO_MIXER_ENUM)
1026 break;
1027 mc->un.ord = sc->sc_unmute[WM8750_OP_MIC] ? 1 : 0;
1028 error = 0;
1029 break;
1030
1031 case WM8750_RECORD_SOURCE:
1032 if (mc->type != AUDIO_MIXER_ENUM)
1033 break;
1034 mc->un.ord = 0; /* MIC only */
1035 error = 0;
1036 break;
1037 }
1038
1039 return error;
1040 }
1041
1042 /*ARGSUSED*/
1043 static int
1044 wm8750_query_devinfo(void *hdl, struct mixer_devinfo *di)
1045 {
1046
1047 switch (di->index) {
1048 case WM8750_SPKR_LVL:
1049 di->type = AUDIO_MIXER_VALUE;
1050 di->mixer_class = WM8750_OUTPUT_CLASS;
1051 di->prev = AUDIO_MIXER_LAST;
1052 di->next = WM8750_SPKR_MUTE;
1053 strlcpy(di->label.name, AudioNspeaker, sizeof(di->label.name));
1054 strlcpy(di->un.v.units.name, AudioNvolume,
1055 sizeof(di->un.v.units.name));
1056 di->un.v.num_channels = 1;
1057 break;
1058
1059 case WM8750_SPKR_MUTE:
1060 di->type = AUDIO_MIXER_ENUM;
1061 di->mixer_class = WM8750_OUTPUT_CLASS;
1062 di->prev = WM8750_SPKR_LVL;
1063 di->next = AUDIO_MIXER_LAST;
1064 goto mute;
1065
1066 case WM8750_HP_LVL:
1067 di->type = AUDIO_MIXER_VALUE;
1068 di->mixer_class = WM8750_OUTPUT_CLASS;
1069 di->prev = AUDIO_MIXER_LAST;
1070 di->next = WM8750_HP_MUTE;
1071 strlcpy(di->label.name, AudioNheadphone,
1072 sizeof(di->label.name));
1073 di->un.v.num_channels = 1;
1074 strlcpy(di->un.v.units.name, AudioNvolume,
1075 sizeof(di->un.v.units.name));
1076 break;
1077
1078 case WM8750_HP_MUTE:
1079 di->type = AUDIO_MIXER_ENUM;
1080 di->mixer_class = WM8750_OUTPUT_CLASS;
1081 di->prev = WM8750_HP_LVL;
1082 di->next = AUDIO_MIXER_LAST;
1083 mute:
1084 strlcpy(di->label.name, AudioNmute, sizeof(di->label.name));
1085 di->un.e.num_mem = 2;
1086 strlcpy(di->un.e.member[0].label.name, AudioNon,
1087 sizeof(di->un.e.member[0].label.name));
1088 di->un.e.member[0].ord = 0;
1089 strlcpy(di->un.e.member[1].label.name, AudioNoff,
1090 sizeof(di->un.e.member[1].label.name));
1091 di->un.e.member[1].ord = 1;
1092 break;
1093
1094 case WM8750_MIC_LVL:
1095 di->type = AUDIO_MIXER_VALUE;
1096 di->mixer_class = WM8750_INPUT_CLASS;
1097 di->prev = AUDIO_MIXER_LAST;
1098 di->next = WM8750_MIC_MUTE;
1099 strlcpy(di->label.name, AudioNmicrophone,
1100 sizeof(di->label.name));
1101 strlcpy(di->un.v.units.name, AudioNvolume,
1102 sizeof(di->un.v.units.name));
1103 di->un.v.num_channels = 1;
1104 break;
1105
1106 case WM8750_MIC_MUTE:
1107 di->type = AUDIO_MIXER_ENUM;
1108 di->mixer_class = WM8750_INPUT_CLASS;
1109 di->prev = WM8750_MIC_LVL;
1110 di->next = AUDIO_MIXER_LAST;
1111 goto mute;
1112
1113 case WM8750_RECORD_SOURCE:
1114 di->type = AUDIO_MIXER_ENUM;
1115 di->mixer_class = WM8750_RECORD_CLASS;
1116 di->prev = AUDIO_MIXER_LAST;
1117 di->next = AUDIO_MIXER_LAST;
1118 strlcpy(di->label.name, AudioNsource, sizeof(di->label.name));
1119 di->un.e.num_mem = 1;
1120 strlcpy(di->un.e.member[0].label.name, AudioNmicrophone,
1121 sizeof(di->un.e.member[0].label.name));
1122 di->un.e.member[0].ord = 0;
1123 break;
1124
1125 case WM8750_OUTPUT_CLASS:
1126 di->type = AUDIO_MIXER_CLASS;
1127 di->mixer_class = WM8750_OUTPUT_CLASS;
1128 di->prev = AUDIO_MIXER_LAST;
1129 di->next = AUDIO_MIXER_LAST;
1130 strlcpy(di->label.name, AudioCoutputs, sizeof(di->label.name));
1131 break;
1132
1133 case WM8750_INPUT_CLASS:
1134 di->type = AUDIO_MIXER_CLASS;
1135 di->mixer_class = WM8750_INPUT_CLASS;
1136 di->prev = AUDIO_MIXER_LAST;
1137 di->next = AUDIO_MIXER_LAST;
1138 strlcpy(di->label.name, AudioCinputs, sizeof(di->label.name));
1139 break;
1140
1141 case WM8750_RECORD_CLASS:
1142 di->type = AUDIO_MIXER_CLASS;
1143 di->mixer_class = WM8750_RECORD_CLASS;
1144 di->prev = AUDIO_MIXER_LAST;
1145 di->next = AUDIO_MIXER_LAST;
1146 strlcpy(di->label.name, AudioCinputs, sizeof(di->label.name));
1147 break;
1148
1149 default:
1150 return ENXIO;
1151 }
1152
1153 return 0;
1154 }
1155
1156 static int
1157 wm8750_start_output(void *hdl, void *block, int bsize, void (*intr)(void *),
1158 void *intrarg)
1159 {
1160 struct zaudio_softc *sc = hdl;
1161 int rv;
1162
1163 /* Power up codec if we are not already playing. */
1164 if (!sc->sc_playing) {
1165 sc->sc_playing = 1;
1166 wm8750_play_setup(sc);
1167 }
1168
1169 /* Start DMA via I2S */
1170 rv = pxa2x0_i2s_start_output(&sc->sc_i2s, block, bsize, intr, intrarg);
1171 if (rv) {
1172 if (!sc->sc_recording)
1173 wm8750_standby(sc);
1174 sc->sc_playing = 0;
1175 }
1176
1177 return rv;
1178 }
1179
1180 static int
1181 wm8750_start_input(void *hdl, void *block, int bsize, void (*intr)(void *),
1182 void *intrarg)
1183 {
1184 struct zaudio_softc *sc = hdl;
1185 int rv;
1186
1187 /* Power up codec if we are not already recording. */
1188 if (!sc->sc_recording) {
1189 sc->sc_recording = 1;
1190 wm8750_record_setup(sc);
1191 }
1192
1193 /* Start DMA via I2S */
1194 rv = pxa2x0_i2s_start_input(&sc->sc_i2s, block, bsize, intr, intrarg);
1195 if (rv) {
1196 if (!sc->sc_playing)
1197 wm8750_standby(sc);
1198 sc->sc_recording = 0;
1199 }
1200 return rv;
1201 }
1202