1 /* $NetBSD: mavb.c,v 1.14 2019/06/07 13:24:21 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
mavb_internal_to_slinear24_32(audio_filter_arg_t * arg)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
mavb_query_format(void * hdl,audio_format_query_t * afp)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
mavb_set_play_rate(struct mavb_softc * sc,u_long sample_rate)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
mavb_set_play_format(struct mavb_softc * sc,u_int encoding)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
mavb_set_format(void * hdl,int setmode,const audio_params_t * play,const audio_params_t * rec,audio_filter_reg_t * pfil,audio_filter_reg_t * rfil)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
mavb_round_blocksize(void * hdl,int bs,int mode,const audio_params_t * p)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
mavb_halt_output(void * hdl)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
mavb_halt_input(void * hdl)317 mavb_halt_input(void *hdl)
318 {
319
320 return 0;
321 }
322
323 int
mavb_getdev(void * hdl,struct audio_device * ret)324 mavb_getdev(void *hdl, struct audio_device *ret)
325 {
326
327 *ret = mavb_device;
328 return 0;
329 }
330
331 int
mavb_set_port(void * hdl,struct mixer_ctrl * mc)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
mavb_get_port(void * hdl,struct mixer_ctrl * mc)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
mavb_query_devinfo(void * hdl,struct mixer_devinfo * di)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
mavb_get_props(void * hdl)711 mavb_get_props(void *hdl)
712 {
713
714 return AUDIO_PROP_PLAYBACK;
715 }
716
717 static void
mavb_dma_output(struct mavb_softc * sc)718 mavb_dma_output(struct mavb_softc *sc)
719 {
720 bus_space_tag_t st = sc->sc_st;
721 bus_space_handle_t sh = sc->sc_sh;
722 uint64_t write_ptr;
723 uint64_t depth;
724 uint8_t *src, *dst;
725 int count;
726
727 KASSERT(mutex_owned(&sc->sc_intr_lock));
728
729 write_ptr = bus_space_read_8(st, sh, MAVB_CHANNEL2_WRITE_PTR);
730 depth = bus_space_read_8(st, sh, MAVB_CHANNEL2_DEPTH);
731
732 dst = sc->sc_ring + write_ptr;
733 src = sc->sc_get;
734
735 count = (MAVB_ISA_RING_SIZE - depth - 32);
736 while (--count >= 0) {
737 *dst++ = *src++;
738 if (dst >= sc->sc_ring + MAVB_ISA_RING_SIZE)
739 dst = sc->sc_ring;
740 if (src >= sc->sc_end)
741 src = sc->sc_start;
742 if (++sc->sc_count >= sc->sc_blksize) {
743 if (sc->sc_intr)
744 sc->sc_intr(sc->sc_intrarg);
745 sc->sc_count = 0;
746 }
747 }
748
749 write_ptr = dst - sc->sc_ring;
750 bus_space_write_8(st, sh, MAVB_CHANNEL2_WRITE_PTR, write_ptr);
751 sc->sc_get = src;
752 }
753
754 int
mavb_trigger_output(void * hdl,void * start,void * end,int blksize,void (* intr)(void *),void * intrarg,const audio_params_t * param)755 mavb_trigger_output(void *hdl, void *start, void *end, int blksize,
756 void (*intr)(void *), void *intrarg,
757 const audio_params_t *param)
758 {
759 struct mavb_softc *sc = (struct mavb_softc *)hdl;
760
761 DPRINTF(1, ("%s: mavb_trigger_output: start=%p end=%p "
762 "blksize=%d intr=%p(%p)\n", device_xname(sc->sc_dev),
763 start, end, blksize, intr, intrarg));
764
765 sc->sc_blksize = blksize;
766 sc->sc_intr = intr;
767 sc->sc_intrarg = intrarg;
768
769 sc->sc_start = sc->sc_get = start;
770 sc->sc_end = end;
771
772 sc->sc_count = 0;
773
774 bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL,
775 MAVB_CHANNEL_RESET);
776 delay(1000);
777 bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL, 0);
778
779 mavb_dma_output(sc);
780
781 bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL,
782 MAVB_CHANNEL_DMA_ENABLE | MAVB_CHANNEL_INT_50);
783
784 return 0;
785 }
786
787 int
mavb_trigger_input(void * hdl,void * start,void * end,int blksize,void (* intr)(void *),void * intrarg,const audio_params_t * param)788 mavb_trigger_input(void *hdl, void *start, void *end, int blksize,
789 void (*intr)(void *), void *intrarg,
790 const audio_params_t *param)
791 {
792
793 return 0;
794 }
795
796 void
mavb_get_locks(void * hdl,kmutex_t ** intr,kmutex_t ** thread)797 mavb_get_locks(void *hdl, kmutex_t **intr, kmutex_t **thread)
798 {
799 struct mavb_softc *sc = (struct mavb_softc *)hdl;
800
801 *intr = &sc->sc_intr_lock;
802 *thread = &sc->sc_lock;
803 }
804
805 static void
mavb_button_repeat(void * hdl)806 mavb_button_repeat(void *hdl)
807 {
808 struct mavb_softc *sc = (struct mavb_softc *)hdl;
809 uint64_t intmask, control;
810 uint16_t value, left, right;
811
812 DPRINTF(1, ("%s: mavb_repeat called\n", device_xname(sc->sc_dev)));
813
814 #define MAVB_CONTROL_VOLUME_BUTTONS \
815 (MAVB_CONTROL_VOLUME_BUTTON_UP | MAVB_CONTROL_VOLUME_BUTTON_DOWN)
816
817 control = bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL);
818 if (control & MAVB_CONTROL_VOLUME_BUTTONS) {
819 value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
820 left = (value & AD1843_LDA1G_MASK) >> AD1843_LDA1G_SHIFT;
821 right = (value & AD1843_RDA1G_MASK) >> AD1843_RDA1G_SHIFT;
822 if (control & MAVB_CONTROL_VOLUME_BUTTON_UP) {
823 control &= ~MAVB_CONTROL_VOLUME_BUTTON_UP;
824 if (left > 0)
825 left--; /* attenuation! */
826 if (right > 0)
827 right--;
828 }
829 if (control & MAVB_CONTROL_VOLUME_BUTTON_DOWN) {
830 control &= ~MAVB_CONTROL_VOLUME_BUTTON_DOWN;
831 if (left < 63)
832 left++;
833 if (right < 63)
834 right++;
835 }
836 bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL, control);
837
838 value &= ~(AD1843_LDA1G_MASK | AD1843_RDA1G_MASK);
839 value |= (left << AD1843_LDA1G_SHIFT);
840 value |= (right << AD1843_RDA1G_SHIFT);
841 ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN, value);
842
843 callout_reset(&sc->sc_volume_button_ch,
844 (hz * MAVB_VOLUME_BUTTON_REPEAT_DELN) / 1000,
845 mavb_button_repeat, sc);
846 } else {
847 /* Enable volume button interrupts again. */
848 intmask = bus_space_read_8(sc->sc_st, sc->sc_isash,
849 MACE_ISA_INT_MASK);
850 bus_space_write_8(sc->sc_st, sc->sc_isash, MACE_ISA_INT_MASK,
851 intmask | MACE_ISA_INT_AUDIO_SC);
852 }
853 }
854
855 static int
mavb_intr(void * arg)856 mavb_intr(void *arg)
857 {
858 struct mavb_softc *sc = arg;
859 uint64_t stat, intmask;
860
861 mutex_spin_enter(&sc->sc_intr_lock);
862
863 stat = bus_space_read_8(sc->sc_st, sc->sc_isash, MACE_ISA_INT_STATUS);
864 DPRINTF(MAVB_DEBUG_INTR, ("%s: mavb_intr: stat = 0x%llx\n",
865 device_xname(sc->sc_dev), stat));
866
867 if (stat & MACE_ISA_INT_AUDIO_SC) {
868 /* Disable volume button interrupts. */
869 intmask = bus_space_read_8(sc->sc_st, sc->sc_isash,
870 MACE_ISA_INT_MASK);
871 bus_space_write_8(sc->sc_st, sc->sc_isash, MACE_ISA_INT_MASK,
872 intmask & ~MACE_ISA_INT_AUDIO_SC);
873
874 callout_reset(&sc->sc_volume_button_ch,
875 (hz * MAVB_VOLUME_BUTTON_REPEAT_DEL1) / 1000,
876 mavb_button_repeat, sc);
877 }
878
879 if (stat & MACE_ISA_INT_AUDIO_DMA2)
880 mavb_dma_output(sc);
881
882 mutex_spin_exit(&sc->sc_intr_lock);
883
884 return 1;
885 }
886
887 int
mavb_match(device_t parent,cfdata_t match,void * aux)888 mavb_match(device_t parent, cfdata_t match, void *aux)
889 {
890
891 return 1;
892 }
893
894 void
mavb_attach(device_t parent,device_t self,void * aux)895 mavb_attach(device_t parent, device_t self, void *aux)
896 {
897 struct mavb_softc *sc = device_private(self);
898 struct mace_attach_args *maa = aux;
899 bus_dma_segment_t seg;
900 uint64_t control;
901 uint16_t value;
902 int rseg;
903
904 sc->sc_dev = self;
905
906 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
907 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
908
909 sc->sc_st = maa->maa_st;
910 if (bus_space_subregion(sc->sc_st, maa->maa_sh, maa->maa_offset,
911 0, &sc->sc_sh) != 0) {
912 printf(": can't map i/o space\n");
913 return;
914 }
915
916 /* XXX We need access to some of the MACE ISA registers. */
917 if (bus_space_subregion(sc->sc_st, maa->maa_sh, 0, 0,
918 &sc->sc_isash) != 0) {
919 printf(": can't map isa i/o space\n");
920 return;
921 }
922
923 /* Set up DMA structures. */
924 sc->sc_dmat = maa->maa_dmat;
925 if (bus_dmamap_create(sc->sc_dmat, 4 * MAVB_ISA_RING_SIZE, 1,
926 4 * MAVB_ISA_RING_SIZE, 0, 0, &sc->sc_dmamap)) {
927 printf(": can't create MACE ISA DMA map\n");
928 return;
929 }
930
931 if (bus_dmamem_alloc(sc->sc_dmat, 4 * MAVB_ISA_RING_SIZE,
932 MACE_ISA_RING_ALIGN, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
933 printf(": can't allocate ring buffer\n");
934 return;
935 }
936
937 if (bus_dmamem_map(sc->sc_dmat, &seg, rseg, 4 * MAVB_ISA_RING_SIZE,
938 (void *)&sc->sc_ring, BUS_DMA_COHERENT)) {
939 printf(": can't map ring buffer\n");
940 return;
941 }
942
943 if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_ring,
944 4 * MAVB_ISA_RING_SIZE, NULL, BUS_DMA_NOWAIT)) {
945 printf(": can't load MACE ISA DMA map\n");
946 return;
947 }
948
949 sc->sc_ring += MAVB_ISA_RING_SIZE; /* XXX */
950
951 bus_space_write_8(sc->sc_st, sc->sc_isash, MACE_ISA_RINGBASE,
952 sc->sc_dmamap->dm_segs[0].ds_addr);
953
954 /* Establish interrupt. */
955 cpu_intr_establish(maa->maa_intr, maa->maa_intrmask,
956 mavb_intr, sc);
957
958 control = bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL);
959 if (!(control & MAVB_CONTROL_CODEC_PRESENT)) {
960 printf(": no codec present\n");
961 return;
962 }
963
964 /* 2. Assert the RESET signal. */
965 bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL,
966 MAVB_CONTROL_RESET);
967 delay(1); /* at least 100 ns */
968
969 /* 3. Deassert the RESET signal and enter a wait period to
970 allow the AD1843 internal clocks and the external
971 crystal oscillator to stabilize. */
972 bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL, 0);
973 delay(800); /* typically 400 us to 800 us */
974 if (ad1843_reg_read(sc, AD1843_CODEC_STATUS) & AD1843_INIT) {
975 printf(": codec not ready\n");
976 return;
977 }
978
979 /* 4. Put the conversion sources into standby. */
980 value = ad1843_reg_read(sc, AD1843_FUNDAMENTAL_SETTINGS);
981 ad1843_reg_write(sc, AD1843_FUNDAMENTAL_SETTINGS,
982 value & ~AD1843_PDNI);
983 delay (500000); /* approximately 474 ms */
984 if (ad1843_reg_read(sc, AD1843_CODEC_STATUS) & AD1843_PDNO) {
985 printf(": can't power up conversion resources\n");
986 return;
987 }
988
989 /* 5. Power up the clock generators and enable clock output pins. */
990 value = ad1843_reg_read(sc, AD1843_FUNDAMENTAL_SETTINGS);
991 ad1843_reg_write(sc, AD1843_FUNDAMENTAL_SETTINGS, value | AD1843_C2EN);
992
993 /* 6. Configure conversion resources while they are in standby. */
994 value = ad1843_reg_read(sc, AD1843_CHANNEL_SAMPLE_RATE);
995 ad1843_reg_write(sc, AD1843_CHANNEL_SAMPLE_RATE,
996 value | (2 << AD1843_DA1C_SHIFT));
997
998 /* 7. Enable conversion resources. */
999 value = ad1843_reg_read(sc, AD1843_CHANNEL_POWER_DOWN);
1000 ad1843_reg_write(sc, AD1843_CHANNEL_POWER_DOWN,
1001 value | (AD1843_DA1EN | AD1843_AAMEN));
1002
1003 /* 8. Configure conversion resources while they are enabled. */
1004 value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
1005 ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN,
1006 value & ~(AD1843_LDA1GM | AD1843_RDA1GM));
1007 value = ad1843_reg_read(sc, AD1843_DAC1_DIGITAL_GAIN);
1008 ad1843_reg_write(sc, AD1843_DAC1_DIGITAL_GAIN,
1009 value & ~(AD1843_LDA1AM | AD1843_RDA1AM));
1010 value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
1011 ad1843_reg_write(sc, AD1843_MISC_SETTINGS,
1012 value & ~(AD1843_HPOM | AD1843_MNOM));
1013
1014 value = ad1843_reg_read(sc, AD1843_CODEC_STATUS);
1015 printf(": AD1843 rev %d\n", (u_int)value & AD1843_REVISION_MASK);
1016
1017 sc->sc_play_rate = 48000;
1018 sc->sc_play_format = AD1843_PCM8;
1019
1020 callout_init(&sc->sc_volume_button_ch, 0);
1021
1022 audio_attach_mi(&mavb_sa_hw_if, sc, self);
1023
1024 return;
1025 }
1026
1027 uint16_t
ad1843_reg_read(struct mavb_softc * sc,ad1843_addr_t addr)1028 ad1843_reg_read(struct mavb_softc *sc, ad1843_addr_t addr)
1029 {
1030 bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_CONTROL,
1031 (addr & MAVB_CODEC_ADDRESS_MASK) << MAVB_CODEC_ADDRESS_SHIFT |
1032 MAVB_CODEC_READ);
1033 delay(200);
1034 return bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_STATUS);
1035 }
1036
1037 uint16_t
ad1843_reg_write(struct mavb_softc * sc,ad1843_addr_t addr,uint16_t value)1038 ad1843_reg_write(struct mavb_softc *sc, ad1843_addr_t addr, uint16_t value)
1039 {
1040 bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_CONTROL,
1041 (addr & MAVB_CODEC_ADDRESS_MASK) << MAVB_CODEC_ADDRESS_SHIFT |
1042 (value & MAVB_CODEC_WORD_MASK) << MAVB_CODEC_WORD_SHIFT);
1043 delay(200);
1044 return bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_STATUS);
1045 }
1046
1047 void
ad1843_dump_regs(struct mavb_softc * sc)1048 ad1843_dump_regs(struct mavb_softc *sc)
1049 {
1050 uint16_t addr;
1051
1052 for (addr = 0; addr < AD1843_NREGS; addr++)
1053 printf("%d: 0x%04x\n", addr, ad1843_reg_read(sc, addr));
1054 }
1055