Browse Source

Merge branch 'fix/asoc' into for-linus

Takashi Iwai 14 years ago
parent
commit
9e8c32cac9

+ 3 - 3
arch/arm/mach-davinci/dm355.c

@@ -359,8 +359,8 @@ static struct clk_lookup dm355_clks[] = {
 	CLK(NULL, "uart1", &uart1_clk),
 	CLK(NULL, "uart1", &uart1_clk),
 	CLK(NULL, "uart2", &uart2_clk),
 	CLK(NULL, "uart2", &uart2_clk),
 	CLK("i2c_davinci.1", NULL, &i2c_clk),
 	CLK("i2c_davinci.1", NULL, &i2c_clk),
-	CLK("davinci-asp.0", NULL, &asp0_clk),
-	CLK("davinci-asp.1", NULL, &asp1_clk),
+	CLK("davinci-mcbsp.0", NULL, &asp0_clk),
+	CLK("davinci-mcbsp.1", NULL, &asp1_clk),
 	CLK("davinci_mmc.0", NULL, &mmcsd0_clk),
 	CLK("davinci_mmc.0", NULL, &mmcsd0_clk),
 	CLK("davinci_mmc.1", NULL, &mmcsd1_clk),
 	CLK("davinci_mmc.1", NULL, &mmcsd1_clk),
 	CLK("spi_davinci.0", NULL, &spi0_clk),
 	CLK("spi_davinci.0", NULL, &spi0_clk),
@@ -664,7 +664,7 @@ static struct resource dm355_asp1_resources[] = {
 };
 };
 
 
 static struct platform_device dm355_asp1_device = {
 static struct platform_device dm355_asp1_device = {
-	.name		= "davinci-asp",
+	.name		= "davinci-mcbsp",
 	.id		= 1,
 	.id		= 1,
 	.num_resources	= ARRAY_SIZE(dm355_asp1_resources),
 	.num_resources	= ARRAY_SIZE(dm355_asp1_resources),
 	.resource	= dm355_asp1_resources,
 	.resource	= dm355_asp1_resources,

+ 3 - 3
arch/arm/mach-davinci/dm365.c

@@ -459,7 +459,7 @@ static struct clk_lookup dm365_clks[] = {
 	CLK(NULL, "usb", &usb_clk),
 	CLK(NULL, "usb", &usb_clk),
 	CLK("davinci_emac.1", NULL, &emac_clk),
 	CLK("davinci_emac.1", NULL, &emac_clk),
 	CLK("davinci_voicecodec", NULL, &voicecodec_clk),
 	CLK("davinci_voicecodec", NULL, &voicecodec_clk),
-	CLK("davinci-asp.0", NULL, &asp0_clk),
+	CLK("davinci-mcbsp", NULL, &asp0_clk),
 	CLK(NULL, "rto", &rto_clk),
 	CLK(NULL, "rto", &rto_clk),
 	CLK(NULL, "mjcp", &mjcp_clk),
 	CLK(NULL, "mjcp", &mjcp_clk),
 	CLK(NULL, NULL, NULL),
 	CLK(NULL, NULL, NULL),
@@ -922,8 +922,8 @@ static struct resource dm365_asp_resources[] = {
 };
 };
 
 
 static struct platform_device dm365_asp_device = {
 static struct platform_device dm365_asp_device = {
-	.name		= "davinci-asp",
-	.id		= 0,
+	.name		= "davinci-mcbsp",
+	.id		= -1,
 	.num_resources	= ARRAY_SIZE(dm365_asp_resources),
 	.num_resources	= ARRAY_SIZE(dm365_asp_resources),
 	.resource	= dm365_asp_resources,
 	.resource	= dm365_asp_resources,
 };
 };

+ 2 - 2
arch/arm/mach-davinci/dm644x.c

@@ -302,7 +302,7 @@ static struct clk_lookup dm644x_clks[] = {
 	CLK("davinci_emac.1", NULL, &emac_clk),
 	CLK("davinci_emac.1", NULL, &emac_clk),
 	CLK("i2c_davinci.1", NULL, &i2c_clk),
 	CLK("i2c_davinci.1", NULL, &i2c_clk),
 	CLK("palm_bk3710", NULL, &ide_clk),
 	CLK("palm_bk3710", NULL, &ide_clk),
-	CLK("davinci-asp", NULL, &asp_clk),
+	CLK("davinci-mcbsp", NULL, &asp_clk),
 	CLK("davinci_mmc.0", NULL, &mmcsd_clk),
 	CLK("davinci_mmc.0", NULL, &mmcsd_clk),
 	CLK(NULL, "spi", &spi_clk),
 	CLK(NULL, "spi", &spi_clk),
 	CLK(NULL, "gpio", &gpio_clk),
 	CLK(NULL, "gpio", &gpio_clk),
@@ -580,7 +580,7 @@ static struct resource dm644x_asp_resources[] = {
 };
 };
 
 
 static struct platform_device dm644x_asp_device = {
 static struct platform_device dm644x_asp_device = {
-	.name		= "davinci-asp",
+	.name		= "davinci-mcbsp",
 	.id		= -1,
 	.id		= -1,
 	.num_resources	= ARRAY_SIZE(dm644x_asp_resources),
 	.num_resources	= ARRAY_SIZE(dm644x_asp_resources),
 	.resource	= dm644x_asp_resources,
 	.resource	= dm644x_asp_resources,

+ 0 - 3
include/linux/mfd/wm8350/audio.h

@@ -522,9 +522,6 @@
 #define WM8350_MCLK_SEL_PLL_32K			3
 #define WM8350_MCLK_SEL_PLL_32K			3
 #define WM8350_MCLK_SEL_MCLK			5
 #define WM8350_MCLK_SEL_MCLK			5
 
 
-#define WM8350_MCLK_DIR_OUT			0
-#define WM8350_MCLK_DIR_IN			1
-
 /* clock divider id's */
 /* clock divider id's */
 #define WM8350_ADC_CLKDIV			0
 #define WM8350_ADC_CLKDIV			0
 #define WM8350_DAC_CLKDIV			1
 #define WM8350_DAC_CLKDIV			1

+ 3 - 2
sound/soc/atmel/Kconfig

@@ -16,7 +16,8 @@ config SND_ATMEL_SOC_SSC
 
 
 config SND_AT91_SOC_SAM9G20_WM8731
 config SND_AT91_SOC_SAM9G20_WM8731
 	tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
 	tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
-	depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC
+	depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC && \
+                   AT91_PROGRAMMABLE_CLOCKS
 	select SND_ATMEL_SOC_SSC
 	select SND_ATMEL_SOC_SSC
 	select SND_SOC_WM8731
 	select SND_SOC_WM8731
 	help
 	help
@@ -25,7 +26,7 @@ config SND_AT91_SOC_SAM9G20_WM8731
 
 
 config SND_AT32_SOC_PLAYPAQ
 config SND_AT32_SOC_PLAYPAQ
         tristate "SoC Audio support for PlayPaq with WM8510"
         tristate "SoC Audio support for PlayPaq with WM8510"
-        depends on SND_ATMEL_SOC && BOARD_PLAYPAQ
+        depends on SND_ATMEL_SOC && BOARD_PLAYPAQ && AT91_PROGRAMMABLE_CLOCKS
         select SND_ATMEL_SOC_SSC
         select SND_ATMEL_SOC_SSC
         select SND_SOC_WM8510
         select SND_SOC_WM8510
         help
         help

+ 10 - 1
sound/soc/codecs/max98088.c

@@ -28,6 +28,11 @@
 #include <sound/max98088.h>
 #include <sound/max98088.h>
 #include "max98088.h"
 #include "max98088.h"
 
 
+enum max98088_type {
+       MAX98088,
+       MAX98089,
+};
+
 struct max98088_cdata {
 struct max98088_cdata {
        unsigned int rate;
        unsigned int rate;
        unsigned int fmt;
        unsigned int fmt;
@@ -36,6 +41,7 @@ struct max98088_cdata {
 
 
 struct max98088_priv {
 struct max98088_priv {
        u8 reg_cache[M98088_REG_CNT];
        u8 reg_cache[M98088_REG_CNT];
+       enum max98088_type devtype;
        void *control_data;
        void *control_data;
        struct max98088_pdata *pdata;
        struct max98088_pdata *pdata;
        unsigned int sysclk;
        unsigned int sysclk;
@@ -2040,6 +2046,8 @@ static int max98088_i2c_probe(struct i2c_client *i2c,
        if (max98088 == NULL)
        if (max98088 == NULL)
                return -ENOMEM;
                return -ENOMEM;
 
 
+       max98088->devtype = id->driver_data;
+
        i2c_set_clientdata(i2c, max98088);
        i2c_set_clientdata(i2c, max98088);
        max98088->control_data = i2c;
        max98088->control_data = i2c;
        max98088->pdata = i2c->dev.platform_data;
        max98088->pdata = i2c->dev.platform_data;
@@ -2059,7 +2067,8 @@ static int __devexit max98088_i2c_remove(struct i2c_client *client)
 }
 }
 
 
 static const struct i2c_device_id max98088_i2c_id[] = {
 static const struct i2c_device_id max98088_i2c_id[] = {
-       { "max98088", 0 },
+       { "max98088", MAX98088 },
+       { "max98089", MAX98089 },
        { }
        { }
 };
 };
 MODULE_DEVICE_TABLE(i2c, max98088_i2c_id);
 MODULE_DEVICE_TABLE(i2c, max98088_i2c_id);

+ 1 - 0
sound/soc/codecs/uda134x.c

@@ -597,6 +597,7 @@ static struct snd_soc_codec_driver soc_codec_dev_uda134x = {
 	.resume =       uda134x_soc_resume,
 	.resume =       uda134x_soc_resume,
 	.reg_cache_size = sizeof(uda134x_reg),
 	.reg_cache_size = sizeof(uda134x_reg),
 	.reg_word_size = sizeof(u8),
 	.reg_word_size = sizeof(u8),
+	.reg_cache_default = uda134x_reg,
 	.reg_cache_step = 1,
 	.reg_cache_step = 1,
 	.read = uda134x_read_reg_cache,
 	.read = uda134x_read_reg_cache,
 	.write = uda134x_write,
 	.write = uda134x_write,

+ 8 - 1
sound/soc/codecs/wm8350.c

@@ -831,7 +831,7 @@ static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 	}
 	}
 
 
 	/* MCLK direction */
 	/* MCLK direction */
-	if (dir == WM8350_MCLK_DIR_OUT)
+	if (dir == SND_SOC_CLOCK_OUT)
 		wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_2,
 		wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_2,
 				WM8350_MCLK_DIR);
 				WM8350_MCLK_DIR);
 	else
 	else
@@ -1586,6 +1586,13 @@ static  int wm8350_codec_probe(struct snd_soc_codec *codec)
 	wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME,
 	wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME,
 			WM8350_OUT2_VU | WM8350_OUT2R_MUTE);
 			WM8350_OUT2_VU | WM8350_OUT2R_MUTE);
 
 
+	/* Make sure AIF tristating is disabled by default */
+	wm8350_clear_bits(wm8350, WM8350_AI_FORMATING, WM8350_AIF_TRI);
+
+	/* Make sure we've got a sane companding setup too */
+	wm8350_clear_bits(wm8350, WM8350_ADC_DAC_COMP,
+			  WM8350_DAC_COMP | WM8350_LOOPBACK);
+
 	/* Make sure jack detect is disabled to start off with */
 	/* Make sure jack detect is disabled to start off with */
 	wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
 	wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
 			  WM8350_JDL_ENA | WM8350_JDR_ENA);
 			  WM8350_JDL_ENA | WM8350_JDR_ENA);

+ 0 - 1
sound/soc/codecs/wm8776.c

@@ -34,7 +34,6 @@
 /* codec private data */
 /* codec private data */
 struct wm8776_priv {
 struct wm8776_priv {
 	enum snd_soc_control_type control_type;
 	enum snd_soc_control_type control_type;
-	u16 reg_cache[WM8776_CACHEREGNUM];
 	int sysclk[2];
 	int sysclk[2];
 };
 };
 
 

+ 4 - 1
sound/soc/codecs/wm8962.c

@@ -3500,8 +3500,11 @@ static ssize_t wm8962_beep_set(struct device *dev,
 {
 {
 	struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
 	struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
 	long int time;
 	long int time;
+	int ret;
 
 
-	strict_strtol(buf, 10, &time);
+	ret = strict_strtol(buf, 10, &time);
+	if (ret != 0)
+		return ret;
 
 
 	input_event(wm8962->beep, EV_SND, SND_TONE, time);
 	input_event(wm8962->beep, EV_SND, SND_TONE, time);
 
 

+ 2 - 0
sound/soc/codecs/wm8994.c

@@ -3903,6 +3903,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 		return -ENOMEM;
 		return -ENOMEM;
 	snd_soc_codec_set_drvdata(codec, wm8994);
 	snd_soc_codec_set_drvdata(codec, wm8994);
 
 
+	codec->reg_cache = &wm8994->reg_cache;
+
 	wm8994->pdata = dev_get_platdata(codec->dev->parent);
 	wm8994->pdata = dev_get_platdata(codec->dev->parent);
 	wm8994->codec = codec;
 	wm8994->codec = codec;
 
 

+ 29 - 11
sound/soc/davinci/davinci-evm.c

@@ -157,12 +157,23 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
 }
 }
 
 
 /* davinci-evm digital audio interface glue - connects codec <--> CPU */
 /* davinci-evm digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link evm_dai = {
+static struct snd_soc_dai_link dm6446_evm_dai = {
 	.name = "TLV320AIC3X",
 	.name = "TLV320AIC3X",
 	.stream_name = "AIC3X",
 	.stream_name = "AIC3X",
-	.cpu_dai_name = "davinci-mcasp.0",
+	.cpu_dai_name = "davinci-mcbsp",
 	.codec_dai_name = "tlv320aic3x-hifi",
 	.codec_dai_name = "tlv320aic3x-hifi",
-	.codec_name = "tlv320aic3x-codec.0-001a",
+	.codec_name = "tlv320aic3x-codec.1-001b",
+	.platform_name = "davinci-pcm-audio",
+	.init = evm_aic3x_init,
+	.ops = &evm_ops,
+};
+
+static struct snd_soc_dai_link dm355_evm_dai = {
+	.name = "TLV320AIC3X",
+	.stream_name = "AIC3X",
+	.cpu_dai_name = "davinci-mcbsp.1",
+	.codec_dai_name = "tlv320aic3x-hifi",
+	.codec_name = "tlv320aic3x-codec.1-001b",
 	.platform_name = "davinci-pcm-audio",
 	.platform_name = "davinci-pcm-audio",
 	.init = evm_aic3x_init,
 	.init = evm_aic3x_init,
 	.ops = &evm_ops,
 	.ops = &evm_ops,
@@ -172,10 +183,10 @@ static struct snd_soc_dai_link dm365_evm_dai = {
 #ifdef CONFIG_SND_DM365_AIC3X_CODEC
 #ifdef CONFIG_SND_DM365_AIC3X_CODEC
 	.name = "TLV320AIC3X",
 	.name = "TLV320AIC3X",
 	.stream_name = "AIC3X",
 	.stream_name = "AIC3X",
-	.cpu_dai_name = "davinci-i2s",
+	.cpu_dai_name = "davinci-mcbsp",
 	.codec_dai_name = "tlv320aic3x-hifi",
 	.codec_dai_name = "tlv320aic3x-hifi",
 	.init = evm_aic3x_init,
 	.init = evm_aic3x_init,
-	.codec_name = "tlv320aic3x-codec.0-001a",
+	.codec_name = "tlv320aic3x-codec.1-0018",
 	.ops = &evm_ops,
 	.ops = &evm_ops,
 #elif defined(CONFIG_SND_DM365_VOICE_CODEC)
 #elif defined(CONFIG_SND_DM365_VOICE_CODEC)
 	.name = "Voice Codec - CQ93VC",
 	.name = "Voice Codec - CQ93VC",
@@ -219,10 +230,17 @@ static struct snd_soc_dai_link da8xx_evm_dai = {
 	.ops = &evm_ops,
 	.ops = &evm_ops,
 };
 };
 
 
-/* davinci dm6446, dm355 evm audio machine driver */
-static struct snd_soc_card snd_soc_card_evm = {
-	.name = "DaVinci EVM",
-	.dai_link = &evm_dai,
+/* davinci dm6446 evm audio machine driver */
+static struct snd_soc_card dm6446_snd_soc_card_evm = {
+	.name = "DaVinci DM6446 EVM",
+	.dai_link = &dm6446_evm_dai,
+	.num_links = 1,
+};
+
+/* davinci dm355 evm audio machine driver */
+static struct snd_soc_card dm355_snd_soc_card_evm = {
+	.name = "DaVinci DM355 EVM",
+	.dai_link = &dm355_evm_dai,
 	.num_links = 1,
 	.num_links = 1,
 };
 };
 
 
@@ -261,10 +279,10 @@ static int __init evm_init(void)
 	int ret;
 	int ret;
 
 
 	if (machine_is_davinci_evm()) {
 	if (machine_is_davinci_evm()) {
-		evm_snd_dev_data = &snd_soc_card_evm;
+		evm_snd_dev_data = &dm6446_snd_soc_card_evm;
 		index = 0;
 		index = 0;
 	} else if (machine_is_davinci_dm355_evm()) {
 	} else if (machine_is_davinci_dm355_evm()) {
-		evm_snd_dev_data = &snd_soc_card_evm;
+		evm_snd_dev_data = &dm355_snd_soc_card_evm;
 		index = 1;
 		index = 1;
 	} else if (machine_is_davinci_dm365_evm()) {
 	} else if (machine_is_davinci_dm365_evm()) {
 		evm_snd_dev_data = &dm365_snd_soc_card_evm;
 		evm_snd_dev_data = &dm365_snd_soc_card_evm;

+ 11 - 4
sound/soc/davinci/davinci-i2s.c

@@ -426,9 +426,6 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
 	snd_pcm_format_t fmt;
 	snd_pcm_format_t fmt;
 	unsigned element_cnt = 1;
 	unsigned element_cnt = 1;
 
 
-	dai->capture_dma_data = dev->dma_params;
-	dai->playback_dma_data = dev->dma_params;
-
 	/* general line settings */
 	/* general line settings */
 	spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
 	spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
@@ -601,6 +598,15 @@ static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
 	return ret;
 	return ret;
 }
 }
 
 
+static int davinci_i2s_startup(struct snd_pcm_substream *substream,
+			       struct snd_soc_dai *dai)
+{
+	struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
+
+	snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
+	return 0;
+}
+
 static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
 static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
 		struct snd_soc_dai *dai)
 		struct snd_soc_dai *dai)
 {
 {
@@ -612,6 +618,7 @@ static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
 #define DAVINCI_I2S_RATES	SNDRV_PCM_RATE_8000_96000
 #define DAVINCI_I2S_RATES	SNDRV_PCM_RATE_8000_96000
 
 
 static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
 static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
+	.startup	= davinci_i2s_startup,
 	.shutdown	= davinci_i2s_shutdown,
 	.shutdown	= davinci_i2s_shutdown,
 	.prepare	= davinci_i2s_prepare,
 	.prepare	= davinci_i2s_prepare,
 	.trigger	= davinci_i2s_trigger,
 	.trigger	= davinci_i2s_trigger,
@@ -749,7 +756,7 @@ static struct platform_driver davinci_mcbsp_driver = {
 	.probe		= davinci_i2s_probe,
 	.probe		= davinci_i2s_probe,
 	.remove		= davinci_i2s_remove,
 	.remove		= davinci_i2s_remove,
 	.driver		= {
 	.driver		= {
-		.name	= "davinci-i2s",
+		.name	= "davinci-mcbsp",
 		.owner	= THIS_MODULE,
 		.owner	= THIS_MODULE,
 	},
 	},
 };
 };

+ 10 - 3
sound/soc/davinci/davinci-mcasp.c

@@ -715,9 +715,6 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
 	int word_length;
 	int word_length;
 	u8 fifo_level;
 	u8 fifo_level;
 
 
-	cpu_dai->capture_dma_data = dev->dma_params;
-	cpu_dai->playback_dma_data = dev->dma_params;
-
 	davinci_hw_common_param(dev, substream->stream);
 	davinci_hw_common_param(dev, substream->stream);
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		fifo_level = dev->txnumevt;
 		fifo_level = dev->txnumevt;
@@ -799,7 +796,17 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
 	return ret;
 	return ret;
 }
 }
 
 
