aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/atmel/Kconfig5
-rw-r--r--sound/soc/codecs/max98088.c11
-rw-r--r--sound/soc/codecs/uda134x.c1
-rw-r--r--sound/soc/codecs/wm8350.c9
-rw-r--r--sound/soc/codecs/wm8776.c1
-rw-r--r--sound/soc/codecs/wm8962.c5
-rw-r--r--sound/soc/codecs/wm8994.c2
-rw-r--r--sound/soc/davinci/davinci-evm.c40
-rw-r--r--sound/soc/davinci/davinci-i2s.c15
-rw-r--r--sound/soc/davinci/davinci-mcasp.c13
-rw-r--r--sound/soc/davinci/davinci-sffsdr.c2
-rw-r--r--sound/soc/davinci/davinci-vcif.c13
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c2
-rw-r--r--sound/soc/imx/eukrea-tlv320.c8
-rw-r--r--sound/soc/imx/imx-pcm-dma-mx2.c221
-rw-r--r--sound/soc/imx/imx-ssi.c44
-rw-r--r--sound/soc/imx/imx-ssi.h4
-rw-r--r--sound/soc/imx/phycore-ac97.c5
-rw-r--r--sound/soc/omap/omap-mcbsp.c8
-rw-r--r--sound/soc/pxa/corgi.c5
-rw-r--r--sound/soc/pxa/magician.c4
-rw-r--r--sound/soc/pxa/poodle.c5
-rw-r--r--sound/soc/pxa/spitz.c5
-rw-r--r--sound/soc/pxa/tosa.c5
-rw-r--r--sound/soc/s3c24xx/Kconfig1
-rw-r--r--sound/soc/s3c24xx/rx1950_uda1380.c20
-rw-r--r--sound/soc/soc-core.c9
-rw-r--r--sound/soc/soc-dapm.c4
28 files changed, 268 insertions, 199 deletions
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
index e720d5e6f04..bee3c94f58b 100644
--- a/sound/soc/atmel/Kconfig
+++ b/sound/soc/atmel/Kconfig
@@ -16,7 +16,8 @@ config SND_ATMEL_SOC_SSC
16 16
17config SND_AT91_SOC_SAM9G20_WM8731 17config SND_AT91_SOC_SAM9G20_WM8731
18 tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board" 18 tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
19 depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC 19 depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC && \
20 AT91_PROGRAMMABLE_CLOCKS
20 select SND_ATMEL_SOC_SSC 21 select SND_ATMEL_SOC_SSC
21 select SND_SOC_WM8731 22 select SND_SOC_WM8731
22 help 23 help
@@ -25,7 +26,7 @@ config SND_AT91_SOC_SAM9G20_WM8731
25 26
26config SND_AT32_SOC_PLAYPAQ 27config SND_AT32_SOC_PLAYPAQ
27 tristate "SoC Audio support for PlayPaq with WM8510" 28 tristate "SoC Audio support for PlayPaq with WM8510"
28 depends on SND_ATMEL_SOC && BOARD_PLAYPAQ 29 depends on SND_ATMEL_SOC && BOARD_PLAYPAQ && AT91_PROGRAMMABLE_CLOCKS
29 select SND_ATMEL_SOC_SSC 30 select SND_ATMEL_SOC_SSC
30 select SND_SOC_WM8510 31 select SND_SOC_WM8510
31 help 32 help
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index bc22ee93a75..470cb93b1d1 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -28,6 +28,11 @@
28#include <sound/max98088.h> 28#include <sound/max98088.h>
29#include "max98088.h" 29#include "max98088.h"
30 30
31enum max98088_type {
32 MAX98088,
33 MAX98089,
34};
35
31struct max98088_cdata { 36struct max98088_cdata {
32 unsigned int rate; 37 unsigned int rate;
33 unsigned int fmt; 38 unsigned int fmt;
@@ -36,6 +41,7 @@ struct max98088_cdata {
36 41
37struct max98088_priv { 42struct max98088_priv {
38 u8 reg_cache[M98088_REG_CNT]; 43 u8 reg_cache[M98088_REG_CNT];
44 enum max98088_type devtype;
39 void *control_data; 45 void *control_data;
40 struct max98088_pdata *pdata; 46 struct max98088_pdata *pdata;
41 unsigned int sysclk; 47 unsigned int sysclk;
@@ -2040,6 +2046,8 @@ static int max98088_i2c_probe(struct i2c_client *i2c,
2040 if (max98088 == NULL) 2046 if (max98088 == NULL)
2041 return -ENOMEM; 2047 return -ENOMEM;
2042 2048
2049 max98088->devtype = id->driver_data;
2050
2043 i2c_set_clientdata(i2c, max98088); 2051 i2c_set_clientdata(i2c, max98088);
2044 max98088->control_data = i2c; 2052 max98088->control_data = i2c;
2045 max98088->pdata = i2c->dev.platform_data; 2053 max98088->pdata = i2c->dev.platform_data;
@@ -2059,7 +2067,8 @@ static int __devexit max98088_i2c_remove(struct i2c_client *client)
2059} 2067}
2060 2068
2061static const struct i2c_device_id max98088_i2c_id[] = { 2069static const struct i2c_device_id max98088_i2c_id[] = {
2062 { "max98088", 0 }, 2070 { "max98088", MAX98088 },
2071 { "max98089", MAX98089 },
2063 { } 2072 { }
2064}; 2073};
2065MODULE_DEVICE_TABLE(i2c, max98088_i2c_id); 2074MODULE_DEVICE_TABLE(i2c, max98088_i2c_id);
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index 7540a509a6f..464f0cfa4c7 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -597,6 +597,7 @@ static struct snd_soc_codec_driver soc_codec_dev_uda134x = {
597 .resume = uda134x_soc_resume, 597 .resume = uda134x_soc_resume,
598 .reg_cache_size = sizeof(uda134x_reg), 598 .reg_cache_size = sizeof(uda134x_reg),
599 .reg_word_size = sizeof(u8), 599 .reg_word_size = sizeof(u8),
600 .reg_cache_default = uda134x_reg,
600 .reg_cache_step = 1, 601 .reg_cache_step = 1,
601 .read = uda134x_read_reg_cache, 602 .read = uda134x_read_reg_cache,
602 .write = uda134x_write, 603 .write = uda134x_write,
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index f4f1fba38eb..7611add7f8c 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -831,7 +831,7 @@ static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
831 } 831 }
832 832
833 /* MCLK direction */ 833 /* MCLK direction */
834 if (dir == WM8350_MCLK_DIR_OUT) 834 if (dir == SND_SOC_CLOCK_OUT)
835 wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_2, 835 wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_2,
836 WM8350_MCLK_DIR); 836 WM8350_MCLK_DIR);
837 else 837 else
@@ -1586,6 +1586,13 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec)
1586 wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME, 1586 wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME,
1587 WM8350_OUT2_VU | WM8350_OUT2R_MUTE); 1587 WM8350_OUT2_VU | WM8350_OUT2R_MUTE);
1588 1588
1589 /* Make sure AIF tristating is disabled by default */
1590 wm8350_clear_bits(wm8350, WM8350_AI_FORMATING, WM8350_AIF_TRI);
1591
1592 /* Make sure we've got a sane companding setup too */
1593 wm8350_clear_bits(wm8350, WM8350_ADC_DAC_COMP,
1594 WM8350_DAC_COMP | WM8350_LOOPBACK);
1595
1589 /* Make sure jack detect is disabled to start off with */ 1596 /* Make sure jack detect is disabled to start off with */
1590 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, 1597 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
1591 WM8350_JDL_ENA | WM8350_JDR_ENA); 1598 WM8350_JDL_ENA | WM8350_JDR_ENA);
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index 04182c464e3..0132a27140a 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -34,7 +34,6 @@
34/* codec private data */ 34/* codec private data */
35struct wm8776_priv { 35struct wm8776_priv {
36 enum snd_soc_control_type control_type; 36 enum snd_soc_control_type control_type;
37 u16 reg_cache[WM8776_CACHEREGNUM];
38 int sysclk[2]; 37 int sysclk[2];
39}; 38};
40 39
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 894d0cd3aa9..e8092745a20 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -3500,8 +3500,11 @@ static ssize_t wm8962_beep_set(struct device *dev,
3500{ 3500{
3501 struct wm8962_priv *wm8962 = dev_get_drvdata(dev); 3501 struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
3502 long int time; 3502 long int time;
3503 int ret;
3503 3504
3504 strict_strtol(buf, 10, &time); 3505 ret = strict_strtol(buf, 10, &time);
3506 if (ret != 0)
3507 return ret;
3505 3508
3506 input_event(wm8962->beep, EV_SND, SND_TONE, time); 3509 input_event(wm8962->beep, EV_SND, SND_TONE, time);
3507 3510
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 0db59c3aa5d..830dfdd66c5 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -3903,6 +3903,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3903 return -ENOMEM; 3903 return -ENOMEM;
3904 snd_soc_codec_set_drvdata(codec, wm8994); 3904 snd_soc_codec_set_drvdata(codec, wm8994);
3905 3905
3906 codec->reg_cache = &wm8994->reg_cache;
3907
3906 wm8994->pdata = dev_get_platdata(codec->dev->parent); 3908 wm8994->pdata = dev_get_platdata(codec->dev->parent);
3907 wm8994->codec = codec; 3909 wm8994->codec = codec;
3908 3910
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 2b07b17a6b2..bc9e6b0b3f6 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -157,12 +157,23 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
157} 157}
158 158
159/* davinci-evm digital audio interface glue - connects codec <--> CPU */ 159/* davinci-evm digital audio interface glue - connects codec <--> CPU */
160static struct snd_soc_dai_link evm_dai = { 160static struct snd_soc_dai_link dm6446_evm_dai = {
161 .name = "TLV320AIC3X", 161 .name = "TLV320AIC3X",
162 .stream_name = "AIC3X", 162 .stream_name = "AIC3X",
163 .cpu_dai_name = "davinci-mcasp.0", 163 .cpu_dai_name = "davinci-mcbsp",
164 .codec_dai_name = "tlv320aic3x-hifi", 164 .codec_dai_name = "tlv320aic3x-hifi",
165 .codec_name = "tlv320aic3x-codec.0-001a", 165 .codec_name = "tlv320aic3x-codec.1-001b",
166 .platform_name = "davinci-pcm-audio",
167 .init = evm_aic3x_init,
168 .ops = &evm_ops,
169};
170
171static struct snd_soc_dai_link dm355_evm_dai = {
172 .name = "TLV320AIC3X",
173 .stream_name = "AIC3X",
174 .cpu_dai_name = "davinci-mcbsp.1",
175 .codec_dai_name = "tlv320aic3x-hifi",
176 .codec_name = "tlv320aic3x-codec.1-001b",
166 .platform_name = "davinci-pcm-audio", 177 .platform_name = "davinci-pcm-audio",
167 .init = evm_aic3x_init, 178 .init = evm_aic3x_init,
168 .ops = &evm_ops, 179 .ops = &evm_ops,
@@ -172,10 +183,10 @@ static struct snd_soc_dai_link dm365_evm_dai = {
172#ifdef CONFIG_SND_DM365_AIC3X_CODEC 183#ifdef CONFIG_SND_DM365_AIC3X_CODEC
173 .name = "TLV320AIC3X", 184 .name = "TLV320AIC3X",
174 .stream_name = "AIC3X", 185 .stream_name = "AIC3X",
175 .cpu_dai_name = "davinci-i2s", 186 .cpu_dai_name = "davinci-mcbsp",
176 .codec_dai_name = "tlv320aic3x-hifi", 187 .codec_dai_name = "tlv320aic3x-hifi",
177 .init = evm_aic3x_init, 188 .init = evm_aic3x_init,
178 .codec_name = "tlv320aic3x-codec.0-001a", 189 .codec_name = "tlv320aic3x-codec.1-0018",
179 .ops = &evm_ops, 190 .ops = &evm_ops,
180#elif defined(CONFIG_SND_DM365_VOICE_CODEC) 191#elif defined(CONFIG_SND_DM365_VOICE_CODEC)
181 .name = "Voice Codec - CQ93VC", 192 .name = "Voice Codec - CQ93VC",
@@ -219,10 +230,17 @@ static struct snd_soc_dai_link da8xx_evm_dai = {
219 .ops = &evm_ops, 230 .ops = &evm_ops,
220}; 231};
221 232
222/* davinci dm6446, dm355 evm audio machine driver */ 233/* davinci dm6446 evm audio machine driver */
223static struct snd_soc_card snd_soc_card_evm = { 234static struct snd_soc_card dm6446_snd_soc_card_evm = {
224 .name = "DaVinci EVM", 235 .name = "DaVinci DM6446 EVM",
225 .dai_link = &evm_dai, 236 .dai_link = &dm6446_evm_dai,
237 .num_links = 1,
238};
239
240/* davinci dm355 evm audio machine driver */
241static struct snd_soc_card dm355_snd_soc_card_evm = {
242 .name = "DaVinci DM355 EVM",
243 .dai_link = &dm355_evm_dai,
226 .num_links = 1, 244 .num_links = 1,
227}; 245};
228 246
@@ -261,10 +279,10 @@ static int __init evm_init(void)
261 int ret; 279 int ret;
262 280
263 if (machine_is_davinci_evm()) { 281 if (machine_is_davinci_evm()) {
264 evm_snd_dev_data = &snd_soc_card_evm; 282 evm_snd_dev_data = &dm6446_snd_soc_card_evm;
265 index = 0; 283 index = 0;
266 } else if (machine_is_davinci_dm355_evm()) { 284 } else if (machine_is_davinci_dm355_evm()) {
267 evm_snd_dev_data = &snd_soc_card_evm; 285 evm_snd_dev_data = &dm355_snd_soc_card_evm;
268 index = 1; 286 index = 1;
269 } else if (machine_is_davinci_dm365_evm()) { 287 } else if (machine_is_davinci_dm365_evm()) {
270 evm_snd_dev_data = &dm365_snd_soc_card_evm; 288 evm_snd_dev_data = &dm365_snd_soc_card_evm;
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index d46b545d41f..9e0e565e6ed 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -426,9 +426,6 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
426 snd_pcm_format_t fmt; 426 snd_pcm_format_t fmt;
427 unsigned element_cnt = 1; 427 unsigned element_cnt = 1;
428 428
429 dai->capture_dma_data = dev->dma_params;
430 dai->playback_dma_data = dev->dma_params;
431
432 /* general line settings */ 429 /* general line settings */
433 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 430 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
434 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 431 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
@@ -601,6 +598,15 @@ static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
601 return ret; 598 return ret;
602} 599}
603 600
601static int davinci_i2s_startup(struct snd_pcm_substream *substream,
602 struct snd_soc_dai *dai)
603{
604 struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
605
606 snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
607 return 0;
608}
609
604static void davinci_i2s_shutdown(struct snd_pcm_substream *substream, 610static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
605 struct snd_soc_dai *dai) 611 struct snd_soc_dai *dai)
606{ 612{
@@ -612,6 +618,7 @@ static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
612#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000 618#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000
613 619
614static struct snd_soc_dai_ops davinci_i2s_dai_ops = { 620static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
621 .startup = davinci_i2s_startup,
615 .shutdown = davinci_i2s_shutdown, 622 .shutdown = davinci_i2s_shutdown,
616 .prepare = davinci_i2s_prepare, 623 .prepare = davinci_i2s_prepare,
617 .trigger = davinci_i2s_trigger, 624 .trigger = davinci_i2s_trigger,
@@ -749,7 +756,7 @@ static struct platform_driver davinci_mcbsp_driver = {
749 .probe = davinci_i2s_probe, 756 .probe = davinci_i2s_probe,
750 .remove = davinci_i2s_remove, 757 .remove = davinci_i2s_remove,
751 .driver = { 758 .driver = {
752 .name = "davinci-i2s", 759 .name = "davinci-mcbsp",
753 .owner = THIS_MODULE, 760 .owner = THIS_MODULE,
754 }, 761 },
755}; 762};
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 86918ee1241..fb55d2c5d70 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -715,9 +715,6 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
715 int word_length; 715 int word_length;
716 u8 fifo_level; 716 u8 fifo_level;
717 717
718 cpu_dai->capture_dma_data = dev->dma_params;
719 cpu_dai->playback_dma_data = dev->dma_params;
720
721 davinci_hw_common_param(dev, substream->stream); 718 davinci_hw_common_param(dev, substream->stream);
722 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 719 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
723 fifo_level = dev->txnumevt; 720 fifo_level = dev->txnumevt;
@@ -799,7 +796,17 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
799 return ret; 796 return ret;
800} 797}
801 798
799static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
800 struct snd_soc_dai *dai)
801{
802 struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai);
803
804 snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
805 return 0;
806}
807
802static struct snd_soc_dai_ops davinci_mcasp_dai_ops = { 808static struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
809 .startup = davinci_mcasp_startup,
803 .trigger = davinci_mcasp_trigger, 810 .trigger = davinci_mcasp_trigger,
804 .hw_params = davinci_mcasp_hw_params, 811 .hw_params = davinci_mcasp_hw_params,
805 .set_fmt = davinci_mcasp_set_dai_fmt, 812 .set_fmt = davinci_mcasp_set_dai_fmt,
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c
index 009b6521a1b..6c6666a1f94 100644
--- a/sound/soc/davinci/davinci-sffsdr.c
+++ b/sound/soc/davinci/davinci-sffsdr.c
@@ -84,7 +84,7 @@ static struct snd_soc_ops sffsdr_ops = {
84static struct snd_soc_dai_link sffsdr_dai = { 84static struct snd_soc_dai_link sffsdr_dai = {
85 .name = "PCM3008", /* Codec name */ 85 .name = "PCM3008", /* Codec name */
86 .stream_name = "PCM3008 HiFi", 86 .stream_name = "PCM3008 HiFi",
87 .cpu_dai_name = "davinci-asp.0", 87 .cpu_dai_name = "davinci-mcbsp",
88 .codec_dai_name = "pcm3008-hifi", 88 .codec_dai_name = "pcm3008-hifi",
89 .codec_name = "pcm3008-codec", 89 .codec_name = "pcm3008-codec",
90 .platform_name = "davinci-pcm-audio", 90 .platform_name = "davinci-pcm-audio",
diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c
index ea232f6a2c2..fb4cc1edf33 100644
--- a/sound/soc/davinci/davinci-vcif.c
+++ b/sound/soc/davinci/davinci-vcif.c
@@ -97,9 +97,6 @@ static int davinci_vcif_hw_params(struct snd_pcm_substream *substream,
97 &davinci_vcif_dev->dma_params[substream->stream]; 97 &davinci_vcif_dev->dma_params[substream->stream];
98 u32 w; 98 u32 w;
99 99
100 dai->capture_dma_data = davinci_vcif_dev->dma_params;
101 dai->playback_dma_data = davinci_vcif_dev->dma_params;
102
103 /* Restart the codec before setup */ 100 /* Restart the codec before setup */
104 davinci_vcif_stop(substream); 101 davinci_vcif_stop(substream);
105 davinci_vcif_start(substream); 102 davinci_vcif_start(substream);
@@ -174,9 +171,19 @@ static int davinci_vcif_trigger(struct snd_pcm_substream *substream, int cmd,
174 return ret; 171 return ret;
175} 172}
176 173
174static int davinci_vcif_startup(struct snd_pcm_substream *substream,
175 struct snd_soc_dai *dai)
176{
177 struct davinci_vcif_dev *dev = snd_soc_dai_get_drvdata(dai);
178
179 snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
180 return 0;
181}
182
177#define DAVINCI_VCIF_RATES SNDRV_PCM_RATE_8000_48000 183#define DAVINCI_VCIF_RATES SNDRV_PCM_RATE_8000_48000
178 184
179static struct snd_soc_dai_ops davinci_vcif_dai_ops = { 185static struct snd_soc_dai_ops davinci_vcif_dai_ops = {
186 .startup = davinci_vcif_startup,
180 .trigger = davinci_vcif_trigger, 187 .trigger = davinci_vcif_trigger,
181 .hw_params = davinci_vcif_hw_params, 188 .hw_params = davinci_vcif_hw_params,
182}; 189};
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index 74ffed41340..9018fa5bf0d 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -160,7 +160,7 @@ static int __devinit psc_i2s_of_probe(struct platform_device *op,
160 rc = snd_soc_register_dais(&op->dev, psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai)); 160 rc = snd_soc_register_dais(&op->dev, psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai));
161 if (rc != 0) { 161 if (rc != 0) {
162 pr_err("Failed to register DAI\n"); 162 pr_err("Failed to register DAI\n");
163 return 0; 163 return rc;
164 } 164 }
165 165
166 psc_dma = dev_get_drvdata(&op->dev); 166 psc_dma = dev_get_drvdata(&op->dev);
diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/imx/eukrea-tlv320.c
index b59675257ce..dd4fffdbd17 100644
--- a/sound/soc/imx/eukrea-tlv320.c
+++ b/sound/soc/imx/eukrea-tlv320.c
@@ -34,8 +34,8 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream,
34 struct snd_pcm_hw_params *params) 34 struct snd_pcm_hw_params *params)
35{ 35{
36 struct snd_soc_pcm_runtime *rtd = substream->private_data; 36 struct snd_soc_pcm_runtime *rtd = substream->private_data;
37 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 37 struct snd_soc_dai *codec_dai = rtd->codec_dai;
38 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 38 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
39 int ret; 39 int ret;
40 40
41 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | 41 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
@@ -79,10 +79,10 @@ static struct snd_soc_ops eukrea_tlv320_snd_ops = {
79static struct snd_soc_dai_link eukrea_tlv320_dai = { 79static struct snd_soc_dai_link eukrea_tlv320_dai = {
80 .name = "tlv320aic23", 80 .name = "tlv320aic23",
81 .stream_name = "TLV320AIC23", 81 .stream_name = "TLV320AIC23",
82 .codec_dai = "tlv320aic23-hifi", 82 .codec_dai_name = "tlv320aic23-hifi",
83 .platform_name = "imx-pcm-audio.0", 83 .platform_name = "imx-pcm-audio.0",
84 .codec_name = "tlv320aic23-codec.0-001a", 84 .codec_name = "tlv320aic23-codec.0-001a",
85 .cpu_dai = "imx-ssi.0", 85 .cpu_dai_name = "imx-ssi.0",
86 .ops = &eukrea_tlv320_snd_ops, 86 .ops = &eukrea_tlv320_snd_ops,
87}; 87};
88 88
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
index fd493ee1428..671ef8dd524 100644
--- a/sound/soc/imx/imx-pcm-dma-mx2.c
+++ b/sound/soc/imx/imx-pcm-dma-mx2.c
@@ -20,6 +20,7 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/dmaengine.h>
23 24
24#include <sound/core.h> 25#include <sound/core.h>
25#include <sound/initval.h> 26#include <sound/initval.h>
@@ -27,165 +28,146 @@
27#include <sound/pcm_params.h> 28#include <sound/pcm_params.h>
28#include <sound/soc.h> 29#include <sound/soc.h>
29 30
30#include <mach/dma-mx1-mx2.h> 31#include <mach/dma.h>
31 32
32#include "imx-ssi.h" 33#include "imx-ssi.h"
33 34
34struct imx_pcm_runtime_data { 35struct imx_pcm_runtime_data {
35 int sg_count; 36 int period_bytes;
36 struct scatterlist *sg_list;
37 int period;
38 int periods; 37 int periods;
39 unsigned long dma_addr;
40 int dma; 38 int dma;
41 struct snd_pcm_substream *substream;
42 unsigned long offset; 39 unsigned long offset;
43 unsigned long size; 40 unsigned long size;
44 unsigned long period_cnt;
45 void *buf; 41 void *buf;
46 int period_time; 42 int period_time;
43 struct dma_async_tx_descriptor *desc;
44 struct dma_chan *dma_chan;
45 struct imx_dma_data dma_data;
47}; 46};
48 47
49/* Called by the DMA framework when a period has elapsed */ 48static void audio_dma_irq(void *data)
50static void imx_ssi_dma_progression(int channel, void *data,
51 struct scatterlist *sg)
52{ 49{
53 struct snd_pcm_substream *substream = data; 50 struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data;
54 struct snd_pcm_runtime *runtime = substream->runtime; 51 struct snd_pcm_runtime *runtime = substream->runtime;
55 struct imx_pcm_runtime_data *iprtd = runtime->private_data; 52 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
56 53
57 if (!sg) 54 iprtd->offset += iprtd->period_bytes;
58 return; 55 iprtd->offset %= iprtd->period_bytes * iprtd->periods;
59
60 runtime = iprtd->substream->runtime;
61 56
62 iprtd->offset = sg->dma_address - runtime->dma_addr; 57 snd_pcm_period_elapsed(substream);
63
64 snd_pcm_period_elapsed(iprtd->substream);
65} 58}
66 59
67static void imx_ssi_dma_callback(int channel, void *data) 60static bool filter(struct dma_chan *chan, void *param)
68{ 61{
69 pr_err("%s shouldn't be called\n", __func__); 62 struct imx_pcm_runtime_data *iprtd = param;
70}
71 63
72static void snd_imx_dma_err_callback(int channel, void *data, int err) 64 if (!imx_dma_is_general_purpose(chan))
73{ 65 return false;
74 struct snd_pcm_substream *substream = data;
75 struct snd_soc_pcm_runtime *rtd = substream->private_data;
76 struct imx_pcm_dma_params *dma_params =
77 snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
78 struct snd_pcm_runtime *runtime = substream->runtime;
79 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
80 int ret;
81 66
82 pr_err("DMA timeout on channel %d -%s%s%s%s\n", 67 chan->private = &iprtd->dma_data;
83 channel,
84 err & IMX_DMA_ERR_BURST ? " burst" : "",
85 err & IMX_DMA_ERR_REQUEST ? " request" : "",
86 err & IMX_DMA_ERR_TRANSFER ? " transfer" : "",
87 err & IMX_DMA_ERR_BUFFER ? " buffer" : "");
88 68
89 imx_dma_disable(iprtd->dma); 69 return true;
90 ret = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count,
91 IMX_DMA_LENGTH_LOOP, dma_params->dma_addr,
92 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
93 DMA_MODE_WRITE : DMA_MODE_READ);
94 if (!ret)
95 imx_dma_enable(iprtd->dma);
96} 70}
97 71
98static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) 72static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream,
73 struct snd_pcm_hw_params *params)
99{ 74{
100 struct snd_soc_pcm_runtime *rtd = substream->private_data; 75 struct snd_soc_pcm_runtime *rtd = substream->private_data;
101 struct imx_pcm_dma_params *dma_params; 76 struct imx_pcm_dma_params *dma_params;
102 struct snd_pcm_runtime *runtime = substream->runtime; 77 struct snd_pcm_runtime *runtime = substream->runtime;
103 struct imx_pcm_runtime_data *iprtd = runtime->private_data; 78 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
79 struct dma_slave_config slave_config;
80 dma_cap_mask_t mask;
81 enum dma_slave_buswidth buswidth;
104 int ret; 82 int ret;
105 83
106 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 84 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
107 85
108 iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); 86 iprtd->dma_data.peripheral_type = IMX_DMATYPE_SSI;
109 if (iprtd->dma < 0) { 87 iprtd->dma_data.priority = DMA_PRIO_HIGH;
110 pr_err("Failed to claim the audio DMA\n"); 88 iprtd->dma_data.dma_request = dma_params->dma;
111 return -ENODEV;
112 }
113 89
114 ret = imx_dma_setup_handlers(iprtd->dma, 90 /* Try to grab a DMA channel */
115 imx_ssi_dma_callback, 91 dma_cap_zero(mask);
116 snd_imx_dma_err_callback, substream); 92 dma_cap_set(DMA_SLAVE, mask);
117 if (ret) 93 iprtd->dma_chan = dma_request_channel(mask, filter, iprtd);
118 goto out; 94 if (!iprtd->dma_chan)
95 return -EINVAL;
119 96
120 ret = imx_dma_setup_progression_handler(iprtd->dma, 97 switch (params_format(params)) {
121 imx_ssi_dma_progression); 98 case SNDRV_PCM_FORMAT_S16_LE:
122 if (ret) { 99 buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
123 pr_err("Failed to setup the DMA handler\n"); 100 break;
124 goto out; 101 case SNDRV_PCM_FORMAT_S20_3LE:
102 case SNDRV_PCM_FORMAT_S24_LE:
103 buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
104 break;
105 default:
106 return 0;
125 } 107 }
126 108
127 ret = imx_dma_config_channel(iprtd->dma, 109 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
128 IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO, 110 slave_config.direction = DMA_TO_DEVICE;
129 IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR, 111 slave_config.dst_addr = dma_params->dma_addr;
130 dma_params->dma, 1); 112 slave_config.dst_addr_width = buswidth;
131 if (ret < 0) { 113 slave_config.dst_maxburst = dma_params->burstsize;
132 pr_err("Cannot configure DMA channel: %d\n", ret); 114 } else {
133 goto out; 115 slave_config.direction = DMA_FROM_DEVICE;
116 slave_config.src_addr = dma_params->dma_addr;
117 slave_config.src_addr_width = buswidth;
118 slave_config.src_maxburst = dma_params->burstsize;
134 } 119 }
135 120
136 imx_dma_config_burstlen(iprtd->dma, dma_params->burstsize * 2); 121 ret = dmaengine_slave_config(iprtd->dma_chan, &slave_config);
122 if (ret)
123 return ret;
137 124
138 return 0; 125 return 0;
139out:
140 imx_dma_free(iprtd->dma);
141 return ret;
142} 126}
143 127
144static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, 128static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
145 struct snd_pcm_hw_params *params) 129 struct snd_pcm_hw_params *params)
146{ 130{
131 struct snd_soc_pcm_runtime *rtd = substream->private_data;
147 struct snd_pcm_runtime *runtime = substream->runtime; 132 struct snd_pcm_runtime *runtime = substream->runtime;
148 struct imx_pcm_runtime_data *iprtd = runtime->private_data; 133 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
149 int i;
150 unsigned long dma_addr; 134 unsigned long dma_addr;
135 struct dma_chan *chan;
136 struct imx_pcm_dma_params *dma_params;
137 int ret;
151 138
152 imx_ssi_dma_alloc(substream); 139 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
140 ret = imx_ssi_dma_alloc(substream, params);
141 if (ret)
142 return ret;
143 chan = iprtd->dma_chan;
153 144
154 iprtd->size = params_buffer_bytes(params); 145 iprtd->size = params_buffer_bytes(params);
155 iprtd->periods = params_periods(params); 146 iprtd->periods = params_periods(params);
156 iprtd->period = params_period_bytes(params); 147 iprtd->period_bytes = params_period_bytes(params);
157 iprtd->offset = 0; 148 iprtd->offset = 0;
158 iprtd->period_time = HZ / (params_rate(params) / 149 iprtd->period_time = HZ / (params_rate(params) /
159 params_period_size(params)); 150 params_period_size(params));
160 151
161 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 152 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
162 153
163 if (iprtd->sg_count != iprtd->periods) {
164 kfree(iprtd->sg_list);
165
166 iprtd->sg_list = kcalloc(iprtd->periods + 1,
167 sizeof(struct scatterlist), GFP_KERNEL);
168 if (!iprtd->sg_list)
169 return -ENOMEM;
170 iprtd->sg_count = iprtd->periods + 1;
171 }
172
173 sg_init_table(iprtd->sg_list, iprtd->sg_count);
174 dma_addr = runtime->dma_addr; 154 dma_addr = runtime->dma_addr;
175 155
176 for (i = 0; i < iprtd->periods; i++) { 156 iprtd->buf = (unsigned int *)substream->dma_buffer.area;
177 iprtd->sg_list[i].page_link = 0; 157
178 iprtd->sg_list[i].offset = 0; 158 iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr,
179 iprtd->sg_list[i].dma_address = dma_addr; 159 iprtd->period_bytes * iprtd->periods,
180 iprtd->sg_list[i].length = iprtd->period; 160 iprtd->period_bytes,
181 dma_addr += iprtd->period; 161 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
162 DMA_TO_DEVICE : DMA_FROM_DEVICE);
163 if (!iprtd->desc) {
164 dev_err(&chan->dev->device, "cannot prepare slave dma\n");
165 return -EINVAL;
182 } 166 }
183 167
184 /* close the loop */ 168 iprtd->desc->callback = audio_dma_irq;
185 iprtd->sg_list[iprtd->sg_count - 1].offset = 0; 169 iprtd->desc->callback_param = substream;
186 iprtd->sg_list[iprtd->sg_count - 1].length = 0; 170
187 iprtd->sg_list[iprtd->sg_count - 1].page_link =
188 ((unsigned long) iprtd->sg_list | 0x01) & ~0x02;
189 return 0; 171 return 0;
190} 172}
191 173
@@ -194,41 +176,21 @@ static int snd_imx_pcm_hw_free(struct snd_pcm_substream *substream)
194 struct snd_pcm_runtime *runtime = substream->runtime; 176 struct snd_pcm_runtime *runtime = substream->runtime;
195 struct imx_pcm_runtime_data *iprtd = runtime->private_data; 177 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
196 178
197 if (iprtd->dma >= 0) { 179 if (iprtd->dma_chan) {
198 imx_dma_free(iprtd->dma); 180 dma_release_channel(iprtd->dma_chan);
199 iprtd->dma = -EINVAL; 181 iprtd->dma_chan = NULL;
200 } 182 }
201 183
202 kfree(iprtd->sg_list);
203 iprtd->sg_list = NULL;
204
205 return 0; 184 return 0;
206} 185}
207 186
208static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream) 187static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
209{ 188{
210 struct snd_pcm_runtime *runtime = substream->runtime;
211 struct snd_soc_pcm_runtime *rtd = substream->private_data; 189 struct snd_soc_pcm_runtime *rtd = substream->private_data;
212 struct imx_pcm_dma_params *dma_params; 190 struct imx_pcm_dma_params *dma_params;
213 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
214 int err;
215 191
216 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 192 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
217 193
218 iprtd->substream = substream;
219 iprtd->buf = (unsigned int *)substream->dma_buffer.area;
220 iprtd->period_cnt = 0;
221
222 pr_debug("%s: buf: %p period: %d periods: %d\n",
223 __func__, iprtd->buf, iprtd->period, iprtd->periods);
224
225 err = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count,
226 IMX_DMA_LENGTH_LOOP, dma_params->dma_addr,
227 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
228 DMA_MODE_WRITE : DMA_MODE_READ);
229 if (err)
230 return err;
231
232 return 0; 194 return 0;
233} 195}
234 196
@@ -241,14 +203,14 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
241 case SNDRV_PCM_TRIGGER_START: 203 case SNDRV_PCM_TRIGGER_START:
242 case SNDRV_PCM_TRIGGER_RESUME: 204 case SNDRV_PCM_TRIGGER_RESUME:
243 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 205 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
244 imx_dma_enable(iprtd->dma); 206 dmaengine_submit(iprtd->desc);
245 207
246 break; 208 break;
247 209
248 case SNDRV_PCM_TRIGGER_STOP: 210 case SNDRV_PCM_TRIGGER_STOP:
249 case SNDRV_PCM_TRIGGER_SUSPEND: 211 case SNDRV_PCM_TRIGGER_SUSPEND:
250 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 212 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
251 imx_dma_disable(iprtd->dma); 213 dmaengine_terminate_all(iprtd->dma_chan);
252 214
253 break; 215 break;
254 default: 216 default:
@@ -263,6 +225,9 @@ static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream
263 struct snd_pcm_runtime *runtime = substream->runtime; 225 struct snd_pcm_runtime *runtime = substream->runtime;
264 struct imx_pcm_runtime_data *iprtd = runtime->private_data; 226 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
265 227
228 pr_debug("%s: %ld %ld\n", __func__, iprtd->offset,
229 bytes_to_frames(substream->runtime, iprtd->offset));
230
266 return bytes_to_frames(substream->runtime, iprtd->offset); 231 return bytes_to_frames(substream->runtime, iprtd->offset);
267} 232}
268 233
@@ -279,7 +244,7 @@ static struct snd_pcm_hardware snd_imx_hardware = {
279 .channels_max = 2, 244 .channels_max = 2,
280 .buffer_bytes_max = IMX_SSI_DMABUF_SIZE, 245 .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
281 .period_bytes_min = 128, 246 .period_bytes_min = 128,
282 .period_bytes_max = 16 * 1024, 247 .period_bytes_max = 65535, /* Limited by SDMA engine */
283 .periods_min = 2, 248 .periods_min = 2,
284 .periods_max = 255, 249 .periods_max = 255,
285 .fifo_size = 0, 250 .fifo_size = 0,
@@ -304,11 +269,23 @@ static int snd_imx_open(struct snd_pcm_substream *substream)
304 } 269 }
305 270
306 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); 271 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
272
273 return 0;
274}
275
276static int snd_imx_close(struct snd_pcm_substream *substream)
277{
278 struct snd_pcm_runtime *runtime = substream->runtime;
279 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
280
281 kfree(iprtd);
282
307 return 0; 283 return 0;
308} 284}
309 285
310static struct snd_pcm_ops imx_pcm_ops = { 286static struct snd_pcm_ops imx_pcm_ops = {
311 .open = snd_imx_open, 287 .open = snd_imx_open,
288 .close = snd_imx_close,
312 .ioctl = snd_pcm_lib_ioctl, 289 .ioctl = snd_pcm_lib_ioctl,
313 .hw_params = snd_imx_pcm_hw_params, 290 .hw_params = snd_imx_pcm_hw_params,
314 .hw_free = snd_imx_pcm_hw_free, 291 .hw_free = snd_imx_pcm_hw_free,
@@ -340,7 +317,6 @@ static struct platform_driver imx_pcm_driver = {
340 .name = "imx-pcm-audio", 317 .name = "imx-pcm-audio",
341 .owner = THIS_MODULE, 318 .owner = THIS_MODULE,
342 }, 319 },
343
344 .probe = imx_soc_platform_probe, 320 .probe = imx_soc_platform_probe,
345 .remove = __devexit_p(imx_soc_platform_remove), 321 .remove = __devexit_p(imx_soc_platform_remove),
346}; 322};
@@ -356,4 +332,3 @@ static void __exit snd_imx_pcm_exit(void)
356 platform_driver_unregister(&imx_pcm_driver); 332 platform_driver_unregister(&imx_pcm_driver);
357} 333}
358module_exit(snd_imx_pcm_exit); 334module_exit(snd_imx_pcm_exit);
359
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index d4bd345b0a8..d2d98c75ee8 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -439,7 +439,22 @@ void imx_pcm_free(struct snd_pcm *pcm)
439} 439}
440EXPORT_SYMBOL_GPL(imx_pcm_free); 440EXPORT_SYMBOL_GPL(imx_pcm_free);
441 441
442static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
443{
444 struct imx_ssi *ssi = dev_get_drvdata(dai->dev);
445 uint32_t val;
446
447 snd_soc_dai_set_drvdata(dai, ssi);
448
449 val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) |
450 SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize);
451 writel(val, ssi->base + SSI_SFCSR);
452
453 return 0;
454}
455
442static struct snd_soc_dai_driver imx_ssi_dai = { 456static struct snd_soc_dai_driver imx_ssi_dai = {
457 .probe = imx_ssi_dai_probe,
443 .playback = { 458 .playback = {
444 .channels_min = 2, 459 .channels_min = 2,
445 .channels_max = 2, 460 .channels_max = 2,
@@ -455,20 +470,6 @@ static struct snd_soc_dai_driver imx_ssi_dai = {
455 .ops = &imx_ssi_pcm_dai_ops, 470 .ops = &imx_ssi_pcm_dai_ops,
456}; 471};
457 472
458static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
459{
460 struct imx_ssi *ssi = dev_get_drvdata(dai->dev);
461 uint32_t val;
462
463 snd_soc_dai_set_drvdata(dai, ssi);
464
465 val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) |
466 SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize);
467 writel(val, ssi->base + SSI_SFCSR);
468
469 return 0;
470}
471
472static struct snd_soc_dai_driver imx_ac97_dai = { 473static struct snd_soc_dai_driver imx_ac97_dai = {
473 .probe = imx_ssi_dai_probe, 474 .probe = imx_ssi_dai_probe,
474 .ac97_control = 1, 475 .ac97_control = 1,
@@ -677,7 +678,17 @@ static int imx_ssi_probe(struct platform_device *pdev)
677 goto failed_register; 678 goto failed_register;
678 } 679 }
679 680
680 ssi->soc_platform_pdev = platform_device_alloc("imx-fiq-pcm-audio", pdev->id); 681 ssi->soc_platform_pdev_fiq = platform_device_alloc("imx-fiq-pcm-audio", pdev->id);
682 if (!ssi->soc_platform_pdev_fiq)
683 goto failed_pdev_fiq_alloc;
684 platform_set_drvdata(ssi->soc_platform_pdev_fiq, ssi);
685 ret = platform_device_add(ssi->soc_platform_pdev_fiq);
686 if (ret) {
687 dev_err(&pdev->dev, "failed to add platform device\n");
688 goto failed_pdev_fiq_add;
689 }
690
691 ssi->soc_platform_pdev = platform_device_alloc("imx-pcm-audio", pdev->id);
681 if (!ssi->soc_platform_pdev) 692 if (!ssi->soc_platform_pdev)
682 goto failed_pdev_alloc; 693 goto failed_pdev_alloc;
683 platform_set_drvdata(ssi->soc_platform_pdev, ssi); 694 platform_set_drvdata(ssi->soc_platform_pdev, ssi);
@@ -692,6 +703,9 @@ static int imx_ssi_probe(struct platform_device *pdev)
692failed_pdev_add: 703failed_pdev_add:
693 platform_device_put(ssi->soc_platform_pdev); 704 platform_device_put(ssi->soc_platform_pdev);
694failed_pdev_alloc: 705failed_pdev_alloc:
706failed_pdev_fiq_add:
707 platform_device_put(ssi->soc_platform_pdev_fiq);
708failed_pdev_fiq_alloc:
695 snd_soc_unregister_dai(&pdev->dev); 709 snd_soc_unregister_dai(&pdev->dev);
696failed_register: 710failed_register:
697failed_ac97: 711failed_ac97:
diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h
index 53b780d9b2b..a4406a13489 100644
--- a/sound/soc/imx/imx-ssi.h
+++ b/sound/soc/imx/imx-ssi.h
@@ -185,6 +185,9 @@
185 185
186#define DRV_NAME "imx-ssi" 186#define DRV_NAME "imx-ssi"
187 187
188#include <linux/dmaengine.h>
189#include <mach/dma.h>
190
188struct imx_pcm_dma_params { 191struct imx_pcm_dma_params {
189 int dma; 192 int dma;
190 unsigned long dma_addr; 193 unsigned long dma_addr;
@@ -212,6 +215,7 @@ struct imx_ssi {
212 int enabled; 215 int enabled;
213 216
214 struct platform_device *soc_platform_pdev; 217 struct platform_device *soc_platform_pdev;
218 struct platform_device *soc_platform_pdev_fiq;
215}; 219};
216 220
217struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev, 221struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev,
diff --git a/sound/soc/imx/phycore-ac97.c b/sound/soc/imx/phycore-ac97.c
index 6a65dd70551..39f23734781 100644
--- a/sound/soc/imx/phycore-ac97.c
+++ b/sound/soc/imx/phycore-ac97.c
@@ -20,9 +20,6 @@
20#include <sound/soc-dapm.h> 20#include <sound/soc-dapm.h>
21#include <asm/mach-types.h> 21#include <asm/mach-types.h>
22 22
23#include "../codecs/wm9712.h"
24#include "imx-ssi.h"
25
26static struct snd_soc_card imx_phycore; 23static struct snd_soc_card imx_phycore;
27 24
28static struct snd_soc_ops imx_phycore_hifi_ops = { 25static struct snd_soc_ops imx_phycore_hifi_ops = {
@@ -41,7 +38,7 @@ static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
41}; 38};
42 39
43static struct snd_soc_card imx_phycore = { 40static struct snd_soc_card imx_phycore = {
44 .name = "PhyCORE-audio", 41 .name = "PhyCORE-ac97-audio",
45 .dai_link = imx_phycore_dai_ac97, 42 .dai_link = imx_phycore_dai_ac97,
46 .num_links = ARRAY_SIZE(imx_phycore_dai_ac97), 43 .num_links = ARRAY_SIZE(imx_phycore_dai_ac97),
47}; 44};
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index d211c9fa5a9..7e84f24b9a8 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -644,15 +644,23 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
644 644
645 645
646 case OMAP_MCBSP_CLKR_SRC_CLKR: 646 case OMAP_MCBSP_CLKR_SRC_CLKR:
647 if (cpu_class_is_omap1())
648 break;
647 omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKR); 649 omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKR);
648 break; 650 break;
649 case OMAP_MCBSP_CLKR_SRC_CLKX: 651 case OMAP_MCBSP_CLKR_SRC_CLKX:
652 if (cpu_class_is_omap1())
653 break;
650 omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKX); 654 omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKX);
651 break; 655 break;
652 case OMAP_MCBSP_FSR_SRC_FSR: 656 case OMAP_MCBSP_FSR_SRC_FSR:
657 if (cpu_class_is_omap1())
658 break;
653 omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSR); 659 omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSR);
654 break; 660 break;
655 case OMAP_MCBSP_FSR_SRC_FSX: 661 case OMAP_MCBSP_FSR_SRC_FSX:
662 if (cpu_class_is_omap1())
663 break;
656 omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSX); 664 omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSX);
657 break; 665 break;
658 default: 666 default:
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 97e9423615c..f451acd4935 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -100,8 +100,13 @@ static int corgi_startup(struct snd_pcm_substream *substream)
100 struct snd_soc_pcm_runtime *rtd = substream->private_data; 100 struct snd_soc_pcm_runtime *rtd = substream->private_data;
101 struct snd_soc_codec *codec = rtd->codec; 101 struct snd_soc_codec *codec = rtd->codec;
102 102
103 mutex_lock(&codec->mutex);
104
103 /* check the jack status at stream startup */ 105 /* check the jack status at stream startup */
104 corgi_ext_control(codec); 106 corgi_ext_control(codec);
107
108 mutex_unlock(&codec->mutex);
109
105 return 0; 110 return 0;
106} 111}
107 112
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index b8207ced407..5ef0526924b 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -72,9 +72,13 @@ static int magician_startup(struct snd_pcm_substream *substream)
72 struct snd_soc_pcm_runtime *rtd = substream->private_data; 72 struct snd_soc_pcm_runtime *rtd = substream->private_data;
73 struct snd_soc_codec *codec = rtd->codec; 73 struct snd_soc_codec *codec = rtd->codec;
74 74
75 mutex_lock(&codec->mutex);
76
75 /* check the jack status at stream startup */ 77 /* check the jack status at stream startup */
76 magician_ext_control(codec); 78 magician_ext_control(codec);
77 79
80 mutex_unlock(&codec->mutex);
81
78 return 0; 82 return 0;
79} 83}
80 84
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index af84ee9c5e1..84edd0385a2 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -77,8 +77,13 @@ static int poodle_startup(struct snd_pcm_substream *substream)
77 struct snd_soc_pcm_runtime *rtd = substream->private_data; 77 struct snd_soc_pcm_runtime *rtd = substream->private_data;
78 struct snd_soc_codec *codec = rtd->codec; 78 struct snd_soc_codec *codec = rtd->codec;
79 79
80 mutex_lock(&codec->mutex);
81
80 /* check the jack status at stream startup */ 82 /* check the jack status at stream startup */
81 poodle_ext_control(codec); 83 poodle_ext_control(codec);
84
85 mutex_unlock(&codec->mutex);
86
82 return 0; 87 return 0;
83} 88}
84 89
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index f470f360f4d..0b30d7de24e 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -108,8 +108,13 @@ static int spitz_startup(struct snd_pcm_substream *substream)
108 struct snd_soc_pcm_runtime *rtd = substream->private_data; 108 struct snd_soc_pcm_runtime *rtd = substream->private_data;
109 struct snd_soc_codec *codec = rtd->codec; 109 struct snd_soc_codec *codec = rtd->codec;
110 110
111 mutex_lock(&codec->mutex);
112
111 /* check the jack status at stream startup */ 113 /* check the jack status at stream startup */
112 spitz_ext_control(codec); 114 spitz_ext_control(codec);
115
116 mutex_unlock(&codec->mutex);
117
113 return 0; 118 return 0;
114} 119}
115 120
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index 73d0edd8ded..7b983f93545 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -81,8 +81,13 @@ static int tosa_startup(struct snd_pcm_substream *substream)
81 struct snd_soc_pcm_runtime *rtd = substream->private_data; 81 struct snd_soc_pcm_runtime *rtd = substream->private_data;
82 struct snd_soc_codec *codec = rtd->codec; 82 struct snd_soc_codec *codec = rtd->codec;
83 83
84 mutex_lock(&codec->mutex);
85
84 /* check the jack status at stream startup */ 86 /* check the jack status at stream startup */
85 tosa_ext_control(codec); 87 tosa_ext_control(codec);
88
89 mutex_unlock(&codec->mutex);
90
86 return 0; 91 return 0;
87} 92}
88 93
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
index 8a6b53ccd20..d85bf8a0abb 100644
--- a/sound/soc/s3c24xx/Kconfig
+++ b/sound/soc/s3c24xx/Kconfig
@@ -2,6 +2,7 @@ config SND_S3C24XX_SOC
2 tristate "SoC Audio for the Samsung S3CXXXX chips" 2 tristate "SoC Audio for the Samsung S3CXXXX chips"
3 depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 3 depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210
4 select S3C64XX_DMA if ARCH_S3C64XX 4 select S3C64XX_DMA if ARCH_S3C64XX
5 select S3C2410_DMA if ARCH_S3C2410
5 help 6 help
6 Say Y or M if you want to add support for codecs attached to 7 Say Y or M if you want to add support for codecs attached to
7 the S3C24XX AC97 or I2S interfaces. You will also need to 8 the S3C24XX AC97 or I2S interfaces. You will also need to
diff --git a/sound/soc/s3c24xx/rx1950_uda1380.c b/sound/soc/s3c24xx/rx1950_uda1380.c
index ffd5cf2fb0a..468cc11fdf4 100644
--- a/sound/soc/s3c24xx/rx1950_uda1380.c
+++ b/sound/soc/s3c24xx/rx1950_uda1380.c
@@ -50,7 +50,6 @@ static unsigned int rates[] = {
50 16000, 50 16000,
51 44100, 51 44100,
52 48000, 52 48000,
53 88200,
54}; 53};
55 54
56static struct snd_pcm_hw_constraint_list hw_rates = { 55static struct snd_pcm_hw_constraint_list hw_rates = {
@@ -130,7 +129,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
130}; 129};
131 130
132static struct platform_device *s3c24xx_snd_device; 131static struct platform_device *s3c24xx_snd_device;
133static struct clk *xtal;
134 132
135static int rx1950_startup(struct snd_pcm_substream *substream) 133static int rx1950_startup(struct snd_pcm_substream *substream)
136{ 134{
@@ -179,10 +177,8 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream,
179 case 44100: 177 case 44100:
180 case 88200: 178 case 88200:
181 clk_source = S3C24XX_CLKSRC_MPLL; 179 clk_source = S3C24XX_CLKSRC_MPLL;
182 fs_mode = S3C2410_IISMOD_256FS; 180 fs_mode = S3C2410_IISMOD_384FS;
183 div = clk_get_rate(xtal) / (256 * rate); 181 div = 1;
184 if (clk_get_rate(xtal) % (256 * rate) > (128 * rate))
185 div++;
186 break; 182 break;
187 default: 183 default:
188 printk(KERN_ERR "%s: rate %d is not supported\n", 184 printk(KERN_ERR "%s: rate %d is not supported\n",
@@ -210,7 +206,7 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream,
210 206
211 /* set MCLK division for sample rate */ 207 /* set MCLK division for sample rate */
212 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, 208 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
213 S3C2410_IISMOD_384FS); 209 fs_mode);
214 if (ret < 0) 210 if (ret < 0)
215 return ret; 211 return ret;
216 212
@@ -295,17 +291,8 @@ static int __init rx1950_init(void)
295 goto err_plat_add; 291 goto err_plat_add;
296 } 292 }
297 293
298 xtal = clk_get(&s3c24xx_snd_device->dev, "xtal");
299
300 if (IS_ERR(xtal)) {
301 ret = PTR_ERR(xtal);
302 platform_device_unregister(s3c24xx_snd_device);
303 goto err_clk;
304 }
305
306 return 0; 294 return 0;
307 295
308err_clk:
309err_plat_add: 296err_plat_add:
310err_plat_alloc: 297err_plat_alloc:
311err_gpio_conf: 298err_gpio_conf:
@@ -320,7 +307,6 @@ static void __exit rx1950_exit(void)
320 platform_device_unregister(s3c24xx_snd_device); 307 platform_device_unregister(s3c24xx_snd_device);
321 snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), 308 snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios),
322 hp_jack_gpios); 309 hp_jack_gpios);
323 clk_put(xtal);
324 gpio_free(S3C2410_GPA(1)); 310 gpio_free(S3C2410_GPA(1));
325} 311}
326 312
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 614a8b30d87..441285ade02 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3043,8 +3043,10 @@ int snd_soc_register_dais(struct device *dev,
3043 for (i = 0; i < count; i++) { 3043 for (i = 0; i < count; i++) {
3044 3044
3045 dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL); 3045 dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL);
3046 if (dai == NULL) 3046 if (dai == NULL) {
3047 return -ENOMEM; 3047 ret = -ENOMEM;
3048 goto err;
3049 }
3048 3050
3049 /* create DAI component name */ 3051 /* create DAI component name */
3050 dai->name = fmt_multiple_name(dev, &dai_drv[i]); 3052 dai->name = fmt_multiple_name(dev, &dai_drv[i]);
@@ -3263,9 +3265,6 @@ int snd_soc_register_codec(struct device *dev,
3263 return 0; 3265 return 0;
3264 3266
3265error: 3267error:
3266 for (i--; i >= 0; i--)
3267 snd_soc_unregister_dai(dev);
3268
3269 if (codec->reg_cache) 3268 if (codec->reg_cache)
3270 kfree(codec->reg_cache); 3269 kfree(codec->reg_cache);
3271 kfree(codec->name); 3270 kfree(codec->name);
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 7d85c6496af..75ed6491222 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -683,12 +683,12 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
683 struct snd_soc_dapm_widget *b, 683 struct snd_soc_dapm_widget *b,
684 int sort[]) 684 int sort[])
685{ 685{
686 if (a->codec != b->codec)
687 return (unsigned long)a - (unsigned long)b;
688 if (sort[a->id] != sort[b->id]) 686 if (sort[a->id] != sort[b->id])
689 return sort[a->id] - sort[b->id]; 687 return sort[a->id] - sort[b->id];
690 if (a->reg != b->reg) 688 if (a->reg != b->reg)
691 return a->reg - b->reg; 689 return a->reg - b->reg;
690 if (a->codec != b->codec)
691 return (unsigned long)a->codec - (unsigned long)b->codec;
692 692
693 return 0; 693 return 0;
694} 694}