Lines Matching +full:i2s +full:- +full:transmitter +full:- +full:1
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
10 * 1. Redistributions of source code must retain the above copyright
61 #define I2S_TCR1 0x04 /* SAI Transmit Configuration 1 */
70 #define I2S_RCR1 0x84 /* SAI Receive Configuration 1 */
83 #define TCR2_BCP (1 << 25) /* Bit Clock Polarity */
84 #define TCR2_BCD (1 << 24) /* Bit Clock Direction */
85 #define TCR3_TCE (1 << 16) /* Transmit Channel Enable */
90 #define TCR4_MF (1 << 4) /* MSB First */
91 #define TCR4_FSE (1 << 3) /* Frame Sync Early */
92 #define TCR4_FSP (1 << 1) /* Frame Sync Polarity Low */
93 #define TCR4_FSD (1 << 0) /* Frame Sync Direction Master */
100 #define TCSR_TE (1 << 31) /* Transmitter Enable */
101 #define TCSR_BCE (1 << 28) /* Bit Clock Enable */
102 #define TCSR_FRDE (1 << 0) /* FIFO Request DMA Enable */
104 #define SAI_NCHANNELS 1
110 uint32_t div; /* Bit Clock Divide. Division value is (div + 1) * 2. */
118 * (div + 1) * 2 = MCLK/(nch * LRCLK * bits/1000000),
120 * MCLK - master clock
121 * nch - number of channels
122 * LRCLK - left right clock
123 * e.g. (div + 1) * 2 = 16.9344/(2 * 44100 * 24/1000000)
126 * { 96000, 1, 18, 40176000, 93000000 },
132 { 192000, 1, 36, 80352000, 93000000 }, /* 36.864 Mhz */
183 { -1, 0 }
202 sc = scp->sc; in saimixer_init()
205 return -1; in saimixer_init()
209 mtx_lock(&sc->lock); in saimixer_init()
210 pcm_setflags(scp->dev, pcm_getflags(scp->dev) | SD_F_SOFTPCMVOL); in saimixer_init()
212 mtx_unlock(&sc->lock); in saimixer_init()
226 device_printf(scp->dev, "saimixer_set() %d %d\n", in saimixer_set()
253 sc = scp->sc; in saichan_init()
255 mtx_lock(&sc->lock); in saichan_init()
256 ch = &scp->chan[0]; in saichan_init()
257 ch->dir = dir; in saichan_init()
258 ch->run = 0; in saichan_init()
259 ch->buffer = b; in saichan_init()
260 ch->channel = c; in saichan_init()
261 ch->parent = scp; in saichan_init()
262 mtx_unlock(&sc->lock); in saichan_init()
264 if (sndbuf_setup(ch->buffer, sc->buf_base, sc->dma_size) != 0) { in saichan_init()
265 device_printf(scp->dev, "Can't setup sndbuf.\n"); in saichan_init()
276 struct sc_pcminfo *scp = ch->parent; in saichan_free()
277 struct sc_info *sc = scp->sc; in saichan_free()
280 device_printf(scp->dev, "saichan_free()\n"); in saichan_free()
283 mtx_lock(&sc->lock); in saichan_free()
285 mtx_unlock(&sc->lock); in saichan_free()
295 ch->format = format; in saichan_setformat()
311 scp = ch->parent; in saichan_setspeed()
312 sc = scp->sc; in saichan_setspeed()
326 threshold = sr->speed + ((rate_map[i + 1].speed != 0) ? in saichan_setspeed()
327 ((rate_map[i + 1].speed - sr->speed) >> 1) : 0); in saichan_setspeed()
333 sc->sr = sr; in saichan_setspeed()
337 return (sr->speed); in saichan_setspeed()
346 sr = sc->sr; in sai_configure_clock()
352 * after re-enabling transmitter (DMA goes stall). in sai_configure_clock()
357 reg |= (sr->div << 0); in sai_configure_clock()
360 pll4_configure_output(sr->mfi, sr->mfn, sr->mfd); in sai_configure_clock()
367 struct sc_pcminfo *scp = ch->parent; in saichan_setblocksize()
368 struct sc_info *sc = scp->sc; in saichan_setblocksize()
370 sndbuf_resize(ch->buffer, sc->dma_size / blocksize, blocksize); in saichan_setblocksize()
372 sc->period = ch->buffer->blksz; in saichan_setblocksize()
373 return (sc->period); in saichan_setblocksize()
386 ch = &scp->chan[0]; in sai_dma_intr()
388 sc = scp->sc; in sai_dma_intr()
389 tcd = sc->tcd; in sai_dma_intr()
391 sc->pos += (tcd->nbytes * tcd->nmajor); in sai_dma_intr()
392 if (sc->pos >= sc->dma_size) in sai_dma_intr()
393 sc->pos -= sc->dma_size; in sai_dma_intr()
395 if (ch->run) in sai_dma_intr()
396 chn_intr(ch->channel); in sai_dma_intr()
414 if ((node = ofw_bus_get_node(sc->dev)) == -1) in find_edma_controller()
417 if ((len = OF_getproplen(node, "edma-controller")) <= 0) in find_edma_controller()
419 if ((len = OF_getproplen(node, "edma-src-transmit")) <= 0) in find_edma_controller()
421 if ((len = OF_getproplen(node, "edma-mux-group")) <= 0) in find_edma_controller()
424 OF_getencprop(node, "edma-src-transmit", &dts_value, len); in find_edma_controller()
426 OF_getencprop(node, "edma-mux-group", &dts_value, len); in find_edma_controller()
428 OF_getencprop(node, "edma-controller", &dts_value, len); in find_edma_controller()
431 if ((len = OF_getproplen(edma_node, "device-id")) <= 0) { in find_edma_controller()
435 OF_getencprop(edma_node, "device-id", &dts_value, len); in find_edma_controller()
444 if (edma_sc->device_id == edma_device_id) { in find_edma_controller()
454 device_printf(sc->dev, "no eDMA. can't operate\n"); in find_edma_controller()
458 sc->edma_sc = edma_sc; in find_edma_controller()
460 sc->edma_chnum = edma_sc->channel_configure(edma_sc, edma_mux_group, in find_edma_controller()
462 if (sc->edma_chnum < 0) { in find_edma_controller()
476 sc = scp->sc; in setup_dma()
479 tcd->channel = sc->edma_chnum; in setup_dma()
480 tcd->ih = sai_dma_intr; in setup_dma()
481 tcd->ih_user = scp; in setup_dma()
482 tcd->saddr = sc->buf_base_phys; in setup_dma()
483 tcd->daddr = rman_get_start(sc->res[0]) + I2S_TDR0; in setup_dma()
489 tcd->nbytes = 64; in setup_dma()
491 tcd->nmajor = 512; in setup_dma()
492 tcd->smod = 17; /* dma_size range */ in setup_dma()
493 tcd->dmod = 0; in setup_dma()
494 tcd->esg = 0; in setup_dma()
495 tcd->soff = 0x4; in setup_dma()
496 tcd->doff = 0; in setup_dma()
497 tcd->ssize = 0x2; in setup_dma()
498 tcd->dsize = 0x2; in setup_dma()
499 tcd->slast = 0; in setup_dma()
500 tcd->dlast_sga = 0; in setup_dma()
502 sc->tcd = tcd; in setup_dma()
504 sc->edma_sc->dma_setup(sc->edma_sc, sc->tcd); in setup_dma()
513 struct sc_pcminfo *scp = ch->parent; in saichan_trigger()
514 struct sc_info *sc = scp->sc; in saichan_trigger()
516 mtx_lock(&sc->lock); in saichan_trigger()
521 device_printf(scp->dev, "trigger start\n"); in saichan_trigger()
523 ch->run = 1; in saichan_trigger()
529 device_printf(scp->dev, "trigger stop or abort\n"); in saichan_trigger()
531 ch->run = 0; in saichan_trigger()
535 mtx_unlock(&sc->lock); in saichan_trigger()
548 scp = ch->parent; in saichan_getptr()
549 sc = scp->sc; in saichan_getptr()
551 return (sc->pos); in saichan_getptr()
556 * eDMA doesn't allow 24-bit coping,
592 if (!ofw_bus_is_compatible(dev, "fsl,mvf600-sai")) in sai_probe()
606 sc = scp->sc; in sai_intr()
608 device_printf(sc->dev, "Error I2S_TCSR == 0x%08x\n", in sai_intr()
634 reg |= (1 << TCR2_MSEL_S); in setup_sai()
644 /* Configure to 32-bit I2S mode */ in setup_sai()
647 reg |= (1 << TCR4_FRSZ_S); /* 2 words per frame */ in setup_sai()
662 /* Enable transmitter */ in setup_sai()
665 reg |= (1 << 10); /* FEIE */ in setup_sai()
690 sc->dev = dev; in sai_attach()
691 sc->sr = &rate_map[0]; in sai_attach()
692 sc->pos = 0; in sai_attach()
694 mtx_init(&sc->lock, device_get_nameunit(dev), "sai softc", MTX_DEF); in sai_attach()
696 if (bus_alloc_resources(dev, sai_spec, sc->res)) { in sai_attach()
702 sc->bst = rman_get_bustag(sc->res[0]); in sai_attach()
703 sc->bsh = rman_get_bushandle(sc->res[0]); in sai_attach()
713 scp->sc = sc; in sai_attach()
714 scp->dev = dev; in sai_attach()
717 sc->dma_size = 131072; in sai_attach()
725 bus_get_dma_tag(sc->dev), in sai_attach()
726 4, sc->dma_size, /* alignment, boundary */ in sai_attach()
730 sc->dma_size, 1, /* maxsize, nsegments */ in sai_attach()
731 sc->dma_size, 0, /* maxsegsize, flags */ in sai_attach()
733 &sc->dma_tag); in sai_attach()
735 err = bus_dmamem_alloc(sc->dma_tag, (void **)&sc->buf_base, in sai_attach()
736 BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &sc->dma_map); in sai_attach()
742 err = bus_dmamap_load(sc->dma_tag, sc->dma_map, sc->buf_base, in sai_attach()
743 sc->dma_size, sai_dmamap_cb, &sc->buf_base_phys, BUS_DMA_NOWAIT); in sai_attach()
749 bzero(sc->buf_base, sc->dma_size); in sai_attach()
752 err = bus_setup_intr(dev, sc->res[1], INTR_MPSAFE | INTR_TYPE_AV, in sai_attach()
753 NULL, sai_intr, scp, &sc->ih); in sai_attach()
763 scp->chnum = 0; in sai_attach()
765 scp->chnum++; in sai_attach()
796 MODULE_VERSION(sai, 1);