pinctrl-ns.c (1758047057dbe329be712a31b79db7151b5871f8) pinctrl-ns.c (4b1643cb57da8df86c02a0826cb12ed750abaed7)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2018 Rafał Miłecki <rafal@milecki.pl>
4 */
5
6#include <linux/err.h>
7#include <linux/io.h>
8#include <linux/module.h>
9#include <linux/of.h>
10#include <linux/of_device.h>
11#include <linux/pinctrl/pinconf-generic.h>
12#include <linux/pinctrl/pinctrl.h>
13#include <linux/pinctrl/pinmux.h>
14#include <linux/platform_device.h>
15#include <linux/slab.h>
16
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2018 Rafał Miłecki <rafal@milecki.pl>
4 */
5
6#include <linux/err.h>
7#include <linux/io.h>
8#include <linux/module.h>
9#include <linux/of.h>
10#include <linux/of_device.h>
11#include <linux/pinctrl/pinconf-generic.h>
12#include <linux/pinctrl/pinctrl.h>
13#include <linux/pinctrl/pinmux.h>
14#include <linux/platform_device.h>
15#include <linux/slab.h>
16
17#include "../core.h"
18#include "../pinmux.h"
19
17#define FLAG_BCM4708 BIT(1)
18#define FLAG_BCM4709 BIT(2)
19#define FLAG_BCM53012 BIT(3)
20
21struct ns_pinctrl {
22 struct device *dev;
23 unsigned int chipset_flag;
24 struct pinctrl_dev *pctldev;
25 void __iomem *base;
26
27 struct pinctrl_desc pctldesc;
20#define FLAG_BCM4708 BIT(1)
21#define FLAG_BCM4709 BIT(2)
22#define FLAG_BCM53012 BIT(3)
23
24struct ns_pinctrl {
25 struct device *dev;
26 unsigned int chipset_flag;
27 struct pinctrl_dev *pctldev;
28 void __iomem *base;
29
30 struct pinctrl_desc pctldesc;
28 struct ns_pinctrl_group *groups;
29 unsigned int num_groups;
30 struct ns_pinctrl_function *functions;
31 unsigned int num_functions;
32};
33
34/*
35 * Pins
36 */
37
38static const struct pinctrl_pin_desc ns_pinctrl_pins[] = {
39 { 0, "spi_clk", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },

--- 20 unchanged lines hidden (view full) ---

60};
61
62/*
63 * Groups
64 */
65
66struct ns_pinctrl_group {
67 const char *name;
31};
32
33/*
34 * Pins
35 */
36
37static const struct pinctrl_pin_desc ns_pinctrl_pins[] = {
38 { 0, "spi_clk", (void *)(FLAG_BCM4708 | FLAG_BCM4709 | FLAG_BCM53012) },

--- 20 unchanged lines hidden (view full) ---

59};
60
61/*
62 * Groups
63 */
64
65struct ns_pinctrl_group {
66 const char *name;
68 const unsigned int *pins;
67 unsigned int *pins;
69 const unsigned int num_pins;
70 unsigned int chipsets;
71};
72
68 const unsigned int num_pins;
69 unsigned int chipsets;
70};
71
73static const unsigned int spi_pins[] = { 0, 1, 2, 3 };
74static const unsigned int i2c_pins[] = { 4, 5 };
75static const unsigned int mdio_pins[] = { 6, 7 };
76static const unsigned int pwm0_pins[] = { 8 };
77static const unsigned int pwm1_pins[] = { 9 };
78static const unsigned int pwm2_pins[] = { 10 };
79static const unsigned int pwm3_pins[] = { 11 };
80static const unsigned int uart1_pins[] = { 12, 13, 14, 15 };
81static const unsigned int uart2_pins[] = { 16, 17 };
82static const unsigned int sdio_pwr_pins[] = { 22 };
83static const unsigned int sdio_1p8v_pins[] = { 23 };
72static unsigned int spi_pins[] = { 0, 1, 2, 3 };
73static unsigned int i2c_pins[] = { 4, 5 };
74static unsigned int mdio_pins[] = { 6, 7 };
75static unsigned int pwm0_pins[] = { 8 };
76static unsigned int pwm1_pins[] = { 9 };
77static unsigned int pwm2_pins[] = { 10 };
78static unsigned int pwm3_pins[] = { 11 };
79static unsigned int uart1_pins[] = { 12, 13, 14, 15 };
80static unsigned int uart2_pins[] = { 16, 17 };
81static unsigned int sdio_pwr_pins[] = { 22 };
82static unsigned int sdio_1p8v_pins[] = { 23 };
84
85#define NS_GROUP(_name, _pins, _chipsets) \
86{ \
87 .name = _name, \
88 .pins = _pins, \
89 .num_pins = ARRAY_SIZE(_pins), \
90 .chipsets = _chipsets, \
91}

