xref: /netbsd-src/sys/arch/amiga/dev/zz9k_ax.c (revision 8d9149a73d8c60ae0227e10e709e085238bd5944)
1*8d9149a7Sphx /*	$NetBSD: zz9k_ax.c,v 1.1 2023/05/03 13:49:30 phx Exp $ */
2*8d9149a7Sphx 
3*8d9149a7Sphx /*
4*8d9149a7Sphx  * Copyright (c) 2020 The NetBSD Foundation, Inc.
5*8d9149a7Sphx  * All rights reserved.
6*8d9149a7Sphx  *
7*8d9149a7Sphx  * This code is derived from software contributed to The NetBSD Foundation
8*8d9149a7Sphx  * by Alain Runa.
9*8d9149a7Sphx  *
10*8d9149a7Sphx  * Redistribution and use in source and binary forms, with or without
11*8d9149a7Sphx  * modification, are permitted provided that the following conditions
12*8d9149a7Sphx  * are met:
13*8d9149a7Sphx  * 1. Redistributions of source code must retain the above copyright
14*8d9149a7Sphx  *	notice, this list of conditions and the following disclaimer.
15*8d9149a7Sphx  * 2. Redistributions in binary form must reproduce the above copyright
16*8d9149a7Sphx  *	notice, this list of conditions and the following disclaimer in the
17*8d9149a7Sphx  *	documentation and/or other materials provided with the distribution.
18*8d9149a7Sphx  *
19*8d9149a7Sphx  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20*8d9149a7Sphx  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21*8d9149a7Sphx  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22*8d9149a7Sphx  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23*8d9149a7Sphx  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24*8d9149a7Sphx  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25*8d9149a7Sphx  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26*8d9149a7Sphx  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27*8d9149a7Sphx  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28*8d9149a7Sphx  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29*8d9149a7Sphx  */
30*8d9149a7Sphx 
31*8d9149a7Sphx #include <sys/cdefs.h>
32*8d9149a7Sphx __KERNEL_RCSID(0, "$NetBSD: zz9k_ax.c,v 1.1 2023/05/03 13:49:30 phx Exp $");
33*8d9149a7Sphx 
34*8d9149a7Sphx /* miscellaneous */
35*8d9149a7Sphx #include <sys/types.h>			/* size_t */
36*8d9149a7Sphx #include <sys/stdint.h>			/* uintXX_t */
37*8d9149a7Sphx #include <sys/stdbool.h>		/* bool */
38*8d9149a7Sphx 
39*8d9149a7Sphx /* driver(9) */
40*8d9149a7Sphx #include <sys/param.h>			/* NODEV */
41*8d9149a7Sphx #include <sys/device.h>			/* CFATTACH_DECL_NEW(), device_priv() */
42*8d9149a7Sphx #include <sys/errno.h>			/* . */
43*8d9149a7Sphx 
44*8d9149a7Sphx /* bus_space(9) and zorro bus */
45*8d9149a7Sphx #include <sys/bus.h>			/* bus_space_xxx(), bus_space_xxx_t */
46*8d9149a7Sphx #include <sys/cpu.h>			/* kvtop() */
47*8d9149a7Sphx #include <sys/systm.h>			/* aprint_xxx() */
48*8d9149a7Sphx 
49*8d9149a7Sphx /* mutex(9) */
50*8d9149a7Sphx #include <sys/mutex.h>
51*8d9149a7Sphx 
52*8d9149a7Sphx /* Interrupt related */
53*8d9149a7Sphx #include <sys/intr.h>
54*8d9149a7Sphx #include <amiga/amiga/isr.h>		/* isr */
55*8d9149a7Sphx 
56*8d9149a7Sphx /* audio(9) */
57*8d9149a7Sphx #include <sys/audioio.h>
58*8d9149a7Sphx #include <dev/audio/audio_if.h>
59*8d9149a7Sphx 
60*8d9149a7Sphx /* zz9k related */
61*8d9149a7Sphx #include <amiga/dev/zz9kvar.h>		/* zz9kbus_attach_args */
62*8d9149a7Sphx #include <amiga/dev/zz9kreg.h>		/* ZZ9000 registers */
63*8d9149a7Sphx #include "zz9k_ax.h"			/* NZZ9K_AX */
64*8d9149a7Sphx 
65*8d9149a7Sphx 
66*8d9149a7Sphx /* The allmighty softc structure */
67*8d9149a7Sphx struct zzax_softc {
68*8d9149a7Sphx 	device_t sc_dev;
69*8d9149a7Sphx 	struct bus_space_tag sc_bst;
70*8d9149a7Sphx 	bus_space_tag_t sc_iot;
71*8d9149a7Sphx 	bus_space_handle_t sc_regh;
72*8d9149a7Sphx 	bus_space_handle_t sc_txbufh;
73*8d9149a7Sphx 	size_t sc_txbufsize;
74*8d9149a7Sphx 
75*8d9149a7Sphx 	struct isr sc_isr;
76*8d9149a7Sphx 
77*8d9149a7Sphx 	kmutex_t  sc_lock;
78*8d9149a7Sphx 	kmutex_t  sc_intr_lock;
79*8d9149a7Sphx };
80*8d9149a7Sphx 
81*8d9149a7Sphx static int zzax_intr(void *arg);
82*8d9149a7Sphx static void zzax_set_param(struct zzax_softc *sc, uint16_t param, uint16_t val);
83*8d9149a7Sphx 
84*8d9149a7Sphx /* audio_hw_if */
85*8d9149a7Sphx static int zzax_open(void *hdl, int flags);
86*8d9149a7Sphx static void zzax_close(void *hdl);
87*8d9149a7Sphx static int zzax_query_format(void *hdl, audio_format_query_t *afp);
88*8d9149a7Sphx static int zzax_set_format(void *hdl, int setmode,
89*8d9149a7Sphx     const audio_params_t *play, const audio_params_t *rec,
90*8d9149a7Sphx     audio_filter_reg_t *pfil, audio_filter_reg_t *rfil);
91*8d9149a7Sphx static int zzax_round_blocksize(void *hdl, int bs, int mode,
92*8d9149a7Sphx     const audio_params_t *param);
93*8d9149a7Sphx static int zzax_commit_settings(void *hdl);
94*8d9149a7Sphx static int zzax_init_output(void *hdl, void *buffer, int size);
95*8d9149a7Sphx static int zzax_init_input(void *hdl, void *buffer, int size);
96*8d9149a7Sphx static int zzax_start_output(void *hdl, void *block, int blksize,
97*8d9149a7Sphx     void (*intr)(void*), void *intrarg);
98*8d9149a7Sphx static int zzax_start_input(void *hdl, void *block, int blksize,
99*8d9149a7Sphx     void (*intr)(void*), void *intrarg);
100*8d9149a7Sphx static int zzax_halt_output(void *hdl);
101*8d9149a7Sphx static int zzax_halt_input(void *hdl);
102*8d9149a7Sphx static int zzax_speaker_ctl(void *hdl, int on);
103*8d9149a7Sphx static int zzax_getdev(void *hdl, struct audio_device *ret);
104*8d9149a7Sphx static int zzax_set_port(void *hdl, mixer_ctrl_t *mc);
105*8d9149a7Sphx static int zzax_get_port(void *hdl, mixer_ctrl_t *mc);
106*8d9149a7Sphx static int zzax_query_devinfo(void *hdl, mixer_devinfo_t *di);
107*8d9149a7Sphx #if 0
108*8d9149a7Sphx static void *zzax_allocm(void *hdl, int direction, size_t size);
109*8d9149a7Sphx static void zzax_freem(void *hdl, void *addr, size_t size);
110*8d9149a7Sphx #endif
111*8d9149a7Sphx static size_t zzax_round_buffersize(void *hdl, int direction, size_t bufsize);
112*8d9149a7Sphx static int zzax_get_props(void *hdl);
113*8d9149a7Sphx static int zzax_trigger_output(void *hdl, void *start, void *end, int blksize,
114*8d9149a7Sphx     void (*intr)(void*), void *intrarg, const audio_params_t *param);
115*8d9149a7Sphx static int zzax_trigger_input(void *hdl, void *start, void *end, int blksize,
116*8d9149a7Sphx     void (*intr)(void*), void *intrarg, const audio_params_t *param);
117*8d9149a7Sphx static int zzax_dev_ioctl(void *hdl, u_long cmd, void *addr, int flag,
118*8d9149a7Sphx     struct lwp *l);
119*8d9149a7Sphx static void zzax_get_locks(void *hdl, kmutex_t **intr, kmutex_t **thread);
120*8d9149a7Sphx 
121*8d9149a7Sphx static const struct audio_hw_if zzax_hw_if = {
122*8d9149a7Sphx 	.open			= zzax_open,
123*8d9149a7Sphx 	.close			= zzax_close,
124*8d9149a7Sphx 	.query_format		= zzax_query_format,
125*8d9149a7Sphx 	.set_format		= zzax_set_format,
126*8d9149a7Sphx 	.round_blocksize	= zzax_round_blocksize,
127*8d9149a7Sphx 	.commit_settings	= zzax_commit_settings,
128*8d9149a7Sphx 	.init_output		= zzax_init_output,
129*8d9149a7Sphx 	.init_input		= zzax_init_input,
130*8d9149a7Sphx 	.start_output		= zzax_start_output,
131*8d9149a7Sphx 	.start_input		= zzax_start_input,
132*8d9149a7Sphx 	.halt_output		= zzax_halt_output,
133*8d9149a7Sphx 	.halt_input		= zzax_halt_input,
134*8d9149a7Sphx 	.speaker_ctl		= zzax_speaker_ctl,
135*8d9149a7Sphx 	.getdev			= zzax_getdev,
136*8d9149a7Sphx 	.set_port		= zzax_set_port,
137*8d9149a7Sphx 	.get_port		= zzax_get_port,
138*8d9149a7Sphx 	.query_devinfo		= zzax_query_devinfo,
139*8d9149a7Sphx #if 0
140*8d9149a7Sphx 	.allocm			= zzax_allocm,
141*8d9149a7Sphx 	.freem			= zzax_freem,
142*8d9149a7Sphx #endif
143*8d9149a7Sphx 	.round_buffersize	= zzax_round_buffersize,
144*8d9149a7Sphx 	.get_props		= zzax_get_props,
145*8d9149a7Sphx 	.trigger_output		= zzax_trigger_output,
146*8d9149a7Sphx 	.trigger_input		= zzax_trigger_input,
147*8d9149a7Sphx 	.dev_ioctl		= zzax_dev_ioctl,
148*8d9149a7Sphx 	.get_locks		= zzax_get_locks
149*8d9149a7Sphx };
150*8d9149a7Sphx 
151*8d9149a7Sphx static const struct audio_format zzax_format = {
152*8d9149a7Sphx 	.mode		= AUMODE_PLAY,
153*8d9149a7Sphx 	.encoding	= AUDIO_ENCODING_SLINEAR_BE,
154*8d9149a7Sphx 	.validbits	= 16,
155*8d9149a7Sphx 	.precision	= 16,
156*8d9149a7Sphx 	.channels	= 2,
157*8d9149a7Sphx 	.channel_mask	= AUFMT_STEREO,
158*8d9149a7Sphx 	.frequency_type	= 0,
159*8d9149a7Sphx 	.frequency	= {8000, 12000, 24000, 32000, 44100, 48000},
160*8d9149a7Sphx 	.priority	= 0
161*8d9149a7Sphx };
162*8d9149a7Sphx 
163*8d9149a7Sphx static const struct audio_device zzax_device = {
164*8d9149a7Sphx 	.name		= "ZZ9000AX",
165*8d9149a7Sphx 	.version	= "1.13",
166*8d9149a7Sphx 	.config		= "zzax"
167*8d9149a7Sphx };
168*8d9149a7Sphx 
169*8d9149a7Sphx /* mixer sets */
170*8d9149a7Sphx #define ZZAX_CHANNELS 0
171*8d9149a7Sphx 
172*8d9149a7Sphx /* mixer values */
173*8d9149a7Sphx #define ZZAX_VOLUME 1
174*8d9149a7Sphx #define ZZAX_OUTPUT_CLASS 2
175*8d9149a7Sphx 
176*8d9149a7Sphx 
177*8d9149a7Sphx /* driver(9) essentials */
178*8d9149a7Sphx static int zzax_match(device_t parent, cfdata_t match, void *aux);
179*8d9149a7Sphx static void zzax_attach(device_t parent, device_t self, void *aux);
180*8d9149a7Sphx CFATTACH_DECL_NEW(zz9k_ax, sizeof(struct zzax_softc),
181*8d9149a7Sphx     zzax_match, zzax_attach, NULL, NULL);
182*8d9149a7Sphx 
183*8d9149a7Sphx 
184*8d9149a7Sphx /* Go ahead, make my day. */
185*8d9149a7Sphx 
186*8d9149a7Sphx static int
zzax_match(device_t parent,cfdata_t match,void * aux)187*8d9149a7Sphx zzax_match(device_t parent, cfdata_t match, void *aux)
188*8d9149a7Sphx {
189*8d9149a7Sphx 	struct zz9kbus_attach_args *bap = aux;
190*8d9149a7Sphx 
191*8d9149a7Sphx 	if (strcmp(bap->zzaa_name, "zz9k_ax") != 0)
192*8d9149a7Sphx 		return 0;
193*8d9149a7Sphx 
194*8d9149a7Sphx 	return 1;
195*8d9149a7Sphx }
196*8d9149a7Sphx 
197*8d9149a7Sphx static void
zzax_attach(device_t parent,device_t self,void * aux)198*8d9149a7Sphx zzax_attach(device_t parent, device_t self, void *aux)
199*8d9149a7Sphx {
200*8d9149a7Sphx 	struct zz9kbus_attach_args *bap = aux;
201*8d9149a7Sphx 	struct zzax_softc *sc = device_private(self);
202*8d9149a7Sphx 	struct zz9k_softc *psc = device_private(parent);
203*8d9149a7Sphx 
204*8d9149a7Sphx 	sc->sc_dev = self;
205*8d9149a7Sphx 	sc->sc_bst.base = bap->zzaa_base;
206*8d9149a7Sphx 	sc->sc_bst.absm = &amiga_bus_stride_1;
207*8d9149a7Sphx 	sc->sc_iot = &sc->sc_bst;
208*8d9149a7Sphx 	sc->sc_regh = psc->sc_regh;
209*8d9149a7Sphx 
210*8d9149a7Sphx 	uint16_t config = ZZREG_R(ZZ9K_AUDIO_CONFIG);
211*8d9149a7Sphx 	aprint_normal(": ZZ9000AX %sdetected.\n",
212*8d9149a7Sphx 	    (config == 0) ? "not " : "");
213*8d9149a7Sphx 	aprint_normal_dev(sc->sc_dev,
214*8d9149a7Sphx 	    "MNT ZZ9000AX driver is not functional yet.\n");
215*8d9149a7Sphx 
216*8d9149a7Sphx 	aprint_debug_dev(sc->sc_dev, "[DEBUG] registers at %p/%p (pa/va)\n",
217*8d9149a7Sphx 	    (void *)kvtop((void *)sc->sc_regh),
218*8d9149a7Sphx 	    bus_space_vaddr(sc->sc_iot, sc->sc_regh));
219*8d9149a7Sphx 
220*8d9149a7Sphx 	sc->sc_txbufsize = 0x10000;
221*8d9149a7Sphx 	uint32_t tx_buffer = psc->sc_zsize - sc->sc_txbufsize;
222*8d9149a7Sphx 	if (bus_space_map(sc->sc_iot, tx_buffer, sc->sc_txbufsize,
223*8d9149a7Sphx 	    BUS_SPACE_MAP_LINEAR, &sc->sc_txbufh)) {
224*8d9149a7Sphx 		aprint_error(": Failed to map MNT ZZ9000AX audio tx buffer.\n");
225*8d9149a7Sphx 		return;
226*8d9149a7Sphx 	}
227*8d9149a7Sphx 
228*8d9149a7Sphx 	aprint_normal_dev(sc->sc_dev, "base: %p/%p size: %i\n",
229*8d9149a7Sphx 	    (void *)kvtop((void *)sc->sc_txbufh),
230*8d9149a7Sphx 	    bus_space_vaddr(sc->sc_iot, sc->sc_txbufh),
231*8d9149a7Sphx 	    sc->sc_txbufsize);
232*8d9149a7Sphx 
233*8d9149a7Sphx 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
234*8d9149a7Sphx 	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
235*8d9149a7Sphx 
236*8d9149a7Sphx 	sc->sc_isr.isr_intr = zzax_intr;
237*8d9149a7Sphx 	sc->sc_isr.isr_arg  = sc;
238*8d9149a7Sphx 	sc->sc_isr.isr_ipl  = 6;
239*8d9149a7Sphx 	add_isr(&sc->sc_isr);
240*8d9149a7Sphx 
241*8d9149a7Sphx 	audio_attach_mi(&zzax_hw_if, sc, self);
242*8d9149a7Sphx 
243*8d9149a7Sphx 	uint16_t conf = ZZREG_R(ZZ9K_AUDIO_CONFIG); /* enable interrupt */
244*8d9149a7Sphx 	ZZREG_W(ZZ9K_AUDIO_CONFIG, conf | ZZ9K_AUDIO_CONFIG_INT_AUDIO);
245*8d9149a7Sphx }
246*8d9149a7Sphx 
247*8d9149a7Sphx static int
zzax_intr(void * arg)248*8d9149a7Sphx zzax_intr(void *arg)
249*8d9149a7Sphx {
250*8d9149a7Sphx 	struct zzax_softc *sc = arg;
251*8d9149a7Sphx 
252*8d9149a7Sphx 	uint16_t conf = ZZREG_R(ZZ9K_CONFIG);
253*8d9149a7Sphx 	if ((conf & ZZ9K_CONFIG_INT_AUDIO) == 0)
254*8d9149a7Sphx 		return 0;
255*8d9149a7Sphx 
256*8d9149a7Sphx #if 0
257*8d9149a7Sphx 	uint16_t conf = ZZREG_R(ZZ9K_AUDIO_CONFIG); /* disable interrupt */
258*8d9149a7Sphx 	ZZREG_W(ZZ9K_AUDIO_CONFIG, conf & ~ZZ9K_AUDIO_CONFIG_INT_AUDIO);
259*8d9149a7Sphx #endif
260*8d9149a7Sphx 	ZZREG_W(ZZ9K_CONFIG, ZZ9K_CONFIG_INT_ACK | ZZ9K_CONFIG_INT_ACK_AUDIO);
261*8d9149a7Sphx 
262*8d9149a7Sphx 	mutex_spin_enter(&sc->sc_intr_lock);
263*8d9149a7Sphx 	/* do stuff */
264*8d9149a7Sphx 	mutex_spin_exit(&sc->sc_intr_lock);
265*8d9149a7Sphx 
266*8d9149a7Sphx #if 0
267*8d9149a7Sphx 	uint16_t conf = ZZREG_R(ZZ9K_AUDIO_CONFIG); /* enable interrupt */
268*8d9149a7Sphx 	ZZREG_W(ZZ9K_AUDIO_CONFIG, conf | ZZ9K_AUDIO_CONFIG_INT_AUDIO);
269*8d9149a7Sphx #endif
270*8d9149a7Sphx 
271*8d9149a7Sphx 	return 1;
272*8d9149a7Sphx }
273*8d9149a7Sphx 
274*8d9149a7Sphx static void
zzax_set_param(struct zzax_softc * sc,uint16_t param,uint16_t val)275*8d9149a7Sphx zzax_set_param(struct zzax_softc *sc, uint16_t param, uint16_t val)
276*8d9149a7Sphx {
277*8d9149a7Sphx 	ZZREG_W(ZZ9K_AUDIO_PARAM, param);
278*8d9149a7Sphx 	ZZREG_W(ZZ9K_AUDIO_VAL, val);
279*8d9149a7Sphx 	ZZREG_W(ZZ9K_AUDIO_PARAM, 0);
280*8d9149a7Sphx }
281*8d9149a7Sphx 
282*8d9149a7Sphx int
zzax_open(void * hdl,int flags)283*8d9149a7Sphx zzax_open(void *hdl, int flags)
284*8d9149a7Sphx {
285*8d9149a7Sphx 	struct zzax_softc *sc = hdl;
286*8d9149a7Sphx 	uint32_t buffer = (uint32_t)bus_space_vaddr(sc->sc_iot, sc->sc_txbufh);
287*8d9149a7Sphx 	zzax_set_param(sc, ZZ9K_AP_TX_BUF_OFFS_HI, buffer >> 16);
288*8d9149a7Sphx 	zzax_set_param(sc, ZZ9K_AP_TX_BUF_OFFS_HI, buffer & 0xFFFF);
289*8d9149a7Sphx 	printf("zzax_open: %X\n", buffer);
290*8d9149a7Sphx 	return 0;
291*8d9149a7Sphx }
292*8d9149a7Sphx 
293*8d9149a7Sphx static void
zzax_close(void * hdl)294*8d9149a7Sphx zzax_close(void *hdl)
295*8d9149a7Sphx {
296*8d9149a7Sphx 	printf("zzax_close:\n");
297*8d9149a7Sphx }
298*8d9149a7Sphx 
299*8d9149a7Sphx static int
zzax_query_format(void * hdl,audio_format_query_t * afp)300*8d9149a7Sphx zzax_query_format(void *hdl, audio_format_query_t *afp)
301*8d9149a7Sphx {
302*8d9149a7Sphx 	printf("zzax_query_format:\n");
303*8d9149a7Sphx 	return audio_query_format(&zzax_format, 1, afp);
304*8d9149a7Sphx }
305*8d9149a7Sphx 
306*8d9149a7Sphx static int
zzax_set_format(void * hdl,int setmode,const audio_params_t * play,const audio_params_t * rec,audio_filter_reg_t * pfil,audio_filter_reg_t * rfil)307*8d9149a7Sphx zzax_set_format(void *hdl, int setmode,
308*8d9149a7Sphx     const audio_params_t *play, const audio_params_t *rec,
309*8d9149a7Sphx     audio_filter_reg_t *pfil, audio_filter_reg_t *rfil)
310*8d9149a7Sphx {
311*8d9149a7Sphx 	struct zzax_softc *sc = hdl;
312*8d9149a7Sphx 
313*8d9149a7Sphx 	printf("zzax_set_format:\n");
314*8d9149a7Sphx 	if (setmode & AUMODE_PLAY) {
315*8d9149a7Sphx 		zzax_set_param(sc, ZZ9K_AP_DSP_SET_LOWPASS, 23900);
316*8d9149a7Sphx 		printf("::play->sample_rate: %i\n", play->sample_rate);
317*8d9149a7Sphx 		printf("::play->encoding: %i\n", play->encoding);
318*8d9149a7Sphx 		printf("::play->precision: %i\n", play->precision);
319*8d9149a7Sphx 		printf("::play->validbits: %i\n", play->validbits);
320*8d9149a7Sphx 		printf("::play->channels: %i\n", play->channels);
321*8d9149a7Sphx 	}
322*8d9149a7Sphx 
323*8d9149a7Sphx 	if (setmode & AUMODE_RECORD) {
324*8d9149a7Sphx 		printf("::rec->sample_rate: %i\n", rec->sample_rate);
325*8d9149a7Sphx 		printf("::rec->encoding: %i\n", rec->encoding);
326*8d9149a7Sphx 		printf("::rec->precision: %i\n", rec->precision);
327*8d9149a7Sphx 		printf("::rec->validbits: %i\n", rec->validbits);
328*8d9149a7Sphx 		printf("::rec->channels: %i\n", rec->channels);
329*8d9149a7Sphx 	}
330*8d9149a7Sphx 
331*8d9149a7Sphx 	return 0;
332*8d9149a7Sphx }
333*8d9149a7Sphx 
334*8d9149a7Sphx static int
zzax_round_blocksize(void * hdl,int bs,int mode,const audio_params_t * param)335*8d9149a7Sphx zzax_round_blocksize(void *hdl, int bs, int mode, const audio_params_t *param)
336*8d9149a7Sphx {
337*8d9149a7Sphx 	printf("zzax_round_blocksize:\n");
338*8d9149a7Sphx 	printf("::bs: %i\n", bs);
339*8d9149a7Sphx 	printf("::mode: %i\n", mode);
340*8d9149a7Sphx 	printf("::param->sample_rate: %i\n", param->sample_rate);
341*8d9149a7Sphx 	printf("::param->encoding: %i\n", param->encoding);
342*8d9149a7Sphx 	printf("::param->precision: %i\n", param->precision);
343*8d9149a7Sphx 	printf("::param->validbits: %i\n", param->validbits);
344*8d9149a7Sphx 	printf("::param->channels: %i\n", param->channels);
345*8d9149a7Sphx 
346*8d9149a7Sphx 	return bs;
347*8d9149a7Sphx }
348*8d9149a7Sphx 
349*8d9149a7Sphx static int
zzax_commit_settings(void * hdl)350*8d9149a7Sphx zzax_commit_settings(void *hdl)
351*8d9149a7Sphx {
352*8d9149a7Sphx 	printf("zzax_commit_settings:\n");
353*8d9149a7Sphx 	return 0;
354*8d9149a7Sphx }
355*8d9149a7Sphx 
356*8d9149a7Sphx static int
zzax_init_output(void * hdl,void * buffer,int size)357*8d9149a7Sphx zzax_init_output(void *hdl, void *buffer, int size)
358*8d9149a7Sphx {
359*8d9149a7Sphx 	printf("zzax_init_output:\n");
360*8d9149a7Sphx 	return 0;
361*8d9149a7Sphx }
362*8d9149a7Sphx 
363*8d9149a7Sphx static int
zzax_init_input(void * hdl,void * buffer,int size)364*8d9149a7Sphx zzax_init_input(void *hdl, void *buffer, int size)
365*8d9149a7Sphx {
366*8d9149a7Sphx 	printf("zzax_init_input:\n");
367*8d9149a7Sphx 	return 0;
368*8d9149a7Sphx }
369*8d9149a7Sphx 
370*8d9149a7Sphx static int
zzax_start_output(void * hdl,void * block,int blksize,void (* intr)(void *),void * intrarg)371*8d9149a7Sphx zzax_start_output(void *hdl, void *block, int blksize,
372*8d9149a7Sphx     void (*intr)(void*), void *intrarg)
373*8d9149a7Sphx {
374*8d9149a7Sphx 	printf("zzax_start_output:\n");
375*8d9149a7Sphx 	return 0;
376*8d9149a7Sphx }
377*8d9149a7Sphx 
378*8d9149a7Sphx static int
zzax_start_input(void * hdl,void * block,int blksize,void (* intr)(void *),void * intrarg)379*8d9149a7Sphx zzax_start_input(void *hdl, void *block, int blksize,
380*8d9149a7Sphx     void (*intr)(void*), void *intrarg)
381*8d9149a7Sphx {
382*8d9149a7Sphx 	printf("zzax_start_input:\n");
383*8d9149a7Sphx 	return ENXIO;
384*8d9149a7Sphx }
385*8d9149a7Sphx 
386*8d9149a7Sphx static int
zzax_halt_output(void * hdl)387*8d9149a7Sphx zzax_halt_output(void *hdl)
388*8d9149a7Sphx {
389*8d9149a7Sphx 	printf("zzax_halt_output:\n");
390*8d9149a7Sphx 	return 0;
391*8d9149a7Sphx }
392*8d9149a7Sphx 
393*8d9149a7Sphx static int
zzax_halt_input(void * hdl)394*8d9149a7Sphx zzax_halt_input(void *hdl)
395*8d9149a7Sphx {
396*8d9149a7Sphx 	printf("zzax_halt_input:\n");
397*8d9149a7Sphx 	return ENXIO;
398*8d9149a7Sphx }
399*8d9149a7Sphx 
400*8d9149a7Sphx static int
zzax_speaker_ctl(void * hdl,int on)401*8d9149a7Sphx zzax_speaker_ctl(void *hdl, int on)
402*8d9149a7Sphx {
403*8d9149a7Sphx 	printf("zzax_speaker_ctl:\n");
404*8d9149a7Sphx 	return 0;
405*8d9149a7Sphx }
406*8d9149a7Sphx 
407*8d9149a7Sphx static int
zzax_getdev(void * hdl,struct audio_device * ret)408*8d9149a7Sphx zzax_getdev(void *hdl, struct audio_device *ret)
409*8d9149a7Sphx {
410*8d9149a7Sphx 	*ret = zzax_device;
411*8d9149a7Sphx 	printf("zzax_getdev: %p\n", ret);
412*8d9149a7Sphx 	return 0;
413*8d9149a7Sphx }
414*8d9149a7Sphx 
415*8d9149a7Sphx static int
zzax_set_port(void * hdl,mixer_ctrl_t * mc)416*8d9149a7Sphx zzax_set_port(void *hdl, mixer_ctrl_t *mc)
417*8d9149a7Sphx {
418*8d9149a7Sphx 	printf("zzax_set_port:\n");
419*8d9149a7Sphx 	return 0;
420*8d9149a7Sphx }
421*8d9149a7Sphx 
422*8d9149a7Sphx static int
zzax_get_port(void * hdl,mixer_ctrl_t * mc)423*8d9149a7Sphx zzax_get_port(void *hdl, mixer_ctrl_t *mc)
424*8d9149a7Sphx {
425*8d9149a7Sphx 	printf("zzax_get_port:\n");
426*8d9149a7Sphx 	return 0;
427*8d9149a7Sphx }
428*8d9149a7Sphx 
429*8d9149a7Sphx static int
zzax_query_devinfo(void * hdl,mixer_devinfo_t * di)430*8d9149a7Sphx zzax_query_devinfo(void *hdl, mixer_devinfo_t *di)
431*8d9149a7Sphx {
432*8d9149a7Sphx 	switch(di->index) {
433*8d9149a7Sphx 	case ZZAX_CHANNELS:
434*8d9149a7Sphx 		strcpy(di->label.name, "speaker");
435*8d9149a7Sphx 		di->type = AUDIO_MIXER_SET;
436*8d9149a7Sphx 		di->mixer_class = ZZAX_OUTPUT_CLASS;
437*8d9149a7Sphx 		di->prev = AUDIO_MIXER_LAST;
438*8d9149a7Sphx 		di->next = AUDIO_MIXER_LAST;
439*8d9149a7Sphx 		di->un.s.num_mem = 1;
440*8d9149a7Sphx 		strcpy(di->un.s.member[0].label.name, "channel0");
441*8d9149a7Sphx 		di->un.s.member[0].mask = 0;
442*8d9149a7Sphx 	case ZZAX_VOLUME:
443*8d9149a7Sphx 		strcpy(di->label.name, "master");
444*8d9149a7Sphx 		di->type = AUDIO_MIXER_VALUE;
445*8d9149a7Sphx 		di->mixer_class = ZZAX_OUTPUT_CLASS;
446*8d9149a7Sphx 		di->prev = AUDIO_MIXER_LAST;
447*8d9149a7Sphx 		di->next = AUDIO_MIXER_LAST;
448*8d9149a7Sphx 		di->un.v.num_channels = 1;
449*8d9149a7Sphx 		strcpy(di->un.v.units.name, "volume");
450*8d9149a7Sphx 		break;
451*8d9149a7Sphx 	case ZZAX_OUTPUT_CLASS:
452*8d9149a7Sphx 		strcpy(di->label.name, "outputs");
453*8d9149a7Sphx 		di->type = AUDIO_MIXER_CLASS;
454*8d9149a7Sphx 		di->mixer_class = ZZAX_OUTPUT_CLASS;
455*8d9149a7Sphx 		di->prev = AUDIO_MIXER_LAST;
456*8d9149a7Sphx 		di->next = AUDIO_MIXER_LAST;
457*8d9149a7Sphx 		break;
458*8d9149a7Sphx 	default:
459*8d9149a7Sphx 		return ENXIO;
460*8d9149a7Sphx 	}
461*8d9149a7Sphx 
462*8d9149a7Sphx 	printf("zzax_query_devinfo: %s\n", di->label.name);
463*8d9149a7Sphx 
464*8d9149a7Sphx 	return 0;
465*8d9149a7Sphx }
466*8d9149a7Sphx 
467*8d9149a7Sphx #if 0
468*8d9149a7Sphx static void*
469*8d9149a7Sphx zzax_allocm(void *hdl, int direction, size_t size)
470*8d9149a7Sphx {
471*8d9149a7Sphx 
472*8d9149a7Sphx }
473*8d9149a7Sphx 
474*8d9149a7Sphx static void
475*8d9149a7Sphx zzax_freem(void *hdl, void *addr, size_t size)
476*8d9149a7Sphx {
477*8d9149a7Sphx 
478*8d9149a7Sphx }
479*8d9149a7Sphx #endif
480*8d9149a7Sphx 
481*8d9149a7Sphx static size_t
zzax_round_buffersize(void * hdl,int direction,size_t bufsize)482*8d9149a7Sphx zzax_round_buffersize(void *hdl, int direction, size_t bufsize)
483*8d9149a7Sphx {
484*8d9149a7Sphx 	printf("zzax_round_buffersize:\n");
485*8d9149a7Sphx 	printf("::direction: %i\n", direction);
486*8d9149a7Sphx 	printf("::bufsize: %zu\n", bufsize);
487*8d9149a7Sphx 	return bufsize;
488*8d9149a7Sphx }
489*8d9149a7Sphx 
490*8d9149a7Sphx static int
zzax_get_props(void * hdl)491*8d9149a7Sphx zzax_get_props(void *hdl)
492*8d9149a7Sphx {
493*8d9149a7Sphx 	return AUDIO_PROP_PLAYBACK;
494*8d9149a7Sphx }
495*8d9149a7Sphx 
496*8d9149a7Sphx static int
zzax_trigger_output(void * hdl,void * start,void * end,int blksize,void (* intr)(void *),void * intrarg,const audio_params_t * param)497*8d9149a7Sphx zzax_trigger_output(void *hdl, void *start, void *end, int blksize,
498*8d9149a7Sphx     void (*intr)(void*), void *intrarg, const audio_params_t *param)
499*8d9149a7Sphx {
500*8d9149a7Sphx 	printf("zzax_trigger_output:\n");
501*8d9149a7Sphx 	return 0;
502*8d9149a7Sphx }
503*8d9149a7Sphx 
504*8d9149a7Sphx static int
zzax_trigger_input(void * hdl,void * start,void * end,int blksize,void (* intr)(void *),void * intrarg,const audio_params_t * param)505*8d9149a7Sphx zzax_trigger_input(void *hdl, void *start, void *end, int blksize,
506*8d9149a7Sphx     void (*intr)(void*), void *intrarg, const audio_params_t *param)
507*8d9149a7Sphx {
508*8d9149a7Sphx 	return 0;
509*8d9149a7Sphx }
510*8d9149a7Sphx 
511*8d9149a7Sphx static int
zzax_dev_ioctl(void * hdl,u_long cmd,void * addr,int flag,struct lwp * l)512*8d9149a7Sphx zzax_dev_ioctl(void *hdl, u_long cmd, void *addr, int flag, struct lwp *l)
513*8d9149a7Sphx {
514*8d9149a7Sphx 	printf("zzax_dev_ioctl: %lu\n", cmd);
515*8d9149a7Sphx 	return 0;
516*8d9149a7Sphx }
517*8d9149a7Sphx 
518*8d9149a7Sphx static void
zzax_get_locks(void * hdl,kmutex_t ** intr,kmutex_t ** thread)519*8d9149a7Sphx zzax_get_locks(void *hdl, kmutex_t **intr, kmutex_t **thread)
520*8d9149a7Sphx {
521*8d9149a7Sphx 	struct zzax_softc *sc = hdl;
522*8d9149a7Sphx 	*intr = &sc->sc_intr_lock;
523*8d9149a7Sphx 	*thread = &sc->sc_lock;
524*8d9149a7Sphx }
525