1 // SPDX-License-Identifier: GPL-2.0-only or BSD-3-Clause
2 /* Copyright (C) 2022 NVIDIA CORPORATION & AFFILIATES */
3 
4 #include <linux/bitfield.h>
5 #include <linux/bitops.h>
6 #include <linux/err.h>
7 #include <linux/io.h>
8 #include <linux/module.h>
9 #include <linux/mod_devicetable.h>
10 #include <linux/platform_device.h>
11 #include <linux/types.h>
12 
13 #include <linux/pinctrl/pinctrl.h>
14 #include <linux/pinctrl/pinmux.h>
15 
16 #define MLXBF3_NGPIOS_GPIO0    32
17 #define MLXBF3_MAX_GPIO_PINS   56
18 
19 enum {
20 	MLXBF3_GPIO_HW_MODE,
21 	MLXBF3_GPIO_SW_MODE,
22 };
23 
24 struct mlxbf3_pinctrl {
25 	void __iomem *fw_ctrl_set0;
26 	void __iomem *fw_ctrl_clr0;
27 	void __iomem *fw_ctrl_set1;
28 	void __iomem *fw_ctrl_clr1;
29 	struct device *dev;
30 	struct pinctrl_dev *pctl;
31 	struct pinctrl_gpio_range gpio_range;
32 };
33 
34 #define MLXBF3_GPIO_RANGE(_id, _pinbase, _gpiobase, _npins)	\
35 	{							\
36 		.name = "mlxbf3_gpio_range",			\
37 		.id = _id,					\
38 		.base = _gpiobase,				\
39 		.pin_base = _pinbase,				\
40 		.npins = _npins,				\
41 	}
42 
43 static struct pinctrl_gpio_range mlxbf3_pinctrl_gpio_ranges[] = {
44 	MLXBF3_GPIO_RANGE(0, 0,  480, 32),
45 	MLXBF3_GPIO_RANGE(1,  32, 456, 24),
46 };
47 
48 static const struct pinctrl_pin_desc mlxbf3_pins[] = {
49 	PINCTRL_PIN(0, "gpio0"),
50 	PINCTRL_PIN(1, "gpio1"),
51 	PINCTRL_PIN(2, "gpio2"),
52 	PINCTRL_PIN(3, "gpio3"),
53 	PINCTRL_PIN(4, "gpio4"),
54 	PINCTRL_PIN(5, "gpio5"),
55 	PINCTRL_PIN(6, "gpio6"),
56 	PINCTRL_PIN(7, "gpio7"),
57 	PINCTRL_PIN(8, "gpio8"),
58 	PINCTRL_PIN(9, "gpio9"),
59 	PINCTRL_PIN(10, "gpio10"),
60 	PINCTRL_PIN(11, "gpio11"),
61 	PINCTRL_PIN(12, "gpio12"),
62 	PINCTRL_PIN(13, "gpio13"),
63 	PINCTRL_PIN(14, "gpio14"),
64 	PINCTRL_PIN(15, "gpio15"),
65 	PINCTRL_PIN(16, "gpio16"),
66 	PINCTRL_PIN(17, "gpio17"),
67 	PINCTRL_PIN(18, "gpio18"),
68 	PINCTRL_PIN(19, "gpio19"),
69 	PINCTRL_PIN(20, "gpio20"),
70 	PINCTRL_PIN(21, "gpio21"),
71 	PINCTRL_PIN(22, "gpio22"),
72 	PINCTRL_PIN(23, "gpio23"),
73 	PINCTRL_PIN(24, "gpio24"),
74 	PINCTRL_PIN(25, "gpio25"),
75 	PINCTRL_PIN(26, "gpio26"),
76 	PINCTRL_PIN(27, "gpio27"),
77 	PINCTRL_PIN(28, "gpio28"),
78 	PINCTRL_PIN(29, "gpio29"),
79 	PINCTRL_PIN(30, "gpio30"),
80 	PINCTRL_PIN(31, "gpio31"),
81 	PINCTRL_PIN(32, "gpio32"),
82 	PINCTRL_PIN(33, "gpio33"),
83 	PINCTRL_PIN(34, "gpio34"),
84 	PINCTRL_PIN(35, "gpio35"),
85 	PINCTRL_PIN(36, "gpio36"),
86 	PINCTRL_PIN(37, "gpio37"),
87 	PINCTRL_PIN(38, "gpio38"),
88 	PINCTRL_PIN(39, "gpio39"),
89 	PINCTRL_PIN(40, "gpio40"),
90 	PINCTRL_PIN(41, "gpio41"),
91 	PINCTRL_PIN(42, "gpio42"),
92 	PINCTRL_PIN(43, "gpio43"),
93 	PINCTRL_PIN(44, "gpio44"),
94 	PINCTRL_PIN(45, "gpio45"),
95 	PINCTRL_PIN(46, "gpio46"),
96 	PINCTRL_PIN(47, "gpio47"),
97 	PINCTRL_PIN(48, "gpio48"),
98 	PINCTRL_PIN(49, "gpio49"),
99 	PINCTRL_PIN(50, "gpio50"),
100 	PINCTRL_PIN(51, "gpio51"),
101 	PINCTRL_PIN(52, "gpio52"),
102 	PINCTRL_PIN(53, "gpio53"),
103 	PINCTRL_PIN(54, "gpio54"),
104 	PINCTRL_PIN(55, "gpio55"),
105 };
106 
107 /*
108  * All single-pin functions can be mapped to any GPIO, however pinmux applies
109  * functions to pin groups and only those groups declared as supporting that
110  * function. To make this work we must put each pin in its own dummy group so
111  * that the functions can be described as applying to all pins.
112  * We use the same name as in the datasheet.
113  */
114 static const char * const mlxbf3_pinctrl_single_group_names[] = {
115 	"gpio0", "gpio1",  "gpio2",  "gpio3",  "gpio4",  "gpio5",  "gpio6", "gpio7",
116 	"gpio8",  "gpio9",  "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", "gpio15",
117 	"gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21", "gpio22", "gpio23",
118 	"gpio24", "gpio25", "gpio26", "gpio27", "gpio28", "gpio29", "gpio30", "gpio31",
119 	"gpio32", "gpio33", "gpio34", "gpio35", "gpio36", "gpio37", "gpio38", "gpio39",
120 	"gpio40", "gpio41", "gpio42", "gpio43", "gpio44", "gpio45", "gpio46", "gpio47",
121 	"gpio48", "gpio49", "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55",
122 };
123 
124 static int mlxbf3_get_groups_count(struct pinctrl_dev *pctldev)
125 {
126 	/* Number single-pin groups */
127 	return MLXBF3_MAX_GPIO_PINS;
128 }
129 
130 static const char *mlxbf3_get_group_name(struct pinctrl_dev *pctldev,
131 					 unsigned int selector)
132 {
133 	return mlxbf3_pinctrl_single_group_names[selector];
134 }
135 
136 static int mlxbf3_get_group_pins(struct pinctrl_dev *pctldev,
137 				 unsigned int selector,
138 				 const unsigned int **pins,
139 				 unsigned int *num_pins)
140 {
141 	/* return the dummy group for a single pin */
142 	*pins = &selector;
143 	*num_pins = 1;
144 
145 	return 0;
146 }
147 
148 static const struct pinctrl_ops mlxbf3_pinctrl_group_ops = {
149 	.get_groups_count = mlxbf3_get_groups_count,
150 	.get_group_name = mlxbf3_get_group_name,
151 	.get_group_pins = mlxbf3_get_group_pins,
152 };
153 
154 /*
155  * Only 2 functions are supported and they apply to all pins:
156  * 1) Default hardware functionality
157  * 2) Software controlled GPIO
158  */
159 static const char * const mlxbf3_gpiofunc_group_names[] = { "swctrl" };
160 static const char * const mlxbf3_hwfunc_group_names[]   = { "hwctrl" };
161 
162 static struct pinfunction mlxbf3_pmx_funcs[] = {
163 	PINCTRL_PINFUNCTION("hwfunc", mlxbf3_hwfunc_group_names, 1),
164 	PINCTRL_PINFUNCTION("gpiofunc", mlxbf3_gpiofunc_group_names, 1),
165 };
166 
167 static int mlxbf3_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
168 {
169 	return ARRAY_SIZE(mlxbf3_pmx_funcs);
170 }
171 
172 static const char *mlxbf3_pmx_get_func_name(struct pinctrl_dev *pctldev,
173 					   unsigned int selector)
174 {
175 	return mlxbf3_pmx_funcs[selector].name;
176 }
177 
178 static int mlxbf3_pmx_get_groups(struct pinctrl_dev *pctldev,
179 				 unsigned int selector,
180 				 const char * const **groups,
181 				 unsigned int * const num_groups)
182 {
183 	*groups = mlxbf3_pmx_funcs[selector].groups;
184 	*num_groups = MLXBF3_MAX_GPIO_PINS;
185 
186 	return 0;
187 }
188 
189 static int mlxbf3_pmx_set(struct pinctrl_dev *pctldev,
190 			      unsigned int selector,
191 			      unsigned int group)
192 {
193 	struct mlxbf3_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev);
194 
195 	if (selector == MLXBF3_GPIO_HW_MODE) {
196 		if (group < MLXBF3_NGPIOS_GPIO0)
197 			writel(BIT(group), priv->fw_ctrl_clr0);
198 		else
199 			writel(BIT(group % MLXBF3_NGPIOS_GPIO0), priv->fw_ctrl_clr1);
200 	}
201 
202 	if (selector == MLXBF3_GPIO_SW_MODE) {
203 		if (group < MLXBF3_NGPIOS_GPIO0)
204 			writel(BIT(group), priv->fw_ctrl_set0);
205 		else
206 			writel(BIT(group % MLXBF3_NGPIOS_GPIO0), priv->fw_ctrl_set1);
207 	}
208 
209 	return 0;
210 }
211 
212 static int mlxbf3_gpio_request_enable(struct pinctrl_dev *pctldev,
213 				     struct pinctrl_gpio_range *range,
214 				     unsigned int offset)
215 {
216 	struct mlxbf3_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev);
217 
218 	if (offset < MLXBF3_NGPIOS_GPIO0)
219 		writel(BIT(offset), priv->fw_ctrl_set0);
220 	else
221 		writel(BIT(offset % MLXBF3_NGPIOS_GPIO0), priv->fw_ctrl_set1);
222 
223 	return 0;
224 }
225 
226 static void mlxbf3_gpio_disable_free(struct pinctrl_dev *pctldev,
227 				    struct pinctrl_gpio_range *range,
228 				    unsigned int offset)
229 {
230 	struct mlxbf3_pinctrl *priv = pinctrl_dev_get_drvdata(pctldev);
231 
232 	/* disable GPIO functionality by giving control back to hardware */
233 	if (offset < MLXBF3_NGPIOS_GPIO0)
234 		writel(BIT(offset), priv->fw_ctrl_clr0);
235 	else
236 		writel(BIT(offset % MLXBF3_NGPIOS_GPIO0), priv->fw_ctrl_clr1);
237 }
238 
239 static const struct pinmux_ops mlxbf3_pmx_ops = {
240 	.get_functions_count = mlxbf3_pmx_get_funcs_count,
241 	.get_function_name = mlxbf3_pmx_get_func_name,
242 	.get_function_groups = mlxbf3_pmx_get_groups,
243 	.set_mux = mlxbf3_pmx_set,
244 	.gpio_request_enable = mlxbf3_gpio_request_enable,
245 	.gpio_disable_free = mlxbf3_gpio_disable_free,
246 };
247 
248 static struct pinctrl_desc mlxbf3_pin_desc = {
249 	.name = "pinctrl-mlxbf3",
250 	.pins = mlxbf3_pins,
251 	.npins = ARRAY_SIZE(mlxbf3_pins),
252 	.pctlops = &mlxbf3_pinctrl_group_ops,
253 	.pmxops = &mlxbf3_pmx_ops,
254 	.owner = THIS_MODULE,
255 };
256 
257 static_assert(ARRAY_SIZE(mlxbf3_pinctrl_single_group_names) == MLXBF3_MAX_GPIO_PINS);
258 
259 static int mlxbf3_pinctrl_probe(struct platform_device *pdev)
260 {
261 	struct device *dev = &pdev->dev;
262 	struct mlxbf3_pinctrl *priv;
263 	int ret;
264 
265 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
266 	if (!priv)
267 		return -ENOMEM;
268 
269 	priv->dev = &pdev->dev;
270 
271 	priv->fw_ctrl_set0 = devm_platform_ioremap_resource(pdev, 0);
272 	if (IS_ERR(priv->fw_ctrl_set0))
273 		return PTR_ERR(priv->fw_ctrl_set0);
274 
275 	priv->fw_ctrl_clr0 = devm_platform_ioremap_resource(pdev, 1);
276 	if (IS_ERR(priv->fw_ctrl_set0))
277 		return PTR_ERR(priv->fw_ctrl_set0);
278 
279 	priv->fw_ctrl_set1 = devm_platform_ioremap_resource(pdev, 2);
280 	if (IS_ERR(priv->fw_ctrl_set0))
281 		return PTR_ERR(priv->fw_ctrl_set0);
282 
283 	priv->fw_ctrl_clr1 = devm_platform_ioremap_resource(pdev, 3);
284 	if (IS_ERR(priv->fw_ctrl_set0))
285 		return PTR_ERR(priv->fw_ctrl_set0);
286 
287 	ret = devm_pinctrl_register_and_init(dev,
288 					     &mlxbf3_pin_desc,
289 					     priv,
290 					     &priv->pctl);
291 	if (ret)
292 		return dev_err_probe(dev, ret, "Failed to register pinctrl\n");
293 
294 	ret = pinctrl_enable(priv->pctl);
295 	if (ret)
296 		return dev_err_probe(dev, ret, "Failed to enable pinctrl\n");
297 
298 	pinctrl_add_gpio_ranges(priv->pctl, mlxbf3_pinctrl_gpio_ranges, 2);
299 
300 	return 0;
301 }
302 
303 static const struct acpi_device_id mlxbf3_pinctrl_acpi_ids[] = {
304 	{ "MLNXBF34", 0 },
305 	{}
306 };
307 MODULE_DEVICE_TABLE(acpi, mlxbf3_pinctrl_acpi_ids);
308 
309 static struct platform_driver mlxbf3_pinctrl_driver = {
310 	.driver = {
311 		.name = "pinctrl-mlxbf3",
312 		.acpi_match_table = mlxbf3_pinctrl_acpi_ids,
313 	},
314 	.probe = mlxbf3_pinctrl_probe,
315 };
316 module_platform_driver(mlxbf3_pinctrl_driver);
317 
318 MODULE_DESCRIPTION("NVIDIA pinctrl driver");
319 MODULE_AUTHOR("Asmaa Mnebhi <asmaa@nvidia.com>");
320 MODULE_LICENSE("Dual BSD/GPL");
321