gpio-palmas.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * TI Palma series PMIC's GPIO driver.
  4. *
  5. * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
  6. *
  7. * Author: Laxman Dewangan <ldewangan@nvidia.com>
  8. */
  9. #include <linux/gpio/driver.h>
  10. #include <linux/kernel.h>
  11. #include <linux/init.h>
  12. #include <linux/mfd/palmas.h>
  13. #include <linux/of.h>
  14. #include <linux/of_device.h>
  15. #include <linux/platform_device.h>
  16. struct palmas_gpio {
  17. struct gpio_chip gpio_chip;
  18. struct palmas *palmas;
  19. };
  20. struct palmas_device_data {
  21. int ngpio;
  22. };
  23. static int palmas_gpio_get(struct gpio_chip *gc, unsigned offset)
  24. {
  25. struct palmas_gpio *pg = gpiochip_get_data(gc);
  26. struct palmas *palmas = pg->palmas;
  27. unsigned int val;
  28. int ret;
  29. unsigned int reg;
  30. int gpio16 = (offset/8);
  31. offset %= 8;
  32. reg = (gpio16) ? PALMAS_GPIO_DATA_DIR2 : PALMAS_GPIO_DATA_DIR;
  33. ret = palmas_read(palmas, PALMAS_GPIO_BASE, reg, &val);
  34. if (ret < 0) {
  35. dev_err(gc->parent, "Reg 0x%02x read failed, %d\n", reg, ret);
  36. return ret;
  37. }
  38. if (val & BIT(offset))
  39. reg = (gpio16) ? PALMAS_GPIO_DATA_OUT2 : PALMAS_GPIO_DATA_OUT;
  40. else
  41. reg = (gpio16) ? PALMAS_GPIO_DATA_IN2 : PALMAS_GPIO_DATA_IN;
  42. ret = palmas_read(palmas, PALMAS_GPIO_BASE, reg, &val);
  43. if (ret < 0) {
  44. dev_err(gc->parent, "Reg 0x%02x read failed, %d\n", reg, ret);
  45. return ret;
  46. }
  47. return !!(val & BIT(offset));
  48. }
  49. static void palmas_gpio_set(struct gpio_chip *gc, unsigned offset,
  50. int value)
  51. {
  52. struct palmas_gpio *pg = gpiochip_get_data(gc);
  53. struct palmas *palmas = pg->palmas;
  54. int ret;
  55. unsigned int reg;
  56. int gpio16 = (offset/8);
  57. offset %= 8;
  58. if (gpio16)
  59. reg = (value) ?
  60. PALMAS_GPIO_SET_DATA_OUT2 : PALMAS_GPIO_CLEAR_DATA_OUT2;
  61. else
  62. reg = (value) ?
  63. PALMAS_GPIO_SET_DATA_OUT : PALMAS_GPIO_CLEAR_DATA_OUT;
  64. ret = palmas_write(palmas, PALMAS_GPIO_BASE, reg, BIT(offset));
  65. if (ret < 0)
  66. dev_err(gc->parent, "Reg 0x%02x write failed, %d\n", reg, ret);
  67. }
  68. static int palmas_gpio_output(struct gpio_chip *gc, unsigned offset,
  69. int value)
  70. {
  71. struct palmas_gpio *pg = gpiochip_get_data(gc);
  72. struct palmas *palmas = pg->palmas;
  73. int ret;
  74. unsigned int reg;
  75. int gpio16 = (offset/8);
  76. offset %= 8;
  77. reg = (gpio16) ? PALMAS_GPIO_DATA_DIR2 : PALMAS_GPIO_DATA_DIR;
  78. /* Set the initial value */
  79. palmas_gpio_set(gc, offset, value);
  80. ret = palmas_update_bits(palmas, PALMAS_GPIO_BASE, reg,
  81. BIT(offset), BIT(offset));
  82. if (ret < 0)
  83. dev_err(gc->parent, "Reg 0x%02x update failed, %d\n", reg,
  84. ret);
  85. return ret;
  86. }
  87. static int palmas_gpio_input(struct gpio_chip *gc, unsigned offset)
  88. {
  89. struct palmas_gpio *pg = gpiochip_get_data(gc);
  90. struct palmas *palmas = pg->palmas;
  91. int ret;
  92. unsigned int reg;
  93. int gpio16 = (offset/8);
  94. offset %= 8;
  95. reg = (gpio16) ? PALMAS_GPIO_DATA_DIR2 : PALMAS_GPIO_DATA_DIR;
  96. ret = palmas_update_bits(palmas, PALMAS_GPIO_BASE, reg, BIT(offset), 0);
  97. if (ret < 0)
  98. dev_err(gc->parent, "Reg 0x%02x update failed, %d\n", reg,
  99. ret);
  100. return ret;
  101. }
  102. static int palmas_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
  103. {
  104. struct palmas_gpio *pg = gpiochip_get_data(gc);
  105. struct palmas *palmas = pg->palmas;
  106. return palmas_irq_get_virq(palmas, PALMAS_GPIO_0_IRQ + offset);
  107. }
  108. static const struct palmas_device_data palmas_dev_data = {
  109. .ngpio = 8,
  110. };
  111. static const struct palmas_device_data tps80036_dev_data = {
  112. .ngpio = 16,
  113. };
  114. static const struct of_device_id of_palmas_gpio_match[] = {
  115. { .compatible = "ti,palmas-gpio", .data = &palmas_dev_data,},
  116. { .compatible = "ti,tps65913-gpio", .data = &palmas_dev_data,},
  117. { .compatible = "ti,tps65914-gpio", .data = &palmas_dev_data,},
  118. { .compatible = "ti,tps80036-gpio", .data = &tps80036_dev_data,},
  119. { },
  120. };
  121. static int palmas_gpio_probe(struct platform_device *pdev)
  122. {
  123. struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
  124. struct palmas_platform_data *palmas_pdata;
  125. struct palmas_gpio *palmas_gpio;
  126. int ret;
  127. const struct palmas_device_data *dev_data;
  128. dev_data = of_device_get_match_data(&pdev->dev);
  129. if (!dev_data)
  130. dev_data = &palmas_dev_data;
  131. palmas_gpio = devm_kzalloc(&pdev->dev,
  132. sizeof(*palmas_gpio), GFP_KERNEL);
  133. if (!palmas_gpio)
  134. return -ENOMEM;
  135. palmas_gpio->palmas = palmas;
  136. palmas_gpio->gpio_chip.owner = THIS_MODULE;
  137. palmas_gpio->gpio_chip.label = dev_name(&pdev->dev);
  138. palmas_gpio->gpio_chip.ngpio = dev_data->ngpio;
  139. palmas_gpio->gpio_chip.can_sleep = true;
  140. palmas_gpio->gpio_chip.direction_input = palmas_gpio_input;
  141. palmas_gpio->gpio_chip.direction_output = palmas_gpio_output;
  142. palmas_gpio->gpio_chip.to_irq = palmas_gpio_to_irq;
  143. palmas_gpio->gpio_chip.set = palmas_gpio_set;
  144. palmas_gpio->gpio_chip.get = palmas_gpio_get;
  145. palmas_gpio->gpio_chip.parent = &pdev->dev;
  146. #ifdef CONFIG_OF_GPIO
  147. palmas_gpio->gpio_chip.of_node = pdev->dev.of_node;
  148. #endif
  149. palmas_pdata = dev_get_platdata(palmas->dev);
  150. if (palmas_pdata && palmas_pdata->gpio_base)
  151. palmas_gpio->gpio_chip.base = palmas_pdata->gpio_base;
  152. else
  153. palmas_gpio->gpio_chip.base = -1;
  154. ret = devm_gpiochip_add_data(&pdev->dev, &palmas_gpio->gpio_chip,
  155. palmas_gpio);
  156. if (ret < 0) {
  157. dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
  158. return ret;
  159. }
  160. platform_set_drvdata(pdev, palmas_gpio);
  161. return ret;
  162. }
  163. static struct platform_driver palmas_gpio_driver = {
  164. .driver.name = "palmas-gpio",
  165. .driver.of_match_table = of_palmas_gpio_match,
  166. .probe = palmas_gpio_probe,
  167. };
  168. static int __init palmas_gpio_init(void)
  169. {
  170. return platform_driver_register(&palmas_gpio_driver);
  171. }
  172. subsys_initcall(palmas_gpio_init);