Lines Matching +full:i2s +full:- +full:controller

1 // SPDX-License-Identifier: GPL-2.0
3 // ALSA SoC Audio Layer - Samsung I2S Controller driver
8 #include <dt-bindings/sound/samsung-i2s.h>
12 #include <linux/clk-provider.h>
21 #include <linux/platform_data/asoc-s3c.h>
25 #include "i2s.h"
26 #include "i2s-regs.h"
101 /* The I2S controller's core clock */
104 /* Clock for generating I2S signals */
110 /* Cache of selected I2S registers for system suspend */
132 /* A flag indicating the I2S slave mode operation */
137 static inline bool is_secondary(struct i2s_dai *i2s)
139 return i2s->drv->id == SAMSUNG_I2S_ID_SECONDARY;
142 /* If this interface of the controller is transmitting data */
143 static inline bool tx_active(struct i2s_dai *i2s)
147 if (!i2s)
150 active = readl(i2s->priv->addr + I2SCON);
152 if (is_secondary(i2s))
161 static inline struct i2s_dai *get_other_dai(struct i2s_dai *i2s)
163 return i2s->pri_dai ? : i2s->sec_dai;
166 /* If the other interface of the controller is transmitting data */
167 static inline bool other_tx_active(struct i2s_dai *i2s)
169 struct i2s_dai *other = get_other_dai(i2s);
174 /* If any interface of the controller is transmitting data */
175 static inline bool any_tx_active(struct i2s_dai *i2s)
177 return tx_active(i2s) || other_tx_active(i2s);
180 /* If this interface of the controller is receiving data */
181 static inline bool rx_active(struct i2s_dai *i2s)
185 if (!i2s)
188 active = readl(i2s->priv->addr + I2SCON) & CON_RXDMA_ACTIVE;
193 /* If the other interface of the controller is receiving data */
194 static inline bool other_rx_active(struct i2s_dai *i2s)
196 struct i2s_dai *other = get_other_dai(i2s);
201 /* If any interface of the controller is receiving data */
202 static inline bool any_rx_active(struct i2s_dai *i2s)
204 return rx_active(i2s) || other_rx_active(i2s);
208 static inline bool other_active(struct i2s_dai *i2s)
210 return other_rx_active(i2s) || other_tx_active(i2s);
214 static inline bool this_active(struct i2s_dai *i2s)
216 return tx_active(i2s) || rx_active(i2s);
219 /* If the controller is active anyway */
220 static inline bool any_active(struct i2s_dai *i2s)
222 return this_active(i2s) || other_active(i2s);
229 return &priv->dai[dai->id - 1];
232 static inline bool is_opened(struct i2s_dai *i2s)
234 if (i2s && (i2s->mode & DAI_OPENED))
240 static inline bool is_manager(struct i2s_dai *i2s)
242 if (is_opened(i2s) && (i2s->mode & DAI_MANAGER))
248 /* Read RCLK of I2S (in multiples of LRCLK) */
249 static inline unsigned get_rfs(struct i2s_dai *i2s)
251 struct samsung_i2s_priv *priv = i2s->priv;
254 rfs = readl(priv->addr + I2SMOD) >> priv->variant_regs->rfs_off;
255 rfs &= priv->variant_regs->rfs_mask;
269 /* Write RCLK of I2S (in multiples of LRCLK) */
270 static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs)
272 struct samsung_i2s_priv *priv = i2s->priv;
273 u32 mod = readl(priv->addr + I2SMOD);
274 int rfs_shift = priv->variant_regs->rfs_off;
276 mod &= ~(priv->variant_regs->rfs_mask << rfs_shift);
305 writel(mod, priv->addr + I2SMOD);
308 /* Read bit-clock of I2S (in multiples of LRCLK) */
309 static inline unsigned get_bfs(struct i2s_dai *i2s)
311 struct samsung_i2s_priv *priv = i2s->priv;
314 bfs = readl(priv->addr + I2SMOD) >> priv->variant_regs->bfs_off;
315 bfs &= priv->variant_regs->bfs_mask;
330 /* Write bit-clock of I2S (in multiples of LRCLK) */
331 static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs)
333 struct samsung_i2s_priv *priv = i2s->priv;
334 u32 mod = readl(priv->addr + I2SMOD);
335 int tdm = priv->quirks & QUIRK_SUPPORTS_TDM;
336 int bfs_shift = priv->variant_regs->bfs_off;
338 /* Non-TDM I2S controllers do not support BCLK > 48 * FS */
340 dev_err(&i2s->pdev->dev, "Unsupported BCLK divider\n");
344 mod &= ~(priv->variant_regs->bfs_mask << bfs_shift);
375 dev_err(&i2s->pdev->dev, "Wrong BCLK Divider!\n");
379 writel(mod, priv->addr + I2SMOD);
383 static inline int get_blc(struct i2s_dai *i2s)
385 int blc = readl(i2s->priv->addr + I2SMOD);
397 static void i2s_txctrl(struct i2s_dai *i2s, int on)
399 struct samsung_i2s_priv *priv = i2s->priv;
400 void __iomem *addr = priv->addr;
401 int txr_off = priv->variant_regs->txr_off;
409 if (is_secondary(i2s)) {
417 if (any_rx_active(i2s))
422 if (is_secondary(i2s)) {
430 if (other_tx_active(i2s)) {
437 if (any_rx_active(i2s))
448 static void i2s_rxctrl(struct i2s_dai *i2s, int on)
450 struct samsung_i2s_priv *priv = i2s->priv;
451 void __iomem *addr = priv->addr;
452 int txr_off = priv->variant_regs->txr_off;
460 if (any_tx_active(i2s))
468 if (any_tx_active(i2s))
479 static inline void i2s_fifo(struct i2s_dai *i2s, u32 flush)
484 if (!i2s)
487 if (is_secondary(i2s))
488 fic = i2s->priv->addr + I2SFICS;
490 fic = i2s->priv->addr + I2SFIC;
497 while (--val)
507 struct i2s_dai *i2s = to_info(dai);
508 struct i2s_dai *other = get_other_dai(i2s);
509 const struct samsung_i2s_variant_regs *i2s_regs = priv->variant_regs;
510 unsigned int cdcon_mask = 1 << i2s_regs->cdclkcon_off;
511 unsigned int rsrc_mask = 1 << i2s_regs->rclksrc_off;
516 pm_runtime_get_sync(dai->dev);
518 spin_lock_irqsave(&priv->lock, flags);
519 mod = readl(priv->addr + I2SMOD);
520 spin_unlock_irqrestore(&priv->lock, flags);
528 mask = 1 << i2s_regs->cdclkcon_off;
533 if ((rfs && other && other->rfs && (other->rfs != rfs)) ||
534 (any_active(i2s) &&
539 dev_err(&i2s->pdev->dev,
541 ret = -EAGAIN;
546 val = 1 << i2s_regs->cdclkcon_off;
548 i2s->rfs = rfs;
553 mask = 1 << i2s_regs->rclksrc_off;
555 if ((priv->quirks & QUIRK_NO_MUXPSR)
561 if (!any_active(i2s)) {
562 if (priv->op_clk && !IS_ERR(priv->op_clk)) {
565 clk_disable_unprepare(priv->op_clk);
566 clk_put(priv->op_clk);
568 priv->rclk_srcrate =
569 clk_get_rate(priv->op_clk);
575 priv->op_clk = clk_get(&i2s->pdev->dev,
578 priv->op_clk = clk_get(&i2s->pdev->dev,
581 if (WARN_ON(IS_ERR(priv->op_clk))) {
582 ret = PTR_ERR(priv->op_clk);
583 priv->op_clk = NULL;
587 ret = clk_prepare_enable(priv->op_clk);
589 clk_put(priv->op_clk);
590 priv->op_clk = NULL;
593 priv->rclk_srcrate = clk_get_rate(priv->op_clk);
597 dev_err(&i2s->pdev->dev,
599 ret = -EAGAIN;
607 val = 1 << i2s_regs->rclksrc_off;
610 dev_err(&i2s->pdev->dev, "We don't serve that!\n");
611 ret = -EINVAL;
615 spin_lock_irqsave(&priv->lock, flags);
616 mod = readl(priv->addr + I2SMOD);
618 writel(mod, priv->addr + I2SMOD);
619 spin_unlock_irqrestore(&priv->lock, flags);
621 pm_runtime_put(dai->dev);
625 pm_runtime_put(dai->dev);
632 struct i2s_dai *i2s = to_info(dai);
637 lrp_shift = priv->variant_regs->lrp_off;
638 sdf_shift = priv->variant_regs->sdf_off;
639 mod_slave = 1 << priv->variant_regs->mss_off;
658 dev_err(&i2s->pdev->dev, "Format not supported\n");
659 return -EINVAL;
663 * INV flag is relative to the FORMAT flag - if set it simply
676 dev_err(&i2s->pdev->dev, "Polarity not supported\n");
677 return -EINVAL;
690 if (priv->rclk_srcrate == 0 && priv->clk_data.clks == NULL)
695 dev_err(&i2s->pdev->dev, "master/slave format not supported\n");
696 return -EINVAL;
699 pm_runtime_get_sync(dai->dev);
700 spin_lock_irqsave(&priv->lock, flags);
701 mod = readl(priv->addr + I2SMOD);
703 * Don't change the I2S mode if any controller is active on this
706 if (any_active(i2s) &&
708 spin_unlock_irqrestore(&priv->lock, flags);
709 pm_runtime_put(dai->dev);
710 dev_err(&i2s->pdev->dev,
712 return -EAGAIN;
717 writel(mod, priv->addr + I2SMOD);
718 priv->slave_mode = (mod & mod_slave);
719 spin_unlock_irqrestore(&priv->lock, flags);
720 pm_runtime_put(dai->dev);
729 struct i2s_dai *i2s = to_info(dai);
734 WARN_ON(!pm_runtime_active(dai->dev));
736 if (!is_secondary(i2s))
747 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
748 i2s->dma_playback.addr_width = 4;
750 i2s->dma_capture.addr_width = 4;
753 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
754 i2s->dma_playback.addr_width = 2;
756 i2s->dma_capture.addr_width = 2;
760 dev_err(&i2s->pdev->dev, "%d channels not supported\n",
762 return -EINVAL;
765 if (is_secondary(i2s))
770 if (is_manager(i2s))
775 if (is_secondary(i2s))
779 if (is_manager(i2s))
783 if (is_secondary(i2s))
787 if (is_manager(i2s))
791 if (is_secondary(i2s))
795 if (is_manager(i2s))
799 dev_err(&i2s->pdev->dev, "Format(%d) not supported\n",
801 return -EINVAL;
804 spin_lock_irqsave(&priv->lock, flags);
805 mod = readl(priv->addr + I2SMOD);
807 writel(mod, priv->addr + I2SMOD);
808 spin_unlock_irqrestore(&priv->lock, flags);
810 snd_soc_dai_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture);
812 i2s->frmclk = params_rate(params);
814 rclksrc = priv->clk_table[CLK_I2S_RCLK_SRC];
816 priv->rclk_srcrate = clk_get_rate(rclksrc);
821 /* We set constraints on the substream according to the version of I2S */
826 struct i2s_dai *i2s = to_info(dai);
827 struct i2s_dai *other = get_other_dai(i2s);
830 pm_runtime_get_sync(dai->dev);
832 spin_lock_irqsave(&priv->pcm_lock, flags);
834 i2s->mode |= DAI_OPENED;
837 i2s->mode &= ~DAI_MANAGER;
839 i2s->mode |= DAI_MANAGER;
841 if (!any_active(i2s) && (priv->quirks & QUIRK_NEED_RSTCLR))
842 writel(CON_RSTCLR, i2s->priv->addr + I2SCON);
844 spin_unlock_irqrestore(&priv->pcm_lock, flags);
853 struct i2s_dai *i2s = to_info(dai);
854 struct i2s_dai *other = get_other_dai(i2s);
857 spin_lock_irqsave(&priv->pcm_lock, flags);
859 i2s->mode &= ~DAI_OPENED;
860 i2s->mode &= ~DAI_MANAGER;
863 other->mode |= DAI_MANAGER;
866 i2s->rfs = 0;
867 i2s->bfs = 0;
869 spin_unlock_irqrestore(&priv->pcm_lock, flags);
871 pm_runtime_put(dai->dev);
874 static int config_setup(struct i2s_dai *i2s)
876 struct samsung_i2s_priv *priv = i2s->priv;
877 struct i2s_dai *other = get_other_dai(i2s);
881 blc = get_blc(i2s);
883 bfs = i2s->bfs;
886 bfs = other->bfs;
892 rfs = i2s->rfs;
895 rfs = other->rfs;
898 dev_err(&i2s->pdev->dev,
899 "%d-RFS not supported for 24-blc\n", rfs);
900 return -EINVAL;
911 if (any_active(i2s) && (get_rfs(i2s) != rfs || get_bfs(i2s) != bfs)) {
912 dev_err(&i2s->pdev->dev,
914 return -EAGAIN;
917 set_bfs(i2s, bfs);
918 set_rfs(i2s, rfs);
921 if (priv->slave_mode)
924 if (!(priv->quirks & QUIRK_NO_MUXPSR)) {
925 psr = priv->rclk_srcrate / i2s->frmclk / rfs;
926 writel(((psr - 1) << 8) | PSR_PSREN, priv->addr + I2SPSR);
927 dev_dbg(&i2s->pdev->dev,
929 priv->rclk_srcrate, psr, rfs, bfs);
939 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
941 struct i2s_dai *i2s = to_info(snd_soc_rtd_to_cpu(rtd, 0));
948 pm_runtime_get_sync(dai->dev);
950 if (priv->fixup_early)
951 priv->fixup_early(substream, dai);
953 spin_lock_irqsave(&priv->lock, flags);
955 if (config_setup(i2s)) {
956 spin_unlock_irqrestore(&priv->lock, flags);
957 return -EINVAL;
960 if (priv->fixup_late)
961 priv->fixup_late(substream, dai);
964 i2s_rxctrl(i2s, 1);
966 i2s_txctrl(i2s, 1);
968 spin_unlock_irqrestore(&priv->lock, flags);
973 spin_lock_irqsave(&priv->lock, flags);
976 i2s_rxctrl(i2s, 0);
977 i2s_fifo(i2s, FIC_RXFLUSH);
979 i2s_txctrl(i2s, 0);
980 i2s_fifo(i2s, FIC_TXFLUSH);
983 spin_unlock_irqrestore(&priv->lock, flags);
984 pm_runtime_put(dai->dev);
994 struct i2s_dai *i2s = to_info(dai);
995 struct i2s_dai *other = get_other_dai(i2s);
999 pm_runtime_get_sync(dai->dev);
1000 if ((any_active(i2s) && div && (get_bfs(i2s) != div))
1001 || (other && other->bfs && (other->bfs != div))) {
1002 pm_runtime_put(dai->dev);
1003 dev_err(&i2s->pdev->dev,
1005 return -EAGAIN;
1007 i2s->bfs = div;
1008 pm_runtime_put(dai->dev);
1011 dev_err(&i2s->pdev->dev,
1013 return -EINVAL;
1023 struct i2s_dai *i2s = to_info(dai);
1024 u32 reg = readl(priv->addr + I2SFIC);
1027 WARN_ON(!pm_runtime_active(dai->dev));
1029 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
1031 else if (is_secondary(i2s))
1032 delay = FICS_TXCOUNT(readl(priv->addr + I2SFICS));
1034 delay = (reg >> priv->variant_regs->ftx0cnt_off) & 0x7f;
1042 return pm_runtime_force_suspend(component->dev);
1047 return pm_runtime_force_resume(component->dev);
1057 struct i2s_dai *i2s = to_info(dai);
1058 struct i2s_dai *other = get_other_dai(i2s);
1061 pm_runtime_get_sync(dai->dev);
1063 if (is_secondary(i2s)) {
1065 snd_soc_dai_init_dma_data(dai, &i2s->dma_playback, NULL);
1067 snd_soc_dai_init_dma_data(dai, &i2s->dma_playback,
1068 &i2s->dma_capture);
1070 if (priv->quirks & QUIRK_NEED_RSTCLR)
1071 writel(CON_RSTCLR, priv->addr + I2SCON);
1073 if (priv->quirks & QUIRK_SUPPORTS_IDMA)
1074 idma_reg_addr_init(priv->addr,
1075 other->idma_playback.addr);
1079 i2s->rfs = 0;
1080 i2s->bfs = 0;
1082 spin_lock_irqsave(&priv->lock, flags);
1083 i2s_txctrl(i2s, 0);
1084 i2s_rxctrl(i2s, 0);
1085 i2s_fifo(i2s, FIC_TXFLUSH);
1087 i2s_fifo(i2s, FIC_RXFLUSH);
1088 spin_unlock_irqrestore(&priv->lock, flags);
1094 pm_runtime_put(dai->dev);
1102 struct i2s_dai *i2s = to_info(dai);
1105 pm_runtime_get_sync(dai->dev);
1107 if (!is_secondary(i2s)) {
1108 if (priv->quirks & QUIRK_NEED_RSTCLR) {
1109 spin_lock_irqsave(&priv->lock, flags);
1110 writel(0, priv->addr + I2SCON);
1111 spin_unlock_irqrestore(&priv->lock, flags);
1115 pm_runtime_put(dai->dev);
1151 .name = "samsung-i2s",
1172 static const char *dai_names[] = { "samsung-i2s", "samsung-i2s-sec" };
1178 priv->dai = devm_kcalloc(&priv->pdev->dev, num_dais,
1180 if (!priv->dai)
1181 return -ENOMEM;
1183 priv->dai_drv = devm_kcalloc(&priv->pdev->dev, num_dais,
1185 if (!priv->dai_drv)
1186 return -ENOMEM;
1189 dai_drv = &priv->dai_drv[i];
1191 dai_drv->symmetric_rate = 1;
1192 dai_drv->ops = &samsung_i2s_dai_ops;
1194 dai_drv->playback.channels_min = 1;
1195 dai_drv->playback.channels_max = 2;
1196 dai_drv->playback.rates = i2s_dai_data->pcm_rates;
1197 dai_drv->playback.formats = SAMSUNG_I2S_FMTS;
1198 dai_drv->playback.stream_name = stream_names[i];
1200 dai_drv->id = i + 1;
1201 dai_drv->name = dai_names[i];
1203 priv->dai[i].drv = &priv->dai_drv[i];
1204 priv->dai[i].pdev = priv->pdev;
1208 dai_drv = &priv->dai_drv[SAMSUNG_I2S_ID_PRIMARY - 1];
1210 dai_drv->capture.channels_min = 1;
1211 dai_drv->capture.channels_max = 2;
1212 dai_drv->capture.rates = i2s_dai_data->pcm_rates;
1213 dai_drv->capture.formats = SAMSUNG_I2S_FMTS;
1214 dai_drv->capture.stream_name = "Primary Capture";
1223 priv->suspend_i2smod = readl(priv->addr + I2SMOD);
1224 priv->suspend_i2scon = readl(priv->addr + I2SCON);
1225 priv->suspend_i2spsr = readl(priv->addr + I2SPSR);
1227 clk_disable_unprepare(priv->op_clk);
1228 clk_disable_unprepare(priv->clk);
1238 ret = clk_prepare_enable(priv->clk);
1242 if (priv->op_clk) {
1243 ret = clk_prepare_enable(priv->op_clk);
1245 clk_disable_unprepare(priv->clk);
1250 writel(priv->suspend_i2scon, priv->addr + I2SCON);
1251 writel(priv->suspend_i2smod, priv->addr + I2SMOD);
1252 writel(priv->suspend_i2spsr, priv->addr + I2SPSR);
1261 for (i = 0; i < priv->clk_data.clk_num; i++) {
1262 if (!IS_ERR(priv->clk_table[i]))
1263 clk_unregister(priv->clk_table[i]);
1269 of_clk_del_provider(priv->pdev->dev.of_node);
1280 struct device *dev = &priv->pdev->dev;
1281 const struct samsung_i2s_variant_regs *reg_info = priv->variant_regs;
1287 if (!of_property_present(dev->of_node, "#clock-cells"))
1303 return -ENOMEM;
1306 if (!(priv->quirks & QUIRK_NO_MUXPSR)) {
1308 u32 val = readl(priv->addr + I2SPSR);
1309 writel(val | PSR_PSREN, priv->addr + I2SPSR);
1311 priv->clk_table[CLK_I2S_RCLK_SRC] = clk_register_mux(dev,
1315 priv->addr + I2SMOD, reg_info->rclksrc_off,
1316 1, 0, &priv->lock);
1318 priv->clk_table[CLK_I2S_RCLK_PSR] = clk_register_divider(dev,
1322 priv->addr + I2SPSR, 8, 6, 0, &priv->lock);
1325 priv->clk_data.clk_num = 2;
1328 priv->clk_table[CLK_I2S_CDCLK] = clk_register_gate(dev,
1331 priv->addr + I2SMOD, reg_info->cdclkcon_off,
1332 CLK_GATE_SET_TO_DISABLE, &priv->lock);
1334 priv->clk_data.clk_num += 1;
1335 priv->clk_data.clks = priv->clk_table;
1337 ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
1338 &priv->clk_data);
1354 devname = devm_kasprintf(&priv->pdev->dev, GFP_KERNEL, "%s-sec",
1355 dev_name(&priv->pdev->dev));
1357 return -ENOMEM;
1359 pdev_sec = platform_device_alloc(devname, -1);
1361 return -ENOMEM;
1363 pdev_sec->driver_override = kstrdup("samsung-i2s", GFP_KERNEL);
1364 if (!pdev_sec->driver_override) {
1366 return -ENOMEM;
1375 ret = device_attach(&pdev_sec->dev);
1377 platform_device_unregister(priv->pdev_sec);
1378 dev_info(&pdev_sec->dev, "device_attach() failed\n");
1382 priv->pdev_sec = pdev_sec;
1389 platform_device_unregister(priv->pdev_sec);
1390 priv->pdev_sec = NULL;
1396 struct s3c_audio_pdata *i2s_pdata = pdev->dev.platform_data;
1398 struct device_node *np = pdev->dev.of_node;
1405 if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
1406 i2s_dai_data = of_device_get_match_data(&pdev->dev);
1414 i2s_dai_data = (struct samsung_i2s_dai_data *)id->driver_data;
1417 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
1419 return -ENOMEM;
1422 priv->quirks = i2s_dai_data->quirks;
1423 priv->fixup_early = i2s_dai_data->fixup_early;
1424 priv->fixup_late = i2s_dai_data->fixup_late;
1427 dev_err(&pdev->dev, "Missing platform data\n");
1428 return -EINVAL;
1430 priv->quirks = i2s_pdata->type.quirks;
1433 num_dais = (priv->quirks & QUIRK_SEC_DAI) ? 2 : 1;
1434 priv->pdev = pdev;
1435 priv->variant_regs = i2s_dai_data->i2s_variant_regs;
1441 pri_dai = &priv->dai[SAMSUNG_I2S_ID_PRIMARY - 1];
1443 spin_lock_init(&priv->lock);
1444 spin_lock_init(&priv->pcm_lock);
1447 pri_dai->dma_playback.filter_data = i2s_pdata->dma_playback;
1448 pri_dai->dma_capture.filter_data = i2s_pdata->dma_capture;
1449 pri_dai->filter = i2s_pdata->dma_filter;
1451 idma_addr = i2s_pdata->type.idma_addr;
1453 if (of_property_read_u32(np, "samsung,idma-addr",
1455 if (priv->quirks & QUIRK_SUPPORTS_IDMA) {
1456 dev_info(&pdev->dev, "idma address is not"\
1462 priv->addr = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
1463 if (IS_ERR(priv->addr))
1464 return PTR_ERR(priv->addr);
1466 regs_base = res->start;
1468 priv->clk = devm_clk_get(&pdev->dev, "iis");
1469 if (IS_ERR(priv->clk)) {
1470 dev_err(&pdev->dev, "Failed to get iis clock\n");
1471 return PTR_ERR(priv->clk);
1474 ret = clk_prepare_enable(priv->clk);
1476 dev_err(&pdev->dev, "failed to enable clock: %d\n", ret);
1479 pri_dai->dma_playback.addr = regs_base + I2STXD;
1480 pri_dai->dma_capture.addr = regs_base + I2SRXD;
1481 pri_dai->dma_playback.chan_name = "tx";
1482 pri_dai->dma_capture.chan_name = "rx";
1483 pri_dai->dma_playback.addr_width = 4;
1484 pri_dai->dma_capture.addr_width = 4;
1485 pri_dai->priv = priv;
1487 if (priv->quirks & QUIRK_PRI_6CHAN)
1488 pri_dai->drv->playback.channels_max = 6;
1490 ret = samsung_asoc_dma_platform_register(&pdev->dev, pri_dai->filter,
1495 if (priv->quirks & QUIRK_SEC_DAI) {
1496 sec_dai = &priv->dai[SAMSUNG_I2S_ID_SECONDARY - 1];
1498 sec_dai->dma_playback.addr = regs_base + I2STXDS;
1499 sec_dai->dma_playback.chan_name = "tx-sec";
1502 sec_dai->dma_playback.filter_data = i2s_pdata->dma_play_sec;
1503 sec_dai->filter = i2s_pdata->dma_filter;
1506 sec_dai->dma_playback.addr_width = 4;
1507 sec_dai->idma_playback.addr = idma_addr;
1508 sec_dai->pri_dai = pri_dai;
1509 sec_dai->priv = priv;
1510 pri_dai->sec_dai = sec_dai;
1516 ret = samsung_asoc_dma_platform_register(&priv->pdev_sec->dev,
1517 sec_dai->filter, "tx-sec", NULL,
1518 &pdev->dev);
1524 if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
1525 dev_err(&pdev->dev, "Unable to configure gpio\n");
1526 ret = -EINVAL;
1530 dev_set_drvdata(&pdev->dev, priv);
1532 ret = devm_snd_soc_register_component(&pdev->dev,
1534 priv->dai_drv, num_dais);
1538 pm_runtime_set_active(&pdev->dev);
1539 pm_runtime_enable(&pdev->dev);
1545 priv->op_clk = clk_get_parent(priv->clk_table[CLK_I2S_RCLK_SRC]);
1550 pm_runtime_disable(&pdev->dev);
1554 clk_disable_unprepare(priv->clk);
1560 struct samsung_i2s_priv *priv = dev_get_drvdata(&pdev->dev);
1566 pm_runtime_get_sync(&pdev->dev);
1567 pm_runtime_disable(&pdev->dev);
1571 clk_disable_unprepare(priv->clk);
1573 pm_runtime_put_noidle(&pdev->dev);
1580 struct i2s_dai *i2s = to_info(snd_soc_rtd_to_cpu(rtd, 0));
1581 struct i2s_dai *other = get_other_dai(i2s);
1594 struct i2s_dai *i2s = to_info(snd_soc_rtd_to_cpu(rtd, 0));
1595 struct i2s_dai *other = get_other_dai(i2s);
1598 writel(PSR_PSVAL(2) | PSR_PSREN, priv->addr + I2SPSR);
1700 .name = "samsung-i2s",
1710 .compatible = "samsung,s3c6410-i2s",
1713 .compatible = "samsung,s5pv210-i2s",
1716 .compatible = "samsung,exynos5420-i2s",
1719 .compatible = "samsung,exynos7-i2s",
1722 .compatible = "samsung,exynos7-i2s1",
1725 .compatible = "tesla,fsd-i2s",
1743 .name = "samsung-i2s",
1753 MODULE_DESCRIPTION("Samsung I2S Interface");