aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-samsung.c
diff options
context:
space:
mode:
authorThomas Abraham <thomas.abraham@linaro.org>2012-09-06 17:07:19 -0400
committerKukjin Kim <kgene.kim@samsung.com>2012-09-06 17:07:19 -0400
commit30574f0db1b16fedf705cb792099f8a3171598eb (patch)
tree3c091a894ab233db2ac2eb887268020d58a48ca3 /drivers/pinctrl/pinctrl-samsung.c
parent4cbe5a555fa58a79b6ecbb6c531b8bab0650778d (diff)
pinctrl: add samsung pinctrl and gpiolib driver
Add a new device tree enabled pinctrl and gpiolib driver for Samsung SoC's. This driver provides a common and extensible framework for all Samsung SoC's to interface with the pinctrl and gpiolib subsystems. This driver supports only device tree based instantiation and hence can be used only on those Samsung platforms that have device tree enabled. This driver is split into two parts: the pinctrl interface and the gpiolib interface. The pinctrl interface registers pinctrl devices with the pinctrl subsystem and gpiolib interface registers gpio chips with the gpiolib subsystem. The information about the pins, pin groups, pin functions and gpio chips, which are SoC specific, are parsed from device tree node. Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org> Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Acked-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Diffstat (limited to 'drivers/pinctrl/pinctrl-samsung.c')
-rw-r--r--drivers/pinctrl/pinctrl-samsung.c888
1 files changed, 888 insertions, 0 deletions
diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c
new file mode 100644
index 000000000000..8a24223d5334
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-samsung.c
@@ -0,0 +1,888 @@
1/*
2 * pin-controller/pin-mux/pin-config/gpio-driver for Samsung's SoC's.
3 *
4 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
6 * Copyright (c) 2012 Linaro Ltd
7 * http://www.linaro.org
8 *
9 * Author: Thomas Abraham <thomas.ab@samsung.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver implements the Samsung pinctrl driver. It supports setting up of
17 * pinmux and pinconf configurations. The gpiolib interface is also included.
18 * External interrupt (gpio and wakeup) support are not included in this driver
19 * but provides extensions to which platform specific implementation of the gpio
20 * and wakeup interrupts can be hooked to.
21 */
22
23#include <linux/module.h>
24#include <linux/platform_device.h>
25#include <linux/io.h>
26#include <linux/slab.h>
27#include <linux/err.h>
28#include <linux/gpio.h>
29
30#include "core.h"
31#include "pinctrl-samsung.h"
32
33#define GROUP_SUFFIX "-grp"
34#define GSUFFIX_LEN sizeof(GROUP_SUFFIX)
35#define FUNCTION_SUFFIX "-mux"
36#define FSUFFIX_LEN sizeof(FUNCTION_SUFFIX)
37
38/* list of all possible config options supported */
39struct pin_config {
40 char *prop_cfg;
41 unsigned int cfg_type;
42} pcfgs[] = {
43 { "samsung,pin-pud", PINCFG_TYPE_PUD },
44 { "samsung,pin-drv", PINCFG_TYPE_DRV },
45 { "samsung,pin-con-pdn", PINCFG_TYPE_CON_PDN },
46 { "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN },
47};
48
49/* check if the selector is a valid pin group selector */
50static int samsung_get_group_count(struct pinctrl_dev *pctldev)
51{
52 struct samsung_pinctrl_drv_data *drvdata;
53
54 drvdata = pinctrl_dev_get_drvdata(pctldev);
55 return drvdata->nr_groups;
56}
57
58/* return the name of the group selected by the group selector */
59static const char *samsung_get_group_name(struct pinctrl_dev *pctldev,
60 unsigned selector)
61{
62 struct samsung_pinctrl_drv_data *drvdata;
63
64 drvdata = pinctrl_dev_get_drvdata(pctldev);
65 return drvdata->pin_groups[selector].name;
66}
67
68/* return the pin numbers associated with the specified group */
69static int samsung_get_group_pins(struct pinctrl_dev *pctldev,
70 unsigned selector, const unsigned **pins, unsigned *num_pins)
71{
72 struct samsung_pinctrl_drv_data *drvdata;
73
74 drvdata = pinctrl_dev_get_drvdata(pctldev);
75 *pins = drvdata->pin_groups[selector].pins;
76 *num_pins = drvdata->pin_groups[selector].num_pins;
77 return 0;
78}
79
80/* create pinctrl_map entries by parsing device tree nodes */
81static int samsung_dt_node_to_map(struct pinctrl_dev *pctldev,
82 struct device_node *np, struct pinctrl_map **maps,
83 unsigned *nmaps)
84{
85 struct device *dev = pctldev->dev;
86 struct pinctrl_map *map;
87 unsigned long *cfg = NULL;
88 char *gname, *fname;
89 int cfg_cnt = 0, map_cnt = 0, idx = 0;
90
91 /* count the number of config options specfied in the node */
92 for (idx = 0; idx < ARRAY_SIZE(pcfgs); idx++) {
93 if (of_find_property(np, pcfgs[idx].prop_cfg, NULL))
94 cfg_cnt++;
95 }
96
97 /*
98 * Find out the number of map entries to create. All the config options
99 * can be accomadated into a single config map entry.
100 */
101 if (cfg_cnt)
102 map_cnt = 1;
103 if (of_find_property(np, "samsung,pin-function", NULL))
104 map_cnt++;
105 if (!map_cnt) {
106 dev_err(dev, "node %s does not have either config or function "
107 "configurations\n", np->name);
108 return -EINVAL;
109 }
110
111 /* Allocate memory for pin-map entries */
112 map = kzalloc(sizeof(*map) * map_cnt, GFP_KERNEL);
113 if (!map) {
114 dev_err(dev, "could not alloc memory for pin-maps\n");
115 return -ENOMEM;
116 }
117 *nmaps = 0;
118
119 /*
120 * Allocate memory for pin group name. The pin group name is derived
121 * from the node name from which these map entries are be created.
122 */
123 gname = kzalloc(strlen(np->name) + GSUFFIX_LEN, GFP_KERNEL);
124 if (!gname) {
125 dev_err(dev, "failed to alloc memory for group name\n");
126 goto free_map;
127 }
128 sprintf(gname, "%s%s", np->name, GROUP_SUFFIX);
129
130 /*
131 * don't have config options? then skip over to creating function
132 * map entries.
133 */
134 if (!cfg_cnt)
135 goto skip_cfgs;
136
137 /* Allocate memory for config entries */
138 cfg = kzalloc(sizeof(*cfg) * cfg_cnt, GFP_KERNEL);
139 if (!cfg) {
140 dev_err(dev, "failed to alloc memory for configs\n");
141 goto free_gname;
142 }
143
144 /* Prepare a list of config settings */
145 for (idx = 0, cfg_cnt = 0; idx < ARRAY_SIZE(pcfgs); idx++) {
146 u32 value;
147 if (!of_property_read_u32(np, pcfgs[idx].prop_cfg, &value))
148 cfg[cfg_cnt++] =
149 PINCFG_PACK(pcfgs[idx].cfg_type, value);
150 }
151
152 /* create the config map entry */
153 map[*nmaps].data.configs.group_or_pin = gname;
154 map[*nmaps].data.configs.configs = cfg;
155 map[*nmaps].data.configs.num_configs = cfg_cnt;
156 map[*nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
157 *nmaps += 1;
158
159skip_cfgs:
160 /* create the function map entry */
161 if (of_find_property(np, "samsung,pin-function", NULL)) {
162 fname = kzalloc(strlen(np->name) + FSUFFIX_LEN, GFP_KERNEL);
163 if (!fname) {
164 dev_err(dev, "failed to alloc memory for func name\n");
165 goto free_cfg;
166 }
167 sprintf(fname, "%s%s", np->name, FUNCTION_SUFFIX);
168
169 map[*nmaps].data.mux.group = gname;
170 map[*nmaps].data.mux.function = fname;
171 map[*nmaps].type = PIN_MAP_TYPE_MUX_GROUP;
172 *nmaps += 1;
173 }
174
175 *maps = map;
176 return 0;
177
178free_cfg:
179 kfree(cfg);
180free_gname:
181 kfree(gname);
182free_map:
183 kfree(map);
184 return -ENOMEM;
185}
186
187/* free the memory allocated to hold the pin-map table */
188static void samsung_dt_free_map(struct pinctrl_dev *pctldev,
189 struct pinctrl_map *map, unsigned num_maps)
190{
191 int idx;
192
193 for (idx = 0; idx < num_maps; idx++) {
194 if (map[idx].type == PIN_MAP_TYPE_MUX_GROUP) {
195 kfree(map[idx].data.mux.function);
196 if (!idx)
197 kfree(map[idx].data.mux.group);
198 } else if (map->type == PIN_MAP_TYPE_CONFIGS_GROUP) {
199 kfree(map[idx].data.configs.configs);
200 if (!idx)
201 kfree(map[idx].data.configs.group_or_pin);
202 }
203 };
204
205 kfree(map);
206}
207
208/* list of pinctrl callbacks for the pinctrl core */
209static struct pinctrl_ops samsung_pctrl_ops = {
210 .get_groups_count = samsung_get_group_count,
211 .get_group_name = samsung_get_group_name,
212 .get_group_pins = samsung_get_group_pins,
213 .dt_node_to_map = samsung_dt_node_to_map,
214 .dt_free_map = samsung_dt_free_map,
215};
216
217/* check if the selector is a valid pin function selector */
218static int samsung_get_functions_count(struct pinctrl_dev *pctldev)
219{
220 struct samsung_pinctrl_drv_data *drvdata;
221
222 drvdata = pinctrl_dev_get_drvdata(pctldev);
223 return drvdata->nr_functions;
224}
225
226/* return the name of the pin function specified */
227static const char *samsung_pinmux_get_fname(struct pinctrl_dev *pctldev,
228 unsigned selector)
229{
230 struct samsung_pinctrl_drv_data *drvdata;
231
232 drvdata = pinctrl_dev_get_drvdata(pctldev);
233 return drvdata->pmx_functions[selector].name;
234}
235
236/* return the groups associated for the specified function selector */
237static int samsung_pinmux_get_groups(struct pinctrl_dev *pctldev,
238 unsigned selector, const char * const **groups,
239 unsigned * const num_groups)
240{
241 struct samsung_pinctrl_drv_data *drvdata;
242
243 drvdata = pinctrl_dev_get_drvdata(pctldev);
244 *groups = drvdata->pmx_functions[selector].groups;
245 *num_groups = drvdata->pmx_functions[selector].num_groups;
246 return 0;
247}
248
249/*
250 * given a pin number that is local to a pin controller, find out the pin bank
251 * and the register base of the pin bank.
252 */
253static void pin_to_reg_bank(struct gpio_chip *gc, unsigned pin,
254 void __iomem **reg, u32 *offset,
255 struct samsung_pin_bank **bank)
256{
257 struct samsung_pinctrl_drv_data *drvdata;
258 struct samsung_pin_bank *b;
259
260 drvdata = dev_get_drvdata(gc->dev);
261 b = drvdata->ctrl->pin_banks;
262
263 while ((pin >= b->pin_base) &&
264 ((b->pin_base + b->nr_pins - 1) < pin))
265 b++;
266
267 *reg = drvdata->virt_base + b->pctl_offset;
268 *offset = pin - b->pin_base;
269 if (bank)
270 *bank = b;
271
272 /* some banks have two config registers in a single bank */
273 if (*offset * b->func_width > BITS_PER_LONG)
274 *reg += 4;
275}
276
277/* enable or disable a pinmux function */
278static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
279 unsigned group, bool enable)
280{
281 struct samsung_pinctrl_drv_data *drvdata;
282 const unsigned int *pins;
283 struct samsung_pin_bank *bank;
284 void __iomem *reg;
285 u32 mask, shift, data, pin_offset, cnt;
286
287 drvdata = pinctrl_dev_get_drvdata(pctldev);
288 pins = drvdata->pin_groups[group].pins;
289
290 /*
291 * for each pin in the pin group selected, program the correspoding pin
292 * pin function number in the config register.
293 */
294 for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) {
295 pin_to_reg_bank(drvdata->gc, pins[cnt] - drvdata->ctrl->base,
296 &reg, &pin_offset, &bank);
297 mask = (1 << bank->func_width) - 1;
298 shift = pin_offset * bank->func_width;
299
300 data = readl(reg);
301 data &= ~(mask << shift);
302 if (enable)
303 data |= drvdata->pin_groups[group].func << shift;
304 writel(data, reg);
305 }
306}
307
308/* enable a specified pinmux by writing to registers */
309static int samsung_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector,
310 unsigned group)
311{
312 samsung_pinmux_setup(pctldev, selector, group, true);
313 return 0;
314}
315
316/* disable a specified pinmux by writing to registers */
317static void samsung_pinmux_disable(struct pinctrl_dev *pctldev,
318 unsigned selector, unsigned group)
319{
320 samsung_pinmux_setup(pctldev, selector, group, false);
321}
322
323/*
324 * The calls to gpio_direction_output() and gpio_direction_input()
325 * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
326 * function called from the gpiolib interface).
327 */
328static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
329 struct pinctrl_gpio_range *range, unsigned offset, bool input)
330{
331 struct samsung_pin_bank *bank;
332 void __iomem *reg;
333 u32 data, pin_offset, mask, shift;
334
335 pin_to_reg_bank(range->gc, offset, &reg, &pin_offset, &bank);
336 mask = (1 << bank->func_width) - 1;
337 shift = pin_offset * bank->func_width;
338
339 data = readl(reg);
340 data &= ~(mask << shift);
341 if (!input)
342 data |= FUNC_OUTPUT << shift;
343 writel(data, reg);
344 return 0;
345}
346
347/* list of pinmux callbacks for the pinmux vertical in pinctrl core */
348static struct pinmux_ops samsung_pinmux_ops = {
349 .get_functions_count = samsung_get_functions_count,
350 .get_function_name = samsung_pinmux_get_fname,
351 .get_function_groups = samsung_pinmux_get_groups,
352 .enable = samsung_pinmux_enable,
353 .disable = samsung_pinmux_disable,
354 .gpio_set_direction = samsung_pinmux_gpio_set_direction,
355};
356
357/* set or get the pin config settings for a specified pin */
358static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,
359 unsigned long *config, bool set)
360{
361 struct samsung_pinctrl_drv_data *drvdata;
362 struct samsung_pin_bank *bank;
363 void __iomem *reg_base;
364 enum pincfg_type cfg_type = PINCFG_UNPACK_TYPE(*config);
365 u32 data, width, pin_offset, mask, shift;
366 u32 cfg_value, cfg_reg;
367
368 drvdata = pinctrl_dev_get_drvdata(pctldev);
369 pin_to_reg_bank(drvdata->gc, pin - drvdata->ctrl->base, &reg_base,
370 &pin_offset, &bank);
371
372 switch (cfg_type) {
373 case PINCFG_TYPE_PUD:
374 width = bank->pud_width;
375 cfg_reg = PUD_REG;
376 break;
377 case PINCFG_TYPE_DRV:
378 width = bank->drv_width;
379 cfg_reg = DRV_REG;
380 break;
381 case PINCFG_TYPE_CON_PDN:
382 width = bank->conpdn_width;
383 cfg_reg = CONPDN_REG;
384 break;
385 case PINCFG_TYPE_PUD_PDN:
386 width = bank->pudpdn_width;
387 cfg_reg = PUDPDN_REG;
388 break;
389 default:
390 WARN_ON(1);
391 return -EINVAL;
392 }
393
394 mask = (1 << width) - 1;
395 shift = pin_offset * width;
396 data = readl(reg_base + cfg_reg);
397
398 if (set) {
399 cfg_value = PINCFG_UNPACK_VALUE(*config);
400 data &= ~(mask << shift);
401 data |= (cfg_value << shift);
402 writel(data, reg_base + cfg_reg);
403 } else {
404 data >>= shift;
405 data &= mask;
406 *config = PINCFG_PACK(cfg_type, data);
407 }
408 return 0;
409}
410
411/* set the pin config settings for a specified pin */
412static int samsung_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
413 unsigned long config)
414{
415 return samsung_pinconf_rw(pctldev, pin, &config, true);
416}
417
418/* get the pin config settings for a specified pin */
419static int samsung_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
420 unsigned long *config)
421{
422 return samsung_pinconf_rw(pctldev, pin, config, false);
423}
424
425/* set the pin config settings for a specified pin group */
426static int samsung_pinconf_group_set(struct pinctrl_dev *pctldev,
427 unsigned group, unsigned long config)
428{
429 struct samsung_pinctrl_drv_data *drvdata;
430 const unsigned int *pins;
431 unsigned int cnt;
432
433 drvdata = pinctrl_dev_get_drvdata(pctldev);
434 pins = drvdata->pin_groups[group].pins;
435
436 for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++)
437 samsung_pinconf_set(pctldev, pins[cnt], config);
438
439 return 0;
440}
441
442/* get the pin config settings for a specified pin group */
443static int samsung_pinconf_group_get(struct pinctrl_dev *pctldev,
444 unsigned int group, unsigned long *config)
445{
446 struct samsung_pinctrl_drv_data *drvdata;
447 const unsigned int *pins;
448
449 drvdata = pinctrl_dev_get_drvdata(pctldev);
450 pins = drvdata->pin_groups[group].pins;
451 samsung_pinconf_get(pctldev, pins[0], config);
452 return 0;
453}
454
455/* list of pinconfig callbacks for pinconfig vertical in the pinctrl code */
456static struct pinconf_ops samsung_pinconf_ops = {
457 .pin_config_get = samsung_pinconf_get,
458 .pin_config_set = samsung_pinconf_set,
459 .pin_config_group_get = samsung_pinconf_group_get,
460 .pin_config_group_set = samsung_pinconf_group_set,
461};
462
463/* gpiolib gpio_set callback function */
464static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
465{
466 void __iomem *reg;
467 u32 pin_offset, data;
468
469 pin_to_reg_bank(gc, offset, &reg, &pin_offset, NULL);
470 data = readl(reg + DAT_REG);
471 data &= ~(1 << pin_offset);
472 if (value)
473 data |= 1 << pin_offset;
474 writel(data, reg + DAT_REG);
475}
476
477/* gpiolib gpio_get callback function */
478static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)
479{
480 void __iomem *reg;
481 u32 pin_offset, data;
482
483 pin_to_reg_bank(gc, offset, &reg, &pin_offset, NULL);
484 data = readl(reg + DAT_REG);
485 data >>= pin_offset;
486 data &= 1;
487 return data;
488}
489
490/*
491 * gpiolib gpio_direction_input callback function. The setting of the pin
492 * mux function as 'gpio input' will be handled by the pinctrl susbsystem
493 * interface.
494 */
495static int samsung_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
496{
497 return pinctrl_gpio_direction_input(gc->base + offset);
498}
499
500/*
501 * gpiolib gpio_direction_output callback function. The setting of the pin
502 * mux function as 'gpio output' will be handled by the pinctrl susbsystem
503 * interface.
504 */
505static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
506 int value)
507{
508 samsung_gpio_set(gc, offset, value);
509 return pinctrl_gpio_direction_output(gc->base + offset);
510}
511
512/*
513 * Parse the pin names listed in the 'samsung,pins' property and convert it
514 * into a list of gpio numbers are create a pin group from it.
515 */
516static int __init samsung_pinctrl_parse_dt_pins(struct platform_device *pdev,
517 struct device_node *cfg_np, struct pinctrl_desc *pctl,
518 unsigned int **pin_list, unsigned int *npins)
519{
520 struct device *dev = &pdev->dev;
521 struct property *prop;
522 struct pinctrl_pin_desc const *pdesc = pctl->pins;
523 unsigned int idx = 0, cnt;
524 const char *pin_name;
525
526 *npins = of_property_count_strings(cfg_np, "samsung,pins");
527 if (*npins < 0) {
528 dev_err(dev, "invalid pin list in %s node", cfg_np->name);
529 return -EINVAL;
530 }
531
532 *pin_list = devm_kzalloc(dev, *npins * sizeof(**pin_list), GFP_KERNEL);
533 if (!*pin_list) {
534 dev_err(dev, "failed to allocate memory for pin list\n");
535 return -ENOMEM;
536 }
537
538 of_property_for_each_string(cfg_np, "samsung,pins", prop, pin_name) {
539 for (cnt = 0; cnt < pctl->npins; cnt++) {
540 if (pdesc[cnt].name) {
541 if (!strcmp(pin_name, pdesc[cnt].name)) {
542 (*pin_list)[idx++] = pdesc[cnt].number;
543 break;
544 }
545 }
546 }
547 if (cnt == pctl->npins) {
548 dev_err(dev, "pin %s not valid in %s node\n",
549 pin_name, cfg_np->name);
550 devm_kfree(dev, *pin_list);
551 return -EINVAL;
552 }
553 }
554
555 return 0;
556}
557
558/*
559 * Parse the information about all the available pin groups and pin functions
560 * from device node of the pin-controller. A pin group is formed with all
561 * the pins listed in the "samsung,pins" property.
562 */
563static int __init samsung_pinctrl_parse_dt(struct platform_device *pdev,
564 struct samsung_pinctrl_drv_data *drvdata)
565{
566 struct device *dev = &pdev->dev;
567 struct device_node *dev_np = dev->of_node;
568 struct device_node *cfg_np;
569 struct samsung_pin_group *groups, *grp;
570 struct samsung_pmx_func *functions, *func;
571 unsigned *pin_list;
572 unsigned int npins, grp_cnt, func_idx = 0;
573 char *gname, *fname;
574 int ret;
575
576 grp_cnt = of_get_child_count(dev_np);
577 if (!grp_cnt)
578 return -EINVAL;
579
580 groups = devm_kzalloc(dev, grp_cnt * sizeof(*groups), GFP_KERNEL);
581 if (!groups) {
582 dev_err(dev, "failed allocate memory for ping group list\n");
583 return -EINVAL;
584 }
585 grp = groups;
586
587 functions = devm_kzalloc(dev, grp_cnt * sizeof(*functions), GFP_KERNEL);
588 if (!functions) {
589 dev_err(dev, "failed to allocate memory for function list\n");
590 return -EINVAL;
591 }
592 func = functions;
593
594 /*
595 * Iterate over all the child nodes of the pin controller node
596 * and create pin groups and pin function lists.
597 */
598 for_each_child_of_node(dev_np, cfg_np) {
599 u32 function;
600 if (of_find_property(cfg_np, "interrupt-controller", NULL))
601 continue;
602
603 ret = samsung_pinctrl_parse_dt_pins(pdev, cfg_np,
604 &drvdata->pctl, &pin_list, &npins);
605 if (ret)
606 return ret;
607
608 /* derive pin group name from the node name */
609 gname = devm_kzalloc(dev, strlen(cfg_np->name) + GSUFFIX_LEN,
610 GFP_KERNEL);
611 if (!gname) {
612 dev_err(dev, "failed to alloc memory for group name\n");
613 return -ENOMEM;
614 }
615 sprintf(gname, "%s%s", cfg_np->name, GROUP_SUFFIX);
616
617 grp->name = gname;
618 grp->pins = pin_list;
619 grp->num_pins = npins;
620 of_property_read_u32(cfg_np, "samsung,pin-function", &function);
621 grp->func = function;
622 grp++;
623
624 if (!of_find_property(cfg_np, "samsung,pin-function", NULL))
625 continue;
626
627 /* derive function name from the node name */
628 fname = devm_kzalloc(dev, strlen(cfg_np->name) + FSUFFIX_LEN,
629 GFP_KERNEL);
630 if (!fname) {
631 dev_err(dev, "failed to alloc memory for func name\n");
632 return -ENOMEM;
633 }
634 sprintf(fname, "%s%s", cfg_np->name, FUNCTION_SUFFIX);
635
636 func->name = fname;
637 func->groups = devm_kzalloc(dev, sizeof(char *), GFP_KERNEL);
638 if (!func->groups) {
639 dev_err(dev, "failed to alloc memory for group list "
640 "in pin function");
641 return -ENOMEM;
642 }
643 func->groups[0] = gname;
644 func->num_groups = 1;
645 func++;
646 func_idx++;
647 }
648
649 drvdata->pin_groups = groups;
650 drvdata->nr_groups = grp_cnt;
651 drvdata->pmx_functions = functions;
652 drvdata->nr_functions = func_idx;
653
654 return 0;
655}
656
657/* register the pinctrl interface with the pinctrl subsystem */
658static int __init samsung_pinctrl_register(struct platform_device *pdev,
659 struct samsung_pinctrl_drv_data *drvdata)
660{
661 struct pinctrl_desc *ctrldesc = &drvdata->pctl;
662 struct pinctrl_pin_desc *pindesc, *pdesc;
663 struct samsung_pin_bank *pin_bank;
664 char *pin_names;
665 int pin, bank, ret;
666
667 ctrldesc->name = "samsung-pinctrl";
668 ctrldesc->owner = THIS_MODULE;
669 ctrldesc->pctlops = &samsung_pctrl_ops;
670 ctrldesc->pmxops = &samsung_pinmux_ops;
671 ctrldesc->confops = &samsung_pinconf_ops;
672
673 pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) *
674 drvdata->ctrl->nr_pins, GFP_KERNEL);
675 if (!pindesc) {
676 dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n");
677 return -ENOMEM;
678 }
679 ctrldesc->pins = pindesc;
680 ctrldesc->npins = drvdata->ctrl->nr_pins;
681 ctrldesc->npins = drvdata->ctrl->nr_pins;
682
683 /* dynamically populate the pin number and pin name for pindesc */
684 for (pin = 0, pdesc = pindesc; pin < ctrldesc->npins; pin++, pdesc++)
685 pdesc->number = pin + drvdata->ctrl->base;
686
687 /*
688 * allocate space for storing the dynamically generated names for all
689 * the pins which belong to this pin-controller.
690 */
691 pin_names = devm_kzalloc(&pdev->dev, sizeof(char) * PIN_NAME_LENGTH *
692 drvdata->ctrl->nr_pins, GFP_KERNEL);
693 if (!pin_names) {
694 dev_err(&pdev->dev, "mem alloc for pin names failed\n");
695 return -ENOMEM;
696 }
697
698 /* for each pin, the name of the pin is pin-bank name + pin number */
699 for (bank = 0; bank < drvdata->ctrl->nr_banks; bank++) {
700 pin_bank = &drvdata->ctrl->pin_banks[bank];
701 for (pin = 0; pin < pin_bank->nr_pins; pin++) {
702 sprintf(pin_names, "%s-%d", pin_bank->name, pin);
703 pdesc = pindesc + pin_bank->pin_base + pin;
704 pdesc->name = pin_names;
705 pin_names += PIN_NAME_LENGTH;
706 }
707 }
708
709 drvdata->pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, drvdata);
710 if (!drvdata->pctl_dev) {
711 dev_err(&pdev->dev, "could not register pinctrl driver\n");
712 return -EINVAL;
713 }
714
715 drvdata->grange.name = "samsung-pctrl-gpio-range";
716 drvdata->grange.id = 0;
717 drvdata->grange.base = drvdata->ctrl->base;
718 drvdata->grange.npins = drvdata->ctrl->nr_pins;
719 drvdata->grange.gc = drvdata->gc;
720 pinctrl_add_gpio_range(drvdata->pctl_dev, &drvdata->grange);
721
722 ret = samsung_pinctrl_parse_dt(pdev, drvdata);
723 if (ret) {
724 pinctrl_unregister(drvdata->pctl_dev);
725 return ret;
726 }
727
728 return 0;
729}
730
731/* register the gpiolib interface with the gpiolib subsystem */
732static int __init samsung_gpiolib_register(struct platform_device *pdev,
733 struct samsung_pinctrl_drv_data *drvdata)
734{
735 struct gpio_chip *gc;
736 int ret;
737
738 gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL);
739 if (!gc) {
740 dev_err(&pdev->dev, "mem alloc for gpio_chip failed\n");
741 return -ENOMEM;
742 }
743
744 drvdata->gc = gc;
745 gc->base = drvdata->ctrl->base;
746 gc->ngpio = drvdata->ctrl->nr_pins;
747 gc->dev = &pdev->dev;
748 gc->set = samsung_gpio_set;
749 gc->get = samsung_gpio_get;
750 gc->direction_input = samsung_gpio_direction_input;
751 gc->direction_output = samsung_gpio_direction_output;
752 gc->label = drvdata->ctrl->label;
753 gc->owner = THIS_MODULE;
754 ret = gpiochip_add(gc);
755 if (ret) {
756 dev_err(&pdev->dev, "failed to register gpio_chip %s, error "
757 "code: %d\n", gc->label, ret);
758 return ret;
759 }
760
761 return 0;
762}
763
764/* unregister the gpiolib interface with the gpiolib subsystem */
765static int __init samsung_gpiolib_unregister(struct platform_device *pdev,
766 struct samsung_pinctrl_drv_data *drvdata)
767{
768 int ret = gpiochip_remove(drvdata->gc);
769 if (ret) {
770 dev_err(&pdev->dev, "gpio chip remove failed\n");
771 return ret;
772 }
773 return 0;
774}
775
776static const struct of_device_id samsung_pinctrl_dt_match[];
777
778/* retrieve the soc specific data */
779static inline struct samsung_pin_ctrl *samsung_pinctrl_get_soc_data(
780 struct platform_device *pdev)
781{
782 int id;
783 const struct of_device_id *match;
784 const struct device_node *node = pdev->dev.of_node;
785
786 id = of_alias_get_id(pdev->dev.of_node, "pinctrl");
787 if (id < 0) {
788 dev_err(&pdev->dev, "failed to get alias id\n");
789 return NULL;
790 }
791 match = of_match_node(samsung_pinctrl_dt_match, node);
792 return (struct samsung_pin_ctrl *)match->data + id;
793}
794
795static int __devinit samsung_pinctrl_probe(struct platform_device *pdev)
796{
797 struct samsung_pinctrl_drv_data *drvdata;
798 struct device *dev = &pdev->dev;
799 struct samsung_pin_ctrl *ctrl;
800 struct resource *res;
801 int ret;
802
803 if (!dev->of_node) {
804 dev_err(dev, "device tree node not found\n");
805 return -ENODEV;
806 }
807
808 ctrl = samsung_pinctrl_get_soc_data(pdev);
809 if (!ctrl) {
810 dev_err(&pdev->dev, "driver data not available\n");
811 return -EINVAL;
812 }
813
814 drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
815 if (!drvdata) {
816 dev_err(dev, "failed to allocate memory for driver's "
817 "private data\n");
818 return -ENOMEM;
819 }
820 drvdata->ctrl = ctrl;
821 drvdata->dev = dev;
822
823 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
824 if (!res) {
825 dev_err(dev, "cannot find IO resource\n");
826 return -ENOENT;
827 }
828
829 drvdata->virt_base = devm_request_and_ioremap(&pdev->dev, res);
830 if (!drvdata->virt_base) {
831 dev_err(dev, "ioremap failed\n");
832 return -ENODEV;
833 }
834
835 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
836 if (res)
837 drvdata->irq = res->start;
838
839 ret = samsung_gpiolib_register(pdev, drvdata);
840 if (ret)
841 return ret;
842
843 ret = samsung_pinctrl_register(pdev, drvdata);
844 if (ret) {
845 samsung_gpiolib_unregister(pdev, drvdata);
846 return ret;
847 }
848
849 if (ctrl->eint_gpio_init)
850 ctrl->eint_gpio_init(drvdata);
851 if (ctrl->eint_wkup_init)
852 ctrl->eint_wkup_init(drvdata);
853
854 platform_set_drvdata(pdev, drvdata);
855 return 0;
856}
857
858static const struct of_device_id samsung_pinctrl_dt_match[] = {
859 { .compatible = "samsung,pinctrl-exynos4210",
860 .data = (void *)exynos4210_pin_ctrl },
861 {},
862};
863MODULE_DEVICE_TABLE(of, samsung_pinctrl_dt_match);
864
865static struct platform_driver samsung_pinctrl_driver = {
866 .probe = samsung_pinctrl_probe,
867 .driver = {
868 .name = "samsung-pinctrl",
869 .owner = THIS_MODULE,
870 .of_match_table = of_match_ptr(samsung_pinctrl_dt_match),
871 },
872};
873
874static int __init samsung_pinctrl_drv_register(void)
875{
876 return platform_driver_register(&samsung_pinctrl_driver);
877}
878postcore_initcall(samsung_pinctrl_drv_register);
879
880static void __exit samsung_pinctrl_drv_unregister(void)
881{
882 platform_driver_unregister(&samsung_pinctrl_driver);
883}
884module_exit(samsung_pinctrl_drv_unregister);
885
886MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>");
887MODULE_DESCRIPTION("Samsung pinctrl driver");
888MODULE_LICENSE("GPL v2");