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 45int 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 61enum { 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. */ 89const 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. */ 101const 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 110static 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 124struct 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 153typedef uint64_t ad1843_addr_t; 154 155uint16_t ad1843_reg_read(struct mavb_softc *, ad1843_addr_t); 156uint16_t ad1843_reg_write(struct mavb_softc *, ad1843_addr_t, uint16_t); 157void ad1843_dump_regs(struct mavb_softc *); 158 159int mavb_match(device_t, cfdata_t, void *); 160void mavb_attach(device_t, device_t, void *); 161 162CFATTACH_DECL_NEW(mavb, sizeof(struct mavb_softc), 163 mavb_match, mavb_attach, NULL, NULL); 164 165int mavb_query_format(void *, audio_format_query_t *); 166int mavb_set_format(void *, int, 167 const audio_params_t *, const audio_params_t *, 168 audio_filter_reg_t *, audio_filter_reg_t *); 169int mavb_round_blocksize(void *hdl, int, int, const audio_params_t *); 170int mavb_halt_output(void *); 171int mavb_halt_input(void *); 172int mavb_getdev(void *, struct audio_device *); 173int mavb_set_port(void *, struct mixer_ctrl *); 174int mavb_get_port(void *, struct mixer_ctrl *); 175int mavb_query_devinfo(void *, struct mixer_devinfo *); 176int mavb_get_props(void *); 177int mavb_trigger_output(void *, void *, void *, int, void (*)(void *), 178 void *, const audio_params_t *); 179int mavb_trigger_input(void *, void *, void *, int, void (*)(void *), 180 void *, const audio_params_t *); 181void mavb_get_locks(void *, kmutex_t **, kmutex_t **); 182 183struct 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 199struct audio_device mavb_device = { 200 "A3", 201 "", 202 "mavb" 203}; 204 205static void 206mavb_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 221int 222mavb_query_format(void *hdl, audio_format_query_t *afp) 223{ 224 225 return audio_query_format(mavb_formats, MAVB_NFORMATS, afp); 226} 227 228static int 229mavb_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 241static int 242mavb_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 265int 266mavb_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 297int 298mavb_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 305int 306mavb_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 316int 317mavb_halt_input(void *hdl) 318{ 319 320 return 0; 321} 322 323int 324mavb_getdev(void *hdl, struct audio_device *ret) 325{ 326 327 *ret = mavb_device; 328 return 0; 329} 330 331int 332mavb_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 454int 455mavb_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 550int 551mavb_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 710int 711mavb_get_props(void *hdl) 712{ 713 714 return AUDIO_PROP_PLAYBACK; 715} 716 717static void 718mavb_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 754int 755mavb_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 787int 788mavb_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 796void 797mavb_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 805static void 806mavb_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 855static int 856mavb_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 887int 888mavb_match(device_t parent, cfdata_t match, void *aux) 889{ 890 891 return 1; 892} 893 894void 895mavb_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 1027uint16_t 1028ad1843_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 1037uint16_t 1038ad1843_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 1047void 1048ad1843_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