Home | History | Annotate | Line # | Download | only in mace
      1  1.14     isaki /* $NetBSD: mavb.c,v 1.14 2019/06/07 13:24:21 isaki Exp $ */
      2   1.1  jmcneill /* $OpenBSD: mavb.c,v 1.6 2005/04/15 13:05:14 mickey Exp $ */
      3   1.1  jmcneill 
      4   1.1  jmcneill /*
      5   1.1  jmcneill  * Copyright (c) 2005 Mark Kettenis
      6   1.1  jmcneill  *
      7   1.1  jmcneill  * Permission to use, copy, modify, and distribute this software for any
      8   1.1  jmcneill  * purpose with or without fee is hereby granted, provided that the above
      9   1.1  jmcneill  * copyright notice and this permission notice appear in all copies.
     10   1.1  jmcneill  *
     11   1.1  jmcneill  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     12   1.1  jmcneill  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     13   1.1  jmcneill  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     14   1.1  jmcneill  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     15   1.1  jmcneill  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     16   1.1  jmcneill  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     17   1.1  jmcneill  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     18   1.1  jmcneill  */
     19   1.1  jmcneill 
     20   1.1  jmcneill #include <sys/param.h>
     21   1.1  jmcneill #include <sys/systm.h>
     22   1.1  jmcneill #include <sys/device.h>
     23   1.1  jmcneill #include <sys/kernel.h>
     24   1.8  jmcneill #include <sys/kmem.h>
     25   1.1  jmcneill #include <sys/callout.h>
     26   1.1  jmcneill 
     27   1.7    dyoung #include <sys/bus.h>
     28   1.1  jmcneill #include <machine/intr.h>
     29   1.1  jmcneill #include <machine/autoconf.h>
     30   1.1  jmcneill 
     31   1.1  jmcneill #include <sys/audioio.h>
     32  1.13     isaki #include <dev/audio/audio_if.h>
     33   1.1  jmcneill 
     34   1.1  jmcneill #include <arch/sgimips/mace/macevar.h>
     35   1.1  jmcneill #include <arch/sgimips/mace/macereg.h>
     36   1.1  jmcneill #include <arch/sgimips/mace/mavbreg.h>
     37   1.1  jmcneill 
     38   1.1  jmcneill #include <dev/ic/ad1843reg.h>
     39   1.1  jmcneill 
     40   1.1  jmcneill #undef MAVB_DEBUG
     41   1.1  jmcneill 
     42   1.1  jmcneill #ifdef MAVB_DEBUG
     43   1.1  jmcneill #define DPRINTF(l,x)	do { if (mavb_debug & (l)) printf x; } while (0)
     44   1.1  jmcneill #define MAVB_DEBUG_INTR		0x0100
     45   1.1  jmcneill int mavb_debug = ~MAVB_DEBUG_INTR;
     46   1.1  jmcneill #else
     47   1.1  jmcneill #define DPRINTF(l,x)	/* nothing */
     48   1.1  jmcneill #endif
     49   1.1  jmcneill 
     50   1.1  jmcneill /* Repeat delays for volume buttons.  */
     51   1.1  jmcneill #define MAVB_VOLUME_BUTTON_REPEAT_DEL1	400	/* 400ms to start repeating */
     52   1.1  jmcneill #define MAVB_VOLUME_BUTTON_REPEAT_DELN  100	/* 100ms between repeats */
     53   1.1  jmcneill 
     54   1.1  jmcneill /* XXX We need access to some of the MACE ISA registers.  */
     55   1.1  jmcneill #define MAVB_ISA_NREGS				0x20
     56   1.1  jmcneill 
     57   1.1  jmcneill /*
     58   1.1  jmcneill  * AD1843 Mixer.
     59   1.1  jmcneill  */
     60   1.1  jmcneill 
     61   1.1  jmcneill enum {
     62   1.1  jmcneill 	AD1843_RECORD_CLASS,
     63   1.1  jmcneill 	AD1843_ADC_SOURCE,	/* ADC Source Select */
     64   1.1  jmcneill 	AD1843_ADC_GAIN,	/* ADC Input Gain */
     65   1.1  jmcneill 
     66   1.1  jmcneill 	AD1843_INPUT_CLASS,
     67   1.1  jmcneill 	AD1843_DAC1_GAIN,	/* DAC1 Analog/Digital Gain/Attenuation */
     68   1.1  jmcneill 	AD1843_DAC1_MUTE,	/* DAC1 Analog Mute */
     69   1.1  jmcneill 	AD1843_DAC2_GAIN,	/* DAC2 Mix Gain */
     70   1.1  jmcneill 	AD1843_AUX1_GAIN,	/* Auxilliary 1 Mix Gain */
     71   1.1  jmcneill 	AD1843_AUX2_GAIN,	/* Auxilliary 2 Mix Gain */
     72   1.1  jmcneill 	AD1843_AUX3_GAIN,	/* Auxilliary 3 Mix Gain */
     73   1.1  jmcneill 	AD1843_MIC_GAIN,	/* Microphone Mix Gain */
     74   1.1  jmcneill 	AD1843_MONO_GAIN,	/* Mono Mix Gain */
     75   1.1  jmcneill 	AD1843_DAC2_MUTE,	/* DAC2 Mix Mute */
     76   1.1  jmcneill 	AD1843_AUX1_MUTE,	/* Auxilliary 1 Mix Mute */
     77   1.1  jmcneill 	AD1843_AUX2_MUTE,	/* Auxilliary 2 Mix Mute */
     78   1.1  jmcneill 	AD1843_AUX3_MUTE,	/* Auxilliary 3 Mix Mute */
     79   1.1  jmcneill 	AD1843_MIC_MUTE,	/* Microphone Mix Mute */
     80   1.1  jmcneill 	AD1843_MONO_MUTE,	/* Mono Mix Mute */
     81   1.1  jmcneill 	AD1843_SUM_MUTE,	/* Sum Mute */
     82   1.1  jmcneill 
     83   1.1  jmcneill 	AD1843_OUTPUT_CLASS,
     84   1.1  jmcneill 	AD1843_MNO_MUTE,	/* Mono Output Mute */
     85   1.1  jmcneill 	AD1843_HPO_MUTE		/* Headphone Output Mute */
     86   1.1  jmcneill };
     87   1.1  jmcneill 
     88   1.1  jmcneill /* ADC Source Select.  The order matches the hardware bits.  */
     89   1.1  jmcneill const char *ad1843_source[] = {
     90   1.1  jmcneill 	AudioNline,
     91   1.1  jmcneill 	AudioNmicrophone,
     92   1.1  jmcneill 	AudioNaux "1",
     93   1.1  jmcneill 	AudioNaux "2",
     94   1.1  jmcneill 	AudioNaux "3",
     95   1.1  jmcneill 	AudioNmono,
     96   1.1  jmcneill 	AudioNdac "1",
     97   1.1  jmcneill 	AudioNdac "2"
     98   1.1  jmcneill };
     99   1.1  jmcneill 
    100   1.1  jmcneill /* Mix Control.  The order matches the hardware register numbering.  */
    101   1.1  jmcneill const char *ad1843_input[] = {
    102   1.1  jmcneill 	AudioNdac "2",		/* AD1843_DAC2__TO_MIXER */
    103   1.1  jmcneill 	AudioNaux "1",
    104   1.1  jmcneill 	AudioNaux "2",
    105   1.1  jmcneill 	AudioNaux "3",
    106   1.1  jmcneill 	AudioNmicrophone,
    107   1.1  jmcneill 	AudioNmono		/* AD1843_MISC_SETTINGS */
    108   1.1  jmcneill };
    109   1.1  jmcneill 
    110  1.13     isaki static const struct audio_format mavb_formats[] = {
    111  1.13     isaki 	{
    112  1.13     isaki 		.mode		= AUMODE_PLAY,
    113  1.13     isaki 		.encoding	= AUDIO_ENCODING_SLINEAR_BE,
    114  1.13     isaki 		.validbits	= 24,
    115  1.13     isaki 		.precision	= 32,
    116  1.13     isaki 		.channels	= 2,
    117  1.13     isaki 		.channel_mask	= AUFMT_STEREO,
    118  1.13     isaki 		.frequency_type	= 0,
    119  1.13     isaki 		.frequency	= { 8000, 48000 },
    120  1.13     isaki 	},
    121   1.5  jmcneill };
    122  1.13     isaki #define MAVB_NFORMATS __arraycount(mavb_formats)
    123   1.5  jmcneill 
    124   1.1  jmcneill struct mavb_softc {
    125   1.9       chs 	device_t sc_dev;
    126   1.8  jmcneill 	kmutex_t sc_lock;
    127   1.8  jmcneill 	kmutex_t sc_intr_lock;
    128   1.1  jmcneill 	bus_space_tag_t sc_st;
    129   1.1  jmcneill 	bus_space_handle_t sc_sh;
    130   1.1  jmcneill 	bus_dma_tag_t sc_dmat;
    131   1.1  jmcneill 	bus_dmamap_t sc_dmamap;
    132   1.1  jmcneill 
    133   1.1  jmcneill 	/* XXX We need access to some of the MACE ISA registers.  */
    134   1.1  jmcneill 	bus_space_handle_t sc_isash;
    135   1.1  jmcneill 
    136   1.1  jmcneill #define MAVB_ISA_RING_SIZE		0x1000
    137   1.1  jmcneill 	uint8_t *sc_ring;
    138   1.1  jmcneill 
    139   1.1  jmcneill 	uint8_t *sc_start, *sc_end;
    140   1.1  jmcneill 	int sc_blksize;
    141   1.1  jmcneill 	void (*sc_intr)(void *);
    142   1.1  jmcneill 	void *sc_intrarg;
    143   1.1  jmcneill 
    144   1.1  jmcneill 	void *sc_get;
    145   1.1  jmcneill 	int sc_count;
    146   1.1  jmcneill 
    147   1.1  jmcneill 	u_long sc_play_rate;
    148   1.1  jmcneill 	u_int sc_play_format;
    149   1.1  jmcneill 
    150   1.1  jmcneill 	struct callout sc_volume_button_ch;
    151   1.1  jmcneill };
    152   1.1  jmcneill 
    153   1.6   tsutsui typedef uint64_t ad1843_addr_t;
    154   1.1  jmcneill 
    155   1.6   tsutsui uint16_t ad1843_reg_read(struct mavb_softc *, ad1843_addr_t);
    156   1.6   tsutsui uint16_t ad1843_reg_write(struct mavb_softc *, ad1843_addr_t, uint16_t);
    157   1.1  jmcneill void ad1843_dump_regs(struct mavb_softc *);
    158   1.1  jmcneill 
    159   1.9       chs int mavb_match(device_t, cfdata_t, void *);
    160   1.9       chs void mavb_attach(device_t, device_t, void *);
    161   1.1  jmcneill 
    162   1.9       chs CFATTACH_DECL_NEW(mavb, sizeof(struct mavb_softc),
    163   1.1  jmcneill     mavb_match, mavb_attach, NULL, NULL);
    164  1.13     isaki 
    165  1.13     isaki int mavb_query_format(void *, audio_format_query_t *);
    166  1.13     isaki int mavb_set_format(void *, int,
    167  1.13     isaki 		    const audio_params_t *, const audio_params_t *,
    168  1.13     isaki 		    audio_filter_reg_t *, audio_filter_reg_t *);
    169   1.1  jmcneill int mavb_round_blocksize(void *hdl, int, int, const audio_params_t *);
    170   1.1  jmcneill int mavb_halt_output(void *);
    171   1.1  jmcneill int mavb_halt_input(void *);
    172   1.1  jmcneill int mavb_getdev(void *, struct audio_device *);
    173   1.1  jmcneill int mavb_set_port(void *, struct mixer_ctrl *);
    174   1.1  jmcneill int mavb_get_port(void *, struct mixer_ctrl *);
    175   1.1  jmcneill int mavb_query_devinfo(void *, struct mixer_devinfo *);
    176   1.1  jmcneill int mavb_get_props(void *);
    177   1.1  jmcneill int mavb_trigger_output(void *, void *, void *, int, void (*)(void *),
    178   1.1  jmcneill 			void *, const audio_params_t *);
    179   1.1  jmcneill int mavb_trigger_input(void *, void *, void *, int, void (*)(void *),
    180   1.1  jmcneill 		       void *, const audio_params_t *);
    181   1.8  jmcneill void mavb_get_locks(void *, kmutex_t **, kmutex_t **);
    182   1.1  jmcneill 
    183   1.1  jmcneill struct audio_hw_if mavb_sa_hw_if = {
    184  1.13     isaki 	.query_format		= mavb_query_format,
    185  1.13     isaki 	.set_format		= mavb_set_format,
    186  1.12     isaki 	.round_blocksize	= mavb_round_blocksize,
    187  1.12     isaki 	.halt_output		= mavb_halt_output,
    188  1.12     isaki 	.halt_input		= mavb_halt_input,
    189  1.12     isaki 	.getdev			= mavb_getdev,
    190  1.12     isaki 	.set_port		= mavb_set_port,
    191  1.12     isaki 	.get_port		= mavb_get_port,
    192  1.12     isaki 	.query_devinfo		= mavb_query_devinfo,
    193  1.12     isaki 	.get_props		= mavb_get_props,
    194  1.12     isaki 	.trigger_output		= mavb_trigger_output,
    195  1.12     isaki 	.trigger_input		= mavb_trigger_input,
    196  1.12     isaki 	.get_locks		= mavb_get_locks,
    197   1.1  jmcneill };
    198   1.1  jmcneill 
    199   1.1  jmcneill struct audio_device mavb_device = {
    200   1.1  jmcneill 	"A3",
    201   1.1  jmcneill 	"",
    202   1.1  jmcneill 	"mavb"
    203   1.1  jmcneill };
    204   1.1  jmcneill 
    205  1.13     isaki static void
    206  1.13     isaki mavb_internal_to_slinear24_32(audio_filter_arg_t *arg)
    207   1.1  jmcneill {
    208  1.13     isaki 	const aint_t *src;
    209  1.13     isaki 	uint32_t *dst;
    210  1.13     isaki 	u_int sample_count;
    211  1.13     isaki 	u_int i;
    212  1.13     isaki 
    213  1.13     isaki 	src = arg->src;
    214  1.13     isaki 	dst = arg->dst;
    215  1.13     isaki 	sample_count = arg->count * arg->srcfmt->channels;
    216  1.13     isaki 	for (i = 0; i < sample_count; i++) {
    217  1.13     isaki 		*dst++ = (*src++) << 8;
    218  1.13     isaki 	}
    219   1.1  jmcneill }
    220   1.1  jmcneill 
    221   1.1  jmcneill int
    222  1.13     isaki mavb_query_format(void *hdl, audio_format_query_t *afp)
    223   1.1  jmcneill {
    224   1.1  jmcneill 
    225  1.13     isaki 	return audio_query_format(mavb_formats, MAVB_NFORMATS, afp);
    226   1.1  jmcneill }
    227   1.1  jmcneill 
    228   1.1  jmcneill static int
    229   1.1  jmcneill mavb_set_play_rate(struct mavb_softc *sc, u_long sample_rate)
    230   1.1  jmcneill {
    231   1.6   tsutsui 
    232  1.13     isaki 	KASSERT((4000 <= sample_rate && sample_rate <= 48000));
    233   1.1  jmcneill 
    234   1.1  jmcneill 	if (sc->sc_play_rate != sample_rate) {
    235   1.1  jmcneill 		ad1843_reg_write(sc, AD1843_CLOCK2_SAMPLE_RATE, sample_rate);
    236   1.1  jmcneill 		sc->sc_play_rate = sample_rate;
    237   1.1  jmcneill 	}
    238   1.6   tsutsui 	return 0;
    239   1.1  jmcneill }
    240   1.1  jmcneill 
    241   1.1  jmcneill static int
    242   1.1  jmcneill mavb_set_play_format(struct mavb_softc *sc, u_int encoding)
    243   1.1  jmcneill {
    244   1.6   tsutsui 	uint16_t value;
    245   1.1  jmcneill 	u_int format;
    246   1.1  jmcneill 
    247   1.1  jmcneill 	switch(encoding) {
    248   1.1  jmcneill 	case AUDIO_ENCODING_SLINEAR_BE:
    249   1.1  jmcneill 		format = AD1843_PCM16;
    250   1.1  jmcneill 		break;
    251   1.1  jmcneill 	default:
    252   1.6   tsutsui 		return EINVAL;
    253   1.1  jmcneill 	}
    254   1.1  jmcneill 
    255   1.1  jmcneill 	if (sc->sc_play_format != format) {
    256   1.1  jmcneill 		value = ad1843_reg_read(sc, AD1843_SERIAL_INTERFACE);
    257   1.1  jmcneill 		value &= ~AD1843_DA1F_MASK;
    258   1.1  jmcneill 		value |= (format << AD1843_DA1F_SHIFT);
    259   1.1  jmcneill 		ad1843_reg_write(sc, AD1843_SERIAL_INTERFACE, value);
    260   1.1  jmcneill 		sc->sc_play_format = format;
    261   1.1  jmcneill 	}
    262   1.6   tsutsui 	return 0;
    263   1.1  jmcneill }
    264   1.1  jmcneill 
    265   1.1  jmcneill int
    266  1.13     isaki mavb_set_format(void *hdl, int setmode,
    267  1.13     isaki     const audio_params_t *play, const audio_params_t *rec,
    268  1.13     isaki     audio_filter_reg_t *pfil, audio_filter_reg_t *rfil)
    269   1.1  jmcneill {
    270   1.1  jmcneill 	struct mavb_softc *sc = (struct mavb_softc *)hdl;
    271   1.1  jmcneill 	int error;
    272   1.1  jmcneill 
    273  1.13     isaki 	DPRINTF(1, ("%s: %s: sample=%u precision=%d channels=%d\n",
    274  1.13     isaki 	    device_xname(sc->sc_dev), __func__,
    275  1.13     isaki 	    play->sample_rate, play->precision, play->channels));
    276   1.1  jmcneill 
    277   1.1  jmcneill 	if (setmode & AUMODE_PLAY) {
    278  1.13     isaki 		pfil->codec = mavb_internal_to_slinear24_32;
    279   1.1  jmcneill 
    280  1.13     isaki 		error = mavb_set_play_rate(sc, play->sample_rate);
    281   1.1  jmcneill 		if (error)
    282   1.6   tsutsui 			return error;
    283   1.1  jmcneill 
    284  1.13     isaki 		error = mavb_set_play_format(sc, play->encoding);
    285   1.1  jmcneill 		if (error)
    286   1.6   tsutsui 			return error;
    287   1.1  jmcneill 	}
    288   1.1  jmcneill 
    289   1.1  jmcneill #if 0
    290   1.1  jmcneill 	if (setmode & AUMODE_RECORD) {
    291   1.1  jmcneill 	}
    292   1.1  jmcneill #endif
    293   1.1  jmcneill 
    294   1.6   tsutsui 	return 0;
    295   1.1  jmcneill }
    296   1.1  jmcneill 
    297   1.1  jmcneill int
    298   1.1  jmcneill mavb_round_blocksize(void *hdl, int bs, int mode, const audio_params_t *p)
    299   1.1  jmcneill {
    300   1.6   tsutsui 
    301   1.1  jmcneill 	/* Block size should be a multiple of 32.  */
    302   1.1  jmcneill 	return (bs + 0x1f) & ~0x1f;
    303   1.1  jmcneill }
    304   1.1  jmcneill 
    305   1.1  jmcneill int
    306   1.1  jmcneill mavb_halt_output(void *hdl)
    307   1.1  jmcneill {
    308   1.1  jmcneill 	struct mavb_softc *sc = (struct mavb_softc *)hdl;
    309   1.1  jmcneill 
    310   1.9       chs 	DPRINTF(1, ("%s: mavb_halt_output called\n", device_xname(sc->sc_dev)));
    311   1.1  jmcneill 
    312   1.1  jmcneill 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL, 0);
    313   1.6   tsutsui 	return 0;
    314   1.1  jmcneill }
    315   1.1  jmcneill 
    316   1.1  jmcneill int
    317   1.1  jmcneill mavb_halt_input(void *hdl)
    318   1.1  jmcneill {
    319   1.6   tsutsui 
    320   1.6   tsutsui 	return 0;
    321   1.1  jmcneill }
    322   1.1  jmcneill 
    323   1.1  jmcneill int
    324   1.1  jmcneill mavb_getdev(void *hdl, struct audio_device *ret)
    325   1.1  jmcneill {
    326   1.6   tsutsui 
    327   1.1  jmcneill 	*ret = mavb_device;
    328   1.6   tsutsui 	return 0;
    329   1.1  jmcneill }
    330   1.1  jmcneill 
    331   1.1  jmcneill int
    332   1.1  jmcneill mavb_set_port(void *hdl, struct mixer_ctrl *mc)
    333   1.1  jmcneill {
    334   1.1  jmcneill 	struct mavb_softc *sc = (struct mavb_softc *)hdl;
    335   1.1  jmcneill 	u_char left, right;
    336   1.1  jmcneill 	ad1843_addr_t reg;
    337   1.6   tsutsui 	uint16_t value;
    338   1.1  jmcneill 
    339   1.9       chs 	DPRINTF(1, ("%s: mavb_set_port: dev=%d\n", device_xname(sc->sc_dev),
    340   1.1  jmcneill 	    mc->dev));
    341   1.1  jmcneill 
    342   1.1  jmcneill 	switch (mc->dev) {
    343   1.1  jmcneill 	case AD1843_ADC_SOURCE:
    344   1.1  jmcneill 		value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
    345   1.1  jmcneill 		value &= ~(AD1843_LSS_MASK | AD1843_RSS_MASK);
    346   1.1  jmcneill 		value |= ((mc->un.ord << AD1843_LSS_SHIFT) & AD1843_LSS_MASK);
    347   1.1  jmcneill 		value |= ((mc->un.ord << AD1843_RSS_SHIFT) & AD1843_RSS_MASK);
    348   1.1  jmcneill 		ad1843_reg_write(sc, AD1843_ADC_SOURCE_GAIN, value);
    349   1.1  jmcneill 		break;
    350   1.1  jmcneill 	case AD1843_ADC_GAIN:
    351   1.1  jmcneill 		left = mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
    352   1.1  jmcneill 		right = mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
    353   1.1  jmcneill 		value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
    354   1.1  jmcneill 		value &= ~(AD1843_LIG_MASK | AD1843_RIG_MASK);
    355   1.1  jmcneill 		value |= ((left >> 4) << AD1843_LIG_SHIFT);
    356   1.1  jmcneill 		value |= ((right >> 4) << AD1843_RIG_SHIFT);
    357   1.1  jmcneill 		ad1843_reg_write(sc, AD1843_ADC_SOURCE_GAIN, value);
    358   1.1  jmcneill 		break;
    359   1.1  jmcneill 
    360   1.1  jmcneill 	case AD1843_DAC1_GAIN:
    361   1.1  jmcneill 		left = AUDIO_MAX_GAIN -
    362   1.1  jmcneill 		    mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
    363   1.1  jmcneill 		right = AUDIO_MAX_GAIN -
    364   1.1  jmcneill                     mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
    365   1.1  jmcneill 		value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
    366   1.1  jmcneill 		value &= ~(AD1843_LDA1G_MASK | AD1843_RDA1G_MASK);
    367   1.1  jmcneill 		value |= ((left >> 2) << AD1843_LDA1G_SHIFT);
    368   1.1  jmcneill 		value |= ((right >> 2) << AD1843_RDA1G_SHIFT);
    369   1.1  jmcneill 		ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN, value);
    370   1.1  jmcneill 		break;
    371   1.1  jmcneill 	case AD1843_DAC1_MUTE:
    372   1.1  jmcneill 		value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
    373   1.1  jmcneill 		if (mc->un.ord == 0)
    374   1.1  jmcneill 			value &= ~(AD1843_LDA1GM | AD1843_RDA1GM);
    375   1.1  jmcneill 		else
    376   1.1  jmcneill 			value |= (AD1843_LDA1GM | AD1843_RDA1GM);
    377   1.1  jmcneill 		ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN, value);
    378   1.1  jmcneill 		break;
    379   1.1  jmcneill 
    380   1.1  jmcneill 	case AD1843_DAC2_GAIN:
    381   1.1  jmcneill 	case AD1843_AUX1_GAIN:
    382   1.1  jmcneill 	case AD1843_AUX2_GAIN:
    383   1.1  jmcneill 	case AD1843_AUX3_GAIN:
    384   1.1  jmcneill 	case AD1843_MIC_GAIN:
    385   1.1  jmcneill 		left = AUDIO_MAX_GAIN -
    386   1.1  jmcneill 		    mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
    387   1.1  jmcneill 		right = AUDIO_MAX_GAIN -
    388   1.1  jmcneill                     mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
    389   1.1  jmcneill 		reg = AD1843_DAC2_TO_MIXER + mc->dev - AD1843_DAC2_GAIN;
    390   1.1  jmcneill 		value = ad1843_reg_read(sc, reg);
    391   1.1  jmcneill 		value &= ~(AD1843_LD2M_MASK | AD1843_RD2M_MASK);
    392   1.1  jmcneill 		value |= ((left >> 3) << AD1843_LD2M_SHIFT);
    393   1.1  jmcneill 		value |= ((right >> 3) << AD1843_RD2M_SHIFT);
    394   1.1  jmcneill 		ad1843_reg_write(sc, reg, value);
    395   1.1  jmcneill 		break;
    396   1.1  jmcneill 	case AD1843_MONO_GAIN:
    397   1.1  jmcneill 		left = AUDIO_MAX_GAIN -
    398   1.1  jmcneill 		    mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
    399   1.1  jmcneill 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    400   1.1  jmcneill 		value &= ~AD1843_MNM_MASK;
    401   1.1  jmcneill 		value |= ((left >> 3) << AD1843_MNM_SHIFT);
    402   1.1  jmcneill 		ad1843_reg_write(sc, AD1843_MISC_SETTINGS, value);
    403   1.1  jmcneill 		break;
    404   1.1  jmcneill 	case AD1843_DAC2_MUTE:
    405   1.1  jmcneill 	case AD1843_AUX1_MUTE:
    406   1.1  jmcneill 	case AD1843_AUX2_MUTE:
    407   1.1  jmcneill 	case AD1843_AUX3_MUTE:
    408   1.1  jmcneill 	case AD1843_MIC_MUTE:
    409   1.1  jmcneill 	case AD1843_MONO_MUTE:	/* matches left channel */
    410   1.1  jmcneill 		reg = AD1843_DAC2_TO_MIXER + mc->dev - AD1843_DAC2_MUTE;
    411   1.1  jmcneill 		value = ad1843_reg_read(sc, reg);
    412   1.1  jmcneill 		if (mc->un.ord == 0)
    413   1.1  jmcneill 			value &= ~(AD1843_LD2MM | AD1843_RD2MM);
    414   1.1  jmcneill 		else
    415   1.1  jmcneill 			value |= (AD1843_LD2MM | AD1843_RD2MM);
    416   1.1  jmcneill 		ad1843_reg_write(sc, reg, value);
    417   1.1  jmcneill 		break;
    418   1.1  jmcneill 
    419   1.1  jmcneill 	case AD1843_SUM_MUTE:
    420   1.1  jmcneill 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    421   1.1  jmcneill 		if (mc->un.ord == 0)
    422   1.1  jmcneill 			value &= ~AD1843_SUMM;
    423   1.1  jmcneill 		else
    424   1.1  jmcneill 			value |= AD1843_SUMM;
    425   1.1  jmcneill 		ad1843_reg_write(sc, AD1843_MISC_SETTINGS, value);
    426   1.1  jmcneill 		break;
    427   1.1  jmcneill 
    428   1.1  jmcneill 	case AD1843_MNO_MUTE:
    429   1.1  jmcneill 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    430   1.1  jmcneill 		if (mc->un.ord == 0)
    431   1.1  jmcneill 			value &= ~AD1843_MNOM;
    432   1.1  jmcneill 		else
    433   1.1  jmcneill 			value |= AD1843_MNOM;
    434   1.1  jmcneill 		ad1843_reg_write(sc, AD1843_MISC_SETTINGS, value);
    435   1.1  jmcneill 		break;
    436   1.1  jmcneill 
    437   1.1  jmcneill 	case AD1843_HPO_MUTE:
    438   1.1  jmcneill 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    439   1.1  jmcneill 		if (mc->un.ord == 0)
    440   1.1  jmcneill 			value &= ~AD1843_HPOM;
    441   1.1  jmcneill 		else
    442   1.1  jmcneill 			value |= AD1843_HPOM;
    443   1.1  jmcneill 		ad1843_reg_write(sc, AD1843_MISC_SETTINGS, value);
    444   1.1  jmcneill 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    445   1.1  jmcneill 		break;
    446   1.1  jmcneill 
    447   1.1  jmcneill 	default:
    448   1.6   tsutsui 		return EINVAL;
    449   1.1  jmcneill 	}
    450   1.1  jmcneill 
    451   1.6   tsutsui 	return 0;
    452   1.1  jmcneill }
    453   1.1  jmcneill 
    454   1.1  jmcneill int
    455   1.1  jmcneill mavb_get_port(void *hdl, struct mixer_ctrl *mc)
    456   1.1  jmcneill {
    457   1.1  jmcneill 	struct mavb_softc *sc = (struct mavb_softc *)hdl;
    458   1.1  jmcneill 	u_char left, right;
    459   1.1  jmcneill 	ad1843_addr_t reg;
    460   1.6   tsutsui 	uint16_t value;
    461   1.1  jmcneill 
    462   1.9       chs 	DPRINTF(1, ("%s: mavb_get_port: dev=%d\n", device_xname(sc->sc_dev),
    463   1.1  jmcneill 	    mc->dev));
    464   1.1  jmcneill 
    465   1.1  jmcneill 	switch (mc->dev) {
    466   1.1  jmcneill 	case AD1843_ADC_SOURCE:
    467   1.1  jmcneill 		value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
    468   1.1  jmcneill 		mc->un.ord = (value & AD1843_LSS_MASK) >> AD1843_LSS_SHIFT;
    469   1.1  jmcneill 		break;
    470   1.1  jmcneill 	case AD1843_ADC_GAIN:
    471   1.1  jmcneill 		value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
    472   1.1  jmcneill 		left = (value & AD1843_LIG_MASK) >> AD1843_LIG_SHIFT;
    473   1.1  jmcneill 		right = (value & AD1843_RIG_MASK) >> AD1843_RIG_SHIFT;
    474   1.1  jmcneill 		mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
    475   1.1  jmcneill 		    (left << 4) | left;
    476   1.1  jmcneill 		mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
    477   1.1  jmcneill 		    (right << 2) | right;
    478   1.1  jmcneill 		break;
    479   1.1  jmcneill 
    480   1.1  jmcneill 	case AD1843_DAC1_GAIN:
    481   1.1  jmcneill 		value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
    482   1.1  jmcneill 		left = (value & AD1843_LDA1G_MASK) >> AD1843_LDA1G_SHIFT;
    483   1.1  jmcneill 		right = (value & AD1843_RDA1G_MASK) >> AD1843_RDA1G_SHIFT;
    484   1.1  jmcneill 		mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
    485   1.1  jmcneill 		    AUDIO_MAX_GAIN - (left << 2);
    486   1.1  jmcneill 		mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
    487   1.1  jmcneill 		    AUDIO_MAX_GAIN - (right << 2);
    488   1.1  jmcneill 		break;
    489   1.1  jmcneill 	case AD1843_DAC1_MUTE:
    490   1.1  jmcneill 		value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
    491   1.1  jmcneill 		mc->un.ord = (value & AD1843_LDA1GM) ? 1 : 0;
    492   1.1  jmcneill 		break;
    493   1.1  jmcneill 
    494   1.1  jmcneill 	case AD1843_DAC2_GAIN:
    495   1.1  jmcneill 	case AD1843_AUX1_GAIN:
    496   1.1  jmcneill 	case AD1843_AUX2_GAIN:
    497   1.1  jmcneill 	case AD1843_AUX3_GAIN:
    498   1.1  jmcneill 	case AD1843_MIC_GAIN:
    499   1.1  jmcneill 		reg = AD1843_DAC2_TO_MIXER + mc->dev - AD1843_DAC2_GAIN;
    500   1.1  jmcneill 		value = ad1843_reg_read(sc, reg);
    501   1.1  jmcneill 		left = (value & AD1843_LD2M_MASK) >> AD1843_LD2M_SHIFT;
    502   1.1  jmcneill 		right = (value & AD1843_RD2M_MASK) >> AD1843_RD2M_SHIFT;
    503   1.1  jmcneill 		mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
    504   1.1  jmcneill 		    AUDIO_MAX_GAIN - (left << 3);
    505   1.1  jmcneill 		mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
    506   1.1  jmcneill 		    AUDIO_MAX_GAIN - (right << 3);
    507   1.1  jmcneill 		break;
    508   1.1  jmcneill 	case AD1843_MONO_GAIN:
    509   1.1  jmcneill 		if (mc->un.value.num_channels != 1)
    510   1.6   tsutsui 			return EINVAL;
    511   1.1  jmcneill 
    512   1.1  jmcneill 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    513   1.1  jmcneill 		left = (value & AD1843_MNM_MASK) >> AD1843_MNM_SHIFT;
    514   1.1  jmcneill 		mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
    515   1.1  jmcneill 		    AUDIO_MAX_GAIN - (left << 3);
    516   1.1  jmcneill 		break;
    517   1.1  jmcneill 	case AD1843_DAC2_MUTE:
    518   1.1  jmcneill 	case AD1843_AUX1_MUTE:
    519   1.1  jmcneill 	case AD1843_AUX2_MUTE:
    520   1.1  jmcneill 	case AD1843_AUX3_MUTE:
    521   1.1  jmcneill 	case AD1843_MIC_MUTE:
    522   1.1  jmcneill 	case AD1843_MONO_MUTE:	/* matches left channel */
    523   1.1  jmcneill 		reg = AD1843_DAC2_TO_MIXER + mc->dev - AD1843_DAC2_MUTE;
    524   1.1  jmcneill 		value = ad1843_reg_read(sc, reg);
    525   1.1  jmcneill 		mc->un.ord = (value & AD1843_LD2MM) ? 1 : 0;
    526   1.1  jmcneill 		break;
    527   1.1  jmcneill 
    528   1.1  jmcneill 	case AD1843_SUM_MUTE:
    529   1.1  jmcneill 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    530   1.1  jmcneill 		mc->un.ord = (value & AD1843_SUMM) ? 1 : 0;
    531   1.1  jmcneill 		break;
    532   1.1  jmcneill 
    533   1.1  jmcneill 	case AD1843_MNO_MUTE:
    534   1.1  jmcneill 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    535   1.1  jmcneill 		mc->un.ord = (value & AD1843_MNOM) ? 1 : 0;
    536   1.1  jmcneill 		break;
    537   1.1  jmcneill 
    538   1.1  jmcneill 	case AD1843_HPO_MUTE:
    539   1.1  jmcneill 		value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
    540   1.1  jmcneill 		mc->un.ord = (value & AD1843_HPOM) ? 1 : 0;
    541   1.1  jmcneill 		break;
    542   1.1  jmcneill 
    543   1.1  jmcneill 	default:
    544   1.6   tsutsui 		return EINVAL;
    545   1.1  jmcneill 	}
    546   1.1  jmcneill 
    547   1.6   tsutsui 	return 0;
    548   1.1  jmcneill }
    549   1.1  jmcneill 
    550   1.1  jmcneill int
    551   1.1  jmcneill mavb_query_devinfo(void *hdl, struct mixer_devinfo *di)
    552   1.1  jmcneill {
    553   1.1  jmcneill 	int i;
    554   1.1  jmcneill 
    555   1.1  jmcneill 	di->prev = di->next = AUDIO_MIXER_LAST;
    556   1.1  jmcneill 
    557   1.1  jmcneill 	switch (di->index) {
    558   1.1  jmcneill 	case AD1843_RECORD_CLASS:
    559   1.1  jmcneill 		di->type = AUDIO_MIXER_CLASS;
    560   1.1  jmcneill 		di->mixer_class = AD1843_RECORD_CLASS;
    561   1.1  jmcneill 		strlcpy(di->label.name, AudioCrecord, sizeof di->label.name);
    562   1.1  jmcneill 		break;
    563   1.1  jmcneill 
    564   1.1  jmcneill 	case AD1843_ADC_SOURCE:
    565   1.1  jmcneill 		di->type = AUDIO_MIXER_ENUM;
    566   1.1  jmcneill 		di->mixer_class = AD1843_RECORD_CLASS;
    567   1.1  jmcneill 		di->next = AD1843_ADC_GAIN;
    568   1.1  jmcneill 		strlcpy(di->label.name, AudioNsource, sizeof di->label.name);
    569   1.1  jmcneill 		di->un.e.num_mem =
    570   1.1  jmcneill 			sizeof ad1843_source / sizeof ad1843_source[1];
    571   1.1  jmcneill 		for (i = 0; i < di->un.e.num_mem; i++) {
    572   1.1  jmcneill 			strlcpy(di->un.e.member[i].label.name,
    573   1.1  jmcneill                             ad1843_source[i],
    574   1.1  jmcneill 			    sizeof di->un.e.member[0].label.name);
    575   1.1  jmcneill 			di->un.e.member[i].ord = i;
    576   1.1  jmcneill 		}
    577   1.1  jmcneill 		break;
    578   1.1  jmcneill 	case AD1843_ADC_GAIN:
    579   1.1  jmcneill 		di->type = AUDIO_MIXER_VALUE;
    580   1.1  jmcneill 		di->mixer_class = AD1843_RECORD_CLASS;
    581   1.1  jmcneill 		di->prev = AD1843_ADC_SOURCE;
    582   1.1  jmcneill 		strlcpy(di->label.name, AudioNvolume, sizeof di->label.name);
    583   1.1  jmcneill 		di->un.v.num_channels = 2;
    584   1.1  jmcneill 		strlcpy(di->un.v.units.name, AudioNvolume,
    585   1.1  jmcneill 		    sizeof di->un.v.units.name);
    586   1.1  jmcneill 		break;
    587   1.1  jmcneill 
    588   1.1  jmcneill 	case AD1843_INPUT_CLASS:
    589   1.1  jmcneill 		di->type = AUDIO_MIXER_CLASS;
    590   1.1  jmcneill 		di->mixer_class = AD1843_INPUT_CLASS;
    591   1.1  jmcneill 		strlcpy(di->label.name, AudioCinputs, sizeof di->label.name);
    592   1.1  jmcneill 		break;
    593   1.1  jmcneill 
    594   1.1  jmcneill 	case AD1843_DAC1_GAIN:
    595   1.1  jmcneill 		di->type = AUDIO_MIXER_VALUE;
    596  1.10  macallan 		di->mixer_class = AD1843_OUTPUT_CLASS;
    597   1.1  jmcneill 		di->next = AD1843_DAC1_MUTE;
    598  1.10  macallan 		strlcpy(di->label.name, AudioNmaster, sizeof di->label.name);
    599   1.1  jmcneill 		di->un.v.num_channels = 2;
    600   1.1  jmcneill 		strlcpy(di->un.v.units.name, AudioNvolume,
    601   1.1  jmcneill 		    sizeof di->un.v.units.name);
    602   1.1  jmcneill 		break;
    603   1.1  jmcneill 	case AD1843_DAC1_MUTE:
    604   1.1  jmcneill 		di->type = AUDIO_MIXER_ENUM;
    605  1.10  macallan 		di->mixer_class = AD1843_OUTPUT_CLASS;
    606   1.1  jmcneill 		di->prev = AD1843_DAC1_GAIN;
    607   1.1  jmcneill 		strlcpy(di->label.name, AudioNmute, sizeof di->label.name);
    608   1.1  jmcneill 		di->un.e.num_mem = 2;
    609   1.1  jmcneill 		strlcpy(di->un.e.member[0].label.name, AudioNoff,
    610   1.1  jmcneill 		    sizeof di->un.e.member[0].label.name);
    611   1.1  jmcneill 		di->un.e.member[0].ord = 0;
    612   1.1  jmcneill 		strlcpy(di->un.e.member[1].label.name, AudioNon,
    613   1.1  jmcneill 		    sizeof di->un.e.member[1].label.name);
    614   1.1  jmcneill 		di->un.e.member[1].ord = 1;
    615   1.1  jmcneill 		break;
    616   1.1  jmcneill 
    617   1.1  jmcneill 	case AD1843_DAC2_GAIN:
    618   1.1  jmcneill 	case AD1843_AUX1_GAIN:
    619   1.1  jmcneill 	case AD1843_AUX2_GAIN:
    620   1.1  jmcneill 	case AD1843_AUX3_GAIN:
    621   1.1  jmcneill 	case AD1843_MIC_GAIN:
    622   1.1  jmcneill 	case AD1843_MONO_GAIN:
    623   1.1  jmcneill 		di->type = AUDIO_MIXER_VALUE;
    624   1.1  jmcneill 		di->mixer_class = AD1843_INPUT_CLASS;
    625   1.1  jmcneill 		di->next = di->index + AD1843_DAC2_MUTE - AD1843_DAC2_GAIN;
    626   1.1  jmcneill 		strlcpy(di->label.name,
    627   1.1  jmcneill                     ad1843_input[di->index - AD1843_DAC2_GAIN],
    628   1.1  jmcneill 		    sizeof di->label.name);
    629   1.1  jmcneill 		if (di->index == AD1843_MONO_GAIN)
    630   1.1  jmcneill 			di->un.v.num_channels = 1;
    631   1.1  jmcneill 		else
    632   1.1  jmcneill 			di->un.v.num_channels = 2;
    633   1.1  jmcneill 		strlcpy(di->un.v.units.name, AudioNvolume,
    634   1.1  jmcneill 		    sizeof di->un.v.units.name);
    635   1.1  jmcneill 		break;
    636   1.1  jmcneill 	case AD1843_DAC2_MUTE:
    637   1.1  jmcneill 	case AD1843_AUX1_MUTE:
    638   1.1  jmcneill 	case AD1843_AUX2_MUTE:
    639   1.1  jmcneill 	case AD1843_AUX3_MUTE:
    640   1.1  jmcneill 	case AD1843_MIC_MUTE:
    641   1.1  jmcneill 	case AD1843_MONO_MUTE:
    642   1.1  jmcneill 		di->type = AUDIO_MIXER_ENUM;
    643   1.1  jmcneill 		di->mixer_class = AD1843_INPUT_CLASS;
    644   1.1  jmcneill 		di->prev = di->index + AD1843_DAC2_GAIN - AD1843_DAC2_MUTE;
    645   1.1  jmcneill 		strlcpy(di->label.name, AudioNmute, sizeof di->label.name);
    646   1.1  jmcneill 		di->un.e.num_mem = 2;
    647   1.1  jmcneill 		strlcpy(di->un.e.member[0].label.name, AudioNoff,
    648   1.1  jmcneill 		    sizeof di->un.e.member[0].label.name);
    649   1.1  jmcneill 		di->un.e.member[0].ord = 0;
    650   1.1  jmcneill 		strlcpy(di->un.e.member[1].label.name, AudioNon,
    651   1.1  jmcneill 		    sizeof di->un.e.member[1].label.name);
    652   1.1  jmcneill 		di->un.e.member[1].ord = 1;
    653   1.1  jmcneill 		break;
    654   1.1  jmcneill 
    655   1.1  jmcneill 	case AD1843_SUM_MUTE:
    656   1.1  jmcneill 		di->type = AUDIO_MIXER_ENUM;
    657   1.1  jmcneill 		di->mixer_class = AD1843_INPUT_CLASS;
    658   1.1  jmcneill 		strlcpy(di->label.name, "sum." AudioNmute,
    659   1.1  jmcneill 		    sizeof di->label.name);
    660   1.1  jmcneill 		di->un.e.num_mem = 2;
    661   1.1  jmcneill 		strlcpy(di->un.e.member[0].label.name, AudioNoff,
    662   1.1  jmcneill 		    sizeof di->un.e.member[0].label.name);
    663   1.1  jmcneill 		di->un.e.member[0].ord = 0;
    664   1.1  jmcneill 		strlcpy(di->un.e.member[1].label.name, AudioNon,
    665   1.1  jmcneill 		    sizeof di->un.e.member[1].label.name);
    666   1.1  jmcneill 		di->un.e.member[1].ord = 1;
    667   1.1  jmcneill 		break;
    668   1.1  jmcneill 
    669   1.1  jmcneill 	case AD1843_OUTPUT_CLASS:
    670   1.1  jmcneill 		di->type = AUDIO_MIXER_CLASS;
    671   1.1  jmcneill 		di->mixer_class = AD1843_OUTPUT_CLASS;
    672   1.1  jmcneill 		strlcpy(di->label.name, AudioCoutputs, sizeof di->label.name);
    673   1.1  jmcneill 		break;
    674   1.1  jmcneill 
    675   1.1  jmcneill 	case AD1843_MNO_MUTE:
    676   1.1  jmcneill 		di->type = AUDIO_MIXER_ENUM;
    677   1.1  jmcneill 		di->mixer_class = AD1843_OUTPUT_CLASS;
    678   1.1  jmcneill 		strlcpy(di->label.name, AudioNmono "." AudioNmute,
    679   1.1  jmcneill 		    sizeof di->label.name);
    680   1.1  jmcneill 		di->un.e.num_mem = 2;
    681   1.1  jmcneill 		strlcpy(di->un.e.member[0].label.name, AudioNoff,
    682   1.1  jmcneill 		    sizeof di->un.e.member[0].label.name);
    683   1.1  jmcneill 		di->un.e.member[0].ord = 0;
    684   1.1  jmcneill 		strlcpy(di->un.e.member[1].label.name, AudioNon,
    685   1.1  jmcneill 		    sizeof di->un.e.member[1].label.name);
    686   1.1  jmcneill 		di->un.e.member[1].ord = 1;
    687   1.1  jmcneill 		break;
    688   1.1  jmcneill 
    689   1.1  jmcneill 	case AD1843_HPO_MUTE:
    690   1.1  jmcneill 		di->type = AUDIO_MIXER_ENUM;
    691   1.1  jmcneill 		di->mixer_class = AD1843_OUTPUT_CLASS;
    692   1.1  jmcneill 		strlcpy(di->label.name, AudioNheadphone "." AudioNmute,
    693   1.1  jmcneill 		    sizeof di->label.name);
    694   1.1  jmcneill 		di->un.e.num_mem = 2;
    695   1.1  jmcneill 		strlcpy(di->un.e.member[0].label.name, AudioNoff,
    696   1.1  jmcneill 		    sizeof di->un.e.member[0].label.name);
    697   1.1  jmcneill 		di->un.e.member[0].ord = 0;
    698   1.1  jmcneill 		strlcpy(di->un.e.member[1].label.name, AudioNon,
    699   1.1  jmcneill 		    sizeof di->un.e.member[1].label.name);
    700   1.1  jmcneill 		di->un.e.member[1].ord = 1;
    701   1.1  jmcneill 		break;
    702   1.1  jmcneill 
    703   1.1  jmcneill 	default:
    704   1.6   tsutsui 		return EINVAL;
    705   1.1  jmcneill 	}
    706   1.1  jmcneill 
    707   1.6   tsutsui 	return 0;
    708   1.1  jmcneill }
    709   1.1  jmcneill 
    710   1.1  jmcneill int
    711   1.1  jmcneill mavb_get_props(void *hdl)
    712   1.1  jmcneill {
    713   1.6   tsutsui 
    714  1.14     isaki 	return AUDIO_PROP_PLAYBACK;
    715   1.1  jmcneill }
    716   1.1  jmcneill 
    717   1.1  jmcneill static void
    718   1.1  jmcneill mavb_dma_output(struct mavb_softc *sc)
    719   1.1  jmcneill {
    720   1.1  jmcneill 	bus_space_tag_t st = sc->sc_st;
    721   1.1  jmcneill 	bus_space_handle_t sh = sc->sc_sh;
    722   1.6   tsutsui 	uint64_t write_ptr;
    723   1.6   tsutsui 	uint64_t depth;
    724   1.1  jmcneill 	uint8_t *src, *dst;
    725   1.1  jmcneill 	int count;
    726   1.1  jmcneill 
    727   1.8  jmcneill 	KASSERT(mutex_owned(&sc->sc_intr_lock));
    728   1.8  jmcneill 
    729   1.1  jmcneill 	write_ptr = bus_space_read_8(st, sh, MAVB_CHANNEL2_WRITE_PTR);
    730   1.1  jmcneill 	depth = bus_space_read_8(st, sh, MAVB_CHANNEL2_DEPTH);
    731   1.1  jmcneill 
    732   1.1  jmcneill 	dst = sc->sc_ring + write_ptr;
    733   1.1  jmcneill 	src = sc->sc_get;
    734   1.1  jmcneill 
    735   1.1  jmcneill 	count = (MAVB_ISA_RING_SIZE - depth - 32);
    736   1.1  jmcneill 	while (--count >= 0) {
    737   1.1  jmcneill 		*dst++ = *src++;
    738   1.1  jmcneill 		if (dst >= sc->sc_ring + MAVB_ISA_RING_SIZE)
    739   1.1  jmcneill 			dst = sc->sc_ring;
    740   1.1  jmcneill 		if (src >= sc->sc_end)
    741   1.1  jmcneill 			src = sc->sc_start;
    742   1.1  jmcneill 		if (++sc->sc_count >= sc->sc_blksize) {
    743   1.1  jmcneill 			if (sc->sc_intr)
    744   1.1  jmcneill 				sc->sc_intr(sc->sc_intrarg);
    745   1.1  jmcneill 			sc->sc_count = 0;
    746   1.1  jmcneill 		}
    747   1.1  jmcneill 	}
    748   1.1  jmcneill 
    749   1.1  jmcneill 	write_ptr = dst - sc->sc_ring;
    750   1.1  jmcneill 	bus_space_write_8(st, sh, MAVB_CHANNEL2_WRITE_PTR, write_ptr);
    751   1.1  jmcneill 	sc->sc_get = src;
    752   1.1  jmcneill }
    753   1.1  jmcneill 
    754   1.1  jmcneill int
    755   1.1  jmcneill mavb_trigger_output(void *hdl, void *start, void *end, int blksize,
    756   1.1  jmcneill 		    void (*intr)(void *), void *intrarg,
    757   1.1  jmcneill 		    const audio_params_t *param)
    758   1.1  jmcneill {
    759   1.1  jmcneill 	struct mavb_softc *sc = (struct mavb_softc *)hdl;
    760   1.1  jmcneill 
    761   1.1  jmcneill 	DPRINTF(1, ("%s: mavb_trigger_output: start=%p end=%p "
    762   1.9       chs 	    "blksize=%d intr=%p(%p)\n", device_xname(sc->sc_dev),
    763   1.1  jmcneill 	    start, end, blksize, intr, intrarg));
    764   1.1  jmcneill 
    765   1.1  jmcneill 	sc->sc_blksize = blksize;
    766   1.1  jmcneill 	sc->sc_intr = intr;
    767   1.1  jmcneill 	sc->sc_intrarg = intrarg;
    768   1.1  jmcneill 
    769   1.1  jmcneill 	sc->sc_start = sc->sc_get = start;
    770   1.1  jmcneill 	sc->sc_end = end;
    771   1.1  jmcneill 
    772   1.1  jmcneill 	sc->sc_count = 0;
    773   1.1  jmcneill 
    774   1.1  jmcneill 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL,
    775   1.1  jmcneill 	    MAVB_CHANNEL_RESET);
    776   1.1  jmcneill 	delay(1000);
    777   1.1  jmcneill 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL, 0);
    778   1.1  jmcneill 
    779   1.1  jmcneill 	mavb_dma_output(sc);
    780   1.1  jmcneill 
    781   1.1  jmcneill 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL,
    782   1.1  jmcneill 	    MAVB_CHANNEL_DMA_ENABLE | MAVB_CHANNEL_INT_50);
    783   1.8  jmcneill 
    784   1.6   tsutsui 	return 0;
    785   1.1  jmcneill }
    786   1.1  jmcneill 
    787   1.1  jmcneill int
    788   1.1  jmcneill mavb_trigger_input(void *hdl, void *start, void *end, int blksize,
    789   1.1  jmcneill 		   void (*intr)(void *), void *intrarg,
    790   1.1  jmcneill 		   const audio_params_t *param)
    791   1.1  jmcneill {
    792   1.6   tsutsui 
    793   1.6   tsutsui 	return 0;
    794   1.1  jmcneill }
    795   1.1  jmcneill 
    796   1.8  jmcneill void
    797   1.8  jmcneill mavb_get_locks(void *hdl, kmutex_t **intr, kmutex_t **thread)
    798   1.8  jmcneill {
    799   1.8  jmcneill 	struct mavb_softc *sc = (struct mavb_softc *)hdl;
    800   1.8  jmcneill 
    801   1.8  jmcneill 	*intr = &sc->sc_intr_lock;
    802   1.8  jmcneill 	*thread = &sc->sc_lock;
    803   1.8  jmcneill }
    804   1.8  jmcneill 
    805   1.1  jmcneill static void
    806   1.1  jmcneill mavb_button_repeat(void *hdl)
    807   1.1  jmcneill {
    808   1.1  jmcneill 	struct mavb_softc *sc = (struct mavb_softc *)hdl;
    809   1.6   tsutsui 	uint64_t intmask, control;
    810   1.6   tsutsui 	uint16_t value, left, right;
    811   1.1  jmcneill 
    812   1.9       chs 	DPRINTF(1, ("%s: mavb_repeat called\n", device_xname(sc->sc_dev)));
    813   1.1  jmcneill 
    814   1.1  jmcneill #define  MAVB_CONTROL_VOLUME_BUTTONS \
    815   1.1  jmcneill     (MAVB_CONTROL_VOLUME_BUTTON_UP | MAVB_CONTROL_VOLUME_BUTTON_DOWN)
    816   1.1  jmcneill 
    817   1.1  jmcneill 	control = bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL);
    818   1.1  jmcneill 	if (control & MAVB_CONTROL_VOLUME_BUTTONS) {
    819   1.1  jmcneill 		value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
    820   1.1  jmcneill 		left = (value & AD1843_LDA1G_MASK) >> AD1843_LDA1G_SHIFT;
    821   1.1  jmcneill 		right = (value & AD1843_RDA1G_MASK) >> AD1843_RDA1G_SHIFT;
    822   1.1  jmcneill 		if (control & MAVB_CONTROL_VOLUME_BUTTON_UP) {
    823   1.1  jmcneill 			control &= ~MAVB_CONTROL_VOLUME_BUTTON_UP;
    824   1.1  jmcneill 			if (left > 0)
    825   1.1  jmcneill 				left--;		/* attenuation! */
    826   1.1  jmcneill 			if (right > 0)
    827   1.1  jmcneill 				right--;
    828   1.1  jmcneill 		}
    829   1.1  jmcneill 		if (control & MAVB_CONTROL_VOLUME_BUTTON_DOWN) {
    830   1.1  jmcneill 			control &= ~MAVB_CONTROL_VOLUME_BUTTON_DOWN;
    831   1.1  jmcneill 			if (left < 63)
    832   1.1  jmcneill 				left++;
    833   1.1  jmcneill 			if (right < 63)
    834   1.1  jmcneill 				right++;
    835   1.1  jmcneill 		}
    836   1.1  jmcneill 		bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL, control);
    837   1.1  jmcneill 
    838   1.1  jmcneill 		value &= ~(AD1843_LDA1G_MASK | AD1843_RDA1G_MASK);
    839   1.1  jmcneill 		value |= (left << AD1843_LDA1G_SHIFT);
    840   1.1  jmcneill 		value |= (right << AD1843_RDA1G_SHIFT);
    841   1.1  jmcneill 		ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN, value);
    842   1.1  jmcneill 
    843   1.1  jmcneill 		callout_reset(&sc->sc_volume_button_ch,
    844   1.1  jmcneill 		    (hz * MAVB_VOLUME_BUTTON_REPEAT_DELN) / 1000,
    845   1.1  jmcneill 		    mavb_button_repeat, sc);
    846   1.1  jmcneill 	} else {
    847   1.1  jmcneill 		/* Enable volume button interrupts again.  */
    848   1.1  jmcneill 		intmask = bus_space_read_8(sc->sc_st, sc->sc_isash,
    849   1.1  jmcneill 		     MACE_ISA_INT_MASK);
    850   1.1  jmcneill 		bus_space_write_8(sc->sc_st, sc->sc_isash, MACE_ISA_INT_MASK,
    851   1.1  jmcneill 		     intmask | MACE_ISA_INT_AUDIO_SC);
    852   1.1  jmcneill 	}
    853   1.1  jmcneill }
    854   1.1  jmcneill 
    855   1.1  jmcneill static int
    856   1.1  jmcneill mavb_intr(void *arg)
    857   1.1  jmcneill {
    858   1.1  jmcneill 	struct mavb_softc *sc = arg;
    859   1.6   tsutsui 	uint64_t stat, intmask;
    860   1.1  jmcneill 
    861   1.8  jmcneill 	mutex_spin_enter(&sc->sc_intr_lock);
    862   1.8  jmcneill 
    863   1.1  jmcneill 	stat = bus_space_read_8(sc->sc_st, sc->sc_isash, MACE_ISA_INT_STATUS);
    864   1.1  jmcneill 	DPRINTF(MAVB_DEBUG_INTR, ("%s: mavb_intr: stat = 0x%llx\n",
    865   1.9       chs             device_xname(sc->sc_dev), stat));
    866   1.1  jmcneill 
    867   1.1  jmcneill 	if (stat & MACE_ISA_INT_AUDIO_SC) {
    868   1.1  jmcneill 		/* Disable volume button interrupts.  */
    869   1.1  jmcneill 		intmask = bus_space_read_8(sc->sc_st, sc->sc_isash,
    870   1.1  jmcneill 		     MACE_ISA_INT_MASK);
    871   1.1  jmcneill 		bus_space_write_8(sc->sc_st, sc->sc_isash, MACE_ISA_INT_MASK,
    872   1.1  jmcneill 		     intmask & ~MACE_ISA_INT_AUDIO_SC);
    873   1.1  jmcneill 
    874   1.1  jmcneill 		callout_reset(&sc->sc_volume_button_ch,
    875   1.1  jmcneill 		    (hz * MAVB_VOLUME_BUTTON_REPEAT_DEL1) / 1000,
    876   1.1  jmcneill 		    mavb_button_repeat, sc);
    877   1.1  jmcneill 	}
    878   1.1  jmcneill 
    879   1.1  jmcneill 	if (stat & MACE_ISA_INT_AUDIO_DMA2)
    880   1.1  jmcneill 		mavb_dma_output(sc);
    881   1.1  jmcneill 
    882   1.8  jmcneill 	mutex_spin_exit(&sc->sc_intr_lock);
    883   1.8  jmcneill 
    884   1.1  jmcneill 	return 1;
    885   1.1  jmcneill }
    886   1.1  jmcneill 
    887   1.1  jmcneill int
    888   1.9       chs mavb_match(device_t parent, cfdata_t match, void *aux)
    889   1.1  jmcneill {
    890   1.6   tsutsui 
    891   1.6   tsutsui 	return 1;
    892   1.1  jmcneill }
    893   1.1  jmcneill 
    894   1.1  jmcneill void
    895   1.9       chs mavb_attach(device_t parent, device_t self, void *aux)
    896   1.1  jmcneill {
    897   1.9       chs 	struct mavb_softc *sc = device_private(self);
    898   1.1  jmcneill 	struct mace_attach_args *maa = aux;
    899   1.1  jmcneill 	bus_dma_segment_t seg;
    900   1.6   tsutsui 	uint64_t control;
    901   1.6   tsutsui 	uint16_t value;
    902  1.13     isaki 	int rseg;
    903   1.1  jmcneill 
    904   1.9       chs 	sc->sc_dev = self;
    905   1.9       chs 
    906   1.8  jmcneill 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
    907   1.8  jmcneill 	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
    908   1.8  jmcneill 
    909   1.1  jmcneill 	sc->sc_st = maa->maa_st;
    910   1.1  jmcneill 	if (bus_space_subregion(sc->sc_st, maa->maa_sh, maa->maa_offset,
    911   1.1  jmcneill 	    0, &sc->sc_sh) != 0) {
    912   1.1  jmcneill 		printf(": can't map i/o space\n");
    913   1.1  jmcneill 		return;
    914   1.1  jmcneill 	}
    915   1.1  jmcneill 
    916   1.1  jmcneill 	/* XXX We need access to some of the MACE ISA registers.  */
    917   1.1  jmcneill 	if (bus_space_subregion(sc->sc_st, maa->maa_sh, 0, 0,
    918   1.1  jmcneill 	    &sc->sc_isash) != 0) {
    919   1.1  jmcneill 		printf(": can't map isa i/o space\n");
    920   1.1  jmcneill 		return;
    921   1.1  jmcneill 	}
    922   1.1  jmcneill 
    923   1.1  jmcneill 	/* Set up DMA structures.  */
    924   1.1  jmcneill 	sc->sc_dmat = maa->maa_dmat;
    925   1.1  jmcneill 	if (bus_dmamap_create(sc->sc_dmat, 4 * MAVB_ISA_RING_SIZE, 1,
    926   1.1  jmcneill 	    4 * MAVB_ISA_RING_SIZE, 0, 0, &sc->sc_dmamap)) {
    927   1.1  jmcneill 		printf(": can't create MACE ISA DMA map\n");
    928   1.1  jmcneill 		return;
    929   1.1  jmcneill 	}
    930   1.1  jmcneill 
    931   1.1  jmcneill 	if (bus_dmamem_alloc(sc->sc_dmat, 4 * MAVB_ISA_RING_SIZE,
    932   1.1  jmcneill 	    MACE_ISA_RING_ALIGN, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
    933   1.1  jmcneill 		printf(": can't allocate ring buffer\n");
    934   1.1  jmcneill 		return;
    935   1.1  jmcneill 	}
    936   1.1  jmcneill 
    937   1.1  jmcneill 	if (bus_dmamem_map(sc->sc_dmat, &seg, rseg, 4 * MAVB_ISA_RING_SIZE,
    938   1.1  jmcneill 	    (void *)&sc->sc_ring, BUS_DMA_COHERENT)) {
    939   1.1  jmcneill 		printf(": can't map ring buffer\n");
    940   1.1  jmcneill 		return;
    941   1.1  jmcneill 	}
    942   1.1  jmcneill 
    943   1.1  jmcneill 	if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_ring,
    944   1.1  jmcneill 	    4 * MAVB_ISA_RING_SIZE, NULL, BUS_DMA_NOWAIT)) {
    945   1.1  jmcneill 		printf(": can't load MACE ISA DMA map\n");
    946   1.1  jmcneill 		return;
    947   1.1  jmcneill 	}
    948   1.1  jmcneill 
    949   1.1  jmcneill 	sc->sc_ring += MAVB_ISA_RING_SIZE; /* XXX */
    950   1.1  jmcneill 
    951   1.1  jmcneill 	bus_space_write_8(sc->sc_st, sc->sc_isash, MACE_ISA_RINGBASE,
    952   1.1  jmcneill 	    sc->sc_dmamap->dm_segs[0].ds_addr);
    953   1.1  jmcneill 
    954   1.1  jmcneill 	/* Establish interrupt.  */
    955   1.1  jmcneill 	cpu_intr_establish(maa->maa_intr, maa->maa_intrmask,
    956   1.1  jmcneill 	    mavb_intr, sc);
    957   1.1  jmcneill 
    958   1.1  jmcneill 	control = bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL);
    959   1.1  jmcneill 	if (!(control & MAVB_CONTROL_CODEC_PRESENT)) {
    960   1.1  jmcneill 		printf(": no codec present\n");
    961   1.1  jmcneill 		return;
    962   1.1  jmcneill 	}
    963   1.1  jmcneill 
    964   1.1  jmcneill 	/* 2. Assert the RESET signal.  */
    965   1.1  jmcneill 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL,
    966   1.1  jmcneill 	    MAVB_CONTROL_RESET);
    967   1.1  jmcneill 	delay(1);		/* at least 100 ns */
    968   1.1  jmcneill 
    969   1.1  jmcneill 	/* 3. Deassert the RESET signal and enter a wait period to
    970   1.1  jmcneill               allow the AD1843 internal clocks and the external
    971   1.1  jmcneill               crystal oscillator to stabilize.  */
    972   1.1  jmcneill 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL, 0);
    973   1.1  jmcneill 	delay(800);		/* typically 400 us to 800 us */
    974   1.1  jmcneill 	if (ad1843_reg_read(sc, AD1843_CODEC_STATUS) & AD1843_INIT) {
    975   1.1  jmcneill 		printf(": codec not ready\n");
    976   1.1  jmcneill 		return;
    977   1.1  jmcneill 	}
    978   1.1  jmcneill 
    979   1.1  jmcneill 	/* 4. Put the conversion sources into standby.  */
    980   1.1  jmcneill 	value = ad1843_reg_read(sc, AD1843_FUNDAMENTAL_SETTINGS);
    981   1.1  jmcneill 	ad1843_reg_write(sc, AD1843_FUNDAMENTAL_SETTINGS,
    982   1.1  jmcneill 	    value & ~AD1843_PDNI);
    983   1.1  jmcneill 	delay (500000);		/* approximately 474 ms */
    984   1.1  jmcneill 	if (ad1843_reg_read(sc, AD1843_CODEC_STATUS) & AD1843_PDNO) {
    985   1.1  jmcneill 		printf(": can't power up conversion resources\n");
    986   1.1  jmcneill 		return;
    987   1.1  jmcneill 	}
    988   1.1  jmcneill 
    989   1.1  jmcneill 	/* 5. Power up the clock generators and enable clock output pins.  */
    990   1.1  jmcneill 	value = ad1843_reg_read(sc, AD1843_FUNDAMENTAL_SETTINGS);
    991   1.1  jmcneill 	ad1843_reg_write(sc, AD1843_FUNDAMENTAL_SETTINGS, value | AD1843_C2EN);
    992   1.1  jmcneill 
    993   1.1  jmcneill 	/* 6. Configure conversion resources while they are in standby.  */
    994   1.1  jmcneill 	value = ad1843_reg_read(sc, AD1843_CHANNEL_SAMPLE_RATE);
    995   1.1  jmcneill 	ad1843_reg_write(sc, AD1843_CHANNEL_SAMPLE_RATE,
    996   1.1  jmcneill 	     value | (2 << AD1843_DA1C_SHIFT));
    997   1.1  jmcneill 
    998   1.1  jmcneill 	/* 7. Enable conversion resources.  */
    999   1.1  jmcneill 	value = ad1843_reg_read(sc, AD1843_CHANNEL_POWER_DOWN);
   1000   1.1  jmcneill 	ad1843_reg_write(sc, AD1843_CHANNEL_POWER_DOWN,
   1001   1.1  jmcneill 	     value | (AD1843_DA1EN | AD1843_AAMEN));
   1002   1.1  jmcneill 
   1003   1.1  jmcneill 	/* 8. Configure conversion resources while they are enabled.  */
   1004   1.1  jmcneill 	value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
   1005   1.1  jmcneill 	ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN,
   1006   1.1  jmcneill             value & ~(AD1843_LDA1GM | AD1843_RDA1GM));
   1007   1.1  jmcneill 	value = ad1843_reg_read(sc, AD1843_DAC1_DIGITAL_GAIN);
   1008   1.1  jmcneill 	ad1843_reg_write(sc, AD1843_DAC1_DIGITAL_GAIN,
   1009   1.1  jmcneill             value & ~(AD1843_LDA1AM | AD1843_RDA1AM));
   1010   1.1  jmcneill 	value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
   1011   1.1  jmcneill 	ad1843_reg_write(sc, AD1843_MISC_SETTINGS,
   1012   1.1  jmcneill             value & ~(AD1843_HPOM | AD1843_MNOM));
   1013   1.1  jmcneill 
   1014   1.1  jmcneill 	value = ad1843_reg_read(sc, AD1843_CODEC_STATUS);
   1015   1.1  jmcneill 	printf(": AD1843 rev %d\n", (u_int)value & AD1843_REVISION_MASK);
   1016   1.1  jmcneill 
   1017   1.1  jmcneill 	sc->sc_play_rate = 48000;
   1018   1.1  jmcneill 	sc->sc_play_format = AD1843_PCM8;
   1019   1.1  jmcneill 
   1020   1.3        ad 	callout_init(&sc->sc_volume_button_ch, 0);
   1021   1.1  jmcneill 
   1022   1.9       chs 	audio_attach_mi(&mavb_sa_hw_if, sc, self);
   1023   1.1  jmcneill 
   1024   1.1  jmcneill 	return;
   1025   1.1  jmcneill }
   1026   1.1  jmcneill 
   1027   1.6   tsutsui uint16_t
   1028   1.1  jmcneill ad1843_reg_read(struct mavb_softc *sc, ad1843_addr_t addr)
   1029   1.1  jmcneill {
   1030   1.1  jmcneill 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_CONTROL,
   1031   1.1  jmcneill             (addr & MAVB_CODEC_ADDRESS_MASK) << MAVB_CODEC_ADDRESS_SHIFT |
   1032   1.1  jmcneill 	    MAVB_CODEC_READ);
   1033   1.1  jmcneill 	delay(200);
   1034   1.1  jmcneill 	return bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_STATUS);
   1035   1.1  jmcneill }
   1036   1.1  jmcneill 
   1037   1.6   tsutsui uint16_t
   1038   1.6   tsutsui ad1843_reg_write(struct mavb_softc *sc, ad1843_addr_t addr, uint16_t value)
   1039   1.1  jmcneill {
   1040   1.1  jmcneill 	bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_CONTROL,
   1041   1.1  jmcneill 	    (addr & MAVB_CODEC_ADDRESS_MASK) << MAVB_CODEC_ADDRESS_SHIFT |
   1042   1.1  jmcneill 	    (value & MAVB_CODEC_WORD_MASK) << MAVB_CODEC_WORD_SHIFT);
   1043   1.1  jmcneill 	delay(200);
   1044   1.1  jmcneill 	return bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_STATUS);
   1045   1.1  jmcneill }
   1046   1.1  jmcneill 
   1047   1.1  jmcneill void
   1048   1.1  jmcneill ad1843_dump_regs(struct mavb_softc *sc)
   1049   1.1  jmcneill {
   1050   1.6   tsutsui 	uint16_t addr;
   1051   1.1  jmcneill 
   1052   1.1  jmcneill 	for (addr = 0; addr < AD1843_NREGS; addr++)
   1053   1.1  jmcneill 		printf("%d: 0x%04x\n", addr, ad1843_reg_read(sc, addr));
   1054   1.1  jmcneill }
   1055