.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * tegra30_i2s.c - Tegra30 I2S driver |
---|
3 | 4 | * |
---|
.. | .. |
---|
11 | 12 | * |
---|
12 | 13 | * Copyright (C) 2010 Google, Inc. |
---|
13 | 14 | * Iliyan Malchev <malchev@google.com> |
---|
14 | | - * |
---|
15 | | - * This program is free software; you can redistribute it and/or modify it |
---|
16 | | - * under the terms and conditions of the GNU General Public License, |
---|
17 | | - * version 2, as published by the Free Software Foundation. |
---|
18 | | - * |
---|
19 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
---|
20 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
21 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
---|
22 | | - * more details. |
---|
23 | | - * |
---|
24 | | - * You should have received a copy of the GNU General Public License |
---|
25 | | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
---|
26 | 15 | */ |
---|
27 | 16 | |
---|
28 | 17 | #include <linux/clk.h> |
---|
.. | .. |
---|
231 | 220 | |
---|
232 | 221 | static void tegra30_i2s_stop_capture(struct tegra30_i2s *i2s) |
---|
233 | 222 | { |
---|
234 | | - tegra30_ahub_disable_rx_fifo(i2s->capture_fifo_cif); |
---|
235 | 223 | regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, |
---|
236 | 224 | TEGRA30_I2S_CTRL_XFER_EN_RX, 0); |
---|
| 225 | + tegra30_ahub_disable_rx_fifo(i2s->capture_fifo_cif); |
---|
237 | 226 | } |
---|
238 | 227 | |
---|
239 | 228 | static int tegra30_i2s_trigger(struct snd_pcm_substream *substream, int cmd, |
---|
.. | .. |
---|
265 | 254 | return 0; |
---|
266 | 255 | } |
---|
267 | 256 | |
---|
| 257 | +static int tegra30_i2s_set_tdm(struct snd_soc_dai *dai, |
---|
| 258 | + unsigned int tx_mask, unsigned int rx_mask, |
---|
| 259 | + int slots, int slot_width) |
---|
| 260 | +{ |
---|
| 261 | + struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
---|
| 262 | + unsigned int mask, val; |
---|
| 263 | + |
---|
| 264 | + dev_dbg(dai->dev, "%s: txmask=0x%08x rxmask=0x%08x slots=%d width=%d\n", |
---|
| 265 | + __func__, tx_mask, rx_mask, slots, slot_width); |
---|
| 266 | + |
---|
| 267 | + mask = TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_MASK | |
---|
| 268 | + TEGRA30_I2S_SLOT_CTRL_RX_SLOT_ENABLES_MASK | |
---|
| 269 | + TEGRA30_I2S_SLOT_CTRL_TX_SLOT_ENABLES_MASK; |
---|
| 270 | + |
---|
| 271 | + val = (tx_mask << TEGRA30_I2S_SLOT_CTRL_TX_SLOT_ENABLES_SHIFT) | |
---|
| 272 | + (rx_mask << TEGRA30_I2S_SLOT_CTRL_RX_SLOT_ENABLES_SHIFT) | |
---|
| 273 | + ((slots - 1) << TEGRA30_I2S_SLOT_CTRL_TOTAL_SLOTS_SHIFT); |
---|
| 274 | + |
---|
| 275 | + pm_runtime_get_sync(dai->dev); |
---|
| 276 | + regmap_update_bits(i2s->regmap, TEGRA30_I2S_SLOT_CTRL, mask, val); |
---|
| 277 | + /* set the fsync width to minimum of 1 clock width */ |
---|
| 278 | + regmap_update_bits(i2s->regmap, TEGRA30_I2S_CH_CTRL, |
---|
| 279 | + TEGRA30_I2S_CH_CTRL_FSYNC_WIDTH_MASK, 0x0); |
---|
| 280 | + pm_runtime_put(dai->dev); |
---|
| 281 | + |
---|
| 282 | + return 0; |
---|
| 283 | +} |
---|
| 284 | + |
---|
268 | 285 | static int tegra30_i2s_probe(struct snd_soc_dai *dai) |
---|
269 | 286 | { |
---|
270 | 287 | struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); |
---|
.. | .. |
---|
279 | 296 | .set_fmt = tegra30_i2s_set_fmt, |
---|
280 | 297 | .hw_params = tegra30_i2s_hw_params, |
---|
281 | 298 | .trigger = tegra30_i2s_trigger, |
---|
| 299 | + .set_tdm_slot = tegra30_i2s_set_tdm, |
---|
282 | 300 | }; |
---|
283 | 301 | |
---|
284 | 302 | static const struct snd_soc_dai_driver tegra30_i2s_dai_template = { |
---|
.. | .. |
---|
379 | 397 | struct tegra30_i2s *i2s; |
---|
380 | 398 | const struct of_device_id *match; |
---|
381 | 399 | u32 cif_ids[2]; |
---|
382 | | - struct resource *mem; |
---|
383 | 400 | void __iomem *regs; |
---|
384 | 401 | int ret; |
---|
385 | 402 | |
---|
.. | .. |
---|
417 | 434 | goto err; |
---|
418 | 435 | } |
---|
419 | 436 | |
---|
420 | | - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
421 | | - regs = devm_ioremap_resource(&pdev->dev, mem); |
---|
| 437 | + regs = devm_platform_ioremap_resource(pdev, 0); |
---|
422 | 438 | if (IS_ERR(regs)) { |
---|
423 | 439 | ret = PTR_ERR(regs); |
---|
424 | 440 | goto err_clk_put; |
---|