Advertisement
danielhilst

0001-MCP23S17-Board-Support.patch

Jan 19th, 2015
278
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 12.39 KB | None | 0 0
  1. From db0ede84b33c6f139a3060b715a0d63a9959d2a4 Mon Sep 17 00:00:00 2001
  2. From: Douglas <douglas.cogubum@csi.ind.br>
  3. Date: Thu, 16 Oct 2014 08:07:40 -0300
  4. Subject: [PATCH] MCP23S17 Board Support I/O Expander for Enlace II MX6. Only
  5.  support Enlace, don't use with other CSI product without confirm compability.
  6.  
  7. ---
  8. arch/arm/configs/var_som_mx6_defconfig |  2 +-
  9.  arch/arm/mach-mx6/board-mx6q_var_som.c | 37 ++++++++++++++++++++-
  10.  arch/arm/mach-mx6/board-mx6q_var_som.h | 10 +++++-
  11.  drivers/gpio/gpiolib.c                 | 35 ++++++++++++++++++++
  12.  drivers/gpio/mcp23s08.c                | 60 +++++++++++++++++++++++++++++++++-
  13.  include/asm-generic/gpio.h             | 13 ++++++++
  14.  include/linux/gpio.h                   | 15 +++++++++
  15.  include/linux/spi/mcp23s08.h           | 17 ++++++++++
  16.  8 files changed, 185 insertions(+), 4 deletions(-)
  17.  
  18. diff --git a/arch/arm/configs/var_som_mx6_defconfig b/arch/arm/configs/var_som_mx6_defconfig
  19. index 1ddb368..e461e44 100644
  20. --- a/arch/arm/configs/var_som_mx6_defconfig
  21. +++ b/arch/arm/configs/var_som_mx6_defconfig
  22. @@ -1588,7 +1588,7 @@ CONFIG_GPIO_SYSFS=y
  23.  # SPI GPIO expanders:
  24.  #
  25.  # CONFIG_GPIO_MAX7301 is not set
  26. -# CONFIG_GPIO_MCP23S08 is not set
  27. +CONFIG_GPIO_MCP23S08=m
  28.  # CONFIG_GPIO_MC33880 is not set
  29.  # CONFIG_GPIO_74X164 is not set
  30.  
  31. diff --git a/arch/arm/mach-mx6/board-mx6q_var_som.c b/arch/arm/mach-mx6/board-mx6q_var_som.c
  32. index c869038..57b9d37 100644
  33. --- a/arch/arm/mach-mx6/board-mx6q_var_som.c
  34. +++ b/arch/arm/mach-mx6/board-mx6q_var_som.c
  35. @@ -31,6 +31,7 @@
  36.  #include <linux/fsl_devices.h>
  37.  #include <linux/spi/spi.h>
  38.  #include <linux/spi/ads7846.h>
  39. +#include <linux/spi/mcp23s08.h>
  40.  #include <linux/i2c.h>
  41.  #include <linux/i2c/pca953x.h>
  42.  #include <linux/ata.h>
  43. @@ -85,6 +86,7 @@
  44.   */
  45.  //#define ANDROID_NAND_RECOVERY
  46.  
  47. +#define VAR_SOM_ECSPI1_CS0      IMX_GPIO_NR(4, 9)
  48.  #define VAR_SOM_ECSPI3_CS0      IMX_GPIO_NR(4, 24)
  49.  #define VAR_SOM_ADS7846_INT     IMX_GPIO_NR(4, 25)
  50.  #define VAR_SOM_ADS7846_PD      IMX_GPIO_NR(4, 25)
  51. @@ -111,6 +113,8 @@
  52.  
  53.  #define VAR_SOM_TSC_CTW6120_IRQ_GPIO IMX_GPIO_NR(3, 7)
  54.  
  55. +#define MCP_INITIAL_BASE   225
  56. +
  57.  static struct clk *sata_clk;
  58.  static struct clk *clko;
  59.  static int enable_lcd_ldb;
  60. @@ -368,15 +372,32 @@ static struct fec_platform_data fec_data __initdata = {
  61.     .phy = PHY_INTERFACE_MODE_RGMII,
  62.  };
  63.  
  64. +static int mx6q_var_som_ecspi1_cs[] = {
  65. +   VAR_SOM_ECSPI1_CS0,
  66. +};
  67. +
  68.  static int mx6q_var_som_spi_cs[] = {
  69.     VAR_SOM_ECSPI3_CS0,
  70.  };
  71.  
  72. +static const struct spi_imx_master mx6q_var_som_ecspi1_data __initconst = {
  73. +   .chipselect     = mx6q_var_som_ecspi1_cs,
  74. +   .num_chipselect = ARRAY_SIZE(mx6q_var_som_ecspi1_cs),
  75. +};
  76. +
  77.  static const struct spi_imx_master mx6q_var_som_spi_data __initconst = {
  78.     .chipselect     = mx6q_var_som_spi_cs,
  79.     .num_chipselect = ARRAY_SIZE(mx6q_var_som_spi_cs),
  80.  };
  81.  
  82. +static struct mcp23s08_platform_data mcp23s08_config = {
  83. +   .chip[0].is_present = true,
  84. +      
  85. +   .chip[0].pullups = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7),
  86. +  
  87. +   .base = MCP_INITIAL_BASE,
  88. +};
  89. +
  90.  static struct ads7846_platform_data ads7846_config = {
  91.     .x_max               = 8080,
  92.     .y_max               = 7980,
  93. @@ -393,6 +414,18 @@ static struct ads7846_platform_data ads7846_config = {
  94.     .wakeup              = true,
  95.  };
  96.  
  97. +static struct spi_board_info mx6_var_som_spi_mcp23s08[] __initdata = {
  98. +   {
  99. +       .modalias = "mcp23s17",
  100. +       .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */
  101. +                .bus_num = 0,
  102. +                .chip_select = 0,
  103. +                .platform_data = &mcp23s08_config,
  104. +       .mode = SPI_MODE_0,
  105. +   },
  106. +
  107. +};
  108. +
  109.  static struct spi_board_info mx6_var_som_spi_ts_device[] __initdata = {
  110.     {
  111.         .modalias = "ads7846",
  112. @@ -410,6 +443,8 @@ static void spi_device_init(void)
  113.         spi_register_board_info(mx6_var_som_spi_ts_device,
  114.                 ARRAY_SIZE(mx6_var_som_spi_ts_device));
  115.     }
  116. +  
  117. +   spi_register_board_info(mx6_var_som_spi_mcp23s08, ARRAY_SIZE(mx6_var_som_spi_mcp23s08));
  118.  }
  119.  
  120.  /* Audio
  121. @@ -1106,7 +1141,6 @@ static void __init mx6_var_som_board_init(void)
  122.  
  123.     imx6q_add_flexcan0(&mx6q_var_som_flexcan0_pdata);
  124.  
  125. -
  126.     imx6q_add_vdoa();
  127.     imx6q_add_lcdif(&lcdif_data);
  128.     imx6q_add_ldb(&ldb_data);
  129. @@ -1150,6 +1184,7 @@ static void __init mx6_var_som_board_init(void)
  130.     gpio_direction_output(VAR_SOM_BACKLIGHT_EN, 1);
  131.  
  132.     /* SPI */
  133. +   imx6q_add_ecspi(0, &mx6q_var_som_ecspi1_data);
  134.     imx6q_add_ecspi(2, &mx6q_var_som_spi_data);
  135.     spi_device_init();
  136.  
  137. diff --git a/arch/arm/mach-mx6/board-mx6q_var_som.h b/arch/arm/mach-mx6/board-mx6q_var_som.h
  138. index dc78c15..31b421b 100644
  139. --- a/arch/arm/mach-mx6/board-mx6q_var_som.h
  140. +++ b/arch/arm/mach-mx6/board-mx6q_var_som.h
  141. @@ -58,6 +58,14 @@ static iomux_v3_cfg_t mx6q_var_som_pads[] = {
  142.     MX6Q_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS,
  143.     MX6Q_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD,
  144.  
  145. +   /* SPI1 (mcp23s17) */
  146. +   MX6Q_PAD_KEY_COL1__ECSPI1_MISO,
  147. +        MX6Q_PAD_KEY_ROW0__ECSPI1_MOSI,
  148. +        MX6Q_PAD_KEY_COL0__ECSPI1_SCLK,        
  149. +
  150. +        MX6Q_PAD_KEY_ROW1__GPIO_4_9, /* mcp23s17 CS0 */   
  151. +   MX6Q_PAD_CSI0_DAT9__GPIO_5_27,
  152. +
  153.     /* SPI3 (ads7846) */
  154.     MX6Q_PAD_DISP0_DAT2__ECSPI3_MISO,
  155.     MX6Q_PAD_DISP0_DAT1__ECSPI3_MOSI,
  156. @@ -126,7 +134,7 @@ static iomux_v3_cfg_t mx6q_var_som_pads[] = {
  157.  
  158.     /* I2C1 */
  159.     MX6Q_PAD_CSI0_DAT8__I2C1_SDA,
  160. -   MX6Q_PAD_CSI0_DAT9__I2C1_SCL,
  161. +   //MX6Q_PAD_CSI0_DAT9__I2C1_SCL,
  162.  
  163.     /* I2C2 */
  164.     MX6Q_PAD_KEY_COL3__I2C2_SCL,
  165. diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
  166. index a971e3d..e9f2374 100644
  167. --- a/drivers/gpio/gpiolib.c
  168. +++ b/drivers/gpio/gpiolib.c
  169. @@ -816,6 +816,29 @@ done:
  170.  }
  171.  EXPORT_SYMBOL_GPL(gpio_export_link);
  172.  
  173. +/**
  174. + * gpio_export_array - export multiple GPIOs in a single call
  175. + * @array: array of the 'struct gpio'
  176. + * @num:   how many GPIOs in the array
  177. + */
  178. +int gpio_export_array(const struct gpio *array, size_t num,
  179. +           bool direction_may_change)
  180. +{
  181. +   int i, err;
  182. +
  183. +   for (i = 0; i < num; i++, array++) {
  184. +       err = gpio_export(array->gpio, direction_may_change);
  185. +       if (err)
  186. +           goto err_export;
  187. +   }
  188. +   return 0;
  189. +
  190. +err_export:
  191. +   while (i--)
  192. +       gpio_unexport((--array)->gpio);
  193. +   return err;
  194. +}
  195. +EXPORT_SYMBOL_GPL(gpio_export_array);
  196.  
  197.  /**
  198.   * gpio_sysfs_set_active_low - set the polarity of gpio sysfs value
  199. @@ -903,6 +926,18 @@ done:
  200.  }
  201.  EXPORT_SYMBOL_GPL(gpio_unexport);
  202.  
  203. +/**
  204. + * gpio_unexport_array - unexport multiple GPIOs in a single call
  205. + * @array: array of the 'struct gpio'
  206. + * @num:   how many GPIOs in the array
  207. + */
  208. +void gpio_unexport_array(const struct gpio *array, size_t num)
  209. +{
  210. +   while (num--)
  211. +       gpio_unexport((array++)->gpio);
  212. +}
  213. +EXPORT_SYMBOL_GPL(gpio_unexport_array);
  214. +
  215.  static int gpiochip_export(struct gpio_chip *chip)
  216.  {
  217.     int     status;
  218. diff --git a/drivers/gpio/mcp23s08.c b/drivers/gpio/mcp23s08.c
  219. index 40e0760..bdd6247 100644
  220. --- a/drivers/gpio/mcp23s08.c
  221. +++ b/drivers/gpio/mcp23s08.c
  222. @@ -76,6 +76,26 @@ struct mcp23s08_driver_data {
  223.     struct mcp23s08     chip[];
  224.  };
  225.  
  226. +/* gpio request and free array */
  227. +struct gpio gpio_csi_array[] = {
  228. +   {INPUT1, GPIOF_DIR_IN, "INPUT1"},
  229. +        {INPUT2, GPIOF_DIR_IN, "INPUT2"},
  230. +        {INPUT3, GPIOF_DIR_IN, "INPUT3"},
  231. +        {INPUT4, GPIOF_DIR_IN, "INPUT4"},
  232. +        {INPUT5, GPIOF_DIR_IN, "INPUT5"},
  233. +        {INPUT6, GPIOF_DIR_IN, "INPUT6"},
  234. +        {INPUT7, GPIOF_DIR_IN, "INPUT7"},
  235. +        {INPUT8, GPIOF_DIR_IN, "INPUT8"},
  236. +        {OUTPUT1, GPIOF_OUT_INIT_LOW, "OUTPUT1"},
  237. +        {OUTPUT2, GPIOF_OUT_INIT_LOW, "OUTPUT2"},
  238. +        {OUTPUT3, GPIOF_OUT_INIT_LOW, "OUTPUT3"},
  239. +        {OUTPUT4, GPIOF_OUT_INIT_LOW, "OUTPUT4"},
  240. +        {OUTPUT5, GPIOF_OUT_INIT_LOW, "OUTPUT5"},
  241. +        {OUTPUT6, GPIOF_OUT_INIT_LOW, "OUTPUT6"},
  242. +        {OUTPUT7, GPIOF_OUT_INIT_LOW, "OUTPUT7"},
  243. +        {OUTPUT8, GPIOF_OUT_INIT_LOW, "OUTPUT8"},
  244. +};
  245. +
  246.  static int mcp23s08_read(struct mcp23s08 *mcp, unsigned reg)
  247.  {
  248.     u8  tx[2], rx[1];
  249. @@ -305,6 +325,7 @@ static int mcp23s08_probe_one(struct spi_device *spi, unsigned addr,
  250.     struct mcp23s08_driver_data *data = spi_get_drvdata(spi);
  251.     struct mcp23s08         *mcp = data->mcp[addr];
  252.     int             status;
  253. +   int             gpio_csi;
  254.  
  255.     mutex_init(&mcp->lock);
  256.  
  257. @@ -372,6 +393,32 @@ static int mcp23s08_probe_one(struct spi_device *spi, unsigned addr,
  258.     }
  259.  
  260.     status = gpiochip_add(&mcp->chip);
  261. +   if(status < 0)
  262. +       goto fail;
  263. +  
  264. +   /* request gpio array */
  265. +   status = gpio_request_array(gpio_csi_array, ARRAY_SIZE(gpio_csi_array));
  266. +   if (status)
  267. +       goto fail;
  268. +
  269. +   /*export gpio array */
  270. +   for(gpio_csi = 225; gpio_csi < 241; gpio_csi++)
  271. +   {
  272. +       status = gpio_export(gpio_csi, true);
  273. +       if(status < 0)
  274. +           goto fail;
  275. +       status = gpio_sysfs_set_active_low(gpio_csi, 1);
  276. +       if(status < 0)
  277. +           goto fail;
  278. +   }
  279. +
  280. +   /* invert only input polarity */
  281. +   for(gpio_csi = 225; gpio_csi < 233; gpio_csi++)
  282. +   {
  283. +       status = gpio_sysfs_set_active_low(gpio_csi, 1);
  284. +       if(status < 0)
  285. +           goto fail;
  286. +   }
  287.  fail:
  288.     if (status < 0)
  289.         dev_dbg(&spi->dev, "can't setup chip %d, --> %d\n",
  290. @@ -465,6 +512,15 @@ static int mcp23s08_remove(struct spi_device *spi)
  291.     struct mcp23s08_platform_data   *pdata = spi->dev.platform_data;
  292.     unsigned            addr;
  293.     int             status = 0;
  294. +   int gpio_csi;
  295. +
  296. +   /*unexport gpio array */
  297. +        for(gpio_csi = 225; gpio_csi < 241; gpio_csi++)
  298. +        {
  299. +                gpio_unexport(gpio_csi);
  300. +        }
  301. +  
  302. +   gpio_free_array(gpio_csi_array, ARRAY_SIZE(gpio_csi_array));
  303.  
  304.     if (pdata->teardown) {
  305.         status = pdata->teardown(spi,
  306. @@ -505,7 +561,7 @@ static struct spi_driver mcp23s08_driver = {
  307.     .remove     = mcp23s08_remove,
  308.     .id_table   = mcp23s08_ids,
  309.     .driver = {
  310. -       .name   = "mcp23s08",
  311. +       .name   = "mcp23s17",
  312.         .owner  = THIS_MODULE,
  313.     },
  314.  };
  315. @@ -528,3 +584,5 @@ static void __exit mcp23s08_exit(void)
  316.  module_exit(mcp23s08_exit);
  317.  
  318.  MODULE_LICENSE("GPL");
  319. +MODULE_AUTHOR("Douglas Hanji de Lima Cogubum <doug_cogubum@hotmail.com>");
  320. +MODULE_DESCRIPTION("MCP23S17 SPI GPIO EXPANDER");
  321. diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
  322. index d494001..d09937c 100644
  323. --- a/include/asm-generic/gpio.h
  324. +++ b/include/asm-generic/gpio.h
  325. @@ -193,10 +193,12 @@ extern void gpio_free_array(const struct gpio *array, size_t num);
  326.   * but more typically is configured entirely from userspace.
  327.   */
  328.  extern int gpio_export(unsigned gpio, bool direction_may_change);
  329. +extern int gpio_export_array(const struct gpio *array, size_t num, bool direction_may_change);
  330.  extern int gpio_export_link(struct device *dev, const char *name,
  331.             unsigned gpio);
  332.  extern int gpio_sysfs_set_active_low(unsigned gpio, int value);
  333.  extern void gpio_unexport(unsigned gpio);
  334. +extern void gpio_unexport_array(const struct gpio *array, size_t num);
  335.  
  336.  #endif /* CONFIG_GPIO_SYSFS */
  337.  
  338. @@ -248,6 +250,12 @@ static inline int gpio_export_link(struct device *dev, const char *name,
  339.     return -ENOSYS;
  340.  }
  341.  
  342. +static inline int gpio_export_array(const struct gpio *array, size_t num,
  343. +           bool direction_may_change)
  344. +{
  345. +   return -ENOSYS;
  346. +}
  347. +
  348.  static inline int gpio_sysfs_set_active_low(unsigned gpio, int value)
  349.  {
  350.     return -ENOSYS;
  351. @@ -256,6 +264,11 @@ static inline int gpio_sysfs_set_active_low(unsigned gpio, int value)
  352.  static inline void gpio_unexport(unsigned gpio)
  353.  {
  354.  }
  355. +
  356. +static inline void gpio_unexport_array(const struct gpio *array,
  357. +           size_t num)
  358. +{
  359. +}
  360.  #endif /* CONFIG_GPIO_SYSFS */
  361.  
  362.  #endif /* _ASM_GENERIC_GPIO_H */
  363. diff --git a/include/linux/gpio.h b/include/linux/gpio.h
  364. index 17b5a0d..434a4b6 100644
  365. --- a/include/linux/gpio.h
  366. +++ b/include/linux/gpio.h
  367. @@ -136,6 +136,14 @@ static inline int gpio_export_link(struct device *dev, const char *name,
  368.     return -EINVAL;
  369.  }
  370.  
  371. +static inline int gpio_export_array(const struct gpio *array, size_t num,
  372. +           bool direction_may_change)
  373. +{
  374. +   /* GPIO can never have been requested or set as {in,out}put */
  375. +   WARN_ON(1);
  376. +   return -EINVAL;
  377. +}
  378. +
  379.  static inline int gpio_sysfs_set_active_low(unsigned gpio, int value)
  380.  {
  381.     /* GPIO can never have been requested */
  382. @@ -143,6 +151,13 @@ static inline int gpio_sysfs_set_active_low(unsigned gpio, int value)
  383.     return -EINVAL;
  384.  }
  385.  
  386. +static inline void gpio_unexport_array(const struct gpio *array,
  387. +           size_t num)
  388. +{
  389. +   /* GPIO array can never have been exported */
  390. +   WARN_ON(1);
  391. +}
  392. +
  393.  static inline void gpio_unexport(unsigned gpio)
  394.  {
  395.     /* GPIO can never have been exported */
  396. diff --git a/include/linux/spi/mcp23s08.h b/include/linux/spi/mcp23s08.h
  397. index c42cff8..d3f60b0 100644
  398. --- a/include/linux/spi/mcp23s08.h
  399. +++ b/include/linux/spi/mcp23s08.h
  400. @@ -1,3 +1,20 @@
  401. +#define INPUT1 225
  402. +#define INPUT2 226
  403. +#define INPUT3 227
  404. +#define INPUT4 228
  405. +#define INPUT5 229
  406. +#define INPUT6 230
  407. +#define INPUT7 231
  408. +#define INPUT8 232
  409. +
  410. +#define OUTPUT1    233
  411. +#define OUTPUT2 234
  412. +#define OUTPUT3 235
  413. +#define OUTPUT4 236
  414. +#define OUTPUT5 237
  415. +#define OUTPUT6 238
  416. +#define OUTPUT7 239
  417. +#define OUTPUT8 240
  418.  
  419.  /* FIXME driver should be able to handle IRQs...  */
  420.  
  421. --
  422. 1.9.1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement