kw_gpio.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * arch/arm/plat-orion/gpio.c
  4. *
  5. * Marvell Orion SoC GPIO handling.
  6. */
  7. /*
  8. * Based on (mostly copied from) plat-orion based Linux 2.6 kernel driver.
  9. * Removed orion_gpiochip struct and kernel level irq handling.
  10. *
  11. * Dieter Kiermaier dk-arm-linux@gmx.de
  12. */
  13. #include <common.h>
  14. #include <linux/bitops.h>
  15. #include <asm/io.h>
  16. #include <asm/arch/soc.h>
  17. #include <asm/arch/gpio.h>
  18. static unsigned long gpio_valid_input[BITS_TO_LONGS(GPIO_MAX)];
  19. static unsigned long gpio_valid_output[BITS_TO_LONGS(GPIO_MAX)];
  20. void __set_direction(unsigned pin, int input)
  21. {
  22. u32 u;
  23. u = readl(GPIO_IO_CONF(pin));
  24. if (input)
  25. u |= 1 << (pin & 31);
  26. else
  27. u &= ~(1 << (pin & 31));
  28. writel(u, GPIO_IO_CONF(pin));
  29. u = readl(GPIO_IO_CONF(pin));
  30. }
  31. static void __set_level(unsigned pin, int high)
  32. {
  33. u32 u;
  34. u = readl(GPIO_OUT(pin));
  35. if (high)
  36. u |= 1 << (pin & 31);
  37. else
  38. u &= ~(1 << (pin & 31));
  39. writel(u, GPIO_OUT(pin));
  40. }
  41. static void __set_blinking(unsigned pin, int blink)
  42. {
  43. u32 u;
  44. u = readl(GPIO_BLINK_EN(pin));
  45. if (blink)
  46. u |= 1 << (pin & 31);
  47. else
  48. u &= ~(1 << (pin & 31));
  49. writel(u, GPIO_BLINK_EN(pin));
  50. }
  51. int kw_gpio_is_valid(unsigned pin, int mode)
  52. {
  53. if (pin < GPIO_MAX) {
  54. if ((mode & GPIO_INPUT_OK) && !test_bit(pin, gpio_valid_input))
  55. goto err_out;
  56. if ((mode & GPIO_OUTPUT_OK) && !test_bit(pin, gpio_valid_output))
  57. goto err_out;
  58. return 0;
  59. }
  60. err_out:
  61. printf("%s: invalid GPIO %d\n", __func__, pin);
  62. return 1;
  63. }
  64. void kw_gpio_set_valid(unsigned pin, int mode)
  65. {
  66. if (mode == 1)
  67. mode = GPIO_INPUT_OK | GPIO_OUTPUT_OK;
  68. if (mode & GPIO_INPUT_OK)
  69. __set_bit(pin, gpio_valid_input);
  70. else
  71. __clear_bit(pin, gpio_valid_input);
  72. if (mode & GPIO_OUTPUT_OK)
  73. __set_bit(pin, gpio_valid_output);
  74. else
  75. __clear_bit(pin, gpio_valid_output);
  76. }
  77. /*
  78. * GENERIC_GPIO primitives.
  79. */
  80. int kw_gpio_direction_input(unsigned pin)
  81. {
  82. if (kw_gpio_is_valid(pin, GPIO_INPUT_OK) != 0)
  83. return 1;
  84. /* Configure GPIO direction. */
  85. __set_direction(pin, 1);
  86. return 0;
  87. }
  88. int kw_gpio_direction_output(unsigned pin, int value)
  89. {
  90. if (kw_gpio_is_valid(pin, GPIO_OUTPUT_OK) != 0)
  91. {
  92. printf("%s: invalid GPIO %d\n", __func__, pin);
  93. return 1;
  94. }
  95. __set_blinking(pin, 0);
  96. /* Configure GPIO output value. */
  97. __set_level(pin, value);
  98. /* Configure GPIO direction. */
  99. __set_direction(pin, 0);
  100. return 0;
  101. }
  102. int kw_gpio_get_value(unsigned pin)
  103. {
  104. int val;
  105. if (readl(GPIO_IO_CONF(pin)) & (1 << (pin & 31)))
  106. val = readl(GPIO_DATA_IN(pin)) ^ readl(GPIO_IN_POL(pin));
  107. else
  108. val = readl(GPIO_OUT(pin));
  109. return (val >> (pin & 31)) & 1;
  110. }
  111. void kw_gpio_set_value(unsigned pin, int value)
  112. {
  113. /* Configure GPIO output value. */
  114. __set_level(pin, value);
  115. }
  116. void kw_gpio_set_blink(unsigned pin, int blink)
  117. {
  118. /* Set output value to zero. */
  119. __set_level(pin, 0);
  120. /* Set blinking. */
  121. __set_blinking(pin, blink);
  122. }