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 BCM6362_BANK_GPIOS 32
0022 #define BCM6362_NUM_GPIOS 48
0023 #define BCM6362_NUM_LEDS 24
0024
0025 #define BCM6362_LED_REG 0x10
0026 #define BCM6362_MODE_REG 0x18
0027 #define BCM6362_CTRL_REG 0x1c
0028 #define BCM6362_BASEMODE_REG 0x38
0029 #define BASEMODE_NAND BIT(2)
0030
0031 enum bcm6362_pinctrl_reg {
0032 BCM6362_LEDCTRL,
0033 BCM6362_MODE,
0034 BCM6362_CTRL,
0035 BCM6362_BASEMODE,
0036 };
0037
0038 struct bcm6362_pingroup {
0039 const char *name;
0040 const unsigned * const pins;
0041 const unsigned num_pins;
0042 };
0043
0044 struct bcm6362_function {
0045 const char *name;
0046 const char * const *groups;
0047 const unsigned num_groups;
0048
0049 enum bcm6362_pinctrl_reg reg;
0050 uint32_t basemode_mask;
0051 };
0052
0053 #define BCM6362_PIN(a, b, mask) \
0054 { \
0055 .number = a, \
0056 .name = b, \
0057 .drv_data = (void *)(mask), \
0058 }
0059
0060 static const struct pinctrl_pin_desc bcm6362_pins[] = {
0061 PINCTRL_PIN(0, "gpio0"),
0062 PINCTRL_PIN(1, "gpio1"),
0063 PINCTRL_PIN(2, "gpio2"),
0064 PINCTRL_PIN(3, "gpio3"),
0065 PINCTRL_PIN(4, "gpio4"),
0066 PINCTRL_PIN(5, "gpio5"),
0067 PINCTRL_PIN(6, "gpio6"),
0068 PINCTRL_PIN(7, "gpio7"),
0069 BCM6362_PIN(8, "gpio8", BASEMODE_NAND),
0070 PINCTRL_PIN(9, "gpio9"),
0071 PINCTRL_PIN(10, "gpio10"),
0072 PINCTRL_PIN(11, "gpio11"),
0073 BCM6362_PIN(12, "gpio12", BASEMODE_NAND),
0074 BCM6362_PIN(13, "gpio13", BASEMODE_NAND),
0075 BCM6362_PIN(14, "gpio14", BASEMODE_NAND),
0076 BCM6362_PIN(15, "gpio15", BASEMODE_NAND),
0077 BCM6362_PIN(16, "gpio16", BASEMODE_NAND),
0078 BCM6362_PIN(17, "gpio17", BASEMODE_NAND),
0079 BCM6362_PIN(18, "gpio18", BASEMODE_NAND),
0080 BCM6362_PIN(19, "gpio19", BASEMODE_NAND),
0081 BCM6362_PIN(20, "gpio20", BASEMODE_NAND),
0082 BCM6362_PIN(21, "gpio21", BASEMODE_NAND),
0083 BCM6362_PIN(22, "gpio22", BASEMODE_NAND),
0084 BCM6362_PIN(23, "gpio23", BASEMODE_NAND),
0085 PINCTRL_PIN(24, "gpio24"),
0086 PINCTRL_PIN(25, "gpio25"),
0087 PINCTRL_PIN(26, "gpio26"),
0088 BCM6362_PIN(27, "gpio27", BASEMODE_NAND),
0089 PINCTRL_PIN(28, "gpio28"),
0090 PINCTRL_PIN(29, "gpio29"),
0091 PINCTRL_PIN(30, "gpio30"),
0092 PINCTRL_PIN(31, "gpio31"),
0093 PINCTRL_PIN(32, "gpio32"),
0094 PINCTRL_PIN(33, "gpio33"),
0095 PINCTRL_PIN(34, "gpio34"),
0096 PINCTRL_PIN(35, "gpio35"),
0097 PINCTRL_PIN(36, "gpio36"),
0098 PINCTRL_PIN(37, "gpio37"),
0099 PINCTRL_PIN(38, "gpio38"),
0100 PINCTRL_PIN(39, "gpio39"),
0101 PINCTRL_PIN(40, "gpio40"),
0102 PINCTRL_PIN(41, "gpio41"),
0103 PINCTRL_PIN(42, "gpio42"),
0104 PINCTRL_PIN(43, "gpio43"),
0105 PINCTRL_PIN(44, "gpio44"),
0106 PINCTRL_PIN(45, "gpio45"),
0107 PINCTRL_PIN(46, "gpio46"),
0108 PINCTRL_PIN(47, "gpio47"),
0109 };
0110
0111 static unsigned gpio0_pins[] = { 0 };
0112 static unsigned gpio1_pins[] = { 1 };
0113 static unsigned gpio2_pins[] = { 2 };
0114 static unsigned gpio3_pins[] = { 3 };
0115 static unsigned gpio4_pins[] = { 4 };
0116 static unsigned gpio5_pins[] = { 5 };
0117 static unsigned gpio6_pins[] = { 6 };
0118 static unsigned gpio7_pins[] = { 7 };
0119 static unsigned gpio8_pins[] = { 8 };
0120 static unsigned gpio9_pins[] = { 9 };
0121 static unsigned gpio10_pins[] = { 10 };
0122 static unsigned gpio11_pins[] = { 11 };
0123 static unsigned gpio12_pins[] = { 12 };
0124 static unsigned gpio13_pins[] = { 13 };
0125 static unsigned gpio14_pins[] = { 14 };
0126 static unsigned gpio15_pins[] = { 15 };
0127 static unsigned gpio16_pins[] = { 16 };
0128 static unsigned gpio17_pins[] = { 17 };
0129 static unsigned gpio18_pins[] = { 18 };
0130 static unsigned gpio19_pins[] = { 19 };
0131 static unsigned gpio20_pins[] = { 20 };
0132 static unsigned gpio21_pins[] = { 21 };
0133 static unsigned gpio22_pins[] = { 22 };
0134 static unsigned gpio23_pins[] = { 23 };
0135 static unsigned gpio24_pins[] = { 24 };
0136 static unsigned gpio25_pins[] = { 25 };
0137 static unsigned gpio26_pins[] = { 26 };
0138 static unsigned gpio27_pins[] = { 27 };
0139 static unsigned gpio28_pins[] = { 28 };
0140 static unsigned gpio29_pins[] = { 29 };
0141 static unsigned gpio30_pins[] = { 30 };
0142 static unsigned gpio31_pins[] = { 31 };
0143 static unsigned gpio32_pins[] = { 32 };
0144 static unsigned gpio33_pins[] = { 33 };
0145 static unsigned gpio34_pins[] = { 34 };
0146 static unsigned gpio35_pins[] = { 35 };
0147 static unsigned gpio36_pins[] = { 36 };
0148 static unsigned gpio37_pins[] = { 37 };
0149 static unsigned gpio38_pins[] = { 38 };
0150 static unsigned gpio39_pins[] = { 39 };
0151 static unsigned gpio40_pins[] = { 40 };
0152 static unsigned gpio41_pins[] = { 41 };
0153 static unsigned gpio42_pins[] = { 42 };
0154 static unsigned gpio43_pins[] = { 43 };
0155 static unsigned gpio44_pins[] = { 44 };
0156 static unsigned gpio45_pins[] = { 45 };
0157 static unsigned gpio46_pins[] = { 46 };
0158 static unsigned gpio47_pins[] = { 47 };
0159
0160 static unsigned nand_grp_pins[] = {
0161 8, 12, 13, 14, 15, 16, 17,
0162 18, 19, 20, 21, 22, 23, 27,
0163 };
0164
0165 #define BCM6362_GROUP(n) \
0166 { \
0167 .name = #n, \
0168 .pins = n##_pins, \
0169 .num_pins = ARRAY_SIZE(n##_pins), \
0170 }
0171
0172 static struct bcm6362_pingroup bcm6362_groups[] = {
0173 BCM6362_GROUP(gpio0),
0174 BCM6362_GROUP(gpio1),
0175 BCM6362_GROUP(gpio2),
0176 BCM6362_GROUP(gpio3),
0177 BCM6362_GROUP(gpio4),
0178 BCM6362_GROUP(gpio5),
0179 BCM6362_GROUP(gpio6),
0180 BCM6362_GROUP(gpio7),
0181 BCM6362_GROUP(gpio8),
0182 BCM6362_GROUP(gpio9),
0183 BCM6362_GROUP(gpio10),
0184 BCM6362_GROUP(gpio11),
0185 BCM6362_GROUP(gpio12),
0186 BCM6362_GROUP(gpio13),
0187 BCM6362_GROUP(gpio14),
0188 BCM6362_GROUP(gpio15),
0189 BCM6362_GROUP(gpio16),
0190 BCM6362_GROUP(gpio17),
0191 BCM6362_GROUP(gpio18),
0192 BCM6362_GROUP(gpio19),
0193 BCM6362_GROUP(gpio20),
0194 BCM6362_GROUP(gpio21),
0195 BCM6362_GROUP(gpio22),
0196 BCM6362_GROUP(gpio23),
0197 BCM6362_GROUP(gpio24),
0198 BCM6362_GROUP(gpio25),
0199 BCM6362_GROUP(gpio26),
0200 BCM6362_GROUP(gpio27),
0201 BCM6362_GROUP(gpio28),
0202 BCM6362_GROUP(gpio29),
0203 BCM6362_GROUP(gpio30),
0204 BCM6362_GROUP(gpio31),
0205 BCM6362_GROUP(gpio32),
0206 BCM6362_GROUP(gpio33),
0207 BCM6362_GROUP(gpio34),
0208 BCM6362_GROUP(gpio35),
0209 BCM6362_GROUP(gpio36),
0210 BCM6362_GROUP(gpio37),
0211 BCM6362_GROUP(gpio38),
0212 BCM6362_GROUP(gpio39),
0213 BCM6362_GROUP(gpio40),
0214 BCM6362_GROUP(gpio41),
0215 BCM6362_GROUP(gpio42),
0216 BCM6362_GROUP(gpio43),
0217 BCM6362_GROUP(gpio44),
0218 BCM6362_GROUP(gpio45),
0219 BCM6362_GROUP(gpio46),
0220 BCM6362_GROUP(gpio47),
0221 BCM6362_GROUP(nand_grp),
0222 };
0223
0224 static const char * const led_groups[] = {
0225 "gpio0",
0226 "gpio1",
0227 "gpio2",
0228 "gpio3",
0229 "gpio4",
0230 "gpio5",
0231 "gpio6",
0232 "gpio7",
0233 "gpio8",
0234 "gpio9",
0235 "gpio10",
0236 "gpio11",
0237 "gpio12",
0238 "gpio13",
0239 "gpio14",
0240 "gpio15",
0241 "gpio16",
0242 "gpio17",
0243 "gpio18",
0244 "gpio19",
0245 "gpio20",
0246 "gpio21",
0247 "gpio22",
0248 "gpio23",
0249 };
0250
0251 static const char * const usb_device_led_groups[] = {
0252 "gpio0",
0253 };
0254
0255 static const char * const sys_irq_groups[] = {
0256 "gpio1",
0257 };
0258
0259 static const char * const serial_led_clk_groups[] = {
0260 "gpio2",
0261 };
0262
0263 static const char * const serial_led_data_groups[] = {
0264 "gpio3",
0265 };
0266
0267 static const char * const robosw_led_data_groups[] = {
0268 "gpio4",
0269 };
0270
0271 static const char * const robosw_led_clk_groups[] = {
0272 "gpio5",
0273 };
0274
0275 static const char * const robosw_led0_groups[] = {
0276 "gpio6",
0277 };
0278
0279 static const char * const robosw_led1_groups[] = {
0280 "gpio7",
0281 };
0282
0283 static const char * const inet_led_groups[] = {
0284 "gpio8",
0285 };
0286
0287 static const char * const spi_cs2_groups[] = {
0288 "gpio9",
0289 };
0290
0291 static const char * const spi_cs3_groups[] = {
0292 "gpio10",
0293 };
0294
0295 static const char * const ntr_pulse_groups[] = {
0296 "gpio11",
0297 };
0298
0299 static const char * const uart1_scts_groups[] = {
0300 "gpio12",
0301 };
0302
0303 static const char * const uart1_srts_groups[] = {
0304 "gpio13",
0305 };
0306
0307 static const char * const uart1_sdin_groups[] = {
0308 "gpio14",
0309 };
0310
0311 static const char * const uart1_sdout_groups[] = {
0312 "gpio15",
0313 };
0314
0315 static const char * const adsl_spi_miso_groups[] = {
0316 "gpio16",
0317 };
0318
0319 static const char * const adsl_spi_mosi_groups[] = {
0320 "gpio17",
0321 };
0322
0323 static const char * const adsl_spi_clk_groups[] = {
0324 "gpio18",
0325 };
0326
0327 static const char * const adsl_spi_cs_groups[] = {
0328 "gpio19",
0329 };
0330
0331 static const char * const ephy0_led_groups[] = {
0332 "gpio20",
0333 };
0334
0335 static const char * const ephy1_led_groups[] = {
0336 "gpio21",
0337 };
0338
0339 static const char * const ephy2_led_groups[] = {
0340 "gpio22",
0341 };
0342
0343 static const char * const ephy3_led_groups[] = {
0344 "gpio23",
0345 };
0346
0347 static const char * const ext_irq0_groups[] = {
0348 "gpio24",
0349 };
0350
0351 static const char * const ext_irq1_groups[] = {
0352 "gpio25",
0353 };
0354
0355 static const char * const ext_irq2_groups[] = {
0356 "gpio26",
0357 };
0358
0359 static const char * const ext_irq3_groups[] = {
0360 "gpio27",
0361 };
0362
0363 static const char * const wifi_groups[] = {
0364 "gpio32",
0365 "gpio33",
0366 "gpio34",
0367 "gpio35",
0368 "gpio36",
0369 "gpio37",
0370 "gpio38",
0371 "gpio39",
0372 "gpio40",
0373 "gpio41",
0374 "gpio42",
0375 "gpio43",
0376 "gpio44",
0377 "gpio45",
0378 "gpio46",
0379 "gpio47",
0380 };
0381
0382 static const char * const nand_groups[] = {
0383 "nand_grp",
0384 };
0385
0386 #define BCM6362_LED_FUN(n) \
0387 { \
0388 .name = #n, \
0389 .groups = n##_groups, \
0390 .num_groups = ARRAY_SIZE(n##_groups), \
0391 .reg = BCM6362_LEDCTRL, \
0392 }
0393
0394 #define BCM6362_MODE_FUN(n) \
0395 { \
0396 .name = #n, \
0397 .groups = n##_groups, \
0398 .num_groups = ARRAY_SIZE(n##_groups), \
0399 .reg = BCM6362_MODE, \
0400 }
0401
0402 #define BCM6362_CTRL_FUN(n) \
0403 { \
0404 .name = #n, \
0405 .groups = n##_groups, \
0406 .num_groups = ARRAY_SIZE(n##_groups), \
0407 .reg = BCM6362_CTRL, \
0408 }
0409
0410 #define BCM6362_BASEMODE_FUN(n, mask) \
0411 { \
0412 .name = #n, \
0413 .groups = n##_groups, \
0414 .num_groups = ARRAY_SIZE(n##_groups), \
0415 .reg = BCM6362_BASEMODE, \
0416 .basemode_mask = (mask), \
0417 }
0418
0419 static const struct bcm6362_function bcm6362_funcs[] = {
0420 BCM6362_LED_FUN(led),
0421 BCM6362_MODE_FUN(usb_device_led),
0422 BCM6362_MODE_FUN(sys_irq),
0423 BCM6362_MODE_FUN(serial_led_clk),
0424 BCM6362_MODE_FUN(serial_led_data),
0425 BCM6362_MODE_FUN(robosw_led_data),
0426 BCM6362_MODE_FUN(robosw_led_clk),
0427 BCM6362_MODE_FUN(robosw_led0),
0428 BCM6362_MODE_FUN(robosw_led1),
0429 BCM6362_MODE_FUN(inet_led),
0430 BCM6362_MODE_FUN(spi_cs2),
0431 BCM6362_MODE_FUN(spi_cs3),
0432 BCM6362_MODE_FUN(ntr_pulse),
0433 BCM6362_MODE_FUN(uart1_scts),
0434 BCM6362_MODE_FUN(uart1_srts),
0435 BCM6362_MODE_FUN(uart1_sdin),
0436 BCM6362_MODE_FUN(uart1_sdout),
0437 BCM6362_MODE_FUN(adsl_spi_miso),
0438 BCM6362_MODE_FUN(adsl_spi_mosi),
0439 BCM6362_MODE_FUN(adsl_spi_clk),
0440 BCM6362_MODE_FUN(adsl_spi_cs),
0441 BCM6362_MODE_FUN(ephy0_led),
0442 BCM6362_MODE_FUN(ephy1_led),
0443 BCM6362_MODE_FUN(ephy2_led),
0444 BCM6362_MODE_FUN(ephy3_led),
0445 BCM6362_MODE_FUN(ext_irq0),
0446 BCM6362_MODE_FUN(ext_irq1),
0447 BCM6362_MODE_FUN(ext_irq2),
0448 BCM6362_MODE_FUN(ext_irq3),
0449 BCM6362_CTRL_FUN(wifi),
0450 BCM6362_BASEMODE_FUN(nand, BASEMODE_NAND),
0451 };
0452
0453 static int bcm6362_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
0454 {
0455 return ARRAY_SIZE(bcm6362_groups);
0456 }
0457
0458 static const char *bcm6362_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
0459 unsigned group)
0460 {
0461 return bcm6362_groups[group].name;
0462 }
0463
0464 static int bcm6362_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
0465 unsigned group, const unsigned **pins,
0466 unsigned *num_pins)
0467 {
0468 *pins = bcm6362_groups[group].pins;
0469 *num_pins = bcm6362_groups[group].num_pins;
0470
0471 return 0;
0472 }
0473
0474 static int bcm6362_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
0475 {
0476 return ARRAY_SIZE(bcm6362_funcs);
0477 }
0478
0479 static const char *bcm6362_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
0480 unsigned selector)
0481 {
0482 return bcm6362_funcs[selector].name;
0483 }
0484
0485 static int bcm6362_pinctrl_get_groups(struct pinctrl_dev *pctldev,
0486 unsigned selector,
0487 const char * const **groups,
0488 unsigned * const num_groups)
0489 {
0490 *groups = bcm6362_funcs[selector].groups;
0491 *num_groups = bcm6362_funcs[selector].num_groups;
0492
0493 return 0;
0494 }
0495
0496 static void bcm6362_set_gpio(struct bcm63xx_pinctrl *pc, unsigned pin)
0497 {
0498 const struct pinctrl_pin_desc *desc = &bcm6362_pins[pin];
0499 unsigned int basemode = (uintptr_t)desc->drv_data;
0500 unsigned int mask = bcm63xx_bank_pin(pin);
0501
0502 if (basemode)
0503 regmap_update_bits(pc->regs, BCM6362_BASEMODE_REG, basemode, 0);
0504
0505 if (pin < BCM63XX_BANK_GPIOS) {
0506
0507 regmap_update_bits(pc->regs, BCM6362_MODE_REG, mask, 0);
0508
0509
0510 if (pin < BCM6362_NUM_LEDS)
0511 regmap_update_bits(pc->regs, BCM6362_LED_REG, mask, 0);
0512 } else {
0513
0514 regmap_update_bits(pc->regs, BCM6362_CTRL_REG, mask, mask);
0515 }
0516 }
0517
0518 static int bcm6362_pinctrl_set_mux(struct pinctrl_dev *pctldev,
0519 unsigned selector, unsigned group)
0520 {
0521 struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
0522 const struct bcm6362_pingroup *pg = &bcm6362_groups[group];
0523 const struct bcm6362_function *f = &bcm6362_funcs[selector];
0524 unsigned i;
0525 unsigned int reg;
0526 unsigned int val, mask;
0527
0528 for (i = 0; i < pg->num_pins; i++)
0529 bcm6362_set_gpio(pc, pg->pins[i]);
0530
0531 switch (f->reg) {
0532 case BCM6362_LEDCTRL:
0533 reg = BCM6362_LED_REG;
0534 mask = BIT(pg->pins[0]);
0535 val = BIT(pg->pins[0]);
0536 break;
0537 case BCM6362_MODE:
0538 reg = BCM6362_MODE_REG;
0539 mask = BIT(pg->pins[0]);
0540 val = BIT(pg->pins[0]);
0541 break;
0542 case BCM6362_CTRL:
0543 reg = BCM6362_CTRL_REG;
0544 mask = BIT(pg->pins[0]);
0545 val = 0;
0546 break;
0547 case BCM6362_BASEMODE:
0548 reg = BCM6362_BASEMODE_REG;
0549 mask = f->basemode_mask;
0550 val = f->basemode_mask;
0551 break;
0552 default:
0553 WARN_ON(1);
0554 return -EINVAL;
0555 }
0556
0557 regmap_update_bits(pc->regs, reg, mask, val);
0558
0559 return 0;
0560 }
0561
0562 static int bcm6362_gpio_request_enable(struct pinctrl_dev *pctldev,
0563 struct pinctrl_gpio_range *range,
0564 unsigned offset)
0565 {
0566 struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
0567
0568
0569 bcm6362_set_gpio(pc, offset);
0570
0571 return 0;
0572 }
0573
0574 static const struct pinctrl_ops bcm6362_pctl_ops = {
0575 .dt_free_map = pinctrl_utils_free_map,
0576 .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
0577 .get_group_name = bcm6362_pinctrl_get_group_name,
0578 .get_group_pins = bcm6362_pinctrl_get_group_pins,
0579 .get_groups_count = bcm6362_pinctrl_get_group_count,
0580 };
0581
0582 static const struct pinmux_ops bcm6362_pmx_ops = {
0583 .get_function_groups = bcm6362_pinctrl_get_groups,
0584 .get_function_name = bcm6362_pinctrl_get_func_name,
0585 .get_functions_count = bcm6362_pinctrl_get_func_count,
0586 .gpio_request_enable = bcm6362_gpio_request_enable,
0587 .set_mux = bcm6362_pinctrl_set_mux,
0588 .strict = true,
0589 };
0590
0591 static const struct bcm63xx_pinctrl_soc bcm6362_soc = {
0592 .ngpios = BCM6362_NUM_GPIOS,
0593 .npins = ARRAY_SIZE(bcm6362_pins),
0594 .pctl_ops = &bcm6362_pctl_ops,
0595 .pins = bcm6362_pins,
0596 .pmx_ops = &bcm6362_pmx_ops,
0597 };
0598
0599 static int bcm6362_pinctrl_probe(struct platform_device *pdev)
0600 {
0601 return bcm63xx_pinctrl_probe(pdev, &bcm6362_soc, NULL);
0602 }
0603
0604 static const struct of_device_id bcm6362_pinctrl_match[] = {
0605 { .compatible = "brcm,bcm6362-pinctrl", },
0606 { }
0607 };
0608
0609 static struct platform_driver bcm6362_pinctrl_driver = {
0610 .probe = bcm6362_pinctrl_probe,
0611 .driver = {
0612 .name = "bcm6362-pinctrl",
0613 .of_match_table = bcm6362_pinctrl_match,
0614 },
0615 };
0616
0617 builtin_platform_driver(bcm6362_pinctrl_driver);