+static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
+				 struct snd_soc_dai *dai)
+{
+	struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai);
+
+	snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
+	return 0;
+}
+
 static struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
 static struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
+	.startup	= davinci_mcasp_startup,
 	.trigger	= davinci_mcasp_trigger,
 	.trigger	= davinci_mcasp_trigger,
 	.hw_params	= davinci_mcasp_hw_params,
 	.hw_params	= davinci_mcasp_hw_params,
 	.set_fmt	= davinci_mcasp_set_dai_fmt,
 	.set_fmt	= davinci_mcasp_set_dai_fmt,

+ 1 - 1
sound/soc/davinci/davinci-sffsdr.c

@@ -84,7 +84,7 @@ static struct snd_soc_ops sffsdr_ops = {
 static struct snd_soc_dai_link sffsdr_dai = {
 static struct snd_soc_dai_link sffsdr_dai = {
 	.name = "PCM3008", /* Codec name */
 	.name = "PCM3008", /* Codec name */
 	.stream_name = "PCM3008 HiFi",
 	.stream_name = "PCM3008 HiFi",
-	.cpu_dai_name = "davinci-asp.0",
+	.cpu_dai_name = "davinci-mcbsp",
 	.codec_dai_name = "pcm3008-hifi",
 	.codec_dai_name = "pcm3008-hifi",
 	.codec_name = "pcm3008-codec",
 	.codec_name = "pcm3008-codec",
 	.platform_name = "davinci-pcm-audio",
 	.platform_name = "davinci-pcm-audio",

+ 10 - 3
sound/soc/davinci/davinci-vcif.c

@@ -97,9 +97,6 @@ static int davinci_vcif_hw_params(struct snd_pcm_substream *substream,
 			&davinci_vcif_dev->dma_params[substream->stream];
 			&davinci_vcif_dev->dma_params[substream->stream];
 	u32 w;
 	u32 w;
 
 
-	dai->capture_dma_data = davinci_vcif_dev->dma_params;
-	dai->playback_dma_data = davinci_vcif_dev->dma_params;
-
 	/* Restart the codec before setup */
 	/* Restart the codec before setup */
 	davinci_vcif_stop(substream);
 	davinci_vcif_stop(substream);
 	davinci_vcif_start(substream);
 	davinci_vcif_start(substream);
@@ -174,9 +171,19 @@ static int davinci_vcif_trigger(struct snd_pcm_substream *substream, int cmd,
 	return ret;
 	return ret;
 }
 }
 
 
+static int davinci_vcif_startup(struct snd_pcm_substream *substream,
+				struct snd_soc_dai *dai)
+{
+	struct davinci_vcif_dev *dev = snd_soc_dai_get_drvdata(dai);
+
+	snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
+	return 0;
+}
+
 #define DAVINCI_VCIF_RATES	SNDRV_PCM_RATE_8000_48000
 #define DAVINCI_VCIF_RATES	SNDRV_PCM_RATE_8000_48000
 
 
 static struct snd_soc_dai_ops davinci_vcif_dai_ops = {
 static struct snd_soc_dai_ops davinci_vcif_dai_ops = {
+	.startup	= davinci_vcif_startup,
 	.trigger	= davinci_vcif_trigger,
 	.trigger	= davinci_vcif_trigger,
 	.hw_params	= davinci_vcif_hw_params,
 	.hw_params	= davinci_vcif_hw_params,
 };
 };

+ 1 - 1
sound/soc/fsl/mpc5200_psc_i2s.c

@@ -160,7 +160,7 @@ static int __devinit psc_i2s_of_probe(struct platform_device *op,
 	rc = snd_soc_register_dais(&op->dev, psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai));
 	rc = snd_soc_register_dais(&op->dev, psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai));
 	if (rc != 0) {
 	if (rc != 0) {
 		pr_err("Failed to register DAI\n");
 		pr_err("Failed to register DAI\n");
-		return 0;
+		return rc;
 	}
 	}
 
 
 	psc_dma = dev_get_drvdata(&op->dev);
 	psc_dma = dev_get_drvdata(&op->dev);

+ 4 - 4
sound/soc/imx/eukrea-tlv320.c

@@ -34,8 +34,8 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params)
 			    struct snd_pcm_hw_params *params)
 {
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
-	struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	int ret;
 	int ret;
 
 
 	ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
 	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 = {
 static struct snd_soc_dai_link eukrea_tlv320_dai = {
 static struct snd_soc_dai_link eukrea_tlv320_dai = {
 	.name		= "tlv320aic23",
 	.name		= "tlv320aic23",
 	.stream_name	= "TLV320AIC23",
 	.stream_name	= "TLV320AIC23",
-	.codec_dai	= "tlv320aic23-hifi",
+	.codec_dai_name	= "tlv320aic23-hifi",
 	.platform_name	= "imx-pcm-audio.0",
 	.platform_name	= "imx-pcm-audio.0",
 	.codec_name	= "tlv320aic23-codec.0-001a",
 	.codec_name	= "tlv320aic23-codec.0-001a",
-	.cpu_dai = "imx-ssi.0",
+	.cpu_dai_name	= "imx-ssi.0",
 	.ops		= &eukrea_tlv320_snd_ops,
 	.ops		= &eukrea_tlv320_snd_ops,
 };
 };
 
 

+ 98 - 123
sound/soc/imx/imx-pcm-dma-mx2.c

@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
+#include <linux/dmaengine.h>
 
 
 #include <sound/core.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/initval.h>
@@ -27,165 +28,146 @@
 #include <sound/pcm_params.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <sound/soc.h>
 
 
-#include <mach/dma-mx1-mx2.h>
+#include <mach/dma.h>
 
 
 #include "imx-ssi.h"
 #include "imx-ssi.h"
 
 
 struct imx_pcm_runtime_data {
 struct imx_pcm_runtime_data {
-	int sg_count;
-	struct scatterlist *sg_list;
-	int period;
+	int period_bytes;
 	int periods;
 	int periods;
-	unsigned long dma_addr;
 	int dma;
 	int dma;
-	struct snd_pcm_substream *substream;
 	unsigned long offset;
 	unsigned long offset;
 	unsigned long size;
 	unsigned long size;
-	unsigned long period_cnt;
 	void *buf;
 	void *buf;
 	int period_time;
 	int period_time;
+	struct dma_async_tx_descriptor *desc;
+	struct dma_chan *dma_chan;
+	struct imx_dma_data dma_data;
 };
 };
 
 
-/* Called by the DMA framework when a period has elapsed */
-static void imx_ssi_dma_progression(int channel, void *data,
-					struct scatterlist *sg)
+static void audio_dma_irq(void *data)
 {
 {
-	struct snd_pcm_substream *substream = data;
+	struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct imx_pcm_runtime_data *iprtd = runtime->private_data;
 	struct imx_pcm_runtime_data *iprtd = runtime->private_data;
 
 
-	if (!sg)
-		return;
-
-	runtime = iprtd->substream->runtime;
+	iprtd->offset += iprtd->period_bytes;
+	iprtd->offset %= iprtd->period_bytes * iprtd->periods;
 
 
-	iprtd->offset = sg->dma_address - runtime->dma_addr;
-
-	snd_pcm_period_elapsed(iprtd->substream);
+	snd_pcm_period_elapsed(substream);
 }
 }
 
 
-static void imx_ssi_dma_callback(int channel, void *data)
+static bool filter(struct dma_chan *chan, void *param)
 {
 {
-	pr_err("%s shouldn't be called\n", __func__);
-}
+	struct imx_pcm_runtime_data *iprtd = param;
 
 
-static void snd_imx_dma_err_callback(int channel, void *data, int err)
-{
-	struct snd_pcm_substream *substream = data;
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct imx_pcm_dma_params *dma_params = 
-		snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct imx_pcm_runtime_data *iprtd = runtime->private_data;
-	int ret;
+	if (!imx_dma_is_general_purpose(chan))
+		return false;
 
 
-	pr_err("DMA timeout on channel %d -%s%s%s%s\n",
-		 channel,
-		 err & IMX_DMA_ERR_BURST ?    " burst" : "",
-		 err & IMX_DMA_ERR_REQUEST ?  " request" : "",
-		 err & IMX_DMA_ERR_TRANSFER ? " transfer" : "",
-		 err & IMX_DMA_ERR_BUFFER ?   " buffer" : "");
+        chan->private = &iprtd->dma_data;
 
 
-	imx_dma_disable(iprtd->dma);
-	ret = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count,
-			IMX_DMA_LENGTH_LOOP, dma_params->dma_addr,
-			substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
-			DMA_MODE_WRITE : DMA_MODE_READ);
-	if (!ret)
-		imx_dma_enable(iprtd->dma);
+        return true;
 }
 }
 
 
-static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream)
+static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream,
+				struct snd_pcm_hw_params *params)
 {
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct imx_pcm_dma_params *dma_params;
 	struct imx_pcm_dma_params *dma_params;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct imx_pcm_runtime_data *iprtd = runtime->private_data;
 	struct imx_pcm_runtime_data *iprtd = runtime->private_data;
+	struct dma_slave_config slave_config;
+	dma_cap_mask_t mask;
+	enum dma_slave_buswidth buswidth;
 	int ret;
 	int ret;
 
 
 	dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
 	dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
 
 
-	iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH);
-	if (iprtd->dma < 0) {
-		pr_err("Failed to claim the audio DMA\n");
-		return -ENODEV;
-	}
+	iprtd->dma_data.peripheral_type = IMX_DMATYPE_SSI;
+	iprtd->dma_data.priority = DMA_PRIO_HIGH;
+	iprtd->dma_data.dma_request = dma_params->dma;
 
 
-	ret = imx_dma_setup_handlers(iprtd->dma,
-				imx_ssi_dma_callback,
-				snd_imx_dma_err_callback, substream);
-	if (ret)
-		goto out;
+	/* Try to grab a DMA channel */
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+	iprtd->dma_chan = dma_request_channel(mask, filter, iprtd);
+	if (!iprtd->dma_chan)
+		return -EINVAL;
 
 
-	ret = imx_dma_setup_progression_handler(iprtd->dma,
-			imx_ssi_dma_progression);
-	if (ret) {
-		pr_err("Failed to setup the DMA handler\n");
-		goto out;
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
+		break;
+	case SNDRV_PCM_FORMAT_S20_3LE:
+	case SNDRV_PCM_FORMAT_S24_LE:
+		buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
+		break;
+	default:
+		return 0;
 	}
 	}
 
 
