xref: /linux/drivers/pinctrl/bcm/pinctrl-bcm6328.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
19bf34ac5SÁlvaro Fernández Rojas // SPDX-License-Identifier: GPL-2.0+
29bf34ac5SÁlvaro Fernández Rojas /*
39bf34ac5SÁlvaro Fernández Rojas  * Driver for BCM6328 GPIO unit (pinctrl + GPIO)
49bf34ac5SÁlvaro Fernández Rojas  *
59bf34ac5SÁlvaro Fernández Rojas  * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
69bf34ac5SÁlvaro Fernández Rojas  * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
79bf34ac5SÁlvaro Fernández Rojas  */
89bf34ac5SÁlvaro Fernández Rojas 
99bf34ac5SÁlvaro Fernández Rojas #include <linux/bits.h>
109bf34ac5SÁlvaro Fernández Rojas #include <linux/gpio/driver.h>
119bf34ac5SÁlvaro Fernández Rojas #include <linux/kernel.h>
129bf34ac5SÁlvaro Fernández Rojas #include <linux/of.h>
139bf34ac5SÁlvaro Fernández Rojas #include <linux/pinctrl/pinmux.h>
149bf34ac5SÁlvaro Fernández Rojas #include <linux/platform_device.h>
159bf34ac5SÁlvaro Fernández Rojas #include <linux/regmap.h>
169bf34ac5SÁlvaro Fernández Rojas 
179bf34ac5SÁlvaro Fernández Rojas #include "../pinctrl-utils.h"
189bf34ac5SÁlvaro Fernández Rojas 
199bf34ac5SÁlvaro Fernández Rojas #include "pinctrl-bcm63xx.h"
209bf34ac5SÁlvaro Fernández Rojas 
219bf34ac5SÁlvaro Fernández Rojas #define BCM6328_NUM_GPIOS	32
229bf34ac5SÁlvaro Fernández Rojas 
239bf34ac5SÁlvaro Fernández Rojas #define BCM6328_MODE_REG	0x18
249bf34ac5SÁlvaro Fernández Rojas #define BCM6328_MUX_HI_REG	0x1c
259bf34ac5SÁlvaro Fernández Rojas #define BCM6328_MUX_LO_REG	0x20
269bf34ac5SÁlvaro Fernández Rojas #define BCM6328_MUX_OTHER_REG	0x24
279bf34ac5SÁlvaro Fernández Rojas #define  BCM6328_MUX_MASK	GENMASK(1, 0)
289bf34ac5SÁlvaro Fernández Rojas 
299bf34ac5SÁlvaro Fernández Rojas struct bcm6328_function {
309bf34ac5SÁlvaro Fernández Rojas 	const char *name;
319bf34ac5SÁlvaro Fernández Rojas 	const char * const *groups;
329bf34ac5SÁlvaro Fernández Rojas 	const unsigned num_groups;
339bf34ac5SÁlvaro Fernández Rojas 
349bf34ac5SÁlvaro Fernández Rojas 	unsigned mode_val:1;
359bf34ac5SÁlvaro Fernández Rojas 	unsigned mux_val:2;
369bf34ac5SÁlvaro Fernández Rojas };
379bf34ac5SÁlvaro Fernández Rojas 
389bf34ac5SÁlvaro Fernández Rojas static const unsigned int bcm6328_mux[] = {
399bf34ac5SÁlvaro Fernández Rojas 	BCM6328_MUX_LO_REG,
409bf34ac5SÁlvaro Fernández Rojas 	BCM6328_MUX_HI_REG,
419bf34ac5SÁlvaro Fernández Rojas 	BCM6328_MUX_OTHER_REG
429bf34ac5SÁlvaro Fernández Rojas };
439bf34ac5SÁlvaro Fernández Rojas 
449bf34ac5SÁlvaro Fernández Rojas static const struct pinctrl_pin_desc bcm6328_pins[] = {
459bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(0, "gpio0"),
469bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(1, "gpio1"),
479bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(2, "gpio2"),
489bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(3, "gpio3"),
499bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(4, "gpio4"),
509bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(5, "gpio5"),
519bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(6, "gpio6"),
529bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(7, "gpio7"),
539bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(8, "gpio8"),
549bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(9, "gpio9"),
559bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(10, "gpio10"),
569bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(11, "gpio11"),
579bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(12, "gpio12"),
589bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(13, "gpio13"),
599bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(14, "gpio14"),
609bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(15, "gpio15"),
619bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(16, "gpio16"),
629bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(17, "gpio17"),
639bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(18, "gpio18"),
649bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(19, "gpio19"),
659bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(20, "gpio20"),
669bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(21, "gpio21"),
679bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(22, "gpio22"),
689bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(23, "gpio23"),
699bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(24, "gpio24"),
709bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(25, "gpio25"),
719bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(26, "gpio26"),
729bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(27, "gpio27"),
739bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(28, "gpio28"),
749bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(29, "gpio29"),
759bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(30, "gpio30"),
769bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(31, "gpio31"),
779bf34ac5SÁlvaro Fernández Rojas 
789bf34ac5SÁlvaro Fernández Rojas 	/*
799bf34ac5SÁlvaro Fernández Rojas 	 * No idea where they really are; so let's put them according
809bf34ac5SÁlvaro Fernández Rojas 	 * to their mux offsets.
819bf34ac5SÁlvaro Fernández Rojas 	 */
829bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(36, "hsspi_cs1"),
839bf34ac5SÁlvaro Fernández Rojas 	PINCTRL_PIN(38, "usb_p2"),
849bf34ac5SÁlvaro Fernández Rojas };
859bf34ac5SÁlvaro Fernández Rojas 
869bf34ac5SÁlvaro Fernández Rojas static unsigned gpio0_pins[] = { 0 };
879bf34ac5SÁlvaro Fernández Rojas static unsigned gpio1_pins[] = { 1 };
889bf34ac5SÁlvaro Fernández Rojas static unsigned gpio2_pins[] = { 2 };
899bf34ac5SÁlvaro Fernández Rojas static unsigned gpio3_pins[] = { 3 };
909bf34ac5SÁlvaro Fernández Rojas static unsigned gpio4_pins[] = { 4 };
919bf34ac5SÁlvaro Fernández Rojas static unsigned gpio5_pins[] = { 5 };
929bf34ac5SÁlvaro Fernández Rojas static unsigned gpio6_pins[] = { 6 };
939bf34ac5SÁlvaro Fernández Rojas static unsigned gpio7_pins[] = { 7 };
949bf34ac5SÁlvaro Fernández Rojas static unsigned gpio8_pins[] = { 8 };
959bf34ac5SÁlvaro Fernández Rojas static unsigned gpio9_pins[] = { 9 };
969bf34ac5SÁlvaro Fernández Rojas static unsigned gpio10_pins[] = { 10 };
979bf34ac5SÁlvaro Fernández Rojas static unsigned gpio11_pins[] = { 11 };
989bf34ac5SÁlvaro Fernández Rojas static unsigned gpio12_pins[] = { 12 };
999bf34ac5SÁlvaro Fernández Rojas static unsigned gpio13_pins[] = { 13 };
1009bf34ac5SÁlvaro Fernández Rojas static unsigned gpio14_pins[] = { 14 };
1019bf34ac5SÁlvaro Fernández Rojas static unsigned gpio15_pins[] = { 15 };
1029bf34ac5SÁlvaro Fernández Rojas static unsigned gpio16_pins[] = { 16 };
1039bf34ac5SÁlvaro Fernández Rojas static unsigned gpio17_pins[] = { 17 };
1049bf34ac5SÁlvaro Fernández Rojas static unsigned gpio18_pins[] = { 18 };
1059bf34ac5SÁlvaro Fernández Rojas static unsigned gpio19_pins[] = { 19 };
1069bf34ac5SÁlvaro Fernández Rojas static unsigned gpio20_pins[] = { 20 };
1079bf34ac5SÁlvaro Fernández Rojas static unsigned gpio21_pins[] = { 21 };
1089bf34ac5SÁlvaro Fernández Rojas static unsigned gpio22_pins[] = { 22 };
1099bf34ac5SÁlvaro Fernández Rojas static unsigned gpio23_pins[] = { 23 };
1109bf34ac5SÁlvaro Fernández Rojas static unsigned gpio24_pins[] = { 24 };
1119bf34ac5SÁlvaro Fernández Rojas static unsigned gpio25_pins[] = { 25 };
1129bf34ac5SÁlvaro Fernández Rojas static unsigned gpio26_pins[] = { 26 };
1139bf34ac5SÁlvaro Fernández Rojas static unsigned gpio27_pins[] = { 27 };
1149bf34ac5SÁlvaro Fernández Rojas static unsigned gpio28_pins[] = { 28 };
1159bf34ac5SÁlvaro Fernández Rojas static unsigned gpio29_pins[] = { 29 };
1169bf34ac5SÁlvaro Fernández Rojas static unsigned gpio30_pins[] = { 30 };
1179bf34ac5SÁlvaro Fernández Rojas static unsigned gpio31_pins[] = { 31 };
1189bf34ac5SÁlvaro Fernández Rojas 
1199bf34ac5SÁlvaro Fernández Rojas static unsigned hsspi_cs1_pins[] = { 36 };
1209bf34ac5SÁlvaro Fernández Rojas static unsigned usb_port1_pins[] = { 38 };
1219bf34ac5SÁlvaro Fernández Rojas 
122*0e3db163SAndy Shevchenko static struct pingroup bcm6328_groups[] = {
123*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio0),
124*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio1),
125*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio2),
126*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio3),
127*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio4),
128*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio5),
129*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio6),
130*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio7),
131*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio8),
132*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio9),
133*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio10),
134*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio11),
135*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio12),
136*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio13),
137*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio14),
138*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio15),
139*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio16),
140*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio17),
141*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio18),
142*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio19),
143*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio20),
144*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio21),
145*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio22),
146*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio23),
147*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio24),
148*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio25),
149*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio26),
150*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio27),
151*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio28),
152*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio29),
153*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio30),
154*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(gpio31),
1559bf34ac5SÁlvaro Fernández Rojas 
156*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(hsspi_cs1),
157*0e3db163SAndy Shevchenko 	BCM_PIN_GROUP(usb_port1),
1589bf34ac5SÁlvaro Fernández Rojas };
1599bf34ac5SÁlvaro Fernández Rojas 
1609bf34ac5SÁlvaro Fernández Rojas /* GPIO_MODE */
1619bf34ac5SÁlvaro Fernández Rojas static const char * const led_groups[] = {
1629bf34ac5SÁlvaro Fernández Rojas 	"gpio0",
1639bf34ac5SÁlvaro Fernández Rojas 	"gpio1",
1649bf34ac5SÁlvaro Fernández Rojas 	"gpio2",
1659bf34ac5SÁlvaro Fernández Rojas 	"gpio3",
1669bf34ac5SÁlvaro Fernández Rojas 	"gpio4",
1679bf34ac5SÁlvaro Fernández Rojas 	"gpio5",
1689bf34ac5SÁlvaro Fernández Rojas 	"gpio6",
1699bf34ac5SÁlvaro Fernández Rojas 	"gpio7",
1709bf34ac5SÁlvaro Fernández Rojas 	"gpio8",
1719bf34ac5SÁlvaro Fernández Rojas 	"gpio9",
1729bf34ac5SÁlvaro Fernández Rojas 	"gpio10",
1739bf34ac5SÁlvaro Fernández Rojas 	"gpio11",
1749bf34ac5SÁlvaro Fernández Rojas 	"gpio12",
1759bf34ac5SÁlvaro Fernández Rojas 	"gpio13",
1769bf34ac5SÁlvaro Fernández Rojas 	"gpio14",
1779bf34ac5SÁlvaro Fernández Rojas 	"gpio15",
1789bf34ac5SÁlvaro Fernández Rojas 	"gpio16",
1799bf34ac5SÁlvaro Fernández Rojas 	"gpio17",
1809bf34ac5SÁlvaro Fernández Rojas 	"gpio18",
1819bf34ac5SÁlvaro Fernández Rojas 	"gpio19",
1829bf34ac5SÁlvaro Fernández Rojas 	"gpio20",
1839bf34ac5SÁlvaro Fernández Rojas 	"gpio21",
1849bf34ac5SÁlvaro Fernández Rojas 	"gpio22",
1859bf34ac5SÁlvaro Fernández Rojas 	"gpio23",
1869bf34ac5SÁlvaro Fernández Rojas };
1879bf34ac5SÁlvaro Fernández Rojas 
1889bf34ac5SÁlvaro Fernández Rojas /* PINMUX_SEL */
1899bf34ac5SÁlvaro Fernández Rojas static const char * const serial_led_data_groups[] = {
1909bf34ac5SÁlvaro Fernández Rojas 	"gpio6",
1919bf34ac5SÁlvaro Fernández Rojas };
1929bf34ac5SÁlvaro Fernández Rojas 
1939bf34ac5SÁlvaro Fernández Rojas static const char * const serial_led_clk_groups[] = {
1949bf34ac5SÁlvaro Fernández Rojas 	"gpio7",
1959bf34ac5SÁlvaro Fernández Rojas };
1969bf34ac5SÁlvaro Fernández Rojas 
1979bf34ac5SÁlvaro Fernández Rojas static const char * const inet_act_led_groups[] = {
1989bf34ac5SÁlvaro Fernández Rojas 	"gpio11",
1999bf34ac5SÁlvaro Fernández Rojas };
2009bf34ac5SÁlvaro Fernández Rojas 
2019bf34ac5SÁlvaro Fernández Rojas static const char * const pcie_clkreq_groups[] = {
2029bf34ac5SÁlvaro Fernández Rojas 	"gpio16",
2039bf34ac5SÁlvaro Fernández Rojas };
2049bf34ac5SÁlvaro Fernández Rojas 
2059bf34ac5SÁlvaro Fernández Rojas static const char * const ephy0_act_led_groups[] = {
2069bf34ac5SÁlvaro Fernández Rojas 	"gpio25",
2079bf34ac5SÁlvaro Fernández Rojas };
2089bf34ac5SÁlvaro Fernández Rojas 
2099bf34ac5SÁlvaro Fernández Rojas static const char * const ephy1_act_led_groups[] = {
2109bf34ac5SÁlvaro Fernández Rojas 	"gpio26",
2119bf34ac5SÁlvaro Fernández Rojas };
2129bf34ac5SÁlvaro Fernández Rojas 
2139bf34ac5SÁlvaro Fernández Rojas static const char * const ephy2_act_led_groups[] = {
2149bf34ac5SÁlvaro Fernández Rojas 	"gpio27",
2159bf34ac5SÁlvaro Fernández Rojas };
2169bf34ac5SÁlvaro Fernández Rojas 
2179bf34ac5SÁlvaro Fernández Rojas static const char * const ephy3_act_led_groups[] = {
2189bf34ac5SÁlvaro Fernández Rojas 	"gpio28",
2199bf34ac5SÁlvaro Fernández Rojas };
2209bf34ac5SÁlvaro Fernández Rojas 
2219bf34ac5SÁlvaro Fernández Rojas static const char * const hsspi_cs1_groups[] = {
2229bf34ac5SÁlvaro Fernández Rojas 	"hsspi_cs1"
2239bf34ac5SÁlvaro Fernández Rojas };
2249bf34ac5SÁlvaro Fernández Rojas 
2259bf34ac5SÁlvaro Fernández Rojas static const char * const usb_host_port_groups[] = {
2269bf34ac5SÁlvaro Fernández Rojas 	"usb_port1",
2279bf34ac5SÁlvaro Fernández Rojas };
2289bf34ac5SÁlvaro Fernández Rojas 
2299bf34ac5SÁlvaro Fernández Rojas static const char * const usb_device_port_groups[] = {
2309bf34ac5SÁlvaro Fernández Rojas 	"usb_port1",
2319bf34ac5SÁlvaro Fernández Rojas };
2329bf34ac5SÁlvaro Fernández Rojas 
2339bf34ac5SÁlvaro Fernández Rojas #define BCM6328_MODE_FUN(n)				\
2349bf34ac5SÁlvaro Fernández Rojas 	{						\
2359bf34ac5SÁlvaro Fernández Rojas 		.name = #n,				\
2369bf34ac5SÁlvaro Fernández Rojas 		.groups = n##_groups,			\
2379bf34ac5SÁlvaro Fernández Rojas 		.num_groups = ARRAY_SIZE(n##_groups),	\
2389bf34ac5SÁlvaro Fernández Rojas 		.mode_val = 1,				\
2399bf34ac5SÁlvaro Fernández Rojas 	}
2409bf34ac5SÁlvaro Fernández Rojas 
2419bf34ac5SÁlvaro Fernández Rojas #define BCM6328_MUX_FUN(n, mux)				\
2429bf34ac5SÁlvaro Fernández Rojas 	{						\
2439bf34ac5SÁlvaro Fernández Rojas 		.name = #n,				\
2449bf34ac5SÁlvaro Fernández Rojas 		.groups = n##_groups,			\
2459bf34ac5SÁlvaro Fernández Rojas 		.num_groups = ARRAY_SIZE(n##_groups),	\
2469bf34ac5SÁlvaro Fernández Rojas 		.mux_val = mux,				\
2479bf34ac5SÁlvaro Fernández Rojas 	}
2489bf34ac5SÁlvaro Fernández Rojas 
2499bf34ac5SÁlvaro Fernández Rojas static const struct bcm6328_function bcm6328_funcs[] = {
2509bf34ac5SÁlvaro Fernández Rojas 	BCM6328_MODE_FUN(led),
2519bf34ac5SÁlvaro Fernández Rojas 	BCM6328_MUX_FUN(serial_led_data, 2),
2529bf34ac5SÁlvaro Fernández Rojas 	BCM6328_MUX_FUN(serial_led_clk, 2),
2539bf34ac5SÁlvaro Fernández Rojas 	BCM6328_MUX_FUN(inet_act_led, 1),
2549bf34ac5SÁlvaro Fernández Rojas 	BCM6328_MUX_FUN(pcie_clkreq, 2),
2559bf34ac5SÁlvaro Fernández Rojas 	BCM6328_MUX_FUN(ephy0_act_led, 1),
2569bf34ac5SÁlvaro Fernández Rojas 	BCM6328_MUX_FUN(ephy1_act_led, 1),
2579bf34ac5SÁlvaro Fernández Rojas 	BCM6328_MUX_FUN(ephy2_act_led, 1),
2589bf34ac5SÁlvaro Fernández Rojas 	BCM6328_MUX_FUN(ephy3_act_led, 1),
2599bf34ac5SÁlvaro Fernández Rojas 	BCM6328_MUX_FUN(hsspi_cs1, 2),
2609bf34ac5SÁlvaro Fernández Rojas 	BCM6328_MUX_FUN(usb_host_port, 1),
2619bf34ac5SÁlvaro Fernández Rojas 	BCM6328_MUX_FUN(usb_device_port, 2),
2629bf34ac5SÁlvaro Fernández Rojas };
2639bf34ac5SÁlvaro Fernández Rojas 
bcm6328_mux_off(unsigned int pin)2649bf34ac5SÁlvaro Fernández Rojas static inline unsigned int bcm6328_mux_off(unsigned int pin)
2659bf34ac5SÁlvaro Fernández Rojas {
2669bf34ac5SÁlvaro Fernández Rojas 	return bcm6328_mux[pin / 16];
2679bf34ac5SÁlvaro Fernández Rojas }
2689bf34ac5SÁlvaro Fernández Rojas 
bcm6328_pinctrl_get_group_count(struct pinctrl_dev * pctldev)2699bf34ac5SÁlvaro Fernández Rojas static int bcm6328_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
2709bf34ac5SÁlvaro Fernández Rojas {
2719bf34ac5SÁlvaro Fernández Rojas 	return ARRAY_SIZE(bcm6328_groups);
2729bf34ac5SÁlvaro Fernández Rojas }
2739bf34ac5SÁlvaro Fernández Rojas 
bcm6328_pinctrl_get_group_name(struct pinctrl_dev * pctldev,unsigned group)2749bf34ac5SÁlvaro Fernández Rojas static const char *bcm6328_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
2759bf34ac5SÁlvaro Fernández Rojas 						  unsigned group)
2769bf34ac5SÁlvaro Fernández Rojas {
2779bf34ac5SÁlvaro Fernández Rojas 	return bcm6328_groups[group].name;
2789bf34ac5SÁlvaro Fernández Rojas }
2799bf34ac5SÁlvaro Fernández Rojas 
bcm6328_pinctrl_get_group_pins(struct pinctrl_dev * pctldev,unsigned group,const unsigned ** pins,unsigned * npins)2809bf34ac5SÁlvaro Fernández Rojas static int bcm6328_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
2819bf34ac5SÁlvaro Fernández Rojas 					  unsigned group, const unsigned **pins,
282*0e3db163SAndy Shevchenko 					  unsigned *npins)
2839bf34ac5SÁlvaro Fernández Rojas {
2849bf34ac5SÁlvaro Fernández Rojas 	*pins = bcm6328_groups[group].pins;
285*0e3db163SAndy Shevchenko 	*npins = bcm6328_groups[group].npins;
2869bf34ac5SÁlvaro Fernández Rojas 
2879bf34ac5SÁlvaro Fernández Rojas 	return 0;
2889bf34ac5SÁlvaro Fernández Rojas }
2899bf34ac5SÁlvaro Fernández Rojas 
bcm6328_pinctrl_get_func_count(struct pinctrl_dev * pctldev)2909bf34ac5SÁlvaro Fernández Rojas static int bcm6328_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
2919bf34ac5SÁlvaro Fernández Rojas {
2929bf34ac5SÁlvaro Fernández Rojas 	return ARRAY_SIZE(bcm6328_funcs);
2939bf34ac5SÁlvaro Fernández Rojas }
2949bf34ac5SÁlvaro Fernández Rojas 
bcm6328_pinctrl_get_func_name(struct pinctrl_dev * pctldev,unsigned selector)2959bf34ac5SÁlvaro Fernández Rojas static const char *bcm6328_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
2969bf34ac5SÁlvaro Fernández Rojas 						 unsigned selector)
2979bf34ac5SÁlvaro Fernández Rojas {
2989bf34ac5SÁlvaro Fernández Rojas 	return bcm6328_funcs[selector].name;
2999bf34ac5SÁlvaro Fernández Rojas }
3009bf34ac5SÁlvaro Fernández Rojas 
bcm6328_pinctrl_get_groups(struct pinctrl_dev * pctldev,unsigned selector,const char * const ** groups,unsigned * const num_groups)3019bf34ac5SÁlvaro Fernández Rojas static int bcm6328_pinctrl_get_groups(struct pinctrl_dev *pctldev,
3029bf34ac5SÁlvaro Fernández Rojas 				      unsigned selector,
3039bf34ac5SÁlvaro Fernández Rojas 				      const char * const **groups,
3049bf34ac5SÁlvaro Fernández Rojas 				      unsigned * const num_groups)
3059bf34ac5SÁlvaro Fernández Rojas {
3069bf34ac5SÁlvaro Fernández Rojas 	*groups = bcm6328_funcs[selector].groups;
3079bf34ac5SÁlvaro Fernández Rojas 	*num_groups = bcm6328_funcs[selector].num_groups;
3089bf34ac5SÁlvaro Fernández Rojas 
3099bf34ac5SÁlvaro Fernández Rojas 	return 0;
3109bf34ac5SÁlvaro Fernández Rojas }
3119bf34ac5SÁlvaro Fernández Rojas 
bcm6328_rmw_mux(struct bcm63xx_pinctrl * pc,unsigned pin,unsigned int mode,unsigned int mux)3129bf34ac5SÁlvaro Fernández Rojas static void bcm6328_rmw_mux(struct bcm63xx_pinctrl *pc, unsigned pin,
3139bf34ac5SÁlvaro Fernández Rojas 			    unsigned int mode, unsigned int mux)
3149bf34ac5SÁlvaro Fernández Rojas {
3159bf34ac5SÁlvaro Fernández Rojas 	if (pin < BCM6328_NUM_GPIOS)
3169bf34ac5SÁlvaro Fernández Rojas 		regmap_update_bits(pc->regs, BCM6328_MODE_REG, BIT(pin),
3179bf34ac5SÁlvaro Fernández Rojas 				   mode ? BIT(pin) : 0);
3189bf34ac5SÁlvaro Fernández Rojas 
3199bf34ac5SÁlvaro Fernández Rojas 	regmap_update_bits(pc->regs, bcm6328_mux_off(pin),
3209bf34ac5SÁlvaro Fernández Rojas 			   BCM6328_MUX_MASK << ((pin % 16) * 2),
3219bf34ac5SÁlvaro Fernández Rojas 			   mux << ((pin % 16) * 2));
3229bf34ac5SÁlvaro Fernández Rojas }
3239bf34ac5SÁlvaro Fernández Rojas 
bcm6328_pinctrl_set_mux(struct pinctrl_dev * pctldev,unsigned selector,unsigned group)3249bf34ac5SÁlvaro Fernández Rojas static int bcm6328_pinctrl_set_mux(struct pinctrl_dev *pctldev,
3259bf34ac5SÁlvaro Fernández Rojas 				   unsigned selector, unsigned group)
3269bf34ac5SÁlvaro Fernández Rojas {
3279bf34ac5SÁlvaro Fernández Rojas 	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
328*0e3db163SAndy Shevchenko 	const struct pingroup *pg = &bcm6328_groups[group];
3299bf34ac5SÁlvaro Fernández Rojas 	const struct bcm6328_function *f = &bcm6328_funcs[selector];
3309bf34ac5SÁlvaro Fernández Rojas 
3319bf34ac5SÁlvaro Fernández Rojas 	bcm6328_rmw_mux(pc, pg->pins[0], f->mode_val, f->mux_val);
3329bf34ac5SÁlvaro Fernández Rojas 
3339bf34ac5SÁlvaro Fernández Rojas 	return 0;
3349bf34ac5SÁlvaro Fernández Rojas }
3359bf34ac5SÁlvaro Fernández Rojas 
bcm6328_gpio_request_enable(struct pinctrl_dev * pctldev,struct pinctrl_gpio_range * range,unsigned offset)3369bf34ac5SÁlvaro Fernández Rojas static int bcm6328_gpio_request_enable(struct pinctrl_dev *pctldev,
3379bf34ac5SÁlvaro Fernández Rojas 				       struct pinctrl_gpio_range *range,
3389bf34ac5SÁlvaro Fernández Rojas 				       unsigned offset)
3399bf34ac5SÁlvaro Fernández Rojas {
3409bf34ac5SÁlvaro Fernández Rojas 	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
3419bf34ac5SÁlvaro Fernández Rojas 
3429bf34ac5SÁlvaro Fernández Rojas 	/* disable all functions using this pin */
3439bf34ac5SÁlvaro Fernández Rojas 	bcm6328_rmw_mux(pc, offset, 0, 0);
3449bf34ac5SÁlvaro Fernández Rojas 
3459bf34ac5SÁlvaro Fernández Rojas 	return 0;
3469bf34ac5SÁlvaro Fernández Rojas }
3479bf34ac5SÁlvaro Fernández Rojas 
348d9779093SRikard Falkeborn static const struct pinctrl_ops bcm6328_pctl_ops = {
3499bf34ac5SÁlvaro Fernández Rojas 	.dt_free_map = pinctrl_utils_free_map,
3509bf34ac5SÁlvaro Fernández Rojas 	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
3519bf34ac5SÁlvaro Fernández Rojas 	.get_group_name = bcm6328_pinctrl_get_group_name,
3529bf34ac5SÁlvaro Fernández Rojas 	.get_group_pins = bcm6328_pinctrl_get_group_pins,
3539bf34ac5SÁlvaro Fernández Rojas 	.get_groups_count = bcm6328_pinctrl_get_group_count,
3549bf34ac5SÁlvaro Fernández Rojas };
3559bf34ac5SÁlvaro Fernández Rojas 
3560c683876SRikard Falkeborn static const struct pinmux_ops bcm6328_pmx_ops = {
3579bf34ac5SÁlvaro Fernández Rojas 	.get_function_groups = bcm6328_pinctrl_get_groups,
3589bf34ac5SÁlvaro Fernández Rojas 	.get_function_name = bcm6328_pinctrl_get_func_name,
3599bf34ac5SÁlvaro Fernández Rojas 	.get_functions_count = bcm6328_pinctrl_get_func_count,
3609bf34ac5SÁlvaro Fernández Rojas 	.gpio_request_enable = bcm6328_gpio_request_enable,
3619bf34ac5SÁlvaro Fernández Rojas 	.set_mux = bcm6328_pinctrl_set_mux,
3629bf34ac5SÁlvaro Fernández Rojas 	.strict = true,
3639bf34ac5SÁlvaro Fernández Rojas };
3649bf34ac5SÁlvaro Fernández Rojas 
3659bf34ac5SÁlvaro Fernández Rojas static const struct bcm63xx_pinctrl_soc bcm6328_soc = {
3669bf34ac5SÁlvaro Fernández Rojas 	.ngpios = BCM6328_NUM_GPIOS,
3679bf34ac5SÁlvaro Fernández Rojas 	.npins = ARRAY_SIZE(bcm6328_pins),
3689bf34ac5SÁlvaro Fernández Rojas 	.pctl_ops = &bcm6328_pctl_ops,
3699bf34ac5SÁlvaro Fernández Rojas 	.pins = bcm6328_pins,
3709bf34ac5SÁlvaro Fernández Rojas 	.pmx_ops = &bcm6328_pmx_ops,
3719bf34ac5SÁlvaro Fernández Rojas };
3729bf34ac5SÁlvaro Fernández Rojas 
bcm6328_pinctrl_probe(struct platform_device * pdev)3739bf34ac5SÁlvaro Fernández Rojas static int bcm6328_pinctrl_probe(struct platform_device *pdev)
3749bf34ac5SÁlvaro Fernández Rojas {
3759bf34ac5SÁlvaro Fernández Rojas 	return bcm63xx_pinctrl_probe(pdev, &bcm6328_soc, NULL);
3769bf34ac5SÁlvaro Fernández Rojas }
3779bf34ac5SÁlvaro Fernández Rojas 
3789bf34ac5SÁlvaro Fernández Rojas static const struct of_device_id bcm6328_pinctrl_match[] = {
3799bf34ac5SÁlvaro Fernández Rojas 	{ .compatible = "brcm,bcm6328-pinctrl", },
3809bf34ac5SÁlvaro Fernández Rojas 	{ /* sentinel */ }
3819bf34ac5SÁlvaro Fernández Rojas };
3829bf34ac5SÁlvaro Fernández Rojas 
3839bf34ac5SÁlvaro Fernández Rojas static struct platform_driver bcm6328_pinctrl_driver = {
3849bf34ac5SÁlvaro Fernández Rojas 	.probe = bcm6328_pinctrl_probe,
3859bf34ac5SÁlvaro Fernández Rojas 	.driver = {
3869bf34ac5SÁlvaro Fernández Rojas 		.name = "bcm6328-pinctrl",
3879bf34ac5SÁlvaro Fernández Rojas 		.of_match_table = bcm6328_pinctrl_match,
3889bf34ac5SÁlvaro Fernández Rojas 	},
3899bf34ac5SÁlvaro Fernández Rojas };
3909bf34ac5SÁlvaro Fernández Rojas 
3919bf34ac5SÁlvaro Fernández Rojas builtin_platform_driver(bcm6328_pinctrl_driver);
392