1 /* $NetBSD: zaudio.c,v 1.10 2009/04/18 05:20:21 nonaka Exp $ */
2 /* $OpenBSD: zaurus_audio.c,v 1.8 2005/08/18 13:23:02 robert Exp $ */
5 * Copyright (c) 2005 Christopher Pascoe <pascoe@openbsd.org>
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.
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.
21 * Copyright (c) 2009 NONAKA Kimihiro <nonaka@netbsd.org>
22 * All rights reserved.
24 * Redistribution and use in source and binary forms, with or without
25 * modification, are permitted provided that the following conditions
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.
33 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
34 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
37 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * - powerhooks (currently only works until first suspend)
51 #include <sys/cdefs.h>
52 __KERNEL_RCSID(0, "$NetBSD: zaudio.c,v 1.10 2009/04/18 05:20:21 nonaka Exp $");
54 #include <sys/param.h>
55 #include <sys/systm.h>
56 #include <sys/callout.h>
57 #include <sys/device.h>
58 #include <sys/malloc.h>
59 #include <sys/kernel.h>
60 #include <sys/audioio.h>
62 #include <machine/intr.h>
63 #include <machine/bus.h>
65 #include <arm/xscale/pxa2x0reg.h>
66 #include <arm/xscale/pxa2x0var.h>
67 #include <arm/xscale/pxa2x0_i2c.h>
68 #include <arm/xscale/pxa2x0_i2s.h>
69 #include <arm/xscale/pxa2x0_dmac.h>
70 #include <arm/xscale/pxa2x0_gpio.h>
72 #include <dev/audio_if.h>
73 #include <dev/mulaw.h>
74 #include <dev/auconv.h>
76 #include <zaurus/dev/wm8750reg.h>
77 #include <zaurus/dev/scoopvar.h>
79 #define WM8750_ADDRESS 0x1B
81 #define wm8750_write(sc, reg, val) \
82 pxa2x0_i2c_write_2(&sc->sc_i2c, WM8750_ADDRESS, \
83 (((reg) << 9) | ((val) & 0x1ff)))
85 static int zaudio_match(device_t
, cfdata_t
, void *);
86 static void zaudio_attach(device_t
, device_t
, void *);
87 static bool zaudio_suspend(device_t dv
, pmf_qual_t
);
88 static bool zaudio_resume(device_t dv
, pmf_qual_t
);
90 #define ZAUDIO_OP_SPKR 0
91 #define ZAUDIO_OP_HP 1
92 #define ZAUDIO_OP_MIC 2
93 #define ZAUDIO_OP_NUM 3
95 #define ZAUDIO_JACK_STATE_OUT 0
96 #define ZAUDIO_JACK_STATE_IN 1
97 #define ZAUDIO_JACK_STATE_INS 2
98 #define ZAUDIO_JACK_STATE_REM 3
101 #define GPIO_HP_IN_C3000 116
103 struct zaudio_volume
{
108 struct zaudio_softc
{
111 /* i2s device softc */
112 /* NB: pxa2x0_i2s requires this to be the second struct member */
113 struct pxa2x0_i2s_softc sc_i2s
;
115 /* i2c device softc */
116 struct pxa2x0_i2c_softc sc_i2c
;
121 struct zaudio_volume sc_volume
[ZAUDIO_OP_NUM
];
122 char sc_unmute
[ZAUDIO_OP_NUM
];
126 struct callout sc_to
;
129 CFATTACH_DECL_NEW(zaudio
, sizeof(struct zaudio_softc
),
130 zaudio_match
, zaudio_attach
, NULL
, NULL
);
132 static struct audio_device wm8750_device
= {
138 static const struct audio_format zaudio_formats
[] = {
141 .mode
= AUMODE_PLAY
| AUMODE_RECORD
,
142 .encoding
= AUDIO_ENCODING_SLINEAR_LE
,
146 .channel_mask
= AUFMT_STEREO
,
148 .frequency
= { 4000, 48000 }
152 .mode
= AUMODE_PLAY
| AUMODE_RECORD
,
153 .encoding
= AUDIO_ENCODING_SLINEAR_LE
,
157 .channel_mask
= AUFMT_MONAURAL
,
159 .frequency
= { 4000, 48000 }
163 .mode
= AUMODE_PLAY
| AUMODE_RECORD
,
164 .encoding
= AUDIO_ENCODING_ULINEAR_LE
,
168 .channel_mask
= AUFMT_STEREO
,
170 .frequency
= { 4000, 48000 }
174 .mode
= AUMODE_PLAY
| AUMODE_RECORD
,
175 .encoding
= AUDIO_ENCODING_ULINEAR_LE
,
179 .channel_mask
= AUFMT_MONAURAL
,
181 .frequency
= { 4000, 48000 }
184 static const int zaudio_nformats
= (int)__arraycount(zaudio_formats
);
186 static void zaudio_init(struct zaudio_softc
*);
187 static int zaudio_jack_intr(void *);
188 static void zaudio_jack(void *);
189 static void zaudio_standby(struct zaudio_softc
*);
190 static void zaudio_update_volume(struct zaudio_softc
*, int);
191 static void zaudio_update_mutes(struct zaudio_softc
*, int);
192 static void zaudio_play_setup(struct zaudio_softc
*);
193 /*static*/ void zaudio_record_setup(struct zaudio_softc
*);
194 static int zaudio_open(void *, int);
195 static void zaudio_close(void *);
196 static int zaudio_query_encoding(void *, struct audio_encoding
*);
197 static int zaudio_set_params(void *, int, int, audio_params_t
*,
198 audio_params_t
*, stream_filter_list_t
*, stream_filter_list_t
*);
199 static int zaudio_round_blocksize(void *, int, int, const audio_params_t
*);
200 static int zaudio_start_output(void *, void *, int, void (*)(void *), void *);
201 static int zaudio_start_input(void *, void *, int, void (*)(void *), void *);
202 static int zaudio_halt_output(void *);
203 static int zaudio_halt_input(void *);
204 static int zaudio_getdev(void *, struct audio_device
*);
205 static int zaudio_set_port(void *, struct mixer_ctrl
*);
206 static int zaudio_get_port(void *, struct mixer_ctrl
*);
207 static int zaudio_query_devinfo(void *, struct mixer_devinfo
*);
208 static void *zaudio_allocm(void *, int, size_t, struct malloc_type
*, int);
209 static void zaudio_freem(void *, void *, struct malloc_type
*);
210 static size_t zaudio_round_buffersize(void *, int, size_t);
211 static paddr_t
zaudio_mappage(void *, void *, off_t
, int);
212 static int zaudio_get_props(void *);
214 struct audio_hw_if wm8750_hw_if
= {
216 .close
= zaudio_close
,
218 .query_encoding
= zaudio_query_encoding
,
219 .set_params
= zaudio_set_params
,
220 .round_blocksize
= zaudio_round_blocksize
,
221 .commit_settings
= NULL
,
224 .start_output
= zaudio_start_output
,
225 .start_input
= zaudio_start_input
,
226 .halt_output
= zaudio_halt_output
,
227 .halt_input
= zaudio_halt_input
,
229 .getdev
= zaudio_getdev
,
231 .set_port
= zaudio_set_port
,
232 .get_port
= zaudio_get_port
,
233 .query_devinfo
= zaudio_query_devinfo
,
234 .allocm
= zaudio_allocm
,
235 .freem
= zaudio_freem
,
236 .round_buffersize
= zaudio_round_buffersize
,
237 .mappage
= zaudio_mappage
,
238 .get_props
= zaudio_get_props
,
239 .trigger_output
= NULL
,
240 .trigger_input
= NULL
,
245 static const uint16_t playback_regs
[][2] = {
247 { ADCDACCTL_REG
, 0x000 },
249 /* 16 bit audio words */
250 { AUDINT_REG
, AUDINT_SET_FORMAT(2) },
252 /* Enable thermal protection, power */
253 { ADCTL1_REG
, ADCTL1_TSDEN
| ADCTL1_SET_VSEL(3) },
255 /* Enable speaker driver, DAC oversampling */
256 { ADCTL2_REG
, ADCTL2_ROUT2INV
| ADCTL2_DACOSR
},
258 /* Set DAC voltage references */
259 { PWRMGMT1_REG
, PWRMGMT1_SET_VMIDSEL(1) | PWRMGMT1_VREF
},
261 /* Direct DACs to output mixers */
262 { LOUTMIX1_REG
, LOUTMIX1_LD2LO
},
263 { LOUTMIX2_REG
, 0x000 },
264 { ROUTMIX1_REG
, 0x000 },
265 { ROUTMIX2_REG
, ROUTMIX2_RD2RO
},
271 static const uint16_t record_regs
[][2] = {
273 { ADCDACCTL_REG
, 0x000 },
275 /* 16 bit audio words */
276 { AUDINT_REG
, AUDINT_SET_FORMAT(2) },
278 /* Enable thermal protection, power, left DAC for both channel */
279 { ADCTL1_REG
, ADCTL1_TSDEN
| ADCTL1_SET_VSEL(3)
280 | ADCTL1_SET_DATSEL(1) },
282 /* Diffrential input select: LINPUT1-RINPUT1, stereo */
283 { ADCINPMODE_REG
, 0x000 },
285 /* L-R differential, micboost 20dB */
286 { ADCLSPATH_REG
, ADCLSPATH_SET_LINSEL(3) | ADCLSPATH_SET_LMICBOOST(2) },
287 { ADCRSPATH_REG
, ADCRSPATH_SET_RINSEL(3) | ADCRSPATH_SET_RMICBOOST(2) },
294 zaudio_match(device_t parent
, cfdata_t cf
, void *aux
)
301 zaudio_attach(device_t parent
, device_t self
, void *aux
)
303 struct zaudio_softc
*sc
= device_private(self
);
304 struct pxaip_attach_args
*pxa
= aux
;
309 aprint_normal(": I2C, I2S, WM8750 Audio\n");
312 if (!pmf_device_register(sc
->sc_dev
, zaudio_suspend
, zaudio_resume
))
313 aprint_error_dev(sc
->sc_dev
,
314 "couldn't establish power handler\n");
316 sc
->sc_i2s
.sc_iot
= pxa
->pxa_iot
;
317 sc
->sc_i2s
.sc_dmat
= pxa
->pxa_dmat
;
318 sc
->sc_i2s
.sc_size
= PXA2X0_I2S_SIZE
;
319 if (pxa2x0_i2s_attach_sub(&sc
->sc_i2s
)) {
320 aprint_error_dev(sc
->sc_dev
, "unable to attach I2S\n");
324 sc
->sc_i2c
.sc_iot
= pxa
->pxa_iot
;
325 sc
->sc_i2c
.sc_size
= PXA2X0_I2C_SIZE
;
326 if (pxa2x0_i2c_attach_sub(&sc
->sc_i2c
)) {
327 aprint_error_dev(sc
->sc_dev
, "unable to attach I2C\n");
331 /* Check for an I2C response from the wm8750 */
332 pxa2x0_i2c_open(&sc
->sc_i2c
);
333 rv
= wm8750_write(sc
, RESET_REG
, 0);
334 pxa2x0_i2c_close(&sc
->sc_i2c
);
336 aprint_error_dev(sc
->sc_dev
, "codec failed to respond\n");
341 /* Speaker on, headphones off by default. */
342 sc
->sc_volume
[ZAUDIO_OP_SPKR
].left
= 240;
343 sc
->sc_unmute
[ZAUDIO_OP_SPKR
] = 1;
344 sc
->sc_volume
[ZAUDIO_OP_HP
].left
= 180;
345 sc
->sc_volume
[ZAUDIO_OP_HP
].right
= 180;
346 sc
->sc_unmute
[ZAUDIO_OP_HP
] = 0;
347 sc
->sc_volume
[ZAUDIO_OP_MIC
].left
= 240;
348 sc
->sc_unmute
[ZAUDIO_OP_MIC
] = 0;
350 /* Configure headphone jack state change handling. */
351 callout_init(&sc
->sc_to
, 0);
352 callout_setfunc(&sc
->sc_to
, zaudio_jack
, sc
);
353 pxa2x0_gpio_set_function(GPIO_HP_IN_C3000
, GPIO_IN
);
354 (void) pxa2x0_gpio_intr_establish(GPIO_HP_IN_C3000
, IST_EDGE_BOTH
,
355 IPL_BIO
, zaudio_jack_intr
, sc
);
359 audio_attach_mi(&wm8750_hw_if
, sc
, sc
->sc_dev
);
364 pxa2x0_i2c_detach_sub(&sc
->sc_i2c
);
366 pxa2x0_i2s_detach_sub(&sc
->sc_i2s
);
368 pmf_device_deregister(self
);
372 zaudio_suspend(device_t dv
, pmf_qual_t qual
)
374 struct zaudio_softc
*sc
= device_private(dv
);
376 callout_stop(&sc
->sc_to
);
383 zaudio_resume(device_t dv
, pmf_qual_t qual
)
385 struct zaudio_softc
*sc
= device_private(dv
);
387 pxa2x0_i2s_init(&sc
->sc_i2s
);
388 pxa2x0_i2c_init(&sc
->sc_i2c
);
395 zaudio_init(struct zaudio_softc
*sc
)
398 pxa2x0_i2c_open(&sc
->sc_i2c
);
400 /* Reset the codec */
401 wm8750_write(sc
, RESET_REG
, 0);
404 /* Switch to standby power only */
405 wm8750_write(sc
, PWRMGMT1_REG
, PWRMGMT1_SET_VMIDSEL(2));
406 wm8750_write(sc
, PWRMGMT2_REG
, 0);
408 /* Configure digital interface for I2S */
409 wm8750_write(sc
, AUDINT_REG
, AUDINT_SET_FORMAT(2));
411 /* Initialise volume levels */
412 zaudio_update_volume(sc
, ZAUDIO_OP_SPKR
);
413 zaudio_update_volume(sc
, ZAUDIO_OP_HP
);
414 zaudio_update_volume(sc
, ZAUDIO_OP_MIC
);
416 pxa2x0_i2c_close(&sc
->sc_i2c
);
418 scoop_set_headphone(0);
419 scoop_set_mic_bias(0);
421 /* Assume that the jack state has changed. */
426 zaudio_jack_intr(void *v
)
428 struct zaudio_softc
*sc
= v
;
430 if (!callout_active(&sc
->sc_to
))
439 struct zaudio_softc
*sc
= v
;
441 switch (sc
->sc_state
) {
442 case ZAUDIO_JACK_STATE_OUT
:
443 if (pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000
)) {
444 sc
->sc_state
= ZAUDIO_JACK_STATE_INS
;
449 case ZAUDIO_JACK_STATE_INS
:
450 if (sc
->sc_icount
++ > 2) {
451 if (pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000
)) {
452 sc
->sc_state
= ZAUDIO_JACK_STATE_IN
;
453 sc
->sc_unmute
[ZAUDIO_OP_SPKR
] = 0;
454 sc
->sc_unmute
[ZAUDIO_OP_HP
] = 1;
455 sc
->sc_unmute
[ZAUDIO_OP_MIC
] = 1;
458 sc
->sc_state
= ZAUDIO_JACK_STATE_OUT
;
462 case ZAUDIO_JACK_STATE_IN
:
463 if (!pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000
)) {
464 sc
->sc_state
= ZAUDIO_JACK_STATE_REM
;
469 case ZAUDIO_JACK_STATE_REM
:
470 if (sc
->sc_icount
++ > 2) {
471 if (!pxa2x0_gpio_get_bit(GPIO_HP_IN_C3000
)) {
472 sc
->sc_state
= ZAUDIO_JACK_STATE_OUT
;
473 sc
->sc_unmute
[ZAUDIO_OP_SPKR
] = 1;
474 sc
->sc_unmute
[ZAUDIO_OP_HP
] = 0;
475 sc
->sc_unmute
[ZAUDIO_OP_MIC
] = 0;
478 sc
->sc_state
= ZAUDIO_JACK_STATE_IN
;
483 callout_schedule(&sc
->sc_to
, hz
/4);
488 callout_stop(&sc
->sc_to
);
490 if (sc
->sc_playing
|| sc
->sc_recording
) {
491 pxa2x0_i2c_open(&sc
->sc_i2c
);
493 zaudio_update_mutes(sc
, 1);
494 if (sc
->sc_recording
)
495 zaudio_update_mutes(sc
, 2);
496 pxa2x0_i2c_close(&sc
->sc_i2c
);
501 zaudio_standby(struct zaudio_softc
*sc
)
504 pxa2x0_i2c_open(&sc
->sc_i2c
);
506 /* Switch codec to standby power only */
507 wm8750_write(sc
, PWRMGMT1_REG
, PWRMGMT1_SET_VMIDSEL(2));
508 wm8750_write(sc
, PWRMGMT2_REG
, 0);
510 pxa2x0_i2c_close(&sc
->sc_i2c
);
512 scoop_set_headphone(0);
513 scoop_set_mic_bias(0);
517 zaudio_update_volume(struct zaudio_softc
*sc
, int output
)
522 wm8750_write(sc
, LOUT2VOL_REG
, LOUT2VOL_LO2VU
| LOUT2VOL_LO2ZC
|
523 LOUT2VOL_SET_LOUT2VOL(sc
->sc_volume
[ZAUDIO_OP_SPKR
].left
>> 1));
524 wm8750_write(sc
, ROUT2VOL_REG
, ROUT2VOL_RO2VU
| ROUT2VOL_RO2ZC
|
525 ROUT2VOL_SET_ROUT2VOL(sc
->sc_volume
[ZAUDIO_OP_SPKR
].left
>> 1));
529 wm8750_write(sc
, LOUT1VOL_REG
, LOUT1VOL_LO1VU
| LOUT1VOL_LO1ZC
|
530 LOUT1VOL_SET_LOUT1VOL(sc
->sc_volume
[ZAUDIO_OP_HP
].left
>> 1));
531 wm8750_write(sc
, ROUT1VOL_REG
, ROUT1VOL_RO1VU
| ROUT1VOL_RO1ZC
|
532 ROUT1VOL_SET_ROUT1VOL(sc
->sc_volume
[ZAUDIO_OP_HP
].right
>> 1));
536 wm8750_write(sc
, LINVOL_REG
, LINVOL_LIVU
|
537 LINVOL_SET_LINVOL(sc
->sc_volume
[ZAUDIO_OP_MIC
].left
>> 2));
538 wm8750_write(sc
, RINVOL_REG
, RINVOL_RIVU
|
539 RINVOL_SET_RINVOL(sc
->sc_volume
[ZAUDIO_OP_MIC
].left
>> 2));
545 zaudio_update_mutes(struct zaudio_softc
*sc
, int mask
)
551 val
= PWRMGMT2_DACL
| PWRMGMT2_DACR
;
552 if (sc
->sc_unmute
[ZAUDIO_OP_SPKR
])
553 val
|= PWRMGMT2_LOUT2
| PWRMGMT2_ROUT2
;
554 if (sc
->sc_unmute
[ZAUDIO_OP_HP
])
555 val
|= PWRMGMT2_LOUT1
| PWRMGMT2_ROUT1
;
556 wm8750_write(sc
, PWRMGMT2_REG
, val
);
557 scoop_set_headphone(sc
->sc_unmute
[ZAUDIO_OP_HP
]);
562 val
= PWRMGMT1_SET_VMIDSEL(1) | PWRMGMT1_VREF
;
563 if (sc
->sc_unmute
[ZAUDIO_OP_MIC
]) {
564 val
|= PWRMGMT1_AINL
| PWRMGMT1_AINR
565 | PWRMGMT1_ADCL
| PWRMGMT1_ADCR
| PWRMGMT1_MICB
;
567 wm8750_write(sc
, PWRMGMT1_REG
, val
);
568 scoop_set_mic_bias(sc
->sc_unmute
[ZAUDIO_OP_MIC
]);
573 zaudio_play_setup(struct zaudio_softc
*sc
)
577 pxa2x0_i2c_open(&sc
->sc_i2c
);
579 /* Program the codec with playback settings */
580 for (i
= 0; playback_regs
[i
][0] != 0xffff; i
++) {
581 wm8750_write(sc
, playback_regs
[i
][0], playback_regs
[i
][1]);
583 zaudio_update_mutes(sc
, 1);
585 pxa2x0_i2c_close(&sc
->sc_i2c
);
589 zaudio_record_setup(struct zaudio_softc
*sc
)
593 pxa2x0_i2c_open(&sc
->sc_i2c
);
595 /* Program the codec with playback settings */
596 for (i
= 0; record_regs
[i
][0] != 0xffff; i
++) {
597 wm8750_write(sc
, record_regs
[i
][0], record_regs
[i
][1]);
600 zaudio_update_mutes(sc
, 2);
602 pxa2x0_i2c_close(&sc
->sc_i2c
);
606 * audio operation functions.
609 zaudio_open(void *hdl
, int flags
)
611 struct zaudio_softc
*sc
= hdl
;
613 /* Power on the I2S bus and codec */
614 pxa2x0_i2s_open(&sc
->sc_i2s
);
620 zaudio_close(void *hdl
)
622 struct zaudio_softc
*sc
= hdl
;
624 /* Power off the I2S bus and codec */
625 pxa2x0_i2s_close(&sc
->sc_i2s
);
629 zaudio_query_encoding(void *hdl
, struct audio_encoding
*aep
)
632 switch (aep
->index
) {
634 strlcpy(aep
->name
, AudioEulinear
, sizeof(aep
->name
));
635 aep
->encoding
= AUDIO_ENCODING_ULINEAR
;
641 strlcpy(aep
->name
, AudioEmulaw
, sizeof(aep
->name
));
642 aep
->encoding
= AUDIO_ENCODING_ULAW
;
644 aep
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
648 strlcpy(aep
->name
, AudioEalaw
, sizeof(aep
->name
));
649 aep
->encoding
= AUDIO_ENCODING_ALAW
;
651 aep
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
655 strlcpy(aep
->name
, AudioEslinear
, sizeof(aep
->name
));
656 aep
->encoding
= AUDIO_ENCODING_SLINEAR
;
658 aep
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
662 strlcpy(aep
->name
, AudioEslinear_le
, sizeof(aep
->name
));
663 aep
->encoding
= AUDIO_ENCODING_SLINEAR_LE
;
669 strlcpy(aep
->name
, AudioEulinear_le
, sizeof(aep
->name
));
670 aep
->encoding
= AUDIO_ENCODING_ULINEAR_LE
;
672 aep
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
676 strlcpy(aep
->name
, AudioEslinear_be
, sizeof(aep
->name
));
677 aep
->encoding
= AUDIO_ENCODING_SLINEAR_BE
;
679 aep
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
683 strlcpy(aep
->name
, AudioEulinear_be
, sizeof(aep
->name
));
684 aep
->encoding
= AUDIO_ENCODING_ULINEAR_BE
;
686 aep
->flags
= AUDIO_ENCODINGFLAG_EMULATED
;
697 zaudio_set_params(void *hdl
, int setmode
, int usemode
,
698 audio_params_t
*play
, audio_params_t
*rec
,
699 stream_filter_list_t
*pfil
, stream_filter_list_t
*rfil
)
701 struct zaudio_softc
*sc
= hdl
;
702 struct audio_params
*p
;
703 stream_filter_list_t
*fil
;
706 if (play
->sample_rate
!= rec
->sample_rate
&&
707 usemode
== (AUMODE_PLAY
| AUMODE_RECORD
)) {
708 if (setmode
== AUMODE_PLAY
) {
709 rec
->sample_rate
= play
->sample_rate
;
710 setmode
|= AUMODE_RECORD
;
711 } else if (setmode
== AUMODE_RECORD
) {
712 play
->sample_rate
= rec
->sample_rate
;
713 setmode
|= AUMODE_PLAY
;
718 for (mode
= AUMODE_RECORD
; mode
!= -1;
719 mode
= (mode
== AUMODE_RECORD
) ? AUMODE_PLAY
: -1) {
720 if ((setmode
& mode
) == 0)
723 p
= (mode
== AUMODE_PLAY
) ? play
: rec
;
725 if (p
->sample_rate
< 4000 || p
->sample_rate
> 48000 ||
726 (p
->precision
!= 8 && p
->precision
!= 16) ||
727 (p
->channels
!= 1 && p
->channels
!= 2))
730 fil
= (mode
== AUMODE_PLAY
) ? pfil
: rfil
;
731 i
= auconv_set_converter(zaudio_formats
, zaudio_nformats
,
732 mode
, p
, false, fil
);
737 if (setmode
== AUMODE_RECORD
)
738 pxa2x0_i2s_setspeed(&sc
->sc_i2s
, &rec
->sample_rate
);
740 pxa2x0_i2s_setspeed(&sc
->sc_i2s
, &play
->sample_rate
);
746 zaudio_round_blocksize(void *hdl
, int bs
, int mode
, const audio_params_t
*param
)
748 struct zaudio_softc
*sc
= hdl
;
750 return pxa2x0_i2s_round_blocksize(&sc
->sc_i2s
, bs
, mode
, param
);
755 zaudio_halt_output(void *hdl
)
757 struct zaudio_softc
*sc
= hdl
;
760 rv
= pxa2x0_i2s_halt_output(&sc
->sc_i2s
);
761 if (!sc
->sc_recording
)
769 zaudio_halt_input(void *hdl
)
771 struct zaudio_softc
*sc
= hdl
;
774 rv
= pxa2x0_i2s_halt_input(&sc
->sc_i2s
);
777 sc
->sc_recording
= 0;
783 zaudio_getdev(void *hdl
, struct audio_device
*ret
)
786 *ret
= wm8750_device
;
790 #define ZAUDIO_SPKR_LVL 0
791 #define ZAUDIO_SPKR_MUTE 1
792 #define ZAUDIO_HP_LVL 2
793 #define ZAUDIO_HP_MUTE 3
794 #define ZAUDIO_MIC_LVL 4
795 #define ZAUDIO_MIC_MUTE 5
796 #define ZAUDIO_RECORD_SOURCE 6
797 #define ZAUDIO_OUTPUT_CLASS 7
798 #define ZAUDIO_INPUT_CLASS 8
799 #define ZAUDIO_RECORD_CLASS 9
802 zaudio_set_port(void *hdl
, struct mixer_ctrl
*mc
)
804 struct zaudio_softc
*sc
= hdl
;
809 pxa2x0_i2c_open(&sc
->sc_i2c
);
812 case ZAUDIO_SPKR_LVL
:
813 if (mc
->type
!= AUDIO_MIXER_VALUE
)
815 if (mc
->un
.value
.num_channels
== 1)
816 sc
->sc_volume
[ZAUDIO_OP_SPKR
].left
=
817 mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_MONO
];
820 zaudio_update_volume(sc
, ZAUDIO_OP_SPKR
);
824 case ZAUDIO_SPKR_MUTE
:
825 if (mc
->type
!= AUDIO_MIXER_ENUM
)
827 sc
->sc_unmute
[ZAUDIO_OP_SPKR
] = mc
->un
.ord
? 1 : 0;
828 zaudio_update_mutes(sc
, 1);
833 if (mc
->type
!= AUDIO_MIXER_VALUE
)
835 if (mc
->un
.value
.num_channels
== 1) {
836 sc
->sc_volume
[ZAUDIO_OP_HP
].left
=
837 mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_MONO
];
838 sc
->sc_volume
[ZAUDIO_OP_HP
].right
=
839 mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_MONO
];
840 } else if (mc
->un
.value
.num_channels
== 2) {
841 sc
->sc_volume
[ZAUDIO_OP_HP
].left
=
842 mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_LEFT
];
843 sc
->sc_volume
[ZAUDIO_OP_HP
].right
=
844 mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_RIGHT
];
848 zaudio_update_volume(sc
, ZAUDIO_OP_HP
);
853 if (mc
->type
!= AUDIO_MIXER_ENUM
)
855 sc
->sc_unmute
[ZAUDIO_OP_HP
] = mc
->un
.ord
? 1 : 0;
856 zaudio_update_mutes(sc
, 1);
861 if (mc
->type
!= AUDIO_MIXER_VALUE
)
863 if (mc
->un
.value
.num_channels
== 1)
864 sc
->sc_volume
[ZAUDIO_OP_MIC
].left
=
865 mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_MONO
];
868 zaudio_update_volume(sc
, ZAUDIO_OP_MIC
);
872 case ZAUDIO_MIC_MUTE
:
873 if (mc
->type
!= AUDIO_MIXER_ENUM
)
875 sc
->sc_unmute
[ZAUDIO_OP_MIC
] = mc
->un
.ord
? 1 : 0;
876 zaudio_update_mutes(sc
, 2);
880 case ZAUDIO_RECORD_SOURCE
:
881 if (mc
->type
!= AUDIO_MIXER_ENUM
)
890 pxa2x0_i2c_close(&sc
->sc_i2c
);
897 zaudio_get_port(void *hdl
, struct mixer_ctrl
*mc
)
899 struct zaudio_softc
*sc
= hdl
;
903 case ZAUDIO_SPKR_LVL
:
904 if (mc
->type
!= AUDIO_MIXER_VALUE
)
906 if (mc
->un
.value
.num_channels
== 1)
907 mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_MONO
] =
908 sc
->sc_volume
[ZAUDIO_OP_SPKR
].left
;
914 case ZAUDIO_SPKR_MUTE
:
915 if (mc
->type
!= AUDIO_MIXER_ENUM
)
917 mc
->un
.ord
= sc
->sc_unmute
[ZAUDIO_OP_SPKR
] ? 1 : 0;
922 if (mc
->type
!= AUDIO_MIXER_VALUE
)
924 if (mc
->un
.value
.num_channels
== 1)
925 mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_MONO
] =
926 sc
->sc_volume
[ZAUDIO_OP_HP
].left
;
927 else if (mc
->un
.value
.num_channels
== 2) {
928 mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_LEFT
] =
929 sc
->sc_volume
[ZAUDIO_OP_HP
].left
;
930 mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_RIGHT
] =
931 sc
->sc_volume
[ZAUDIO_OP_HP
].right
;
939 if (mc
->type
!= AUDIO_MIXER_ENUM
)
941 mc
->un
.ord
= sc
->sc_unmute
[ZAUDIO_OP_HP
] ? 1 : 0;
946 if (mc
->type
!= AUDIO_MIXER_VALUE
)
948 if (mc
->un
.value
.num_channels
== 1)
949 mc
->un
.value
.level
[AUDIO_MIXER_LEVEL_MONO
] =
950 sc
->sc_volume
[ZAUDIO_OP_MIC
].left
;
956 case ZAUDIO_MIC_MUTE
:
957 if (mc
->type
!= AUDIO_MIXER_ENUM
)
959 mc
->un
.ord
= sc
->sc_unmute
[ZAUDIO_OP_MIC
] ? 1 : 0;
963 case ZAUDIO_RECORD_SOURCE
:
964 if (mc
->type
!= AUDIO_MIXER_ENUM
)
966 mc
->un
.ord
= 0; /* MIC only */
976 zaudio_query_devinfo(void *hdl
, struct mixer_devinfo
*di
)
980 case ZAUDIO_SPKR_LVL
:
981 di
->type
= AUDIO_MIXER_VALUE
;
982 di
->mixer_class
= ZAUDIO_OUTPUT_CLASS
;
983 di
->prev
= AUDIO_MIXER_LAST
;
984 di
->next
= ZAUDIO_SPKR_MUTE
;
985 strlcpy(di
->label
.name
, AudioNspeaker
, sizeof(di
->label
.name
));
986 strlcpy(di
->un
.v
.units
.name
, AudioNvolume
,
987 sizeof(di
->un
.v
.units
.name
));
988 di
->un
.v
.num_channels
= 1;
991 case ZAUDIO_SPKR_MUTE
:
992 di
->type
= AUDIO_MIXER_ENUM
;
993 di
->mixer_class
= ZAUDIO_OUTPUT_CLASS
;
994 di
->prev
= ZAUDIO_SPKR_LVL
;
995 di
->next
= AUDIO_MIXER_LAST
;
999 di
->type
= AUDIO_MIXER_VALUE
;
1000 di
->mixer_class
= ZAUDIO_OUTPUT_CLASS
;
1001 di
->prev
= AUDIO_MIXER_LAST
;
1002 di
->next
= ZAUDIO_HP_MUTE
;
1003 strlcpy(di
->label
.name
, AudioNheadphone
,
1004 sizeof(di
->label
.name
));
1005 di
->un
.v
.num_channels
= 1;
1006 strlcpy(di
->un
.v
.units
.name
, AudioNvolume
,
1007 sizeof(di
->un
.v
.units
.name
));
1010 case ZAUDIO_HP_MUTE
:
1011 di
->type
= AUDIO_MIXER_ENUM
;
1012 di
->mixer_class
= ZAUDIO_OUTPUT_CLASS
;
1013 di
->prev
= ZAUDIO_HP_LVL
;
1014 di
->next
= AUDIO_MIXER_LAST
;
1016 strlcpy(di
->label
.name
, AudioNmute
, sizeof(di
->label
.name
));
1017 di
->un
.e
.num_mem
= 2;
1018 strlcpy(di
->un
.e
.member
[0].label
.name
, AudioNon
,
1019 sizeof(di
->un
.e
.member
[0].label
.name
));
1020 di
->un
.e
.member
[0].ord
= 0;
1021 strlcpy(di
->un
.e
.member
[1].label
.name
, AudioNoff
,
1022 sizeof(di
->un
.e
.member
[1].label
.name
));
1023 di
->un
.e
.member
[1].ord
= 1;
1026 case ZAUDIO_MIC_LVL
:
1027 di
->type
= AUDIO_MIXER_VALUE
;
1028 di
->mixer_class
= ZAUDIO_INPUT_CLASS
;
1029 di
->prev
= AUDIO_MIXER_LAST
;
1030 di
->next
= ZAUDIO_MIC_MUTE
;
1031 strlcpy(di
->label
.name
, AudioNmicrophone
,
1032 sizeof(di
->label
.name
));
1033 strlcpy(di
->un
.v
.units
.name
, AudioNvolume
,
1034 sizeof(di
->un
.v
.units
.name
));
1035 di
->un
.v
.num_channels
= 1;
1038 case ZAUDIO_MIC_MUTE
:
1039 di
->type
= AUDIO_MIXER_ENUM
;
1040 di
->mixer_class
= ZAUDIO_INPUT_CLASS
;
1041 di
->prev
= ZAUDIO_MIC_LVL
;
1042 di
->next
= AUDIO_MIXER_LAST
;
1045 case ZAUDIO_RECORD_SOURCE
:
1046 di
->type
= AUDIO_MIXER_ENUM
;
1047 di
->mixer_class
= ZAUDIO_RECORD_CLASS
;
1048 di
->prev
= AUDIO_MIXER_LAST
;
1049 di
->next
= AUDIO_MIXER_LAST
;
1050 strlcpy(di
->label
.name
, AudioNsource
, sizeof(di
->label
.name
));
1051 di
->un
.e
.num_mem
= 1;
1052 strlcpy(di
->un
.e
.member
[0].label
.name
, AudioNmicrophone
,
1053 sizeof(di
->un
.e
.member
[0].label
.name
));
1054 di
->un
.e
.member
[0].ord
= 0;
1057 case ZAUDIO_OUTPUT_CLASS
:
1058 di
->type
= AUDIO_MIXER_CLASS
;
1059 di
->mixer_class
= ZAUDIO_OUTPUT_CLASS
;
1060 di
->prev
= AUDIO_MIXER_LAST
;
1061 di
->next
= AUDIO_MIXER_LAST
;
1062 strlcpy(di
->label
.name
, AudioCoutputs
, sizeof(di
->label
.name
));
1065 case ZAUDIO_INPUT_CLASS
:
1066 di
->type
= AUDIO_MIXER_CLASS
;
1067 di
->mixer_class
= ZAUDIO_INPUT_CLASS
;
1068 di
->prev
= AUDIO_MIXER_LAST
;
1069 di
->next
= AUDIO_MIXER_LAST
;
1070 strlcpy(di
->label
.name
, AudioCinputs
, sizeof(di
->label
.name
));
1073 case ZAUDIO_RECORD_CLASS
:
1074 di
->type
= AUDIO_MIXER_CLASS
;
1075 di
->mixer_class
= ZAUDIO_RECORD_CLASS
;
1076 di
->prev
= AUDIO_MIXER_LAST
;
1077 di
->next
= AUDIO_MIXER_LAST
;
1078 strlcpy(di
->label
.name
, AudioCinputs
, sizeof(di
->label
.name
));
1089 zaudio_allocm(void *hdl
, int direction
, size_t size
, struct malloc_type
*type
,
1092 struct zaudio_softc
*sc
= hdl
;
1094 return pxa2x0_i2s_allocm(&sc
->sc_i2s
, direction
, size
, type
, flags
);
1098 zaudio_freem(void *hdl
, void *ptr
, struct malloc_type
*type
)
1100 struct zaudio_softc
*sc
= hdl
;
1102 return pxa2x0_i2s_freem(&sc
->sc_i2s
, ptr
, type
);
1106 zaudio_round_buffersize(void *hdl
, int direction
, size_t bufsize
)
1108 struct zaudio_softc
*sc
= hdl
;
1110 return pxa2x0_i2s_round_buffersize(&sc
->sc_i2s
, direction
, bufsize
);
1114 zaudio_mappage(void *hdl
, void *mem
, off_t off
, int prot
)
1116 struct zaudio_softc
*sc
= hdl
;
1118 return pxa2x0_i2s_mappage(&sc
->sc_i2s
, mem
, off
, prot
);
1122 zaudio_get_props(void *hdl
)
1125 return AUDIO_PROP_MMAP
|AUDIO_PROP_INDEPENDENT
;
1129 zaudio_start_output(void *hdl
, void *block
, int bsize
, void (*intr
)(void *),
1132 struct zaudio_softc
*sc
= hdl
;
1135 /* Power up codec if we are not already playing. */
1136 if (!sc
->sc_playing
) {
1138 zaudio_play_setup(sc
);
1141 /* Start DMA via I2S */
1142 rv
= pxa2x0_i2s_start_output(&sc
->sc_i2s
, block
, bsize
, intr
, intrarg
);
1144 if (!sc
->sc_recording
)
1152 zaudio_start_input(void *hdl
, void *block
, int bsize
, void (*intr
)(void *),
1155 struct zaudio_softc
*sc
= hdl
;
1158 /* Power up codec if we are not already recording. */
1159 if (!sc
->sc_recording
) {
1160 sc
->sc_recording
= 1;
1161 zaudio_record_setup(sc
);
1164 /* Start DMA via I2S */
1165 rv
= pxa2x0_i2s_start_input(&sc
->sc_i2s
, block
, bsize
, intr
, intrarg
);
1167 if (!sc
->sc_playing
)
1169 sc
->sc_recording
= 0;