1 /* $OpenBSD: i2s.c,v 1.17 2008/11/07 19:53:20 todd Exp $ */ 2 /* $NetBSD: i2s.c,v 1.1 2003/12/27 02:19:34 grant Exp $ */ 3 4 /*- 5 * Copyright (c) 2002 Tsubai Masanari. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <sys/param.h> 31 #include <sys/audioio.h> 32 #include <sys/device.h> 33 #include <sys/malloc.h> 34 #include <sys/systm.h> 35 36 #include <dev/auconv.h> 37 #include <dev/audio_if.h> 38 #include <dev/mulaw.h> 39 #include <dev/ofw/openfirm.h> 40 #include <macppc/dev/dbdma.h> 41 42 #include <uvm/uvm_extern.h> 43 44 #include <machine/autoconf.h> 45 #include <machine/pio.h> 46 47 #include <macppc/dev/i2svar.h> 48 #include <macppc/dev/i2sreg.h> 49 50 #ifdef I2S_DEBUG 51 # define DPRINTF(x) printf x 52 #else 53 # define DPRINTF(x) 54 #endif 55 56 struct audio_params i2s_audio_default = { 57 44100, /* sample_rate */ 58 AUDIO_ENCODING_SLINEAR_BE, /* encoding */ 59 16, /* precision */ 60 2, /* channels */ 61 NULL, /* sw_code */ 62 1 /* factor */ 63 }; 64 65 struct i2s_mode *i2s_find_mode(u_int, u_int, u_int); 66 67 static int gpio_read(char *); 68 static void gpio_write(char *, int); 69 void i2s_mute_speaker(struct i2s_softc *, int); 70 void i2s_mute_headphone(struct i2s_softc *, int); 71 void i2s_mute_lineout(struct i2s_softc *, int); 72 int i2s_cint(void *); 73 u_char *i2s_gpio_map(struct i2s_softc *, char *, int *); 74 void i2s_init(struct i2s_softc *, int); 75 76 int i2s_intr(void *); 77 int i2s_iintr(void *); 78 79 /* XXX */ 80 void keylargo_fcr_enable(int, u_int32_t); 81 void keylargo_fcr_disable(int, u_int32_t); 82 83 struct cfdriver i2s_cd = { 84 NULL, "i2s", DV_DULL 85 }; 86 87 static u_char *amp_mute; 88 static u_char *headphone_mute; 89 static u_char *lineout_mute; 90 static u_char *audio_hw_reset; 91 static u_char *headphone_detect; 92 static int headphone_detect_active; 93 static u_char *lineout_detect; 94 static int lineout_detect_active; 95 96 /* GPIO bits */ 97 #define GPIO_OUTSEL 0xf0 /* Output select */ 98 /* 0x00 GPIO bit0 is output 99 0x10 media-bay power 100 0x20 reserved 101 0x30 MPIC */ 102 103 #define GPIO_ALTOE 0x08 /* Alternate output enable */ 104 /* 0x00 Use DDR 105 0x08 Use output select */ 106 107 #define GPIO_DDR 0x04 /* Data direction */ 108 #define GPIO_DDR_OUTPUT 0x04 /* Output */ 109 #define GPIO_DDR_INPUT 0x00 /* Input */ 110 111 #define GPIO_LEVEL 0x02 /* Pin level (RO) */ 112 113 #define GPIO_DATA 0x01 /* Data */ 114 115 void 116 i2s_attach(struct device *parent, struct i2s_softc *sc, struct confargs *ca) 117 { 118 int cirq, oirq, iirq, cirq_type, oirq_type, iirq_type; 119 u_int32_t reg[6], intr[6]; 120 121 sc->sc_node = OF_child(ca->ca_node); 122 sc->sc_baseaddr = ca->ca_baseaddr; 123 124 OF_getprop(sc->sc_node, "reg", reg, sizeof reg); 125 reg[0] += sc->sc_baseaddr; 126 reg[2] += sc->sc_baseaddr; 127 reg[4] += sc->sc_baseaddr; 128 129 sc->sc_reg = mapiodev(reg[0], reg[1]); 130 131 sc->sc_dmat = ca->ca_dmat; 132 sc->sc_odma = mapiodev(reg[2], reg[3]); /* out */ 133 sc->sc_idma = mapiodev(reg[4], reg[5]); /* in */ 134 sc->sc_odbdma = dbdma_alloc(sc->sc_dmat, I2S_DMALIST_MAX); 135 sc->sc_odmacmd = sc->sc_odbdma->d_addr; 136 sc->sc_idbdma = dbdma_alloc(sc->sc_dmat, I2S_DMALIST_MAX); 137 sc->sc_idmacmd = sc->sc_idbdma->d_addr; 138 139 OF_getprop(sc->sc_node, "interrupts", intr, sizeof intr); 140 cirq = intr[0]; 141 oirq = intr[2]; 142 iirq = intr[4]; 143 cirq_type = intr[1] ? IST_LEVEL : IST_EDGE; 144 oirq_type = intr[3] ? IST_LEVEL : IST_EDGE; 145 iirq_type = intr[5] ? IST_LEVEL : IST_EDGE; 146 147 /* intr_establish(cirq, cirq_type, IPL_AUDIO, i2s_intr, sc); */ 148 mac_intr_establish(parent, oirq, oirq_type, IPL_AUDIO, i2s_intr, 149 sc, sc->sc_dev.dv_xname); 150 mac_intr_establish(parent, iirq, iirq_type, IPL_AUDIO, i2s_iintr, 151 sc, sc->sc_dev.dv_xname); 152 153 printf(": irq %d,%d,%d\n", cirq, oirq, iirq); 154 155 i2s_set_rate(sc, 44100); 156 i2s_gpio_init(sc, ca->ca_node, parent); 157 } 158 159 int 160 i2s_intr(v) 161 void *v; 162 { 163 struct i2s_softc *sc = v; 164 struct dbdma_command *cmd = sc->sc_odmap; 165 u_int16_t c, status; 166 167 /* if not set we are not running */ 168 if (!cmd) 169 return (0); 170 DPRINTF(("i2s_intr: cmd %x\n", cmd)); 171 172 c = in16rb(&cmd->d_command); 173 status = in16rb(&cmd->d_status); 174 175 if (c >> 12 == DBDMA_CMD_OUT_LAST) 176 sc->sc_odmap = sc->sc_odmacmd; 177 else 178 sc->sc_odmap++; 179 180 if (c & (DBDMA_INT_ALWAYS << 4)) { 181 cmd->d_status = 0; 182 if (status) /* status == 0x8400 */ 183 if (sc->sc_ointr) 184 (*sc->sc_ointr)(sc->sc_oarg); 185 } 186 187 return 1; 188 } 189 190 int 191 i2s_iintr(v) 192 void *v; 193 { 194 struct i2s_softc *sc = v; 195 struct dbdma_command *cmd = sc->sc_idmap; 196 u_int16_t c, status; 197 198 /* if not set we are not running */ 199 if (!cmd) 200 return (0); 201 DPRINTF(("i2s_intr: cmd %x\n", cmd)); 202 203 c = in16rb(&cmd->d_command); 204 status = in16rb(&cmd->d_status); 205 206 if (c >> 12 == DBDMA_CMD_IN_LAST) 207 sc->sc_idmap = sc->sc_idmacmd; 208 else 209 sc->sc_idmap++; 210 211 if (c & (DBDMA_INT_ALWAYS << 4)) { 212 cmd->d_status = 0; 213 if (status) /* status == 0x8400 */ 214 if (sc->sc_iintr) 215 (*sc->sc_iintr)(sc->sc_iarg); 216 } 217 218 return 1; 219 } 220 221 int 222 i2s_open(h, flags) 223 void *h; 224 int flags; 225 { 226 return 0; 227 } 228 229 /* 230 * Close function is called at splaudio(). 231 */ 232 void 233 i2s_close(h) 234 void *h; 235 { 236 struct i2s_softc *sc = h; 237 238 i2s_halt_output(sc); 239 i2s_halt_input(sc); 240 241 sc->sc_ointr = 0; 242 sc->sc_iintr = 0; 243 } 244 245 int 246 i2s_query_encoding(h, ae) 247 void *h; 248 struct audio_encoding *ae; 249 { 250 int err = 0; 251 252 switch (ae->index) { 253 case 0: 254 strlcpy(ae->name, AudioEslinear, sizeof(ae->name)); 255 ae->encoding = AUDIO_ENCODING_SLINEAR; 256 ae->precision = 16; 257 ae->flags = 0; 258 break; 259 case 1: 260 strlcpy(ae->name, AudioEslinear_be, sizeof(ae->name)); 261 ae->encoding = AUDIO_ENCODING_SLINEAR_BE; 262 ae->precision = 16; 263 ae->flags = 0; 264 break; 265 case 2: 266 strlcpy(ae->name, AudioEslinear_le, sizeof(ae->name)); 267 ae->encoding = AUDIO_ENCODING_SLINEAR_LE; 268 ae->precision = 16; 269 ae->flags = AUDIO_ENCODINGFLAG_EMULATED; 270 break; 271 case 3: 272 strlcpy(ae->name, AudioEulinear_be, sizeof(ae->name)); 273 ae->encoding = AUDIO_ENCODING_ULINEAR_BE; 274 ae->precision = 16; 275 ae->flags = AUDIO_ENCODINGFLAG_EMULATED; 276 break; 277 case 4: 278 strlcpy(ae->name, AudioEulinear_le, sizeof(ae->name)); 279 ae->encoding = AUDIO_ENCODING_ULINEAR_LE; 280 ae->precision = 16; 281 ae->flags = AUDIO_ENCODINGFLAG_EMULATED; 282 break; 283 case 5: 284 strlcpy(ae->name, AudioEmulaw, sizeof(ae->name)); 285 ae->encoding = AUDIO_ENCODING_ULAW; 286 ae->precision = 8; 287 ae->flags = AUDIO_ENCODINGFLAG_EMULATED; 288 break; 289 case 6: 290 strlcpy(ae->name, AudioEalaw, sizeof(ae->name)); 291 ae->encoding = AUDIO_ENCODING_ALAW; 292 ae->precision = 8; 293 ae->flags = AUDIO_ENCODINGFLAG_EMULATED; 294 break; 295 case 7: 296 strlcpy(ae->name, AudioEslinear, sizeof(ae->name)); 297 ae->encoding = AUDIO_ENCODING_SLINEAR; 298 ae->precision = 8; 299 ae->flags = AUDIO_ENCODINGFLAG_EMULATED; 300 break; 301 case 8: 302 strlcpy(ae->name, AudioEulinear, sizeof(ae->name)); 303 ae->encoding = AUDIO_ENCODING_ULINEAR; 304 ae->precision = 8; 305 ae->flags = AUDIO_ENCODINGFLAG_EMULATED; 306 break; 307 default: 308 err = EINVAL; 309 break; 310 } 311 return (err); 312 } 313 314 315 struct i2s_mode { 316 u_int encoding; 317 u_int precision; 318 u_int channels; 319 void (*sw_code)(void *, u_char *, int); 320 int factor; 321 } i2s_modes[] = { 322 { AUDIO_ENCODING_SLINEAR_LE, 8, 1, linear8_to_linear16_be_mts, 4 }, 323 { AUDIO_ENCODING_SLINEAR_LE, 8, 2, linear8_to_linear16_be, 2 }, 324 { AUDIO_ENCODING_SLINEAR_LE, 16, 1, swap_bytes_mts, 2 }, 325 { AUDIO_ENCODING_SLINEAR_LE, 16, 2, swap_bytes, 1 }, 326 { AUDIO_ENCODING_SLINEAR_BE, 8, 1, linear8_to_linear16_be_mts, 4 }, 327 { AUDIO_ENCODING_SLINEAR_BE, 8, 2, linear8_to_linear16_be, 2 }, 328 { AUDIO_ENCODING_SLINEAR_BE, 16, 1, noswap_bytes_mts, 2 }, 329 { AUDIO_ENCODING_SLINEAR_BE, 16, 2, NULL, 1 }, 330 { AUDIO_ENCODING_ULINEAR_LE, 8, 1, ulinear8_to_linear16_be_mts, 4 }, 331 { AUDIO_ENCODING_ULINEAR_LE, 8, 2, ulinear8_to_linear16_be, 2 }, 332 { AUDIO_ENCODING_ULINEAR_LE, 16, 1, change_sign16_swap_bytes_le_mts, 2 }, 333 { AUDIO_ENCODING_ULINEAR_LE, 16, 2, swap_bytes_change_sign16_be, 1 }, 334 { AUDIO_ENCODING_ULINEAR_BE, 8, 1, ulinear8_to_linear16_be_mts, 4 }, 335 { AUDIO_ENCODING_ULINEAR_BE, 8, 2, ulinear8_to_linear16_be, 2 }, 336 { AUDIO_ENCODING_ULINEAR_BE, 16, 1, change_sign16_be_mts, 2 }, 337 { AUDIO_ENCODING_ULINEAR_BE, 16, 2, change_sign16_be, 1 } 338 }; 339 340 341 struct i2s_mode * 342 i2s_find_mode(u_int encoding, u_int precision, u_int channels) 343 { 344 struct i2s_mode *m; 345 int i; 346 347 for (i = 0; i < sizeof(i2s_modes)/sizeof(i2s_modes[0]); i++) { 348 m = &i2s_modes[i]; 349 if (m->encoding == encoding && 350 m->precision == precision && 351 m->channels == channels) 352 return (m); 353 } 354 return (NULL); 355 } 356 357 int 358 i2s_set_params(h, setmode, usemode, play, rec) 359 void *h; 360 int setmode, usemode; 361 struct audio_params *play, *rec; 362 { 363 struct i2s_mode *m; 364 struct i2s_softc *sc = h; 365 struct audio_params *p; 366 int mode; 367 368 p = play; /* default to play */ 369 370 /* 371 * This device only has one clock, so make the sample rates match. 372 */ 373 if (play->sample_rate != rec->sample_rate && 374 usemode == (AUMODE_PLAY | AUMODE_RECORD)) { 375 if (setmode == AUMODE_PLAY) { 376 rec->sample_rate = play->sample_rate; 377 setmode |= AUMODE_RECORD; 378 } else if (setmode == AUMODE_RECORD) { 379 play->sample_rate = rec->sample_rate; 380 setmode |= AUMODE_PLAY; 381 } else 382 return EINVAL; 383 } 384 385 for (mode = AUMODE_RECORD; mode != -1; 386 mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { 387 if ((setmode & mode) == 0) 388 continue; 389 390 p = mode == AUMODE_PLAY ? play : rec; 391 392 if (p->sample_rate < 4000) 393 p->sample_rate = 4000; 394 if (p->sample_rate > 50000) 395 p->sample_rate = 50000; 396 if (p->precision > 16) 397 p->precision = 16; 398 if (p->channels > 2) 399 p->channels = 2; 400 401 switch (p->encoding) { 402 case AUDIO_ENCODING_SLINEAR_LE: 403 case AUDIO_ENCODING_SLINEAR_BE: 404 case AUDIO_ENCODING_ULINEAR_LE: 405 case AUDIO_ENCODING_ULINEAR_BE: 406 m = i2s_find_mode(p->encoding, p->precision, 407 p->channels); 408 if (m == NULL) { 409 printf("mode not found: %u/%u/%u\n", 410 p->encoding, p->precision, p->channels); 411 return (EINVAL); 412 } 413 p->factor = m->factor; 414 p->sw_code = m->sw_code; 415 break; 416 417 case AUDIO_ENCODING_ULAW: 418 if (mode == AUMODE_PLAY) { 419 if (p->channels == 1) { 420 p->factor = 4; 421 p->sw_code = mulaw_to_slinear16_be_mts; 422 break; 423 } 424 if (p->channels == 2) { 425 p->factor = 2; 426 p->sw_code = mulaw_to_slinear16_be; 427 break; 428 } 429 } else 430 break; /* XXX */ 431 return (EINVAL); 432 433 case AUDIO_ENCODING_ALAW: 434 if (mode == AUMODE_PLAY) { 435 if (p->channels == 1) { 436 p->factor = 4; 437 p->sw_code = alaw_to_slinear16_be_mts; 438 break; 439 } 440 if (p->channels == 2) { 441 p->factor = 2; 442 p->sw_code = alaw_to_slinear16_be; 443 break; 444 } 445 } else 446 break; /* XXX */ 447 return (EINVAL); 448 449 default: 450 return (EINVAL); 451 } 452 } 453 454 /* Set the speed */ 455 if (i2s_set_rate(sc, play->sample_rate)) 456 return EINVAL; 457 458 p->sample_rate = sc->sc_rate; 459 460 return 0; 461 } 462 463 void 464 i2s_get_default_params(struct audio_params *params) 465 { 466 *params = i2s_audio_default; 467 } 468 469 int 470 i2s_round_blocksize(h, size) 471 void *h; 472 int size; 473 { 474 if (size < NBPG) 475 size = NBPG; 476 return size & ~PGOFSET; 477 } 478 479 int 480 i2s_halt_output(h) 481 void *h; 482 { 483 struct i2s_softc *sc = h; 484 485 dbdma_stop(sc->sc_odma); 486 dbdma_reset(sc->sc_odma); 487 return 0; 488 } 489 490 int 491 i2s_halt_input(h) 492 void *h; 493 { 494 struct i2s_softc *sc = h; 495 496 dbdma_stop(sc->sc_idma); 497 dbdma_reset(sc->sc_idma); 498 return 0; 499 } 500 501 enum { 502 I2S_OUTPUT_CLASS, 503 I2S_RECORD_CLASS, 504 I2S_OUTPUT_SELECT, 505 I2S_VOL_OUTPUT, 506 I2S_INPUT_SELECT, 507 I2S_VOL_INPUT, 508 I2S_BASS, 509 I2S_TREBLE, 510 I2S_ENUM_LAST 511 }; 512 513 int 514 i2s_set_port(h, mc) 515 void *h; 516 mixer_ctrl_t *mc; 517 { 518 struct i2s_softc *sc = h; 519 int l, r; 520 521 DPRINTF(("i2s_set_port dev = %d, type = %d\n", mc->dev, mc->type)); 522 523 l = mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; 524 r = mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; 525 526 switch (mc->dev) { 527 case I2S_OUTPUT_SELECT: 528 /* No change necessary? */ 529 if (mc->un.mask == sc->sc_output_mask) 530 return 0; 531 532 i2s_mute_speaker(sc, 1); 533 i2s_mute_headphone(sc, 1); 534 i2s_mute_lineout(sc, 1); 535 if (mc->un.mask & 1 << 0) 536 i2s_mute_speaker(sc, 0); 537 if (mc->un.mask & 1 << 1) 538 i2s_mute_headphone(sc, 0); 539 if (mc->un.mask & 1 << 2) 540 i2s_mute_lineout(sc, 0); 541 542 sc->sc_output_mask = mc->un.mask; 543 return 0; 544 545 case I2S_VOL_OUTPUT: 546 (*sc->sc_setvolume)(sc, l, r); 547 return 0; 548 549 case I2S_BASS: 550 if (sc->sc_setbass != NULL) 551 (*sc->sc_setbass)(sc, l); 552 return (0); 553 554 case I2S_TREBLE: 555 if (sc->sc_settreble != NULL) 556 (*sc->sc_settreble)(sc, l); 557 return (0); 558 559 case I2S_INPUT_SELECT: 560 /* no change necessary? */ 561 if (mc->un.mask == sc->sc_record_source) 562 return 0; 563 switch (mc->un.mask) { 564 case 1 << 0: /* microphone */ 565 case 1 << 1: /* line in */ 566 /* XXX TO BE DONE */ 567 break; 568 default: /* invalid argument */ 569 return EINVAL; 570 } 571 if (sc->sc_setinput != NULL) 572 (*sc->sc_setinput)(sc, mc->un.mask); 573 sc->sc_record_source = mc->un.mask; 574 return 0; 575 576 case I2S_VOL_INPUT: 577 /* XXX TO BE DONE */ 578 return 0; 579 } 580 581 return ENXIO; 582 } 583 584 int 585 i2s_get_port(h, mc) 586 void *h; 587 mixer_ctrl_t *mc; 588 { 589 struct i2s_softc *sc = h; 590 591 DPRINTF(("i2s_get_port dev = %d, type = %d\n", mc->dev, mc->type)); 592 593 switch (mc->dev) { 594 case I2S_OUTPUT_SELECT: 595 mc->un.mask = sc->sc_output_mask; 596 return 0; 597 598 case I2S_VOL_OUTPUT: 599 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = sc->sc_vol_l; 600 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = sc->sc_vol_r; 601 return 0; 602 603 case I2S_INPUT_SELECT: 604 mc->un.mask = sc->sc_record_source; 605 return 0; 606 607 case I2S_BASS: 608 if (mc->un.value.num_channels != 1) 609 return ENXIO; 610 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_bass; 611 return 0; 612 613 case I2S_TREBLE: 614 if (mc->un.value.num_channels != 1) 615 return ENXIO; 616 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_treble; 617 return 0; 618 619 case I2S_VOL_INPUT: 620 /* XXX TO BE DONE */ 621 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = 0; 622 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 0; 623 return 0; 624 625 default: 626 return ENXIO; 627 } 628 629 return 0; 630 } 631 632 int 633 i2s_query_devinfo(h, dip) 634 void *h; 635 mixer_devinfo_t *dip; 636 { 637 struct i2s_softc *sc = h; 638 int n = 0; 639 640 switch (dip->index) { 641 642 case I2S_OUTPUT_SELECT: 643 dip->mixer_class = I2S_OUTPUT_CLASS; 644 strlcpy(dip->label.name, AudioNselect, sizeof(dip->label.name)); 645 dip->type = AUDIO_MIXER_SET; 646 dip->prev = dip->next = AUDIO_MIXER_LAST; 647 strlcpy(dip->un.s.member[n].label.name, AudioNspeaker, 648 sizeof(dip->un.s.member[n].label.name)); 649 dip->un.s.member[n++].mask = 1 << 0; 650 if (headphone_mute) { 651 strlcpy(dip->un.s.member[n].label.name, 652 AudioNheadphone, 653 sizeof(dip->un.s.member[n].label.name)); 654 dip->un.s.member[n++].mask = 1 << 1; 655 } 656 if (lineout_mute) { 657 strlcpy(dip->un.s.member[n].label.name, AudioNline, 658 sizeof(dip->un.s.member[n].label.name)); 659 dip->un.s.member[n++].mask = 1 << 2; 660 } 661 dip->un.s.num_mem = n; 662 return 0; 663 664 case I2S_VOL_OUTPUT: 665 dip->mixer_class = I2S_OUTPUT_CLASS; 666 strlcpy(dip->label.name, AudioNmaster, sizeof(dip->label.name)); 667 dip->type = AUDIO_MIXER_VALUE; 668 dip->prev = dip->next = AUDIO_MIXER_LAST; 669 dip->un.v.num_channels = 2; 670 strlcpy(dip->un.v.units.name, AudioNvolume, 671 sizeof(dip->un.v.units.name)); 672 return 0; 673 674 case I2S_INPUT_SELECT: 675 dip->mixer_class = I2S_RECORD_CLASS; 676 strlcpy(dip->label.name, AudioNsource, sizeof(dip->label.name)); 677 dip->type = AUDIO_MIXER_SET; 678 dip->prev = dip->next = AUDIO_MIXER_LAST; 679 dip->un.s.num_mem = 2; 680 strlcpy(dip->un.s.member[0].label.name, AudioNmicrophone, 681 sizeof(dip->un.s.member[0].label.name)); 682 dip->un.s.member[0].mask = 1 << 0; 683 strlcpy(dip->un.s.member[1].label.name, AudioNline, 684 sizeof(dip->un.s.member[1].label.name)); 685 dip->un.s.member[1].mask = 1 << 1; 686 return 0; 687 688 case I2S_VOL_INPUT: 689 dip->mixer_class = I2S_RECORD_CLASS; 690 strlcpy(dip->label.name, AudioNrecord, sizeof(dip->label.name)); 691 dip->type = AUDIO_MIXER_VALUE; 692 dip->prev = dip->next = AUDIO_MIXER_LAST; 693 dip->un.v.num_channels = 2; 694 strlcpy(dip->un.v.units.name, AudioNvolume, 695 sizeof(dip->un.v.units.name)); 696 return 0; 697 698 case I2S_OUTPUT_CLASS: 699 dip->mixer_class = I2S_OUTPUT_CLASS; 700 strlcpy(dip->label.name, AudioCoutputs, 701 sizeof(dip->label.name)); 702 dip->type = AUDIO_MIXER_CLASS; 703 dip->next = dip->prev = AUDIO_MIXER_LAST; 704 return 0; 705 706 case I2S_RECORD_CLASS: 707 dip->mixer_class = I2S_RECORD_CLASS; 708 strlcpy(dip->label.name, AudioCrecord, sizeof(dip->label.name)); 709 dip->type = AUDIO_MIXER_CLASS; 710 dip->next = dip->prev = AUDIO_MIXER_LAST; 711 return 0; 712 713 case I2S_BASS: 714 if (sc->sc_setbass == NULL) 715 return (ENXIO); 716 dip->mixer_class = I2S_OUTPUT_CLASS; 717 strlcpy(dip->label.name, AudioNbass, sizeof(dip->label.name)); 718 dip->type = AUDIO_MIXER_VALUE; 719 dip->prev = dip->next = AUDIO_MIXER_LAST; 720 dip->un.v.num_channels = 1; 721 return (0); 722 723 case I2S_TREBLE: 724 if (sc->sc_settreble == NULL) 725 return (ENXIO); 726 dip->mixer_class = I2S_OUTPUT_CLASS; 727 strlcpy(dip->label.name, AudioNtreble, sizeof(dip->label.name)); 728 dip->type = AUDIO_MIXER_VALUE; 729 dip->prev = dip->next = AUDIO_MIXER_LAST; 730 dip->un.v.num_channels = 1; 731 return (0); 732 } 733 734 return ENXIO; 735 } 736 737 size_t 738 i2s_round_buffersize(h, dir, size) 739 void *h; 740 int dir; 741 size_t size; 742 { 743 if (size > 65536) 744 size = 65536; 745 return size; 746 } 747 748 paddr_t 749 i2s_mappage(h, mem, off, prot) 750 void *h; 751 void *mem; 752 off_t off; 753 int prot; 754 { 755 if (off < 0) 756 return -1; 757 return -1; /* XXX */ 758 } 759 760 int 761 i2s_get_props(h) 762 void *h; 763 { 764 return AUDIO_PROP_FULLDUPLEX /* | AUDIO_PROP_MMAP */; 765 } 766 767 int 768 i2s_trigger_output(h, start, end, bsize, intr, arg, param) 769 void *h; 770 void *start, *end; 771 int bsize; 772 void (*intr)(void *); 773 void *arg; 774 struct audio_params *param; 775 { 776 struct i2s_softc *sc = h; 777 struct i2s_dma *p; 778 struct dbdma_command *cmd = sc->sc_odmacmd; 779 vaddr_t spa, pa, epa; 780 int c; 781 782 DPRINTF(("trigger_output %p %p 0x%x\n", start, end, bsize)); 783 784 for (p = sc->sc_dmas; p && p->addr != start; p = p->next); 785 if (!p) 786 return -1; 787 788 sc->sc_ointr = intr; 789 sc->sc_oarg = arg; 790 sc->sc_odmap = sc->sc_odmacmd; 791 792 spa = p->segs[0].ds_addr; 793 c = DBDMA_CMD_OUT_MORE; 794 for (pa = spa, epa = spa + (end - start); 795 pa < epa; pa += bsize, cmd++) { 796 797 if (pa + bsize == epa) 798 c = DBDMA_CMD_OUT_LAST; 799 800 DBDMA_BUILD(cmd, c, 0, bsize, pa, DBDMA_INT_ALWAYS, 801 DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); 802 } 803 804 DBDMA_BUILD(cmd, DBDMA_CMD_NOP, 0, 0, 0, 805 DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_ALWAYS); 806 dbdma_st32(&cmd->d_cmddep, sc->sc_odbdma->d_paddr); 807 808 dbdma_start(sc->sc_odma, sc->sc_odbdma); 809 810 return 0; 811 } 812 813 int 814 i2s_trigger_input(h, start, end, bsize, intr, arg, param) 815 void *h; 816 void *start, *end; 817 int bsize; 818 void (*intr)(void *); 819 void *arg; 820 struct audio_params *param; 821 { 822 struct i2s_softc *sc = h; 823 struct i2s_dma *p; 824 struct dbdma_command *cmd = sc->sc_idmacmd; 825 vaddr_t spa, pa, epa; 826 int c; 827 828 DPRINTF(("trigger_input %p %p 0x%x\n", start, end, bsize)); 829 830 for (p = sc->sc_dmas; p && p->addr != start; p = p->next); 831 if (!p) 832 return -1; 833 834 sc->sc_iintr = intr; 835 sc->sc_iarg = arg; 836 sc->sc_idmap = sc->sc_idmacmd; 837 838 spa = p->segs[0].ds_addr; 839 c = DBDMA_CMD_IN_MORE; 840 for (pa = spa, epa = spa + (end - start); 841 pa < epa; pa += bsize, cmd++) { 842 843 if (pa + bsize == epa) 844 c = DBDMA_CMD_IN_LAST; 845 846 DBDMA_BUILD(cmd, c, 0, bsize, pa, DBDMA_INT_ALWAYS, 847 DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); 848 } 849 850 DBDMA_BUILD(cmd, DBDMA_CMD_NOP, 0, 0, 0, 851 DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_ALWAYS); 852 dbdma_st32(&cmd->d_cmddep, sc->sc_idbdma->d_paddr); 853 854 dbdma_start(sc->sc_idma, sc->sc_idbdma); 855 856 return 0; 857 } 858 859 860 /* rate = fs = LRCLK 861 * SCLK = 64*LRCLK (I2S) 862 * MCLK = 256fs (typ. -- changeable) 863 * MCLK = clksrc / mdiv 864 * SCLK = MCLK / sdiv 865 * rate = SCLK / 64 ( = LRCLK = fs) 866 */ 867 int 868 i2s_set_rate(sc, rate) 869 struct i2s_softc *sc; 870 int rate; 871 { 872 u_int reg = 0; 873 int MCLK; 874 int clksrc, mdiv, sdiv; 875 int mclk_fs; 876 int timo; 877 878 /* sanify */ 879 if (rate > (48000 + 44100) / 2) 880 rate = 48000; 881 else 882 rate = 44100; 883 884 switch (rate) { 885 case 44100: 886 clksrc = 45158400; /* 45MHz */ 887 reg = CLKSRC_45MHz; 888 mclk_fs = 256; 889 break; 890 891 case 48000: 892 clksrc = 49152000; /* 49MHz */ 893 reg = CLKSRC_49MHz; 894 mclk_fs = 256; 895 break; 896 897 default: 898 return EINVAL; 899 } 900 901 MCLK = rate * mclk_fs; 902 mdiv = clksrc / MCLK; /* 4 */ 903 sdiv = mclk_fs / 64; /* 4 */ 904 905 switch (mdiv) { 906 case 1: 907 reg |= MCLK_DIV1; 908 break; 909 case 3: 910 reg |= MCLK_DIV3; 911 break; 912 case 5: 913 reg |= MCLK_DIV5; 914 break; 915 default: 916 reg |= ((mdiv / 2 - 1) << 24) & 0x1f000000; 917 break; 918 } 919 920 switch (sdiv) { 921 case 1: 922 reg |= SCLK_DIV1; 923 break; 924 case 3: 925 reg |= SCLK_DIV3; 926 break; 927 default: 928 reg |= ((sdiv / 2 - 1) << 20) & 0x00f00000; 929 break; 930 } 931 932 reg |= SCLK_MASTER; /* XXX master mode */ 933 934 reg |= SERIAL_64x; 935 936 if (sc->sc_rate == rate) 937 return (0); 938 939 /* stereo input and output */ 940 DPRINTF(("I2SSetDataWordSizeReg 0x%08x -> 0x%08x\n", 941 in32rb(sc->sc_reg + I2S_WORDSIZE), 0x02000200)); 942 out32rb(sc->sc_reg + I2S_WORDSIZE, 0x02000200); 943 944 /* Clear CLKSTOPPEND */ 945 out32rb(sc->sc_reg + I2S_INT, I2S_INT_CLKSTOPPEND); 946 947 keylargo_fcr_disable(I2SClockOffset, I2S0CLKEN); 948 949 /* Wait until clock is stopped */ 950 for (timo = 50; timo > 0; timo--) { 951 if (in32rb(sc->sc_reg + I2S_INT) & I2S_INT_CLKSTOPPEND) 952 goto done; 953 delay(10); 954 } 955 956 printf("i2s_set_rate: timeout\n"); 957 958 done: 959 DPRINTF(("I2SSetSerialFormatReg 0x%x -> 0x%x\n", 960 in32rb(sc->sc_reg + I2S_FORMAT), reg)); 961 out32rb(sc->sc_reg + I2S_FORMAT, reg); 962 963 keylargo_fcr_enable(I2SClockOffset, I2S0CLKEN); 964 965 sc->sc_rate = rate; 966 967 return 0; 968 } 969 970 int 971 gpio_read(addr) 972 char *addr; 973 { 974 if (*addr & GPIO_DATA) 975 return 1; 976 return 0; 977 } 978 979 void 980 gpio_write(addr, val) 981 char *addr; 982 int val; 983 { 984 u_int data = GPIO_DDR_OUTPUT; 985 986 if (val) 987 data |= GPIO_DATA; 988 *addr = data; 989 asm volatile ("eieio" ::: "memory"); 990 } 991 992 #define amp_active 0 /* XXX OF */ 993 #define headphone_active 0 /* XXX OF */ 994 #define lineout_active 0 /* XXX OF */ 995 996 void 997 i2s_mute_speaker(sc, mute) 998 struct i2s_softc *sc; 999 int mute; 1000 { 1001 u_int x; 1002 1003 if (amp_mute == NULL) 1004 return; 1005 1006 DPRINTF(("ampmute %d --> ", gpio_read(amp_mute))); 1007 1008 if (mute) 1009 x = amp_active; /* mute */ 1010 else 1011 x = !amp_active; /* unmute */ 1012 if (x != gpio_read(amp_mute)) 1013 gpio_write(amp_mute, x); 1014 1015 DPRINTF(("%d\n", gpio_read(amp_mute))); 1016 } 1017 1018 void 1019 i2s_mute_headphone(sc, mute) 1020 struct i2s_softc *sc; 1021 int mute; 1022 { 1023 u_int x; 1024 1025 if (headphone_mute == NULL) 1026 return; 1027 1028 DPRINTF(("headphonemute %d --> ", gpio_read(headphone_mute))); 1029 1030 if (mute) 1031 x = headphone_active; /* mute */ 1032 else 1033 x = !headphone_active; /* unmute */ 1034 if (x != gpio_read(headphone_mute)) 1035 gpio_write(headphone_mute, x); 1036 1037 DPRINTF(("%d\n", gpio_read(headphone_mute))); 1038 } 1039 1040 void 1041 i2s_mute_lineout(sc, mute) 1042 struct i2s_softc *sc; 1043 int mute; 1044 { 1045 u_int x; 1046 1047 if (lineout_mute == NULL) 1048 return; 1049 1050 DPRINTF(("lineout %d --> ", gpio_read(lineout_mute))); 1051 1052 if (mute) 1053 x = lineout_active; /* mute */ 1054 else 1055 x = !lineout_active; /* unmute */ 1056 if (x != gpio_read(lineout_mute)) 1057 gpio_write(lineout_mute, x); 1058 1059 DPRINTF(("%d\n", gpio_read(lineout_mute))); 1060 } 1061 1062 int 1063 i2s_cint(v) 1064 void *v; 1065 { 1066 struct i2s_softc *sc = v; 1067 u_int sense; 1068 1069 sc->sc_output_mask = 0; 1070 i2s_mute_speaker(sc, 1); 1071 i2s_mute_headphone(sc, 1); 1072 i2s_mute_lineout(sc, 1); 1073 1074 if (headphone_detect) 1075 sense = *headphone_detect; 1076 else 1077 sense = !headphone_detect_active << 1; 1078 DPRINTF(("headphone detect = 0x%x\n", sense)); 1079 1080 if (((sense & 0x02) >> 1) == headphone_detect_active) { 1081 DPRINTF(("headphone is inserted\n")); 1082 sc->sc_output_mask |= 1 << 1; 1083 i2s_mute_headphone(sc, 0); 1084 } else { 1085 DPRINTF(("headphone is NOT inserted\n")); 1086 } 1087 1088 if (lineout_detect) 1089 sense = *lineout_detect; 1090 else 1091 sense = !lineout_detect_active << 1; 1092 DPRINTF(("lineout detect = 0x%x\n", sense)); 1093 1094 if (((sense & 0x02) >> 1) == lineout_detect_active) { 1095 DPRINTF(("lineout is inserted\n")); 1096 sc->sc_output_mask |= 1 << 2; 1097 i2s_mute_lineout(sc, 0); 1098 } else { 1099 DPRINTF(("lineout is NOT inserted\n")); 1100 } 1101 1102 if (sc->sc_output_mask == 0) { 1103 sc->sc_output_mask |= 1 << 0; 1104 i2s_mute_speaker(sc, 0); 1105 } 1106 1107 return 1; 1108 } 1109 1110 u_char * 1111 i2s_gpio_map(struct i2s_softc *sc, char *name, int *irq) 1112 { 1113 u_int32_t reg[2]; 1114 u_int32_t intr[2]; 1115 int gpio; 1116 1117 if (OF_getprop(sc->sc_node, name, &gpio, 1118 sizeof(gpio)) != sizeof(gpio) || 1119 OF_getprop(gpio, "reg", ®[0], 1120 sizeof(reg[0])) != sizeof(reg[0]) || 1121 OF_getprop(OF_parent(gpio), "reg", ®[1], 1122 sizeof(reg[1])) != sizeof(reg[1])) 1123 return NULL; 1124 1125 if (irq && OF_getprop(gpio, "interrupts", 1126 intr, sizeof(intr)) == sizeof(intr)) { 1127 *irq = intr[0]; 1128 } 1129 1130 return mapiodev(sc->sc_baseaddr + reg[0] + reg[1], 1); 1131 } 1132 1133 void 1134 i2s_gpio_init(sc, node, parent) 1135 struct i2s_softc *sc; 1136 int node; 1137 struct device *parent; 1138 { 1139 int gpio; 1140 int headphone_detect_intr = -1, headphone_detect_intrtype; 1141 int lineout_detect_intr = -1; 1142 1143 /* Map gpios. */ 1144 amp_mute = i2s_gpio_map(sc, "platform-amp-mute", NULL); 1145 headphone_mute = i2s_gpio_map(sc, "platform-headphone-mute", NULL); 1146 headphone_detect = i2s_gpio_map(sc, "platform-headphone-detect", 1147 &headphone_detect_intr); 1148 lineout_mute = i2s_gpio_map(sc, "platform-lineout-mute", NULL); 1149 lineout_detect = i2s_gpio_map(sc, "platform-lineout-detect", 1150 &lineout_detect_intr); 1151 audio_hw_reset = i2s_gpio_map(sc, "platform-hw-reset", NULL); 1152 1153 gpio = OF_getnodebyname(OF_parent(node), "gpio"); 1154 DPRINTF((" /gpio 0x%x\n", gpio)); 1155 gpio = OF_child(gpio); 1156 while (gpio) { 1157 char name[64], audio_gpio[64]; 1158 int intr[2]; 1159 paddr_t addr; 1160 1161 bzero(name, sizeof name); 1162 bzero(audio_gpio, sizeof audio_gpio); 1163 addr = 0; 1164 OF_getprop(gpio, "name", name, sizeof name); 1165 OF_getprop(gpio, "audio-gpio", audio_gpio, sizeof audio_gpio); 1166 OF_getprop(gpio, "AAPL,address", &addr, sizeof addr); 1167 /* printf("0x%x %s %s\n", gpio, name, audio_gpio); */ 1168 1169 /* gpio5 */ 1170 if (headphone_mute == NULL && 1171 strcmp(audio_gpio, "headphone-mute") == 0) 1172 headphone_mute = mapiodev(addr,1); 1173 1174 /* gpio6 */ 1175 if (amp_mute == NULL && 1176 strcmp(audio_gpio, "amp-mute") == 0) 1177 amp_mute = mapiodev(addr,1); 1178 1179 /* extint-gpio15 */ 1180 if (headphone_detect == NULL && 1181 strcmp(audio_gpio, "headphone-detect") == 0) { 1182 headphone_detect = mapiodev(addr,1); 1183 OF_getprop(gpio, "audio-gpio-active-state", 1184 &headphone_detect_active, 4); 1185 OF_getprop(gpio, "interrupts", intr, 8); 1186 headphone_detect_intr = intr[0]; 1187 headphone_detect_intrtype = intr[1]; 1188 } 1189 1190 /* gpio11 (keywest-11) */ 1191 if (audio_hw_reset == NULL && 1192 strcmp(audio_gpio, "audio-hw-reset") == 0) 1193 audio_hw_reset = mapiodev(addr,1); 1194 1195 gpio = OF_peer(gpio); 1196 } 1197 DPRINTF((" amp-mute %p\n", amp_mute)); 1198 DPRINTF((" headphone-mute %p\n", headphone_mute)); 1199 DPRINTF((" headphone-detect %p\n", headphone_detect)); 1200 DPRINTF((" headphone-detect active %x\n", headphone_detect_active)); 1201 DPRINTF((" headphone-detect intr %x\n", headphone_detect_intr)); 1202 DPRINTF((" lineout-mute %p\n", lineout_mute)); 1203 DPRINTF((" lineout-detect %p\n", lineout_detect)); 1204 DPRINTF((" lineout-detect active %x\n", lineout_detect_active)); 1205 DPRINTF((" lineout-detect intr %x\n", lineout_detect_intr)); 1206 DPRINTF((" audio-hw-reset %p\n", audio_hw_reset)); 1207 1208 if (headphone_detect_intr != -1) 1209 mac_intr_establish(parent, headphone_detect_intr, IST_EDGE, 1210 IPL_AUDIO, i2s_cint, sc, sc->sc_dev.dv_xname); 1211 1212 if (lineout_detect_intr != -1) 1213 mac_intr_establish(parent, lineout_detect_intr, IST_EDGE, 1214 IPL_AUDIO, i2s_cint, sc, sc->sc_dev.dv_xname); 1215 1216 /* Enable headphone interrupt? */ 1217 *headphone_detect |= 0x80; 1218 asm volatile("eieio"); 1219 1220 /* Update headphone status. */ 1221 i2s_cint(sc); 1222 } 1223 1224 void * 1225 i2s_allocm(void *h, int dir, size_t size, int type, int flags) 1226 { 1227 struct i2s_softc *sc = h; 1228 struct i2s_dma *p; 1229 int error; 1230 1231 if (size > I2S_DMALIST_MAX * I2S_DMASEG_MAX) 1232 return (NULL); 1233 1234 p = malloc(sizeof(*p), type, flags | M_ZERO); 1235 if (!p) 1236 return (NULL); 1237 1238 /* convert to the bus.h style, not used otherwise */ 1239 if (flags & M_NOWAIT) 1240 flags = BUS_DMA_NOWAIT; 1241 1242 p->size = size; 1243 if ((error = bus_dmamem_alloc(sc->sc_dmat, p->size, NBPG, 0, p->segs, 1244 1, &p->nsegs, flags)) != 0) { 1245 printf("%s: unable to allocate dma, error = %d\n", 1246 sc->sc_dev.dv_xname, error); 1247 free(p, type); 1248 return NULL; 1249 } 1250 1251 if ((error = bus_dmamem_map(sc->sc_dmat, p->segs, p->nsegs, p->size, 1252 &p->addr, flags | BUS_DMA_COHERENT)) != 0) { 1253 printf("%s: unable to map dma, error = %d\n", 1254 sc->sc_dev.dv_xname, error); 1255 bus_dmamem_free(sc->sc_dmat, p->segs, p->nsegs); 1256 free(p, type); 1257 return NULL; 1258 } 1259 1260 if ((error = bus_dmamap_create(sc->sc_dmat, p->size, 1, 1261 p->size, 0, flags, &p->map)) != 0) { 1262 printf("%s: unable to create dma map, error = %d\n", 1263 sc->sc_dev.dv_xname, error); 1264 bus_dmamem_unmap(sc->sc_dmat, p->addr, size); 1265 bus_dmamem_free(sc->sc_dmat, p->segs, p->nsegs); 1266 free(p, type); 1267 return NULL; 1268 } 1269 1270 if ((error = bus_dmamap_load(sc->sc_dmat, p->map, p->addr, p->size, 1271 NULL, flags)) != 0) { 1272 printf("%s: unable to load dma map, error = %d\n", 1273 sc->sc_dev.dv_xname, error); 1274 bus_dmamap_destroy(sc->sc_dmat, p->map); 1275 bus_dmamem_unmap(sc->sc_dmat, p->addr, size); 1276 bus_dmamem_free(sc->sc_dmat, p->segs, p->nsegs); 1277 free(p, type); 1278 return NULL; 1279 } 1280 1281 p->next = sc->sc_dmas; 1282 sc->sc_dmas = p; 1283 1284 return p->addr; 1285 } 1286 1287 #define reset_active 0 1288 1289 int 1290 deq_reset(struct i2s_softc *sc) 1291 { 1292 if (audio_hw_reset == NULL) 1293 return (-1); 1294 1295 gpio_write(audio_hw_reset, !reset_active); 1296 delay(1000000); 1297 1298 gpio_write(audio_hw_reset, reset_active); 1299 delay(1); 1300 1301 gpio_write(audio_hw_reset, !reset_active); 1302 delay(10000); 1303 1304 return (0); 1305 } 1306