1*9bf34ac5SÁlvaro Fernández Rojas // SPDX-License-Identifier: GPL-2.0+ 2*9bf34ac5SÁlvaro Fernández Rojas /* 3*9bf34ac5SÁlvaro Fernández Rojas * Driver for BCM6328 GPIO unit (pinctrl + GPIO) 4*9bf34ac5SÁlvaro Fernández Rojas * 5*9bf34ac5SÁlvaro Fernández Rojas * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com> 6*9bf34ac5SÁlvaro Fernández Rojas * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com> 7*9bf34ac5SÁlvaro Fernández Rojas */ 8*9bf34ac5SÁlvaro Fernández Rojas 9*9bf34ac5SÁlvaro Fernández Rojas #include <linux/bits.h> 10*9bf34ac5SÁlvaro Fernández Rojas #include <linux/gpio/driver.h> 11*9bf34ac5SÁlvaro Fernández Rojas #include <linux/kernel.h> 12*9bf34ac5SÁlvaro Fernández Rojas #include <linux/of.h> 13*9bf34ac5SÁlvaro Fernández Rojas #include <linux/pinctrl/pinmux.h> 14*9bf34ac5SÁlvaro Fernández Rojas #include <linux/platform_device.h> 15*9bf34ac5SÁlvaro Fernández Rojas #include <linux/regmap.h> 16*9bf34ac5SÁlvaro Fernández Rojas 17*9bf34ac5SÁlvaro Fernández Rojas #include "../pinctrl-utils.h" 18*9bf34ac5SÁlvaro Fernández Rojas 19*9bf34ac5SÁlvaro Fernández Rojas #include "pinctrl-bcm63xx.h" 20*9bf34ac5SÁlvaro Fernández Rojas 21*9bf34ac5SÁlvaro Fernández Rojas #define BCM6328_NUM_GPIOS 32 22*9bf34ac5SÁlvaro Fernández Rojas 23*9bf34ac5SÁlvaro Fernández Rojas #define BCM6328_MODE_REG 0x18 24*9bf34ac5SÁlvaro Fernández Rojas #define BCM6328_MUX_HI_REG 0x1c 25*9bf34ac5SÁlvaro Fernández Rojas #define BCM6328_MUX_LO_REG 0x20 26*9bf34ac5SÁlvaro Fernández Rojas #define BCM6328_MUX_OTHER_REG 0x24 27*9bf34ac5SÁlvaro Fernández Rojas #define BCM6328_MUX_MASK GENMASK(1, 0) 28*9bf34ac5SÁlvaro Fernández Rojas 29*9bf34ac5SÁlvaro Fernández Rojas struct bcm6328_pingroup { 30*9bf34ac5SÁlvaro Fernández Rojas const char *name; 31*9bf34ac5SÁlvaro Fernández Rojas const unsigned * const pins; 32*9bf34ac5SÁlvaro Fernández Rojas const unsigned num_pins; 33*9bf34ac5SÁlvaro Fernández Rojas }; 34*9bf34ac5SÁlvaro Fernández Rojas 35*9bf34ac5SÁlvaro Fernández Rojas struct bcm6328_function { 36*9bf34ac5SÁlvaro Fernández Rojas const char *name; 37*9bf34ac5SÁlvaro Fernández Rojas const char * const *groups; 38*9bf34ac5SÁlvaro Fernández Rojas const unsigned num_groups; 39*9bf34ac5SÁlvaro Fernández Rojas 40*9bf34ac5SÁlvaro Fernández Rojas unsigned mode_val:1; 41*9bf34ac5SÁlvaro Fernández Rojas unsigned mux_val:2; 42*9bf34ac5SÁlvaro Fernández Rojas }; 43*9bf34ac5SÁlvaro Fernández Rojas 44*9bf34ac5SÁlvaro Fernández Rojas static const unsigned int bcm6328_mux[] = { 45*9bf34ac5SÁlvaro Fernández Rojas BCM6328_MUX_LO_REG, 46*9bf34ac5SÁlvaro Fernández Rojas BCM6328_MUX_HI_REG, 47*9bf34ac5SÁlvaro Fernández Rojas BCM6328_MUX_OTHER_REG 48*9bf34ac5SÁlvaro Fernández Rojas }; 49*9bf34ac5SÁlvaro Fernández Rojas 50*9bf34ac5SÁlvaro Fernández Rojas static const struct pinctrl_pin_desc bcm6328_pins[] = { 51*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(0, "gpio0"), 52*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(1, "gpio1"), 53*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(2, "gpio2"), 54*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(3, "gpio3"), 55*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(4, "gpio4"), 56*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(5, "gpio5"), 57*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(6, "gpio6"), 58*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(7, "gpio7"), 59*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(8, "gpio8"), 60*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(9, "gpio9"), 61*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(10, "gpio10"), 62*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(11, "gpio11"), 63*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(12, "gpio12"), 64*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(13, "gpio13"), 65*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(14, "gpio14"), 66*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(15, "gpio15"), 67*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(16, "gpio16"), 68*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(17, "gpio17"), 69*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(18, "gpio18"), 70*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(19, "gpio19"), 71*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(20, "gpio20"), 72*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(21, "gpio21"), 73*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(22, "gpio22"), 74*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(23, "gpio23"), 75*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(24, "gpio24"), 76*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(25, "gpio25"), 77*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(26, "gpio26"), 78*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(27, "gpio27"), 79*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(28, "gpio28"), 80*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(29, "gpio29"), 81*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(30, "gpio30"), 82*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(31, "gpio31"), 83*9bf34ac5SÁlvaro Fernández Rojas 84*9bf34ac5SÁlvaro Fernández Rojas /* 85*9bf34ac5SÁlvaro Fernández Rojas * No idea where they really are; so let's put them according 86*9bf34ac5SÁlvaro Fernández Rojas * to their mux offsets. 87*9bf34ac5SÁlvaro Fernández Rojas */ 88*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(36, "hsspi_cs1"), 89*9bf34ac5SÁlvaro Fernández Rojas PINCTRL_PIN(38, "usb_p2"), 90*9bf34ac5SÁlvaro Fernández Rojas }; 91*9bf34ac5SÁlvaro Fernández Rojas 92*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio0_pins[] = { 0 }; 93*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio1_pins[] = { 1 }; 94*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio2_pins[] = { 2 }; 95*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio3_pins[] = { 3 }; 96*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio4_pins[] = { 4 }; 97*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio5_pins[] = { 5 }; 98*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio6_pins[] = { 6 }; 99*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio7_pins[] = { 7 }; 100*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio8_pins[] = { 8 }; 101*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio9_pins[] = { 9 }; 102*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio10_pins[] = { 10 }; 103*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio11_pins[] = { 11 }; 104*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio12_pins[] = { 12 }; 105*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio13_pins[] = { 13 }; 106*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio14_pins[] = { 14 }; 107*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio15_pins[] = { 15 }; 108*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio16_pins[] = { 16 }; 109*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio17_pins[] = { 17 }; 110*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio18_pins[] = { 18 }; 111*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio19_pins[] = { 19 }; 112*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio20_pins[] = { 20 }; 113*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio21_pins[] = { 21 }; 114*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio22_pins[] = { 22 }; 115*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio23_pins[] = { 23 }; 116*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio24_pins[] = { 24 }; 117*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio25_pins[] = { 25 }; 118*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio26_pins[] = { 26 }; 119*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio27_pins[] = { 27 }; 120*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio28_pins[] = { 28 }; 121*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio29_pins[] = { 29 }; 122*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio30_pins[] = { 30 }; 123*9bf34ac5SÁlvaro Fernández Rojas static unsigned gpio31_pins[] = { 31 }; 124*9bf34ac5SÁlvaro Fernández Rojas 125*9bf34ac5SÁlvaro Fernández Rojas static unsigned hsspi_cs1_pins[] = { 36 }; 126*9bf34ac5SÁlvaro Fernández Rojas static unsigned usb_port1_pins[] = { 38 }; 127*9bf34ac5SÁlvaro Fernández Rojas 128*9bf34ac5SÁlvaro Fernández Rojas #define BCM6328_GROUP(n) \ 129*9bf34ac5SÁlvaro Fernández Rojas { \ 130*9bf34ac5SÁlvaro Fernández Rojas .name = #n, \ 131*9bf34ac5SÁlvaro Fernández Rojas .pins = n##_pins, \ 132*9bf34ac5SÁlvaro Fernández Rojas .num_pins = ARRAY_SIZE(n##_pins), \ 133*9bf34ac5SÁlvaro Fernández Rojas } 134*9bf34ac5SÁlvaro Fernández Rojas 135*9bf34ac5SÁlvaro Fernández Rojas static struct bcm6328_pingroup bcm6328_groups[] = { 136*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio0), 137*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio1), 138*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio2), 139*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio3), 140*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio4), 141*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio5), 142*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio6), 143*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio7), 144*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio8), 145*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio9), 146*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio10), 147*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio11), 148*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio12), 149*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio13), 150*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio14), 151*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio15), 152*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio16), 153*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio17), 154*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio18), 155*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio19), 156*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio20), 157*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio21), 158*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio22), 159*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio23), 160*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio24), 161*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio25), 162*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio26), 163*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio27), 164*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio28), 165*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio29), 166*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio30), 167*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(gpio31), 168*9bf34ac5SÁlvaro Fernández Rojas 169*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(hsspi_cs1), 170*9bf34ac5SÁlvaro Fernández Rojas BCM6328_GROUP(usb_port1), 171*9bf34ac5SÁlvaro Fernández Rojas }; 172*9bf34ac5SÁlvaro Fernández Rojas 173*9bf34ac5SÁlvaro Fernández Rojas /* GPIO_MODE */ 174*9bf34ac5SÁlvaro Fernández Rojas static const char * const led_groups[] = { 175*9bf34ac5SÁlvaro Fernández Rojas "gpio0", 176*9bf34ac5SÁlvaro Fernández Rojas "gpio1", 177*9bf34ac5SÁlvaro Fernández Rojas "gpio2", 178*9bf34ac5SÁlvaro Fernández Rojas "gpio3", 179*9bf34ac5SÁlvaro Fernández Rojas "gpio4", 180*9bf34ac5SÁlvaro Fernández Rojas "gpio5", 181*9bf34ac5SÁlvaro Fernández Rojas "gpio6", 182*9bf34ac5SÁlvaro Fernández Rojas "gpio7", 183*9bf34ac5SÁlvaro Fernández Rojas "gpio8", 184*9bf34ac5SÁlvaro Fernández Rojas "gpio9", 185*9bf34ac5SÁlvaro Fernández Rojas "gpio10", 186*9bf34ac5SÁlvaro Fernández Rojas "gpio11", 187*9bf34ac5SÁlvaro Fernández Rojas "gpio12", 188*9bf34ac5SÁlvaro Fernández Rojas "gpio13", 189*9bf34ac5SÁlvaro Fernández Rojas "gpio14", 190*9bf34ac5SÁlvaro Fernández Rojas "gpio15", 191*9bf34ac5SÁlvaro Fernández Rojas "gpio16", 192*9bf34ac5SÁlvaro Fernández Rojas "gpio17", 193*9bf34ac5SÁlvaro Fernández Rojas "gpio18", 194*9bf34ac5SÁlvaro Fernández Rojas "gpio19", 195*9bf34ac5SÁlvaro Fernández Rojas "gpio20", 196*9bf34ac5SÁlvaro Fernández Rojas "gpio21", 197*9bf34ac5SÁlvaro Fernández Rojas "gpio22", 198*9bf34ac5SÁlvaro Fernández Rojas "gpio23", 199*9bf34ac5SÁlvaro Fernández Rojas }; 200*9bf34ac5SÁlvaro Fernández Rojas 201*9bf34ac5SÁlvaro Fernández Rojas /* PINMUX_SEL */ 202*9bf34ac5SÁlvaro Fernández Rojas static const char * const serial_led_data_groups[] = { 203*9bf34ac5SÁlvaro Fernández Rojas "gpio6", 204*9bf34ac5SÁlvaro Fernández Rojas }; 205*9bf34ac5SÁlvaro Fernández Rojas 206*9bf34ac5SÁlvaro Fernández Rojas static const char * const serial_led_clk_groups[] = { 207*9bf34ac5SÁlvaro Fernández Rojas "gpio7", 208*9bf34ac5SÁlvaro Fernández Rojas }; 209*9bf34ac5SÁlvaro Fernández Rojas 210*9bf34ac5SÁlvaro Fernández Rojas static const char * const inet_act_led_groups[] = { 211*9bf34ac5SÁlvaro Fernández Rojas "gpio11", 212*9bf34ac5SÁlvaro Fernández Rojas }; 213*9bf34ac5SÁlvaro Fernández Rojas 214*9bf34ac5SÁlvaro Fernández Rojas static const char * const pcie_clkreq_groups[] = { 215*9bf34ac5SÁlvaro Fernández Rojas "gpio16", 216*9bf34ac5SÁlvaro Fernández Rojas }; 217*9bf34ac5SÁlvaro Fernández Rojas 218*9bf34ac5SÁlvaro Fernández Rojas static const char * const ephy0_act_led_groups[] = { 219*9bf34ac5SÁlvaro Fernández Rojas "gpio25", 220*9bf34ac5SÁlvaro Fernández Rojas }; 221*9bf34ac5SÁlvaro Fernández Rojas 222*9bf34ac5SÁlvaro Fernández Rojas static const char * const ephy1_act_led_groups[] = { 223*9bf34ac5SÁlvaro Fernández Rojas "gpio26", 224*9bf34ac5SÁlvaro Fernández Rojas }; 225*9bf34ac5SÁlvaro Fernández Rojas 226*9bf34ac5SÁlvaro Fernández Rojas static const char * const ephy2_act_led_groups[] = { 227*9bf34ac5SÁlvaro Fernández Rojas "gpio27", 228*9bf34ac5SÁlvaro Fernández Rojas }; 229*9bf34ac5SÁlvaro Fernández Rojas 230*9bf34ac5SÁlvaro Fernández Rojas static const char * const ephy3_act_led_groups[] = { 231*9bf34ac5SÁlvaro Fernández Rojas "gpio28", 232*9bf34ac5SÁlvaro Fernández Rojas }; 233*9bf34ac5SÁlvaro Fernández Rojas 234*9bf34ac5SÁlvaro Fernández Rojas static const char * const hsspi_cs1_groups[] = { 235*9bf34ac5SÁlvaro Fernández Rojas "hsspi_cs1" 236*9bf34ac5SÁlvaro Fernández Rojas }; 237*9bf34ac5SÁlvaro Fernández Rojas 238*9bf34ac5SÁlvaro Fernández Rojas static const char * const usb_host_port_groups[] = { 239*9bf34ac5SÁlvaro Fernández Rojas "usb_port1", 240*9bf34ac5SÁlvaro Fernández Rojas }; 241*9bf34ac5SÁlvaro Fernández Rojas 242*9bf34ac5SÁlvaro Fernández Rojas static const char * const usb_device_port_groups[] = { 243*9bf34ac5SÁlvaro Fernández Rojas "usb_port1", 244*9bf34ac5SÁlvaro Fernández Rojas }; 245*9bf34ac5SÁlvaro Fernández Rojas 246*9bf34ac5SÁlvaro Fernández Rojas #define BCM6328_MODE_FUN(n) \ 247*9bf34ac5SÁlvaro Fernández Rojas { \ 248*9bf34ac5SÁlvaro Fernández Rojas .name = #n, \ 249*9bf34ac5SÁlvaro Fernández Rojas .groups = n##_groups, \ 250*9bf34ac5SÁlvaro Fernández Rojas .num_groups = ARRAY_SIZE(n##_groups), \ 251*9bf34ac5SÁlvaro Fernández Rojas .mode_val = 1, \ 252*9bf34ac5SÁlvaro Fernández Rojas } 253*9bf34ac5SÁlvaro Fernández Rojas 254*9bf34ac5SÁlvaro Fernández Rojas #define BCM6328_MUX_FUN(n, mux) \ 255*9bf34ac5SÁlvaro Fernández Rojas { \ 256*9bf34ac5SÁlvaro Fernández Rojas .name = #n, \ 257*9bf34ac5SÁlvaro Fernández Rojas .groups = n##_groups, \ 258*9bf34ac5SÁlvaro Fernández Rojas .num_groups = ARRAY_SIZE(n##_groups), \ 259*9bf34ac5SÁlvaro Fernández Rojas .mux_val = mux, \ 260*9bf34ac5SÁlvaro Fernández Rojas } 261*9bf34ac5SÁlvaro Fernández Rojas 262*9bf34ac5SÁlvaro Fernández Rojas static const struct bcm6328_function bcm6328_funcs[] = { 263*9bf34ac5SÁlvaro Fernández Rojas BCM6328_MODE_FUN(led), 264*9bf34ac5SÁlvaro Fernández Rojas BCM6328_MUX_FUN(serial_led_data, 2), 265*9bf34ac5SÁlvaro Fernández Rojas BCM6328_MUX_FUN(serial_led_clk, 2), 266*9bf34ac5SÁlvaro Fernández Rojas BCM6328_MUX_FUN(inet_act_led, 1), 267*9bf34ac5SÁlvaro Fernández Rojas BCM6328_MUX_FUN(pcie_clkreq, 2), 268*9bf34ac5SÁlvaro Fernández Rojas BCM6328_MUX_FUN(ephy0_act_led, 1), 269*9bf34ac5SÁlvaro Fernández Rojas BCM6328_MUX_FUN(ephy1_act_led, 1), 270*9bf34ac5SÁlvaro Fernández Rojas BCM6328_MUX_FUN(ephy2_act_led, 1), 271*9bf34ac5SÁlvaro Fernández Rojas BCM6328_MUX_FUN(ephy3_act_led, 1), 272*9bf34ac5SÁlvaro Fernández Rojas BCM6328_MUX_FUN(hsspi_cs1, 2), 273*9bf34ac5SÁlvaro Fernández Rojas BCM6328_MUX_FUN(usb_host_port, 1), 274*9bf34ac5SÁlvaro Fernández Rojas BCM6328_MUX_FUN(usb_device_port, 2), 275*9bf34ac5SÁlvaro Fernández Rojas }; 276*9bf34ac5SÁlvaro Fernández Rojas 277*9bf34ac5SÁlvaro Fernández Rojas static inline unsigned int bcm6328_mux_off(unsigned int pin) 278*9bf34ac5SÁlvaro Fernández Rojas { 279*9bf34ac5SÁlvaro Fernández Rojas return bcm6328_mux[pin / 16]; 280*9bf34ac5SÁlvaro Fernández Rojas } 281*9bf34ac5SÁlvaro Fernández Rojas 282*9bf34ac5SÁlvaro Fernández Rojas static int bcm6328_pinctrl_get_group_count(struct pinctrl_dev *pctldev) 283*9bf34ac5SÁlvaro Fernández Rojas { 284*9bf34ac5SÁlvaro Fernández Rojas return ARRAY_SIZE(bcm6328_groups); 285*9bf34ac5SÁlvaro Fernández Rojas } 286*9bf34ac5SÁlvaro Fernández Rojas 287*9bf34ac5SÁlvaro Fernández Rojas static const char *bcm6328_pinctrl_get_group_name(struct pinctrl_dev *pctldev, 288*9bf34ac5SÁlvaro Fernández Rojas unsigned group) 289*9bf34ac5SÁlvaro Fernández Rojas { 290*9bf34ac5SÁlvaro Fernández Rojas return bcm6328_groups[group].name; 291*9bf34ac5SÁlvaro Fernández Rojas } 292*9bf34ac5SÁlvaro Fernández Rojas 293*9bf34ac5SÁlvaro Fernández Rojas static int bcm6328_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, 294*9bf34ac5SÁlvaro Fernández Rojas unsigned group, const unsigned **pins, 295*9bf34ac5SÁlvaro Fernández Rojas unsigned *num_pins) 296*9bf34ac5SÁlvaro Fernández Rojas { 297*9bf34ac5SÁlvaro Fernández Rojas *pins = bcm6328_groups[group].pins; 298*9bf34ac5SÁlvaro Fernández Rojas *num_pins = bcm6328_groups[group].num_pins; 299*9bf34ac5SÁlvaro Fernández Rojas 300*9bf34ac5SÁlvaro Fernández Rojas return 0; 301*9bf34ac5SÁlvaro Fernández Rojas } 302*9bf34ac5SÁlvaro Fernández Rojas 303*9bf34ac5SÁlvaro Fernández Rojas static int bcm6328_pinctrl_get_func_count(struct pinctrl_dev *pctldev) 304*9bf34ac5SÁlvaro Fernández Rojas { 305*9bf34ac5SÁlvaro Fernández Rojas return ARRAY_SIZE(bcm6328_funcs); 306*9bf34ac5SÁlvaro Fernández Rojas } 307*9bf34ac5SÁlvaro Fernández Rojas 308*9bf34ac5SÁlvaro Fernández Rojas static const char *bcm6328_pinctrl_get_func_name(struct pinctrl_dev *pctldev, 309*9bf34ac5SÁlvaro Fernández Rojas unsigned selector) 310*9bf34ac5SÁlvaro Fernández Rojas { 311*9bf34ac5SÁlvaro Fernández Rojas return bcm6328_funcs[selector].name; 312*9bf34ac5SÁlvaro Fernández Rojas } 313*9bf34ac5SÁlvaro Fernández Rojas 314*9bf34ac5SÁlvaro Fernández Rojas static int bcm6328_pinctrl_get_groups(struct pinctrl_dev *pctldev, 315*9bf34ac5SÁlvaro Fernández Rojas unsigned selector, 316*9bf34ac5SÁlvaro Fernández Rojas const char * const **groups, 317*9bf34ac5SÁlvaro Fernández Rojas unsigned * const num_groups) 318*9bf34ac5SÁlvaro Fernández Rojas { 319*9bf34ac5SÁlvaro Fernández Rojas *groups = bcm6328_funcs[selector].groups; 320*9bf34ac5SÁlvaro Fernández Rojas *num_groups = bcm6328_funcs[selector].num_groups; 321*9bf34ac5SÁlvaro Fernández Rojas 322*9bf34ac5SÁlvaro Fernández Rojas return 0; 323*9bf34ac5SÁlvaro Fernández Rojas } 324*9bf34ac5SÁlvaro Fernández Rojas 325*9bf34ac5SÁlvaro Fernández Rojas static void bcm6328_rmw_mux(struct bcm63xx_pinctrl *pc, unsigned pin, 326*9bf34ac5SÁlvaro Fernández Rojas unsigned int mode, unsigned int mux) 327*9bf34ac5SÁlvaro Fernández Rojas { 328*9bf34ac5SÁlvaro Fernández Rojas if (pin < BCM6328_NUM_GPIOS) 329*9bf34ac5SÁlvaro Fernández Rojas regmap_update_bits(pc->regs, BCM6328_MODE_REG, BIT(pin), 330*9bf34ac5SÁlvaro Fernández Rojas mode ? BIT(pin) : 0); 331*9bf34ac5SÁlvaro Fernández Rojas 332*9bf34ac5SÁlvaro Fernández Rojas regmap_update_bits(pc->regs, bcm6328_mux_off(pin), 333*9bf34ac5SÁlvaro Fernández Rojas BCM6328_MUX_MASK << ((pin % 16) * 2), 334*9bf34ac5SÁlvaro Fernández Rojas mux << ((pin % 16) * 2)); 335*9bf34ac5SÁlvaro Fernández Rojas } 336*9bf34ac5SÁlvaro Fernández Rojas 337*9bf34ac5SÁlvaro Fernández Rojas static int bcm6328_pinctrl_set_mux(struct pinctrl_dev *pctldev, 338*9bf34ac5SÁlvaro Fernández Rojas unsigned selector, unsigned group) 339*9bf34ac5SÁlvaro Fernández Rojas { 340*9bf34ac5SÁlvaro Fernández Rojas struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); 341*9bf34ac5SÁlvaro Fernández Rojas const struct bcm6328_pingroup *pg = &bcm6328_groups[group]; 342*9bf34ac5SÁlvaro Fernández Rojas const struct bcm6328_function *f = &bcm6328_funcs[selector]; 343*9bf34ac5SÁlvaro Fernández Rojas 344*9bf34ac5SÁlvaro Fernández Rojas bcm6328_rmw_mux(pc, pg->pins[0], f->mode_val, f->mux_val); 345*9bf34ac5SÁlvaro Fernández Rojas 346*9bf34ac5SÁlvaro Fernández Rojas return 0; 347*9bf34ac5SÁlvaro Fernández Rojas } 348*9bf34ac5SÁlvaro Fernández Rojas 349*9bf34ac5SÁlvaro Fernández Rojas static int bcm6328_gpio_request_enable(struct pinctrl_dev *pctldev, 350*9bf34ac5SÁlvaro Fernández Rojas struct pinctrl_gpio_range *range, 351*9bf34ac5SÁlvaro Fernández Rojas unsigned offset) 352*9bf34ac5SÁlvaro Fernández Rojas { 353*9bf34ac5SÁlvaro Fernández Rojas struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); 354*9bf34ac5SÁlvaro Fernández Rojas 355*9bf34ac5SÁlvaro Fernández Rojas /* disable all functions using this pin */ 356*9bf34ac5SÁlvaro Fernández Rojas bcm6328_rmw_mux(pc, offset, 0, 0); 357*9bf34ac5SÁlvaro Fernández Rojas 358*9bf34ac5SÁlvaro Fernández Rojas return 0; 359*9bf34ac5SÁlvaro Fernández Rojas } 360*9bf34ac5SÁlvaro Fernández Rojas 361*9bf34ac5SÁlvaro Fernández Rojas static struct pinctrl_ops bcm6328_pctl_ops = { 362*9bf34ac5SÁlvaro Fernández Rojas .dt_free_map = pinctrl_utils_free_map, 363*9bf34ac5SÁlvaro Fernández Rojas .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, 364*9bf34ac5SÁlvaro Fernández Rojas .get_group_name = bcm6328_pinctrl_get_group_name, 365*9bf34ac5SÁlvaro Fernández Rojas .get_group_pins = bcm6328_pinctrl_get_group_pins, 366*9bf34ac5SÁlvaro Fernández Rojas .get_groups_count = bcm6328_pinctrl_get_group_count, 367*9bf34ac5SÁlvaro Fernández Rojas }; 368*9bf34ac5SÁlvaro Fernández Rojas 369*9bf34ac5SÁlvaro Fernández Rojas static struct pinmux_ops bcm6328_pmx_ops = { 370*9bf34ac5SÁlvaro Fernández Rojas .get_function_groups = bcm6328_pinctrl_get_groups, 371*9bf34ac5SÁlvaro Fernández Rojas .get_function_name = bcm6328_pinctrl_get_func_name, 372*9bf34ac5SÁlvaro Fernández Rojas .get_functions_count = bcm6328_pinctrl_get_func_count, 373*9bf34ac5SÁlvaro Fernández Rojas .gpio_request_enable = bcm6328_gpio_request_enable, 374*9bf34ac5SÁlvaro Fernández Rojas .set_mux = bcm6328_pinctrl_set_mux, 375*9bf34ac5SÁlvaro Fernández Rojas .strict = true, 376*9bf34ac5SÁlvaro Fernández Rojas }; 377*9bf34ac5SÁlvaro Fernández Rojas 378*9bf34ac5SÁlvaro Fernández Rojas static const struct bcm63xx_pinctrl_soc bcm6328_soc = { 379*9bf34ac5SÁlvaro Fernández Rojas .ngpios = BCM6328_NUM_GPIOS, 380*9bf34ac5SÁlvaro Fernández Rojas .npins = ARRAY_SIZE(bcm6328_pins), 381*9bf34ac5SÁlvaro Fernández Rojas .pctl_ops = &bcm6328_pctl_ops, 382*9bf34ac5SÁlvaro Fernández Rojas .pins = bcm6328_pins, 383*9bf34ac5SÁlvaro Fernández Rojas .pmx_ops = &bcm6328_pmx_ops, 384*9bf34ac5SÁlvaro Fernández Rojas }; 385*9bf34ac5SÁlvaro Fernández Rojas 386*9bf34ac5SÁlvaro Fernández Rojas static int bcm6328_pinctrl_probe(struct platform_device *pdev) 387*9bf34ac5SÁlvaro Fernández Rojas { 388*9bf34ac5SÁlvaro Fernández Rojas return bcm63xx_pinctrl_probe(pdev, &bcm6328_soc, NULL); 389*9bf34ac5SÁlvaro Fernández Rojas } 390*9bf34ac5SÁlvaro Fernández Rojas 391*9bf34ac5SÁlvaro Fernández Rojas static const struct of_device_id bcm6328_pinctrl_match[] = { 392*9bf34ac5SÁlvaro Fernández Rojas { .compatible = "brcm,bcm6328-pinctrl", }, 393*9bf34ac5SÁlvaro Fernández Rojas { /* sentinel */ } 394*9bf34ac5SÁlvaro Fernández Rojas }; 395*9bf34ac5SÁlvaro Fernández Rojas 396*9bf34ac5SÁlvaro Fernández Rojas static struct platform_driver bcm6328_pinctrl_driver = { 397*9bf34ac5SÁlvaro Fernández Rojas .probe = bcm6328_pinctrl_probe, 398*9bf34ac5SÁlvaro Fernández Rojas .driver = { 399*9bf34ac5SÁlvaro Fernández Rojas .name = "bcm6328-pinctrl", 400*9bf34ac5SÁlvaro Fernández Rojas .of_match_table = bcm6328_pinctrl_match, 401*9bf34ac5SÁlvaro Fernández Rojas }, 402*9bf34ac5SÁlvaro Fernández Rojas }; 403*9bf34ac5SÁlvaro Fernández Rojas 404*9bf34ac5SÁlvaro Fernández Rojas builtin_platform_driver(bcm6328_pinctrl_driver); 405