gpio-exar.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * GPIO driver for Exar XR17V35X chip
  4. *
  5. * Copyright (C) 2015 Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>
  6. */
  7. #include <linux/bitops.h>
  8. #include <linux/device.h>
  9. #include <linux/gpio/driver.h>
  10. #include <linux/init.h>
  11. #include <linux/kernel.h>
  12. #include <linux/module.h>
  13. #include <linux/pci.h>
  14. #include <linux/platform_device.h>
  15. #define EXAR_OFFSET_MPIOLVL_LO 0x90
  16. #define EXAR_OFFSET_MPIOSEL_LO 0x93
  17. #define EXAR_OFFSET_MPIOLVL_HI 0x96
  18. #define EXAR_OFFSET_MPIOSEL_HI 0x99
  19. #define DRIVER_NAME "gpio_exar"
  20. static DEFINE_IDA(ida_index);
  21. struct exar_gpio_chip {
  22. struct gpio_chip gpio_chip;
  23. struct mutex lock;
  24. int index;
  25. void __iomem *regs;
  26. char name[20];
  27. unsigned int first_pin;
  28. };
  29. static void exar_update(struct gpio_chip *chip, unsigned int reg, int val,
  30. unsigned int offset)
  31. {
  32. struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
  33. int temp;
  34. mutex_lock(&exar_gpio->lock);
  35. temp = readb(exar_gpio->regs + reg);
  36. temp &= ~BIT(offset);
  37. if (val)
  38. temp |= BIT(offset);
  39. writeb(temp, exar_gpio->regs + reg);
  40. mutex_unlock(&exar_gpio->lock);
  41. }
  42. static int exar_set_direction(struct gpio_chip *chip, int direction,
  43. unsigned int offset)
  44. {
  45. struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
  46. unsigned int addr = (offset + exar_gpio->first_pin) / 8 ?
  47. EXAR_OFFSET_MPIOSEL_HI : EXAR_OFFSET_MPIOSEL_LO;
  48. unsigned int bit = (offset + exar_gpio->first_pin) % 8;
  49. exar_update(chip, addr, direction, bit);
  50. return 0;
  51. }
  52. static int exar_get(struct gpio_chip *chip, unsigned int reg)
  53. {
  54. struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
  55. int value;
  56. mutex_lock(&exar_gpio->lock);
  57. value = readb(exar_gpio->regs + reg);
  58. mutex_unlock(&exar_gpio->lock);
  59. return value;
  60. }
  61. static int exar_get_direction(struct gpio_chip *chip, unsigned int offset)
  62. {
  63. struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
  64. unsigned int addr = (offset + exar_gpio->first_pin) / 8 ?
  65. EXAR_OFFSET_MPIOSEL_HI : EXAR_OFFSET_MPIOSEL_LO;
  66. unsigned int bit = (offset + exar_gpio->first_pin) % 8;
  67. if (exar_get(chip, addr) & BIT(bit))
  68. return GPIO_LINE_DIRECTION_IN;
  69. return GPIO_LINE_DIRECTION_OUT;
  70. }
  71. static int exar_get_value(struct gpio_chip *chip, unsigned int offset)
  72. {
  73. struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
  74. unsigned int addr = (offset + exar_gpio->first_pin) / 8 ?
  75. EXAR_OFFSET_MPIOLVL_HI : EXAR_OFFSET_MPIOLVL_LO;
  76. unsigned int bit = (offset + exar_gpio->first_pin) % 8;
  77. return !!(exar_get(chip, addr) & BIT(bit));
  78. }
  79. static void exar_set_value(struct gpio_chip *chip, unsigned int offset,
  80. int value)
  81. {
  82. struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
  83. unsigned int addr = (offset + exar_gpio->first_pin) / 8 ?
  84. EXAR_OFFSET_MPIOLVL_HI : EXAR_OFFSET_MPIOLVL_LO;
  85. unsigned int bit = (offset + exar_gpio->first_pin) % 8;
  86. exar_update(chip, addr, value, bit);
  87. }
  88. static int exar_direction_output(struct gpio_chip *chip, unsigned int offset,
  89. int value)
  90. {
  91. exar_set_value(chip, offset, value);
  92. return exar_set_direction(chip, 0, offset);
  93. }
  94. static int exar_direction_input(struct gpio_chip *chip, unsigned int offset)
  95. {
  96. return exar_set_direction(chip, 1, offset);
  97. }
  98. static int gpio_exar_probe(struct platform_device *pdev)
  99. {
  100. struct pci_dev *pcidev = to_pci_dev(pdev->dev.parent);
  101. struct exar_gpio_chip *exar_gpio;
  102. u32 first_pin, ngpios;
  103. void __iomem *p;
  104. int index, ret;
  105. /*
  106. * The UART driver must have mapped region 0 prior to registering this
  107. * device - use it.
  108. */
  109. p = pcim_iomap_table(pcidev)[0];
  110. if (!p)
  111. return -ENOMEM;
  112. ret = device_property_read_u32(&pdev->dev, "exar,first-pin",
  113. &first_pin);
  114. if (ret)
  115. return ret;
  116. ret = device_property_read_u32(&pdev->dev, "ngpios", &ngpios);
  117. if (ret)
  118. return ret;
  119. exar_gpio = devm_kzalloc(&pdev->dev, sizeof(*exar_gpio), GFP_KERNEL);
  120. if (!exar_gpio)
  121. return -ENOMEM;
  122. mutex_init(&exar_gpio->lock);
  123. index = ida_simple_get(&ida_index, 0, 0, GFP_KERNEL);
  124. if (index < 0) {
  125. ret = index;
  126. goto err_mutex_destroy;
  127. }
  128. sprintf(exar_gpio->name, "exar_gpio%d", index);
  129. exar_gpio->gpio_chip.label = exar_gpio->name;
  130. exar_gpio->gpio_chip.parent = &pdev->dev;
  131. exar_gpio->gpio_chip.direction_output = exar_direction_output;
  132. exar_gpio->gpio_chip.direction_input = exar_direction_input;
  133. exar_gpio->gpio_chip.get_direction = exar_get_direction;
  134. exar_gpio->gpio_chip.get = exar_get_value;
  135. exar_gpio->gpio_chip.set = exar_set_value;
  136. exar_gpio->gpio_chip.base = -1;
  137. exar_gpio->gpio_chip.ngpio = ngpios;
  138. exar_gpio->regs = p;
  139. exar_gpio->index = index;
  140. exar_gpio->first_pin = first_pin;
  141. ret = devm_gpiochip_add_data(&pdev->dev,
  142. &exar_gpio->gpio_chip, exar_gpio);
  143. if (ret)
  144. goto err_destroy;
  145. platform_set_drvdata(pdev, exar_gpio);
  146. return 0;
  147. err_destroy:
  148. ida_simple_remove(&ida_index, index);
  149. err_mutex_destroy:
  150. mutex_destroy(&exar_gpio->lock);
  151. return ret;
  152. }
  153. static int gpio_exar_remove(struct platform_device *pdev)
  154. {
  155. struct exar_gpio_chip *exar_gpio = platform_get_drvdata(pdev);
  156. ida_simple_remove(&ida_index, exar_gpio->index);
  157. mutex_destroy(&exar_gpio->lock);
  158. return 0;
  159. }
  160. static struct platform_driver gpio_exar_driver = {
  161. .probe = gpio_exar_probe,
  162. .remove = gpio_exar_remove,
  163. .driver = {
  164. .name = DRIVER_NAME,
  165. },
  166. };
  167. module_platform_driver(gpio_exar_driver);
  168. MODULE_ALIAS("platform:" DRIVER_NAME);
  169. MODULE_DESCRIPTION("Exar GPIO driver");
  170. MODULE_AUTHOR("Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>");
  171. MODULE_LICENSE("GPL");