Lines Matching defs:sai

56 #define STM_SAI_HAS_EXT_SYNC(x) (!STM_SAI_IS_F4(sai->pdata))
186 static int stm32_sai_sub_reg_up(struct stm32_sai_sub_data *sai,
192 ret = clk_enable(sai->pdata->pclk);
196 ret = regmap_update_bits(sai->regmap, reg, mask, val);
198 clk_disable(sai->pdata->pclk);
203 static int stm32_sai_sub_reg_wr(struct stm32_sai_sub_data *sai,
209 ret = clk_enable(sai->pdata->pclk);
213 ret = regmap_write_bits(sai->regmap, reg, mask, val);
215 clk_disable(sai->pdata->pclk);
220 static int stm32_sai_sub_reg_rd(struct stm32_sai_sub_data *sai,
225 ret = clk_enable(sai->pdata->pclk);
229 ret = regmap_read(sai->regmap, reg, val);
231 clk_disable(sai->pdata->pclk);
272 struct stm32_sai_sub_data *sai = snd_kcontrol_chip(kcontrol);
274 mutex_lock(&sai->ctrl_lock);
275 memcpy(uctl->value.iec958.status, sai->iec958.status, 4);
276 mutex_unlock(&sai->ctrl_lock);
284 struct stm32_sai_sub_data *sai = snd_kcontrol_chip(kcontrol);
286 mutex_lock(&sai->ctrl_lock);
287 memcpy(sai->iec958.status, uctl->value.iec958.status, 4);
288 mutex_unlock(&sai->ctrl_lock);
312 static int stm32_sai_get_clk_div(struct stm32_sai_sub_data *sai,
316 int version = sai->pdata->conf.version;
321 dev_err(&sai->pdev->dev, "Divider %d out of range\n", div);
324 dev_dbg(&sai->pdev->dev, "SAI divider %d\n", div);
327 dev_dbg(&sai->pdev->dev,
334 static int stm32_sai_set_clk_div(struct stm32_sai_sub_data *sai,
337 int version = sai->pdata->conf.version;
341 dev_err(&sai->pdev->dev, "Divider %d out of range\n", div);
347 ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, mask, cr1);
349 dev_err(&sai->pdev->dev, "Failed to update CR1 register\n");
354 static int stm32_sai_set_parent_clock(struct stm32_sai_sub_data *sai,
357 struct platform_device *pdev = sai->pdev;
358 struct clk *parent_clk = sai->pdata->clk_x8k;
362 parent_clk = sai->pdata->clk_x11k;
364 ret = clk_set_parent(sai->sai_ck, parent_clk);
377 struct stm32_sai_sub_data *sai = mclk->sai_data;
380 div = stm32_sai_get_clk_div(sai, *prate, rate);
401 struct stm32_sai_sub_data *sai = mclk->sai_data;
404 div = stm32_sai_get_clk_div(sai, parent_rate, rate);
408 ret = stm32_sai_set_clk_div(sai, div);
420 struct stm32_sai_sub_data *sai = mclk->sai_data;
422 dev_dbg(&sai->pdev->dev, "Enable master clock\n");
424 return stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
431 struct stm32_sai_sub_data *sai = mclk->sai_data;
433 dev_dbg(&sai->pdev->dev, "Disable master clock\n");
435 stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, SAI_XCR1_MCKEN, 0);
446 static int stm32_sai_add_mclk_provider(struct stm32_sai_sub_data *sai)
450 struct device *dev = &sai->pdev->dev;
451 const char *pname = __clk_get_name(sai->sai_ck);
473 STM_SAI_IS_SUB_A(sai) ? strcat(p, "a_mclk") : strcat(p, "b_mclk");
476 mclk->sai_data = sai;
480 ret = devm_clk_hw_register(&sai->pdev->dev, hw);
485 sai->sai_mclk = hw->clk;
493 struct stm32_sai_sub_data *sai = (struct stm32_sai_sub_data *)devid;
494 struct platform_device *pdev = sai->pdev;
498 stm32_sai_sub_reg_rd(sai, STM_SAI_IMR_REGX, &imr);
499 stm32_sai_sub_reg_rd(sai, STM_SAI_SR_REGX, &sr);
505 stm32_sai_sub_reg_wr(sai, STM_SAI_CLRFR_REGX, SAI_XCLRFR_MASK,
508 if (!sai->substream) {
515 STM_SAI_IS_PLAYBACK(sai) ? "underrun" : "overrun");
540 spin_lock(&sai->irq_lock);
541 if (status != SNDRV_PCM_STATE_RUNNING && sai->substream)
542 snd_pcm_stop_xrun(sai->substream);
543 spin_unlock(&sai->irq_lock);
551 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
554 if (dir == SND_SOC_CLOCK_OUT && sai->sai_mclk) {
555 ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
564 if (sai->mclk_rate) {
565 clk_rate_exclusive_put(sai->sai_mclk);
566 sai->mclk_rate = 0;
572 ret = stm32_sai_set_parent_clock(sai, freq);
576 ret = clk_set_rate_exclusive(sai->sai_mclk, freq);
586 sai->mclk_rate = freq;
595 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
598 if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
623 if (STM_SAI_IS_PLAYBACK(sai)) {
624 sai->slot_mask = tx_mask;
628 if (STM_SAI_IS_CAPTURE(sai)) {
629 sai->slot_mask = rx_mask;
635 stm32_sai_sub_reg_up(sai, STM_SAI_SLOTR_REGX, slotr_mask, slotr);
637 sai->slot_width = slot_width;
638 sai->slots = slots;
645 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
657 if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
717 stm32_sai_sub_reg_up(sai, STM_SAI_FRCR_REGX, frcr_mask, frcr);
724 sai->master = false;
727 sai->master = true;
736 if (sai->sync) {
739 sai->master = false;
745 ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, cr1_mask, cr1);
751 sai->fmt = fmt;
759 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
763 spin_lock_irqsave(&sai->irq_lock, flags);
764 sai->substream = substream;
765 spin_unlock_irqrestore(&sai->irq_lock, flags);
767 if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
775 ret = clk_prepare_enable(sai->sai_ck);
782 stm32_sai_sub_reg_wr(sai, STM_SAI_CLRFR_REGX,
786 if (STM_SAI_IS_CAPTURE(sai)) {
787 stm32_sai_sub_reg_rd(sai, STM_SAI_CR2_REGX, &cr2);
792 if (sai->master)
797 stm32_sai_sub_reg_up(sai, STM_SAI_IMR_REGX,
807 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
815 stm32_sai_sub_reg_wr(sai, STM_SAI_CR2_REGX,
821 if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
822 sai->spdif_frm_cnt = 0;
844 if ((sai->slots == 2) && (params_channels(params) == 1))
847 ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, cr1_mask, cr1);
858 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
861 stm32_sai_sub_reg_rd(sai, STM_SAI_SLOTR_REGX, &slotr);
869 sai->slot_width = sai->data_size;
871 if (sai->slot_width < sai->data_size) {
874 sai->data_size);
879 if (!sai->slots)
880 sai->slots = 2;
883 stm32_sai_sub_reg_up(sai, STM_SAI_SLOTR_REGX,
885 SAI_XSLOTR_NBSLOT_SET((sai->slots - 1)));
889 sai->slot_mask = (1 << sai->slots) - 1;
890 stm32_sai_sub_reg_up(sai,
892 SAI_XSLOTR_SLOTEN_SET(sai->slot_mask));
896 sai->slots, sai->slot_width);
903 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
907 format = sai->fmt & SND_SOC_DAIFMT_FORMAT_MASK;
908 sai->fs_length = sai->slot_width * sai->slots;
910 fs_active = sai->fs_length / 2;
915 frcr = SAI_XFRCR_FRL_SET((sai->fs_length - 1));
920 sai->fs_length, fs_active);
922 stm32_sai_sub_reg_up(sai, STM_SAI_FRCR_REGX, frcr_mask, frcr);
924 if ((sai->fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_LSB) {
925 offset = sai->slot_width - sai->data_size;
927 stm32_sai_sub_reg_up(sai, STM_SAI_SLOTR_REGX,
933 static void stm32_sai_init_iec958_status(struct stm32_sai_sub_data *sai)
935 unsigned char *cs = sai->iec958.status;
943 static void stm32_sai_set_iec958_status(struct stm32_sai_sub_data *sai,
950 mutex_lock(&sai->ctrl_lock);
953 sai->iec958.status[3] = IEC958_AES3_CON_FS_22050;
956 sai->iec958.status[3] = IEC958_AES3_CON_FS_44100;
959 sai->iec958.status[3] = IEC958_AES3_CON_FS_88200;
962 sai->iec958.status[3] = IEC958_AES3_CON_FS_176400;
965 sai->iec958.status[3] = IEC958_AES3_CON_FS_24000;
968 sai->iec958.status[3] = IEC958_AES3_CON_FS_48000;
971 sai->iec958.status[3] = IEC958_AES3_CON_FS_96000;
974 sai->iec958.status[3] = IEC958_AES3_CON_FS_192000;
977 sai->iec958.status[3] = IEC958_AES3_CON_FS_32000;
980 sai->iec958.status[3] = IEC958_AES3_CON_FS_NOTID;
983 mutex_unlock(&sai->ctrl_lock);
989 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
995 if (!sai->sai_mclk) {
996 ret = stm32_sai_set_parent_clock(sai, rate);
1000 sai_clk_rate = clk_get_rate(sai->sai_ck);
1002 if (STM_SAI_IS_F4(sai->pdata)) {
1010 if (!sai->mclk_rate)
1013 if (2 * sai_clk_rate >= 3 * sai->mclk_rate) {
1014 div = stm32_sai_get_clk_div(sai, sai_clk_rate,
1015 2 * sai->mclk_rate);
1029 if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
1030 div = stm32_sai_get_clk_div(sai, sai_clk_rate,
1035 if (sai->mclk_rate) {
1036 mclk_ratio = sai->mclk_rate / rate;
1046 stm32_sai_sub_reg_up(sai,
1050 div = stm32_sai_get_clk_div(sai, sai_clk_rate,
1051 sai->mclk_rate);
1056 den = sai->fs_length * params_rate(params);
1057 div = stm32_sai_get_clk_div(sai, sai_clk_rate,
1065 return stm32_sai_set_clk_div(sai, div);
1072 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
1075 sai->data_size = params_width(params);
1077 if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
1080 stm32_sai_set_iec958_status(sai, substream->runtime);
1092 if (sai->master)
1101 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
1110 stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
1114 ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
1124 stm32_sai_sub_reg_up(sai, STM_SAI_IMR_REGX,
1127 stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
1131 ret = stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX,
1137 if (STM_SAI_PROTOCOL_IS_SPDIF(sai))
1138 sai->spdif_frm_cnt = 0;
1150 struct stm32_sai_sub_data *sai = snd_soc_dai_get_drvdata(cpu_dai);
1153 stm32_sai_sub_reg_up(sai, STM_SAI_IMR_REGX, SAI_XIMR_MASK, 0);
1155 clk_disable_unprepare(sai->sai_ck);
1157 spin_lock_irqsave(&sai->irq_lock, flags);
1158 sai->substream = NULL;
1159 spin_unlock_irqrestore(&sai->irq_lock, flags);
1165 struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev);
1168 if (STM_SAI_PROTOCOL_IS_SPDIF(sai)) {
1169 dev_dbg(&sai->pdev->dev, "%s: register iec controls", __func__);
1171 return snd_ctl_add(rtd->pcm->card, snd_ctl_new1(&knew, sai));
1179 struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev);
1182 sai->cpu_dai = cpu_dai;
1184 sai->dma_params.addr = (dma_addr_t)(sai->phys_addr + STM_SAI_DR_REGX);
1190 sai->dma_params.maxburst = 4;
1191 if (sai->pdata->conf.fifo_size < 8)
1192 sai->dma_params.maxburst = 1;
1194 sai->dma_params.addr_width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
1196 if (STM_SAI_IS_PLAYBACK(sai))
1197 snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params, NULL);
1199 snd_soc_dai_init_dma_data(cpu_dai, NULL, &sai->dma_params);
1202 if (STM_SAI_PROTOCOL_IS_SPDIF(sai))
1206 if (STM_SAI_IS_CAPTURE(sai))
1210 if (sai->sync == SAI_SYNC_EXTERNAL) {
1212 ret = sai->pdata->set_sync(sai->pdata, sai->np_sync_provider,
1213 sai->synco, sai->synci);
1219 cr1 |= SAI_XCR1_SYNCEN_SET(sai->sync);
1221 return stm32_sai_sub_reg_up(sai, STM_SAI_CR1_REGX, cr1_mask, cr1);
1254 struct stm32_sai_sub_data *sai = dev_get_drvdata(cpu_dai->dev);
1258 unsigned int frm_cnt = sai->spdif_frm_cnt;
1268 if (sai->iec958.status[byte] & mask)
1278 sai->spdif_frm_cnt = frm_cnt;
1348 .name = "stm32-sai",
1353 { .compatible = "st,stm32-sai-sub-a",
1355 { .compatible = "st,stm32-sai-sub-b",
1362 struct stm32_sai_sub_data *sai)
1377 sai->phys_addr = res->start;
1379 sai->regmap_config = &stm32_sai_sub_regmap_config_f4;
1381 if (STM_SAI_HAS_PDM(sai) && STM_SAI_IS_SUB_A(sai))
1382 sai->regmap_config = &stm32_sai_sub_regmap_config_h7;
1386 * can lead to circular locking issue with sai master clock provider.
1389 sai->regmap = devm_regmap_init_mmio(&pdev->dev, base,
1390 sai->regmap_config);
1391 if (IS_ERR(sai->regmap))
1392 return dev_err_probe(&pdev->dev, PTR_ERR(sai->regmap),
1397 sai->dir = SNDRV_PCM_STREAM_PLAYBACK;
1399 sai->dir = SNDRV_PCM_STREAM_CAPTURE;
1406 sai->spdif = false;
1408 if (!STM_SAI_HAS_SPDIF(sai) ||
1409 sai->dir == SNDRV_PCM_STREAM_CAPTURE) {
1413 stm32_sai_init_iec958_status(sai);
1414 sai->spdif = true;
1415 sai->master = true;
1426 sai->sync = SAI_SYNC_NONE;
1434 sai->np_sync_provider = of_get_parent(args.np);
1435 if (!sai->np_sync_provider) {
1442 sai->sync = SAI_SYNC_INTERNAL;
1443 if (sai->np_sync_provider != sai->pdata->pdev->dev.of_node) {
1444 if (!STM_SAI_HAS_EXT_SYNC(sai)) {
1450 sai->sync = SAI_SYNC_EXTERNAL;
1452 sai->synci = args.args[0];
1453 if (sai->synci < 1 ||
1454 (sai->synci > (SAI_GCR_SYNCIN_MAX + 1))) {
1461 "st,stm32-sai-sub-a") >= 0)
1462 sai->synco = STM_SAI_SYNC_OUT_A;
1465 "st,stm32-sai-sub-b") >= 0)
1466 sai->synco = STM_SAI_SYNC_OUT_B;
1468 if (!sai->synco) {
1480 sai->sai_ck = devm_clk_get(&pdev->dev, "sai_ck");
1481 if (IS_ERR(sai->sai_ck))
1482 return dev_err_probe(&pdev->dev, PTR_ERR(sai->sai_ck),
1485 ret = clk_prepare(sai->pdata->pclk);
1489 if (STM_SAI_IS_F4(sai->pdata))
1494 ret = stm32_sai_add_mclk_provider(sai);
1498 sai->sai_mclk = devm_clk_get_optional(&pdev->dev, "MCLK");
1499 if (IS_ERR(sai->sai_mclk))
1500 return PTR_ERR(sai->sai_mclk);
1508 struct stm32_sai_sub_data *sai;
1512 sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
1513 if (!sai)
1516 sai->id = (uintptr_t)device_get_match_data(&pdev->dev);
1518 sai->pdev = pdev;
1519 mutex_init(&sai->ctrl_lock);
1520 spin_lock_init(&sai->irq_lock);
1521 platform_set_drvdata(pdev, sai);
1523 sai->pdata = dev_get_drvdata(pdev->dev.parent);
1524 if (!sai->pdata) {
1529 ret = stm32_sai_sub_parse_of(pdev, sai);
1533 if (STM_SAI_IS_PLAYBACK(sai))
1534 sai->cpu_dai_drv = stm32_sai_playback_dai;
1536 sai->cpu_dai_drv = stm32_sai_capture_dai;
1537 sai->cpu_dai_drv.name = dev_name(&pdev->dev);
1539 ret = devm_request_irq(&pdev->dev, sai->pdata->irq, stm32_sai_isr,
1540 IRQF_SHARED, dev_name(&pdev->dev), sai);
1546 if (STM_SAI_PROTOCOL_IS_SPDIF(sai))
1554 &sai->cpu_dai_drv, 1);
1567 struct stm32_sai_sub_data *sai = dev_get_drvdata(&pdev->dev);
1569 clk_unprepare(sai->pdata->pclk);
1578 struct stm32_sai_sub_data *sai = dev_get_drvdata(dev);
1581 ret = clk_enable(sai->pdata->pclk);
1585 regcache_cache_only(sai->regmap, true);
1586 regcache_mark_dirty(sai->regmap);
1588 clk_disable(sai->pdata->pclk);
1595 struct stm32_sai_sub_data *sai = dev_get_drvdata(dev);
1598 ret = clk_enable(sai->pdata->pclk);
1602 regcache_cache_only(sai->regmap, false);
1603 ret = regcache_sync(sai->regmap);
1605 clk_disable(sai->pdata->pclk);
1617 .name = "st,stm32-sai-sub",
1629 MODULE_ALIAS("platform:st,stm32-sai-sub");