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