summaryrefslogtreecommitdiffstats
path: root/sound/soc/tegra
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-24 03:36:55 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-24 03:36:55 +0100
commitf2c73464d7b399cf4e0c601c1c7d7b079080fa52 (patch)
tree902decd0c280757075bce5068fee679e0ccc261e /sound/soc/tegra
parentMerge tag 'fixes-nc-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/g... (diff)
parentMerge tag 'at91-cleanup2' of git://github.com/at91linux/linux-at91 into next/... (diff)
downloadlinux-f2c73464d7b399cf4e0c601c1c7d7b079080fa52.tar.xz
linux-f2c73464d7b399cf4e0c601c1c7d7b079080fa52.zip
Merge tag 'cleanup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC cleanups from Olof Johansson: "This is the branch where we usually queue up cleanup efforts, moving drivers out of the architecture directory, header file restructuring, etc. Sometimes they tangle with new development so it's hard to keep it strictly to cleanups. Some of the things included in this branch are: * Atmel SAMA5 conversion to common clock * Reset framework conversion for tegra platforms - Some of this depends on tegra clock driver reworks that are shared with Mike Turquette's clk tree. * Tegra DMA refactoring, which are shared branches with the DMA tree. * Removal of some header files on exynos to prepare for multiplatform" * tag 'cleanup-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (169 commits) ARM: mvebu: move Armada 370/XP specific definitions to armada-370-xp.h ARM: mvebu: remove prototypes of non-existing functions from common.h ARM: mvebu: move ARMADA_XP_MAX_CPUS to armada-370-xp.h serial: sh-sci: Rework baud rate calculation serial: sh-sci: Compute overrun_bit without using baud rate algo serial: sh-sci: Remove unused GPIO request code serial: sh-sci: Move overrun_bit and error_mask fields out of pdata serial: sh-sci: Support resources passed through platform resources serial: sh-sci: Don't check IRQ in verify port operation serial: sh-sci: Set the UPF_FIXED_PORT flag serial: sh-sci: Remove duplicate interrupt check in verify port op serial: sh-sci: Simplify baud rate calculation algorithms serial: sh-sci: Remove baud rate calculation algorithm 5 serial: sh-sci: Sort headers alphabetically ARM: EXYNOS: Kill exynos_pm_late_initcall() ARM: EXYNOS: Consolidate selection of PM_GENERIC_DOMAINS for Exynos4 ARM: at91: switch Calao QIL-A9260 board to DT clk: at91: fix pmc_clk_ids data type attriubte PM / devfreq: use inclusion <mach/map.h> instead of <plat/map-s5p.h> ARM: EXYNOS: remove <mach/regs-clock.h> for exynos ...
Diffstat (limited to 'sound/soc/tegra')
-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 65a85f542521..9f9c1856f822 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -1,6 +1,8 @@
config SND_SOC_TEGRA
tristate "SoC Audio for the Tegra System-on-Chip"
depends on (ARCH_TEGRA && TEGRA20_APB_DMA) || COMPILE_TEST
+ depends on COMMON_CLK
+ depends on RESET_CONTROLLER
select REGMAP_MMIO
select SND_SOC_GENERIC_DMAENGINE_PCM
help
diff --git a/sound/soc/tegra/tegra20_ac97.c b/sound/soc/tegra/tegra20_ac97.c
index 088518d7694a..cf5e1cfe818d 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)
{
struct tegra20_ac97 *ac97;
struct resource *mem;
- u32 of_dma[2];
void __iomem *regs;
int ret = 0;
@@ -348,14 +347,6 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
goto err_clk_put;
}
- if (of_property_read_u32_array(pdev->dev.of_node,
- "nvidia,dma-request-selector",
- of_dma, 2) < 0) {
- dev_err(&pdev->dev, "No DMA resource\n");
- ret = -ENODEV;
- goto err_clk_put;
- }
-
ac97->reset_gpio = of_get_named_gpio(pdev->dev.of_node,
"nvidia,codec-reset-gpio", 0);
if (gpio_is_valid(ac97->reset_gpio)) {
@@ -380,12 +371,10 @@ static int tegra20_ac97_platform_probe(struct platform_device *pdev)
ac97->capture_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_RX1;
ac97->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
ac97->capture_dma_data.maxburst = 4;
- ac97->capture_dma_data.slave_id = of_dma[1];
ac97->playback_dma_data.addr = mem->start + TEGRA20_AC97_FIFO_TX1;
ac97->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
ac97->playback_dma_data.maxburst = 4;
- ac97->playback_dma_data.slave_id = of_dma[1];
ret = tegra_asoc_utils_init(&ac97->util_data, &pdev->dev);
if (ret)
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c
index 8c819f811470..42c1f6bfaf2e 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 = {
static int tegra20_i2s_platform_probe(struct platform_device *pdev)
{
struct tegra20_i2s *i2s;
- struct resource *mem, *memregion, *dmareq;
- u32 of_dma[2];
- u32 dma_ch;
+ struct resource *mem, *memregion;
void __iomem *regs;
int ret;
@@ -370,20 +368,6 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev)
goto err_clk_put;
}
- dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0);
- if (!dmareq) {
- if (of_property_read_u32_array(pdev->dev.of_node,
- "nvidia,dma-request-selector",
- of_dma, 2) < 0) {
- dev_err(&pdev->dev, "No DMA resource\n");
- ret = -ENODEV;
- goto err_clk_put;
- }
- dma_ch = of_dma[1];
- } else {
- dma_ch = dmareq->start;
- }
-
memregion = devm_request_mem_region(&pdev->dev, mem->start,
resource_size(mem), DRV_NAME);
if (!memregion) {
@@ -410,12 +394,10 @@ static int tegra20_i2s_platform_probe(struct platform_device *pdev)
i2s->capture_dma_data.addr = mem->start + TEGRA20_I2S_FIFO2;
i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
i2s->capture_dma_data.maxburst = 4;
- i2s->capture_dma_data.slave_id = dma_ch;
i2s->playback_dma_data.addr = mem->start + TEGRA20_I2S_FIFO1;
i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
i2s->playback_dma_data.maxburst = 4;
- i2s->playback_dma_data.slave_id = dma_ch;
pm_runtime_enable(&pdev->dev);
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 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
+#include <linux/reset.h>
#include <linux/slab.h>
-#include <linux/clk/tegra.h>
#include <sound/soc.h>
#include "tegra30_ahub.h"
@@ -95,8 +95,8 @@ static int tegra30_ahub_runtime_resume(struct device *dev)
}
int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
- dma_addr_t *fiforeg,
- unsigned int *reqsel)
+ char *dmachan, int dmachan_len,
+ dma_addr_t *fiforeg)
{
int channel;
u32 reg, val;
@@ -110,9 +110,11 @@ int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
__set_bit(channel, ahub->rx_usage);
*rxcif = TEGRA30_AHUB_RXCIF_APBIF_RX0 + channel;
+ snprintf(dmachan, dmachan_len, "rx%d", channel);
*fiforeg = ahub->apbif_addr + TEGRA30_AHUB_CHANNEL_RXFIFO +
(channel * TEGRA30_AHUB_CHANNEL_RXFIFO_STRIDE);
- *reqsel = ahub->dma_sel + channel;
+
+ pm_runtime_get_sync(ahub->dev);
reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
@@ -140,6 +142,8 @@ int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
(channel * TEGRA30_AHUB_CIF_RX_CTRL_STRIDE);
ahub->soc_data->set_audio_cif(ahub->regmap_apbif, reg, &cif_conf);
+ pm_runtime_put(ahub->dev);
+
return 0;
}
EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_rx_fifo);
@@ -149,12 +153,16 @@ int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif)
int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
int reg, val;
+ pm_runtime_get_sync(ahub->dev);
+
reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
val = tegra30_apbif_read(reg);
val |= TEGRA30_AHUB_CHANNEL_CTRL_RX_EN;
tegra30_apbif_write(reg, val);
+ pm_runtime_put(ahub->dev);
+
return 0;
}
EXPORT_SYMBOL_GPL(tegra30_ahub_enable_rx_fifo);
@@ -164,12 +172,16 @@ int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif)
int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
int reg, val;
+ pm_runtime_get_sync(ahub->dev);
+
reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
val = tegra30_apbif_read(reg);
val &= ~TEGRA30_AHUB_CHANNEL_CTRL_RX_EN;
tegra30_apbif_write(reg, val);
+ pm_runtime_put(ahub->dev);
+
return 0;
}
EXPORT_SYMBOL_GPL(tegra30_ahub_disable_rx_fifo);
@@ -185,8 +197,8 @@ int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif)
EXPORT_SYMBOL_GPL(tegra30_ahub_free_rx_fifo);
int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
- dma_addr_t *fiforeg,
- unsigned int *reqsel)
+ char *dmachan, int dmachan_len,
+ dma_addr_t *fiforeg)
{
int channel;
u32 reg, val;
@@ -200,9 +212,11 @@ int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
__set_bit(channel, ahub->tx_usage);
*txcif = TEGRA30_AHUB_TXCIF_APBIF_TX0 + channel;
+ snprintf(dmachan, dmachan_len, "tx%d", channel);
*fiforeg = ahub->apbif_addr + TEGRA30_AHUB_CHANNEL_TXFIFO +
(channel * TEGRA30_AHUB_CHANNEL_TXFIFO_STRIDE);
- *reqsel = ahub->dma_sel + channel;
+
+ pm_runtime_get_sync(ahub->dev);
reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
@@ -230,6 +244,8 @@ int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
(channel * TEGRA30_AHUB_CIF_TX_CTRL_STRIDE);
ahub->soc_data->set_audio_cif(ahub->regmap_apbif, reg, &cif_conf);
+ pm_runtime_put(ahub->dev);
+
return 0;
}
EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_tx_fifo);
@@ -239,12 +255,16 @@ int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif)
int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0;
int reg, val;
+ pm_runtime_get_sync(ahub->dev);
+
reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
val = tegra30_apbif_read(reg);
val |= TEGRA30_AHUB_CHANNEL_CTRL_TX_EN;
tegra30_apbif_write(reg, val);
+ pm_runtime_put(ahub->dev);
+
return 0;
}
EXPORT_SYMBOL_GPL(tegra30_ahub_enable_tx_fifo);
@@ -254,12 +274,16 @@ int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif)
int channel = txcif - TEGRA30_AHUB_TXCIF_APBIF_TX0;
int reg, val;
+ pm_runtime_get_sync(ahub->dev);
+
reg = TEGRA30_AHUB_CHANNEL_CTRL +
(channel * TEGRA30_AHUB_CHANNEL_CTRL_STRIDE);
val = tegra30_apbif_read(reg);
val &= ~TEGRA30_AHUB_CHANNEL_CTRL_TX_EN;
tegra30_apbif_write(reg, val);
+ pm_runtime_put(ahub->dev);
+
return 0;
}
EXPORT_SYMBOL_GPL(tegra30_ahub_disable_tx_fifo);
@@ -280,10 +304,14 @@ int tegra30_ahub_set_rx_cif_source(enum tegra30_ahub_rxcif rxcif,
int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
int reg;
+ pm_runtime_get_sync(ahub->dev);
+
reg = TEGRA30_AHUB_AUDIO_RX +
(channel * TEGRA30_AHUB_AUDIO_RX_STRIDE);
tegra30_audio_write(reg, 1 << txcif);
+ pm_runtime_put(ahub->dev);
+
return 0;
}
EXPORT_SYMBOL_GPL(tegra30_ahub_set_rx_cif_source);
@@ -293,35 +321,51 @@ int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif)
int channel = rxcif - TEGRA30_AHUB_RXCIF_APBIF_RX0;
int reg;
+ pm_runtime_get_sync(ahub->dev);
+
reg = TEGRA30_AHUB_AUDIO_RX +
(channel * TEGRA30_AHUB_AUDIO_RX_STRIDE);
tegra30_audio_write(reg, 0);
+ pm_runtime_put(ahub->dev);
+
return 0;
}
EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source);
-#define CLK_LIST_MASK_TEGRA30 BIT(0)
-#define CLK_LIST_MASK_TEGRA114 BIT(1)
+#define MOD_LIST_MASK_TEGRA30 BIT(0)
+#define MOD_LIST_MASK_TEGRA114 BIT(1)
+#define MOD_LIST_MASK_TEGRA124 BIT(2)
-#define CLK_LIST_MASK_TEGRA30_OR_LATER \
- (CLK_LIST_MASK_TEGRA30 | CLK_LIST_MASK_TEGRA114)
+#define MOD_LIST_MASK_TEGRA30_OR_LATER \
+ (MOD_LIST_MASK_TEGRA30 | MOD_LIST_MASK_TEGRA114 | \
+ MOD_LIST_MASK_TEGRA124)
+#define MOD_LIST_MASK_TEGRA114_OR_LATER \
+ (MOD_LIST_MASK_TEGRA114 | MOD_LIST_MASK_TEGRA124)
static const struct {
- const char *clk_name;
- u32 clk_list_mask;
-} configlink_clocks[] = {
- { "i2s0", CLK_LIST_MASK_TEGRA30_OR_LATER },
- { "i2s1", CLK_LIST_MASK_TEGRA30_OR_LATER },
- { "i2s2", CLK_LIST_MASK_TEGRA30_OR_LATER },
- { "i2s3", CLK_LIST_MASK_TEGRA30_OR_LATER },
- { "i2s4", CLK_LIST_MASK_TEGRA30_OR_LATER },
- { "dam0", CLK_LIST_MASK_TEGRA30_OR_LATER },
- { "dam1", CLK_LIST_MASK_TEGRA30_OR_LATER },
- { "dam2", CLK_LIST_MASK_TEGRA30_OR_LATER },
- { "spdif_in", CLK_LIST_MASK_TEGRA30_OR_LATER },
- { "amx", CLK_LIST_MASK_TEGRA114 },
- { "adx", CLK_LIST_MASK_TEGRA114 },
+ const char *rst_name;
+ u32 mod_list_mask;
+} configlink_mods[] = {
+ { "i2s0", MOD_LIST_MASK_TEGRA30_OR_LATER },
+ { "i2s1", MOD_LIST_MASK_TEGRA30_OR_LATER },
+ { "i2s2", MOD_LIST_MASK_TEGRA30_OR_LATER },
+ { "i2s3", MOD_LIST_MASK_TEGRA30_OR_LATER },
+ { "i2s4", MOD_LIST_MASK_TEGRA30_OR_LATER },
+ { "dam0", MOD_LIST_MASK_TEGRA30_OR_LATER },
+ { "dam1", MOD_LIST_MASK_TEGRA30_OR_LATER },
+ { "dam2", MOD_LIST_MASK_TEGRA30_OR_LATER },
+ { "spdif", MOD_LIST_MASK_TEGRA30_OR_LATER },
+ { "amx", MOD_LIST_MASK_TEGRA114_OR_LATER },
+ { "adx", MOD_LIST_MASK_TEGRA114_OR_LATER },
+ { "amx1", MOD_LIST_MASK_TEGRA124 },
+ { "adx1", MOD_LIST_MASK_TEGRA124 },
+ { "afc0", MOD_LIST_MASK_TEGRA124 },
+ { "afc1", MOD_LIST_MASK_TEGRA124 },
+ { "afc2", MOD_LIST_MASK_TEGRA124 },
+ { "afc3", MOD_LIST_MASK_TEGRA124 },
+ { "afc4", MOD_LIST_MASK_TEGRA124 },
+ { "afc5", MOD_LIST_MASK_TEGRA124 },
};
#define LAST_REG(name) \
@@ -450,17 +494,17 @@ static const struct regmap_config tegra30_ahub_ahub_regmap_config = {
};
static struct tegra30_ahub_soc_data soc_data_tegra30 = {
- .clk_list_mask = CLK_LIST_MASK_TEGRA30,
+ .mod_list_mask = MOD_LIST_MASK_TEGRA30,
.set_audio_cif = tegra30_ahub_set_cif,
};
static struct tegra30_ahub_soc_data soc_data_tegra114 = {
- .clk_list_mask = CLK_LIST_MASK_TEGRA114,
+ .mod_list_mask = MOD_LIST_MASK_TEGRA114,
.set_audio_cif = tegra30_ahub_set_cif,
};
static struct tegra30_ahub_soc_data soc_data_tegra124 = {
- .clk_list_mask = CLK_LIST_MASK_TEGRA114,
+ .mod_list_mask = MOD_LIST_MASK_TEGRA124,
.set_audio_cif = tegra124_ahub_set_cif,
};
@@ -475,10 +519,9 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
const struct tegra30_ahub_soc_data *soc_data;
- struct clk *clk;
+ struct reset_control *rst;
int i;
struct resource *res0, *res1, *region;
- u32 of_dma[2];
void __iomem *regs_apbif, *regs_ahub;
int ret = 0;
@@ -495,19 +538,24 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
* operate correctly, all devices on this bus must be out of reset.
* Ensure that here.
*/
- for (i = 0; i < ARRAY_SIZE(configlink_clocks); i++) {
- if (!(configlink_clocks[i].clk_list_mask &
- soc_data->clk_list_mask))
+ for (i = 0; i < ARRAY_SIZE(configlink_mods); i++) {
+ if (!(configlink_mods[i].mod_list_mask &
+ soc_data->mod_list_mask))
continue;
- clk = clk_get(&pdev->dev, configlink_clocks[i].clk_name);
- if (IS_ERR(clk)) {
- dev_err(&pdev->dev, "Can't get clock %s\n",
- configlink_clocks[i].clk_name);
- ret = PTR_ERR(clk);
+
+ rst = reset_control_get(&pdev->dev,
+ configlink_mods[i].rst_name);
+ if (IS_ERR(rst)) {
+ dev_err(&pdev->dev, "Can't get reset %s\n",
+ configlink_mods[i].rst_name);
+ ret = PTR_ERR(rst);
goto err;
}
- tegra_periph_reset_deassert(clk);
- clk_put(clk);
+
+ ret = reset_control_deassert(rst);
+ reset_control_put(rst);
+ if (ret)
+ goto err;
}
ahub = devm_kzalloc(&pdev->dev, sizeof(struct tegra30_ahub),
@@ -536,16 +584,6 @@ static int tegra30_ahub_probe(struct platform_device *pdev)
goto err_clk_put_d_audio;
}
- if (of_property_read_u32_array(pdev->dev.of_node,
- "nvidia,dma-request-selector",
- of_dma, 2) < 0) {
- dev_err(&pdev->dev,
- "Missing property nvidia,dma-request-selector\n");
- ret = -ENODEV;
- goto err_clk_put_d_audio;
- }
- ahub->dma_sel = of_dma[1];
-
res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res0) {
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 {
};
extern int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif *rxcif,
- dma_addr_t *fiforeg,
- unsigned int *reqsel);
+ char *dmachan, int dmachan_len,
+ dma_addr_t *fiforeg);
extern int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif);
extern int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif);
extern int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif);
extern int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif *txcif,
- dma_addr_t *fiforeg,
- unsigned int *reqsel);
+ char *dmachan, int dmachan_len,
+ dma_addr_t *fiforeg);
extern int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif);
extern int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif);
extern 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,
struct tegra30_ahub_cif_conf *conf);
struct tegra30_ahub_soc_data {
- u32 clk_list_mask;
+ u32 mod_list_mask;
void (*set_audio_cif)(struct regmap *regmap,
unsigned int reg,
struct tegra30_ahub_cif_conf *conf);
@@ -524,7 +524,6 @@ struct tegra30_ahub {
struct device *dev;
struct clk *clk_d_audio;
struct clk *clk_apbif;
- int dma_sel;
resource_size_t apbif_addr;
struct regmap *regmap_apbif;
struct regmap *regmap_ahub;
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index 02247fee1cf7..49ad9366add8 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)
return 0;
}
-static int tegra30_i2s_startup(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
- int ret;
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif,
- &i2s->playback_dma_data.addr,
- &i2s->playback_dma_data.slave_id);
- i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
- i2s->playback_dma_data.maxburst = 4;
- tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif,
- i2s->playback_fifo_cif);
- } else {
- ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif,
- &i2s->capture_dma_data.addr,
- &i2s->capture_dma_data.slave_id);
- i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
- i2s->capture_dma_data.maxburst = 4;
- tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif,
- i2s->capture_i2s_cif);
- }
-
- return ret;
-}
-
-static void tegra30_i2s_shutdown(struct snd_pcm_substream *substream,
- struct snd_soc_dai *dai)
-{
- struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif);
- tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
- } else {
- tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif);
- tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif);
- }
-}
-
static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
unsigned int fmt)
{
@@ -317,8 +276,6 @@ static int tegra30_i2s_probe(struct snd_soc_dai *dai)
}
static struct snd_soc_dai_ops tegra30_i2s_dai_ops = {
- .startup = tegra30_i2s_startup,
- .shutdown = tegra30_i2s_shutdown,
.set_fmt = tegra30_i2s_set_fmt,
.hw_params = tegra30_i2s_hw_params,
.trigger = tegra30_i2s_trigger,
@@ -499,15 +456,51 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
goto err_pm_disable;
}
+ i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ i2s->playback_dma_data.maxburst = 4;
+ ret = tegra30_ahub_allocate_tx_fifo(&i2s->playback_fifo_cif,
+ i2s->playback_dma_chan,
+ sizeof(i2s->playback_dma_chan),
+ &i2s->playback_dma_data.addr);
+ if (ret) {
+ dev_err(&pdev->dev, "Could not alloc TX FIFO: %d\n", ret);
+ goto err_suspend;
+ }
+ ret = tegra30_ahub_set_rx_cif_source(i2s->playback_i2s_cif,
+ i2s->playback_fifo_cif);
+ if (ret) {
+ dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret);
+ goto err_free_tx_fifo;
+ }
+
+ i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+ i2s->capture_dma_data.maxburst = 4;
+ ret = tegra30_ahub_allocate_rx_fifo(&i2s->capture_fifo_cif,
+ i2s->capture_dma_chan,
+ sizeof(i2s->capture_dma_chan),
+ &i2s->capture_dma_data.addr);
+ if (ret) {
+ dev_err(&pdev->dev, "Could not alloc RX FIFO: %d\n", ret);
+ goto err_unroute_tx_fifo;
+ }
+ ret = tegra30_ahub_set_rx_cif_source(i2s->capture_fifo_cif,
+ i2s->capture_i2s_cif);
+ if (ret) {
+ dev_err(&pdev->dev, "Could not route TX FIFO: %d\n", ret);
+ goto err_free_rx_fifo;
+ }
+
ret = snd_soc_register_component(&pdev->dev, &tegra30_i2s_component,
&i2s->dai, 1);
if (ret) {
dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
ret = -ENOMEM;
- goto err_suspend;
+ goto err_unroute_rx_fifo;
}
- ret = tegra_pcm_platform_register(&pdev->dev);
+ ret = tegra_pcm_platform_register_with_chan_names(&pdev->dev,
+ &i2s->dma_config, i2s->playback_dma_chan,
+ i2s->capture_dma_chan);
if (ret) {
dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
goto err_unregister_component;
@@ -517,6 +510,14 @@ static int tegra30_i2s_platform_probe(struct platform_device *pdev)
err_unregister_component:
snd_soc_unregister_component(&pdev->dev);
+err_unroute_rx_fifo:
+ tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif);
+err_free_rx_fifo:
+ tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif);
+err_unroute_tx_fifo:
+ tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif);
+err_free_tx_fifo:
+ tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
err_suspend:
if (!pm_runtime_status_suspended(&pdev->dev))
tegra30_i2s_runtime_suspend(&pdev->dev);
@@ -539,6 +540,12 @@ static int tegra30_i2s_platform_remove(struct platform_device *pdev)
tegra_pcm_platform_unregister(&pdev->dev);
snd_soc_unregister_component(&pdev->dev);
+ tegra30_ahub_unset_rx_cif_source(i2s->capture_fifo_cif);
+ tegra30_ahub_free_rx_fifo(i2s->capture_fifo_cif);
+
+ tegra30_ahub_unset_rx_cif_source(i2s->playback_i2s_cif);
+ tegra30_ahub_free_tx_fifo(i2s->playback_fifo_cif);
+
clk_put(i2s->clk_i2s);
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 {
struct clk *clk_i2s;
enum tegra30_ahub_txcif capture_i2s_cif;
enum tegra30_ahub_rxcif capture_fifo_cif;
+ char capture_dma_chan[8];
struct snd_dmaengine_dai_dma_data capture_dma_data;
enum tegra30_ahub_rxcif playback_i2s_cif;
enum tegra30_ahub_txcif playback_fifo_cif;
+ char playback_dma_chan[8];
struct snd_dmaengine_dai_dma_data playback_dma_data;
struct regmap *regmap;
+ struct snd_dmaengine_pcm_config dma_config;
};
#endif
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index c09ffd18791b..93caed500565 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -58,12 +58,23 @@ static const struct snd_dmaengine_pcm_config tegra_dmaengine_pcm_config = {
int tegra_pcm_platform_register(struct device *dev)
{
- return snd_dmaengine_pcm_register(dev, &tegra_dmaengine_pcm_config,
- SND_DMAENGINE_PCM_FLAG_NO_DT |
- SND_DMAENGINE_PCM_FLAG_COMPAT);
+ return snd_dmaengine_pcm_register(dev, &tegra_dmaengine_pcm_config, 0);
}
EXPORT_SYMBOL_GPL(tegra_pcm_platform_register);
+int tegra_pcm_platform_register_with_chan_names(struct device *dev,
+ struct snd_dmaengine_pcm_config *config,
+ char *txdmachan, char *rxdmachan)
+{
+ *config = tegra_dmaengine_pcm_config;
+ config->dma_dev = dev->parent;
+ config->chan_names[0] = txdmachan;
+ config->chan_names[1] = rxdmachan;
+
+ return snd_dmaengine_pcm_register(dev, config, 0);
+}
+EXPORT_SYMBOL_GPL(tegra_pcm_platform_register_with_chan_names);
+
void tegra_pcm_platform_unregister(struct device *dev)
{
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 @@
#ifndef __TEGRA_PCM_H__
#define __TEGRA_PCM_H__
+struct snd_dmaengine_pcm_config;
+
int tegra_pcm_platform_register(struct device *dev);
+int tegra_pcm_platform_register_with_chan_names(struct device *dev,
+ struct snd_dmaengine_pcm_config *config,
+ char *txdmachan, char *rxdmachan);
void tegra_pcm_platform_unregister(struct device *dev);
#endif