diff options
Diffstat (limited to 'arch/arm/mach-ux500/board-mop500.c')
-rw-r--r-- | arch/arm/mach-ux500/board-mop500.c | 375 |
1 files changed, 313 insertions, 62 deletions
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index a393f57..6e1907fa 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -17,72 +17,62 @@ #include <linux/gpio.h> #include <linux/amba/bus.h> #include <linux/amba/pl022.h> +#include <linux/amba/serial.h> #include <linux/spi/spi.h> #include <linux/mfd/ab8500.h> +#include <linux/regulator/ab8500.h> #include <linux/mfd/tc3589x.h> +#include <linux/mfd/tps6105x.h> +#include <linux/mfd/ab8500/gpio.h> +#include <linux/leds-lp5521.h> +#include <linux/input.h> +#include <linux/gpio_keys.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -#include <plat/pincfg.h> #include <plat/i2c.h> +#include <plat/ste_dma40.h> #include <mach/hardware.h> #include <mach/setup.h> #include <mach/devices.h> #include <mach/irqs.h> +#include "ste-dma40-db8500.h" #include "devices-db8500.h" -#include "pins-db8500.h" #include "board-mop500.h" #include "board-mop500-regulators.h" -static pin_cfg_t mop500_pins[] = { - /* SSP0 */ - GPIO143_SSP0_CLK, - GPIO144_SSP0_FRM, - GPIO145_SSP0_RXD, - GPIO146_SSP0_TXD, - - /* I2C */ - GPIO147_I2C0_SCL, - GPIO148_I2C0_SDA, - GPIO16_I2C1_SCL, - GPIO17_I2C1_SDA, - GPIO10_I2C2_SDA, - GPIO11_I2C2_SCL, - GPIO229_I2C3_SDA, - GPIO230_I2C3_SCL, - - /* SKE keypad */ - GPIO153_KP_I7, - GPIO154_KP_I6, - GPIO155_KP_I5, - GPIO156_KP_I4, - GPIO157_KP_O7, - GPIO158_KP_O6, - GPIO159_KP_O5, - GPIO160_KP_O4, - GPIO161_KP_I3, - GPIO162_KP_I2, - GPIO163_KP_I1, - GPIO164_KP_I0, - GPIO165_KP_O3, - GPIO166_KP_O2, - GPIO167_KP_O1, - GPIO168_KP_O0, - - /* GPIO_EXP_INT */ - GPIO217_GPIO, - - /* STMPE1601 IRQ */ - GPIO218_GPIO | PIN_INPUT_PULLUP, +static struct ab8500_gpio_platform_data ab8500_gpio_pdata = { + .gpio_base = MOP500_AB8500_GPIO(0), + .irq_base = MOP500_AB8500_VIR_GPIO_IRQ_BASE, + /* config_reg is the initial configuration of ab8500 pins. + * The pins can be configured as GPIO or alt functions based + * on value present in GpioSel1 to GpioSel6 and AlternatFunction + * register. This is the array of 7 configuration settings. + * One has to compile time decide these settings. Below is the + * explanation of these setting + * GpioSel1 = 0x00 => Pins GPIO1 to GPIO8 are not used as GPIO + * GpioSel2 = 0x1E => Pins GPIO10 to GPIO13 are configured as GPIO + * GpioSel3 = 0x80 => Pin GPIO24 is configured as GPIO + * GpioSel4 = 0x01 => Pin GPIo25 is configured as GPIO + * GpioSel5 = 0x7A => Pins GPIO34, GPIO36 to GPIO39 are conf as GPIO + * GpioSel6 = 0x00 => Pins GPIO41 & GPIo42 are not configured as GPIO + * AlternaFunction = 0x00 => If Pins GPIO10 to 13 are not configured + * as GPIO then this register selectes the alternate fucntions + */ + .config_reg = {0x00, 0x1E, 0x80, 0x01, + 0x7A, 0x00, 0x00}, }; static struct ab8500_platform_data ab8500_platdata = { .irq_base = MOP500_AB8500_IRQ_BASE, + .regulator_reg_init = ab8500_regulator_reg_init, + .num_regulator_reg_init = ARRAY_SIZE(ab8500_regulator_reg_init), .regulator = ab8500_regulators, .num_regulator = ARRAY_SIZE(ab8500_regulators), + .gpio = &ab8500_gpio_pdata, }; static struct resource ab8500_resources[] = { @@ -103,14 +93,13 @@ struct platform_device ab8500_device = { .resource = ab8500_resources, }; -static struct pl022_ssp_controller ssp0_platform_data = { - .bus_id = 0, - /* pl022 not yet supports dma */ - .enable_dma = 0, - /* on this platform, gpio 31,142,144,214 & - * 224 are connected as chip selects - */ - .num_chipselect = 5, +/* + * TPS61052 + */ + +static struct tps6105x_platform_data mop500_tps61052_data = { + .mode = TPS6105X_MODE_VOLTAGE, + .regulator_data = &tps61052_regulator, }; /* @@ -133,12 +122,86 @@ static struct tc3589x_platform_data mop500_tc35892_data = { .irq_base = MOP500_EGPIO_IRQ_BASE, }; -static struct i2c_board_info mop500_i2c0_devices[] = { +static struct lp5521_led_config lp5521_pri_led[] = { + [0] = { + .chan_nr = 0, + .led_current = 0x2f, + .max_current = 0x5f, + }, + [1] = { + .chan_nr = 1, + .led_current = 0x2f, + .max_current = 0x5f, + }, + [2] = { + .chan_nr = 2, + .led_current = 0x2f, + .max_current = 0x5f, + }, +}; + +static struct lp5521_platform_data __initdata lp5521_pri_data = { + .label = "lp5521_pri", + .led_config = &lp5521_pri_led[0], + .num_channels = 3, + .clock_mode = LP5521_CLOCK_EXT, +}; + +static struct lp5521_led_config lp5521_sec_led[] = { + [0] = { + .chan_nr = 0, + .led_current = 0x2f, + .max_current = 0x5f, + }, + [1] = { + .chan_nr = 1, + .led_current = 0x2f, + .max_current = 0x5f, + }, + [2] = { + .chan_nr = 2, + .led_current = 0x2f, + .max_current = 0x5f, + }, +}; + +static struct lp5521_platform_data __initdata lp5521_sec_data = { + .label = "lp5521_sec", + .led_config = &lp5521_sec_led[0], + .num_channels = 3, + .clock_mode = LP5521_CLOCK_EXT, +}; + +static struct i2c_board_info __initdata mop500_i2c0_devices[] = { { I2C_BOARD_INFO("tc3589x", 0x42), - .irq = NOMADIK_GPIO_TO_IRQ(217), + .irq = NOMADIK_GPIO_TO_IRQ(217), .platform_data = &mop500_tc35892_data, }, + /* I2C0 devices only available prior to HREFv60 */ + { + I2C_BOARD_INFO("tps61052", 0x33), + .platform_data = &mop500_tps61052_data, + }, +}; + +#define NUM_PRE_V60_I2C0_DEVICES 1 + +static struct i2c_board_info __initdata mop500_i2c2_devices[] = { + { + /* lp5521 LED driver, 1st device */ + I2C_BOARD_INFO("lp5521", 0x33), + .platform_data = &lp5521_pri_data, + }, + { + /* lp5521 LED driver, 2st device */ + I2C_BOARD_INFO("lp5521", 0x34), + .platform_data = &lp5521_sec_data, + }, + { + /* Light sensor Rohm BH1780GLI */ + I2C_BOARD_INFO("bh1780", 0x29), + }, }; #define U8500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, _sm) \ @@ -178,8 +241,93 @@ static void __init mop500_i2c_init(void) db8500_add_i2c3(&u8500_i2c3_data); } +static struct gpio_keys_button mop500_gpio_keys[] = { + { + .desc = "SFH7741 Proximity Sensor", + .type = EV_SW, + .code = SW_FRONT_PROXIMITY, + .active_low = 0, + .can_disable = 1, + } +}; + +static struct regulator *prox_regulator; +static int mop500_prox_activate(struct device *dev); +static void mop500_prox_deactivate(struct device *dev); + +static struct gpio_keys_platform_data mop500_gpio_keys_data = { + .buttons = mop500_gpio_keys, + .nbuttons = ARRAY_SIZE(mop500_gpio_keys), + .enable = mop500_prox_activate, + .disable = mop500_prox_deactivate, +}; + +static struct platform_device mop500_gpio_keys_device = { + .name = "gpio-keys", + .id = 0, + .dev = { + .platform_data = &mop500_gpio_keys_data, + }, +}; + +static int mop500_prox_activate(struct device *dev) +{ + prox_regulator = regulator_get(&mop500_gpio_keys_device.dev, + "vcc"); + if (IS_ERR(prox_regulator)) { + dev_err(&mop500_gpio_keys_device.dev, + "no regulator\n"); + return PTR_ERR(prox_regulator); + } + regulator_enable(prox_regulator); + return 0; +} + +static void mop500_prox_deactivate(struct device *dev) +{ + regulator_disable(prox_regulator); + regulator_put(prox_regulator); +} + /* add any platform devices here - TODO */ static struct platform_device *platform_devs[] __initdata = { + &mop500_gpio_keys_device, +}; + +#ifdef CONFIG_STE_DMA40 +static struct stedma40_chan_cfg ssp0_dma_cfg_rx = { + .mode = STEDMA40_MODE_LOGICAL, + .dir = STEDMA40_PERIPH_TO_MEM, + .src_dev_type = DB8500_DMA_DEV8_SSP0_RX, + .dst_dev_type = STEDMA40_DEV_DST_MEMORY, + .src_info.data_width = STEDMA40_BYTE_WIDTH, + .dst_info.data_width = STEDMA40_BYTE_WIDTH, +}; + +static struct stedma40_chan_cfg ssp0_dma_cfg_tx = { + .mode = STEDMA40_MODE_LOGICAL, + .dir = STEDMA40_MEM_TO_PERIPH, + .src_dev_type = STEDMA40_DEV_SRC_MEMORY, + .dst_dev_type = DB8500_DMA_DEV8_SSP0_TX, + .src_info.data_width = STEDMA40_BYTE_WIDTH, + .dst_info.data_width = STEDMA40_BYTE_WIDTH, +}; +#endif + +static struct pl022_ssp_controller ssp0_platform_data = { + .bus_id = 0, +#ifdef CONFIG_STE_DMA40 + .enable_dma = 1, + .dma_filter = stedma40_filter, + .dma_rx_param = &ssp0_dma_cfg_rx, + .dma_tx_param = &ssp0_dma_cfg_tx, +#else + .enable_dma = 0, +#endif + /* on this platform, gpio 31,142,144,214 & + * 224 are connected as chip selects + */ + .num_chipselect = 5, }; static void __init mop500_spi_init(void) @@ -187,18 +335,110 @@ static void __init mop500_spi_init(void) db8500_add_ssp0(&ssp0_platform_data); } +#ifdef CONFIG_STE_DMA40 +static struct stedma40_chan_cfg uart0_dma_cfg_rx = { + .mode = STEDMA40_MODE_LOGICAL, + .dir = STEDMA40_PERIPH_TO_MEM, + .src_dev_type = DB8500_DMA_DEV13_UART0_RX, + .dst_dev_type = STEDMA40_DEV_DST_MEMORY, + .src_info.data_width = STEDMA40_BYTE_WIDTH, + .dst_info.data_width = STEDMA40_BYTE_WIDTH, +}; + +static struct stedma40_chan_cfg uart0_dma_cfg_tx = { + .mode = STEDMA40_MODE_LOGICAL, + .dir = STEDMA40_MEM_TO_PERIPH, + .src_dev_type = STEDMA40_DEV_SRC_MEMORY, + .dst_dev_type = DB8500_DMA_DEV13_UART0_TX, + .src_info.data_width = STEDMA40_BYTE_WIDTH, + .dst_info.data_width = STEDMA40_BYTE_WIDTH, +}; + +static struct stedma40_chan_cfg uart1_dma_cfg_rx = { + .mode = STEDMA40_MODE_LOGICAL, + .dir = STEDMA40_PERIPH_TO_MEM, + .src_dev_type = DB8500_DMA_DEV12_UART1_RX, + .dst_dev_type = STEDMA40_DEV_DST_MEMORY, + .src_info.data_width = STEDMA40_BYTE_WIDTH, + .dst_info.data_width = STEDMA40_BYTE_WIDTH, +}; + +static struct stedma40_chan_cfg uart1_dma_cfg_tx = { + .mode = STEDMA40_MODE_LOGICAL, + .dir = STEDMA40_MEM_TO_PERIPH, + .src_dev_type = STEDMA40_DEV_SRC_MEMORY, + .dst_dev_type = DB8500_DMA_DEV12_UART1_TX, + .src_info.data_width = STEDMA40_BYTE_WIDTH, + .dst_info.data_width = STEDMA40_BYTE_WIDTH, +}; + +static struct stedma40_chan_cfg uart2_dma_cfg_rx = { + .mode = STEDMA40_MODE_LOGICAL, + .dir = STEDMA40_PERIPH_TO_MEM, + .src_dev_type = DB8500_DMA_DEV11_UART2_RX, + .dst_dev_type = STEDMA40_DEV_DST_MEMORY, + .src_info.data_width = STEDMA40_BYTE_WIDTH, + .dst_info.data_width = STEDMA40_BYTE_WIDTH, +}; + +static struct stedma40_chan_cfg uart2_dma_cfg_tx = { + .mode = STEDMA40_MODE_LOGICAL, + .dir = STEDMA40_MEM_TO_PERIPH, + .src_dev_type = STEDMA40_DEV_SRC_MEMORY, + .dst_dev_type = DB8500_DMA_DEV11_UART2_TX, + .src_info.data_width = STEDMA40_BYTE_WIDTH, + .dst_info.data_width = STEDMA40_BYTE_WIDTH, +}; +#endif + +static struct amba_pl011_data uart0_plat = { +#ifdef CONFIG_STE_DMA40 + .dma_filter = stedma40_filter, + .dma_rx_param = &uart0_dma_cfg_rx, + .dma_tx_param = &uart0_dma_cfg_tx, +#endif +}; + +static struct amba_pl011_data uart1_plat = { +#ifdef CONFIG_STE_DMA40 + .dma_filter = stedma40_filter, + .dma_rx_param = &uart1_dma_cfg_rx, + .dma_tx_param = &uart1_dma_cfg_tx, +#endif +}; + +static struct amba_pl011_data uart2_plat = { +#ifdef CONFIG_STE_DMA40 + .dma_filter = stedma40_filter, + .dma_rx_param = &uart2_dma_cfg_rx, + .dma_tx_param = &uart2_dma_cfg_tx, +#endif +}; + static void __init mop500_uart_init(void) { - db8500_add_uart0(); - db8500_add_uart1(); - db8500_add_uart2(); + db8500_add_uart0(&uart0_plat); + db8500_add_uart1(&uart1_plat); + db8500_add_uart2(&uart2_plat); } -static void __init u8500_init_machine(void) +static void __init mop500_init_machine(void) { + int i2c0_devs; + + /* + * The HREFv60 board removed a GPIO expander and routed + * all these GPIO pins to the internal GPIO controller + * instead. + */ + if (machine_is_hrefv60()) + mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO; + else + mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR; + u8500_init_devices(); - nmk_config_pins(mop500_pins, ARRAY_SIZE(mop500_pins)); + mop500_pins_init(); platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); @@ -207,12 +447,15 @@ static void __init u8500_init_machine(void) mop500_spi_init(); mop500_uart_init(); - mop500_keypad_init(); - platform_device_register(&ab8500_device); - i2c_register_board_info(0, mop500_i2c0_devices, - ARRAY_SIZE(mop500_i2c0_devices)); + i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices); + if (machine_is_hrefv60()) + i2c0_devs -= NUM_PRE_V60_I2C0_DEVICES; + + i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs); + i2c_register_board_info(2, mop500_i2c2_devices, + ARRAY_SIZE(mop500_i2c2_devices)); } MACHINE_START(U8500, "ST-Ericsson MOP500 platform") @@ -222,5 +465,13 @@ MACHINE_START(U8500, "ST-Ericsson MOP500 platform") .init_irq = ux500_init_irq, /* we re-use nomadik timer here */ .timer = &ux500_timer, - .init_machine = u8500_init_machine, + .init_machine = mop500_init_machine, +MACHINE_END + +MACHINE_START(HREFV60, "ST-Ericsson U8500 Platform HREFv60+") + .boot_params = 0x100, + .map_io = u8500_map_io, + .init_irq = ux500_init_irq, + .timer = &ux500_timer, + .init_machine = mop500_init_machine, MACHINE_END |