pinctrl-spear310.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. /*
  2. * Driver for the ST Microelectronics SPEAr310 pinmux
  3. *
  4. * Copyright (C) 2012 ST Microelectronics
  5. * Viresh Kumar <vireshk@kernel.org>
  6. *
  7. * This file is licensed under the terms of the GNU General Public
  8. * License version 2. This program is licensed "as is" without any
  9. * warranty of any kind, whether express or implied.
  10. */
  11. #include <linux/err.h>
  12. #include <linux/init.h>
  13. #include <linux/module.h>
  14. #include <linux/of_device.h>
  15. #include <linux/platform_device.h>
  16. #include "pinctrl-spear3xx.h"
  17. #define DRIVER_NAME "spear310-pinmux"
  18. /* addresses */
  19. #define PMX_CONFIG_REG 0x08
  20. /* emi_cs_0_to_5_pins */
  21. static const unsigned emi_cs_0_to_5_pins[] = { 45, 46, 47, 48, 49, 50 };
  22. static struct spear_muxreg emi_cs_0_to_5_muxreg[] = {
  23. {
  24. .reg = PMX_CONFIG_REG,
  25. .mask = PMX_TIMER_0_1_MASK | PMX_TIMER_2_3_MASK,
  26. .val = 0,
  27. },
  28. };
  29. static struct spear_modemux emi_cs_0_to_5_modemux[] = {
  30. {
  31. .muxregs = emi_cs_0_to_5_muxreg,
  32. .nmuxregs = ARRAY_SIZE(emi_cs_0_to_5_muxreg),
  33. },
  34. };
  35. static struct spear_pingroup emi_cs_0_to_5_pingroup = {
  36. .name = "emi_cs_0_to_5_grp",
  37. .pins = emi_cs_0_to_5_pins,
  38. .npins = ARRAY_SIZE(emi_cs_0_to_5_pins),
  39. .modemuxs = emi_cs_0_to_5_modemux,
  40. .nmodemuxs = ARRAY_SIZE(emi_cs_0_to_5_modemux),
  41. };
  42. static const char *const emi_cs_0_to_5_grps[] = { "emi_cs_0_to_5_grp" };
  43. static struct spear_function emi_cs_0_to_5_function = {
  44. .name = "emi",
  45. .groups = emi_cs_0_to_5_grps,
  46. .ngroups = ARRAY_SIZE(emi_cs_0_to_5_grps),
  47. };
  48. /* uart1_pins */
  49. static const unsigned uart1_pins[] = { 0, 1 };
  50. static struct spear_muxreg uart1_muxreg[] = {
  51. {
  52. .reg = PMX_CONFIG_REG,
  53. .mask = PMX_FIRDA_MASK,
  54. .val = 0,
  55. },
  56. };
  57. static struct spear_modemux uart1_modemux[] = {
  58. {
  59. .muxregs = uart1_muxreg,
  60. .nmuxregs = ARRAY_SIZE(uart1_muxreg),
  61. },
  62. };
  63. static struct spear_pingroup uart1_pingroup = {
  64. .name = "uart1_grp",
  65. .pins = uart1_pins,
  66. .npins = ARRAY_SIZE(uart1_pins),
  67. .modemuxs = uart1_modemux,
  68. .nmodemuxs = ARRAY_SIZE(uart1_modemux),
  69. };
  70. static const char *const uart1_grps[] = { "uart1_grp" };
  71. static struct spear_function uart1_function = {
  72. .name = "uart1",
  73. .groups = uart1_grps,
  74. .ngroups = ARRAY_SIZE(uart1_grps),
  75. };
  76. /* uart2_pins */
  77. static const unsigned uart2_pins[] = { 43, 44 };
  78. static struct spear_muxreg uart2_muxreg[] = {
  79. {
  80. .reg = PMX_CONFIG_REG,
  81. .mask = PMX_TIMER_0_1_MASK,
  82. .val = 0,
  83. },
  84. };
  85. static struct spear_modemux uart2_modemux[] = {
  86. {
  87. .muxregs = uart2_muxreg,
  88. .nmuxregs = ARRAY_SIZE(uart2_muxreg),
  89. },
  90. };
  91. static struct spear_pingroup uart2_pingroup = {
  92. .name = "uart2_grp",
  93. .pins = uart2_pins,
  94. .npins = ARRAY_SIZE(uart2_pins),
  95. .modemuxs = uart2_modemux,
  96. .nmodemuxs = ARRAY_SIZE(uart2_modemux),
  97. };
  98. static const char *const uart2_grps[] = { "uart2_grp" };
  99. static struct spear_function uart2_function = {
  100. .name = "uart2",
  101. .groups = uart2_grps,
  102. .ngroups = ARRAY_SIZE(uart2_grps),
  103. };
  104. /* uart3_pins */
  105. static const unsigned uart3_pins[] = { 37, 38 };
  106. static struct spear_muxreg uart3_muxreg[] = {
  107. {
  108. .reg = PMX_CONFIG_REG,
  109. .mask = PMX_UART0_MODEM_MASK,
  110. .val = 0,
  111. },
  112. };
  113. static struct spear_modemux uart3_modemux[] = {
  114. {
  115. .muxregs = uart3_muxreg,
  116. .nmuxregs = ARRAY_SIZE(uart3_muxreg),
  117. },
  118. };
  119. static struct spear_pingroup uart3_pingroup = {
  120. .name = "uart3_grp",
  121. .pins = uart3_pins,
  122. .npins = ARRAY_SIZE(uart3_pins),
  123. .modemuxs = uart3_modemux,
  124. .nmodemuxs = ARRAY_SIZE(uart3_modemux),
  125. };
  126. static const char *const uart3_grps[] = { "uart3_grp" };
  127. static struct spear_function uart3_function = {
  128. .name = "uart3",
  129. .groups = uart3_grps,
  130. .ngroups = ARRAY_SIZE(uart3_grps),
  131. };
  132. /* uart4_pins */
  133. static const unsigned uart4_pins[] = { 39, 40 };
  134. static struct spear_muxreg uart4_muxreg[] = {
  135. {
  136. .reg = PMX_CONFIG_REG,
  137. .mask = PMX_UART0_MODEM_MASK,
  138. .val = 0,
  139. },
  140. };
  141. static struct spear_modemux uart4_modemux[] = {
  142. {
  143. .muxregs = uart4_muxreg,
  144. .nmuxregs = ARRAY_SIZE(uart4_muxreg),
  145. },
  146. };
  147. static struct spear_pingroup uart4_pingroup = {
  148. .name = "uart4_grp",
  149. .pins = uart4_pins,
  150. .npins = ARRAY_SIZE(uart4_pins),
  151. .modemuxs = uart4_modemux,
  152. .nmodemuxs = ARRAY_SIZE(uart4_modemux),
  153. };
  154. static const char *const uart4_grps[] = { "uart4_grp" };
  155. static struct spear_function uart4_function = {
  156. .name = "uart4",
  157. .groups = uart4_grps,
  158. .ngroups = ARRAY_SIZE(uart4_grps),
  159. };
  160. /* uart5_pins */
  161. static const unsigned uart5_pins[] = { 41, 42 };
  162. static struct spear_muxreg uart5_muxreg[] = {
  163. {
  164. .reg = PMX_CONFIG_REG,
  165. .mask = PMX_UART0_MODEM_MASK,
  166. .val = 0,
  167. },
  168. };
  169. static struct spear_modemux uart5_modemux[] = {
  170. {
  171. .muxregs = uart5_muxreg,
  172. .nmuxregs = ARRAY_SIZE(uart5_muxreg),
  173. },
  174. };
  175. static struct spear_pingroup uart5_pingroup = {
  176. .name = "uart5_grp",
  177. .pins = uart5_pins,
  178. .npins = ARRAY_SIZE(uart5_pins),
  179. .modemuxs = uart5_modemux,
  180. .nmodemuxs = ARRAY_SIZE(uart5_modemux),
  181. };
  182. static const char *const uart5_grps[] = { "uart5_grp" };
  183. static struct spear_function uart5_function = {
  184. .name = "uart5",
  185. .groups = uart5_grps,
  186. .ngroups = ARRAY_SIZE(uart5_grps),
  187. };
  188. /* fsmc_pins */
  189. static const unsigned fsmc_pins[] = { 34, 35, 36 };
  190. static struct spear_muxreg fsmc_muxreg[] = {
  191. {
  192. .reg = PMX_CONFIG_REG,
  193. .mask = PMX_SSP_CS_MASK,
  194. .val = 0,
  195. },
  196. };
  197. static struct spear_modemux fsmc_modemux[] = {
  198. {
  199. .muxregs = fsmc_muxreg,
  200. .nmuxregs = ARRAY_SIZE(fsmc_muxreg),
  201. },
  202. };
  203. static struct spear_pingroup fsmc_pingroup = {
  204. .name = "fsmc_grp",
  205. .pins = fsmc_pins,
  206. .npins = ARRAY_SIZE(fsmc_pins),
  207. .modemuxs = fsmc_modemux,
  208. .nmodemuxs = ARRAY_SIZE(fsmc_modemux),
  209. };
  210. static const char *const fsmc_grps[] = { "fsmc_grp" };
  211. static struct spear_function fsmc_function = {
  212. .name = "fsmc",
  213. .groups = fsmc_grps,
  214. .ngroups = ARRAY_SIZE(fsmc_grps),
  215. };
  216. /* rs485_0_pins */
  217. static const unsigned rs485_0_pins[] = { 19, 20, 21, 22, 23 };
  218. static struct spear_muxreg rs485_0_muxreg[] = {
  219. {
  220. .reg = PMX_CONFIG_REG,
  221. .mask = PMX_MII_MASK,
  222. .val = 0,
  223. },
  224. };
  225. static struct spear_modemux rs485_0_modemux[] = {
  226. {
  227. .muxregs = rs485_0_muxreg,
  228. .nmuxregs = ARRAY_SIZE(rs485_0_muxreg),
  229. },
  230. };
  231. static struct spear_pingroup rs485_0_pingroup = {
  232. .name = "rs485_0_grp",
  233. .pins = rs485_0_pins,
  234. .npins = ARRAY_SIZE(rs485_0_pins),
  235. .modemuxs = rs485_0_modemux,
  236. .nmodemuxs = ARRAY_SIZE(rs485_0_modemux),
  237. };
  238. static const char *const rs485_0_grps[] = { "rs485_0" };
  239. static struct spear_function rs485_0_function = {
  240. .name = "rs485_0",
  241. .groups = rs485_0_grps,
  242. .ngroups = ARRAY_SIZE(rs485_0_grps),
  243. };
  244. /* rs485_1_pins */
  245. static const unsigned rs485_1_pins[] = { 14, 15, 16, 17, 18 };
  246. static struct spear_muxreg rs485_1_muxreg[] = {
  247. {
  248. .reg = PMX_CONFIG_REG,
  249. .mask = PMX_MII_MASK,
  250. .val = 0,
  251. },
  252. };
  253. static struct spear_modemux rs485_1_modemux[] = {
  254. {
  255. .muxregs = rs485_1_muxreg,
  256. .nmuxregs = ARRAY_SIZE(rs485_1_muxreg),
  257. },
  258. };
  259. static struct spear_pingroup rs485_1_pingroup = {
  260. .name = "rs485_1_grp",
  261. .pins = rs485_1_pins,
  262. .npins = ARRAY_SIZE(rs485_1_pins),
  263. .modemuxs = rs485_1_modemux,
  264. .nmodemuxs = ARRAY_SIZE(rs485_1_modemux),
  265. };
  266. static const char *const rs485_1_grps[] = { "rs485_1" };
  267. static struct spear_function rs485_1_function = {
  268. .name = "rs485_1",
  269. .groups = rs485_1_grps,
  270. .ngroups = ARRAY_SIZE(rs485_1_grps),
  271. };
  272. /* tdm_pins */
  273. static const unsigned tdm_pins[] = { 10, 11, 12, 13 };
  274. static struct spear_muxreg tdm_muxreg[] = {
  275. {
  276. .reg = PMX_CONFIG_REG,
  277. .mask = PMX_MII_MASK,
  278. .val = 0,
  279. },
  280. };
  281. static struct spear_modemux tdm_modemux[] = {
  282. {
  283. .muxregs = tdm_muxreg,
  284. .nmuxregs = ARRAY_SIZE(tdm_muxreg),
  285. },
  286. };
  287. static struct spear_pingroup tdm_pingroup = {
  288. .name = "tdm_grp",
  289. .pins = tdm_pins,
  290. .npins = ARRAY_SIZE(tdm_pins),
  291. .modemuxs = tdm_modemux,
  292. .nmodemuxs = ARRAY_SIZE(tdm_modemux),
  293. };
  294. static const char *const tdm_grps[] = { "tdm_grp" };
  295. static struct spear_function tdm_function = {
  296. .name = "tdm",
  297. .groups = tdm_grps,
  298. .ngroups = ARRAY_SIZE(tdm_grps),
  299. };
  300. /* pingroups */
  301. static struct spear_pingroup *spear310_pingroups[] = {
  302. SPEAR3XX_COMMON_PINGROUPS,
  303. &emi_cs_0_to_5_pingroup,
  304. &uart1_pingroup,
  305. &uart2_pingroup,
  306. &uart3_pingroup,
  307. &uart4_pingroup,
  308. &uart5_pingroup,
  309. &fsmc_pingroup,
  310. &rs485_0_pingroup,
  311. &rs485_1_pingroup,
  312. &tdm_pingroup,
  313. };
  314. /* functions */
  315. static struct spear_function *spear310_functions[] = {
  316. SPEAR3XX_COMMON_FUNCTIONS,
  317. &emi_cs_0_to_5_function,
  318. &uart1_function,
  319. &uart2_function,
  320. &uart3_function,
  321. &uart4_function,
  322. &uart5_function,
  323. &fsmc_function,
  324. &rs485_0_function,
  325. &rs485_1_function,
  326. &tdm_function,
  327. };
  328. static const struct of_device_id spear310_pinctrl_of_match[] = {
  329. {
  330. .compatible = "st,spear310-pinmux",
  331. },
  332. {},
  333. };
  334. static int spear310_pinctrl_probe(struct platform_device *pdev)
  335. {
  336. int ret;
  337. spear3xx_machdata.groups = spear310_pingroups;
  338. spear3xx_machdata.ngroups = ARRAY_SIZE(spear310_pingroups);
  339. spear3xx_machdata.functions = spear310_functions;
  340. spear3xx_machdata.nfunctions = ARRAY_SIZE(spear310_functions);
  341. pmx_init_addr(&spear3xx_machdata, PMX_CONFIG_REG);
  342. pmx_init_gpio_pingroup_addr(spear3xx_machdata.gpio_pingroups,
  343. spear3xx_machdata.ngpio_pingroups, PMX_CONFIG_REG);
  344. spear3xx_machdata.modes_supported = false;
  345. ret = spear_pinctrl_probe(pdev, &spear3xx_machdata);
  346. if (ret)
  347. return ret;
  348. return 0;
  349. }
  350. static int spear310_pinctrl_remove(struct platform_device *pdev)
  351. {
  352. return spear_pinctrl_remove(pdev);
  353. }
  354. static struct platform_driver spear310_pinctrl_driver = {
  355. .driver = {
  356. .name = DRIVER_NAME,
  357. .of_match_table = spear310_pinctrl_of_match,
  358. },
  359. .probe = spear310_pinctrl_probe,
  360. .remove = spear310_pinctrl_remove,
  361. };
  362. static int __init spear310_pinctrl_init(void)
  363. {
  364. return platform_driver_register(&spear310_pinctrl_driver);
  365. }
  366. arch_initcall(spear310_pinctrl_init);
  367. static void __exit spear310_pinctrl_exit(void)
  368. {
  369. platform_driver_unregister(&spear310_pinctrl_driver);
  370. }
  371. module_exit(spear310_pinctrl_exit);
  372. MODULE_AUTHOR("Viresh Kumar <vireshk@kernel.org>");
  373. MODULE_DESCRIPTION("ST Microelectronics SPEAr310 pinctrl driver");
  374. MODULE_LICENSE("GPL v2");
  375. MODULE_DEVICE_TABLE(of, spear310_pinctrl_of_match);