--- 49 unchanged lines hidden (view full) ---

141 NS_FUNCTION("uart2", uart2_groups, FLAG_BCM4709 | FLAG_BCM53012),
142 NS_FUNCTION("sdio", sdio_groups, FLAG_BCM4709 | FLAG_BCM53012),
143};
144
145/*
146 * Groups code
147 */
148
83
84#define NS_GROUP(_name, _pins, _chipsets) \
85{ \
86 .name = _name, \
87 .pins = _pins, \
88 .num_pins = ARRAY_SIZE(_pins), \
89 .chipsets = _chipsets, \
90}

--- 49 unchanged lines hidden (view full) ---

140 NS_FUNCTION("uart2", uart2_groups, FLAG_BCM4709 | FLAG_BCM53012),
141 NS_FUNCTION("sdio", sdio_groups, FLAG_BCM4709 | FLAG_BCM53012),
142};
143
144/*
145 * Groups code
146 */
147
149static int ns_pinctrl_get_groups_count(struct pinctrl_dev *pctrl_dev)
150{
151 struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
152
153 return ns_pinctrl->num_groups;
154}
155
156static const char *ns_pinctrl_get_group_name(struct pinctrl_dev *pctrl_dev,
157 unsigned int selector)
158{
159 struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
160
161 return ns_pinctrl->groups[selector].name;
162}
163
164static int ns_pinctrl_get_group_pins(struct pinctrl_dev *pctrl_dev,
165 unsigned int selector,
166 const unsigned int **pins,
167 unsigned int *num_pins)
168{
169 struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
170
171 *pins = ns_pinctrl->groups[selector].pins;
172 *num_pins = ns_pinctrl->groups[selector].num_pins;
173
174 return 0;
175}
176
177static const struct pinctrl_ops ns_pinctrl_ops = {
148static const struct pinctrl_ops ns_pinctrl_ops = {
178 .get_groups_count = ns_pinctrl_get_groups_count,
179 .get_group_name = ns_pinctrl_get_group_name,
180 .get_group_pins = ns_pinctrl_get_group_pins,
149 .get_groups_count = pinctrl_generic_get_group_count,
150 .get_group_name = pinctrl_generic_get_group_name,
151 .get_group_pins = pinctrl_generic_get_group_pins,
181 .dt_node_to_map = pinconf_generic_dt_node_to_map_group,
182 .dt_free_map = pinconf_generic_dt_free_map,
183};
184
185/*
186 * Functions code
187 */
188
152 .dt_node_to_map = pinconf_generic_dt_node_to_map_group,
153 .dt_free_map = pinconf_generic_dt_free_map,
154};
155
156/*
157 * Functions code
158 */
159
189static int ns_pinctrl_get_functions_count(struct pinctrl_dev *pctrl_dev)
190{
191 struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
192
193 return ns_pinctrl->num_functions;
194}
195
196static const char *ns_pinctrl_get_function_name(struct pinctrl_dev *pctrl_dev,
197 unsigned int selector)
198{
199 struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
200
201 return ns_pinctrl->functions[selector].name;
202}
203
204static int ns_pinctrl_get_function_groups(struct pinctrl_dev *pctrl_dev,
205 unsigned int selector,
206 const char * const **groups,
207 unsigned * const num_groups)
208{
209 struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
210
211 *groups = ns_pinctrl->functions[selector].groups;
212 *num_groups = ns_pinctrl->functions[selector].num_groups;
213
214 return 0;
215}
216
217static int ns_pinctrl_set_mux(struct pinctrl_dev *pctrl_dev,
218 unsigned int func_select,
160static int ns_pinctrl_set_mux(struct pinctrl_dev *pctrl_dev,
161 unsigned int func_select,
219 unsigned int grp_select)
162 unsigned int group_selector)
220{
221 struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
163{
164 struct ns_pinctrl *ns_pinctrl = pinctrl_dev_get_drvdata(pctrl_dev);
165 struct group_desc *group;
222 u32 unset = 0;
223 u32 tmp;
224 int i;
225
166 u32 unset = 0;
167 u32 tmp;
168 int i;
169
226 for (i = 0; i < ns_pinctrl->groups[grp_select].num_pins; i++) {
227 int pin_number = ns_pinctrl->groups[grp_select].pins[i];
170 group = pinctrl_generic_get_group(pctrl_dev, group_selector);
171 if (!group)
172 return -EINVAL;
228
173
229 unset |= BIT(pin_number);
230 }
174 for (i = 0; i < group->num_pins; i++)
175 unset |= BIT(group->pins[i]);
231
232 tmp = readl(ns_pinctrl->base);
233 tmp &= ~unset;
234 writel(tmp, ns_pinctrl->base);
235
236 return 0;
237}
238
239static const struct pinmux_ops ns_pinctrl_pmxops = {
176
177 tmp = readl(ns_pinctrl->base);
178 tmp &= ~unset;
179 writel(tmp, ns_pinctrl->base);
180
181 return 0;
182}
183
184static const struct pinmux_ops ns_pinctrl_pmxops = {
240 .get_functions_count = ns_pinctrl_get_functions_count,
241 .get_function_name = ns_pinctrl_get_function_name,
242 .get_function_groups = ns_pinctrl_get_function_groups,
185 .get_functions_count = pinmux_generic_get_function_count,
186 .get_function_name = pinmux_generic_get_function_name,
187 .get_function_groups = pinmux_generic_get_function_groups,
243 .set_mux = ns_pinctrl_set_mux,
244};
245
246/*
247 * Controller code
248 */
249
250static struct pinctrl_desc ns_pinctrl_desc = {

--- 11 unchanged lines hidden (view full) ---

262
263static int ns_pinctrl_probe(struct platform_device *pdev)
264{
265 struct device *dev = &pdev->dev;
266 const struct of_device_id *of_id;
267 struct ns_pinctrl *ns_pinctrl;
268 struct pinctrl_desc *pctldesc;
269 struct pinctrl_pin_desc *pin;
188 .set_mux = ns_pinctrl_set_mux,
189};
190
191/*
192 * Controller code
193 */
194
195static struct pinctrl_desc ns_pinctrl_desc = {

--- 11 unchanged lines hidden (view full) ---

207
208static int ns_pinctrl_probe(struct platform_device *pdev)
209{
210 struct device *dev = &pdev->dev;
211 const struct of_device_id *of_id;
212 struct ns_pinctrl *ns_pinctrl;
213 struct pinctrl_desc *pctldesc;
214 struct pinctrl_pin_desc *pin;
270 struct ns_pinctrl_group *group;
271 struct ns_pinctrl_function *function;
272 struct resource *res;
273 int i;
274
275 ns_pinctrl = devm_kzalloc(dev, sizeof(*ns_pinctrl), GFP_KERNEL);
276 if (!ns_pinctrl)
277 return -ENOMEM;
278 pctldesc = &ns_pinctrl->pctldesc;
279 platform_set_drvdata(pdev, ns_pinctrl);

--- 30 unchanged lines hidden (view full) ---

310 unsigned int chipsets = (uintptr_t)src->drv_data;
311
312 if (chipsets & ns_pinctrl->chipset_flag) {
313 memcpy(pin++, src, sizeof(*src));
314 pctldesc->npins++;
315 }
316 }
317
215 struct resource *res;
216 int i;
217
218 ns_pinctrl = devm_kzalloc(dev, sizeof(*ns_pinctrl), GFP_KERNEL);
219 if (!ns_pinctrl)
220 return -ENOMEM;
221 pctldesc = &ns_pinctrl->pctldesc;
222 platform_set_drvdata(pdev, ns_pinctrl);

--- 30 unchanged lines hidden (view full) ---

253 unsigned int chipsets = (uintptr_t)src->drv_data;
254
255 if (chipsets & ns_pinctrl->chipset_flag) {
256 memcpy(pin++, src, sizeof(*src));
257 pctldesc->npins++;
258 }
259 }
260
318 ns_pinctrl->groups = devm_kcalloc(dev, ARRAY_SIZE(ns_pinctrl_groups),
319 sizeof(struct ns_pinctrl_group),
320 GFP_KERNEL);
321 if (!ns_pinctrl->groups)
322 return -ENOMEM;
323 for (i = 0, group = &ns_pinctrl->groups[0];
324 i < ARRAY_SIZE(ns_pinctrl_groups); i++) {
325 const struct ns_pinctrl_group *src = &ns_pinctrl_groups[i];
261 /* Register */
326
262
327 if (src->chipsets & ns_pinctrl->chipset_flag) {
328 memcpy(group++, src, sizeof(*src));
329 ns_pinctrl->num_groups++;
330 }
263 ns_pinctrl->pctldev = devm_pinctrl_register(dev, pctldesc, ns_pinctrl);
264 if (IS_ERR(ns_pinctrl->pctldev)) {
265 dev_err(dev, "Failed to register pinctrl\n");
266 return PTR_ERR(ns_pinctrl->pctldev);
331 }
332
267 }
268
333 ns_pinctrl->functions = devm_kcalloc(dev,
334 ARRAY_SIZE(ns_pinctrl_functions),
335 sizeof(struct ns_pinctrl_function),
336 GFP_KERNEL);
337 if (!ns_pinctrl->functions)
338 return -ENOMEM;
339 for (i = 0, function = &ns_pinctrl->functions[0];
340 i < ARRAY_SIZE(ns_pinctrl_functions); i++) {
341 const struct ns_pinctrl_function *src = &ns_pinctrl_functions[i];
269 for (i = 0; i < ARRAY_SIZE(ns_pinctrl_groups); i++) {
270 const struct ns_pinctrl_group *group = &ns_pinctrl_groups[i];
342
271
343 if (src->chipsets & ns_pinctrl->chipset_flag) {
344 memcpy(function++, src, sizeof(*src));
345 ns_pinctrl->num_functions++;
346 }
272 if (!(group->chipsets & ns_pinctrl->chipset_flag))
273 continue;
274
275 pinctrl_generic_add_group(ns_pinctrl->pctldev, group->name,
276 group->pins, group->num_pins, NULL);
347 }
348
277 }
278
349 /* Register */
279 for (i = 0; i < ARRAY_SIZE(ns_pinctrl_functions); i++) {
280 const struct ns_pinctrl_function *function = &ns_pinctrl_functions[i];
350
281
351 ns_pinctrl->pctldev = devm_pinctrl_register(dev, pctldesc, ns_pinctrl);
352 if (IS_ERR(ns_pinctrl->pctldev)) {
353 dev_err(dev, "Failed to register pinctrl\n");
354 return PTR_ERR(ns_pinctrl->pctldev);
282 if (!(function->chipsets & ns_pinctrl->chipset_flag))
283 continue;
284
285 pinmux_generic_add_function(ns_pinctrl->pctldev, function->name,
286 function->groups,
287 function->num_groups, NULL);
355 }
356
357 return 0;
358}
359
360static struct platform_driver ns_pinctrl_driver = {
361 .probe = ns_pinctrl_probe,
362 .driver = {
363 .name = "ns-pinmux",
364 .of_match_table = ns_pinctrl_of_match_table,
365 },
366};
367
368module_platform_driver(ns_pinctrl_driver);
369
370MODULE_AUTHOR("Rafał Miłecki");
371MODULE_LICENSE("GPL v2");
372MODULE_DEVICE_TABLE(of, ns_pinctrl_of_match_table);
288 }
289
290 return 0;
291}
292
293static struct platform_driver ns_pinctrl_driver = {
294 .probe = ns_pinctrl_probe,
295 .driver = {
296 .name = "ns-pinmux",
297 .of_match_table = ns_pinctrl_of_match_table,
298 },
299};
300
301module_platform_driver(ns_pinctrl_driver);
302
303MODULE_AUTHOR("Rafał Miłecki");
304MODULE_LICENSE("GPL v2");
305MODULE_DEVICE_TABLE(of, ns_pinctrl_of_match_table);