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