Lines Matching defs:sai
47 * @sai: SAI context
50 static inline bool fsl_sai_dir_is_synced(struct fsl_sai *sai, int dir)
55 return !sai->synchronous[dir] && sai->synchronous[adir];
60 struct fsl_sai *sai = (struct fsl_sai *)devid;
61 unsigned int ofs = sai->soc_data->reg_offset;
62 struct device *dev = &sai->pdev->dev;
74 regmap_read(sai->regmap, FSL_SAI_TCSR(ofs), &xcsr);
104 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), flags | xcsr);
108 regmap_read(sai->regmap, FSL_SAI_RCSR(ofs), &xcsr);
138 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), flags | xcsr);
150 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
152 sai->slots = slots;
153 sai->slot_width = slot_width;
161 struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);
163 sai->bclk_ratio = ratio;
171 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
172 unsigned int ofs = sai->soc_data->reg_offset;
193 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
225 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
226 unsigned int ofs = sai->soc_data->reg_offset;
230 if (!sai->is_lsb_first)
233 sai->is_dsp_mode = false;
262 sai->is_dsp_mode = true;
270 sai->is_dsp_mode = true;
305 sai->is_slave_mode = false;
308 sai->is_slave_mode = true;
312 sai->is_slave_mode = false;
316 sai->is_slave_mode = true;
322 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
324 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
350 struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);
351 unsigned int ofs = sai->soc_data->reg_offset;
360 if (sai->is_slave_mode)
364 clk_rate = clk_get_rate(sai->mclk_clk[id]);
390 sai->mclk_id[tx] = id;
414 if (fsl_sai_dir_is_synced(sai, adir)) {
415 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(!tx, ofs),
417 FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
418 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(!tx, ofs),
420 } else if (!sai->synchronous[dir]) {
421 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
423 FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
424 regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, ofs),
429 sai->mclk_id[tx], savediv, savesub);
438 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
439 unsigned int ofs = sai->soc_data->reg_offset;
450 if (sai->slots)
451 slots = sai->slots;
453 if (sai->slot_width)
454 slot_width = sai->slot_width;
458 if (!sai->is_slave_mode) {
459 if (sai->bclk_ratio)
461 sai->bclk_ratio *
471 if (!(sai->mclk_streams & BIT(substream->stream))) {
472 ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[tx]]);
476 sai->mclk_streams |= BIT(substream->stream);
480 if (!sai->is_dsp_mode)
486 if (sai->is_lsb_first)
503 if (!sai->is_slave_mode && fsl_sai_dir_is_synced(sai, adir)) {
504 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(!tx, ofs),
508 regmap_update_bits(sai->regmap, FSL_SAI_xCR5(!tx, ofs),
513 regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs),
516 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, ofs),
520 regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, ofs),
523 regmap_write(sai->regmap, FSL_SAI_xMR(tx),
532 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
534 unsigned int ofs = sai->soc_data->reg_offset;
536 regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, ofs),
539 if (!sai->is_slave_mode &&
540 sai->mclk_streams & BIT(substream->stream)) {
541 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[tx]]);
542 sai->mclk_streams &= ~BIT(substream->stream);
548 static void fsl_sai_config_disable(struct fsl_sai *sai, int dir)
550 unsigned int ofs = sai->soc_data->reg_offset;
554 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
560 regmap_read(sai->regmap, FSL_SAI_xCSR(tx, ofs), &xcsr);
563 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
567 * For sai master mode, after several open/close sai,
571 * next sai version.
573 if (!sai->is_slave_mode) {
575 regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), FSL_SAI_CSR_SR);
577 regmap_write(sai->regmap, FSL_SAI_xCSR(tx, ofs), 0);
584 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
585 unsigned int ofs = sai->soc_data->reg_offset;
597 regmap_update_bits(sai->regmap, FSL_SAI_TCR2(ofs), FSL_SAI_CR2_SYNC,
598 sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0);
599 regmap_update_bits(sai->regmap, FSL_SAI_RCR2(ofs), FSL_SAI_CR2_SYNC,
600 sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0);
610 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
613 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
626 if (fsl_sai_dir_is_synced(sai, adir))
627 regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx), ofs),
630 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
636 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
638 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, ofs),
642 regmap_read(sai->regmap, FSL_SAI_xCSR(!tx, ofs), &xcsr);
648 if (fsl_sai_dir_is_synced(sai, adir) && !(xcsr & FSL_SAI_CSR_FRDE))
649 fsl_sai_config_disable(sai, adir);
657 if (!fsl_sai_dir_is_synced(sai, dir) || !(xcsr & FSL_SAI_CSR_FRDE))
658 fsl_sai_config_disable(sai, dir);
671 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
679 if (sai->soc_data->use_edma)
682 tx ? sai->dma_params_tx.maxburst :
683 sai->dma_params_rx.maxburst);
704 struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
705 unsigned int ofs = sai->soc_data->reg_offset;
708 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR);
709 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR);
711 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0);
712 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0);
714 regmap_update_bits(sai->regmap, FSL_SAI_TCR1(ofs),
715 FSL_SAI_CR1_RFW_MASK(sai->soc_data->fifo_depth),
716 sai->soc_data->fifo_depth - FSL_SAI_MAXBURST_TX);
717 regmap_update_bits(sai->regmap, FSL_SAI_RCR1(ofs),
718 FSL_SAI_CR1_RFW_MASK(sai->soc_data->fifo_depth),
721 snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx,
722 &sai->dma_params_rx);
724 snd_soc_dai_set_drvdata(cpu_dai, sai);
753 .name = "fsl-sai",
806 struct fsl_sai *sai = dev_get_drvdata(dev);
807 unsigned int ofs = sai->soc_data->reg_offset;
862 struct fsl_sai *sai = dev_get_drvdata(dev);
863 unsigned int ofs = sai->soc_data->reg_offset;
905 struct fsl_sai *sai = dev_get_drvdata(dev);
906 unsigned int ofs = sai->soc_data->reg_offset;
952 struct fsl_sai *sai = dev_get_drvdata(dev);
953 unsigned char ofs = sai->soc_data->reg_offset;
960 ret = regmap_read(sai->regmap, FSL_SAI_VERID, &val);
966 sai->verid.major = (val & FSL_SAI_VERID_MAJOR_MASK) >>
968 sai->verid.minor = (val & FSL_SAI_VERID_MINOR_MASK) >>
970 sai->verid.feature = val & FSL_SAI_VERID_FEATURE_MASK;
972 ret = regmap_read(sai->regmap, FSL_SAI_PARAM, &val);
979 sai->param.slot_num = 1 <<
983 sai->param.fifo_depth = 1 <<
987 sai->param.dataline = val & FSL_SAI_PARAM_DLN_MASK;
995 struct fsl_sai *sai;
1003 sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
1004 if (!sai)
1007 sai->pdev = pdev;
1008 sai->soc_data = of_device_get_match_data(&pdev->dev);
1010 sai->is_lsb_first = of_property_read_bool(np, "lsb-first");
1017 if (sai->soc_data->reg_offset == 8) {
1024 sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
1028 if (IS_ERR(sai->regmap) && PTR_ERR(sai->regmap) != -EPROBE_DEFER)
1029 sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
1030 "sai", base, &fsl_sai_regmap_config);
1031 if (IS_ERR(sai->regmap)) {
1033 return PTR_ERR(sai->regmap);
1037 sai->bus_clk = devm_clk_get(&pdev->dev, "bus");
1038 if (IS_ERR(sai->bus_clk)) {
1040 PTR_ERR(sai->bus_clk));
1041 sai->bus_clk = NULL;
1044 sai->mclk_clk[0] = sai->bus_clk;
1047 sai->mclk_clk[i] = devm_clk_get(&pdev->dev, tmp);
1048 if (IS_ERR(sai->mclk_clk[i])) {
1050 i + 1, PTR_ERR(sai->mclk_clk[i]));
1051 sai->mclk_clk[i] = NULL;
1060 np->name, sai);
1066 memcpy(&sai->cpu_dai_drv, &fsl_sai_dai_template,
1070 sai->synchronous[RX] = true;
1071 sai->synchronous[TX] = false;
1072 sai->cpu_dai_drv.symmetric_rates = 1;
1073 sai->cpu_dai_drv.symmetric_channels = 1;
1074 sai->cpu_dai_drv.symmetric_samplebits = 1;
1076 if (of_find_property(np, "fsl,sai-synchronous-rx", NULL) &&
1077 of_find_property(np, "fsl,sai-asynchronous", NULL)) {
1083 if (of_find_property(np, "fsl,sai-synchronous-rx", NULL)) {
1085 sai->synchronous[RX] = false;
1086 sai->synchronous[TX] = true;
1087 } else if (of_find_property(np, "fsl,sai-asynchronous", NULL)) {
1089 sai->synchronous[RX] = false;
1090 sai->synchronous[TX] = false;
1091 sai->cpu_dai_drv.symmetric_rates = 0;
1092 sai->cpu_dai_drv.symmetric_channels = 0;
1093 sai->cpu_dai_drv.symmetric_samplebits = 0;
1096 if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) &&
1097 of_device_is_compatible(np, "fsl,imx6ul-sai")) {
1104 index = of_alias_get_id(np, "sai");
1112 sai->dma_params_rx.addr = res->start + FSL_SAI_RDR0;
1113 sai->dma_params_tx.addr = res->start + FSL_SAI_TDR0;
1114 sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX;
1115 sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX;
1117 platform_set_drvdata(pdev, sai);
1119 /* Get sai version */
1125 if (of_find_property(np, "fsl,sai-mclk-direction-output", NULL) &&
1126 sai->verid.major >= 3 && sai->verid.minor >= 1) {
1127 regmap_update_bits(sai->regmap, FSL_SAI_MCTL,
1132 regcache_cache_only(sai->regmap, true);
1135 &sai->cpu_dai_drv, 1);
1139 if (sai->soc_data->use_imx_pcm) {
1200 { .compatible = "fsl,vf610-sai", .data = &fsl_sai_vf610_data },
1201 { .compatible = "fsl,imx6sx-sai", .data = &fsl_sai_imx6sx_data },
1202 { .compatible = "fsl,imx6ul-sai", .data = &fsl_sai_imx6sx_data },
1203 { .compatible = "fsl,imx7ulp-sai", .data = &fsl_sai_imx7ulp_data },
1204 { .compatible = "fsl,imx8mq-sai", .data = &fsl_sai_imx8mq_data },
1205 { .compatible = "fsl,imx8qm-sai", .data = &fsl_sai_imx8qm_data },
1213 struct fsl_sai *sai = dev_get_drvdata(dev);
1215 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE))
1216 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);
1218 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK))
1219 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);
1221 clk_disable_unprepare(sai->bus_clk);
1223 regcache_cache_only(sai->regmap, true);
1230 struct fsl_sai *sai = dev_get_drvdata(dev);
1231 unsigned int ofs = sai->soc_data->reg_offset;
1234 ret = clk_prepare_enable(sai->bus_clk);
1240 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK)) {
1241 ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[1]]);
1246 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE)) {
1247 ret = clk_prepare_enable(sai->mclk_clk[sai->mclk_id[0]]);
1252 regcache_cache_only(sai->regmap, false);
1253 regcache_mark_dirty(sai->regmap);
1254 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR);
1255 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR);
1257 regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), 0);
1258 regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), 0);
1260 ret = regcache_sync(sai->regmap);
1267 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_CAPTURE))
1268 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[0]]);
1270 if (sai->mclk_streams & BIT(SNDRV_PCM_STREAM_PLAYBACK))
1271 clk_disable_unprepare(sai->mclk_clk[sai->mclk_id[1]]);
1273 clk_disable_unprepare(sai->bus_clk);
1290 .name = "fsl-sai",
1299 MODULE_ALIAS("platform:fsl-sai");