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