382-pinctrl-add-a-pincontrol-driver-for-BCM6318.patch 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. From bd9c250ef85e6f99aa5d59b21abb87d0a48f2f61 Mon Sep 17 00:00:00 2001
  2. From: Jonas Gorski <[email protected]>
  3. Date: Fri, 24 Jun 2016 22:20:39 +0200
  4. Subject: [PATCH 15/16] pinctrl: add a pincontrol driver for BCM6318
  5. Add a pincontrol driver for BCM6318. BCM6318 allows muxing most GPIOs
  6. to different functions. BCM6318 is similar to BCM6328 with the addition
  7. of a pad register, and the GPIO meaning of the mux register changes
  8. based on the GPIO number.
  9. Signed-off-by: Jonas Gorski <[email protected]>
  10. ---
  11. drivers/pinctrl/bcm63xx/Kconfig | 7 +
  12. drivers/pinctrl/bcm63xx/Makefile | 1 +
  13. drivers/pinctrl/bcm63xx/pinctrl-bcm6318.c | 564 ++++++++++++++++++++++++++++++
  14. 3 files changed, 572 insertions(+)
  15. create mode 100644 drivers/pinctrl/bcm63xx/pinctrl-bcm6318.c
  16. --- a/drivers/pinctrl/bcm63xx/Kconfig
  17. +++ b/drivers/pinctrl/bcm63xx/Kconfig
  18. @@ -2,6 +2,13 @@ config PINCTRL_BCM63XX
  19. bool
  20. select GPIO_GENERIC
  21. +config PINCTRL_BCM6318
  22. + bool "BCM6318 pincontrol driver" if COMPILE_TEST
  23. + select PINMUX
  24. + select PINCONF
  25. + select PINCTRL_BCM63XX
  26. + select GENERIC_PINCONF
  27. +
  28. config PINCTRL_BCM6328
  29. bool "BCM6328 pincontrol driver" if COMPILE_TEST
  30. select PINMUX
  31. --- a/drivers/pinctrl/bcm63xx/Makefile
  32. +++ b/drivers/pinctrl/bcm63xx/Makefile
  33. @@ -1,4 +1,5 @@
  34. obj-$(CONFIG_PINCTRL_BCM63XX) += pinctrl-bcm63xx.o
  35. +obj-$(CONFIG_PINCTRL_BCM6318) += pinctrl-bcm6318.o
  36. obj-$(CONFIG_PINCTRL_BCM6328) += pinctrl-bcm6328.o
  37. obj-$(CONFIG_PINCTRL_BCM6348) += pinctrl-bcm6348.o
  38. obj-$(CONFIG_PINCTRL_BCM6358) += pinctrl-bcm6358.o
  39. --- /dev/null
  40. +++ b/drivers/pinctrl/bcm63xx/pinctrl-bcm6318.c
  41. @@ -0,0 +1,564 @@
  42. +/*
  43. + * This file is subject to the terms and conditions of the GNU General Public
  44. + * License. See the file "COPYING" in the main directory of this archive
  45. + * for more details.
  46. + *
  47. + * Copyright (C) 2016 Jonas Gorski <[email protected]>
  48. + */
  49. +
  50. +#include <linux/kernel.h>
  51. +#include <linux/spinlock.h>
  52. +#include <linux/bitops.h>
  53. +#include <linux/gpio.h>
  54. +#include <linux/gpio/driver.h>
  55. +#include <linux/of.h>
  56. +#include <linux/of_gpio.h>
  57. +#include <linux/slab.h>
  58. +#include <linux/platform_device.h>
  59. +
  60. +#include <linux/pinctrl/pinconf.h>
  61. +#include <linux/pinctrl/pinconf-generic.h>
  62. +#include <linux/pinctrl/pinmux.h>
  63. +#include <linux/pinctrl/machine.h>
  64. +
  65. +#include "../core.h"
  66. +#include "../pinctrl-utils.h"
  67. +
  68. +#include "pinctrl-bcm63xx.h"
  69. +
  70. +#define BCM6318_NGPIO 50
  71. +
  72. +struct bcm6318_pingroup {
  73. + const char *name;
  74. + const unsigned * const pins;
  75. + const unsigned num_pins;
  76. +};
  77. +
  78. +struct bcm6318_function {
  79. + const char *name;
  80. + const char * const *groups;
  81. + const unsigned num_groups;
  82. +
  83. + unsigned mode_val:1;
  84. + unsigned mux_val:2;
  85. +};
  86. +
  87. +struct bcm6318_pinctrl {
  88. + struct pinctrl_dev *pctldev;
  89. + struct pinctrl_desc desc;
  90. +
  91. + void __iomem *mode;
  92. + void __iomem *mux[3];
  93. + void __iomem *pad[6];
  94. +
  95. + /* register access lock */
  96. + spinlock_t lock;
  97. +
  98. + struct gpio_chip gpio[2];
  99. +};
  100. +
  101. +static const struct pinctrl_pin_desc bcm6318_pins[] = {
  102. + PINCTRL_PIN(0, "gpio0"),
  103. + PINCTRL_PIN(1, "gpio1"),
  104. + PINCTRL_PIN(2, "gpio2"),
  105. + PINCTRL_PIN(3, "gpio3"),
  106. + PINCTRL_PIN(4, "gpio4"),
  107. + PINCTRL_PIN(5, "gpio5"),
  108. + PINCTRL_PIN(6, "gpio6"),
  109. + PINCTRL_PIN(7, "gpio7"),
  110. + PINCTRL_PIN(8, "gpio8"),
  111. + PINCTRL_PIN(9, "gpio9"),
  112. + PINCTRL_PIN(10, "gpio10"),
  113. + PINCTRL_PIN(11, "gpio11"),
  114. + PINCTRL_PIN(12, "gpio12"),
  115. + PINCTRL_PIN(13, "gpio13"),
  116. + PINCTRL_PIN(14, "gpio14"),
  117. + PINCTRL_PIN(15, "gpio15"),
  118. + PINCTRL_PIN(16, "gpio16"),
  119. + PINCTRL_PIN(17, "gpio17"),
  120. + PINCTRL_PIN(18, "gpio18"),
  121. + PINCTRL_PIN(19, "gpio19"),
  122. + PINCTRL_PIN(20, "gpio20"),
  123. + PINCTRL_PIN(21, "gpio21"),
  124. + PINCTRL_PIN(22, "gpio22"),
  125. + PINCTRL_PIN(23, "gpio23"),
  126. + PINCTRL_PIN(24, "gpio24"),
  127. + PINCTRL_PIN(25, "gpio25"),
  128. + PINCTRL_PIN(26, "gpio26"),
  129. + PINCTRL_PIN(27, "gpio27"),
  130. + PINCTRL_PIN(28, "gpio28"),
  131. + PINCTRL_PIN(29, "gpio29"),
  132. + PINCTRL_PIN(30, "gpio30"),
  133. + PINCTRL_PIN(31, "gpio31"),
  134. + PINCTRL_PIN(32, "gpio32"),
  135. + PINCTRL_PIN(33, "gpio33"),
  136. + PINCTRL_PIN(34, "gpio34"),
  137. + PINCTRL_PIN(35, "gpio35"),
  138. + PINCTRL_PIN(36, "gpio36"),
  139. + PINCTRL_PIN(37, "gpio37"),
  140. + PINCTRL_PIN(38, "gpio38"),
  141. + PINCTRL_PIN(39, "gpio39"),
  142. + PINCTRL_PIN(40, "gpio40"),
  143. + PINCTRL_PIN(41, "gpio41"),
  144. + PINCTRL_PIN(42, "gpio42"),
  145. + PINCTRL_PIN(43, "gpio43"),
  146. + PINCTRL_PIN(44, "gpio44"),
  147. + PINCTRL_PIN(45, "gpio45"),
  148. + PINCTRL_PIN(46, "gpio46"),
  149. + PINCTRL_PIN(47, "gpio47"),
  150. + PINCTRL_PIN(48, "gpio48"),
  151. + PINCTRL_PIN(49, "gpio49"),
  152. +};
  153. +
  154. +static unsigned gpio0_pins[] = { 0 };
  155. +static unsigned gpio1_pins[] = { 1 };
  156. +static unsigned gpio2_pins[] = { 2 };
  157. +static unsigned gpio3_pins[] = { 3 };
  158. +static unsigned gpio4_pins[] = { 4 };
  159. +static unsigned gpio5_pins[] = { 5 };
  160. +static unsigned gpio6_pins[] = { 6 };
  161. +static unsigned gpio7_pins[] = { 7 };
  162. +static unsigned gpio8_pins[] = { 8 };
  163. +static unsigned gpio9_pins[] = { 9 };
  164. +static unsigned gpio10_pins[] = { 10 };
  165. +static unsigned gpio11_pins[] = { 11 };
  166. +static unsigned gpio12_pins[] = { 12 };
  167. +static unsigned gpio13_pins[] = { 13 };
  168. +static unsigned gpio14_pins[] = { 14 };
  169. +static unsigned gpio15_pins[] = { 15 };
  170. +static unsigned gpio16_pins[] = { 16 };
  171. +static unsigned gpio17_pins[] = { 17 };
  172. +static unsigned gpio18_pins[] = { 18 };
  173. +static unsigned gpio19_pins[] = { 19 };
  174. +static unsigned gpio20_pins[] = { 20 };
  175. +static unsigned gpio21_pins[] = { 21 };
  176. +static unsigned gpio22_pins[] = { 22 };
  177. +static unsigned gpio23_pins[] = { 23 };
  178. +static unsigned gpio24_pins[] = { 24 };
  179. +static unsigned gpio25_pins[] = { 25 };
  180. +static unsigned gpio26_pins[] = { 26 };
  181. +static unsigned gpio27_pins[] = { 27 };
  182. +static unsigned gpio28_pins[] = { 28 };
  183. +static unsigned gpio29_pins[] = { 29 };
  184. +static unsigned gpio30_pins[] = { 30 };
  185. +static unsigned gpio31_pins[] = { 31 };
  186. +static unsigned gpio32_pins[] = { 32 };
  187. +static unsigned gpio33_pins[] = { 33 };
  188. +static unsigned gpio34_pins[] = { 34 };
  189. +static unsigned gpio35_pins[] = { 35 };
  190. +static unsigned gpio36_pins[] = { 36 };
  191. +static unsigned gpio37_pins[] = { 37 };
  192. +static unsigned gpio38_pins[] = { 38 };
  193. +static unsigned gpio39_pins[] = { 39 };
  194. +static unsigned gpio40_pins[] = { 40 };
  195. +static unsigned gpio41_pins[] = { 41 };
  196. +static unsigned gpio42_pins[] = { 42 };
  197. +static unsigned gpio43_pins[] = { 43 };
  198. +static unsigned gpio44_pins[] = { 44 };
  199. +static unsigned gpio45_pins[] = { 45 };
  200. +static unsigned gpio46_pins[] = { 46 };
  201. +static unsigned gpio47_pins[] = { 47 };
  202. +static unsigned gpio48_pins[] = { 48 };
  203. +static unsigned gpio49_pins[] = { 49 };
  204. +
  205. +#define BCM6318_GROUP(n) \
  206. + { \
  207. + .name = #n, \
  208. + .pins = n##_pins, \
  209. + .num_pins = ARRAY_SIZE(n##_pins), \
  210. + }
  211. +
  212. +static struct bcm6318_pingroup bcm6318_groups[] = {
  213. + BCM6318_GROUP(gpio0),
  214. + BCM6318_GROUP(gpio1),
  215. + BCM6318_GROUP(gpio2),
  216. + BCM6318_GROUP(gpio3),
  217. + BCM6318_GROUP(gpio4),
  218. + BCM6318_GROUP(gpio5),
  219. + BCM6318_GROUP(gpio6),
  220. + BCM6318_GROUP(gpio7),
  221. + BCM6318_GROUP(gpio8),
  222. + BCM6318_GROUP(gpio9),
  223. + BCM6318_GROUP(gpio10),
  224. + BCM6318_GROUP(gpio11),
  225. + BCM6318_GROUP(gpio12),
  226. + BCM6318_GROUP(gpio13),
  227. + BCM6318_GROUP(gpio14),
  228. + BCM6318_GROUP(gpio15),
  229. + BCM6318_GROUP(gpio16),
  230. + BCM6318_GROUP(gpio17),
  231. + BCM6318_GROUP(gpio18),
  232. + BCM6318_GROUP(gpio19),
  233. + BCM6318_GROUP(gpio20),
  234. + BCM6318_GROUP(gpio21),
  235. + BCM6318_GROUP(gpio22),
  236. + BCM6318_GROUP(gpio23),
  237. + BCM6318_GROUP(gpio24),
  238. + BCM6318_GROUP(gpio25),
  239. + BCM6318_GROUP(gpio26),
  240. + BCM6318_GROUP(gpio27),
  241. + BCM6318_GROUP(gpio28),
  242. + BCM6318_GROUP(gpio29),
  243. + BCM6318_GROUP(gpio30),
  244. + BCM6318_GROUP(gpio31),
  245. + BCM6318_GROUP(gpio32),
  246. + BCM6318_GROUP(gpio33),
  247. + BCM6318_GROUP(gpio34),
  248. + BCM6318_GROUP(gpio35),
  249. + BCM6318_GROUP(gpio36),
  250. + BCM6318_GROUP(gpio37),
  251. + BCM6318_GROUP(gpio38),
  252. + BCM6318_GROUP(gpio39),
  253. + BCM6318_GROUP(gpio40),
  254. + BCM6318_GROUP(gpio41),
  255. + BCM6318_GROUP(gpio42),
  256. + BCM6318_GROUP(gpio43),
  257. + BCM6318_GROUP(gpio44),
  258. + BCM6318_GROUP(gpio45),
  259. + BCM6318_GROUP(gpio46),
  260. + BCM6318_GROUP(gpio47),
  261. + BCM6318_GROUP(gpio48),
  262. + BCM6318_GROUP(gpio49),
  263. +};
  264. +
  265. +/* GPIO_MODE */
  266. +static const char * const led_groups[] = {
  267. + "gpio0",
  268. + "gpio1",
  269. + "gpio2",
  270. + "gpio3",
  271. + "gpio4",
  272. + "gpio5",
  273. + "gpio6",
  274. + "gpio7",
  275. + "gpio8",
  276. + "gpio9",
  277. + "gpio10",
  278. + "gpio11",
  279. + "gpio12",
  280. + "gpio13",
  281. + "gpio14",
  282. + "gpio15",
  283. + "gpio16",
  284. + "gpio17",
  285. + "gpio18",
  286. + "gpio19",
  287. + "gpio20",
  288. + "gpio21",
  289. + "gpio22",
  290. + "gpio23",
  291. +};
  292. +
  293. +/* PINMUX_SEL */
  294. +static const char * const ephy0_spd_led_groups[] = {
  295. + "gpio0",
  296. +};
  297. +
  298. +static const char * const ephy1_spd_led_groups[] = {
  299. + "gpio1",
  300. +};
  301. +
  302. +static const char * const ephy2_spd_led_groups[] = {
  303. + "gpio2",
  304. +};
  305. +
  306. +static const char * const ephy3_spd_led_groups[] = {
  307. + "gpio3",
  308. +};
  309. +
  310. +static const char * const ephy0_act_led_groups[] = {
  311. + "gpio4",
  312. +};
  313. +
  314. +static const char * const ephy1_act_led_groups[] = {
  315. + "gpio5",
  316. +};
  317. +
  318. +static const char * const ephy2_act_led_groups[] = {
  319. + "gpio6",
  320. +};
  321. +
  322. +static const char * const ephy3_act_led_groups[] = {
  323. + "gpio7",
  324. +};
  325. +
  326. +static const char * const serial_led_data_groups[] = {
  327. + "gpio6",
  328. +};
  329. +
  330. +static const char * const serial_led_clk_groups[] = {
  331. + "gpio7",
  332. +};
  333. +
  334. +static const char * const inet_act_led_groups[] = {
  335. + "gpio8",
  336. +};
  337. +
  338. +static const char * const inet_fail_led_groups[] = {
  339. + "gpio9",
  340. +};
  341. +
  342. +static const char * const dsl_led_groups[] = {
  343. + "gpio10",
  344. +};
  345. +
  346. +static const char * const post_fail_led_groups[] = {
  347. + "gpio11",
  348. +};
  349. +
  350. +static const char * const wlan_wps_led_groups[] = {
  351. + "gpio12",
  352. +};
  353. +
  354. +static const char * const usb_pwron_groups[] = {
  355. + "gpio13",
  356. +};
  357. +
  358. +static const char * const usb_device_led_groups[] = {
  359. + "gpio13",
  360. +};
  361. +
  362. +static const char * const usb_active_groups[] = {
  363. + "gpio40",
  364. +};
  365. +
  366. +#define BCM6318_MODE_FUN(n) \
  367. + { \
  368. + .name = #n, \
  369. + .groups = n##_groups, \
  370. + .num_groups = ARRAY_SIZE(n##_groups), \
  371. + .mode_val = 1, \
  372. + }
  373. +
  374. +#define BCM6318_MUX_FUN(n, mux) \
  375. + { \
  376. + .name = #n, \
  377. + .groups = n##_groups, \
  378. + .num_groups = ARRAY_SIZE(n##_groups), \
  379. + .mux_val = mux, \
  380. + }
  381. +
  382. +static const struct bcm6318_function bcm6318_funcs[] = {
  383. + BCM6318_MODE_FUN(led),
  384. + BCM6318_MUX_FUN(ephy0_spd_led, 1),
  385. + BCM6318_MUX_FUN(ephy1_spd_led, 1),
  386. + BCM6318_MUX_FUN(ephy2_spd_led, 1),
  387. + BCM6318_MUX_FUN(ephy3_spd_led, 1),
  388. + BCM6318_MUX_FUN(ephy0_act_led, 1),
  389. + BCM6318_MUX_FUN(ephy1_act_led, 1),
  390. + BCM6318_MUX_FUN(ephy2_act_led, 1),
  391. + BCM6318_MUX_FUN(ephy3_act_led, 1),
  392. + BCM6318_MUX_FUN(serial_led_data, 3),
  393. + BCM6318_MUX_FUN(serial_led_clk, 3),
  394. + BCM6318_MUX_FUN(inet_act_led, 1),
  395. + BCM6318_MUX_FUN(inet_fail_led, 1),
  396. + BCM6318_MUX_FUN(dsl_led, 1),
  397. + BCM6318_MUX_FUN(post_fail_led, 1),
  398. + BCM6318_MUX_FUN(wlan_wps_led, 1),
  399. + BCM6318_MUX_FUN(usb_pwron, 1),
  400. + BCM6318_MUX_FUN(usb_device_led, 2),
  401. + BCM6318_MUX_FUN(usb_active, 2),
  402. +};
  403. +
  404. +static int bcm6318_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
  405. +{
  406. + return ARRAY_SIZE(bcm6318_groups);
  407. +}
  408. +
  409. +static const char *bcm6318_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
  410. + unsigned group)
  411. +{
  412. + return bcm6318_groups[group].name;
  413. +}
  414. +
  415. +static int bcm6318_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
  416. + unsigned group, const unsigned **pins,
  417. + unsigned *num_pins)
  418. +{
  419. + *pins = bcm6318_groups[group].pins;
  420. + *num_pins = bcm6318_groups[group].num_pins;
  421. +
  422. + return 0;
  423. +}
  424. +
  425. +static int bcm6318_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
  426. +{
  427. + return ARRAY_SIZE(bcm6318_funcs);
  428. +}
  429. +
  430. +static const char *bcm6318_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
  431. + unsigned selector)
  432. +{
  433. + return bcm6318_funcs[selector].name;
  434. +}
  435. +
  436. +static int bcm6318_pinctrl_get_groups(struct pinctrl_dev *pctldev,
  437. + unsigned selector,
  438. + const char * const **groups,
  439. + unsigned * const num_groups)
  440. +{
  441. + *groups = bcm6318_funcs[selector].groups;
  442. + *num_groups = bcm6318_funcs[selector].num_groups;
  443. +
  444. + return 0;
  445. +}
  446. +
  447. +static void bcm6318_rmw_mux(struct bcm6318_pinctrl *pctl, unsigned pin,
  448. + u32 mode, u32 mux)
  449. +{
  450. + unsigned long flags;
  451. + u32 reg;
  452. +
  453. + spin_lock_irqsave(&pctl->lock, flags);
  454. + if (pin < 32) {
  455. + reg = __raw_readl(pctl->mode);
  456. + reg &= ~BIT(pin);
  457. + if (mode)
  458. + reg |= BIT(pin);
  459. + __raw_writel(reg, pctl->mode);
  460. + }
  461. +
  462. + if (pin < 48) {
  463. + reg = __raw_readl(pctl->mux[pin / 16]);
  464. + reg &= ~(3UL << ((pin % 16) * 2));
  465. + reg |= mux << ((pin % 16) * 2);
  466. + __raw_writel(reg, pctl->mux[pin / 16]);
  467. + }
  468. + spin_unlock_irqrestore(&pctl->lock, flags);
  469. +}
  470. +
  471. +static void bcm6318_set_pad(struct bcm6318_pinctrl *pctl, unsigned pin, u8 val)
  472. +{
  473. + unsigned long flags;
  474. + u32 reg;
  475. +
  476. + spin_lock_irqsave(&pctl->lock, flags);
  477. + reg = __raw_readl(pctl->pad[pin / 8]);
  478. + reg &= ~(0xfUL << ((pin % 8) * 4));
  479. + reg |= val << ((pin % 8) * 4);
  480. + __raw_writel(reg, pctl->pad[pin / 8]);
  481. + spin_unlock_irqrestore(&pctl->lock, flags);
  482. +}
  483. +
  484. +static int bcm6318_pinctrl_set_mux(struct pinctrl_dev *pctldev,
  485. + unsigned selector, unsigned group)
  486. +{
  487. + struct bcm6318_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
  488. + const struct bcm6318_pingroup *grp = &bcm6318_groups[group];
  489. + const struct bcm6318_function *f = &bcm6318_funcs[selector];
  490. +
  491. + bcm6318_rmw_mux(pctl, grp->pins[0], f->mode_val, f->mux_val);
  492. +
  493. + return 0;
  494. +}
  495. +
  496. +static int bcm6318_gpio_request_enable(struct pinctrl_dev *pctldev,
  497. + struct pinctrl_gpio_range *range,
  498. + unsigned offset)
  499. +{
  500. + struct bcm6318_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
  501. +
  502. + /* disable all functions using this pin */
  503. + if (offset < 13) {
  504. + /* GPIOs 0-12 use mux 0 as GPIO function */
  505. + bcm6318_rmw_mux(pctl, offset, 0, 0);
  506. + } else if (offset < 42) {
  507. + /* GPIOs 13-41 use mux 3 as GPIO function */
  508. + bcm6318_rmw_mux(pctl, offset, 0, 3);
  509. +
  510. + /* FIXME: revert to old value for non gpio? */
  511. + bcm6318_set_pad(pctl, offset, 0);
  512. + } else {
  513. + /* no idea, really */
  514. + }
  515. +
  516. + return 0;
  517. +}
  518. +
  519. +static struct pinctrl_ops bcm6318_pctl_ops = {
  520. + .get_groups_count = bcm6318_pinctrl_get_group_count,
  521. + .get_group_name = bcm6318_pinctrl_get_group_name,
  522. + .get_group_pins = bcm6318_pinctrl_get_group_pins,
  523. +#ifdef CONFIG_OF
  524. + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
  525. + .dt_free_map = pinctrl_utils_free_map,
  526. +#endif
  527. +};
  528. +
  529. +static struct pinmux_ops bcm6318_pmx_ops = {
  530. + .get_functions_count = bcm6318_pinctrl_get_func_count,
  531. + .get_function_name = bcm6318_pinctrl_get_func_name,
  532. + .get_function_groups = bcm6318_pinctrl_get_groups,
  533. + .set_mux = bcm6318_pinctrl_set_mux,
  534. + .gpio_request_enable = bcm6318_gpio_request_enable,
  535. + .strict = true,
  536. +};
  537. +
  538. +static int bcm6318_pinctrl_probe(struct platform_device *pdev)
  539. +{
  540. + struct bcm6318_pinctrl *pctl;
  541. + struct resource *res;
  542. + void __iomem *mode, *mux, *pad;
  543. + unsigned i;
  544. +
  545. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mode");
  546. + mode = devm_ioremap_resource(&pdev->dev, res);
  547. + if (IS_ERR(mode))
  548. + return PTR_ERR(mode);
  549. +
  550. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mux");
  551. + mux = devm_ioremap_resource(&pdev->dev, res);
  552. + if (IS_ERR(mux))
  553. + return PTR_ERR(mux);
  554. +
  555. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pad");
  556. + pad = devm_ioremap_resource(&pdev->dev, res);
  557. + if (IS_ERR(pad))
  558. + return PTR_ERR(pad);
  559. +
  560. + pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
  561. + if (!pctl)
  562. + return -ENOMEM;
  563. +
  564. + spin_lock_init(&pctl->lock);
  565. +
  566. + pctl->mode = mode;
  567. +
  568. + for (i = 0; i < 3; i++)
  569. + pctl->mux[i] = mux + (i * 4);
  570. +
  571. + for (i = 0; i < 6; i++)
  572. + pctl->pad[i] = pad + (i * 4);
  573. +
  574. + pctl->desc.name = dev_name(&pdev->dev);
  575. + pctl->desc.owner = THIS_MODULE;
  576. + pctl->desc.pctlops = &bcm6318_pctl_ops;
  577. + pctl->desc.pmxops = &bcm6318_pmx_ops;
  578. +
  579. + pctl->desc.npins = ARRAY_SIZE(bcm6318_pins);
  580. + pctl->desc.pins = bcm6318_pins;
  581. +
  582. + platform_set_drvdata(pdev, pctl);
  583. +
  584. + pctl->pctldev = bcm63xx_pinctrl_register(pdev, &pctl->desc, pctl,
  585. + pctl->gpio, BCM6318_NGPIO);
  586. + if (IS_ERR(pctl->pctldev))
  587. + return PTR_ERR(pctl->pctldev);
  588. +
  589. + return 0;
  590. +}
  591. +
  592. +static const struct of_device_id bcm6318_pinctrl_match[] = {
  593. + { .compatible = "brcm,bcm6318-pinctrl", },
  594. + { },
  595. +};
  596. +
  597. +static struct platform_driver bcm6318_pinctrl_driver = {
  598. + .probe = bcm6318_pinctrl_probe,
  599. + .driver = {
  600. + .name = "bcm6318-pinctrl",
  601. + .of_match_table = bcm6318_pinctrl_match,
  602. + },
  603. +};
  604. +
  605. +builtin_platform_driver(bcm6318_pinctrl_driver);