1/*- 2 * Copyright (c) 2015 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 * i.MX6 Synchronous Serial Interface (SSI) 29 * 30 * Chapter 61, i.MX 6Dual/6Quad Applications Processor Reference Manual, 31 * Rev. 1, 04/2013 32 */ 33 34#include <sys/cdefs.h> 35__FBSDID("$FreeBSD: stable/11/sys/arm/freescale/imx/imx6_ssi.c 318118 2017-05-09 21:25:49Z gonzo $"); 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 47#include <dev/sound/pcm/sound.h> 48#include <dev/sound/chip.h> 49#include <mixer_if.h> 50 51#include <dev/fdt/fdt_common.h> 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/imx/imx6_sdma.h> 61#include <arm/freescale/imx/imx6_anatopvar.h> 62#include <arm/freescale/imx/imx_ccmvar.h> 63 64#define READ4(_sc, _reg) \ 65 bus_space_read_4(_sc->bst, _sc->bsh, _reg) 66#define WRITE4(_sc, _reg, _val) \ 67 bus_space_write_4(_sc->bst, _sc->bsh, _reg, _val) 68 69#define SSI_NCHANNELS 1 70#define DMAS_TOTAL 8 71 72/* i.MX6 SSI registers */ 73 74#define SSI_STX0 0x00 /* Transmit Data Register n */ 75#define SSI_STX1 0x04 /* Transmit Data Register n */ 76#define SSI_SRX0 0x08 /* Receive Data Register n */ 77#define SSI_SRX1 0x0C /* Receive Data Register n */ 78#define SSI_SCR 0x10 /* Control Register */ 79#define SCR_I2S_MODE_S 5 /* I2S Mode Select. */ 80#define SCR_I2S_MODE_M 0x3 81#define SCR_SYN (1 << 4) 82#define SCR_NET (1 << 3) /* Network mode */ 83#define SCR_RE (1 << 2) /* Receive Enable. */ 84#define SCR_TE (1 << 1) /* Transmit Enable. */ 85#define SCR_SSIEN (1 << 0) /* SSI Enable */ 86#define SSI_SISR 0x14 /* Interrupt Status Register */ 87#define SSI_SIER 0x18 /* Interrupt Enable Register */ 88#define SIER_RDMAE (1 << 22) /* Receive DMA Enable. */ 89#define SIER_RIE (1 << 21) /* Receive Interrupt Enable. */ 90#define SIER_TDMAE (1 << 20) /* Transmit DMA Enable. */ 91#define SIER_TIE (1 << 19) /* Transmit Interrupt Enable. */ 92#define SIER_TDE0IE (1 << 12) /* Transmit Data Register Empty 0. */ 93#define SIER_TUE0IE (1 << 8) /* Transmitter Underrun Error 0. */ 94#define SIER_TFE0IE (1 << 0) /* Transmit FIFO Empty 0 IE. */ 95#define SSI_STCR 0x1C /* Transmit Configuration Register */ 96#define STCR_TXBIT0 (1 << 9) /* Transmit Bit 0 shift MSB/LSB */ 97#define STCR_TFEN1 (1 << 8) /* Transmit FIFO Enable 1. */ 98#define STCR_TFEN0 (1 << 7) /* Transmit FIFO Enable 0. */ 99#define STCR_TFDIR (1 << 6) /* Transmit Frame Direction. */ 100#define STCR_TXDIR (1 << 5) /* Transmit Clock Direction. */ 101#define STCR_TSHFD (1 << 4) /* Transmit Shift Direction. */ 102#define STCR_TSCKP (1 << 3) /* Transmit Clock Polarity. */ 103#define STCR_TFSI (1 << 2) /* Transmit Frame Sync Invert. */ 104#define STCR_TFSL (1 << 1) /* Transmit Frame Sync Length. */ 105#define STCR_TEFS (1 << 0) /* Transmit Early Frame Sync. */ 106#define SSI_SRCR 0x20 /* Receive Configuration Register */ 107#define SSI_STCCR 0x24 /* Transmit Clock Control Register */ 108#define STCCR_DIV2 (1 << 18) /* Divide By 2. */ 109#define STCCR_PSR (1 << 17) /* Divide clock by 8. */ 110#define WL3_WL0_S 13 111#define WL3_WL0_M 0xf 112#define DC4_DC0_S 8 113#define DC4_DC0_M 0x1f 114#define PM7_PM0_S 0 115#define PM7_PM0_M 0xff 116#define SSI_SRCCR 0x28 /* Receive Clock Control Register */ 117#define SSI_SFCSR 0x2C /* FIFO Control/Status Register */ 118#define SFCSR_RFWM1_S 20 /* Receive FIFO Empty WaterMark 1 */ 119#define SFCSR_RFWM1_M 0xf 120#define SFCSR_TFWM1_S 16 /* Transmit FIFO Empty WaterMark 1 */ 121#define SFCSR_TFWM1_M 0xf 122#define SFCSR_RFWM0_S 4 /* Receive FIFO Empty WaterMark 0 */ 123#define SFCSR_RFWM0_M 0xf 124#define SFCSR_TFWM0_S 0 /* Transmit FIFO Empty WaterMark 0 */ 125#define SFCSR_TFWM0_M 0xf 126#define SSI_SACNT 0x38 /* AC97 Control Register */ 127#define SSI_SACADD 0x3C /* AC97 Command Address Register */ 128#define SSI_SACDAT 0x40 /* AC97 Command Data Register */ 129#define SSI_SATAG 0x44 /* AC97 Tag Register */ 130#define SSI_STMSK 0x48 /* Transmit Time Slot Mask Register */ 131#define SSI_SRMSK 0x4C /* Receive Time Slot Mask Register */ 132#define SSI_SACCST 0x50 /* AC97 Channel Status Register */ 133#define SSI_SACCEN 0x54 /* AC97 Channel Enable Register */ 134#define SSI_SACCDIS 0x58 /* AC97 Channel Disable Register */ 135 136static MALLOC_DEFINE(M_SSI, "ssi", "ssi audio"); 137 138uint32_t ssi_dma_intr(void *arg, int chn); 139 140struct ssi_rate { 141 uint32_t speed; 142 uint32_t mfi; /* PLL4 Multiplication Factor Integer */ 143 uint32_t mfn; /* PLL4 Multiplication Factor Numerator */ 144 uint32_t mfd; /* PLL4 Multiplication Factor Denominator */ 145 /* More dividers to configure can be added here */ 146}; 147 148static struct ssi_rate rate_map[] = { 149 { 192000, 49, 152, 1000 }, /* PLL4 49.152 Mhz */ 150 /* TODO: add more frequences */ 151 { 0, 0 }, 152}; 153 154/* 155 * i.MX6 example bit clock formula 156 * 157 * BCLK = 2 channels * 192000 hz * 24 bit = 9216000 hz = 158 * (24000000 * (49 + 152/1000.0) / 4 / 4 / 2 / 2 / 2 / 1 / 1) 159 * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 160 * | | | | | | | | | | | 161 * Fref ------/ | | | | | | | | | | 162 * PLL4 div select -/ | | | | | | | | | 163 * PLL4 num --------------/ | | | | | | | | 164 * PLL4 denom -------------------/ | | | | | | | 165 * PLL4 post div ---------------------/ | | | | | | 166 * CCM ssi pre div (CCM_CS1CDR) ----------/ | | | | | 167 * CCM ssi post div (CCM_CS1CDR) -------------/ | | | | 168 * SSI PM7_PM0_S ---------------------------------/ | | | 169 * SSI Fixed divider ---------------------------------/ | | 170 * SSI DIV2 ----------------------------------------------/ | 171 * SSI PSR (prescaler /1 or /8) ------------------------------/ 172 * 173 * MCLK (Master clock) depends on DAC, usually BCLK * 4 174 */ 175 176struct sc_info { 177 struct resource *res[2]; 178 bus_space_tag_t bst; 179 bus_space_handle_t bsh; 180 device_t dev; 181 struct mtx *lock; 182 void *ih; 183 int pos; 184 int dma_size; 185 bus_dma_tag_t dma_tag; 186 bus_dmamap_t dma_map; 187 bus_addr_t buf_base_phys; 188 uint32_t *buf_base; 189 struct sdma_conf *conf; 190 struct ssi_rate *sr; 191 struct sdma_softc *sdma_sc; 192 uint32_t sdma_ev_rx; 193 uint32_t sdma_ev_tx; 194 int sdma_channel; 195}; 196 197/* Channel registers */ 198struct sc_chinfo { 199 struct snd_dbuf *buffer; 200 struct pcm_channel *channel; 201 struct sc_pcminfo *parent; 202 203 /* Channel information */ 204 uint32_t dir; 205 uint32_t format; 206 207 /* Flags */ 208 uint32_t run; 209}; 210 211/* PCM device private data */ 212struct sc_pcminfo { 213 device_t dev; 214 uint32_t (*ih)(struct sc_pcminfo *scp); 215 uint32_t chnum; 216 struct sc_chinfo chan[SSI_NCHANNELS]; 217 struct sc_info *sc; 218}; 219 220static struct resource_spec ssi_spec[] = { 221 { SYS_RES_MEMORY, 0, RF_ACTIVE }, 222 { SYS_RES_IRQ, 0, RF_ACTIVE }, 223 { -1, 0 } 224}; 225 226static int setup_dma(struct sc_pcminfo *scp); 227static void setup_ssi(struct sc_info *); 228static void ssi_configure_clock(struct sc_info *); 229 230/* 231 * Mixer interface. 232 */ 233 234static int 235ssimixer_init(struct snd_mixer *m) 236{ 237 struct sc_pcminfo *scp; 238 struct sc_info *sc; 239 int mask; 240 241 scp = mix_getdevinfo(m); 242 sc = scp->sc; 243 244 if (sc == NULL) 245 return -1; 246 247 mask = SOUND_MASK_PCM; 248 mask |= SOUND_MASK_VOLUME; 249 250 snd_mtxlock(sc->lock); 251 pcm_setflags(scp->dev, pcm_getflags(scp->dev) | SD_F_SOFTPCMVOL); 252 mix_setdevs(m, mask); 253 snd_mtxunlock(sc->lock); 254 255 return (0); 256} 257 258static int 259ssimixer_set(struct snd_mixer *m, unsigned dev, 260 unsigned left, unsigned right) 261{ 262 struct sc_pcminfo *scp; 263 264 scp = mix_getdevinfo(m); 265 266 /* Here we can configure hardware volume on our DAC */ 267 268#if 1 269 device_printf(scp->dev, "ssimixer_set() %d %d\n", 270 left, right); 271#endif 272 273 return (0); 274} 275 276static kobj_method_t ssimixer_methods[] = { 277 KOBJMETHOD(mixer_init, ssimixer_init), 278 KOBJMETHOD(mixer_set, ssimixer_set), 279 KOBJMETHOD_END 280}; 281MIXER_DECLARE(ssimixer); 282 283 284/* 285 * Channel interface. 286 */ 287 288static void * 289ssichan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, 290 struct pcm_channel *c, int dir) 291{ 292 struct sc_pcminfo *scp; 293 struct sc_chinfo *ch; 294 struct sc_info *sc; 295 296 scp = (struct sc_pcminfo *)devinfo; 297 sc = scp->sc; 298 299 snd_mtxlock(sc->lock); 300 ch = &scp->chan[0]; 301 ch->dir = dir; 302 ch->run = 0; 303 ch->buffer = b; 304 ch->channel = c; 305 ch->parent = scp; 306 snd_mtxunlock(sc->lock); 307 308 if (sndbuf_setup(ch->buffer, sc->buf_base, sc->dma_size) != 0) { 309 device_printf(scp->dev, "Can't setup sndbuf.\n"); 310 return NULL; 311 } 312 313 return ch; 314} 315 316static int 317ssichan_free(kobj_t obj, void *data) 318{ 319 struct sc_chinfo *ch = data; 320 struct sc_pcminfo *scp = ch->parent; 321 struct sc_info *sc = scp->sc; 322 323#if 0 324 device_printf(scp->dev, "ssichan_free()\n"); 325#endif 326 327 snd_mtxlock(sc->lock); 328 /* TODO: free channel buffer */ 329 snd_mtxunlock(sc->lock); 330 331 return (0); 332} 333 334static int 335ssichan_setformat(kobj_t obj, void *data, uint32_t format) 336{ 337 struct sc_chinfo *ch = data; 338 339 ch->format = format; 340 341 return (0); 342} 343 344static uint32_t 345ssichan_setspeed(kobj_t obj, void *data, uint32_t speed) 346{ 347 struct sc_pcminfo *scp; 348 struct sc_chinfo *ch; 349 struct ssi_rate *sr; 350 struct sc_info *sc; 351 int threshold; 352 int i; 353 354 ch = data; 355 scp = ch->parent; 356 sc = scp->sc; 357 358 sr = NULL; 359 360 /* First look for equal frequency. */ 361 for (i = 0; rate_map[i].speed != 0; i++) { 362 if (rate_map[i].speed == speed) 363 sr = &rate_map[i]; 364 } 365 366 /* If no match, just find nearest. */ 367 if (sr == NULL) { 368 for (i = 0; rate_map[i].speed != 0; i++) { 369 sr = &rate_map[i]; 370 threshold = sr->speed + ((rate_map[i + 1].speed != 0) ? 371 ((rate_map[i + 1].speed - sr->speed) >> 1) : 0); 372 if (speed < threshold) 373 break; 374 } 375 } 376 377 sc->sr = sr; 378 379 ssi_configure_clock(sc); 380 381 return (sr->speed); 382} 383 384static void 385ssi_configure_clock(struct sc_info *sc) 386{ 387 struct ssi_rate *sr; 388 389 sr = sc->sr; 390 391 pll4_configure_output(sr->mfi, sr->mfn, sr->mfd); 392 393 /* Configure other dividers here, if any */ 394} 395 396static uint32_t 397ssichan_setblocksize(kobj_t obj, void *data, uint32_t blocksize) 398{ 399 struct sc_chinfo *ch = data; 400 struct sc_pcminfo *scp = ch->parent; 401 struct sc_info *sc = scp->sc; 402 403 sndbuf_resize(ch->buffer, sc->dma_size / blocksize, blocksize); 404 405 setup_dma(scp); 406 407 return (sndbuf_getblksz(ch->buffer)); 408} 409 410uint32_t 411ssi_dma_intr(void *arg, int chn) 412{ 413 struct sc_pcminfo *scp; 414 struct sdma_conf *conf; 415 struct sc_chinfo *ch; 416 struct sc_info *sc; 417 int bufsize; 418 419 scp = arg; 420 ch = &scp->chan[0]; 421 sc = scp->sc; 422 conf = sc->conf; 423 424 bufsize = sndbuf_getsize(ch->buffer); 425 426 sc->pos += conf->period; 427 if (sc->pos >= bufsize) 428 sc->pos -= bufsize; 429 430 if (ch->run) 431 chn_intr(ch->channel); 432 433 return (0); 434} 435 436static int 437find_sdma_controller(struct sc_info *sc) 438{ 439 struct sdma_softc *sdma_sc; 440 phandle_t node, sdma_node; 441 device_t sdma_dev; 442 pcell_t dts_value[DMAS_TOTAL]; 443 int len; 444 445 if ((node = ofw_bus_get_node(sc->dev)) == -1) 446 return (ENXIO); 447 448 if ((len = OF_getproplen(node, "dmas")) <= 0) 449 return (ENXIO); 450 451 if (len != sizeof(dts_value)) { 452 device_printf(sc->dev, 453 "\"dmas\" property length is invalid: %d (expected %d)", 454 len, sizeof(dts_value)); 455 return (ENXIO); 456 } 457 458 OF_getencprop(node, "dmas", dts_value, sizeof(dts_value)); 459 460 sc->sdma_ev_rx = dts_value[1]; 461 sc->sdma_ev_tx = dts_value[5]; 462 463 sdma_node = OF_node_from_xref(dts_value[0]); 464 465 sdma_sc = NULL; 466 467 sdma_dev = devclass_get_device(devclass_find("sdma"), 0); 468 if (sdma_dev) 469 sdma_sc = device_get_softc(sdma_dev); 470 471 if (sdma_sc == NULL) { 472 device_printf(sc->dev, "No sDMA found. Can't operate\n"); 473 return (ENXIO); 474 } 475 476 sc->sdma_sc = sdma_sc; 477 478 return (0); 479}; 480 481static int 482setup_dma(struct sc_pcminfo *scp) 483{ 484 struct sdma_conf *conf; 485 struct sc_chinfo *ch; 486 struct sc_info *sc; 487 int fmt; 488 489 ch = &scp->chan[0]; 490 sc = scp->sc; 491 conf = sc->conf; 492 493 conf->ih = ssi_dma_intr; 494 conf->ih_user = scp; 495 conf->saddr = sc->buf_base_phys; 496 conf->daddr = rman_get_start(sc->res[0]) + SSI_STX0; 497 conf->event = sc->sdma_ev_tx; /* SDMA TX event */ 498 conf->period = sndbuf_getblksz(ch->buffer); 499 conf->num_bd = sndbuf_getblkcnt(ch->buffer); 500 501 /* 502 * Word Length 503 * Can be 32, 24, 16 or 8 for sDMA. 504 * 505 * SSI supports 24 at max. 506 */ 507 508 fmt = sndbuf_getfmt(ch->buffer); 509 510 if (fmt & AFMT_16BIT) { 511 conf->word_length = 16; 512 conf->command = CMD_2BYTES; 513 } else if (fmt & AFMT_24BIT) { 514 conf->word_length = 24; 515 conf->command = CMD_3BYTES; 516 } else { 517 device_printf(sc->dev, "Unknown format\n"); 518 return (-1); 519 } 520 521 return (0); 522} 523 524static int 525ssi_start(struct sc_pcminfo *scp) 526{ 527 struct sc_info *sc; 528 int reg; 529 530 sc = scp->sc; 531 532 if (sdma_configure(sc->sdma_channel, sc->conf) != 0) { 533 device_printf(sc->dev, "Can't configure sDMA\n"); 534 return (-1); 535 } 536 537 /* Enable DMA interrupt */ 538 reg = (SIER_TDMAE); 539 WRITE4(sc, SSI_SIER, reg); 540 541 sdma_start(sc->sdma_channel); 542 543 return (0); 544} 545 546static int 547ssi_stop(struct sc_pcminfo *scp) 548{ 549 struct sc_info *sc; 550 int reg; 551 552 sc = scp->sc; 553 554 reg = READ4(sc, SSI_SIER); 555 reg &= ~(SIER_TDMAE); 556 WRITE4(sc, SSI_SIER, reg); 557 558 sdma_stop(sc->sdma_channel); 559 560 bzero(sc->buf_base, sc->dma_size); 561 562 return (0); 563} 564 565static int 566ssichan_trigger(kobj_t obj, void *data, int go) 567{ 568 struct sc_pcminfo *scp; 569 struct sc_chinfo *ch; 570 struct sc_info *sc; 571 572 ch = data; 573 scp = ch->parent; 574 sc = scp->sc; 575 576 snd_mtxlock(sc->lock); 577 578 switch (go) { 579 case PCMTRIG_START: 580#if 0 581 device_printf(scp->dev, "trigger start\n"); 582#endif 583 ch->run = 1; 584 585 ssi_start(scp); 586 587 break; 588 589 case PCMTRIG_STOP: 590 case PCMTRIG_ABORT: 591#if 0 592 device_printf(scp->dev, "trigger stop or abort\n"); 593#endif 594 ch->run = 0; 595 596 ssi_stop(scp); 597 598 break; 599 } 600 601 snd_mtxunlock(sc->lock); 602 603 return (0); 604} 605 606static uint32_t 607ssichan_getptr(kobj_t obj, void *data) 608{ 609 struct sc_pcminfo *scp; 610 struct sc_chinfo *ch; 611 struct sc_info *sc; 612 613 ch = data; 614 scp = ch->parent; 615 sc = scp->sc; 616 617 return (sc->pos); 618} 619 620static uint32_t ssi_pfmt[] = { 621 SND_FORMAT(AFMT_S24_LE, 2, 0), 622 0 623}; 624 625static struct pcmchan_caps ssi_pcaps = {44100, 192000, ssi_pfmt, 0}; 626 627static struct pcmchan_caps * 628ssichan_getcaps(kobj_t obj, void *data) 629{ 630 631 return (&ssi_pcaps); 632} 633 634static kobj_method_t ssichan_methods[] = { 635 KOBJMETHOD(channel_init, ssichan_init), 636 KOBJMETHOD(channel_free, ssichan_free), 637 KOBJMETHOD(channel_setformat, ssichan_setformat), 638 KOBJMETHOD(channel_setspeed, ssichan_setspeed), 639 KOBJMETHOD(channel_setblocksize, ssichan_setblocksize), 640 KOBJMETHOD(channel_trigger, ssichan_trigger), 641 KOBJMETHOD(channel_getptr, ssichan_getptr), 642 KOBJMETHOD(channel_getcaps, ssichan_getcaps), 643 KOBJMETHOD_END 644}; 645CHANNEL_DECLARE(ssichan); 646 647static int 648ssi_probe(device_t dev) 649{ 650 651 if (!ofw_bus_status_okay(dev)) 652 return (ENXIO); 653 654 if (!ofw_bus_is_compatible(dev, "fsl,imx6q-ssi")) 655 return (ENXIO); 656 657 device_set_desc(dev, "i.MX6 Synchronous Serial Interface (SSI)"); 658 return (BUS_PROBE_DEFAULT); 659} 660 661static void 662ssi_intr(void *arg) 663{ 664 struct sc_pcminfo *scp; 665 struct sc_chinfo *ch; 666 struct sc_info *sc; 667 668 scp = arg; 669 sc = scp->sc; 670 ch = &scp->chan[0]; 671 672 /* We don't use SSI interrupt */ 673#if 0 674 device_printf(sc->dev, "SSI Intr 0x%08x\n", 675 READ4(sc, SSI_SISR)); 676#endif 677} 678 679static void 680setup_ssi(struct sc_info *sc) 681{ 682 int reg; 683 684 reg = READ4(sc, SSI_STCCR); 685 reg &= ~(WL3_WL0_M << WL3_WL0_S); 686 reg |= (0xb << WL3_WL0_S); /* 24 bit */ 687 reg &= ~(DC4_DC0_M << DC4_DC0_S); 688 reg |= (1 << DC4_DC0_S); /* 2 words per frame */ 689 reg &= ~(STCCR_DIV2); /* Divide by 1 */ 690 reg &= ~(STCCR_PSR); /* Divide by 1 */ 691 reg &= ~(PM7_PM0_M << PM7_PM0_S); 692 reg |= (1 << PM7_PM0_S); /* Divide by 2 */ 693 WRITE4(sc, SSI_STCCR, reg); 694 695 reg = READ4(sc, SSI_SFCSR); 696 reg &= ~(SFCSR_TFWM0_M << SFCSR_TFWM0_S); 697 reg |= (8 << SFCSR_TFWM0_S); /* empty slots */ 698 WRITE4(sc, SSI_SFCSR, reg); 699 700 reg = READ4(sc, SSI_STCR); 701 reg |= (STCR_TFEN0); 702 reg &= ~(STCR_TFEN1); 703 reg &= ~(STCR_TSHFD); /* MSB */ 704 reg |= (STCR_TXBIT0); 705 reg |= (STCR_TXDIR | STCR_TFDIR); 706 reg |= (STCR_TSCKP); /* falling edge */ 707 reg |= (STCR_TFSI); 708 reg &= ~(STCR_TFSI); /* active high frame sync */ 709 reg &= ~(STCR_TFSL); 710 reg |= STCR_TEFS; 711 WRITE4(sc, SSI_STCR, reg); 712 713 reg = READ4(sc, SSI_SCR); 714 reg &= ~(SCR_I2S_MODE_M << SCR_I2S_MODE_S); /* Not master */ 715 reg |= (SCR_SSIEN | SCR_TE); 716 reg |= (SCR_NET); 717 reg |= (SCR_SYN); 718 WRITE4(sc, SSI_SCR, reg); 719} 720 721static void 722ssi_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err) 723{ 724 bus_addr_t *addr; 725 726 if (err) 727 return; 728 729 addr = (bus_addr_t*)arg; 730 *addr = segs[0].ds_addr; 731} 732 733static int 734ssi_attach(device_t dev) 735{ 736 char status[SND_STATUSLEN]; 737 struct sc_pcminfo *scp; 738 struct sc_info *sc; 739 int err; 740 741 sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO); 742 sc->dev = dev; 743 sc->sr = &rate_map[0]; 744 sc->pos = 0; 745 sc->conf = malloc(sizeof(struct sdma_conf), M_DEVBUF, M_WAITOK | M_ZERO); 746 747 sc->lock = snd_mtxcreate(device_get_nameunit(dev), "ssi softc"); 748 if (sc->lock == NULL) { 749 device_printf(dev, "Can't create mtx\n"); 750 return (ENXIO); 751 } 752 753 if (bus_alloc_resources(dev, ssi_spec, sc->res)) { 754 device_printf(dev, "could not allocate resources\n"); 755 return (ENXIO); 756 } 757 758 /* Memory interface */ 759 sc->bst = rman_get_bustag(sc->res[0]); 760 sc->bsh = rman_get_bushandle(sc->res[0]); 761 762 /* SDMA */ 763 if (find_sdma_controller(sc)) { 764 device_printf(dev, "could not find active SDMA\n"); 765 return (ENXIO); 766 } 767 768 /* Setup PCM */ 769 scp = malloc(sizeof(struct sc_pcminfo), M_DEVBUF, M_NOWAIT | M_ZERO); 770 scp->sc = sc; 771 scp->dev = dev; 772 773 /* 774 * Maximum possible DMA buffer. 775 * Will be used partially to match 24 bit word. 776 */ 777 sc->dma_size = 131072; 778 779 /* 780 * Must use dma_size boundary as modulo feature required. 781 * Modulo feature allows setup circular buffer. 782 */ 783 784 err = bus_dma_tag_create( 785 bus_get_dma_tag(sc->dev), 786 4, sc->dma_size, /* alignment, boundary */ 787 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 788 BUS_SPACE_MAXADDR, /* highaddr */ 789 NULL, NULL, /* filter, filterarg */ 790 sc->dma_size, 1, /* maxsize, nsegments */ 791 sc->dma_size, 0, /* maxsegsize, flags */ 792 NULL, NULL, /* lockfunc, lockarg */ 793 &sc->dma_tag); 794 795 err = bus_dmamem_alloc(sc->dma_tag, (void **)&sc->buf_base, 796 BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &sc->dma_map); 797 if (err) { 798 device_printf(dev, "cannot allocate framebuffer\n"); 799 return (ENXIO); 800 } 801 802 err = bus_dmamap_load(sc->dma_tag, sc->dma_map, sc->buf_base, 803 sc->dma_size, ssi_dmamap_cb, &sc->buf_base_phys, BUS_DMA_NOWAIT); 804 if (err) { 805 device_printf(dev, "cannot load DMA map\n"); 806 return (ENXIO); 807 } 808 809 bzero(sc->buf_base, sc->dma_size); 810 811 /* Setup interrupt handler */ 812 err = bus_setup_intr(dev, sc->res[1], INTR_MPSAFE | INTR_TYPE_AV, 813 NULL, ssi_intr, scp, &sc->ih); 814 if (err) { 815 device_printf(dev, "Unable to alloc interrupt resource.\n"); 816 return (ENXIO); 817 } 818 819 pcm_setflags(dev, pcm_getflags(dev) | SD_F_MPSAFE); 820 821 err = pcm_register(dev, scp, 1, 0); 822 if (err) { 823 device_printf(dev, "Can't register pcm.\n"); 824 return (ENXIO); 825 } 826 827 scp->chnum = 0; 828 pcm_addchan(dev, PCMDIR_PLAY, &ssichan_class, scp); 829 scp->chnum++; 830 831 snprintf(status, SND_STATUSLEN, "at simplebus"); 832 pcm_setstatus(dev, status); 833 834 mixer_init(dev, &ssimixer_class, scp); 835 setup_ssi(sc); 836 837 imx_ccm_ssi_configure(dev); 838 839 sc->sdma_channel = sdma_alloc(); 840 if (sc->sdma_channel < 0) { 841 device_printf(sc->dev, "Can't get sDMA channel\n"); 842 return (1); 843 } 844 845 return (0); 846} 847 848static device_method_t ssi_pcm_methods[] = { 849 DEVMETHOD(device_probe, ssi_probe), 850 DEVMETHOD(device_attach, ssi_attach), 851 { 0, 0 } 852}; 853 854static driver_t ssi_pcm_driver = { 855 "pcm", 856 ssi_pcm_methods, 857 PCM_SOFTC_SIZE, 858}; 859 860DRIVER_MODULE(ssi, simplebus, ssi_pcm_driver, pcm_devclass, 0, 0); 861MODULE_DEPEND(ssi, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); 862MODULE_DEPEND(ssi, sdma, 0, 0, 0); 863MODULE_VERSION(ssi, 1); 864