Lines Matching refs:sai
51 * @sai: SAI context
54 static inline bool fsl_sai_dir_is_synced(struct fsl_sai *sai, int dir)
59 return !sai->synchronous[dir] && sai->synchronous[adir];
62 static struct pinctrl_state *fsl_sai_get_pins_state(struct fsl_sai *sai, u32 bclk)
66 if (sai->is_pdm_mode) {
69 state = pinctrl_lookup_state(sai->pinctrl, "dsd512");
73 state = pinctrl_lookup_state(sai->pinctrl, "dsd");
77 state = pinctrl_lookup_state(sai->pinctrl, "pcm_b2m");
82 state = pinctrl_lookup_state(sai->pinctrl, "default");
89 struct fsl_sai *sai = (struct fsl_sai *)devid;
90 unsigned int ofs = sai->soc_data->reg_offset;
91 struct device *dev = &sai->pdev->dev;
103 regmap_read(sai->regmap, FSL_SAI_TCSR(ofs), &xcsr);
130 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), flags | xcsr);
134 regmap_read(sai->regmap, FSL_SAI_RCSR(ofs), &xcsr);
161 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), flags | xcsr);
170 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
172 sai->slots = slots;
173 sai->slot_width = slot_width;
181 struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);
183 sai->bclk_ratio = ratio;
191 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
192 unsigned int ofs = sai->soc_data->reg_offset;
212 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
220 struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);
223 fsl_asoc_reparent_pll_clocks(dai->dev, sai->mclk_clk[clk_id],
224 sai->pll8k_clk, sai->pll11k_clk, freq);
226 ret = clk_set_rate(sai->mclk_clk[clk_id], freq);
236 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
248 if (IS_ERR_OR_NULL(sai->mclk_clk[clk_id])) {
253 if (sai->mclk_streams == 0) {
276 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
277 unsigned int ofs = sai->soc_data->reg_offset;
280 if (!sai->is_lsb_first)
283 sai->is_pdm_mode = false;
284 sai->is_dsp_mode = false;
313 sai->is_dsp_mode = true;
321 sai->is_dsp_mode = true;
326 sai->is_pdm_mode = true;
361 sai->is_consumer_mode = false;
364 sai->is_consumer_mode = true;
368 sai->is_consumer_mode = false;
372 sai->is_consumer_mode = true;
378 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
380 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
406 struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);
407 unsigned int reg, ofs = sai->soc_data->reg_offset;
413 bool support_1_1_ratio = sai->verid.version >= 0x0301;
416 if (sai->is_consumer_mode)
424 id = sai->soc_data->mclk0_is_mclk1 ? 1 : 0;
429 clk_rate = clk_get_rate(sai->mclk_clk[id]);
457 sai->mclk_id[tx] = id;
472 sai->mclk_id[tx], savediv, bestdiff);
484 if (fsl_sai_dir_is_synced(sai, adir))
486 else if (!sai->synchronous[dir])
491 regmap_update_bits(sai->regmap, reg, FSL_SAI_CR2_MSEL_MASK,
492 FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
495 regmap_update_bits(sai->regmap, reg,
498 if (fsl_sai_dir_is_synced(sai, adir))
499 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
502 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
505 regmap_update_bits(sai->regmap, reg,
517 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
518 unsigned int ofs = sai->soc_data->reg_offset;
522 struct fsl_sai_dl_cfg *dl_cfg = sai->dl_cfg;
525 int dl_cfg_cnt = sai->dl_cfg_cnt;
535 if (sai->slot_width)
536 slot_width = sai->slot_width;
538 if (sai->slots)
539 slots = sai->slots;
540 else if (sai->bclk_ratio)
541 slots = sai->bclk_ratio / slot_width;
549 if (sai->is_pdm_mode) {
566 bclk = params_rate(params) * (sai->bclk_ratio ? sai->bclk_ratio : slots * slot_width);
568 if (!IS_ERR_OR_NULL(sai->pinctrl)) {
569 sai->pins_state = fsl_sai_get_pins_state(sai, bclk);
570 if (!IS_ERR_OR_NULL(sai->pins_state)) {
571 ret = pinctrl_select_state(sai->pinctrl, sai->pins_state);
579 if (!sai->is_consumer_mode) {
585 if (!(sai->mclk_streams & BIT(substream->stream))) {
586 ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[tx]]);
590 sai->mclk_streams |= BIT(substream->stream);
594 if (!sai->is_dsp_mode && !sai->is_pdm_mode)
600 if (sai->is_lsb_first || sai->is_pdm_mode)
617 if (!sai->is_consumer_mode && fsl_sai_dir_is_synced(sai, adir)) {
618 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(!tx, ofs),
622 regmap_update_bits(sai->regmap, FSL_SAI_xCR5(!tx, ofs),
635 if (hweight8(dl_cfg[dl_cfg_idx].mask[tx]) <= 1 || sai->is_multi_fifo_dma)
636 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
639 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
642 dma_params = tx ? &sai->dma_params_tx : &sai->dma_params_rx;
643 dma_params->addr = sai->res->start + FSL_SAI_xDR0(tx) +
646 if (sai->is_multi_fifo_dma) {
647 sai->audio_config[tx].words_per_fifo = min(slots, channels);
649 sai->audio_config[tx].n_fifos_dst = pins;
650 sai->audio_config[tx].stride_fifos_dst = dl_cfg[dl_cfg_idx].next_off[tx];
652 sai->audio_config[tx].n_fifos_src = pins;
653 sai->audio_config[tx].stride_fifos_src = dl_cfg[dl_cfg_idx].next_off[tx];
655 dma_params->maxburst = sai->audio_config[tx].words_per_fifo * pins;
656 dma_params->peripheral_config = &sai->audio_config[tx];
657 dma_params->peripheral_size = sizeof(sai->audio_config[tx]);
659 watermark = tx ? (sai->soc_data->fifo_depth - dma_params->maxburst) :
661 regmap_update_bits(sai->regmap, FSL_SAI_xCR1(tx, ofs),
662 FSL_SAI_CR1_RFW_MASK(sai->soc_data->fifo_depth),
667 for (i = 0; i < sai->soc_data->pins; i++) {
673 regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs),
686 if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output &&
687 !sai->is_consumer_mode)
688 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
691 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
695 regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, ofs),
700 if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output &&
701 !sai->is_consumer_mode)
702 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
705 regmap_write(sai->regmap, FSL_SAI_xMR(tx),
714 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
716 unsigned int ofs = sai->soc_data->reg_offset;
719 regmap_write(sai->regmap, FSL_SAI_xMR(tx), 0);
721 regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs),
724 if (!sai->is_consumer_mode &&
725 sai->mclk_streams & BIT(substream->stream)) {
726 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[tx]]);
727 sai->mclk_streams &= ~BIT(substream->stream);
733 static void fsl_sai_config_disable(struct fsl_sai *sai, int dir)
735 unsigned int ofs = sai->soc_data->reg_offset;
739 if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output)
744 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
750 regmap_read(sai->regmap, FSL_SAI_xCSR(tx, ofs), &xcsr);
753 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
757 * For sai master mode, after several open/close sai,
761 * next sai version.
763 if (!sai->is_consumer_mode) {
765 regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), FSL_SAI_CSR_SR);
767 regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), 0);
774 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
775 unsigned int ofs = sai->soc_data->reg_offset;
787 regmap_update_bits(sai->regmap, FSL_SAI_TCR2(ofs), FSL_SAI_CR2_SYNC,
788 sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0);
789 regmap_update_bits(sai->regmap, FSL_SAI_RCR2(ofs), FSL_SAI_CR2_SYNC,
790 sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0);
800 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
803 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
816 if (fsl_sai_dir_is_synced(sai, adir))
817 regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx), ofs),
820 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
826 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
828 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
832 regmap_read(sai->regmap, FSL_SAI_xCSR(!tx, ofs), &xcsr);
838 if (fsl_sai_dir_is_synced(sai, adir) && !(xcsr & FSL_SAI_CSR_FRDE))
839 fsl_sai_config_disable(sai, adir);
847 if (!fsl_sai_dir_is_synced(sai, dir) || !(xcsr & FSL_SAI_CSR_FRDE))
848 fsl_sai_config_disable(sai, dir);
861 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
869 if (sai->soc_data->use_edma)
872 tx ? sai->dma_params_tx.maxburst :
873 sai->dma_params_rx.maxburst);
883 struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
884 unsigned int ofs = sai->soc_data->reg_offset;
887 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR);
888 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR);
890 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0);
891 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0);
893 regmap_update_bits(sai->regmap, FSL_SAI_TCR1(ofs),
894 FSL_SAI_CR1_RFW_MASK(sai->soc_data->fifo_depth),
895 sai->soc_data->fifo_depth - sai->dma_params_tx.maxburst);
896 regmap_update_bits(sai->regmap, FSL_SAI_RCR1(ofs),
897 FSL_SAI_CR1_RFW_MASK(sai->soc_data->fifo_depth),
898 sai->dma_params_rx.maxburst - 1);
900 snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx,
901 &sai->dma_params_rx);
920 struct fsl_sai *sai = snd_soc_component_get_drvdata(component);
921 struct device *dev = &sai->pdev->dev;
924 if (!IS_ERR_OR_NULL(sai->pinctrl) && !IS_ERR_OR_NULL(sai->pins_state)) {
925 ret = pinctrl_select_state(sai->pinctrl, sai->pins_state);
958 .name = "fsl-sai",
1013 struct fsl_sai *sai = dev_get_drvdata(dev);
1014 unsigned int ofs = sai->soc_data->reg_offset;
1069 struct fsl_sai *sai = dev_get_drvdata(dev);
1070 unsigned int ofs = sai->soc_data->reg_offset;
1112 struct fsl_sai *sai = dev_get_drvdata(dev);
1113 unsigned int ofs = sai->soc_data->reg_offset;
1159 struct fsl_sai *sai = dev_get_drvdata(dev);
1160 unsigned char ofs = sai->soc_data->reg_offset;
1167 ret = regmap_read(sai->regmap, FSL_SAI_VERID, &val);
1173 sai->verid.version = val &
1175 sai->verid.version >>= FSL_SAI_VERID_MINOR_SHIFT;
1176 sai->verid.feature = val & FSL_SAI_VERID_FEATURE_MASK;
1178 ret = regmap_read(sai->regmap, FSL_SAI_PARAM, &val);
1185 sai->param.slot_num = 1 <<
1189 sai->param.fifo_depth = 1 <<
1193 sai->param.dataline = val & FSL_SAI_PARAM_DLN_MASK;
1225 static int fsl_sai_read_dlcfg(struct fsl_sai *sai)
1227 struct platform_device *pdev = sai->pdev;
1253 soc_dl = BIT(sai->soc_data->pins) - 1;
1255 cfg[0].pins[0] = sai->soc_data->pins;
1260 cfg[0].pins[1] = sai->soc_data->pins;
1305 sai->dl_cfg = cfg;
1306 sai->dl_cfg_cnt = num_cfg + 1;
1317 struct fsl_sai *sai;
1325 sai = devm_kzalloc(dev, sizeof(*sai), GFP_KERNEL);
1326 if (!sai)
1329 sai->pdev = pdev;
1330 sai->soc_data = of_device_get_match_data(dev);
1332 sai->is_lsb_first = of_property_read_bool(np, "lsb-first");
1334 base = devm_platform_get_and_ioremap_resource(pdev, 0, &sai->res);
1338 if (sai->soc_data->reg_offset == 8) {
1345 sai->regmap = devm_regmap_init_mmio(dev, base, &fsl_sai_regmap_config);
1346 if (IS_ERR(sai->regmap)) {
1348 return PTR_ERR(sai->regmap);
1351 sai->bus_clk = devm_clk_get(dev, "bus");
1353 if (IS_ERR(sai->bus_clk) && PTR_ERR(sai->bus_clk) != -EPROBE_DEFER)
1354 sai->bus_clk = devm_clk_get(dev, "sai");
1355 if (IS_ERR(sai->bus_clk)) {
1357 PTR_ERR(sai->bus_clk));
1359 return PTR_ERR(sai->bus_clk);
1364 sai->mclk_clk[i] = devm_clk_get(dev, tmp);
1365 if (IS_ERR(sai->mclk_clk[i])) {
1367 i, PTR_ERR(sai->mclk_clk[i]));
1368 sai->mclk_clk[i] = NULL;
1372 if (sai->soc_data->mclk0_is_mclk1)
1373 sai->mclk_clk[0] = sai->mclk_clk[1];
1375 sai->mclk_clk[0] = sai->bus_clk;
1377 fsl_asoc_get_pll_clocks(&pdev->dev, &sai->pll8k_clk,
1378 &sai->pll11k_clk);
1382 if (!sai->soc_data->use_edma && !ret && dmas[2] == IMX_DMATYPE_MULTI_SAI)
1383 sai->is_multi_fifo_dma = true;
1386 ret = fsl_sai_read_dlcfg(sai);
1397 np->name, sai);
1403 memcpy(&sai->cpu_dai_drv, &fsl_sai_dai_template,
1407 sai->synchronous[RX] = true;
1408 sai->synchronous[TX] = false;
1409 sai->cpu_dai_drv.symmetric_rate = 1;
1410 sai->cpu_dai_drv.symmetric_channels = 1;
1411 sai->cpu_dai_drv.symmetric_sample_bits = 1;
1413 if (of_property_read_bool(np, "fsl,sai-synchronous-rx") &&
1414 of_property_read_bool(np, "fsl,sai-asynchronous")) {
1420 if (of_property_read_bool(np, "fsl,sai-synchronous-rx")) {
1422 sai->synchronous[RX] = false;
1423 sai->synchronous[TX] = true;
1424 } else if (of_property_read_bool(np, "fsl,sai-asynchronous")) {
1426 sai->synchronous[RX] = false;
1427 sai->synchronous[TX] = false;
1428 sai->cpu_dai_drv.symmetric_rate = 0;
1429 sai->cpu_dai_drv.symmetric_channels = 0;
1430 sai->cpu_dai_drv.symmetric_sample_bits = 0;
1433 sai->mclk_direction_output = of_property_read_bool(np, "fsl,sai-mclk-direction-output");
1435 if (sai->mclk_direction_output &&
1436 of_device_is_compatible(np, "fsl,imx6ul-sai")) {
1443 index = of_alias_get_id(np, "sai");
1451 sai->dma_params_rx.addr = sai->res->start + FSL_SAI_RDR0;
1452 sai->dma_params_tx.addr = sai->res->start + FSL_SAI_TDR0;
1453 sai->dma_params_rx.maxburst =
1454 sai->soc_data->max_burst[RX] ? sai->soc_data->max_burst[RX] : FSL_SAI_MAXBURST_RX;
1455 sai->dma_params_tx.maxburst =
1456 sai->soc_data->max_burst[TX] ? sai->soc_data->max_burst[TX] : FSL_SAI_MAXBURST_TX;
1458 sai->pinctrl = devm_pinctrl_get(&pdev->dev);
1460 platform_set_drvdata(pdev, sai);
1472 /* Get sai version */
1478 if (sai->mclk_direction_output &&
1479 sai->soc_data->max_register >= FSL_SAI_MCTL) {
1480 regmap_update_bits(sai->regmap, FSL_SAI_MCTL,
1492 if (sai->soc_data->use_imx_pcm) {
1509 &sai->cpu_dai_drv, 1);
1644 { .compatible = "fsl,vf610-sai", .data = &fsl_sai_vf610_data },
1645 { .compatible = "fsl,imx6sx-sai", .data = &fsl_sai_imx6sx_data },
1646 { .compatible = "fsl,imx6ul-sai", .data = &fsl_sai_imx6sx_data },
1647 { .compatible = "fsl,imx7ulp-sai", .data = &fsl_sai_imx7ulp_data },
1648 { .compatible = "fsl,imx8mq-sai", .data = &fsl_sai_imx8mq_data },
1649 { .compatible = "fsl,imx8qm-sai", .data = &fsl_sai_imx8qm_data },
1650 { .compatible = "fsl,imx8mm-sai", .data = &fsl_sai_imx8mm_data },
1651 { .compatible = "fsl,imx8mp-sai", .data = &fsl_sai_imx8mp_data },
1652 { .compatible = "fsl,imx8ulp-sai", .data = &fsl_sai_imx8ulp_data },
1653 { .compatible = "fsl,imx8mn-sai", .data = &fsl_sai_imx8mn_data },
1654 { .compatible = "fsl,imx93-sai", .data = &fsl_sai_imx93_data },
1661 struct fsl_sai *sai = dev_get_drvdata(dev);
1663 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE))
1664 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);
1666 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK))
1667 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);
1669 clk_disable_unprepare(sai->bus_clk);
1671 if (sai->soc_data->flags & PMQOS_CPU_LATENCY)
1672 cpu_latency_qos_remove_request(&sai->pm_qos_req);
1674 regcache_cache_only(sai->regmap, true);
1681 struct fsl_sai *sai = dev_get_drvdata(dev);
1682 unsigned int ofs = sai->soc_data->reg_offset;
1685 ret = clk_prepare_enable(sai->bus_clk);
1691 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK)) {
1692 ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[1]]);
1697 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE)) {
1698 ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[0]]);
1703 if (sai->soc_data->flags & PMQOS_CPU_LATENCY)
1704 cpu_latency_qos_add_request(&sai->pm_qos_req, 0);
1706 regcache_cache_only(sai->regmap, false);
1707 regcache_mark_dirty(sai->regmap);
1708 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR);
1709 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR);
1711 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0);
1712 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0);
1714 ret = regcache_sync(sai->regmap);
1718 if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output)
1719 regmap_update_bits(sai->regmap, FSL_SAI_TCSR(ofs),
1725 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE))
1726 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);
1728 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK))
1729 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);
1731 clk_disable_unprepare(sai->bus_clk);
1747 .name = "fsl-sai",
1756 MODULE_ALIAS("platform:fsl-sai");