gpio-exar.c 5.4 KB

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