Merge branch 'master' into upstream
[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: %d\n",
38                         pdev->id);
39                 return -EINVAL;
40         }
41
42         s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3));
43
44         return 0;
45 }
46
47 static int s3c64xx_i2sv4_cfg_gpio(struct platform_device *pdev)
48 {
49         s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5));
50         s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5));
51         s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5));
52         s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5));
53
54         return 0;
55 }
56
57 static struct resource s3c64xx_iis0_resource[] = {
58         [0] = {
59                 .start = S3C64XX_PA_IIS0,
60                 .end   = S3C64XX_PA_IIS0 + 0x100 - 1,
61                 .flags = IORESOURCE_MEM,
62         },
63         [1] = {
64                 .start = DMACH_I2S0_OUT,
65                 .end   = DMACH_I2S0_OUT,
66                 .flags = IORESOURCE_DMA,
67         },
68         [2] = {
69                 .start = DMACH_I2S0_IN,
70                 .end   = DMACH_I2S0_IN,
71                 .flags = IORESOURCE_DMA,
72         },
73 };
74
75 static struct s3c_audio_pdata s3c_i2s0_pdata = {
76         .cfg_gpio = s3c64xx_i2sv3_cfg_gpio,
77 };
78
79 struct platform_device s3c64xx_device_iis0 = {
80         .name             = "s3c64xx-iis",
81         .id               = 0,
82         .num_resources    = ARRAY_SIZE(s3c64xx_iis0_resource),
83         .resource         = s3c64xx_iis0_resource,
84         .dev = {
85                 .platform_data = &s3c_i2s0_pdata,
86         },
87 };
88 EXPORT_SYMBOL(s3c64xx_device_iis0);
89
90 static struct resource s3c64xx_iis1_resource[] = {
91         [0] = {
92                 .start = S3C64XX_PA_IIS1,
93                 .end   = S3C64XX_PA_IIS1 + 0x100 - 1,
94                 .flags = IORESOURCE_MEM,
95         },
96         [1] = {
97                 .start = DMACH_I2S1_OUT,
98                 .end   = DMACH_I2S1_OUT,
99                 .flags = IORESOURCE_DMA,
100         },
101         [2] = {
102                 .start = DMACH_I2S1_IN,
103                 .end   = DMACH_I2S1_IN,
104                 .flags = IORESOURCE_DMA,
105         },
106 };
107
108 static struct s3c_audio_pdata s3c_i2s1_pdata = {
109         .cfg_gpio = s3c64xx_i2sv3_cfg_gpio,
110 };
111
112 struct platform_device s3c64xx_device_iis1 = {
113         .name             = "s3c64xx-iis",
114         .id               = 1,
115         .num_resources    = ARRAY_SIZE(s3c64xx_iis1_resource),
116         .resource         = s3c64xx_iis1_resource,
117         .dev = {
118                 .platform_data = &s3c_i2s1_pdata,
119         },
120 };
121 EXPORT_SYMBOL(s3c64xx_device_iis1);
122
123 static struct resource s3c64xx_iisv4_resource[] = {
124         [0] = {
125                 .start = S3C64XX_PA_IISV4,
126                 .end   = S3C64XX_PA_IISV4 + 0x100 - 1,
127                 .flags = IORESOURCE_MEM,
128         },
129         [1] = {
130                 .start = DMACH_HSI_I2SV40_TX,
131                 .end   = DMACH_HSI_I2SV40_TX,
132                 .flags = IORESOURCE_DMA,
133         },
134         [2] = {
135                 .start = DMACH_HSI_I2SV40_RX,
136                 .end   = DMACH_HSI_I2SV40_RX,
137                 .flags = IORESOURCE_DMA,
138         },
139 };
140
141 static struct s3c_audio_pdata s3c_i2sv4_pdata = {
142         .cfg_gpio = s3c64xx_i2sv4_cfg_gpio,
143 };
144
145 struct platform_device s3c64xx_device_iisv4 = {
146         .name             = "s3c64xx-iis-v4",
147         .id               = -1,
148         .num_resources    = ARRAY_SIZE(s3c64xx_iisv4_resource),
149         .resource         = s3c64xx_iisv4_resource,
150         .dev = {
151                 .platform_data = &s3c_i2sv4_pdata,
152         },
153 };
154 EXPORT_SYMBOL(s3c64xx_device_iisv4);
155
156
157 /* PCM Controller platform_devices */
158
159 static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
160 {
161         unsigned int base;
162
163         switch (pdev->id) {
164         case 0:
165                 base = S3C64XX_GPD(0);
166                 break;
167         case 1:
168                 base = S3C64XX_GPE(0);
169                 break;
170         default:
171                 printk(KERN_DEBUG "Invalid PCM Controller number: %d\n",
172                         pdev->id);
173                 return -EINVAL;
174         }
175
176         s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2));
177         return 0;
178 }
179
180 static struct resource s3c64xx_pcm0_resource[] = {
181         [0] = {
182                 .start = S3C64XX_PA_PCM0,
183                 .end   = S3C64XX_PA_PCM0 + 0x100 - 1,
184                 .flags = IORESOURCE_MEM,
185         },
186         [1] = {
187                 .start = DMACH_PCM0_TX,
188                 .end   = DMACH_PCM0_TX,
189                 .flags = IORESOURCE_DMA,
190         },
191         [2] = {
192                 .start = DMACH_PCM0_RX,
193                 .end   = DMACH_PCM0_RX,
194                 .flags = IORESOURCE_DMA,
195         },
196 };
197
198 static struct s3c_audio_pdata s3c_pcm0_pdata = {
199         .cfg_gpio = s3c64xx_pcm_cfg_gpio,
200 };
201
202 struct platform_device s3c64xx_device_pcm0 = {
203         .name             = "samsung-pcm",
204         .id               = 0,
205         .num_resources    = ARRAY_SIZE(s3c64xx_pcm0_resource),
206         .resource         = s3c64xx_pcm0_resource,
207         .dev = {
208                 .platform_data = &s3c_pcm0_pdata,
209         },
210 };
211 EXPORT_SYMBOL(s3c64xx_device_pcm0);
212
213 static struct resource s3c64xx_pcm1_resource[] = {
214         [0] = {
215                 .start = S3C64XX_PA_PCM1,
216                 .end   = S3C64XX_PA_PCM1 + 0x100 - 1,
217                 .flags = IORESOURCE_MEM,
218         },
219         [1] = {
220                 .start = DMACH_PCM1_TX,
221                 .end   = DMACH_PCM1_TX,
222                 .flags = IORESOURCE_DMA,
223         },
224         [2] = {
225                 .start = DMACH_PCM1_RX,
226                 .end   = DMACH_PCM1_RX,
227                 .flags = IORESOURCE_DMA,
228         },
229 };
230
231 static struct s3c_audio_pdata s3c_pcm1_pdata = {
232         .cfg_gpio = s3c64xx_pcm_cfg_gpio,
233 };
234
235 struct platform_device s3c64xx_device_pcm1 = {
236         .name             = "samsung-pcm",
237         .id               = 1,
238         .num_resources    = ARRAY_SIZE(s3c64xx_pcm1_resource),
239         .resource         = s3c64xx_pcm1_resource,
240         .dev = {
241                 .platform_data = &s3c_pcm1_pdata,
242         },
243 };
244 EXPORT_SYMBOL(s3c64xx_device_pcm1);
245
246 /* AC97 Controller platform devices */
247
248 static int s3c64xx_ac97_cfg_gpd(struct platform_device *pdev)
249 {
250         return s3c_gpio_cfgpin_range(S3C64XX_GPD(0), 5, S3C_GPIO_SFN(4));
251 }
252
253 static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev)
254 {
255         return s3c_gpio_cfgpin_range(S3C64XX_GPE(0), 5, S3C_GPIO_SFN(4));
256 }
257
258 static struct resource s3c64xx_ac97_resource[] = {
259         [0] = {
260                 .start = S3C64XX_PA_AC97,
261                 .end   = S3C64XX_PA_AC97 + 0x100 - 1,
262                 .flags = IORESOURCE_MEM,
263         },
264         [1] = {
265                 .start = DMACH_AC97_PCMOUT,
266                 .end   = DMACH_AC97_PCMOUT,
267                 .flags = IORESOURCE_DMA,
268         },
269         [2] = {
270                 .start = DMACH_AC97_PCMIN,
271                 .end   = DMACH_AC97_PCMIN,
272                 .flags = IORESOURCE_DMA,
273         },
274         [3] = {
275                 .start = DMACH_AC97_MICIN,
276                 .end   = DMACH_AC97_MICIN,
277                 .flags = IORESOURCE_DMA,
278         },
279         [4] = {
280                 .start = IRQ_AC97,
281                 .end   = IRQ_AC97,
282                 .flags = IORESOURCE_IRQ,
283         },
284 };
285
286 static struct s3c_audio_pdata s3c_ac97_pdata;
287
288 static u64 s3c64xx_ac97_dmamask = DMA_BIT_MASK(32);
289
290 struct platform_device s3c64xx_device_ac97 = {
291         .name             = "s3c-ac97",
292         .id               = -1,
293         .num_resources    = ARRAY_SIZE(s3c64xx_ac97_resource),
294         .resource         = s3c64xx_ac97_resource,
295         .dev = {
296                 .platform_data = &s3c_ac97_pdata,
297                 .dma_mask = &s3c64xx_ac97_dmamask,
298                 .coherent_dma_mask = DMA_BIT_MASK(32),
299         },
300 };
301 EXPORT_SYMBOL(s3c64xx_device_ac97);
302
303 void __init s3c64xx_ac97_setup_gpio(int num)
304 {
305         if (num == S3C64XX_AC97_GPD)
306                 s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpd;
307         else
308                 s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpe;
309 }
310
311 static u64 s3c_device_audio_dmamask = 0xffffffffUL;
312
313 struct platform_device s3c_device_pcm = {
314         .name             = "s3c24xx-pcm-audio",
315         .id               = -1,
316         .dev              = {
317                 .dma_mask = &s3c_device_audio_dmamask,
318                 .coherent_dma_mask = 0xffffffffUL
319         }
320 };
321 EXPORT_SYMBOL(s3c_device_pcm);
322