0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/bits.h>
0010 #include <linux/gpio/driver.h>
0011 #include <linux/kernel.h>
0012 #include <linux/of.h>
0013 #include <linux/pinctrl/pinmux.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/regmap.h>
0016
0017 #include "../pinctrl-utils.h"
0018
0019 #include "pinctrl-bcm63xx.h"
0020
0021 #define BCM6318_NUM_GPIOS 50
0022 #define BCM6318_NUM_MUX 48
0023
0024 #define BCM6318_MODE_REG 0x18
0025 #define BCM6318_MUX_REG 0x1c
0026 #define BCM6328_MUX_MASK GENMASK(1, 0)
0027 #define BCM6318_PAD_REG 0x54
0028 #define BCM6328_PAD_MASK GENMASK(3, 0)
0029
0030 struct bcm6318_pingroup {
0031 const char *name;
0032 const unsigned * const pins;
0033 const unsigned num_pins;
0034 };
0035
0036 struct bcm6318_function {
0037 const char *name;
0038 const char * const *groups;
0039 const unsigned num_groups;
0040
0041 unsigned mode_val:1;
0042 unsigned mux_val:2;
0043 };
0044
0045 static const struct pinctrl_pin_desc bcm6318_pins[] = {
0046 PINCTRL_PIN(0, "gpio0"),
0047 PINCTRL_PIN(1, "gpio1"),
0048 PINCTRL_PIN(2, "gpio2"),
0049 PINCTRL_PIN(3, "gpio3"),
0050 PINCTRL_PIN(4, "gpio4"),
0051 PINCTRL_PIN(5, "gpio5"),
0052 PINCTRL_PIN(6, "gpio6"),
0053 PINCTRL_PIN(7, "gpio7"),
0054 PINCTRL_PIN(8, "gpio8"),
0055 PINCTRL_PIN(9, "gpio9"),
0056 PINCTRL_PIN(10, "gpio10"),
0057 PINCTRL_PIN(11, "gpio11"),
0058 PINCTRL_PIN(12, "gpio12"),
0059 PINCTRL_PIN(13, "gpio13"),
0060 PINCTRL_PIN(14, "gpio14"),
0061 PINCTRL_PIN(15, "gpio15"),
0062 PINCTRL_PIN(16, "gpio16"),
0063 PINCTRL_PIN(17, "gpio17"),
0064 PINCTRL_PIN(18, "gpio18"),
0065 PINCTRL_PIN(19, "gpio19"),
0066 PINCTRL_PIN(20, "gpio20"),
0067 PINCTRL_PIN(21, "gpio21"),
0068 PINCTRL_PIN(22, "gpio22"),
0069 PINCTRL_PIN(23, "gpio23"),
0070 PINCTRL_PIN(24, "gpio24"),
0071 PINCTRL_PIN(25, "gpio25"),
0072 PINCTRL_PIN(26, "gpio26"),
0073 PINCTRL_PIN(27, "gpio27"),
0074 PINCTRL_PIN(28, "gpio28"),
0075 PINCTRL_PIN(29, "gpio29"),
0076 PINCTRL_PIN(30, "gpio30"),
0077 PINCTRL_PIN(31, "gpio31"),
0078 PINCTRL_PIN(32, "gpio32"),
0079 PINCTRL_PIN(33, "gpio33"),
0080 PINCTRL_PIN(34, "gpio34"),
0081 PINCTRL_PIN(35, "gpio35"),
0082 PINCTRL_PIN(36, "gpio36"),
0083 PINCTRL_PIN(37, "gpio37"),
0084 PINCTRL_PIN(38, "gpio38"),
0085 PINCTRL_PIN(39, "gpio39"),
0086 PINCTRL_PIN(40, "gpio40"),
0087 PINCTRL_PIN(41, "gpio41"),
0088 PINCTRL_PIN(42, "gpio42"),
0089 PINCTRL_PIN(43, "gpio43"),
0090 PINCTRL_PIN(44, "gpio44"),
0091 PINCTRL_PIN(45, "gpio45"),
0092 PINCTRL_PIN(46, "gpio46"),
0093 PINCTRL_PIN(47, "gpio47"),
0094 PINCTRL_PIN(48, "gpio48"),
0095 PINCTRL_PIN(49, "gpio49"),
0096 };
0097
0098 static unsigned gpio0_pins[] = { 0 };
0099 static unsigned gpio1_pins[] = { 1 };
0100 static unsigned gpio2_pins[] = { 2 };
0101 static unsigned gpio3_pins[] = { 3 };
0102 static unsigned gpio4_pins[] = { 4 };
0103 static unsigned gpio5_pins[] = { 5 };
0104 static unsigned gpio6_pins[] = { 6 };
0105 static unsigned gpio7_pins[] = { 7 };
0106 static unsigned gpio8_pins[] = { 8 };
0107 static unsigned gpio9_pins[] = { 9 };
0108 static unsigned gpio10_pins[] = { 10 };
0109 static unsigned gpio11_pins[] = { 11 };
0110 static unsigned gpio12_pins[] = { 12 };
0111 static unsigned gpio13_pins[] = { 13 };
0112 static unsigned gpio14_pins[] = { 14 };
0113 static unsigned gpio15_pins[] = { 15 };
0114 static unsigned gpio16_pins[] = { 16 };
0115 static unsigned gpio17_pins[] = { 17 };
0116 static unsigned gpio18_pins[] = { 18 };
0117 static unsigned gpio19_pins[] = { 19 };
0118 static unsigned gpio20_pins[] = { 20 };
0119 static unsigned gpio21_pins[] = { 21 };
0120 static unsigned gpio22_pins[] = { 22 };
0121 static unsigned gpio23_pins[] = { 23 };
0122 static unsigned gpio24_pins[] = { 24 };
0123 static unsigned gpio25_pins[] = { 25 };
0124 static unsigned gpio26_pins[] = { 26 };
0125 static unsigned gpio27_pins[] = { 27 };
0126 static unsigned gpio28_pins[] = { 28 };
0127 static unsigned gpio29_pins[] = { 29 };
0128 static unsigned gpio30_pins[] = { 30 };
0129 static unsigned gpio31_pins[] = { 31 };
0130 static unsigned gpio32_pins[] = { 32 };
0131 static unsigned gpio33_pins[] = { 33 };
0132 static unsigned gpio34_pins[] = { 34 };
0133 static unsigned gpio35_pins[] = { 35 };
0134 static unsigned gpio36_pins[] = { 36 };
0135 static unsigned gpio37_pins[] = { 37 };
0136 static unsigned gpio38_pins[] = { 38 };
0137 static unsigned gpio39_pins[] = { 39 };
0138 static unsigned gpio40_pins[] = { 40 };
0139 static unsigned gpio41_pins[] = { 41 };
0140 static unsigned gpio42_pins[] = { 42 };
0141 static unsigned gpio43_pins[] = { 43 };
0142 static unsigned gpio44_pins[] = { 44 };
0143 static unsigned gpio45_pins[] = { 45 };
0144 static unsigned gpio46_pins[] = { 46 };
0145 static unsigned gpio47_pins[] = { 47 };
0146 static unsigned gpio48_pins[] = { 48 };
0147 static unsigned gpio49_pins[] = { 49 };
0148
0149 #define BCM6318_GROUP(n) \
0150 { \
0151 .name = #n, \
0152 .pins = n##_pins, \
0153 .num_pins = ARRAY_SIZE(n##_pins), \
0154 }
0155
0156 static struct bcm6318_pingroup bcm6318_groups[] = {
0157 BCM6318_GROUP(gpio0),
0158 BCM6318_GROUP(gpio1),
0159 BCM6318_GROUP(gpio2),
0160 BCM6318_GROUP(gpio3),
0161 BCM6318_GROUP(gpio4),
0162 BCM6318_GROUP(gpio5),
0163 BCM6318_GROUP(gpio6),
0164 BCM6318_GROUP(gpio7),
0165 BCM6318_GROUP(gpio8),
0166 BCM6318_GROUP(gpio9),
0167 BCM6318_GROUP(gpio10),
0168 BCM6318_GROUP(gpio11),
0169 BCM6318_GROUP(gpio12),
0170 BCM6318_GROUP(gpio13),
0171 BCM6318_GROUP(gpio14),
0172 BCM6318_GROUP(gpio15),
0173 BCM6318_GROUP(gpio16),
0174 BCM6318_GROUP(gpio17),
0175 BCM6318_GROUP(gpio18),
0176 BCM6318_GROUP(gpio19),
0177 BCM6318_GROUP(gpio20),
0178 BCM6318_GROUP(gpio21),
0179 BCM6318_GROUP(gpio22),
0180 BCM6318_GROUP(gpio23),
0181 BCM6318_GROUP(gpio24),
0182 BCM6318_GROUP(gpio25),
0183 BCM6318_GROUP(gpio26),
0184 BCM6318_GROUP(gpio27),
0185 BCM6318_GROUP(gpio28),
0186 BCM6318_GROUP(gpio29),
0187 BCM6318_GROUP(gpio30),
0188 BCM6318_GROUP(gpio31),
0189 BCM6318_GROUP(gpio32),
0190 BCM6318_GROUP(gpio33),
0191 BCM6318_GROUP(gpio34),
0192 BCM6318_GROUP(gpio35),
0193 BCM6318_GROUP(gpio36),
0194 BCM6318_GROUP(gpio37),
0195 BCM6318_GROUP(gpio38),
0196 BCM6318_GROUP(gpio39),
0197 BCM6318_GROUP(gpio40),
0198 BCM6318_GROUP(gpio41),
0199 BCM6318_GROUP(gpio42),
0200 BCM6318_GROUP(gpio43),
0201 BCM6318_GROUP(gpio44),
0202 BCM6318_GROUP(gpio45),
0203 BCM6318_GROUP(gpio46),
0204 BCM6318_GROUP(gpio47),
0205 BCM6318_GROUP(gpio48),
0206 BCM6318_GROUP(gpio49),
0207 };
0208
0209
0210 static const char * const led_groups[] = {
0211 "gpio0",
0212 "gpio1",
0213 "gpio2",
0214 "gpio3",
0215 "gpio4",
0216 "gpio5",
0217 "gpio6",
0218 "gpio7",
0219 "gpio8",
0220 "gpio9",
0221 "gpio10",
0222 "gpio11",
0223 "gpio12",
0224 "gpio13",
0225 "gpio14",
0226 "gpio15",
0227 "gpio16",
0228 "gpio17",
0229 "gpio18",
0230 "gpio19",
0231 "gpio20",
0232 "gpio21",
0233 "gpio22",
0234 "gpio23",
0235 };
0236
0237
0238 static const char * const ephy0_spd_led_groups[] = {
0239 "gpio0",
0240 };
0241
0242 static const char * const ephy1_spd_led_groups[] = {
0243 "gpio1",
0244 };
0245
0246 static const char * const ephy2_spd_led_groups[] = {
0247 "gpio2",
0248 };
0249
0250 static const char * const ephy3_spd_led_groups[] = {
0251 "gpio3",
0252 };
0253
0254 static const char * const ephy0_act_led_groups[] = {
0255 "gpio4",
0256 };
0257
0258 static const char * const ephy1_act_led_groups[] = {
0259 "gpio5",
0260 };
0261
0262 static const char * const ephy2_act_led_groups[] = {
0263 "gpio6",
0264 };
0265
0266 static const char * const ephy3_act_led_groups[] = {
0267 "gpio7",
0268 };
0269
0270 static const char * const serial_led_data_groups[] = {
0271 "gpio6",
0272 };
0273
0274 static const char * const serial_led_clk_groups[] = {
0275 "gpio7",
0276 };
0277
0278 static const char * const inet_act_led_groups[] = {
0279 "gpio8",
0280 };
0281
0282 static const char * const inet_fail_led_groups[] = {
0283 "gpio9",
0284 };
0285
0286 static const char * const dsl_led_groups[] = {
0287 "gpio10",
0288 };
0289
0290 static const char * const post_fail_led_groups[] = {
0291 "gpio11",
0292 };
0293
0294 static const char * const wlan_wps_led_groups[] = {
0295 "gpio12",
0296 };
0297
0298 static const char * const usb_pwron_groups[] = {
0299 "gpio13",
0300 };
0301
0302 static const char * const usb_device_led_groups[] = {
0303 "gpio13",
0304 };
0305
0306 static const char * const usb_active_groups[] = {
0307 "gpio40",
0308 };
0309
0310 #define BCM6318_MODE_FUN(n) \
0311 { \
0312 .name = #n, \
0313 .groups = n##_groups, \
0314 .num_groups = ARRAY_SIZE(n##_groups), \
0315 .mode_val = 1, \
0316 }
0317
0318 #define BCM6318_MUX_FUN(n, mux) \
0319 { \
0320 .name = #n, \
0321 .groups = n##_groups, \
0322 .num_groups = ARRAY_SIZE(n##_groups), \
0323 .mux_val = mux, \
0324 }
0325
0326 static const struct bcm6318_function bcm6318_funcs[] = {
0327 BCM6318_MODE_FUN(led),
0328 BCM6318_MUX_FUN(ephy0_spd_led, 1),
0329 BCM6318_MUX_FUN(ephy1_spd_led, 1),
0330 BCM6318_MUX_FUN(ephy2_spd_led, 1),
0331 BCM6318_MUX_FUN(ephy3_spd_led, 1),
0332 BCM6318_MUX_FUN(ephy0_act_led, 1),
0333 BCM6318_MUX_FUN(ephy1_act_led, 1),
0334 BCM6318_MUX_FUN(ephy2_act_led, 1),
0335 BCM6318_MUX_FUN(ephy3_act_led, 1),
0336 BCM6318_MUX_FUN(serial_led_data, 3),
0337 BCM6318_MUX_FUN(serial_led_clk, 3),
0338 BCM6318_MUX_FUN(inet_act_led, 1),
0339 BCM6318_MUX_FUN(inet_fail_led, 1),
0340 BCM6318_MUX_FUN(dsl_led, 1),
0341 BCM6318_MUX_FUN(post_fail_led, 1),
0342 BCM6318_MUX_FUN(wlan_wps_led, 1),
0343 BCM6318_MUX_FUN(usb_pwron, 1),
0344 BCM6318_MUX_FUN(usb_device_led, 2),
0345 BCM6318_MUX_FUN(usb_active, 2),
0346 };
0347
0348 static inline unsigned int bcm6318_mux_off(unsigned int pin)
0349 {
0350 return BCM6318_MUX_REG + (pin / 16) * 4;
0351 }
0352
0353 static inline unsigned int bcm6318_pad_off(unsigned int pin)
0354 {
0355 return BCM6318_PAD_REG + (pin / 8) * 4;
0356 }
0357
0358 static int bcm6318_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
0359 {
0360 return ARRAY_SIZE(bcm6318_groups);
0361 }
0362
0363 static const char *bcm6318_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
0364 unsigned group)
0365 {
0366 return bcm6318_groups[group].name;
0367 }
0368
0369 static int bcm6318_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
0370 unsigned group, const unsigned **pins,
0371 unsigned *num_pins)
0372 {
0373 *pins = bcm6318_groups[group].pins;
0374 *num_pins = bcm6318_groups[group].num_pins;
0375
0376 return 0;
0377 }
0378
0379 static int bcm6318_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
0380 {
0381 return ARRAY_SIZE(bcm6318_funcs);
0382 }
0383
0384 static const char *bcm6318_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
0385 unsigned selector)
0386 {
0387 return bcm6318_funcs[selector].name;
0388 }
0389
0390 static int bcm6318_pinctrl_get_groups(struct pinctrl_dev *pctldev,
0391 unsigned selector,
0392 const char * const **groups,
0393 unsigned * const num_groups)
0394 {
0395 *groups = bcm6318_funcs[selector].groups;
0396 *num_groups = bcm6318_funcs[selector].num_groups;
0397
0398 return 0;
0399 }
0400
0401 static inline void bcm6318_rmw_mux(struct bcm63xx_pinctrl *pc, unsigned pin,
0402 unsigned int mode, unsigned int mux)
0403 {
0404 if (pin < BCM63XX_BANK_GPIOS)
0405 regmap_update_bits(pc->regs, BCM6318_MODE_REG, BIT(pin),
0406 mode ? BIT(pin) : 0);
0407
0408 if (pin < BCM6318_NUM_MUX)
0409 regmap_update_bits(pc->regs,
0410 bcm6318_mux_off(pin),
0411 BCM6328_MUX_MASK << ((pin % 16) * 2),
0412 mux << ((pin % 16) * 2));
0413 }
0414
0415 static inline void bcm6318_set_pad(struct bcm63xx_pinctrl *pc, unsigned pin,
0416 uint8_t val)
0417 {
0418 regmap_update_bits(pc->regs, bcm6318_pad_off(pin),
0419 BCM6328_PAD_MASK << ((pin % 8) * 4),
0420 val << ((pin % 8) * 4));
0421 }
0422
0423 static int bcm6318_pinctrl_set_mux(struct pinctrl_dev *pctldev,
0424 unsigned selector, unsigned group)
0425 {
0426 struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
0427 const struct bcm6318_pingroup *pg = &bcm6318_groups[group];
0428 const struct bcm6318_function *f = &bcm6318_funcs[selector];
0429
0430 bcm6318_rmw_mux(pc, pg->pins[0], f->mode_val, f->mux_val);
0431
0432 return 0;
0433 }
0434
0435 static int bcm6318_gpio_request_enable(struct pinctrl_dev *pctldev,
0436 struct pinctrl_gpio_range *range,
0437 unsigned offset)
0438 {
0439 struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
0440
0441
0442 if (offset < 13) {
0443
0444 bcm6318_rmw_mux(pc, offset, 0, 0);
0445 } else if (offset < 42) {
0446
0447 bcm6318_rmw_mux(pc, offset, 0, 3);
0448
0449 bcm6318_set_pad(pc, offset, 0);
0450 }
0451
0452 return 0;
0453 }
0454
0455 static const struct pinctrl_ops bcm6318_pctl_ops = {
0456 .dt_free_map = pinctrl_utils_free_map,
0457 .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
0458 .get_group_name = bcm6318_pinctrl_get_group_name,
0459 .get_group_pins = bcm6318_pinctrl_get_group_pins,
0460 .get_groups_count = bcm6318_pinctrl_get_group_count,
0461 };
0462
0463 static const struct pinmux_ops bcm6318_pmx_ops = {
0464 .get_function_groups = bcm6318_pinctrl_get_groups,
0465 .get_function_name = bcm6318_pinctrl_get_func_name,
0466 .get_functions_count = bcm6318_pinctrl_get_func_count,
0467 .gpio_request_enable = bcm6318_gpio_request_enable,
0468 .set_mux = bcm6318_pinctrl_set_mux,
0469 .strict = true,
0470 };
0471
0472 static const struct bcm63xx_pinctrl_soc bcm6318_soc = {
0473 .ngpios = BCM6318_NUM_GPIOS,
0474 .npins = ARRAY_SIZE(bcm6318_pins),
0475 .pctl_ops = &bcm6318_pctl_ops,
0476 .pins = bcm6318_pins,
0477 .pmx_ops = &bcm6318_pmx_ops,
0478 };
0479
0480 static int bcm6318_pinctrl_probe(struct platform_device *pdev)
0481 {
0482 return bcm63xx_pinctrl_probe(pdev, &bcm6318_soc, NULL);
0483 }
0484
0485 static const struct of_device_id bcm6318_pinctrl_match[] = {
0486 { .compatible = "brcm,bcm6318-pinctrl", },
0487 { }
0488 };
0489
0490 static struct platform_driver bcm6318_pinctrl_driver = {
0491 .probe = bcm6318_pinctrl_probe,
0492 .driver = {
0493 .name = "bcm6318-pinctrl",
0494 .of_match_table = bcm6318_pinctrl_match,
0495 },
0496 };
0497
0498 builtin_platform_driver(bcm6318_pinctrl_driver);