wm8350-gpio.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /*
  2. * wm8350-core.c -- Device access for Wolfson WM8350
  3. *
  4. * Copyright 2007, 2008 Wolfson Microelectronics PLC.
  5. *
  6. * Author: Liam Girdwood
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License as published by the
  10. * Free Software Foundation; either version 2 of the License, or (at your
  11. * option) any later version.
  12. *
  13. */
  14. #include <linux/kernel.h>
  15. #include <linux/module.h>
  16. #include <linux/errno.h>
  17. #include <linux/mfd/wm8350/core.h>
  18. #include <linux/mfd/wm8350/gpio.h>
  19. #include <linux/mfd/wm8350/pmic.h>
  20. static int gpio_set_dir(struct wm8350 *wm8350, int gpio, int dir)
  21. {
  22. int ret;
  23. wm8350_reg_unlock(wm8350);
  24. if (dir == WM8350_GPIO_DIR_OUT)
  25. ret = wm8350_clear_bits(wm8350,
  26. WM8350_GPIO_CONFIGURATION_I_O,
  27. 1 << gpio);
  28. else
  29. ret = wm8350_set_bits(wm8350,
  30. WM8350_GPIO_CONFIGURATION_I_O,
  31. 1 << gpio);
  32. wm8350_reg_lock(wm8350);
  33. return ret;
  34. }
  35. static int wm8350_gpio_set_debounce(struct wm8350 *wm8350, int gpio, int db)
  36. {
  37. if (db == WM8350_GPIO_DEBOUNCE_ON)
  38. return wm8350_set_bits(wm8350, WM8350_GPIO_DEBOUNCE,
  39. 1 << gpio);
  40. else
  41. return wm8350_clear_bits(wm8350,
  42. WM8350_GPIO_DEBOUNCE, 1 << gpio);
  43. }
  44. static int gpio_set_func(struct wm8350 *wm8350, int gpio, int func)
  45. {
  46. u16 reg;
  47. wm8350_reg_unlock(wm8350);
  48. switch (gpio) {
  49. case 0:
  50. reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)
  51. & ~WM8350_GP0_FN_MASK;
  52. wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,
  53. reg | ((func & 0xf) << 0));
  54. break;
  55. case 1:
  56. reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)
  57. & ~WM8350_GP1_FN_MASK;
  58. wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,
  59. reg | ((func & 0xf) << 4));
  60. break;
  61. case 2:
  62. reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)
  63. & ~WM8350_GP2_FN_MASK;
  64. wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,
  65. reg | ((func & 0xf) << 8));
  66. break;
  67. case 3:
  68. reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)
  69. & ~WM8350_GP3_FN_MASK;
  70. wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,
  71. reg | ((func & 0xf) << 12));
  72. break;
  73. case 4:
  74. reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)
  75. & ~WM8350_GP4_FN_MASK;
  76. wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,
  77. reg | ((func & 0xf) << 0));
  78. break;
  79. case 5:
  80. reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)
  81. & ~WM8350_GP5_FN_MASK;
  82. wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,
  83. reg | ((func & 0xf) << 4));
  84. break;
  85. case 6:
  86. reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)
  87. & ~WM8350_GP6_FN_MASK;
  88. wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,
  89. reg | ((func & 0xf) << 8));
  90. break;
  91. case 7:
  92. reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)
  93. & ~WM8350_GP7_FN_MASK;
  94. wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,
  95. reg | ((func & 0xf) << 12));
  96. break;
  97. case 8:
  98. reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)
  99. & ~WM8350_GP8_FN_MASK;
  100. wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,
  101. reg | ((func & 0xf) << 0));
  102. break;
  103. case 9:
  104. reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)
  105. & ~WM8350_GP9_FN_MASK;
  106. wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,
  107. reg | ((func & 0xf) << 4));
  108. break;
  109. case 10:
  110. reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)
  111. & ~WM8350_GP10_FN_MASK;
  112. wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,
  113. reg | ((func & 0xf) << 8));
  114. break;
  115. case 11:
  116. reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)
  117. & ~WM8350_GP11_FN_MASK;
  118. wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,
  119. reg | ((func & 0xf) << 12));
  120. break;
  121. case 12:
  122. reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_4)
  123. & ~WM8350_GP12_FN_MASK;
  124. wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_4,
  125. reg | ((func & 0xf) << 0));
  126. break;
  127. default:
  128. wm8350_reg_lock(wm8350);
  129. return -EINVAL;
  130. }
  131. wm8350_reg_lock(wm8350);
  132. return 0;
  133. }
  134. static int gpio_set_pull_up(struct wm8350 *wm8350, int gpio, int up)
  135. {
  136. if (up)
  137. return wm8350_set_bits(wm8350,
  138. WM8350_GPIO_PIN_PULL_UP_CONTROL,
  139. 1 << gpio);
  140. else
  141. return wm8350_clear_bits(wm8350,
  142. WM8350_GPIO_PIN_PULL_UP_CONTROL,
  143. 1 << gpio);
  144. }
  145. static int gpio_set_pull_down(struct wm8350 *wm8350, int gpio, int down)
  146. {
  147. if (down)
  148. return wm8350_set_bits(wm8350,
  149. WM8350_GPIO_PULL_DOWN_CONTROL,
  150. 1 << gpio);
  151. else
  152. return wm8350_clear_bits(wm8350,
  153. WM8350_GPIO_PULL_DOWN_CONTROL,
  154. 1 << gpio);
  155. }
  156. static int gpio_set_polarity(struct wm8350 *wm8350, int gpio, int pol)
  157. {
  158. if (pol == WM8350_GPIO_ACTIVE_HIGH)
  159. return wm8350_set_bits(wm8350,
  160. WM8350_GPIO_PIN_POLARITY_TYPE,
  161. 1 << gpio);
  162. else
  163. return wm8350_clear_bits(wm8350,
  164. WM8350_GPIO_PIN_POLARITY_TYPE,
  165. 1 << gpio);
  166. }
  167. static int gpio_set_invert(struct wm8350 *wm8350, int gpio, int invert)
  168. {
  169. if (invert == WM8350_GPIO_INVERT_ON)
  170. return wm8350_set_bits(wm8350, WM8350_GPIO_INT_MODE, 1 << gpio);
  171. else
  172. return wm8350_clear_bits(wm8350,
  173. WM8350_GPIO_INT_MODE, 1 << gpio);
  174. }
  175. int wm8350_gpio_config(struct wm8350 *wm8350, int gpio, int dir, int func,
  176. int pol, int pull, int invert, int debounce)
  177. {
  178. /* make sure we never pull up and down at the same time */
  179. if (pull == WM8350_GPIO_PULL_NONE) {
  180. if (gpio_set_pull_up(wm8350, gpio, 0))
  181. goto err;
  182. if (gpio_set_pull_down(wm8350, gpio, 0))
  183. goto err;
  184. } else if (pull == WM8350_GPIO_PULL_UP) {
  185. if (gpio_set_pull_down(wm8350, gpio, 0))
  186. goto err;
  187. if (gpio_set_pull_up(wm8350, gpio, 1))
  188. goto err;
  189. } else if (pull == WM8350_GPIO_PULL_DOWN) {
  190. if (gpio_set_pull_up(wm8350, gpio, 0))
  191. goto err;
  192. if (gpio_set_pull_down(wm8350, gpio, 1))
  193. goto err;
  194. }
  195. if (gpio_set_invert(wm8350, gpio, invert))
  196. goto err;
  197. if (gpio_set_polarity(wm8350, gpio, pol))
  198. goto err;
  199. if (wm8350_gpio_set_debounce(wm8350, gpio, debounce))
  200. goto err;
  201. if (gpio_set_dir(wm8350, gpio, dir))
  202. goto err;
  203. return gpio_set_func(wm8350, gpio, func);
  204. err:
  205. return -EIO;
  206. }
  207. EXPORT_SYMBOL_GPL(wm8350_gpio_config);