-	ret = imx_dma_config_channel(iprtd->dma,
-			IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
-			IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
-			dma_params->dma, 1);
-	if (ret < 0) {
-		pr_err("Cannot configure DMA channel: %d\n", ret);
-		goto out;
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		slave_config.direction = DMA_TO_DEVICE;
+		slave_config.dst_addr = dma_params->dma_addr;
+		slave_config.dst_addr_width = buswidth;
+		slave_config.dst_maxburst = dma_params->burstsize;
+	} else {
+		slave_config.direction = DMA_FROM_DEVICE;
+		slave_config.src_addr = dma_params->dma_addr;
+		slave_config.src_addr_width = buswidth;
+		slave_config.src_maxburst = dma_params->burstsize;
 	}
 	}
 
 
-	imx_dma_config_burstlen(iprtd->dma, dma_params->burstsize * 2);
+	ret = dmaengine_slave_config(iprtd->dma_chan, &slave_config);
+	if (ret)
+		return ret;
 
 
 	return 0;
 	return 0;
-out:
-	imx_dma_free(iprtd->dma);
-	return ret;
 }
 }
 
 
 static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
 static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
 				struct snd_pcm_hw_params *params)
 				struct snd_pcm_hw_params *params)
 {
 {
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct imx_pcm_runtime_data *iprtd = runtime->private_data;
 	struct imx_pcm_runtime_data *iprtd = runtime->private_data;
-	int i;
 	unsigned long dma_addr;
 	unsigned long dma_addr;
+	struct dma_chan *chan;
+	struct imx_pcm_dma_params *dma_params;
+	int ret;
 
 
-	imx_ssi_dma_alloc(substream);
+	dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+	ret = imx_ssi_dma_alloc(substream, params);
+	if (ret)
+		return ret;
+	chan = iprtd->dma_chan;
 
 
 	iprtd->size = params_buffer_bytes(params);
 	iprtd->size = params_buffer_bytes(params);
 	iprtd->periods = params_periods(params);
 	iprtd->periods = params_periods(params);
-	iprtd->period = params_period_bytes(params);
+	iprtd->period_bytes = params_period_bytes(params);
 	iprtd->offset = 0;
 	iprtd->offset = 0;
 	iprtd->period_time = HZ / (params_rate(params) /
 	iprtd->period_time = HZ / (params_rate(params) /
 			params_period_size(params));
 			params_period_size(params));
 
 
 	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
 	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
 
 
-	if (iprtd->sg_count != iprtd->periods) {
-		kfree(iprtd->sg_list);
-
-		iprtd->sg_list = kcalloc(iprtd->periods + 1,
-				sizeof(struct scatterlist), GFP_KERNEL);
-		if (!iprtd->sg_list)
-			return -ENOMEM;
-		iprtd->sg_count = iprtd->periods + 1;
-	}
-
-	sg_init_table(iprtd->sg_list, iprtd->sg_count);
 	dma_addr = runtime->dma_addr;
 	dma_addr = runtime->dma_addr;
 
 
-	for (i = 0; i < iprtd->periods; i++) {
-		iprtd->sg_list[i].page_link = 0;
-		iprtd->sg_list[i].offset = 0;
-		iprtd->sg_list[i].dma_address = dma_addr;
-		iprtd->sg_list[i].length = iprtd->period;
-		dma_addr += iprtd->period;
+	iprtd->buf = (unsigned int *)substream->dma_buffer.area;
+
+	iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr,
+			iprtd->period_bytes * iprtd->periods,
+			iprtd->period_bytes,
+			substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
+			DMA_TO_DEVICE : DMA_FROM_DEVICE);
+	if (!iprtd->desc) {
+		dev_err(&chan->dev->device, "cannot prepare slave dma\n");
+		return -EINVAL;
 	}
 	}
 
 
-	/* close the loop */
-	iprtd->sg_list[iprtd->sg_count - 1].offset = 0;
-	iprtd->sg_list[iprtd->sg_count - 1].length = 0;
-	iprtd->sg_list[iprtd->sg_count - 1].page_link =
-			((unsigned long) iprtd->sg_list | 0x01) & ~0x02;
+	iprtd->desc->callback = audio_dma_irq;
+	iprtd->desc->callback_param = substream;
+
 	return 0;
 	return 0;
 }
 }
 
 
