Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Driver for BCM6328 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 BCM6328_NUM_GPIOS   32
0022 
0023 #define BCM6328_MODE_REG    0x18
0024 #define BCM6328_MUX_HI_REG  0x1c
0025 #define BCM6328_MUX_LO_REG  0x20
0026 #define BCM6328_MUX_OTHER_REG   0x24
0027 #define  BCM6328_MUX_MASK   GENMASK(1, 0)
0028 
0029 struct bcm6328_pingroup {
0030     const char *name;
0031     const unsigned * const pins;
0032     const unsigned num_pins;
0033 };
0034 
0035 struct bcm6328_function {
0036     const char *name;
0037     const char * const *groups;
0038     const unsigned num_groups;
0039 
0040     unsigned mode_val:1;
0041     unsigned mux_val:2;
0042 };
0043 
0044 static const unsigned int bcm6328_mux[] = {
0045     BCM6328_MUX_LO_REG,
0046     BCM6328_MUX_HI_REG,
0047     BCM6328_MUX_OTHER_REG
0048 };
0049 
0050 static const struct pinctrl_pin_desc bcm6328_pins[] = {
0051     PINCTRL_PIN(0, "gpio0"),
0052     PINCTRL_PIN(1, "gpio1"),
0053     PINCTRL_PIN(2, "gpio2"),
0054     PINCTRL_PIN(3, "gpio3"),
0055     PINCTRL_PIN(4, "gpio4"),
0056     PINCTRL_PIN(5, "gpio5"),
0057     PINCTRL_PIN(6, "gpio6"),
0058     PINCTRL_PIN(7, "gpio7"),
0059     PINCTRL_PIN(8, "gpio8"),
0060     PINCTRL_PIN(9, "gpio9"),
0061     PINCTRL_PIN(10, "gpio10"),
0062     PINCTRL_PIN(11, "gpio11"),
0063     PINCTRL_PIN(12, "gpio12"),
0064     PINCTRL_PIN(13, "gpio13"),
0065     PINCTRL_PIN(14, "gpio14"),
0066     PINCTRL_PIN(15, "gpio15"),
0067     PINCTRL_PIN(16, "gpio16"),
0068     PINCTRL_PIN(17, "gpio17"),
0069     PINCTRL_PIN(18, "gpio18"),
0070     PINCTRL_PIN(19, "gpio19"),
0071     PINCTRL_PIN(20, "gpio20"),
0072     PINCTRL_PIN(21, "gpio21"),
0073     PINCTRL_PIN(22, "gpio22"),
0074     PINCTRL_PIN(23, "gpio23"),
0075     PINCTRL_PIN(24, "gpio24"),
0076     PINCTRL_PIN(25, "gpio25"),
0077     PINCTRL_PIN(26, "gpio26"),
0078     PINCTRL_PIN(27, "gpio27"),
0079     PINCTRL_PIN(28, "gpio28"),
0080     PINCTRL_PIN(29, "gpio29"),
0081     PINCTRL_PIN(30, "gpio30"),
0082     PINCTRL_PIN(31, "gpio31"),
0083 
0084     /*
0085      * No idea where they really are; so let's put them according
0086      * to their mux offsets.
0087      */
0088     PINCTRL_PIN(36, "hsspi_cs1"),
0089     PINCTRL_PIN(38, "usb_p2"),
0090 };
0091 
0092 static unsigned gpio0_pins[] = { 0 };
0093 static unsigned gpio1_pins[] = { 1 };
0094 static unsigned gpio2_pins[] = { 2 };
0095 static unsigned gpio3_pins[] = { 3 };
0096 static unsigned gpio4_pins[] = { 4 };
0097 static unsigned gpio5_pins[] = { 5 };
0098 static unsigned gpio6_pins[] = { 6 };
0099 static unsigned gpio7_pins[] = { 7 };
0100 static unsigned gpio8_pins[] = { 8 };
0101 static unsigned gpio9_pins[] = { 9 };
0102 static unsigned gpio10_pins[] = { 10 };
0103 static unsigned gpio11_pins[] = { 11 };
0104 static unsigned gpio12_pins[] = { 12 };
0105 static unsigned gpio13_pins[] = { 13 };
0106 static unsigned gpio14_pins[] = { 14 };
0107 static unsigned gpio15_pins[] = { 15 };
0108 static unsigned gpio16_pins[] = { 16 };
0109 static unsigned gpio17_pins[] = { 17 };
0110 static unsigned gpio18_pins[] = { 18 };
0111 static unsigned gpio19_pins[] = { 19 };
0112 static unsigned gpio20_pins[] = { 20 };
0113 static unsigned gpio21_pins[] = { 21 };
0114 static unsigned gpio22_pins[] = { 22 };
0115 static unsigned gpio23_pins[] = { 23 };
0116 static unsigned gpio24_pins[] = { 24 };
0117 static unsigned gpio25_pins[] = { 25 };
0118 static unsigned gpio26_pins[] = { 26 };
0119 static unsigned gpio27_pins[] = { 27 };
0120 static unsigned gpio28_pins[] = { 28 };
0121 static unsigned gpio29_pins[] = { 29 };
0122 static unsigned gpio30_pins[] = { 30 };
0123 static unsigned gpio31_pins[] = { 31 };
0124 
0125 static unsigned hsspi_cs1_pins[] = { 36 };
0126 static unsigned usb_port1_pins[] = { 38 };
0127 
0128 #define BCM6328_GROUP(n)                    \
0129     {                           \
0130         .name = #n,                 \
0131         .pins = n##_pins,               \
0132         .num_pins = ARRAY_SIZE(n##_pins),       \
0133     }
0134 
0135 static struct bcm6328_pingroup bcm6328_groups[] = {
0136     BCM6328_GROUP(gpio0),
0137     BCM6328_GROUP(gpio1),
0138     BCM6328_GROUP(gpio2),
0139     BCM6328_GROUP(gpio3),
0140     BCM6328_GROUP(gpio4),
0141     BCM6328_GROUP(gpio5),
0142     BCM6328_GROUP(gpio6),
0143     BCM6328_GROUP(gpio7),
0144     BCM6328_GROUP(gpio8),
0145     BCM6328_GROUP(gpio9),
0146     BCM6328_GROUP(gpio10),
0147     BCM6328_GROUP(gpio11),
0148     BCM6328_GROUP(gpio12),
0149     BCM6328_GROUP(gpio13),
0150     BCM6328_GROUP(gpio14),
0151     BCM6328_GROUP(gpio15),
0152     BCM6328_GROUP(gpio16),
0153     BCM6328_GROUP(gpio17),
0154     BCM6328_GROUP(gpio18),
0155     BCM6328_GROUP(gpio19),
0156     BCM6328_GROUP(gpio20),
0157     BCM6328_GROUP(gpio21),
0158     BCM6328_GROUP(gpio22),
0159     BCM6328_GROUP(gpio23),
0160     BCM6328_GROUP(gpio24),
0161     BCM6328_GROUP(gpio25),
0162     BCM6328_GROUP(gpio26),
0163     BCM6328_GROUP(gpio27),
0164     BCM6328_GROUP(gpio28),
0165     BCM6328_GROUP(gpio29),
0166     BCM6328_GROUP(gpio30),
0167     BCM6328_GROUP(gpio31),
0168 
0169     BCM6328_GROUP(hsspi_cs1),
0170     BCM6328_GROUP(usb_port1),
0171 };
0172 
0173 /* GPIO_MODE */
0174 static const char * const led_groups[] = {
0175     "gpio0",
0176     "gpio1",
0177     "gpio2",
0178     "gpio3",
0179     "gpio4",
0180     "gpio5",
0181     "gpio6",
0182     "gpio7",
0183     "gpio8",
0184     "gpio9",
0185     "gpio10",
0186     "gpio11",
0187     "gpio12",
0188     "gpio13",
0189     "gpio14",
0190     "gpio15",
0191     "gpio16",
0192     "gpio17",
0193     "gpio18",
0194     "gpio19",
0195     "gpio20",
0196     "gpio21",
0197     "gpio22",
0198     "gpio23",
0199 };
0200 
0201 /* PINMUX_SEL */
0202 static const char * const serial_led_data_groups[] = {
0203     "gpio6",
0204 };
0205 
0206 static const char * const serial_led_clk_groups[] = {
0207     "gpio7",
0208 };
0209 
0210 static const char * const inet_act_led_groups[] = {
0211     "gpio11",
0212 };
0213 
0214 static const char * const pcie_clkreq_groups[] = {
0215     "gpio16",
0216 };
0217 
0218 static const char * const ephy0_act_led_groups[] = {
0219     "gpio25",
0220 };
0221 
0222 static const char * const ephy1_act_led_groups[] = {
0223     "gpio26",
0224 };
0225 
0226 static const char * const ephy2_act_led_groups[] = {
0227     "gpio27",
0228 };
0229 
0230 static const char * const ephy3_act_led_groups[] = {
0231     "gpio28",
0232 };
0233 
0234 static const char * const hsspi_cs1_groups[] = {
0235     "hsspi_cs1"
0236 };
0237 
0238 static const char * const usb_host_port_groups[] = {
0239     "usb_port1",
0240 };
0241 
0242 static const char * const usb_device_port_groups[] = {
0243     "usb_port1",
0244 };
0245 
0246 #define BCM6328_MODE_FUN(n)             \
0247     {                       \
0248         .name = #n,             \
0249         .groups = n##_groups,           \
0250         .num_groups = ARRAY_SIZE(n##_groups),   \
0251         .mode_val = 1,              \
0252     }
0253 
0254 #define BCM6328_MUX_FUN(n, mux)             \
0255     {                       \
0256         .name = #n,             \
0257         .groups = n##_groups,           \
0258         .num_groups = ARRAY_SIZE(n##_groups),   \
0259         .mux_val = mux,             \
0260     }
0261 
0262 static const struct bcm6328_function bcm6328_funcs[] = {
0263     BCM6328_MODE_FUN(led),
0264     BCM6328_MUX_FUN(serial_led_data, 2),
0265     BCM6328_MUX_FUN(serial_led_clk, 2),
0266     BCM6328_MUX_FUN(inet_act_led, 1),
0267     BCM6328_MUX_FUN(pcie_clkreq, 2),
0268     BCM6328_MUX_FUN(ephy0_act_led, 1),
0269     BCM6328_MUX_FUN(ephy1_act_led, 1),
0270     BCM6328_MUX_FUN(ephy2_act_led, 1),
0271     BCM6328_MUX_FUN(ephy3_act_led, 1),
0272     BCM6328_MUX_FUN(hsspi_cs1, 2),
0273     BCM6328_MUX_FUN(usb_host_port, 1),
0274     BCM6328_MUX_FUN(usb_device_port, 2),
0275 };
0276 
0277 static inline unsigned int bcm6328_mux_off(unsigned int pin)
0278 {
0279     return bcm6328_mux[pin / 16];
0280 }
0281 
0282 static int bcm6328_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
0283 {
0284     return ARRAY_SIZE(bcm6328_groups);
0285 }
0286 
0287 static const char *bcm6328_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
0288                           unsigned group)
0289 {
0290     return bcm6328_groups[group].name;
0291 }
0292 
0293 static int bcm6328_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
0294                       unsigned group, const unsigned **pins,
0295                       unsigned *num_pins)
0296 {
0297     *pins = bcm6328_groups[group].pins;
0298     *num_pins = bcm6328_groups[group].num_pins;
0299 
0300     return 0;
0301 }
0302 
0303 static int bcm6328_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
0304 {
0305     return ARRAY_SIZE(bcm6328_funcs);
0306 }
0307 
0308 static const char *bcm6328_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
0309                          unsigned selector)
0310 {
0311     return bcm6328_funcs[selector].name;
0312 }
0313 
0314 static int bcm6328_pinctrl_get_groups(struct pinctrl_dev *pctldev,
0315                       unsigned selector,
0316                       const char * const **groups,
0317                       unsigned * const num_groups)
0318 {
0319     *groups = bcm6328_funcs[selector].groups;
0320     *num_groups = bcm6328_funcs[selector].num_groups;
0321 
0322     return 0;
0323 }
0324 
0325 static void bcm6328_rmw_mux(struct bcm63xx_pinctrl *pc, unsigned pin,
0326                 unsigned int mode, unsigned int mux)
0327 {
0328     if (pin < BCM6328_NUM_GPIOS)
0329         regmap_update_bits(pc->regs, BCM6328_MODE_REG, BIT(pin),
0330                    mode ? BIT(pin) : 0);
0331 
0332     regmap_update_bits(pc->regs, bcm6328_mux_off(pin),
0333                BCM6328_MUX_MASK << ((pin % 16) * 2),
0334                mux << ((pin % 16) * 2));
0335 }
0336 
0337 static int bcm6328_pinctrl_set_mux(struct pinctrl_dev *pctldev,
0338                    unsigned selector, unsigned group)
0339 {
0340     struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
0341     const struct bcm6328_pingroup *pg = &bcm6328_groups[group];
0342     const struct bcm6328_function *f = &bcm6328_funcs[selector];
0343 
0344     bcm6328_rmw_mux(pc, pg->pins[0], f->mode_val, f->mux_val);
0345 
0346     return 0;
0347 }
0348 
0349 static int bcm6328_gpio_request_enable(struct pinctrl_dev *pctldev,
0350                        struct pinctrl_gpio_range *range,
0351                        unsigned offset)
0352 {
0353     struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
0354 
0355     /* disable all functions using this pin */
0356     bcm6328_rmw_mux(pc, offset, 0, 0);
0357 
0358     return 0;
0359 }
0360 
0361 static const struct pinctrl_ops bcm6328_pctl_ops = {
0362     .dt_free_map = pinctrl_utils_free_map,
0363     .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
0364     .get_group_name = bcm6328_pinctrl_get_group_name,
0365     .get_group_pins = bcm6328_pinctrl_get_group_pins,
0366     .get_groups_count = bcm6328_pinctrl_get_group_count,
0367 };
0368 
0369 static const struct pinmux_ops bcm6328_pmx_ops = {
0370     .get_function_groups = bcm6328_pinctrl_get_groups,
0371     .get_function_name = bcm6328_pinctrl_get_func_name,
0372     .get_functions_count = bcm6328_pinctrl_get_func_count,
0373     .gpio_request_enable = bcm6328_gpio_request_enable,
0374     .set_mux = bcm6328_pinctrl_set_mux,
0375     .strict = true,
0376 };
0377 
0378 static const struct bcm63xx_pinctrl_soc bcm6328_soc = {
0379     .ngpios = BCM6328_NUM_GPIOS,
0380     .npins = ARRAY_SIZE(bcm6328_pins),
0381     .pctl_ops = &bcm6328_pctl_ops,
0382     .pins = bcm6328_pins,
0383     .pmx_ops = &bcm6328_pmx_ops,
0384 };
0385 
0386 static int bcm6328_pinctrl_probe(struct platform_device *pdev)
0387 {
0388     return bcm63xx_pinctrl_probe(pdev, &bcm6328_soc, NULL);
0389 }
0390 
0391 static const struct of_device_id bcm6328_pinctrl_match[] = {
0392     { .compatible = "brcm,bcm6328-pinctrl", },
0393     { /* sentinel */ }
0394 };
0395 
0396 static struct platform_driver bcm6328_pinctrl_driver = {
0397     .probe = bcm6328_pinctrl_probe,
0398     .driver = {
0399         .name = "bcm6328-pinctrl",
0400         .of_match_table = bcm6328_pinctrl_match,
0401     },
0402 };
0403 
0404 builtin_platform_driver(bcm6328_pinctrl_driver);