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