@@ -194,41 +176,21 @@ static int snd_imx_pcm_hw_free(struct snd_pcm_substream *substream)
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct imx_pcm_runtime_data *iprtd = runtime->private_data;
 	struct imx_pcm_runtime_data *iprtd = runtime->private_data;
 
 
-	if (iprtd->dma >= 0) {
-		imx_dma_free(iprtd->dma);
-		iprtd->dma = -EINVAL;
+	if (iprtd->dma_chan) {
+		dma_release_channel(iprtd->dma_chan);
+		iprtd->dma_chan = NULL;
 	}
 	}
 
 
-	kfree(iprtd->sg_list);
-	iprtd->sg_list = NULL;
-
 	return 0;
 	return 0;
 }
 }
 
 
 static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
 static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
 {
 {
-	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct imx_pcm_dma_params *dma_params;
 	struct imx_pcm_dma_params *dma_params;
-	struct imx_pcm_runtime_data *iprtd = runtime->private_data;
-	int err;
 
 
 	dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
 	dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
 
 
-	iprtd->substream = substream;
-	iprtd->buf = (unsigned int *)substream->dma_buffer.area;
-	iprtd->period_cnt = 0;
-
-	pr_debug("%s: buf: %p period: %d periods: %d\n",
-			__func__, iprtd->buf, iprtd->period, iprtd->periods);
-
-	err = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count,
-			IMX_DMA_LENGTH_LOOP, dma_params->dma_addr,
-			substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
-			DMA_MODE_WRITE : DMA_MODE_READ);
-	if (err)
-		return err;
-
 	return 0;
 	return 0;
 }
 }
 
 
