axp_gpio.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
  3. *
  4. * X-Powers AXP Power Management ICs gpio driver
  5. *
  6. * SPDX-License-Identifier: GPL-2.0+
  7. */
  8. #include <common.h>
  9. #include <asm/arch/gpio.h>
  10. #include <asm/arch/pmic_bus.h>
  11. #include <errno.h>
  12. #ifdef CONFIG_AXP152_POWER
  13. #include <axp152.h>
  14. #elif defined CONFIG_AXP209_POWER
  15. #include <axp209.h>
  16. #elif defined CONFIG_AXP221_POWER
  17. #include <axp221.h>
  18. #else
  19. #error Unknown AXP model
  20. #endif
  21. static u8 axp_get_gpio_ctrl_reg(unsigned pin)
  22. {
  23. switch (pin) {
  24. case 0: return AXP_GPIO0_CTRL;
  25. case 1: return AXP_GPIO1_CTRL;
  26. #ifdef AXP_GPIO2_CTRL
  27. case 2: return AXP_GPIO2_CTRL;
  28. #endif
  29. #ifdef AXP_GPIO3_CTRL
  30. case 3: return AXP_GPIO3_CTRL;
  31. #endif
  32. }
  33. return 0;
  34. }
  35. int axp_gpio_direction_input(struct udevice *dev, unsigned pin)
  36. {
  37. u8 reg;
  38. switch (pin) {
  39. #ifndef CONFIG_AXP152_POWER /* NA on axp152 */
  40. case SUNXI_GPIO_AXP0_VBUS_DETECT:
  41. return 0;
  42. #endif
  43. default:
  44. reg = axp_get_gpio_ctrl_reg(pin);
  45. if (reg == 0)
  46. return -EINVAL;
  47. return pmic_bus_write(reg, AXP_GPIO_CTRL_INPUT);
  48. }
  49. }
  50. int axp_gpio_direction_output(struct udevice *dev, unsigned pin, int val)
  51. {
  52. __maybe_unused int ret;
  53. u8 reg;
  54. switch (pin) {
  55. #ifdef CONFIG_AXP221_POWER /* Only available on axp221/axp223 */
  56. case SUNXI_GPIO_AXP0_VBUS_ENABLE:
  57. ret = pmic_bus_clrbits(AXP221_MISC_CTRL,
  58. AXP221_MISC_CTRL_N_VBUSEN_FUNC);
  59. if (ret)
  60. return ret;
  61. return axp_gpio_set_value(dev, pin, val);
  62. #endif
  63. default:
  64. reg = axp_get_gpio_ctrl_reg(pin);
  65. if (reg == 0)
  66. return -EINVAL;
  67. return pmic_bus_write(reg, val ? AXP_GPIO_CTRL_OUTPUT_HIGH :
  68. AXP_GPIO_CTRL_OUTPUT_LOW);
  69. }
  70. }
  71. int axp_gpio_get_value(struct udevice *dev, unsigned pin)
  72. {
  73. u8 reg, val, mask;
  74. int ret;
  75. switch (pin) {
  76. #ifndef CONFIG_AXP152_POWER /* NA on axp152 */
  77. case SUNXI_GPIO_AXP0_VBUS_DETECT:
  78. ret = pmic_bus_read(AXP_POWER_STATUS, &val);
  79. mask = AXP_POWER_STATUS_VBUS_PRESENT;
  80. break;
  81. #endif
  82. #ifdef CONFIG_AXP221_POWER /* Only available on axp221/axp223 */
  83. case SUNXI_GPIO_AXP0_VBUS_ENABLE:
  84. ret = pmic_bus_read(AXP221_VBUS_IPSOUT, &val);
  85. mask = AXP221_VBUS_IPSOUT_DRIVEBUS;
  86. break;
  87. #endif
  88. default:
  89. reg = axp_get_gpio_ctrl_reg(pin);
  90. if (reg == 0)
  91. return -EINVAL;
  92. ret = pmic_bus_read(AXP_GPIO_STATE, &val);
  93. mask = 1 << (pin + AXP_GPIO_STATE_OFFSET);
  94. }
  95. if (ret)
  96. return ret;
  97. return (val & mask) ? 1 : 0;
  98. }
  99. int axp_gpio_set_value(struct udevice *dev, unsigned pin, int val)
  100. {
  101. u8 reg;
  102. switch (pin) {
  103. #ifdef CONFIG_AXP221_POWER /* Only available on axp221/axp223 */
  104. case SUNXI_GPIO_AXP0_VBUS_ENABLE:
  105. if (val)
  106. return pmic_bus_setbits(AXP221_VBUS_IPSOUT,
  107. AXP221_VBUS_IPSOUT_DRIVEBUS);
  108. else
  109. return pmic_bus_clrbits(AXP221_VBUS_IPSOUT,
  110. AXP221_VBUS_IPSOUT_DRIVEBUS);
  111. #endif
  112. default:
  113. reg = axp_get_gpio_ctrl_reg(pin);
  114. if (reg == 0)
  115. return -EINVAL;
  116. return pmic_bus_write(reg, val ? AXP_GPIO_CTRL_OUTPUT_HIGH :
  117. AXP_GPIO_CTRL_OUTPUT_LOW);
  118. }
  119. }
  120. int axp_gpio_init(void)
  121. {
  122. int ret;
  123. ret = pmic_bus_init();
  124. if (ret)
  125. return ret;
  126. return 0;
  127. }