diff options
Diffstat (limited to 'arch/arm/mach-omap2/board-4430sdp.c')
-rw-r--r-- | arch/arm/mach-omap2/board-4430sdp.c | 563 |
1 files changed, 540 insertions, 23 deletions
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c index 57e477bd89c6..a70bdf28e2bc 100644 --- a/arch/arm/mach-omap2/board-4430sdp.c +++ b/arch/arm/mach-omap2/board-4430sdp.c @@ -17,17 +17,207 @@ #include <linux/platform_device.h> #include <linux/io.h> #include <linux/gpio.h> +#include <linux/usb/otg.h> +#include <linux/spi/spi.h> +#include <linux/i2c/twl.h> +#include <linux/gpio_keys.h> +#include <linux/regulator/machine.h> +#include <linux/leds.h> +#include <linux/leds_pwm.h> #include <mach/hardware.h> +#include <mach/omap4-common.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <mach/board.h> -#include <mach/common.h> -#include <mach/control.h> -#include <mach/timer-gp.h> -#include <asm/hardware/gic.h> +#include <plat/board.h> +#include <plat/common.h> +#include <plat/usb.h> +#include <plat/mmc.h> + +#include "mux.h" +#include "hsmmc.h" +#include "timer-gp.h" +#include "control.h" + +#define ETH_KS8851_IRQ 34 +#define ETH_KS8851_POWER_ON 48 +#define ETH_KS8851_QUART 138 +#define OMAP4SDP_MDM_PWR_EN_GPIO 157 +#define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO 184 +#define OMAP4_SFH7741_ENABLE_GPIO 188 + +static struct gpio_led sdp4430_gpio_leds[] = { + { + .name = "omap4:green:debug0", + .gpio = 61, + }, + { + .name = "omap4:green:debug1", + .gpio = 30, + }, + { + .name = "omap4:green:debug2", + .gpio = 7, + }, + { + .name = "omap4:green:debug3", + .gpio = 8, + }, + { + .name = "omap4:green:debug4", + .gpio = 50, + }, + { + .name = "omap4:blue:user", + .gpio = 169, + }, + { + .name = "omap4:red:user", + .gpio = 170, + }, + { + .name = "omap4:green:user", + .gpio = 139, + }, + +}; + +static struct gpio_keys_button sdp4430_gpio_keys[] = { + { + .desc = "Proximity Sensor", + .type = EV_SW, + .code = SW_FRONT_PROXIMITY, + .gpio = OMAP4_SFH7741_SENSOR_OUTPUT_GPIO, + .active_low = 0, + } +}; + +static struct gpio_led_platform_data sdp4430_led_data = { + .leds = sdp4430_gpio_leds, + .num_leds = ARRAY_SIZE(sdp4430_gpio_leds), +}; + +static struct led_pwm sdp4430_pwm_leds[] = { + { + .name = "omap4:green:chrg", + .pwm_id = 1, + .max_brightness = 255, + .pwm_period_ns = 7812500, + }, +}; + +static struct led_pwm_platform_data sdp4430_pwm_data = { + .num_leds = ARRAY_SIZE(sdp4430_pwm_leds), + .leds = sdp4430_pwm_leds, +}; + +static struct platform_device sdp4430_leds_pwm = { + .name = "leds_pwm", + .id = -1, + .dev = { + .platform_data = &sdp4430_pwm_data, + }, +}; + +static int omap_prox_activate(struct device *dev) +{ + gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 1); + return 0; +} + +static void omap_prox_deactivate(struct device *dev) +{ + gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 0); +} + +static struct gpio_keys_platform_data sdp4430_gpio_keys_data = { + .buttons = sdp4430_gpio_keys, + .nbuttons = ARRAY_SIZE(sdp4430_gpio_keys), + .enable = omap_prox_activate, + .disable = omap_prox_deactivate, +}; + +static struct platform_device sdp4430_gpio_keys_device = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &sdp4430_gpio_keys_data, + }, +}; + +static struct platform_device sdp4430_leds_gpio = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &sdp4430_led_data, + }, +}; +static struct spi_board_info sdp4430_spi_board_info[] __initdata = { + { + .modalias = "ks8851", + .bus_num = 1, + .chip_select = 0, + .max_speed_hz = 24000000, + .irq = ETH_KS8851_IRQ, + }, +}; + +static int omap_ethernet_init(void) +{ + int status; + + /* Request of GPIO lines */ + + status = gpio_request(ETH_KS8851_POWER_ON, "eth_power"); + if (status) { + pr_err("Cannot request GPIO %d\n", ETH_KS8851_POWER_ON); + return status; + } + + status = gpio_request(ETH_KS8851_QUART, "quart"); + if (status) { + pr_err("Cannot request GPIO %d\n", ETH_KS8851_QUART); + goto error1; + } + + status = gpio_request(ETH_KS8851_IRQ, "eth_irq"); + if (status) { + pr_err("Cannot request GPIO %d\n", ETH_KS8851_IRQ); + goto error2; + } + + /* Configuration of requested GPIO lines */ + + status = gpio_direction_output(ETH_KS8851_POWER_ON, 1); + if (status) { + pr_err("Cannot set output GPIO %d\n", ETH_KS8851_IRQ); + goto error3; + } + + status = gpio_direction_output(ETH_KS8851_QUART, 1); + if (status) { + pr_err("Cannot set output GPIO %d\n", ETH_KS8851_QUART); + goto error3; + } + + status = gpio_direction_input(ETH_KS8851_IRQ); + if (status) { + pr_err("Cannot set input GPIO %d\n", ETH_KS8851_IRQ); + goto error3; + } + + return 0; + +error3: + gpio_free(ETH_KS8851_IRQ); +error2: + gpio_free(ETH_KS8851_QUART); +error1: + gpio_free(ETH_KS8851_POWER_ON); + return status; +} static struct platform_device sdp4430_lcd_device = { .name = "sdp4430_lcd", @@ -36,10 +226,9 @@ static struct platform_device sdp4430_lcd_device = { static struct platform_device *sdp4430_devices[] __initdata = { &sdp4430_lcd_device, -}; - -static struct omap_uart_config sdp4430_uart_config __initdata = { - .enabled_uarts = (1 << 0) | (1 << 1) | (1 << 2), + &sdp4430_gpio_keys_device, + &sdp4430_leds_gpio, + &sdp4430_leds_pwm, }; static struct omap_lcd_config sdp4430_lcd_config __initdata = { @@ -47,47 +236,375 @@ static struct omap_lcd_config sdp4430_lcd_config __initdata = { }; static struct omap_board_config_kernel sdp4430_config[] __initdata = { - { OMAP_TAG_UART, &sdp4430_uart_config }, { OMAP_TAG_LCD, &sdp4430_lcd_config }, }; -static void __init gic_init_irq(void) -{ - gic_dist_init(0, IO_ADDRESS(OMAP44XX_GIC_DIST_BASE), 29); - gic_cpu_init(0, IO_ADDRESS(OMAP44XX_GIC_CPU_BASE)); -} - static void __init omap_4430sdp_init_irq(void) { - omap2_init_common_hw(NULL); + omap_board_config = sdp4430_config; + omap_board_config_size = ARRAY_SIZE(sdp4430_config); + omap2_init_common_infrastructure(); + omap2_init_common_devices(NULL, NULL); #ifdef CONFIG_OMAP_32K_TIMER omap2_gp_clockevent_set_gptimer(1); #endif gic_init_irq(); - omap_gpio_init(); } +static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = { + .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY, + .port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN, + .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN, + .phy_reset = false, + .reset_gpio_port[0] = -EINVAL, + .reset_gpio_port[1] = -EINVAL, + .reset_gpio_port[2] = -EINVAL, +}; + +static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_UTMI, + .mode = MUSB_OTG, + .power = 100, +}; + +static struct twl4030_usb_data omap4_usbphy_data = { + .phy_init = omap4430_phy_init, + .phy_exit = omap4430_phy_exit, + .phy_power = omap4430_phy_power, + .phy_set_clock = omap4430_phy_set_clk, +}; + +static struct omap2_hsmmc_info mmc[] = { + { + .mmc = 1, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, + .gpio_wp = -EINVAL, + }, + { + .mmc = 2, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, + .gpio_cd = -EINVAL, + .gpio_wp = -EINVAL, + .nonremovable = true, + .ocr_mask = MMC_VDD_29_30, + }, + {} /* Terminator */ +}; + +static struct regulator_consumer_supply sdp4430_vaux_supply[] = { + { + .supply = "vmmc", + .dev_name = "mmci-omap-hs.1", + }, +}; +static struct regulator_consumer_supply sdp4430_vmmc_supply[] = { + { + .supply = "vmmc", + .dev_name = "mmci-omap-hs.0", + }, +}; + +static int omap4_twl6030_hsmmc_late_init(struct device *dev) +{ + int ret = 0; + struct platform_device *pdev = container_of(dev, + struct platform_device, dev); + struct omap_mmc_platform_data *pdata = dev->platform_data; + + /* Setting MMC1 Card detect Irq */ + if (pdev->id == 0) { + ret = twl6030_mmc_card_detect_config(); + if (ret) + pr_err("Failed configuring MMC1 card detect\n"); + pdata->slots[0].card_detect_irq = TWL6030_IRQ_BASE + + MMCDETECT_INTR_OFFSET; + pdata->slots[0].card_detect = twl6030_mmc_card_detect; + } + return ret; +} + +static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev) +{ + struct omap_mmc_platform_data *pdata; + + /* dev can be null if CONFIG_MMC_OMAP_HS is not set */ + if (!dev) { + pr_err("Failed %s\n", __func__); + return; + } + pdata = dev->platform_data; + pdata->init = omap4_twl6030_hsmmc_late_init; +} + +static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers) +{ + struct omap2_hsmmc_info *c; + + omap2_hsmmc_init(controllers); + for (c = controllers; c->mmc; c++) + omap4_twl6030_hsmmc_set_late_init(c->dev); + + return 0; +} + +static struct regulator_init_data sdp4430_vaux1 = { + .constraints = { + .min_uV = 1000000, + .max_uV = 3000000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = sdp4430_vaux_supply, +}; + +static struct regulator_init_data sdp4430_vaux2 = { + .constraints = { + .min_uV = 1200000, + .max_uV = 2800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data sdp4430_vaux3 = { + .constraints = { + .min_uV = 1000000, + .max_uV = 3000000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +/* VMMC1 for MMC1 card */ +static struct regulator_init_data sdp4430_vmmc = { + .constraints = { + .min_uV = 1200000, + .max_uV = 3000000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = sdp4430_vmmc_supply, +}; + +static struct regulator_init_data sdp4430_vpp = { + .constraints = { + .min_uV = 1800000, + .max_uV = 2500000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data sdp4430_vusim = { + .constraints = { + .min_uV = 1200000, + .max_uV = 2900000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data sdp4430_vana = { + .constraints = { + .min_uV = 2100000, + .max_uV = 2100000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data sdp4430_vcxio = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data sdp4430_vdac = { + .constraints = { + .min_uV = 1800000, + .max_uV = 1800000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct regulator_init_data sdp4430_vusb = { + .constraints = { + .min_uV = 3300000, + .max_uV = 3300000, + .apply_uV = true, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, +}; + +static struct twl4030_platform_data sdp4430_twldata = { + .irq_base = TWL6030_IRQ_BASE, + .irq_end = TWL6030_IRQ_END, + + /* Regulators */ + .vmmc = &sdp4430_vmmc, + .vpp = &sdp4430_vpp, + .vusim = &sdp4430_vusim, + .vana = &sdp4430_vana, + .vcxio = &sdp4430_vcxio, + .vdac = &sdp4430_vdac, + .vusb = &sdp4430_vusb, + .vaux1 = &sdp4430_vaux1, + .vaux2 = &sdp4430_vaux2, + .vaux3 = &sdp4430_vaux3, + .usb = &omap4_usbphy_data +}; + +static struct i2c_board_info __initdata sdp4430_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl6030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = OMAP44XX_IRQ_SYS_1N, + .platform_data = &sdp4430_twldata, + }, +}; +static struct i2c_board_info __initdata sdp4430_i2c_3_boardinfo[] = { + { + I2C_BOARD_INFO("tmp105", 0x48), + }, + { + I2C_BOARD_INFO("bh1780", 0x29), + }, +}; +static struct i2c_board_info __initdata sdp4430_i2c_4_boardinfo[] = { + { + I2C_BOARD_INFO("hmc5843", 0x1e), + }, +}; +static int __init omap4_i2c_init(void) +{ + /* + * Phoenix Audio IC needs I2C1 to + * start with 400 KHz or less + */ + omap_register_i2c_bus(1, 400, sdp4430_i2c_boardinfo, + ARRAY_SIZE(sdp4430_i2c_boardinfo)); + omap_register_i2c_bus(2, 400, NULL, 0); + omap_register_i2c_bus(3, 400, sdp4430_i2c_3_boardinfo, + ARRAY_SIZE(sdp4430_i2c_3_boardinfo)); + omap_register_i2c_bus(4, 400, sdp4430_i2c_4_boardinfo, + ARRAY_SIZE(sdp4430_i2c_4_boardinfo)); + return 0; +} + +static void __init omap_sfh7741prox_init(void) +{ + int error; + + error = gpio_request(OMAP4_SFH7741_ENABLE_GPIO, "sfh7741"); + if (error < 0) { + pr_err("%s:failed to request GPIO %d, error %d\n", + __func__, OMAP4_SFH7741_ENABLE_GPIO, error); + return; + } + + error = gpio_direction_output(OMAP4_SFH7741_ENABLE_GPIO , 0); + if (error < 0) { + pr_err("%s: GPIO configuration failed: GPIO %d,error %d\n", + __func__, OMAP4_SFH7741_ENABLE_GPIO, error); + gpio_free(OMAP4_SFH7741_ENABLE_GPIO); + } +} + +#ifdef CONFIG_OMAP_MUX +static struct omap_board_mux board_mux[] __initdata = { + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#else +#define board_mux NULL +#endif static void __init omap_4430sdp_init(void) { + int status; + int package = OMAP_PACKAGE_CBS; + + if (omap_rev() == OMAP4430_REV_ES1_0) + package = OMAP_PACKAGE_CBL; + omap4_mux_init(board_mux, package); + + omap4_i2c_init(); + omap_sfh7741prox_init(); platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices)); - omap_board_config = sdp4430_config; - omap_board_config_size = ARRAY_SIZE(sdp4430_config); omap_serial_init(); + omap4_twl6030_hsmmc_init(mmc); + + /* Power on the ULPI PHY */ + if (gpio_is_valid(OMAP4SDP_MDM_PWR_EN_GPIO)) { + /* FIXME: Assumes pad is already muxed for GPIO mode */ + gpio_request(OMAP4SDP_MDM_PWR_EN_GPIO, "USBB1 PHY VMDM_3V3"); + gpio_direction_output(OMAP4SDP_MDM_PWR_EN_GPIO, 1); + } + usb_ehci_init(&ehci_pdata); + usb_musb_init(&musb_board_data); + + status = omap_ethernet_init(); + if (status) { + pr_err("Ethernet initialization failed: %d\n", status); + } else { + sdp4430_spi_board_info[0].irq = gpio_to_irq(ETH_KS8851_IRQ); + spi_register_board_info(sdp4430_spi_board_info, + ARRAY_SIZE(sdp4430_spi_board_info)); + } } static void __init omap_4430sdp_map_io(void) { omap2_set_globals_443x(); - omap2_map_common_io(); + omap44xx_map_common_io(); } MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board") /* Maintainer: Santosh Shilimkar - Texas Instruments Inc */ - .phys_io = 0x48000000, - .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc, .boot_params = 0x80000100, .map_io = omap_4430sdp_map_io, + .reserve = omap_reserve, .init_irq = omap_4430sdp_init_irq, .init_machine = omap_4430sdp_init, .timer = &omap_timer, |