Lines Matching defs:sai

50  * @sai: SAI context
53 static inline bool fsl_sai_dir_is_synced(struct fsl_sai *sai, int dir)
58 return !sai->synchronous[dir] && sai->synchronous[adir];
61 static struct pinctrl_state *fsl_sai_get_pins_state(struct fsl_sai *sai, u32 bclk)
65 if (sai->is_pdm_mode) {
68 state = pinctrl_lookup_state(sai->pinctrl, "dsd512");
72 state = pinctrl_lookup_state(sai->pinctrl, "dsd");
76 state = pinctrl_lookup_state(sai->pinctrl, "pcm_b2m");
81 state = pinctrl_lookup_state(sai->pinctrl, "default");
88 struct fsl_sai *sai = (struct fsl_sai *)devid;
89 unsigned int ofs = sai->soc_data->reg_offset;
90 struct device *dev = &sai->pdev->dev;
102 regmap_read(sai->regmap, FSL_SAI_TCSR(ofs), &xcsr);
129 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), flags | xcsr);
133 regmap_read(sai->regmap, FSL_SAI_RCSR(ofs), &xcsr);
160 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), flags | xcsr);
169 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
171 sai->slots = slots;
172 sai->slot_width = slot_width;
180 struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);
182 sai->bclk_ratio = ratio;
190 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
191 unsigned int ofs = sai->soc_data->reg_offset;
211 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
219 struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);
222 fsl_asoc_reparent_pll_clocks(dai->dev, sai->mclk_clk[clk_id],
223 sai->pll8k_clk, sai->pll11k_clk, freq);
225 ret = clk_set_rate(sai->mclk_clk[clk_id], freq);
235 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
247 if (IS_ERR_OR_NULL(sai->mclk_clk[clk_id])) {
252 if (sai->mclk_streams == 0) {
275 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
276 unsigned int ofs = sai->soc_data->reg_offset;
279 if (!sai->is_lsb_first)
282 sai->is_pdm_mode = false;
283 sai->is_dsp_mode = false;
312 sai->is_dsp_mode = true;
320 sai->is_dsp_mode = true;
325 sai->is_pdm_mode = true;
360 sai->is_consumer_mode = false;
363 sai->is_consumer_mode = true;
367 sai->is_consumer_mode = false;
371 sai->is_consumer_mode = true;
377 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
379 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
405 struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);
406 unsigned int reg, ofs = sai->soc_data->reg_offset;
412 bool support_1_1_ratio = sai->verid.version >= 0x0301;
415 if (sai->is_consumer_mode)
423 id = sai->soc_data->mclk0_is_mclk1 ? 1 : 0;
428 clk_rate = clk_get_rate(sai->mclk_clk[id]);
456 sai->mclk_id[tx] = id;
471 sai->mclk_id[tx], savediv, bestdiff);
483 if (fsl_sai_dir_is_synced(sai, adir))
485 else if (!sai->synchronous[dir])
490 regmap_update_bits(sai->regmap, reg, FSL_SAI_CR2_MSEL_MASK,
491 FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
494 regmap_update_bits(sai->regmap, reg,
497 if (fsl_sai_dir_is_synced(sai, adir))
498 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
501 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
504 regmap_update_bits(sai->regmap, reg,
516 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
517 unsigned int ofs = sai->soc_data->reg_offset;
521 struct fsl_sai_dl_cfg *dl_cfg = sai->dl_cfg;
524 int dl_cfg_cnt = sai->dl_cfg_cnt;
534 if (sai->slot_width)
535 slot_width = sai->slot_width;
537 if (sai->slots)
538 slots = sai->slots;
539 else if (sai->bclk_ratio)
540 slots = sai->bclk_ratio / slot_width;
548 if (sai->is_pdm_mode) {
565 bclk = params_rate(params) * (sai->bclk_ratio ? sai->bclk_ratio : slots * slot_width);
567 if (!IS_ERR_OR_NULL(sai->pinctrl)) {
568 sai->pins_state = fsl_sai_get_pins_state(sai, bclk);
569 if (!IS_ERR_OR_NULL(sai->pins_state)) {
570 ret = pinctrl_select_state(sai->pinctrl, sai->pins_state);
578 if (!sai->is_consumer_mode) {
584 if (!(sai->mclk_streams & BIT(substream->stream))) {
585 ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[tx]]);
589 sai->mclk_streams |= BIT(substream->stream);
593 if (!sai->is_dsp_mode && !sai->is_pdm_mode)
599 if (sai->is_lsb_first || sai->is_pdm_mode)
616 if (!sai->is_consumer_mode && fsl_sai_dir_is_synced(sai, adir)) {
617 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(!tx, ofs),
621 regmap_update_bits(sai->regmap, FSL_SAI_xCR5(!tx, ofs),
634 if (hweight8(dl_cfg[dl_cfg_idx].mask[tx]) <= 1 || sai->is_multi_fifo_dma)
635 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
638 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
641 dma_params = tx ? &sai->dma_params_tx : &sai->dma_params_rx;
642 dma_params->addr = sai->res->start + FSL_SAI_xDR0(tx) +
645 if (sai->is_multi_fifo_dma) {
646 sai->audio_config[tx].words_per_fifo = min(slots, channels);
648 sai->audio_config[tx].n_fifos_dst = pins;
649 sai->audio_config[tx].stride_fifos_dst = dl_cfg[dl_cfg_idx].next_off[tx];
651 sai->audio_config[tx].n_fifos_src = pins;
652 sai->audio_config[tx].stride_fifos_src = dl_cfg[dl_cfg_idx].next_off[tx];
654 dma_params->maxburst = sai->audio_config[tx].words_per_fifo * pins;
655 dma_params->peripheral_config = &sai->audio_config[tx];
656 dma_params->peripheral_size = sizeof(sai->audio_config[tx]);
658 watermark = tx ? (sai->soc_data->fifo_depth - dma_params->maxburst) :
660 regmap_update_bits(sai->regmap, FSL_SAI_xCR1(tx, ofs),
661 FSL_SAI_CR1_RFW_MASK(sai->soc_data->fifo_depth),
666 for (i = 0; i < sai->soc_data->pins; i++) {
672 regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs),
685 if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output &&
686 !sai->is_consumer_mode)
687 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
690 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
694 regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, ofs),
699 if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output &&
700 !sai->is_consumer_mode)
701 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
704 regmap_write(sai->regmap, FSL_SAI_xMR(tx),
713 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
715 unsigned int ofs = sai->soc_data->reg_offset;
718 regmap_write(sai->regmap, FSL_SAI_xMR(tx), 0);
720 regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs),
723 if (!sai->is_consumer_mode &&
724 sai->mclk_streams & BIT(substream->stream)) {
725 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[tx]]);
726 sai->mclk_streams &= ~BIT(substream->stream);
732 static void fsl_sai_config_disable(struct fsl_sai *sai, int dir)
734 unsigned int ofs = sai->soc_data->reg_offset;
738 if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output)
743 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
749 regmap_read(sai->regmap, FSL_SAI_xCSR(tx, ofs), &xcsr);
752 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
756 * For sai master mode, after several open/close sai,
760 * next sai version.
762 if (!sai->is_consumer_mode) {
764 regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), FSL_SAI_CSR_SR);
766 regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), 0);
773 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
774 unsigned int ofs = sai->soc_data->reg_offset;
786 regmap_update_bits(sai->regmap, FSL_SAI_TCR2(ofs), FSL_SAI_CR2_SYNC,
787 sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0);
788 regmap_update_bits(sai->regmap, FSL_SAI_RCR2(ofs), FSL_SAI_CR2_SYNC,
789 sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0);
799 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
802 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
815 if (fsl_sai_dir_is_synced(sai, adir))
816 regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx), ofs),
819 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
825 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
827 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
831 regmap_read(sai->regmap, FSL_SAI_xCSR(!tx, ofs), &xcsr);
837 if (fsl_sai_dir_is_synced(sai, adir) && !(xcsr & FSL_SAI_CSR_FRDE))
838 fsl_sai_config_disable(sai, adir);
846 if (!fsl_sai_dir_is_synced(sai, dir) || !(xcsr & FSL_SAI_CSR_FRDE))
847 fsl_sai_config_disable(sai, dir);
860 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
868 if (sai->soc_data->use_edma)
871 tx ? sai->dma_params_tx.maxburst :
872 sai->dma_params_rx.maxburst);
882 struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
883 unsigned int ofs = sai->soc_data->reg_offset;
886 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR);
887 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR);
889 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0);
890 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0);
892 regmap_update_bits(sai->regmap, FSL_SAI_TCR1(ofs),
893 FSL_SAI_CR1_RFW_MASK(sai->soc_data->fifo_depth),
894 sai->soc_data->fifo_depth - sai->dma_params_tx.maxburst);
895 regmap_update_bits(sai->regmap, FSL_SAI_RCR1(ofs),
896 FSL_SAI_CR1_RFW_MASK(sai->soc_data->fifo_depth),
897 sai->dma_params_rx.maxburst - 1);
899 snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx,
900 &sai->dma_params_rx);
919 struct fsl_sai *sai = snd_soc_component_get_drvdata(component);
920 struct device *dev = &sai->pdev->dev;
923 if (!IS_ERR_OR_NULL(sai->pinctrl) && !IS_ERR_OR_NULL(sai->pins_state)) {
924 ret = pinctrl_select_state(sai->pinctrl, sai->pins_state);
957 .name = "fsl-sai",
1012 struct fsl_sai *sai = dev_get_drvdata(dev);
1013 unsigned int ofs = sai->soc_data->reg_offset;
1068 struct fsl_sai *sai = dev_get_drvdata(dev);
1069 unsigned int ofs = sai->soc_data->reg_offset;
1111 struct fsl_sai *sai = dev_get_drvdata(dev);
1112 unsigned int ofs = sai->soc_data->reg_offset;
1158 struct fsl_sai *sai = dev_get_drvdata(dev);
1159 unsigned char ofs = sai->soc_data->reg_offset;
1166 ret = regmap_read(sai->regmap, FSL_SAI_VERID, &val);
1172 sai->verid.version = val &
1174 sai->verid.version >>= FSL_SAI_VERID_MINOR_SHIFT;
1175 sai->verid.feature = val & FSL_SAI_VERID_FEATURE_MASK;
1177 ret = regmap_read(sai->regmap, FSL_SAI_PARAM, &val);
1184 sai->param.slot_num = 1 <<
1188 sai->param.fifo_depth = 1 <<
1192 sai->param.dataline = val & FSL_SAI_PARAM_DLN_MASK;
1224 static int fsl_sai_read_dlcfg(struct fsl_sai *sai)
1226 struct platform_device *pdev = sai->pdev;
1252 soc_dl = BIT(sai->soc_data->pins) - 1;
1254 cfg[0].pins[0] = sai->soc_data->pins;
1259 cfg[0].pins[1] = sai->soc_data->pins;
1304 sai->dl_cfg = cfg;
1305 sai->dl_cfg_cnt = num_cfg + 1;
1316 struct fsl_sai *sai;
1324 sai = devm_kzalloc(dev, sizeof(*sai), GFP_KERNEL);
1325 if (!sai)
1328 sai->pdev = pdev;
1329 sai->soc_data = of_device_get_match_data(dev);
1331 sai->is_lsb_first = of_property_read_bool(np, "lsb-first");
1333 base = devm_platform_get_and_ioremap_resource(pdev, 0, &sai->res);
1337 if (sai->soc_data->reg_offset == 8) {
1344 sai->regmap = devm_regmap_init_mmio(dev, base, &fsl_sai_regmap_config);
1345 if (IS_ERR(sai->regmap)) {
1347 return PTR_ERR(sai->regmap);
1350 sai->bus_clk = devm_clk_get(dev, "bus");
1352 if (IS_ERR(sai->bus_clk) && PTR_ERR(sai->bus_clk) != -EPROBE_DEFER)
1353 sai->bus_clk = devm_clk_get(dev, "sai");
1354 if (IS_ERR(sai->bus_clk)) {
1356 PTR_ERR(sai->bus_clk));
1358 return PTR_ERR(sai->bus_clk);
1363 sai->mclk_clk[i] = devm_clk_get(dev, tmp);
1364 if (IS_ERR(sai->mclk_clk[i])) {
1366 i, PTR_ERR(sai->mclk_clk[i]));
1367 sai->mclk_clk[i] = NULL;
1371 if (sai->soc_data->mclk0_is_mclk1)
1372 sai->mclk_clk[0] = sai->mclk_clk[1];
1374 sai->mclk_clk[0] = sai->bus_clk;
1376 fsl_asoc_get_pll_clocks(&pdev->dev, &sai->pll8k_clk,
1377 &sai->pll11k_clk);
1381 if (!sai->soc_data->use_edma && !ret && dmas[2] == IMX_DMATYPE_MULTI_SAI)
1382 sai->is_multi_fifo_dma = true;
1385 ret = fsl_sai_read_dlcfg(sai);
1396 np->name, sai);
1402 memcpy(&sai->cpu_dai_drv, &fsl_sai_dai_template,
1406 sai->synchronous[RX] = true;
1407 sai->synchronous[TX] = false;
1408 sai->cpu_dai_drv.symmetric_rate = 1;
1409 sai->cpu_dai_drv.symmetric_channels = 1;
1410 sai->cpu_dai_drv.symmetric_sample_bits = 1;
1412 if (of_property_read_bool(np, "fsl,sai-synchronous-rx") &&
1413 of_property_read_bool(np, "fsl,sai-asynchronous")) {
1419 if (of_property_read_bool(np, "fsl,sai-synchronous-rx")) {
1421 sai->synchronous[RX] = false;
1422 sai->synchronous[TX] = true;
1423 } else if (of_property_read_bool(np, "fsl,sai-asynchronous")) {
1425 sai->synchronous[RX] = false;
1426 sai->synchronous[TX] = false;
1427 sai->cpu_dai_drv.symmetric_rate = 0;
1428 sai->cpu_dai_drv.symmetric_channels = 0;
1429 sai->cpu_dai_drv.symmetric_sample_bits = 0;
1432 sai->mclk_direction_output = of_property_read_bool(np, "fsl,sai-mclk-direction-output");
1434 if (sai->mclk_direction_output &&
1435 of_device_is_compatible(np, "fsl,imx6ul-sai")) {
1442 index = of_alias_get_id(np, "sai");
1450 sai->dma_params_rx.addr = sai->res->start + FSL_SAI_RDR0;
1451 sai->dma_params_tx.addr = sai->res->start + FSL_SAI_TDR0;
1452 sai->dma_params_rx.maxburst =
1453 sai->soc_data->max_burst[RX] ? sai->soc_data->max_burst[RX] : FSL_SAI_MAXBURST_RX;
1454 sai->dma_params_tx.maxburst =
1455 sai->soc_data->max_burst[TX] ? sai->soc_data->max_burst[TX] : FSL_SAI_MAXBURST_TX;
1457 sai->pinctrl = devm_pinctrl_get(&pdev->dev);
1459 platform_set_drvdata(pdev, sai);
1471 /* Get sai version */
1477 if (sai->mclk_direction_output &&
1478 sai->soc_data->max_register >= FSL_SAI_MCTL) {
1479 regmap_update_bits(sai->regmap, FSL_SAI_MCTL,
1491 if (sai->soc_data->use_imx_pcm) {
1508 &sai->cpu_dai_drv, 1);
1655 { .compatible = "fsl,vf610-sai", .data = &fsl_sai_vf610_data },
1656 { .compatible = "fsl,imx6sx-sai", .data = &fsl_sai_imx6sx_data },
1657 { .compatible = "fsl,imx6ul-sai", .data = &fsl_sai_imx6sx_data },
1658 { .compatible = "fsl,imx7ulp-sai", .data = &fsl_sai_imx7ulp_data },
1659 { .compatible = "fsl,imx8mq-sai", .data = &fsl_sai_imx8mq_data },
1660 { .compatible = "fsl,imx8qm-sai", .data = &fsl_sai_imx8qm_data },
1661 { .compatible = "fsl,imx8mm-sai", .data = &fsl_sai_imx8mm_data },
1662 { .compatible = "fsl,imx8mp-sai", .data = &fsl_sai_imx8mp_data },
1663 { .compatible = "fsl,imx8ulp-sai", .data = &fsl_sai_imx8ulp_data },
1664 { .compatible = "fsl,imx8mn-sai", .data = &fsl_sai_imx8mn_data },
1665 { .compatible = "fsl,imx93-sai", .data = &fsl_sai_imx93_data },
1666 { .compatible = "fsl,imx95-sai", .data = &fsl_sai_imx95_data },
1673 struct fsl_sai *sai = dev_get_drvdata(dev);
1675 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE))
1676 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);
1678 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK))
1679 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);
1681 clk_disable_unprepare(sai->bus_clk);
1683 if (sai->soc_data->flags & PMQOS_CPU_LATENCY)
1684 cpu_latency_qos_remove_request(&sai->pm_qos_req);
1686 regcache_cache_only(sai->regmap, true);
1693 struct fsl_sai *sai = dev_get_drvdata(dev);
1694 unsigned int ofs = sai->soc_data->reg_offset;
1697 ret = clk_prepare_enable(sai->bus_clk);
1703 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK)) {
1704 ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[1]]);
1709 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE)) {
1710 ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[0]]);
1715 if (sai->soc_data->flags & PMQOS_CPU_LATENCY)
1716 cpu_latency_qos_add_request(&sai->pm_qos_req, 0);
1718 regcache_cache_only(sai->regmap, false);
1719 regcache_mark_dirty(sai->regmap);
1720 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR);
1721 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR);
1723 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0);
1724 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0);
1726 ret = regcache_sync(sai->regmap);
1730 if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output)
1731 regmap_update_bits(sai->regmap, FSL_SAI_TCSR(ofs),
1737 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE))
1738 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);
1740 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK))
1741 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);
1743 clk_disable_unprepare(sai->bus_clk);
1759 .name = "fsl-sai",
1768 MODULE_ALIAS("platform:fsl-sai");