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