1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * arch/arm/mach-ep93xx/edb93xx.c |
4 | * Cirrus Logic EDB93xx Development Board support. |
5 | * |
6 | * EDB93XX, EDB9301, EDB9307A |
7 | * Copyright (C) 2008-2009 H Hartley Sweeten <hsweeten@visionengravers.com> |
8 | * |
9 | * EDB9302 |
10 | * Copyright (C) 2006 George Kashperko <george@chas.com.ua> |
11 | * |
12 | * EDB9302A, EDB9315, EDB9315A |
13 | * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> |
14 | * |
15 | * EDB9307 |
16 | * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org> |
17 | * |
18 | * EDB9312 |
19 | * Copyright (C) 2006 Infosys Technologies Limited |
20 | * Toufeeq Hussain <toufeeq_hussain@infosys.com> |
21 | */ |
22 | |
23 | #include <linux/kernel.h> |
24 | #include <linux/init.h> |
25 | #include <linux/platform_device.h> |
26 | #include <linux/i2c.h> |
27 | #include <linux/spi/spi.h> |
28 | #include <linux/gpio/machine.h> |
29 | |
30 | #include <sound/cs4271.h> |
31 | |
32 | #include "hardware.h" |
33 | #include <linux/platform_data/video-ep93xx.h> |
34 | #include <linux/platform_data/spi-ep93xx.h> |
35 | #include "gpio-ep93xx.h" |
36 | |
37 | #include <asm/mach-types.h> |
38 | #include <asm/mach/arch.h> |
39 | |
40 | #include "soc.h" |
41 | |
42 | static void __init edb93xx_register_flash(void) |
43 | { |
44 | if (machine_is_edb9307() || machine_is_edb9312() || |
45 | machine_is_edb9315()) { |
46 | ep93xx_register_flash(width: 4, EP93XX_CS6_PHYS_BASE, SZ_32M); |
47 | } else { |
48 | ep93xx_register_flash(width: 2, EP93XX_CS6_PHYS_BASE, SZ_16M); |
49 | } |
50 | } |
51 | |
52 | static struct ep93xx_eth_data __initdata edb93xx_eth_data = { |
53 | .phy_id = 1, |
54 | }; |
55 | |
56 | |
57 | /************************************************************************* |
58 | * EDB93xx i2c peripheral handling |
59 | *************************************************************************/ |
60 | |
61 | static struct i2c_board_info __initdata edb93xxa_i2c_board_info[] = { |
62 | { |
63 | I2C_BOARD_INFO("isl1208" , 0x6f), |
64 | }, |
65 | }; |
66 | |
67 | static struct i2c_board_info __initdata edb93xx_i2c_board_info[] = { |
68 | { |
69 | I2C_BOARD_INFO("ds1337" , 0x68), |
70 | }, |
71 | }; |
72 | |
73 | static void __init edb93xx_register_i2c(void) |
74 | { |
75 | if (machine_is_edb9302a() || machine_is_edb9307a() || |
76 | machine_is_edb9315a()) { |
77 | ep93xx_register_i2c(devices: edb93xxa_i2c_board_info, |
78 | ARRAY_SIZE(edb93xxa_i2c_board_info)); |
79 | } else if (machine_is_edb9302() || machine_is_edb9307() |
80 | || machine_is_edb9312() || machine_is_edb9315()) { |
81 | ep93xx_register_i2c(devices: edb93xx_i2c_board_info, |
82 | ARRAY_SIZE(edb93xx_i2c_board_info)); |
83 | } |
84 | } |
85 | |
86 | |
87 | /************************************************************************* |
88 | * EDB93xx SPI peripheral handling |
89 | *************************************************************************/ |
90 | static struct cs4271_platform_data edb93xx_cs4271_data = { |
91 | /* Intentionally left blank */ |
92 | }; |
93 | |
94 | static struct spi_board_info edb93xx_spi_board_info[] __initdata = { |
95 | { |
96 | .modalias = "cs4271" , |
97 | .platform_data = &edb93xx_cs4271_data, |
98 | .max_speed_hz = 6000000, |
99 | .bus_num = 0, |
100 | .chip_select = 0, |
101 | .mode = SPI_MODE_3, |
102 | }, |
103 | }; |
104 | |
105 | static struct gpiod_lookup_table edb93xx_spi_cs_gpio_table = { |
106 | .dev_id = "spi0" , |
107 | .table = { |
108 | GPIO_LOOKUP("A" , 6, "cs" , GPIO_ACTIVE_LOW), |
109 | { }, |
110 | }, |
111 | }; |
112 | |
113 | static struct ep93xx_spi_info edb93xx_spi_info __initdata = { |
114 | /* Intentionally left blank */ |
115 | }; |
116 | |
117 | static struct gpiod_lookup_table edb93xx_cs4272_edb9301_gpio_table = { |
118 | .dev_id = "spi0.0" , /* CS0 on SPI0 */ |
119 | .table = { |
120 | GPIO_LOOKUP("A" , 1, "reset" , GPIO_ACTIVE_LOW), |
121 | { }, |
122 | }, |
123 | }; |
124 | |
125 | static struct gpiod_lookup_table edb93xx_cs4272_edb9302_gpio_table = { |
126 | .dev_id = "spi0.0" , /* CS0 on SPI0 */ |
127 | .table = { |
128 | GPIO_LOOKUP("H" , 2, "reset" , GPIO_ACTIVE_LOW), |
129 | { }, |
130 | }, |
131 | }; |
132 | |
133 | static struct gpiod_lookup_table edb93xx_cs4272_edb9315_gpio_table = { |
134 | .dev_id = "spi0.0" , /* CS0 on SPI0 */ |
135 | .table = { |
136 | GPIO_LOOKUP("B" , 6, "reset" , GPIO_ACTIVE_LOW), |
137 | { }, |
138 | }, |
139 | }; |
140 | |
141 | static void __init edb93xx_register_spi(void) |
142 | { |
143 | if (machine_is_edb9301() || machine_is_edb9302()) |
144 | gpiod_add_lookup_table(table: &edb93xx_cs4272_edb9301_gpio_table); |
145 | else if (machine_is_edb9302a() || machine_is_edb9307a()) |
146 | gpiod_add_lookup_table(table: &edb93xx_cs4272_edb9302_gpio_table); |
147 | else if (machine_is_edb9315a()) |
148 | gpiod_add_lookup_table(table: &edb93xx_cs4272_edb9315_gpio_table); |
149 | |
150 | gpiod_add_lookup_table(table: &edb93xx_spi_cs_gpio_table); |
151 | ep93xx_register_spi(info: &edb93xx_spi_info, devices: edb93xx_spi_board_info, |
152 | ARRAY_SIZE(edb93xx_spi_board_info)); |
153 | } |
154 | |
155 | |
156 | /************************************************************************* |
157 | * EDB93xx I2S |
158 | *************************************************************************/ |
159 | static struct platform_device edb93xx_audio_device = { |
160 | .name = "edb93xx-audio" , |
161 | .id = -1, |
162 | }; |
163 | |
164 | static int __init edb93xx_has_audio(void) |
165 | { |
166 | return (machine_is_edb9301() || machine_is_edb9302() || |
167 | machine_is_edb9302a() || machine_is_edb9307a() || |
168 | machine_is_edb9315a()); |
169 | } |
170 | |
171 | static void __init edb93xx_register_i2s(void) |
172 | { |
173 | if (edb93xx_has_audio()) { |
174 | ep93xx_register_i2s(); |
175 | platform_device_register(&edb93xx_audio_device); |
176 | } |
177 | } |
178 | |
179 | |
180 | /************************************************************************* |
181 | * EDB93xx pwm |
182 | *************************************************************************/ |
183 | static void __init edb93xx_register_pwm(void) |
184 | { |
185 | if (machine_is_edb9301() || |
186 | machine_is_edb9302() || machine_is_edb9302a()) { |
187 | /* EP9301 and EP9302 only have pwm.1 (EGPIO14) */ |
188 | ep93xx_register_pwm(pwm0: 0, pwm1: 1); |
189 | } else if (machine_is_edb9307() || machine_is_edb9307a()) { |
190 | /* EP9307 only has pwm.0 (PWMOUT) */ |
191 | ep93xx_register_pwm(pwm0: 1, pwm1: 0); |
192 | } else { |
193 | /* EP9312 and EP9315 have both */ |
194 | ep93xx_register_pwm(pwm0: 1, pwm1: 1); |
195 | } |
196 | } |
197 | |
198 | |
199 | /************************************************************************* |
200 | * EDB93xx framebuffer |
201 | *************************************************************************/ |
202 | static struct ep93xxfb_mach_info __initdata edb93xxfb_info = { |
203 | .flags = 0, |
204 | }; |
205 | |
206 | static int __init edb93xx_has_fb(void) |
207 | { |
208 | /* These platforms have an ep93xx with video capability */ |
209 | return machine_is_edb9307() || machine_is_edb9307a() || |
210 | machine_is_edb9312() || machine_is_edb9315() || |
211 | machine_is_edb9315a(); |
212 | } |
213 | |
214 | static void __init edb93xx_register_fb(void) |
215 | { |
216 | if (!edb93xx_has_fb()) |
217 | return; |
218 | |
219 | if (machine_is_edb9307a() || machine_is_edb9315a()) |
220 | edb93xxfb_info.flags |= EP93XXFB_USE_SDCSN0; |
221 | else |
222 | edb93xxfb_info.flags |= EP93XXFB_USE_SDCSN3; |
223 | |
224 | ep93xx_register_fb(data: &edb93xxfb_info); |
225 | } |
226 | |
227 | |
228 | /************************************************************************* |
229 | * EDB93xx IDE |
230 | *************************************************************************/ |
231 | static int __init edb93xx_has_ide(void) |
232 | { |
233 | /* |
234 | * Although EDB9312 and EDB9315 do have IDE capability, they have |
235 | * INTRQ line wired as pull-up, which makes using IDE interface |
236 | * problematic. |
237 | */ |
238 | return machine_is_edb9312() || machine_is_edb9315() || |
239 | machine_is_edb9315a(); |
240 | } |
241 | |
242 | static void __init edb93xx_register_ide(void) |
243 | { |
244 | if (!edb93xx_has_ide()) |
245 | return; |
246 | |
247 | ep93xx_register_ide(); |
248 | } |
249 | |
250 | |
251 | static void __init edb93xx_init_machine(void) |
252 | { |
253 | ep93xx_init_devices(); |
254 | edb93xx_register_flash(); |
255 | ep93xx_register_eth(data: &edb93xx_eth_data, copy_addr: 1); |
256 | edb93xx_register_i2c(); |
257 | edb93xx_register_spi(); |
258 | edb93xx_register_i2s(); |
259 | edb93xx_register_pwm(); |
260 | edb93xx_register_fb(); |
261 | edb93xx_register_ide(); |
262 | ep93xx_register_adc(); |
263 | } |
264 | |
265 | |
266 | #ifdef CONFIG_MACH_EDB9301 |
267 | MACHINE_START(EDB9301, "Cirrus Logic EDB9301 Evaluation Board" ) |
268 | /* Maintainer: H Hartley Sweeten <hsweeten@visionengravers.com> */ |
269 | .atag_offset = 0x100, |
270 | .nr_irqs = NR_EP93XX_IRQS, |
271 | .map_io = ep93xx_map_io, |
272 | .init_irq = ep93xx_init_irq, |
273 | .init_time = ep93xx_timer_init, |
274 | .init_machine = edb93xx_init_machine, |
275 | .restart = ep93xx_restart, |
276 | MACHINE_END |
277 | #endif |
278 | |
279 | #ifdef CONFIG_MACH_EDB9302 |
280 | MACHINE_START(EDB9302, "Cirrus Logic EDB9302 Evaluation Board" ) |
281 | /* Maintainer: George Kashperko <george@chas.com.ua> */ |
282 | .atag_offset = 0x100, |
283 | .nr_irqs = NR_EP93XX_IRQS, |
284 | .map_io = ep93xx_map_io, |
285 | .init_irq = ep93xx_init_irq, |
286 | .init_time = ep93xx_timer_init, |
287 | .init_machine = edb93xx_init_machine, |
288 | .restart = ep93xx_restart, |
289 | MACHINE_END |
290 | #endif |
291 | |
292 | #ifdef CONFIG_MACH_EDB9302A |
293 | MACHINE_START(EDB9302A, "Cirrus Logic EDB9302A Evaluation Board" ) |
294 | /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ |
295 | .atag_offset = 0x100, |
296 | .nr_irqs = NR_EP93XX_IRQS, |
297 | .map_io = ep93xx_map_io, |
298 | .init_irq = ep93xx_init_irq, |
299 | .init_time = ep93xx_timer_init, |
300 | .init_machine = edb93xx_init_machine, |
301 | .restart = ep93xx_restart, |
302 | MACHINE_END |
303 | #endif |
304 | |
305 | #ifdef CONFIG_MACH_EDB9307 |
306 | MACHINE_START(EDB9307, "Cirrus Logic EDB9307 Evaluation Board" ) |
307 | /* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */ |
308 | .atag_offset = 0x100, |
309 | .nr_irqs = NR_EP93XX_IRQS, |
310 | .map_io = ep93xx_map_io, |
311 | .init_irq = ep93xx_init_irq, |
312 | .init_time = ep93xx_timer_init, |
313 | .init_machine = edb93xx_init_machine, |
314 | .restart = ep93xx_restart, |
315 | MACHINE_END |
316 | #endif |
317 | |
318 | #ifdef CONFIG_MACH_EDB9307A |
319 | MACHINE_START(EDB9307A, "Cirrus Logic EDB9307A Evaluation Board" ) |
320 | /* Maintainer: H Hartley Sweeten <hsweeten@visionengravers.com> */ |
321 | .atag_offset = 0x100, |
322 | .nr_irqs = NR_EP93XX_IRQS, |
323 | .map_io = ep93xx_map_io, |
324 | .init_irq = ep93xx_init_irq, |
325 | .init_time = ep93xx_timer_init, |
326 | .init_machine = edb93xx_init_machine, |
327 | .restart = ep93xx_restart, |
328 | MACHINE_END |
329 | #endif |
330 | |
331 | #ifdef CONFIG_MACH_EDB9312 |
332 | MACHINE_START(EDB9312, "Cirrus Logic EDB9312 Evaluation Board" ) |
333 | /* Maintainer: Toufeeq Hussain <toufeeq_hussain@infosys.com> */ |
334 | .atag_offset = 0x100, |
335 | .nr_irqs = NR_EP93XX_IRQS, |
336 | .map_io = ep93xx_map_io, |
337 | .init_irq = ep93xx_init_irq, |
338 | .init_time = ep93xx_timer_init, |
339 | .init_machine = edb93xx_init_machine, |
340 | .restart = ep93xx_restart, |
341 | MACHINE_END |
342 | #endif |
343 | |
344 | #ifdef CONFIG_MACH_EDB9315 |
345 | MACHINE_START(EDB9315, "Cirrus Logic EDB9315 Evaluation Board" ) |
346 | /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ |
347 | .atag_offset = 0x100, |
348 | .nr_irqs = NR_EP93XX_IRQS, |
349 | .map_io = ep93xx_map_io, |
350 | .init_irq = ep93xx_init_irq, |
351 | .init_time = ep93xx_timer_init, |
352 | .init_machine = edb93xx_init_machine, |
353 | .restart = ep93xx_restart, |
354 | MACHINE_END |
355 | #endif |
356 | |
357 | #ifdef CONFIG_MACH_EDB9315A |
358 | MACHINE_START(EDB9315A, "Cirrus Logic EDB9315A Evaluation Board" ) |
359 | /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ |
360 | .atag_offset = 0x100, |
361 | .nr_irqs = NR_EP93XX_IRQS, |
362 | .map_io = ep93xx_map_io, |
363 | .init_irq = ep93xx_init_irq, |
364 | .init_time = ep93xx_timer_init, |
365 | .init_machine = edb93xx_init_machine, |
366 | .restart = ep93xx_restart, |
367 | MACHINE_END |
368 | #endif |
369 | |