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