@@ -241,14 +203,14 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		imx_dma_enable(iprtd->dma);
+		dmaengine_submit(iprtd->desc);
 
 
 		break;
 		break;
 
 
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		imx_dma_disable(iprtd->dma);
+		dmaengine_terminate_all(iprtd->dma_chan);
 
 
 		break;
 		break;
 	default:
 	default:
@@ -263,6 +225,9 @@ static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct imx_pcm_runtime_data *iprtd = runtime->private_data;
 	struct imx_pcm_runtime_data *iprtd = runtime->private_data;
 
 
+	pr_debug("%s: %ld %ld\n", __func__, iprtd->offset,
+			bytes_to_frames(substream->runtime, iprtd->offset));
+
 	return bytes_to_frames(substream->runtime, iprtd->offset);
 	return bytes_to_frames(substream->runtime, iprtd->offset);
 }
 }
 
 
@@ -279,7 +244,7 @@ static struct snd_pcm_hardware snd_imx_hardware = {
 	.channels_max = 2,
 	.channels_max = 2,
 	.buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
 	.buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
 	.period_bytes_min = 128,
 	.period_bytes_min = 128,
-	.period_bytes_max = 16 * 1024,
+	.period_bytes_max = 65535, /* Limited by SDMA engine */
 	.periods_min = 2,
 	.periods_min = 2,
 	.periods_max = 255,
 	.periods_max = 255,
 	.fifo_size = 0,
 	.fifo_size = 0,
@@ -304,11 +269,23 @@ static int snd_imx_open(struct snd_pcm_substream *substream)
 	}
 	}
 
 
 	snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
 	snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
