gpio-tps65910.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*
  2. * TI TPS6591x GPIO driver
  3. *
  4. * Copyright 2010 Texas Instruments Inc.
  5. *
  6. * Author: Graeme Gregory <gg@slimlogic.co.uk>
  7. * Author: Jorge Eduardo Candelaria jedu@slimlogic.co.uk>
  8. *
  9. * This program is free software; you can redistribute it and/or modify it
  10. * under the terms of the GNU General Public License as published by the
  11. * Free Software Foundation; either version 2 of the License, or (at your
  12. * option) any later version.
  13. *
  14. */
  15. #include <linux/kernel.h>
  16. #include <linux/module.h>
  17. #include <linux/errno.h>
  18. #include <linux/gpio.h>
  19. #include <linux/i2c.h>
  20. #include <linux/platform_device.h>
  21. #include <linux/mfd/tps65910.h>
  22. #include <linux/of_device.h>
  23. struct tps65910_gpio {
  24. struct gpio_chip gpio_chip;
  25. struct tps65910 *tps65910;
  26. };
  27. static inline struct tps65910_gpio *to_tps65910_gpio(struct gpio_chip *chip)
  28. {
  29. return container_of(chip, struct tps65910_gpio, gpio_chip);
  30. }
  31. static int tps65910_gpio_get(struct gpio_chip *gc, unsigned offset)
  32. {
  33. struct tps65910_gpio *tps65910_gpio = to_tps65910_gpio(gc);
  34. struct tps65910 *tps65910 = tps65910_gpio->tps65910;
  35. unsigned int val;
  36. tps65910_reg_read(tps65910, TPS65910_GPIO0 + offset, &val);
  37. if (val & GPIO_STS_MASK)
  38. return 1;
  39. return 0;
  40. }
  41. static void tps65910_gpio_set(struct gpio_chip *gc, unsigned offset,
  42. int value)
  43. {
  44. struct tps65910_gpio *tps65910_gpio = to_tps65910_gpio(gc);
  45. struct tps65910 *tps65910 = tps65910_gpio->tps65910;
  46. if (value)
  47. tps65910_reg_set_bits(tps65910, TPS65910_GPIO0 + offset,
  48. GPIO_SET_MASK);
  49. else
  50. tps65910_reg_clear_bits(tps65910, TPS65910_GPIO0 + offset,
  51. GPIO_SET_MASK);
  52. }
  53. static int tps65910_gpio_output(struct gpio_chip *gc, unsigned offset,
  54. int value)
  55. {
  56. struct tps65910_gpio *tps65910_gpio = to_tps65910_gpio(gc);
  57. struct tps65910 *tps65910 = tps65910_gpio->tps65910;
  58. /* Set the initial value */
  59. tps65910_gpio_set(gc, offset, value);
  60. return tps65910_reg_set_bits(tps65910, TPS65910_GPIO0 + offset,
  61. GPIO_CFG_MASK);
  62. }
  63. static int tps65910_gpio_input(struct gpio_chip *gc, unsigned offset)
  64. {
  65. struct tps65910_gpio *tps65910_gpio = to_tps65910_gpio(gc);
  66. struct tps65910 *tps65910 = tps65910_gpio->tps65910;
  67. return tps65910_reg_clear_bits(tps65910, TPS65910_GPIO0 + offset,
  68. GPIO_CFG_MASK);
  69. }
  70. #ifdef CONFIG_OF
  71. static struct tps65910_board *tps65910_parse_dt_for_gpio(struct device *dev,
  72. struct tps65910 *tps65910, int chip_ngpio)
  73. {
  74. struct tps65910_board *tps65910_board = tps65910->of_plat_data;
  75. unsigned int prop_array[TPS6591X_MAX_NUM_GPIO];
  76. int ngpio = min(chip_ngpio, TPS6591X_MAX_NUM_GPIO);
  77. int ret;
  78. int idx;
  79. tps65910_board->gpio_base = -1;
  80. ret = of_property_read_u32_array(tps65910->dev->of_node,
  81. "ti,en-gpio-sleep", prop_array, ngpio);
  82. if (ret < 0) {
  83. dev_dbg(dev, "ti,en-gpio-sleep not specified\n");
  84. return tps65910_board;
  85. }
  86. for (idx = 0; idx < ngpio; idx++)
  87. tps65910_board->en_gpio_sleep[idx] = (prop_array[idx] != 0);
  88. return tps65910_board;
  89. }
  90. #else
  91. static struct tps65910_board *tps65910_parse_dt_for_gpio(struct device *dev,
  92. struct tps65910 *tps65910, int chip_ngpio)
  93. {
  94. return NULL;
  95. }
  96. #endif
  97. static int tps65910_gpio_probe(struct platform_device *pdev)
  98. {
  99. struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
  100. struct tps65910_board *pdata = dev_get_platdata(tps65910->dev);
  101. struct tps65910_gpio *tps65910_gpio;
  102. int ret;
  103. int i;
  104. tps65910_gpio = devm_kzalloc(&pdev->dev,
  105. sizeof(*tps65910_gpio), GFP_KERNEL);
  106. if (!tps65910_gpio)
  107. return -ENOMEM;
  108. tps65910_gpio->tps65910 = tps65910;
  109. tps65910_gpio->gpio_chip.owner = THIS_MODULE;
  110. tps65910_gpio->gpio_chip.label = tps65910->i2c_client->name;
  111. switch (tps65910_chip_id(tps65910)) {
  112. case TPS65910:
  113. tps65910_gpio->gpio_chip.ngpio = TPS65910_NUM_GPIO;
  114. break;
  115. case TPS65911:
  116. tps65910_gpio->gpio_chip.ngpio = TPS65911_NUM_GPIO;
  117. break;
  118. default:
  119. return -EINVAL;
  120. }
  121. tps65910_gpio->gpio_chip.can_sleep = true;
  122. tps65910_gpio->gpio_chip.direction_input = tps65910_gpio_input;
  123. tps65910_gpio->gpio_chip.direction_output = tps65910_gpio_output;
  124. tps65910_gpio->gpio_chip.set = tps65910_gpio_set;
  125. tps65910_gpio->gpio_chip.get = tps65910_gpio_get;
  126. tps65910_gpio->gpio_chip.dev = &pdev->dev;
  127. #ifdef CONFIG_OF_GPIO
  128. tps65910_gpio->gpio_chip.of_node = tps65910->dev->of_node;
  129. #endif
  130. if (pdata && pdata->gpio_base)
  131. tps65910_gpio->gpio_chip.base = pdata->gpio_base;
  132. else
  133. tps65910_gpio->gpio_chip.base = -1;
  134. if (!pdata && tps65910->dev->of_node)
  135. pdata = tps65910_parse_dt_for_gpio(&pdev->dev, tps65910,
  136. tps65910_gpio->gpio_chip.ngpio);
  137. if (!pdata)
  138. goto skip_init;
  139. /* Configure sleep control for gpios if provided */
  140. for (i = 0; i < tps65910_gpio->gpio_chip.ngpio; ++i) {
  141. if (!pdata->en_gpio_sleep[i])
  142. continue;
  143. ret = tps65910_reg_set_bits(tps65910,
  144. TPS65910_GPIO0 + i, GPIO_SLEEP_MASK);
  145. if (ret < 0)
  146. dev_warn(tps65910->dev,
  147. "GPIO Sleep setting failed with err %d\n", ret);
  148. }
  149. skip_init:
  150. ret = gpiochip_add(&tps65910_gpio->gpio_chip);
  151. if (ret < 0) {
  152. dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
  153. return ret;
  154. }
  155. platform_set_drvdata(pdev, tps65910_gpio);
  156. return ret;
  157. }
  158. static int tps65910_gpio_remove(struct platform_device *pdev)
  159. {
  160. struct tps65910_gpio *tps65910_gpio = platform_get_drvdata(pdev);
  161. gpiochip_remove(&tps65910_gpio->gpio_chip);
  162. return 0;
  163. }
  164. static struct platform_driver tps65910_gpio_driver = {
  165. .driver.name = "tps65910-gpio",
  166. .driver.owner = THIS_MODULE,
  167. .probe = tps65910_gpio_probe,
  168. .remove = tps65910_gpio_remove,
  169. };
  170. static int __init tps65910_gpio_init(void)
  171. {
  172. return platform_driver_register(&tps65910_gpio_driver);
  173. }
  174. subsys_initcall(tps65910_gpio_init);
  175. static void __exit tps65910_gpio_exit(void)
  176. {
  177. platform_driver_unregister(&tps65910_gpio_driver);
  178. }
  179. module_exit(tps65910_gpio_exit);
  180. MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
  181. MODULE_AUTHOR("Jorge Eduardo Candelaria jedu@slimlogic.co.uk>");
  182. MODULE_DESCRIPTION("GPIO interface for TPS65910/TPS6511 PMICs");
  183. MODULE_LICENSE("GPL v2");
  184. MODULE_ALIAS("platform:tps65910-gpio");