aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/codecs/wm8990.c40
-rw-r--r--sound/soc/davinci/Kconfig7
-rw-r--r--sound/soc/davinci/davinci-evm.c63
-rw-r--r--sound/soc/davinci/davinci-i2s.c26
-rw-r--r--sound/soc/davinci/davinci-pcm.c71
-rw-r--r--sound/soc/soc-core.c3
6 files changed, 144 insertions, 66 deletions
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index c518c3e5aa3f..40cd274eb1ef 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -729,7 +729,7 @@ SND_SOC_DAPM_MIXER_E("INMIXL", WM8990_INTDRIVBITS, WM8990_INMIXL_PWR_BIT, 0,
729 inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 729 inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
730 730
731/* AINLMUX */ 731/* AINLMUX */
732SND_SOC_DAPM_MUX_E("AILNMUX", WM8990_INTDRIVBITS, WM8990_AINLMUX_PWR_BIT, 0, 732SND_SOC_DAPM_MUX_E("AINLMUX", WM8990_INTDRIVBITS, WM8990_AINLMUX_PWR_BIT, 0,
733 &wm8990_dapm_ainlmux_controls, inmixer_event, 733 &wm8990_dapm_ainlmux_controls, inmixer_event,
734 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 734 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
735 735
@@ -740,7 +740,7 @@ SND_SOC_DAPM_MIXER_E("INMIXR", WM8990_INTDRIVBITS, WM8990_INMIXR_PWR_BIT, 0,
740 inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 740 inmixer_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
741 741
742/* AINRMUX */ 742/* AINRMUX */
743SND_SOC_DAPM_MUX_E("AIRNMUX", WM8990_INTDRIVBITS, WM8990_AINRMUX_PWR_BIT, 0, 743SND_SOC_DAPM_MUX_E("AINRMUX", WM8990_INTDRIVBITS, WM8990_AINRMUX_PWR_BIT, 0,
744 &wm8990_dapm_ainrmux_controls, inmixer_event, 744 &wm8990_dapm_ainrmux_controls, inmixer_event,
745 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 745 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
746 746
@@ -848,40 +848,40 @@ static const struct snd_soc_dapm_route audio_map[] = {
848 {"LIN12 PGA", "LIN2 Switch", "LIN2"}, 848 {"LIN12 PGA", "LIN2 Switch", "LIN2"},
849 /* LIN34 PGA */ 849 /* LIN34 PGA */
850 {"LIN34 PGA", "LIN3 Switch", "LIN3"}, 850 {"LIN34 PGA", "LIN3 Switch", "LIN3"},
851 {"LIN34 PGA", "LIN4 Switch", "LIN4"}, 851 {"LIN34 PGA", "LIN4 Switch", "LIN4/RXN"},
852 /* INMIXL */ 852 /* INMIXL */
853 {"INMIXL", "Record Left Volume", "LOMIX"}, 853 {"INMIXL", "Record Left Volume", "LOMIX"},
854 {"INMIXL", "LIN2 Volume", "LIN2"}, 854 {"INMIXL", "LIN2 Volume", "LIN2"},
855 {"INMIXL", "LINPGA12 Switch", "LIN12 PGA"}, 855 {"INMIXL", "LINPGA12 Switch", "LIN12 PGA"},
856 {"INMIXL", "LINPGA34 Switch", "LIN34 PGA"}, 856 {"INMIXL", "LINPGA34 Switch", "LIN34 PGA"},
857 /* AILNMUX */ 857 /* AINLMUX */
858 {"AILNMUX", "INMIXL Mix", "INMIXL"}, 858 {"AINLMUX", "INMIXL Mix", "INMIXL"},
859 {"AILNMUX", "DIFFINL Mix", "LIN12PGA"}, 859 {"AINLMUX", "DIFFINL Mix", "LIN12 PGA"},
860 {"AILNMUX", "DIFFINL Mix", "LIN34PGA"}, 860 {"AINLMUX", "DIFFINL Mix", "LIN34 PGA"},
861 {"AILNMUX", "RXVOICE Mix", "LIN4/RXN"}, 861 {"AINLMUX", "RXVOICE Mix", "LIN4/RXN"},
862 {"AILNMUX", "RXVOICE Mix", "RIN4/RXP"}, 862 {"AINLMUX", "RXVOICE Mix", "RIN4/RXP"},
863 /* ADC */ 863 /* ADC */
864 {"Left ADC", NULL, "AILNMUX"}, 864 {"Left ADC", NULL, "AINLMUX"},
865 865
866 /* RIN12 PGA */ 866 /* RIN12 PGA */
867 {"RIN12 PGA", "RIN1 Switch", "RIN1"}, 867 {"RIN12 PGA", "RIN1 Switch", "RIN1"},
868 {"RIN12 PGA", "RIN2 Switch", "RIN2"}, 868 {"RIN12 PGA", "RIN2 Switch", "RIN2"},
869 /* RIN34 PGA */ 869 /* RIN34 PGA */
870 {"RIN34 PGA", "RIN3 Switch", "RIN3"}, 870 {"RIN34 PGA", "RIN3 Switch", "RIN3"},
871 {"RIN34 PGA", "RIN4 Switch", "RIN4"}, 871 {"RIN34 PGA", "RIN4 Switch", "RIN4/RXP"},
872 /* INMIXL */ 872 /* INMIXL */
873 {"INMIXR", "Record Right Volume", "ROMIX"}, 873 {"INMIXR", "Record Right Volume", "ROMIX"},
874 {"INMIXR", "RIN2 Volume", "RIN2"}, 874 {"INMIXR", "RIN2 Volume", "RIN2"},
875 {"INMIXR", "RINPGA12 Switch", "RIN12 PGA"}, 875 {"INMIXR", "RINPGA12 Switch", "RIN12 PGA"},
876 {"INMIXR", "RINPGA34 Switch", "RIN34 PGA"}, 876 {"INMIXR", "RINPGA34 Switch", "RIN34 PGA"},
877 /* AIRNMUX */ 877 /* AINRMUX */
878 {"AIRNMUX", "INMIXR Mix", "INMIXR"}, 878 {"AINRMUX", "INMIXR Mix", "INMIXR"},
879 {"AIRNMUX", "DIFFINR Mix", "RIN12PGA"}, 879 {"AINRMUX", "DIFFINR Mix", "RIN12 PGA"},
880 {"AIRNMUX", "DIFFINR Mix", "RIN34PGA"}, 880 {"AINRMUX", "DIFFINR Mix", "RIN34 PGA"},
881 {"AIRNMUX", "RXVOICE Mix", "RIN4/RXN"}, 881 {"AINRMUX", "RXVOICE Mix", "LIN4/RXN"},
882 {"AIRNMUX", "RXVOICE Mix", "RIN4/RXP"}, 882 {"AINRMUX", "RXVOICE Mix", "RIN4/RXP"},
883 /* ADC */ 883 /* ADC */
884 {"Right ADC", NULL, "AIRNMUX"}, 884 {"Right ADC", NULL, "AINRMUX"},
885 885
886 /* LOMIX */ 886 /* LOMIX */
887 {"LOMIX", "LOMIX RIN3 Bypass Switch", "RIN3"}, 887 {"LOMIX", "LOMIX RIN3 Bypass Switch", "RIN3"},
@@ -922,7 +922,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
922 {"LOPMIX", "LOPMIX Left Mixer PGA Switch", "LOPGA"}, 922 {"LOPMIX", "LOPMIX Left Mixer PGA Switch", "LOPGA"},
923 923
924 /* OUT3MIX */ 924 /* OUT3MIX */
925 {"OUT3MIX", "OUT3MIX LIN4/RXP Bypass Switch", "LIN4/RXP"}, 925 {"OUT3MIX", "OUT3MIX LIN4/RXP Bypass Switch", "LIN4/RXN"},
926 {"OUT3MIX", "OUT3MIX Left Out PGA Switch", "LOPGA"}, 926 {"OUT3MIX", "OUT3MIX Left Out PGA Switch", "LOPGA"},
927 927
928 /* OUT4MIX */ 928 /* OUT4MIX */
@@ -949,7 +949,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
949 /* Output Pins */ 949 /* Output Pins */
950 {"LON", NULL, "LONMIX"}, 950 {"LON", NULL, "LONMIX"},
951 {"LOP", NULL, "LOPMIX"}, 951 {"LOP", NULL, "LOPMIX"},
952 {"OUT", NULL, "OUT3MIX"}, 952 {"OUT3", NULL, "OUT3MIX"},
953 {"LOUT", NULL, "LOUT PGA"}, 953 {"LOUT", NULL, "LOUT PGA"},
954 {"SPKN", NULL, "SPKMIX"}, 954 {"SPKN", NULL, "SPKMIX"},
955 {"ROUT", NULL, "ROUT PGA"}, 955 {"ROUT", NULL, "ROUT PGA"},
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig
index bd7392c9657e..411a710be660 100644
--- a/sound/soc/davinci/Kconfig
+++ b/sound/soc/davinci/Kconfig
@@ -10,13 +10,14 @@ config SND_DAVINCI_SOC_I2S
10 tristate 10 tristate
11 11
12config SND_DAVINCI_SOC_EVM 12config SND_DAVINCI_SOC_EVM
13 tristate "SoC Audio support for DaVinci EVM" 13 tristate "SoC Audio support for DaVinci DM6446 or DM355 EVM"
14 depends on SND_DAVINCI_SOC && MACH_DAVINCI_EVM 14 depends on SND_DAVINCI_SOC
15 depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM
15 select SND_DAVINCI_SOC_I2S 16 select SND_DAVINCI_SOC_I2S
16 select SND_SOC_TLV320AIC3X 17 select SND_SOC_TLV320AIC3X
17 help 18 help
18 Say Y if you want to add support for SoC audio on TI 19 Say Y if you want to add support for SoC audio on TI
19 DaVinci EVM platform. 20 DaVinci DM6446 or DM355 EVM platforms.
20 21
21config SND_DAVINCI_SOC_SFFSDR 22config SND_DAVINCI_SOC_SFFSDR
22 tristate "SoC Audio support for SFFSDR" 23 tristate "SoC Audio support for SFFSDR"
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 9b90b347007c..58fd1cbedd88 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -20,7 +20,11 @@
20#include <sound/soc-dapm.h> 20#include <sound/soc-dapm.h>
21 21
22#include <asm/dma.h> 22#include <asm/dma.h>
23#include <mach/hardware.h> 23#include <asm/mach-types.h>
24
25#include <mach/asp.h>
26#include <mach/edma.h>
27#include <mach/mux.h>
24 28
25#include "../codecs/tlv320aic3x.h" 29#include "../codecs/tlv320aic3x.h"
26#include "davinci-pcm.h" 30#include "davinci-pcm.h"
@@ -150,7 +154,7 @@ static struct snd_soc_card snd_soc_card_evm = {
150 154
151/* evm audio private data */ 155/* evm audio private data */
152static struct aic3x_setup_data evm_aic3x_setup = { 156static struct aic3x_setup_data evm_aic3x_setup = {
153 .i2c_bus = 0, 157 .i2c_bus = 1,
154 .i2c_address = 0x1b, 158 .i2c_address = 0x1b,
155}; 159};
156 160
@@ -161,36 +165,73 @@ static struct snd_soc_device evm_snd_devdata = {
161 .codec_data = &evm_aic3x_setup, 165 .codec_data = &evm_aic3x_setup,
162}; 166};
163 167
168/* DM6446 EVM uses ASP0; line-out is a pair of RCA jacks */
164static struct resource evm_snd_resources[] = { 169static struct resource evm_snd_resources[] = {
165 { 170 {
166 .start = DAVINCI_MCBSP_BASE, 171 .start = DAVINCI_ASP0_BASE,
167 .end = DAVINCI_MCBSP_BASE + SZ_8K - 1, 172 .end = DAVINCI_ASP0_BASE + SZ_8K - 1,
168 .flags = IORESOURCE_MEM, 173 .flags = IORESOURCE_MEM,
169 }, 174 },
170}; 175};
171 176
172static struct evm_snd_platform_data evm_snd_data = { 177static struct evm_snd_platform_data evm_snd_data = {
173 .tx_dma_ch = DM644X_DMACH_MCBSP_TX, 178 .tx_dma_ch = DAVINCI_DMA_ASP0_TX,
174 .rx_dma_ch = DM644X_DMACH_MCBSP_RX, 179 .rx_dma_ch = DAVINCI_DMA_ASP0_RX,
180};
181
182/* DM335 EVM uses ASP1; line-out is a stereo mini-jack */
183static struct resource dm335evm_snd_resources[] = {
184 {
185 .start = DAVINCI_ASP1_BASE,
186 .end = DAVINCI_ASP1_BASE + SZ_8K - 1,
187 .flags = IORESOURCE_MEM,
188 },
189};
190
191static struct evm_snd_platform_data dm335evm_snd_data = {
192 .tx_dma_ch = DAVINCI_DMA_ASP1_TX,
193 .rx_dma_ch = DAVINCI_DMA_ASP1_RX,
175}; 194};
176 195
177static struct platform_device *evm_snd_device; 196static struct platform_device *evm_snd_device;
178 197
179static int __init evm_init(void) 198static int __init evm_init(void)
180{ 199{
200 struct resource *resources;
201 unsigned num_resources;
202 struct evm_snd_platform_data *data;
203 int index;
181 int ret; 204 int ret;
182 205
183 evm_snd_device = platform_device_alloc("soc-audio", 0); 206 if (machine_is_davinci_evm()) {
207 davinci_cfg_reg(DM644X_MCBSP);
208
209 resources = evm_snd_resources;
210 num_resources = ARRAY_SIZE(evm_snd_resources);
211 data = &evm_snd_data;
212 index = 0;
213 } else if (machine_is_davinci_dm355_evm()) {
214 /* we don't use ASP1 IRQs, or we'd need to mux them ... */
215 davinci_cfg_reg(DM355_EVT8_ASP1_TX);
216 davinci_cfg_reg(DM355_EVT9_ASP1_RX);
217
218 resources = dm335evm_snd_resources;
219 num_resources = ARRAY_SIZE(dm335evm_snd_resources);
220 data = &dm335evm_snd_data;
221 index = 1;
222 } else
223 return -EINVAL;
224
225 evm_snd_device = platform_device_alloc("soc-audio", index);
184 if (!evm_snd_device) 226 if (!evm_snd_device)
185 return -ENOMEM; 227 return -ENOMEM;
186 228
187 platform_set_drvdata(evm_snd_device, &evm_snd_devdata); 229 platform_set_drvdata(evm_snd_device, &evm_snd_devdata);
188 evm_snd_devdata.dev = &evm_snd_device->dev; 230 evm_snd_devdata.dev = &evm_snd_device->dev;
189 platform_device_add_data(evm_snd_device, &evm_snd_data, 231 platform_device_add_data(evm_snd_device, data, sizeof(*data));
190 sizeof(evm_snd_data));
191 232
192 ret = platform_device_add_resources(evm_snd_device, evm_snd_resources, 233 ret = platform_device_add_resources(evm_snd_device, resources,
193 ARRAY_SIZE(evm_snd_resources)); 234 num_resources);
194 if (ret) { 235 if (ret) {
195 platform_device_put(evm_snd_device); 236 platform_device_put(evm_snd_device);
196 return ret; 237 return ret;
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index ffdb9439d3d8..b1ea52fc83c7 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -24,6 +24,26 @@
24 24
25#include "davinci-pcm.h" 25#include "davinci-pcm.h"
26 26
27
28/*
29 * NOTE: terminology here is confusing.
30 *
31 * - This driver supports the "Audio Serial Port" (ASP),
32 * found on dm6446, dm355, and other DaVinci chips.
33 *
34 * - But it labels it a "Multi-channel Buffered Serial Port"
35 * (McBSP) as on older chips like the dm642 ... which was
36 * backward-compatible, possibly explaining that confusion.
37 *
38 * - OMAP chips have a controller called McBSP, which is
39 * incompatible with the DaVinci flavor of McBSP.
40 *
41 * - Newer DaVinci chips have a controller called McASP,
42 * incompatible with ASP and with either McBSP.
43 *
44 * In short: this uses ASP to implement I2S, not McBSP.
45 * And it won't be the only DaVinci implemention of I2S.
46 */
27#define DAVINCI_MCBSP_DRR_REG 0x00 47#define DAVINCI_MCBSP_DRR_REG 0x00
28#define DAVINCI_MCBSP_DXR_REG 0x04 48#define DAVINCI_MCBSP_DXR_REG 0x04
29#define DAVINCI_MCBSP_SPCR_REG 0x08 49#define DAVINCI_MCBSP_SPCR_REG 0x08
@@ -421,7 +441,7 @@ static int davinci_i2s_probe(struct platform_device *pdev,
421{ 441{
422 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 442 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
423 struct snd_soc_card *card = socdev->card; 443 struct snd_soc_card *card = socdev->card;
424 struct snd_soc_dai *cpu_dai = card->dai_link[pdev->id].cpu_dai; 444 struct snd_soc_dai *cpu_dai = card->dai_link->cpu_dai;
425 struct davinci_mcbsp_dev *dev; 445 struct davinci_mcbsp_dev *dev;
426 struct resource *mem, *ioarea; 446 struct resource *mem, *ioarea;
427 struct evm_snd_platform_data *pdata; 447 struct evm_snd_platform_data *pdata;
@@ -448,7 +468,7 @@ static int davinci_i2s_probe(struct platform_device *pdev,
448 468
449 cpu_dai->private_data = dev; 469 cpu_dai->private_data = dev;
450 470
451 dev->clk = clk_get(&pdev->dev, "McBSPCLK"); 471 dev->clk = clk_get(&pdev->dev, NULL);
452 if (IS_ERR(dev->clk)) { 472 if (IS_ERR(dev->clk)) {
453 ret = -ENODEV; 473 ret = -ENODEV;
454 goto err_free_mem; 474 goto err_free_mem;
@@ -483,7 +503,7 @@ static void davinci_i2s_remove(struct platform_device *pdev,
483{ 503{
484 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 504 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
485 struct snd_soc_card *card = socdev->card; 505 struct snd_soc_card *card = socdev->card;
486 struct snd_soc_dai *cpu_dai = card->dai_link[pdev->id].cpu_dai; 506 struct snd_soc_dai *cpu_dai = card->dai_link->cpu_dai;
487 struct davinci_mcbsp_dev *dev = cpu_dai->private_data; 507 struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
488 struct resource *mem; 508 struct resource *mem;
489 509
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index 7af3b5b3a53d..a05996588489 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -22,6 +22,7 @@
22#include <sound/soc.h> 22#include <sound/soc.h>
23 23
24#include <asm/dma.h> 24#include <asm/dma.h>
25#include <mach/edma.h>
25 26
26#include "davinci-pcm.h" 27#include "davinci-pcm.h"
27 28
@@ -51,7 +52,7 @@ struct davinci_runtime_data {
51 spinlock_t lock; 52 spinlock_t lock;
52 int period; /* current DMA period */ 53 int period; /* current DMA period */
53 int master_lch; /* Master DMA channel */ 54 int master_lch; /* Master DMA channel */
54 int slave_lch; /* Slave DMA channel */ 55 int slave_lch; /* linked parameter RAM reload slot */
55 struct davinci_pcm_dma_params *params; /* DMA params */ 56 struct davinci_pcm_dma_params *params; /* DMA params */
56}; 57};
57 58
@@ -90,18 +91,18 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
90 dst_bidx = data_type; 91 dst_bidx = data_type;
91 } 92 }
92 93
93 davinci_set_dma_src_params(lch, src, INCR, W8BIT); 94 edma_set_src(lch, src, INCR, W8BIT);
94 davinci_set_dma_dest_params(lch, dst, INCR, W8BIT); 95 edma_set_dest(lch, dst, INCR, W8BIT);
95 davinci_set_dma_src_index(lch, src_bidx, 0); 96 edma_set_src_index(lch, src_bidx, 0);
96 davinci_set_dma_dest_index(lch, dst_bidx, 0); 97 edma_set_dest_index(lch, dst_bidx, 0);
97 davinci_set_dma_transfer_params(lch, data_type, count, 1, 0, ASYNC); 98 edma_set_transfer_params(lch, data_type, count, 1, 0, ASYNC);
98 99
99 prtd->period++; 100 prtd->period++;
100 if (unlikely(prtd->period >= runtime->periods)) 101 if (unlikely(prtd->period >= runtime->periods))
101 prtd->period = 0; 102 prtd->period = 0;
102} 103}
103 104
104static void davinci_pcm_dma_irq(int lch, u16 ch_status, void *data) 105static void davinci_pcm_dma_irq(unsigned lch, u16 ch_status, void *data)
105{ 106{
106 struct snd_pcm_substream *substream = data; 107 struct snd_pcm_substream *substream = data;
107 struct davinci_runtime_data *prtd = substream->runtime->private_data; 108 struct davinci_runtime_data *prtd = substream->runtime->private_data;
@@ -125,7 +126,7 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
125 struct davinci_runtime_data *prtd = substream->runtime->private_data; 126 struct davinci_runtime_data *prtd = substream->runtime->private_data;
126 struct snd_soc_pcm_runtime *rtd = substream->private_data; 127 struct snd_soc_pcm_runtime *rtd = substream->private_data;
127 struct davinci_pcm_dma_params *dma_data = rtd->dai->cpu_dai->dma_data; 128 struct davinci_pcm_dma_params *dma_data = rtd->dai->cpu_dai->dma_data;
128 int tcc = TCC_ANY; 129 struct edmacc_param p_ram;
129 int ret; 130 int ret;
130 131
131 if (!dma_data) 132 if (!dma_data)
@@ -134,22 +135,34 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
134 prtd->params = dma_data; 135 prtd->params = dma_data;
135 136
136 /* Request master DMA channel */ 137 /* Request master DMA channel */
137 ret = davinci_request_dma(prtd->params->channel, prtd->params->name, 138 ret = edma_alloc_channel(prtd->params->channel,
138 davinci_pcm_dma_irq, substream, 139 davinci_pcm_dma_irq, substream,
139 &prtd->master_lch, &tcc, EVENTQ_0); 140 EVENTQ_0);
140 if (ret) 141 if (ret < 0)
141 return ret; 142 return ret;
143 prtd->master_lch = ret;
142 144
143 /* Request slave DMA channel */ 145 /* Request parameter RAM reload slot */
144 ret = davinci_request_dma(PARAM_ANY, "Link", 146 ret = edma_alloc_slot(EDMA_SLOT_ANY);
145 NULL, NULL, &prtd->slave_lch, &tcc, EVENTQ_0); 147 if (ret < 0) {
146 if (ret) { 148 edma_free_channel(prtd->master_lch);
147 davinci_free_dma(prtd->master_lch);
148 return ret; 149 return ret;
149 } 150 }
150 151 prtd->slave_lch = ret;
151 /* Link slave DMA channel in loopback */ 152
152 davinci_dma_link_lch(prtd->slave_lch, prtd->slave_lch); 153 /* Issue transfer completion IRQ when the channel completes a
154 * transfer, then always reload from the same slot (by a kind
155 * of loopback link). The completion IRQ handler will update
156 * the reload slot with a new buffer.
157 *
158 * REVISIT save p_ram here after setting up everything except
159 * the buffer and its length (ccnt) ... use it as a template
160 * so davinci_pcm_enqueue_dma() takes less time in IRQ.
161 */
162 edma_read_slot(prtd->slave_lch, &p_ram);
163 p_ram.opt |= TCINTEN | EDMA_TCC(prtd->master_lch);
164 p_ram.link_bcntrld = prtd->slave_lch << 5;
165 edma_write_slot(prtd->slave_lch, &p_ram);
153 166
154 return 0; 167 return 0;
155} 168}
@@ -165,12 +178,12 @@ static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
165 case SNDRV_PCM_TRIGGER_START: 178 case SNDRV_PCM_TRIGGER_START:
166 case SNDRV_PCM_TRIGGER_RESUME: 179 case SNDRV_PCM_TRIGGER_RESUME:
167 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 180 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
168 davinci_start_dma(prtd->master_lch); 181 edma_start(prtd->master_lch);
169 break; 182 break;
170 case SNDRV_PCM_TRIGGER_STOP: 183 case SNDRV_PCM_TRIGGER_STOP:
171 case SNDRV_PCM_TRIGGER_SUSPEND: 184 case SNDRV_PCM_TRIGGER_SUSPEND:
172 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 185 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
173 davinci_stop_dma(prtd->master_lch); 186 edma_stop(prtd->master_lch);
174 break; 187 break;
175 default: 188 default:
176 ret = -EINVAL; 189 ret = -EINVAL;
@@ -185,14 +198,14 @@ static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
185static int davinci_pcm_prepare(struct snd_pcm_substream *substream) 198static int davinci_pcm_prepare(struct snd_pcm_substream *substream)
186{ 199{
187 struct davinci_runtime_data *prtd = substream->runtime->private_data; 200 struct davinci_runtime_data *prtd = substream->runtime->private_data;
188 struct paramentry_descriptor temp; 201 struct edmacc_param temp;
189 202
190 prtd->period = 0; 203 prtd->period = 0;
191 davinci_pcm_enqueue_dma(substream); 204 davinci_pcm_enqueue_dma(substream);
192 205
193 /* Get slave channel dma params for master channel startup */ 206 /* Copy self-linked parameter RAM entry into master channel */
194 davinci_get_dma_params(prtd->slave_lch, &temp); 207 edma_read_slot(prtd->slave_lch, &temp);
195 davinci_set_dma_params(prtd->master_lch, &temp); 208 edma_write_slot(prtd->master_lch, &temp);
196 209
197 return 0; 210 return 0;
198} 211}
@@ -208,7 +221,7 @@ davinci_pcm_pointer(struct snd_pcm_substream *substream)
208 221
209 spin_lock(&prtd->lock); 222 spin_lock(&prtd->lock);
210 223
211 davinci_dma_getposition(prtd->master_lch, &src, &dst); 224 edma_get_position(prtd->master_lch, &src, &dst);
212 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 225 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
213 count = src - runtime->dma_addr; 226 count = src - runtime->dma_addr;
214 else 227 else
@@ -253,10 +266,10 @@ static int davinci_pcm_close(struct snd_pcm_substream *substream)
253 struct snd_pcm_runtime *runtime = substream->runtime; 266 struct snd_pcm_runtime *runtime = substream->runtime;
254 struct davinci_runtime_data *prtd = runtime->private_data; 267 struct davinci_runtime_data *prtd = runtime->private_data;
255 268
256 davinci_dma_unlink_lch(prtd->slave_lch, prtd->slave_lch); 269 edma_unlink(prtd->slave_lch);
257 270
258 davinci_free_dma(prtd->slave_lch); 271 edma_free_slot(prtd->slave_lch);
259 davinci_free_dma(prtd->master_lch); 272 edma_free_channel(prtd->master_lch);
260 273
261 kfree(prtd); 274 kfree(prtd);
262 275
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 99712f652d0d..1cd149b9ce69 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -954,6 +954,9 @@ static int soc_remove(struct platform_device *pdev)
954 struct snd_soc_platform *platform = card->platform; 954 struct snd_soc_platform *platform = card->platform;
955 struct snd_soc_codec_device *codec_dev = socdev->codec_dev; 955 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
956 956
957 if (!card->instantiated)
958 return 0;
959
957 run_delayed_work(&card->delayed_work); 960 run_delayed_work(&card->delayed_work);
958 961
959 if (platform->remove) 962 if (platform->remove)