diff options
author | Mark Brown <broonie@linaro.org> | 2013-08-30 06:04:23 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-08-30 06:04:23 -0400 |
commit | 0f97b69a9feb1b0f21d25925715de142838fcc32 (patch) | |
tree | 2e7556672199d5152af5c41387571aaef87ea4bf /sound | |
parent | 812e6bbf2caea2c2e55b5838f1148f4a577944ee (diff) | |
parent | 2f82cdbafd53a01e3a3995a618b650653eed9c1a (diff) |
Merge remote-tracking branch 'asoc/topic/fsl' into tmp
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/fsl/Kconfig | 10 | ||||
-rw-r--r-- | sound/soc/fsl/Makefile | 2 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_spdif.c | 17 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 1 | ||||
-rw-r--r-- | sound/soc/fsl/imx-spdif.c | 148 |
5 files changed, 163 insertions, 15 deletions
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index cd088cc8c866..704e246f5b1e 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig | |||
@@ -193,6 +193,16 @@ config SND_SOC_IMX_SGTL5000 | |||
193 | Say Y if you want to add support for SoC audio on an i.MX board with | 193 | Say Y if you want to add support for SoC audio on an i.MX board with |
194 | a sgtl5000 codec. | 194 | a sgtl5000 codec. |
195 | 195 | ||
196 | config SND_SOC_IMX_SPDIF | ||
197 | tristate "SoC Audio support for i.MX boards with S/PDIF" | ||
198 | select SND_SOC_IMX_PCM_DMA | ||
199 | select SND_SOC_FSL_SPDIF | ||
200 | select SND_SOC_SPDIF | ||
201 | help | ||
202 | SoC Audio support for i.MX boards with S/PDIF | ||
203 | Say Y if you want to add support for SoC audio on an i.MX board with | ||
204 | a S/DPDIF. | ||
205 | |||
196 | config SND_SOC_IMX_MC13783 | 206 | config SND_SOC_IMX_MC13783 |
197 | tristate "SoC Audio support for I.MX boards with mc13783" | 207 | tristate "SoC Audio support for I.MX boards with mc13783" |
198 | depends on MFD_MC13783 && ARM | 208 | depends on MFD_MC13783 && ARM |
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index 4b5970e014dd..e2aaff717f8a 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile | |||
@@ -45,6 +45,7 @@ snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o | |||
45 | snd-soc-wm1133-ev1-objs := wm1133-ev1.o | 45 | snd-soc-wm1133-ev1-objs := wm1133-ev1.o |
46 | snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o | 46 | snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o |
47 | snd-soc-imx-wm8962-objs := imx-wm8962.o | 47 | snd-soc-imx-wm8962-objs := imx-wm8962.o |
48 | snd-soc-imx-spdif-objs :=imx-spdif.o | ||
48 | snd-soc-imx-mc13783-objs := imx-mc13783.o | 49 | snd-soc-imx-mc13783-objs := imx-mc13783.o |
49 | 50 | ||
50 | obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o | 51 | obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o |
@@ -53,4 +54,5 @@ obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o | |||
53 | obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o | 54 | obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o |
54 | obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o | 55 | obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o |
55 | obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o | 56 | obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o |
57 | obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o | ||
56 | obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o | 58 | obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o |
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index 42a43820d993..e93dc0dfb0d9 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c | |||
@@ -555,7 +555,6 @@ struct snd_soc_dai_ops fsl_spdif_dai_ops = { | |||
555 | 555 | ||
556 | 556 | ||
557 | /* | 557 | /* |
558 | * ============================================ | ||
559 | * FSL SPDIF IEC958 controller(mixer) functions | 558 | * FSL SPDIF IEC958 controller(mixer) functions |
560 | * | 559 | * |
561 | * Channel status get/put control | 560 | * Channel status get/put control |
@@ -563,7 +562,6 @@ struct snd_soc_dai_ops fsl_spdif_dai_ops = { | |||
563 | * Valid bit value get control | 562 | * Valid bit value get control |
564 | * DPLL lock status get control | 563 | * DPLL lock status get control |
565 | * User bit sync mode selection control | 564 | * User bit sync mode selection control |
566 | * ============================================ | ||
567 | */ | 565 | */ |
568 | 566 | ||
569 | static int fsl_spdif_info(struct snd_kcontrol *kcontrol, | 567 | static int fsl_spdif_info(struct snd_kcontrol *kcontrol, |
@@ -942,11 +940,7 @@ static const struct snd_soc_component_driver fsl_spdif_component = { | |||
942 | .name = "fsl-spdif", | 940 | .name = "fsl-spdif", |
943 | }; | 941 | }; |
944 | 942 | ||
945 | /* | 943 | /* FSL SPDIF REGMAP */ |
946 | * ================ | ||
947 | * FSL SPDIF REGMAP | ||
948 | * ================ | ||
949 | */ | ||
950 | 944 | ||
951 | static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg) | 945 | static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg) |
952 | { | 946 | { |
@@ -1119,10 +1113,8 @@ static int fsl_spdif_probe(struct platform_device *pdev) | |||
1119 | } | 1113 | } |
1120 | 1114 | ||
1121 | regs = devm_ioremap_resource(&pdev->dev, res); | 1115 | regs = devm_ioremap_resource(&pdev->dev, res); |
1122 | if (IS_ERR(regs)) { | 1116 | if (IS_ERR(regs)) |
1123 | dev_err(&pdev->dev, "could not map device resources\n"); | ||
1124 | return PTR_ERR(regs); | 1117 | return PTR_ERR(regs); |
1125 | } | ||
1126 | 1118 | ||
1127 | spdif_priv->regmap = devm_regmap_init_mmio_clk(&pdev->dev, | 1119 | spdif_priv->regmap = devm_regmap_init_mmio_clk(&pdev->dev, |
1128 | "core", regs, &fsl_spdif_regmap_config); | 1120 | "core", regs, &fsl_spdif_regmap_config); |
@@ -1184,7 +1176,7 @@ static int fsl_spdif_probe(struct platform_device *pdev) | |||
1184 | &spdif_priv->cpu_dai_drv, 1); | 1176 | &spdif_priv->cpu_dai_drv, 1); |
1185 | if (ret) { | 1177 | if (ret) { |
1186 | dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); | 1178 | dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); |
1187 | goto error_dev; | 1179 | return ret; |
1188 | } | 1180 | } |
1189 | 1181 | ||
1190 | ret = imx_pcm_dma_init(pdev); | 1182 | ret = imx_pcm_dma_init(pdev); |
@@ -1197,8 +1189,6 @@ static int fsl_spdif_probe(struct platform_device *pdev) | |||
1197 | 1189 | ||
1198 | error_component: | 1190 | error_component: |
1199 | snd_soc_unregister_component(&pdev->dev); | 1191 | snd_soc_unregister_component(&pdev->dev); |
1200 | error_dev: | ||
1201 | dev_set_drvdata(&pdev->dev, NULL); | ||
1202 | 1192 | ||
1203 | return ret; | 1193 | return ret; |
1204 | } | 1194 | } |
@@ -1207,7 +1197,6 @@ static int fsl_spdif_remove(struct platform_device *pdev) | |||
1207 | { | 1197 | { |
1208 | imx_pcm_dma_exit(pdev); | 1198 | imx_pcm_dma_exit(pdev); |
1209 | snd_soc_unregister_component(&pdev->dev); | 1199 | snd_soc_unregister_component(&pdev->dev); |
1210 | dev_set_drvdata(&pdev->dev, NULL); | ||
1211 | 1200 | ||
1212 | return 0; | 1201 | return 0; |
1213 | } | 1202 | } |
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 5cf626c4dc96..c6b743978d5e 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
@@ -1114,7 +1114,6 @@ error_dai: | |||
1114 | snd_soc_unregister_component(&pdev->dev); | 1114 | snd_soc_unregister_component(&pdev->dev); |
1115 | 1115 | ||
1116 | error_dev: | 1116 | error_dev: |
1117 | dev_set_drvdata(&pdev->dev, NULL); | ||
1118 | device_remove_file(&pdev->dev, dev_attr); | 1117 | device_remove_file(&pdev->dev, dev_attr); |
1119 | 1118 | ||
1120 | error_clk: | 1119 | error_clk: |
diff --git a/sound/soc/fsl/imx-spdif.c b/sound/soc/fsl/imx-spdif.c new file mode 100644 index 000000000000..816013b0ebba --- /dev/null +++ b/sound/soc/fsl/imx-spdif.c | |||
@@ -0,0 +1,148 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Freescale Semiconductor, Inc. | ||
3 | * | ||
4 | * The code contained herein is licensed under the GNU General Public | ||
5 | * License. You may obtain a copy of the GNU General Public License | ||
6 | * Version 2 or later at the following locations: | ||
7 | * | ||
8 | * http://www.opensource.org/licenses/gpl-license.html | ||
9 | * http://www.gnu.org/copyleft/gpl.html | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/of_platform.h> | ||
14 | #include <sound/soc.h> | ||
15 | |||
16 | struct imx_spdif_data { | ||
17 | struct snd_soc_dai_link dai[2]; | ||
18 | struct snd_soc_card card; | ||
19 | struct platform_device *txdev; | ||
20 | struct platform_device *rxdev; | ||
21 | }; | ||
22 | |||
23 | static int imx_spdif_audio_probe(struct platform_device *pdev) | ||
24 | { | ||
25 | struct device_node *spdif_np, *np = pdev->dev.of_node; | ||
26 | struct imx_spdif_data *data; | ||
27 | int ret = 0, num_links = 0; | ||
28 | |||
29 | spdif_np = of_parse_phandle(np, "spdif-controller", 0); | ||
30 | if (!spdif_np) { | ||
31 | dev_err(&pdev->dev, "failed to find spdif-controller\n"); | ||
32 | ret = -EINVAL; | ||
33 | goto end; | ||
34 | } | ||
35 | |||
36 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | ||
37 | if (!data) { | ||
38 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
39 | ret = -ENOMEM; | ||
40 | goto end; | ||
41 | } | ||
42 | |||
43 | if (of_property_read_bool(np, "spdif-out")) { | ||
44 | data->dai[num_links].name = "S/PDIF TX"; | ||
45 | data->dai[num_links].stream_name = "S/PDIF PCM Playback"; | ||
46 | data->dai[num_links].codec_dai_name = "dit-hifi"; | ||
47 | data->dai[num_links].codec_name = "spdif-dit"; | ||
48 | data->dai[num_links].cpu_of_node = spdif_np; | ||
49 | data->dai[num_links].platform_of_node = spdif_np; | ||
50 | num_links++; | ||
51 | |||
52 | data->txdev = platform_device_register_simple("spdif-dit", -1, NULL, 0); | ||
53 | if (IS_ERR(data->txdev)) { | ||
54 | ret = PTR_ERR(data->txdev); | ||
55 | dev_err(&pdev->dev, "register dit failed: %d\n", ret); | ||
56 | goto end; | ||
57 | } | ||
58 | } | ||
59 | |||
60 | if (of_property_read_bool(np, "spdif-in")) { | ||
61 | data->dai[num_links].name = "S/PDIF RX"; | ||
62 | data->dai[num_links].stream_name = "S/PDIF PCM Capture"; | ||
63 | data->dai[num_links].codec_dai_name = "dir-hifi"; | ||
64 | data->dai[num_links].codec_name = "spdif-dir"; | ||
65 | data->dai[num_links].cpu_of_node = spdif_np; | ||
66 | data->dai[num_links].platform_of_node = spdif_np; | ||
67 | num_links++; | ||
68 | |||
69 | data->rxdev = platform_device_register_simple("spdif-dir", -1, NULL, 0); | ||
70 | if (IS_ERR(data->rxdev)) { | ||
71 | ret = PTR_ERR(data->rxdev); | ||
72 | dev_err(&pdev->dev, "register dir failed: %d\n", ret); | ||
73 | goto error_dit; | ||
74 | } | ||
75 | } | ||
76 | |||
77 | if (!num_links) { | ||
78 | dev_err(&pdev->dev, "no enabled S/PDIF DAI link\n"); | ||
79 | goto error_dir; | ||
80 | } | ||
81 | |||
82 | data->card.dev = &pdev->dev; | ||
83 | data->card.num_links = num_links; | ||
84 | data->card.dai_link = data->dai; | ||
85 | |||
86 | ret = snd_soc_of_parse_card_name(&data->card, "model"); | ||
87 | if (ret) | ||
88 | goto error_dir; | ||
89 | |||
90 | ret = snd_soc_register_card(&data->card); | ||
91 | if (ret) { | ||
92 | dev_err(&pdev->dev, "snd_soc_register_card failed: %d\n", ret); | ||
93 | goto error_dir; | ||
94 | } | ||
95 | |||
96 | platform_set_drvdata(pdev, data); | ||
97 | |||
98 | goto end; | ||
99 | |||
100 | error_dir: | ||
101 | if (data->rxdev) | ||
102 | platform_device_unregister(data->rxdev); | ||
103 | error_dit: | ||
104 | if (data->txdev) | ||
105 | platform_device_unregister(data->txdev); | ||
106 | end: | ||
107 | if (spdif_np) | ||
108 | of_node_put(spdif_np); | ||
109 | |||
110 | return ret; | ||
111 | } | ||
112 | |||
113 | static int imx_spdif_audio_remove(struct platform_device *pdev) | ||
114 | { | ||
115 | struct imx_spdif_data *data = platform_get_drvdata(pdev); | ||
116 | |||
117 | if (data->rxdev) | ||
118 | platform_device_unregister(data->rxdev); | ||
119 | if (data->txdev) | ||
120 | platform_device_unregister(data->txdev); | ||
121 | |||
122 | snd_soc_unregister_card(&data->card); | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static const struct of_device_id imx_spdif_dt_ids[] = { | ||
128 | { .compatible = "fsl,imx-audio-spdif", }, | ||
129 | { /* sentinel */ } | ||
130 | }; | ||
131 | MODULE_DEVICE_TABLE(of, imx_spdif_dt_ids); | ||
132 | |||
133 | static struct platform_driver imx_spdif_driver = { | ||
134 | .driver = { | ||
135 | .name = "imx-spdif", | ||
136 | .owner = THIS_MODULE, | ||
137 | .of_match_table = imx_spdif_dt_ids, | ||
138 | }, | ||
139 | .probe = imx_spdif_audio_probe, | ||
140 | .remove = imx_spdif_audio_remove, | ||
141 | }; | ||
142 | |||
143 | module_platform_driver(imx_spdif_driver); | ||
144 | |||
145 | MODULE_AUTHOR("Freescale Semiconductor, Inc."); | ||
146 | MODULE_DESCRIPTION("Freescale i.MX S/PDIF machine driver"); | ||
147 | MODULE_LICENSE("GPL v2"); | ||
148 | MODULE_ALIAS("platform:imx-spdif"); | ||