diff options
author | Shawn Guo <shawn.guo@linaro.org> | 2012-03-05 09:30:53 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-03-05 19:03:00 -0500 |
commit | 3c77c29c49c6213c55ad8dacc687817b3568c0ce (patch) | |
tree | aa2470aafbd4434d3d7429265ed70e163d45b7f8 /arch/arm/plat-mxc | |
parent | 3bc34a6143359d2bf19a5e79b9017aeffc6660ad (diff) |
ASoC: imx: move audmux driver into sound/soc/imx
As audmux becomes a platform driver and its callers are all ASoC
machine drivers, there is no reason to keep it in arch folder, so
move it to sound/soc/imx.
One bonus point would be those ASoC machine drivers stop including
mach/audmux.h, since it's been moved to sound/soc/imx/imx-audmux.h.
This should be a move to the right direction in terms of single kernel
image goal.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'arch/arm/plat-mxc')
-rw-r--r-- | arch/arm/plat-mxc/Kconfig | 3 | ||||
-rw-r--r-- | arch/arm/plat-mxc/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/plat-mxc/audmux.c | 299 | ||||
-rw-r--r-- | arch/arm/plat-mxc/include/mach/audmux.h | 60 |
4 files changed, 0 insertions, 363 deletions
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig index 0461d16e5ca6..c722f9ce6918 100644 --- a/arch/arm/plat-mxc/Kconfig +++ b/arch/arm/plat-mxc/Kconfig | |||
@@ -88,9 +88,6 @@ config IMX_HAVE_IOMUX_V1 | |||
88 | config ARCH_MXC_IOMUX_V3 | 88 | config ARCH_MXC_IOMUX_V3 |
89 | bool | 89 | bool |
90 | 90 | ||
91 | config ARCH_MXC_AUDMUX | ||
92 | bool | ||
93 | |||
94 | config IRAM_ALLOC | 91 | config IRAM_ALLOC |
95 | bool | 92 | bool |
96 | select GENERIC_ALLOCATOR | 93 | select GENERIC_ALLOCATOR |
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index 530c81dfd9be..e81290c27c65 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile | |||
@@ -14,7 +14,6 @@ obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o | |||
14 | obj-$(CONFIG_MXC_PWM) += pwm.o | 14 | obj-$(CONFIG_MXC_PWM) += pwm.o |
15 | obj-$(CONFIG_MXC_ULPI) += ulpi.o | 15 | obj-$(CONFIG_MXC_ULPI) += ulpi.o |
16 | obj-$(CONFIG_MXC_USE_EPIT) += epit.o | 16 | obj-$(CONFIG_MXC_USE_EPIT) += epit.o |
17 | obj-$(CONFIG_ARCH_MXC_AUDMUX) += audmux.o | ||
18 | obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o | 17 | obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o |
19 | obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o | 18 | obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o |
20 | ifdef CONFIG_SND_IMX_SOC | 19 | ifdef CONFIG_SND_IMX_SOC |
diff --git a/arch/arm/plat-mxc/audmux.c b/arch/arm/plat-mxc/audmux.c deleted file mode 100644 index a8c9e04771bf..000000000000 --- a/arch/arm/plat-mxc/audmux.c +++ /dev/null | |||
@@ -1,299 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2012 Freescale Semiconductor, Inc. | ||
3 | * Copyright 2012 Linaro Ltd. | ||
4 | * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> | ||
5 | * | ||
6 | * Initial development of this code was funded by | ||
7 | * Phytec Messtechnik GmbH, http://www.phytec.de | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | */ | ||
19 | |||
20 | #include <linux/clk.h> | ||
21 | #include <linux/debugfs.h> | ||
22 | #include <linux/err.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <mach/audmux.h> | ||
28 | |||
29 | #define DRIVER_NAME "imx-audmux" | ||
30 | |||
31 | static struct clk *audmux_clk; | ||
32 | static void __iomem *audmux_base; | ||
33 | |||
34 | #define MXC_AUDMUX_V2_PTCR(x) ((x) * 8) | ||
35 | #define MXC_AUDMUX_V2_PDCR(x) ((x) * 8 + 4) | ||
36 | |||
37 | #ifdef CONFIG_DEBUG_FS | ||
38 | static struct dentry *audmux_debugfs_root; | ||
39 | |||
40 | static int audmux_open_file(struct inode *inode, struct file *file) | ||
41 | { | ||
42 | file->private_data = inode->i_private; | ||
43 | return 0; | ||
44 | } | ||
45 | |||
46 | /* There is an annoying discontinuity in the SSI numbering with regard | ||
47 | * to the Linux number of the devices */ | ||
48 | static const char *audmux_port_string(int port) | ||
49 | { | ||
50 | switch (port) { | ||
51 | case MX31_AUDMUX_PORT1_SSI0: | ||
52 | return "imx-ssi.0"; | ||
53 | case MX31_AUDMUX_PORT2_SSI1: | ||
54 | return "imx-ssi.1"; | ||
55 | case MX31_AUDMUX_PORT3_SSI_PINS_3: | ||
56 | return "SSI3"; | ||
57 | case MX31_AUDMUX_PORT4_SSI_PINS_4: | ||
58 | return "SSI4"; | ||
59 | case MX31_AUDMUX_PORT5_SSI_PINS_5: | ||
60 | return "SSI5"; | ||
61 | case MX31_AUDMUX_PORT6_SSI_PINS_6: | ||
62 | return "SSI6"; | ||
63 | default: | ||
64 | return "UNKNOWN"; | ||
65 | } | ||
66 | } | ||
67 | |||
68 | static ssize_t audmux_read_file(struct file *file, char __user *user_buf, | ||
69 | size_t count, loff_t *ppos) | ||
70 | { | ||
71 | ssize_t ret; | ||
72 | char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
73 | int port = (int)file->private_data; | ||
74 | u32 pdcr, ptcr; | ||
75 | |||
76 | if (!buf) | ||
77 | return -ENOMEM; | ||
78 | |||
79 | if (audmux_clk) | ||
80 | clk_enable(audmux_clk); | ||
81 | |||
82 | ptcr = readl(audmux_base + MXC_AUDMUX_V2_PTCR(port)); | ||
83 | pdcr = readl(audmux_base + MXC_AUDMUX_V2_PDCR(port)); | ||
84 | |||
85 | if (audmux_clk) | ||
86 | clk_disable(audmux_clk); | ||
87 | |||
88 | ret = snprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n", | ||
89 | pdcr, ptcr); | ||
90 | |||
91 | if (ptcr & MXC_AUDMUX_V2_PTCR_TFSDIR) | ||
92 | ret += snprintf(buf + ret, PAGE_SIZE - ret, | ||
93 | "TxFS output from %s, ", | ||
94 | audmux_port_string((ptcr >> 27) & 0x7)); | ||
95 | else | ||
96 | ret += snprintf(buf + ret, PAGE_SIZE - ret, | ||
97 | "TxFS input, "); | ||
98 | |||
99 | if (ptcr & MXC_AUDMUX_V2_PTCR_TCLKDIR) | ||
100 | ret += snprintf(buf + ret, PAGE_SIZE - ret, | ||
101 | "TxClk output from %s", | ||
102 | audmux_port_string((ptcr >> 22) & 0x7)); | ||
103 | else | ||
104 | ret += snprintf(buf + ret, PAGE_SIZE - ret, | ||
105 | "TxClk input"); | ||
106 | |||
107 | ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); | ||
108 | |||
109 | if (ptcr & MXC_AUDMUX_V2_PTCR_SYN) { | ||
110 | ret += snprintf(buf + ret, PAGE_SIZE - ret, | ||
111 | "Port is symmetric"); | ||
112 | } else { | ||
113 | if (ptcr & MXC_AUDMUX_V2_PTCR_RFSDIR) | ||
114 | ret += snprintf(buf + ret, PAGE_SIZE - ret, | ||
115 | "RxFS output from %s, ", | ||
116 | audmux_port_string((ptcr >> 17) & 0x7)); | ||
117 | else | ||
118 | ret += snprintf(buf + ret, PAGE_SIZE - ret, | ||
119 | "RxFS input, "); | ||
120 | |||
121 | if (ptcr & MXC_AUDMUX_V2_PTCR_RCLKDIR) | ||
122 | ret += snprintf(buf + ret, PAGE_SIZE - ret, | ||
123 | "RxClk output from %s", | ||
124 | audmux_port_string((ptcr >> 12) & 0x7)); | ||
125 | else | ||
126 | ret += snprintf(buf + ret, PAGE_SIZE - ret, | ||
127 | "RxClk input"); | ||
128 | } | ||
129 | |||
130 | ret += snprintf(buf + ret, PAGE_SIZE - ret, | ||
131 | "\nData received from %s\n", | ||
132 | audmux_port_string((pdcr >> 13) & 0x7)); | ||
133 | |||
134 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); | ||
135 | |||
136 | kfree(buf); | ||
137 | |||
138 | return ret; | ||
139 | } | ||
140 | |||
141 | static const struct file_operations audmux_debugfs_fops = { | ||
142 | .open = audmux_open_file, | ||
143 | .read = audmux_read_file, | ||
144 | .llseek = default_llseek, | ||
145 | }; | ||
146 | |||
147 | static void __init audmux_debugfs_init(void) | ||
148 | { | ||
149 | int i; | ||
150 | char buf[20]; | ||
151 | |||
152 | audmux_debugfs_root = debugfs_create_dir("audmux", NULL); | ||
153 | if (!audmux_debugfs_root) { | ||
154 | pr_warning("Failed to create AUDMUX debugfs root\n"); | ||
155 | return; | ||
156 | } | ||
157 | |||
158 | for (i = 1; i < 8; i++) { | ||
159 | snprintf(buf, sizeof(buf), "ssi%d", i); | ||
160 | if (!debugfs_create_file(buf, 0444, audmux_debugfs_root, | ||
161 | (void *)i, &audmux_debugfs_fops)) | ||
162 | pr_warning("Failed to create AUDMUX port %d debugfs file\n", | ||
163 | i); | ||
164 | } | ||
165 | } | ||
166 | |||
167 | static void __exit audmux_debugfs_remove(void) | ||
168 | { | ||
169 | debugfs_remove_recursive(audmux_debugfs_root); | ||
170 | } | ||
171 | #else | ||
172 | static inline void audmux_debugfs_init(void) | ||
173 | { | ||
174 | } | ||
175 | |||
176 | static inline void audmux_debugfs_remove(void) | ||
177 | { | ||
178 | } | ||
179 | #endif | ||
180 | |||
181 | enum imx_audmux_type { | ||
182 | IMX21_AUDMUX, | ||
183 | IMX31_AUDMUX, | ||
184 | } audmux_type; | ||
185 | |||
186 | static struct platform_device_id imx_audmux_ids[] = { | ||
187 | { | ||
188 | .name = "imx21-audmux", | ||
189 | .driver_data = IMX21_AUDMUX, | ||
190 | }, { | ||
191 | .name = "imx31-audmux", | ||
192 | .driver_data = IMX31_AUDMUX, | ||
193 | }, { | ||
194 | /* sentinel */ | ||
195 | } | ||
196 | }; | ||
197 | MODULE_DEVICE_TABLE(platform, imx_audmux_ids); | ||
198 | |||
199 | static const uint8_t port_mapping[] = { | ||
200 | 0x0, 0x4, 0x8, 0x10, 0x14, 0x1c, | ||
201 | }; | ||
202 | |||
203 | int mxc_audmux_v1_configure_port(unsigned int port, unsigned int pcr) | ||
204 | { | ||
205 | if (audmux_type != IMX21_AUDMUX) | ||
206 | return -EINVAL; | ||
207 | |||
208 | if (!audmux_base) | ||
209 | return -ENOSYS; | ||
210 | |||
211 | if (port >= ARRAY_SIZE(port_mapping)) | ||
212 | return -EINVAL; | ||
213 | |||
214 | writel(pcr, audmux_base + port_mapping[port]); | ||
215 | |||
216 | return 0; | ||
217 | } | ||
218 | EXPORT_SYMBOL_GPL(mxc_audmux_v1_configure_port); | ||
219 | |||
220 | int mxc_audmux_v2_configure_port(unsigned int port, unsigned int ptcr, | ||
221 | unsigned int pdcr) | ||
222 | { | ||
223 | if (audmux_type != IMX31_AUDMUX) | ||
224 | return -EINVAL; | ||
225 | |||
226 | if (!audmux_base) | ||
227 | return -ENOSYS; | ||
228 | |||
229 | if (audmux_clk) | ||
230 | clk_enable(audmux_clk); | ||
231 | |||
232 | writel(ptcr, audmux_base + MXC_AUDMUX_V2_PTCR(port)); | ||
233 | writel(pdcr, audmux_base + MXC_AUDMUX_V2_PDCR(port)); | ||
234 | |||
235 | if (audmux_clk) | ||
236 | clk_disable(audmux_clk); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | EXPORT_SYMBOL_GPL(mxc_audmux_v2_configure_port); | ||
241 | |||
242 | static int __init imx_audmux_probe(struct platform_device *pdev) | ||
243 | { | ||
244 | struct resource *res; | ||
245 | |||
246 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
247 | audmux_base = devm_request_and_ioremap(&pdev->dev, res); | ||
248 | if (!audmux_base) | ||
249 | return -EADDRNOTAVAIL; | ||
250 | |||
251 | audmux_clk = clk_get(&pdev->dev, "audmux"); | ||
252 | if (IS_ERR(audmux_clk)) { | ||
253 | dev_dbg(&pdev->dev, "cannot get clock: %ld\n", | ||
254 | PTR_ERR(audmux_clk)); | ||
255 | audmux_clk = NULL; | ||
256 | } | ||
257 | |||
258 | audmux_type = pdev->id_entry->driver_data; | ||
259 | if (audmux_type == IMX31_AUDMUX) | ||
260 | audmux_debugfs_init(); | ||
261 | |||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | static int __exit imx_audmux_remove(struct platform_device *pdev) | ||
266 | { | ||
267 | if (audmux_type == IMX31_AUDMUX) | ||
268 | audmux_debugfs_remove(); | ||
269 | clk_put(audmux_clk); | ||
270 | |||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | static struct platform_driver imx_audmux_driver = { | ||
275 | .probe = imx_audmux_probe, | ||
276 | .remove = __exit_p(imx_audmux_remove), | ||
277 | .id_table = imx_audmux_ids, | ||
278 | .driver = { | ||
279 | .name = DRIVER_NAME, | ||
280 | .owner = THIS_MODULE, | ||
281 | } | ||
282 | }; | ||
283 | |||
284 | static int __init imx_audmux_init(void) | ||
285 | { | ||
286 | return platform_driver_register(&imx_audmux_driver); | ||
287 | } | ||
288 | subsys_initcall(imx_audmux_init); | ||
289 | |||
290 | static void __exit imx_audmux_exit(void) | ||
291 | { | ||
292 | platform_driver_unregister(&imx_audmux_driver); | ||
293 | } | ||
294 | module_exit(imx_audmux_exit); | ||
295 | |||
296 | MODULE_DESCRIPTION("Freescale i.MX AUDMUX driver"); | ||
297 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); | ||
298 | MODULE_LICENSE("GPL v2"); | ||
299 | MODULE_ALIAS("platform:" DRIVER_NAME); | ||
diff --git a/arch/arm/plat-mxc/include/mach/audmux.h b/arch/arm/plat-mxc/include/mach/audmux.h deleted file mode 100644 index 6fda788ed0e9..000000000000 --- a/arch/arm/plat-mxc/include/mach/audmux.h +++ /dev/null | |||
@@ -1,60 +0,0 @@ | |||
1 | #ifndef __MACH_AUDMUX_H | ||
2 | #define __MACH_AUDMUX_H | ||
3 | |||
4 | #define MX27_AUDMUX_HPCR1_SSI0 0 | ||
5 | #define MX27_AUDMUX_HPCR2_SSI1 1 | ||
6 | #define MX27_AUDMUX_HPCR3_SSI_PINS_4 2 | ||
7 | #define MX27_AUDMUX_PPCR1_SSI_PINS_1 3 | ||
8 | #define MX27_AUDMUX_PPCR2_SSI_PINS_2 4 | ||
9 | #define MX27_AUDMUX_PPCR3_SSI_PINS_3 5 | ||
10 | |||
11 | #define MX31_AUDMUX_PORT1_SSI0 0 | ||
12 | #define MX31_AUDMUX_PORT2_SSI1 1 | ||
13 | #define MX31_AUDMUX_PORT3_SSI_PINS_3 2 | ||
14 | #define MX31_AUDMUX_PORT4_SSI_PINS_4 3 | ||
15 | #define MX31_AUDMUX_PORT5_SSI_PINS_5 4 | ||
16 | #define MX31_AUDMUX_PORT6_SSI_PINS_6 5 | ||
17 | |||
18 | #define MX51_AUDMUX_PORT1_SSI0 0 | ||
19 | #define MX51_AUDMUX_PORT2_SSI1 1 | ||
20 | #define MX51_AUDMUX_PORT3 2 | ||
21 | #define MX51_AUDMUX_PORT4 3 | ||
22 | #define MX51_AUDMUX_PORT5 4 | ||
23 | #define MX51_AUDMUX_PORT6 5 | ||
24 | #define MX51_AUDMUX_PORT7 6 | ||
25 | |||
26 | /* Register definitions for the i.MX21/27 Digital Audio Multiplexer */ | ||
27 | #define MXC_AUDMUX_V1_PCR_INMMASK(x) ((x) & 0xff) | ||
28 | #define MXC_AUDMUX_V1_PCR_INMEN (1 << 8) | ||
29 | #define MXC_AUDMUX_V1_PCR_TXRXEN (1 << 10) | ||
30 | #define MXC_AUDMUX_V1_PCR_SYN (1 << 12) | ||
31 | #define MXC_AUDMUX_V1_PCR_RXDSEL(x) (((x) & 0x7) << 13) | ||
32 | #define MXC_AUDMUX_V1_PCR_RFCSEL(x) (((x) & 0xf) << 20) | ||
33 | #define MXC_AUDMUX_V1_PCR_RCLKDIR (1 << 24) | ||
34 | #define MXC_AUDMUX_V1_PCR_RFSDIR (1 << 25) | ||
35 | #define MXC_AUDMUX_V1_PCR_TFCSEL(x) (((x) & 0xf) << 26) | ||
36 | #define MXC_AUDMUX_V1_PCR_TCLKDIR (1 << 30) | ||
37 | #define MXC_AUDMUX_V1_PCR_TFSDIR (1 << 31) | ||
38 | |||
39 | /* Register definitions for the i.MX25/31/35/51 Digital Audio Multiplexer */ | ||
40 | #define MXC_AUDMUX_V2_PTCR_TFSDIR (1 << 31) | ||
41 | #define MXC_AUDMUX_V2_PTCR_TFSEL(x) (((x) & 0xf) << 27) | ||
42 | #define MXC_AUDMUX_V2_PTCR_TCLKDIR (1 << 26) | ||
43 | #define MXC_AUDMUX_V2_PTCR_TCSEL(x) (((x) & 0xf) << 22) | ||
44 | #define MXC_AUDMUX_V2_PTCR_RFSDIR (1 << 21) | ||
45 | #define MXC_AUDMUX_V2_PTCR_RFSEL(x) (((x) & 0xf) << 17) | ||
46 | #define MXC_AUDMUX_V2_PTCR_RCLKDIR (1 << 16) | ||
47 | #define MXC_AUDMUX_V2_PTCR_RCSEL(x) (((x) & 0xf) << 12) | ||
48 | #define MXC_AUDMUX_V2_PTCR_SYN (1 << 11) | ||
49 | |||
50 | #define MXC_AUDMUX_V2_PDCR_RXDSEL(x) (((x) & 0x7) << 13) | ||
51 | #define MXC_AUDMUX_V2_PDCR_TXRXEN (1 << 12) | ||
52 | #define MXC_AUDMUX_V2_PDCR_MODE(x) (((x) & 0x3) << 8) | ||
53 | #define MXC_AUDMUX_V2_PDCR_INMMASK(x) ((x) & 0xff) | ||
54 | |||
55 | int mxc_audmux_v1_configure_port(unsigned int port, unsigned int pcr); | ||
56 | |||
57 | int mxc_audmux_v2_configure_port(unsigned int port, unsigned int ptcr, | ||
58 | unsigned int pdcr); | ||
59 | |||
60 | #endif /* __MACH_AUDMUX_H */ | ||