1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // |
3 | // Copyright (c) 2011 Samsung Electronics Co., Ltd. |
4 | // http://www.samsung.com |
5 | // |
6 | // Base Samsung platform device definitions |
7 | |
8 | #include <linux/gpio.h> |
9 | #include <linux/kernel.h> |
10 | #include <linux/types.h> |
11 | #include <linux/interrupt.h> |
12 | #include <linux/list.h> |
13 | #include <linux/timer.h> |
14 | #include <linux/init.h> |
15 | #include <linux/serial_core.h> |
16 | #include <linux/serial_s3c.h> |
17 | #include <linux/platform_device.h> |
18 | #include <linux/io.h> |
19 | #include <linux/slab.h> |
20 | #include <linux/string.h> |
21 | #include <linux/dma-mapping.h> |
22 | #include <linux/fb.h> |
23 | #include <linux/gfp.h> |
24 | #include <linux/mmc/host.h> |
25 | #include <linux/ioport.h> |
26 | #include <linux/sizes.h> |
27 | #include <linux/platform_data/s3c-hsotg.h> |
28 | |
29 | #include <asm/irq.h> |
30 | #include <asm/mach/arch.h> |
31 | #include <asm/mach/map.h> |
32 | #include <asm/mach/irq.h> |
33 | |
34 | #include "irqs.h" |
35 | #include "map.h" |
36 | #include "gpio-samsung.h" |
37 | #include "gpio-cfg.h" |
38 | |
39 | #include "cpu.h" |
40 | #include "devs.h" |
41 | #include "fb.h" |
42 | #include <linux/platform_data/i2c-s3c2410.h> |
43 | #include "keypad.h" |
44 | #include "pwm-core.h" |
45 | #include "sdhci.h" |
46 | #include "usb-phy.h" |
47 | #include <linux/platform_data/asoc-s3c.h> |
48 | #include <linux/platform_data/spi-s3c64xx.h> |
49 | |
50 | #define samsung_device_dma_mask (*((u64[]) { DMA_BIT_MASK(32) })) |
51 | |
52 | /* FB */ |
53 | |
54 | #ifdef CONFIG_S3C_DEV_FB |
55 | static struct resource s3c_fb_resource[] = { |
56 | [0] = DEFINE_RES_MEM(S3C_PA_FB, SZ_16K), |
57 | [1] = DEFINE_RES_IRQ(IRQ_LCD_VSYNC), |
58 | [2] = DEFINE_RES_IRQ(IRQ_LCD_FIFO), |
59 | [3] = DEFINE_RES_IRQ(IRQ_LCD_SYSTEM), |
60 | }; |
61 | |
62 | struct platform_device s3c_device_fb = { |
63 | .name = "s3c-fb" , |
64 | .id = -1, |
65 | .num_resources = ARRAY_SIZE(s3c_fb_resource), |
66 | .resource = s3c_fb_resource, |
67 | .dev = { |
68 | .dma_mask = &samsung_device_dma_mask, |
69 | .coherent_dma_mask = DMA_BIT_MASK(32), |
70 | }, |
71 | }; |
72 | |
73 | void __init s3c_fb_set_platdata(struct s3c_fb_platdata *pd) |
74 | { |
75 | s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata), |
76 | &s3c_device_fb); |
77 | } |
78 | #endif /* CONFIG_S3C_DEV_FB */ |
79 | |
80 | /* HSMMC */ |
81 | |
82 | #ifdef CONFIG_S3C_DEV_HSMMC |
83 | static struct resource s3c_hsmmc_resource[] = { |
84 | [0] = DEFINE_RES_MEM(S3C_PA_HSMMC0, SZ_4K), |
85 | [1] = DEFINE_RES_IRQ(IRQ_HSMMC0), |
86 | }; |
87 | |
88 | struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = { |
89 | .max_width = 4, |
90 | .host_caps = (MMC_CAP_4_BIT_DATA | |
91 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), |
92 | }; |
93 | |
94 | struct platform_device s3c_device_hsmmc0 = { |
95 | .name = "s3c-sdhci" , |
96 | .id = 0, |
97 | .num_resources = ARRAY_SIZE(s3c_hsmmc_resource), |
98 | .resource = s3c_hsmmc_resource, |
99 | .dev = { |
100 | .dma_mask = &samsung_device_dma_mask, |
101 | .coherent_dma_mask = DMA_BIT_MASK(32), |
102 | .platform_data = &s3c_hsmmc0_def_platdata, |
103 | }, |
104 | }; |
105 | |
106 | void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd) |
107 | { |
108 | s3c_sdhci_set_platdata(pd, &s3c_hsmmc0_def_platdata); |
109 | } |
110 | #endif /* CONFIG_S3C_DEV_HSMMC */ |
111 | |
112 | #ifdef CONFIG_S3C_DEV_HSMMC1 |
113 | static struct resource s3c_hsmmc1_resource[] = { |
114 | [0] = DEFINE_RES_MEM(S3C_PA_HSMMC1, SZ_4K), |
115 | [1] = DEFINE_RES_IRQ(IRQ_HSMMC1), |
116 | }; |
117 | |
118 | struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata = { |
119 | .max_width = 4, |
120 | .host_caps = (MMC_CAP_4_BIT_DATA | |
121 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), |
122 | }; |
123 | |
124 | struct platform_device s3c_device_hsmmc1 = { |
125 | .name = "s3c-sdhci" , |
126 | .id = 1, |
127 | .num_resources = ARRAY_SIZE(s3c_hsmmc1_resource), |
128 | .resource = s3c_hsmmc1_resource, |
129 | .dev = { |
130 | .dma_mask = &samsung_device_dma_mask, |
131 | .coherent_dma_mask = DMA_BIT_MASK(32), |
132 | .platform_data = &s3c_hsmmc1_def_platdata, |
133 | }, |
134 | }; |
135 | |
136 | void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd) |
137 | { |
138 | s3c_sdhci_set_platdata(pd, &s3c_hsmmc1_def_platdata); |
139 | } |
140 | #endif /* CONFIG_S3C_DEV_HSMMC1 */ |
141 | |
142 | /* HSMMC2 */ |
143 | |
144 | #ifdef CONFIG_S3C_DEV_HSMMC2 |
145 | static struct resource s3c_hsmmc2_resource[] = { |
146 | [0] = DEFINE_RES_MEM(S3C_PA_HSMMC2, SZ_4K), |
147 | [1] = DEFINE_RES_IRQ(IRQ_HSMMC2), |
148 | }; |
149 | |
150 | struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata = { |
151 | .max_width = 4, |
152 | .host_caps = (MMC_CAP_4_BIT_DATA | |
153 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), |
154 | }; |
155 | |
156 | struct platform_device s3c_device_hsmmc2 = { |
157 | .name = "s3c-sdhci" , |
158 | .id = 2, |
159 | .num_resources = ARRAY_SIZE(s3c_hsmmc2_resource), |
160 | .resource = s3c_hsmmc2_resource, |
161 | .dev = { |
162 | .dma_mask = &samsung_device_dma_mask, |
163 | .coherent_dma_mask = DMA_BIT_MASK(32), |
164 | .platform_data = &s3c_hsmmc2_def_platdata, |
165 | }, |
166 | }; |
167 | |
168 | void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd) |
169 | { |
170 | s3c_sdhci_set_platdata(pd, &s3c_hsmmc2_def_platdata); |
171 | } |
172 | #endif /* CONFIG_S3C_DEV_HSMMC2 */ |
173 | |
174 | #ifdef CONFIG_S3C_DEV_HSMMC3 |
175 | static struct resource s3c_hsmmc3_resource[] = { |
176 | [0] = DEFINE_RES_MEM(S3C_PA_HSMMC3, SZ_4K), |
177 | [1] = DEFINE_RES_IRQ(IRQ_HSMMC3), |
178 | }; |
179 | |
180 | struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = { |
181 | .max_width = 4, |
182 | .host_caps = (MMC_CAP_4_BIT_DATA | |
183 | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), |
184 | }; |
185 | |
186 | struct platform_device s3c_device_hsmmc3 = { |
187 | .name = "s3c-sdhci" , |
188 | .id = 3, |
189 | .num_resources = ARRAY_SIZE(s3c_hsmmc3_resource), |
190 | .resource = s3c_hsmmc3_resource, |
191 | .dev = { |
192 | .dma_mask = &samsung_device_dma_mask, |
193 | .coherent_dma_mask = DMA_BIT_MASK(32), |
194 | .platform_data = &s3c_hsmmc3_def_platdata, |
195 | }, |
196 | }; |
197 | |
198 | void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd) |
199 | { |
200 | s3c_sdhci_set_platdata(pd, &s3c_hsmmc3_def_platdata); |
201 | } |
202 | #endif /* CONFIG_S3C_DEV_HSMMC3 */ |
203 | |
204 | /* I2C */ |
205 | |
206 | static struct resource s3c_i2c0_resource[] = { |
207 | [0] = DEFINE_RES_MEM(S3C_PA_IIC, SZ_4K), |
208 | [1] = DEFINE_RES_IRQ(IRQ_IIC), |
209 | }; |
210 | |
211 | struct platform_device s3c_device_i2c0 = { |
212 | .name = "s3c2410-i2c" , |
213 | .id = 0, |
214 | .num_resources = ARRAY_SIZE(s3c_i2c0_resource), |
215 | .resource = s3c_i2c0_resource, |
216 | }; |
217 | |
218 | struct s3c2410_platform_i2c default_i2c_data __initdata = { |
219 | .flags = 0, |
220 | .slave_addr = 0x10, |
221 | .frequency = 100*1000, |
222 | .sda_delay = 100, |
223 | }; |
224 | |
225 | void __init s3c_i2c0_set_platdata(struct s3c2410_platform_i2c *pd) |
226 | { |
227 | struct s3c2410_platform_i2c *npd; |
228 | |
229 | if (!pd) { |
230 | pd = &default_i2c_data; |
231 | pd->bus_num = 0; |
232 | } |
233 | |
234 | npd = s3c_set_platdata(pd, pdsize: sizeof(*npd), pdev: &s3c_device_i2c0); |
235 | |
236 | if (!npd->cfg_gpio) |
237 | npd->cfg_gpio = s3c_i2c0_cfg_gpio; |
238 | } |
239 | |
240 | #ifdef CONFIG_S3C_DEV_I2C1 |
241 | static struct resource s3c_i2c1_resource[] = { |
242 | [0] = DEFINE_RES_MEM(S3C_PA_IIC1, SZ_4K), |
243 | [1] = DEFINE_RES_IRQ(IRQ_IIC1), |
244 | }; |
245 | |
246 | struct platform_device s3c_device_i2c1 = { |
247 | .name = "s3c2410-i2c" , |
248 | .id = 1, |
249 | .num_resources = ARRAY_SIZE(s3c_i2c1_resource), |
250 | .resource = s3c_i2c1_resource, |
251 | }; |
252 | |
253 | void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd) |
254 | { |
255 | struct s3c2410_platform_i2c *npd; |
256 | |
257 | if (!pd) { |
258 | pd = &default_i2c_data; |
259 | pd->bus_num = 1; |
260 | } |
261 | |
262 | npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_i2c1); |
263 | |
264 | if (!npd->cfg_gpio) |
265 | npd->cfg_gpio = s3c_i2c1_cfg_gpio; |
266 | } |
267 | #endif /* CONFIG_S3C_DEV_I2C1 */ |
268 | |
269 | /* KEYPAD */ |
270 | |
271 | #ifdef CONFIG_SAMSUNG_DEV_KEYPAD |
272 | static struct resource samsung_keypad_resources[] = { |
273 | [0] = DEFINE_RES_MEM(SAMSUNG_PA_KEYPAD, SZ_32), |
274 | [1] = DEFINE_RES_IRQ(IRQ_KEYPAD), |
275 | }; |
276 | |
277 | struct platform_device samsung_device_keypad = { |
278 | .name = "samsung-keypad" , |
279 | .id = -1, |
280 | .num_resources = ARRAY_SIZE(samsung_keypad_resources), |
281 | .resource = samsung_keypad_resources, |
282 | }; |
283 | |
284 | void __init samsung_keypad_set_platdata(struct samsung_keypad_platdata *pd) |
285 | { |
286 | struct samsung_keypad_platdata *npd; |
287 | |
288 | npd = s3c_set_platdata(pd, sizeof(*npd), &samsung_device_keypad); |
289 | |
290 | if (!npd->cfg_gpio) |
291 | npd->cfg_gpio = samsung_keypad_cfg_gpio; |
292 | } |
293 | #endif /* CONFIG_SAMSUNG_DEV_KEYPAD */ |
294 | |
295 | /* PWM Timer */ |
296 | |
297 | #ifdef CONFIG_SAMSUNG_DEV_PWM |
298 | static struct resource samsung_pwm_resource[] = { |
299 | DEFINE_RES_MEM(SAMSUNG_PA_TIMER, SZ_4K), |
300 | }; |
301 | |
302 | struct platform_device samsung_device_pwm = { |
303 | .name = "samsung-pwm" , |
304 | .id = -1, |
305 | .num_resources = ARRAY_SIZE(samsung_pwm_resource), |
306 | .resource = samsung_pwm_resource, |
307 | }; |
308 | |
309 | void __init samsung_pwm_set_platdata(struct samsung_pwm_variant *pd) |
310 | { |
311 | samsung_device_pwm.dev.platform_data = pd; |
312 | } |
313 | #endif /* CONFIG_SAMSUNG_DEV_PWM */ |
314 | |
315 | /* USB */ |
316 | |
317 | #ifdef CONFIG_S3C_DEV_USB_HOST |
318 | static struct resource s3c_usb_resource[] = { |
319 | [0] = DEFINE_RES_MEM(S3C_PA_USBHOST, SZ_256), |
320 | [1] = DEFINE_RES_IRQ(IRQ_USBH), |
321 | }; |
322 | |
323 | struct platform_device s3c_device_ohci = { |
324 | .name = "s3c2410-ohci" , |
325 | .id = -1, |
326 | .num_resources = ARRAY_SIZE(s3c_usb_resource), |
327 | .resource = s3c_usb_resource, |
328 | .dev = { |
329 | .dma_mask = &samsung_device_dma_mask, |
330 | .coherent_dma_mask = DMA_BIT_MASK(32), |
331 | } |
332 | }; |
333 | #endif /* CONFIG_S3C_DEV_USB_HOST */ |
334 | |
335 | /* USB HSOTG */ |
336 | |
337 | #ifdef CONFIG_S3C_DEV_USB_HSOTG |
338 | static struct resource s3c_usb_hsotg_resources[] = { |
339 | [0] = DEFINE_RES_MEM(S3C_PA_USB_HSOTG, SZ_128K), |
340 | [1] = DEFINE_RES_IRQ(IRQ_OTG), |
341 | }; |
342 | |
343 | struct platform_device s3c_device_usb_hsotg = { |
344 | .name = "s3c-hsotg" , |
345 | .id = -1, |
346 | .num_resources = ARRAY_SIZE(s3c_usb_hsotg_resources), |
347 | .resource = s3c_usb_hsotg_resources, |
348 | .dev = { |
349 | .dma_mask = &samsung_device_dma_mask, |
350 | .coherent_dma_mask = DMA_BIT_MASK(32), |
351 | }, |
352 | }; |
353 | |
354 | void __init dwc2_hsotg_set_platdata(struct dwc2_hsotg_plat *pd) |
355 | { |
356 | struct dwc2_hsotg_plat *npd; |
357 | |
358 | npd = s3c_set_platdata(pd, sizeof(*npd), &s3c_device_usb_hsotg); |
359 | |
360 | if (!npd->phy_init) |
361 | npd->phy_init = s3c_usb_phy_init; |
362 | if (!npd->phy_exit) |
363 | npd->phy_exit = s3c_usb_phy_exit; |
364 | } |
365 | #endif /* CONFIG_S3C_DEV_USB_HSOTG */ |
366 | |
367 | #ifdef CONFIG_S3C64XX_DEV_SPI0 |
368 | static struct resource s3c64xx_spi0_resource[] = { |
369 | [0] = DEFINE_RES_MEM(S3C_PA_SPI0, SZ_256), |
370 | [1] = DEFINE_RES_IRQ(IRQ_SPI0), |
371 | }; |
372 | |
373 | struct platform_device s3c64xx_device_spi0 = { |
374 | .name = "s3c6410-spi" , |
375 | .id = 0, |
376 | .num_resources = ARRAY_SIZE(s3c64xx_spi0_resource), |
377 | .resource = s3c64xx_spi0_resource, |
378 | .dev = { |
379 | .dma_mask = &samsung_device_dma_mask, |
380 | .coherent_dma_mask = DMA_BIT_MASK(32), |
381 | }, |
382 | }; |
383 | |
384 | void __init s3c64xx_spi0_set_platdata(int src_clk_nr, int num_cs) |
385 | { |
386 | struct s3c64xx_spi_info pd; |
387 | |
388 | /* Reject invalid configuration */ |
389 | if (!num_cs || src_clk_nr < 0) { |
390 | pr_err("%s: Invalid SPI configuration\n" , __func__); |
391 | return; |
392 | } |
393 | |
394 | pd.num_cs = num_cs; |
395 | pd.src_clk_nr = src_clk_nr; |
396 | pd.cfg_gpio = s3c64xx_spi0_cfg_gpio; |
397 | |
398 | s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi0); |
399 | } |
400 | #endif /* CONFIG_S3C64XX_DEV_SPI0 */ |
401 | |