msp_gpio_macros.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. /*
  2. *
  3. * Macros for external SMP-safe access to the PMC MSP71xx reference
  4. * board GPIO pins
  5. *
  6. * Copyright 2010 PMC-Sierra, Inc.
  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. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  14. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  15. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
  16. * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  17. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  18. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  19. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  20. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  21. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  22. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23. *
  24. * You should have received a copy of the GNU General Public License along
  25. * with this program; if not, write to the Free Software Foundation, Inc.,
  26. * 675 Mass Ave, Cambridge, MA 02139, USA.
  27. */
  28. #ifndef __MSP_GPIO_MACROS_H__
  29. #define __MSP_GPIO_MACROS_H__
  30. #include <msp_regops.h>
  31. #include <msp_regs.h>
  32. #ifdef CONFIG_PMC_MSP7120_GW
  33. #define MSP_NUM_GPIOS 20
  34. #else
  35. #define MSP_NUM_GPIOS 28
  36. #endif
  37. /* -- GPIO Enumerations -- */
  38. enum msp_gpio_data {
  39. MSP_GPIO_LO = 0,
  40. MSP_GPIO_HI = 1,
  41. MSP_GPIO_NONE, /* Special - Means pin is out of range */
  42. MSP_GPIO_TOGGLE, /* Special - Sets pin to opposite */
  43. };
  44. enum msp_gpio_mode {
  45. MSP_GPIO_INPUT = 0x0,
  46. /* MSP_GPIO_ INTERRUPT = 0x1, Not supported yet */
  47. MSP_GPIO_UART_INPUT = 0x2, /* Only GPIO 4 or 5 */
  48. MSP_GPIO_OUTPUT = 0x8,
  49. MSP_GPIO_UART_OUTPUT = 0x9, /* Only GPIO 2 or 3 */
  50. MSP_GPIO_PERIF_TIMERA = 0x9, /* Only GPIO 0 or 1 */
  51. MSP_GPIO_PERIF_TIMERB = 0xa, /* Only GPIO 0 or 1 */
  52. MSP_GPIO_UNKNOWN = 0xb, /* No such GPIO or mode */
  53. };
  54. /* -- Static Tables -- */
  55. /* Maps pins to data register */
  56. static volatile u32 * const MSP_GPIO_DATA_REGISTER[] = {
  57. /* GPIO 0 and 1 on the first register */
  58. GPIO_DATA1_REG, GPIO_DATA1_REG,
  59. /* GPIO 2, 3, 4, and 5 on the second register */
  60. GPIO_DATA2_REG, GPIO_DATA2_REG, GPIO_DATA2_REG, GPIO_DATA2_REG,
  61. /* GPIO 6, 7, 8, and 9 on the third register */
  62. GPIO_DATA3_REG, GPIO_DATA3_REG, GPIO_DATA3_REG, GPIO_DATA3_REG,
  63. /* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
  64. GPIO_DATA4_REG, GPIO_DATA4_REG, GPIO_DATA4_REG, GPIO_DATA4_REG,
  65. GPIO_DATA4_REG, GPIO_DATA4_REG,
  66. /* GPIO 16 - 23 on the first strange EXTENDED register */
  67. EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
  68. EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
  69. EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
  70. /* GPIO 24 - 27 on the second strange EXTENDED register */
  71. EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG,
  72. EXTENDED_GPIO2_REG,
  73. };
  74. /* Maps pins to mode register */
  75. static volatile u32 * const MSP_GPIO_MODE_REGISTER[] = {
  76. /* GPIO 0 and 1 on the first register */
  77. GPIO_CFG1_REG, GPIO_CFG1_REG,
  78. /* GPIO 2, 3, 4, and 5 on the second register */
  79. GPIO_CFG2_REG, GPIO_CFG2_REG, GPIO_CFG2_REG, GPIO_CFG2_REG,
  80. /* GPIO 6, 7, 8, and 9 on the third register */
  81. GPIO_CFG3_REG, GPIO_CFG3_REG, GPIO_CFG3_REG, GPIO_CFG3_REG,
  82. /* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
  83. GPIO_CFG4_REG, GPIO_CFG4_REG, GPIO_CFG4_REG, GPIO_CFG4_REG,
  84. GPIO_CFG4_REG, GPIO_CFG4_REG,
  85. /* GPIO 16 - 23 on the first strange EXTENDED register */
  86. EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
  87. EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
  88. EXTENDED_GPIO1_REG, EXTENDED_GPIO1_REG,
  89. /* GPIO 24 - 27 on the second strange EXTENDED register */
  90. EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG, EXTENDED_GPIO2_REG,
  91. EXTENDED_GPIO2_REG,
  92. };
  93. /* Maps 'basic' pins to relative offset from 0 per register */
  94. static int MSP_GPIO_OFFSET[] = {
  95. /* GPIO 0 and 1 on the first register */
  96. 0, 0,
  97. /* GPIO 2, 3, 4, and 5 on the second register */
  98. 2, 2, 2, 2,
  99. /* GPIO 6, 7, 8, and 9 on the third register */
  100. 6, 6, 6, 6,
  101. /* GPIO 10, 11, 12, 13, 14, and 15 on the fourth register */
  102. 10, 10, 10, 10, 10, 10,
  103. };
  104. /* Maps MODE to allowed pin mask */
  105. static unsigned int MSP_GPIO_MODE_ALLOWED[] = {
  106. 0xffffffff, /* Mode 0 - INPUT */
  107. 0x00000, /* Mode 1 - INTERRUPT */
  108. 0x00030, /* Mode 2 - UART_INPUT (GPIO 4, 5)*/
  109. 0, 0, 0, 0, 0, /* Modes 3, 4, 5, 6, and 7 are reserved */
  110. 0xffffffff, /* Mode 8 - OUTPUT */
  111. 0x0000f, /* Mode 9 - UART_OUTPUT/
  112. PERF_TIMERA (GPIO 0, 1, 2, 3) */
  113. 0x00003, /* Mode a - PERF_TIMERB (GPIO 0, 1) */
  114. 0x00000, /* Mode b - Not really a mode! */
  115. };
  116. /* -- Bit masks -- */
  117. /* This gives you the 'register relative offset gpio' number */
  118. #define OFFSET_GPIO_NUMBER(gpio) (gpio - MSP_GPIO_OFFSET[gpio])
  119. /* These take the 'register relative offset gpio' number */
  120. #define BASIC_DATA_REG_MASK(ogpio) (1 << ogpio)
  121. #define BASIC_MODE_REG_VALUE(mode, ogpio) \
  122. (mode << BASIC_MODE_REG_SHIFT(ogpio))
  123. #define BASIC_MODE_REG_MASK(ogpio) \
  124. BASIC_MODE_REG_VALUE(0xf, ogpio)
  125. #define BASIC_MODE_REG_SHIFT(ogpio) (ogpio * 4)
  126. #define BASIC_MODE_REG_FROM_REG(data, ogpio) \
  127. ((data & BASIC_MODE_REG_MASK(ogpio)) >> BASIC_MODE_REG_SHIFT(ogpio))
  128. /* These take the actual GPIO number (0 through 15) */
  129. #define BASIC_DATA_MASK(gpio) \
  130. BASIC_DATA_REG_MASK(OFFSET_GPIO_NUMBER(gpio))
  131. #define BASIC_MODE_MASK(gpio) \
  132. BASIC_MODE_REG_MASK(OFFSET_GPIO_NUMBER(gpio))
  133. #define BASIC_MODE(mode, gpio) \
  134. BASIC_MODE_REG_VALUE(mode, OFFSET_GPIO_NUMBER(gpio))
  135. #define BASIC_MODE_SHIFT(gpio) \
  136. BASIC_MODE_REG_SHIFT(OFFSET_GPIO_NUMBER(gpio))
  137. #define BASIC_MODE_FROM_REG(data, gpio) \
  138. BASIC_MODE_REG_FROM_REG(data, OFFSET_GPIO_NUMBER(gpio))
  139. /*
  140. * Each extended GPIO register is 32 bits long and is responsible for up to
  141. * eight GPIOs. The least significant 16 bits contain the set and clear bit
  142. * pair for each of the GPIOs. The most significant 16 bits contain the
  143. * disable and enable bit pair for each of the GPIOs. For example, the
  144. * extended GPIO reg for GPIOs 16-23 is as follows:
  145. *
  146. * 31: GPIO23_DISABLE
  147. * ...
  148. * 19: GPIO17_DISABLE
  149. * 18: GPIO17_ENABLE
  150. * 17: GPIO16_DISABLE
  151. * 16: GPIO16_ENABLE
  152. * ...
  153. * 3: GPIO17_SET
  154. * 2: GPIO17_CLEAR
  155. * 1: GPIO16_SET
  156. * 0: GPIO16_CLEAR
  157. */
  158. /* This gives the 'register relative offset gpio' number */
  159. #define EXTENDED_OFFSET_GPIO(gpio) (gpio < 24 ? gpio - 16 : gpio - 24)
  160. /* These take the 'register relative offset gpio' number */
  161. #define EXTENDED_REG_DISABLE(ogpio) (0x2 << ((ogpio * 2) + 16))
  162. #define EXTENDED_REG_ENABLE(ogpio) (0x1 << ((ogpio * 2) + 16))
  163. #define EXTENDED_REG_SET(ogpio) (0x2 << (ogpio * 2))
  164. #define EXTENDED_REG_CLR(ogpio) (0x1 << (ogpio * 2))
  165. /* These take the actual GPIO number (16 through 27) */
  166. #define EXTENDED_DISABLE(gpio) \
  167. EXTENDED_REG_DISABLE(EXTENDED_OFFSET_GPIO(gpio))
  168. #define EXTENDED_ENABLE(gpio) \
  169. EXTENDED_REG_ENABLE(EXTENDED_OFFSET_GPIO(gpio))
  170. #define EXTENDED_SET(gpio) \
  171. EXTENDED_REG_SET(EXTENDED_OFFSET_GPIO(gpio))
  172. #define EXTENDED_CLR(gpio) \
  173. EXTENDED_REG_CLR(EXTENDED_OFFSET_GPIO(gpio))
  174. #define EXTENDED_FULL_MASK (0xffffffff)
  175. /* -- API inline-functions -- */
  176. /*
  177. * Gets the current value of the specified pin
  178. */
  179. static inline enum msp_gpio_data msp_gpio_pin_get(unsigned int gpio)
  180. {
  181. u32 pinhi_mask = 0, pinhi_mask2 = 0;
  182. if (gpio >= MSP_NUM_GPIOS)
  183. return MSP_GPIO_NONE;
  184. if (gpio < 16) {
  185. pinhi_mask = BASIC_DATA_MASK(gpio);
  186. } else {
  187. /*
  188. * Two cases are possible with the EXTENDED register:
  189. * - In output mode (ENABLED flag set), check the CLR bit
  190. * - In input mode (ENABLED flag not set), check the SET bit
  191. */
  192. pinhi_mask = EXTENDED_ENABLE(gpio) | EXTENDED_CLR(gpio);
  193. pinhi_mask2 = EXTENDED_SET(gpio);
  194. }
  195. if (((*MSP_GPIO_DATA_REGISTER[gpio] & pinhi_mask) == pinhi_mask) ||
  196. (*MSP_GPIO_DATA_REGISTER[gpio] & pinhi_mask2))
  197. return MSP_GPIO_HI;
  198. else
  199. return MSP_GPIO_LO;
  200. }
  201. /* Sets the specified pin to the specified value */
  202. static inline void msp_gpio_pin_set(enum msp_gpio_data data, unsigned int gpio)
  203. {
  204. if (gpio >= MSP_NUM_GPIOS)
  205. return;
  206. if (gpio < 16) {
  207. if (data == MSP_GPIO_TOGGLE)
  208. toggle_reg32(MSP_GPIO_DATA_REGISTER[gpio],
  209. BASIC_DATA_MASK(gpio));
  210. else if (data == MSP_GPIO_HI)
  211. set_reg32(MSP_GPIO_DATA_REGISTER[gpio],
  212. BASIC_DATA_MASK(gpio));
  213. else
  214. clear_reg32(MSP_GPIO_DATA_REGISTER[gpio],
  215. BASIC_DATA_MASK(gpio));
  216. } else {
  217. if (data == MSP_GPIO_TOGGLE) {
  218. /* Special ugly case:
  219. * We have to read the CLR bit.
  220. * If set, we write the CLR bit.
  221. * If not, we write the SET bit.
  222. */
  223. u32 tmpdata;
  224. custom_read_reg32(MSP_GPIO_DATA_REGISTER[gpio],
  225. tmpdata);
  226. if (tmpdata & EXTENDED_CLR(gpio))
  227. tmpdata = EXTENDED_CLR(gpio);
  228. else
  229. tmpdata = EXTENDED_SET(gpio);
  230. custom_write_reg32(MSP_GPIO_DATA_REGISTER[gpio],
  231. tmpdata);
  232. } else {
  233. u32 newdata;
  234. if (data == MSP_GPIO_HI)
  235. newdata = EXTENDED_SET(gpio);
  236. else
  237. newdata = EXTENDED_CLR(gpio);
  238. set_value_reg32(MSP_GPIO_DATA_REGISTER[gpio],
  239. EXTENDED_FULL_MASK, newdata);
  240. }
  241. }
  242. }
  243. /* Sets the specified pin to the specified value */
  244. static inline void msp_gpio_pin_hi(unsigned int gpio)
  245. {
  246. msp_gpio_pin_set(MSP_GPIO_HI, gpio);
  247. }
  248. /* Sets the specified pin to the specified value */
  249. static inline void msp_gpio_pin_lo(unsigned int gpio)
  250. {
  251. msp_gpio_pin_set(MSP_GPIO_LO, gpio);
  252. }
  253. /* Sets the specified pin to the opposite value */
  254. static inline void msp_gpio_pin_toggle(unsigned int gpio)
  255. {
  256. msp_gpio_pin_set(MSP_GPIO_TOGGLE, gpio);
  257. }
  258. /* Gets the mode of the specified pin */
  259. static inline enum msp_gpio_mode msp_gpio_pin_get_mode(unsigned int gpio)
  260. {
  261. enum msp_gpio_mode retval = MSP_GPIO_UNKNOWN;
  262. uint32_t data;
  263. if (gpio >= MSP_NUM_GPIOS)
  264. return retval;
  265. data = *MSP_GPIO_MODE_REGISTER[gpio];
  266. if (gpio < 16) {
  267. retval = BASIC_MODE_FROM_REG(data, gpio);
  268. } else {
  269. /* Extended pins can only be either INPUT or OUTPUT */
  270. if (data & EXTENDED_ENABLE(gpio))
  271. retval = MSP_GPIO_OUTPUT;
  272. else
  273. retval = MSP_GPIO_INPUT;
  274. }
  275. return retval;
  276. }
  277. /*
  278. * Sets the specified mode on the requested pin
  279. * Returns 0 on success, or -1 if that mode is not allowed on this pin
  280. */
  281. static inline int msp_gpio_pin_mode(enum msp_gpio_mode mode, unsigned int gpio)
  282. {
  283. u32 modemask, newmode;
  284. if ((1 << gpio) & ~MSP_GPIO_MODE_ALLOWED[mode])
  285. return -1;
  286. if (gpio >= MSP_NUM_GPIOS)
  287. return -1;
  288. if (gpio < 16) {
  289. modemask = BASIC_MODE_MASK(gpio);
  290. newmode = BASIC_MODE(mode, gpio);
  291. } else {
  292. modemask = EXTENDED_FULL_MASK;
  293. if (mode == MSP_GPIO_INPUT)
  294. newmode = EXTENDED_DISABLE(gpio);
  295. else
  296. newmode = EXTENDED_ENABLE(gpio);
  297. }
  298. /* Do the set atomically */
  299. set_value_reg32(MSP_GPIO_MODE_REGISTER[gpio], modemask, newmode);
  300. return 0;
  301. }
  302. #endif /* __MSP_GPIO_MACROS_H__ */