diff options
Diffstat (limited to 'arch/arm/mach-mx2/pcm038.c')
-rw-r--r-- | arch/arm/mach-mx2/pcm038.c | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/arch/arm/mach-mx2/pcm038.c b/arch/arm/mach-mx2/pcm038.c index 5bdf083da14..d5673b7e641 100644 --- a/arch/arm/mach-mx2/pcm038.c +++ b/arch/arm/mach-mx2/pcm038.c @@ -18,6 +18,8 @@ #include <linux/platform_device.h> #include <linux/mtd/physmap.h> +#include <linux/i2c.h> +#include <linux/spi/spi.h> #include <linux/serial.h> #include <asm/arch/common.h> #include <asm/hardware.h> @@ -25,7 +27,10 @@ #include <asm/mach/arch.h> #include <asm/arch/clock.h> #include <asm/arch/gpio.h> +#include <asm/arch/imx_i2c.h> +#include <asm/arch/imx_spi.h> #include <asm/arch/imx_uart.h> +#include <asm/arch/pmic/platform.h> #include "serial.h" #include "devices.h" #include "gpio_mux.h" @@ -54,6 +59,137 @@ static struct platform_device pcm038_nor_mtd_device = { .resource = &pcm038_flash_resource, }; +#ifdef CONFIG_I2C +static int pcm038_i2c_1_init(struct platform_device *pdev) +{ + gpio_request_mux(MX27_PIN_I2C2_SCL, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_I2C2_SDA, GPIO_MUX_PRIMARY); + return 0; +} + +static int pcm038_i2c_1_exit(struct platform_device *pdev) +{ + gpio_free_mux(MX27_PIN_I2C2_SCL); + gpio_free_mux(MX27_PIN_I2C2_SDA); + return 0; +} + +static struct imx_i2c_platform_data pcm038_i2c_1_data = { + .i2c_clk = 100000, + .init = pcm038_i2c_1_init, + .exit = pcm038_i2c_1_exit, +}; + +static struct i2c_board_info pcm038_i2c_devices[] = { + [0] = { + .driver_name = "st24cxx", + .type = "m24c32", + .flags = 0, /* FIXME */ + .addr = 0x52, /* E0=0, E1=1, E2=0 */ + .platform_data = NULL, + .irq = 0 + }, + [1] = { + .driver_name = "rtc-pcf8563", + .type = "rtc8564", + .flags = 0, /* FIXME */ + .addr = 0x51, + .platform_data = NULL, + .irq = 0 + }, + [2] = { + .driver_name = "lm75", + .type = "", + .flags = 0, + .addr = 0x4a, + .platform_data = NULL, + .irq = 0 + } +}; +#endif + +static int gpio_spi_active_0(struct platform_device *pdev) +{ + gpio_request_mux(MX27_PIN_CSPI1_MOSI, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSPI1_MISO, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSPI1_SCLK, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSPI1_RDY, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSPI1_SS0, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSPI1_SS1, GPIO_MUX_PRIMARY); + gpio_request_mux(MX27_PIN_CSPI1_SS2, GPIO_MUX_PRIMARY); /* pcm038: we don't have this one */ + return 0; +} + +static int gpio_spi_active_2(struct platform_device *pdev) +{ + gpio_request_mux(MX27_PIN_SD1_D0, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_SD1_CMD, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_SD1_CLK, GPIO_MUX_ALT); + gpio_request_mux(MX27_PIN_SD1_D3, GPIO_MUX_ALT); + return 0; +} + +static int gpio_spi_inactive_0(struct platform_device *pdev) +{ + gpio_free_mux(MX27_PIN_CSPI1_MOSI); + gpio_free_mux(MX27_PIN_CSPI1_MISO); + gpio_free_mux(MX27_PIN_CSPI1_SCLK); + gpio_free_mux(MX27_PIN_CSPI1_RDY); + gpio_free_mux(MX27_PIN_CSPI1_SS0); + gpio_free_mux(MX27_PIN_CSPI1_SS1); + gpio_free_mux(MX27_PIN_CSPI1_SS2); + return 0; +} + +static int gpio_spi_inactive_2(struct platform_device *pdev) +{ + gpio_free_mux(MX27_PIN_SD1_D0); + gpio_free_mux(MX27_PIN_SD1_CMD); + gpio_free_mux(MX27_PIN_SD1_CLK); + gpio_free_mux(MX27_PIN_SD1_D3); + return 0; +} + +static struct mxc_spi_master pcm038_spi_0_data = { + .maxchipselect = 4, /* FIXME */ + .spi_version = 0, /* ??????????????? */ + .init = gpio_spi_active_0, + .exit = gpio_spi_inactive_0, +}; + +static int gpio_pmic_active(void) +{ + gpio_config_mux(MX27_PIN_USB_PWR, GPIO_MUX_GPIO); + mxc_set_gpio_direction(MX27_PIN_USB_PWR, 1); + return 0; +} + +static struct pmic_platform_data pcm038_pmic_irq = { + .init = gpio_pmic_active, + .exit = NULL /* TODO required? */ +}; + +/* + * spi bus 1 description + * - serviced by SPI master unit 1 (be seen in kernel as #0) + * - SS0 selects the external MC13783 + * - MC13783's interrupt is connected to PB23 + * - SS1: external available + * - SS2: external available + * - SS3: external available + * FIXME: does this use the spi init functions correctly? + */ +static struct spi_board_info pcm038_spi_board_info[] __initdata = { + { + .modalias = "pmic_spi", + .irq = PCM038_PMIC_INT_LINE, + .max_speed_hz = /* 4000000 */ 3000000, /* FIXME: Depends on internal PLL? */ + .bus_num = PCM038_PMIC_SPI_CHANNEL, + .chip_select = 0, + .platform_data = &pcm038_pmic_irq + } +}; + static int uart_mxc_port0_init(struct platform_device *pdev) { gpio_request_mux(MX27_PIN_UART1_TXD, GPIO_MUX_PRIMARY); @@ -182,6 +318,19 @@ static void __init pcm038_init(void) mxc_init_uart(1, 0, uart_mxc_port1_init, uart_mxc_port1_exit); mxc_init_uart(2, 0, uart_mxc_port2_init, uart_mxc_port2_exit); +#ifdef CONFIG_I2C + /* only the i2c master 1 is used on this CPU card */ + i2c_register_board_info(PCM038_I2C_BUS, pcm038_i2c_devices, + ARRAY_SIZE(pcm038_i2c_devices)); + + mxc_init_i2c(1, &pcm038_i2c_1_data); +#endif + + mxc_init_spi(0, &pcm038_spi_0_data); + + spi_register_board_info(pcm038_spi_board_info, + ARRAY_SIZE(pcm038_spi_board_info)); + platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); #ifdef CONFIG_MACH_PCM970_BASEBOARD |