Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From db0ede84b33c6f139a3060b715a0d63a9959d2a4 Mon Sep 17 00:00:00 2001
- From: Douglas <douglas.cogubum@csi.ind.br>
- Date: Thu, 16 Oct 2014 08:07:40 -0300
- Subject: [PATCH] MCP23S17 Board Support I/O Expander for Enlace II MX6. Only
- support Enlace, don't use with other CSI product without confirm compability.
- ---
- arch/arm/configs/var_som_mx6_defconfig | 2 +-
- arch/arm/mach-mx6/board-mx6q_var_som.c | 37 ++++++++++++++++++++-
- arch/arm/mach-mx6/board-mx6q_var_som.h | 10 +++++-
- drivers/gpio/gpiolib.c | 35 ++++++++++++++++++++
- drivers/gpio/mcp23s08.c | 60 +++++++++++++++++++++++++++++++++-
- include/asm-generic/gpio.h | 13 ++++++++
- include/linux/gpio.h | 15 +++++++++
- include/linux/spi/mcp23s08.h | 17 ++++++++++
- 8 files changed, 185 insertions(+), 4 deletions(-)
- diff --git a/arch/arm/configs/var_som_mx6_defconfig b/arch/arm/configs/var_som_mx6_defconfig
- index 1ddb368..e461e44 100644
- --- a/arch/arm/configs/var_som_mx6_defconfig
- +++ b/arch/arm/configs/var_som_mx6_defconfig
- @@ -1588,7 +1588,7 @@ CONFIG_GPIO_SYSFS=y
- # SPI GPIO expanders:
- #
- # CONFIG_GPIO_MAX7301 is not set
- -# CONFIG_GPIO_MCP23S08 is not set
- +CONFIG_GPIO_MCP23S08=m
- # CONFIG_GPIO_MC33880 is not set
- # CONFIG_GPIO_74X164 is not set
- diff --git a/arch/arm/mach-mx6/board-mx6q_var_som.c b/arch/arm/mach-mx6/board-mx6q_var_som.c
- index c869038..57b9d37 100644
- --- a/arch/arm/mach-mx6/board-mx6q_var_som.c
- +++ b/arch/arm/mach-mx6/board-mx6q_var_som.c
- @@ -31,6 +31,7 @@
- #include <linux/fsl_devices.h>
- #include <linux/spi/spi.h>
- #include <linux/spi/ads7846.h>
- +#include <linux/spi/mcp23s08.h>
- #include <linux/i2c.h>
- #include <linux/i2c/pca953x.h>
- #include <linux/ata.h>
- @@ -85,6 +86,7 @@
- */
- //#define ANDROID_NAND_RECOVERY
- +#define VAR_SOM_ECSPI1_CS0 IMX_GPIO_NR(4, 9)
- #define VAR_SOM_ECSPI3_CS0 IMX_GPIO_NR(4, 24)
- #define VAR_SOM_ADS7846_INT IMX_GPIO_NR(4, 25)
- #define VAR_SOM_ADS7846_PD IMX_GPIO_NR(4, 25)
- @@ -111,6 +113,8 @@
- #define VAR_SOM_TSC_CTW6120_IRQ_GPIO IMX_GPIO_NR(3, 7)
- +#define MCP_INITIAL_BASE 225
- +
- static struct clk *sata_clk;
- static struct clk *clko;
- static int enable_lcd_ldb;
- @@ -368,15 +372,32 @@ static struct fec_platform_data fec_data __initdata = {
- .phy = PHY_INTERFACE_MODE_RGMII,
- };
- +static int mx6q_var_som_ecspi1_cs[] = {
- + VAR_SOM_ECSPI1_CS0,
- +};
- +
- static int mx6q_var_som_spi_cs[] = {
- VAR_SOM_ECSPI3_CS0,
- };
- +static const struct spi_imx_master mx6q_var_som_ecspi1_data __initconst = {
- + .chipselect = mx6q_var_som_ecspi1_cs,
- + .num_chipselect = ARRAY_SIZE(mx6q_var_som_ecspi1_cs),
- +};
- +
- static const struct spi_imx_master mx6q_var_som_spi_data __initconst = {
- .chipselect = mx6q_var_som_spi_cs,
- .num_chipselect = ARRAY_SIZE(mx6q_var_som_spi_cs),
- };
- +static struct mcp23s08_platform_data mcp23s08_config = {
- + .chip[0].is_present = true,
- +
- + .chip[0].pullups = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7),
- +
- + .base = MCP_INITIAL_BASE,
- +};
- +
- static struct ads7846_platform_data ads7846_config = {
- .x_max = 8080,
- .y_max = 7980,
- @@ -393,6 +414,18 @@ static struct ads7846_platform_data ads7846_config = {
- .wakeup = true,
- };
- +static struct spi_board_info mx6_var_som_spi_mcp23s08[] __initdata = {
- + {
- + .modalias = "mcp23s17",
- + .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */
- + .bus_num = 0,
- + .chip_select = 0,
- + .platform_data = &mcp23s08_config,
- + .mode = SPI_MODE_0,
- + },
- +
- +};
- +
- static struct spi_board_info mx6_var_som_spi_ts_device[] __initdata = {
- {
- .modalias = "ads7846",
- @@ -410,6 +443,8 @@ static void spi_device_init(void)
- spi_register_board_info(mx6_var_som_spi_ts_device,
- ARRAY_SIZE(mx6_var_som_spi_ts_device));
- }
- +
- + spi_register_board_info(mx6_var_som_spi_mcp23s08, ARRAY_SIZE(mx6_var_som_spi_mcp23s08));
- }
- /* Audio
- @@ -1106,7 +1141,6 @@ static void __init mx6_var_som_board_init(void)
- imx6q_add_flexcan0(&mx6q_var_som_flexcan0_pdata);
- -
- imx6q_add_vdoa();
- imx6q_add_lcdif(&lcdif_data);
- imx6q_add_ldb(&ldb_data);
- @@ -1150,6 +1184,7 @@ static void __init mx6_var_som_board_init(void)
- gpio_direction_output(VAR_SOM_BACKLIGHT_EN, 1);
- /* SPI */
- + imx6q_add_ecspi(0, &mx6q_var_som_ecspi1_data);
- imx6q_add_ecspi(2, &mx6q_var_som_spi_data);
- spi_device_init();
- diff --git a/arch/arm/mach-mx6/board-mx6q_var_som.h b/arch/arm/mach-mx6/board-mx6q_var_som.h
- index dc78c15..31b421b 100644
- --- a/arch/arm/mach-mx6/board-mx6q_var_som.h
- +++ b/arch/arm/mach-mx6/board-mx6q_var_som.h
- @@ -58,6 +58,14 @@ static iomux_v3_cfg_t mx6q_var_som_pads[] = {
- MX6Q_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS,
- MX6Q_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD,
- + /* SPI1 (mcp23s17) */
- + MX6Q_PAD_KEY_COL1__ECSPI1_MISO,
- + MX6Q_PAD_KEY_ROW0__ECSPI1_MOSI,
- + MX6Q_PAD_KEY_COL0__ECSPI1_SCLK,
- +
- + MX6Q_PAD_KEY_ROW1__GPIO_4_9, /* mcp23s17 CS0 */
- + MX6Q_PAD_CSI0_DAT9__GPIO_5_27,
- +
- /* SPI3 (ads7846) */
- MX6Q_PAD_DISP0_DAT2__ECSPI3_MISO,
- MX6Q_PAD_DISP0_DAT1__ECSPI3_MOSI,
- @@ -126,7 +134,7 @@ static iomux_v3_cfg_t mx6q_var_som_pads[] = {
- /* I2C1 */
- MX6Q_PAD_CSI0_DAT8__I2C1_SDA,
- - MX6Q_PAD_CSI0_DAT9__I2C1_SCL,
- + //MX6Q_PAD_CSI0_DAT9__I2C1_SCL,
- /* I2C2 */
- MX6Q_PAD_KEY_COL3__I2C2_SCL,
- diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
- index a971e3d..e9f2374 100644
- --- a/drivers/gpio/gpiolib.c
- +++ b/drivers/gpio/gpiolib.c
- @@ -816,6 +816,29 @@ done:
- }
- EXPORT_SYMBOL_GPL(gpio_export_link);
- +/**
- + * gpio_export_array - export multiple GPIOs in a single call
- + * @array: array of the 'struct gpio'
- + * @num: how many GPIOs in the array
- + */
- +int gpio_export_array(const struct gpio *array, size_t num,
- + bool direction_may_change)
- +{
- + int i, err;
- +
- + for (i = 0; i < num; i++, array++) {
- + err = gpio_export(array->gpio, direction_may_change);
- + if (err)
- + goto err_export;
- + }
- + return 0;
- +
- +err_export:
- + while (i--)
- + gpio_unexport((--array)->gpio);
- + return err;
- +}
- +EXPORT_SYMBOL_GPL(gpio_export_array);
- /**
- * gpio_sysfs_set_active_low - set the polarity of gpio sysfs value
- @@ -903,6 +926,18 @@ done:
- }
- EXPORT_SYMBOL_GPL(gpio_unexport);
- +/**
- + * gpio_unexport_array - unexport multiple GPIOs in a single call
- + * @array: array of the 'struct gpio'
- + * @num: how many GPIOs in the array
- + */
- +void gpio_unexport_array(const struct gpio *array, size_t num)
- +{
- + while (num--)
- + gpio_unexport((array++)->gpio);
- +}
- +EXPORT_SYMBOL_GPL(gpio_unexport_array);
- +
- static int gpiochip_export(struct gpio_chip *chip)
- {
- int status;
- diff --git a/drivers/gpio/mcp23s08.c b/drivers/gpio/mcp23s08.c
- index 40e0760..bdd6247 100644
- --- a/drivers/gpio/mcp23s08.c
- +++ b/drivers/gpio/mcp23s08.c
- @@ -76,6 +76,26 @@ struct mcp23s08_driver_data {
- struct mcp23s08 chip[];
- };
- +/* gpio request and free array */
- +struct gpio gpio_csi_array[] = {
- + {INPUT1, GPIOF_DIR_IN, "INPUT1"},
- + {INPUT2, GPIOF_DIR_IN, "INPUT2"},
- + {INPUT3, GPIOF_DIR_IN, "INPUT3"},
- + {INPUT4, GPIOF_DIR_IN, "INPUT4"},
- + {INPUT5, GPIOF_DIR_IN, "INPUT5"},
- + {INPUT6, GPIOF_DIR_IN, "INPUT6"},
- + {INPUT7, GPIOF_DIR_IN, "INPUT7"},
- + {INPUT8, GPIOF_DIR_IN, "INPUT8"},
- + {OUTPUT1, GPIOF_OUT_INIT_LOW, "OUTPUT1"},
- + {OUTPUT2, GPIOF_OUT_INIT_LOW, "OUTPUT2"},
- + {OUTPUT3, GPIOF_OUT_INIT_LOW, "OUTPUT3"},
- + {OUTPUT4, GPIOF_OUT_INIT_LOW, "OUTPUT4"},
- + {OUTPUT5, GPIOF_OUT_INIT_LOW, "OUTPUT5"},
- + {OUTPUT6, GPIOF_OUT_INIT_LOW, "OUTPUT6"},
- + {OUTPUT7, GPIOF_OUT_INIT_LOW, "OUTPUT7"},
- + {OUTPUT8, GPIOF_OUT_INIT_LOW, "OUTPUT8"},
- +};
- +
- static int mcp23s08_read(struct mcp23s08 *mcp, unsigned reg)
- {
- u8 tx[2], rx[1];
- @@ -305,6 +325,7 @@ static int mcp23s08_probe_one(struct spi_device *spi, unsigned addr,
- struct mcp23s08_driver_data *data = spi_get_drvdata(spi);
- struct mcp23s08 *mcp = data->mcp[addr];
- int status;
- + int gpio_csi;
- mutex_init(&mcp->lock);
- @@ -372,6 +393,32 @@ static int mcp23s08_probe_one(struct spi_device *spi, unsigned addr,
- }
- status = gpiochip_add(&mcp->chip);
- + if(status < 0)
- + goto fail;
- +
- + /* request gpio array */
- + status = gpio_request_array(gpio_csi_array, ARRAY_SIZE(gpio_csi_array));
- + if (status)
- + goto fail;
- +
- + /*export gpio array */
- + for(gpio_csi = 225; gpio_csi < 241; gpio_csi++)
- + {
- + status = gpio_export(gpio_csi, true);
- + if(status < 0)
- + goto fail;
- + status = gpio_sysfs_set_active_low(gpio_csi, 1);
- + if(status < 0)
- + goto fail;
- + }
- +
- + /* invert only input polarity */
- + for(gpio_csi = 225; gpio_csi < 233; gpio_csi++)
- + {
- + status = gpio_sysfs_set_active_low(gpio_csi, 1);
- + if(status < 0)
- + goto fail;
- + }
- fail:
- if (status < 0)
- dev_dbg(&spi->dev, "can't setup chip %d, --> %d\n",
- @@ -465,6 +512,15 @@ static int mcp23s08_remove(struct spi_device *spi)
- struct mcp23s08_platform_data *pdata = spi->dev.platform_data;
- unsigned addr;
- int status = 0;
- + int gpio_csi;
- +
- + /*unexport gpio array */
- + for(gpio_csi = 225; gpio_csi < 241; gpio_csi++)
- + {
- + gpio_unexport(gpio_csi);
- + }
- +
- + gpio_free_array(gpio_csi_array, ARRAY_SIZE(gpio_csi_array));
- if (pdata->teardown) {
- status = pdata->teardown(spi,
- @@ -505,7 +561,7 @@ static struct spi_driver mcp23s08_driver = {
- .remove = mcp23s08_remove,
- .id_table = mcp23s08_ids,
- .driver = {
- - .name = "mcp23s08",
- + .name = "mcp23s17",
- .owner = THIS_MODULE,
- },
- };
- @@ -528,3 +584,5 @@ static void __exit mcp23s08_exit(void)
- module_exit(mcp23s08_exit);
- MODULE_LICENSE("GPL");
- +MODULE_AUTHOR("Douglas Hanji de Lima Cogubum <doug_cogubum@hotmail.com>");
- +MODULE_DESCRIPTION("MCP23S17 SPI GPIO EXPANDER");
- diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
- index d494001..d09937c 100644
- --- a/include/asm-generic/gpio.h
- +++ b/include/asm-generic/gpio.h
- @@ -193,10 +193,12 @@ extern void gpio_free_array(const struct gpio *array, size_t num);
- * but more typically is configured entirely from userspace.
- */
- extern int gpio_export(unsigned gpio, bool direction_may_change);
- +extern int gpio_export_array(const struct gpio *array, size_t num, bool direction_may_change);
- extern int gpio_export_link(struct device *dev, const char *name,
- unsigned gpio);
- extern int gpio_sysfs_set_active_low(unsigned gpio, int value);
- extern void gpio_unexport(unsigned gpio);
- +extern void gpio_unexport_array(const struct gpio *array, size_t num);
- #endif /* CONFIG_GPIO_SYSFS */
- @@ -248,6 +250,12 @@ static inline int gpio_export_link(struct device *dev, const char *name,
- return -ENOSYS;
- }
- +static inline int gpio_export_array(const struct gpio *array, size_t num,
- + bool direction_may_change)
- +{
- + return -ENOSYS;
- +}
- +
- static inline int gpio_sysfs_set_active_low(unsigned gpio, int value)
- {
- return -ENOSYS;
- @@ -256,6 +264,11 @@ static inline int gpio_sysfs_set_active_low(unsigned gpio, int value)
- static inline void gpio_unexport(unsigned gpio)
- {
- }
- +
- +static inline void gpio_unexport_array(const struct gpio *array,
- + size_t num)
- +{
- +}
- #endif /* CONFIG_GPIO_SYSFS */
- #endif /* _ASM_GENERIC_GPIO_H */
- diff --git a/include/linux/gpio.h b/include/linux/gpio.h
- index 17b5a0d..434a4b6 100644
- --- a/include/linux/gpio.h
- +++ b/include/linux/gpio.h
- @@ -136,6 +136,14 @@ static inline int gpio_export_link(struct device *dev, const char *name,
- return -EINVAL;
- }
- +static inline int gpio_export_array(const struct gpio *array, size_t num,
- + bool direction_may_change)
- +{
- + /* GPIO can never have been requested or set as {in,out}put */
- + WARN_ON(1);
- + return -EINVAL;
- +}
- +
- static inline int gpio_sysfs_set_active_low(unsigned gpio, int value)
- {
- /* GPIO can never have been requested */
- @@ -143,6 +151,13 @@ static inline int gpio_sysfs_set_active_low(unsigned gpio, int value)
- return -EINVAL;
- }
- +static inline void gpio_unexport_array(const struct gpio *array,
- + size_t num)
- +{
- + /* GPIO array can never have been exported */
- + WARN_ON(1);
- +}
- +
- static inline void gpio_unexport(unsigned gpio)
- {
- /* GPIO can never have been exported */
- diff --git a/include/linux/spi/mcp23s08.h b/include/linux/spi/mcp23s08.h
- index c42cff8..d3f60b0 100644
- --- a/include/linux/spi/mcp23s08.h
- +++ b/include/linux/spi/mcp23s08.h
- @@ -1,3 +1,20 @@
- +#define INPUT1 225
- +#define INPUT2 226
- +#define INPUT3 227
- +#define INPUT4 228
- +#define INPUT5 229
- +#define INPUT6 230
- +#define INPUT7 231
- +#define INPUT8 232
- +
- +#define OUTPUT1 233
- +#define OUTPUT2 234
- +#define OUTPUT3 235
- +#define OUTPUT4 236
- +#define OUTPUT5 237
- +#define OUTPUT6 238
- +#define OUTPUT7 239
- +#define OUTPUT8 240
- /* FIXME driver should be able to handle IRQs... */
- --
- 1.9.1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement