Lines Matching +full:i2s +full:- +full:input
1 // SPDX-License-Identifier: GPL-2.0-only
3 * IMG I2S input controller driver
67 struct img_i2s_in *i2s = dev_get_drvdata(dev); in img_i2s_in_runtime_suspend() local
69 clk_disable_unprepare(i2s->clk_sys); in img_i2s_in_runtime_suspend()
76 struct img_i2s_in *i2s = dev_get_drvdata(dev); in img_i2s_in_runtime_resume() local
79 ret = clk_prepare_enable(i2s->clk_sys); in img_i2s_in_runtime_resume()
88 static inline void img_i2s_in_writel(struct img_i2s_in *i2s, u32 val, u32 reg) in img_i2s_in_writel() argument
90 writel(val, i2s->base + reg); in img_i2s_in_writel()
93 static inline u32 img_i2s_in_readl(struct img_i2s_in *i2s, u32 reg) in img_i2s_in_readl() argument
95 return readl(i2s->base + reg); in img_i2s_in_readl()
98 static inline void img_i2s_in_ch_writel(struct img_i2s_in *i2s, u32 chan, in img_i2s_in_ch_writel() argument
101 writel(val, i2s->channel_base + (chan * IMG_I2S_IN_CH_STRIDE) + reg); in img_i2s_in_ch_writel()
104 static inline u32 img_i2s_in_ch_readl(struct img_i2s_in *i2s, u32 chan, in img_i2s_in_ch_readl() argument
107 return readl(i2s->channel_base + (chan * IMG_I2S_IN_CH_STRIDE) + reg); in img_i2s_in_ch_readl()
110 static inline void img_i2s_in_ch_disable(struct img_i2s_in *i2s, u32 chan) in img_i2s_in_ch_disable() argument
114 reg = img_i2s_in_ch_readl(i2s, chan, IMG_I2S_IN_CH_CTL); in img_i2s_in_ch_disable()
116 img_i2s_in_ch_writel(i2s, chan, reg, IMG_I2S_IN_CH_CTL); in img_i2s_in_ch_disable()
119 static inline void img_i2s_in_ch_enable(struct img_i2s_in *i2s, u32 chan) in img_i2s_in_ch_enable() argument
123 reg = img_i2s_in_ch_readl(i2s, chan, IMG_I2S_IN_CH_CTL); in img_i2s_in_ch_enable()
125 img_i2s_in_ch_writel(i2s, chan, reg, IMG_I2S_IN_CH_CTL); in img_i2s_in_ch_enable()
128 static inline void img_i2s_in_disable(struct img_i2s_in *i2s) in img_i2s_in_disable() argument
132 reg = img_i2s_in_readl(i2s, IMG_I2S_IN_CTL); in img_i2s_in_disable()
134 img_i2s_in_writel(i2s, reg, IMG_I2S_IN_CTL); in img_i2s_in_disable()
137 static inline void img_i2s_in_enable(struct img_i2s_in *i2s) in img_i2s_in_enable() argument
141 reg = img_i2s_in_readl(i2s, IMG_I2S_IN_CTL); in img_i2s_in_enable()
143 img_i2s_in_writel(i2s, reg, IMG_I2S_IN_CTL); in img_i2s_in_enable()
146 static inline void img_i2s_in_flush(struct img_i2s_in *i2s) in img_i2s_in_flush() argument
151 for (i = 0; i < i2s->active_channels; i++) { in img_i2s_in_flush()
152 reg = img_i2s_in_ch_readl(i2s, i, IMG_I2S_IN_CH_CTL); in img_i2s_in_flush()
154 img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL); in img_i2s_in_flush()
156 img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL); in img_i2s_in_flush()
163 struct img_i2s_in *i2s = snd_soc_dai_get_drvdata(dai); in img_i2s_in_trigger() local
169 img_i2s_in_enable(i2s); in img_i2s_in_trigger()
175 img_i2s_in_disable(i2s); in img_i2s_in_trigger()
178 return -EINVAL; in img_i2s_in_trigger()
184 static int img_i2s_in_check_rate(struct img_i2s_in *i2s, in img_i2s_in_check_rate() argument
193 cur_freq = clk_get_rate(i2s->clk_sys); in img_i2s_in_check_rate()
205 dev_err(i2s->dev, in img_i2s_in_check_rate()
208 return -EINVAL; in img_i2s_in_check_rate()
217 struct img_i2s_in *i2s = snd_soc_dai_get_drvdata(dai); in img_i2s_in_hw_params() local
248 return -EINVAL; in img_i2s_in_hw_params()
252 (channels > (i2s->max_i2s_chan * 2)) || in img_i2s_in_hw_params()
254 return -EINVAL; in img_i2s_in_hw_params()
256 control_set |= ((i2s_channels - 1) << IMG_I2S_IN_CTL_ACTIVE_CH_SHIFT); in img_i2s_in_hw_params()
258 ret = img_i2s_in_check_rate(i2s, rate, frame_size, in img_i2s_in_hw_params()
279 reg = img_i2s_in_readl(i2s, IMG_I2S_IN_CTL); in img_i2s_in_hw_params()
281 img_i2s_in_writel(i2s, reg, IMG_I2S_IN_CTL); in img_i2s_in_hw_params()
283 for (i = 0; i < i2s->active_channels; i++) in img_i2s_in_hw_params()
284 img_i2s_in_ch_disable(i2s, i); in img_i2s_in_hw_params()
286 for (i = 0; i < i2s->max_i2s_chan; i++) { in img_i2s_in_hw_params()
287 reg = img_i2s_in_ch_readl(i2s, i, IMG_I2S_IN_CH_CTL); in img_i2s_in_hw_params()
289 img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL); in img_i2s_in_hw_params()
292 i2s->active_channels = i2s_channels; in img_i2s_in_hw_params()
294 img_i2s_in_flush(i2s); in img_i2s_in_hw_params()
296 for (i = 0; i < i2s->active_channels; i++) in img_i2s_in_hw_params()
297 img_i2s_in_ch_enable(i2s, i); in img_i2s_in_hw_params()
304 struct img_i2s_in *i2s = snd_soc_dai_get_drvdata(dai); in img_i2s_in_set_fmt() local
323 return -EINVAL; in img_i2s_in_set_fmt()
333 return -EINVAL; in img_i2s_in_set_fmt()
340 return -EINVAL; in img_i2s_in_set_fmt()
345 ret = pm_runtime_resume_and_get(i2s->dev); in img_i2s_in_set_fmt()
349 for (i = 0; i < i2s->active_channels; i++) in img_i2s_in_set_fmt()
350 img_i2s_in_ch_disable(i2s, i); in img_i2s_in_set_fmt()
355 for (i = 0; i < i2s->max_i2s_chan; i++) { in img_i2s_in_set_fmt()
356 reg = img_i2s_in_ch_readl(i2s, i, IMG_I2S_IN_CH_CTL); in img_i2s_in_set_fmt()
358 img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL); in img_i2s_in_set_fmt()
360 img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL); in img_i2s_in_set_fmt()
362 img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL); in img_i2s_in_set_fmt()
365 for (i = 0; i < i2s->active_channels; i++) in img_i2s_in_set_fmt()
366 img_i2s_in_ch_enable(i2s, i); in img_i2s_in_set_fmt()
368 pm_runtime_put(i2s->dev); in img_i2s_in_set_fmt()
375 struct img_i2s_in *i2s = snd_soc_dai_get_drvdata(dai); in img_i2s_in_dai_probe() local
377 snd_soc_dai_init_dma_data(dai, NULL, &i2s->dma_data); in img_i2s_in_dai_probe()
390 .name = "img-i2s-in",
408 sc->src_addr = dma_data->addr; in img_i2s_in_dma_prepare_slave_config()
409 sc->src_addr_width = dma_data->addr_width; in img_i2s_in_dma_prepare_slave_config()
410 sc->src_maxburst = 4 * i2s_channels; in img_i2s_in_dma_prepare_slave_config()
421 struct img_i2s_in *i2s; in img_i2s_in_probe() local
427 struct device *dev = &pdev->dev; in img_i2s_in_probe()
429 i2s = devm_kzalloc(dev, sizeof(*i2s), GFP_KERNEL); in img_i2s_in_probe()
430 if (!i2s) in img_i2s_in_probe()
431 return -ENOMEM; in img_i2s_in_probe()
433 platform_set_drvdata(pdev, i2s); in img_i2s_in_probe()
435 i2s->dev = dev; in img_i2s_in_probe()
441 i2s->base = base; in img_i2s_in_probe()
443 if (of_property_read_u32(pdev->dev.of_node, "img,i2s-channels", in img_i2s_in_probe()
444 &i2s->max_i2s_chan)) { in img_i2s_in_probe()
445 dev_err(dev, "No img,i2s-channels property\n"); in img_i2s_in_probe()
446 return -EINVAL; in img_i2s_in_probe()
449 max_i2s_chan_pow_2 = 1 << get_count_order(i2s->max_i2s_chan); in img_i2s_in_probe()
451 i2s->channel_base = base + (max_i2s_chan_pow_2 * 0x20); in img_i2s_in_probe()
453 i2s->clk_sys = devm_clk_get(dev, "sys"); in img_i2s_in_probe()
454 if (IS_ERR(i2s->clk_sys)) in img_i2s_in_probe()
455 return dev_err_probe(dev, PTR_ERR(i2s->clk_sys), in img_i2s_in_probe()
458 pm_runtime_enable(&pdev->dev); in img_i2s_in_probe()
459 if (!pm_runtime_enabled(&pdev->dev)) { in img_i2s_in_probe()
460 ret = img_i2s_in_runtime_resume(&pdev->dev); in img_i2s_in_probe()
464 ret = pm_runtime_resume_and_get(&pdev->dev); in img_i2s_in_probe()
468 i2s->active_channels = 1; in img_i2s_in_probe()
469 i2s->dma_data.addr = res->start + IMG_I2S_IN_RX_FIFO; in img_i2s_in_probe()
470 i2s->dma_data.addr_width = 4; in img_i2s_in_probe()
472 i2s->dai_driver.capture.channels_min = 2; in img_i2s_in_probe()
473 i2s->dai_driver.capture.channels_max = i2s->max_i2s_chan * 2; in img_i2s_in_probe()
474 i2s->dai_driver.capture.rates = SNDRV_PCM_RATE_8000_192000; in img_i2s_in_probe()
475 i2s->dai_driver.capture.formats = SNDRV_PCM_FMTBIT_S32_LE | in img_i2s_in_probe()
477 i2s->dai_driver.ops = &img_i2s_in_dai_ops; in img_i2s_in_probe()
481 if (PTR_ERR(rst) == -EPROBE_DEFER) { in img_i2s_in_probe()
482 ret = -EPROBE_DEFER; in img_i2s_in_probe()
483 pm_runtime_put(&pdev->dev); in img_i2s_in_probe()
489 img_i2s_in_disable(i2s); in img_i2s_in_probe()
491 for (i = 0; i < i2s->max_i2s_chan; i++) in img_i2s_in_probe()
492 img_i2s_in_ch_disable(i2s, i); in img_i2s_in_probe()
498 img_i2s_in_writel(i2s, 0, IMG_I2S_IN_CTL); in img_i2s_in_probe()
500 for (i = 0; i < i2s->max_i2s_chan; i++) in img_i2s_in_probe()
501 img_i2s_in_ch_writel(i2s, i, in img_i2s_in_probe()
506 pm_runtime_put(&pdev->dev); in img_i2s_in_probe()
508 i2s->suspend_ch_ctl = devm_kcalloc(dev, in img_i2s_in_probe()
509 i2s->max_i2s_chan, sizeof(*i2s->suspend_ch_ctl), GFP_KERNEL); in img_i2s_in_probe()
510 if (!i2s->suspend_ch_ctl) { in img_i2s_in_probe()
511 ret = -ENOMEM; in img_i2s_in_probe()
516 &i2s->dai_driver, 1); in img_i2s_in_probe()
527 if (!pm_runtime_enabled(&pdev->dev)) in img_i2s_in_probe()
528 img_i2s_in_runtime_suspend(&pdev->dev); in img_i2s_in_probe()
530 pm_runtime_disable(&pdev->dev); in img_i2s_in_probe()
537 pm_runtime_disable(&pdev->dev); in img_i2s_in_dev_remove()
538 if (!pm_runtime_status_suspended(&pdev->dev)) in img_i2s_in_dev_remove()
539 img_i2s_in_runtime_suspend(&pdev->dev); in img_i2s_in_dev_remove()
545 struct img_i2s_in *i2s = dev_get_drvdata(dev); in img_i2s_in_suspend() local
555 for (i = 0; i < i2s->max_i2s_chan; i++) { in img_i2s_in_suspend()
556 reg = img_i2s_in_ch_readl(i2s, i, IMG_I2S_IN_CH_CTL); in img_i2s_in_suspend()
557 i2s->suspend_ch_ctl[i] = reg; in img_i2s_in_suspend()
560 i2s->suspend_ctl = img_i2s_in_readl(i2s, IMG_I2S_IN_CTL); in img_i2s_in_suspend()
569 struct img_i2s_in *i2s = dev_get_drvdata(dev); in img_i2s_in_resume() local
577 for (i = 0; i < i2s->max_i2s_chan; i++) { in img_i2s_in_resume()
578 reg = i2s->suspend_ch_ctl[i]; in img_i2s_in_resume()
579 img_i2s_in_ch_writel(i2s, i, reg, IMG_I2S_IN_CH_CTL); in img_i2s_in_resume()
582 img_i2s_in_writel(i2s, i2s->suspend_ctl, IMG_I2S_IN_CTL); in img_i2s_in_resume()
592 { .compatible = "img,i2s-in" },
605 .name = "img-i2s-in",
615 MODULE_DESCRIPTION("IMG I2S Input Driver");