Lines Matching full:sai

3 // Freescale ALSA SoC Digital Audio Interface (SAI) driver.
46 * SAI supports synchronous mode using bit/frame clocks of either Transmitter's
50 * @sai: SAI context
53 static inline bool fsl_sai_dir_is_synced(struct fsl_sai *sai, int dir) in fsl_sai_dir_is_synced() argument
58 return !sai->synchronous[dir] && sai->synchronous[adir]; in fsl_sai_dir_is_synced()
61 static struct pinctrl_state *fsl_sai_get_pins_state(struct fsl_sai *sai, u32 bclk) in fsl_sai_get_pins_state() argument
65 if (sai->is_pdm_mode) { in fsl_sai_get_pins_state()
68 state = pinctrl_lookup_state(sai->pinctrl, "dsd512"); in fsl_sai_get_pins_state()
72 state = pinctrl_lookup_state(sai->pinctrl, "dsd"); in fsl_sai_get_pins_state()
76 state = pinctrl_lookup_state(sai->pinctrl, "pcm_b2m"); in fsl_sai_get_pins_state()
81 state = pinctrl_lookup_state(sai->pinctrl, "default"); in fsl_sai_get_pins_state()
88 struct fsl_sai *sai = (struct fsl_sai *)devid; in fsl_sai_isr() local
89 unsigned int ofs = sai->soc_data->reg_offset; in fsl_sai_isr()
90 struct device *dev = &sai->pdev->dev; in fsl_sai_isr()
102 regmap_read(sai->regmap, FSL_SAI_TCSR(ofs), &xcsr); in fsl_sai_isr()
129 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), flags | xcsr); in fsl_sai_isr()
133 regmap_read(sai->regmap, FSL_SAI_RCSR(ofs), &xcsr); in fsl_sai_isr()
160 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), flags | xcsr); in fsl_sai_isr()
169 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); in fsl_sai_set_dai_tdm_slot() local
171 sai->slots = slots; in fsl_sai_set_dai_tdm_slot()
172 sai->slot_width = slot_width; in fsl_sai_set_dai_tdm_slot()
180 struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai); in fsl_sai_set_dai_bclk_ratio() local
182 sai->bclk_ratio = ratio; in fsl_sai_set_dai_bclk_ratio()
190 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); in fsl_sai_set_dai_sysclk_tr() local
191 unsigned int ofs = sai->soc_data->reg_offset; in fsl_sai_set_dai_sysclk_tr()
211 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs), in fsl_sai_set_dai_sysclk_tr()
219 struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai); in fsl_sai_set_mclk_rate() local
222 fsl_asoc_reparent_pll_clocks(dai->dev, sai->mclk_clk[clk_id], in fsl_sai_set_mclk_rate()
223 sai->pll8k_clk, sai->pll11k_clk, freq); in fsl_sai_set_mclk_rate()
225 ret = clk_set_rate(sai->mclk_clk[clk_id], freq); in fsl_sai_set_mclk_rate()
235 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); in fsl_sai_set_dai_sysclk() local
247 if (IS_ERR_OR_NULL(sai->mclk_clk[clk_id])) { in fsl_sai_set_dai_sysclk()
252 if (sai->mclk_streams == 0) { in fsl_sai_set_dai_sysclk()
275 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); in fsl_sai_set_dai_fmt_tr() local
276 unsigned int ofs = sai->soc_data->reg_offset; in fsl_sai_set_dai_fmt_tr()
279 if (!sai->is_lsb_first) in fsl_sai_set_dai_fmt_tr()
282 sai->is_pdm_mode = false; in fsl_sai_set_dai_fmt_tr()
283 sai->is_dsp_mode = false; in fsl_sai_set_dai_fmt_tr()
312 sai->is_dsp_mode = true; in fsl_sai_set_dai_fmt_tr()
320 sai->is_dsp_mode = true; in fsl_sai_set_dai_fmt_tr()
325 sai->is_pdm_mode = true; in fsl_sai_set_dai_fmt_tr()
360 sai->is_consumer_mode[tx] = false; in fsl_sai_set_dai_fmt_tr()
363 sai->is_consumer_mode[tx] = true; in fsl_sai_set_dai_fmt_tr()
367 sai->is_consumer_mode[tx] = false; in fsl_sai_set_dai_fmt_tr()
371 sai->is_consumer_mode[tx] = true; in fsl_sai_set_dai_fmt_tr()
377 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs), in fsl_sai_set_dai_fmt_tr()
379 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), in fsl_sai_set_dai_fmt_tr()
415 struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai); in fsl_sai_set_bclk() local
416 unsigned int reg, ofs = sai->soc_data->reg_offset; in fsl_sai_set_bclk()
422 bool support_1_1_ratio = sai->verid.version >= 0x0301; in fsl_sai_set_bclk()
425 if (sai->is_consumer_mode[tx]) in fsl_sai_set_bclk()
433 id = sai->soc_data->mclk0_is_mclk1 ? 1 : 0; in fsl_sai_set_bclk()
438 clk_rate = clk_get_rate(sai->mclk_clk[id]); in fsl_sai_set_bclk()
466 sai->mclk_id[tx] = id; in fsl_sai_set_bclk()
481 sai->mclk_id[tx], savediv, bestdiff); in fsl_sai_set_bclk()
490 * 4) For Tx and Rx are both Synchronous with another SAI, we just in fsl_sai_set_bclk()
493 if (fsl_sai_dir_is_synced(sai, adir)) in fsl_sai_set_bclk()
495 else if (!sai->synchronous[dir]) in fsl_sai_set_bclk()
500 regmap_update_bits(sai->regmap, reg, FSL_SAI_CR2_MSEL_MASK, in fsl_sai_set_bclk()
501 FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); in fsl_sai_set_bclk()
504 regmap_update_bits(sai->regmap, reg, in fsl_sai_set_bclk()
507 if (fsl_sai_dir_is_synced(sai, adir)) in fsl_sai_set_bclk()
508 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs), in fsl_sai_set_bclk()
511 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs), in fsl_sai_set_bclk()
514 regmap_update_bits(sai->regmap, reg, in fsl_sai_set_bclk()
526 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); in fsl_sai_hw_params() local
527 unsigned int ofs = sai->soc_data->reg_offset; in fsl_sai_hw_params()
531 struct fsl_sai_dl_cfg *dl_cfg = sai->dl_cfg; in fsl_sai_hw_params()
534 int dl_cfg_cnt = sai->dl_cfg_cnt; in fsl_sai_hw_params()
544 if (sai->slot_width) in fsl_sai_hw_params()
545 slot_width = sai->slot_width; in fsl_sai_hw_params()
547 if (sai->slots) in fsl_sai_hw_params()
548 slots = sai->slots; in fsl_sai_hw_params()
549 else if (sai->bclk_ratio) in fsl_sai_hw_params()
550 slots = sai->bclk_ratio / slot_width; in fsl_sai_hw_params()
558 if (sai->is_pdm_mode) { in fsl_sai_hw_params()
575 bclk = params_rate(params) * (sai->bclk_ratio ? sai->bclk_ratio : slots * slot_width); in fsl_sai_hw_params()
577 if (!IS_ERR_OR_NULL(sai->pinctrl)) { in fsl_sai_hw_params()
578 sai->pins_state = fsl_sai_get_pins_state(sai, bclk); in fsl_sai_hw_params()
579 if (!IS_ERR_OR_NULL(sai->pins_state)) { in fsl_sai_hw_params()
580 ret = pinctrl_select_state(sai->pinctrl, sai->pins_state); in fsl_sai_hw_params()
588 if (!sai->is_consumer_mode[tx]) { in fsl_sai_hw_params()
594 if (!(sai->mclk_streams & BIT(substream->stream))) { in fsl_sai_hw_params()
595 ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[tx]]); in fsl_sai_hw_params()
599 sai->mclk_streams |= BIT(substream->stream); in fsl_sai_hw_params()
603 if (!sai->is_dsp_mode && !sai->is_pdm_mode) in fsl_sai_hw_params()
609 if (sai->is_lsb_first || sai->is_pdm_mode) in fsl_sai_hw_params()
624 * For SAI provider mode, when Tx(Rx) sync with Rx(Tx) clock, Rx(Tx) will in fsl_sai_hw_params()
629 if (!sai->is_consumer_mode[tx] && fsl_sai_dir_is_synced(sai, adir)) { in fsl_sai_hw_params()
630 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(!tx, ofs), in fsl_sai_hw_params()
634 regmap_update_bits(sai->regmap, FSL_SAI_xCR5(!tx, ofs), in fsl_sai_hw_params()
647 if (hweight8(dl_cfg[dl_cfg_idx].mask[tx]) <= 1 || sai->is_multi_fifo_dma) in fsl_sai_hw_params()
648 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), in fsl_sai_hw_params()
651 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), in fsl_sai_hw_params()
654 dma_params = tx ? &sai->dma_params_tx : &sai->dma_params_rx; in fsl_sai_hw_params()
655 dma_params->addr = sai->res->start + FSL_SAI_xDR0(tx) + in fsl_sai_hw_params()
658 if (sai->is_multi_fifo_dma) { in fsl_sai_hw_params()
659 sai->audio_config[tx].words_per_fifo = min(slots, channels); in fsl_sai_hw_params()
661 sai->audio_config[tx].n_fifos_dst = pins; in fsl_sai_hw_params()
662 sai->audio_config[tx].stride_fifos_dst = dl_cfg[dl_cfg_idx].next_off[tx]; in fsl_sai_hw_params()
664 sai->audio_config[tx].n_fifos_src = pins; in fsl_sai_hw_params()
665 sai->audio_config[tx].stride_fifos_src = dl_cfg[dl_cfg_idx].next_off[tx]; in fsl_sai_hw_params()
667 dma_params->maxburst = sai->audio_config[tx].words_per_fifo * pins; in fsl_sai_hw_params()
668 dma_params->peripheral_config = &sai->audio_config[tx]; in fsl_sai_hw_params()
669 dma_params->peripheral_size = sizeof(sai->audio_config[tx]); in fsl_sai_hw_params()
671 watermark = tx ? (sai->soc_data->fifo_depth - dma_params->maxburst) : in fsl_sai_hw_params()
673 regmap_update_bits(sai->regmap, FSL_SAI_xCR1(tx, ofs), in fsl_sai_hw_params()
674 FSL_SAI_CR1_RFW_MASK(sai->soc_data->fifo_depth), in fsl_sai_hw_params()
679 for (i = 0; i < sai->soc_data->pins; i++) { in fsl_sai_hw_params()
685 regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs), in fsl_sai_hw_params()
698 if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output && in fsl_sai_hw_params()
699 !sai->is_consumer_mode[tx]) in fsl_sai_hw_params()
700 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), in fsl_sai_hw_params()
703 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), in fsl_sai_hw_params()
707 regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, ofs), in fsl_sai_hw_params()
712 if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output && in fsl_sai_hw_params()
713 !sai->is_consumer_mode[tx]) in fsl_sai_hw_params()
714 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs), in fsl_sai_hw_params()
717 regmap_write(sai->regmap, FSL_SAI_xMR(tx), in fsl_sai_hw_params()
726 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); in fsl_sai_hw_free() local
728 unsigned int ofs = sai->soc_data->reg_offset; in fsl_sai_hw_free()
731 regmap_write(sai->regmap, FSL_SAI_xMR(tx), 0); in fsl_sai_hw_free()
733 regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs), in fsl_sai_hw_free()
736 if (!sai->is_consumer_mode[tx] && in fsl_sai_hw_free()
737 sai->mclk_streams & BIT(substream->stream)) { in fsl_sai_hw_free()
738 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[tx]]); in fsl_sai_hw_free()
739 sai->mclk_streams &= ~BIT(substream->stream); in fsl_sai_hw_free()
745 static void fsl_sai_config_disable(struct fsl_sai *sai, int dir) in fsl_sai_config_disable() argument
747 unsigned int ofs = sai->soc_data->reg_offset; in fsl_sai_config_disable()
751 if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output) in fsl_sai_config_disable()
756 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), in fsl_sai_config_disable()
762 regmap_read(sai->regmap, FSL_SAI_xCSR(tx, ofs), &xcsr); in fsl_sai_config_disable()
765 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), in fsl_sai_config_disable()
769 * For sai master mode, after several open/close sai, in fsl_sai_config_disable()
773 * next sai version. in fsl_sai_config_disable()
775 if (!sai->is_consumer_mode[tx]) { in fsl_sai_config_disable()
777 regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), FSL_SAI_CSR_SR); in fsl_sai_config_disable()
779 regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), 0); in fsl_sai_config_disable()
786 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); in fsl_sai_trigger() local
787 unsigned int ofs = sai->soc_data->reg_offset; in fsl_sai_trigger()
799 regmap_update_bits(sai->regmap, FSL_SAI_TCR2(ofs), FSL_SAI_CR2_SYNC, in fsl_sai_trigger()
800 sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0); in fsl_sai_trigger()
801 regmap_update_bits(sai->regmap, FSL_SAI_RCR2(ofs), FSL_SAI_CR2_SYNC, in fsl_sai_trigger()
802 sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0); in fsl_sai_trigger()
812 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), in fsl_sai_trigger()
815 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), in fsl_sai_trigger()
828 if (fsl_sai_dir_is_synced(sai, adir)) in fsl_sai_trigger()
829 regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx), ofs), in fsl_sai_trigger()
832 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), in fsl_sai_trigger()
838 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), in fsl_sai_trigger()
840 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs), in fsl_sai_trigger()
844 regmap_read(sai->regmap, FSL_SAI_xCSR(!tx, ofs), &xcsr); in fsl_sai_trigger()
850 if (fsl_sai_dir_is_synced(sai, adir) && !(xcsr & FSL_SAI_CSR_FRDE)) in fsl_sai_trigger()
851 fsl_sai_config_disable(sai, adir); in fsl_sai_trigger()
859 if (!fsl_sai_dir_is_synced(sai, dir) || !(xcsr & FSL_SAI_CSR_FRDE)) in fsl_sai_trigger()
860 fsl_sai_config_disable(sai, dir); in fsl_sai_trigger()
873 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); in fsl_sai_startup() local
881 if (sai->soc_data->use_edma) in fsl_sai_startup()
884 tx ? sai->dma_params_tx.maxburst : in fsl_sai_startup()
885 sai->dma_params_rx.maxburst); in fsl_sai_startup()
895 struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); in fsl_sai_dai_probe() local
896 unsigned int ofs = sai->soc_data->reg_offset; in fsl_sai_dai_probe()
899 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR); in fsl_sai_dai_probe()
900 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR); in fsl_sai_dai_probe()
902 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0); in fsl_sai_dai_probe()
903 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0); in fsl_sai_dai_probe()
905 regmap_update_bits(sai->regmap, FSL_SAI_TCR1(ofs), in fsl_sai_dai_probe()
906 FSL_SAI_CR1_RFW_MASK(sai->soc_data->fifo_depth), in fsl_sai_dai_probe()
907 sai->soc_data->fifo_depth - sai->dma_params_tx.maxburst); in fsl_sai_dai_probe()
908 regmap_update_bits(sai->regmap, FSL_SAI_RCR1(ofs), in fsl_sai_dai_probe()
909 FSL_SAI_CR1_RFW_MASK(sai->soc_data->fifo_depth), in fsl_sai_dai_probe()
910 sai->dma_params_rx.maxburst - 1); in fsl_sai_dai_probe()
912 snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx, in fsl_sai_dai_probe()
913 &sai->dma_params_rx); in fsl_sai_dai_probe()
956 struct fsl_sai *sai = snd_soc_component_get_drvdata(component); in fsl_sai_dai_resume() local
957 struct device *dev = &sai->pdev->dev; in fsl_sai_dai_resume()
960 if (!IS_ERR_OR_NULL(sai->pinctrl) && !IS_ERR_OR_NULL(sai->pins_state)) { in fsl_sai_dai_resume()
961 ret = pinctrl_select_state(sai->pinctrl, sai->pins_state); in fsl_sai_dai_resume()
973 .name = "sai-tx-rx",
995 .name = "sai-tx",
1008 .name = "sai-rx",
1023 .name = "fsl-sai",
1078 struct fsl_sai *sai = dev_get_drvdata(dev); in fsl_sai_readable_reg() local
1079 unsigned int ofs = sai->soc_data->reg_offset; in fsl_sai_readable_reg()
1134 struct fsl_sai *sai = dev_get_drvdata(dev); in fsl_sai_volatile_reg() local
1135 unsigned int ofs = sai->soc_data->reg_offset; in fsl_sai_volatile_reg()
1177 struct fsl_sai *sai = dev_get_drvdata(dev); in fsl_sai_writeable_reg() local
1178 unsigned int ofs = sai->soc_data->reg_offset; in fsl_sai_writeable_reg()
1224 struct fsl_sai *sai = dev_get_drvdata(dev); in fsl_sai_check_version() local
1225 unsigned char ofs = sai->soc_data->reg_offset; in fsl_sai_check_version()
1232 ret = regmap_read(sai->regmap, FSL_SAI_VERID, &val); in fsl_sai_check_version()
1238 sai->verid.version = val & in fsl_sai_check_version()
1240 sai->verid.version >>= FSL_SAI_VERID_MINOR_SHIFT; in fsl_sai_check_version()
1241 sai->verid.feature = val & FSL_SAI_VERID_FEATURE_MASK; in fsl_sai_check_version()
1243 ret = regmap_read(sai->regmap, FSL_SAI_PARAM, &val); in fsl_sai_check_version()
1250 sai->param.slot_num = 1 << in fsl_sai_check_version()
1254 sai->param.fifo_depth = 1 << in fsl_sai_check_version()
1258 sai->param.dataline = val & FSL_SAI_PARAM_DLN_MASK; in fsl_sai_check_version()
1290 static int fsl_sai_read_dlcfg(struct fsl_sai *sai) in fsl_sai_read_dlcfg() argument
1292 struct platform_device *pdev = sai->pdev; in fsl_sai_read_dlcfg()
1318 soc_dl = BIT(sai->soc_data->pins) - 1; in fsl_sai_read_dlcfg()
1320 cfg[0].pins[0] = sai->soc_data->pins; in fsl_sai_read_dlcfg()
1325 cfg[0].pins[1] = sai->soc_data->pins; in fsl_sai_read_dlcfg()
1370 sai->dl_cfg = cfg; in fsl_sai_read_dlcfg()
1371 sai->dl_cfg_cnt = num_cfg + 1; in fsl_sai_read_dlcfg()
1382 struct fsl_sai *sai; in fsl_sai_probe() local
1390 sai = devm_kzalloc(dev, sizeof(*sai), GFP_KERNEL); in fsl_sai_probe()
1391 if (!sai) in fsl_sai_probe()
1394 sai->pdev = pdev; in fsl_sai_probe()
1395 sai->soc_data = of_device_get_match_data(dev); in fsl_sai_probe()
1397 sai->is_lsb_first = of_property_read_bool(np, "lsb-first"); in fsl_sai_probe()
1399 base = devm_platform_get_and_ioremap_resource(pdev, 0, &sai->res); in fsl_sai_probe()
1403 if (sai->soc_data->reg_offset == 8) { in fsl_sai_probe()
1410 sai->regmap = devm_regmap_init_mmio(dev, base, &fsl_sai_regmap_config); in fsl_sai_probe()
1411 if (IS_ERR(sai->regmap)) { in fsl_sai_probe()
1413 return PTR_ERR(sai->regmap); in fsl_sai_probe()
1416 sai->bus_clk = devm_clk_get(dev, "bus"); in fsl_sai_probe()
1418 if (IS_ERR(sai->bus_clk) && PTR_ERR(sai->bus_clk) != -EPROBE_DEFER) in fsl_sai_probe()
1419 sai->bus_clk = devm_clk_get(dev, "sai"); in fsl_sai_probe()
1420 if (IS_ERR(sai->bus_clk)) { in fsl_sai_probe()
1422 PTR_ERR(sai->bus_clk)); in fsl_sai_probe()
1424 return PTR_ERR(sai->bus_clk); in fsl_sai_probe()
1429 sai->mclk_clk[i] = devm_clk_get(dev, tmp); in fsl_sai_probe()
1430 if (IS_ERR(sai->mclk_clk[i])) { in fsl_sai_probe()
1432 i, PTR_ERR(sai->mclk_clk[i])); in fsl_sai_probe()
1433 sai->mclk_clk[i] = NULL; in fsl_sai_probe()
1437 if (sai->soc_data->mclk0_is_mclk1) in fsl_sai_probe()
1438 sai->mclk_clk[0] = sai->mclk_clk[1]; in fsl_sai_probe()
1440 sai->mclk_clk[0] = sai->bus_clk; in fsl_sai_probe()
1442 fsl_asoc_get_pll_clocks(&pdev->dev, &sai->pll8k_clk, in fsl_sai_probe()
1443 &sai->pll11k_clk); in fsl_sai_probe()
1447 if (!sai->soc_data->use_edma && !ret && dmas[2] == IMX_DMATYPE_MULTI_SAI) in fsl_sai_probe()
1448 sai->is_multi_fifo_dma = true; in fsl_sai_probe()
1451 ret = fsl_sai_read_dlcfg(sai); in fsl_sai_probe()
1462 np->name, sai); in fsl_sai_probe()
1468 memcpy(&sai->cpu_dai_drv, fsl_sai_dai_template, in fsl_sai_probe()
1472 sai->synchronous[RX] = true; in fsl_sai_probe()
1473 sai->synchronous[TX] = false; in fsl_sai_probe()
1474 sai->cpu_dai_drv[0].symmetric_rate = 1; in fsl_sai_probe()
1475 sai->cpu_dai_drv[0].symmetric_channels = 1; in fsl_sai_probe()
1476 sai->cpu_dai_drv[0].symmetric_sample_bits = 1; in fsl_sai_probe()
1478 if (of_property_read_bool(np, "fsl,sai-synchronous-rx") && in fsl_sai_probe()
1479 of_property_read_bool(np, "fsl,sai-asynchronous")) { in fsl_sai_probe()
1485 if (of_property_read_bool(np, "fsl,sai-synchronous-rx")) { in fsl_sai_probe()
1487 sai->synchronous[RX] = false; in fsl_sai_probe()
1488 sai->synchronous[TX] = true; in fsl_sai_probe()
1489 } else if (of_property_read_bool(np, "fsl,sai-asynchronous")) { in fsl_sai_probe()
1491 sai->synchronous[RX] = false; in fsl_sai_probe()
1492 sai->synchronous[TX] = false; in fsl_sai_probe()
1493 sai->cpu_dai_drv[0].symmetric_rate = 0; in fsl_sai_probe()
1494 sai->cpu_dai_drv[0].symmetric_channels = 0; in fsl_sai_probe()
1495 sai->cpu_dai_drv[0].symmetric_sample_bits = 0; in fsl_sai_probe()
1498 sai->mclk_direction_output = of_property_read_bool(np, "fsl,sai-mclk-direction-output"); in fsl_sai_probe()
1500 if (sai->mclk_direction_output && in fsl_sai_probe()
1501 of_device_is_compatible(np, "fsl,imx6ul-sai")) { in fsl_sai_probe()
1508 index = of_alias_get_id(np, "sai"); in fsl_sai_probe()
1516 sai->dma_params_rx.addr = sai->res->start + FSL_SAI_RDR0; in fsl_sai_probe()
1517 sai->dma_params_tx.addr = sai->res->start + FSL_SAI_TDR0; in fsl_sai_probe()
1518 sai->dma_params_rx.maxburst = in fsl_sai_probe()
1519 sai->soc_data->max_burst[RX] ? sai->soc_data->max_burst[RX] : FSL_SAI_MAXBURST_RX; in fsl_sai_probe()
1520 sai->dma_params_tx.maxburst = in fsl_sai_probe()
1521 sai->soc_data->max_burst[TX] ? sai->soc_data->max_burst[TX] : FSL_SAI_MAXBURST_TX; in fsl_sai_probe()
1523 sai->pinctrl = devm_pinctrl_get(&pdev->dev); in fsl_sai_probe()
1525 platform_set_drvdata(pdev, sai); in fsl_sai_probe()
1537 /* Get sai version */ in fsl_sai_probe()
1540 dev_warn(dev, "Error reading SAI version: %d\n", ret); in fsl_sai_probe()
1543 if (sai->mclk_direction_output && in fsl_sai_probe()
1544 sai->soc_data->max_register >= FSL_SAI_MCTL) { in fsl_sai_probe()
1545 regmap_update_bits(sai->regmap, FSL_SAI_MCTL, in fsl_sai_probe()
1557 if (sai->soc_data->use_imx_pcm) { in fsl_sai_probe()
1574 sai->cpu_dai_drv, ARRAY_SIZE(fsl_sai_dai_template)); in fsl_sai_probe()
1721 { .compatible = "fsl,vf610-sai", .data = &fsl_sai_vf610_data },
1722 { .compatible = "fsl,imx6sx-sai", .data = &fsl_sai_imx6sx_data },
1723 { .compatible = "fsl,imx6ul-sai", .data = &fsl_sai_imx6sx_data },
1724 { .compatible = "fsl,imx7ulp-sai", .data = &fsl_sai_imx7ulp_data },
1725 { .compatible = "fsl,imx8mq-sai", .data = &fsl_sai_imx8mq_data },
1726 { .compatible = "fsl,imx8qm-sai", .data = &fsl_sai_imx8qm_data },
1727 { .compatible = "fsl,imx8mm-sai", .data = &fsl_sai_imx8mm_data },
1728 { .compatible = "fsl,imx8mp-sai", .data = &fsl_sai_imx8mp_data },
1729 { .compatible = "fsl,imx8ulp-sai", .data = &fsl_sai_imx8ulp_data },
1730 { .compatible = "fsl,imx8mn-sai", .data = &fsl_sai_imx8mn_data },
1731 { .compatible = "fsl,imx93-sai", .data = &fsl_sai_imx93_data },
1732 { .compatible = "fsl,imx95-sai", .data = &fsl_sai_imx95_data },
1739 struct fsl_sai *sai = dev_get_drvdata(dev); in fsl_sai_runtime_suspend() local
1741 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE)) in fsl_sai_runtime_suspend()
1742 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]); in fsl_sai_runtime_suspend()
1744 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK)) in fsl_sai_runtime_suspend()
1745 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]); in fsl_sai_runtime_suspend()
1747 clk_disable_unprepare(sai->bus_clk); in fsl_sai_runtime_suspend()
1749 if (sai->soc_data->flags & PMQOS_CPU_LATENCY) in fsl_sai_runtime_suspend()
1750 cpu_latency_qos_remove_request(&sai->pm_qos_req); in fsl_sai_runtime_suspend()
1752 regcache_cache_only(sai->regmap, true); in fsl_sai_runtime_suspend()
1759 struct fsl_sai *sai = dev_get_drvdata(dev); in fsl_sai_runtime_resume() local
1760 unsigned int ofs = sai->soc_data->reg_offset; in fsl_sai_runtime_resume()
1763 ret = clk_prepare_enable(sai->bus_clk); in fsl_sai_runtime_resume()
1769 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK)) { in fsl_sai_runtime_resume()
1770 ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[1]]); in fsl_sai_runtime_resume()
1775 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE)) { in fsl_sai_runtime_resume()
1776 ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[0]]); in fsl_sai_runtime_resume()
1781 if (sai->soc_data->flags & PMQOS_CPU_LATENCY) in fsl_sai_runtime_resume()
1782 cpu_latency_qos_add_request(&sai->pm_qos_req, 0); in fsl_sai_runtime_resume()
1784 regcache_cache_only(sai->regmap, false); in fsl_sai_runtime_resume()
1785 regcache_mark_dirty(sai->regmap); in fsl_sai_runtime_resume()
1786 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR); in fsl_sai_runtime_resume()
1787 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR); in fsl_sai_runtime_resume()
1789 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0); in fsl_sai_runtime_resume()
1790 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0); in fsl_sai_runtime_resume()
1792 ret = regcache_sync(sai->regmap); in fsl_sai_runtime_resume()
1796 if (sai->soc_data->mclk_with_tere && sai->mclk_direction_output) in fsl_sai_runtime_resume()
1797 regmap_update_bits(sai->regmap, FSL_SAI_TCSR(ofs), in fsl_sai_runtime_resume()
1803 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE)) in fsl_sai_runtime_resume()
1804 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]); in fsl_sai_runtime_resume()
1806 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK)) in fsl_sai_runtime_resume()
1807 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]); in fsl_sai_runtime_resume()
1809 clk_disable_unprepare(sai->bus_clk); in fsl_sai_runtime_resume()
1825 .name = "fsl-sai",
1832 MODULE_DESCRIPTION("Freescale Soc SAI Interface");
1834 MODULE_ALIAS("platform:fsl-sai");