Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Driver for BCM6318 GPIO unit (pinctrl + GPIO)
0004  *
0005  * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
0006  * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
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 /* GPIO_MODE */
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 /* PINMUX_SEL */
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     /* disable all functions using this pin */
0442     if (offset < 13) {
0443         /* GPIOs 0-12 use mux 0 as GPIO function */
0444         bcm6318_rmw_mux(pc, offset, 0, 0);
0445     } else if (offset < 42) {
0446         /* GPIOs 13-41 use mux 3 as GPIO function */
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     { /* sentinel */ }
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);