mavb.c revision 1.1 1 1.1 jmcneill /* $NetBSD: mavb.c,v 1.1 2007/04/13 03:37:41 jmcneill 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.1 jmcneill #include <sys/malloc.h>
25 1.1 jmcneill #include <sys/callout.h>
26 1.1 jmcneill
27 1.1 jmcneill #include <machine/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.1 jmcneill #include <dev/auconv.h>
33 1.1 jmcneill #include <dev/audio_if.h>
34 1.1 jmcneill
35 1.1 jmcneill #include <arch/sgimips/mace/macevar.h>
36 1.1 jmcneill #include <arch/sgimips/mace/macereg.h>
37 1.1 jmcneill #include <arch/sgimips/mace/mavbreg.h>
38 1.1 jmcneill
39 1.1 jmcneill #include <dev/ic/ad1843reg.h>
40 1.1 jmcneill
41 1.1 jmcneill #undef MAVB_DEBUG
42 1.1 jmcneill
43 1.1 jmcneill #ifdef MAVB_DEBUG
44 1.1 jmcneill #define DPRINTF(l,x) do { if (mavb_debug & (l)) printf x; } while (0)
45 1.1 jmcneill #define MAVB_DEBUG_INTR 0x0100
46 1.1 jmcneill int mavb_debug = ~MAVB_DEBUG_INTR;
47 1.1 jmcneill #else
48 1.1 jmcneill #define DPRINTF(l,x) /* nothing */
49 1.1 jmcneill #endif
50 1.1 jmcneill
51 1.1 jmcneill /* Repeat delays for volume buttons. */
52 1.1 jmcneill #define MAVB_VOLUME_BUTTON_REPEAT_DEL1 400 /* 400ms to start repeating */
53 1.1 jmcneill #define MAVB_VOLUME_BUTTON_REPEAT_DELN 100 /* 100ms between repeats */
54 1.1 jmcneill
55 1.1 jmcneill /* XXX We need access to some of the MACE ISA registers. */
56 1.1 jmcneill #define MAVB_ISA_NREGS 0x20
57 1.1 jmcneill
58 1.1 jmcneill /*
59 1.1 jmcneill * AD1843 Mixer.
60 1.1 jmcneill */
61 1.1 jmcneill
62 1.1 jmcneill enum {
63 1.1 jmcneill AD1843_RECORD_CLASS,
64 1.1 jmcneill AD1843_ADC_SOURCE, /* ADC Source Select */
65 1.1 jmcneill AD1843_ADC_GAIN, /* ADC Input Gain */
66 1.1 jmcneill
67 1.1 jmcneill AD1843_INPUT_CLASS,
68 1.1 jmcneill AD1843_DAC1_GAIN, /* DAC1 Analog/Digital Gain/Attenuation */
69 1.1 jmcneill AD1843_DAC1_MUTE, /* DAC1 Analog Mute */
70 1.1 jmcneill AD1843_DAC2_GAIN, /* DAC2 Mix Gain */
71 1.1 jmcneill AD1843_AUX1_GAIN, /* Auxilliary 1 Mix Gain */
72 1.1 jmcneill AD1843_AUX2_GAIN, /* Auxilliary 2 Mix Gain */
73 1.1 jmcneill AD1843_AUX3_GAIN, /* Auxilliary 3 Mix Gain */
74 1.1 jmcneill AD1843_MIC_GAIN, /* Microphone Mix Gain */
75 1.1 jmcneill AD1843_MONO_GAIN, /* Mono Mix Gain */
76 1.1 jmcneill AD1843_DAC2_MUTE, /* DAC2 Mix Mute */
77 1.1 jmcneill AD1843_AUX1_MUTE, /* Auxilliary 1 Mix Mute */
78 1.1 jmcneill AD1843_AUX2_MUTE, /* Auxilliary 2 Mix Mute */
79 1.1 jmcneill AD1843_AUX3_MUTE, /* Auxilliary 3 Mix Mute */
80 1.1 jmcneill AD1843_MIC_MUTE, /* Microphone Mix Mute */
81 1.1 jmcneill AD1843_MONO_MUTE, /* Mono Mix Mute */
82 1.1 jmcneill AD1843_SUM_MUTE, /* Sum Mute */
83 1.1 jmcneill
84 1.1 jmcneill AD1843_OUTPUT_CLASS,
85 1.1 jmcneill AD1843_MNO_MUTE, /* Mono Output Mute */
86 1.1 jmcneill AD1843_HPO_MUTE /* Headphone Output Mute */
87 1.1 jmcneill };
88 1.1 jmcneill
89 1.1 jmcneill /* ADC Source Select. The order matches the hardware bits. */
90 1.1 jmcneill const char *ad1843_source[] = {
91 1.1 jmcneill AudioNline,
92 1.1 jmcneill AudioNmicrophone,
93 1.1 jmcneill AudioNaux "1",
94 1.1 jmcneill AudioNaux "2",
95 1.1 jmcneill AudioNaux "3",
96 1.1 jmcneill AudioNmono,
97 1.1 jmcneill AudioNdac "1",
98 1.1 jmcneill AudioNdac "2"
99 1.1 jmcneill };
100 1.1 jmcneill
101 1.1 jmcneill /* Mix Control. The order matches the hardware register numbering. */
102 1.1 jmcneill const char *ad1843_input[] = {
103 1.1 jmcneill AudioNdac "2", /* AD1843_DAC2__TO_MIXER */
104 1.1 jmcneill AudioNaux "1",
105 1.1 jmcneill AudioNaux "2",
106 1.1 jmcneill AudioNaux "3",
107 1.1 jmcneill AudioNmicrophone,
108 1.1 jmcneill AudioNmono /* AD1843_MISC_SETTINGS */
109 1.1 jmcneill };
110 1.1 jmcneill
111 1.1 jmcneill struct mavb_softc {
112 1.1 jmcneill struct device sc_dev;
113 1.1 jmcneill bus_space_tag_t sc_st;
114 1.1 jmcneill bus_space_handle_t sc_sh;
115 1.1 jmcneill bus_dma_tag_t sc_dmat;
116 1.1 jmcneill bus_dmamap_t sc_dmamap;
117 1.1 jmcneill
118 1.1 jmcneill /* XXX We need access to some of the MACE ISA registers. */
119 1.1 jmcneill bus_space_handle_t sc_isash;
120 1.1 jmcneill
121 1.1 jmcneill #define MAVB_ISA_RING_SIZE 0x1000
122 1.1 jmcneill uint8_t *sc_ring;
123 1.1 jmcneill
124 1.1 jmcneill uint8_t *sc_start, *sc_end;
125 1.1 jmcneill int sc_blksize;
126 1.1 jmcneill void (*sc_intr)(void *);
127 1.1 jmcneill void *sc_intrarg;
128 1.1 jmcneill
129 1.1 jmcneill void *sc_get;
130 1.1 jmcneill int sc_count;
131 1.1 jmcneill
132 1.1 jmcneill u_long sc_play_rate;
133 1.1 jmcneill u_int sc_play_format;
134 1.1 jmcneill
135 1.1 jmcneill //struct timeout sc_volume_button_to;
136 1.1 jmcneill struct callout sc_volume_button_ch;
137 1.1 jmcneill };
138 1.1 jmcneill
139 1.1 jmcneill /* XXX mavb supports way more than this, but for now I'm going to be
140 1.1 jmcneill * lazy and let auconv work its magic
141 1.1 jmcneill */
142 1.1 jmcneill #define MAVB_NENCODINGS 8
143 1.1 jmcneill static audio_encoding_t mavb_encoding[MAVB_NENCODINGS] = {
144 1.1 jmcneill { 0, AudioEulinear, AUDIO_ENCODING_ULINEAR, 8,
145 1.1 jmcneill AUDIO_ENCODINGFLAG_EMULATED },
146 1.1 jmcneill { 1, AudioEmulaw, AUDIO_ENCODING_ULAW, 8,
147 1.1 jmcneill AUDIO_ENCODINGFLAG_EMULATED },
148 1.1 jmcneill { 2, AudioEalaw, AUDIO_ENCODING_ALAW, 8,
149 1.1 jmcneill AUDIO_ENCODINGFLAG_EMULATED },
150 1.1 jmcneill { 3, AudioEslinear, AUDIO_ENCODING_SLINEAR, 8,
151 1.1 jmcneill AUDIO_ENCODINGFLAG_EMULATED },
152 1.1 jmcneill { 4, AudioEslinear_le, AUDIO_ENCODING_SLINEAR, 16,
153 1.1 jmcneill AUDIO_ENCODINGFLAG_EMULATED },
154 1.1 jmcneill { 5, AudioEulinear_le, AUDIO_ENCODING_ULINEAR, 16,
155 1.1 jmcneill AUDIO_ENCODINGFLAG_EMULATED },
156 1.1 jmcneill { 6, AudioEslinear_be, AUDIO_ENCODING_SLINEAR, 16,
157 1.1 jmcneill 0 },
158 1.1 jmcneill { 7, AudioEulinear_be, AUDIO_ENCODING_ULINEAR, 16,
159 1.1 jmcneill AUDIO_ENCODINGFLAG_EMULATED },
160 1.1 jmcneill };
161 1.1 jmcneill
162 1.1 jmcneill #define MAVB_NFORMATS 3
163 1.1 jmcneill static const struct audio_format mavb_formats[MAVB_NFORMATS] = {
164 1.1 jmcneill { NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_BE, 16, 16,
165 1.1 jmcneill 2, AUFMT_STEREO, 0, { 8000, 48000 } },
166 1.1 jmcneill { NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_BE, 16, 16,
167 1.1 jmcneill 1, AUFMT_MONAURAL, 0, { 8000, 48000 } },
168 1.1 jmcneill };
169 1.1 jmcneill
170 1.1 jmcneill struct mavb_codecvar {
171 1.1 jmcneill stream_filter_t base;
172 1.1 jmcneill };
173 1.1 jmcneill
174 1.1 jmcneill static stream_filter_t *mavb_factory
175 1.1 jmcneill (int (*)(stream_fetcher_t *, audio_stream_t *, int));
176 1.1 jmcneill static void mavb_dtor(stream_filter_t *);
177 1.1 jmcneill
178 1.1 jmcneill /* XXX I'm going to complain every time I have to copy this macro */
179 1.1 jmcneill #define DEFINE_FILTER(name) \
180 1.1 jmcneill static int \
181 1.1 jmcneill name##_fetch_to(stream_fetcher_t *, audio_stream_t *, int); \
182 1.1 jmcneill stream_filter_t *name(struct audio_softc *, \
183 1.1 jmcneill const audio_params_t *, const audio_params_t *); \
184 1.1 jmcneill stream_filter_t * \
185 1.1 jmcneill name(struct audio_softc *sc, const audio_params_t *from, \
186 1.1 jmcneill const audio_params_t *to) \
187 1.1 jmcneill { \
188 1.1 jmcneill return mavb_factory(name##_fetch_to); \
189 1.1 jmcneill } \
190 1.1 jmcneill static int \
191 1.1 jmcneill name##_fetch_to(stream_fetcher_t *self, audio_stream_t *dst, int max_used)
192 1.1 jmcneill
193 1.1 jmcneill DEFINE_FILTER(mavb_16to24)
194 1.1 jmcneill {
195 1.1 jmcneill stream_filter_t *this;
196 1.1 jmcneill int m, err;
197 1.1 jmcneill
198 1.1 jmcneill this = (stream_filter_t *)self;
199 1.1 jmcneill max_used = (max_used + 1) & ~1;
200 1.1 jmcneill if ((err = this->prev->fetch_to(this->prev, this->src, max_used)))
201 1.1 jmcneill return err;
202 1.1 jmcneill m = (dst->end - dst->start) & ~1;
203 1.1 jmcneill m = min(m, max_used);
204 1.1 jmcneill FILTER_LOOP_PROLOGUE(this->src, 2, dst, 4, m) {
205 1.1 jmcneill d[3] = 0;
206 1.1 jmcneill d[2] = s[1];
207 1.1 jmcneill d[1] = s[0];
208 1.1 jmcneill d[0] = (s[0] & 0x80) ? 0xff : 0;
209 1.1 jmcneill } FILTER_LOOP_EPILOGUE(this->src, dst);
210 1.1 jmcneill
211 1.1 jmcneill return 0;
212 1.1 jmcneill }
213 1.1 jmcneill
214 1.1 jmcneill DEFINE_FILTER(mavb_mts)
215 1.1 jmcneill {
216 1.1 jmcneill stream_filter_t *this;
217 1.1 jmcneill int m, err;
218 1.1 jmcneill
219 1.1 jmcneill this = (stream_filter_t *)self;
220 1.1 jmcneill max_used = (max_used + 1) & ~1;
221 1.1 jmcneill if ((err = this->prev->fetch_to(this->prev, this->src, max_used)))
222 1.1 jmcneill return err;
223 1.1 jmcneill m = (dst->end - dst->start) & ~1;
224 1.1 jmcneill m = min(m, max_used);
225 1.1 jmcneill FILTER_LOOP_PROLOGUE(this->src, 4, dst, 8, m) {
226 1.1 jmcneill d[3] = d[7] = s[3];
227 1.1 jmcneill d[2] = d[6] = s[2];
228 1.1 jmcneill d[1] = d[5] = s[1];
229 1.1 jmcneill d[0] = d[4] = s[0];
230 1.1 jmcneill } FILTER_LOOP_EPILOGUE(this->src, dst);
231 1.1 jmcneill
232 1.1 jmcneill return 0;
233 1.1 jmcneill }
234 1.1 jmcneill
235 1.1 jmcneill static stream_filter_t *
236 1.1 jmcneill mavb_factory(int (*fetch_to)(stream_fetcher_t *, audio_stream_t *, int))
237 1.1 jmcneill {
238 1.1 jmcneill struct mavb_codecvar *this;
239 1.1 jmcneill
240 1.1 jmcneill this = malloc(sizeof(*this), M_DEVBUF, M_WAITOK | M_ZERO);
241 1.1 jmcneill this->base.base.fetch_to = fetch_to;
242 1.1 jmcneill this->base.dtor = mavb_dtor;
243 1.1 jmcneill this->base.set_fetcher = stream_filter_set_fetcher;
244 1.1 jmcneill this->base.set_inputbuffer = stream_filter_set_inputbuffer;
245 1.1 jmcneill
246 1.1 jmcneill return &this->base;
247 1.1 jmcneill }
248 1.1 jmcneill
249 1.1 jmcneill static void
250 1.1 jmcneill mavb_dtor(stream_filter_t *this)
251 1.1 jmcneill {
252 1.1 jmcneill if (this != NULL)
253 1.1 jmcneill free(this, M_DEVBUF);
254 1.1 jmcneill }
255 1.1 jmcneill
256 1.1 jmcneill typedef u_int64_t ad1843_addr_t;
257 1.1 jmcneill
258 1.1 jmcneill u_int16_t ad1843_reg_read(struct mavb_softc *, ad1843_addr_t);
259 1.1 jmcneill u_int16_t ad1843_reg_write(struct mavb_softc *, ad1843_addr_t, u_int16_t);
260 1.1 jmcneill void ad1843_dump_regs(struct mavb_softc *);
261 1.1 jmcneill
262 1.1 jmcneill int mavb_match(struct device *, struct cfdata *, void *);
263 1.1 jmcneill void mavb_attach(struct device *, struct device *, void *);
264 1.1 jmcneill
265 1.1 jmcneill CFATTACH_DECL(mavb, sizeof(struct mavb_softc),
266 1.1 jmcneill mavb_match, mavb_attach, NULL, NULL);
267 1.1 jmcneill
268 1.1 jmcneill int mavb_open(void *, int);
269 1.1 jmcneill void mavb_close(void *);
270 1.1 jmcneill int mavb_query_encoding(void *, struct audio_encoding *);
271 1.1 jmcneill int mavb_set_params(void *, int, int, struct audio_params *,
272 1.1 jmcneill struct audio_params *, stream_filter_list_t *,
273 1.1 jmcneill stream_filter_list_t *);
274 1.1 jmcneill int mavb_round_blocksize(void *hdl, int, int, const audio_params_t *);
275 1.1 jmcneill int mavb_halt_output(void *);
276 1.1 jmcneill int mavb_halt_input(void *);
277 1.1 jmcneill int mavb_getdev(void *, struct audio_device *);
278 1.1 jmcneill int mavb_set_port(void *, struct mixer_ctrl *);
279 1.1 jmcneill int mavb_get_port(void *, struct mixer_ctrl *);
280 1.1 jmcneill int mavb_query_devinfo(void *, struct mixer_devinfo *);
281 1.1 jmcneill size_t mavb_round_buffersize(void *, int, size_t);
282 1.1 jmcneill int mavb_get_props(void *);
283 1.1 jmcneill int mavb_trigger_output(void *, void *, void *, int, void (*)(void *),
284 1.1 jmcneill void *, const audio_params_t *);
285 1.1 jmcneill int mavb_trigger_input(void *, void *, void *, int, void (*)(void *),
286 1.1 jmcneill void *, const audio_params_t *);
287 1.1 jmcneill
288 1.1 jmcneill struct audio_hw_if mavb_sa_hw_if = {
289 1.1 jmcneill mavb_open,
290 1.1 jmcneill mavb_close,
291 1.1 jmcneill 0,
292 1.1 jmcneill mavb_query_encoding,
293 1.1 jmcneill mavb_set_params,
294 1.1 jmcneill mavb_round_blocksize,
295 1.1 jmcneill 0,
296 1.1 jmcneill 0,
297 1.1 jmcneill 0,
298 1.1 jmcneill 0,
299 1.1 jmcneill 0,
300 1.1 jmcneill mavb_halt_output,
301 1.1 jmcneill mavb_halt_input,
302 1.1 jmcneill 0,
303 1.1 jmcneill mavb_getdev,
304 1.1 jmcneill 0,
305 1.1 jmcneill mavb_set_port,
306 1.1 jmcneill mavb_get_port,
307 1.1 jmcneill mavb_query_devinfo,
308 1.1 jmcneill 0,
309 1.1 jmcneill 0,
310 1.1 jmcneill mavb_round_buffersize,
311 1.1 jmcneill 0,
312 1.1 jmcneill mavb_get_props,
313 1.1 jmcneill mavb_trigger_output,
314 1.1 jmcneill mavb_trigger_input,
315 1.1 jmcneill NULL,
316 1.1 jmcneill };
317 1.1 jmcneill
318 1.1 jmcneill struct audio_device mavb_device = {
319 1.1 jmcneill "A3",
320 1.1 jmcneill "",
321 1.1 jmcneill "mavb"
322 1.1 jmcneill };
323 1.1 jmcneill
324 1.1 jmcneill int
325 1.1 jmcneill mavb_open(void *hdl, int flags)
326 1.1 jmcneill {
327 1.1 jmcneill return (0);
328 1.1 jmcneill }
329 1.1 jmcneill
330 1.1 jmcneill void
331 1.1 jmcneill mavb_close(void *hdl)
332 1.1 jmcneill {
333 1.1 jmcneill }
334 1.1 jmcneill
335 1.1 jmcneill int
336 1.1 jmcneill mavb_query_encoding(void *hdl, struct audio_encoding *ae)
337 1.1 jmcneill {
338 1.1 jmcneill if (ae->index < 0 || ae->index >= MAVB_NENCODINGS)
339 1.1 jmcneill return (EINVAL);
340 1.1 jmcneill *ae = mavb_encoding[ae->index];
341 1.1 jmcneill
342 1.1 jmcneill return (0);
343 1.1 jmcneill }
344 1.1 jmcneill
345 1.1 jmcneill static int
346 1.1 jmcneill mavb_set_play_rate(struct mavb_softc *sc, u_long sample_rate)
347 1.1 jmcneill {
348 1.1 jmcneill if (sample_rate < 4000 || sample_rate > 48000)
349 1.1 jmcneill return (EINVAL);
350 1.1 jmcneill
351 1.1 jmcneill if (sc->sc_play_rate != sample_rate) {
352 1.1 jmcneill ad1843_reg_write(sc, AD1843_CLOCK2_SAMPLE_RATE, sample_rate);
353 1.1 jmcneill sc->sc_play_rate = sample_rate;
354 1.1 jmcneill }
355 1.1 jmcneill return (0);
356 1.1 jmcneill }
357 1.1 jmcneill
358 1.1 jmcneill static int
359 1.1 jmcneill mavb_set_play_format(struct mavb_softc *sc, u_int encoding)
360 1.1 jmcneill {
361 1.1 jmcneill u_int16_t value;
362 1.1 jmcneill u_int format;
363 1.1 jmcneill
364 1.1 jmcneill switch(encoding) {
365 1.1 jmcneill case AUDIO_ENCODING_ULINEAR_BE:
366 1.1 jmcneill format = AD1843_PCM8;
367 1.1 jmcneill break;
368 1.1 jmcneill case AUDIO_ENCODING_SLINEAR_BE:
369 1.1 jmcneill format = AD1843_PCM16;
370 1.1 jmcneill break;
371 1.1 jmcneill case AUDIO_ENCODING_ULAW:
372 1.1 jmcneill format = AD1843_ULAW;
373 1.1 jmcneill break;
374 1.1 jmcneill case AUDIO_ENCODING_ALAW:
375 1.1 jmcneill format = AD1843_ALAW;
376 1.1 jmcneill break;
377 1.1 jmcneill default:
378 1.1 jmcneill return (EINVAL);
379 1.1 jmcneill }
380 1.1 jmcneill
381 1.1 jmcneill if (sc->sc_play_format != format) {
382 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_SERIAL_INTERFACE);
383 1.1 jmcneill value &= ~AD1843_DA1F_MASK;
384 1.1 jmcneill value |= (format << AD1843_DA1F_SHIFT);
385 1.1 jmcneill ad1843_reg_write(sc, AD1843_SERIAL_INTERFACE, value);
386 1.1 jmcneill sc->sc_play_format = format;
387 1.1 jmcneill }
388 1.1 jmcneill return (0);
389 1.1 jmcneill }
390 1.1 jmcneill
391 1.1 jmcneill int
392 1.1 jmcneill mavb_set_params(void *hdl, int setmode, int usemode,
393 1.1 jmcneill struct audio_params *play, struct audio_params *rec,
394 1.1 jmcneill stream_filter_list_t *pfil, stream_filter_list_t *rfil)
395 1.1 jmcneill {
396 1.1 jmcneill struct mavb_softc *sc = (struct mavb_softc *)hdl;
397 1.1 jmcneill struct audio_params *p;
398 1.1 jmcneill stream_filter_list_t *fil;
399 1.1 jmcneill int error;
400 1.1 jmcneill
401 1.1 jmcneill DPRINTF(1, ("%s: mavb_set_params: sample=%u precision=%d "
402 1.1 jmcneill "channels=%d\n", sc->sc_dev.dv_xname, play->sample_rate,
403 1.1 jmcneill play->precision, play->channels));
404 1.1 jmcneill
405 1.1 jmcneill if (setmode & AUMODE_PLAY) {
406 1.1 jmcneill if (play->sample_rate < 4000 || play->sample_rate > 48000)
407 1.1 jmcneill return (EINVAL);
408 1.1 jmcneill
409 1.1 jmcneill p = play;
410 1.1 jmcneill fil = pfil;
411 1.1 jmcneill if (auconv_set_converter(mavb_formats, MAVB_NFORMATS,
412 1.1 jmcneill AUMODE_PLAY, p, FALSE, fil) < 0)
413 1.1 jmcneill return (EINVAL);
414 1.1 jmcneill
415 1.1 jmcneill fil->append(fil, mavb_16to24, p);
416 1.1 jmcneill if (p->channels == 1)
417 1.1 jmcneill fil->append(fil, mavb_mts, p);
418 1.1 jmcneill if (fil->req_size > 0)
419 1.1 jmcneill p = &fil->filters[0].param;
420 1.1 jmcneill
421 1.1 jmcneill error = mavb_set_play_rate(sc, p->sample_rate);
422 1.1 jmcneill if (error)
423 1.1 jmcneill return (error);
424 1.1 jmcneill
425 1.1 jmcneill error = mavb_set_play_format(sc, p->encoding);
426 1.1 jmcneill if (error)
427 1.1 jmcneill return (error);
428 1.1 jmcneill }
429 1.1 jmcneill
430 1.1 jmcneill #if 0
431 1.1 jmcneill if (setmode & AUMODE_RECORD) {
432 1.1 jmcneill if (rec->sample_rate < 4000 || rec->sample_rate > 48000)
433 1.1 jmcneill return (EINVAL);
434 1.1 jmcneill }
435 1.1 jmcneill #endif
436 1.1 jmcneill
437 1.1 jmcneill return (0);
438 1.1 jmcneill }
439 1.1 jmcneill
440 1.1 jmcneill int
441 1.1 jmcneill mavb_round_blocksize(void *hdl, int bs, int mode, const audio_params_t *p)
442 1.1 jmcneill {
443 1.1 jmcneill /* Block size should be a multiple of 32. */
444 1.1 jmcneill return (bs + 0x1f) & ~0x1f;
445 1.1 jmcneill }
446 1.1 jmcneill
447 1.1 jmcneill int
448 1.1 jmcneill mavb_halt_output(void *hdl)
449 1.1 jmcneill {
450 1.1 jmcneill struct mavb_softc *sc = (struct mavb_softc *)hdl;
451 1.1 jmcneill
452 1.1 jmcneill DPRINTF(1, ("%s: mavb_halt_output called\n", sc->sc_dev.dv_xname));
453 1.1 jmcneill
454 1.1 jmcneill bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL, 0);
455 1.1 jmcneill return (0);
456 1.1 jmcneill }
457 1.1 jmcneill
458 1.1 jmcneill int
459 1.1 jmcneill mavb_halt_input(void *hdl)
460 1.1 jmcneill {
461 1.1 jmcneill return (0);
462 1.1 jmcneill }
463 1.1 jmcneill
464 1.1 jmcneill int
465 1.1 jmcneill mavb_getdev(void *hdl, struct audio_device *ret)
466 1.1 jmcneill {
467 1.1 jmcneill *ret = mavb_device;
468 1.1 jmcneill return (0);
469 1.1 jmcneill }
470 1.1 jmcneill
471 1.1 jmcneill int
472 1.1 jmcneill mavb_set_port(void *hdl, struct mixer_ctrl *mc)
473 1.1 jmcneill {
474 1.1 jmcneill struct mavb_softc *sc = (struct mavb_softc *)hdl;
475 1.1 jmcneill u_char left, right;
476 1.1 jmcneill ad1843_addr_t reg;
477 1.1 jmcneill u_int16_t value;
478 1.1 jmcneill
479 1.1 jmcneill DPRINTF(1, ("%s: mavb_set_port: dev=%d\n", sc->sc_dev.dv_xname,
480 1.1 jmcneill mc->dev));
481 1.1 jmcneill
482 1.1 jmcneill switch (mc->dev) {
483 1.1 jmcneill case AD1843_ADC_SOURCE:
484 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
485 1.1 jmcneill value &= ~(AD1843_LSS_MASK | AD1843_RSS_MASK);
486 1.1 jmcneill value |= ((mc->un.ord << AD1843_LSS_SHIFT) & AD1843_LSS_MASK);
487 1.1 jmcneill value |= ((mc->un.ord << AD1843_RSS_SHIFT) & AD1843_RSS_MASK);
488 1.1 jmcneill ad1843_reg_write(sc, AD1843_ADC_SOURCE_GAIN, value);
489 1.1 jmcneill break;
490 1.1 jmcneill case AD1843_ADC_GAIN:
491 1.1 jmcneill left = mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
492 1.1 jmcneill right = mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
493 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
494 1.1 jmcneill value &= ~(AD1843_LIG_MASK | AD1843_RIG_MASK);
495 1.1 jmcneill value |= ((left >> 4) << AD1843_LIG_SHIFT);
496 1.1 jmcneill value |= ((right >> 4) << AD1843_RIG_SHIFT);
497 1.1 jmcneill ad1843_reg_write(sc, AD1843_ADC_SOURCE_GAIN, value);
498 1.1 jmcneill break;
499 1.1 jmcneill
500 1.1 jmcneill case AD1843_DAC1_GAIN:
501 1.1 jmcneill left = AUDIO_MAX_GAIN -
502 1.1 jmcneill mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
503 1.1 jmcneill right = AUDIO_MAX_GAIN -
504 1.1 jmcneill mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
505 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
506 1.1 jmcneill value &= ~(AD1843_LDA1G_MASK | AD1843_RDA1G_MASK);
507 1.1 jmcneill value |= ((left >> 2) << AD1843_LDA1G_SHIFT);
508 1.1 jmcneill value |= ((right >> 2) << AD1843_RDA1G_SHIFT);
509 1.1 jmcneill ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN, value);
510 1.1 jmcneill break;
511 1.1 jmcneill case AD1843_DAC1_MUTE:
512 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
513 1.1 jmcneill if (mc->un.ord == 0)
514 1.1 jmcneill value &= ~(AD1843_LDA1GM | AD1843_RDA1GM);
515 1.1 jmcneill else
516 1.1 jmcneill value |= (AD1843_LDA1GM | AD1843_RDA1GM);
517 1.1 jmcneill ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN, value);
518 1.1 jmcneill break;
519 1.1 jmcneill
520 1.1 jmcneill case AD1843_DAC2_GAIN:
521 1.1 jmcneill case AD1843_AUX1_GAIN:
522 1.1 jmcneill case AD1843_AUX2_GAIN:
523 1.1 jmcneill case AD1843_AUX3_GAIN:
524 1.1 jmcneill case AD1843_MIC_GAIN:
525 1.1 jmcneill left = AUDIO_MAX_GAIN -
526 1.1 jmcneill mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
527 1.1 jmcneill right = AUDIO_MAX_GAIN -
528 1.1 jmcneill mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
529 1.1 jmcneill reg = AD1843_DAC2_TO_MIXER + mc->dev - AD1843_DAC2_GAIN;
530 1.1 jmcneill value = ad1843_reg_read(sc, reg);
531 1.1 jmcneill value &= ~(AD1843_LD2M_MASK | AD1843_RD2M_MASK);
532 1.1 jmcneill value |= ((left >> 3) << AD1843_LD2M_SHIFT);
533 1.1 jmcneill value |= ((right >> 3) << AD1843_RD2M_SHIFT);
534 1.1 jmcneill ad1843_reg_write(sc, reg, value);
535 1.1 jmcneill break;
536 1.1 jmcneill case AD1843_MONO_GAIN:
537 1.1 jmcneill left = AUDIO_MAX_GAIN -
538 1.1 jmcneill mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
539 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
540 1.1 jmcneill value &= ~AD1843_MNM_MASK;
541 1.1 jmcneill value |= ((left >> 3) << AD1843_MNM_SHIFT);
542 1.1 jmcneill ad1843_reg_write(sc, AD1843_MISC_SETTINGS, value);
543 1.1 jmcneill break;
544 1.1 jmcneill case AD1843_DAC2_MUTE:
545 1.1 jmcneill case AD1843_AUX1_MUTE:
546 1.1 jmcneill case AD1843_AUX2_MUTE:
547 1.1 jmcneill case AD1843_AUX3_MUTE:
548 1.1 jmcneill case AD1843_MIC_MUTE:
549 1.1 jmcneill case AD1843_MONO_MUTE: /* matches left channel */
550 1.1 jmcneill reg = AD1843_DAC2_TO_MIXER + mc->dev - AD1843_DAC2_MUTE;
551 1.1 jmcneill value = ad1843_reg_read(sc, reg);
552 1.1 jmcneill if (mc->un.ord == 0)
553 1.1 jmcneill value &= ~(AD1843_LD2MM | AD1843_RD2MM);
554 1.1 jmcneill else
555 1.1 jmcneill value |= (AD1843_LD2MM | AD1843_RD2MM);
556 1.1 jmcneill ad1843_reg_write(sc, reg, value);
557 1.1 jmcneill break;
558 1.1 jmcneill
559 1.1 jmcneill case AD1843_SUM_MUTE:
560 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
561 1.1 jmcneill if (mc->un.ord == 0)
562 1.1 jmcneill value &= ~AD1843_SUMM;
563 1.1 jmcneill else
564 1.1 jmcneill value |= AD1843_SUMM;
565 1.1 jmcneill ad1843_reg_write(sc, AD1843_MISC_SETTINGS, value);
566 1.1 jmcneill break;
567 1.1 jmcneill
568 1.1 jmcneill case AD1843_MNO_MUTE:
569 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
570 1.1 jmcneill if (mc->un.ord == 0)
571 1.1 jmcneill value &= ~AD1843_MNOM;
572 1.1 jmcneill else
573 1.1 jmcneill value |= AD1843_MNOM;
574 1.1 jmcneill ad1843_reg_write(sc, AD1843_MISC_SETTINGS, value);
575 1.1 jmcneill break;
576 1.1 jmcneill
577 1.1 jmcneill case AD1843_HPO_MUTE:
578 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
579 1.1 jmcneill if (mc->un.ord == 0)
580 1.1 jmcneill value &= ~AD1843_HPOM;
581 1.1 jmcneill else
582 1.1 jmcneill value |= AD1843_HPOM;
583 1.1 jmcneill ad1843_reg_write(sc, AD1843_MISC_SETTINGS, value);
584 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
585 1.1 jmcneill break;
586 1.1 jmcneill
587 1.1 jmcneill default:
588 1.1 jmcneill return (EINVAL);
589 1.1 jmcneill }
590 1.1 jmcneill
591 1.1 jmcneill return (0);
592 1.1 jmcneill }
593 1.1 jmcneill
594 1.1 jmcneill int
595 1.1 jmcneill mavb_get_port(void *hdl, struct mixer_ctrl *mc)
596 1.1 jmcneill {
597 1.1 jmcneill struct mavb_softc *sc = (struct mavb_softc *)hdl;
598 1.1 jmcneill u_char left, right;
599 1.1 jmcneill ad1843_addr_t reg;
600 1.1 jmcneill u_int16_t value;
601 1.1 jmcneill
602 1.1 jmcneill DPRINTF(1, ("%s: mavb_get_port: dev=%d\n", sc->sc_dev.dv_xname,
603 1.1 jmcneill mc->dev));
604 1.1 jmcneill
605 1.1 jmcneill switch (mc->dev) {
606 1.1 jmcneill case AD1843_ADC_SOURCE:
607 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
608 1.1 jmcneill mc->un.ord = (value & AD1843_LSS_MASK) >> AD1843_LSS_SHIFT;
609 1.1 jmcneill break;
610 1.1 jmcneill case AD1843_ADC_GAIN:
611 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
612 1.1 jmcneill left = (value & AD1843_LIG_MASK) >> AD1843_LIG_SHIFT;
613 1.1 jmcneill right = (value & AD1843_RIG_MASK) >> AD1843_RIG_SHIFT;
614 1.1 jmcneill mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
615 1.1 jmcneill (left << 4) | left;
616 1.1 jmcneill mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
617 1.1 jmcneill (right << 2) | right;
618 1.1 jmcneill break;
619 1.1 jmcneill
620 1.1 jmcneill case AD1843_DAC1_GAIN:
621 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
622 1.1 jmcneill left = (value & AD1843_LDA1G_MASK) >> AD1843_LDA1G_SHIFT;
623 1.1 jmcneill right = (value & AD1843_RDA1G_MASK) >> AD1843_RDA1G_SHIFT;
624 1.1 jmcneill mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
625 1.1 jmcneill AUDIO_MAX_GAIN - (left << 2);
626 1.1 jmcneill mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
627 1.1 jmcneill AUDIO_MAX_GAIN - (right << 2);
628 1.1 jmcneill break;
629 1.1 jmcneill case AD1843_DAC1_MUTE:
630 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
631 1.1 jmcneill mc->un.ord = (value & AD1843_LDA1GM) ? 1 : 0;
632 1.1 jmcneill break;
633 1.1 jmcneill
634 1.1 jmcneill case AD1843_DAC2_GAIN:
635 1.1 jmcneill case AD1843_AUX1_GAIN:
636 1.1 jmcneill case AD1843_AUX2_GAIN:
637 1.1 jmcneill case AD1843_AUX3_GAIN:
638 1.1 jmcneill case AD1843_MIC_GAIN:
639 1.1 jmcneill reg = AD1843_DAC2_TO_MIXER + mc->dev - AD1843_DAC2_GAIN;
640 1.1 jmcneill value = ad1843_reg_read(sc, reg);
641 1.1 jmcneill left = (value & AD1843_LD2M_MASK) >> AD1843_LD2M_SHIFT;
642 1.1 jmcneill right = (value & AD1843_RD2M_MASK) >> AD1843_RD2M_SHIFT;
643 1.1 jmcneill mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
644 1.1 jmcneill AUDIO_MAX_GAIN - (left << 3);
645 1.1 jmcneill mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
646 1.1 jmcneill AUDIO_MAX_GAIN - (right << 3);
647 1.1 jmcneill break;
648 1.1 jmcneill case AD1843_MONO_GAIN:
649 1.1 jmcneill if (mc->un.value.num_channels != 1)
650 1.1 jmcneill return (EINVAL);
651 1.1 jmcneill
652 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
653 1.1 jmcneill left = (value & AD1843_MNM_MASK) >> AD1843_MNM_SHIFT;
654 1.1 jmcneill mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
655 1.1 jmcneill AUDIO_MAX_GAIN - (left << 3);
656 1.1 jmcneill break;
657 1.1 jmcneill case AD1843_DAC2_MUTE:
658 1.1 jmcneill case AD1843_AUX1_MUTE:
659 1.1 jmcneill case AD1843_AUX2_MUTE:
660 1.1 jmcneill case AD1843_AUX3_MUTE:
661 1.1 jmcneill case AD1843_MIC_MUTE:
662 1.1 jmcneill case AD1843_MONO_MUTE: /* matches left channel */
663 1.1 jmcneill reg = AD1843_DAC2_TO_MIXER + mc->dev - AD1843_DAC2_MUTE;
664 1.1 jmcneill value = ad1843_reg_read(sc, reg);
665 1.1 jmcneill mc->un.ord = (value & AD1843_LD2MM) ? 1 : 0;
666 1.1 jmcneill break;
667 1.1 jmcneill
668 1.1 jmcneill case AD1843_SUM_MUTE:
669 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
670 1.1 jmcneill mc->un.ord = (value & AD1843_SUMM) ? 1 : 0;
671 1.1 jmcneill break;
672 1.1 jmcneill
673 1.1 jmcneill case AD1843_MNO_MUTE:
674 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
675 1.1 jmcneill mc->un.ord = (value & AD1843_MNOM) ? 1 : 0;
676 1.1 jmcneill break;
677 1.1 jmcneill
678 1.1 jmcneill case AD1843_HPO_MUTE:
679 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
680 1.1 jmcneill mc->un.ord = (value & AD1843_HPOM) ? 1 : 0;
681 1.1 jmcneill break;
682 1.1 jmcneill
683 1.1 jmcneill default:
684 1.1 jmcneill return (EINVAL);
685 1.1 jmcneill }
686 1.1 jmcneill
687 1.1 jmcneill return (0);
688 1.1 jmcneill }
689 1.1 jmcneill
690 1.1 jmcneill int
691 1.1 jmcneill mavb_query_devinfo(void *hdl, struct mixer_devinfo *di)
692 1.1 jmcneill {
693 1.1 jmcneill int i;
694 1.1 jmcneill
695 1.1 jmcneill di->prev = di->next = AUDIO_MIXER_LAST;
696 1.1 jmcneill
697 1.1 jmcneill switch (di->index) {
698 1.1 jmcneill case AD1843_RECORD_CLASS:
699 1.1 jmcneill di->type = AUDIO_MIXER_CLASS;
700 1.1 jmcneill di->mixer_class = AD1843_RECORD_CLASS;
701 1.1 jmcneill strlcpy(di->label.name, AudioCrecord, sizeof di->label.name);
702 1.1 jmcneill break;
703 1.1 jmcneill
704 1.1 jmcneill case AD1843_ADC_SOURCE:
705 1.1 jmcneill di->type = AUDIO_MIXER_ENUM;
706 1.1 jmcneill di->mixer_class = AD1843_RECORD_CLASS;
707 1.1 jmcneill di->next = AD1843_ADC_GAIN;
708 1.1 jmcneill strlcpy(di->label.name, AudioNsource, sizeof di->label.name);
709 1.1 jmcneill di->un.e.num_mem =
710 1.1 jmcneill sizeof ad1843_source / sizeof ad1843_source[1];
711 1.1 jmcneill for (i = 0; i < di->un.e.num_mem; i++) {
712 1.1 jmcneill strlcpy(di->un.e.member[i].label.name,
713 1.1 jmcneill ad1843_source[i],
714 1.1 jmcneill sizeof di->un.e.member[0].label.name);
715 1.1 jmcneill di->un.e.member[i].ord = i;
716 1.1 jmcneill }
717 1.1 jmcneill break;
718 1.1 jmcneill case AD1843_ADC_GAIN:
719 1.1 jmcneill di->type = AUDIO_MIXER_VALUE;
720 1.1 jmcneill di->mixer_class = AD1843_RECORD_CLASS;
721 1.1 jmcneill di->prev = AD1843_ADC_SOURCE;
722 1.1 jmcneill strlcpy(di->label.name, AudioNvolume, sizeof di->label.name);
723 1.1 jmcneill di->un.v.num_channels = 2;
724 1.1 jmcneill strlcpy(di->un.v.units.name, AudioNvolume,
725 1.1 jmcneill sizeof di->un.v.units.name);
726 1.1 jmcneill break;
727 1.1 jmcneill
728 1.1 jmcneill case AD1843_INPUT_CLASS:
729 1.1 jmcneill di->type = AUDIO_MIXER_CLASS;
730 1.1 jmcneill di->mixer_class = AD1843_INPUT_CLASS;
731 1.1 jmcneill strlcpy(di->label.name, AudioCinputs, sizeof di->label.name);
732 1.1 jmcneill break;
733 1.1 jmcneill
734 1.1 jmcneill case AD1843_DAC1_GAIN:
735 1.1 jmcneill di->type = AUDIO_MIXER_VALUE;
736 1.1 jmcneill di->mixer_class = AD1843_INPUT_CLASS;
737 1.1 jmcneill di->next = AD1843_DAC1_MUTE;
738 1.1 jmcneill strlcpy(di->label.name, AudioNdac "1", sizeof di->label.name);
739 1.1 jmcneill di->un.v.num_channels = 2;
740 1.1 jmcneill strlcpy(di->un.v.units.name, AudioNvolume,
741 1.1 jmcneill sizeof di->un.v.units.name);
742 1.1 jmcneill break;
743 1.1 jmcneill case AD1843_DAC1_MUTE:
744 1.1 jmcneill di->type = AUDIO_MIXER_ENUM;
745 1.1 jmcneill di->mixer_class = AD1843_INPUT_CLASS;
746 1.1 jmcneill di->prev = AD1843_DAC1_GAIN;
747 1.1 jmcneill strlcpy(di->label.name, AudioNmute, sizeof di->label.name);
748 1.1 jmcneill di->un.e.num_mem = 2;
749 1.1 jmcneill strlcpy(di->un.e.member[0].label.name, AudioNoff,
750 1.1 jmcneill sizeof di->un.e.member[0].label.name);
751 1.1 jmcneill di->un.e.member[0].ord = 0;
752 1.1 jmcneill strlcpy(di->un.e.member[1].label.name, AudioNon,
753 1.1 jmcneill sizeof di->un.e.member[1].label.name);
754 1.1 jmcneill di->un.e.member[1].ord = 1;
755 1.1 jmcneill break;
756 1.1 jmcneill
757 1.1 jmcneill case AD1843_DAC2_GAIN:
758 1.1 jmcneill case AD1843_AUX1_GAIN:
759 1.1 jmcneill case AD1843_AUX2_GAIN:
760 1.1 jmcneill case AD1843_AUX3_GAIN:
761 1.1 jmcneill case AD1843_MIC_GAIN:
762 1.1 jmcneill case AD1843_MONO_GAIN:
763 1.1 jmcneill di->type = AUDIO_MIXER_VALUE;
764 1.1 jmcneill di->mixer_class = AD1843_INPUT_CLASS;
765 1.1 jmcneill di->next = di->index + AD1843_DAC2_MUTE - AD1843_DAC2_GAIN;
766 1.1 jmcneill strlcpy(di->label.name,
767 1.1 jmcneill ad1843_input[di->index - AD1843_DAC2_GAIN],
768 1.1 jmcneill sizeof di->label.name);
769 1.1 jmcneill if (di->index == AD1843_MONO_GAIN)
770 1.1 jmcneill di->un.v.num_channels = 1;
771 1.1 jmcneill else
772 1.1 jmcneill di->un.v.num_channels = 2;
773 1.1 jmcneill strlcpy(di->un.v.units.name, AudioNvolume,
774 1.1 jmcneill sizeof di->un.v.units.name);
775 1.1 jmcneill break;
776 1.1 jmcneill case AD1843_DAC2_MUTE:
777 1.1 jmcneill case AD1843_AUX1_MUTE:
778 1.1 jmcneill case AD1843_AUX2_MUTE:
779 1.1 jmcneill case AD1843_AUX3_MUTE:
780 1.1 jmcneill case AD1843_MIC_MUTE:
781 1.1 jmcneill case AD1843_MONO_MUTE:
782 1.1 jmcneill di->type = AUDIO_MIXER_ENUM;
783 1.1 jmcneill di->mixer_class = AD1843_INPUT_CLASS;
784 1.1 jmcneill di->prev = di->index + AD1843_DAC2_GAIN - AD1843_DAC2_MUTE;
785 1.1 jmcneill strlcpy(di->label.name, AudioNmute, sizeof di->label.name);
786 1.1 jmcneill di->un.e.num_mem = 2;
787 1.1 jmcneill strlcpy(di->un.e.member[0].label.name, AudioNoff,
788 1.1 jmcneill sizeof di->un.e.member[0].label.name);
789 1.1 jmcneill di->un.e.member[0].ord = 0;
790 1.1 jmcneill strlcpy(di->un.e.member[1].label.name, AudioNon,
791 1.1 jmcneill sizeof di->un.e.member[1].label.name);
792 1.1 jmcneill di->un.e.member[1].ord = 1;
793 1.1 jmcneill break;
794 1.1 jmcneill
795 1.1 jmcneill case AD1843_SUM_MUTE:
796 1.1 jmcneill di->type = AUDIO_MIXER_ENUM;
797 1.1 jmcneill di->mixer_class = AD1843_INPUT_CLASS;
798 1.1 jmcneill strlcpy(di->label.name, "sum." AudioNmute,
799 1.1 jmcneill sizeof di->label.name);
800 1.1 jmcneill di->un.e.num_mem = 2;
801 1.1 jmcneill strlcpy(di->un.e.member[0].label.name, AudioNoff,
802 1.1 jmcneill sizeof di->un.e.member[0].label.name);
803 1.1 jmcneill di->un.e.member[0].ord = 0;
804 1.1 jmcneill strlcpy(di->un.e.member[1].label.name, AudioNon,
805 1.1 jmcneill sizeof di->un.e.member[1].label.name);
806 1.1 jmcneill di->un.e.member[1].ord = 1;
807 1.1 jmcneill break;
808 1.1 jmcneill
809 1.1 jmcneill case AD1843_OUTPUT_CLASS:
810 1.1 jmcneill di->type = AUDIO_MIXER_CLASS;
811 1.1 jmcneill di->mixer_class = AD1843_OUTPUT_CLASS;
812 1.1 jmcneill strlcpy(di->label.name, AudioCoutputs, sizeof di->label.name);
813 1.1 jmcneill break;
814 1.1 jmcneill
815 1.1 jmcneill case AD1843_MNO_MUTE:
816 1.1 jmcneill di->type = AUDIO_MIXER_ENUM;
817 1.1 jmcneill di->mixer_class = AD1843_OUTPUT_CLASS;
818 1.1 jmcneill strlcpy(di->label.name, AudioNmono "." AudioNmute,
819 1.1 jmcneill sizeof di->label.name);
820 1.1 jmcneill di->un.e.num_mem = 2;
821 1.1 jmcneill strlcpy(di->un.e.member[0].label.name, AudioNoff,
822 1.1 jmcneill sizeof di->un.e.member[0].label.name);
823 1.1 jmcneill di->un.e.member[0].ord = 0;
824 1.1 jmcneill strlcpy(di->un.e.member[1].label.name, AudioNon,
825 1.1 jmcneill sizeof di->un.e.member[1].label.name);
826 1.1 jmcneill di->un.e.member[1].ord = 1;
827 1.1 jmcneill break;
828 1.1 jmcneill
829 1.1 jmcneill case AD1843_HPO_MUTE:
830 1.1 jmcneill di->type = AUDIO_MIXER_ENUM;
831 1.1 jmcneill di->mixer_class = AD1843_OUTPUT_CLASS;
832 1.1 jmcneill strlcpy(di->label.name, AudioNheadphone "." AudioNmute,
833 1.1 jmcneill sizeof di->label.name);
834 1.1 jmcneill di->un.e.num_mem = 2;
835 1.1 jmcneill strlcpy(di->un.e.member[0].label.name, AudioNoff,
836 1.1 jmcneill sizeof di->un.e.member[0].label.name);
837 1.1 jmcneill di->un.e.member[0].ord = 0;
838 1.1 jmcneill strlcpy(di->un.e.member[1].label.name, AudioNon,
839 1.1 jmcneill sizeof di->un.e.member[1].label.name);
840 1.1 jmcneill di->un.e.member[1].ord = 1;
841 1.1 jmcneill break;
842 1.1 jmcneill
843 1.1 jmcneill default:
844 1.1 jmcneill return (EINVAL);
845 1.1 jmcneill }
846 1.1 jmcneill
847 1.1 jmcneill return (0);
848 1.1 jmcneill }
849 1.1 jmcneill
850 1.1 jmcneill size_t
851 1.1 jmcneill mavb_round_buffersize(void *hdl, int dir, size_t bufsize)
852 1.1 jmcneill {
853 1.1 jmcneill
854 1.1 jmcneill return bufsize;
855 1.1 jmcneill }
856 1.1 jmcneill
857 1.1 jmcneill int
858 1.1 jmcneill mavb_get_props(void *hdl)
859 1.1 jmcneill {
860 1.1 jmcneill return (AUDIO_PROP_FULLDUPLEX | AUDIO_PROP_INDEPENDENT);
861 1.1 jmcneill }
862 1.1 jmcneill
863 1.1 jmcneill static void
864 1.1 jmcneill mavb_dma_output(struct mavb_softc *sc)
865 1.1 jmcneill {
866 1.1 jmcneill bus_space_tag_t st = sc->sc_st;
867 1.1 jmcneill bus_space_handle_t sh = sc->sc_sh;
868 1.1 jmcneill u_int64_t write_ptr;
869 1.1 jmcneill u_int64_t depth;
870 1.1 jmcneill uint8_t *src, *dst;
871 1.1 jmcneill int count;
872 1.1 jmcneill
873 1.1 jmcneill write_ptr = bus_space_read_8(st, sh, MAVB_CHANNEL2_WRITE_PTR);
874 1.1 jmcneill depth = bus_space_read_8(st, sh, MAVB_CHANNEL2_DEPTH);
875 1.1 jmcneill
876 1.1 jmcneill dst = sc->sc_ring + write_ptr;
877 1.1 jmcneill src = sc->sc_get;
878 1.1 jmcneill
879 1.1 jmcneill count = (MAVB_ISA_RING_SIZE - depth - 32);
880 1.1 jmcneill while (--count >= 0) {
881 1.1 jmcneill *dst++ = *src++;
882 1.1 jmcneill if (dst >= sc->sc_ring + MAVB_ISA_RING_SIZE)
883 1.1 jmcneill dst = sc->sc_ring;
884 1.1 jmcneill if (src >= sc->sc_end)
885 1.1 jmcneill src = sc->sc_start;
886 1.1 jmcneill if (++sc->sc_count >= sc->sc_blksize) {
887 1.1 jmcneill if (sc->sc_intr)
888 1.1 jmcneill sc->sc_intr(sc->sc_intrarg);
889 1.1 jmcneill sc->sc_count = 0;
890 1.1 jmcneill }
891 1.1 jmcneill }
892 1.1 jmcneill
893 1.1 jmcneill write_ptr = dst - sc->sc_ring;
894 1.1 jmcneill bus_space_write_8(st, sh, MAVB_CHANNEL2_WRITE_PTR, write_ptr);
895 1.1 jmcneill sc->sc_get = src;
896 1.1 jmcneill }
897 1.1 jmcneill
898 1.1 jmcneill int
899 1.1 jmcneill mavb_trigger_output(void *hdl, void *start, void *end, int blksize,
900 1.1 jmcneill void (*intr)(void *), void *intrarg,
901 1.1 jmcneill const audio_params_t *param)
902 1.1 jmcneill {
903 1.1 jmcneill struct mavb_softc *sc = (struct mavb_softc *)hdl;
904 1.1 jmcneill
905 1.1 jmcneill DPRINTF(1, ("%s: mavb_trigger_output: start=%p end=%p "
906 1.1 jmcneill "blksize=%d intr=%p(%p)\n", sc->sc_dev.dv_xname,
907 1.1 jmcneill start, end, blksize, intr, intrarg));
908 1.1 jmcneill
909 1.1 jmcneill sc->sc_blksize = blksize;
910 1.1 jmcneill sc->sc_intr = intr;
911 1.1 jmcneill sc->sc_intrarg = intrarg;
912 1.1 jmcneill
913 1.1 jmcneill sc->sc_start = sc->sc_get = start;
914 1.1 jmcneill sc->sc_end = end;
915 1.1 jmcneill
916 1.1 jmcneill sc->sc_count = 0;
917 1.1 jmcneill
918 1.1 jmcneill bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL,
919 1.1 jmcneill MAVB_CHANNEL_RESET);
920 1.1 jmcneill delay(1000);
921 1.1 jmcneill bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL, 0);
922 1.1 jmcneill
923 1.1 jmcneill mavb_dma_output(sc);
924 1.1 jmcneill
925 1.1 jmcneill bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL,
926 1.1 jmcneill MAVB_CHANNEL_DMA_ENABLE | MAVB_CHANNEL_INT_50);
927 1.1 jmcneill return (0);
928 1.1 jmcneill }
929 1.1 jmcneill
930 1.1 jmcneill int
931 1.1 jmcneill mavb_trigger_input(void *hdl, void *start, void *end, int blksize,
932 1.1 jmcneill void (*intr)(void *), void *intrarg,
933 1.1 jmcneill const audio_params_t *param)
934 1.1 jmcneill {
935 1.1 jmcneill return (0);
936 1.1 jmcneill }
937 1.1 jmcneill
938 1.1 jmcneill static void
939 1.1 jmcneill mavb_button_repeat(void *hdl)
940 1.1 jmcneill {
941 1.1 jmcneill struct mavb_softc *sc = (struct mavb_softc *)hdl;
942 1.1 jmcneill u_int64_t intmask, control;
943 1.1 jmcneill u_int16_t value, left, right;
944 1.1 jmcneill
945 1.1 jmcneill DPRINTF(1, ("%s: mavb_repeat called\n", sc->sc_dev.dv_xname));
946 1.1 jmcneill
947 1.1 jmcneill #define MAVB_CONTROL_VOLUME_BUTTONS \
948 1.1 jmcneill (MAVB_CONTROL_VOLUME_BUTTON_UP | MAVB_CONTROL_VOLUME_BUTTON_DOWN)
949 1.1 jmcneill
950 1.1 jmcneill control = bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL);
951 1.1 jmcneill if (control & MAVB_CONTROL_VOLUME_BUTTONS) {
952 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
953 1.1 jmcneill left = (value & AD1843_LDA1G_MASK) >> AD1843_LDA1G_SHIFT;
954 1.1 jmcneill right = (value & AD1843_RDA1G_MASK) >> AD1843_RDA1G_SHIFT;
955 1.1 jmcneill if (control & MAVB_CONTROL_VOLUME_BUTTON_UP) {
956 1.1 jmcneill control &= ~MAVB_CONTROL_VOLUME_BUTTON_UP;
957 1.1 jmcneill if (left > 0)
958 1.1 jmcneill left--; /* attenuation! */
959 1.1 jmcneill if (right > 0)
960 1.1 jmcneill right--;
961 1.1 jmcneill }
962 1.1 jmcneill if (control & MAVB_CONTROL_VOLUME_BUTTON_DOWN) {
963 1.1 jmcneill control &= ~MAVB_CONTROL_VOLUME_BUTTON_DOWN;
964 1.1 jmcneill if (left < 63)
965 1.1 jmcneill left++;
966 1.1 jmcneill if (right < 63)
967 1.1 jmcneill right++;
968 1.1 jmcneill }
969 1.1 jmcneill bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL, control);
970 1.1 jmcneill
971 1.1 jmcneill value &= ~(AD1843_LDA1G_MASK | AD1843_RDA1G_MASK);
972 1.1 jmcneill value |= (left << AD1843_LDA1G_SHIFT);
973 1.1 jmcneill value |= (right << AD1843_RDA1G_SHIFT);
974 1.1 jmcneill ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN, value);
975 1.1 jmcneill
976 1.1 jmcneill callout_reset(&sc->sc_volume_button_ch,
977 1.1 jmcneill (hz * MAVB_VOLUME_BUTTON_REPEAT_DELN) / 1000,
978 1.1 jmcneill mavb_button_repeat, sc);
979 1.1 jmcneill //timeout_add(&sc->sc_volume_button_to,
980 1.1 jmcneill // (hz * MAVB_VOLUME_BUTTON_REPEAT_DELN) / 1000);
981 1.1 jmcneill } else {
982 1.1 jmcneill /* Enable volume button interrupts again. */
983 1.1 jmcneill intmask = bus_space_read_8(sc->sc_st, sc->sc_isash,
984 1.1 jmcneill MACE_ISA_INT_MASK);
985 1.1 jmcneill bus_space_write_8(sc->sc_st, sc->sc_isash, MACE_ISA_INT_MASK,
986 1.1 jmcneill intmask | MACE_ISA_INT_AUDIO_SC);
987 1.1 jmcneill }
988 1.1 jmcneill }
989 1.1 jmcneill
990 1.1 jmcneill static int
991 1.1 jmcneill mavb_intr(void *arg)
992 1.1 jmcneill {
993 1.1 jmcneill struct mavb_softc *sc = arg;
994 1.1 jmcneill u_int64_t stat, intmask;
995 1.1 jmcneill
996 1.1 jmcneill stat = bus_space_read_8(sc->sc_st, sc->sc_isash, MACE_ISA_INT_STATUS);
997 1.1 jmcneill DPRINTF(MAVB_DEBUG_INTR, ("%s: mavb_intr: stat = 0x%llx\n",
998 1.1 jmcneill sc->sc_dev.dv_xname, stat));
999 1.1 jmcneill
1000 1.1 jmcneill if (stat & MACE_ISA_INT_AUDIO_SC) {
1001 1.1 jmcneill /* Disable volume button interrupts. */
1002 1.1 jmcneill intmask = bus_space_read_8(sc->sc_st, sc->sc_isash,
1003 1.1 jmcneill MACE_ISA_INT_MASK);
1004 1.1 jmcneill bus_space_write_8(sc->sc_st, sc->sc_isash, MACE_ISA_INT_MASK,
1005 1.1 jmcneill intmask & ~MACE_ISA_INT_AUDIO_SC);
1006 1.1 jmcneill
1007 1.1 jmcneill callout_reset(&sc->sc_volume_button_ch,
1008 1.1 jmcneill (hz * MAVB_VOLUME_BUTTON_REPEAT_DEL1) / 1000,
1009 1.1 jmcneill mavb_button_repeat, sc);
1010 1.1 jmcneill //timeout_add(&sc->sc_volume_button_to,
1011 1.1 jmcneill // (hz * MAVB_VOLUME_BUTTON_REPEAT_DEL1) / 1000);
1012 1.1 jmcneill }
1013 1.1 jmcneill
1014 1.1 jmcneill if (stat & MACE_ISA_INT_AUDIO_DMA2)
1015 1.1 jmcneill mavb_dma_output(sc);
1016 1.1 jmcneill
1017 1.1 jmcneill return 1;
1018 1.1 jmcneill }
1019 1.1 jmcneill
1020 1.1 jmcneill int
1021 1.1 jmcneill mavb_match(struct device *parent, struct cfdata *match, void *aux)
1022 1.1 jmcneill {
1023 1.1 jmcneill return (1);
1024 1.1 jmcneill }
1025 1.1 jmcneill
1026 1.1 jmcneill void
1027 1.1 jmcneill mavb_attach(struct device *parent, struct device *self, void *aux)
1028 1.1 jmcneill {
1029 1.1 jmcneill struct mavb_softc *sc = (void *)self;
1030 1.1 jmcneill struct mace_attach_args *maa = aux;
1031 1.1 jmcneill bus_dma_segment_t seg;
1032 1.1 jmcneill u_int64_t control;
1033 1.1 jmcneill u_int16_t value;
1034 1.1 jmcneill int rseg;
1035 1.1 jmcneill
1036 1.1 jmcneill sc->sc_st = maa->maa_st;
1037 1.1 jmcneill if (bus_space_subregion(sc->sc_st, maa->maa_sh, maa->maa_offset,
1038 1.1 jmcneill 0, &sc->sc_sh) != 0) {
1039 1.1 jmcneill printf(": can't map i/o space\n");
1040 1.1 jmcneill return;
1041 1.1 jmcneill }
1042 1.1 jmcneill
1043 1.1 jmcneill /* XXX We need access to some of the MACE ISA registers. */
1044 1.1 jmcneill if (bus_space_subregion(sc->sc_st, maa->maa_sh, 0, 0,
1045 1.1 jmcneill &sc->sc_isash) != 0) {
1046 1.1 jmcneill printf(": can't map isa i/o space\n");
1047 1.1 jmcneill return;
1048 1.1 jmcneill }
1049 1.1 jmcneill
1050 1.1 jmcneill /* Set up DMA structures. */
1051 1.1 jmcneill sc->sc_dmat = maa->maa_dmat;
1052 1.1 jmcneill if (bus_dmamap_create(sc->sc_dmat, 4 * MAVB_ISA_RING_SIZE, 1,
1053 1.1 jmcneill 4 * MAVB_ISA_RING_SIZE, 0, 0, &sc->sc_dmamap)) {
1054 1.1 jmcneill printf(": can't create MACE ISA DMA map\n");
1055 1.1 jmcneill return;
1056 1.1 jmcneill }
1057 1.1 jmcneill
1058 1.1 jmcneill if (bus_dmamem_alloc(sc->sc_dmat, 4 * MAVB_ISA_RING_SIZE,
1059 1.1 jmcneill MACE_ISA_RING_ALIGN, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
1060 1.1 jmcneill printf(": can't allocate ring buffer\n");
1061 1.1 jmcneill return;
1062 1.1 jmcneill }
1063 1.1 jmcneill
1064 1.1 jmcneill if (bus_dmamem_map(sc->sc_dmat, &seg, rseg, 4 * MAVB_ISA_RING_SIZE,
1065 1.1 jmcneill (void *)&sc->sc_ring, BUS_DMA_COHERENT)) {
1066 1.1 jmcneill printf(": can't map ring buffer\n");
1067 1.1 jmcneill return;
1068 1.1 jmcneill }
1069 1.1 jmcneill
1070 1.1 jmcneill if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_ring,
1071 1.1 jmcneill 4 * MAVB_ISA_RING_SIZE, NULL, BUS_DMA_NOWAIT)) {
1072 1.1 jmcneill printf(": can't load MACE ISA DMA map\n");
1073 1.1 jmcneill return;
1074 1.1 jmcneill }
1075 1.1 jmcneill
1076 1.1 jmcneill sc->sc_ring += MAVB_ISA_RING_SIZE; /* XXX */
1077 1.1 jmcneill
1078 1.1 jmcneill bus_space_write_8(sc->sc_st, sc->sc_isash, MACE_ISA_RINGBASE,
1079 1.1 jmcneill sc->sc_dmamap->dm_segs[0].ds_addr);
1080 1.1 jmcneill
1081 1.1 jmcneill /* Establish interrupt. */
1082 1.1 jmcneill cpu_intr_establish(maa->maa_intr, maa->maa_intrmask,
1083 1.1 jmcneill mavb_intr, sc);
1084 1.1 jmcneill
1085 1.1 jmcneill control = bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL);
1086 1.1 jmcneill if (!(control & MAVB_CONTROL_CODEC_PRESENT)) {
1087 1.1 jmcneill printf(": no codec present\n");
1088 1.1 jmcneill return;
1089 1.1 jmcneill }
1090 1.1 jmcneill
1091 1.1 jmcneill /* 2. Assert the RESET signal. */
1092 1.1 jmcneill bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL,
1093 1.1 jmcneill MAVB_CONTROL_RESET);
1094 1.1 jmcneill delay(1); /* at least 100 ns */
1095 1.1 jmcneill
1096 1.1 jmcneill /* 3. Deassert the RESET signal and enter a wait period to
1097 1.1 jmcneill allow the AD1843 internal clocks and the external
1098 1.1 jmcneill crystal oscillator to stabilize. */
1099 1.1 jmcneill bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL, 0);
1100 1.1 jmcneill delay(800); /* typically 400 us to 800 us */
1101 1.1 jmcneill if (ad1843_reg_read(sc, AD1843_CODEC_STATUS) & AD1843_INIT) {
1102 1.1 jmcneill printf(": codec not ready\n");
1103 1.1 jmcneill return;
1104 1.1 jmcneill }
1105 1.1 jmcneill
1106 1.1 jmcneill /* 4. Put the conversion sources into standby. */
1107 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_FUNDAMENTAL_SETTINGS);
1108 1.1 jmcneill ad1843_reg_write(sc, AD1843_FUNDAMENTAL_SETTINGS,
1109 1.1 jmcneill value & ~AD1843_PDNI);
1110 1.1 jmcneill delay (500000); /* approximately 474 ms */
1111 1.1 jmcneill if (ad1843_reg_read(sc, AD1843_CODEC_STATUS) & AD1843_PDNO) {
1112 1.1 jmcneill printf(": can't power up conversion resources\n");
1113 1.1 jmcneill return;
1114 1.1 jmcneill }
1115 1.1 jmcneill
1116 1.1 jmcneill /* 5. Power up the clock generators and enable clock output pins. */
1117 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_FUNDAMENTAL_SETTINGS);
1118 1.1 jmcneill ad1843_reg_write(sc, AD1843_FUNDAMENTAL_SETTINGS, value | AD1843_C2EN);
1119 1.1 jmcneill
1120 1.1 jmcneill /* 6. Configure conversion resources while they are in standby. */
1121 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_CHANNEL_SAMPLE_RATE);
1122 1.1 jmcneill ad1843_reg_write(sc, AD1843_CHANNEL_SAMPLE_RATE,
1123 1.1 jmcneill value | (2 << AD1843_DA1C_SHIFT));
1124 1.1 jmcneill
1125 1.1 jmcneill /* 7. Enable conversion resources. */
1126 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_CHANNEL_POWER_DOWN);
1127 1.1 jmcneill ad1843_reg_write(sc, AD1843_CHANNEL_POWER_DOWN,
1128 1.1 jmcneill value | (AD1843_DA1EN | AD1843_AAMEN));
1129 1.1 jmcneill
1130 1.1 jmcneill /* 8. Configure conversion resources while they are enabled. */
1131 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
1132 1.1 jmcneill ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN,
1133 1.1 jmcneill value & ~(AD1843_LDA1GM | AD1843_RDA1GM));
1134 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_DAC1_DIGITAL_GAIN);
1135 1.1 jmcneill ad1843_reg_write(sc, AD1843_DAC1_DIGITAL_GAIN,
1136 1.1 jmcneill value & ~(AD1843_LDA1AM | AD1843_RDA1AM));
1137 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
1138 1.1 jmcneill ad1843_reg_write(sc, AD1843_MISC_SETTINGS,
1139 1.1 jmcneill value & ~(AD1843_HPOM | AD1843_MNOM));
1140 1.1 jmcneill
1141 1.1 jmcneill value = ad1843_reg_read(sc, AD1843_CODEC_STATUS);
1142 1.1 jmcneill printf(": AD1843 rev %d\n", (u_int)value & AD1843_REVISION_MASK);
1143 1.1 jmcneill
1144 1.1 jmcneill sc->sc_play_rate = 48000;
1145 1.1 jmcneill sc->sc_play_format = AD1843_PCM8;
1146 1.1 jmcneill
1147 1.1 jmcneill //timeout_set(&sc->sc_volume_button_to, mavb_button_repeat, sc);
1148 1.1 jmcneill callout_init(&sc->sc_volume_button_ch);
1149 1.1 jmcneill
1150 1.1 jmcneill audio_attach_mi(&mavb_sa_hw_if, sc, &sc->sc_dev);
1151 1.1 jmcneill
1152 1.1 jmcneill return;
1153 1.1 jmcneill }
1154 1.1 jmcneill
1155 1.1 jmcneill u_int16_t
1156 1.1 jmcneill ad1843_reg_read(struct mavb_softc *sc, ad1843_addr_t addr)
1157 1.1 jmcneill {
1158 1.1 jmcneill bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_CONTROL,
1159 1.1 jmcneill (addr & MAVB_CODEC_ADDRESS_MASK) << MAVB_CODEC_ADDRESS_SHIFT |
1160 1.1 jmcneill MAVB_CODEC_READ);
1161 1.1 jmcneill delay(200);
1162 1.1 jmcneill return bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_STATUS);
1163 1.1 jmcneill }
1164 1.1 jmcneill
1165 1.1 jmcneill u_int16_t
1166 1.1 jmcneill ad1843_reg_write(struct mavb_softc *sc, ad1843_addr_t addr, u_int16_t value)
1167 1.1 jmcneill {
1168 1.1 jmcneill bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_CONTROL,
1169 1.1 jmcneill (addr & MAVB_CODEC_ADDRESS_MASK) << MAVB_CODEC_ADDRESS_SHIFT |
1170 1.1 jmcneill (value & MAVB_CODEC_WORD_MASK) << MAVB_CODEC_WORD_SHIFT);
1171 1.1 jmcneill delay(200);
1172 1.1 jmcneill return bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_STATUS);
1173 1.1 jmcneill }
1174 1.1 jmcneill
1175 1.1 jmcneill void
1176 1.1 jmcneill ad1843_dump_regs(struct mavb_softc *sc)
1177 1.1 jmcneill {
1178 1.1 jmcneill u_int16_t addr;
1179 1.1 jmcneill
1180 1.1 jmcneill for (addr = 0; addr < AD1843_NREGS; addr++)
1181 1.1 jmcneill printf("%d: 0x%04x\n", addr, ad1843_reg_read(sc, addr));
1182 1.1 jmcneill }
1183