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