aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2013-12-26 13:33:05 -0500
committerOlof Johansson <olof@lixom.net>2013-12-26 13:33:05 -0500
commite7d248f0e0f93b86c56466ede82c46234f622615 (patch)
tree36adb8e2ff0b4cc570334372389f82a73e352002 /sound
parent1c7af42fe579b5cf8c942319cbed38801305dda4 (diff)
parent8a0a1af30cbf56b41220a02e34835022c4d72f41 (diff)
Merge tag 'tegra-for-3.14-dmas-resets-rework' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into next/cleanup
From Stephen Warren: ARM: tegra: implement common DMA and resets DT bindings This series converts the Tegra DTs and drivers to use the common/ standard DMA and reset bindings, rather than custom bindings. It also adds complete documentation for the Tegra clock bindings without actually changing any binding definitions. This conversion relies on a few sets of patches in branches from outside the Tegra tree: 1) A patch to add an DMA channel request API which allows deferred probe to be implemented. 2) A patch to implement a common part of the of_xlate function for DMA controllers. 3) Some ASoC patches (which in turn rely on (1) above), which support deferred probe during DMA channel allocation. 4) The Tegra clock driver changes for 3.14. Consequently, this branch is based on a merge of all of those external branches. In turn, this branch is or will be pulled into a few places that either rely on features introduced here, or would otherwise conflict with the patches: a) Tegra's own for-3.14/powergate and for-4.14/dt branches, to avoid conflicts. b) The DRM tree, which introduces new code that relies on the reset controller framework introduced in this branch, and to avoid conflicts. * tag 'tegra-for-3.14-dmas-resets-rework' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux: (30 commits) spi: tegra: checking for ERR_PTR instead of NULL ASoC: tegra: update module reset list for Tegra124 clk: tegra: remove bogus PCIE_XCLK clk: tegra: remove legacy reset APIs ARM: tegra: remove legacy DMA entries from DT ARM: tegra: remove legacy clock entries from DT USB: EHCI: tegra: use reset framework Input: tegra-kbc - use reset framework serial: tegra: convert to standard DMA DT bindings serial: tegra: use reset framework spi: tegra: convert to standard DMA DT bindings spi: tegra: use reset framework staging: nvec: use reset framework i2c: tegra: use reset framework ASoC: tegra: convert to standard DMA DT bindings ASoC: tegra: allocate AHUB FIFO during probe() not startup() ASoC: tegra: call pm_runtime APIs around register accesses ASoC: tegra: use reset framework dma: tegra: register as an OF DMA controller dma: tegra: use reset framework ... Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/tegra/Kconfig2
-rw-r--r--sound/soc/tegra/tegra20_ac97.c11
-rw-r--r--sound/soc/tegra/tegra20_i2s.c20
-rw-r--r--sound/soc/tegra/tegra30_ahub.c138
-rw-r--r--sound/soc/tegra/tegra30_ahub.h11
-rw-r--r--sound/soc/tegra/tegra30_i2s.c97
-rw-r--r--sound/soc/tegra/tegra30_i2s.h3
-rw-r--r--sound/soc/tegra/tegra_pcm.c17
-rw-r--r--sound/soc/tegra/tegra_pcm.h5
9 files changed, 170 insertions, 134 deletions
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index 8fc653ca3ab4..896292bb853f 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -1,6 +1,8 @@
1config SND_SOC_TEGRA 1config SND_SOC_TEGRA
2 tristate "SoC Audio for the Tegra System-on-Chip" 2 tristate "SoC Audio for the Tegra System-on-Chip"
3 depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST 3 depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
4 depends on COMMON_CLK
5 depends on RESET_CONTROLLER
4 select REGMAP_MMIO 6 select REGMAP_MMIO
5 select SND_SOC_GENERIC_DMAENGINE_PCM 7 select SND_SOC_GENERIC_DMAENGINE_PCM
6 help 8 help
diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c
index ae27bcd586d2..d8b98d70ff41 100644
--- a/sound/soc/tegra/tegra20_ac97.c
+++ b/sound/soc/tegra/tegra20_ac97.c
@@ -313,7 +313,6 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
313{ 313{
314 struct tegra20_ac97 *ac97; 314 struct tegra20_ac97 *ac97;
315 struct resource *mem; 315 struct resource *mem;
316 u32 of_dma[2];
317 void __iomem *regs; 316 void __iomem *regs;
318 int ret = 0; 317 int ret = 0;
319 318
@@ -348,14 +347,6 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
348 goto err_clk_put; 347 goto err_clk_put;
349 } 348 }
350 349
351 if (of_property_read_u32_array(pdev->dev.of_node,
352 "nvidia,dma-request-selector",
353 of_dma, 2) < 0) {
354 dev_err(&pdev->dev, "No DMA resource\n");
355 ret = -ENODEV;
356 goto err_clk_put;
357 }
358
359 ac97->reset_gpio = of_get_named_gpio(pdev->dev.of_node, 350 ac97->reset_gpio = of_get_named_gpio(pdev->dev.of_node,
360 "nvidia,codec-reset-gpio", 0); 351 "nvidia,codec-reset-gpio", 0);
361 if (gpio_is_valid(ac97->reset_gpio)) { 352 if (gpio_is_valid(ac97->reset_gpio)) {
@@ -380,12 +371,10 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
380 ac97->capture_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_RX1; 371 ac97->capture_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_RX1;
381 ac97->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 372 ac97->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
382 ac97->capture_dma_data.maxburst = 4; 373 ac97->capture_dma_data.maxburst = 4;
383 ac97->capture_dma_data.slave_id = of_dma[1];
384 374
385 ac97->playback_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_TX1; 375 ac97->playback_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_TX1;
386 ac97->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 376 ac97->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
387 ac97->playback_dma_data.maxburst = 4; 377 ac97->playback_dma_data.maxburst = 4;
388 ac97->playback_dma_data.slave_id = of_dma[1];
389 378
390 ret = tegra_asoc_utils_init(&ac97->util_data, &pdev->dev); 379 ret = tegra_asoc_utils_init(&ac97->util_data, &pdev->dev);
391 if (ret) 380 if (ret)
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c
index 364bf6a907e1..1dc869c475e7 100644
--- a/sound/soc/tegra/tegra20_i2s.c
+++ b/sound/soc/tegra/tegra20_i2s.c
@@ -339,9 +339,7 @@ static const struct regmap_config tegra20_i2s_regmap_config = {
339static int tegra20_i2s_platform_probe(struct platform_device *pdev) 339static int tegra20_i2s_platform_probe(struct platform_device *pdev)
340{ 340{
341 struct tegra20_i2s *i2s; 341 struct tegra20_i2s *i2s;
342 struct resource *mem, *memregion, *dmareq; 342 struct resource *mem, *memregion;
343 u32 of_dma[2];
344 u32 dma_ch;
345 void __iomem *regs; 343 void __iomem *regs;
346 int ret; 344 int ret;
347 345
@@ -370,20 +368,6 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev)
370 goto err_clk_put; 368 goto err_clk_put;
371 } 369 }
372 370
373 dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0);
374 if (!dmareq) {
375 if (of_property_read_u32_array(pdev->dev.of_node,
376 "nvidia,dma-request-selector",
377 of_dma, 2) < 0) {
378 dev_err(&pdev->dev, "No DMA resource\n");
379 ret = -ENODEV;
380 goto err_clk_put;
381 }
382 dma_ch = of_dma[1];
383 } else {
384 dma_ch = dmareq->start;
385 }
386
387 memregion = devm_request_mem_region(&pdev->dev, mem->start, 371 memregion = devm_request_mem_region(&pdev->dev, mem->start,
388 resource_size(mem), DRV_NAME); 372 resource_size(mem), DRV_NAME);
389 if (!memregion) { 373 if (!memregion) {
@@ -410,12 +394,10 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev)
410 i2s->capture_dma_data.addr = mem->start + TEGRA20_I2S_FIFO2; 394 i2s->capture_dma_data.addr = mem->start + TEGRA20_I2S_FIFO2;
411 i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 395 i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
412 i2s->capture_dma_data.maxburst = 4; 396 i2s->capture_dma_data.maxburst = 4;
413 i2s->capture_dma_data.slave_id = dma_ch;
414 397
415 i2s->playback_dma_data.addr = mem->start + TEGRA20_I2S_FIFO1; 398 i2s->playback_dma_data.addr = mem->start + TEGRA20_I2S_FIFO1;
416 i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 399 i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
417 i2s->playback_dma_data.maxburst = 4; 400 i2s->playback_dma_data.maxburst = 4;
418 i2s->playback_dma_data.slave_id = dma_ch;
419 401
420 pm_runtime_enable(&pdev->dev); 402 pm_runtime_enable(&pdev->dev);
421 if (!pm_runtime_enabled(&pdev->dev)) { 403 if (!pm_runtime_enabled(&pdev->dev)) {
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c
index 31154338c1eb..d6f4c9940e0c 100644
--- a/sound/soc/tegra/tegra30_ahub.c
+++ b/sound/soc/tegra/tegra30_ahub.c
@@ -24,8 +24,8 @@
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/pm_runtime.h> 25#include <linux/pm_runtime.h>
26#include <linux/regmap.h> 26#include <linux/regmap.h>
27#include <linux/reset.h>
27#include <linux/slab.h> 28#include <linux/slab.h>
28#include <linux/clk/tegra.h>
29#include <sound/soc.h> 29#include <sound/soc.h>
30#include "tegra30_ahub.h" 30#include "tegra30_ahub.h"
31 31
@@ -95,8 +95,8 @@ static int tegra30_ahub_runtime_resume(struct device *dev)
95} 95}
96 96
97int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, 97int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
98 dma_addr_t *fiforeg, 98 char *dmachan, int dmachan_len,
99 unsigned int *reqsel) 99 dma_addr_t *fiforeg)
100{ 100{
101 int channel; 101 int channel;
102 u32 reg, val; 102 u32 reg, val;
@@ -110,9 +110,11 @@ int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
110 __set_bit(channel, ahub->rx_usage); 110 __set_bit(channel, ahub->rx_usage);
111 111
112 *rxcif = TEGRA30_AHUB_RXCIF_APBIF_RX0 + channel; 112 *rxcif = TEGRA30_AHUB_RXCIF_APBIF_RX0 + channel;
113 snprintf(dmachan, dmachan_len, "rx%d", channel);
113 *fiforeg = ahub->apbif_addr + TEGRA30_AHUB_CHANNEL_RXFIFO + 114 *fiforeg = ahub->apbif_addr + TEGRA30_AHUB_CHANNEL_RXFIFO +
114 (channel * TEGRA30_AHUB_CHANNEL_RXFIFO_STRIDE); 115 (channel * TEGRA30_AHUB_CHANNEL_RXFIFO_STRIDE);
115 *reqsel = ahub->dma_sel + channel; 116
117 pm_runtime_get_sync(ahub->dev);
116 118
117 reg = TEGRA30_AHUB_CHANNEL_CTRL + 119 reg = TEGRA30_AHUB_CHANNEL_CTRL +
118 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); 120 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
@@ -140,6 +142,8 @@ int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
140 (channel * TEGRA30_AHUB_CIF_RX_CTRL_STRIDE); 142 (channel * TEGRA30_AHUB_CIF_RX_CTRL_STRIDE);
141 ahub->soc_data->set_audio_cif(ahub->regmap_apbif, reg, &cif_conf); 143 ahub->soc_data->set_audio_cif(ahub->regmap_apbif, reg, &cif_conf);
142 144
145 pm_runtime_put(ahub->dev);
146
143 return 0; 147 return 0;
144} 148}
145EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_rx_fifo); 149EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_rx_fifo);
@@ -149,12 +153,16 @@ int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif)
149 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0; 153 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
150 int reg, val; 154 int reg, val;
151 155
156 pm_runtime_get_sync(ahub->dev);
157
152 reg = TEGRA30_AHUB_CHANNEL_CTRL + 158 reg = TEGRA30_AHUB_CHANNEL_CTRL +
153 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); 159 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
154 val = tegra30_apbif_read(reg); 160 val = tegra30_apbif_read(reg);
155 val |= TEGRA30_AHUB_CHANNEL_CTRL_RX_EN; 161 val |= TEGRA30_AHUB_CHANNEL_CTRL_RX_EN;
156 tegra30_apbif_write(reg, val); 162 tegra30_apbif_write(reg, val);
157 163
164 pm_runtime_put(ahub->dev);
165
158 return 0; 166 return 0;
159} 167}
160EXPORT_SYMBOL_GPL(tegra30_ahub_enable_rx_fifo); 168EXPORT_SYMBOL_GPL(tegra30_ahub_enable_rx_fifo);
@@ -164,12 +172,16 @@ int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif)
164 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0; 172 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
165 int reg, val; 173 int reg, val;
166 174
175 pm_runtime_get_sync(ahub->dev);
176
167 reg = TEGRA30_AHUB_CHANNEL_CTRL + 177 reg = TEGRA30_AHUB_CHANNEL_CTRL +
168 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); 178 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
169 val = tegra30_apbif_read(reg); 179 val = tegra30_apbif_read(reg);
170 val &= ~TEGRA30_AHUB_CHANNEL_CTRL_RX_EN; 180 val &= ~TEGRA30_AHUB_CHANNEL_CTRL_RX_EN;
171 tegra30_apbif_write(reg, val); 181 tegra30_apbif_write(reg, val);
172 182
183 pm_runtime_put(ahub->dev);
184
173 return 0; 185 return 0;
174} 186}
175EXPORT_SYMBOL_GPL(tegra30_ahub_disable_rx_fifo); 187EXPORT_SYMBOL_GPL(tegra30_ahub_disable_rx_fifo);
@@ -185,8 +197,8 @@ int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif)
185EXPORT_SYMBOL_GPL(tegra30_ahub_free_rx_fifo); 197EXPORT_SYMBOL_GPL(tegra30_ahub_free_rx_fifo);
186 198
187int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, 199int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
188 dma_addr_t *fiforeg, 200 char *dmachan, int dmachan_len,
189 unsigned int *reqsel) 201 dma_addr_t *fiforeg)
190{ 202{
191 int channel; 203 int channel;
192 u32 reg, val; 204 u32 reg, val;
@@ -200,9 +212,11 @@ int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
200 __set_bit(channel, ahub->tx_usage); 212 __set_bit(channel, ahub->tx_usage);
201 213
202 *txcif = TEGRA30_AHUB_TXCIF_APBIF_TX0 + channel; 214 *txcif = TEGRA30_AHUB_TXCIF_APBIF_TX0 + channel;
215 snprintf(dmachan, dmachan_len, "tx%d", channel);
203 *fiforeg = ahub->apbif_addr + TEGRA30_AHUB_CHANNEL_TXFIFO + 216 *fiforeg = ahub->apbif_addr + TEGRA30_AHUB_CHANNEL_TXFIFO +
204 (channel * TEGRA30_AHUB_CHANNEL_TXFIFO_STRIDE); 217 (channel * TEGRA30_AHUB_CHANNEL_TXFIFO_STRIDE);
205 *reqsel = ahub->dma_sel + channel; 218
219 pm_runtime_get_sync(ahub->dev);
206 220
207 reg = TEGRA30_AHUB_CHANNEL_CTRL + 221 reg = TEGRA30_AHUB_CHANNEL_CTRL +
208 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); 222 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
@@ -230,6 +244,8 @@ int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
230 (channel * TEGRA30_AHUB_CIF_TX_CTRL_STRIDE); 244 (channel * TEGRA30_AHUB_CIF_TX_CTRL_STRIDE);
231 ahub->soc_data->set_audio_cif(ahub->regmap_apbif, reg, &cif_conf); 245 ahub->soc_data->set_audio_cif(ahub->regmap_apbif, reg, &cif_conf);
232 246
247 pm_runtime_put(ahub->dev);
248
233 return 0; 249 return 0;
234} 250}
235EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_tx_fifo); 251EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_tx_fifo);
@@ -239,12 +255,16 @@ int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif)
239 int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0; 255 int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0;
240 int reg, val; 256 int reg, val;
241 257
258 pm_runtime_get_sync(ahub->dev);
259
242 reg = TEGRA30_AHUB_CHANNEL_CTRL + 260 reg = TEGRA30_AHUB_CHANNEL_CTRL +
243 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); 261 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
244 val = tegra30_apbif_read(reg); 262 val = tegra30_apbif_read(reg);
245 val |= TEGRA30_AHUB_CHANNEL_CTRL_TX_EN; 263 val |= TEGRA30_AHUB_CHANNEL_CTRL_TX_EN;
246 tegra30_apbif_write(reg, val); 264 tegra30_apbif_write(reg, val);
247 265
266 pm_runtime_put(ahub->dev);
267
248 return 0; 268 return 0;
249} 269}
250EXPORT_SYMBOL_GPL(tegra30_ahub_enable_tx_fifo); 270EXPORT_SYMBOL_GPL(tegra30_ahub_enable_tx_fifo);
@@ -254,12 +274,16 @@ int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif)
254 int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0; 274 int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0;
255 int reg, val; 275 int reg, val;
256 276
277 pm_runtime_get_sync(ahub->dev);
278
257 reg = TEGRA30_AHUB_CHANNEL_CTRL + 279 reg = TEGRA30_AHUB_CHANNEL_CTRL +
258 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE); 280 (channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
259 val = tegra30_apbif_read(reg); 281 val = tegra30_apbif_read(reg);
260 val &= ~TEGRA30_AHUB_CHANNEL_CTRL_TX_EN; 282 val &= ~TEGRA30_AHUB_CHANNEL_CTRL_TX_EN;
261 tegra30_apbif_write(reg, val); 283 tegra30_apbif_write(reg, val);
262 284
285 pm_runtime_put(ahub->dev);
286
263 return 0; 287 return 0;
264} 288}
265EXPORT_SYMBOL_GPL(tegra30_ahub_disable_tx_fifo); 289EXPORT_SYMBOL_GPL(tegra30_ahub_disable_tx_fifo);
@@ -280,10 +304,14 @@ int tegra30_ahub_set_rx_cif_source(enum tegra30_ahub_rxcif rxcif,
280 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0; 304 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
281 int reg; 305 int reg;
282 306
307 pm_runtime_get_sync(ahub->dev);
308
283 reg = TEGRA30_AHUB_AUDIO_RX + 309 reg = TEGRA30_AHUB_AUDIO_RX +
284 (channel * TEGRA30_AHUB_AUDIO_RX_STRIDE); 310 (channel * TEGRA30_AHUB_AUDIO_RX_STRIDE);
285 tegra30_audio_write(reg, 1 << txcif); 311 tegra30_audio_write(reg, 1 << txcif);
286 312
313 pm_runtime_put(ahub->dev);
314
287 return 0; 315 return 0;
288} 316}
289EXPORT_SYMBOL_GPL(tegra30_ahub_set_rx_cif_source); 317EXPORT_SYMBOL_GPL(tegra30_ahub_set_rx_cif_source);
@@ -293,35 +321,51 @@ int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif)
293 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0; 321 int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
294 int reg; 322 int reg;
295 323
324 pm_runtime_get_sync(ahub->dev);
325
296 reg = TEGRA30_AHUB_AUDIO_RX + 326 reg = TEGRA30_AHUB_AUDIO_RX +
297 (channel * TEGRA30_AHUB_AUDIO_RX_STRIDE); 327 (channel * TEGRA30_AHUB_AUDIO_RX_STRIDE);
298 tegra30_audio_write(reg, 0); 328 tegra30_audio_write(reg, 0);
299 329
330 pm_runtime_put(ahub->dev);
331
300 return 0; 332 return 0;
301} 333}
302EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source); 334EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source);
303 335
304#define CLK_LIST_MASK_TEGRA30 BIT(0) 336#define MOD_LIST_MASK_TEGRA30 BIT(0)
305#define CLK_LIST_MASK_TEGRA114 BIT(1) 337#define MOD_LIST_MASK_TEGRA114 BIT(1)
338#define MOD_LIST_MASK_TEGRA124 BIT(2)
306 339
307#define CLK_LIST_MASK_TEGRA30_OR_LATER \ 340#define MOD_LIST_MASK_TEGRA30_OR_LATER \
308 (CLK_LIST_MASK_TEGRA30 | CLK_LIST_MASK_TEGRA114) 341 (MOD_LIST_MASK_TEGRA30 | MOD_LIST_MASK_TEGRA114 | \
342 MOD_LIST_MASK_TEGRA124)
343#define MOD_LIST_MASK_TEGRA114_OR_LATER \
344 (MOD_LIST_MASK_TEGRA114 | MOD_LIST_MASK_TEGRA124)
309 345
310static const struct { 346static const struct {
311 const char *clk_name; 347 const char *rst_name;
312 u32 clk_list_mask; 348 u32 mod_list_mask;
313} configlink_clocks[] = { 349} configlink_mods[] = {
314 { "i2s0", CLK_LIST_MASK_TEGRA30_OR_LATER }, 350 { "i2s0", MOD_LIST_MASK_TEGRA30_OR_LATER },
315 { "i2s1", CLK_LIST_MASK_TEGRA30_OR_LATER }, 351 { "i2s1", MOD_LIST_MASK_TEGRA30_OR_LATER },
316 { "i2s2", CLK_LIST_MASK_TEGRA30_OR_LATER }, 352 { "i2s2", MOD_LIST_MASK_TEGRA30_OR_LATER },
317 { "i2s3", CLK_LIST_MASK_TEGRA30_OR_LATER }, 353 { "i2s3", MOD_LIST_MASK_TEGRA30_OR_LATER },
318 { "i2s4", CLK_LIST_MASK_TEGRA30_OR_LATER }, 354 { "i2s4", MOD_LIST_MASK_TEGRA30_OR_LATER },
319 { "dam0", CLK_LIST_MASK_TEGRA30_OR_LATER }, 355 { "dam0", MOD_LIST_MASK_TEGRA30_OR_LATER },
320 { "dam1", CLK_LIST_MASK_TEGRA30_OR_LATER }, 356 { "dam1", MOD_LIST_MASK_TEGRA30_OR_LATER },
321 { "dam2", CLK_LIST_MASK_TEGRA30_OR_LATER }, 357 { "dam2", MOD_LIST_MASK_TEGRA30_OR_LATER },
322 { "spdif_in", CLK_LIST_MASK_TEGRA30_OR_LATER }, 358 { "spdif", MOD_LIST_MASK_TEGRA30_OR_LATER },
323 { "amx", CLK_LIST_MASK_TEGRA114 }, 359 { "amx", MOD_LIST_MASK_TEGRA114_OR_LATER },
324 { "adx", CLK_LIST_MASK_TEGRA114 }, 360 { "adx", MOD_LIST_MASK_TEGRA114_OR_LATER },
361 { "amx1", MOD_LIST_MASK_TEGRA124 },
362 { "adx1", MOD_LIST_MASK_TEGRA124 },
363 { "afc0", MOD_LIST_MASK_TEGRA124 },
364 { "afc1", MOD_LIST_MASK_TEGRA124 },
365 { "afc2", MOD_LIST_MASK_TEGRA124 },
366 { "afc3", MOD_LIST_MASK_TEGRA124 },
367 { "afc4", MOD_LIST_MASK_TEGRA124 },
368 { "afc5", MOD_LIST_MASK_TEGRA124 },
325}; 369};
326 370
327#define LAST_REG(name) \ 371#define LAST_REG(name) \
@@ -450,17 +494,17 @@ static const struct regmap_config tegra30_ahub_ahub_regmap_config = {
450}; 494};
451 495
452static struct tegra30_ahub_soc_data soc_data_tegra30 = { 496static struct tegra30_ahub_soc_data soc_data_tegra30 = {
453 .clk_list_mask = CLK_LIST_MASK_TEGRA30, 497 .mod_list_mask = MOD_LIST_MASK_TEGRA30,
454 .set_audio_cif = tegra30_ahub_set_cif, 498 .set_audio_cif = tegra30_ahub_set_cif,
455}; 499};
456 500
457static struct tegra30_ahub_soc_data soc_data_tegra114 = { 501static struct tegra30_ahub_soc_data soc_data_tegra114 = {
458 .clk_list_mask = CLK_LIST_MASK_TEGRA114, 502 .mod_list_mask = MOD_LIST_MASK_TEGRA114,
459 .set_audio_cif = tegra30_ahub_set_cif, 503 .set_audio_cif = tegra30_ahub_set_cif,
460}; 504};
461 505
462static struct tegra30_ahub_soc_data soc_data_tegra124 = { 506static struct tegra30_ahub_soc_data soc_data_tegra124 = {
463 .clk_list_mask = CLK_LIST_MASK_TEGRA114, 507 .mod_list_mask = MOD_LIST_MASK_TEGRA124,
464 .set_audio_cif = tegra124_ahub_set_cif, 508 .set_audio_cif = tegra124_ahub_set_cif,
465}; 509};
466 510
@@ -475,10 +519,9 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
475{ 519{
476 const struct of_device_id *match; 520 const struct of_device_id *match;
477 const struct tegra30_ahub_soc_data *soc_data; 521 const struct tegra30_ahub_soc_data *soc_data;
478 struct clk *clk; 522 struct reset_control *rst;
479 int i; 523 int i;
480 struct resource *res0, *res1, *region; 524 struct resource *res0, *res1, *region;
481 u32 of_dma[2];
482 void __iomem *regs_apbif, *regs_ahub; 525 void __iomem *regs_apbif, *regs_ahub;
483 int ret = 0; 526 int ret = 0;
484 527
@@ -495,19 +538,24 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
495 * operate correctly, all devices on this bus must be out of reset. 538 * operate correctly, all devices on this bus must be out of reset.
496 * Ensure that here. 539 * Ensure that here.
497 */ 540 */
498 for (i = 0; i < ARRAY_SIZE(configlink_clocks); i++) { 541 for (i = 0; i < ARRAY_SIZE(configlink_mods); i++) {
499 if (!(configlink_clocks[i].clk_list_mask & 542 if (!(configlink_mods[i].mod_list_mask &
500 soc_data->clk_list_mask)) 543 soc_data->mod_list_mask))
501 continue; 544 continue;
502 clk = clk_get(&pdev->dev, configlink_clocks[i].clk_name); 545
503 if (IS_ERR(clk)) { 546 rst = reset_control_get(&pdev->dev,
504 dev_err(&pdev->dev, "Can't get clock %s\n", 547 configlink_mods[i].rst_name);
505 configlink_clocks[i].clk_name); 548 if (IS_ERR(rst)) {
506 ret = PTR_ERR(clk); 549 dev_err(&pdev->dev, "Can't get reset %s\n",
550 configlink_mods[i].rst_name);
551 ret = PTR_ERR(rst);
507 goto err; 552 goto err;
508 } 553 }
509 tegra_periph_reset_deassert(clk); 554
510 clk_put(clk); 555 ret = reset_control_deassert(rst);
556 reset_control_put(rst);
557 if (ret)
558 goto err;
511 } 559 }
512 560
513 ahub = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_ahub), 561 ahub = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_ahub),
@@ -536,16 +584,6 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
536 goto err_clk_put_d_audio; 584 goto err_clk_put_d_audio;
537 } 585 }
538 586
539 if (of_property_read_u32_array(pdev->dev.of_node,
540 "nvidia,dma-request-selector",
541 of_dma, 2) < 0) {
542 dev_err(&pdev->dev,
543 "Missing property nvidia,dma-request-selector\n");
544 ret = -ENODEV;
545 goto err_clk_put_d_audio;
546 }
547 ahub->dma_sel = of_dma[1];
548
549 res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); 587 res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
550 if (!res0) { 588 if (!res0) {
551 dev_err(&pdev->dev, "No apbif memory resource\n"); 589 dev_err(&pdev->dev, "No apbif memory resource\n");
diff --git a/sound/soc/tegra/tegra30_ahub.h b/sound/soc/tegra/tegra30_ahub.h
index d67321d90faa..fd7ba75ed814 100644
--- a/sound/soc/tegra/tegra30_ahub.h
+++ b/sound/soc/tegra/tegra30_ahub.h
@@ -465,15 +465,15 @@ enum tegra30_ahub_rxcif {
465}; 465};
466 466
467extern int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif, 467extern int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
468 dma_addr_t *fiforeg, 468 char *dmachan, int dmachan_len,
469 unsigned int *reqsel); 469 dma_addr_t *fiforeg);
470extern int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif); 470extern int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif);
471extern int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif); 471extern int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif);
472extern int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif); 472extern int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif);
473 473
474extern int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif, 474extern int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
475 dma_addr_t *fiforeg, 475 char *dmachan, int dmachan_len,
476 unsigned int *reqsel); 476 dma_addr_t *fiforeg);
477extern int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif); 477extern int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif);
478extern int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif); 478extern int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif);
479extern int tegra30_ahub_free_tx_fifo(enum tegra30_ahub_txcif txcif); 479extern int tegra30_ahub_free_tx_fifo(enum tegra30_ahub_txcif txcif);
@@ -502,7 +502,7 @@ void tegra124_ahub_set_cif(struct regmap *regmap, unsigned int reg,
502 struct tegra30_ahub_cif_conf *conf); 502 struct tegra30_ahub_cif_conf *conf);
503 503
504struct tegra30_ahub_soc_data { 504struct tegra30_ahub_soc_data {
505 u32 clk_list_mask; 505 u32 mod_list_mask;
506 void (*set_audio_cif)(struct regmap *regmap, 506 void (*set_audio_cif)(struct regmap *regmap,
507 unsigned int reg, 507 unsigned int reg,
508 struct tegra30_ahub_cif_conf *conf); 508 struct tegra30_ahub_cif_conf *conf);
@@ -524,7 +524,6 @@ struct tegra30_ahub {
524 struct device *dev; 524 struct device *dev;
525 struct clk *clk_d_audio; 525 struct clk *clk_d_audio;
526 struct clk *clk_apbif; 526 struct clk *clk_apbif;
527 int dma_sel;
528 resource_size_t apbif_addr; 527 resource_size_t apbif_addr;
529 struct regmap *regmap_apbif; 528 struct regmap *regmap_apbif;
530 struct regmap *regmap_ahub; 529 struct regmap *regmap_ahub;
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index 231a785b3921..362e8f728ddf 100644
--- a/sound/soc/tegra/tegra30_i2s.c
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -73,47 +73,6 @@ static int tegra30_i2s_runtime_resume(struct device *dev)
73 return 0; 73 return 0;
74} 74}
75 75
76static int tegra30_i2s_startup(struct snd_pcm_substream *substream,
77 struct snd_soc_dai *dai)
78{
79 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
80 int ret;
81
82 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
83 ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif,
84 &i2s->playback_dma_data.addr,
85 &i2s->playback_dma_data.slave_id);
86 i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
87 i2s->playback_dma_data.maxburst = 4;
88 tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif,
89 i2s->playback_fifo_cif);
90 } else {
91 ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif,
92 &i2s->capture_dma_data.addr,
93 &i2s->capture_dma_data.slave_id);
94 i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
95 i2s->capture_dma_data.maxburst = 4;
96 tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif,
97 i2s->capture_i2s_cif);
98 }
99
100 return ret;
101}
102
103static void tegra30_i2s_shutdown(struct snd_pcm_substream *substream,
104 struct snd_soc_dai *dai)
105{
106 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
107
108 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
109 tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif);
110 tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
111 } else {
112 tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif);
113 tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif);
114 }
115}
116
117static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai, 76static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
118 unsigned int fmt) 77 unsigned int fmt)
119{ 78{
@@ -317,8 +276,6 @@ static int tegra30_i2s_probe(struct snd_soc_dai *dai)
317} 276}
318 277
319static struct snd_soc_dai_ops tegra30_i2s_dai_ops = { 278static struct snd_soc_dai_ops tegra30_i2s_dai_ops = {
320 .startup = tegra30_i2s_startup,
321 .shutdown = tegra30_i2s_shutdown,
322 .set_fmt = tegra30_i2s_set_fmt, 279 .set_fmt = tegra30_i2s_set_fmt,
323 .hw_params = tegra30_i2s_hw_params, 280 .hw_params = tegra30_i2s_hw_params,
324 .trigger = tegra30_i2s_trigger, 281 .trigger = tegra30_i2s_trigger,
@@ -499,15 +456,51 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
499 goto err_pm_disable; 456 goto err_pm_disable;
500 } 457 }
501 458
459 i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
460 i2s->playback_dma_data.maxburst = 4;
461 ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif,
462 i2s->playback_dma_chan,
463 sizeof(i2s->playback_dma_chan),
464 &i2s->playback_dma_data.addr);
465 if (ret) {
466 dev_err(&pdev->dev, "Could not alloc TX FIFO: %d\n", ret);
467 goto err_suspend;
468 }
469 ret = tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif,
470 i2s->playback_fifo_cif);
471 if (ret) {
472 dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret);
473 goto err_free_tx_fifo;
474 }
475
476 i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
477 i2s->capture_dma_data.maxburst = 4;
478 ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif,
479 i2s->capture_dma_chan,
480 sizeof(i2s->capture_dma_chan),
481 &i2s->capture_dma_data.addr);
482 if (ret) {
483 dev_err(&pdev->dev, "Could not alloc RX FIFO: %d\n", ret);
484 goto err_unroute_tx_fifo;
485 }
486 ret = tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif,
487 i2s->capture_i2s_cif);
488 if (ret) {
489 dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret);
490 goto err_free_rx_fifo;
491 }
492
502 ret = snd_soc_register_component(&pdev->dev, &tegra30_i2s_component, 493 ret = snd_soc_register_component(&pdev->dev, &tegra30_i2s_component,
503 &i2s->dai, 1); 494 &i2s->dai, 1);
504 if (ret) { 495 if (ret) {
505 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); 496 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
506 ret = -ENOMEM; 497 ret = -ENOMEM;
507 goto err_suspend; 498 goto err_unroute_rx_fifo;
508 } 499 }
509 500
510 ret = tegra_pcm_platform_register(&pdev->dev); 501 ret = tegra_pcm_platform_register_with_chan_names(&pdev->dev,
502 &i2s->dma_config, i2s->playback_dma_chan,
503 i2s->capture_dma_chan);
511 if (ret) { 504 if (ret) {
512 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret); 505 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
513 goto err_unregister_component; 506 goto err_unregister_component;
@@ -517,6 +510,14 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
517 510
518err_unregister_component: 511err_unregister_component:
519 snd_soc_unregister_component(&pdev->dev); 512 snd_soc_unregister_component(&pdev->dev);
513err_unroute_rx_fifo:
514 tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif);
515err_free_rx_fifo:
516 tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif);
517err_unroute_tx_fifo:
518 tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif);
519err_free_tx_fifo:
520 tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
520err_suspend: 521err_suspend:
521 if (!pm_runtime_status_suspended(&pdev->dev)) 522 if (!pm_runtime_status_suspended(&pdev->dev))
522 tegra30_i2s_runtime_suspend(&pdev->dev); 523 tegra30_i2s_runtime_suspend(&pdev->dev);
@@ -539,6 +540,12 @@ static int tegra30_i2s_platform_remove(struct platform_device *pdev)
539 tegra_pcm_platform_unregister(&pdev->dev); 540 tegra_pcm_platform_unregister(&pdev->dev);
540 snd_soc_unregister_component(&pdev->dev); 541 snd_soc_unregister_component(&pdev->dev);
541 542
543 tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif);
544 tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif);
545
546 tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif);
547 tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
548
542 clk_put(i2s->clk_i2s); 549 clk_put(i2s->clk_i2s);
543 550
544 return 0; 551 return 0;
diff --git a/sound/soc/tegra/tegra30_i2s.h b/sound/soc/tegra/tegra30_i2s.h
index 4d0b0a30dbfb..774fc6ad2026 100644
--- a/sound/soc/tegra/tegra30_i2s.h
+++ b/sound/soc/tegra/tegra30_i2s.h
@@ -238,11 +238,14 @@ struct tegra30_i2s {
238 struct clk *clk_i2s; 238 struct clk *clk_i2s;
239 enum tegra30_ahub_txcif capture_i2s_cif; 239 enum tegra30_ahub_txcif capture_i2s_cif;
240 enum tegra30_ahub_rxcif capture_fifo_cif; 240 enum tegra30_ahub_rxcif capture_fifo_cif;
241 char capture_dma_chan[8];
241 struct snd_dmaengine_dai_dma_data capture_dma_data; 242 struct snd_dmaengine_dai_dma_data capture_dma_data;
242 enum tegra30_ahub_rxcif playback_i2s_cif; 243 enum tegra30_ahub_rxcif playback_i2s_cif;
243 enum tegra30_ahub_txcif playback_fifo_cif; 244 enum tegra30_ahub_txcif playback_fifo_cif;
245 char playback_dma_chan[8];
244 struct snd_dmaengine_dai_dma_data playback_dma_data; 246 struct snd_dmaengine_dai_dma_data playback_dma_data;
245 struct regmap *regmap; 247 struct regmap *regmap;
248 struct snd_dmaengine_pcm_config dma_config;
246}; 249};
247 250
248#endif 251#endif
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index 7b2d23ba69b3..7ce5c334a660 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -61,12 +61,23 @@ static const struct snd_dmaengine_pcm_config tegra_dmaengine_pcm_config = {
61 61
62int tegra_pcm_platform_register(struct device *dev) 62int tegra_pcm_platform_register(struct device *dev)
63{ 63{
64 return snd_dmaengine_pcm_register(dev, &tegra_dmaengine_pcm_config, 64 return snd_dmaengine_pcm_register(dev, &tegra_dmaengine_pcm_config, 0);
65 SND_DMAENGINE_PCM_FLAG_NO_DT |
66 SND_DMAENGINE_PCM_FLAG_COMPAT);
67} 65}
68EXPORT_SYMBOL_GPL(tegra_pcm_platform_register); 66EXPORT_SYMBOL_GPL(tegra_pcm_platform_register);
69 67
68int tegra_pcm_platform_register_with_chan_names(struct device *dev,
69 struct snd_dmaengine_pcm_config *config,
70 char *txdmachan, char *rxdmachan)
71{
72 *config = tegra_dmaengine_pcm_config;
73 config->dma_dev = dev->parent;
74 config->chan_names[0] = txdmachan;
75 config->chan_names[1] = rxdmachan;
76
77 return snd_dmaengine_pcm_register(dev, config, 0);
78}
79EXPORT_SYMBOL_GPL(tegra_pcm_platform_register_with_chan_names);
80
70void tegra_pcm_platform_unregister(struct device *dev) 81void tegra_pcm_platform_unregister(struct device *dev)
71{ 82{
72 return snd_dmaengine_pcm_unregister(dev); 83 return snd_dmaengine_pcm_unregister(dev);
diff --git a/sound/soc/tegra/tegra_pcm.h b/sound/soc/tegra/tegra_pcm.h
index 68ad901714a9..7883dec748a3 100644
--- a/sound/soc/tegra/tegra_pcm.h
+++ b/sound/soc/tegra/tegra_pcm.h
@@ -31,7 +31,12 @@
31#ifndef __TEGRA_PCM_H__ 31#ifndef __TEGRA_PCM_H__
32#define __TEGRA_PCM_H__ 32#define __TEGRA_PCM_H__
33 33
34struct snd_dmaengine_pcm_config;
35
34int tegra_pcm_platform_register(struct device *dev); 36int tegra_pcm_platform_register(struct device *dev);
37int tegra_pcm_platform_register_with_chan_names(struct device *dev,
38 struct snd_dmaengine_pcm_config *config,
39 char *txdmachan, char *rxdmachan);
35void tegra_pcm_platform_unregister(struct device *dev); 40void tegra_pcm_platform_unregister(struct device *dev);
36 41
37#endif 42#endif