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