gpio-rc5t583.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * GPIO driver for RICOH583 power management chip.
  4. *
  5. * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
  6. * Author: Laxman dewangan <ldewangan@nvidia.com>
  7. *
  8. * Based on code
  9. * Copyright (C) 2011 RICOH COMPANY,LTD
  10. */
  11. #include <linux/init.h>
  12. #include <linux/kernel.h>
  13. #include <linux/slab.h>
  14. #include <linux/platform_device.h>
  15. #include <linux/device.h>
  16. #include <linux/gpio/driver.h>
  17. #include <linux/mfd/rc5t583.h>
  18. struct rc5t583_gpio {
  19. struct gpio_chip gpio_chip;
  20. struct rc5t583 *rc5t583;
  21. };
  22. static int rc5t583_gpio_get(struct gpio_chip *gc, unsigned int offset)
  23. {
  24. struct rc5t583_gpio *rc5t583_gpio = gpiochip_get_data(gc);
  25. struct device *parent = rc5t583_gpio->rc5t583->dev;
  26. uint8_t val = 0;
  27. int ret;
  28. ret = rc5t583_read(parent, RC5T583_GPIO_MON_IOIN, &val);
  29. if (ret < 0)
  30. return ret;
  31. return !!(val & BIT(offset));
  32. }
  33. static void rc5t583_gpio_set(struct gpio_chip *gc, unsigned int offset, int val)
  34. {
  35. struct rc5t583_gpio *rc5t583_gpio = gpiochip_get_data(gc);
  36. struct device *parent = rc5t583_gpio->rc5t583->dev;
  37. if (val)
  38. rc5t583_set_bits(parent, RC5T583_GPIO_IOOUT, BIT(offset));
  39. else
  40. rc5t583_clear_bits(parent, RC5T583_GPIO_IOOUT, BIT(offset));
  41. }
  42. static int rc5t583_gpio_dir_input(struct gpio_chip *gc, unsigned int offset)
  43. {
  44. struct rc5t583_gpio *rc5t583_gpio = gpiochip_get_data(gc);
  45. struct device *parent = rc5t583_gpio->rc5t583->dev;
  46. int ret;
  47. ret = rc5t583_clear_bits(parent, RC5T583_GPIO_IOSEL, BIT(offset));
  48. if (ret < 0)
  49. return ret;
  50. /* Set pin to gpio mode */
  51. return rc5t583_clear_bits(parent, RC5T583_GPIO_PGSEL, BIT(offset));
  52. }
  53. static int rc5t583_gpio_dir_output(struct gpio_chip *gc, unsigned offset,
  54. int value)
  55. {
  56. struct rc5t583_gpio *rc5t583_gpio = gpiochip_get_data(gc);
  57. struct device *parent = rc5t583_gpio->rc5t583->dev;
  58. int ret;
  59. rc5t583_gpio_set(gc, offset, value);
  60. ret = rc5t583_set_bits(parent, RC5T583_GPIO_IOSEL, BIT(offset));
  61. if (ret < 0)
  62. return ret;
  63. /* Set pin to gpio mode */
  64. return rc5t583_clear_bits(parent, RC5T583_GPIO_PGSEL, BIT(offset));
  65. }
  66. static int rc5t583_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
  67. {
  68. struct rc5t583_gpio *rc5t583_gpio = gpiochip_get_data(gc);
  69. if (offset < RC5T583_MAX_GPIO)
  70. return rc5t583_gpio->rc5t583->irq_base +
  71. RC5T583_IRQ_GPIO0 + offset;
  72. return -EINVAL;
  73. }
  74. static void rc5t583_gpio_free(struct gpio_chip *gc, unsigned offset)
  75. {
  76. struct rc5t583_gpio *rc5t583_gpio = gpiochip_get_data(gc);
  77. struct device *parent = rc5t583_gpio->rc5t583->dev;
  78. rc5t583_set_bits(parent, RC5T583_GPIO_PGSEL, BIT(offset));
  79. }
  80. static int rc5t583_gpio_probe(struct platform_device *pdev)
  81. {
  82. struct rc5t583 *rc5t583 = dev_get_drvdata(pdev->dev.parent);
  83. struct rc5t583_platform_data *pdata = dev_get_platdata(rc5t583->dev);
  84. struct rc5t583_gpio *rc5t583_gpio;
  85. rc5t583_gpio = devm_kzalloc(&pdev->dev, sizeof(*rc5t583_gpio),
  86. GFP_KERNEL);
  87. if (!rc5t583_gpio)
  88. return -ENOMEM;
  89. rc5t583_gpio->gpio_chip.label = "gpio-rc5t583",
  90. rc5t583_gpio->gpio_chip.owner = THIS_MODULE,
  91. rc5t583_gpio->gpio_chip.free = rc5t583_gpio_free,
  92. rc5t583_gpio->gpio_chip.direction_input = rc5t583_gpio_dir_input,
  93. rc5t583_gpio->gpio_chip.direction_output = rc5t583_gpio_dir_output,
  94. rc5t583_gpio->gpio_chip.set = rc5t583_gpio_set,
  95. rc5t583_gpio->gpio_chip.get = rc5t583_gpio_get,
  96. rc5t583_gpio->gpio_chip.to_irq = rc5t583_gpio_to_irq,
  97. rc5t583_gpio->gpio_chip.ngpio = RC5T583_MAX_GPIO,
  98. rc5t583_gpio->gpio_chip.can_sleep = true,
  99. rc5t583_gpio->gpio_chip.parent = &pdev->dev;
  100. rc5t583_gpio->gpio_chip.base = -1;
  101. rc5t583_gpio->rc5t583 = rc5t583;
  102. if (pdata && pdata->gpio_base)
  103. rc5t583_gpio->gpio_chip.base = pdata->gpio_base;
  104. platform_set_drvdata(pdev, rc5t583_gpio);
  105. return devm_gpiochip_add_data(&pdev->dev, &rc5t583_gpio->gpio_chip,
  106. rc5t583_gpio);
  107. }
  108. static struct platform_driver rc5t583_gpio_driver = {
  109. .driver = {
  110. .name = "rc5t583-gpio",
  111. },
  112. .probe = rc5t583_gpio_probe,
  113. };
  114. static int __init rc5t583_gpio_init(void)
  115. {
  116. return platform_driver_register(&rc5t583_gpio_driver);
  117. }
  118. subsys_initcall(rc5t583_gpio_init);