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