+
+	return 0;
+}
+
+static int snd_imx_close(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct imx_pcm_runtime_data *iprtd = runtime->private_data;
+
+	kfree(iprtd);
+
 	return 0;
 	return 0;
 }
 }
 
 
 static struct snd_pcm_ops imx_pcm_ops = {
 static struct snd_pcm_ops imx_pcm_ops = {
 	.open		= snd_imx_open,
 	.open		= snd_imx_open,
+	.close		= snd_imx_close,
 	.ioctl		= snd_pcm_lib_ioctl,
 	.ioctl		= snd_pcm_lib_ioctl,
 	.hw_params	= snd_imx_pcm_hw_params,
 	.hw_params	= snd_imx_pcm_hw_params,
 	.hw_free	= snd_imx_pcm_hw_free,
 	.hw_free	= snd_imx_pcm_hw_free,
@@ -340,7 +317,6 @@ static struct platform_driver imx_pcm_driver = {
 			.name = "imx-pcm-audio",
 			.name = "imx-pcm-audio",
 			.owner = THIS_MODULE,
 			.owner = THIS_MODULE,
 	},
 	},
-
 	.probe = imx_soc_platform_probe,
 	.probe = imx_soc_platform_probe,
 	.remove = __devexit_p(imx_soc_platform_remove),
 	.remove = __devexit_p(imx_soc_platform_remove),
 };
 };
@@ -356,4 +332,3 @@ static void __exit snd_imx_pcm_exit(void)
 	platform_driver_unregister(&imx_pcm_driver);
 	platform_driver_unregister(&imx_pcm_driver);
 }
 }
 module_exit(snd_imx_pcm_exit);
 module_exit(snd_imx_pcm_exit);
-

+ 29 - 15
sound/soc/imx/imx-ssi.c

@@ -439,7 +439,22 @@ void imx_pcm_free(struct snd_pcm *pcm)
 }
 }
 EXPORT_SYMBOL_GPL(imx_pcm_free);
 EXPORT_SYMBOL_GPL(imx_pcm_free);
 
 
