gpio-en7523.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. #include <linux/types.h>
  3. #include <linux/io.h>
  4. #include <linux/bits.h>
  5. #include <linux/gpio/driver.h>
  6. #include <linux/mod_devicetable.h>
  7. #include <linux/module.h>
  8. #include <linux/platform_device.h>
  9. #include <linux/property.h>
  10. #define AIROHA_GPIO_MAX 32
  11. /**
  12. * airoha_gpio_ctrl - Airoha GPIO driver data
  13. * @gc: Associated gpio_chip instance.
  14. * @data: The data register.
  15. * @dir0: The direction register for the lower 16 pins.
  16. * @dir1: The direction register for the higher 16 pins.
  17. * @output: The output enable register.
  18. */
  19. struct airoha_gpio_ctrl {
  20. struct gpio_chip gc;
  21. void __iomem *data;
  22. void __iomem *dir[2];
  23. void __iomem *output;
  24. };
  25. static struct airoha_gpio_ctrl *gc_to_ctrl(struct gpio_chip *gc)
  26. {
  27. return container_of(gc, struct airoha_gpio_ctrl, gc);
  28. }
  29. static int airoha_dir_set(struct gpio_chip *gc, unsigned int gpio,
  30. int val, int out)
  31. {
  32. struct airoha_gpio_ctrl *ctrl = gc_to_ctrl(gc);
  33. u32 dir = ioread32(ctrl->dir[gpio / 16]);
  34. u32 output = ioread32(ctrl->output);
  35. u32 mask = BIT((gpio % 16) * 2);
  36. if (out) {
  37. dir |= mask;
  38. output |= BIT(gpio);
  39. } else {
  40. dir &= ~mask;
  41. output &= ~BIT(gpio);
  42. }
  43. iowrite32(dir, ctrl->dir[gpio / 16]);
  44. if (out)
  45. gc->set(gc, gpio, val);
  46. iowrite32(output, ctrl->output);
  47. return 0;
  48. }
  49. static int airoha_dir_out(struct gpio_chip *gc, unsigned int gpio,
  50. int val)
  51. {
  52. return airoha_dir_set(gc, gpio, val, 1);
  53. }
  54. static int airoha_dir_in(struct gpio_chip *gc, unsigned int gpio)
  55. {
  56. return airoha_dir_set(gc, gpio, 0, 0);
  57. }
  58. static int airoha_get_dir(struct gpio_chip *gc, unsigned int gpio)
  59. {
  60. struct airoha_gpio_ctrl *ctrl = gc_to_ctrl(gc);
  61. u32 dir = ioread32(ctrl->dir[gpio / 16]);
  62. u32 mask = BIT((gpio % 16) * 2);
  63. return (dir & mask) ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
  64. }
  65. static int airoha_gpio_probe(struct platform_device *pdev)
  66. {
  67. struct device *dev = &pdev->dev;
  68. struct airoha_gpio_ctrl *ctrl;
  69. int err;
  70. ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
  71. if (!ctrl)
  72. return -ENOMEM;
  73. ctrl->data = devm_platform_ioremap_resource(pdev, 0);
  74. if (IS_ERR(ctrl->data))
  75. return PTR_ERR(ctrl->data);
  76. ctrl->dir[0] = devm_platform_ioremap_resource(pdev, 1);
  77. if (IS_ERR(ctrl->dir[0]))
  78. return PTR_ERR(ctrl->dir[0]);
  79. ctrl->dir[1] = devm_platform_ioremap_resource(pdev, 2);
  80. if (IS_ERR(ctrl->dir[1]))
  81. return PTR_ERR(ctrl->dir[1]);
  82. ctrl->output = devm_platform_ioremap_resource(pdev, 3);
  83. if (IS_ERR(ctrl->output))
  84. return PTR_ERR(ctrl->output);
  85. err = bgpio_init(&ctrl->gc, dev, 4, ctrl->data, NULL,
  86. NULL, NULL, NULL, 0);
  87. if (err)
  88. return dev_err_probe(dev, err, "unable to init generic GPIO");
  89. ctrl->gc.ngpio = AIROHA_GPIO_MAX;
  90. ctrl->gc.owner = THIS_MODULE;
  91. ctrl->gc.direction_output = airoha_dir_out;
  92. ctrl->gc.direction_input = airoha_dir_in;
  93. ctrl->gc.get_direction = airoha_get_dir;
  94. return devm_gpiochip_add_data(dev, &ctrl->gc, ctrl);
  95. }
  96. static const struct of_device_id airoha_gpio_of_match[] = {
  97. { .compatible = "airoha,en7523-gpio" },
  98. { }
  99. };
  100. MODULE_DEVICE_TABLE(of, airoha_gpio_of_match);
  101. static struct platform_driver airoha_gpio_driver = {
  102. .driver = {
  103. .name = "airoha-gpio",
  104. .of_match_table = airoha_gpio_of_match,
  105. },
  106. .probe = airoha_gpio_probe,
  107. };
  108. module_platform_driver(airoha_gpio_driver);
  109. MODULE_DESCRIPTION("Airoha GPIO support");
  110. MODULE_AUTHOR("John Crispin <[email protected]>");
  111. MODULE_LICENSE("GPL v2");