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