Lines Matching refs:sai
58 #define STM_SAI_HAS_EXT_SYNC(x) (!STM_SAI_IS_F4(sai->pdata))
188 static int stm32_sai_sub_reg_up(struct stm32_sai_sub_data *sai,
194 ret = clk_enable(sai->pdata->pclk);
198 ret = regmap_update_bits(sai->regmap, reg, mask, val);
200 clk_disable(sai->pdata->pclk);
205 static int stm32_sai_sub_reg_wr(struct stm32_sai_sub_data *sai,
211 ret = clk_enable(sai->pdata->pclk);
215 ret = regmap_write_bits(sai->regmap, reg, mask, val);
217 clk_disable(sai->pdata->pclk);
222 static int stm32_sai_sub_reg_rd(struct stm32_sai_sub_data *sai,
227 ret = clk_enable(sai->pdata->pclk);
231 ret = regmap_read(sai->regmap, reg, val);
233 clk_disable(sai->pdata->pclk);
274 struct stm32_sai_sub_data *sai = snd_kcontrol_chip(kcontrol);
276 mutex_lock(&sai->ctrl_lock);
277 memcpy(uctl->value.iec958.status, sai->iec958.status, 4);
278 mutex_unlock(&sai->ctrl_lock);
286 struct stm32_sai_sub_data *sai = snd_kcontrol_chip(kcontrol);
288 mutex_lock(&sai->ctrl_lock);
289 memcpy(sai->iec958.status, uctl->value.iec958.status, 4);
290 mutex_unlock(&sai->ctrl_lock);
314 static int stm32_sai_get_clk_div(struct stm32_sai_sub_data *sai,
318 int version = sai->pdata->conf.version;
323 dev_err(&sai->pdev->dev, "Divider %d out of range\n", div);
326 dev_dbg(&sai->pdev->dev, "SAI divider %d\n", div);
329 dev_dbg(&sai->pdev->dev,
336 static int stm32_sai_set_clk_div(struct stm32_sai_sub_data *sai,
339 int version = sai->pdata->conf.version;
343 dev_err(&sai->pdev->dev, "Divider %d out of range\n", div);
349 ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, mask, cr1);
351 dev_err(&sai->pdev->dev, "Failed to update CR1 register\n");
356 static int stm32_sai_set_parent_clock(struct stm32_sai_sub_data *sai,
359 struct platform_device *pdev = sai->pdev;
360 struct clk *parent_clk = sai->pdata->clk_x8k;
364 parent_clk = sai->pdata->clk_x11k;
366 ret = clk_set_parent(sai->sai_ck, parent_clk);
379 struct stm32_sai_sub_data *sai = mclk->sai_data;
382 div = stm32_sai_get_clk_div(sai, *prate, rate);
403 struct stm32_sai_sub_data *sai = mclk->sai_data;
406 div = stm32_sai_get_clk_div(sai, parent_rate, rate);
410 ret = stm32_sai_set_clk_div(sai, div);
422 struct stm32_sai_sub_data *sai = mclk->sai_data;
424 dev_dbg(&sai->pdev->dev, "Enable master clock\n");
426 return stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
433 struct stm32_sai_sub_data *sai = mclk->sai_data;
435 dev_dbg(&sai->pdev->dev, "Disable master clock\n");
437 stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, SAI_XCR1_MCKEN, 0);
448 static int stm32_sai_add_mclk_provider(struct stm32_sai_sub_data *sai)
452 struct device *dev = &sai->pdev->dev;
453 const char *pname = __clk_get_name(sai->sai_ck);
475 STM_SAI_IS_SUB_A(sai) ? strcat(p, "a_mclk") : strcat(p, "b_mclk");
478 mclk->sai_data = sai;
482 ret = devm_clk_hw_register(&sai->pdev->dev, hw);
487 sai->sai_mclk = hw->clk;
495 struct stm32_sai_sub_data *sai = (struct stm32_sai_sub_data *)devid;
496 struct platform_device *pdev = sai->pdev;
500 stm32_sai_sub_reg_rd(sai, STM_SAI_IMR_REGX, &imr);
501 stm32_sai_sub_reg_rd(sai, STM_SAI_SR_REGX, &sr);
507 stm32_sai_sub_reg_wr(sai, STM_SAI_CLRFR_REGX, SAI_XCLRFR_MASK,
510 if (!sai->substream) {
517 STM_SAI_IS_PLAYBACK(sai) ? "underrun" : "overrun");
542 spin_lock(&sai->irq_lock);
543 if (status != SNDRV_PCM_STATE_RUNNING && sai->substream)
544 snd_pcm_stop_xrun(sai->substream);
545 spin_unlock(&sai->irq_lock);
553 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
556 if (dir == SND_SOC_CLOCK_OUT && sai->sai_mclk) {
557 ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
566 if (sai->mclk_rate) {
567 clk_rate_exclusive_put(sai->sai_mclk);
568 sai->mclk_rate = 0;
574 ret = stm32_sai_set_parent_clock(sai, freq);
578 ret = clk_set_rate_exclusive(sai->sai_mclk, freq);
588 sai->mclk_rate = freq;
597 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
600 if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
625 if (STM_SAI_IS_PLAYBACK(sai)) {
626 sai->slot_mask = tx_mask;
630 if (STM_SAI_IS_CAPTURE(sai)) {
631 sai->slot_mask = rx_mask;
637 stm32_sai_sub_reg_up(sai, STM_SAI_SLOTR_REGX, slotr_mask, slotr);
639 sai->slot_width = slot_width;
640 sai->slots = slots;
647 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
659 if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
719 stm32_sai_sub_reg_up(sai, STM_SAI_FRCR_REGX, frcr_mask, frcr);
726 sai->master = false;
729 sai->master = true;
738 if (sai->sync) {
741 sai->master = false;
747 ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, cr1_mask, cr1);
753 sai->fmt = fmt;
761 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
765 spin_lock_irqsave(&sai->irq_lock, flags);
766 sai->substream = substream;
767 spin_unlock_irqrestore(&sai->irq_lock, flags);
769 if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
777 ret = clk_prepare_enable(sai->sai_ck);
784 stm32_sai_sub_reg_wr(sai, STM_SAI_CLRFR_REGX,
788 if (STM_SAI_IS_CAPTURE(sai)) {
789 stm32_sai_sub_reg_rd(sai, STM_SAI_CR2_REGX, &cr2);
794 if (sai->master)
799 stm32_sai_sub_reg_up(sai, STM_SAI_IMR_REGX,
809 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
817 stm32_sai_sub_reg_wr(sai, STM_SAI_CR2_REGX,
823 if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
824 sai->spdif_frm_cnt = 0;
846 if ((sai->slots == 2) && (params_channels(params) == 1))
849 ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, cr1_mask, cr1);
860 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
863 stm32_sai_sub_reg_rd(sai, STM_SAI_SLOTR_REGX, &slotr);
871 sai->slot_width = sai->data_size;
873 if (sai->slot_width < sai->data_size) {
876 sai->data_size);
881 if (!sai->slots)
882 sai->slots = 2;
885 stm32_sai_sub_reg_up(sai, STM_SAI_SLOTR_REGX,
887 SAI_XSLOTR_NBSLOT_SET((sai->slots - 1)));
891 sai->slot_mask = (1 << sai->slots) - 1;
892 stm32_sai_sub_reg_up(sai,
894 SAI_XSLOTR_SLOTEN_SET(sai->slot_mask));
898 sai->slots, sai->slot_width);
905 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
909 format = sai->fmt & SND_SOC_DAIFMT_FORMAT_MASK;
910 sai->fs_length = sai->slot_width * sai->slots;
912 fs_active = sai->fs_length / 2;
917 frcr = SAI_XFRCR_FRL_SET((sai->fs_length - 1));
922 sai->fs_length, fs_active);
924 stm32_sai_sub_reg_up(sai, STM_SAI_FRCR_REGX, frcr_mask, frcr);
926 if ((sai->fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_LSB) {
927 offset = sai->slot_width - sai->data_size;
929 stm32_sai_sub_reg_up(sai, STM_SAI_SLOTR_REGX,
935 static void stm32_sai_init_iec958_status(struct stm32_sai_sub_data *sai)
937 unsigned char *cs = sai->iec958.status;
945 static void stm32_sai_set_iec958_status(struct stm32_sai_sub_data *sai,
952 mutex_lock(&sai->ctrl_lock);
955 sai->iec958.status[3] = IEC958_AES3_CON_FS_22050;
958 sai->iec958.status[3] = IEC958_AES3_CON_FS_44100;
961 sai->iec958.status[3] = IEC958_AES3_CON_FS_88200;
964 sai->iec958.status[3] = IEC958_AES3_CON_FS_176400;
967 sai->iec958.status[3] = IEC958_AES3_CON_FS_24000;
970 sai->iec958.status[3] = IEC958_AES3_CON_FS_48000;
973 sai->iec958.status[3] = IEC958_AES3_CON_FS_96000;
976 sai->iec958.status[3] = IEC958_AES3_CON_FS_192000;
979 sai->iec958.status[3] = IEC958_AES3_CON_FS_32000;
982 sai->iec958.status[3] = IEC958_AES3_CON_FS_NOTID;
985 mutex_unlock(&sai->ctrl_lock);
991 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
997 if (!sai->sai_mclk) {
998 ret = stm32_sai_set_parent_clock(sai, rate);
1002 sai_clk_rate = clk_get_rate(sai->sai_ck);
1004 if (STM_SAI_IS_F4(sai->pdata)) {
1012 if (!sai->mclk_rate)
1015 if (2 * sai_clk_rate >= 3 * sai->mclk_rate) {
1016 div = stm32_sai_get_clk_div(sai, sai_clk_rate,
1017 2 * sai->mclk_rate);
1031 if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
1032 div = stm32_sai_get_clk_div(sai, sai_clk_rate,
1037 if (sai->mclk_rate) {
1038 mclk_ratio = sai->mclk_rate / rate;
1048 stm32_sai_sub_reg_up(sai,
1052 div = stm32_sai_get_clk_div(sai, sai_clk_rate,
1053 sai->mclk_rate);
1058 den = sai->fs_length * params_rate(params);
1059 div = stm32_sai_get_clk_div(sai, sai_clk_rate,
1067 return stm32_sai_set_clk_div(sai, div);
1074 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
1077 sai->data_size = params_width(params);
1079 if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
1082 stm32_sai_set_iec958_status(sai, substream->runtime);
1094 if (sai->master)
1103 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
1112 stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
1116 ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
1126 stm32_sai_sub_reg_up(sai, STM_SAI_IMR_REGX,
1129 stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
1133 ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
1139 if (STM_SAI_PROTOCOL_IS_SPDIF(sai))
1140 sai->spdif_frm_cnt = 0;
1152 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
1155 stm32_sai_sub_reg_up(sai, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0);
1157 clk_disable_unprepare(sai->sai_ck);
1159 spin_lock_irqsave(&sai->irq_lock, flags);
1160 sai->substream = NULL;
1161 spin_unlock_irqrestore(&sai->irq_lock, flags);
1167 struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev);
1170 if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
1171 dev_dbg(&sai->pdev->dev, "%s: register iec controls", __func__);
1173 return snd_ctl_add(rtd->pcm->card, snd_ctl_new1(&knew, sai));
1181 struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev);
1184 sai->cpu_dai = cpu_dai;
1186 sai->dma_params.addr = (dma_addr_t)(sai->phys_addr + STM_SAI_DR_REGX);
1192 sai->dma_params.maxburst = 4;
1193 if (sai->pdata->conf.fifo_size < 8)
1194 sai->dma_params.maxburst = 1;
1196 sai->dma_params.addr_width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
1198 if (STM_SAI_IS_PLAYBACK(sai))
1199 snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params, NULL);
1201 snd_soc_dai_init_dma_data(cpu_dai, NULL, &sai->dma_params);
1204 if (STM_SAI_PROTOCOL_IS_SPDIF(sai))
1208 if (STM_SAI_IS_CAPTURE(sai))
1212 if (sai->sync == SAI_SYNC_EXTERNAL) {
1214 ret = sai->pdata->set_sync(sai->pdata, sai->np_sync_provider,
1215 sai->synco, sai->synci);
1221 cr1 |= SAI_XCR1_SYNCEN_SET(sai->sync);
1223 return stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, cr1_mask, cr1);
1243 struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev);
1247 unsigned int frm_cnt = sai->spdif_frm_cnt;
1257 if (sai->iec958.status[byte] & mask)
1267 sai->spdif_frm_cnt = frm_cnt;
1340 .name = "stm32-sai",
1344 { .compatible = "st,stm32-sai-sub-a",
1346 { .compatible = "st,stm32-sai-sub-b",
1353 struct stm32_sai_sub_data *sai)
1369 sai->phys_addr = res->start;
1371 sai->regmap_config = &stm32_sai_sub_regmap_config_f4;
1373 if (STM_SAI_HAS_PDM(sai) && STM_SAI_IS_SUB_A(sai))
1374 sai->regmap_config = &stm32_sai_sub_regmap_config_h7;
1378 * can lead to circular locking issue with sai master clock provider.
1381 sai->regmap = devm_regmap_init_mmio(&pdev->dev, base,
1382 sai->regmap_config);
1383 if (IS_ERR(sai->regmap)) {
1384 if (PTR_ERR(sai->regmap) != -EPROBE_DEFER)
1386 PTR_ERR(sai->regmap));
1387 return PTR_ERR(sai->regmap);
1392 sai->dir = SNDRV_PCM_STREAM_PLAYBACK;
1394 sai->dir = SNDRV_PCM_STREAM_CAPTURE;
1401 sai->spdif = false;
1403 if (!STM_SAI_HAS_SPDIF(sai) ||
1404 sai->dir == SNDRV_PCM_STREAM_CAPTURE) {
1408 stm32_sai_init_iec958_status(sai);
1409 sai->spdif = true;
1410 sai->master = true;
1421 sai->sync = SAI_SYNC_NONE;
1429 sai->np_sync_provider = of_get_parent(args.np);
1430 if (!sai->np_sync_provider) {
1437 sai->sync = SAI_SYNC_INTERNAL;
1438 if (sai->np_sync_provider != sai->pdata->pdev->dev.of_node) {
1439 if (!STM_SAI_HAS_EXT_SYNC(sai)) {
1445 sai->sync = SAI_SYNC_EXTERNAL;
1447 sai->synci = args.args[0];
1448 if (sai->synci < 1 ||
1449 (sai->synci > (SAI_GCR_SYNCIN_MAX + 1))) {
1456 "st,stm32-sai-sub-a") >= 0)
1457 sai->synco = STM_SAI_SYNC_OUT_A;
1460 "st,stm32-sai-sub-b") >= 0)
1461 sai->synco = STM_SAI_SYNC_OUT_B;
1463 if (!sai->synco) {
1475 sai->sai_ck = devm_clk_get(&pdev->dev, "sai_ck");
1476 if (IS_ERR(sai->sai_ck)) {
1477 if (PTR_ERR(sai->sai_ck) != -EPROBE_DEFER)
1479 PTR_ERR(sai->sai_ck));
1480 return PTR_ERR(sai->sai_ck);
1483 ret = clk_prepare(sai->pdata->pclk);
1487 if (STM_SAI_IS_F4(sai->pdata))
1492 ret = stm32_sai_add_mclk_provider(sai);
1496 sai->sai_mclk = devm_clk_get(&pdev->dev, "MCLK");
1497 if (IS_ERR(sai->sai_mclk)) {
1498 if (PTR_ERR(sai->sai_mclk) != -ENOENT)
1499 return PTR_ERR(sai->sai_mclk);
1500 sai->sai_mclk = NULL;
1509 struct stm32_sai_sub_data *sai;
1514 sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
1515 if (!sai)
1521 sai->id = (uintptr_t)of_id->data;
1523 sai->pdev = pdev;
1524 mutex_init(&sai->ctrl_lock);
1525 spin_lock_init(&sai->irq_lock);
1526 platform_set_drvdata(pdev, sai);
1528 sai->pdata = dev_get_drvdata(pdev->dev.parent);
1529 if (!sai->pdata) {
1534 ret = stm32_sai_sub_parse_of(pdev, sai);
1538 if (STM_SAI_IS_PLAYBACK(sai))
1539 sai->cpu_dai_drv = stm32_sai_playback_dai;
1541 sai->cpu_dai_drv = stm32_sai_capture_dai;
1542 sai->cpu_dai_drv.name = dev_name(&pdev->dev);
1544 ret = devm_request_irq(&pdev->dev, sai->pdata->irq, stm32_sai_isr,
1545 IRQF_SHARED, dev_name(&pdev->dev), sai);
1551 if (STM_SAI_PROTOCOL_IS_SPDIF(sai))
1562 &sai->cpu_dai_drv, 1);
1575 struct stm32_sai_sub_data *sai = dev_get_drvdata(&pdev->dev);
1577 clk_unprepare(sai->pdata->pclk);
1588 struct stm32_sai_sub_data *sai = dev_get_drvdata(dev);
1591 ret = clk_enable(sai->pdata->pclk);
1595 regcache_cache_only(sai->regmap, true);
1596 regcache_mark_dirty(sai->regmap);
1598 clk_disable(sai->pdata->pclk);
1605 struct stm32_sai_sub_data *sai = dev_get_drvdata(dev);
1608 ret = clk_enable(sai->pdata->pclk);
1612 regcache_cache_only(sai->regmap, false);
1613 ret = regcache_sync(sai->regmap);
1615 clk_disable(sai->pdata->pclk);
1627 .name = "st,stm32-sai-sub",
1639 MODULE_ALIAS("platform:st,stm32-sai-sub");