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