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