+static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
+{
+	struct imx_ssi *ssi = dev_get_drvdata(dai->dev);
+	uint32_t val;
+
+	snd_soc_dai_set_drvdata(dai, ssi);
+
+	val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) |
+		SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize);
+	writel(val, ssi->base + SSI_SFCSR);
+
+	return 0;
+}
+
 static struct snd_soc_dai_driver imx_ssi_dai = {
 static struct snd_soc_dai_driver imx_ssi_dai = {
+	.probe = imx_ssi_dai_probe,
 	.playback = {
 	.playback = {
 		.channels_min = 2,
 		.channels_min = 2,
 		.channels_max = 2,
 		.channels_max = 2,
@@ -455,20 +470,6 @@ static struct snd_soc_dai_driver imx_ssi_dai = {
 	.ops = &imx_ssi_pcm_dai_ops,
 	.ops = &imx_ssi_pcm_dai_ops,
 };
 };
 
 
-static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
-{
-	struct imx_ssi *ssi = dev_get_drvdata(dai->dev);
-	uint32_t val;
-
-	snd_soc_dai_set_drvdata(dai, ssi);
-
-	val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) |
-		SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize);
-	writel(val, ssi->base + SSI_SFCSR);
-
-	return 0;
-}
-
 static struct snd_soc_dai_driver imx_ac97_dai = {
 static struct snd_soc_dai_driver imx_ac97_dai = {
 	.probe = imx_ssi_dai_probe,
 	.probe = imx_ssi_dai_probe,
 	.ac97_control = 1,
 	.ac97_control = 1,
@@ -677,7 +678,17 @@ static int imx_ssi_probe(struct platform_device *pdev)
 		goto failed_register;
 		goto failed_register;
 	}
 	}
 
 
-	ssi->soc_platform_pdev = platform_device_alloc("imx-fiq-pcm-audio", pdev->id);
+	ssi->soc_platform_pdev_fiq = platform_device_alloc("imx-fiq-pcm-audio", pdev->id);
+	if (!ssi->soc_platform_pdev_fiq)
+		goto failed_pdev_fiq_alloc;
+	platform_set_drvdata(ssi->soc_platform_pdev_fiq, ssi);
+	ret = platform_device_add(ssi->soc_platform_pdev_fiq);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to add platform device\n");
+		goto failed_pdev_fiq_add;
+	}
+
+	ssi->soc_platform_pdev = platform_device_alloc("imx-pcm-audio", pdev->id);
 	if (!ssi->soc_platform_pdev)
 	if (!ssi->soc_platform_pdev)
 		goto failed_pdev_alloc;
 		goto failed_pdev_alloc;
 	platform_set_drvdata(ssi->soc_platform_pdev, ssi);
 	platform_set_drvdata(ssi->soc_platform_pdev, ssi);
@@ -692,6 +703,9 @@ static int imx_ssi_probe(struct platform_device *pdev)
 failed_pdev_add:
 failed_pdev_add:
 	platform_device_put(ssi->soc_platform_pdev);
 	platform_device_put(ssi->soc_platform_pdev);
 failed_pdev_alloc:
 failed_pdev_alloc:
+failed_pdev_fiq_add:
+	platform_device_put(ssi->soc_platform_pdev_fiq);
+failed_pdev_fiq_alloc:
 	snd_soc_unregister_dai(&pdev->dev);
 	snd_soc_unregister_dai(&pdev->dev);
 failed_register:
 failed_register:
 failed_ac97:
 failed_ac97:

+ 4 - 0
sound/soc/imx/imx-ssi.h

@@ -185,6 +185,9 @@
 
 
 #define DRV_NAME "imx-ssi"
 #define DRV_NAME "imx-ssi"
 
 
+#include <linux/dmaengine.h>
+#include <mach/dma.h>
+
 struct imx_pcm_dma_params {
 struct imx_pcm_dma_params {
 	int dma;
 	int dma;
 	unsigned long dma_addr;
 	unsigned long dma_addr;
@@ -212,6 +215,7 @@ struct imx_ssi {
 	int enabled;
 	int enabled;
 
 
 	struct platform_device *soc_platform_pdev;
 	struct platform_device *soc_platform_pdev;
+	struct platform_device *soc_platform_pdev_fiq;
 };
 };
 
 
 struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev,
 struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev,

+ 1 - 4
sound/soc/imx/phycore-ac97.c

@@ -20,9 +20,6 @@
 #include <sound/soc-dapm.h>
 #include <sound/soc-dapm.h>
 #include <asm/mach-types.h>
 #include <asm/mach-types.h>
 
 
-#include "../codecs/wm9712.h"
-#include "imx-ssi.h"
-
 static struct snd_soc_card imx_phycore;
 static struct snd_soc_card imx_phycore;
 
 
 static struct snd_soc_ops imx_phycore_hifi_ops = {
 static struct snd_soc_ops imx_phycore_hifi_ops = {
@@ -41,7 +38,7 @@ static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
 };
 };
 
 
 static struct snd_soc_card imx_phycore = {
 static struct snd_soc_card imx_phycore = {
-	.name		= "PhyCORE-audio",
+	.name		= "PhyCORE-ac97-audio",
 	.dai_link	= imx_phycore_dai_ac97,
 	.dai_link	= imx_phycore_dai_ac97,
 	.num_links	= ARRAY_SIZE(imx_phycore_dai_ac97),
 	.num_links	= ARRAY_SIZE(imx_phycore_dai_ac97),
 };
 };

+ 8 - 0
sound/soc/omap/omap-mcbsp.c

@@ -644,15 +644,23 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
 
 
 
 
 	case OMAP_MCBSP_CLKR_SRC_CLKR:
 	case OMAP_MCBSP_CLKR_SRC_CLKR:
+		if (cpu_class_is_omap1())
+			break;
 		omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKR);
 		omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKR);
 		break;
 		break;
 	case OMAP_MCBSP_CLKR_SRC_CLKX:
 	case OMAP_MCBSP_CLKR_SRC_CLKX:
+		if (cpu_class_is_omap1())
+			break;
 		omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKX);
 		omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKX);
 		break;
 		break;
 	case OMAP_MCBSP_FSR_SRC_FSR:
 	case OMAP_MCBSP_FSR_SRC_FSR:
+		if (cpu_class_is_omap1())
+			break;
 		omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSR);
 		omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSR);
 		break;
 		break;
 	case OMAP_MCBSP_FSR_SRC_FSX:
 	case OMAP_MCBSP_FSR_SRC_FSX:
+		if (cpu_class_is_omap1())
+			break;
 		omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSX);
 		omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSX);
 		break;
 		break;
 	default:
 	default:

+ 5 - 0
sound/soc/pxa/corgi.c

@@ -100,8 +100,13 @@ static int corgi_startup(struct snd_pcm_substream *substream)
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_codec *codec = rtd->codec;
 	struct snd_soc_codec *codec = rtd->codec;
 
 
+	mutex_lock(&codec->mutex);
+
 	/* check the jack status at stream startup */
 	/* check the jack status at stream startup */
 	corgi_ext_control(codec);
 	corgi_ext_control(codec);
+
+	mutex_unlock(&codec->mutex);
+
 	return 0;
 	return 0;
 }
 }
 
 

+ 4 - 0
sound/soc/pxa/magician.c

@@ -72,9 +72,13 @@ static int magician_startup(struct snd_pcm_substream *substream)
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_codec *codec = rtd->codec;
 	struct snd_soc_codec *codec = rtd->codec;
 
 
+	mutex_lock(&codec->mutex);
+
 	/* check the jack status at stream startup */
 	/* check the jack status at stream startup */
 	magician_ext_control(codec);
 	magician_ext_control(codec);
 
 
+	mutex_unlock(&codec->mutex);
+
 	return 0;
 	return 0;
 }
 }
 
 

+ 5 - 0
sound/soc/pxa/poodle.c

@@ -77,8 +77,13 @@ static int poodle_startup(struct snd_pcm_substream *substream)
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_codec *codec = rtd->codec;
 	struct snd_soc_codec *codec = rtd->codec;
 
 
+	mutex_lock(&codec->mutex);
+
 	/* check the jack status at stream startup */
 	/* check the jack status at stream startup */
 	poodle_ext_control(codec);
 	poodle_ext_control(codec);
