Lines Matching +full:i2s +full:- +full:regs

1 // SPDX-License-Identifier: GPL-2.0-only
3 * tegra30_i2s.c - Tegra30 I2S driver
6 * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved.
10 * Copyright (c) 2009-2010, NVIDIA Corporation.
37 #define DRV_NAME "tegra30-i2s"
41 struct tegra30_i2s *i2s = dev_get_drvdata(dev); in tegra30_i2s_runtime_suspend() local
43 regcache_cache_only(i2s->regmap, true); in tegra30_i2s_runtime_suspend()
45 clk_disable_unprepare(i2s->clk_i2s); in tegra30_i2s_runtime_suspend()
52 struct tegra30_i2s *i2s = dev_get_drvdata(dev); in tegra30_i2s_runtime_resume() local
55 ret = clk_prepare_enable(i2s->clk_i2s); in tegra30_i2s_runtime_resume()
61 regcache_cache_only(i2s->regmap, false); in tegra30_i2s_runtime_resume()
62 regcache_mark_dirty(i2s->regmap); in tegra30_i2s_runtime_resume()
64 ret = regcache_sync(i2s->regmap); in tegra30_i2s_runtime_resume()
71 clk_disable_unprepare(i2s->clk_i2s); in tegra30_i2s_runtime_resume()
79 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); in tegra30_i2s_set_fmt() local
86 return -EINVAL; in tegra30_i2s_set_fmt()
97 return -EINVAL; in tegra30_i2s_set_fmt()
124 return -EINVAL; in tegra30_i2s_set_fmt()
127 pm_runtime_get_sync(dai->dev); in tegra30_i2s_set_fmt()
128 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, mask, val); in tegra30_i2s_set_fmt()
129 pm_runtime_put(dai->dev); in tegra30_i2s_set_fmt()
138 struct device *dev = dai->dev; in tegra30_i2s_hw_params()
139 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); in tegra30_i2s_hw_params() local
145 return -EINVAL; in tegra30_i2s_hw_params()
154 return -EINVAL; in tegra30_i2s_hw_params()
157 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, mask, val); in tegra30_i2s_hw_params()
164 bitcnt = (i2sclock / (2 * srate)) - 1; in tegra30_i2s_hw_params()
166 return -EINVAL; in tegra30_i2s_hw_params()
168 ret = clk_set_rate(i2s->clk_i2s, i2sclock); in tegra30_i2s_hw_params()
170 dev_err(dev, "Can't set I2S clock rate: %d\n", ret); in tegra30_i2s_hw_params()
179 regmap_write(i2s->regmap, TEGRA30_I2S_TIMING, val); in tegra30_i2s_hw_params()
192 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in tegra30_i2s_hw_params()
200 i2s->soc_data->set_audio_cif(i2s->regmap, reg, &cif_conf); in tegra30_i2s_hw_params()
204 regmap_write(i2s->regmap, TEGRA30_I2S_OFFSET, val); in tegra30_i2s_hw_params()
209 static void tegra30_i2s_start_playback(struct tegra30_i2s *i2s) in tegra30_i2s_start_playback() argument
211 tegra30_ahub_enable_tx_fifo(i2s->playback_fifo_cif); in tegra30_i2s_start_playback()
212 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, in tegra30_i2s_start_playback()
217 static void tegra30_i2s_stop_playback(struct tegra30_i2s *i2s) in tegra30_i2s_stop_playback() argument
219 tegra30_ahub_disable_tx_fifo(i2s->playback_fifo_cif); in tegra30_i2s_stop_playback()
220 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, in tegra30_i2s_stop_playback()
224 static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s) in tegra30_i2s_start_capture() argument
226 tegra30_ahub_enable_rx_fifo(i2s->capture_fifo_cif); in tegra30_i2s_start_capture()
227 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, in tegra30_i2s_start_capture()
232 static void tegra30_i2s_stop_capture(struct tegra30_i2s *i2s) in tegra30_i2s_stop_capture() argument
234 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, in tegra30_i2s_stop_capture()
236 tegra30_ahub_disable_rx_fifo(i2s->capture_fifo_cif); in tegra30_i2s_stop_capture()
242 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); in tegra30_i2s_trigger() local
248 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in tegra30_i2s_trigger()
249 tegra30_i2s_start_playback(i2s); in tegra30_i2s_trigger()
251 tegra30_i2s_start_capture(i2s); in tegra30_i2s_trigger()
256 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in tegra30_i2s_trigger()
257 tegra30_i2s_stop_playback(i2s); in tegra30_i2s_trigger()
259 tegra30_i2s_stop_capture(i2s); in tegra30_i2s_trigger()
262 return -EINVAL; in tegra30_i2s_trigger()
272 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); in tegra30_i2s_set_tdm() local
275 dev_dbg(dai->dev, "%s: txmask=0x%08x rxmask=0x%08x slots=%d width=%d\n", in tegra30_i2s_set_tdm()
284 ((slots - 1) << TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_SHIFT); in tegra30_i2s_set_tdm()
286 pm_runtime_get_sync(dai->dev); in tegra30_i2s_set_tdm()
287 regmap_update_bits(i2s->regmap, TEGRA30_I2S_SLOT_CTRL, mask, val); in tegra30_i2s_set_tdm()
289 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CH_CTRL, in tegra30_i2s_set_tdm()
291 pm_runtime_put(dai->dev); in tegra30_i2s_set_tdm()
298 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); in tegra30_i2s_probe() local
300 snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data, in tegra30_i2s_probe()
301 &i2s->capture_dma_data); in tegra30_i2s_probe()
402 { .compatible = "nvidia,tegra124-i2s", .data = &tegra124_i2s_config },
403 { .compatible = "nvidia,tegra30-i2s", .data = &tegra30_i2s_config },
409 struct tegra30_i2s *i2s; in tegra30_i2s_platform_probe() local
412 void __iomem *regs; in tegra30_i2s_platform_probe() local
415 i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_i2s), GFP_KERNEL); in tegra30_i2s_platform_probe()
416 if (!i2s) { in tegra30_i2s_platform_probe()
417 ret = -ENOMEM; in tegra30_i2s_platform_probe()
420 dev_set_drvdata(&pdev->dev, i2s); in tegra30_i2s_platform_probe()
422 soc_data = of_device_get_match_data(&pdev->dev); in tegra30_i2s_platform_probe()
424 dev_err(&pdev->dev, "Error: No device match found\n"); in tegra30_i2s_platform_probe()
425 ret = -ENODEV; in tegra30_i2s_platform_probe()
428 i2s->soc_data = soc_data; in tegra30_i2s_platform_probe()
430 i2s->dai = tegra30_i2s_dai_template; in tegra30_i2s_platform_probe()
431 i2s->dai.name = dev_name(&pdev->dev); in tegra30_i2s_platform_probe()
433 ret = of_property_read_u32_array(pdev->dev.of_node, in tegra30_i2s_platform_probe()
434 "nvidia,ahub-cif-ids", cif_ids, in tegra30_i2s_platform_probe()
439 i2s->playback_i2s_cif = cif_ids[0]; in tegra30_i2s_platform_probe()
440 i2s->capture_i2s_cif = cif_ids[1]; in tegra30_i2s_platform_probe()
442 i2s->clk_i2s = devm_clk_get(&pdev->dev, NULL); in tegra30_i2s_platform_probe()
443 if (IS_ERR(i2s->clk_i2s)) { in tegra30_i2s_platform_probe()
444 dev_err(&pdev->dev, "Can't retrieve i2s clock\n"); in tegra30_i2s_platform_probe()
445 ret = PTR_ERR(i2s->clk_i2s); in tegra30_i2s_platform_probe()
449 regs = devm_platform_ioremap_resource(pdev, 0); in tegra30_i2s_platform_probe()
450 if (IS_ERR(regs)) { in tegra30_i2s_platform_probe()
451 ret = PTR_ERR(regs); in tegra30_i2s_platform_probe()
455 i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs, in tegra30_i2s_platform_probe()
457 if (IS_ERR(i2s->regmap)) { in tegra30_i2s_platform_probe()
458 dev_err(&pdev->dev, "regmap init failed\n"); in tegra30_i2s_platform_probe()
459 ret = PTR_ERR(i2s->regmap); in tegra30_i2s_platform_probe()
462 regcache_cache_only(i2s->regmap, true); in tegra30_i2s_platform_probe()
464 pm_runtime_enable(&pdev->dev); in tegra30_i2s_platform_probe()
466 i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; in tegra30_i2s_platform_probe()
467 i2s->playback_dma_data.maxburst = 4; in tegra30_i2s_platform_probe()
468 ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif, in tegra30_i2s_platform_probe()
469 i2s->playback_dma_chan, in tegra30_i2s_platform_probe()
470 sizeof(i2s->playback_dma_chan), in tegra30_i2s_platform_probe()
471 &i2s->playback_dma_data.addr); in tegra30_i2s_platform_probe()
473 dev_err(&pdev->dev, "Could not alloc TX FIFO: %d\n", ret); in tegra30_i2s_platform_probe()
476 ret = tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif, in tegra30_i2s_platform_probe()
477 i2s->playback_fifo_cif); in tegra30_i2s_platform_probe()
479 dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret); in tegra30_i2s_platform_probe()
483 i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; in tegra30_i2s_platform_probe()
484 i2s->capture_dma_data.maxburst = 4; in tegra30_i2s_platform_probe()
485 ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif, in tegra30_i2s_platform_probe()
486 i2s->capture_dma_chan, in tegra30_i2s_platform_probe()
487 sizeof(i2s->capture_dma_chan), in tegra30_i2s_platform_probe()
488 &i2s->capture_dma_data.addr); in tegra30_i2s_platform_probe()
490 dev_err(&pdev->dev, "Could not alloc RX FIFO: %d\n", ret); in tegra30_i2s_platform_probe()
493 ret = tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif, in tegra30_i2s_platform_probe()
494 i2s->capture_i2s_cif); in tegra30_i2s_platform_probe()
496 dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret); in tegra30_i2s_platform_probe()
500 ret = snd_soc_register_component(&pdev->dev, &tegra30_i2s_component, in tegra30_i2s_platform_probe()
501 &i2s->dai, 1); in tegra30_i2s_platform_probe()
503 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); in tegra30_i2s_platform_probe()
504 ret = -ENOMEM; in tegra30_i2s_platform_probe()
508 ret = tegra_pcm_platform_register_with_chan_names(&pdev->dev, in tegra30_i2s_platform_probe()
509 &i2s->dma_config, i2s->playback_dma_chan, in tegra30_i2s_platform_probe()
510 i2s->capture_dma_chan); in tegra30_i2s_platform_probe()
512 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); in tegra30_i2s_platform_probe()
519 snd_soc_unregister_component(&pdev->dev); in tegra30_i2s_platform_probe()
521 tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif); in tegra30_i2s_platform_probe()
523 tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif); in tegra30_i2s_platform_probe()
525 tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif); in tegra30_i2s_platform_probe()
527 tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif); in tegra30_i2s_platform_probe()
529 pm_runtime_disable(&pdev->dev); in tegra30_i2s_platform_probe()
536 struct tegra30_i2s *i2s = dev_get_drvdata(&pdev->dev); in tegra30_i2s_platform_remove() local
538 tegra_pcm_platform_unregister(&pdev->dev); in tegra30_i2s_platform_remove()
539 snd_soc_unregister_component(&pdev->dev); in tegra30_i2s_platform_remove()
541 tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif); in tegra30_i2s_platform_remove()
542 tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif); in tegra30_i2s_platform_remove()
544 tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif); in tegra30_i2s_platform_remove()
545 tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif); in tegra30_i2s_platform_remove()
547 pm_runtime_disable(&pdev->dev); in tegra30_i2s_platform_remove()
569 MODULE_DESCRIPTION("Tegra30 I2S ASoC driver");