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