1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * arch/arm/mach-ep93xx/vision_ep9307.c
4 * Vision Engraving Systems EP9307 SoM support.
5 *
6 * Copyright (C) 2008-2011 Vision Engraving Systems
7 * H Hartley Sweeten <hsweeten@visionengravers.com>
8 */
9
10#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/platform_device.h>
15#include <linux/irq.h>
16#include <linux/gpio.h>
17#include <linux/gpio/machine.h>
18#include <linux/fb.h>
19#include <linux/io.h>
20#include <linux/mtd/partitions.h>
21#include <linux/i2c.h>
22#include <linux/platform_data/pca953x.h>
23#include <linux/spi/spi.h>
24#include <linux/spi/flash.h>
25#include <linux/spi/mmc_spi.h>
26#include <linux/mmc/host.h>
27
28#include <sound/cs4271.h>
29
30#include "hardware.h"
31#include <linux/platform_data/video-ep93xx.h>
32#include <linux/platform_data/spi-ep93xx.h>
33#include "gpio-ep93xx.h"
34
35#include <asm/mach-types.h>
36#include <asm/mach/map.h>
37#include <asm/mach/arch.h>
38
39#include "soc.h"
40
41/*************************************************************************
42 * Static I/O mappings for the FPGA
43 *************************************************************************/
44#define VISION_PHYS_BASE	EP93XX_CS7_PHYS_BASE
45#define VISION_VIRT_BASE	0xfebff000
46
47static struct map_desc vision_io_desc[] __initdata = {
48	{
49		.virtual	= VISION_VIRT_BASE,
50		.pfn		= __phys_to_pfn(VISION_PHYS_BASE),
51		.length		= SZ_4K,
52		.type		= MT_DEVICE,
53	},
54};
55
56static void __init vision_map_io(void)
57{
58	ep93xx_map_io();
59
60	iotable_init(vision_io_desc, ARRAY_SIZE(vision_io_desc));
61}
62
63/*************************************************************************
64 * Ethernet
65 *************************************************************************/
66static struct ep93xx_eth_data vision_eth_data __initdata = {
67	.phy_id		= 1,
68};
69
70/*************************************************************************
71 * Framebuffer
72 *************************************************************************/
73#define VISION_LCD_ENABLE	EP93XX_GPIO_LINE_EGPIO1
74
75static int vision_lcd_setup(struct platform_device *pdev)
76{
77	int err;
78
79	err = gpio_request_one(VISION_LCD_ENABLE, GPIOF_INIT_HIGH,
80				dev_name(&pdev->dev));
81	if (err)
82		return err;
83
84	ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_RAS |
85				 EP93XX_SYSCON_DEVCFG_RASONP3 |
86				 EP93XX_SYSCON_DEVCFG_EXVC);
87
88	return 0;
89}
90
91static void vision_lcd_teardown(struct platform_device *pdev)
92{
93	gpio_free(VISION_LCD_ENABLE);
94}
95
96static void vision_lcd_blank(int blank_mode, struct fb_info *info)
97{
98	if (blank_mode)
99		gpio_set_value(VISION_LCD_ENABLE, 0);
100	else
101		gpio_set_value(VISION_LCD_ENABLE, 1);
102}
103
104static struct ep93xxfb_mach_info ep93xxfb_info __initdata = {
105	.flags		= EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING,
106	.setup		= vision_lcd_setup,
107	.teardown	= vision_lcd_teardown,
108	.blank		= vision_lcd_blank,
109};
110
111
112/*************************************************************************
113 * GPIO Expanders
114 *************************************************************************/
115#define PCA9539_74_GPIO_BASE	(EP93XX_GPIO_LINE_MAX + 1)
116#define PCA9539_75_GPIO_BASE	(PCA9539_74_GPIO_BASE + 16)
117#define PCA9539_76_GPIO_BASE	(PCA9539_75_GPIO_BASE + 16)
118#define PCA9539_77_GPIO_BASE	(PCA9539_76_GPIO_BASE + 16)
119
120static struct pca953x_platform_data pca953x_74_gpio_data = {
121	.gpio_base	= PCA9539_74_GPIO_BASE,
122	.irq_base	= EP93XX_BOARD_IRQ(0),
123};
124
125static struct pca953x_platform_data pca953x_75_gpio_data = {
126	.gpio_base	= PCA9539_75_GPIO_BASE,
127	.irq_base	= -1,
128};
129
130static struct pca953x_platform_data pca953x_76_gpio_data = {
131	.gpio_base	= PCA9539_76_GPIO_BASE,
132	.irq_base	= -1,
133};
134
135static struct pca953x_platform_data pca953x_77_gpio_data = {
136	.gpio_base	= PCA9539_77_GPIO_BASE,
137	.irq_base	= -1,
138};
139
140/*************************************************************************
141 * I2C Bus
142 *************************************************************************/
143
144static struct i2c_board_info vision_i2c_info[] __initdata = {
145	{
146		I2C_BOARD_INFO("isl1208", 0x6f),
147		.irq		= IRQ_EP93XX_EXT1,
148	}, {
149		I2C_BOARD_INFO("pca9539", 0x74),
150		.platform_data	= &pca953x_74_gpio_data,
151	}, {
152		I2C_BOARD_INFO("pca9539", 0x75),
153		.platform_data	= &pca953x_75_gpio_data,
154	}, {
155		I2C_BOARD_INFO("pca9539", 0x76),
156		.platform_data	= &pca953x_76_gpio_data,
157	}, {
158		I2C_BOARD_INFO("pca9539", 0x77),
159		.platform_data	= &pca953x_77_gpio_data,
160	},
161};
162
163/*************************************************************************
164 * SPI CS4271 Audio Codec
165 *************************************************************************/
166static struct cs4271_platform_data vision_cs4271_data = {
167	/* Intentionally left blank */
168};
169
170/*************************************************************************
171 * SPI Flash
172 *************************************************************************/
173static struct mtd_partition vision_spi_flash_partitions[] = {
174	{
175		.name	= "SPI bootstrap",
176		.offset	= 0,
177		.size	= SZ_4K,
178	}, {
179		.name	= "Bootstrap config",
180		.offset	= MTDPART_OFS_APPEND,
181		.size	= SZ_4K,
182	}, {
183		.name	= "System config",
184		.offset	= MTDPART_OFS_APPEND,
185		.size	= MTDPART_SIZ_FULL,
186	},
187};
188
189static struct flash_platform_data vision_spi_flash_data = {
190	.name		= "SPI Flash",
191	.parts		= vision_spi_flash_partitions,
192	.nr_parts	= ARRAY_SIZE(vision_spi_flash_partitions),
193};
194
195/*************************************************************************
196 * SPI SD/MMC host
197 *************************************************************************/
198static struct mmc_spi_platform_data vision_spi_mmc_data = {
199	.detect_delay	= 100,
200	.powerup_msecs	= 100,
201	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
202	.caps2		= MMC_CAP2_RO_ACTIVE_HIGH,
203};
204
205static struct gpiod_lookup_table vision_spi_mmc_gpio_table = {
206	.dev_id = "mmc_spi.2", /* "mmc_spi @ CS2 */
207	.table = {
208		/* Card detect */
209		GPIO_LOOKUP_IDX("B", 7, NULL, 0, GPIO_ACTIVE_LOW),
210		/* Write protect */
211		GPIO_LOOKUP_IDX("F", 0, NULL, 1, GPIO_ACTIVE_HIGH),
212		{ },
213	},
214};
215
216/*************************************************************************
217 * SPI Bus
218 *************************************************************************/
219static struct spi_board_info vision_spi_board_info[] __initdata = {
220	{
221		.modalias		= "cs4271",
222		.platform_data		= &vision_cs4271_data,
223		.max_speed_hz		= 6000000,
224		.bus_num		= 0,
225		.chip_select		= 0,
226		.mode			= SPI_MODE_3,
227	}, {
228		.modalias		= "sst25l",
229		.platform_data		= &vision_spi_flash_data,
230		.max_speed_hz		= 20000000,
231		.bus_num		= 0,
232		.chip_select		= 1,
233		.mode			= SPI_MODE_3,
234	}, {
235		.modalias		= "mmc_spi",
236		.platform_data		= &vision_spi_mmc_data,
237		.max_speed_hz		= 20000000,
238		.bus_num		= 0,
239		.chip_select		= 2,
240		.mode			= SPI_MODE_3,
241	},
242};
243
244static struct gpiod_lookup_table vision_spi_cs4271_gpio_table = {
245	.dev_id = "spi0.0", /* cs4271 @ CS0 */
246	.table = {
247		/* RESET */
248		GPIO_LOOKUP_IDX("H", 2, NULL, 0, GPIO_ACTIVE_LOW),
249		{ },
250	},
251};
252
253static struct gpiod_lookup_table vision_spi_cs_gpio_table = {
254	.dev_id = "spi0",
255	.table = {
256		GPIO_LOOKUP_IDX("A", 6, "cs", 0, GPIO_ACTIVE_LOW),
257		GPIO_LOOKUP_IDX("A", 7, "cs", 1, GPIO_ACTIVE_LOW),
258		GPIO_LOOKUP_IDX("G", 2, "cs", 2, GPIO_ACTIVE_LOW),
259		{ },
260	},
261};
262
263static struct ep93xx_spi_info vision_spi_master __initdata = {
264	.use_dma	= 1,
265};
266
267/*************************************************************************
268 * I2S Audio
269 *************************************************************************/
270static struct platform_device vision_audio_device = {
271	.name		= "edb93xx-audio",
272	.id		= -1,
273};
274
275static void __init vision_register_i2s(void)
276{
277	ep93xx_register_i2s();
278	platform_device_register(&vision_audio_device);
279}
280
281/*************************************************************************
282 * Machine Initialization
283 *************************************************************************/
284static void __init vision_init_machine(void)
285{
286	ep93xx_init_devices();
287	ep93xx_register_flash(2, EP93XX_CS6_PHYS_BASE, SZ_64M);
288	ep93xx_register_eth(&vision_eth_data, 1);
289	ep93xx_register_fb(&ep93xxfb_info);
290	ep93xx_register_pwm(1, 0);
291
292	/*
293	 * Request the gpio expander's interrupt gpio line now to prevent
294	 * the kernel from doing a WARN in gpiolib:gpio_ensure_requested().
295	 */
296	if (gpio_request_one(EP93XX_GPIO_LINE_F(7), GPIOF_DIR_IN,
297				"pca9539:74"))
298		pr_warn("cannot request interrupt gpio for pca9539:74\n");
299
300	vision_i2c_info[1].irq = gpio_to_irq(EP93XX_GPIO_LINE_F(7));
301
302	ep93xx_register_i2c(vision_i2c_info,
303				ARRAY_SIZE(vision_i2c_info));
304	gpiod_add_lookup_table(&vision_spi_cs4271_gpio_table);
305	gpiod_add_lookup_table(&vision_spi_mmc_gpio_table);
306	gpiod_add_lookup_table(&vision_spi_cs_gpio_table);
307	ep93xx_register_spi(&vision_spi_master, vision_spi_board_info,
308				ARRAY_SIZE(vision_spi_board_info));
309	vision_register_i2s();
310}
311
312MACHINE_START(VISION_EP9307, "Vision Engraving Systems EP9307")
313	/* Maintainer: H Hartley Sweeten <hsweeten@visionengravers.com> */
314	.atag_offset	= 0x100,
315	.nr_irqs	= NR_EP93XX_IRQS + EP93XX_BOARD_IRQS,
316	.map_io		= vision_map_io,
317	.init_irq	= ep93xx_init_irq,
318	.init_time	= ep93xx_timer_init,
319	.init_machine	= vision_init_machine,
320	.restart	= ep93xx_restart,
321MACHINE_END
322