1 /*- 2 * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 /* 28 * Vybrid Family Synchronous Audio Interface (SAI) 29 * Chapter 51, Vybrid Reference Manual, Rev. 5, 07/2013 30 */ 31 32 #include <sys/cdefs.h> 33 __FBSDID("$FreeBSD$"); 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/bus.h> 38 #include <sys/kernel.h> 39 #include <sys/module.h> 40 #include <sys/malloc.h> 41 #include <sys/rman.h> 42 #include <sys/timeet.h> 43 #include <sys/timetc.h> 44 #include <sys/watchdog.h> 45 46 #include <dev/sound/pcm/sound.h> 47 #include <dev/sound/chip.h> 48 #include <mixer_if.h> 49 50 #include <dev/fdt/fdt_common.h> 51 #include <dev/ofw/openfirm.h> 52 #include <dev/ofw/ofw_bus.h> 53 #include <dev/ofw/ofw_bus_subr.h> 54 55 #include <machine/bus.h> 56 #include <machine/fdt.h> 57 #include <machine/cpu.h> 58 #include <machine/intr.h> 59 60 #include <arm/freescale/vybrid/vf_common.h> 61 #include <arm/freescale/vybrid/vf_dmamux.h> 62 #include <arm/freescale/vybrid/vf_edma.h> 63 64 #define I2S_TCSR 0x00 /* SAI Transmit Control */ 65 #define I2S_TCR1 0x04 /* SAI Transmit Configuration 1 */ 66 #define I2S_TCR2 0x08 /* SAI Transmit Configuration 2 */ 67 #define I2S_TCR3 0x0C /* SAI Transmit Configuration 3 */ 68 #define I2S_TCR4 0x10 /* SAI Transmit Configuration 4 */ 69 #define I2S_TCR5 0x14 /* SAI Transmit Configuration 5 */ 70 #define I2S_TDR0 0x20 /* SAI Transmit Data */ 71 #define I2S_TFR0 0x40 /* SAI Transmit FIFO */ 72 #define I2S_TMR 0x60 /* SAI Transmit Mask */ 73 #define I2S_RCSR 0x80 /* SAI Receive Control */ 74 #define I2S_RCR1 0x84 /* SAI Receive Configuration 1 */ 75 #define I2S_RCR2 0x88 /* SAI Receive Configuration 2 */ 76 #define I2S_RCR3 0x8C /* SAI Receive Configuration 3 */ 77 #define I2S_RCR4 0x90 /* SAI Receive Configuration 4 */ 78 #define I2S_RCR5 0x94 /* SAI Receive Configuration 5 */ 79 #define I2S_RDR0 0xA0 /* SAI Receive Data */ 80 #define I2S_RFR0 0xC0 /* SAI Receive FIFO */ 81 #define I2S_RMR 0xE0 /* SAI Receive Mask */ 82 83 #define TCR1_TFW_M 0x1f /* Transmit FIFO Watermark Mask */ 84 #define TCR1_TFW_S 0 /* Transmit FIFO Watermark Shift */ 85 #define TCR2_MSEL_M 0x3 /* MCLK Select Mask*/ 86 #define TCR2_MSEL_S 26 /* MCLK Select Shift*/ 87 #define TCR2_BCP (1 << 25) /* Bit Clock Polarity */ 88 #define TCR2_BCD (1 << 24) /* Bit Clock Direction */ 89 #define TCR3_TCE (1 << 16) /* Transmit Channel Enable */ 90 #define TCR4_FRSZ_M 0x1f /* Frame size Mask */ 91 #define TCR4_FRSZ_S 16 /* Frame size Shift */ 92 #define TCR4_SYWD_M 0x1f /* Sync Width Mask */ 93 #define TCR4_SYWD_S 8 /* Sync Width Shift */ 94 #define TCR4_MF (1 << 4) /* MSB First */ 95 #define TCR4_FSE (1 << 3) /* Frame Sync Early */ 96 #define TCR4_FSP (1 << 1) /* Frame Sync Polarity Low */ 97 #define TCR4_FSD (1 << 0) /* Frame Sync Direction Master */ 98 #define TCR5_FBT_M 0x1f /* First Bit Shifted */ 99 #define TCR5_FBT_S 8 /* First Bit Shifted */ 100 #define TCR5_W0W_M 0x1f /* Word 0 Width */ 101 #define TCR5_W0W_S 16 /* Word 0 Width */ 102 #define TCR5_WNW_M 0x1f /* Word N Width */ 103 #define TCR5_WNW_S 24 /* Word N Width */ 104 #define TCSR_TE (1 << 31) /* Transmitter Enable */ 105 #define TCSR_BCE (1 << 28) /* Bit Clock Enable */ 106 #define TCSR_FRDE (1 << 0) /* FIFO Request DMA Enable */ 107 108 #define SAI_NCHANNELS 1 109 110 static MALLOC_DEFINE(M_SAI, "sai", "sai audio"); 111 112 struct sai_rate { 113 uint32_t speed; 114 uint32_t div; /* Bit Clock Divide. Division value is (div + 1) * 2. */ 115 uint32_t mfi; /* PLL4 Multiplication Factor Integer */ 116 uint32_t mfn; /* PLL4 Multiplication Factor Numerator */ 117 uint32_t mfd; /* PLL4 Multiplication Factor Denominator */ 118 }; 119 120 /* 121 * Bit clock divider formula 122 * (div + 1) * 2 = MCLK/(nch * LRCLK * bits/1000000), 123 * where: 124 * MCLK - master clock 125 * nch - number of channels 126 * LRCLK - left right clock 127 * e.g. (div + 1) * 2 = 16.9344/(2 * 44100 * 24/1000000) 128 * 129 * Example for 96khz, 24bit, 18.432 Mhz mclk (192fs) 130 * { 96000, 1, 18, 40176000, 93000000 }, 131 */ 132 133 static struct sai_rate rate_map[] = { 134 { 44100, 7, 33, 80798400, 93000000 }, /* 33.8688 Mhz */ 135 { 96000, 3, 36, 80352000, 93000000 }, /* 36.864 Mhz */ 136 { 192000, 1, 36, 80352000, 93000000 }, /* 36.864 Mhz */ 137 { 0, 0 }, 138 }; 139 140 struct sc_info { 141 struct resource *res[2]; 142 bus_space_tag_t bst; 143 bus_space_handle_t bsh; 144 device_t dev; 145 struct mtx *lock; 146 uint32_t speed; 147 uint32_t period; 148 void *ih; 149 int pos; 150 int dma_size; 151 bus_dma_tag_t dma_tag; 152 bus_dmamap_t dma_map; 153 bus_addr_t buf_base_phys; 154 uint32_t *buf_base; 155 struct tcd_conf *tcd; 156 struct sai_rate *sr; 157 struct edma_softc *edma_sc; 158 int edma_chnum; 159 }; 160 161 /* Channel registers */ 162 struct sc_chinfo { 163 struct snd_dbuf *buffer; 164 struct pcm_channel *channel; 165 struct sc_pcminfo *parent; 166 167 /* Channel information */ 168 uint32_t dir; 169 uint32_t format; 170 171 /* Flags */ 172 uint32_t run; 173 }; 174 175 /* PCM device private data */ 176 struct sc_pcminfo { 177 device_t dev; 178 uint32_t (*ih) (struct sc_pcminfo *scp); 179 uint32_t chnum; 180 struct sc_chinfo chan[SAI_NCHANNELS]; 181 struct sc_info *sc; 182 }; 183 184 static struct resource_spec sai_spec[] = { 185 { SYS_RES_MEMORY, 0, RF_ACTIVE }, 186 { SYS_RES_IRQ, 0, RF_ACTIVE }, 187 { -1, 0 } 188 }; 189 190 static int setup_dma(struct sc_pcminfo *scp); 191 static void setup_sai(struct sc_info *); 192 static void sai_configure_clock(struct sc_info *); 193 194 /* 195 * Mixer interface. 196 */ 197 198 static int 199 saimixer_init(struct snd_mixer *m) 200 { 201 struct sc_pcminfo *scp; 202 struct sc_info *sc; 203 int mask; 204 205 scp = mix_getdevinfo(m); 206 sc = scp->sc; 207 208 if (sc == NULL) 209 return -1; 210 211 mask = SOUND_MASK_PCM; 212 213 snd_mtxlock(sc->lock); 214 pcm_setflags(scp->dev, pcm_getflags(scp->dev) | SD_F_SOFTPCMVOL); 215 mix_setdevs(m, mask); 216 snd_mtxunlock(sc->lock); 217 218 return (0); 219 } 220 221 static int 222 saimixer_set(struct snd_mixer *m, unsigned dev, 223 unsigned left, unsigned right) 224 { 225 struct sc_pcminfo *scp; 226 227 scp = mix_getdevinfo(m); 228 229 #if 0 230 device_printf(scp->dev, "saimixer_set() %d %d\n", 231 left, right); 232 #endif 233 234 return (0); 235 } 236 237 static kobj_method_t saimixer_methods[] = { 238 KOBJMETHOD(mixer_init, saimixer_init), 239 KOBJMETHOD(mixer_set, saimixer_set), 240 KOBJMETHOD_END 241 }; 242 MIXER_DECLARE(saimixer); 243 244 /* 245 * Channel interface. 246 */ 247 248 static void * 249 saichan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, 250 struct pcm_channel *c, int dir) 251 { 252 struct sc_pcminfo *scp; 253 struct sc_chinfo *ch; 254 struct sc_info *sc; 255 256 scp = (struct sc_pcminfo *)devinfo; 257 sc = scp->sc; 258 259 snd_mtxlock(sc->lock); 260 ch = &scp->chan[0]; 261 ch->dir = dir; 262 ch->run = 0; 263 ch->buffer = b; 264 ch->channel = c; 265 ch->parent = scp; 266 snd_mtxunlock(sc->lock); 267 268 if (sndbuf_setup(ch->buffer, sc->buf_base, sc->dma_size) != 0) { 269 device_printf(scp->dev, "Can't setup sndbuf.\n"); 270 return NULL; 271 } 272 273 return ch; 274 } 275 276 static int 277 saichan_free(kobj_t obj, void *data) 278 { 279 struct sc_chinfo *ch = data; 280 struct sc_pcminfo *scp = ch->parent; 281 struct sc_info *sc = scp->sc; 282 283 #if 0 284 device_printf(scp->dev, "saichan_free()\n"); 285 #endif 286 287 snd_mtxlock(sc->lock); 288 /* TODO: free channel buffer */ 289 snd_mtxunlock(sc->lock); 290 291 return (0); 292 } 293 294 static int 295 saichan_setformat(kobj_t obj, void *data, uint32_t format) 296 { 297 struct sc_chinfo *ch = data; 298 299 ch->format = format; 300 301 return (0); 302 } 303 304 static uint32_t 305 saichan_setspeed(kobj_t obj, void *data, uint32_t speed) 306 { 307 struct sc_pcminfo *scp; 308 struct sc_chinfo *ch; 309 struct sai_rate *sr; 310 struct sc_info *sc; 311 int threshold; 312 int i; 313 314 ch = data; 315 scp = ch->parent; 316 sc = scp->sc; 317 318 sr = NULL; 319 320 /* First look for equal frequency. */ 321 for (i = 0; rate_map[i].speed != 0; i++) { 322 if (rate_map[i].speed == speed) 323 sr = &rate_map[i]; 324 } 325 326 /* If no match, just find nearest. */ 327 if (sr == NULL) { 328 for (i = 0; rate_map[i].speed != 0; i++) { 329 sr = &rate_map[i]; 330 threshold = sr->speed + ((rate_map[i + 1].speed != 0) ? 331 ((rate_map[i + 1].speed - sr->speed) >> 1) : 0); 332 if (speed < threshold) 333 break; 334 } 335 } 336 337 sc->sr = sr; 338 339 sai_configure_clock(sc); 340 341 return (sr->speed); 342 } 343 344 static void 345 sai_configure_clock(struct sc_info *sc) 346 { 347 struct sai_rate *sr; 348 int reg; 349 350 sr = sc->sr; 351 352 /* 353 * Manual says that TCR/RCR registers must not be 354 * altered when TCSR[TE] is set. 355 * We ignore it since we have problem sometimes 356 * after re-enabling transmitter (DMA goes stall). 357 */ 358 359 reg = READ4(sc, I2S_TCR2); 360 reg &= ~(0xff << 0); 361 reg |= (sr->div << 0); 362 WRITE4(sc, I2S_TCR2, reg); 363 364 pll4_configure_output(sr->mfi, sr->mfn, sr->mfd); 365 } 366 367 static uint32_t 368 saichan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) 369 { 370 struct sc_chinfo *ch = data; 371 struct sc_pcminfo *scp = ch->parent; 372 struct sc_info *sc = scp->sc; 373 374 sndbuf_resize(ch->buffer, sc->dma_size / blocksize, blocksize); 375 376 sc->period = sndbuf_getblksz(ch->buffer); 377 return (sc->period); 378 } 379 380 uint32_t sai_dma_intr(void *arg, int chn); 381 uint32_t 382 sai_dma_intr(void *arg, int chn) 383 { 384 struct sc_pcminfo *scp; 385 struct sc_chinfo *ch; 386 struct sc_info *sc; 387 struct tcd_conf *tcd; 388 389 scp = arg; 390 ch = &scp->chan[0]; 391 392 sc = scp->sc; 393 tcd = sc->tcd; 394 395 sc->pos += (tcd->nbytes * tcd->nmajor); 396 if (sc->pos >= sc->dma_size) 397 sc->pos -= sc->dma_size; 398 399 if (ch->run) 400 chn_intr(ch->channel); 401 402 return (0); 403 } 404 405 static int 406 find_edma_controller(struct sc_info *sc) 407 { 408 struct edma_softc *edma_sc; 409 phandle_t node, edma_node; 410 int edma_src_transmit; 411 int edma_mux_group; 412 int edma_device_id; 413 device_t edma_dev; 414 int dts_value; 415 int len; 416 int i; 417 418 if ((node = ofw_bus_get_node(sc->dev)) == -1) 419 return (ENXIO); 420 421 if ((len = OF_getproplen(node, "edma-controller")) <= 0) 422 return (ENXIO); 423 if ((len = OF_getproplen(node, "edma-src-transmit")) <= 0) 424 return (ENXIO); 425 if ((len = OF_getproplen(node, "edma-mux-group")) <= 0) 426 return (ENXIO); 427 428 OF_getprop(node, "edma-src-transmit", &dts_value, len); 429 edma_src_transmit = fdt32_to_cpu(dts_value); 430 OF_getprop(node, "edma-mux-group", &dts_value, len); 431 edma_mux_group = fdt32_to_cpu(dts_value); 432 OF_getprop(node, "edma-controller", &dts_value, len); 433 edma_node = OF_xref_phandle(fdt32_to_cpu(dts_value)); 434 435 if ((len = OF_getproplen(edma_node, "device-id")) <= 0) { 436 return (ENXIO); 437 }; 438 439 OF_getprop(edma_node, "device-id", &dts_value, len); 440 edma_device_id = fdt32_to_cpu(dts_value); 441 442 edma_sc = NULL; 443 444 for (i = 0; i < EDMA_NUM_DEVICES; i++) { 445 edma_dev = devclass_get_device(devclass_find("edma"), i); 446 if (edma_dev) { 447 edma_sc = device_get_softc(edma_dev); 448 if (edma_sc->device_id == edma_device_id) { 449 /* found */ 450 break; 451 }; 452 453 edma_sc = NULL; 454 }; 455 }; 456 457 if (edma_sc == NULL) { 458 device_printf(sc->dev, "no eDMA. can't operate\n"); 459 return (ENXIO); 460 }; 461 462 sc->edma_sc = edma_sc; 463 464 sc->edma_chnum = edma_sc->channel_configure(edma_sc, edma_mux_group, 465 edma_src_transmit); 466 if (sc->edma_chnum < 0) { 467 /* cant setup eDMA */ 468 return (ENXIO); 469 }; 470 471 return (0); 472 }; 473 474 static int 475 setup_dma(struct sc_pcminfo *scp) 476 { 477 struct tcd_conf *tcd; 478 struct sc_info *sc; 479 480 sc = scp->sc; 481 482 tcd = malloc(sizeof(struct tcd_conf), M_DEVBUF, M_WAITOK | M_ZERO); 483 tcd->channel = sc->edma_chnum; 484 tcd->ih = sai_dma_intr; 485 tcd->ih_user = scp; 486 tcd->saddr = sc->buf_base_phys; 487 tcd->daddr = rman_get_start(sc->res[0]) + I2S_TDR0; 488 489 /* 490 * Bytes to transfer per each minor loop. 491 * Hardware FIFO buffer size is 32x32bits. 492 */ 493 tcd->nbytes = 64; 494 495 tcd->nmajor = 512; 496 tcd->smod = 17; /* dma_size range */ 497 tcd->dmod = 0; 498 tcd->esg = 0; 499 tcd->soff = 0x4; 500 tcd->doff = 0; 501 tcd->ssize = 0x2; 502 tcd->dsize = 0x2; 503 tcd->slast = 0; 504 tcd->dlast_sga = 0; 505 506 sc->tcd = tcd; 507 508 sc->edma_sc->dma_setup(sc->edma_sc, sc->tcd); 509 510 return (0); 511 } 512 513 static int 514 saichan_trigger(kobj_t obj, void *data, int go) 515 { 516 struct sc_chinfo *ch = data; 517 struct sc_pcminfo *scp = ch->parent; 518 struct sc_info *sc = scp->sc; 519 520 snd_mtxlock(sc->lock); 521 522 switch (go) { 523 case PCMTRIG_START: 524 #if 0 525 device_printf(scp->dev, "trigger start\n"); 526 #endif 527 ch->run = 1; 528 break; 529 530 case PCMTRIG_STOP: 531 case PCMTRIG_ABORT: 532 #if 0 533 device_printf(scp->dev, "trigger stop or abort\n"); 534 #endif 535 ch->run = 0; 536 break; 537 } 538 539 snd_mtxunlock(sc->lock); 540 541 return (0); 542 } 543 544 static uint32_t 545 saichan_getptr(kobj_t obj, void *data) 546 { 547 struct sc_pcminfo *scp; 548 struct sc_chinfo *ch; 549 struct sc_info *sc; 550 551 ch = data; 552 scp = ch->parent; 553 sc = scp->sc; 554 555 return (sc->pos); 556 } 557 558 static uint32_t sai_pfmt[] = { 559 /* 560 * eDMA doesn't allow 24-bit coping, 561 * so we use 32. 562 */ 563 SND_FORMAT(AFMT_S32_LE, 2, 0), 564 0 565 }; 566 567 static struct pcmchan_caps sai_pcaps = {44100, 192000, sai_pfmt, 0}; 568 569 static struct pcmchan_caps * 570 saichan_getcaps(kobj_t obj, void *data) 571 { 572 573 return (&sai_pcaps); 574 } 575 576 static kobj_method_t saichan_methods[] = { 577 KOBJMETHOD(channel_init, saichan_init), 578 KOBJMETHOD(channel_free, saichan_free), 579 KOBJMETHOD(channel_setformat, saichan_setformat), 580 KOBJMETHOD(channel_setspeed, saichan_setspeed), 581 KOBJMETHOD(channel_setblocksize, saichan_setblocksize), 582 KOBJMETHOD(channel_trigger, saichan_trigger), 583 KOBJMETHOD(channel_getptr, saichan_getptr), 584 KOBJMETHOD(channel_getcaps, saichan_getcaps), 585 KOBJMETHOD_END 586 }; 587 CHANNEL_DECLARE(saichan); 588 589 static int 590 sai_probe(device_t dev) 591 { 592 593 if (!ofw_bus_status_okay(dev)) 594 return (ENXIO); 595 596 if (!ofw_bus_is_compatible(dev, "fsl,mvf600-sai")) 597 return (ENXIO); 598 599 device_set_desc(dev, "Vybrid Family Synchronous Audio Interface"); 600 return (BUS_PROBE_DEFAULT); 601 } 602 603 static void 604 sai_intr(void *arg) 605 { 606 struct sc_pcminfo *scp; 607 struct sc_info *sc; 608 609 scp = arg; 610 sc = scp->sc; 611 612 device_printf(sc->dev, "Error I2S_TCSR == 0x%08x\n", 613 READ4(sc, I2S_TCSR)); 614 } 615 616 static void 617 setup_sai(struct sc_info *sc) 618 { 619 int reg; 620 621 /* 622 * TCR/RCR registers must not be altered when TCSR[TE] is set. 623 */ 624 625 reg = READ4(sc, I2S_TCSR); 626 reg &= ~(TCSR_BCE | TCSR_TE | TCSR_FRDE); 627 WRITE4(sc, I2S_TCSR, reg); 628 629 reg = READ4(sc, I2S_TCR3); 630 reg &= ~(TCR3_TCE); 631 WRITE4(sc, I2S_TCR3, reg); 632 633 reg = (64 << TCR1_TFW_S); 634 WRITE4(sc, I2S_TCR1, reg); 635 636 reg = READ4(sc, I2S_TCR2); 637 reg &= ~(TCR2_MSEL_M << TCR2_MSEL_S); 638 reg |= (1 << TCR2_MSEL_S); 639 reg |= (TCR2_BCP | TCR2_BCD); 640 WRITE4(sc, I2S_TCR2, reg); 641 642 sai_configure_clock(sc); 643 644 reg = READ4(sc, I2S_TCR3); 645 reg |= (TCR3_TCE); 646 WRITE4(sc, I2S_TCR3, reg); 647 648 /* Configure to 32-bit I2S mode */ 649 reg = READ4(sc, I2S_TCR4); 650 reg &= ~(TCR4_FRSZ_M << TCR4_FRSZ_S); 651 reg |= (1 << TCR4_FRSZ_S); /* 2 words per frame */ 652 reg &= ~(TCR4_SYWD_M << TCR4_SYWD_S); 653 reg |= (23 << TCR4_SYWD_S); 654 reg |= (TCR4_MF | TCR4_FSE | TCR4_FSP | TCR4_FSD); 655 WRITE4(sc, I2S_TCR4, reg); 656 657 reg = READ4(sc, I2S_TCR5); 658 reg &= ~(TCR5_W0W_M << TCR5_W0W_S); 659 reg |= (23 << TCR5_W0W_S); 660 reg &= ~(TCR5_WNW_M << TCR5_WNW_S); 661 reg |= (23 << TCR5_WNW_S); 662 reg &= ~(TCR5_FBT_M << TCR5_FBT_S); 663 reg |= (31 << TCR5_FBT_S); 664 WRITE4(sc, I2S_TCR5, reg); 665 666 /* Enable transmitter */ 667 reg = READ4(sc, I2S_TCSR); 668 reg |= (TCSR_BCE | TCSR_TE | TCSR_FRDE); 669 reg |= (1 << 10); /* FEIE */ 670 WRITE4(sc, I2S_TCSR, reg); 671 } 672 673 674 static void 675 sai_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err) 676 { 677 bus_addr_t *addr; 678 679 if (err) 680 return; 681 682 addr = (bus_addr_t*)arg; 683 *addr = segs[0].ds_addr; 684 } 685 686 static int 687 sai_attach(device_t dev) 688 { 689 char status[SND_STATUSLEN]; 690 struct sc_pcminfo *scp; 691 struct sc_info *sc; 692 int err; 693 694 sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); 695 sc->dev = dev; 696 sc->sr = &rate_map[0]; 697 sc->pos = 0; 698 699 sc->lock = snd_mtxcreate(device_get_nameunit(dev), "sai softc"); 700 if (sc->lock == NULL) { 701 device_printf(dev, "Cant create mtx\n"); 702 return (ENXIO); 703 } 704 705 if (bus_alloc_resources(dev, sai_spec, sc->res)) { 706 device_printf(dev, "could not allocate resources\n"); 707 return (ENXIO); 708 } 709 710 /* Memory interface */ 711 sc->bst = rman_get_bustag(sc->res[0]); 712 sc->bsh = rman_get_bushandle(sc->res[0]); 713 714 /* eDMA */ 715 if (find_edma_controller(sc)) { 716 device_printf(dev, "could not find active eDMA\n"); 717 return (ENXIO); 718 } 719 720 /* Setup PCM */ 721 scp = malloc(sizeof(struct sc_pcminfo), M_DEVBUF, M_NOWAIT | M_ZERO); 722 scp->sc = sc; 723 scp->dev = dev; 724 725 /* DMA */ 726 sc->dma_size = 131072; 727 728 /* 729 * Must use dma_size boundary as modulo feature required. 730 * Modulo feature allows setup circular buffer. 731 */ 732 733 err = bus_dma_tag_create( 734 bus_get_dma_tag(sc->dev), 735 4, sc->dma_size, /* alignment, boundary */ 736 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 737 BUS_SPACE_MAXADDR, /* highaddr */ 738 NULL, NULL, /* filter, filterarg */ 739 sc->dma_size, 1, /* maxsize, nsegments */ 740 sc->dma_size, 0, /* maxsegsize, flags */ 741 NULL, NULL, /* lockfunc, lockarg */ 742 &sc->dma_tag); 743 744 err = bus_dmamem_alloc(sc->dma_tag, (void **)&sc->buf_base, 745 BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &sc->dma_map); 746 if (err) { 747 device_printf(dev, "cannot allocate framebuffer\n"); 748 return (ENXIO); 749 } 750 751 err = bus_dmamap_load(sc->dma_tag, sc->dma_map, sc->buf_base, 752 sc->dma_size, sai_dmamap_cb, &sc->buf_base_phys, BUS_DMA_NOWAIT); 753 if (err) { 754 device_printf(dev, "cannot load DMA map\n"); 755 return (ENXIO); 756 } 757 758 bzero(sc->buf_base, sc->dma_size); 759 760 /* Setup interrupt handler */ 761 err = bus_setup_intr(dev, sc->res[1], INTR_MPSAFE | INTR_TYPE_AV, 762 NULL, sai_intr, scp, &sc->ih); 763 if (err) { 764 device_printf(dev, "Unable to alloc interrupt resource.\n"); 765 return (ENXIO); 766 } 767 768 pcm_setflags(dev, pcm_getflags(dev) | SD_F_MPSAFE); 769 770 err = pcm_register(dev, scp, 1, 0); 771 if (err) { 772 device_printf(dev, "Can't register pcm.\n"); 773 return (ENXIO); 774 } 775 776 scp->chnum = 0; 777 pcm_addchan(dev, PCMDIR_PLAY, &saichan_class, scp); 778 scp->chnum++; 779 780 snprintf(status, SND_STATUSLEN, "at simplebus"); 781 pcm_setstatus(dev, status); 782 783 mixer_init(dev, &saimixer_class, scp); 784 785 setup_dma(scp); 786 setup_sai(sc); 787 788 return (0); 789 } 790 791 static device_method_t sai_pcm_methods[] = { 792 DEVMETHOD(device_probe, sai_probe), 793 DEVMETHOD(device_attach, sai_attach), 794 { 0, 0 } 795 }; 796 797 static driver_t sai_pcm_driver = { 798 "pcm", 799 sai_pcm_methods, 800 PCM_SOFTC_SIZE, 801 }; 802 803 DRIVER_MODULE(sai, simplebus, sai_pcm_driver, pcm_devclass, 0, 0); 804 MODULE_DEPEND(sai, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); 805 MODULE_VERSION(sai, 1); 806