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