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