aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/codecs/ab8500-codec.c81
-rw-r--r--sound/soc/codecs/arizona.c2
-rw-r--r--sound/soc/codecs/mc13783.c8
-rw-r--r--sound/soc/codecs/wm8904.c2
-rw-r--r--sound/soc/fsl/imx-sgtl5000.c2
-rw-r--r--sound/soc/omap/am3517evm.c2
-rw-r--r--sound/soc/samsung/dma.c8
-rw-r--r--sound/soc/soc-dapm.c5
-rw-r--r--sound/soc/spear/spear_pcm.c2
-rw-r--r--sound/soc/tegra/tegra_alc5632.c1
-rw-r--r--sound/soc/tegra/tegra_pcm.c4
-rw-r--r--sound/soc/ux500/mop500.c47
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c6
-rw-r--r--sound/soc/ux500/ux500_msp_i2s.c114
-rw-r--r--sound/soc/ux500/ux500_msp_i2s.h8
15 files changed, 226 insertions, 66 deletions
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index 23b40186f9b8..07abd09e0b1d 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -34,6 +34,7 @@
34#include <linux/mfd/abx500/ab8500-sysctrl.h> 34#include <linux/mfd/abx500/ab8500-sysctrl.h>
35#include <linux/mfd/abx500/ab8500-codec.h> 35#include <linux/mfd/abx500/ab8500-codec.h>
36#include <linux/regulator/consumer.h> 36#include <linux/regulator/consumer.h>
37#include <linux/of.h>
37 38
38#include <sound/core.h> 39#include <sound/core.h>
39#include <sound/pcm.h> 40#include <sound/pcm.h>
@@ -2394,9 +2395,65 @@ struct snd_soc_dai_driver ab8500_codec_dai[] = {
2394 } 2395 }
2395}; 2396};
2396 2397
2398static void ab8500_codec_of_probe(struct device *dev, struct device_node *np,
2399 struct ab8500_codec_platform_data *codec)
2400{
2401 u32 value;
2402
2403 if (of_get_property(np, "stericsson,amic1-type-single-ended", NULL))
2404 codec->amics.mic1_type = AMIC_TYPE_SINGLE_ENDED;
2405 else
2406 codec->amics.mic1_type = AMIC_TYPE_DIFFERENTIAL;
2407
2408 if (of_get_property(np, "stericsson,amic2-type-single-ended", NULL))
2409 codec->amics.mic2_type = AMIC_TYPE_SINGLE_ENDED;
2410 else
2411 codec->amics.mic2_type = AMIC_TYPE_DIFFERENTIAL;
2412
2413 /* Has a non-standard Vamic been requested? */
2414 if (of_get_property(np, "stericsson,amic1a-bias-vamic2", NULL))
2415 codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC2;
2416 else
2417 codec->amics.mic1a_micbias = AMIC_MICBIAS_VAMIC1;
2418
2419 if (of_get_property(np, "stericsson,amic1b-bias-vamic2", NULL))
2420 codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC2;
2421 else
2422 codec->amics.mic1b_micbias = AMIC_MICBIAS_VAMIC1;
2423
2424 if (of_get_property(np, "stericsson,amic2-bias-vamic1", NULL))
2425 codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC1;
2426 else
2427 codec->amics.mic2_micbias = AMIC_MICBIAS_VAMIC2;
2428
2429 if (!of_property_read_u32(np, "stericsson,earpeice-cmv", &value)) {
2430 switch (value) {
2431 case 950 :
2432 codec->ear_cmv = EAR_CMV_0_95V;
2433 break;
2434 case 1100 :
2435 codec->ear_cmv = EAR_CMV_1_10V;
2436 break;
2437 case 1270 :
2438 codec->ear_cmv = EAR_CMV_1_27V;
2439 break;
2440 case 1580 :
2441 codec->ear_cmv = EAR_CMV_1_58V;
2442 break;
2443 default :
2444 codec->ear_cmv = EAR_CMV_UNKNOWN;
2445 dev_err(dev, "Unsuitable earpiece voltage found in DT\n");
2446 }
2447 } else {
2448 dev_warn(dev, "No earpiece voltage found in DT - using default\n");
2449 codec->ear_cmv = EAR_CMV_0_95V;
2450 }
2451}
2452
2397static int ab8500_codec_probe(struct snd_soc_codec *codec) 2453static int ab8500_codec_probe(struct snd_soc_codec *codec)
2398{ 2454{
2399 struct device *dev = codec->dev; 2455 struct device *dev = codec->dev;
2456 struct device_node *np = dev->of_node;
2400 struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev); 2457 struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev);
2401 struct ab8500_platform_data *pdata; 2458 struct ab8500_platform_data *pdata;
2402 struct filter_control *fc; 2459 struct filter_control *fc;
@@ -2410,6 +2467,30 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
2410 /* Inform SoC Core that we have our own I/O arrangements. */ 2467 /* Inform SoC Core that we have our own I/O arrangements. */
2411 codec->control_data = (void *)true; 2468 codec->control_data = (void *)true;
2412 2469
2470 if (np) {
2471 if (!pdata)
2472 pdata = devm_kzalloc(dev,
2473 sizeof(struct ab8500_platform_data),
2474 GFP_KERNEL);
2475
2476 if (pdata && !pdata->codec)
2477 pdata->codec
2478 = devm_kzalloc(dev,
2479 sizeof(struct ab8500_codec_platform_data),
2480 GFP_KERNEL);
2481
2482 if (!(pdata && pdata->codec))
2483 return -ENOMEM;
2484
2485 ab8500_codec_of_probe(dev, np, pdata->codec);
2486
2487 } else {
2488 if (!(pdata && pdata->codec)) {
2489 dev_err(dev, "No codec platform data or DT found\n");
2490 return -EINVAL;
2491 }
2492 }
2493
2413 status = ab8500_audio_setup_mics(codec, &pdata->codec->amics); 2494 status = ab8500_audio_setup_mics(codec, &pdata->codec->amics);
2414 if (status < 0) { 2495 if (status < 0) {
2415 pr_err("%s: Failed to setup mics (%d)!\n", __func__, status); 2496 pr_err("%s: Failed to setup mics (%d)!\n", __func__, status);
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 5c9cacaf2d52..1cf7a32d1b21 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -426,7 +426,7 @@ static const int arizona_44k1_bclk_rates[] = {
426 940800, 426 940800,
427 1411200, 427 1411200,
428 1881600, 428 1881600,
429 2882400, 429 2822400,
430 3763200, 430 3763200,
431 5644800, 431 5644800,
432 7526400, 432 7526400,
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c
index 8f726c063f42..115a40301810 100644
--- a/sound/soc/codecs/mc13783.c
+++ b/sound/soc/codecs/mc13783.c
@@ -659,7 +659,7 @@ static struct snd_soc_dai_driver mc13783_dai_async[] = {
659 .id = MC13783_ID_STEREO_DAC, 659 .id = MC13783_ID_STEREO_DAC,
660 .playback = { 660 .playback = {
661 .stream_name = "Playback", 661 .stream_name = "Playback",
662 .channels_min = 1, 662 .channels_min = 2,
663 .channels_max = 2, 663 .channels_max = 2,
664 .rates = SNDRV_PCM_RATE_8000_96000, 664 .rates = SNDRV_PCM_RATE_8000_96000,
665 .formats = MC13783_FORMATS, 665 .formats = MC13783_FORMATS,
@@ -670,7 +670,7 @@ static struct snd_soc_dai_driver mc13783_dai_async[] = {
670 .id = MC13783_ID_STEREO_CODEC, 670 .id = MC13783_ID_STEREO_CODEC,
671 .capture = { 671 .capture = {
672 .stream_name = "Capture", 672 .stream_name = "Capture",
673 .channels_min = 1, 673 .channels_min = 2,
674 .channels_max = 2, 674 .channels_max = 2,
675 .rates = MC13783_RATES_RECORD, 675 .rates = MC13783_RATES_RECORD,
676 .formats = MC13783_FORMATS, 676 .formats = MC13783_FORMATS,
@@ -692,14 +692,14 @@ static struct snd_soc_dai_driver mc13783_dai_sync[] = {
692 .id = MC13783_ID_SYNC, 692 .id = MC13783_ID_SYNC,
693 .playback = { 693 .playback = {
694 .stream_name = "Playback", 694 .stream_name = "Playback",
695 .channels_min = 1, 695 .channels_min = 2,
696 .channels_max = 2, 696 .channels_max = 2,
697 .rates = SNDRV_PCM_RATE_8000_96000, 697 .rates = SNDRV_PCM_RATE_8000_96000,
698 .formats = MC13783_FORMATS, 698 .formats = MC13783_FORMATS,
699 }, 699 },
700 .capture = { 700 .capture = {
701 .stream_name = "Capture", 701 .stream_name = "Capture",
702 .channels_min = 1, 702 .channels_min = 2,
703 .channels_max = 2, 703 .channels_max = 2,
704 .rates = MC13783_RATES_RECORD, 704 .rates = MC13783_RATES_RECORD,
705 .formats = MC13783_FORMATS, 705 .formats = MC13783_FORMATS,
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 0013afe48e66..dc4262eea4b7 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -100,7 +100,7 @@ static const struct reg_default wm8904_reg_defaults[] = {
100 { 14, 0x0000 }, /* R14 - Power Management 2 */ 100 { 14, 0x0000 }, /* R14 - Power Management 2 */
101 { 15, 0x0000 }, /* R15 - Power Management 3 */ 101 { 15, 0x0000 }, /* R15 - Power Management 3 */
102 { 18, 0x0000 }, /* R18 - Power Management 6 */ 102 { 18, 0x0000 }, /* R18 - Power Management 6 */
103 { 19, 0x945E }, /* R20 - Clock Rates 0 */ 103 { 20, 0x945E }, /* R20 - Clock Rates 0 */
104 { 21, 0x0C05 }, /* R21 - Clock Rates 1 */ 104 { 21, 0x0C05 }, /* R21 - Clock Rates 1 */
105 { 22, 0x0006 }, /* R22 - Clock Rates 2 */ 105 { 22, 0x0006 }, /* R22 - Clock Rates 2 */
106 { 24, 0x0050 }, /* R24 - Audio Interface 0 */ 106 { 24, 0x0050 }, /* R24 - Audio Interface 0 */
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c
index fb21b17f17f5..199408ec4261 100644
--- a/sound/soc/fsl/imx-sgtl5000.c
+++ b/sound/soc/fsl/imx-sgtl5000.c
@@ -94,7 +94,7 @@ static int __devinit imx_sgtl5000_probe(struct platform_device *pdev)
94 dev_err(&pdev->dev, "audmux internal port setup failed\n"); 94 dev_err(&pdev->dev, "audmux internal port setup failed\n");
95 return ret; 95 return ret;
96 } 96 }
97 imx_audmux_v2_configure_port(ext_port, 97 ret = imx_audmux_v2_configure_port(ext_port,
98 IMX_AUDMUX_V2_PTCR_SYN, 98 IMX_AUDMUX_V2_PTCR_SYN,
99 IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)); 99 IMX_AUDMUX_V2_PDCR_RXDSEL(int_port));
100 if (ret) { 100 if (ret) {
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
index 009533ab8d18..df65f98211ec 100644
--- a/sound/soc/omap/am3517evm.c
+++ b/sound/soc/omap/am3517evm.c
@@ -59,7 +59,7 @@ static int am3517evm_hw_params(struct snd_pcm_substream *substream,
59 return ret; 59 return ret;
60 } 60 }
61 61
62 snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_FSR_SRC_FSX, 0, 62 ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_FSR_SRC_FSX, 0,
63 SND_SOC_CLOCK_IN); 63 SND_SOC_CLOCK_IN);
64 if (ret < 0) { 64 if (ret < 0) {
65 printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_FSR_SRC_FSX\n"); 65 printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_FSR_SRC_FSX\n");
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c
index f3ebc38c10fe..b70964ea448c 100644
--- a/sound/soc/samsung/dma.c
+++ b/sound/soc/samsung/dma.c
@@ -34,9 +34,7 @@ static const struct snd_pcm_hardware dma_hardware = {
34 .info = SNDRV_PCM_INFO_INTERLEAVED | 34 .info = SNDRV_PCM_INFO_INTERLEAVED |
35 SNDRV_PCM_INFO_BLOCK_TRANSFER | 35 SNDRV_PCM_INFO_BLOCK_TRANSFER |
36 SNDRV_PCM_INFO_MMAP | 36 SNDRV_PCM_INFO_MMAP |
37 SNDRV_PCM_INFO_MMAP_VALID | 37 SNDRV_PCM_INFO_MMAP_VALID,
38 SNDRV_PCM_INFO_PAUSE |
39 SNDRV_PCM_INFO_RESUME,
40 .formats = SNDRV_PCM_FMTBIT_S16_LE | 38 .formats = SNDRV_PCM_FMTBIT_S16_LE |
41 SNDRV_PCM_FMTBIT_U16_LE | 39 SNDRV_PCM_FMTBIT_U16_LE |
42 SNDRV_PCM_FMTBIT_U8 | 40 SNDRV_PCM_FMTBIT_U8 |
@@ -248,15 +246,11 @@ static int dma_trigger(struct snd_pcm_substream *substream, int cmd)
248 246
249 switch (cmd) { 247 switch (cmd) {
250 case SNDRV_PCM_TRIGGER_START: 248 case SNDRV_PCM_TRIGGER_START:
251 case SNDRV_PCM_TRIGGER_RESUME:
252 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
253 prtd->state |= ST_RUNNING; 249 prtd->state |= ST_RUNNING;
254 prtd->params->ops->trigger(prtd->params->ch); 250 prtd->params->ops->trigger(prtd->params->ch);
255 break; 251 break;
256 252
257 case SNDRV_PCM_TRIGGER_STOP: 253 case SNDRV_PCM_TRIGGER_STOP:
258 case SNDRV_PCM_TRIGGER_SUSPEND:
259 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
260 prtd->state &= ~ST_RUNNING; 254 prtd->state &= ~ST_RUNNING;
261 prtd->params->ops->stop(prtd->params->ch); 255 prtd->params->ops->stop(prtd->params->ch);
262 break; 256 break;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index dd7c49fafd75..f90139b5f50d 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -291,8 +291,11 @@ static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm,
291 if (dapm->codec->driver->set_bias_level) 291 if (dapm->codec->driver->set_bias_level)
292 ret = dapm->codec->driver->set_bias_level(dapm->codec, 292 ret = dapm->codec->driver->set_bias_level(dapm->codec,
293 level); 293 level);
294 } else 294 else
295 dapm->bias_level = level;
296 } else if (!card || dapm != &card->dapm) {
295 dapm->bias_level = level; 297 dapm->bias_level = level;
298 }
296 299
297 if (ret != 0) 300 if (ret != 0)
298 goto out; 301 goto out;
diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c
index 97c2cac8e92c..8c7f23729446 100644
--- a/sound/soc/spear/spear_pcm.c
+++ b/sound/soc/spear/spear_pcm.c
@@ -138,7 +138,7 @@ static void spear_pcm_free(struct snd_pcm *pcm)
138 continue; 138 continue;
139 139
140 buf = &substream->dma_buffer; 140 buf = &substream->dma_buffer;
141 if (!buf && !buf->area) 141 if (!buf || !buf->area)
142 continue; 142 continue;
143 143
144 dma_free_writecombine(pcm->card->dev, buf->bytes, 144 dma_free_writecombine(pcm->card->dev, buf->bytes,
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index e463529b38bb..76cb1b363b71 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -89,7 +89,6 @@ static struct snd_soc_jack_gpio tegra_alc5632_hp_jack_gpio = {
89 .name = "Headset detection", 89 .name = "Headset detection",
90 .report = SND_JACK_HEADSET, 90 .report = SND_JACK_HEADSET,
91 .debounce_time = 150, 91 .debounce_time = 150,
92 .invert = 1,
93}; 92};
94 93
95static const struct snd_soc_dapm_widget tegra_alc5632_dapm_widgets[] = { 94static const struct snd_soc_dapm_widget tegra_alc5632_dapm_widgets[] = {
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index 5658bcec1931..8d6900c1ee47 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -334,11 +334,11 @@ static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
334 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 334 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
335 slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 335 slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
336 slave_config.dst_addr = dmap->addr; 336 slave_config.dst_addr = dmap->addr;
337 slave_config.src_maxburst = 0; 337 slave_config.dst_maxburst = 4;
338 } else { 338 } else {
339 slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 339 slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
340 slave_config.src_addr = dmap->addr; 340 slave_config.src_addr = dmap->addr;
341 slave_config.dst_maxburst = 0; 341 slave_config.src_maxburst = 4;
342 } 342 }
343 slave_config.slave_id = dmap->req_sel; 343 slave_config.slave_id = dmap->req_sel;
344 344
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c
index 31c4d26d0359..356611d9654d 100644
--- a/sound/soc/ux500/mop500.c
+++ b/sound/soc/ux500/mop500.c
@@ -16,6 +16,7 @@
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/spi/spi.h> 18#include <linux/spi/spi.h>
19#include <linux/of.h>
19 20
20#include <sound/soc.h> 21#include <sound/soc.h>
21#include <sound/initval.h> 22#include <sound/initval.h>
@@ -56,16 +57,47 @@ static struct snd_soc_card mop500_card = {
56 .num_links = ARRAY_SIZE(mop500_dai_links), 57 .num_links = ARRAY_SIZE(mop500_dai_links),
57}; 58};
58 59
60static int __devinit mop500_of_probe(struct platform_device *pdev,
61 struct device_node *np)
62{
63 struct device_node *codec_np, *msp_np[2];
64 int i;
65
66 msp_np[0] = of_parse_phandle(np, "stericsson,cpu-dai", 0);
67 msp_np[1] = of_parse_phandle(np, "stericsson,cpu-dai", 1);
68 codec_np = of_parse_phandle(np, "stericsson,audio-codec", 0);
69
70 if (!(msp_np[0] && msp_np[1] && codec_np)) {
71 dev_err(&pdev->dev, "Phandle missing or invalid\n");
72 return -EINVAL;
73 }
74
75 for (i = 0; i < 2; i++) {
76 mop500_dai_links[i].cpu_of_node = msp_np[i];
77 mop500_dai_links[i].cpu_dai_name = NULL;
78 mop500_dai_links[i].codec_of_node = codec_np;
79 mop500_dai_links[i].codec_name = NULL;
80 }
81
82 snd_soc_of_parse_card_name(&mop500_card, "stericsson,card-name");
83
84 return 0;
85}
59static int __devinit mop500_probe(struct platform_device *pdev) 86static int __devinit mop500_probe(struct platform_device *pdev)
60{ 87{
88 struct device_node *np = pdev->dev.of_node;
61 int ret; 89 int ret;
62 90
63 pr_debug("%s: Enter.\n", __func__);
64
65 dev_dbg(&pdev->dev, "%s: Enter.\n", __func__); 91 dev_dbg(&pdev->dev, "%s: Enter.\n", __func__);
66 92
67 mop500_card.dev = &pdev->dev; 93 mop500_card.dev = &pdev->dev;
68 94
95 if (np) {
96 ret = mop500_of_probe(pdev, np);
97 if (ret)
98 return ret;
99 }
100
69 dev_dbg(&pdev->dev, "%s: Card %s: Set platform drvdata.\n", 101 dev_dbg(&pdev->dev, "%s: Card %s: Set platform drvdata.\n",
70 __func__, mop500_card.name); 102 __func__, mop500_card.name);
71 platform_set_drvdata(pdev, &mop500_card); 103 platform_set_drvdata(pdev, &mop500_card);
@@ -83,8 +115,7 @@ static int __devinit mop500_probe(struct platform_device *pdev)
83 ret = snd_soc_register_card(&mop500_card); 115 ret = snd_soc_register_card(&mop500_card);
84 if (ret) 116 if (ret)
85 dev_err(&pdev->dev, 117 dev_err(&pdev->dev,
86 "Error: snd_soc_register_card failed (%d)!\n", 118 "Error: snd_soc_register_card failed (%d)!\n", ret);
87 ret);
88 119
89 return ret; 120 return ret;
90} 121}
@@ -97,14 +128,20 @@ static int __devexit mop500_remove(struct platform_device *pdev)
97 128
98 snd_soc_unregister_card(mop500_card); 129 snd_soc_unregister_card(mop500_card);
99 mop500_ab8500_remove(mop500_card); 130 mop500_ab8500_remove(mop500_card);
100 131
101 return 0; 132 return 0;
102} 133}
103 134
135static const struct of_device_id snd_soc_mop500_match[] = {
136 { .compatible = "stericsson,snd-soc-mop500", },
137 {},
138};
139
104static struct platform_driver snd_soc_mop500_driver = { 140static struct platform_driver snd_soc_mop500_driver = {
105 .driver = { 141 .driver = {
106 .owner = THIS_MODULE, 142 .owner = THIS_MODULE,
107 .name = "snd-soc-mop500", 143 .name = "snd-soc-mop500",
144 .of_match_table = snd_soc_mop500_match,
108 }, 145 },
109 .probe = mop500_probe, 146 .probe = mop500_probe,
110 .remove = __devexit_p(mop500_remove), 147 .remove = __devexit_p(mop500_remove),
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index 057e28ef770e..45e43b4057b0 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -830,10 +830,16 @@ static int __devexit ux500_msp_drv_remove(struct platform_device *pdev)
830 return 0; 830 return 0;
831} 831}
832 832
833static const struct of_device_id ux500_msp_i2s_match[] = {
834 { .compatible = "stericsson,ux500-msp-i2s", },
835 {},
836};
837
833static struct platform_driver msp_i2s_driver = { 838static struct platform_driver msp_i2s_driver = {
834 .driver = { 839 .driver = {
835 .name = "ux500-msp-i2s", 840 .name = "ux500-msp-i2s",
836 .owner = THIS_MODULE, 841 .owner = THIS_MODULE,
842 .of_match_table = ux500_msp_i2s_match,
837 }, 843 },
838 .probe = ux500_msp_drv_probe, 844 .probe = ux500_msp_drv_probe,
839 .remove = ux500_msp_drv_remove, 845 .remove = ux500_msp_drv_remove,
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index 5c472f335a64..e5c79ca42518 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -15,8 +15,10 @@
15 15
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/pinctrl/consumer.h>
18#include <linux/delay.h> 19#include <linux/delay.h>
19#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/of.h>
20 22
21#include <mach/hardware.h> 23#include <mach/hardware.h>
22#include <mach/msp.h> 24#include <mach/msp.h>
@@ -25,6 +27,9 @@
25 27
26#include "ux500_msp_i2s.h" 28#include "ux500_msp_i2s.h"
27 29
30/* MSP1/3 Tx/Rx usage protection */
31static DEFINE_SPINLOCK(msp_rxtx_lock);
32
28 /* Protocol desciptors */ 33 /* Protocol desciptors */
29static const struct msp_protdesc prot_descs[] = { 34static const struct msp_protdesc prot_descs[] = {
30 { /* I2S */ 35 { /* I2S */
@@ -352,17 +357,23 @@ static int configure_multichannel(struct ux500_msp *msp,
352 357
353static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config) 358static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config)
354{ 359{
355 int status = 0; 360 int status = 0, retval = 0;
356 u32 reg_val_DMACR, reg_val_GCR; 361 u32 reg_val_DMACR, reg_val_GCR;
362 unsigned long flags;
357 363
358 /* Check msp state whether in RUN or CONFIGURED Mode */ 364 /* Check msp state whether in RUN or CONFIGURED Mode */
359 if ((msp->msp_state == MSP_STATE_IDLE) && (msp->plat_init)) { 365 if (msp->msp_state == MSP_STATE_IDLE) {
360 status = msp->plat_init(); 366 spin_lock_irqsave(&msp_rxtx_lock, flags);
361 if (status) { 367 if (msp->pinctrl_rxtx_ref == 0 &&
362 dev_err(msp->dev, "%s: ERROR: Failed to init MSP (%d)!\n", 368 !(IS_ERR(msp->pinctrl_p) || IS_ERR(msp->pinctrl_def))) {
363 __func__, status); 369 retval = pinctrl_select_state(msp->pinctrl_p,
364 return status; 370 msp->pinctrl_def);
371 if (retval)
372 pr_err("could not set MSP defstate\n");
365 } 373 }
374 if (!retval)
375 msp->pinctrl_rxtx_ref++;
376 spin_unlock_irqrestore(&msp_rxtx_lock, flags);
366 } 377 }
367 378
368 /* Configure msp with protocol dependent settings */ 379 /* Configure msp with protocol dependent settings */
@@ -620,7 +631,8 @@ int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction)
620 631
621int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir) 632int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
622{ 633{
623 int status = 0; 634 int status = 0, retval = 0;
635 unsigned long flags;
624 636
625 dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir); 637 dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir);
626 638
@@ -631,12 +643,19 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
631 writel((readl(msp->registers + MSP_GCR) & 643 writel((readl(msp->registers + MSP_GCR) &
632 (~(FRAME_GEN_ENABLE | SRG_ENABLE))), 644 (~(FRAME_GEN_ENABLE | SRG_ENABLE))),
633 msp->registers + MSP_GCR); 645 msp->registers + MSP_GCR);
634 if (msp->plat_exit) 646
635 status = msp->plat_exit(); 647 spin_lock_irqsave(&msp_rxtx_lock, flags);
636 if (status) 648 WARN_ON(!msp->pinctrl_rxtx_ref);
637 dev_warn(msp->dev, 649 msp->pinctrl_rxtx_ref--;
638 "%s: WARN: ux500_msp_i2s_exit failed (%d)!\n", 650 if (msp->pinctrl_rxtx_ref == 0 &&
639 __func__, status); 651 !(IS_ERR(msp->pinctrl_p) || IS_ERR(msp->pinctrl_sleep))) {
652 retval = pinctrl_select_state(msp->pinctrl_p,
653 msp->pinctrl_sleep);
654 if (retval)
655 pr_err("could not set MSP sleepstate\n");
656 }
657 spin_unlock_irqrestore(&msp_rxtx_lock, flags);
658
640 writel(0, msp->registers + MSP_GCR); 659 writel(0, msp->registers + MSP_GCR);
641 writel(0, msp->registers + MSP_TCF); 660 writel(0, msp->registers + MSP_TCF);
642 writel(0, msp->registers + MSP_RCF); 661 writel(0, msp->registers + MSP_RCF);
@@ -663,21 +682,33 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
663 struct ux500_msp **msp_p, 682 struct ux500_msp **msp_p,
664 struct msp_i2s_platform_data *platform_data) 683 struct msp_i2s_platform_data *platform_data)
665{ 684{
666 int ret = 0;
667 struct resource *res = NULL; 685 struct resource *res = NULL;
668 struct i2s_controller *i2s_cont; 686 struct i2s_controller *i2s_cont;
687 struct device_node *np = pdev->dev.of_node;
669 struct ux500_msp *msp; 688 struct ux500_msp *msp;
670 689
671 dev_dbg(&pdev->dev, "%s: Enter (name: %s, id: %d).\n", __func__,
672 pdev->name, platform_data->id);
673
674 *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL); 690 *msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL);
675 msp = *msp_p; 691 msp = *msp_p;
676 692
693 if (np) {
694 if (!platform_data) {
695 platform_data = devm_kzalloc(&pdev->dev,
696 sizeof(struct msp_i2s_platform_data), GFP_KERNEL);
697 if (!platform_data)
698 ret = -ENOMEM;
699 }
700 } else
701 if (!platform_data)
702 ret = -EINVAL;
703
704 if (ret)
705 goto err_res;
706
707 dev_dbg(&pdev->dev, "%s: Enter (name: %s, id: %d).\n", __func__,
708 pdev->name, platform_data->id);
709
677 msp->id = platform_data->id; 710 msp->id = platform_data->id;
678 msp->dev = &pdev->dev; 711 msp->dev = &pdev->dev;
679 msp->plat_init = platform_data->msp_i2s_init;
680 msp->plat_exit = platform_data->msp_i2s_exit;
681 msp->dma_cfg_rx = platform_data->msp_i2s_dma_rx; 712 msp->dma_cfg_rx = platform_data->msp_i2s_dma_rx;
682 msp->dma_cfg_tx = platform_data->msp_i2s_dma_tx; 713 msp->dma_cfg_tx = platform_data->msp_i2s_dma_tx;
683 714
@@ -685,15 +716,14 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
685 if (res == NULL) { 716 if (res == NULL) {
686 dev_err(&pdev->dev, "%s: ERROR: Unable to get resource!\n", 717 dev_err(&pdev->dev, "%s: ERROR: Unable to get resource!\n",
687 __func__); 718 __func__);
688 ret = -ENOMEM; 719 return -ENOMEM;
689 goto err_res;
690 } 720 }
691 721
692 msp->registers = ioremap(res->start, (res->end - res->start + 1)); 722 msp->registers = devm_ioremap(&pdev->dev, res->start,
723 resource_size(res));
693 if (msp->registers == NULL) { 724 if (msp->registers == NULL) {
694 dev_err(&pdev->dev, "%s: ERROR: ioremap failed!\n", __func__); 725 dev_err(&pdev->dev, "%s: ERROR: ioremap failed!\n", __func__);
695 ret = -ENOMEM; 726 return -ENOMEM;
696 goto err_res;
697 } 727 }
698 728
699 msp->msp_state = MSP_STATE_IDLE; 729 msp->msp_state = MSP_STATE_IDLE;
@@ -705,7 +735,7 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
705 dev_err(&pdev->dev, 735 dev_err(&pdev->dev,
706 "%s: ERROR: Failed to allocate I2S-controller!\n", 736 "%s: ERROR: Failed to allocate I2S-controller!\n",
707 __func__); 737 __func__);
708 goto err_i2s_cont; 738 return -ENOMEM;
709 } 739 }
710 i2s_cont->dev.parent = &pdev->dev; 740 i2s_cont->dev.parent = &pdev->dev;
711 i2s_cont->data = (void *)msp; 741 i2s_cont->data = (void *)msp;
@@ -715,15 +745,26 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
715 dev_dbg(&pdev->dev, "I2S device-name: '%s'\n", i2s_cont->name); 745 dev_dbg(&pdev->dev, "I2S device-name: '%s'\n", i2s_cont->name);
716 msp->i2s_cont = i2s_cont; 746 msp->i2s_cont = i2s_cont;
717 747
718 return 0; 748 msp->pinctrl_p = pinctrl_get(msp->dev);
719 749 if (IS_ERR(msp->pinctrl_p))
720err_i2s_cont: 750 dev_err(&pdev->dev, "could not get MSP pinctrl\n");
721 iounmap(msp->registers); 751 else {
722 752 msp->pinctrl_def = pinctrl_lookup_state(msp->pinctrl_p,
723err_res: 753 PINCTRL_STATE_DEFAULT);
724 devm_kfree(&pdev->dev, msp); 754 if (IS_ERR(msp->pinctrl_def)) {
755 dev_err(&pdev->dev,
756 "could not get MSP defstate (%li)\n",
757 PTR_ERR(msp->pinctrl_def));
758 }
759 msp->pinctrl_sleep = pinctrl_lookup_state(msp->pinctrl_p,
760 PINCTRL_STATE_SLEEP);
761 if (IS_ERR(msp->pinctrl_sleep))
762 dev_err(&pdev->dev,
763 "could not get MSP idlestate (%li)\n",
764 PTR_ERR(msp->pinctrl_def));
765 }
725 766
726 return ret; 767 return 0;
727} 768}
728 769
729void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev, 770void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev,
@@ -732,11 +773,6 @@ void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev,
732 dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id); 773 dev_dbg(msp->dev, "%s: Enter (id = %d).\n", __func__, msp->id);
733 774
734 device_unregister(&msp->i2s_cont->dev); 775 device_unregister(&msp->i2s_cont->dev);
735 devm_kfree(&pdev->dev, msp->i2s_cont);
736
737 iounmap(msp->registers);
738
739 devm_kfree(&pdev->dev, msp);
740} 776}
741 777
742MODULE_LICENSE("GPL v2"); 778MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h
index 2d9136da9865..1311c0df7628 100644
--- a/sound/soc/ux500/ux500_msp_i2s.h
+++ b/sound/soc/ux500/ux500_msp_i2s.h
@@ -524,14 +524,18 @@ struct ux500_msp {
524 struct dma_chan *rx_pipeid; 524 struct dma_chan *rx_pipeid;
525 enum msp_state msp_state; 525 enum msp_state msp_state;
526 int (*transfer) (struct ux500_msp *msp, struct i2s_message *message); 526 int (*transfer) (struct ux500_msp *msp, struct i2s_message *message);
527 int (*plat_init) (void);
528 int (*plat_exit) (void);
529 struct timer_list notify_timer; 527 struct timer_list notify_timer;
530 int def_elem_len; 528 int def_elem_len;
531 unsigned int dir_busy; 529 unsigned int dir_busy;
532 int loopback_enable; 530 int loopback_enable;
533 u32 backup_regs[MAX_MSP_BACKUP_REGS]; 531 u32 backup_regs[MAX_MSP_BACKUP_REGS];
534 unsigned int f_bitclk; 532 unsigned int f_bitclk;
533 /* Pin modes */
534 struct pinctrl *pinctrl_p;
535 struct pinctrl_state *pinctrl_def;
536 struct pinctrl_state *pinctrl_sleep;
537 /* Reference Count */
538 int pinctrl_rxtx_ref;
535}; 539};
536 540
537struct ux500_msp_dma_params { 541struct ux500_msp_dma_params {