aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-10-24 06:24:04 -0400
committerMark Brown <broonie@linaro.org>2013-10-24 06:24:04 -0400
commitcf44fba0899152daf481dfc7fde53e53f0d50141 (patch)
tree964346fcab3e808fff58a65ae977cb5836c563a5
parent07056901106b71c69623a224bbb16e83585e5530 (diff)
parentee2f615d6e59cea2b9a415661a7f27caffcb3528 (diff)
Merge remote-tracking branch 'asoc/topic/davinci' into asoc-next
-rw-r--r--Documentation/devicetree/bindings/sound/davinci-evm-audio.txt42
-rw-r--r--Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt41
-rw-r--r--include/linux/platform_data/davinci_asp.h2
-rw-r--r--sound/soc/davinci/Kconfig18
-rw-r--r--sound/soc/davinci/Makefile1
-rw-r--r--sound/soc/davinci/davinci-evm.c188
-rw-r--r--sound/soc/davinci/davinci-mcasp.c169
-rw-r--r--sound/soc/davinci/davinci-mcasp.h12
8 files changed, 382 insertions, 91 deletions
diff --git a/Documentation/devicetree/bindings/sound/davinci-evm-audio.txt b/Documentation/devicetree/bindings/sound/davinci-evm-audio.txt
new file mode 100644
index 000000000000..865178d5cdf3
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/davinci-evm-audio.txt
@@ -0,0 +1,42 @@
1* Texas Instruments SoC audio setups with TLV320AIC3X Codec
2
3Required properties:
4- compatible : "ti,da830-evm-audio" : forDM365/DA8xx/OMAPL1x/AM33xx
5- ti,model : The user-visible name of this sound complex.
6- ti,audio-codec : The phandle of the TLV320AIC3x audio codec
7- ti,mcasp-controller : The phandle of the McASP controller
8- ti,codec-clock-rate : The Codec Clock rate (in Hz) applied to the Codec
9- ti,audio-routing : A list of the connections between audio components.
10 Each entry is a pair of strings, the first being the connection's sink,
11 the second being the connection's source. Valid names for sources and
12 sinks are the codec's pins, and the jacks on the board:
13
14 Board connectors:
15
16 * Headphone Jack
17 * Line Out
18 * Mic Jack
19 * Line In
20
21
22Example:
23
24sound {
25 compatible = "ti,da830-evm-audio";
26 ti,model = "DA830 EVM";
27 ti,audio-codec = <&tlv320aic3x>;
28 ti,mcasp-controller = <&mcasp1>;
29 ti,codec-clock-rate = <12000000>;
30 ti,audio-routing =
31 "Headphone Jack", "HPLOUT",
32 "Headphone Jack", "HPROUT",
33 "Line Out", "LLOUT",
34 "Line Out", "RLOUT",
35 "MIC3L", "Mic Bias 2V",
36 "MIC3R", "Mic Bias 2V",
37 "Mic Bias 2V", "Mic Jack",
38 "LINE1L", "Line In",
39 "LINE2L", "Line In",
40 "LINE1R", "Line In",
41 "LINE2R", "Line In";
42};
diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt
index 374e145c2ef1..ed785b3f67be 100644
--- a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt
+++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt
@@ -4,17 +4,25 @@ Required properties:
4- compatible : 4- compatible :
5 "ti,dm646x-mcasp-audio" : for DM646x platforms 5 "ti,dm646x-mcasp-audio" : for DM646x platforms
6 "ti,da830-mcasp-audio" : for both DA830 & DA850 platforms 6 "ti,da830-mcasp-audio" : for both DA830 & DA850 platforms
7 "ti,omap2-mcasp-audio" : for OMAP2 platforms (TI81xx, AM33xx) 7 "ti,am33xx-mcasp-audio" : for AM33xx platforms (AM33xx, TI81xx)
8
9- reg : Should contain McASP registers offset and length
10- interrupts : Interrupt number for McASP
11- op-mode : I2S/DIT ops mode.
12- tdm-slots : Slots for TDM operation.
13- num-serializer : Serializers used by McASP.
14- serial-dir : A list of serializer pin mode. The list number should be equal
15 to "num-serializer" parameter. Each entry is a number indication
16 serializer pin direction. (0 - INACTIVE, 1 - TX, 2 - RX)
17 8
9- reg : Should contain reg specifiers for the entries in the reg-names property.
10- reg-names : Should contain:
11 * "mpu" for the main registers (required). For compatibility with
12 existing software, it is recommended this is the first entry.
13 * "dat" for separate data port register access (optional).
14- op-mode : I2S/DIT ops mode. 0 for I2S mode. 1 for DIT mode used for S/PDIF,
15 IEC60958-1, and AES-3 formats.
16- tdm-slots : Slots for TDM operation. Indicates number of channels transmitted
17 or received over one serializer.
18- serial-dir : A list of serializer configuration. Each entry is a number
19 indication for serializer pin direction.
20 (0 - INACTIVE, 1 - TX, 2 - RX)
21- dmas: two element list of DMA controller phandles and DMA request line
22 ordered pairs.
23- dma-names: identifier string for each DMA request line in the dmas property.
24 These strings correspond 1:1 with the ordered pairs in dmas. The dma
25 identifiers must be "rx" and "tx".
18 26
19Optional properties: 27Optional properties:
20 28
@@ -23,18 +31,23 @@ Optional properties:
23- rx-num-evt : FIFO levels. 31- rx-num-evt : FIFO levels.
24- sram-size-playback : size of sram to be allocated during playback 32- sram-size-playback : size of sram to be allocated during playback
25- sram-size-capture : size of sram to be allocated during capture 33- sram-size-capture : size of sram to be allocated during capture
34- interrupts : Interrupt numbers for McASP, currently not used by the driver
35- interrupt-names : Known interrupt names are "tx" and "rx"
36- pinctrl-0: Should specify pin control group used for this controller.
37- pinctrl-names: Should contain only one value - "default", for more details
38 please refer to pinctrl-bindings.txt
39
26 40
27Example: 41Example:
28 42
29mcasp0: mcasp0@1d00000 { 43mcasp0: mcasp0@1d00000 {
30 compatible = "ti,da830-mcasp-audio"; 44 compatible = "ti,da830-mcasp-audio";
31 #address-cells = <1>;
32 #size-cells = <0>;
33 reg = <0x100000 0x3000>; 45 reg = <0x100000 0x3000>;
34 interrupts = <82 83>; 46 reg-names "mpu";
47 interrupts = <82>, <83>;
48 interrupts-names = "tx", "rx";
35 op-mode = <0>; /* MCASP_IIS_MODE */ 49 op-mode = <0>; /* MCASP_IIS_MODE */
36 tdm-slots = <2>; 50 tdm-slots = <2>;
37 num-serializer = <16>;
38 serial-dir = < 51 serial-dir = <
39 0 0 0 0 /* 0: INACTIVE, 1: TX, 2: RX */ 52 0 0 0 0 /* 0: INACTIVE, 1: TX, 2: RX */
40 0 0 0 0 53 0 0 0 0
diff --git a/include/linux/platform_data/davinci_asp.h b/include/linux/platform_data/davinci_asp.h
index 8db5ae03b6e3..689a856b86f9 100644
--- a/include/linux/platform_data/davinci_asp.h
+++ b/include/linux/platform_data/davinci_asp.h
@@ -84,6 +84,8 @@ struct snd_platform_data {
84 u8 version; 84 u8 version;
85 u8 txnumevt; 85 u8 txnumevt;
86 u8 rxnumevt; 86 u8 rxnumevt;
87 int tx_dma_channel;
88 int rx_dma_channel;
87}; 89};
88 90
89enum { 91enum {
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig
index c82f89c9475b..95970f5db3ec 100644
--- a/sound/soc/davinci/Kconfig
+++ b/sound/soc/davinci/Kconfig
@@ -1,9 +1,10 @@
1config SND_DAVINCI_SOC 1config SND_DAVINCI_SOC
2 tristate "SoC Audio for the TI DAVINCI chip" 2 tristate "SoC Audio for the TI DAVINCI or AM33XX chip"
3 depends on ARCH_DAVINCI 3 depends on ARCH_DAVINCI || SOC_AM33XX
4 help 4 help
5 Platform driver for daVinci or AM33xx
5 Say Y or M if you want to add support for codecs attached to 6 Say Y or M if you want to add support for codecs attached to
6 the DAVINCI AC97 or I2S interface. You will also need 7 the DAVINCI AC97, I2S, or McASP interface. You will also need
7 to select the audio interfaces to support below. 8 to select the audio interfaces to support below.
8 9
9config SND_DAVINCI_SOC_I2S 10config SND_DAVINCI_SOC_I2S
@@ -15,6 +16,17 @@ config SND_DAVINCI_SOC_MCASP
15config SND_DAVINCI_SOC_VCIF 16config SND_DAVINCI_SOC_VCIF
16 tristate 17 tristate
17 18
19config SND_AM33XX_SOC_EVM
20 tristate "SoC Audio for the AM33XX chip based boards"
21 depends on SND_DAVINCI_SOC && SOC_AM33XX
22 select SND_SOC_TLV320AIC3X
23 select SND_DAVINCI_SOC_MCASP
24 help
25 Say Y or M if you want to add support for SoC audio on AM33XX
26 boards using McASP and TLV320AIC3X codec. For example AM335X-EVM,
27 AM335X-EVMSK, and BeagelBone with AudioCape boards have this
28 setup.
29
18config SND_DAVINCI_SOC_EVM 30config SND_DAVINCI_SOC_EVM
19 tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM" 31 tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM"
20 depends on SND_DAVINCI_SOC 32 depends on SND_DAVINCI_SOC
diff --git a/sound/soc/davinci/Makefile b/sound/soc/davinci/Makefile
index a396ab6d6d5e..bc81e79fc301 100644
--- a/sound/soc/davinci/Makefile
+++ b/sound/soc/davinci/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_SND_DAVINCI_SOC_VCIF) += snd-soc-davinci-vcif.o
13snd-soc-evm-objs := davinci-evm.o 13snd-soc-evm-objs := davinci-evm.o
14 14
15obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o 15obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o
16obj-$(CONFIG_SND_AM33XX_SOC_EVM) += snd-soc-evm.o
16obj-$(CONFIG_SND_DM6467_SOC_EVM) += snd-soc-evm.o 17obj-$(CONFIG_SND_DM6467_SOC_EVM) += snd-soc-evm.o
17obj-$(CONFIG_SND_DA830_SOC_EVM) += snd-soc-evm.o 18obj-$(CONFIG_SND_DA830_SOC_EVM) += snd-soc-evm.o
18obj-$(CONFIG_SND_DA850_SOC_EVM) += snd-soc-evm.o 19obj-$(CONFIG_SND_DA850_SOC_EVM) += snd-soc-evm.o
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index fd7c45b9ed5a..623eb5e7c089 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -16,6 +16,7 @@
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/platform_data/edma.h> 17#include <linux/platform_data/edma.h>
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/of_platform.h>
19#include <sound/core.h> 20#include <sound/core.h>
20#include <sound/pcm.h> 21#include <sound/pcm.h>
21#include <sound/soc.h> 22#include <sound/soc.h>
@@ -23,10 +24,16 @@
23#include <asm/dma.h> 24#include <asm/dma.h>
24#include <asm/mach-types.h> 25#include <asm/mach-types.h>
25 26
27#include <linux/edma.h>
28
26#include "davinci-pcm.h" 29#include "davinci-pcm.h"
27#include "davinci-i2s.h" 30#include "davinci-i2s.h"
28#include "davinci-mcasp.h" 31#include "davinci-mcasp.h"
29 32
33struct snd_soc_card_drvdata_davinci {
34 unsigned sysclk;
35};
36
30#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \ 37#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
31 SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF) 38 SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF)
32static int evm_hw_params(struct snd_pcm_substream *substream, 39static int evm_hw_params(struct snd_pcm_substream *substream,
@@ -35,27 +42,11 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
35 struct snd_soc_pcm_runtime *rtd = substream->private_data; 42 struct snd_soc_pcm_runtime *rtd = substream->private_data;
36 struct snd_soc_dai *codec_dai = rtd->codec_dai; 43 struct snd_soc_dai *codec_dai = rtd->codec_dai;
37 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 44 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
45 struct snd_soc_codec *codec = rtd->codec;
46 struct snd_soc_card *soc_card = codec->card;
38 int ret = 0; 47 int ret = 0;
39 unsigned sysclk; 48 unsigned sysclk = ((struct snd_soc_card_drvdata_davinci *)
40 49 snd_soc_card_get_drvdata(soc_card))->sysclk;
41 /* ASP1 on DM355 EVM is clocked by an external oscillator */
42 if (machine_is_davinci_dm355_evm() || machine_is_davinci_dm6467_evm() ||
43 machine_is_davinci_dm365_evm())
44 sysclk = 27000000;
45
46 /* ASP0 in DM6446 EVM is clocked by U55, as configured by
47 * board-dm644x-evm.c using GPIOs from U18. There are six
48 * options; here we "know" we use a 48 KHz sample rate.
49 */
50 else if (machine_is_davinci_evm())
51 sysclk = 12288000;
52
53 else if (machine_is_davinci_da830_evm() ||
54 machine_is_davinci_da850_evm())
55 sysclk = 24576000;
56
57 else
58 return -EINVAL;
59 50
60 /* set codec DAI configuration */ 51 /* set codec DAI configuration */
61 ret = snd_soc_dai_set_fmt(codec_dai, AUDIO_FORMAT); 52 ret = snd_soc_dai_set_fmt(codec_dai, AUDIO_FORMAT);
@@ -133,13 +124,22 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
133{ 124{
134 struct snd_soc_codec *codec = rtd->codec; 125 struct snd_soc_codec *codec = rtd->codec;
135 struct snd_soc_dapm_context *dapm = &codec->dapm; 126 struct snd_soc_dapm_context *dapm = &codec->dapm;
127 struct device_node *np = codec->card->dev->of_node;
128 int ret;
136 129
137 /* Add davinci-evm specific widgets */ 130 /* Add davinci-evm specific widgets */
138 snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets, 131 snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
139 ARRAY_SIZE(aic3x_dapm_widgets)); 132 ARRAY_SIZE(aic3x_dapm_widgets));
140 133
141 /* Set up davinci-evm specific audio path audio_map */ 134 if (np) {
142 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); 135 ret = snd_soc_of_parse_audio_routing(codec->card,
136 "ti,audio-routing");
137 if (ret)
138 return ret;
139 } else {
140 /* Set up davinci-evm specific audio path audio_map */
141 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
142 }
143 143
144 /* not connected */ 144 /* not connected */
145 snd_soc_dapm_disable_pin(dapm, "MONO_LOUT"); 145 snd_soc_dapm_disable_pin(dapm, "MONO_LOUT");
@@ -243,35 +243,65 @@ static struct snd_soc_dai_link da850_evm_dai = {
243}; 243};
244 244
245/* davinci dm6446 evm audio machine driver */ 245/* davinci dm6446 evm audio machine driver */
246/*
247 * ASP0 in DM6446 EVM is clocked by U55, as configured by
248 * board-dm644x-evm.c using GPIOs from U18. There are six
249 * options; here we "know" we use a 48 KHz sample rate.
250 */
251static struct snd_soc_card_drvdata_davinci dm6446_snd_soc_card_drvdata = {
252 .sysclk = 12288000,
253};
254
246static struct snd_soc_card dm6446_snd_soc_card_evm = { 255static struct snd_soc_card dm6446_snd_soc_card_evm = {
247 .name = "DaVinci DM6446 EVM", 256 .name = "DaVinci DM6446 EVM",
248 .owner = THIS_MODULE, 257 .owner = THIS_MODULE,
249 .dai_link = &dm6446_evm_dai, 258 .dai_link = &dm6446_evm_dai,
250 .num_links = 1, 259 .num_links = 1,
260 .drvdata = &dm6446_snd_soc_card_drvdata,
251}; 261};
252 262
253/* davinci dm355 evm audio machine driver */ 263/* davinci dm355 evm audio machine driver */
264/* ASP1 on DM355 EVM is clocked by an external oscillator */
265static struct snd_soc_card_drvdata_davinci dm355_snd_soc_card_drvdata = {
266 .sysclk = 27000000,
267};
268
254static struct snd_soc_card dm355_snd_soc_card_evm = { 269static struct snd_soc_card dm355_snd_soc_card_evm = {
255 .name = "DaVinci DM355 EVM", 270 .name = "DaVinci DM355 EVM",
256 .owner = THIS_MODULE, 271 .owner = THIS_MODULE,
257 .dai_link = &dm355_evm_dai, 272 .dai_link = &dm355_evm_dai,
258 .num_links = 1, 273 .num_links = 1,
274 .drvdata = &dm355_snd_soc_card_drvdata,
259}; 275};
260 276
261/* davinci dm365 evm audio machine driver */ 277/* davinci dm365 evm audio machine driver */
278static struct snd_soc_card_drvdata_davinci dm365_snd_soc_card_drvdata = {
279 .sysclk = 27000000,
280};
281
262static struct snd_soc_card dm365_snd_soc_card_evm = { 282static struct snd_soc_card dm365_snd_soc_card_evm = {
263 .name = "DaVinci DM365 EVM", 283 .name = "DaVinci DM365 EVM",
264 .owner = THIS_MODULE, 284 .owner = THIS_MODULE,
265 .dai_link = &dm365_evm_dai, 285 .dai_link = &dm365_evm_dai,
266 .num_links = 1, 286 .num_links = 1,
287 .drvdata = &dm365_snd_soc_card_drvdata,
267}; 288};
268 289
269/* davinci dm6467 evm audio machine driver */ 290/* davinci dm6467 evm audio machine driver */
291static struct snd_soc_card_drvdata_davinci dm6467_snd_soc_card_drvdata = {
292 .sysclk = 27000000,
293};
294
270static struct snd_soc_card dm6467_snd_soc_card_evm = { 295static struct snd_soc_card dm6467_snd_soc_card_evm = {
271 .name = "DaVinci DM6467 EVM", 296 .name = "DaVinci DM6467 EVM",
272 .owner = THIS_MODULE, 297 .owner = THIS_MODULE,
273 .dai_link = dm6467_evm_dai, 298 .dai_link = dm6467_evm_dai,
274 .num_links = ARRAY_SIZE(dm6467_evm_dai), 299 .num_links = ARRAY_SIZE(dm6467_evm_dai),
300 .drvdata = &dm6467_snd_soc_card_drvdata,
301};
302
303static struct snd_soc_card_drvdata_davinci da830_snd_soc_card_drvdata = {
304 .sysclk = 24576000,
275}; 305};
276 306
277static struct snd_soc_card da830_snd_soc_card = { 307static struct snd_soc_card da830_snd_soc_card = {
@@ -279,6 +309,11 @@ static struct snd_soc_card da830_snd_soc_card = {
279 .owner = THIS_MODULE, 309 .owner = THIS_MODULE,
280 .dai_link = &da830_evm_dai, 310 .dai_link = &da830_evm_dai,
281 .num_links = 1, 311 .num_links = 1,
312 .drvdata = &da830_snd_soc_card_drvdata,
313};
314
315static struct snd_soc_card_drvdata_davinci da850_snd_soc_card_drvdata = {
316 .sysclk = 24576000,
282}; 317};
283 318
284static struct snd_soc_card da850_snd_soc_card = { 319static struct snd_soc_card da850_snd_soc_card = {
@@ -286,8 +321,101 @@ static struct snd_soc_card da850_snd_soc_card = {
286 .owner = THIS_MODULE, 321 .owner = THIS_MODULE,
287 .dai_link = &da850_evm_dai, 322 .dai_link = &da850_evm_dai,
288 .num_links = 1, 323 .num_links = 1,
324 .drvdata = &da850_snd_soc_card_drvdata,
325};
326
327#if defined(CONFIG_OF)
328
329/*
330 * The struct is used as place holder. It will be completely
331 * filled with data from dt node.
332 */
333static struct snd_soc_dai_link evm_dai_tlv320aic3x = {
334 .name = "TLV320AIC3X",
335 .stream_name = "AIC3X",
336 .codec_dai_name = "tlv320aic3x-hifi",
337 .ops = &evm_ops,
338 .init = evm_aic3x_init,
339};
340
341static const struct of_device_id davinci_evm_dt_ids[] = {
342 {
343 .compatible = "ti,da830-evm-audio",
344 .data = (void *) &evm_dai_tlv320aic3x,
345 },
346 { /* sentinel */ }
347};
348MODULE_DEVICE_TABLE(of, davinci_evm_dt_ids);
349
350/* davinci evm audio machine driver */
351static struct snd_soc_card evm_soc_card = {
352 .owner = THIS_MODULE,
353 .num_links = 1,
289}; 354};
290 355
356static int davinci_evm_probe(struct platform_device *pdev)
357{
358 struct device_node *np = pdev->dev.of_node;
359 const struct of_device_id *match =
360 of_match_device(of_match_ptr(davinci_evm_dt_ids), &pdev->dev);
361 struct snd_soc_dai_link *dai = (struct snd_soc_dai_link *) match->data;
362 struct snd_soc_card_drvdata_davinci *drvdata = NULL;
363 int ret = 0;
364
365 evm_soc_card.dai_link = dai;
366
367 dai->codec_of_node = of_parse_phandle(np, "ti,audio-codec", 0);
368 if (!dai->codec_of_node)
369 return -EINVAL;
370
371 dai->cpu_of_node = of_parse_phandle(np, "ti,mcasp-controller", 0);
372 if (!dai->cpu_of_node)
373 return -EINVAL;
374
375 dai->platform_of_node = dai->cpu_of_node;
376
377 evm_soc_card.dev = &pdev->dev;
378 ret = snd_soc_of_parse_card_name(&evm_soc_card, "ti,model");
379 if (ret)
380 return ret;
381
382 drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
383 if (!drvdata)
384 return -ENOMEM;
385
386 ret = of_property_read_u32(np, "ti,codec-clock-rate", &drvdata->sysclk);
387 if (ret < 0)
388 return -EINVAL;
389
390 snd_soc_card_set_drvdata(&evm_soc_card, drvdata);
391 ret = devm_snd_soc_register_card(&pdev->dev, &evm_soc_card);
392
393 if (ret)
394 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
395
396 return ret;
397}
398
399static int davinci_evm_remove(struct platform_device *pdev)
400{
401 struct snd_soc_card *card = platform_get_drvdata(pdev);
402
403 snd_soc_unregister_card(card);
404
405 return 0;
406}
407
408static struct platform_driver davinci_evm_driver = {
409 .probe = davinci_evm_probe,
410 .remove = davinci_evm_remove,
411 .driver = {
412 .name = "davinci_evm",
413 .owner = THIS_MODULE,
414 .of_match_table = of_match_ptr(davinci_evm_dt_ids),
415 },
416};
417#endif
418
291static struct platform_device *evm_snd_device; 419static struct platform_device *evm_snd_device;
292 420
293static int __init evm_init(void) 421static int __init evm_init(void)
@@ -296,6 +424,15 @@ static int __init evm_init(void)
296 int index; 424 int index;
297 int ret; 425 int ret;
298 426
427 /*
428 * If dtb is there, the devices will be created dynamically.
429 * Only register platfrom driver structure.
430 */
431#if defined(CONFIG_OF)
432 if (of_have_populated_dt())
433 return platform_driver_register(&davinci_evm_driver);
434#endif
435
299 if (machine_is_davinci_evm()) { 436 if (machine_is_davinci_evm()) {
300 evm_snd_dev_data = &dm6446_snd_soc_card_evm; 437 evm_snd_dev_data = &dm6446_snd_soc_card_evm;
301 index = 0; 438 index = 0;
@@ -331,6 +468,13 @@ static int __init evm_init(void)
331 468
332static void __exit evm_exit(void) 469static void __exit evm_exit(void)
333{ 470{
471#if defined(CONFIG_OF)
472 if (of_have_populated_dt()) {
473 platform_driver_unregister(&davinci_evm_driver);
474 return;
475 }
476#endif
477
334 platform_device_unregister(evm_snd_device); 478 platform_device_unregister(evm_snd_device);
335} 479}
336 480
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 32ddb7fe5034..71e14bb3a8cd 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -1001,18 +1001,40 @@ static const struct snd_soc_component_driver davinci_mcasp_component = {
1001 .name = "davinci-mcasp", 1001 .name = "davinci-mcasp",
1002}; 1002};
1003 1003
1004/* Some HW specific values and defaults. The rest is filled in from DT. */
1005static struct snd_platform_data dm646x_mcasp_pdata = {
1006 .tx_dma_offset = 0x400,
1007 .rx_dma_offset = 0x400,
1008 .asp_chan_q = EVENTQ_0,
1009 .version = MCASP_VERSION_1,
1010};
1011
1012static struct snd_platform_data da830_mcasp_pdata = {
1013 .tx_dma_offset = 0x2000,
1014 .rx_dma_offset = 0x2000,
1015 .asp_chan_q = EVENTQ_0,
1016 .version = MCASP_VERSION_2,
1017};
1018
1019static struct snd_platform_data omap2_mcasp_pdata = {
1020 .tx_dma_offset = 0,
1021 .rx_dma_offset = 0,
1022 .asp_chan_q = EVENTQ_0,
1023 .version = MCASP_VERSION_3,
1024};
1025
1004static const struct of_device_id mcasp_dt_ids[] = { 1026static const struct of_device_id mcasp_dt_ids[] = {
1005 { 1027 {
1006 .compatible = "ti,dm646x-mcasp-audio", 1028 .compatible = "ti,dm646x-mcasp-audio",
1007 .data = (void *)MCASP_VERSION_1, 1029 .data = &dm646x_mcasp_pdata,
1008 }, 1030 },
1009 { 1031 {
1010 .compatible = "ti,da830-mcasp-audio", 1032 .compatible = "ti,da830-mcasp-audio",
1011 .data = (void *)MCASP_VERSION_2, 1033 .data = &da830_mcasp_pdata,
1012 }, 1034 },
1013 { 1035 {
1014 .compatible = "ti,omap2-mcasp-audio", 1036 .compatible = "ti,am33xx-mcasp-audio",
1015 .data = (void *)MCASP_VERSION_3, 1037 .data = &omap2_mcasp_pdata,
1016 }, 1038 },
1017 { /* sentinel */ } 1039 { /* sentinel */ }
1018}; 1040};
@@ -1025,9 +1047,9 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
1025 struct snd_platform_data *pdata = NULL; 1047 struct snd_platform_data *pdata = NULL;
1026 const struct of_device_id *match = 1048 const struct of_device_id *match =
1027 of_match_device(mcasp_dt_ids, &pdev->dev); 1049 of_match_device(mcasp_dt_ids, &pdev->dev);
1050 struct of_phandle_args dma_spec;
1028 1051
1029 const u32 *of_serial_dir32; 1052 const u32 *of_serial_dir32;
1030 u8 *of_serial_dir;
1031 u32 val; 1053 u32 val;
1032 int i, ret = 0; 1054 int i, ret = 0;
1033 1055
@@ -1035,20 +1057,13 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
1035 pdata = pdev->dev.platform_data; 1057 pdata = pdev->dev.platform_data;
1036 return pdata; 1058 return pdata;
1037 } else if (match) { 1059 } else if (match) {
1038 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 1060 pdata = (struct snd_platform_data *) match->data;
1039 if (!pdata) {
1040 ret = -ENOMEM;
1041 goto nodata;
1042 }
1043 } else { 1061 } else {
1044 /* control shouldn't reach here. something is wrong */ 1062 /* control shouldn't reach here. something is wrong */
1045 ret = -EINVAL; 1063 ret = -EINVAL;
1046 goto nodata; 1064 goto nodata;
1047 } 1065 }
1048 1066
1049 if (match->data)
1050 pdata->version = (u8)((int)match->data);
1051
1052 ret = of_property_read_u32(np, "op-mode", &val); 1067 ret = of_property_read_u32(np, "op-mode", &val);
1053 if (ret >= 0) 1068 if (ret >= 0)
1054 pdata->op_mode = val; 1069 pdata->op_mode = val;
@@ -1065,35 +1080,46 @@ static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
1065 pdata->tdm_slots = val; 1080 pdata->tdm_slots = val;
1066 } 1081 }
1067 1082
1068 ret = of_property_read_u32(np, "num-serializer", &val);
1069 if (ret >= 0)
1070 pdata->num_serializer = val;
1071
1072 of_serial_dir32 = of_get_property(np, "serial-dir", &val); 1083 of_serial_dir32 = of_get_property(np, "serial-dir", &val);
1073 val /= sizeof(u32); 1084 val /= sizeof(u32);
1074 if (val != pdata->num_serializer) {
1075 dev_err(&pdev->dev,
1076 "num-serializer(%d) != serial-dir size(%d)\n",
1077 pdata->num_serializer, val);
1078 ret = -EINVAL;
1079 goto nodata;
1080 }
1081
1082 if (of_serial_dir32) { 1085 if (of_serial_dir32) {
1083 of_serial_dir = devm_kzalloc(&pdev->dev, 1086 u8 *of_serial_dir = devm_kzalloc(&pdev->dev,
1084 (sizeof(*of_serial_dir) * val), 1087 (sizeof(*of_serial_dir) * val),
1085 GFP_KERNEL); 1088 GFP_KERNEL);
1086 if (!of_serial_dir) { 1089 if (!of_serial_dir) {
1087 ret = -ENOMEM; 1090 ret = -ENOMEM;
1088 goto nodata; 1091 goto nodata;
1089 } 1092 }
1090 1093
1091 for (i = 0; i < pdata->num_serializer; i++) 1094 for (i = 0; i < val; i++)
1092 of_serial_dir[i] = be32_to_cpup(&of_serial_dir32[i]); 1095 of_serial_dir[i] = be32_to_cpup(&of_serial_dir32[i]);
1093 1096
1097 pdata->num_serializer = val;
1094 pdata->serial_dir = of_serial_dir; 1098 pdata->serial_dir = of_serial_dir;
1095 } 1099 }
1096 1100
1101 ret = of_property_match_string(np, "dma-names", "tx");
1102 if (ret < 0)
1103 goto nodata;
1104
1105 ret = of_parse_phandle_with_args(np, "dmas", "#dma-cells", ret,
1106 &dma_spec);
1107 if (ret < 0)
1108 goto nodata;
1109
1110 pdata->tx_dma_channel = dma_spec.args[0];
1111
1112 ret = of_property_match_string(np, "dma-names", "rx");
1113 if (ret < 0)
1114 goto nodata;
1115
1116 ret = of_parse_phandle_with_args(np, "dmas", "#dma-cells", ret,
1117 &dma_spec);
1118 if (ret < 0)
1119 goto nodata;
1120
1121 pdata->rx_dma_channel = dma_spec.args[0];
1122
1097 ret = of_property_read_u32(np, "tx-num-evt", &val); 1123 ret = of_property_read_u32(np, "tx-num-evt", &val);
1098 if (ret >= 0) 1124 if (ret >= 0)
1099 pdata->txnumevt = val; 1125 pdata->txnumevt = val;
@@ -1124,7 +1150,7 @@ nodata:
1124static int davinci_mcasp_probe(struct platform_device *pdev) 1150static int davinci_mcasp_probe(struct platform_device *pdev)
1125{ 1151{
1126 struct davinci_pcm_dma_params *dma_data; 1152 struct davinci_pcm_dma_params *dma_data;
1127 struct resource *mem, *ioarea, *res; 1153 struct resource *mem, *ioarea, *res, *dat;
1128 struct snd_platform_data *pdata; 1154 struct snd_platform_data *pdata;
1129 struct davinci_audio_dev *dev; 1155 struct davinci_audio_dev *dev;
1130 int ret; 1156 int ret;
@@ -1145,10 +1171,15 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1145 return -EINVAL; 1171 return -EINVAL;
1146 } 1172 }
1147 1173
1148 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1174 mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
1149 if (!mem) { 1175 if (!mem) {
1150 dev_err(&pdev->dev, "no mem resource?\n"); 1176 dev_warn(dev->dev,
1151 return -ENODEV; 1177 "\"mpu\" mem resource not found, using index 0\n");
1178 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1179 if (!mem) {
1180 dev_err(&pdev->dev, "no mem resource?\n");
1181 return -ENODEV;
1182 }
1152 } 1183 }
1153 1184
1154 ioarea = devm_request_mem_region(&pdev->dev, mem->start, 1185 ioarea = devm_request_mem_region(&pdev->dev, mem->start,
@@ -1182,40 +1213,36 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
1182 dev->rxnumevt = pdata->rxnumevt; 1213 dev->rxnumevt = pdata->rxnumevt;
1183 dev->dev = &pdev->dev; 1214 dev->dev = &pdev->dev;
1184 1215
1216 dat = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat");
1217 if (!dat)
1218 dat = mem;
1219
1185 dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]; 1220 dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
1186 dma_data->asp_chan_q = pdata->asp_chan_q; 1221 dma_data->asp_chan_q = pdata->asp_chan_q;
1187 dma_data->ram_chan_q = pdata->ram_chan_q; 1222 dma_data->ram_chan_q = pdata->ram_chan_q;
1188 dma_data->sram_pool = pdata->sram_pool; 1223 dma_data->sram_pool = pdata->sram_pool;
1189 dma_data->sram_size = pdata->sram_size_playback; 1224 dma_data->sram_size = pdata->sram_size_playback;
1190 dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset + 1225 dma_data->dma_addr = dat->start + pdata->tx_dma_offset;
1191 mem->start);
1192 1226
1193 /* first TX, then RX */
1194 res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 1227 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
1195 if (!res) { 1228 if (res)
1196 dev_err(&pdev->dev, "no DMA resource\n"); 1229 dma_data->channel = res->start;
1197 ret = -ENODEV; 1230 else
1198 goto err_release_clk; 1231 dma_data->channel = pdata->tx_dma_channel;
1199 }
1200
1201 dma_data->channel = res->start;
1202 1232
1203 dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]; 1233 dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE];
1204 dma_data->asp_chan_q = pdata->asp_chan_q; 1234 dma_data->asp_chan_q = pdata->asp_chan_q;
1205 dma_data->ram_chan_q = pdata->ram_chan_q; 1235 dma_data->ram_chan_q = pdata->ram_chan_q;
1206 dma_data->sram_pool = pdata->sram_pool; 1236 dma_data->sram_pool = pdata->sram_pool;
1207 dma_data->sram_size = pdata->sram_size_capture; 1237 dma_data->sram_size = pdata->sram_size_capture;
1208 dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset + 1238 dma_data->dma_addr = dat->start + pdata->rx_dma_offset;
1209 mem->start);
1210 1239
1211 res = platform_get_resource(pdev, IORESOURCE_DMA, 1); 1240 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
1212 if (!res) { 1241 if (res)
1213 dev_err(&pdev->dev, "no DMA resource\n"); 1242 dma_data->channel = res->start;
1214 ret = -ENODEV; 1243 else
1215 goto err_release_clk; 1244 dma_data->channel = pdata->rx_dma_channel;
1216 }
1217 1245
1218 dma_data->channel = res->start;
1219 dev_set_drvdata(&pdev->dev, dev); 1246 dev_set_drvdata(&pdev->dev, dev);
1220 ret = snd_soc_register_component(&pdev->dev, &davinci_mcasp_component, 1247 ret = snd_soc_register_component(&pdev->dev, &davinci_mcasp_component,
1221 &davinci_mcasp_dai[pdata->op_mode], 1); 1248 &davinci_mcasp_dai[pdata->op_mode], 1);
@@ -1251,12 +1278,51 @@ static int davinci_mcasp_remove(struct platform_device *pdev)
1251 return 0; 1278 return 0;
1252} 1279}
1253 1280
1281#ifdef CONFIG_PM_SLEEP
1282static int davinci_mcasp_suspend(struct device *dev)
1283{
1284 struct davinci_audio_dev *a = dev_get_drvdata(dev);
1285 void __iomem *base = a->base;
1286
1287 a->context.txfmtctl = mcasp_get_reg(base + DAVINCI_MCASP_TXFMCTL_REG);
1288 a->context.rxfmtctl = mcasp_get_reg(base + DAVINCI_MCASP_RXFMCTL_REG);
1289 a->context.txfmt = mcasp_get_reg(base + DAVINCI_MCASP_TXFMT_REG);
1290 a->context.rxfmt = mcasp_get_reg(base + DAVINCI_MCASP_RXFMT_REG);
1291 a->context.aclkxctl = mcasp_get_reg(base + DAVINCI_MCASP_ACLKXCTL_REG);
1292 a->context.aclkrctl = mcasp_get_reg(base + DAVINCI_MCASP_ACLKRCTL_REG);
1293 a->context.pdir = mcasp_get_reg(base + DAVINCI_MCASP_PDIR_REG);
1294
1295 return 0;
1296}
1297
1298static int davinci_mcasp_resume(struct device *dev)
1299{
1300 struct davinci_audio_dev *a = dev_get_drvdata(dev);
1301 void __iomem *base = a->base;
1302
1303 mcasp_set_reg(base + DAVINCI_MCASP_TXFMCTL_REG, a->context.txfmtctl);
1304 mcasp_set_reg(base + DAVINCI_MCASP_RXFMCTL_REG, a->context.rxfmtctl);
1305 mcasp_set_reg(base + DAVINCI_MCASP_TXFMT_REG, a->context.txfmt);
1306 mcasp_set_reg(base + DAVINCI_MCASP_RXFMT_REG, a->context.rxfmt);
1307 mcasp_set_reg(base + DAVINCI_MCASP_ACLKXCTL_REG, a->context.aclkxctl);
1308 mcasp_set_reg(base + DAVINCI_MCASP_ACLKRCTL_REG, a->context.aclkrctl);
1309 mcasp_set_reg(base + DAVINCI_MCASP_PDIR_REG, a->context.pdir);
1310
1311 return 0;
1312}
1313#endif
1314
1315SIMPLE_DEV_PM_OPS(davinci_mcasp_pm_ops,
1316 davinci_mcasp_suspend,
1317 davinci_mcasp_resume);
1318
1254static struct platform_driver davinci_mcasp_driver = { 1319static struct platform_driver davinci_mcasp_driver = {
1255 .probe = davinci_mcasp_probe, 1320 .probe = davinci_mcasp_probe,
1256 .remove = davinci_mcasp_remove, 1321 .remove = davinci_mcasp_remove,
1257 .driver = { 1322 .driver = {
1258 .name = "davinci-mcasp", 1323 .name = "davinci-mcasp",
1259 .owner = THIS_MODULE, 1324 .owner = THIS_MODULE,
1325 .pm = &davinci_mcasp_pm_ops,
1260 .of_match_table = mcasp_dt_ids, 1326 .of_match_table = mcasp_dt_ids,
1261 }, 1327 },
1262}; 1328};
@@ -1266,4 +1332,3 @@ module_platform_driver(davinci_mcasp_driver);
1266MODULE_AUTHOR("Steve Chen"); 1332MODULE_AUTHOR("Steve Chen");
1267MODULE_DESCRIPTION("TI DAVINCI McASP SoC Interface"); 1333MODULE_DESCRIPTION("TI DAVINCI McASP SoC Interface");
1268MODULE_LICENSE("GPL"); 1334MODULE_LICENSE("GPL");
1269
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h
index a9ac0c11da71..a2e27e1c32f3 100644
--- a/sound/soc/davinci/davinci-mcasp.h
+++ b/sound/soc/davinci/davinci-mcasp.h
@@ -43,6 +43,18 @@ struct davinci_audio_dev {
43 /* McASP FIFO related */ 43 /* McASP FIFO related */
44 u8 txnumevt; 44 u8 txnumevt;
45 u8 rxnumevt; 45 u8 rxnumevt;
46
47#ifdef CONFIG_PM_SLEEP
48 struct {
49 u32 txfmtctl;
50 u32 rxfmtctl;
51 u32 txfmt;
52 u32 rxfmt;
53 u32 aclkxctl;
54 u32 aclkrctl;
55 u32 pdir;
56 } context;
57#endif
46}; 58};
47 59
48#endif /* DAVINCI_MCASP_H */ 60#endif /* DAVINCI_MCASP_H */