162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * arch/arm/mach-ep93xx/vision_ep9307.c
462306a36Sopenharmony_ci * Vision Engraving Systems EP9307 SoM support.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (C) 2008-2011 Vision Engraving Systems
762306a36Sopenharmony_ci * H Hartley Sweeten <hsweeten@visionengravers.com>
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include <linux/kernel.h>
1362306a36Sopenharmony_ci#include <linux/init.h>
1462306a36Sopenharmony_ci#include <linux/platform_device.h>
1562306a36Sopenharmony_ci#include <linux/irq.h>
1662306a36Sopenharmony_ci#include <linux/gpio.h>
1762306a36Sopenharmony_ci#include <linux/gpio/machine.h>
1862306a36Sopenharmony_ci#include <linux/fb.h>
1962306a36Sopenharmony_ci#include <linux/io.h>
2062306a36Sopenharmony_ci#include <linux/mtd/partitions.h>
2162306a36Sopenharmony_ci#include <linux/i2c.h>
2262306a36Sopenharmony_ci#include <linux/platform_data/pca953x.h>
2362306a36Sopenharmony_ci#include <linux/spi/spi.h>
2462306a36Sopenharmony_ci#include <linux/spi/flash.h>
2562306a36Sopenharmony_ci#include <linux/spi/mmc_spi.h>
2662306a36Sopenharmony_ci#include <linux/mmc/host.h>
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci#include <sound/cs4271.h>
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci#include "hardware.h"
3162306a36Sopenharmony_ci#include <linux/platform_data/video-ep93xx.h>
3262306a36Sopenharmony_ci#include <linux/platform_data/spi-ep93xx.h>
3362306a36Sopenharmony_ci#include "gpio-ep93xx.h"
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci#include <asm/mach-types.h>
3662306a36Sopenharmony_ci#include <asm/mach/map.h>
3762306a36Sopenharmony_ci#include <asm/mach/arch.h>
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci#include "soc.h"
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci/*************************************************************************
4262306a36Sopenharmony_ci * Static I/O mappings for the FPGA
4362306a36Sopenharmony_ci *************************************************************************/
4462306a36Sopenharmony_ci#define VISION_PHYS_BASE	EP93XX_CS7_PHYS_BASE
4562306a36Sopenharmony_ci#define VISION_VIRT_BASE	0xfebff000
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cistatic struct map_desc vision_io_desc[] __initdata = {
4862306a36Sopenharmony_ci	{
4962306a36Sopenharmony_ci		.virtual	= VISION_VIRT_BASE,
5062306a36Sopenharmony_ci		.pfn		= __phys_to_pfn(VISION_PHYS_BASE),
5162306a36Sopenharmony_ci		.length		= SZ_4K,
5262306a36Sopenharmony_ci		.type		= MT_DEVICE,
5362306a36Sopenharmony_ci	},
5462306a36Sopenharmony_ci};
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_cistatic void __init vision_map_io(void)
5762306a36Sopenharmony_ci{
5862306a36Sopenharmony_ci	ep93xx_map_io();
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	iotable_init(vision_io_desc, ARRAY_SIZE(vision_io_desc));
6162306a36Sopenharmony_ci}
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci/*************************************************************************
6462306a36Sopenharmony_ci * Ethernet
6562306a36Sopenharmony_ci *************************************************************************/
6662306a36Sopenharmony_cistatic struct ep93xx_eth_data vision_eth_data __initdata = {
6762306a36Sopenharmony_ci	.phy_id		= 1,
6862306a36Sopenharmony_ci};
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci/*************************************************************************
7162306a36Sopenharmony_ci * Framebuffer
7262306a36Sopenharmony_ci *************************************************************************/
7362306a36Sopenharmony_ci#define VISION_LCD_ENABLE	EP93XX_GPIO_LINE_EGPIO1
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_cistatic int vision_lcd_setup(struct platform_device *pdev)
7662306a36Sopenharmony_ci{
7762306a36Sopenharmony_ci	int err;
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci	err = gpio_request_one(VISION_LCD_ENABLE, GPIOF_INIT_HIGH,
8062306a36Sopenharmony_ci				dev_name(&pdev->dev));
8162306a36Sopenharmony_ci	if (err)
8262306a36Sopenharmony_ci		return err;
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_RAS |
8562306a36Sopenharmony_ci				 EP93XX_SYSCON_DEVCFG_RASONP3 |
8662306a36Sopenharmony_ci				 EP93XX_SYSCON_DEVCFG_EXVC);
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	return 0;
8962306a36Sopenharmony_ci}
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_cistatic void vision_lcd_teardown(struct platform_device *pdev)
9262306a36Sopenharmony_ci{
9362306a36Sopenharmony_ci	gpio_free(VISION_LCD_ENABLE);
9462306a36Sopenharmony_ci}
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_cistatic void vision_lcd_blank(int blank_mode, struct fb_info *info)
9762306a36Sopenharmony_ci{
9862306a36Sopenharmony_ci	if (blank_mode)
9962306a36Sopenharmony_ci		gpio_set_value(VISION_LCD_ENABLE, 0);
10062306a36Sopenharmony_ci	else
10162306a36Sopenharmony_ci		gpio_set_value(VISION_LCD_ENABLE, 1);
10262306a36Sopenharmony_ci}
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_cistatic struct ep93xxfb_mach_info ep93xxfb_info __initdata = {
10562306a36Sopenharmony_ci	.flags		= EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING,
10662306a36Sopenharmony_ci	.setup		= vision_lcd_setup,
10762306a36Sopenharmony_ci	.teardown	= vision_lcd_teardown,
10862306a36Sopenharmony_ci	.blank		= vision_lcd_blank,
10962306a36Sopenharmony_ci};
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci/*************************************************************************
11362306a36Sopenharmony_ci * GPIO Expanders
11462306a36Sopenharmony_ci *************************************************************************/
11562306a36Sopenharmony_ci#define PCA9539_74_GPIO_BASE	(EP93XX_GPIO_LINE_MAX + 1)
11662306a36Sopenharmony_ci#define PCA9539_75_GPIO_BASE	(PCA9539_74_GPIO_BASE + 16)
11762306a36Sopenharmony_ci#define PCA9539_76_GPIO_BASE	(PCA9539_75_GPIO_BASE + 16)
11862306a36Sopenharmony_ci#define PCA9539_77_GPIO_BASE	(PCA9539_76_GPIO_BASE + 16)
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_cistatic struct pca953x_platform_data pca953x_74_gpio_data = {
12162306a36Sopenharmony_ci	.gpio_base	= PCA9539_74_GPIO_BASE,
12262306a36Sopenharmony_ci	.irq_base	= EP93XX_BOARD_IRQ(0),
12362306a36Sopenharmony_ci};
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_cistatic struct pca953x_platform_data pca953x_75_gpio_data = {
12662306a36Sopenharmony_ci	.gpio_base	= PCA9539_75_GPIO_BASE,
12762306a36Sopenharmony_ci	.irq_base	= -1,
12862306a36Sopenharmony_ci};
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_cistatic struct pca953x_platform_data pca953x_76_gpio_data = {
13162306a36Sopenharmony_ci	.gpio_base	= PCA9539_76_GPIO_BASE,
13262306a36Sopenharmony_ci	.irq_base	= -1,
13362306a36Sopenharmony_ci};
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_cistatic struct pca953x_platform_data pca953x_77_gpio_data = {
13662306a36Sopenharmony_ci	.gpio_base	= PCA9539_77_GPIO_BASE,
13762306a36Sopenharmony_ci	.irq_base	= -1,
13862306a36Sopenharmony_ci};
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci/*************************************************************************
14162306a36Sopenharmony_ci * I2C Bus
14262306a36Sopenharmony_ci *************************************************************************/
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_cistatic struct i2c_board_info vision_i2c_info[] __initdata = {
14562306a36Sopenharmony_ci	{
14662306a36Sopenharmony_ci		I2C_BOARD_INFO("isl1208", 0x6f),
14762306a36Sopenharmony_ci		.irq		= IRQ_EP93XX_EXT1,
14862306a36Sopenharmony_ci	}, {
14962306a36Sopenharmony_ci		I2C_BOARD_INFO("pca9539", 0x74),
15062306a36Sopenharmony_ci		.platform_data	= &pca953x_74_gpio_data,
15162306a36Sopenharmony_ci	}, {
15262306a36Sopenharmony_ci		I2C_BOARD_INFO("pca9539", 0x75),
15362306a36Sopenharmony_ci		.platform_data	= &pca953x_75_gpio_data,
15462306a36Sopenharmony_ci	}, {
15562306a36Sopenharmony_ci		I2C_BOARD_INFO("pca9539", 0x76),
15662306a36Sopenharmony_ci		.platform_data	= &pca953x_76_gpio_data,
15762306a36Sopenharmony_ci	}, {
15862306a36Sopenharmony_ci		I2C_BOARD_INFO("pca9539", 0x77),
15962306a36Sopenharmony_ci		.platform_data	= &pca953x_77_gpio_data,
16062306a36Sopenharmony_ci	},
16162306a36Sopenharmony_ci};
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci/*************************************************************************
16462306a36Sopenharmony_ci * SPI CS4271 Audio Codec
16562306a36Sopenharmony_ci *************************************************************************/
16662306a36Sopenharmony_cistatic struct cs4271_platform_data vision_cs4271_data = {
16762306a36Sopenharmony_ci	.gpio_nreset	= EP93XX_GPIO_LINE_H(2),
16862306a36Sopenharmony_ci};
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci/*************************************************************************
17162306a36Sopenharmony_ci * SPI Flash
17262306a36Sopenharmony_ci *************************************************************************/
17362306a36Sopenharmony_cistatic struct mtd_partition vision_spi_flash_partitions[] = {
17462306a36Sopenharmony_ci	{
17562306a36Sopenharmony_ci		.name	= "SPI bootstrap",
17662306a36Sopenharmony_ci		.offset	= 0,
17762306a36Sopenharmony_ci		.size	= SZ_4K,
17862306a36Sopenharmony_ci	}, {
17962306a36Sopenharmony_ci		.name	= "Bootstrap config",
18062306a36Sopenharmony_ci		.offset	= MTDPART_OFS_APPEND,
18162306a36Sopenharmony_ci		.size	= SZ_4K,
18262306a36Sopenharmony_ci	}, {
18362306a36Sopenharmony_ci		.name	= "System config",
18462306a36Sopenharmony_ci		.offset	= MTDPART_OFS_APPEND,
18562306a36Sopenharmony_ci		.size	= MTDPART_SIZ_FULL,
18662306a36Sopenharmony_ci	},
18762306a36Sopenharmony_ci};
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_cistatic struct flash_platform_data vision_spi_flash_data = {
19062306a36Sopenharmony_ci	.name		= "SPI Flash",
19162306a36Sopenharmony_ci	.parts		= vision_spi_flash_partitions,
19262306a36Sopenharmony_ci	.nr_parts	= ARRAY_SIZE(vision_spi_flash_partitions),
19362306a36Sopenharmony_ci};
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci/*************************************************************************
19662306a36Sopenharmony_ci * SPI SD/MMC host
19762306a36Sopenharmony_ci *************************************************************************/
19862306a36Sopenharmony_cistatic struct mmc_spi_platform_data vision_spi_mmc_data = {
19962306a36Sopenharmony_ci	.detect_delay	= 100,
20062306a36Sopenharmony_ci	.powerup_msecs	= 100,
20162306a36Sopenharmony_ci	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
20262306a36Sopenharmony_ci	.caps2		= MMC_CAP2_RO_ACTIVE_HIGH,
20362306a36Sopenharmony_ci};
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_cistatic struct gpiod_lookup_table vision_spi_mmc_gpio_table = {
20662306a36Sopenharmony_ci	.dev_id = "mmc_spi.2", /* "mmc_spi @ CS2 */
20762306a36Sopenharmony_ci	.table = {
20862306a36Sopenharmony_ci		/* Card detect */
20962306a36Sopenharmony_ci		GPIO_LOOKUP_IDX("B", 7, NULL, 0, GPIO_ACTIVE_LOW),
21062306a36Sopenharmony_ci		/* Write protect */
21162306a36Sopenharmony_ci		GPIO_LOOKUP_IDX("F", 0, NULL, 1, GPIO_ACTIVE_HIGH),
21262306a36Sopenharmony_ci		{ },
21362306a36Sopenharmony_ci	},
21462306a36Sopenharmony_ci};
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ci/*************************************************************************
21762306a36Sopenharmony_ci * SPI Bus
21862306a36Sopenharmony_ci *************************************************************************/
21962306a36Sopenharmony_cistatic struct spi_board_info vision_spi_board_info[] __initdata = {
22062306a36Sopenharmony_ci	{
22162306a36Sopenharmony_ci		.modalias		= "cs4271",
22262306a36Sopenharmony_ci		.platform_data		= &vision_cs4271_data,
22362306a36Sopenharmony_ci		.max_speed_hz		= 6000000,
22462306a36Sopenharmony_ci		.bus_num		= 0,
22562306a36Sopenharmony_ci		.chip_select		= 0,
22662306a36Sopenharmony_ci		.mode			= SPI_MODE_3,
22762306a36Sopenharmony_ci	}, {
22862306a36Sopenharmony_ci		.modalias		= "sst25l",
22962306a36Sopenharmony_ci		.platform_data		= &vision_spi_flash_data,
23062306a36Sopenharmony_ci		.max_speed_hz		= 20000000,
23162306a36Sopenharmony_ci		.bus_num		= 0,
23262306a36Sopenharmony_ci		.chip_select		= 1,
23362306a36Sopenharmony_ci		.mode			= SPI_MODE_3,
23462306a36Sopenharmony_ci	}, {
23562306a36Sopenharmony_ci		.modalias		= "mmc_spi",
23662306a36Sopenharmony_ci		.platform_data		= &vision_spi_mmc_data,
23762306a36Sopenharmony_ci		.max_speed_hz		= 20000000,
23862306a36Sopenharmony_ci		.bus_num		= 0,
23962306a36Sopenharmony_ci		.chip_select		= 2,
24062306a36Sopenharmony_ci		.mode			= SPI_MODE_3,
24162306a36Sopenharmony_ci	},
24262306a36Sopenharmony_ci};
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_cistatic struct gpiod_lookup_table vision_spi_cs_gpio_table = {
24562306a36Sopenharmony_ci	.dev_id = "spi0",
24662306a36Sopenharmony_ci	.table = {
24762306a36Sopenharmony_ci		GPIO_LOOKUP_IDX("A", 6, "cs", 0, GPIO_ACTIVE_LOW),
24862306a36Sopenharmony_ci		GPIO_LOOKUP_IDX("A", 7, "cs", 1, GPIO_ACTIVE_LOW),
24962306a36Sopenharmony_ci		GPIO_LOOKUP_IDX("G", 2, "cs", 2, GPIO_ACTIVE_LOW),
25062306a36Sopenharmony_ci		{ },
25162306a36Sopenharmony_ci	},
25262306a36Sopenharmony_ci};
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_cistatic struct ep93xx_spi_info vision_spi_master __initdata = {
25562306a36Sopenharmony_ci	.use_dma	= 1,
25662306a36Sopenharmony_ci};
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci/*************************************************************************
25962306a36Sopenharmony_ci * I2S Audio
26062306a36Sopenharmony_ci *************************************************************************/
26162306a36Sopenharmony_cistatic struct platform_device vision_audio_device = {
26262306a36Sopenharmony_ci	.name		= "edb93xx-audio",
26362306a36Sopenharmony_ci	.id		= -1,
26462306a36Sopenharmony_ci};
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_cistatic void __init vision_register_i2s(void)
26762306a36Sopenharmony_ci{
26862306a36Sopenharmony_ci	ep93xx_register_i2s();
26962306a36Sopenharmony_ci	platform_device_register(&vision_audio_device);
27062306a36Sopenharmony_ci}
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci/*************************************************************************
27362306a36Sopenharmony_ci * Machine Initialization
27462306a36Sopenharmony_ci *************************************************************************/
27562306a36Sopenharmony_cistatic void __init vision_init_machine(void)
27662306a36Sopenharmony_ci{
27762306a36Sopenharmony_ci	ep93xx_init_devices();
27862306a36Sopenharmony_ci	ep93xx_register_flash(2, EP93XX_CS6_PHYS_BASE, SZ_64M);
27962306a36Sopenharmony_ci	ep93xx_register_eth(&vision_eth_data, 1);
28062306a36Sopenharmony_ci	ep93xx_register_fb(&ep93xxfb_info);
28162306a36Sopenharmony_ci	ep93xx_register_pwm(1, 0);
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci	/*
28462306a36Sopenharmony_ci	 * Request the gpio expander's interrupt gpio line now to prevent
28562306a36Sopenharmony_ci	 * the kernel from doing a WARN in gpiolib:gpio_ensure_requested().
28662306a36Sopenharmony_ci	 */
28762306a36Sopenharmony_ci	if (gpio_request_one(EP93XX_GPIO_LINE_F(7), GPIOF_DIR_IN,
28862306a36Sopenharmony_ci				"pca9539:74"))
28962306a36Sopenharmony_ci		pr_warn("cannot request interrupt gpio for pca9539:74\n");
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci	vision_i2c_info[1].irq = gpio_to_irq(EP93XX_GPIO_LINE_F(7));
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci	ep93xx_register_i2c(vision_i2c_info,
29462306a36Sopenharmony_ci				ARRAY_SIZE(vision_i2c_info));
29562306a36Sopenharmony_ci	gpiod_add_lookup_table(&vision_spi_mmc_gpio_table);
29662306a36Sopenharmony_ci	gpiod_add_lookup_table(&vision_spi_cs_gpio_table);
29762306a36Sopenharmony_ci	ep93xx_register_spi(&vision_spi_master, vision_spi_board_info,
29862306a36Sopenharmony_ci				ARRAY_SIZE(vision_spi_board_info));
29962306a36Sopenharmony_ci	vision_register_i2s();
30062306a36Sopenharmony_ci}
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ciMACHINE_START(VISION_EP9307, "Vision Engraving Systems EP9307")
30362306a36Sopenharmony_ci	/* Maintainer: H Hartley Sweeten <hsweeten@visionengravers.com> */
30462306a36Sopenharmony_ci	.atag_offset	= 0x100,
30562306a36Sopenharmony_ci	.nr_irqs	= NR_EP93XX_IRQS + EP93XX_BOARD_IRQS,
30662306a36Sopenharmony_ci	.map_io		= vision_map_io,
30762306a36Sopenharmony_ci	.init_irq	= ep93xx_init_irq,
30862306a36Sopenharmony_ci	.init_time	= ep93xx_timer_init,
30962306a36Sopenharmony_ci	.init_machine	= vision_init_machine,
31062306a36Sopenharmony_ci	.restart	= ep93xx_restart,
31162306a36Sopenharmony_ciMACHINE_END
312