vf_sai.c revision 330897
1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com> 5 * 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 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29/* 30 * Vybrid Family Synchronous Audio Interface (SAI) 31 * Chapter 51, Vybrid Reference Manual, Rev. 5, 07/2013 32 */ 33 34#include <sys/cdefs.h> 35__FBSDID("$FreeBSD: stable/11/sys/arm/freescale/vybrid/vf_sai.c 330897 2018-03-14 03:19:51Z eadler $"); 36 37#include <sys/param.h> 38#include <sys/systm.h> 39#include <sys/bus.h> 40#include <sys/kernel.h> 41#include <sys/module.h> 42#include <sys/malloc.h> 43#include <sys/rman.h> 44#include <sys/timeet.h> 45#include <sys/timetc.h> 46#include <sys/watchdog.h> 47 48#include <dev/sound/pcm/sound.h> 49#include <dev/sound/chip.h> 50#include <mixer_if.h> 51 52#include <dev/ofw/openfirm.h> 53#include <dev/ofw/ofw_bus.h> 54#include <dev/ofw/ofw_bus_subr.h> 55 56#include <machine/bus.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 110static MALLOC_DEFINE(M_SAI, "sai", "sai audio"); 111 112struct 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 133static 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 140struct 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 */ 162struct 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 */ 176struct 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 184static struct resource_spec sai_spec[] = { 185 { SYS_RES_MEMORY, 0, RF_ACTIVE }, 186 { SYS_RES_IRQ, 0, RF_ACTIVE }, 187 { -1, 0 } 188}; 189 190static int setup_dma(struct sc_pcminfo *scp); 191static void setup_sai(struct sc_info *); 192static void sai_configure_clock(struct sc_info *); 193 194/* 195 * Mixer interface. 196 */ 197 198static int 199saimixer_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 221static int 222saimixer_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 237static kobj_method_t saimixer_methods[] = { 238 KOBJMETHOD(mixer_init, saimixer_init), 239 KOBJMETHOD(mixer_set, saimixer_set), 240 KOBJMETHOD_END 241}; 242MIXER_DECLARE(saimixer); 243 244/* 245 * Channel interface. 246 */ 247 248static void * 249saichan_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 276static int 277saichan_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 294static int 295saichan_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 304static uint32_t 305saichan_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 344static void 345sai_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 367static uint32_t 368saichan_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 380uint32_t sai_dma_intr(void *arg, int chn); 381uint32_t 382sai_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 405static int 406find_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_getencprop(node, "edma-src-transmit", &dts_value, len); 429 edma_src_transmit = dts_value; 430 OF_getencprop(node, "edma-mux-group", &dts_value, len); 431 edma_mux_group = dts_value; 432 OF_getencprop(node, "edma-controller", &dts_value, len); 433 edma_node = OF_node_from_xref(dts_value); 434 435 if ((len = OF_getproplen(edma_node, "device-id")) <= 0) { 436 return (ENXIO); 437 } 438 439 OF_getencprop(edma_node, "device-id", &dts_value, len); 440 edma_device_id = 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 474static int 475setup_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 513static int 514saichan_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 544static uint32_t 545saichan_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 558static 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 567static struct pcmchan_caps sai_pcaps = {44100, 192000, sai_pfmt, 0}; 568 569static struct pcmchan_caps * 570saichan_getcaps(kobj_t obj, void *data) 571{ 572 573 return (&sai_pcaps); 574} 575 576static 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}; 587CHANNEL_DECLARE(saichan); 588 589static int 590sai_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 603static void 604sai_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 616static void 617setup_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 674static void 675sai_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 686static int 687sai_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 791static device_method_t sai_pcm_methods[] = { 792 DEVMETHOD(device_probe, sai_probe), 793 DEVMETHOD(device_attach, sai_attach), 794 { 0, 0 } 795}; 796 797static driver_t sai_pcm_driver = { 798 "pcm", 799 sai_pcm_methods, 800 PCM_SOFTC_SIZE, 801}; 802 803DRIVER_MODULE(sai, simplebus, sai_pcm_driver, pcm_devclass, 0, 0); 804MODULE_DEPEND(sai, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); 805MODULE_VERSION(sai, 1); 806