blob: 15f501d89026f2360cf59639c464e5200f5e03c8 [file] [log] [blame]
John Crispin3f8c50c2012-08-28 12:44:59 +02001/*
2 * linux/drivers/pinctrl/pinctrl-lantiq.c
3 * based on linux/drivers/pinctrl/pinctrl-pxa3xx.c
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * publishhed by the Free Software Foundation.
8 *
9 * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
10 */
11
12#include <linux/module.h>
13#include <linux/device.h>
14#include <linux/io.h>
15#include <linux/platform_device.h>
16#include <linux/slab.h>
17#include <linux/of.h>
18
19#include "pinctrl-lantiq.h"
20
21static int ltq_get_group_count(struct pinctrl_dev *pctrldev)
22{
23 struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
24 return info->num_grps;
25}
26
27static const char *ltq_get_group_name(struct pinctrl_dev *pctrldev,
28 unsigned selector)
29{
30 struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
31 if (selector >= info->num_grps)
32 return NULL;
33 return info->grps[selector].name;
34}
35
36static int ltq_get_group_pins(struct pinctrl_dev *pctrldev,
37 unsigned selector,
38 const unsigned **pins,
39 unsigned *num_pins)
40{
41 struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
42 if (selector >= info->num_grps)
43 return -EINVAL;
44 *pins = info->grps[selector].pins;
45 *num_pins = info->grps[selector].npins;
46 return 0;
47}
48
Axel Lin89377aa2012-11-08 00:10:17 +080049static void ltq_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
50 struct pinctrl_map *map, unsigned num_maps)
John Crispin3f8c50c2012-08-28 12:44:59 +020051{
52 int i;
53
54 for (i = 0; i < num_maps; i++)
55 if (map[i].type == PIN_MAP_TYPE_CONFIGS_PIN)
56 kfree(map[i].data.configs.configs);
57 kfree(map);
58}
59
60static void ltq_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
61 struct seq_file *s,
62 unsigned offset)
63{
64 seq_printf(s, " %s", dev_name(pctldev->dev));
65}
66
67static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
68 struct device_node *np,
69 struct pinctrl_map **map)
70{
71 struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
72 unsigned long configs[3];
73 unsigned num_configs = 0;
74 struct property *prop;
75 const char *group, *pin;
76 const char *function;
77 int ret, i;
78
79 ret = of_property_read_string(np, "lantiq,function", &function);
80 if (!ret) {
81 of_property_for_each_string(np, "lantiq,groups", prop, group) {
82 (*map)->type = PIN_MAP_TYPE_MUX_GROUP;
83 (*map)->name = function;
84 (*map)->data.mux.group = group;
85 (*map)->data.mux.function = function;
86 (*map)++;
87 }
88 if (of_find_property(np, "lantiq,pins", NULL))
89 dev_err(pctldev->dev,
90 "%s mixes pins and groups settings\n",
91 np->name);
92 return 0;
93 }
94
95 for (i = 0; i < info->num_params; i++) {
96 u32 val;
97 int ret = of_property_read_u32(np,
98 info->params[i].property, &val);
99 if (!ret)
100 configs[num_configs++] =
101 LTQ_PINCONF_PACK(info->params[i].param,
102 val);
103 }
104
105 if (!num_configs)
106 return -EINVAL;
107
108 of_property_for_each_string(np, "lantiq,pins", prop, pin) {
109 (*map)->data.configs.configs = kmemdup(configs,
110 num_configs * sizeof(unsigned long),
111 GFP_KERNEL);
112 (*map)->type = PIN_MAP_TYPE_CONFIGS_PIN;
113 (*map)->name = pin;
114 (*map)->data.configs.group_or_pin = pin;
115 (*map)->data.configs.num_configs = num_configs;
116 (*map)++;
117 }
118 return 0;
119}
120
121static int ltq_pinctrl_dt_subnode_size(struct device_node *np)
122{
123 int ret;
124
125 ret = of_property_count_strings(np, "lantiq,groups");
126 if (ret < 0)
127 ret = of_property_count_strings(np, "lantiq,pins");
128 return ret;
129}
130
Axel Lin89377aa2012-11-08 00:10:17 +0800131static int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
132 struct device_node *np_config,
133 struct pinctrl_map **map,
134 unsigned *num_maps)
John Crispin3f8c50c2012-08-28 12:44:59 +0200135{
136 struct pinctrl_map *tmp;
137 struct device_node *np;
138 int ret;
139
140 *num_maps = 0;
141 for_each_child_of_node(np_config, np)
142 *num_maps += ltq_pinctrl_dt_subnode_size(np);
143 *map = kzalloc(*num_maps * sizeof(struct pinctrl_map), GFP_KERNEL);
144 if (!*map)
145 return -ENOMEM;
146 tmp = *map;
147
148 for_each_child_of_node(np_config, np) {
149 ret = ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
150 if (ret < 0) {
151 ltq_pinctrl_dt_free_map(pctldev, *map, *num_maps);
152 return ret;
153 }
154 }
155 return 0;
156}
157
158static struct pinctrl_ops ltq_pctrl_ops = {
159 .get_groups_count = ltq_get_group_count,
160 .get_group_name = ltq_get_group_name,
161 .get_group_pins = ltq_get_group_pins,
162 .pin_dbg_show = ltq_pinctrl_pin_dbg_show,
163 .dt_node_to_map = ltq_pinctrl_dt_node_to_map,
164 .dt_free_map = ltq_pinctrl_dt_free_map,
165};
166
167static int ltq_pmx_func_count(struct pinctrl_dev *pctrldev)
168{
169 struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
170
171 return info->num_funcs;
172}
173
174static const char *ltq_pmx_func_name(struct pinctrl_dev *pctrldev,
175 unsigned selector)
176{
177 struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
178
179 if (selector >= info->num_funcs)
180 return NULL;
181
182 return info->funcs[selector].name;
183}
184
185static int ltq_pmx_get_groups(struct pinctrl_dev *pctrldev,
186 unsigned func,
187 const char * const **groups,
188 unsigned * const num_groups)
189{
190 struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
191
192 *groups = info->funcs[func].groups;
193 *num_groups = info->funcs[func].num_groups;
194
195 return 0;
196}
197
198/* Return function number. If failure, return negative value. */
199static int match_mux(const struct ltq_mfp_pin *mfp, unsigned mux)
200{
201 int i;
202 for (i = 0; i < LTQ_MAX_MUX; i++) {
203 if (mfp->func[i] == mux)
204 break;
205 }
206 if (i >= LTQ_MAX_MUX)
207 return -EINVAL;
208 return i;
209}
210
211/* dont assume .mfp is linearly mapped. find the mfp with the correct .pin */
212static int match_mfp(const struct ltq_pinmux_info *info, int pin)
213{
214 int i;
215 for (i = 0; i < info->num_mfp; i++) {
216 if (info->mfp[i].pin == pin)
217 return i;
218 }
219 return -1;
220}
221
222/* check whether current pin configuration is valid. Negative for failure */
223static int match_group_mux(const struct ltq_pin_group *grp,
224 const struct ltq_pinmux_info *info,
225 unsigned mux)
226{
227 int i, pin, ret = 0;
228 for (i = 0; i < grp->npins; i++) {
229 pin = match_mfp(info, grp->pins[i]);
230 if (pin < 0) {
231 dev_err(info->dev, "could not find mfp for pin %d\n",
232 grp->pins[i]);
233 return -EINVAL;
234 }
235 ret = match_mux(&info->mfp[pin], mux);
236 if (ret < 0) {
237 dev_err(info->dev, "Can't find mux %d on pin%d\n",
238 mux, pin);
239 break;
240 }
241 }
242 return ret;
243}
244
245static int ltq_pmx_enable(struct pinctrl_dev *pctrldev,
246 unsigned func,
247 unsigned group)
248{
249 struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
250 const struct ltq_pin_group *pin_grp = &info->grps[group];
251 int i, pin, pin_func, ret;
252
253 if (!pin_grp->npins ||
254 (match_group_mux(pin_grp, info, pin_grp->mux) < 0)) {
255 dev_err(info->dev, "Failed to set the pin group: %s\n",
256 info->grps[group].name);
257 return -EINVAL;
258 }
259 for (i = 0; i < pin_grp->npins; i++) {
260 pin = match_mfp(info, pin_grp->pins[i]);
261 if (pin < 0) {
262 dev_err(info->dev, "could not find mfp for pin %d\n",
263 pin_grp->pins[i]);
264 return -EINVAL;
265 }
266 pin_func = match_mux(&info->mfp[pin], pin_grp->mux);
267 ret = info->apply_mux(pctrldev, pin, pin_func);
268 if (ret) {
269 dev_err(info->dev,
270 "failed to apply mux %d for pin %d\n",
271 pin_func, pin);
272 return ret;
273 }
274 }
275 return 0;
276}
277
John Crispin3f8c50c2012-08-28 12:44:59 +0200278static int ltq_pmx_gpio_request_enable(struct pinctrl_dev *pctrldev,
279 struct pinctrl_gpio_range *range,
280 unsigned pin)
281{
282 struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
283 int mfp = match_mfp(info, pin + (range->id * 32));
284 int pin_func;
285
286 if (mfp < 0) {
287 dev_err(info->dev, "could not find mfp for pin %d\n", pin);
288 return -EINVAL;
289 }
290
291 pin_func = match_mux(&info->mfp[mfp], 0);
292 if (pin_func < 0) {
293 dev_err(info->dev, "No GPIO function on pin%d\n", mfp);
294 return -EINVAL;
295 }
296
297 return info->apply_mux(pctrldev, mfp, pin_func);
298}
299
300static struct pinmux_ops ltq_pmx_ops = {
301 .get_functions_count = ltq_pmx_func_count,
302 .get_function_name = ltq_pmx_func_name,
303 .get_function_groups = ltq_pmx_get_groups,
304 .enable = ltq_pmx_enable,
John Crispin3f8c50c2012-08-28 12:44:59 +0200305 .gpio_request_enable = ltq_pmx_gpio_request_enable,
306};
307
308/*
309 * allow different socs to register with the generic part of the lanti
310 * pinctrl code
311 */
312int ltq_pinctrl_register(struct platform_device *pdev,
313 struct ltq_pinmux_info *info)
314{
315 struct pinctrl_desc *desc;
316
317 if (!info)
318 return -EINVAL;
319 desc = info->desc;
320 desc->pctlops = &ltq_pctrl_ops;
321 desc->pmxops = &ltq_pmx_ops;
322 info->dev = &pdev->dev;
323
324 info->pctrl = pinctrl_register(desc, &pdev->dev, info);
325 if (!info->pctrl) {
326 dev_err(&pdev->dev, "failed to register LTQ pinmux driver\n");
327 return -EINVAL;
328 }
329 platform_set_drvdata(pdev, info);
330 return 0;
331}