]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - arch/arm/mach-exynos/dev-audio.c
Merge branch 'misc' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild
[linux-2.6.git] / arch / arm / mach-exynos / dev-audio.c
1 /* linux/arch/arm/mach-exynos4/dev-audio.c
2  *
3  * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4  *              http://www.samsung.com
5  *
6  * Copyright (c) 2010 Samsung Electronics Co. Ltd
7  *      Jaswinder Singh <jassi.brar@samsung.com>
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 version 2 as
11  * published by the Free Software Foundation.
12  */
13
14 #include <linux/platform_device.h>
15 #include <linux/dma-mapping.h>
16 #include <linux/gpio.h>
17
18 #include <plat/gpio-cfg.h>
19 #include <plat/audio.h>
20
21 #include <mach/map.h>
22 #include <mach/dma.h>
23 #include <mach/irqs.h>
24 #include <mach/regs-audss.h>
25
26 static const char *rclksrc[] = {
27         [0] = "busclk",
28         [1] = "i2sclk",
29 };
30
31 static int exynos4_cfg_i2s(struct platform_device *pdev)
32 {
33         /* configure GPIO for i2s port */
34         switch (pdev->id) {
35         case 0:
36                 s3c_gpio_cfgpin_range(EXYNOS4_GPZ(0), 7, S3C_GPIO_SFN(2));
37                 break;
38         case 1:
39                 s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(2));
40                 break;
41         case 2:
42                 s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 5, S3C_GPIO_SFN(4));
43                 break;
44         default:
45                 printk(KERN_ERR "Invalid Device %d\n", pdev->id);
46                 return -EINVAL;
47         }
48
49         return 0;
50 }
51
52 static struct s3c_audio_pdata i2sv5_pdata = {
53         .cfg_gpio = exynos4_cfg_i2s,
54         .type = {
55                 .i2s = {
56                         .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI
57                                          | QUIRK_NEED_RSTCLR,
58                         .src_clk = rclksrc,
59                         .idma_addr = EXYNOS4_AUDSS_INT_MEM,
60                 },
61         },
62 };
63
64 static struct resource exynos4_i2s0_resource[] = {
65         [0] = {
66                 .start  = EXYNOS4_PA_I2S0,
67                 .end    = EXYNOS4_PA_I2S0 + 0x100 - 1,
68                 .flags  = IORESOURCE_MEM,
69         },
70         [1] = {
71                 .start  = DMACH_I2S0_TX,
72                 .end    = DMACH_I2S0_TX,
73                 .flags  = IORESOURCE_DMA,
74         },
75         [2] = {
76                 .start  = DMACH_I2S0_RX,
77                 .end    = DMACH_I2S0_RX,
78                 .flags  = IORESOURCE_DMA,
79         },
80         [3] = {
81                 .start  = DMACH_I2S0S_TX,
82                 .end    = DMACH_I2S0S_TX,
83                 .flags  = IORESOURCE_DMA,
84         },
85 };
86
87 struct platform_device exynos4_device_i2s0 = {
88         .name = "samsung-i2s",
89         .id = 0,
90         .num_resources = ARRAY_SIZE(exynos4_i2s0_resource),
91         .resource = exynos4_i2s0_resource,
92         .dev = {
93                 .platform_data = &i2sv5_pdata,
94         },
95 };
96
97 static const char *rclksrc_v3[] = {
98         [0] = "sclk_i2s",
99         [1] = "no_such_clock",
100 };
101
102 static struct s3c_audio_pdata i2sv3_pdata = {
103         .cfg_gpio = exynos4_cfg_i2s,
104         .type = {
105                 .i2s = {
106                         .quirks = QUIRK_NO_MUXPSR,
107                         .src_clk = rclksrc_v3,
108                 },
109         },
110 };
111
112 static struct resource exynos4_i2s1_resource[] = {
113         [0] = {
114                 .start  = EXYNOS4_PA_I2S1,
115                 .end    = EXYNOS4_PA_I2S1 + 0x100 - 1,
116                 .flags  = IORESOURCE_MEM,
117         },
118         [1] = {
119                 .start  = DMACH_I2S1_TX,
120                 .end    = DMACH_I2S1_TX,
121                 .flags  = IORESOURCE_DMA,
122         },
123         [2] = {
124                 .start  = DMACH_I2S1_RX,
125                 .end    = DMACH_I2S1_RX,
126                 .flags  = IORESOURCE_DMA,
127         },
128 };
129
130 struct platform_device exynos4_device_i2s1 = {
131         .name = "samsung-i2s",
132         .id = 1,
133         .num_resources = ARRAY_SIZE(exynos4_i2s1_resource),
134         .resource = exynos4_i2s1_resource,
135         .dev = {
136                 .platform_data = &i2sv3_pdata,
137         },
138 };
139
140 static struct resource exynos4_i2s2_resource[] = {
141         [0] = {
142                 .start  = EXYNOS4_PA_I2S2,
143                 .end    = EXYNOS4_PA_I2S2 + 0x100 - 1,
144                 .flags  = IORESOURCE_MEM,
145         },
146         [1] = {
147                 .start  = DMACH_I2S2_TX,
148                 .end    = DMACH_I2S2_TX,
149                 .flags  = IORESOURCE_DMA,
150         },
151         [2] = {
152                 .start  = DMACH_I2S2_RX,
153                 .end    = DMACH_I2S2_RX,
154                 .flags  = IORESOURCE_DMA,
155         },
156 };
157
158 struct platform_device exynos4_device_i2s2 = {
159         .name = "samsung-i2s",
160         .id = 2,
161         .num_resources = ARRAY_SIZE(exynos4_i2s2_resource),
162         .resource = exynos4_i2s2_resource,
163         .dev = {
164                 .platform_data = &i2sv3_pdata,
165         },
166 };
167
168 /* PCM Controller platform_devices */
169
170 static int exynos4_pcm_cfg_gpio(struct platform_device *pdev)
171 {
172         switch (pdev->id) {
173         case 0:
174                 s3c_gpio_cfgpin_range(EXYNOS4_GPZ(0), 5, S3C_GPIO_SFN(3));
175                 break;
176         case 1:
177                 s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(3));
178                 break;
179         case 2:
180                 s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 5, S3C_GPIO_SFN(3));
181                 break;
182         default:
183                 printk(KERN_DEBUG "Invalid PCM Controller number!");
184                 return -EINVAL;
185         }
186
187         return 0;
188 }
189
190 static struct s3c_audio_pdata s3c_pcm_pdata = {
191         .cfg_gpio = exynos4_pcm_cfg_gpio,
192 };
193
194 static struct resource exynos4_pcm0_resource[] = {
195         [0] = {
196                 .start  = EXYNOS4_PA_PCM0,
197                 .end    = EXYNOS4_PA_PCM0 + 0x100 - 1,
198                 .flags  = IORESOURCE_MEM,
199         },
200         [1] = {
201                 .start  = DMACH_PCM0_TX,
202                 .end    = DMACH_PCM0_TX,
203                 .flags  = IORESOURCE_DMA,
204         },
205         [2] = {
206                 .start  = DMACH_PCM0_RX,
207                 .end    = DMACH_PCM0_RX,
208                 .flags  = IORESOURCE_DMA,
209         },
210 };
211
212 struct platform_device exynos4_device_pcm0 = {
213         .name = "samsung-pcm",
214         .id = 0,
215         .num_resources = ARRAY_SIZE(exynos4_pcm0_resource),
216         .resource = exynos4_pcm0_resource,
217         .dev = {
218                 .platform_data = &s3c_pcm_pdata,
219         },
220 };
221
222 static struct resource exynos4_pcm1_resource[] = {
223         [0] = {
224                 .start  = EXYNOS4_PA_PCM1,
225                 .end    = EXYNOS4_PA_PCM1 + 0x100 - 1,
226                 .flags  = IORESOURCE_MEM,
227         },
228         [1] = {
229                 .start  = DMACH_PCM1_TX,
230                 .end    = DMACH_PCM1_TX,
231                 .flags  = IORESOURCE_DMA,
232         },
233         [2] = {
234                 .start  = DMACH_PCM1_RX,
235                 .end    = DMACH_PCM1_RX,
236                 .flags  = IORESOURCE_DMA,
237         },
238 };
239
240 struct platform_device exynos4_device_pcm1 = {
241         .name = "samsung-pcm",
242         .id = 1,
243         .num_resources = ARRAY_SIZE(exynos4_pcm1_resource),
244         .resource = exynos4_pcm1_resource,
245         .dev = {
246                 .platform_data = &s3c_pcm_pdata,
247         },
248 };
249
250 static struct resource exynos4_pcm2_resource[] = {
251         [0] = {
252                 .start  = EXYNOS4_PA_PCM2,
253                 .end    = EXYNOS4_PA_PCM2 + 0x100 - 1,
254                 .flags  = IORESOURCE_MEM,
255         },
256         [1] = {
257                 .start  = DMACH_PCM2_TX,
258                 .end    = DMACH_PCM2_TX,
259                 .flags  = IORESOURCE_DMA,
260         },
261         [2] = {
262                 .start  = DMACH_PCM2_RX,
263                 .end    = DMACH_PCM2_RX,
264                 .flags  = IORESOURCE_DMA,
265         },
266 };
267
268 struct platform_device exynos4_device_pcm2 = {
269         .name = "samsung-pcm",
270         .id = 2,
271         .num_resources = ARRAY_SIZE(exynos4_pcm2_resource),
272         .resource = exynos4_pcm2_resource,
273         .dev = {
274                 .platform_data = &s3c_pcm_pdata,
275         },
276 };
277
278 /* AC97 Controller platform devices */
279
280 static int exynos4_ac97_cfg_gpio(struct platform_device *pdev)
281 {
282         return s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(4));
283 }
284
285 static struct resource exynos4_ac97_resource[] = {
286         [0] = {
287                 .start  = EXYNOS4_PA_AC97,
288                 .end    = EXYNOS4_PA_AC97 + 0x100 - 1,
289                 .flags  = IORESOURCE_MEM,
290         },
291         [1] = {
292                 .start  = DMACH_AC97_PCMOUT,
293                 .end    = DMACH_AC97_PCMOUT,
294                 .flags  = IORESOURCE_DMA,
295         },
296         [2] = {
297                 .start  = DMACH_AC97_PCMIN,
298                 .end    = DMACH_AC97_PCMIN,
299                 .flags  = IORESOURCE_DMA,
300         },
301         [3] = {
302                 .start  = DMACH_AC97_MICIN,
303                 .end    = DMACH_AC97_MICIN,
304                 .flags  = IORESOURCE_DMA,
305         },
306         [4] = {
307                 .start  = IRQ_AC97,
308                 .end    = IRQ_AC97,
309                 .flags  = IORESOURCE_IRQ,
310         },
311 };
312
313 static struct s3c_audio_pdata s3c_ac97_pdata = {
314         .cfg_gpio = exynos4_ac97_cfg_gpio,
315 };
316
317 static u64 exynos4_ac97_dmamask = DMA_BIT_MASK(32);
318
319 struct platform_device exynos4_device_ac97 = {
320         .name = "samsung-ac97",
321         .id = -1,
322         .num_resources = ARRAY_SIZE(exynos4_ac97_resource),
323         .resource = exynos4_ac97_resource,
324         .dev = {
325                 .platform_data = &s3c_ac97_pdata,
326                 .dma_mask = &exynos4_ac97_dmamask,
327                 .coherent_dma_mask = DMA_BIT_MASK(32),
328         },
329 };
330
331 /* S/PDIF Controller platform_device */
332
333 static int exynos4_spdif_cfg_gpio(struct platform_device *pdev)
334 {
335         s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 2, S3C_GPIO_SFN(4));
336
337         return 0;
338 }
339
340 static struct resource exynos4_spdif_resource[] = {
341         [0] = {
342                 .start  = EXYNOS4_PA_SPDIF,
343                 .end    = EXYNOS4_PA_SPDIF + 0x100 - 1,
344                 .flags  = IORESOURCE_MEM,
345         },
346         [1] = {
347                 .start  = DMACH_SPDIF,
348                 .end    = DMACH_SPDIF,
349                 .flags  = IORESOURCE_DMA,
350         },
351 };
352
353 static struct s3c_audio_pdata samsung_spdif_pdata = {
354         .cfg_gpio = exynos4_spdif_cfg_gpio,
355 };
356
357 static u64 exynos4_spdif_dmamask = DMA_BIT_MASK(32);
358
359 struct platform_device exynos4_device_spdif = {
360         .name = "samsung-spdif",
361         .id = -1,
362         .num_resources = ARRAY_SIZE(exynos4_spdif_resource),
363         .resource = exynos4_spdif_resource,
364         .dev = {
365                 .platform_data = &samsung_spdif_pdata,
366                 .dma_mask = &exynos4_spdif_dmamask,
367                 .coherent_dma_mask = DMA_BIT_MASK(32),
368         },
369 };