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