Lines Matching +full:tdm +full:- +full:data +full:- +full:delay
1 // SPDX-License-Identifier: GPL-2.0
3 // ALSA SoC Audio Layer - Samsung I2S Controller driver
8 #include <dt-bindings/sound/samsung-i2s.h>
9 #include <linux/delay.h>
12 #include <linux/clk-provider.h>
23 #include <linux/platform_data/asoc-s3c.h>
28 #include "i2s-regs.h"
116 /* The clock provider's data */
133 return i2s->drv->id == SAMSUNG_I2S_ID_SECONDARY; in is_secondary()
136 /* If this interface of the controller is transmitting data */
144 active = readl(i2s->priv->addr + I2SCON); in tx_active()
157 return i2s->pri_dai ? : i2s->sec_dai; in get_other_dai()
160 /* If the other interface of the controller is transmitting data */
168 /* If any interface of the controller is transmitting data */
174 /* If this interface of the controller is receiving data */
182 active = readl(i2s->priv->addr + I2SCON) & CON_RXDMA_ACTIVE; in rx_active()
187 /* If the other interface of the controller is receiving data */
195 /* If any interface of the controller is receiving data */
201 /* If the other DAI is transmitting or receiving data */
207 /* If this DAI is transmitting or receiving data */
223 return &priv->dai[dai->id - 1]; in to_info()
228 if (i2s && (i2s->mode & DAI_OPENED)) in is_opened()
236 if (is_opened(i2s) && (i2s->mode & DAI_MANAGER)) in is_manager()
245 struct samsung_i2s_priv *priv = i2s->priv; in get_rfs()
248 rfs = readl(priv->addr + I2SMOD) >> priv->variant_regs->rfs_off; in get_rfs()
249 rfs &= priv->variant_regs->rfs_mask; in get_rfs()
266 struct samsung_i2s_priv *priv = i2s->priv; in set_rfs()
267 u32 mod = readl(priv->addr + I2SMOD); in set_rfs()
268 int rfs_shift = priv->variant_regs->rfs_off; in set_rfs()
270 mod &= ~(priv->variant_regs->rfs_mask << rfs_shift); in set_rfs()
299 writel(mod, priv->addr + I2SMOD); in set_rfs()
302 /* Read bit-clock of I2S (in multiples of LRCLK) */
305 struct samsung_i2s_priv *priv = i2s->priv; in get_bfs()
308 bfs = readl(priv->addr + I2SMOD) >> priv->variant_regs->bfs_off; in get_bfs()
309 bfs &= priv->variant_regs->bfs_mask; in get_bfs()
324 /* Write bit-clock of I2S (in multiples of LRCLK) */
327 struct samsung_i2s_priv *priv = i2s->priv; in set_bfs()
328 u32 mod = readl(priv->addr + I2SMOD); in set_bfs()
329 int tdm = priv->quirks & QUIRK_SUPPORTS_TDM; in set_bfs() local
330 int bfs_shift = priv->variant_regs->bfs_off; in set_bfs()
332 /* Non-TDM I2S controllers do not support BCLK > 48 * FS */ in set_bfs()
333 if (!tdm && bfs > 48) { in set_bfs()
334 dev_err(&i2s->pdev->dev, "Unsupported BCLK divider\n"); in set_bfs()
338 mod &= ~(priv->variant_regs->bfs_mask << bfs_shift); in set_bfs()
369 dev_err(&i2s->pdev->dev, "Wrong BCLK Divider!\n"); in set_bfs()
373 writel(mod, priv->addr + I2SMOD); in set_bfs()
379 int blc = readl(i2s->priv->addr + I2SMOD); in get_blc()
393 struct samsung_i2s_priv *priv = i2s->priv; in i2s_txctrl()
394 void __iomem *addr = priv->addr; in i2s_txctrl()
395 int txr_off = priv->variant_regs->txr_off; in i2s_txctrl()
444 struct samsung_i2s_priv *priv = i2s->priv; in i2s_rxctrl()
445 void __iomem *addr = priv->addr; in i2s_rxctrl()
446 int txr_off = priv->variant_regs->txr_off; in i2s_rxctrl()
482 fic = i2s->priv->addr + I2SFICS; in i2s_fifo()
484 fic = i2s->priv->addr + I2SFIC; in i2s_fifo()
491 while (--val) in i2s_fifo()
503 const struct samsung_i2s_variant_regs *i2s_regs = priv->variant_regs; in i2s_set_sysclk()
504 unsigned int cdcon_mask = 1 << i2s_regs->cdclkcon_off; in i2s_set_sysclk()
505 unsigned int rsrc_mask = 1 << i2s_regs->rclksrc_off; in i2s_set_sysclk()
510 pm_runtime_get_sync(dai->dev); in i2s_set_sysclk()
512 spin_lock_irqsave(&priv->lock, flags); in i2s_set_sysclk()
513 mod = readl(priv->addr + I2SMOD); in i2s_set_sysclk()
514 spin_unlock_irqrestore(&priv->lock, flags); in i2s_set_sysclk()
522 mask = 1 << i2s_regs->cdclkcon_off; in i2s_set_sysclk()
527 if ((rfs && other && other->rfs && (other->rfs != rfs)) || in i2s_set_sysclk()
533 dev_err(&i2s->pdev->dev, in i2s_set_sysclk()
535 ret = -EAGAIN; in i2s_set_sysclk()
540 val = 1 << i2s_regs->cdclkcon_off; in i2s_set_sysclk()
542 i2s->rfs = rfs; in i2s_set_sysclk()
547 mask = 1 << i2s_regs->rclksrc_off; in i2s_set_sysclk()
549 if ((priv->quirks & QUIRK_NO_MUXPSR) in i2s_set_sysclk()
556 if (priv->op_clk && !IS_ERR(priv->op_clk)) { in i2s_set_sysclk()
559 clk_disable_unprepare(priv->op_clk); in i2s_set_sysclk()
560 clk_put(priv->op_clk); in i2s_set_sysclk()
562 priv->rclk_srcrate = in i2s_set_sysclk()
563 clk_get_rate(priv->op_clk); in i2s_set_sysclk()
569 priv->op_clk = clk_get(&i2s->pdev->dev, in i2s_set_sysclk()
572 priv->op_clk = clk_get(&i2s->pdev->dev, in i2s_set_sysclk()
575 if (WARN_ON(IS_ERR(priv->op_clk))) { in i2s_set_sysclk()
576 ret = PTR_ERR(priv->op_clk); in i2s_set_sysclk()
577 priv->op_clk = NULL; in i2s_set_sysclk()
581 ret = clk_prepare_enable(priv->op_clk); in i2s_set_sysclk()
583 clk_put(priv->op_clk); in i2s_set_sysclk()
584 priv->op_clk = NULL; in i2s_set_sysclk()
587 priv->rclk_srcrate = clk_get_rate(priv->op_clk); in i2s_set_sysclk()
591 dev_err(&i2s->pdev->dev, in i2s_set_sysclk()
593 ret = -EAGAIN; in i2s_set_sysclk()
601 val = 1 << i2s_regs->rclksrc_off; in i2s_set_sysclk()
604 dev_err(&i2s->pdev->dev, "We don't serve that!\n"); in i2s_set_sysclk()
605 ret = -EINVAL; in i2s_set_sysclk()
609 spin_lock_irqsave(&priv->lock, flags); in i2s_set_sysclk()
610 mod = readl(priv->addr + I2SMOD); in i2s_set_sysclk()
612 writel(mod, priv->addr + I2SMOD); in i2s_set_sysclk()
613 spin_unlock_irqrestore(&priv->lock, flags); in i2s_set_sysclk()
615 pm_runtime_put(dai->dev); in i2s_set_sysclk()
619 pm_runtime_put(dai->dev); in i2s_set_sysclk()
631 lrp_shift = priv->variant_regs->lrp_off; in i2s_set_fmt()
632 sdf_shift = priv->variant_regs->sdf_off; in i2s_set_fmt()
633 mod_slave = 1 << priv->variant_regs->mss_off; in i2s_set_fmt()
652 dev_err(&i2s->pdev->dev, "Format not supported\n"); in i2s_set_fmt()
653 return -EINVAL; in i2s_set_fmt()
657 * INV flag is relative to the FORMAT flag - if set it simply in i2s_set_fmt()
670 dev_err(&i2s->pdev->dev, "Polarity not supported\n"); in i2s_set_fmt()
671 return -EINVAL; in i2s_set_fmt()
684 if (priv->rclk_srcrate == 0 && priv->clk_data.clks == NULL) in i2s_set_fmt()
689 dev_err(&i2s->pdev->dev, "master/slave format not supported\n"); in i2s_set_fmt()
690 return -EINVAL; in i2s_set_fmt()
693 pm_runtime_get_sync(dai->dev); in i2s_set_fmt()
694 spin_lock_irqsave(&priv->lock, flags); in i2s_set_fmt()
695 mod = readl(priv->addr + I2SMOD); in i2s_set_fmt()
702 spin_unlock_irqrestore(&priv->lock, flags); in i2s_set_fmt()
703 pm_runtime_put(dai->dev); in i2s_set_fmt()
704 dev_err(&i2s->pdev->dev, in i2s_set_fmt()
706 return -EAGAIN; in i2s_set_fmt()
711 writel(mod, priv->addr + I2SMOD); in i2s_set_fmt()
712 priv->slave_mode = (mod & mod_slave); in i2s_set_fmt()
713 spin_unlock_irqrestore(&priv->lock, flags); in i2s_set_fmt()
714 pm_runtime_put(dai->dev); in i2s_set_fmt()
728 WARN_ON(!pm_runtime_active(dai->dev)); in i2s_hw_params()
741 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in i2s_hw_params()
742 i2s->dma_playback.addr_width = 4; in i2s_hw_params()
744 i2s->dma_capture.addr_width = 4; in i2s_hw_params()
747 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in i2s_hw_params()
748 i2s->dma_playback.addr_width = 2; in i2s_hw_params()
750 i2s->dma_capture.addr_width = 2; in i2s_hw_params()
754 dev_err(&i2s->pdev->dev, "%d channels not supported\n", in i2s_hw_params()
756 return -EINVAL; in i2s_hw_params()
793 dev_err(&i2s->pdev->dev, "Format(%d) not supported\n", in i2s_hw_params()
795 return -EINVAL; in i2s_hw_params()
798 spin_lock_irqsave(&priv->lock, flags); in i2s_hw_params()
799 mod = readl(priv->addr + I2SMOD); in i2s_hw_params()
801 writel(mod, priv->addr + I2SMOD); in i2s_hw_params()
802 spin_unlock_irqrestore(&priv->lock, flags); in i2s_hw_params()
804 snd_soc_dai_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); in i2s_hw_params()
806 i2s->frmclk = params_rate(params); in i2s_hw_params()
808 rclksrc = priv->clk_table[CLK_I2S_RCLK_SRC]; in i2s_hw_params()
810 priv->rclk_srcrate = clk_get_rate(rclksrc); in i2s_hw_params()
824 pm_runtime_get_sync(dai->dev); in i2s_startup()
826 spin_lock_irqsave(&priv->pcm_lock, flags); in i2s_startup()
828 i2s->mode |= DAI_OPENED; in i2s_startup()
831 i2s->mode &= ~DAI_MANAGER; in i2s_startup()
833 i2s->mode |= DAI_MANAGER; in i2s_startup()
835 if (!any_active(i2s) && (priv->quirks & QUIRK_NEED_RSTCLR)) in i2s_startup()
836 writel(CON_RSTCLR, i2s->priv->addr + I2SCON); in i2s_startup()
838 spin_unlock_irqrestore(&priv->pcm_lock, flags); in i2s_startup()
851 spin_lock_irqsave(&priv->pcm_lock, flags); in i2s_shutdown()
853 i2s->mode &= ~DAI_OPENED; in i2s_shutdown()
854 i2s->mode &= ~DAI_MANAGER; in i2s_shutdown()
857 other->mode |= DAI_MANAGER; in i2s_shutdown()
860 i2s->rfs = 0; in i2s_shutdown()
861 i2s->bfs = 0; in i2s_shutdown()
863 spin_unlock_irqrestore(&priv->pcm_lock, flags); in i2s_shutdown()
865 pm_runtime_put(dai->dev); in i2s_shutdown()
870 struct samsung_i2s_priv *priv = i2s->priv; in config_setup()
877 bfs = i2s->bfs; in config_setup()
880 bfs = other->bfs; in config_setup()
886 rfs = i2s->rfs; in config_setup()
889 rfs = other->rfs; in config_setup()
892 dev_err(&i2s->pdev->dev, in config_setup()
893 "%d-RFS not supported for 24-blc\n", rfs); in config_setup()
894 return -EINVAL; in config_setup()
906 dev_err(&i2s->pdev->dev, in config_setup()
908 return -EAGAIN; in config_setup()
915 if (priv->slave_mode) in config_setup()
918 if (!(priv->quirks & QUIRK_NO_MUXPSR)) { in config_setup()
919 psr = priv->rclk_srcrate / i2s->frmclk / rfs; in config_setup()
920 writel(((psr - 1) << 8) | PSR_PSREN, priv->addr + I2SPSR); in config_setup()
921 dev_dbg(&i2s->pdev->dev, in config_setup()
923 priv->rclk_srcrate, psr, rfs, bfs); in config_setup()
933 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); in i2s_trigger()
942 pm_runtime_get_sync(dai->dev); in i2s_trigger()
943 spin_lock_irqsave(&priv->lock, flags); in i2s_trigger()
946 spin_unlock_irqrestore(&priv->lock, flags); in i2s_trigger()
947 return -EINVAL; in i2s_trigger()
955 spin_unlock_irqrestore(&priv->lock, flags); in i2s_trigger()
960 spin_lock_irqsave(&priv->lock, flags); in i2s_trigger()
970 spin_unlock_irqrestore(&priv->lock, flags); in i2s_trigger()
971 pm_runtime_put(dai->dev); in i2s_trigger()
986 pm_runtime_get_sync(dai->dev); in i2s_set_clkdiv()
988 || (other && other->bfs && (other->bfs != div))) { in i2s_set_clkdiv()
989 pm_runtime_put(dai->dev); in i2s_set_clkdiv()
990 dev_err(&i2s->pdev->dev, in i2s_set_clkdiv()
992 return -EAGAIN; in i2s_set_clkdiv()
994 i2s->bfs = div; in i2s_set_clkdiv()
995 pm_runtime_put(dai->dev); in i2s_set_clkdiv()
998 dev_err(&i2s->pdev->dev, in i2s_set_clkdiv()
1000 return -EINVAL; in i2s_set_clkdiv()
1011 u32 reg = readl(priv->addr + I2SFIC); in i2s_delay()
1012 snd_pcm_sframes_t delay; in i2s_delay() local
1014 WARN_ON(!pm_runtime_active(dai->dev)); in i2s_delay()
1016 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) in i2s_delay()
1017 delay = FIC_RXCOUNT(reg); in i2s_delay()
1019 delay = FICS_TXCOUNT(readl(priv->addr + I2SFICS)); in i2s_delay()
1021 delay = (reg >> priv->variant_regs->ftx0cnt_off) & 0x7f; in i2s_delay()
1023 return delay; in i2s_delay()
1029 return pm_runtime_force_suspend(component->dev); in i2s_suspend()
1034 return pm_runtime_force_resume(component->dev); in i2s_resume()
1048 pm_runtime_get_sync(dai->dev); in samsung_i2s_dai_probe()
1052 snd_soc_dai_init_dma_data(dai, &i2s->dma_playback, NULL); in samsung_i2s_dai_probe()
1054 snd_soc_dai_init_dma_data(dai, &i2s->dma_playback, in samsung_i2s_dai_probe()
1055 &i2s->dma_capture); in samsung_i2s_dai_probe()
1057 if (priv->quirks & QUIRK_NEED_RSTCLR) in samsung_i2s_dai_probe()
1058 writel(CON_RSTCLR, priv->addr + I2SCON); in samsung_i2s_dai_probe()
1060 if (priv->quirks & QUIRK_SUPPORTS_IDMA) in samsung_i2s_dai_probe()
1061 idma_reg_addr_init(priv->addr, in samsung_i2s_dai_probe()
1062 other->idma_playback.addr); in samsung_i2s_dai_probe()
1066 i2s->rfs = 0; in samsung_i2s_dai_probe()
1067 i2s->bfs = 0; in samsung_i2s_dai_probe()
1069 spin_lock_irqsave(&priv->lock, flags); in samsung_i2s_dai_probe()
1075 spin_unlock_irqrestore(&priv->lock, flags); in samsung_i2s_dai_probe()
1081 pm_runtime_put(dai->dev); in samsung_i2s_dai_probe()
1092 pm_runtime_get_sync(dai->dev); in samsung_i2s_dai_remove()
1095 if (priv->quirks & QUIRK_NEED_RSTCLR) { in samsung_i2s_dai_remove()
1096 spin_lock_irqsave(&priv->lock, flags); in samsung_i2s_dai_remove()
1097 writel(0, priv->addr + I2SCON); in samsung_i2s_dai_remove()
1098 spin_unlock_irqrestore(&priv->lock, flags); in samsung_i2s_dai_remove()
1102 pm_runtime_put(dai->dev); in samsung_i2s_dai_remove()
1115 .delay = i2s_delay,
1136 .name = "samsung-i2s",
1157 static const char *dai_names[] = { "samsung-i2s", "samsung-i2s-sec" }; in i2s_alloc_dais()
1163 priv->dai = devm_kcalloc(&priv->pdev->dev, num_dais, in i2s_alloc_dais()
1165 if (!priv->dai) in i2s_alloc_dais()
1166 return -ENOMEM; in i2s_alloc_dais()
1168 priv->dai_drv = devm_kcalloc(&priv->pdev->dev, num_dais, in i2s_alloc_dais()
1170 if (!priv->dai_drv) in i2s_alloc_dais()
1171 return -ENOMEM; in i2s_alloc_dais()
1174 dai_drv = &priv->dai_drv[i]; in i2s_alloc_dais()
1176 dai_drv->probe = samsung_i2s_dai_probe; in i2s_alloc_dais()
1177 dai_drv->remove = samsung_i2s_dai_remove; in i2s_alloc_dais()
1179 dai_drv->symmetric_rate = 1; in i2s_alloc_dais()
1180 dai_drv->ops = &samsung_i2s_dai_ops; in i2s_alloc_dais()
1182 dai_drv->playback.channels_min = 1; in i2s_alloc_dais()
1183 dai_drv->playback.channels_max = 2; in i2s_alloc_dais()
1184 dai_drv->playback.rates = i2s_dai_data->pcm_rates; in i2s_alloc_dais()
1185 dai_drv->playback.formats = SAMSUNG_I2S_FMTS; in i2s_alloc_dais()
1186 dai_drv->playback.stream_name = stream_names[i]; in i2s_alloc_dais()
1188 dai_drv->id = i + 1; in i2s_alloc_dais()
1189 dai_drv->name = dai_names[i]; in i2s_alloc_dais()
1191 priv->dai[i].drv = &priv->dai_drv[i]; in i2s_alloc_dais()
1192 priv->dai[i].pdev = priv->pdev; in i2s_alloc_dais()
1196 dai_drv = &priv->dai_drv[SAMSUNG_I2S_ID_PRIMARY - 1]; in i2s_alloc_dais()
1198 dai_drv->capture.channels_min = 1; in i2s_alloc_dais()
1199 dai_drv->capture.channels_max = 2; in i2s_alloc_dais()
1200 dai_drv->capture.rates = i2s_dai_data->pcm_rates; in i2s_alloc_dais()
1201 dai_drv->capture.formats = SAMSUNG_I2S_FMTS; in i2s_alloc_dais()
1202 dai_drv->capture.stream_name = "Primary Capture"; in i2s_alloc_dais()
1212 priv->suspend_i2smod = readl(priv->addr + I2SMOD); in i2s_runtime_suspend()
1213 priv->suspend_i2scon = readl(priv->addr + I2SCON); in i2s_runtime_suspend()
1214 priv->suspend_i2spsr = readl(priv->addr + I2SPSR); in i2s_runtime_suspend()
1216 clk_disable_unprepare(priv->op_clk); in i2s_runtime_suspend()
1217 clk_disable_unprepare(priv->clk); in i2s_runtime_suspend()
1227 ret = clk_prepare_enable(priv->clk); in i2s_runtime_resume()
1231 if (priv->op_clk) { in i2s_runtime_resume()
1232 ret = clk_prepare_enable(priv->op_clk); in i2s_runtime_resume()
1234 clk_disable_unprepare(priv->clk); in i2s_runtime_resume()
1239 writel(priv->suspend_i2scon, priv->addr + I2SCON); in i2s_runtime_resume()
1240 writel(priv->suspend_i2smod, priv->addr + I2SMOD); in i2s_runtime_resume()
1241 writel(priv->suspend_i2spsr, priv->addr + I2SPSR); in i2s_runtime_resume()
1251 for (i = 0; i < priv->clk_data.clk_num; i++) { in i2s_unregister_clocks()
1252 if (!IS_ERR(priv->clk_table[i])) in i2s_unregister_clocks()
1253 clk_unregister(priv->clk_table[i]); in i2s_unregister_clocks()
1259 of_clk_del_provider(priv->pdev->dev.of_node); in i2s_unregister_clock_provider()
1270 struct device *dev = &priv->pdev->dev; in i2s_register_clock_provider()
1271 const struct samsung_i2s_variant_regs *reg_info = priv->variant_regs; in i2s_register_clock_provider()
1277 if (!of_find_property(dev->of_node, "#clock-cells", NULL)) in i2s_register_clock_provider()
1293 return -ENOMEM; in i2s_register_clock_provider()
1296 if (!(priv->quirks & QUIRK_NO_MUXPSR)) { in i2s_register_clock_provider()
1298 u32 val = readl(priv->addr + I2SPSR); in i2s_register_clock_provider()
1299 writel(val | PSR_PSREN, priv->addr + I2SPSR); in i2s_register_clock_provider()
1301 priv->clk_table[CLK_I2S_RCLK_SRC] = clk_register_mux(dev, in i2s_register_clock_provider()
1305 priv->addr + I2SMOD, reg_info->rclksrc_off, in i2s_register_clock_provider()
1306 1, 0, &priv->lock); in i2s_register_clock_provider()
1308 priv->clk_table[CLK_I2S_RCLK_PSR] = clk_register_divider(dev, in i2s_register_clock_provider()
1312 priv->addr + I2SPSR, 8, 6, 0, &priv->lock); in i2s_register_clock_provider()
1315 priv->clk_data.clk_num = 2; in i2s_register_clock_provider()
1318 priv->clk_table[CLK_I2S_CDCLK] = clk_register_gate(dev, in i2s_register_clock_provider()
1321 priv->addr + I2SMOD, reg_info->cdclkcon_off, in i2s_register_clock_provider()
1322 CLK_GATE_SET_TO_DISABLE, &priv->lock); in i2s_register_clock_provider()
1324 priv->clk_data.clk_num += 1; in i2s_register_clock_provider()
1325 priv->clk_data.clks = priv->clk_table; in i2s_register_clock_provider()
1327 ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get, in i2s_register_clock_provider()
1328 &priv->clk_data); in i2s_register_clock_provider()
1344 devname = devm_kasprintf(&priv->pdev->dev, GFP_KERNEL, "%s-sec", in i2s_create_secondary_device()
1345 dev_name(&priv->pdev->dev)); in i2s_create_secondary_device()
1347 return -ENOMEM; in i2s_create_secondary_device()
1349 pdev_sec = platform_device_alloc(devname, -1); in i2s_create_secondary_device()
1351 return -ENOMEM; in i2s_create_secondary_device()
1353 pdev_sec->driver_override = kstrdup("samsung-i2s", GFP_KERNEL); in i2s_create_secondary_device()
1354 if (!pdev_sec->driver_override) { in i2s_create_secondary_device()
1356 return -ENOMEM; in i2s_create_secondary_device()
1365 ret = device_attach(&pdev_sec->dev); in i2s_create_secondary_device()
1367 platform_device_unregister(priv->pdev_sec); in i2s_create_secondary_device()
1368 dev_info(&pdev_sec->dev, "device_attach() failed\n"); in i2s_create_secondary_device()
1372 priv->pdev_sec = pdev_sec; in i2s_create_secondary_device()
1379 platform_device_unregister(priv->pdev_sec); in i2s_delete_secondary_device()
1380 priv->pdev_sec = NULL; in i2s_delete_secondary_device()
1386 struct s3c_audio_pdata *i2s_pdata = pdev->dev.platform_data; in samsung_i2s_probe()
1388 struct device_node *np = pdev->dev.of_node; in samsung_i2s_probe()
1395 if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { in samsung_i2s_probe()
1396 i2s_dai_data = of_device_get_match_data(&pdev->dev); in samsung_i2s_probe()
1404 i2s_dai_data = (struct samsung_i2s_dai_data *)id->driver_data; in samsung_i2s_probe()
1407 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); in samsung_i2s_probe()
1409 return -ENOMEM; in samsung_i2s_probe()
1412 priv->quirks = i2s_dai_data->quirks; in samsung_i2s_probe()
1415 dev_err(&pdev->dev, "Missing platform data\n"); in samsung_i2s_probe()
1416 return -EINVAL; in samsung_i2s_probe()
1418 priv->quirks = i2s_pdata->type.quirks; in samsung_i2s_probe()
1421 num_dais = (priv->quirks & QUIRK_SEC_DAI) ? 2 : 1; in samsung_i2s_probe()
1422 priv->pdev = pdev; in samsung_i2s_probe()
1423 priv->variant_regs = i2s_dai_data->i2s_variant_regs; in samsung_i2s_probe()
1429 pri_dai = &priv->dai[SAMSUNG_I2S_ID_PRIMARY - 1]; in samsung_i2s_probe()
1431 spin_lock_init(&priv->lock); in samsung_i2s_probe()
1432 spin_lock_init(&priv->pcm_lock); in samsung_i2s_probe()
1435 pri_dai->dma_playback.filter_data = i2s_pdata->dma_playback; in samsung_i2s_probe()
1436 pri_dai->dma_capture.filter_data = i2s_pdata->dma_capture; in samsung_i2s_probe()
1437 pri_dai->filter = i2s_pdata->dma_filter; in samsung_i2s_probe()
1439 idma_addr = i2s_pdata->type.idma_addr; in samsung_i2s_probe()
1441 if (of_property_read_u32(np, "samsung,idma-addr", in samsung_i2s_probe()
1443 if (priv->quirks & QUIRK_SUPPORTS_IDMA) { in samsung_i2s_probe()
1444 dev_info(&pdev->dev, "idma address is not"\ in samsung_i2s_probe()
1450 priv->addr = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in samsung_i2s_probe()
1451 if (IS_ERR(priv->addr)) in samsung_i2s_probe()
1452 return PTR_ERR(priv->addr); in samsung_i2s_probe()
1454 regs_base = res->start; in samsung_i2s_probe()
1456 priv->clk = devm_clk_get(&pdev->dev, "iis"); in samsung_i2s_probe()
1457 if (IS_ERR(priv->clk)) { in samsung_i2s_probe()
1458 dev_err(&pdev->dev, "Failed to get iis clock\n"); in samsung_i2s_probe()
1459 return PTR_ERR(priv->clk); in samsung_i2s_probe()
1462 ret = clk_prepare_enable(priv->clk); in samsung_i2s_probe()
1464 dev_err(&pdev->dev, "failed to enable clock: %d\n", ret); in samsung_i2s_probe()
1467 pri_dai->dma_playback.addr = regs_base + I2STXD; in samsung_i2s_probe()
1468 pri_dai->dma_capture.addr = regs_base + I2SRXD; in samsung_i2s_probe()
1469 pri_dai->dma_playback.chan_name = "tx"; in samsung_i2s_probe()
1470 pri_dai->dma_capture.chan_name = "rx"; in samsung_i2s_probe()
1471 pri_dai->dma_playback.addr_width = 4; in samsung_i2s_probe()
1472 pri_dai->dma_capture.addr_width = 4; in samsung_i2s_probe()
1473 pri_dai->priv = priv; in samsung_i2s_probe()
1475 if (priv->quirks & QUIRK_PRI_6CHAN) in samsung_i2s_probe()
1476 pri_dai->drv->playback.channels_max = 6; in samsung_i2s_probe()
1478 ret = samsung_asoc_dma_platform_register(&pdev->dev, pri_dai->filter, in samsung_i2s_probe()
1483 if (priv->quirks & QUIRK_SEC_DAI) { in samsung_i2s_probe()
1484 sec_dai = &priv->dai[SAMSUNG_I2S_ID_SECONDARY - 1]; in samsung_i2s_probe()
1486 sec_dai->dma_playback.addr = regs_base + I2STXDS; in samsung_i2s_probe()
1487 sec_dai->dma_playback.chan_name = "tx-sec"; in samsung_i2s_probe()
1490 sec_dai->dma_playback.filter_data = i2s_pdata->dma_play_sec; in samsung_i2s_probe()
1491 sec_dai->filter = i2s_pdata->dma_filter; in samsung_i2s_probe()
1494 sec_dai->dma_playback.addr_width = 4; in samsung_i2s_probe()
1495 sec_dai->idma_playback.addr = idma_addr; in samsung_i2s_probe()
1496 sec_dai->pri_dai = pri_dai; in samsung_i2s_probe()
1497 sec_dai->priv = priv; in samsung_i2s_probe()
1498 pri_dai->sec_dai = sec_dai; in samsung_i2s_probe()
1504 ret = samsung_asoc_dma_platform_register(&priv->pdev_sec->dev, in samsung_i2s_probe()
1505 sec_dai->filter, "tx-sec", NULL, in samsung_i2s_probe()
1506 &pdev->dev); in samsung_i2s_probe()
1512 if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { in samsung_i2s_probe()
1513 dev_err(&pdev->dev, "Unable to configure gpio\n"); in samsung_i2s_probe()
1514 ret = -EINVAL; in samsung_i2s_probe()
1518 dev_set_drvdata(&pdev->dev, priv); in samsung_i2s_probe()
1520 ret = devm_snd_soc_register_component(&pdev->dev, in samsung_i2s_probe()
1522 priv->dai_drv, num_dais); in samsung_i2s_probe()
1526 pm_runtime_set_active(&pdev->dev); in samsung_i2s_probe()
1527 pm_runtime_enable(&pdev->dev); in samsung_i2s_probe()
1533 priv->op_clk = clk_get_parent(priv->clk_table[CLK_I2S_RCLK_SRC]); in samsung_i2s_probe()
1538 pm_runtime_disable(&pdev->dev); in samsung_i2s_probe()
1542 clk_disable_unprepare(priv->clk); in samsung_i2s_probe()
1548 struct samsung_i2s_priv *priv = dev_get_drvdata(&pdev->dev); in samsung_i2s_remove()
1550 /* The secondary device has no driver data assigned */ in samsung_i2s_remove()
1554 pm_runtime_get_sync(&pdev->dev); in samsung_i2s_remove()
1555 pm_runtime_disable(&pdev->dev); in samsung_i2s_remove()
1559 clk_disable_unprepare(priv->clk); in samsung_i2s_remove()
1561 pm_runtime_put_noidle(&pdev->dev); in samsung_i2s_remove()
1657 .name = "samsung-i2s",
1667 .compatible = "samsung,s3c6410-i2s",
1668 .data = &i2sv3_dai_type,
1670 .compatible = "samsung,s5pv210-i2s",
1671 .data = &i2sv5_dai_type,
1673 .compatible = "samsung,exynos5420-i2s",
1674 .data = &i2sv6_dai_type,
1676 .compatible = "samsung,exynos7-i2s",
1677 .data = &i2sv7_dai_type,
1679 .compatible = "samsung,exynos7-i2s1",
1680 .data = &i2sv5_dai_type_i2s1,
1699 .name = "samsung-i2s",
1710 MODULE_ALIAS("platform:samsung-i2s");