aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
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