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