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
19enum {
20 MLXBF3_GPIO_HW_MODE,
21 MLXBF3_GPIO_SW_MODE,
22};
23
24struct 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
43static 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
48static 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 */
114static 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
124static int mlxbf3_get_groups_count(struct pinctrl_dev *pctldev)
125{
126 /* Number single-pin groups */
127 return MLXBF3_MAX_GPIO_PINS;
128}
129
130static 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
136static 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
148static 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 */
159static const char * const mlxbf3_gpiofunc_group_names[] = { "swctrl" };
160static const char * const mlxbf3_hwfunc_group_names[] = { "hwctrl" };
161
162static 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
167static int mlxbf3_pmx_get_funcs_count(struct pinctrl_dev *pctldev)
168{
169 return ARRAY_SIZE(mlxbf3_pmx_funcs);
170}
171
172static 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
178static 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
189static 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), addr: priv->fw_ctrl_clr0);
198 else
199 writel(BIT(group % MLXBF3_NGPIOS_GPIO0), addr: priv->fw_ctrl_clr1);
200 }
201
202 if (selector == MLXBF3_GPIO_SW_MODE) {
203 if (group < MLXBF3_NGPIOS_GPIO0)
204 writel(BIT(group), addr: priv->fw_ctrl_set0);
205 else
206 writel(BIT(group % MLXBF3_NGPIOS_GPIO0), addr: priv->fw_ctrl_set1);
207 }
208
209 return 0;
210}
211
212static 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), addr: priv->fw_ctrl_set0);
220 else
221 writel(BIT(offset % MLXBF3_NGPIOS_GPIO0), addr: priv->fw_ctrl_set1);
222
223 return 0;
224}
225
226static const struct pinmux_ops mlxbf3_pmx_ops = {
227 .get_functions_count = mlxbf3_pmx_get_funcs_count,
228 .get_function_name = mlxbf3_pmx_get_func_name,
229 .get_function_groups = mlxbf3_pmx_get_groups,
230 .set_mux = mlxbf3_pmx_set,
231 .gpio_request_enable = mlxbf3_gpio_request_enable,
232};
233
234static struct pinctrl_desc mlxbf3_pin_desc = {
235 .name = "pinctrl-mlxbf3",
236 .pins = mlxbf3_pins,
237 .npins = ARRAY_SIZE(mlxbf3_pins),
238 .pctlops = &mlxbf3_pinctrl_group_ops,
239 .pmxops = &mlxbf3_pmx_ops,
240 .owner = THIS_MODULE,
241};
242
243static_assert(ARRAY_SIZE(mlxbf3_pinctrl_single_group_names) == MLXBF3_MAX_GPIO_PINS);
244
245static int mlxbf3_pinctrl_probe(struct platform_device *pdev)
246{
247 struct device *dev = &pdev->dev;
248 struct mlxbf3_pinctrl *priv;
249 int ret;
250
251 priv = devm_kzalloc(dev, size: sizeof(*priv), GFP_KERNEL);
252 if (!priv)
253 return -ENOMEM;
254
255 priv->dev = &pdev->dev;
256
257 priv->fw_ctrl_set0 = devm_platform_ioremap_resource(pdev, index: 0);
258 if (IS_ERR(ptr: priv->fw_ctrl_set0))
259 return PTR_ERR(ptr: priv->fw_ctrl_set0);
260
261 priv->fw_ctrl_clr0 = devm_platform_ioremap_resource(pdev, index: 1);
262 if (IS_ERR(ptr: priv->fw_ctrl_set0))
263 return PTR_ERR(ptr: priv->fw_ctrl_set0);
264
265 priv->fw_ctrl_set1 = devm_platform_ioremap_resource(pdev, index: 2);
266 if (IS_ERR(ptr: priv->fw_ctrl_set0))
267 return PTR_ERR(ptr: priv->fw_ctrl_set0);
268
269 priv->fw_ctrl_clr1 = devm_platform_ioremap_resource(pdev, index: 3);
270 if (IS_ERR(ptr: priv->fw_ctrl_set0))
271 return PTR_ERR(ptr: priv->fw_ctrl_set0);
272
273 ret = devm_pinctrl_register_and_init(dev,
274 pctldesc: &mlxbf3_pin_desc,
275 driver_data: priv,
276 pctldev: &priv->pctl);
277 if (ret)
278 return dev_err_probe(dev, err: ret, fmt: "Failed to register pinctrl\n");
279
280 ret = pinctrl_enable(pctldev: priv->pctl);
281 if (ret)
282 return dev_err_probe(dev, err: ret, fmt: "Failed to enable pinctrl\n");
283
284 pinctrl_add_gpio_ranges(pctldev: priv->pctl, ranges: mlxbf3_pinctrl_gpio_ranges, nranges: 2);
285
286 return 0;
287}
288
289static const struct acpi_device_id mlxbf3_pinctrl_acpi_ids[] = {
290 { "MLNXBF34", 0 },
291 {}
292};
293MODULE_DEVICE_TABLE(acpi, mlxbf3_pinctrl_acpi_ids);
294
295static struct platform_driver mlxbf3_pinctrl_driver = {
296 .driver = {
297 .name = "pinctrl-mlxbf3",
298 .acpi_match_table = mlxbf3_pinctrl_acpi_ids,
299 },
300 .probe = mlxbf3_pinctrl_probe,
301};
302module_platform_driver(mlxbf3_pinctrl_driver);
303
304MODULE_DESCRIPTION("NVIDIA pinctrl driver");
305MODULE_AUTHOR("Asmaa Mnebhi <asmaa@nvidia.com>");
306MODULE_LICENSE("Dual BSD/GPL");
307

source code of linux/drivers/pinctrl/pinctrl-mlxbf3.c