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