+
+	mutex_unlock(&codec->mutex);
+
 	return 0;
 	return 0;
 }
 }
 
 

+ 5 - 0
sound/soc/pxa/spitz.c

@@ -108,8 +108,13 @@ static int spitz_startup(struct snd_pcm_substream *substream)
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_codec *codec = rtd->codec;
 	struct snd_soc_codec *codec = rtd->codec;
 
 
+	mutex_lock(&codec->mutex);
+
 	/* check the jack status at stream startup */
 	/* check the jack status at stream startup */
 	spitz_ext_control(codec);
 	spitz_ext_control(codec);
+
+	mutex_unlock(&codec->mutex);
+
 	return 0;
 	return 0;
 }
 }
 
 

+ 5 - 0
sound/soc/pxa/tosa.c

@@ -81,8 +81,13 @@ static int tosa_startup(struct snd_pcm_substream *substream)
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_codec *codec = rtd->codec;
 	struct snd_soc_codec *codec = rtd->codec;
 
 
+	mutex_lock(&codec->mutex);
+
 	/* check the jack status at stream startup */
 	/* check the jack status at stream startup */
 	tosa_ext_control(codec);
 	tosa_ext_control(codec);
+
+	mutex_unlock(&codec->mutex);
+
 	return 0;
 	return 0;
 }
 }
 
 

+ 1 - 0
sound/soc/s3c24xx/Kconfig

@@ -2,6 +2,7 @@ config SND_S3C24XX_SOC
 	tristate "SoC Audio for the Samsung S3CXXXX chips"
 	tristate "SoC Audio for the Samsung S3CXXXX chips"
 	depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210
 	depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210
 	select S3C64XX_DMA if ARCH_S3C64XX
 	select S3C64XX_DMA if ARCH_S3C64XX
+	select S3C2410_DMA if ARCH_S3C2410
 	help
 	help
 	  Say Y or M if you want to add support for codecs attached to
 	  Say Y or M if you want to add support for codecs attached to
 	  the S3C24XX AC97 or I2S interfaces. You will also need to
 	  the S3C24XX AC97 or I2S interfaces. You will also need to

+ 3 - 17
sound/soc/s3c24xx/rx1950_uda1380.c

@@ -50,7 +50,6 @@ static unsigned int rates[] = {
 	16000,
 	16000,
 	44100,
 	44100,
 	48000,
 	48000,
-	88200,
 };
 };
 
 
 static struct snd_pcm_hw_constraint_list hw_rates = {
 static struct snd_pcm_hw_constraint_list hw_rates = {
@@ -130,7 +129,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
 };
 };
 
 
 static struct platform_device *s3c24xx_snd_device;
 static struct platform_device *s3c24xx_snd_device;
-static struct clk *xtal;
 
 
 static int rx1950_startup(struct snd_pcm_substream *substream)
 static int rx1950_startup(struct snd_pcm_substream *substream)
 {
 {
@@ -179,10 +177,8 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream,
 	case 44100:
 	case 44100:
 	case 88200:
 	case 88200:
 		clk_source = S3C24XX_CLKSRC_MPLL;
 		clk_source = S3C24XX_CLKSRC_MPLL;
-		fs_mode = S3C2410_IISMOD_256FS;
-		div = clk_get_rate(xtal) / (256 * rate);
-		if (clk_get_rate(xtal) % (256 * rate) > (128 * rate))
-			div++;
+		fs_mode = S3C2410_IISMOD_384FS;
+		div = 1;
 		break;
 		break;
 	default:
 	default:
 		printk(KERN_ERR "%s: rate %d is not supported\n",
 		printk(KERN_ERR "%s: rate %d is not supported\n",
@@ -210,7 +206,7 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream,
 
 
 	/* set MCLK division for sample rate */
 	/* set MCLK division for sample rate */
 	ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
 	ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
-		S3C2410_IISMOD_384FS);
+		fs_mode);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
@@ -295,17 +291,8 @@ static int __init rx1950_init(void)
 		goto err_plat_add;
 		goto err_plat_add;
 	}
 	}
 
 
-	xtal = clk_get(&s3c24xx_snd_device->dev, "xtal");
-
-	if (IS_ERR(xtal)) {
-		ret = PTR_ERR(xtal);
-		platform_device_unregister(s3c24xx_snd_device);
-		goto err_clk;
-	}
-
 	return 0;
 	return 0;
 
 
-err_clk:
 err_plat_add:
 err_plat_add:
 err_plat_alloc:
 err_plat_alloc:
 err_gpio_conf:
 err_gpio_conf:
@@ -320,7 +307,6 @@ static void __exit rx1950_exit(void)
 	platform_device_unregister(s3c24xx_snd_device);
 	platform_device_unregister(s3c24xx_snd_device);
 	snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios),
 	snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios),
 		hp_jack_gpios);
 		hp_jack_gpios);
-	clk_put(xtal);
 	gpio_free(S3C2410_GPA(1));
 	gpio_free(S3C2410_GPA(1));
 }
 }
 
 

+ 4 - 5
sound/soc/soc-core.c

@@ -3043,8 +3043,10 @@ int snd_soc_register_dais(struct device *dev,
 	for (i = 0; i < count; i++) {
 	for (i = 0; i < count; i++) {
 
 
 		dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL);
 		dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL);
-		if (dai == NULL)
-			return -ENOMEM;
+		if (dai == NULL) {
+			ret = -ENOMEM;
+			goto err;
+		}
 
 
 		/* create DAI component name */
 		/* create DAI component name */
 		dai->name = fmt_multiple_name(dev, &dai_drv[i]);
 		dai->name = fmt_multiple_name(dev, &dai_drv[i]);
@@ -3263,9 +3265,6 @@ int snd_soc_register_codec(struct device *dev,
 	return 0;
 	return 0;
 
 
 error:
 error:
-	for (i--; i >= 0; i--)
-		snd_soc_unregister_dai(dev);
-
 	if (codec->reg_cache)
 	if (codec->reg_cache)
 		kfree(codec->reg_cache);
 		kfree(codec->reg_cache);
 	kfree(codec->name);
 	kfree(codec->name);

+ 2 - 2
sound/soc/soc-dapm.c

@@ -683,12 +683,12 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
 			    struct snd_soc_dapm_widget *b,
 			    struct snd_soc_dapm_widget *b,
 			    int sort[])
 			    int sort[])
 {
 {
-	if (a->codec != b->codec)
-		return (unsigned long)a - (unsigned long)b;
 	if (sort[a->id] != sort[b->id])
 	if (sort[a->id] != sort[b->id])
 		return sort[a->id] - sort[b->id];
 		return sort[a->id] - sort[b->id];
 	if (a->reg != b->reg)
 	if (a->reg != b->reg)
 		return a->reg - b->reg;
 		return a->reg - b->reg;
+	if (a->codec != b->codec)
+		return (unsigned long)a->codec - (unsigned long)b->codec;
 
 
 	return 0;
 	return 0;
 }
 }