atmel_pio4.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /*
  2. * Atmel PIO4 device driver
  3. *
  4. * Copyright (C) 2015 Atmel Corporation
  5. * Wenyou.Yang <wenyou.yang@atmel.com>
  6. *
  7. * SPDX-License-Identifier: GPL-2.0+
  8. */
  9. #include <common.h>
  10. #include <dm.h>
  11. #include <asm/arch/hardware.h>
  12. #include <mach/gpio.h>
  13. #include <mach/atmel_pio4.h>
  14. #define ATMEL_PIO4_PINS_PER_BANK 32
  15. /*
  16. * Register Field Definitions
  17. */
  18. #define ATMEL_PIO4_CFGR_FUNC (0x7 << 0)
  19. #define ATMEL_PIO4_CFGR_FUNC_GPIO (0x0 << 0)
  20. #define ATMEL_PIO4_CFGR_FUNC_PERIPH_A (0x1 << 0)
  21. #define ATMEL_PIO4_CFGR_FUNC_PERIPH_B (0x2 << 0)
  22. #define ATMEL_PIO4_CFGR_FUNC_PERIPH_C (0x3 << 0)
  23. #define ATMEL_PIO4_CFGR_FUNC_PERIPH_D (0x4 << 0)
  24. #define ATMEL_PIO4_CFGR_FUNC_PERIPH_E (0x5 << 0)
  25. #define ATMEL_PIO4_CFGR_FUNC_PERIPH_F (0x6 << 0)
  26. #define ATMEL_PIO4_CFGR_FUNC_PERIPH_G (0x7 << 0)
  27. #define ATMEL_PIO4_CFGR_DIR (0x1 << 8)
  28. #define ATMEL_PIO4_CFGR_PUEN (0x1 << 9)
  29. #define ATMEL_PIO4_CFGR_PDEN (0x1 << 10)
  30. #define ATMEL_PIO4_CFGR_IFEN (0x1 << 12)
  31. #define ATMEL_PIO4_CFGR_IFSCEN (0x1 << 13)
  32. #define ATMEL_PIO4_CFGR_OPD (0x1 << 14)
  33. #define ATMEL_PIO4_CFGR_SCHMITT (0x1 << 15)
  34. #define ATMEL_PIO4_CFGR_DRVSTR (0x3 << 16)
  35. #define ATMEL_PIO4_CFGR_DRVSTR_LOW0 (0x0 << 16)
  36. #define ATMEL_PIO4_CFGR_DRVSTR_LOW1 (0x1 << 16)
  37. #define ATMEL_PIO4_CFGR_DRVSTR_MEDIUM (0x2 << 16)
  38. #define ATMEL_PIO4_CFGR_DRVSTR_HIGH (0x3 << 16)
  39. #define ATMEL_PIO4_CFGR_EVTSEL (0x7 << 24)
  40. #define ATMEL_PIO4_CFGR_EVTSEL_FALLING (0x0 << 24)
  41. #define ATMEL_PIO4_CFGR_EVTSEL_RISING (0x1 << 24)
  42. #define ATMEL_PIO4_CFGR_EVTSEL_BOTH (0x2 << 24)
  43. #define ATMEL_PIO4_CFGR_EVTSEL_LOW (0x3 << 24)
  44. #define ATMEL_PIO4_CFGR_EVTSEL_HIGH (0x4 << 24)
  45. #define ATMEL_PIO4_CFGR_PCFS (0x1 << 29)
  46. #define ATMEL_PIO4_CFGR_ICFS (0x1 << 30)
  47. static struct atmel_pio4_port *atmel_pio4_port_base(u32 port)
  48. {
  49. struct atmel_pio4_port *base = NULL;
  50. switch (port) {
  51. case AT91_PIO_PORTA:
  52. base = (struct atmel_pio4_port *)ATMEL_BASE_PIOA;
  53. break;
  54. case AT91_PIO_PORTB:
  55. base = (struct atmel_pio4_port *)ATMEL_BASE_PIOB;
  56. break;
  57. case AT91_PIO_PORTC:
  58. base = (struct atmel_pio4_port *)ATMEL_BASE_PIOC;
  59. break;
  60. case AT91_PIO_PORTD:
  61. base = (struct atmel_pio4_port *)ATMEL_BASE_PIOD;
  62. break;
  63. default:
  64. printf("Error: Atmel PIO4: Failed to get PIO base of port#%d!\n",
  65. port);
  66. break;
  67. }
  68. return base;
  69. }
  70. static int atmel_pio4_config_io_func(u32 port, u32 pin,
  71. u32 func, u32 use_pullup)
  72. {
  73. struct atmel_pio4_port *port_base;
  74. u32 reg, mask;
  75. if (pin >= ATMEL_PIO4_PINS_PER_BANK)
  76. return -ENODEV;
  77. port_base = atmel_pio4_port_base(port);
  78. if (!port_base)
  79. return -ENODEV;
  80. mask = 1 << pin;
  81. reg = func;
  82. reg |= use_pullup ? ATMEL_PIO4_CFGR_PUEN : 0;
  83. writel(mask, &port_base->mskr);
  84. writel(reg, &port_base->cfgr);
  85. return 0;
  86. }
  87. int atmel_pio4_set_gpio(u32 port, u32 pin, u32 use_pullup)
  88. {
  89. return atmel_pio4_config_io_func(port, pin,
  90. ATMEL_PIO4_CFGR_FUNC_GPIO,
  91. use_pullup);
  92. }
  93. int atmel_pio4_set_a_periph(u32 port, u32 pin, u32 use_pullup)
  94. {
  95. return atmel_pio4_config_io_func(port, pin,
  96. ATMEL_PIO4_CFGR_FUNC_PERIPH_A,
  97. use_pullup);
  98. }
  99. int atmel_pio4_set_b_periph(u32 port, u32 pin, u32 use_pullup)
  100. {
  101. return atmel_pio4_config_io_func(port, pin,
  102. ATMEL_PIO4_CFGR_FUNC_PERIPH_B,
  103. use_pullup);
  104. }
  105. int atmel_pio4_set_c_periph(u32 port, u32 pin, u32 use_pullup)
  106. {
  107. return atmel_pio4_config_io_func(port, pin,
  108. ATMEL_PIO4_CFGR_FUNC_PERIPH_C,
  109. use_pullup);
  110. }
  111. int atmel_pio4_set_d_periph(u32 port, u32 pin, u32 use_pullup)
  112. {
  113. return atmel_pio4_config_io_func(port, pin,
  114. ATMEL_PIO4_CFGR_FUNC_PERIPH_D,
  115. use_pullup);
  116. }
  117. int atmel_pio4_set_e_periph(u32 port, u32 pin, u32 use_pullup)
  118. {
  119. return atmel_pio4_config_io_func(port, pin,
  120. ATMEL_PIO4_CFGR_FUNC_PERIPH_E,
  121. use_pullup);
  122. }
  123. int atmel_pio4_set_f_periph(u32 port, u32 pin, u32 use_pullup)
  124. {
  125. return atmel_pio4_config_io_func(port, pin,
  126. ATMEL_PIO4_CFGR_FUNC_PERIPH_F,
  127. use_pullup);
  128. }
  129. int atmel_pio4_set_g_periph(u32 port, u32 pin, u32 use_pullup)
  130. {
  131. return atmel_pio4_config_io_func(port, pin,
  132. ATMEL_PIO4_CFGR_FUNC_PERIPH_G,
  133. use_pullup);
  134. }
  135. int atmel_pio4_set_pio_output(u32 port, u32 pin, u32 value)
  136. {
  137. struct atmel_pio4_port *port_base;
  138. u32 reg, mask;
  139. if (pin >= ATMEL_PIO4_PINS_PER_BANK)
  140. return -ENODEV;
  141. port_base = atmel_pio4_port_base(port);
  142. if (!port_base)
  143. return -ENODEV;
  144. mask = 0x01 << pin;
  145. reg = ATMEL_PIO4_CFGR_FUNC_GPIO | ATMEL_PIO4_CFGR_DIR;
  146. writel(mask, &port_base->mskr);
  147. writel(reg, &port_base->cfgr);
  148. if (value)
  149. writel(mask, &port_base->sodr);
  150. else
  151. writel(mask, &port_base->codr);
  152. return 0;
  153. }
  154. int atmel_pio4_get_pio_input(u32 port, u32 pin)
  155. {
  156. struct atmel_pio4_port *port_base;
  157. u32 reg, mask;
  158. if (pin >= ATMEL_PIO4_PINS_PER_BANK)
  159. return -ENODEV;
  160. port_base = atmel_pio4_port_base(port);
  161. if (!port_base)
  162. return -ENODEV;
  163. mask = 0x01 << pin;
  164. reg = ATMEL_PIO4_CFGR_FUNC_GPIO;
  165. writel(mask, &port_base->mskr);
  166. writel(reg, &port_base->cfgr);
  167. return (readl(&port_base->pdsr) & mask) ? 1 : 0;
  168. }
  169. #ifdef CONFIG_DM_GPIO
  170. static int atmel_pio4_direction_input(struct udevice *dev, unsigned offset)
  171. {
  172. struct at91_port_platdata *plat = dev_get_platdata(dev);
  173. struct atmel_pio4_port *port_base = (atmel_pio4_port *)plat->base_addr;
  174. u32 mask = 0x01 << offset;
  175. u32 reg = ATMEL_PIO4_CFGR_FUNC_GPIO;
  176. writel(mask, &port_base->mskr);
  177. writel(reg, &port_base->cfgr);
  178. return 0;
  179. }
  180. static int atmel_pio4_direction_output(struct udevice *dev,
  181. unsigned offset, int value)
  182. {
  183. struct at91_port_platdata *plat = dev_get_platdata(dev);
  184. struct atmel_pio4_port *port_base = (atmel_pio4_port *)plat->base_addr;
  185. u32 mask = 0x01 << offset;
  186. u32 reg = ATMEL_PIO4_CFGR_FUNC_GPIO | ATMEL_PIO4_CFGR_DIR;
  187. writel(mask, &port_base->mskr);
  188. writel(reg, &port_base->cfgr);
  189. if (value)
  190. writel(mask, &port_base->sodr);
  191. else
  192. writel(mask, &port_base->codr);
  193. return 0;
  194. }
  195. static int atmel_pio4_get_value(struct udevice *dev, unsigned offset)
  196. {
  197. struct at91_port_platdata *plat = dev_get_platdata(dev);
  198. struct atmel_pio4_port *port_base = (atmel_pio4_port *)plat->base_addr;
  199. u32 mask = 0x01 << offset;
  200. return (readl(&port_base->pdsr) & mask) ? 1 : 0;
  201. }
  202. static int atmel_pio4_set_value(struct udevice *dev,
  203. unsigned offset, int value)
  204. {
  205. struct at91_port_platdata *plat = dev_get_platdata(dev);
  206. struct atmel_pio4_port *port_base = (atmel_pio4_port *)plat->base_addr;
  207. u32 mask = 0x01 << offset;
  208. if (value)
  209. writel(mask, &port_base->sodr);
  210. else
  211. writel(mask, &port_base->codr);
  212. return 0;
  213. }
  214. static int atmel_pio4_get_function(struct udevice *dev, unsigned offset)
  215. {
  216. struct at91_port_platdata *plat = dev_get_platdata(dev);
  217. struct atmel_pio4_port *port_base = (atmel_pio4_port *)plat->base_addr;
  218. u32 mask = 0x01 << offset;
  219. writel(mask, &port_base->mskr);
  220. return (readl(&port_base->cfgr) &
  221. ATMEL_PIO4_CFGR_DIR) ? GPIOF_OUTPUT : GPIOF_INPUT;
  222. }
  223. static const struct dm_gpio_ops atmel_pio4_ops = {
  224. .direction_input = atmel_pio4_direction_input,
  225. .direction_output = atmel_pio4_direction_output,
  226. .get_value = atmel_pio4_get_value,
  227. .set_value = atmel_pio4_set_value,
  228. .get_function = atmel_pio4_get_function,
  229. };
  230. static int atmel_pio4_probe(struct udevice *dev)
  231. {
  232. struct at91_port_platdata *plat = dev_get_platdata(dev);
  233. struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
  234. uc_priv->bank_name = plat->bank_name;
  235. uc_priv->gpio_count = ATMEL_PIO4_PINS_PER_BANK;
  236. return 0;
  237. }
  238. U_BOOT_DRIVER(gpio_atmel_pio4) = {
  239. .name = "gpio_atmel_pio4",
  240. .id = UCLASS_GPIO,
  241. .ops = &atmel_pio4_ops,
  242. .probe = atmel_pio4_probe,
  243. };
  244. #endif