Lines Matching +full:tegra210 +full:- +full:admaif
1 // SPDX-License-Identifier: GPL-2.0-only
3 // tegra210_admaif.c - Tegra ADMAIF driver
23 #define CH_TX_REG(reg, id) CH_REG(admaif->soc_data->tx_base, reg, id)
25 #define CH_RX_REG(reg, id) CH_REG(admaif->soc_data->rx_base, reg, id)
36 REG_DEFAULTS((id) - 1, \
68 ADMAIF_REG_DEFAULTS(1, TEGRA210),
69 ADMAIF_REG_DEFAULTS(2, TEGRA210),
70 ADMAIF_REG_DEFAULTS(3, TEGRA210),
71 ADMAIF_REG_DEFAULTS(4, TEGRA210),
72 ADMAIF_REG_DEFAULTS(5, TEGRA210),
73 ADMAIF_REG_DEFAULTS(6, TEGRA210),
74 ADMAIF_REG_DEFAULTS(7, TEGRA210),
75 ADMAIF_REG_DEFAULTS(8, TEGRA210),
76 ADMAIF_REG_DEFAULTS(9, TEGRA210),
77 ADMAIF_REG_DEFAULTS(10, TEGRA210)
82 struct tegra_admaif *admaif = dev_get_drvdata(dev); in tegra_admaif_wr_reg() local
84 unsigned int num_ch = admaif->soc_data->num_ch; in tegra_admaif_wr_reg()
85 unsigned int rx_base = admaif->soc_data->rx_base; in tegra_admaif_wr_reg()
86 unsigned int tx_base = admaif->soc_data->tx_base; in tegra_admaif_wr_reg()
87 unsigned int global_base = admaif->soc_data->global_base; in tegra_admaif_wr_reg()
88 unsigned int reg_max = admaif->soc_data->regmap_conf->max_register; in tegra_admaif_wr_reg()
93 reg = (reg - rx_base) % ch_stride; in tegra_admaif_wr_reg()
100 reg = (reg - tx_base) % ch_stride; in tegra_admaif_wr_reg()
116 struct tegra_admaif *admaif = dev_get_drvdata(dev); in tegra_admaif_rd_reg() local
118 unsigned int num_ch = admaif->soc_data->num_ch; in tegra_admaif_rd_reg()
119 unsigned int rx_base = admaif->soc_data->rx_base; in tegra_admaif_rd_reg()
120 unsigned int tx_base = admaif->soc_data->tx_base; in tegra_admaif_rd_reg()
121 unsigned int global_base = admaif->soc_data->global_base; in tegra_admaif_rd_reg()
122 unsigned int reg_max = admaif->soc_data->regmap_conf->max_register; in tegra_admaif_rd_reg()
127 reg = (reg - rx_base) % ch_stride; in tegra_admaif_rd_reg()
136 reg = (reg - tx_base) % ch_stride; in tegra_admaif_rd_reg()
160 struct tegra_admaif *admaif = dev_get_drvdata(dev); in tegra_admaif_volatile_reg() local
162 unsigned int num_ch = admaif->soc_data->num_ch; in tegra_admaif_volatile_reg()
163 unsigned int rx_base = admaif->soc_data->rx_base; in tegra_admaif_volatile_reg()
164 unsigned int tx_base = admaif->soc_data->tx_base; in tegra_admaif_volatile_reg()
165 unsigned int global_base = admaif->soc_data->global_base; in tegra_admaif_volatile_reg()
166 unsigned int reg_max = admaif->soc_data->regmap_conf->max_register; in tegra_admaif_volatile_reg()
171 reg = (reg - rx_base) % ch_stride; in tegra_admaif_volatile_reg()
178 reg = (reg - tx_base) % ch_stride; in tegra_admaif_volatile_reg()
224 struct tegra_admaif *admaif = dev_get_drvdata(dev); in tegra_admaif_runtime_suspend() local
226 regcache_cache_only(admaif->regmap, true); in tegra_admaif_runtime_suspend()
227 regcache_mark_dirty(admaif->regmap); in tegra_admaif_runtime_suspend()
234 struct tegra_admaif *admaif = dev_get_drvdata(dev); in tegra_admaif_runtime_resume() local
236 regcache_cache_only(admaif->regmap, false); in tegra_admaif_runtime_resume()
237 regcache_sync(admaif->regmap); in tegra_admaif_runtime_resume()
259 return -EINVAL; in tegra_admaif_set_pack_mode()
269 struct device *dev = dai->dev; in tegra_admaif_hw_params()
270 struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai); in tegra_admaif_hw_params() local
295 return -EOPNOTSUPP; in tegra_admaif_hw_params()
302 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in tegra_admaif_hw_params()
304 reg = CH_TX_REG(TEGRA_ADMAIF_CH_ACIF_TX_CTRL, dai->id); in tegra_admaif_hw_params()
307 reg = CH_RX_REG(TEGRA_ADMAIF_CH_ACIF_RX_CTRL, dai->id); in tegra_admaif_hw_params()
310 cif_conf.mono_conv = admaif->mono_to_stereo[path][dai->id]; in tegra_admaif_hw_params()
311 cif_conf.stereo_conv = admaif->stereo_to_mono[path][dai->id]; in tegra_admaif_hw_params()
313 tegra_admaif_set_pack_mode(admaif->regmap, reg, valid_bit); in tegra_admaif_hw_params()
315 tegra_set_cif(admaif->regmap, reg, &cif_conf); in tegra_admaif_hw_params()
322 struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai); in tegra_admaif_start() local
329 reg = CH_TX_REG(TEGRA_ADMAIF_TX_ENABLE, dai->id); in tegra_admaif_start()
334 reg = CH_RX_REG(TEGRA_ADMAIF_RX_ENABLE, dai->id); in tegra_admaif_start()
337 return -EINVAL; in tegra_admaif_start()
340 regmap_update_bits(admaif->regmap, reg, mask, val); in tegra_admaif_start()
347 struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai); in tegra_admaif_stop() local
357 enable_reg = CH_TX_REG(TEGRA_ADMAIF_TX_ENABLE, dai->id); in tegra_admaif_stop()
358 status_reg = CH_TX_REG(TEGRA_ADMAIF_TX_STATUS, dai->id); in tegra_admaif_stop()
359 reset_reg = CH_TX_REG(TEGRA_ADMAIF_TX_SOFT_RESET, dai->id); in tegra_admaif_stop()
365 enable_reg = CH_RX_REG(TEGRA_ADMAIF_RX_ENABLE, dai->id); in tegra_admaif_stop()
366 status_reg = CH_RX_REG(TEGRA_ADMAIF_RX_STATUS, dai->id); in tegra_admaif_stop()
367 reset_reg = CH_RX_REG(TEGRA_ADMAIF_RX_SOFT_RESET, dai->id); in tegra_admaif_stop()
370 return -EINVAL; in tegra_admaif_stop()
374 regmap_update_bits(admaif->regmap, enable_reg, mask, ~enable); in tegra_admaif_stop()
376 /* Wait until ADMAIF TX/RX status is disabled */ in tegra_admaif_stop()
377 err = regmap_read_poll_timeout_atomic(admaif->regmap, status_reg, val, in tegra_admaif_stop()
380 dev_warn(dai->dev, "timeout: failed to disable ADMAIF%d_%s\n", in tegra_admaif_stop()
381 dai->id + 1, dir_name); in tegra_admaif_stop()
384 regmap_update_bits(admaif->regmap, reset_reg, SW_RESET_MASK, SW_RESET); in tegra_admaif_stop()
387 err = regmap_read_poll_timeout_atomic(admaif->regmap, reset_reg, val, in tegra_admaif_stop()
391 dev_err(dai->dev, "timeout: SW reset failed for ADMAIF%d_%s\n", in tegra_admaif_stop()
392 dai->id + 1, dir_name); in tegra_admaif_stop()
412 return tegra_admaif_start(dai, substream->stream); in tegra_admaif_trigger()
416 return tegra_admaif_stop(dai, substream->stream); in tegra_admaif_trigger()
418 return -EINVAL; in tegra_admaif_trigger()
426 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); in tegra210_admaif_pget_mono_to_stereo() local
427 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; in tegra210_admaif_pget_mono_to_stereo()
429 ucontrol->value.enumerated.item[0] = in tegra210_admaif_pget_mono_to_stereo()
430 admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg]; in tegra210_admaif_pget_mono_to_stereo()
439 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); in tegra210_admaif_pput_mono_to_stereo() local
440 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; in tegra210_admaif_pput_mono_to_stereo()
441 unsigned int value = ucontrol->value.enumerated.item[0]; in tegra210_admaif_pput_mono_to_stereo()
443 if (value == admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg]) in tegra210_admaif_pput_mono_to_stereo()
446 admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value; in tegra210_admaif_pput_mono_to_stereo()
455 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); in tegra210_admaif_cget_mono_to_stereo() local
456 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; in tegra210_admaif_cget_mono_to_stereo()
458 ucontrol->value.enumerated.item[0] = in tegra210_admaif_cget_mono_to_stereo()
459 admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg]; in tegra210_admaif_cget_mono_to_stereo()
468 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); in tegra210_admaif_cput_mono_to_stereo() local
469 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; in tegra210_admaif_cput_mono_to_stereo()
470 unsigned int value = ucontrol->value.enumerated.item[0]; in tegra210_admaif_cput_mono_to_stereo()
472 if (value == admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg]) in tegra210_admaif_cput_mono_to_stereo()
475 admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value; in tegra210_admaif_cput_mono_to_stereo()
484 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); in tegra210_admaif_pget_stereo_to_mono() local
485 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; in tegra210_admaif_pget_stereo_to_mono()
487 ucontrol->value.enumerated.item[0] = in tegra210_admaif_pget_stereo_to_mono()
488 admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg]; in tegra210_admaif_pget_stereo_to_mono()
497 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); in tegra210_admaif_pput_stereo_to_mono() local
498 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; in tegra210_admaif_pput_stereo_to_mono()
499 unsigned int value = ucontrol->value.enumerated.item[0]; in tegra210_admaif_pput_stereo_to_mono()
501 if (value == admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg]) in tegra210_admaif_pput_stereo_to_mono()
504 admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value; in tegra210_admaif_pput_stereo_to_mono()
513 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); in tegra210_admaif_cget_stereo_to_mono() local
514 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; in tegra210_admaif_cget_stereo_to_mono()
516 ucontrol->value.enumerated.item[0] = in tegra210_admaif_cget_stereo_to_mono()
517 admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg]; in tegra210_admaif_cget_stereo_to_mono()
526 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); in tegra210_admaif_cput_stereo_to_mono() local
527 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; in tegra210_admaif_cput_stereo_to_mono()
528 unsigned int value = ucontrol->value.enumerated.item[0]; in tegra210_admaif_cput_stereo_to_mono()
530 if (value == admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg]) in tegra210_admaif_cput_stereo_to_mono()
533 admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value; in tegra210_admaif_cput_stereo_to_mono()
540 struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai); in tegra_admaif_dai_probe() local
542 snd_soc_dai_init_dma_data(dai, &admaif->playback_dma_data[dai->id], in tegra_admaif_dai_probe()
543 &admaif->capture_dma_data[dai->id]); in tegra_admaif_dai_probe()
638 NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Mono To Stereo", reg - 1, \
642 NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Stereo To Mono", reg - 1, \
646 NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Mono To Stereo", reg - 1, \
650 NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Stereo To Mono", reg - 1, \
732 { .compatible = "nvidia,tegra210-admaif", .data = &soc_data_tegra210 },
733 { .compatible = "nvidia,tegra186-admaif", .data = &soc_data_tegra186 },
740 struct tegra_admaif *admaif; in tegra_admaif_probe() local
745 admaif = devm_kzalloc(&pdev->dev, sizeof(*admaif), GFP_KERNEL); in tegra_admaif_probe()
746 if (!admaif) in tegra_admaif_probe()
747 return -ENOMEM; in tegra_admaif_probe()
749 admaif->soc_data = of_device_get_match_data(&pdev->dev); in tegra_admaif_probe()
751 dev_set_drvdata(&pdev->dev, admaif); in tegra_admaif_probe()
753 admaif->capture_dma_data = in tegra_admaif_probe()
754 devm_kcalloc(&pdev->dev, in tegra_admaif_probe()
755 admaif->soc_data->num_ch, in tegra_admaif_probe()
758 if (!admaif->capture_dma_data) in tegra_admaif_probe()
759 return -ENOMEM; in tegra_admaif_probe()
761 admaif->playback_dma_data = in tegra_admaif_probe()
762 devm_kcalloc(&pdev->dev, in tegra_admaif_probe()
763 admaif->soc_data->num_ch, in tegra_admaif_probe()
766 if (!admaif->playback_dma_data) in tegra_admaif_probe()
767 return -ENOMEM; in tegra_admaif_probe()
770 admaif->mono_to_stereo[i] = in tegra_admaif_probe()
771 devm_kcalloc(&pdev->dev, admaif->soc_data->num_ch, in tegra_admaif_probe()
773 if (!admaif->mono_to_stereo[i]) in tegra_admaif_probe()
774 return -ENOMEM; in tegra_admaif_probe()
776 admaif->stereo_to_mono[i] = in tegra_admaif_probe()
777 devm_kcalloc(&pdev->dev, admaif->soc_data->num_ch, in tegra_admaif_probe()
779 if (!admaif->stereo_to_mono[i]) in tegra_admaif_probe()
780 return -ENOMEM; in tegra_admaif_probe()
787 admaif->regmap = devm_regmap_init_mmio(&pdev->dev, regs, in tegra_admaif_probe()
788 admaif->soc_data->regmap_conf); in tegra_admaif_probe()
789 if (IS_ERR(admaif->regmap)) { in tegra_admaif_probe()
790 dev_err(&pdev->dev, "regmap init failed\n"); in tegra_admaif_probe()
791 return PTR_ERR(admaif->regmap); in tegra_admaif_probe()
794 regcache_cache_only(admaif->regmap, true); in tegra_admaif_probe()
796 regmap_update_bits(admaif->regmap, admaif->soc_data->global_base + in tegra_admaif_probe()
799 for (i = 0; i < admaif->soc_data->num_ch; i++) { in tegra_admaif_probe()
800 admaif->playback_dma_data[i].addr = res->start + in tegra_admaif_probe()
803 admaif->capture_dma_data[i].addr = res->start + in tegra_admaif_probe()
806 admaif->playback_dma_data[i].addr_width = 32; in tegra_admaif_probe()
808 if (of_property_read_string_index(pdev->dev.of_node, in tegra_admaif_probe()
809 "dma-names", (i * 2) + 1, in tegra_admaif_probe()
810 &admaif->playback_dma_data[i].chan_name) < 0) { in tegra_admaif_probe()
811 dev_err(&pdev->dev, in tegra_admaif_probe()
812 "missing property nvidia,dma-names\n"); in tegra_admaif_probe()
814 return -ENODEV; in tegra_admaif_probe()
817 admaif->capture_dma_data[i].addr_width = 32; in tegra_admaif_probe()
819 if (of_property_read_string_index(pdev->dev.of_node, in tegra_admaif_probe()
820 "dma-names", in tegra_admaif_probe()
822 &admaif->capture_dma_data[i].chan_name) < 0) { in tegra_admaif_probe()
823 dev_err(&pdev->dev, in tegra_admaif_probe()
824 "missing property nvidia,dma-names\n"); in tegra_admaif_probe()
826 return -ENODEV; in tegra_admaif_probe()
830 err = devm_snd_soc_register_component(&pdev->dev, in tegra_admaif_probe()
831 admaif->soc_data->cmpnt, in tegra_admaif_probe()
832 admaif->soc_data->dais, in tegra_admaif_probe()
833 admaif->soc_data->num_ch); in tegra_admaif_probe()
835 dev_err(&pdev->dev, in tegra_admaif_probe()
836 "can't register ADMAIF component, err: %d\n", err); in tegra_admaif_probe()
840 pm_runtime_enable(&pdev->dev); in tegra_admaif_probe()
847 pm_runtime_disable(&pdev->dev); in tegra_admaif_remove()
861 .name = "tegra210-admaif",
869 MODULE_DESCRIPTION("Tegra210 ASoC ADMAIF driver");