150554accSÁlvaro Fernández Rojas // SPDX-License-Identifier: GPL-2.0+ 250554accSÁlvaro Fernández Rojas /* 350554accSÁlvaro Fernández Rojas * Driver for BCM6368 GPIO unit (pinctrl + GPIO) 450554accSÁlvaro Fernández Rojas * 550554accSÁlvaro Fernández Rojas * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com> 650554accSÁlvaro Fernández Rojas * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com> 750554accSÁlvaro Fernández Rojas */ 850554accSÁlvaro Fernández Rojas 950554accSÁlvaro Fernández Rojas #include <linux/bits.h> 1050554accSÁlvaro Fernández Rojas #include <linux/gpio/driver.h> 1150554accSÁlvaro Fernández Rojas #include <linux/kernel.h> 1250554accSÁlvaro Fernández Rojas #include <linux/of.h> 1350554accSÁlvaro Fernández Rojas #include <linux/pinctrl/pinmux.h> 1450554accSÁlvaro Fernández Rojas #include <linux/platform_device.h> 1550554accSÁlvaro Fernández Rojas #include <linux/regmap.h> 1650554accSÁlvaro Fernández Rojas 1750554accSÁlvaro Fernández Rojas #include "../pinctrl-utils.h" 1850554accSÁlvaro Fernández Rojas 1950554accSÁlvaro Fernández Rojas #include "pinctrl-bcm63xx.h" 2050554accSÁlvaro Fernández Rojas 2150554accSÁlvaro Fernández Rojas #define BCM6368_NUM_GPIOS 38 2250554accSÁlvaro Fernández Rojas 2350554accSÁlvaro Fernández Rojas #define BCM6368_MODE_REG 0x18 2450554accSÁlvaro Fernández Rojas #define BCM6368_BASEMODE_REG 0x38 2550554accSÁlvaro Fernández Rojas #define BCM6368_BASEMODE_MASK 0x7 2650554accSÁlvaro Fernández Rojas #define BCM6368_BASEMODE_GPIO 0x0 2750554accSÁlvaro Fernández Rojas #define BCM6368_BASEMODE_UART1 0x1 2850554accSÁlvaro Fernández Rojas 2950554accSÁlvaro Fernández Rojas struct bcm6368_function { 3050554accSÁlvaro Fernández Rojas const char *name; 3150554accSÁlvaro Fernández Rojas const char * const *groups; 3250554accSÁlvaro Fernández Rojas const unsigned num_groups; 3350554accSÁlvaro Fernández Rojas 3450554accSÁlvaro Fernández Rojas unsigned dir_out:16; 3550554accSÁlvaro Fernández Rojas unsigned basemode:3; 3650554accSÁlvaro Fernández Rojas }; 3750554accSÁlvaro Fernández Rojas 3850554accSÁlvaro Fernández Rojas struct bcm6368_priv { 3950554accSÁlvaro Fernández Rojas struct regmap_field *overlays; 4050554accSÁlvaro Fernández Rojas }; 4150554accSÁlvaro Fernández Rojas 4250554accSÁlvaro Fernández Rojas #define BCM6368_BASEMODE_PIN(a, b) \ 4350554accSÁlvaro Fernández Rojas { \ 4450554accSÁlvaro Fernández Rojas .number = a, \ 4550554accSÁlvaro Fernández Rojas .name = b, \ 4650554accSÁlvaro Fernández Rojas .drv_data = (void *)true \ 4750554accSÁlvaro Fernández Rojas } 4850554accSÁlvaro Fernández Rojas 4950554accSÁlvaro Fernández Rojas static const struct pinctrl_pin_desc bcm6368_pins[] = { 5050554accSÁlvaro Fernández Rojas PINCTRL_PIN(0, "gpio0"), 5150554accSÁlvaro Fernández Rojas PINCTRL_PIN(1, "gpio1"), 5250554accSÁlvaro Fernández Rojas PINCTRL_PIN(2, "gpio2"), 5350554accSÁlvaro Fernández Rojas PINCTRL_PIN(3, "gpio3"), 5450554accSÁlvaro Fernández Rojas PINCTRL_PIN(4, "gpio4"), 5550554accSÁlvaro Fernández Rojas PINCTRL_PIN(5, "gpio5"), 5650554accSÁlvaro Fernández Rojas PINCTRL_PIN(6, "gpio6"), 5750554accSÁlvaro Fernández Rojas PINCTRL_PIN(7, "gpio7"), 5850554accSÁlvaro Fernández Rojas PINCTRL_PIN(8, "gpio8"), 5950554accSÁlvaro Fernández Rojas PINCTRL_PIN(9, "gpio9"), 6050554accSÁlvaro Fernández Rojas PINCTRL_PIN(10, "gpio10"), 6150554accSÁlvaro Fernández Rojas PINCTRL_PIN(11, "gpio11"), 6250554accSÁlvaro Fernández Rojas PINCTRL_PIN(12, "gpio12"), 6350554accSÁlvaro Fernández Rojas PINCTRL_PIN(13, "gpio13"), 6450554accSÁlvaro Fernández Rojas PINCTRL_PIN(14, "gpio14"), 6550554accSÁlvaro Fernández Rojas PINCTRL_PIN(15, "gpio15"), 6650554accSÁlvaro Fernández Rojas PINCTRL_PIN(16, "gpio16"), 6750554accSÁlvaro Fernández Rojas PINCTRL_PIN(17, "gpio17"), 6850554accSÁlvaro Fernández Rojas PINCTRL_PIN(18, "gpio18"), 6950554accSÁlvaro Fernández Rojas PINCTRL_PIN(19, "gpio19"), 7050554accSÁlvaro Fernández Rojas PINCTRL_PIN(20, "gpio20"), 7150554accSÁlvaro Fernández Rojas PINCTRL_PIN(21, "gpio21"), 7250554accSÁlvaro Fernández Rojas PINCTRL_PIN(22, "gpio22"), 7350554accSÁlvaro Fernández Rojas PINCTRL_PIN(23, "gpio23"), 7450554accSÁlvaro Fernández Rojas PINCTRL_PIN(24, "gpio24"), 7550554accSÁlvaro Fernández Rojas PINCTRL_PIN(25, "gpio25"), 7650554accSÁlvaro Fernández Rojas PINCTRL_PIN(26, "gpio26"), 7750554accSÁlvaro Fernández Rojas PINCTRL_PIN(27, "gpio27"), 7850554accSÁlvaro Fernández Rojas PINCTRL_PIN(28, "gpio28"), 7950554accSÁlvaro Fernández Rojas PINCTRL_PIN(29, "gpio29"), 8050554accSÁlvaro Fernández Rojas BCM6368_BASEMODE_PIN(30, "gpio30"), 8150554accSÁlvaro Fernández Rojas BCM6368_BASEMODE_PIN(31, "gpio31"), 8250554accSÁlvaro Fernández Rojas BCM6368_BASEMODE_PIN(32, "gpio32"), 8350554accSÁlvaro Fernández Rojas BCM6368_BASEMODE_PIN(33, "gpio33"), 8450554accSÁlvaro Fernández Rojas PINCTRL_PIN(34, "gpio34"), 8550554accSÁlvaro Fernández Rojas PINCTRL_PIN(35, "gpio35"), 8650554accSÁlvaro Fernández Rojas PINCTRL_PIN(36, "gpio36"), 8750554accSÁlvaro Fernández Rojas PINCTRL_PIN(37, "gpio37"), 8850554accSÁlvaro Fernández Rojas }; 8950554accSÁlvaro Fernández Rojas 9050554accSÁlvaro Fernández Rojas static unsigned gpio0_pins[] = { 0 }; 9150554accSÁlvaro Fernández Rojas static unsigned gpio1_pins[] = { 1 }; 9250554accSÁlvaro Fernández Rojas static unsigned gpio2_pins[] = { 2 }; 9350554accSÁlvaro Fernández Rojas static unsigned gpio3_pins[] = { 3 }; 9450554accSÁlvaro Fernández Rojas static unsigned gpio4_pins[] = { 4 }; 9550554accSÁlvaro Fernández Rojas static unsigned gpio5_pins[] = { 5 }; 9650554accSÁlvaro Fernández Rojas static unsigned gpio6_pins[] = { 6 }; 9750554accSÁlvaro Fernández Rojas static unsigned gpio7_pins[] = { 7 }; 9850554accSÁlvaro Fernández Rojas static unsigned gpio8_pins[] = { 8 }; 9950554accSÁlvaro Fernández Rojas static unsigned gpio9_pins[] = { 9 }; 10050554accSÁlvaro Fernández Rojas static unsigned gpio10_pins[] = { 10 }; 10150554accSÁlvaro Fernández Rojas static unsigned gpio11_pins[] = { 11 }; 10250554accSÁlvaro Fernández Rojas static unsigned gpio12_pins[] = { 12 }; 10350554accSÁlvaro Fernández Rojas static unsigned gpio13_pins[] = { 13 }; 10450554accSÁlvaro Fernández Rojas static unsigned gpio14_pins[] = { 14 }; 10550554accSÁlvaro Fernández Rojas static unsigned gpio15_pins[] = { 15 }; 10650554accSÁlvaro Fernández Rojas static unsigned gpio16_pins[] = { 16 }; 10750554accSÁlvaro Fernández Rojas static unsigned gpio17_pins[] = { 17 }; 10850554accSÁlvaro Fernández Rojas static unsigned gpio18_pins[] = { 18 }; 10950554accSÁlvaro Fernández Rojas static unsigned gpio19_pins[] = { 19 }; 11050554accSÁlvaro Fernández Rojas static unsigned gpio20_pins[] = { 20 }; 11150554accSÁlvaro Fernández Rojas static unsigned gpio21_pins[] = { 21 }; 11250554accSÁlvaro Fernández Rojas static unsigned gpio22_pins[] = { 22 }; 11350554accSÁlvaro Fernández Rojas static unsigned gpio23_pins[] = { 23 }; 11450554accSÁlvaro Fernández Rojas static unsigned gpio24_pins[] = { 24 }; 11550554accSÁlvaro Fernández Rojas static unsigned gpio25_pins[] = { 25 }; 11650554accSÁlvaro Fernández Rojas static unsigned gpio26_pins[] = { 26 }; 11750554accSÁlvaro Fernández Rojas static unsigned gpio27_pins[] = { 27 }; 11850554accSÁlvaro Fernández Rojas static unsigned gpio28_pins[] = { 28 }; 11950554accSÁlvaro Fernández Rojas static unsigned gpio29_pins[] = { 29 }; 12050554accSÁlvaro Fernández Rojas static unsigned gpio30_pins[] = { 30 }; 12150554accSÁlvaro Fernández Rojas static unsigned gpio31_pins[] = { 31 }; 12250554accSÁlvaro Fernández Rojas static unsigned uart1_grp_pins[] = { 30, 31, 32, 33 }; 12350554accSÁlvaro Fernández Rojas 124*0e3db163SAndy Shevchenko static struct pingroup bcm6368_groups[] = { 125*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio0), 126*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio1), 127*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio2), 128*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio3), 129*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio4), 130*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio5), 131*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio6), 132*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio7), 133*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio8), 134*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio9), 135*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio10), 136*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio11), 137*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio12), 138*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio13), 139*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio14), 140*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio15), 141*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio16), 142*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio17), 143*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio18), 144*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio19), 145*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio20), 146*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio21), 147*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio22), 148*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio23), 149*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio24), 150*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio25), 151*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio26), 152*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio27), 153*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio28), 154*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio29), 155*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio30), 156*0e3db163SAndy Shevchenko BCM_PIN_GROUP(gpio31), 157*0e3db163SAndy Shevchenko BCM_PIN_GROUP(uart1_grp), 15850554accSÁlvaro Fernández Rojas }; 15950554accSÁlvaro Fernández Rojas 16050554accSÁlvaro Fernández Rojas static const char * const analog_afe_0_groups[] = { 16150554accSÁlvaro Fernández Rojas "gpio0", 16250554accSÁlvaro Fernández Rojas }; 16350554accSÁlvaro Fernández Rojas 16450554accSÁlvaro Fernández Rojas static const char * const analog_afe_1_groups[] = { 16550554accSÁlvaro Fernández Rojas "gpio1", 16650554accSÁlvaro Fernández Rojas }; 16750554accSÁlvaro Fernández Rojas 16850554accSÁlvaro Fernández Rojas static const char * const sys_irq_groups[] = { 16950554accSÁlvaro Fernández Rojas "gpio2", 17050554accSÁlvaro Fernández Rojas }; 17150554accSÁlvaro Fernández Rojas 17250554accSÁlvaro Fernández Rojas static const char * const serial_led_data_groups[] = { 17350554accSÁlvaro Fernández Rojas "gpio3", 17450554accSÁlvaro Fernández Rojas }; 17550554accSÁlvaro Fernández Rojas 17650554accSÁlvaro Fernández Rojas static const char * const serial_led_clk_groups[] = { 17750554accSÁlvaro Fernández Rojas "gpio4", 17850554accSÁlvaro Fernández Rojas }; 17950554accSÁlvaro Fernández Rojas 18050554accSÁlvaro Fernández Rojas static const char * const inet_led_groups[] = { 18150554accSÁlvaro Fernández Rojas "gpio5", 18250554accSÁlvaro Fernández Rojas }; 18350554accSÁlvaro Fernández Rojas 18450554accSÁlvaro Fernández Rojas static const char * const ephy0_led_groups[] = { 18550554accSÁlvaro Fernández Rojas "gpio6", 18650554accSÁlvaro Fernández Rojas }; 18750554accSÁlvaro Fernández Rojas 18850554accSÁlvaro Fernández Rojas static const char * const ephy1_led_groups[] = { 18950554accSÁlvaro Fernández Rojas "gpio7", 19050554accSÁlvaro Fernández Rojas }; 19150554accSÁlvaro Fernández Rojas 19250554accSÁlvaro Fernández Rojas static const char * const ephy2_led_groups[] = { 19350554accSÁlvaro Fernández Rojas "gpio8", 19450554accSÁlvaro Fernández Rojas }; 19550554accSÁlvaro Fernández Rojas 19650554accSÁlvaro Fernández Rojas static const char * const ephy3_led_groups[] = { 19750554accSÁlvaro Fernández Rojas "gpio9", 19850554accSÁlvaro Fernández Rojas }; 19950554accSÁlvaro Fernández Rojas 20050554accSÁlvaro Fernández Rojas static const char * const robosw_led_data_groups[] = { 20150554accSÁlvaro Fernández Rojas "gpio10", 20250554accSÁlvaro Fernández Rojas }; 20350554accSÁlvaro Fernández Rojas 20450554accSÁlvaro Fernández Rojas static const char * const robosw_led_clk_groups[] = { 20550554accSÁlvaro Fernández Rojas "gpio11", 20650554accSÁlvaro Fernández Rojas }; 20750554accSÁlvaro Fernández Rojas 20850554accSÁlvaro Fernández Rojas static const char * const robosw_led0_groups[] = { 20950554accSÁlvaro Fernández Rojas "gpio12", 21050554accSÁlvaro Fernández Rojas }; 21150554accSÁlvaro Fernández Rojas 21250554accSÁlvaro Fernández Rojas static const char * const robosw_led1_groups[] = { 21350554accSÁlvaro Fernández Rojas "gpio13", 21450554accSÁlvaro Fernández Rojas }; 21550554accSÁlvaro Fernández Rojas 21650554accSÁlvaro Fernández Rojas static const char * const usb_device_led_groups[] = { 21750554accSÁlvaro Fernández Rojas "gpio14", 21850554accSÁlvaro Fernández Rojas }; 21950554accSÁlvaro Fernández Rojas 22050554accSÁlvaro Fernández Rojas static const char * const pci_req1_groups[] = { 22150554accSÁlvaro Fernández Rojas "gpio16", 22250554accSÁlvaro Fernández Rojas }; 22350554accSÁlvaro Fernández Rojas 22450554accSÁlvaro Fernández Rojas static const char * const pci_gnt1_groups[] = { 22550554accSÁlvaro Fernández Rojas "gpio17", 22650554accSÁlvaro Fernández Rojas }; 22750554accSÁlvaro Fernández Rojas 22850554accSÁlvaro Fernández Rojas static const char * const pci_intb_groups[] = { 22950554accSÁlvaro Fernández Rojas "gpio18", 23050554accSÁlvaro Fernández Rojas }; 23150554accSÁlvaro Fernández Rojas 23250554accSÁlvaro Fernández Rojas static const char * const pci_req0_groups[] = { 23350554accSÁlvaro Fernández Rojas "gpio19", 23450554accSÁlvaro Fernández Rojas }; 23550554accSÁlvaro Fernández Rojas 23650554accSÁlvaro Fernández Rojas static const char * const pci_gnt0_groups[] = { 23750554accSÁlvaro Fernández Rojas "gpio20", 23850554accSÁlvaro Fernández Rojas }; 23950554accSÁlvaro Fernández Rojas 24050554accSÁlvaro Fernández Rojas static const char * const pcmcia_cd1_groups[] = { 24150554accSÁlvaro Fernández Rojas "gpio22", 24250554accSÁlvaro Fernández Rojas }; 24350554accSÁlvaro Fernández Rojas 24450554accSÁlvaro Fernández Rojas static const char * const pcmcia_cd2_groups[] = { 24550554accSÁlvaro Fernández Rojas "gpio23", 24650554accSÁlvaro Fernández Rojas }; 24750554accSÁlvaro Fernández Rojas 24850554accSÁlvaro Fernández Rojas static const char * const pcmcia_vs1_groups[] = { 24950554accSÁlvaro Fernández Rojas "gpio24", 25050554accSÁlvaro Fernández Rojas }; 25150554accSÁlvaro Fernández Rojas 25250554accSÁlvaro Fernández Rojas static const char * const pcmcia_vs2_groups[] = { 25350554accSÁlvaro Fernández Rojas "gpio25", 25450554accSÁlvaro Fernández Rojas }; 25550554accSÁlvaro Fernández Rojas 25650554accSÁlvaro Fernández Rojas static const char * const ebi_cs2_groups[] = { 25750554accSÁlvaro Fernández Rojas "gpio26", 25850554accSÁlvaro Fernández Rojas }; 25950554accSÁlvaro Fernández Rojas 26050554accSÁlvaro Fernández Rojas static const char * const ebi_cs3_groups[] = { 26150554accSÁlvaro Fernández Rojas "gpio27", 26250554accSÁlvaro Fernández Rojas }; 26350554accSÁlvaro Fernández Rojas 26450554accSÁlvaro Fernández Rojas static const char * const spi_cs2_groups[] = { 26550554accSÁlvaro Fernández Rojas "gpio28", 26650554accSÁlvaro Fernández Rojas }; 26750554accSÁlvaro Fernández Rojas 26850554accSÁlvaro Fernández Rojas static const char * const spi_cs3_groups[] = { 26950554accSÁlvaro Fernández Rojas "gpio29", 27050554accSÁlvaro Fernández Rojas }; 27150554accSÁlvaro Fernández Rojas 27250554accSÁlvaro Fernández Rojas static const char * const spi_cs4_groups[] = { 27350554accSÁlvaro Fernández Rojas "gpio30", 27450554accSÁlvaro Fernández Rojas }; 27550554accSÁlvaro Fernández Rojas 27650554accSÁlvaro Fernández Rojas static const char * const spi_cs5_groups[] = { 27750554accSÁlvaro Fernández Rojas "gpio31", 27850554accSÁlvaro Fernández Rojas }; 27950554accSÁlvaro Fernández Rojas 28050554accSÁlvaro Fernández Rojas static const char * const uart1_groups[] = { 28150554accSÁlvaro Fernández Rojas "uart1_grp", 28250554accSÁlvaro Fernández Rojas }; 28350554accSÁlvaro Fernández Rojas 28450554accSÁlvaro Fernández Rojas #define BCM6368_FUN(n, out) \ 28550554accSÁlvaro Fernández Rojas { \ 28650554accSÁlvaro Fernández Rojas .name = #n, \ 28750554accSÁlvaro Fernández Rojas .groups = n##_groups, \ 28850554accSÁlvaro Fernández Rojas .num_groups = ARRAY_SIZE(n##_groups), \ 28950554accSÁlvaro Fernández Rojas .dir_out = out, \ 29050554accSÁlvaro Fernández Rojas } 29150554accSÁlvaro Fernández Rojas 29250554accSÁlvaro Fernández Rojas #define BCM6368_BASEMODE_FUN(n, val, out) \ 29350554accSÁlvaro Fernández Rojas { \ 29450554accSÁlvaro Fernández Rojas .name = #n, \ 29550554accSÁlvaro Fernández Rojas .groups = n##_groups, \ 29650554accSÁlvaro Fernández Rojas .num_groups = ARRAY_SIZE(n##_groups), \ 29750554accSÁlvaro Fernández Rojas .basemode = BCM6368_BASEMODE_##val, \ 29850554accSÁlvaro Fernández Rojas .dir_out = out, \ 29950554accSÁlvaro Fernández Rojas } 30050554accSÁlvaro Fernández Rojas 30150554accSÁlvaro Fernández Rojas static const struct bcm6368_function bcm6368_funcs[] = { 30250554accSÁlvaro Fernández Rojas BCM6368_FUN(analog_afe_0, 1), 30350554accSÁlvaro Fernández Rojas BCM6368_FUN(analog_afe_1, 1), 30450554accSÁlvaro Fernández Rojas BCM6368_FUN(sys_irq, 1), 30550554accSÁlvaro Fernández Rojas BCM6368_FUN(serial_led_data, 1), 30650554accSÁlvaro Fernández Rojas BCM6368_FUN(serial_led_clk, 1), 30750554accSÁlvaro Fernández Rojas BCM6368_FUN(inet_led, 1), 30850554accSÁlvaro Fernández Rojas BCM6368_FUN(ephy0_led, 1), 30950554accSÁlvaro Fernández Rojas BCM6368_FUN(ephy1_led, 1), 31050554accSÁlvaro Fernández Rojas BCM6368_FUN(ephy2_led, 1), 31150554accSÁlvaro Fernández Rojas BCM6368_FUN(ephy3_led, 1), 31250554accSÁlvaro Fernández Rojas BCM6368_FUN(robosw_led_data, 1), 31350554accSÁlvaro Fernández Rojas BCM6368_FUN(robosw_led_clk, 1), 31450554accSÁlvaro Fernández Rojas BCM6368_FUN(robosw_led0, 1), 31550554accSÁlvaro Fernández Rojas BCM6368_FUN(robosw_led1, 1), 31650554accSÁlvaro Fernández Rojas BCM6368_FUN(usb_device_led, 1), 31750554accSÁlvaro Fernández Rojas BCM6368_FUN(pci_req1, 0), 31850554accSÁlvaro Fernández Rojas BCM6368_FUN(pci_gnt1, 0), 31950554accSÁlvaro Fernández Rojas BCM6368_FUN(pci_intb, 0), 32050554accSÁlvaro Fernández Rojas BCM6368_FUN(pci_req0, 0), 32150554accSÁlvaro Fernández Rojas BCM6368_FUN(pci_gnt0, 0), 32250554accSÁlvaro Fernández Rojas BCM6368_FUN(pcmcia_cd1, 0), 32350554accSÁlvaro Fernández Rojas BCM6368_FUN(pcmcia_cd2, 0), 32450554accSÁlvaro Fernández Rojas BCM6368_FUN(pcmcia_vs1, 0), 32550554accSÁlvaro Fernández Rojas BCM6368_FUN(pcmcia_vs2, 0), 32650554accSÁlvaro Fernández Rojas BCM6368_FUN(ebi_cs2, 1), 32750554accSÁlvaro Fernández Rojas BCM6368_FUN(ebi_cs3, 1), 32850554accSÁlvaro Fernández Rojas BCM6368_FUN(spi_cs2, 1), 32950554accSÁlvaro Fernández Rojas BCM6368_FUN(spi_cs3, 1), 33050554accSÁlvaro Fernández Rojas BCM6368_FUN(spi_cs4, 1), 33150554accSÁlvaro Fernández Rojas BCM6368_FUN(spi_cs5, 1), 33250554accSÁlvaro Fernández Rojas BCM6368_BASEMODE_FUN(uart1, UART1, 0x6), 33350554accSÁlvaro Fernández Rojas }; 33450554accSÁlvaro Fernández Rojas 33550554accSÁlvaro Fernández Rojas static int bcm6368_pinctrl_get_group_count(struct pinctrl_dev *pctldev) 33650554accSÁlvaro Fernández Rojas { 33750554accSÁlvaro Fernández Rojas return ARRAY_SIZE(bcm6368_groups); 33850554accSÁlvaro Fernández Rojas } 33950554accSÁlvaro Fernández Rojas 34050554accSÁlvaro Fernández Rojas static const char *bcm6368_pinctrl_get_group_name(struct pinctrl_dev *pctldev, 34150554accSÁlvaro Fernández Rojas unsigned group) 34250554accSÁlvaro Fernández Rojas { 34350554accSÁlvaro Fernández Rojas return bcm6368_groups[group].name; 34450554accSÁlvaro Fernández Rojas } 34550554accSÁlvaro Fernández Rojas 34650554accSÁlvaro Fernández Rojas static int bcm6368_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, 34750554accSÁlvaro Fernández Rojas unsigned group, const unsigned **pins, 348*0e3db163SAndy Shevchenko unsigned *npins) 34950554accSÁlvaro Fernández Rojas { 35050554accSÁlvaro Fernández Rojas *pins = bcm6368_groups[group].pins; 351*0e3db163SAndy Shevchenko *npins = bcm6368_groups[group].npins; 35250554accSÁlvaro Fernández Rojas 35350554accSÁlvaro Fernández Rojas return 0; 35450554accSÁlvaro Fernández Rojas } 35550554accSÁlvaro Fernández Rojas 35650554accSÁlvaro Fernández Rojas static int bcm6368_pinctrl_get_func_count(struct pinctrl_dev *pctldev) 35750554accSÁlvaro Fernández Rojas { 35850554accSÁlvaro Fernández Rojas return ARRAY_SIZE(bcm6368_funcs); 35950554accSÁlvaro Fernández Rojas } 36050554accSÁlvaro Fernández Rojas 36150554accSÁlvaro Fernández Rojas static const char *bcm6368_pinctrl_get_func_name(struct pinctrl_dev *pctldev, 36250554accSÁlvaro Fernández Rojas unsigned selector) 36350554accSÁlvaro Fernández Rojas { 36450554accSÁlvaro Fernández Rojas return bcm6368_funcs[selector].name; 36550554accSÁlvaro Fernández Rojas } 36650554accSÁlvaro Fernández Rojas 36750554accSÁlvaro Fernández Rojas static int bcm6368_pinctrl_get_groups(struct pinctrl_dev *pctldev, 36850554accSÁlvaro Fernández Rojas unsigned selector, 36950554accSÁlvaro Fernández Rojas const char * const **groups, 37050554accSÁlvaro Fernández Rojas unsigned * const num_groups) 37150554accSÁlvaro Fernández Rojas { 37250554accSÁlvaro Fernández Rojas *groups = bcm6368_funcs[selector].groups; 37350554accSÁlvaro Fernández Rojas *num_groups = bcm6368_funcs[selector].num_groups; 37450554accSÁlvaro Fernández Rojas 37550554accSÁlvaro Fernández Rojas return 0; 37650554accSÁlvaro Fernández Rojas } 37750554accSÁlvaro Fernández Rojas 37850554accSÁlvaro Fernández Rojas static int bcm6368_pinctrl_set_mux(struct pinctrl_dev *pctldev, 37950554accSÁlvaro Fernández Rojas unsigned selector, unsigned group) 38050554accSÁlvaro Fernández Rojas { 38150554accSÁlvaro Fernández Rojas struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); 38250554accSÁlvaro Fernández Rojas struct bcm6368_priv *priv = pc->driver_data; 383*0e3db163SAndy Shevchenko const struct pingroup *pg = &bcm6368_groups[group]; 38450554accSÁlvaro Fernández Rojas const struct bcm6368_function *fun = &bcm6368_funcs[selector]; 38550554accSÁlvaro Fernández Rojas int i, pin; 38650554accSÁlvaro Fernández Rojas 38750554accSÁlvaro Fernández Rojas if (fun->basemode) { 38850554accSÁlvaro Fernández Rojas unsigned int mask = 0; 38950554accSÁlvaro Fernández Rojas 390*0e3db163SAndy Shevchenko for (i = 0; i < pg->npins; i++) { 39150554accSÁlvaro Fernández Rojas pin = pg->pins[i]; 39250554accSÁlvaro Fernández Rojas if (pin < BCM63XX_BANK_GPIOS) 39350554accSÁlvaro Fernández Rojas mask |= BIT(pin); 39450554accSÁlvaro Fernández Rojas } 39550554accSÁlvaro Fernández Rojas 39650554accSÁlvaro Fernández Rojas regmap_update_bits(pc->regs, BCM6368_MODE_REG, mask, 0); 39750554accSÁlvaro Fernández Rojas regmap_field_write(priv->overlays, fun->basemode); 39850554accSÁlvaro Fernández Rojas } else { 39950554accSÁlvaro Fernández Rojas pin = pg->pins[0]; 40050554accSÁlvaro Fernández Rojas 40150554accSÁlvaro Fernández Rojas if (bcm6368_pins[pin].drv_data) 40250554accSÁlvaro Fernández Rojas regmap_field_write(priv->overlays, 40350554accSÁlvaro Fernández Rojas BCM6368_BASEMODE_GPIO); 40450554accSÁlvaro Fernández Rojas 40550554accSÁlvaro Fernández Rojas regmap_update_bits(pc->regs, BCM6368_MODE_REG, BIT(pin), 40650554accSÁlvaro Fernández Rojas BIT(pin)); 40750554accSÁlvaro Fernández Rojas } 40850554accSÁlvaro Fernández Rojas 409*0e3db163SAndy Shevchenko for (pin = 0; pin < pg->npins; pin++) { 41050554accSÁlvaro Fernández Rojas struct pinctrl_gpio_range *range; 41150554accSÁlvaro Fernández Rojas int hw_gpio = bcm6368_pins[pin].number; 41250554accSÁlvaro Fernández Rojas 41350554accSÁlvaro Fernández Rojas range = pinctrl_find_gpio_range_from_pin(pctldev, hw_gpio); 41450554accSÁlvaro Fernández Rojas if (range) { 41550554accSÁlvaro Fernández Rojas struct gpio_chip *gc = range->gc; 41650554accSÁlvaro Fernández Rojas 41750554accSÁlvaro Fernández Rojas if (fun->dir_out & BIT(pin)) 41850554accSÁlvaro Fernández Rojas gc->direction_output(gc, hw_gpio, 0); 41950554accSÁlvaro Fernández Rojas else 42050554accSÁlvaro Fernández Rojas gc->direction_input(gc, hw_gpio); 42150554accSÁlvaro Fernández Rojas } 42250554accSÁlvaro Fernández Rojas } 42350554accSÁlvaro Fernández Rojas 42450554accSÁlvaro Fernández Rojas return 0; 42550554accSÁlvaro Fernández Rojas } 42650554accSÁlvaro Fernández Rojas 42750554accSÁlvaro Fernández Rojas static int bcm6368_gpio_request_enable(struct pinctrl_dev *pctldev, 42850554accSÁlvaro Fernández Rojas struct pinctrl_gpio_range *range, 42950554accSÁlvaro Fernández Rojas unsigned offset) 43050554accSÁlvaro Fernández Rojas { 43150554accSÁlvaro Fernández Rojas struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev); 43250554accSÁlvaro Fernández Rojas struct bcm6368_priv *priv = pc->driver_data; 43350554accSÁlvaro Fernández Rojas 43450554accSÁlvaro Fernández Rojas if (offset >= BCM63XX_BANK_GPIOS && !bcm6368_pins[offset].drv_data) 43550554accSÁlvaro Fernández Rojas return 0; 43650554accSÁlvaro Fernández Rojas 43750554accSÁlvaro Fernández Rojas /* disable all functions using this pin */ 43850554accSÁlvaro Fernández Rojas if (offset < BCM63XX_BANK_GPIOS) 43950554accSÁlvaro Fernández Rojas regmap_update_bits(pc->regs, BCM6368_MODE_REG, BIT(offset), 0); 44050554accSÁlvaro Fernández Rojas 44150554accSÁlvaro Fernández Rojas if (bcm6368_pins[offset].drv_data) 44250554accSÁlvaro Fernández Rojas regmap_field_write(priv->overlays, BCM6368_BASEMODE_GPIO); 44350554accSÁlvaro Fernández Rojas 44450554accSÁlvaro Fernández Rojas return 0; 44550554accSÁlvaro Fernández Rojas } 44650554accSÁlvaro Fernández Rojas 447d9779093SRikard Falkeborn static const struct pinctrl_ops bcm6368_pctl_ops = { 44850554accSÁlvaro Fernández Rojas .dt_free_map = pinctrl_utils_free_map, 44950554accSÁlvaro Fernández Rojas .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, 45050554accSÁlvaro Fernández Rojas .get_group_name = bcm6368_pinctrl_get_group_name, 45150554accSÁlvaro Fernández Rojas .get_group_pins = bcm6368_pinctrl_get_group_pins, 45250554accSÁlvaro Fernández Rojas .get_groups_count = bcm6368_pinctrl_get_group_count, 45350554accSÁlvaro Fernández Rojas }; 45450554accSÁlvaro Fernández Rojas 4550c683876SRikard Falkeborn static const struct pinmux_ops bcm6368_pmx_ops = { 45650554accSÁlvaro Fernández Rojas .get_function_groups = bcm6368_pinctrl_get_groups, 45750554accSÁlvaro Fernández Rojas .get_function_name = bcm6368_pinctrl_get_func_name, 45850554accSÁlvaro Fernández Rojas .get_functions_count = bcm6368_pinctrl_get_func_count, 45950554accSÁlvaro Fernández Rojas .gpio_request_enable = bcm6368_gpio_request_enable, 46050554accSÁlvaro Fernández Rojas .set_mux = bcm6368_pinctrl_set_mux, 46150554accSÁlvaro Fernández Rojas .strict = true, 46250554accSÁlvaro Fernández Rojas }; 46350554accSÁlvaro Fernández Rojas 46450554accSÁlvaro Fernández Rojas static const struct bcm63xx_pinctrl_soc bcm6368_soc = { 46550554accSÁlvaro Fernández Rojas .ngpios = BCM6368_NUM_GPIOS, 46650554accSÁlvaro Fernández Rojas .npins = ARRAY_SIZE(bcm6368_pins), 46750554accSÁlvaro Fernández Rojas .pctl_ops = &bcm6368_pctl_ops, 46850554accSÁlvaro Fernández Rojas .pins = bcm6368_pins, 46950554accSÁlvaro Fernández Rojas .pmx_ops = &bcm6368_pmx_ops, 47050554accSÁlvaro Fernández Rojas }; 47150554accSÁlvaro Fernández Rojas 47250554accSÁlvaro Fernández Rojas static int bcm6368_pinctrl_probe(struct platform_device *pdev) 47350554accSÁlvaro Fernández Rojas { 47450554accSÁlvaro Fernández Rojas struct reg_field overlays = REG_FIELD(BCM6368_BASEMODE_REG, 0, 15); 47550554accSÁlvaro Fernández Rojas struct device *dev = &pdev->dev; 47650554accSÁlvaro Fernández Rojas struct bcm63xx_pinctrl *pc; 47750554accSÁlvaro Fernández Rojas struct bcm6368_priv *priv; 47850554accSÁlvaro Fernández Rojas int err; 47950554accSÁlvaro Fernández Rojas 48050554accSÁlvaro Fernández Rojas priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 48150554accSÁlvaro Fernández Rojas if (!priv) 48250554accSÁlvaro Fernández Rojas return -ENOMEM; 48350554accSÁlvaro Fernández Rojas 48450554accSÁlvaro Fernández Rojas err = bcm63xx_pinctrl_probe(pdev, &bcm6368_soc, (void *) priv); 48550554accSÁlvaro Fernández Rojas if (err) 48650554accSÁlvaro Fernández Rojas return err; 48750554accSÁlvaro Fernández Rojas 48850554accSÁlvaro Fernández Rojas pc = platform_get_drvdata(pdev); 48950554accSÁlvaro Fernández Rojas 49050554accSÁlvaro Fernández Rojas priv->overlays = devm_regmap_field_alloc(dev, pc->regs, overlays); 49150554accSÁlvaro Fernández Rojas if (IS_ERR(priv->overlays)) 49250554accSÁlvaro Fernández Rojas return PTR_ERR(priv->overlays); 49350554accSÁlvaro Fernández Rojas 49450554accSÁlvaro Fernández Rojas return 0; 49550554accSÁlvaro Fernández Rojas } 49650554accSÁlvaro Fernández Rojas 49750554accSÁlvaro Fernández Rojas static const struct of_device_id bcm6368_pinctrl_match[] = { 49850554accSÁlvaro Fernández Rojas { .compatible = "brcm,bcm6368-pinctrl", }, 49950554accSÁlvaro Fernández Rojas { /* sentinel */ } 50050554accSÁlvaro Fernández Rojas }; 50150554accSÁlvaro Fernández Rojas 50250554accSÁlvaro Fernández Rojas static struct platform_driver bcm6368_pinctrl_driver = { 50350554accSÁlvaro Fernández Rojas .probe = bcm6368_pinctrl_probe, 50450554accSÁlvaro Fernández Rojas .driver = { 50550554accSÁlvaro Fernández Rojas .name = "bcm6368-pinctrl", 50650554accSÁlvaro Fernández Rojas .of_match_table = bcm6368_pinctrl_match, 50750554accSÁlvaro Fernández Rojas }, 50850554accSÁlvaro Fernández Rojas }; 50950554accSÁlvaro Fernández Rojas 51050554accSÁlvaro Fernández Rojas builtin_platform_driver(bcm6368_pinctrl_driver); 511