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