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