Merge branch 'exynos-drm-next' of git://git.infradead.org/users/kmpark/linux-samsung...
[cascardo/linux.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 <linux/platform_data/asoc-s3c.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] = DEFINE_RES_MEM(EXYNOS4_PA_I2S0, SZ_256),
66         [1] = DEFINE_RES_DMA(DMACH_I2S0_TX),
67         [2] = DEFINE_RES_DMA(DMACH_I2S0_RX),
68         [3] = DEFINE_RES_DMA(DMACH_I2S0S_TX),
69 };
70
71 struct platform_device exynos4_device_i2s0 = {
72         .name = "samsung-i2s",
73         .id = 0,
74         .num_resources = ARRAY_SIZE(exynos4_i2s0_resource),
75         .resource = exynos4_i2s0_resource,
76         .dev = {
77                 .platform_data = &i2sv5_pdata,
78         },
79 };
80
81 static const char *rclksrc_v3[] = {
82         [0] = "sclk_i2s",
83         [1] = "no_such_clock",
84 };
85
86 static struct s3c_audio_pdata i2sv3_pdata = {
87         .cfg_gpio = exynos4_cfg_i2s,
88         .type = {
89                 .i2s = {
90                         .quirks = QUIRK_NO_MUXPSR,
91                         .src_clk = rclksrc_v3,
92                 },
93         },
94 };
95
96 static struct resource exynos4_i2s1_resource[] = {
97         [0] = DEFINE_RES_MEM(EXYNOS4_PA_I2S1, SZ_256),
98         [1] = DEFINE_RES_DMA(DMACH_I2S1_TX),
99         [2] = DEFINE_RES_DMA(DMACH_I2S1_RX),
100 };
101
102 struct platform_device exynos4_device_i2s1 = {
103         .name = "samsung-i2s",
104         .id = 1,
105         .num_resources = ARRAY_SIZE(exynos4_i2s1_resource),
106         .resource = exynos4_i2s1_resource,
107         .dev = {
108                 .platform_data = &i2sv3_pdata,
109         },
110 };
111
112 static struct resource exynos4_i2s2_resource[] = {
113         [0] = DEFINE_RES_MEM(EXYNOS4_PA_I2S2, SZ_256),
114         [1] = DEFINE_RES_DMA(DMACH_I2S2_TX),
115         [2] = DEFINE_RES_DMA(DMACH_I2S2_RX),
116 };
117
118 struct platform_device exynos4_device_i2s2 = {
119         .name = "samsung-i2s",
120         .id = 2,
121         .num_resources = ARRAY_SIZE(exynos4_i2s2_resource),
122         .resource = exynos4_i2s2_resource,
123         .dev = {
124                 .platform_data = &i2sv3_pdata,
125         },
126 };
127
128 /* PCM Controller platform_devices */
129
130 static int exynos4_pcm_cfg_gpio(struct platform_device *pdev)
131 {
132         switch (pdev->id) {
133         case 0:
134                 s3c_gpio_cfgpin_range(EXYNOS4_GPZ(0), 5, S3C_GPIO_SFN(3));
135                 break;
136         case 1:
137                 s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(3));
138                 break;
139         case 2:
140                 s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 5, S3C_GPIO_SFN(3));
141                 break;
142         default:
143                 printk(KERN_DEBUG "Invalid PCM Controller number!");
144                 return -EINVAL;
145         }
146
147         return 0;
148 }
149
150 static struct s3c_audio_pdata s3c_pcm_pdata = {
151         .cfg_gpio = exynos4_pcm_cfg_gpio,
152 };
153
154 static struct resource exynos4_pcm0_resource[] = {
155         [0] = DEFINE_RES_MEM(EXYNOS4_PA_PCM0, SZ_256),
156         [1] = DEFINE_RES_DMA(DMACH_PCM0_TX),
157         [2] = DEFINE_RES_DMA(DMACH_PCM0_RX),
158 };
159
160 struct platform_device exynos4_device_pcm0 = {
161         .name = "samsung-pcm",
162         .id = 0,
163         .num_resources = ARRAY_SIZE(exynos4_pcm0_resource),
164         .resource = exynos4_pcm0_resource,
165         .dev = {
166                 .platform_data = &s3c_pcm_pdata,
167         },
168 };
169
170 static struct resource exynos4_pcm1_resource[] = {
171         [0] = DEFINE_RES_MEM(EXYNOS4_PA_PCM1, SZ_256),
172         [1] = DEFINE_RES_DMA(DMACH_PCM1_TX),
173         [2] = DEFINE_RES_DMA(DMACH_PCM1_RX),
174 };
175
176 struct platform_device exynos4_device_pcm1 = {
177         .name = "samsung-pcm",
178         .id = 1,
179         .num_resources = ARRAY_SIZE(exynos4_pcm1_resource),
180         .resource = exynos4_pcm1_resource,
181         .dev = {
182                 .platform_data = &s3c_pcm_pdata,
183         },
184 };
185
186 static struct resource exynos4_pcm2_resource[] = {
187         [0] = DEFINE_RES_MEM(EXYNOS4_PA_PCM2, SZ_256),
188         [1] = DEFINE_RES_DMA(DMACH_PCM2_TX),
189         [2] = DEFINE_RES_DMA(DMACH_PCM2_RX),
190 };
191
192 struct platform_device exynos4_device_pcm2 = {
193         .name = "samsung-pcm",
194         .id = 2,
195         .num_resources = ARRAY_SIZE(exynos4_pcm2_resource),
196         .resource = exynos4_pcm2_resource,
197         .dev = {
198                 .platform_data = &s3c_pcm_pdata,
199         },
200 };
201
202 /* AC97 Controller platform devices */
203
204 static int exynos4_ac97_cfg_gpio(struct platform_device *pdev)
205 {
206         return s3c_gpio_cfgpin_range(EXYNOS4_GPC0(0), 5, S3C_GPIO_SFN(4));
207 }
208
209 static struct resource exynos4_ac97_resource[] = {
210         [0] = DEFINE_RES_MEM(EXYNOS4_PA_AC97, SZ_256),
211         [1] = DEFINE_RES_DMA(DMACH_AC97_PCMOUT),
212         [2] = DEFINE_RES_DMA(DMACH_AC97_PCMIN),
213         [3] = DEFINE_RES_DMA(DMACH_AC97_MICIN),
214         [4] = DEFINE_RES_IRQ(EXYNOS4_IRQ_AC97),
215 };
216
217 static struct s3c_audio_pdata s3c_ac97_pdata = {
218         .cfg_gpio = exynos4_ac97_cfg_gpio,
219 };
220
221 static u64 exynos4_ac97_dmamask = DMA_BIT_MASK(32);
222
223 struct platform_device exynos4_device_ac97 = {
224         .name = "samsung-ac97",
225         .id = -1,
226         .num_resources = ARRAY_SIZE(exynos4_ac97_resource),
227         .resource = exynos4_ac97_resource,
228         .dev = {
229                 .platform_data = &s3c_ac97_pdata,
230                 .dma_mask = &exynos4_ac97_dmamask,
231                 .coherent_dma_mask = DMA_BIT_MASK(32),
232         },
233 };
234
235 /* S/PDIF Controller platform_device */
236
237 static int exynos4_spdif_cfg_gpio(struct platform_device *pdev)
238 {
239         s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 2, S3C_GPIO_SFN(4));
240
241         return 0;
242 }
243
244 static struct resource exynos4_spdif_resource[] = {
245         [0] = DEFINE_RES_MEM(EXYNOS4_PA_SPDIF, SZ_256),
246         [1] = DEFINE_RES_DMA(DMACH_SPDIF),
247 };
248
249 static struct s3c_audio_pdata samsung_spdif_pdata = {
250         .cfg_gpio = exynos4_spdif_cfg_gpio,
251 };
252
253 static u64 exynos4_spdif_dmamask = DMA_BIT_MASK(32);
254
255 struct platform_device exynos4_device_spdif = {
256         .name = "samsung-spdif",
257         .id = -1,
258         .num_resources = ARRAY_SIZE(exynos4_spdif_resource),
259         .resource = exynos4_spdif_resource,
260         .dev = {
261                 .platform_data = &samsung_spdif_pdata,
262                 .dma_mask = &exynos4_spdif_dmamask,
263                 .coherent_dma_mask = DMA_BIT_MASK(32),
264         },
265 };