162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * arch/arm/mach-ep93xx/edb93xx.c
462306a36Sopenharmony_ci * Cirrus Logic EDB93xx Development Board support.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * EDB93XX, EDB9301, EDB9307A
762306a36Sopenharmony_ci * Copyright (C) 2008-2009 H Hartley Sweeten <hsweeten@visionengravers.com>
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci * EDB9302
1062306a36Sopenharmony_ci * Copyright (C) 2006 George Kashperko <george@chas.com.ua>
1162306a36Sopenharmony_ci *
1262306a36Sopenharmony_ci * EDB9302A, EDB9315, EDB9315A
1362306a36Sopenharmony_ci * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
1462306a36Sopenharmony_ci *
1562306a36Sopenharmony_ci * EDB9307
1662306a36Sopenharmony_ci * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org>
1762306a36Sopenharmony_ci *
1862306a36Sopenharmony_ci * EDB9312
1962306a36Sopenharmony_ci * Copyright (C) 2006 Infosys Technologies Limited
2062306a36Sopenharmony_ci *                    Toufeeq Hussain <toufeeq_hussain@infosys.com>
2162306a36Sopenharmony_ci */
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#include <linux/kernel.h>
2462306a36Sopenharmony_ci#include <linux/init.h>
2562306a36Sopenharmony_ci#include <linux/platform_device.h>
2662306a36Sopenharmony_ci#include <linux/i2c.h>
2762306a36Sopenharmony_ci#include <linux/spi/spi.h>
2862306a36Sopenharmony_ci#include <linux/gpio/machine.h>
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci#include <sound/cs4271.h>
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci#include "hardware.h"
3362306a36Sopenharmony_ci#include <linux/platform_data/video-ep93xx.h>
3462306a36Sopenharmony_ci#include <linux/platform_data/spi-ep93xx.h>
3562306a36Sopenharmony_ci#include "gpio-ep93xx.h"
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#include <asm/mach-types.h>
3862306a36Sopenharmony_ci#include <asm/mach/arch.h>
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci#include "soc.h"
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_cistatic void __init edb93xx_register_flash(void)
4362306a36Sopenharmony_ci{
4462306a36Sopenharmony_ci	if (machine_is_edb9307() || machine_is_edb9312() ||
4562306a36Sopenharmony_ci	    machine_is_edb9315()) {
4662306a36Sopenharmony_ci		ep93xx_register_flash(4, EP93XX_CS6_PHYS_BASE, SZ_32M);
4762306a36Sopenharmony_ci	} else {
4862306a36Sopenharmony_ci		ep93xx_register_flash(2, EP93XX_CS6_PHYS_BASE, SZ_16M);
4962306a36Sopenharmony_ci	}
5062306a36Sopenharmony_ci}
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_cistatic struct ep93xx_eth_data __initdata edb93xx_eth_data = {
5362306a36Sopenharmony_ci	.phy_id		= 1,
5462306a36Sopenharmony_ci};
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci/*************************************************************************
5862306a36Sopenharmony_ci * EDB93xx i2c peripheral handling
5962306a36Sopenharmony_ci *************************************************************************/
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_cistatic struct i2c_board_info __initdata edb93xxa_i2c_board_info[] = {
6262306a36Sopenharmony_ci	{
6362306a36Sopenharmony_ci		I2C_BOARD_INFO("isl1208", 0x6f),
6462306a36Sopenharmony_ci	},
6562306a36Sopenharmony_ci};
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_cistatic struct i2c_board_info __initdata edb93xx_i2c_board_info[] = {
6862306a36Sopenharmony_ci	{
6962306a36Sopenharmony_ci		I2C_BOARD_INFO("ds1337", 0x68),
7062306a36Sopenharmony_ci	},
7162306a36Sopenharmony_ci};
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_cistatic void __init edb93xx_register_i2c(void)
7462306a36Sopenharmony_ci{
7562306a36Sopenharmony_ci	if (machine_is_edb9302a() || machine_is_edb9307a() ||
7662306a36Sopenharmony_ci	    machine_is_edb9315a()) {
7762306a36Sopenharmony_ci		ep93xx_register_i2c(edb93xxa_i2c_board_info,
7862306a36Sopenharmony_ci				    ARRAY_SIZE(edb93xxa_i2c_board_info));
7962306a36Sopenharmony_ci	} else if (machine_is_edb9302() || machine_is_edb9307()
8062306a36Sopenharmony_ci		|| machine_is_edb9312() || machine_is_edb9315()) {
8162306a36Sopenharmony_ci		ep93xx_register_i2c(edb93xx_i2c_board_info,
8262306a36Sopenharmony_ci				    ARRAY_SIZE(edb93xx_i2c_board_info));
8362306a36Sopenharmony_ci	}
8462306a36Sopenharmony_ci}
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci/*************************************************************************
8862306a36Sopenharmony_ci * EDB93xx SPI peripheral handling
8962306a36Sopenharmony_ci *************************************************************************/
9062306a36Sopenharmony_cistatic struct cs4271_platform_data edb93xx_cs4271_data = {
9162306a36Sopenharmony_ci	.gpio_nreset	= -EINVAL,	/* filled in later */
9262306a36Sopenharmony_ci};
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_cistatic struct spi_board_info edb93xx_spi_board_info[] __initdata = {
9562306a36Sopenharmony_ci	{
9662306a36Sopenharmony_ci		.modalias		= "cs4271",
9762306a36Sopenharmony_ci		.platform_data		= &edb93xx_cs4271_data,
9862306a36Sopenharmony_ci		.max_speed_hz		= 6000000,
9962306a36Sopenharmony_ci		.bus_num		= 0,
10062306a36Sopenharmony_ci		.chip_select		= 0,
10162306a36Sopenharmony_ci		.mode			= SPI_MODE_3,
10262306a36Sopenharmony_ci	},
10362306a36Sopenharmony_ci};
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_cistatic struct gpiod_lookup_table edb93xx_spi_cs_gpio_table = {
10662306a36Sopenharmony_ci	.dev_id = "spi0",
10762306a36Sopenharmony_ci	.table = {
10862306a36Sopenharmony_ci		GPIO_LOOKUP("A", 6, "cs", GPIO_ACTIVE_LOW),
10962306a36Sopenharmony_ci		{ },
11062306a36Sopenharmony_ci	},
11162306a36Sopenharmony_ci};
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_cistatic struct ep93xx_spi_info edb93xx_spi_info __initdata = {
11462306a36Sopenharmony_ci	/* Intentionally left blank */
11562306a36Sopenharmony_ci};
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_cistatic void __init edb93xx_register_spi(void)
11862306a36Sopenharmony_ci{
11962306a36Sopenharmony_ci	if (machine_is_edb9301() || machine_is_edb9302())
12062306a36Sopenharmony_ci		edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_EGPIO1;
12162306a36Sopenharmony_ci	else if (machine_is_edb9302a() || machine_is_edb9307a())
12262306a36Sopenharmony_ci		edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_H(2);
12362306a36Sopenharmony_ci	else if (machine_is_edb9315a())
12462306a36Sopenharmony_ci		edb93xx_cs4271_data.gpio_nreset = EP93XX_GPIO_LINE_EGPIO14;
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci	gpiod_add_lookup_table(&edb93xx_spi_cs_gpio_table);
12762306a36Sopenharmony_ci	ep93xx_register_spi(&edb93xx_spi_info, edb93xx_spi_board_info,
12862306a36Sopenharmony_ci			    ARRAY_SIZE(edb93xx_spi_board_info));
12962306a36Sopenharmony_ci}
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci/*************************************************************************
13362306a36Sopenharmony_ci * EDB93xx I2S
13462306a36Sopenharmony_ci *************************************************************************/
13562306a36Sopenharmony_cistatic struct platform_device edb93xx_audio_device = {
13662306a36Sopenharmony_ci	.name		= "edb93xx-audio",
13762306a36Sopenharmony_ci	.id		= -1,
13862306a36Sopenharmony_ci};
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_cistatic int __init edb93xx_has_audio(void)
14162306a36Sopenharmony_ci{
14262306a36Sopenharmony_ci	return (machine_is_edb9301() || machine_is_edb9302() ||
14362306a36Sopenharmony_ci		machine_is_edb9302a() || machine_is_edb9307a() ||
14462306a36Sopenharmony_ci		machine_is_edb9315a());
14562306a36Sopenharmony_ci}
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_cistatic void __init edb93xx_register_i2s(void)
14862306a36Sopenharmony_ci{
14962306a36Sopenharmony_ci	if (edb93xx_has_audio()) {
15062306a36Sopenharmony_ci		ep93xx_register_i2s();
15162306a36Sopenharmony_ci		platform_device_register(&edb93xx_audio_device);
15262306a36Sopenharmony_ci	}
15362306a36Sopenharmony_ci}
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci/*************************************************************************
15762306a36Sopenharmony_ci * EDB93xx pwm
15862306a36Sopenharmony_ci *************************************************************************/
15962306a36Sopenharmony_cistatic void __init edb93xx_register_pwm(void)
16062306a36Sopenharmony_ci{
16162306a36Sopenharmony_ci	if (machine_is_edb9301() ||
16262306a36Sopenharmony_ci	    machine_is_edb9302() || machine_is_edb9302a()) {
16362306a36Sopenharmony_ci		/* EP9301 and EP9302 only have pwm.1 (EGPIO14) */
16462306a36Sopenharmony_ci		ep93xx_register_pwm(0, 1);
16562306a36Sopenharmony_ci	} else if (machine_is_edb9307() || machine_is_edb9307a()) {
16662306a36Sopenharmony_ci		/* EP9307 only has pwm.0 (PWMOUT) */
16762306a36Sopenharmony_ci		ep93xx_register_pwm(1, 0);
16862306a36Sopenharmony_ci	} else {
16962306a36Sopenharmony_ci		/* EP9312 and EP9315 have both */
17062306a36Sopenharmony_ci		ep93xx_register_pwm(1, 1);
17162306a36Sopenharmony_ci	}
17262306a36Sopenharmony_ci}
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci/*************************************************************************
17662306a36Sopenharmony_ci * EDB93xx framebuffer
17762306a36Sopenharmony_ci *************************************************************************/
17862306a36Sopenharmony_cistatic struct ep93xxfb_mach_info __initdata edb93xxfb_info = {
17962306a36Sopenharmony_ci	.flags		= 0,
18062306a36Sopenharmony_ci};
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_cistatic int __init edb93xx_has_fb(void)
18362306a36Sopenharmony_ci{
18462306a36Sopenharmony_ci	/* These platforms have an ep93xx with video capability */
18562306a36Sopenharmony_ci	return machine_is_edb9307() || machine_is_edb9307a() ||
18662306a36Sopenharmony_ci	       machine_is_edb9312() || machine_is_edb9315() ||
18762306a36Sopenharmony_ci	       machine_is_edb9315a();
18862306a36Sopenharmony_ci}
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_cistatic void __init edb93xx_register_fb(void)
19162306a36Sopenharmony_ci{
19262306a36Sopenharmony_ci	if (!edb93xx_has_fb())
19362306a36Sopenharmony_ci		return;
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci	if (machine_is_edb9307a() || machine_is_edb9315a())
19662306a36Sopenharmony_ci		edb93xxfb_info.flags |= EP93XXFB_USE_SDCSN0;
19762306a36Sopenharmony_ci	else
19862306a36Sopenharmony_ci		edb93xxfb_info.flags |= EP93XXFB_USE_SDCSN3;
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci	ep93xx_register_fb(&edb93xxfb_info);
20162306a36Sopenharmony_ci}
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci/*************************************************************************
20562306a36Sopenharmony_ci * EDB93xx IDE
20662306a36Sopenharmony_ci *************************************************************************/
20762306a36Sopenharmony_cistatic int __init edb93xx_has_ide(void)
20862306a36Sopenharmony_ci{
20962306a36Sopenharmony_ci	/*
21062306a36Sopenharmony_ci	 * Although EDB9312 and EDB9315 do have IDE capability, they have
21162306a36Sopenharmony_ci	 * INTRQ line wired as pull-up, which makes using IDE interface
21262306a36Sopenharmony_ci	 * problematic.
21362306a36Sopenharmony_ci	 */
21462306a36Sopenharmony_ci	return machine_is_edb9312() || machine_is_edb9315() ||
21562306a36Sopenharmony_ci	       machine_is_edb9315a();
21662306a36Sopenharmony_ci}
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_cistatic void __init edb93xx_register_ide(void)
21962306a36Sopenharmony_ci{
22062306a36Sopenharmony_ci	if (!edb93xx_has_ide())
22162306a36Sopenharmony_ci		return;
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci	ep93xx_register_ide();
22462306a36Sopenharmony_ci}
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_cistatic void __init edb93xx_init_machine(void)
22862306a36Sopenharmony_ci{
22962306a36Sopenharmony_ci	ep93xx_init_devices();
23062306a36Sopenharmony_ci	edb93xx_register_flash();
23162306a36Sopenharmony_ci	ep93xx_register_eth(&edb93xx_eth_data, 1);
23262306a36Sopenharmony_ci	edb93xx_register_i2c();
23362306a36Sopenharmony_ci	edb93xx_register_spi();
23462306a36Sopenharmony_ci	edb93xx_register_i2s();
23562306a36Sopenharmony_ci	edb93xx_register_pwm();
23662306a36Sopenharmony_ci	edb93xx_register_fb();
23762306a36Sopenharmony_ci	edb93xx_register_ide();
23862306a36Sopenharmony_ci	ep93xx_register_adc();
23962306a36Sopenharmony_ci}
24062306a36Sopenharmony_ci
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci#ifdef CONFIG_MACH_EDB9301
24362306a36Sopenharmony_ciMACHINE_START(EDB9301, "Cirrus Logic EDB9301 Evaluation Board")
24462306a36Sopenharmony_ci	/* Maintainer: H Hartley Sweeten <hsweeten@visionengravers.com> */
24562306a36Sopenharmony_ci	.atag_offset	= 0x100,
24662306a36Sopenharmony_ci	.nr_irqs	= NR_EP93XX_IRQS,
24762306a36Sopenharmony_ci	.map_io		= ep93xx_map_io,
24862306a36Sopenharmony_ci	.init_irq	= ep93xx_init_irq,
24962306a36Sopenharmony_ci	.init_time	= ep93xx_timer_init,
25062306a36Sopenharmony_ci	.init_machine	= edb93xx_init_machine,
25162306a36Sopenharmony_ci	.restart	= ep93xx_restart,
25262306a36Sopenharmony_ciMACHINE_END
25362306a36Sopenharmony_ci#endif
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci#ifdef CONFIG_MACH_EDB9302
25662306a36Sopenharmony_ciMACHINE_START(EDB9302, "Cirrus Logic EDB9302 Evaluation Board")
25762306a36Sopenharmony_ci	/* Maintainer: George Kashperko <george@chas.com.ua> */
25862306a36Sopenharmony_ci	.atag_offset	= 0x100,
25962306a36Sopenharmony_ci	.nr_irqs	= NR_EP93XX_IRQS,
26062306a36Sopenharmony_ci	.map_io		= ep93xx_map_io,
26162306a36Sopenharmony_ci	.init_irq	= ep93xx_init_irq,
26262306a36Sopenharmony_ci	.init_time	= ep93xx_timer_init,
26362306a36Sopenharmony_ci	.init_machine	= edb93xx_init_machine,
26462306a36Sopenharmony_ci	.restart	= ep93xx_restart,
26562306a36Sopenharmony_ciMACHINE_END
26662306a36Sopenharmony_ci#endif
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci#ifdef CONFIG_MACH_EDB9302A
26962306a36Sopenharmony_ciMACHINE_START(EDB9302A, "Cirrus Logic EDB9302A Evaluation Board")
27062306a36Sopenharmony_ci	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
27162306a36Sopenharmony_ci	.atag_offset	= 0x100,
27262306a36Sopenharmony_ci	.nr_irqs	= NR_EP93XX_IRQS,
27362306a36Sopenharmony_ci	.map_io		= ep93xx_map_io,
27462306a36Sopenharmony_ci	.init_irq	= ep93xx_init_irq,
27562306a36Sopenharmony_ci	.init_time	= ep93xx_timer_init,
27662306a36Sopenharmony_ci	.init_machine	= edb93xx_init_machine,
27762306a36Sopenharmony_ci	.restart	= ep93xx_restart,
27862306a36Sopenharmony_ciMACHINE_END
27962306a36Sopenharmony_ci#endif
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci#ifdef CONFIG_MACH_EDB9307
28262306a36Sopenharmony_ciMACHINE_START(EDB9307, "Cirrus Logic EDB9307 Evaluation Board")
28362306a36Sopenharmony_ci	/* Maintainer: Herbert Valerio Riedel <hvr@gnu.org> */
28462306a36Sopenharmony_ci	.atag_offset	= 0x100,
28562306a36Sopenharmony_ci	.nr_irqs	= NR_EP93XX_IRQS,
28662306a36Sopenharmony_ci	.map_io		= ep93xx_map_io,
28762306a36Sopenharmony_ci	.init_irq	= ep93xx_init_irq,
28862306a36Sopenharmony_ci	.init_time	= ep93xx_timer_init,
28962306a36Sopenharmony_ci	.init_machine	= edb93xx_init_machine,
29062306a36Sopenharmony_ci	.restart	= ep93xx_restart,
29162306a36Sopenharmony_ciMACHINE_END
29262306a36Sopenharmony_ci#endif
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci#ifdef CONFIG_MACH_EDB9307A
29562306a36Sopenharmony_ciMACHINE_START(EDB9307A, "Cirrus Logic EDB9307A Evaluation Board")
29662306a36Sopenharmony_ci	/* Maintainer: H Hartley Sweeten <hsweeten@visionengravers.com> */
29762306a36Sopenharmony_ci	.atag_offset	= 0x100,
29862306a36Sopenharmony_ci	.nr_irqs	= NR_EP93XX_IRQS,
29962306a36Sopenharmony_ci	.map_io		= ep93xx_map_io,
30062306a36Sopenharmony_ci	.init_irq	= ep93xx_init_irq,
30162306a36Sopenharmony_ci	.init_time	= ep93xx_timer_init,
30262306a36Sopenharmony_ci	.init_machine	= edb93xx_init_machine,
30362306a36Sopenharmony_ci	.restart	= ep93xx_restart,
30462306a36Sopenharmony_ciMACHINE_END
30562306a36Sopenharmony_ci#endif
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_ci#ifdef CONFIG_MACH_EDB9312
30862306a36Sopenharmony_ciMACHINE_START(EDB9312, "Cirrus Logic EDB9312 Evaluation Board")
30962306a36Sopenharmony_ci	/* Maintainer: Toufeeq Hussain <toufeeq_hussain@infosys.com> */
31062306a36Sopenharmony_ci	.atag_offset	= 0x100,
31162306a36Sopenharmony_ci	.nr_irqs	= NR_EP93XX_IRQS,
31262306a36Sopenharmony_ci	.map_io		= ep93xx_map_io,
31362306a36Sopenharmony_ci	.init_irq	= ep93xx_init_irq,
31462306a36Sopenharmony_ci	.init_time	= ep93xx_timer_init,
31562306a36Sopenharmony_ci	.init_machine	= edb93xx_init_machine,
31662306a36Sopenharmony_ci	.restart	= ep93xx_restart,
31762306a36Sopenharmony_ciMACHINE_END
31862306a36Sopenharmony_ci#endif
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci#ifdef CONFIG_MACH_EDB9315
32162306a36Sopenharmony_ciMACHINE_START(EDB9315, "Cirrus Logic EDB9315 Evaluation Board")
32262306a36Sopenharmony_ci	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
32362306a36Sopenharmony_ci	.atag_offset	= 0x100,
32462306a36Sopenharmony_ci	.nr_irqs	= NR_EP93XX_IRQS,
32562306a36Sopenharmony_ci	.map_io		= ep93xx_map_io,
32662306a36Sopenharmony_ci	.init_irq	= ep93xx_init_irq,
32762306a36Sopenharmony_ci	.init_time	= ep93xx_timer_init,
32862306a36Sopenharmony_ci	.init_machine	= edb93xx_init_machine,
32962306a36Sopenharmony_ci	.restart	= ep93xx_restart,
33062306a36Sopenharmony_ciMACHINE_END
33162306a36Sopenharmony_ci#endif
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci#ifdef CONFIG_MACH_EDB9315A
33462306a36Sopenharmony_ciMACHINE_START(EDB9315A, "Cirrus Logic EDB9315A Evaluation Board")
33562306a36Sopenharmony_ci	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
33662306a36Sopenharmony_ci	.atag_offset	= 0x100,
33762306a36Sopenharmony_ci	.nr_irqs	= NR_EP93XX_IRQS,
33862306a36Sopenharmony_ci	.map_io		= ep93xx_map_io,
33962306a36Sopenharmony_ci	.init_irq	= ep93xx_init_irq,
34062306a36Sopenharmony_ci	.init_time	= ep93xx_timer_init,
34162306a36Sopenharmony_ci	.init_machine	= edb93xx_init_machine,
34262306a36Sopenharmony_ci	.restart	= ep93xx_restart,
34362306a36Sopenharmony_ciMACHINE_END
34462306a36Sopenharmony_ci#endif
345