pinctrl-bcm6328.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Driver for BCM6328 GPIO unit (pinctrl + GPIO)
  4. *
  5. * Copyright (C) 2021 Álvaro Fernández Rojas <[email protected]>
  6. * Copyright (C) 2016 Jonas Gorski <[email protected]>
  7. */
  8. #include <linux/bits.h>
  9. #include <linux/gpio/driver.h>
  10. #include <linux/kernel.h>
  11. #include <linux/of.h>
  12. #include <linux/pinctrl/pinmux.h>
  13. #include <linux/platform_device.h>
  14. #include <linux/regmap.h>
  15. #include "../pinctrl-utils.h"
  16. #include "pinctrl-bcm63xx.h"
  17. #define BCM6328_NUM_GPIOS 32
  18. #define BCM6328_MODE_REG 0x18
  19. #define BCM6328_MUX_HI_REG 0x1c
  20. #define BCM6328_MUX_LO_REG 0x20
  21. #define BCM6328_MUX_OTHER_REG 0x24
  22. #define BCM6328_MUX_MASK GENMASK(1, 0)
  23. struct bcm6328_function {
  24. const char *name;
  25. const char * const *groups;
  26. const unsigned num_groups;
  27. unsigned mode_val:1;
  28. unsigned mux_val:2;
  29. };
  30. static const unsigned int bcm6328_mux[] = {
  31. BCM6328_MUX_LO_REG,
  32. BCM6328_MUX_HI_REG,
  33. BCM6328_MUX_OTHER_REG
  34. };
  35. static const struct pinctrl_pin_desc bcm6328_pins[] = {
  36. PINCTRL_PIN(0, "gpio0"),
  37. PINCTRL_PIN(1, "gpio1"),
  38. PINCTRL_PIN(2, "gpio2"),
  39. PINCTRL_PIN(3, "gpio3"),
  40. PINCTRL_PIN(4, "gpio4"),
  41. PINCTRL_PIN(5, "gpio5"),
  42. PINCTRL_PIN(6, "gpio6"),
  43. PINCTRL_PIN(7, "gpio7"),
  44. PINCTRL_PIN(8, "gpio8"),
  45. PINCTRL_PIN(9, "gpio9"),
  46. PINCTRL_PIN(10, "gpio10"),
  47. PINCTRL_PIN(11, "gpio11"),
  48. PINCTRL_PIN(12, "gpio12"),
  49. PINCTRL_PIN(13, "gpio13"),
  50. PINCTRL_PIN(14, "gpio14"),
  51. PINCTRL_PIN(15, "gpio15"),
  52. PINCTRL_PIN(16, "gpio16"),
  53. PINCTRL_PIN(17, "gpio17"),
  54. PINCTRL_PIN(18, "gpio18"),
  55. PINCTRL_PIN(19, "gpio19"),
  56. PINCTRL_PIN(20, "gpio20"),
  57. PINCTRL_PIN(21, "gpio21"),
  58. PINCTRL_PIN(22, "gpio22"),
  59. PINCTRL_PIN(23, "gpio23"),
  60. PINCTRL_PIN(24, "gpio24"),
  61. PINCTRL_PIN(25, "gpio25"),
  62. PINCTRL_PIN(26, "gpio26"),
  63. PINCTRL_PIN(27, "gpio27"),
  64. PINCTRL_PIN(28, "gpio28"),
  65. PINCTRL_PIN(29, "gpio29"),
  66. PINCTRL_PIN(30, "gpio30"),
  67. PINCTRL_PIN(31, "gpio31"),
  68. /*
  69. * No idea where they really are; so let's put them according
  70. * to their mux offsets.
  71. */
  72. PINCTRL_PIN(36, "hsspi_cs1"),
  73. PINCTRL_PIN(38, "usb_p2"),
  74. };
  75. static unsigned gpio0_pins[] = { 0 };
  76. static unsigned gpio1_pins[] = { 1 };
  77. static unsigned gpio2_pins[] = { 2 };
  78. static unsigned gpio3_pins[] = { 3 };
  79. static unsigned gpio4_pins[] = { 4 };
  80. static unsigned gpio5_pins[] = { 5 };
  81. static unsigned gpio6_pins[] = { 6 };
  82. static unsigned gpio7_pins[] = { 7 };
  83. static unsigned gpio8_pins[] = { 8 };
  84. static unsigned gpio9_pins[] = { 9 };
  85. static unsigned gpio10_pins[] = { 10 };
  86. static unsigned gpio11_pins[] = { 11 };
  87. static unsigned gpio12_pins[] = { 12 };
  88. static unsigned gpio13_pins[] = { 13 };
  89. static unsigned gpio14_pins[] = { 14 };
  90. static unsigned gpio15_pins[] = { 15 };
  91. static unsigned gpio16_pins[] = { 16 };
  92. static unsigned gpio17_pins[] = { 17 };
  93. static unsigned gpio18_pins[] = { 18 };
  94. static unsigned gpio19_pins[] = { 19 };
  95. static unsigned gpio20_pins[] = { 20 };
  96. static unsigned gpio21_pins[] = { 21 };
  97. static unsigned gpio22_pins[] = { 22 };
  98. static unsigned gpio23_pins[] = { 23 };
  99. static unsigned gpio24_pins[] = { 24 };
  100. static unsigned gpio25_pins[] = { 25 };
  101. static unsigned gpio26_pins[] = { 26 };
  102. static unsigned gpio27_pins[] = { 27 };
  103. static unsigned gpio28_pins[] = { 28 };
  104. static unsigned gpio29_pins[] = { 29 };
  105. static unsigned gpio30_pins[] = { 30 };
  106. static unsigned gpio31_pins[] = { 31 };
  107. static unsigned hsspi_cs1_pins[] = { 36 };
  108. static unsigned usb_port1_pins[] = { 38 };
  109. static struct pingroup bcm6328_groups[] = {
  110. BCM_PIN_GROUP(gpio0),
  111. BCM_PIN_GROUP(gpio1),
  112. BCM_PIN_GROUP(gpio2),
  113. BCM_PIN_GROUP(gpio3),
  114. BCM_PIN_GROUP(gpio4),
  115. BCM_PIN_GROUP(gpio5),
  116. BCM_PIN_GROUP(gpio6),
  117. BCM_PIN_GROUP(gpio7),
  118. BCM_PIN_GROUP(gpio8),
  119. BCM_PIN_GROUP(gpio9),
  120. BCM_PIN_GROUP(gpio10),
  121. BCM_PIN_GROUP(gpio11),
  122. BCM_PIN_GROUP(gpio12),
  123. BCM_PIN_GROUP(gpio13),
  124. BCM_PIN_GROUP(gpio14),
  125. BCM_PIN_GROUP(gpio15),
  126. BCM_PIN_GROUP(gpio16),
  127. BCM_PIN_GROUP(gpio17),
  128. BCM_PIN_GROUP(gpio18),
  129. BCM_PIN_GROUP(gpio19),
  130. BCM_PIN_GROUP(gpio20),
  131. BCM_PIN_GROUP(gpio21),
  132. BCM_PIN_GROUP(gpio22),
  133. BCM_PIN_GROUP(gpio23),
  134. BCM_PIN_GROUP(gpio24),
  135. BCM_PIN_GROUP(gpio25),
  136. BCM_PIN_GROUP(gpio26),
  137. BCM_PIN_GROUP(gpio27),
  138. BCM_PIN_GROUP(gpio28),
  139. BCM_PIN_GROUP(gpio29),
  140. BCM_PIN_GROUP(gpio30),
  141. BCM_PIN_GROUP(gpio31),
  142. BCM_PIN_GROUP(hsspi_cs1),
  143. BCM_PIN_GROUP(usb_port1),
  144. };
  145. /* GPIO_MODE */
  146. static const char * const led_groups[] = {
  147. "gpio0",
  148. "gpio1",
  149. "gpio2",
  150. "gpio3",
  151. "gpio4",
  152. "gpio5",
  153. "gpio6",
  154. "gpio7",
  155. "gpio8",
  156. "gpio9",
  157. "gpio10",
  158. "gpio11",
  159. "gpio12",
  160. "gpio13",
  161. "gpio14",
  162. "gpio15",
  163. "gpio16",
  164. "gpio17",
  165. "gpio18",
  166. "gpio19",
  167. "gpio20",
  168. "gpio21",
  169. "gpio22",
  170. "gpio23",
  171. };
  172. /* PINMUX_SEL */
  173. static const char * const serial_led_data_groups[] = {
  174. "gpio6",
  175. };
  176. static const char * const serial_led_clk_groups[] = {
  177. "gpio7",
  178. };
  179. static const char * const inet_act_led_groups[] = {
  180. "gpio11",
  181. };
  182. static const char * const pcie_clkreq_groups[] = {
  183. "gpio16",
  184. };
  185. static const char * const ephy0_act_led_groups[] = {
  186. "gpio25",
  187. };
  188. static const char * const ephy1_act_led_groups[] = {
  189. "gpio26",
  190. };
  191. static const char * const ephy2_act_led_groups[] = {
  192. "gpio27",
  193. };
  194. static const char * const ephy3_act_led_groups[] = {
  195. "gpio28",
  196. };
  197. static const char * const hsspi_cs1_groups[] = {
  198. "hsspi_cs1"
  199. };
  200. static const char * const usb_host_port_groups[] = {
  201. "usb_port1",
  202. };
  203. static const char * const usb_device_port_groups[] = {
  204. "usb_port1",
  205. };
  206. #define BCM6328_MODE_FUN(n) \
  207. { \
  208. .name = #n, \
  209. .groups = n##_groups, \
  210. .num_groups = ARRAY_SIZE(n##_groups), \
  211. .mode_val = 1, \
  212. }
  213. #define BCM6328_MUX_FUN(n, mux) \
  214. { \
  215. .name = #n, \
  216. .groups = n##_groups, \
  217. .num_groups = ARRAY_SIZE(n##_groups), \
  218. .mux_val = mux, \
  219. }
  220. static const struct bcm6328_function bcm6328_funcs[] = {
  221. BCM6328_MODE_FUN(led),
  222. BCM6328_MUX_FUN(serial_led_data, 2),
  223. BCM6328_MUX_FUN(serial_led_clk, 2),
  224. BCM6328_MUX_FUN(inet_act_led, 1),
  225. BCM6328_MUX_FUN(pcie_clkreq, 2),
  226. BCM6328_MUX_FUN(ephy0_act_led, 1),
  227. BCM6328_MUX_FUN(ephy1_act_led, 1),
  228. BCM6328_MUX_FUN(ephy2_act_led, 1),
  229. BCM6328_MUX_FUN(ephy3_act_led, 1),
  230. BCM6328_MUX_FUN(hsspi_cs1, 2),
  231. BCM6328_MUX_FUN(usb_host_port, 1),
  232. BCM6328_MUX_FUN(usb_device_port, 2),
  233. };
  234. static inline unsigned int bcm6328_mux_off(unsigned int pin)
  235. {
  236. return bcm6328_mux[pin / 16];
  237. }
  238. static int bcm6328_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
  239. {
  240. return ARRAY_SIZE(bcm6328_groups);
  241. }
  242. static const char *bcm6328_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
  243. unsigned group)
  244. {
  245. return bcm6328_groups[group].name;
  246. }
  247. static int bcm6328_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
  248. unsigned group, const unsigned **pins,
  249. unsigned *npins)
  250. {
  251. *pins = bcm6328_groups[group].pins;
  252. *npins = bcm6328_groups[group].npins;
  253. return 0;
  254. }
  255. static int bcm6328_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
  256. {
  257. return ARRAY_SIZE(bcm6328_funcs);
  258. }
  259. static const char *bcm6328_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
  260. unsigned selector)
  261. {
  262. return bcm6328_funcs[selector].name;
  263. }
  264. static int bcm6328_pinctrl_get_groups(struct pinctrl_dev *pctldev,
  265. unsigned selector,
  266. const char * const **groups,
  267. unsigned * const num_groups)
  268. {
  269. *groups = bcm6328_funcs[selector].groups;
  270. *num_groups = bcm6328_funcs[selector].num_groups;
  271. return 0;
  272. }
  273. static void bcm6328_rmw_mux(struct bcm63xx_pinctrl *pc, unsigned pin,
  274. unsigned int mode, unsigned int mux)
  275. {
  276. if (pin < BCM6328_NUM_GPIOS)
  277. regmap_update_bits(pc->regs, BCM6328_MODE_REG, BIT(pin),
  278. mode ? BIT(pin) : 0);
  279. regmap_update_bits(pc->regs, bcm6328_mux_off(pin),
  280. BCM6328_MUX_MASK << ((pin % 16) * 2),
  281. mux << ((pin % 16) * 2));
  282. }
  283. static int bcm6328_pinctrl_set_mux(struct pinctrl_dev *pctldev,
  284. unsigned selector, unsigned group)
  285. {
  286. struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
  287. const struct pingroup *pg = &bcm6328_groups[group];
  288. const struct bcm6328_function *f = &bcm6328_funcs[selector];
  289. bcm6328_rmw_mux(pc, pg->pins[0], f->mode_val, f->mux_val);
  290. return 0;
  291. }
  292. static int bcm6328_gpio_request_enable(struct pinctrl_dev *pctldev,
  293. struct pinctrl_gpio_range *range,
  294. unsigned offset)
  295. {
  296. struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
  297. /* disable all functions using this pin */
  298. bcm6328_rmw_mux(pc, offset, 0, 0);
  299. return 0;
  300. }
  301. static const struct pinctrl_ops bcm6328_pctl_ops = {
  302. .dt_free_map = pinctrl_utils_free_map,
  303. .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
  304. .get_group_name = bcm6328_pinctrl_get_group_name,
  305. .get_group_pins = bcm6328_pinctrl_get_group_pins,
  306. .get_groups_count = bcm6328_pinctrl_get_group_count,
  307. };
  308. static const struct pinmux_ops bcm6328_pmx_ops = {
  309. .get_function_groups = bcm6328_pinctrl_get_groups,
  310. .get_function_name = bcm6328_pinctrl_get_func_name,
  311. .get_functions_count = bcm6328_pinctrl_get_func_count,
  312. .gpio_request_enable = bcm6328_gpio_request_enable,
  313. .set_mux = bcm6328_pinctrl_set_mux,
  314. .strict = true,
  315. };
  316. static const struct bcm63xx_pinctrl_soc bcm6328_soc = {
  317. .ngpios = BCM6328_NUM_GPIOS,
  318. .npins = ARRAY_SIZE(bcm6328_pins),
  319. .pctl_ops = &bcm6328_pctl_ops,
  320. .pins = bcm6328_pins,
  321. .pmx_ops = &bcm6328_pmx_ops,
  322. };
  323. static int bcm6328_pinctrl_probe(struct platform_device *pdev)
  324. {
  325. return bcm63xx_pinctrl_probe(pdev, &bcm6328_soc, NULL);
  326. }
  327. static const struct of_device_id bcm6328_pinctrl_match[] = {
  328. { .compatible = "brcm,bcm6328-pinctrl", },
  329. { /* sentinel */ }
  330. };
  331. static struct platform_driver bcm6328_pinctrl_driver = {
  332. .probe = bcm6328_pinctrl_probe,
  333. .driver = {
  334. .name = "bcm6328-pinctrl",
  335. .of_match_table = bcm6328_pinctrl_match,
  336. },
  337. };
  338. builtin_platform_driver(bcm6328_pinctrl_driver);