Merge branch 'next-s3c64xx' into for-next
[pandora-kernel.git] / arch / arm / mach-s3c64xx / dev-audio.c
1 /* linux/arch/arm/plat-s3c/dev-audio.c
2  *
3  * Copyright 2009 Wolfson Microelectronics
4  *      Mark Brown <broonie@opensource.wolfsonmicro.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10
11 #include <linux/kernel.h>
12 #include <linux/string.h>
13 #include <linux/platform_device.h>
14 #include <linux/dma-mapping.h>
15 #include <linux/gpio.h>
16
17 #include <mach/irqs.h>
18 #include <mach/map.h>
19 #include <mach/dma.h>
20
21 #include <plat/devs.h>
22 #include <plat/audio.h>
23 #include <plat/gpio-cfg.h>
24
25 static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev)
26 {
27         unsigned int base;
28
29         switch (pdev->id) {
30         case 0:
31                 base = S3C64XX_GPD(0);
32                 break;
33         case 1:
34                 base = S3C64XX_GPE(0);
35                 break;
36         default:
37                 printk(KERN_DEBUG "Invalid I2S Controller number!");
38                 return -EINVAL;
39         }
40
41         s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3));
42
43         return 0;
44 }
45
46 static int s3c64xx_i2sv4_cfg_gpio(struct platform_device *pdev)
47 {
48         s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5));
49         s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5));
50         s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5));
51         s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5));
52
53         return 0;
54 }
55
56 static struct resource s3c64xx_iis0_resource[] = {
57         [0] = {
58                 .start = S3C64XX_PA_IIS0,
59                 .end   = S3C64XX_PA_IIS0 + 0x100 - 1,
60                 .flags = IORESOURCE_MEM,
61         },
62         [1] = {
63                 .start = DMACH_I2S0_OUT,
64                 .end   = DMACH_I2S0_OUT,
65                 .flags = IORESOURCE_DMA,
66         },
67         [2] = {
68                 .start = DMACH_I2S0_IN,
69                 .end   = DMACH_I2S0_IN,
70                 .flags = IORESOURCE_DMA,
71         },
72 };
73
74 static struct s3c_audio_pdata s3c_i2s0_pdata = {
75         .cfg_gpio = s3c64xx_i2sv3_cfg_gpio,
76 };
77
78 struct platform_device s3c64xx_device_iis0 = {
79         .name             = "s3c64xx-iis",
80         .id               = 0,
81         .num_resources    = ARRAY_SIZE(s3c64xx_iis0_resource),
82         .resource         = s3c64xx_iis0_resource,
83         .dev = {
84                 .platform_data = &s3c_i2s0_pdata,
85         },
86 };
87 EXPORT_SYMBOL(s3c64xx_device_iis0);
88
89 static struct resource s3c64xx_iis1_resource[] = {
90         [0] = {
91                 .start = S3C64XX_PA_IIS1,
92                 .end   = S3C64XX_PA_IIS1 + 0x100 - 1,
93                 .flags = IORESOURCE_MEM,
94         },
95         [1] = {
96                 .start = DMACH_I2S1_OUT,
97                 .end   = DMACH_I2S1_OUT,
98                 .flags = IORESOURCE_DMA,
99         },
100         [2] = {
101                 .start = DMACH_I2S1_IN,
102                 .end   = DMACH_I2S1_IN,
103                 .flags = IORESOURCE_DMA,
104         },
105 };
106
107 static struct s3c_audio_pdata s3c_i2s1_pdata = {
108         .cfg_gpio = s3c64xx_i2sv3_cfg_gpio,
109 };
110
111 struct platform_device s3c64xx_device_iis1 = {
112         .name             = "s3c64xx-iis",
113         .id               = 1,
114         .num_resources    = ARRAY_SIZE(s3c64xx_iis1_resource),
115         .resource         = s3c64xx_iis1_resource,
116         .dev = {
117                 .platform_data = &s3c_i2s1_pdata,
118         },
119 };
120 EXPORT_SYMBOL(s3c64xx_device_iis1);
121
122 static struct resource s3c64xx_iisv4_resource[] = {
123         [0] = {
124                 .start = S3C64XX_PA_IISV4,
125                 .end   = S3C64XX_PA_IISV4 + 0x100 - 1,
126                 .flags = IORESOURCE_MEM,
127         },
128         [1] = {
129                 .start = DMACH_HSI_I2SV40_TX,
130                 .end   = DMACH_HSI_I2SV40_TX,
131                 .flags = IORESOURCE_DMA,
132         },
133         [2] = {
134                 .start = DMACH_HSI_I2SV40_RX,
135                 .end   = DMACH_HSI_I2SV40_RX,
136                 .flags = IORESOURCE_DMA,
137         },
138 };
139
140 static struct s3c_audio_pdata s3c_i2sv4_pdata = {
141         .cfg_gpio = s3c64xx_i2sv4_cfg_gpio,
142 };
143
144 struct platform_device s3c64xx_device_iisv4 = {
145         .name             = "s3c64xx-iis-v4",
146         .id               = -1,
147         .num_resources    = ARRAY_SIZE(s3c64xx_iisv4_resource),
148         .resource         = s3c64xx_iisv4_resource,
149         .dev = {
150                 .platform_data = &s3c_i2sv4_pdata,
151         },
152 };
153 EXPORT_SYMBOL(s3c64xx_device_iisv4);
154
155
156 /* PCM Controller platform_devices */
157
158 static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
159 {
160         unsigned int base;
161
162         switch (pdev->id) {
163         case 0:
164                 base = S3C64XX_GPD(0);
165                 break;
166         case 1:
167                 base = S3C64XX_GPE(0);
168                 break;
169         default:
170                 printk(KERN_DEBUG "Invalid PCM Controller number!");
171                 return -EINVAL;
172         }
173
174         s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2));
175         return 0;
176 }
177
178 static struct resource s3c64xx_pcm0_resource[] = {
179         [0] = {
180                 .start = S3C64XX_PA_PCM0,
181                 .end   = S3C64XX_PA_PCM0 + 0x100 - 1,
182                 .flags = IORESOURCE_MEM,
183         },
184         [1] = {
185                 .start = DMACH_PCM0_TX,
186                 .end   = DMACH_PCM0_TX,
187                 .flags = IORESOURCE_DMA,
188         },
189         [2] = {
190                 .start = DMACH_PCM0_RX,
191                 .end   = DMACH_PCM0_RX,
192                 .flags = IORESOURCE_DMA,
193         },
194 };
195
196 static struct s3c_audio_pdata s3c_pcm0_pdata = {
197         .cfg_gpio = s3c64xx_pcm_cfg_gpio,
198 };
199
200 struct platform_device s3c64xx_device_pcm0 = {
201         .name             = "samsung-pcm",
202         .id               = 0,
203         .num_resources    = ARRAY_SIZE(s3c64xx_pcm0_resource),
204         .resource         = s3c64xx_pcm0_resource,
205         .dev = {
206                 .platform_data = &s3c_pcm0_pdata,
207         },
208 };
209 EXPORT_SYMBOL(s3c64xx_device_pcm0);
210
211 static struct resource s3c64xx_pcm1_resource[] = {
212         [0] = {
213                 .start = S3C64XX_PA_PCM1,
214                 .end   = S3C64XX_PA_PCM1 + 0x100 - 1,
215                 .flags = IORESOURCE_MEM,
216         },
217         [1] = {
218                 .start = DMACH_PCM1_TX,
219                 .end   = DMACH_PCM1_TX,
220                 .flags = IORESOURCE_DMA,
221         },
222         [2] = {
223                 .start = DMACH_PCM1_RX,
224                 .end   = DMACH_PCM1_RX,
225                 .flags = IORESOURCE_DMA,
226         },
227 };
228
229 static struct s3c_audio_pdata s3c_pcm1_pdata = {
230         .cfg_gpio = s3c64xx_pcm_cfg_gpio,
231 };
232
233 struct platform_device s3c64xx_device_pcm1 = {
234         .name             = "samsung-pcm",
235         .id               = 1,
236         .num_resources    = ARRAY_SIZE(s3c64xx_pcm1_resource),
237         .resource         = s3c64xx_pcm1_resource,
238         .dev = {
239                 .platform_data = &s3c_pcm1_pdata,
240         },
241 };
242 EXPORT_SYMBOL(s3c64xx_device_pcm1);
243
244 /* AC97 Controller platform devices */
245
246 static int s3c64xx_ac97_cfg_gpd(struct platform_device *pdev)
247 {
248         return s3c_gpio_cfgpin_range(S3C64XX_GPD(0), 5, S3C_GPIO_SFN(4));
249 }
250
251 static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev)
252 {
253         return s3c_gpio_cfgpin_range(S3C64XX_GPE(0), 5, S3C_GPIO_SFN(4));
254 }
255
256 static struct resource s3c64xx_ac97_resource[] = {
257         [0] = {
258                 .start = S3C64XX_PA_AC97,
259                 .end   = S3C64XX_PA_AC97 + 0x100 - 1,
260                 .flags = IORESOURCE_MEM,
261         },
262         [1] = {
263                 .start = DMACH_AC97_PCMOUT,
264                 .end   = DMACH_AC97_PCMOUT,
265                 .flags = IORESOURCE_DMA,
266         },
267         [2] = {
268                 .start = DMACH_AC97_PCMIN,
269                 .end   = DMACH_AC97_PCMIN,
270                 .flags = IORESOURCE_DMA,
271         },
272         [3] = {
273                 .start = DMACH_AC97_MICIN,
274                 .end   = DMACH_AC97_MICIN,
275                 .flags = IORESOURCE_DMA,
276         },
277         [4] = {
278                 .start = IRQ_AC97,
279                 .end   = IRQ_AC97,
280                 .flags = IORESOURCE_IRQ,
281         },
282 };
283
284 static struct s3c_audio_pdata s3c_ac97_pdata;
285
286 static u64 s3c64xx_ac97_dmamask = DMA_BIT_MASK(32);
287
288 struct platform_device s3c64xx_device_ac97 = {
289         .name             = "s3c-ac97",
290         .id               = -1,
291         .num_resources    = ARRAY_SIZE(s3c64xx_ac97_resource),
292         .resource         = s3c64xx_ac97_resource,
293         .dev = {
294                 .platform_data = &s3c_ac97_pdata,
295                 .dma_mask = &s3c64xx_ac97_dmamask,
296                 .coherent_dma_mask = DMA_BIT_MASK(32),
297         },
298 };
299 EXPORT_SYMBOL(s3c64xx_device_ac97);
300
301 void __init s3c64xx_ac97_setup_gpio(int num)
302 {
303         if (num == S3C64XX_AC97_GPD)
304                 s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpd;
305         else
306                 s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpe;
307 }