]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/pinctrl/sh-pfc/pinctrl.c
sh-pfc: Constify all SoC data
[mirror_ubuntu-artful-kernel.git] / drivers / pinctrl / sh-pfc / pinctrl.c
CommitLineData
ca5481c6
PM
1/*
2 * SuperH Pin Function Controller pinmux support.
3 *
4 * Copyright (C) 2012 Paul Mundt
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
54407110 10
c6193eac 11#define DRV_NAME "sh-pfc"
f9492fda 12#define pr_fmt(fmt) KBUILD_MODNAME " pinctrl: " fmt
ca5481c6 13
1724acfd 14#include <linux/device.h>
90efde22 15#include <linux/err.h>
ca5481c6
PM
16#include <linux/init.h>
17#include <linux/module.h>
ca5481c6 18#include <linux/pinctrl/consumer.h>
ca5481c6 19#include <linux/pinctrl/pinconf.h>
ca5481c6 20#include <linux/pinctrl/pinconf-generic.h>
90efde22
LP
21#include <linux/pinctrl/pinctrl.h>
22#include <linux/pinctrl/pinmux.h>
90efde22
LP
23#include <linux/slab.h>
24#include <linux/spinlock.h>
ca5481c6 25
f9165132
LP
26#include "core.h"
27
1a0039dc
LP
28struct sh_pfc_pin_config {
29 u32 type;
30};
31
ca5481c6
PM
32struct sh_pfc_pinctrl {
33 struct pinctrl_dev *pctl;
dcc427e1 34 struct pinctrl_desc pctl_desc;
dcc427e1 35
ca5481c6
PM
36 struct sh_pfc *pfc;
37
3d8d9f1d 38 struct pinctrl_pin_desc *pins;
1a0039dc 39 struct sh_pfc_pin_config *configs;
ca5481c6
PM
40};
41
e3f805e8 42static int sh_pfc_get_groups_count(struct pinctrl_dev *pctldev)
ca5481c6 43{
e3f805e8
PM
44 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
45
3d8d9f1d 46 return pmx->pfc->info->nr_groups;
ca5481c6
PM
47}
48
e3f805e8 49static const char *sh_pfc_get_group_name(struct pinctrl_dev *pctldev,
ca5481c6
PM
50 unsigned selector)
51{
e3f805e8
PM
52 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
53
3d8d9f1d 54 return pmx->pfc->info->groups[selector].name;
ca5481c6
PM
55}
56
3d8d9f1d 57static int sh_pfc_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector,
ca5481c6
PM
58 const unsigned **pins, unsigned *num_pins)
59{
e3f805e8
PM
60 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
61
3d8d9f1d
LP
62 *pins = pmx->pfc->info->groups[selector].pins;
63 *num_pins = pmx->pfc->info->groups[selector].nr_pins;
e3f805e8
PM
64
65 return 0;
ca5481c6
PM
66}
67
fdd85ec3
PM
68static void sh_pfc_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
69 unsigned offset)
70{
71 seq_printf(s, "%s", DRV_NAME);
72}
73
fe330ce8 74static const struct pinctrl_ops sh_pfc_pinctrl_ops = {
e3f805e8
PM
75 .get_groups_count = sh_pfc_get_groups_count,
76 .get_group_name = sh_pfc_get_group_name,
ca5481c6 77 .get_group_pins = sh_pfc_get_group_pins,
fdd85ec3 78 .pin_dbg_show = sh_pfc_pin_dbg_show,
ca5481c6
PM
79};
80
d93a891f
PM
81static int sh_pfc_get_functions_count(struct pinctrl_dev *pctldev)
82{
83 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
84
3d8d9f1d 85 return pmx->pfc->info->nr_functions;
d93a891f
PM
86}
87
88static const char *sh_pfc_get_function_name(struct pinctrl_dev *pctldev,
89 unsigned selector)
90{
91 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
92
3d8d9f1d 93 return pmx->pfc->info->functions[selector].name;
d93a891f 94}
ca5481c6 95
3d8d9f1d
LP
96static int sh_pfc_get_function_groups(struct pinctrl_dev *pctldev,
97 unsigned selector,
ca5481c6
PM
98 const char * const **groups,
99 unsigned * const num_groups)
100{
d93a891f
PM
101 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
102
3d8d9f1d
LP
103 *groups = pmx->pfc->info->functions[selector].groups;
104 *num_groups = pmx->pfc->info->functions[selector].nr_groups;
d93a891f 105
ca5481c6
PM
106 return 0;
107}
108
3d8d9f1d 109static int sh_pfc_func_enable(struct pinctrl_dev *pctldev, unsigned selector,
ca5481c6
PM
110 unsigned group)
111{
3d8d9f1d
LP
112 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
113 struct sh_pfc *pfc = pmx->pfc;
114 const struct sh_pfc_pin_group *grp = &pfc->info->groups[group];
115 unsigned long flags;
116 unsigned int i;
117 int ret = -EINVAL;
118
119 spin_lock_irqsave(&pfc->lock, flags);
120
121 for (i = 0; i < grp->nr_pins; ++i) {
861601de 122 if (sh_pfc_config_mux(pfc, grp->mux[i], PINMUX_TYPE_FUNCTION))
3d8d9f1d
LP
123 goto done;
124 }
125
126 ret = 0;
127
128done:
129 spin_unlock_irqrestore(&pfc->lock, flags);
130 return ret;
ca5481c6
PM
131}
132
3d8d9f1d 133static void sh_pfc_func_disable(struct pinctrl_dev *pctldev, unsigned selector,
ca5481c6
PM
134 unsigned group)
135{
136}
137
1a0039dc 138static int sh_pfc_reconfig_pin(struct sh_pfc_pinctrl *pmx, unsigned offset,
fdd85ec3
PM
139 int new_type)
140{
1a0039dc
LP
141 struct sh_pfc *pfc = pmx->pfc;
142 int idx = sh_pfc_get_pin_index(pfc, offset);
143 struct sh_pfc_pin_config *cfg = &pmx->configs[idx];
cd3c1bee 144 const struct sh_pfc_pin *pin = &pfc->info->pins[idx];
934cb02b 145 unsigned int mark = pin->enum_id;
fdd85ec3 146 unsigned long flags;
fdd85ec3
PM
147 int ret = -EINVAL;
148
149 spin_lock_irqsave(&pfc->lock, flags);
150
1a0039dc 151 switch (cfg->type) {
fdd85ec3 152 case PINMUX_TYPE_GPIO:
fdd85ec3
PM
153 case PINMUX_TYPE_OUTPUT:
154 case PINMUX_TYPE_INPUT:
155 case PINMUX_TYPE_INPUT_PULLUP:
156 case PINMUX_TYPE_INPUT_PULLDOWN:
fdd85ec3
PM
157 break;
158 default:
159 goto err;
160 }
161
861601de 162 if (sh_pfc_config_mux(pfc, mark, new_type) != 0)
fdd85ec3
PM
163 goto err;
164
1a0039dc 165 cfg->type = new_type;
fdd85ec3
PM
166
167 ret = 0;
168
169err:
170 spin_unlock_irqrestore(&pfc->lock, flags);
171
172 return ret;
173}
174
ca5481c6
PM
175static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev,
176 struct pinctrl_gpio_range *range,
177 unsigned offset)
178{
179 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
180 struct sh_pfc *pfc = pmx->pfc;
1a0039dc
LP
181 int idx = sh_pfc_get_pin_index(pfc, offset);
182 struct sh_pfc_pin_config *cfg = &pmx->configs[idx];
ca5481c6 183 unsigned long flags;
1a0039dc 184 int ret;
ca5481c6
PM
185
186 spin_lock_irqsave(&pfc->lock, flags);
187
1a0039dc 188 switch (cfg->type) {
d93a891f 189 case PINMUX_TYPE_GPIO:
16d74ebe
PM
190 case PINMUX_TYPE_INPUT:
191 case PINMUX_TYPE_OUTPUT:
d93a891f 192 break;
2119f7c9 193 case PINMUX_TYPE_FUNCTION:
d93a891f 194 default:
1a0039dc 195 pr_err("Unsupported mux type (%d), bailing...\n", cfg->type);
077664a2
LP
196 ret = -ENOTSUPP;
197 goto err;
d93a891f 198 }
ca5481c6
PM
199
200 ret = 0;
201
202err:
203 spin_unlock_irqrestore(&pfc->lock, flags);
204
205 return ret;
206}
207
208static void sh_pfc_gpio_disable_free(struct pinctrl_dev *pctldev,
209 struct pinctrl_gpio_range *range,
210 unsigned offset)
211{
ca5481c6
PM
212}
213
214static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev,
215 struct pinctrl_gpio_range *range,
216 unsigned offset, bool input)
217{
218 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
fdd85ec3 219 int type = input ? PINMUX_TYPE_INPUT : PINMUX_TYPE_OUTPUT;
ca5481c6 220
1a0039dc 221 return sh_pfc_reconfig_pin(pmx, offset, type);
ca5481c6
PM
222}
223
fe330ce8 224static const struct pinmux_ops sh_pfc_pinmux_ops = {
d93a891f
PM
225 .get_functions_count = sh_pfc_get_functions_count,
226 .get_function_name = sh_pfc_get_function_name,
ca5481c6 227 .get_function_groups = sh_pfc_get_function_groups,
3d8d9f1d
LP
228 .enable = sh_pfc_func_enable,
229 .disable = sh_pfc_func_disable,
ca5481c6
PM
230 .gpio_request_enable = sh_pfc_gpio_request_enable,
231 .gpio_disable_free = sh_pfc_gpio_disable_free,
232 .gpio_set_direction = sh_pfc_gpio_set_direction,
233};
234
934cb02b 235static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin,
ca5481c6
PM
236 unsigned long *config)
237{
fdd85ec3
PM
238 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
239 struct sh_pfc *pfc = pmx->pfc;
1a0039dc
LP
240 int idx = sh_pfc_get_pin_index(pfc, _pin);
241 struct sh_pfc_pin_config *cfg = &pmx->configs[idx];
d93a891f 242
1a0039dc 243 *config = cfg->type;
d93a891f 244
fdd85ec3 245 return 0;
ca5481c6
PM
246}
247
248static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin,
249 unsigned long config)
250{
fdd85ec3 251 struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev);
fdd85ec3
PM
252
253 /* Validate the new type */
254 if (config >= PINMUX_FLAG_TYPE)
255 return -EINVAL;
256
1a0039dc 257 return sh_pfc_reconfig_pin(pmx, pin, config);
fdd85ec3
PM
258}
259
260static void sh_pfc_pinconf_dbg_show(struct pinctrl_dev *pctldev,
261 struct seq_file *s, unsigned pin)
262{
263 const char *pinmux_type_str[] = {
264 [PINMUX_TYPE_NONE] = "none",
265 [PINMUX_TYPE_FUNCTION] = "function",
266 [PINMUX_TYPE_GPIO] = "gpio",
267 [PINMUX_TYPE_OUTPUT] = "output",
268 [PINMUX_TYPE_INPUT] = "input",
269 [PINMUX_TYPE_INPUT_PULLUP] = "input bias pull up",
270 [PINMUX_TYPE_INPUT_PULLDOWN] = "input bias pull down",
271 };
272 unsigned long config;
273 int rc;
274
275 rc = sh_pfc_pinconf_get(pctldev, pin, &config);
276 if (unlikely(rc != 0))
277 return;
278
279 seq_printf(s, " %s", pinmux_type_str[config]);
ca5481c6
PM
280}
281
fe330ce8 282static const struct pinconf_ops sh_pfc_pinconf_ops = {
ca5481c6
PM
283 .pin_config_get = sh_pfc_pinconf_get,
284 .pin_config_set = sh_pfc_pinconf_set,
fdd85ec3 285 .pin_config_dbg_show = sh_pfc_pinconf_dbg_show,
ca5481c6
PM
286};
287
63d57383
LP
288/* PFC ranges -> pinctrl pin descs */
289static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx)
ca5481c6 290{
63d57383
LP
291 const struct pinmux_range *ranges;
292 struct pinmux_range def_range;
293 unsigned int nr_ranges;
294 unsigned int nr_pins;
295 unsigned int i;
296
297 if (pfc->info->ranges == NULL) {
298 def_range.begin = 0;
299 def_range.end = pfc->info->nr_pins - 1;
300 ranges = &def_range;
301 nr_ranges = 1;
302 } else {
303 ranges = pfc->info->ranges;
304 nr_ranges = pfc->info->nr_ranges;
305 }
ca5481c6 306
3d8d9f1d
LP
307 pmx->pins = devm_kzalloc(pfc->dev,
308 sizeof(*pmx->pins) * pfc->info->nr_pins,
1724acfd 309 GFP_KERNEL);
3d8d9f1d 310 if (unlikely(!pmx->pins))
ca5481c6 311 return -ENOMEM;
ca5481c6 312
1a0039dc
LP
313 pmx->configs = devm_kzalloc(pfc->dev,
314 sizeof(*pmx->configs) * pfc->info->nr_pins,
315 GFP_KERNEL);
316 if (unlikely(!pmx->configs))
317 return -ENOMEM;
318
63d57383
LP
319 for (i = 0, nr_pins = 0; i < nr_ranges; ++i) {
320 const struct pinmux_range *range = &ranges[i];
321 unsigned int number;
322
323 for (number = range->begin; number <= range->end;
324 number++, nr_pins++) {
1a0039dc 325 struct sh_pfc_pin_config *cfg = &pmx->configs[nr_pins];
3d8d9f1d 326 struct pinctrl_pin_desc *pin = &pmx->pins[nr_pins];
cd3c1bee
LP
327 const struct sh_pfc_pin *info =
328 &pfc->info->pins[nr_pins];
ca5481c6 329
63d57383
LP
330 pin->number = number;
331 pin->name = info->name;
1a0039dc 332 cfg->type = PINMUX_TYPE_GPIO;
63d57383 333 }
ca5481c6
PM
334 }
335
63d57383
LP
336 pfc->nr_pins = ranges[nr_ranges-1].end + 1;
337
338 return nr_ranges;
ca5481c6
PM
339}
340
c6193eac 341int sh_pfc_register_pinctrl(struct sh_pfc *pfc)
ca5481c6 342{
c6193eac 343 struct sh_pfc_pinctrl *pmx;
63d57383 344 int nr_ranges;
ca5481c6 345
1724acfd 346 pmx = devm_kzalloc(pfc->dev, sizeof(*pmx), GFP_KERNEL);
c6193eac
LP
347 if (unlikely(!pmx))
348 return -ENOMEM;
349
c6193eac
LP
350 pmx->pfc = pfc;
351 pfc->pinctrl = pmx;
ca5481c6 352
63d57383
LP
353 nr_ranges = sh_pfc_map_pins(pfc, pmx);
354 if (unlikely(nr_ranges < 0))
355 return nr_ranges;
ca5481c6 356
dcc427e1
LP
357 pmx->pctl_desc.name = DRV_NAME;
358 pmx->pctl_desc.owner = THIS_MODULE;
359 pmx->pctl_desc.pctlops = &sh_pfc_pinctrl_ops;
360 pmx->pctl_desc.pmxops = &sh_pfc_pinmux_ops;
361 pmx->pctl_desc.confops = &sh_pfc_pinconf_ops;
3d8d9f1d 362 pmx->pctl_desc.pins = pmx->pins;
63d57383 363 pmx->pctl_desc.npins = pfc->info->nr_pins;
dcc427e1
LP
364
365 pmx->pctl = pinctrl_register(&pmx->pctl_desc, pfc->dev, pmx);
fd9d05b0
WY
366 if (pmx->pctl == NULL)
367 return -EINVAL;
ca5481c6 368
ca5481c6 369 return 0;
ca5481c6
PM
370}
371
c6193eac 372int sh_pfc_unregister_pinctrl(struct sh_pfc *pfc)
ca5481c6 373{
c6193eac 374 struct sh_pfc_pinctrl *pmx = pfc->pinctrl;
ca5481c6 375
ca5481c6
PM
376 pinctrl_unregister(pmx->pctl);
377
c6193eac 378 pfc->pinctrl = NULL;
ca5481c6
PM
379 return 0;
380}