pinctrl-bcm6318.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Driver for BCM6318 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 BCM6318_NUM_GPIOS 50
  18. #define BCM6318_NUM_MUX 48
  19. #define BCM6318_MODE_REG 0x18
  20. #define BCM6318_MUX_REG 0x1c
  21. #define BCM6328_MUX_MASK GENMASK(1, 0)
  22. #define BCM6318_PAD_REG 0x54
  23. #define BCM6328_PAD_MASK GENMASK(3, 0)
  24. struct bcm6318_function {
  25. const char *name;
  26. const char * const *groups;
  27. const unsigned num_groups;
  28. unsigned mode_val:1;
  29. unsigned mux_val:2;
  30. };
  31. static const struct pinctrl_pin_desc bcm6318_pins[] = {
  32. PINCTRL_PIN(0, "gpio0"),
  33. PINCTRL_PIN(1, "gpio1"),
  34. PINCTRL_PIN(2, "gpio2"),
  35. PINCTRL_PIN(3, "gpio3"),
  36. PINCTRL_PIN(4, "gpio4"),
  37. PINCTRL_PIN(5, "gpio5"),
  38. PINCTRL_PIN(6, "gpio6"),
  39. PINCTRL_PIN(7, "gpio7"),
  40. PINCTRL_PIN(8, "gpio8"),
  41. PINCTRL_PIN(9, "gpio9"),
  42. PINCTRL_PIN(10, "gpio10"),
  43. PINCTRL_PIN(11, "gpio11"),
  44. PINCTRL_PIN(12, "gpio12"),
  45. PINCTRL_PIN(13, "gpio13"),
  46. PINCTRL_PIN(14, "gpio14"),
  47. PINCTRL_PIN(15, "gpio15"),
  48. PINCTRL_PIN(16, "gpio16"),
  49. PINCTRL_PIN(17, "gpio17"),
  50. PINCTRL_PIN(18, "gpio18"),
  51. PINCTRL_PIN(19, "gpio19"),
  52. PINCTRL_PIN(20, "gpio20"),
  53. PINCTRL_PIN(21, "gpio21"),
  54. PINCTRL_PIN(22, "gpio22"),
  55. PINCTRL_PIN(23, "gpio23"),
  56. PINCTRL_PIN(24, "gpio24"),
  57. PINCTRL_PIN(25, "gpio25"),
  58. PINCTRL_PIN(26, "gpio26"),
  59. PINCTRL_PIN(27, "gpio27"),
  60. PINCTRL_PIN(28, "gpio28"),
  61. PINCTRL_PIN(29, "gpio29"),
  62. PINCTRL_PIN(30, "gpio30"),
  63. PINCTRL_PIN(31, "gpio31"),
  64. PINCTRL_PIN(32, "gpio32"),
  65. PINCTRL_PIN(33, "gpio33"),
  66. PINCTRL_PIN(34, "gpio34"),
  67. PINCTRL_PIN(35, "gpio35"),
  68. PINCTRL_PIN(36, "gpio36"),
  69. PINCTRL_PIN(37, "gpio37"),
  70. PINCTRL_PIN(38, "gpio38"),
  71. PINCTRL_PIN(39, "gpio39"),
  72. PINCTRL_PIN(40, "gpio40"),
  73. PINCTRL_PIN(41, "gpio41"),
  74. PINCTRL_PIN(42, "gpio42"),
  75. PINCTRL_PIN(43, "gpio43"),
  76. PINCTRL_PIN(44, "gpio44"),
  77. PINCTRL_PIN(45, "gpio45"),
  78. PINCTRL_PIN(46, "gpio46"),
  79. PINCTRL_PIN(47, "gpio47"),
  80. PINCTRL_PIN(48, "gpio48"),
  81. PINCTRL_PIN(49, "gpio49"),
  82. };
  83. static unsigned gpio0_pins[] = { 0 };
  84. static unsigned gpio1_pins[] = { 1 };
  85. static unsigned gpio2_pins[] = { 2 };
  86. static unsigned gpio3_pins[] = { 3 };
  87. static unsigned gpio4_pins[] = { 4 };
  88. static unsigned gpio5_pins[] = { 5 };
  89. static unsigned gpio6_pins[] = { 6 };
  90. static unsigned gpio7_pins[] = { 7 };
  91. static unsigned gpio8_pins[] = { 8 };
  92. static unsigned gpio9_pins[] = { 9 };
  93. static unsigned gpio10_pins[] = { 10 };
  94. static unsigned gpio11_pins[] = { 11 };
  95. static unsigned gpio12_pins[] = { 12 };
  96. static unsigned gpio13_pins[] = { 13 };
  97. static unsigned gpio14_pins[] = { 14 };
  98. static unsigned gpio15_pins[] = { 15 };
  99. static unsigned gpio16_pins[] = { 16 };
  100. static unsigned gpio17_pins[] = { 17 };
  101. static unsigned gpio18_pins[] = { 18 };
  102. static unsigned gpio19_pins[] = { 19 };
  103. static unsigned gpio20_pins[] = { 20 };
  104. static unsigned gpio21_pins[] = { 21 };
  105. static unsigned gpio22_pins[] = { 22 };
  106. static unsigned gpio23_pins[] = { 23 };
  107. static unsigned gpio24_pins[] = { 24 };
  108. static unsigned gpio25_pins[] = { 25 };
  109. static unsigned gpio26_pins[] = { 26 };
  110. static unsigned gpio27_pins[] = { 27 };
  111. static unsigned gpio28_pins[] = { 28 };
  112. static unsigned gpio29_pins[] = { 29 };
  113. static unsigned gpio30_pins[] = { 30 };
  114. static unsigned gpio31_pins[] = { 31 };
  115. static unsigned gpio32_pins[] = { 32 };
  116. static unsigned gpio33_pins[] = { 33 };
  117. static unsigned gpio34_pins[] = { 34 };
  118. static unsigned gpio35_pins[] = { 35 };
  119. static unsigned gpio36_pins[] = { 36 };
  120. static unsigned gpio37_pins[] = { 37 };
  121. static unsigned gpio38_pins[] = { 38 };
  122. static unsigned gpio39_pins[] = { 39 };
  123. static unsigned gpio40_pins[] = { 40 };
  124. static unsigned gpio41_pins[] = { 41 };
  125. static unsigned gpio42_pins[] = { 42 };
  126. static unsigned gpio43_pins[] = { 43 };
  127. static unsigned gpio44_pins[] = { 44 };
  128. static unsigned gpio45_pins[] = { 45 };
  129. static unsigned gpio46_pins[] = { 46 };
  130. static unsigned gpio47_pins[] = { 47 };
  131. static unsigned gpio48_pins[] = { 48 };
  132. static unsigned gpio49_pins[] = { 49 };
  133. static struct pingroup bcm6318_groups[] = {
  134. BCM_PIN_GROUP(gpio0),
  135. BCM_PIN_GROUP(gpio1),
  136. BCM_PIN_GROUP(gpio2),
  137. BCM_PIN_GROUP(gpio3),
  138. BCM_PIN_GROUP(gpio4),
  139. BCM_PIN_GROUP(gpio5),
  140. BCM_PIN_GROUP(gpio6),
  141. BCM_PIN_GROUP(gpio7),
  142. BCM_PIN_GROUP(gpio8),
  143. BCM_PIN_GROUP(gpio9),
  144. BCM_PIN_GROUP(gpio10),
  145. BCM_PIN_GROUP(gpio11),
  146. BCM_PIN_GROUP(gpio12),
  147. BCM_PIN_GROUP(gpio13),
  148. BCM_PIN_GROUP(gpio14),
  149. BCM_PIN_GROUP(gpio15),
  150. BCM_PIN_GROUP(gpio16),
  151. BCM_PIN_GROUP(gpio17),
  152. BCM_PIN_GROUP(gpio18),
  153. BCM_PIN_GROUP(gpio19),
  154. BCM_PIN_GROUP(gpio20),
  155. BCM_PIN_GROUP(gpio21),
  156. BCM_PIN_GROUP(gpio22),
  157. BCM_PIN_GROUP(gpio23),
  158. BCM_PIN_GROUP(gpio24),
  159. BCM_PIN_GROUP(gpio25),
  160. BCM_PIN_GROUP(gpio26),
  161. BCM_PIN_GROUP(gpio27),
  162. BCM_PIN_GROUP(gpio28),
  163. BCM_PIN_GROUP(gpio29),
  164. BCM_PIN_GROUP(gpio30),
  165. BCM_PIN_GROUP(gpio31),
  166. BCM_PIN_GROUP(gpio32),
  167. BCM_PIN_GROUP(gpio33),
  168. BCM_PIN_GROUP(gpio34),
  169. BCM_PIN_GROUP(gpio35),
  170. BCM_PIN_GROUP(gpio36),
  171. BCM_PIN_GROUP(gpio37),
  172. BCM_PIN_GROUP(gpio38),
  173. BCM_PIN_GROUP(gpio39),
  174. BCM_PIN_GROUP(gpio40),
  175. BCM_PIN_GROUP(gpio41),
  176. BCM_PIN_GROUP(gpio42),
  177. BCM_PIN_GROUP(gpio43),
  178. BCM_PIN_GROUP(gpio44),
  179. BCM_PIN_GROUP(gpio45),
  180. BCM_PIN_GROUP(gpio46),
  181. BCM_PIN_GROUP(gpio47),
  182. BCM_PIN_GROUP(gpio48),
  183. BCM_PIN_GROUP(gpio49),
  184. };
  185. /* GPIO_MODE */
  186. static const char * const led_groups[] = {
  187. "gpio0",
  188. "gpio1",
  189. "gpio2",
  190. "gpio3",
  191. "gpio4",
  192. "gpio5",
  193. "gpio6",
  194. "gpio7",
  195. "gpio8",
  196. "gpio9",
  197. "gpio10",
  198. "gpio11",
  199. "gpio12",
  200. "gpio13",
  201. "gpio14",
  202. "gpio15",
  203. "gpio16",
  204. "gpio17",
  205. "gpio18",
  206. "gpio19",
  207. "gpio20",
  208. "gpio21",
  209. "gpio22",
  210. "gpio23",
  211. };
  212. /* PINMUX_SEL */
  213. static const char * const ephy0_spd_led_groups[] = {
  214. "gpio0",
  215. };
  216. static const char * const ephy1_spd_led_groups[] = {
  217. "gpio1",
  218. };
  219. static const char * const ephy2_spd_led_groups[] = {
  220. "gpio2",
  221. };
  222. static const char * const ephy3_spd_led_groups[] = {
  223. "gpio3",
  224. };
  225. static const char * const ephy0_act_led_groups[] = {
  226. "gpio4",
  227. };
  228. static const char * const ephy1_act_led_groups[] = {
  229. "gpio5",
  230. };
  231. static const char * const ephy2_act_led_groups[] = {
  232. "gpio6",
  233. };
  234. static const char * const ephy3_act_led_groups[] = {
  235. "gpio7",
  236. };
  237. static const char * const serial_led_data_groups[] = {
  238. "gpio6",
  239. };
  240. static const char * const serial_led_clk_groups[] = {
  241. "gpio7",
  242. };
  243. static const char * const inet_act_led_groups[] = {
  244. "gpio8",
  245. };
  246. static const char * const inet_fail_led_groups[] = {
  247. "gpio9",
  248. };
  249. static const char * const dsl_led_groups[] = {
  250. "gpio10",
  251. };
  252. static const char * const post_fail_led_groups[] = {
  253. "gpio11",
  254. };
  255. static const char * const wlan_wps_led_groups[] = {
  256. "gpio12",
  257. };
  258. static const char * const usb_pwron_groups[] = {
  259. "gpio13",
  260. };
  261. static const char * const usb_device_led_groups[] = {
  262. "gpio13",
  263. };
  264. static const char * const usb_active_groups[] = {
  265. "gpio40",
  266. };
  267. #define BCM6318_MODE_FUN(n) \
  268. { \
  269. .name = #n, \
  270. .groups = n##_groups, \
  271. .num_groups = ARRAY_SIZE(n##_groups), \
  272. .mode_val = 1, \
  273. }
  274. #define BCM6318_MUX_FUN(n, mux) \
  275. { \
  276. .name = #n, \
  277. .groups = n##_groups, \
  278. .num_groups = ARRAY_SIZE(n##_groups), \
  279. .mux_val = mux, \
  280. }
  281. static const struct bcm6318_function bcm6318_funcs[] = {
  282. BCM6318_MODE_FUN(led),
  283. BCM6318_MUX_FUN(ephy0_spd_led, 1),
  284. BCM6318_MUX_FUN(ephy1_spd_led, 1),
  285. BCM6318_MUX_FUN(ephy2_spd_led, 1),
  286. BCM6318_MUX_FUN(ephy3_spd_led, 1),
  287. BCM6318_MUX_FUN(ephy0_act_led, 1),
  288. BCM6318_MUX_FUN(ephy1_act_led, 1),
  289. BCM6318_MUX_FUN(ephy2_act_led, 1),
  290. BCM6318_MUX_FUN(ephy3_act_led, 1),
  291. BCM6318_MUX_FUN(serial_led_data, 3),
  292. BCM6318_MUX_FUN(serial_led_clk, 3),
  293. BCM6318_MUX_FUN(inet_act_led, 1),
  294. BCM6318_MUX_FUN(inet_fail_led, 1),
  295. BCM6318_MUX_FUN(dsl_led, 1),
  296. BCM6318_MUX_FUN(post_fail_led, 1),
  297. BCM6318_MUX_FUN(wlan_wps_led, 1),
  298. BCM6318_MUX_FUN(usb_pwron, 1),
  299. BCM6318_MUX_FUN(usb_device_led, 2),
  300. BCM6318_MUX_FUN(usb_active, 2),
  301. };
  302. static inline unsigned int bcm6318_mux_off(unsigned int pin)
  303. {
  304. return BCM6318_MUX_REG + (pin / 16) * 4;
  305. }
  306. static inline unsigned int bcm6318_pad_off(unsigned int pin)
  307. {
  308. return BCM6318_PAD_REG + (pin / 8) * 4;
  309. }
  310. static int bcm6318_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
  311. {
  312. return ARRAY_SIZE(bcm6318_groups);
  313. }
  314. static const char *bcm6318_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
  315. unsigned group)
  316. {
  317. return bcm6318_groups[group].name;
  318. }
  319. static int bcm6318_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
  320. unsigned group, const unsigned **pins,
  321. unsigned *npins)
  322. {
  323. *pins = bcm6318_groups[group].pins;
  324. *npins = bcm6318_groups[group].npins;
  325. return 0;
  326. }
  327. static int bcm6318_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
  328. {
  329. return ARRAY_SIZE(bcm6318_funcs);
  330. }
  331. static const char *bcm6318_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
  332. unsigned selector)
  333. {
  334. return bcm6318_funcs[selector].name;
  335. }
  336. static int bcm6318_pinctrl_get_groups(struct pinctrl_dev *pctldev,
  337. unsigned selector,
  338. const char * const **groups,
  339. unsigned * const num_groups)
  340. {
  341. *groups = bcm6318_funcs[selector].groups;
  342. *num_groups = bcm6318_funcs[selector].num_groups;
  343. return 0;
  344. }
  345. static inline void bcm6318_rmw_mux(struct bcm63xx_pinctrl *pc, unsigned pin,
  346. unsigned int mode, unsigned int mux)
  347. {
  348. if (pin < BCM63XX_BANK_GPIOS)
  349. regmap_update_bits(pc->regs, BCM6318_MODE_REG, BIT(pin),
  350. mode ? BIT(pin) : 0);
  351. if (pin < BCM6318_NUM_MUX)
  352. regmap_update_bits(pc->regs,
  353. bcm6318_mux_off(pin),
  354. BCM6328_MUX_MASK << ((pin % 16) * 2),
  355. mux << ((pin % 16) * 2));
  356. }
  357. static inline void bcm6318_set_pad(struct bcm63xx_pinctrl *pc, unsigned pin,
  358. uint8_t val)
  359. {
  360. regmap_update_bits(pc->regs, bcm6318_pad_off(pin),
  361. BCM6328_PAD_MASK << ((pin % 8) * 4),
  362. val << ((pin % 8) * 4));
  363. }
  364. static int bcm6318_pinctrl_set_mux(struct pinctrl_dev *pctldev,
  365. unsigned selector, unsigned group)
  366. {
  367. struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
  368. const struct pingroup *pg = &bcm6318_groups[group];
  369. const struct bcm6318_function *f = &bcm6318_funcs[selector];
  370. bcm6318_rmw_mux(pc, pg->pins[0], f->mode_val, f->mux_val);
  371. return 0;
  372. }
  373. static int bcm6318_gpio_request_enable(struct pinctrl_dev *pctldev,
  374. struct pinctrl_gpio_range *range,
  375. unsigned offset)
  376. {
  377. struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
  378. /* disable all functions using this pin */
  379. if (offset < 13) {
  380. /* GPIOs 0-12 use mux 0 as GPIO function */
  381. bcm6318_rmw_mux(pc, offset, 0, 0);
  382. } else if (offset < 42) {
  383. /* GPIOs 13-41 use mux 3 as GPIO function */
  384. bcm6318_rmw_mux(pc, offset, 0, 3);
  385. bcm6318_set_pad(pc, offset, 0);
  386. }
  387. return 0;
  388. }
  389. static const struct pinctrl_ops bcm6318_pctl_ops = {
  390. .dt_free_map = pinctrl_utils_free_map,
  391. .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
  392. .get_group_name = bcm6318_pinctrl_get_group_name,
  393. .get_group_pins = bcm6318_pinctrl_get_group_pins,
  394. .get_groups_count = bcm6318_pinctrl_get_group_count,
  395. };
  396. static const struct pinmux_ops bcm6318_pmx_ops = {
  397. .get_function_groups = bcm6318_pinctrl_get_groups,
  398. .get_function_name = bcm6318_pinctrl_get_func_name,
  399. .get_functions_count = bcm6318_pinctrl_get_func_count,
  400. .gpio_request_enable = bcm6318_gpio_request_enable,
  401. .set_mux = bcm6318_pinctrl_set_mux,
  402. .strict = true,
  403. };
  404. static const struct bcm63xx_pinctrl_soc bcm6318_soc = {
  405. .ngpios = BCM6318_NUM_GPIOS,
  406. .npins = ARRAY_SIZE(bcm6318_pins),
  407. .pctl_ops = &bcm6318_pctl_ops,
  408. .pins = bcm6318_pins,
  409. .pmx_ops = &bcm6318_pmx_ops,
  410. };
  411. static int bcm6318_pinctrl_probe(struct platform_device *pdev)
  412. {
  413. return bcm63xx_pinctrl_probe(pdev, &bcm6318_soc, NULL);
  414. }
  415. static const struct of_device_id bcm6318_pinctrl_match[] = {
  416. { .compatible = "brcm,bcm6318-pinctrl", },
  417. { /* sentinel */ }
  418. };
  419. static struct platform_driver bcm6318_pinctrl_driver = {
  420. .probe = bcm6318_pinctrl_probe,
  421. .driver = {
  422. .name = "bcm6318-pinctrl",
  423. .of_match_table = bcm6318_pinctrl_match,
  424. },
  425. };
  426. builtin_platform_driver(bcm6318_pinctrl_driver);