gpio-ge.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * Driver for GE FPGA based GPIO
  3. *
  4. * Author: Martyn Welch <martyn.welch@ge.com>
  5. *
  6. * 2008 (c) GE Intelligent Platforms Embedded Systems, Inc.
  7. *
  8. * This file is licensed under the terms of the GNU General Public License
  9. * version 2. This program is licensed "as is" without any warranty of any
  10. * kind, whether express or implied.
  11. */
  12. /* TODO
  13. *
  14. * Configuration of output modes (totem-pole/open-drain)
  15. * Interrupt configuration - interrupts are always generated the FPGA relies on
  16. * the I/O interrupt controllers mask to stop them propergating
  17. */
  18. #include <linux/kernel.h>
  19. #include <linux/io.h>
  20. #include <linux/of_device.h>
  21. #include <linux/of_gpio.h>
  22. #include <linux/module.h>
  23. #define GEF_GPIO_DIRECT 0x00
  24. #define GEF_GPIO_IN 0x04
  25. #define GEF_GPIO_OUT 0x08
  26. #define GEF_GPIO_TRIG 0x0C
  27. #define GEF_GPIO_POLAR_A 0x10
  28. #define GEF_GPIO_POLAR_B 0x14
  29. #define GEF_GPIO_INT_STAT 0x18
  30. #define GEF_GPIO_OVERRUN 0x1C
  31. #define GEF_GPIO_MODE 0x20
  32. static void gef_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
  33. {
  34. struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
  35. unsigned int data;
  36. data = ioread32be(mmchip->regs + GEF_GPIO_OUT);
  37. if (value)
  38. data = data | BIT(offset);
  39. else
  40. data = data & ~BIT(offset);
  41. iowrite32be(data, mmchip->regs + GEF_GPIO_OUT);
  42. }
  43. static int gef_gpio_dir_in(struct gpio_chip *chip, unsigned offset)
  44. {
  45. unsigned int data;
  46. struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
  47. data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT);
  48. data = data | BIT(offset);
  49. iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT);
  50. return 0;
  51. }
  52. static int gef_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int value)
  53. {
  54. unsigned int data;
  55. struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
  56. /* Set value before switching to output */
  57. gef_gpio_set(mmchip->regs + GEF_GPIO_OUT, offset, value);
  58. data = ioread32be(mmchip->regs + GEF_GPIO_DIRECT);
  59. data = data & ~BIT(offset);
  60. iowrite32be(data, mmchip->regs + GEF_GPIO_DIRECT);
  61. return 0;
  62. }
  63. static int gef_gpio_get(struct gpio_chip *chip, unsigned offset)
  64. {
  65. struct of_mm_gpio_chip *mmchip = to_of_mm_gpio_chip(chip);
  66. return !!(ioread32be(mmchip->regs + GEF_GPIO_IN) & BIT(offset));
  67. }
  68. static const struct of_device_id gef_gpio_ids[] = {
  69. {
  70. .compatible = "gef,sbc610-gpio",
  71. .data = (void *)19,
  72. }, {
  73. .compatible = "gef,sbc310-gpio",
  74. .data = (void *)6,
  75. }, {
  76. .compatible = "ge,imp3a-gpio",
  77. .data = (void *)16,
  78. },
  79. { }
  80. };
  81. MODULE_DEVICE_TABLE(of, gef_gpio_ids);
  82. static int __init gef_gpio_probe(struct platform_device *pdev)
  83. {
  84. const struct of_device_id *of_id =
  85. of_match_device(gef_gpio_ids, &pdev->dev);
  86. struct of_mm_gpio_chip *mmchip;
  87. mmchip = devm_kzalloc(&pdev->dev, sizeof(*mmchip), GFP_KERNEL);
  88. if (!mmchip)
  89. return -ENOMEM;
  90. /* Setup pointers to chip functions */
  91. mmchip->gc.ngpio = (u16)(uintptr_t)of_id->data;
  92. mmchip->gc.of_gpio_n_cells = 2;
  93. mmchip->gc.direction_input = gef_gpio_dir_in;
  94. mmchip->gc.direction_output = gef_gpio_dir_out;
  95. mmchip->gc.get = gef_gpio_get;
  96. mmchip->gc.set = gef_gpio_set;
  97. /* This function adds a memory mapped GPIO chip */
  98. return of_mm_gpiochip_add(pdev->dev.of_node, mmchip);
  99. };
  100. static struct platform_driver gef_gpio_driver = {
  101. .driver = {
  102. .name = "gef-gpio",
  103. .owner = THIS_MODULE,
  104. .of_match_table = gef_gpio_ids,
  105. },
  106. };
  107. module_platform_driver_probe(gef_gpio_driver, gef_gpio_probe);
  108. MODULE_DESCRIPTION("GE I/O FPGA GPIO driver");
  109. MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com");
  110. MODULE_LICENSE("GPL");