aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/ux500-mop500.txt39
-rw-r--r--Documentation/devicetree/bindings/sound/ux500-msp.txt43
-rw-r--r--arch/arm/mach-ux500/board-mop500-msp.c79
-rw-r--r--arch/arm/mach-ux500/include/mach/msp.h2
-rw-r--r--include/linux/mfd/abx500/ab8500-codec.h6
-rw-r--r--sound/soc/codecs/ab8500-codec.c81
-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.c89
-rw-r--r--sound/soc/ux500/ux500_msp_i2s.h8
10 files changed, 292 insertions, 108 deletions
diff --git a/Documentation/devicetree/bindings/sound/ux500-mop500.txt b/Documentation/devicetree/bindings/sound/ux500-mop500.txt
new file mode 100644
index 000000000000..48e071c96b46
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/ux500-mop500.txt
@@ -0,0 +1,39 @@
1* MOP500 Audio Machine Driver
2
3This node is responsible for linking together all ux500 Audio Driver components.
4
5Required properties:
6 - compatible : "stericsson,snd-soc-mop500"
7
8Non-standard properties:
9 - stericsson,cpu-dai : Phandle to the CPU-side DAI
10 - stericsson,audio-codec : Phandle to the Audio CODEC
11 - stericsson,card-name : Over-ride default card name
12
13Example:
14
15 sound {
16 compatible = "stericsson,snd-soc-mop500";
17
18 stericsson,cpu-dai = <&msp1 &msp3>;
19 stericsson,audio-codec = <&codec>;
20 };
21
22 msp1: msp@80124000 {
23 compatible = "stericsson,ux500-msp-i2s";
24 reg = <0x80124000 0x1000>;
25 interrupts = <0 62 0x4>;
26 v-ape-supply = <&db8500_vape_reg>;
27 };
28
29 msp3: msp@80125000 {
30 compatible = "stericsson,ux500-msp-i2s";
31 reg = <0x80125000 0x1000>;
32 interrupts = <0 62 0x4>;
33 v-ape-supply = <&db8500_vape_reg>;
34 };
35
36 codec: ab8500-codec {
37 compatible = "stericsson,ab8500-codec";
38 stericsson,earpeice-cmv = <950>; /* Units in mV. */
39 };
diff --git a/Documentation/devicetree/bindings/sound/ux500-msp.txt b/Documentation/devicetree/bindings/sound/ux500-msp.txt
new file mode 100644
index 000000000000..99acd9c774e1
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/ux500-msp.txt
@@ -0,0 +1,43 @@
1* ux500 MSP (CPU-side Digital Audio Interface)
2
3Required properties:
4 - compatible :"stericsson,ux500-msp-i2s"
5 - reg : Physical base address and length of the device's registers.
6
7Optional properties:
8 - interrupts : The interrupt output from the device.
9 - interrupt-parent : The parent interrupt controller.
10 - <name>-supply : Phandle to the regulator <name> supply
11
12Example:
13
14 sound {
15 compatible = "stericsson,snd-soc-mop500";
16
17 stericsson,platform-pcm-dma = <&pcm>;
18 stericsson,cpu-dai = <&msp1 &msp3>;
19 stericsson,audio-codec = <&codec>;
20 };
21
22 pcm: ux500-pcm {
23 compatible = "stericsson,ux500-pcm";
24 };
25
26 msp1: msp@80124000 {
27 compatible = "stericsson,ux500-msp-i2s";
28 reg = <0x80124000 0x1000>;
29 interrupts = <0 62 0x4>;
30 v-ape-supply = <&db8500_vape_reg>;
31 };
32
33 msp3: msp@80125000 {
34 compatible = "stericsson,ux500-msp-i2s";
35 reg = <0x80125000 0x1000>;
36 interrupts = <0 62 0x4>;
37 v-ape-supply = <&db8500_vape_reg>;
38 };
39
40 codec: ab8500-codec {
41 compatible = "stericsson,ab8500-codec";
42 stericsson,earpeice-cmv = <950>; /* Units in mV. */
43 };
diff --git a/arch/arm/mach-ux500/board-mop500-msp.c b/arch/arm/mach-ux500/board-mop500-msp.c
index df15646036aa..ace6c051bc1a 100644
--- a/arch/arm/mach-ux500/board-mop500-msp.c
+++ b/arch/arm/mach-ux500/board-mop500-msp.c
@@ -7,7 +7,6 @@
7#include <linux/platform_device.h> 7#include <linux/platform_device.h>
8#include <linux/init.h> 8#include <linux/init.h>
9#include <linux/gpio.h> 9#include <linux/gpio.h>
10#include <linux/pinctrl/consumer.h>
11 10
12#include <plat/gpio-nomadik.h> 11#include <plat/gpio-nomadik.h>
13#include <plat/pincfg.h> 12#include <plat/pincfg.h>
@@ -23,53 +22,6 @@
23#include "devices-db8500.h" 22#include "devices-db8500.h"
24#include "pins-db8500.h" 23#include "pins-db8500.h"
25 24
26/* MSP1/3 Tx/Rx usage protection */
27static DEFINE_SPINLOCK(msp_rxtx_lock);
28
29/* Reference Count */
30static int msp_rxtx_ref;
31
32/* Pin modes */
33struct pinctrl *msp1_p;
34struct pinctrl_state *msp1_def;
35struct pinctrl_state *msp1_sleep;
36
37int msp13_i2s_init(void)
38{
39 int retval = 0;
40 unsigned long flags;
41
42 spin_lock_irqsave(&msp_rxtx_lock, flags);
43 if (msp_rxtx_ref == 0 && !(IS_ERR(msp1_p) || IS_ERR(msp1_def))) {
44 retval = pinctrl_select_state(msp1_p, msp1_def);
45 if (retval)
46 pr_err("could not set MSP1 defstate\n");
47 }
48 if (!retval)
49 msp_rxtx_ref++;
50 spin_unlock_irqrestore(&msp_rxtx_lock, flags);
51
52 return retval;
53}
54
55int msp13_i2s_exit(void)
56{
57 int retval = 0;
58 unsigned long flags;
59
60 spin_lock_irqsave(&msp_rxtx_lock, flags);
61 WARN_ON(!msp_rxtx_ref);
62 msp_rxtx_ref--;
63 if (msp_rxtx_ref == 0 && !(IS_ERR(msp1_p) || IS_ERR(msp1_sleep))) {
64 retval = pinctrl_select_state(msp1_p, msp1_sleep);
65 if (retval)
66 pr_err("could not set MSP1 sleepstate\n");
67 }
68 spin_unlock_irqrestore(&msp_rxtx_lock, flags);
69
70 return retval;
71}
72
73static struct stedma40_chan_cfg msp0_dma_rx = { 25static struct stedma40_chan_cfg msp0_dma_rx = {
74 .high_priority = true, 26 .high_priority = true,
75 .dir = STEDMA40_PERIPH_TO_MEM, 27 .dir = STEDMA40_PERIPH_TO_MEM,
@@ -132,8 +84,6 @@ static struct msp_i2s_platform_data msp1_platform_data = {
132 .id = MSP_I2S_1, 84 .id = MSP_I2S_1,
133 .msp_i2s_dma_rx = NULL, 85 .msp_i2s_dma_rx = NULL,
134 .msp_i2s_dma_tx = &msp1_dma_tx, 86 .msp_i2s_dma_tx = &msp1_dma_tx,
135 .msp_i2s_init = msp13_i2s_init,
136 .msp_i2s_exit = msp13_i2s_exit,
137}; 87};
138 88
139static struct stedma40_chan_cfg msp2_dma_rx = { 89static struct stedma40_chan_cfg msp2_dma_rx = {
@@ -219,49 +169,22 @@ static struct msp_i2s_platform_data msp3_platform_data = {
219 .id = MSP_I2S_3, 169 .id = MSP_I2S_3,
220 .msp_i2s_dma_rx = &msp1_dma_rx, 170 .msp_i2s_dma_rx = &msp1_dma_rx,
221 .msp_i2s_dma_tx = NULL, 171 .msp_i2s_dma_tx = NULL,
222 .msp_i2s_init = msp13_i2s_init,
223 .msp_i2s_exit = msp13_i2s_exit,
224}; 172};
225 173
226int mop500_msp_init(struct device *parent) 174int mop500_msp_init(struct device *parent)
227{ 175{
228 struct platform_device *msp1;
229
230 pr_info("%s: Register platform-device 'snd-soc-mop500'.\n", __func__); 176 pr_info("%s: Register platform-device 'snd-soc-mop500'.\n", __func__);
231 platform_device_register(&snd_soc_mop500); 177 platform_device_register(&snd_soc_mop500);
232 178
233 pr_info("Initialize MSP I2S-devices.\n"); 179 pr_info("Initialize MSP I2S-devices.\n");
234 db8500_add_msp_i2s(parent, 0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, 180 db8500_add_msp_i2s(parent, 0, U8500_MSP0_BASE, IRQ_DB8500_MSP0,
235 &msp0_platform_data); 181 &msp0_platform_data);
236 msp1 = db8500_add_msp_i2s(parent, 1, U8500_MSP1_BASE, IRQ_DB8500_MSP1, 182 db8500_add_msp_i2s(parent, 1, U8500_MSP1_BASE, IRQ_DB8500_MSP1,
237 &msp1_platform_data); 183 &msp1_platform_data);
238 db8500_add_msp_i2s(parent, 2, U8500_MSP2_BASE, IRQ_DB8500_MSP2, 184 db8500_add_msp_i2s(parent, 2, U8500_MSP2_BASE, IRQ_DB8500_MSP2,
239 &msp2_platform_data); 185 &msp2_platform_data);
240 db8500_add_msp_i2s(parent, 3, U8500_MSP3_BASE, IRQ_DB8500_MSP1, 186 db8500_add_msp_i2s(parent, 3, U8500_MSP3_BASE, IRQ_DB8500_MSP1,
241 &msp3_platform_data); 187 &msp3_platform_data);
242 188
243 /* Get the pinctrl handle for MSP1 */
244 if (msp1) {
245 msp1_p = pinctrl_get(&msp1->dev);
246 if (IS_ERR(msp1_p))
247 dev_err(&msp1->dev, "could not get MSP1 pinctrl\n");
248 else {
249 msp1_def = pinctrl_lookup_state(msp1_p,
250 PINCTRL_STATE_DEFAULT);
251 if (IS_ERR(msp1_def)) {
252 dev_err(&msp1->dev,
253 "could not get MSP1 defstate\n");
254 }
255 msp1_sleep = pinctrl_lookup_state(msp1_p,
256 PINCTRL_STATE_SLEEP);
257 if (IS_ERR(msp1_sleep))
258 dev_err(&msp1->dev,
259 "could not get MSP1 idlestate\n");
260 }
261 }
262
263 pr_info("%s: Register platform-device 'ux500-pcm'\n", __func__);
264 platform_device_register(&ux500_pcm);
265
266 return 0; 189 return 0;
267} 190}
diff --git a/arch/arm/mach-ux500/include/mach/msp.h b/arch/arm/mach-ux500/include/mach/msp.h
index 798be19129ef..3cc7142eee02 100644
--- a/arch/arm/mach-ux500/include/mach/msp.h
+++ b/arch/arm/mach-ux500/include/mach/msp.h
@@ -22,8 +22,6 @@ struct msp_i2s_platform_data {
22 enum msp_i2s_id id; 22 enum msp_i2s_id id;
23 struct stedma40_chan_cfg *msp_i2s_dma_rx; 23 struct stedma40_chan_cfg *msp_i2s_dma_rx;
24 struct stedma40_chan_cfg *msp_i2s_dma_tx; 24 struct stedma40_chan_cfg *msp_i2s_dma_tx;
25 int (*msp_i2s_init) (void);
26 int (*msp_i2s_exit) (void);
27}; 25};
28 26
29#endif 27#endif
diff --git a/include/linux/mfd/abx500/ab8500-codec.h b/include/linux/mfd/abx500/ab8500-codec.h
index dc6529202cdd..d7079413def0 100644
--- a/include/linux/mfd/abx500/ab8500-codec.h
+++ b/include/linux/mfd/abx500/ab8500-codec.h
@@ -23,7 +23,8 @@ enum amic_type {
23/* Mic-biases */ 23/* Mic-biases */
24enum amic_micbias { 24enum amic_micbias {
25 AMIC_MICBIAS_VAMIC1, 25 AMIC_MICBIAS_VAMIC1,
26 AMIC_MICBIAS_VAMIC2 26 AMIC_MICBIAS_VAMIC2,
27 AMIC_MICBIAS_UNKNOWN
27}; 28};
28 29
29/* Bias-voltage */ 30/* Bias-voltage */
@@ -31,7 +32,8 @@ enum ear_cm_voltage {
31 EAR_CMV_0_95V, 32 EAR_CMV_0_95V,
32 EAR_CMV_1_10V, 33 EAR_CMV_1_10V,
33 EAR_CMV_1_27V, 34 EAR_CMV_1_27V,
34 EAR_CMV_1_58V 35 EAR_CMV_1_58V,
36 EAR_CMV_UNKNOWN
35}; 37};
36 38
37/* Analog microphone settings */ 39/* Analog microphone settings */
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index 2c1c2524ef8c..af547490b4f7 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;
@@ -2407,6 +2464,30 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec)
2407 /* Setup AB8500 according to board-settings */ 2464 /* Setup AB8500 according to board-settings */
2408 pdata = dev_get_platdata(dev->parent); 2465 pdata = dev_get_platdata(dev->parent);
2409 2466
2467 if (np) {
2468 if (!pdata)
2469 pdata = devm_kzalloc(dev,
2470 sizeof(struct ab8500_platform_data),
2471 GFP_KERNEL);
2472
2473 if (pdata && !pdata->codec)
2474 pdata->codec
2475 = devm_kzalloc(dev,
2476 sizeof(struct ab8500_codec_platform_data),
2477 GFP_KERNEL);
2478
2479 if (!(pdata && pdata->codec))
2480 return -ENOMEM;
2481
2482 ab8500_codec_of_probe(dev, np, pdata->codec);
2483
2484 } else {
2485 if (!(pdata && pdata->codec)) {
2486 dev_err(dev, "No codec platform data or DT found\n");
2487 return -EINVAL;
2488 }
2489 }
2490
2410 status = ab8500_audio_setup_mics(codec, &pdata->codec->amics); 2491 status = ab8500_audio_setup_mics(codec, &pdata->codec->amics);
2411 if (status < 0) { 2492 if (status < 0) {
2412 pr_err("%s: Failed to setup mics (%d)!\n", __func__, status); 2493 pr_err("%s: Failed to setup mics (%d)!\n", __func__, status);
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 772cb19d2fb3..be94bf9bf94f 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -833,10 +833,16 @@ static int __devexit ux500_msp_drv_remove(struct platform_device *pdev)
833 return 0; 833 return 0;
834} 834}
835 835
836static const struct of_device_id ux500_msp_i2s_match[] = {
837 { .compatible = "stericsson,ux500-msp-i2s", },
838 {},
839};
840
836static struct platform_driver msp_i2s_driver = { 841static struct platform_driver msp_i2s_driver = {
837 .driver = { 842 .driver = {
838 .name = "ux500-msp-i2s", 843 .name = "ux500-msp-i2s",
839 .owner = THIS_MODULE, 844 .owner = THIS_MODULE,
845 .of_match_table = ux500_msp_i2s_match,
840 }, 846 },
841 .probe = ux500_msp_drv_probe, 847 .probe = ux500_msp_drv_probe,
842 .remove = ux500_msp_drv_remove, 848 .remove = ux500_msp_drv_remove,
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index 1b7c2f58ce13..b7c996e77570 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);
@@ -665,20 +684,33 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
665{ 684{
666 struct resource *res = NULL; 685 struct resource *res = NULL;
667 struct i2s_controller *i2s_cont; 686 struct i2s_controller *i2s_cont;
687 struct device_node *np = pdev->dev.of_node;
668 struct ux500_msp *msp; 688 struct ux500_msp *msp;
669 689
670 dev_dbg(&pdev->dev, "%s: Enter (name: %s, id: %d).\n", __func__,
671 pdev->name, platform_data->id);
672
673 *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);
674 msp = *msp_p; 691 msp = *msp_p;
675 if (!msp) 692 if (!msp)
676 return -ENOMEM; 693 return -ENOMEM;
677 694
695 if (np) {
696 if (!platform_data) {
697 platform_data = devm_kzalloc(&pdev->dev,
698 sizeof(struct msp_i2s_platform_data), GFP_KERNEL);
699 if (!platform_data)
700 ret = -ENOMEM;
701 }
702 } else
703 if (!platform_data)
704 ret = -EINVAL;
705
706 if (ret)
707 goto err_res;
708
709 dev_dbg(&pdev->dev, "%s: Enter (name: %s, id: %d).\n", __func__,
710 pdev->name, platform_data->id);
711
678 msp->id = platform_data->id; 712 msp->id = platform_data->id;
679 msp->dev = &pdev->dev; 713 msp->dev = &pdev->dev;
680 msp->plat_init = platform_data->msp_i2s_init;
681 msp->plat_exit = platform_data->msp_i2s_exit;
682 msp->dma_cfg_rx = platform_data->msp_i2s_dma_rx; 714 msp->dma_cfg_rx = platform_data->msp_i2s_dma_rx;
683 msp->dma_cfg_tx = platform_data->msp_i2s_dma_tx; 715 msp->dma_cfg_tx = platform_data->msp_i2s_dma_tx;
684 716
@@ -715,6 +747,25 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
715 dev_dbg(&pdev->dev, "I2S device-name: '%s'\n", i2s_cont->name); 747 dev_dbg(&pdev->dev, "I2S device-name: '%s'\n", i2s_cont->name);
716 msp->i2s_cont = i2s_cont; 748 msp->i2s_cont = i2s_cont;
717 749
750 msp->pinctrl_p = pinctrl_get(msp->dev);
751 if (IS_ERR(msp->pinctrl_p))
752 dev_err(&pdev->dev, "could not get MSP pinctrl\n");
753 else {
754 msp->pinctrl_def = pinctrl_lookup_state(msp->pinctrl_p,
755 PINCTRL_STATE_DEFAULT);
756 if (IS_ERR(msp->pinctrl_def)) {
757 dev_err(&pdev->dev,
758 "could not get MSP defstate (%li)\n",
759 PTR_ERR(msp->pinctrl_def));
760 }
761 msp->pinctrl_sleep = pinctrl_lookup_state(msp->pinctrl_p,
762 PINCTRL_STATE_SLEEP);
763 if (IS_ERR(msp->pinctrl_sleep))
764 dev_err(&pdev->dev,
765 "could not get MSP idlestate (%li)\n",
766 PTR_ERR(msp->pinctrl_def));
767 }
768
718 return 0; 769 return 0;
719} 770}
720 771
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 {