aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorThomas Abraham <thomas.abraham@linaro.org>2012-10-09 20:41:12 -0400
committerKukjin Kim <kgene.kim@samsung.com>2012-11-21 23:42:58 -0500
commitf0b9a7e521fa2fc5f3e0e57472126a6fed9cbb99 (patch)
tree8b3a56553fc658e84f55ecf38180b2f2576459ba /drivers/pinctrl
parent1355bbc480b12ea5b5ec7d171ee34399dc57ec23 (diff)
pinctrl: exynos5440: add pinctrl driver for Samsung EXYNOS5440 SoC
Add a new pinctrl driver for Samsung EXYNOS5440 SoC. The pin controller module in EXYNOS5440 is different from the pin controller found on other Samsung SoC. Hence, the pin controller driver for EXYNOS5440 SoC is independent of the Samsung pinctrl framework. Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/Kconfig5
-rw-r--r--drivers/pinctrl/Makefile1
-rw-r--r--drivers/pinctrl/pinctrl-exynos5440.c919
3 files changed, 925 insertions, 0 deletions
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index d96caefd914a..dd08b490d091 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -188,6 +188,11 @@ config PINCTRL_EXYNOS4
188 depends on OF && GPIOLIB 188 depends on OF && GPIOLIB
189 select PINCTRL_SAMSUNG 189 select PINCTRL_SAMSUNG
190 190
191config PINCTRL_EXYNOS5440
192 bool "Samsung EXYNOS5440 SoC pinctrl driver"
193 select PINMUX
194 select PINCONF
195
191config PINCTRL_MVEBU 196config PINCTRL_MVEBU
192 bool 197 bool
193 depends on ARCH_MVEBU 198 depends on ARCH_MVEBU
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index f395ba5cec25..476928bb97c2 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o
36obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o 36obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o
37obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o 37obj-$(CONFIG_PINCTRL_SAMSUNG) += pinctrl-samsung.o
38obj-$(CONFIG_PINCTRL_EXYNOS4) += pinctrl-exynos.o 38obj-$(CONFIG_PINCTRL_EXYNOS4) += pinctrl-exynos.o
39obj-$(CONFIG_PINCTRL_EXYNOS5440) += pinctrl-exynos5440.o
39obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o 40obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o
40obj-$(CONFIG_PINCTRL_DOVE) += pinctrl-dove.o 41obj-$(CONFIG_PINCTRL_DOVE) += pinctrl-dove.o
41obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o 42obj-$(CONFIG_PINCTRL_KIRKWOOD) += pinctrl-kirkwood.o
diff --git a/drivers/pinctrl/pinctrl-exynos5440.c b/drivers/pinctrl/pinctrl-exynos5440.c
new file mode 100644
index 000000000000..b8635f634e91
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-exynos5440.c
@@ -0,0 +1,919 @@
1/*
2 * pin-controller/pin-mux/pin-config/gpio-driver for Samsung's EXYNOS5440 SoC.
3 *
4 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13#include <linux/module.h>
14#include <linux/platform_device.h>
15#include <linux/io.h>
16#include <linux/slab.h>
17#include <linux/err.h>
18#include <linux/gpio.h>
19#include <linux/device.h>
20#include <linux/pinctrl/pinctrl.h>
21#include <linux/pinctrl/pinmux.h>
22#include <linux/pinctrl/pinconf.h>
23#include "core.h"
24
25/* EXYNOS5440 GPIO and Pinctrl register offsets */
26#define GPIO_MUX 0x00
27#define GPIO_IE 0x04
28#define GPIO_INT 0x08
29#define GPIO_TYPE 0x0C
30#define GPIO_VAL 0x10
31#define GPIO_OE 0x14
32#define GPIO_IN 0x18
33#define GPIO_PE 0x1C
34#define GPIO_PS 0x20
35#define GPIO_SR 0x24
36#define GPIO_DS0 0x28
37#define GPIO_DS1 0x2C
38
39#define EXYNOS5440_MAX_PINS 23
40#define PIN_NAME_LENGTH 10
41
42#define GROUP_SUFFIX "-grp"
43#define GSUFFIX_LEN sizeof(GROUP_SUFFIX)
44#define FUNCTION_SUFFIX "-mux"
45#define FSUFFIX_LEN sizeof(FUNCTION_SUFFIX)
46
47/*
48 * pin configuration type and its value are packed together into a 16-bits.
49 * The upper 8-bits represent the configuration type and the lower 8-bits
50 * hold the value of the configuration type.
51 */
52#define PINCFG_TYPE_MASK 0xFF
53#define PINCFG_VALUE_SHIFT 8
54#define PINCFG_VALUE_MASK (0xFF << PINCFG_VALUE_SHIFT)
55#define PINCFG_PACK(type, value) (((value) << PINCFG_VALUE_SHIFT) | type)
56#define PINCFG_UNPACK_TYPE(cfg) ((cfg) & PINCFG_TYPE_MASK)
57#define PINCFG_UNPACK_VALUE(cfg) (((cfg) & PINCFG_VALUE_MASK) >> \
58 PINCFG_VALUE_SHIFT)
59
60/**
61 * enum pincfg_type - possible pin configuration types supported.
62 * @PINCFG_TYPE_PUD: Pull up/down configuration.
63 * @PINCFG_TYPE_DRV: Drive strength configuration.
64 * @PINCFG_TYPE_SKEW_RATE: Skew rate configuration.
65 * @PINCFG_TYPE_INPUT_TYPE: Pin input type configuration.
66 */
67enum pincfg_type {
68 PINCFG_TYPE_PUD,
69 PINCFG_TYPE_DRV,
70 PINCFG_TYPE_SKEW_RATE,
71 PINCFG_TYPE_INPUT_TYPE
72};
73
74/**
75 * struct exynos5440_pin_group: represent group of pins for pincfg setting.
76 * @name: name of the pin group, used to lookup the group.
77 * @pins: the pins included in this group.
78 * @num_pins: number of pins included in this group.
79 */
80struct exynos5440_pin_group {
81 const char *name;
82 const unsigned int *pins;
83 u8 num_pins;
84};
85
86/**
87 * struct exynos5440_pmx_func: represent a pin function.
88 * @name: name of the pin function, used to lookup the function.
89 * @groups: one or more names of pin groups that provide this function.
90 * @num_groups: number of groups included in @groups.
91 * @function: the function number to be programmed when selected.
92 */
93struct exynos5440_pmx_func {
94 const char *name;
95 const char **groups;
96 u8 num_groups;
97 unsigned long function;
98};
99
100/**
101 * struct exynos5440_pinctrl_priv_data: driver's private runtime data.
102 * @reg_base: ioremapped based address of the register space.
103 * @gc: gpio chip registered with gpiolib.
104 * @pin_groups: list of pin groups parsed from device tree.
105 * @nr_groups: number of pin groups available.
106 * @pmx_functions: list of pin functions parsed from device tree.
107 * @nr_functions: number of pin functions available.
108 */
109struct exynos5440_pinctrl_priv_data {
110 void __iomem *reg_base;
111 struct gpio_chip *gc;
112
113 const struct exynos5440_pin_group *pin_groups;
114 unsigned int nr_groups;
115 const struct exynos5440_pmx_func *pmx_functions;
116 unsigned int nr_functions;
117};
118
119/* list of all possible config options supported */
120struct pin_config {
121 char *prop_cfg;
122 unsigned int cfg_type;
123} pcfgs[] = {
124 { "samsung,exynos5440-pin-pud", PINCFG_TYPE_PUD },
125 { "samsung,exynos5440-pin-drv", PINCFG_TYPE_DRV },
126 { "samsung,exynos5440-pin-skew-rate", PINCFG_TYPE_SKEW_RATE },
127 { "samsung,exynos5440-pin-input-type", PINCFG_TYPE_INPUT_TYPE },
128};
129
130/* check if the selector is a valid pin group selector */
131static int exynos5440_get_group_count(struct pinctrl_dev *pctldev)
132{
133 struct exynos5440_pinctrl_priv_data *priv;
134
135 priv = pinctrl_dev_get_drvdata(pctldev);
136 return priv->nr_groups;
137}
138
139/* return the name of the group selected by the group selector */
140static const char *exynos5440_get_group_name(struct pinctrl_dev *pctldev,
141 unsigned selector)
142{
143 struct exynos5440_pinctrl_priv_data *priv;
144
145 priv = pinctrl_dev_get_drvdata(pctldev);
146 return priv->pin_groups[selector].name;
147}
148
149/* return the pin numbers associated with the specified group */
150static int exynos5440_get_group_pins(struct pinctrl_dev *pctldev,
151 unsigned selector, const unsigned **pins, unsigned *num_pins)
152{
153 struct exynos5440_pinctrl_priv_data *priv;
154
155 priv = pinctrl_dev_get_drvdata(pctldev);
156 *pins = priv->pin_groups[selector].pins;
157 *num_pins = priv->pin_groups[selector].num_pins;
158 return 0;
159}
160
161/* create pinctrl_map entries by parsing device tree nodes */
162static int exynos5440_dt_node_to_map(struct pinctrl_dev *pctldev,
163 struct device_node *np, struct pinctrl_map **maps,
164 unsigned *nmaps)
165{
166 struct device *dev = pctldev->dev;
167 struct pinctrl_map *map;
168 unsigned long *cfg = NULL;
169 char *gname, *fname;
170 int cfg_cnt = 0, map_cnt = 0, idx = 0;
171
172 /* count the number of config options specfied in the node */
173 for (idx = 0; idx < ARRAY_SIZE(pcfgs); idx++)
174 if (of_find_property(np, pcfgs[idx].prop_cfg, NULL))
175 cfg_cnt++;
176
177 /*
178 * Find out the number of map entries to create. All the config options
179 * can be accomadated into a single config map entry.
180 */
181 if (cfg_cnt)
182 map_cnt = 1;
183 if (of_find_property(np, "samsung,exynos5440-pin-function", NULL))
184 map_cnt++;
185 if (!map_cnt) {
186 dev_err(dev, "node %s does not have either config or function "
187 "configurations\n", np->name);
188 return -EINVAL;
189 }
190
191 /* Allocate memory for pin-map entries */
192 map = kzalloc(sizeof(*map) * map_cnt, GFP_KERNEL);
193 if (!map) {
194 dev_err(dev, "could not alloc memory for pin-maps\n");
195 return -ENOMEM;
196 }
197 *nmaps = 0;
198
199 /*
200 * Allocate memory for pin group name. The pin group name is derived
201 * from the node name from which these map entries are be created.
202 */
203 gname = kzalloc(strlen(np->name) + GSUFFIX_LEN, GFP_KERNEL);
204 if (!gname) {
205 dev_err(dev, "failed to alloc memory for group name\n");
206 goto free_map;
207 }
208 sprintf(gname, "%s%s", np->name, GROUP_SUFFIX);
209
210 /*
211 * don't have config options? then skip over to creating function
212 * map entries.
213 */
214 if (!cfg_cnt)
215 goto skip_cfgs;
216
217 /* Allocate memory for config entries */
218 cfg = kzalloc(sizeof(*cfg) * cfg_cnt, GFP_KERNEL);
219 if (!cfg) {
220 dev_err(dev, "failed to alloc memory for configs\n");
221 goto free_gname;
222 }
223
224 /* Prepare a list of config settings */
225 for (idx = 0, cfg_cnt = 0; idx < ARRAY_SIZE(pcfgs); idx++) {
226 u32 value;
227 if (!of_property_read_u32(np, pcfgs[idx].prop_cfg, &value))
228 cfg[cfg_cnt++] =
229 PINCFG_PACK(pcfgs[idx].cfg_type, value);
230 }
231
232 /* create the config map entry */
233 map[*nmaps].data.configs.group_or_pin = gname;
234 map[*nmaps].data.configs.configs = cfg;
235 map[*nmaps].data.configs.num_configs = cfg_cnt;
236 map[*nmaps].type = PIN_MAP_TYPE_CONFIGS_GROUP;
237 *nmaps += 1;
238
239skip_cfgs:
240 /* create the function map entry */
241 if (of_find_property(np, "samsung,exynos5440-pin-function", NULL)) {
242 fname = kzalloc(strlen(np->name) + FSUFFIX_LEN, GFP_KERNEL);
243 if (!fname) {
244 dev_err(dev, "failed to alloc memory for func name\n");
245 goto free_cfg;
246 }
247 sprintf(fname, "%s%s", np->name, FUNCTION_SUFFIX);
248
249 map[*nmaps].data.mux.group = gname;
250 map[*nmaps].data.mux.function = fname;
251 map[*nmaps].type = PIN_MAP_TYPE_MUX_GROUP;
252 *nmaps += 1;
253 }
254
255 *maps = map;
256 return 0;
257
258free_cfg:
259 kfree(cfg);
260free_gname:
261 kfree(gname);
262free_map:
263 kfree(map);
264 return -ENOMEM;
265}
266
267/* free the memory allocated to hold the pin-map table */
268static void exynos5440_dt_free_map(struct pinctrl_dev *pctldev,
269 struct pinctrl_map *map, unsigned num_maps)
270{
271 int idx;
272
273 for (idx = 0; idx < num_maps; idx++) {
274 if (map[idx].type == PIN_MAP_TYPE_MUX_GROUP) {
275 kfree(map[idx].data.mux.function);
276 if (!idx)
277 kfree(map[idx].data.mux.group);
278 } else if (map->type == PIN_MAP_TYPE_CONFIGS_GROUP) {
279 kfree(map[idx].data.configs.configs);
280 if (!idx)
281 kfree(map[idx].data.configs.group_or_pin);
282 }
283 };
284
285 kfree(map);
286}
287
288/* list of pinctrl callbacks for the pinctrl core */
289static struct pinctrl_ops exynos5440_pctrl_ops = {
290 .get_groups_count = exynos5440_get_group_count,
291 .get_group_name = exynos5440_get_group_name,
292 .get_group_pins = exynos5440_get_group_pins,
293 .dt_node_to_map = exynos5440_dt_node_to_map,
294 .dt_free_map = exynos5440_dt_free_map,
295};
296
297/* check if the selector is a valid pin function selector */
298static int exynos5440_get_functions_count(struct pinctrl_dev *pctldev)
299{
300 struct exynos5440_pinctrl_priv_data *priv;
301
302 priv = pinctrl_dev_get_drvdata(pctldev);
303 return priv->nr_functions;
304}
305
306/* return the name of the pin function specified */
307static const char *exynos5440_pinmux_get_fname(struct pinctrl_dev *pctldev,
308 unsigned selector)
309{
310 struct exynos5440_pinctrl_priv_data *priv;
311
312 priv = pinctrl_dev_get_drvdata(pctldev);
313 return priv->pmx_functions[selector].name;
314}
315
316/* return the groups associated for the specified function selector */
317static int exynos5440_pinmux_get_groups(struct pinctrl_dev *pctldev,
318 unsigned selector, const char * const **groups,
319 unsigned * const num_groups)
320{
321 struct exynos5440_pinctrl_priv_data *priv;
322
323 priv = pinctrl_dev_get_drvdata(pctldev);
324 *groups = priv->pmx_functions[selector].groups;
325 *num_groups = priv->pmx_functions[selector].num_groups;
326 return 0;
327}
328
329/* enable or disable a pinmux function */
330static void exynos5440_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,
331 unsigned group, bool enable)
332{
333 struct exynos5440_pinctrl_priv_data *priv;
334 void __iomem *base;
335 u32 function;
336 u32 data;
337
338 priv = pinctrl_dev_get_drvdata(pctldev);
339 base = priv->reg_base;
340 function = priv->pmx_functions[selector].function;
341
342 data = readl(base + GPIO_MUX);
343 if (enable)
344 data |= (1 << function);
345 else
346 data &= ~(1 << function);
347 writel(data, base + GPIO_MUX);
348}
349
350/* enable a specified pinmux by writing to registers */
351static int exynos5440_pinmux_enable(struct pinctrl_dev *pctldev, unsigned selector,
352 unsigned group)
353{
354 exynos5440_pinmux_setup(pctldev, selector, group, true);
355 return 0;
356}
357
358/* disable a specified pinmux by writing to registers */
359static void exynos5440_pinmux_disable(struct pinctrl_dev *pctldev,
360 unsigned selector, unsigned group)
361{
362 exynos5440_pinmux_setup(pctldev, selector, group, false);
363}
364
365/*
366 * The calls to gpio_direction_output() and gpio_direction_input()
367 * leads to this function call (via the pinctrl_gpio_direction_{input|output}()
368 * function called from the gpiolib interface).
369 */
370static int exynos5440_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev,
371 struct pinctrl_gpio_range *range, unsigned offset, bool input)
372{
373 return 0;
374}
375
376/* list of pinmux callbacks for the pinmux vertical in pinctrl core */
377static struct pinmux_ops exynos5440_pinmux_ops = {
378 .get_functions_count = exynos5440_get_functions_count,
379 .get_function_name = exynos5440_pinmux_get_fname,
380 .get_function_groups = exynos5440_pinmux_get_groups,
381 .enable = exynos5440_pinmux_enable,
382 .disable = exynos5440_pinmux_disable,
383 .gpio_set_direction = exynos5440_pinmux_gpio_set_direction,
384};
385
386/* set the pin config settings for a specified pin */
387static int exynos5440_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
388 unsigned long config)
389{
390 struct exynos5440_pinctrl_priv_data *priv;
391 void __iomem *base;
392 enum pincfg_type cfg_type = PINCFG_UNPACK_TYPE(config);
393 u32 cfg_value = PINCFG_UNPACK_VALUE(config);
394 u32 data;
395
396 priv = pinctrl_dev_get_drvdata(pctldev);
397 base = priv->reg_base;
398
399 switch (cfg_type) {
400 case PINCFG_TYPE_PUD:
401 /* first set pull enable/disable bit */
402 data = readl(base + GPIO_PE);
403 data &= ~(1 << pin);
404 if (cfg_value)
405 data |= (1 << pin);
406 writel(data, base + GPIO_PE);
407
408 /* then set pull up/down bit */
409 data = readl(base + GPIO_PS);
410 data &= ~(1 << pin);
411 if (cfg_value == 2)
412 data |= (1 << pin);
413 writel(data, base + GPIO_PS);
414 break;
415
416 case PINCFG_TYPE_DRV:
417 /* set the first bit of the drive strength */
418 data = readl(base + GPIO_DS0);
419 data &= ~(1 << pin);
420 data |= ((cfg_value & 1) << pin);
421 writel(data, base + GPIO_DS0);
422 cfg_value >>= 1;
423
424 /* set the second bit of the driver strength */
425 data = readl(base + GPIO_DS1);
426 data &= ~(1 << pin);
427 data |= ((cfg_value & 1) << pin);
428 writel(data, base + GPIO_DS1);
429 break;
430 case PINCFG_TYPE_SKEW_RATE:
431 data = readl(base + GPIO_SR);
432 data &= ~(1 << pin);
433 data |= ((cfg_value & 1) << pin);
434 writel(data, base + GPIO_SR);
435 break;
436 case PINCFG_TYPE_INPUT_TYPE:
437 data = readl(base + GPIO_TYPE);
438 data &= ~(1 << pin);
439 data |= ((cfg_value & 1) << pin);
440 writel(data, base + GPIO_TYPE);
441 break;
442 default:
443 WARN_ON(1);
444 return -EINVAL;
445 }
446
447 return 0;
448}
449
450/* get the pin config settings for a specified pin */
451static int exynos5440_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
452 unsigned long *config)
453{
454 struct exynos5440_pinctrl_priv_data *priv;
455 void __iomem *base;
456 enum pincfg_type cfg_type = PINCFG_UNPACK_TYPE(*config);
457 u32 data;
458
459 priv = pinctrl_dev_get_drvdata(pctldev);
460 base = priv->reg_base;
461
462 switch (cfg_type) {
463 case PINCFG_TYPE_PUD:
464 data = readl(base + GPIO_PE);
465 data = (data >> pin) & 1;
466 if (!data)
467 *config = 0;
468 else
469 *config = ((readl(base + GPIO_PS) >> pin) & 1) + 1;
470 break;
471 case PINCFG_TYPE_DRV:
472 data = readl(base + GPIO_DS0);
473 data = (data >> pin) & 1;
474 *config = data;
475 data = readl(base + GPIO_DS1);
476 data = (data >> pin) & 1;
477 *config |= (data << 1);
478 break;
479 case PINCFG_TYPE_SKEW_RATE:
480 data = readl(base + GPIO_SR);
481 *config = (data >> pin) & 1;
482 break;
483 case PINCFG_TYPE_INPUT_TYPE:
484 data = readl(base + GPIO_TYPE);
485 *config = (data >> pin) & 1;
486 break;
487 default:
488 WARN_ON(1);
489 return -EINVAL;
490 }
491
492 return 0;
493}
494
495/* set the pin config settings for a specified pin group */
496static int exynos5440_pinconf_group_set(struct pinctrl_dev *pctldev,
497 unsigned group, unsigned long config)
498{
499 struct exynos5440_pinctrl_priv_data *priv;
500 const unsigned int *pins;
501 unsigned int cnt;
502
503 priv = pinctrl_dev_get_drvdata(pctldev);
504 pins = priv->pin_groups[group].pins;
505
506 for (cnt = 0; cnt < priv->pin_groups[group].num_pins; cnt++)
507 exynos5440_pinconf_set(pctldev, pins[cnt], config);
508
509 return 0;
510}
511
512/* get the pin config settings for a specified pin group */
513static int exynos5440_pinconf_group_get(struct pinctrl_dev *pctldev,
514 unsigned int group, unsigned long *config)
515{
516 struct exynos5440_pinctrl_priv_data *priv;
517 const unsigned int *pins;
518
519 priv = pinctrl_dev_get_drvdata(pctldev);
520 pins = priv->pin_groups[group].pins;
521 exynos5440_pinconf_get(pctldev, pins[0], config);
522 return 0;
523}
524
525/* list of pinconfig callbacks for pinconfig vertical in the pinctrl code */
526static struct pinconf_ops exynos5440_pinconf_ops = {
527 .pin_config_get = exynos5440_pinconf_get,
528 .pin_config_set = exynos5440_pinconf_set,
529 .pin_config_group_get = exynos5440_pinconf_group_get,
530 .pin_config_group_set = exynos5440_pinconf_group_set,
531};
532
533/* gpiolib gpio_set callback function */
534static void exynos5440_gpio_set(struct gpio_chip *gc, unsigned offset, int value)
535{
536 struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev);
537 void __iomem *base = priv->reg_base;
538 u32 data;
539
540 data = readl(base + GPIO_VAL);
541 data &= ~(1 << offset);
542 if (value)
543 data |= 1 << offset;
544 writel(data, base + GPIO_VAL);
545}
546
547/* gpiolib gpio_get callback function */
548static int exynos5440_gpio_get(struct gpio_chip *gc, unsigned offset)
549{
550 struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev);
551 void __iomem *base = priv->reg_base;
552 u32 data;
553
554 data = readl(base + GPIO_IN);
555 data >>= offset;
556 data &= 1;
557 return data;
558}
559
560/* gpiolib gpio_direction_input callback function */
561static int exynos5440_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
562{
563 struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev);
564 void __iomem *base = priv->reg_base;
565 u32 data;
566
567 /* first disable the data output enable on this pin */
568 data = readl(base + GPIO_OE);
569 data &= ~(1 << offset);
570 writel(data, base + GPIO_OE);
571
572 /* now enable input on this pin */
573 data = readl(base + GPIO_IE);
574 data |= 1 << offset;
575 writel(data, base + GPIO_IE);
576 return 0;
577}
578
579/* gpiolib gpio_direction_output callback function */
580static int exynos5440_gpio_direction_output(struct gpio_chip *gc, unsigned offset,
581 int value)
582{
583 struct exynos5440_pinctrl_priv_data *priv = dev_get_drvdata(gc->dev);
584 void __iomem *base = priv->reg_base;
585 u32 data;
586
587 exynos5440_gpio_set(gc, offset, value);
588
589 /* first disable the data input enable on this pin */
590 data = readl(base + GPIO_IE);
591 data &= ~(1 << offset);
592 writel(data, base + GPIO_IE);
593
594 /* now enable output on this pin */
595 data = readl(base + GPIO_OE);
596 data |= 1 << offset;
597 writel(data, base + GPIO_OE);
598 return 0;
599}
600
601/* parse the pin numbers listed in the 'samsung,exynos5440-pins' property */
602static int __init exynos5440_pinctrl_parse_dt_pins(struct platform_device *pdev,
603 struct device_node *cfg_np, unsigned int **pin_list,
604 unsigned int *npins)
605{
606 struct device *dev = &pdev->dev;
607 struct property *prop;
608
609 prop = of_find_property(cfg_np, "samsung,exynos5440-pins", NULL);
610 if (!prop)
611 return -ENOENT;
612
613 *npins = prop->length / sizeof(unsigned long);
614 if (!*npins) {
615 dev_err(dev, "invalid pin list in %s node", cfg_np->name);
616 return -EINVAL;
617 }
618
619 *pin_list = devm_kzalloc(dev, *npins * sizeof(**pin_list), GFP_KERNEL);
620 if (!*pin_list) {
621 dev_err(dev, "failed to allocate memory for pin list\n");
622 return -ENOMEM;
623 }
624
625 return of_property_read_u32_array(cfg_np, "samsung,exynos5440-pins",
626 *pin_list, *npins);
627}
628
629/*
630 * Parse the information about all the available pin groups and pin functions
631 * from device node of the pin-controller.
632 */
633static int __init exynos5440_pinctrl_parse_dt(struct platform_device *pdev,
634 struct exynos5440_pinctrl_priv_data *priv)
635{
636 struct device *dev = &pdev->dev;
637 struct device_node *dev_np = dev->of_node;
638 struct device_node *cfg_np;
639 struct exynos5440_pin_group *groups, *grp;
640 struct exynos5440_pmx_func *functions, *func;
641 unsigned *pin_list;
642 unsigned int npins, grp_cnt, func_idx = 0;
643 char *gname, *fname;
644 int ret;
645
646 grp_cnt = of_get_child_count(dev_np);
647 if (!grp_cnt)
648 return -EINVAL;
649
650 groups = devm_kzalloc(dev, grp_cnt * sizeof(*groups), GFP_KERNEL);
651 if (!groups) {
652 dev_err(dev, "failed allocate memory for ping group list\n");
653 return -EINVAL;
654 }
655 grp = groups;
656
657 functions = devm_kzalloc(dev, grp_cnt * sizeof(*functions), GFP_KERNEL);
658 if (!functions) {
659 dev_err(dev, "failed to allocate memory for function list\n");
660 return -EINVAL;
661 }
662 func = functions;
663
664 /*
665 * Iterate over all the child nodes of the pin controller node
666 * and create pin groups and pin function lists.
667 */
668 for_each_child_of_node(dev_np, cfg_np) {
669 u32 function;
670
671 ret = exynos5440_pinctrl_parse_dt_pins(pdev, cfg_np,
672 &pin_list, &npins);
673 if (ret)
674 return ret;
675
676 /* derive pin group name from the node name */
677 gname = devm_kzalloc(dev, strlen(cfg_np->name) + GSUFFIX_LEN,
678 GFP_KERNEL);
679 if (!gname) {
680 dev_err(dev, "failed to alloc memory for group name\n");
681 return -ENOMEM;
682 }
683 sprintf(gname, "%s%s", cfg_np->name, GROUP_SUFFIX);
684
685 grp->name = gname;
686 grp->pins = pin_list;
687 grp->num_pins = npins;
688 grp++;
689
690 ret = of_property_read_u32(cfg_np, "samsung,exynos5440-pin-function",
691 &function);
692 if (ret)
693 continue;
694
695 /* derive function name from the node name */
696 fname = devm_kzalloc(dev, strlen(cfg_np->name) + FSUFFIX_LEN,
697 GFP_KERNEL);
698 if (!fname) {
699 dev_err(dev, "failed to alloc memory for func name\n");
700 return -ENOMEM;
701 }
702 sprintf(fname, "%s%s", cfg_np->name, FUNCTION_SUFFIX);
703
704 func->name = fname;
705 func->groups = devm_kzalloc(dev, sizeof(char *), GFP_KERNEL);
706 if (!func->groups) {
707 dev_err(dev, "failed to alloc memory for group list "
708 "in pin function");
709 return -ENOMEM;
710 }
711 func->groups[0] = gname;
712 func->num_groups = 1;
713 func->function = function;
714 func++;
715 func_idx++;
716 }
717
718 priv->pin_groups = groups;
719 priv->nr_groups = grp_cnt;
720 priv->pmx_functions = functions;
721 priv->nr_functions = func_idx;
722 return 0;
723}
724
725/* register the pinctrl interface with the pinctrl subsystem */
726static int __init exynos5440_pinctrl_register(struct platform_device *pdev,
727 struct exynos5440_pinctrl_priv_data *priv)
728{
729 struct device *dev = &pdev->dev;
730 struct pinctrl_desc *ctrldesc;
731 struct pinctrl_dev *pctl_dev;
732 struct pinctrl_pin_desc *pindesc, *pdesc;
733 struct pinctrl_gpio_range grange;
734 char *pin_names;
735 int pin, ret;
736
737 ctrldesc = devm_kzalloc(dev, sizeof(*ctrldesc), GFP_KERNEL);
738 if (!ctrldesc) {
739 dev_err(dev, "could not allocate memory for pinctrl desc\n");
740 return -ENOMEM;
741 }
742
743 ctrldesc->name = "exynos5440-pinctrl";
744 ctrldesc->owner = THIS_MODULE;
745 ctrldesc->pctlops = &exynos5440_pctrl_ops;
746 ctrldesc->pmxops = &exynos5440_pinmux_ops;
747 ctrldesc->confops = &exynos5440_pinconf_ops;
748
749 pindesc = devm_kzalloc(&pdev->dev, sizeof(*pindesc) *
750 EXYNOS5440_MAX_PINS, GFP_KERNEL);
751 if (!pindesc) {
752 dev_err(&pdev->dev, "mem alloc for pin descriptors failed\n");
753 return -ENOMEM;
754 }
755 ctrldesc->pins = pindesc;
756 ctrldesc->npins = EXYNOS5440_MAX_PINS;
757
758 /* dynamically populate the pin number and pin name for pindesc */
759 for (pin = 0, pdesc = pindesc; pin < ctrldesc->npins; pin++, pdesc++)
760 pdesc->number = pin;
761
762 /*
763 * allocate space for storing the dynamically generated names for all
764 * the pins which belong to this pin-controller.
765 */
766 pin_names = devm_kzalloc(&pdev->dev, sizeof(char) * PIN_NAME_LENGTH *
767 ctrldesc->npins, GFP_KERNEL);
768 if (!pin_names) {
769 dev_err(&pdev->dev, "mem alloc for pin names failed\n");
770 return -ENOMEM;
771 }
772
773 /* for each pin, set the name of the pin */
774 for (pin = 0; pin < ctrldesc->npins; pin++) {
775 sprintf(pin_names, "gpio%02d", pin);
776 pdesc = pindesc + pin;
777 pdesc->name = pin_names;
778 pin_names += PIN_NAME_LENGTH;
779 }
780
781 ret = exynos5440_pinctrl_parse_dt(pdev, priv);
782 if (ret)
783 return ret;
784
785 pctl_dev = pinctrl_register(ctrldesc, &pdev->dev, priv);
786 if (!pctl_dev) {
787 dev_err(&pdev->dev, "could not register pinctrl driver\n");
788 return -EINVAL;
789 }
790
791 grange.name = "exynos5440-pctrl-gpio-range";
792 grange.id = 0;
793 grange.base = 0;
794 grange.npins = EXYNOS5440_MAX_PINS;
795 grange.gc = priv->gc;
796 pinctrl_add_gpio_range(pctl_dev, &grange);
797 return 0;
798}
799
800/* register the gpiolib interface with the gpiolib subsystem */
801static int __init exynos5440_gpiolib_register(struct platform_device *pdev,
802 struct exynos5440_pinctrl_priv_data *priv)
803{
804 struct gpio_chip *gc;
805 int ret;
806
807 gc = devm_kzalloc(&pdev->dev, sizeof(*gc), GFP_KERNEL);
808 if (!gc) {
809 dev_err(&pdev->dev, "mem alloc for gpio_chip failed\n");
810 return -ENOMEM;
811 }
812
813 priv->gc = gc;
814 gc->base = 0;
815 gc->ngpio = EXYNOS5440_MAX_PINS;
816 gc->dev = &pdev->dev;
817 gc->set = exynos5440_gpio_set;
818 gc->get = exynos5440_gpio_get;
819 gc->direction_input = exynos5440_gpio_direction_input;
820 gc->direction_output = exynos5440_gpio_direction_output;
821 gc->label = "gpiolib-exynos5440";
822 gc->owner = THIS_MODULE;
823 ret = gpiochip_add(gc);
824 if (ret) {
825 dev_err(&pdev->dev, "failed to register gpio_chip %s, error "
826 "code: %d\n", gc->label, ret);
827 return ret;
828 }
829
830 return 0;
831}
832
833/* unregister the gpiolib interface with the gpiolib subsystem */
834static int __init exynos5440_gpiolib_unregister(struct platform_device *pdev,
835 struct exynos5440_pinctrl_priv_data *priv)
836{
837 int ret = gpiochip_remove(priv->gc);
838 if (ret) {
839 dev_err(&pdev->dev, "gpio chip remove failed\n");
840 return ret;
841 }
842 return 0;
843}
844
845static int __devinit exynos5440_pinctrl_probe(struct platform_device *pdev)
846{
847 struct device *dev = &pdev->dev;
848 struct exynos5440_pinctrl_priv_data *priv;
849 struct resource *res;
850 int ret;
851
852 if (!dev->of_node) {
853 dev_err(dev, "device tree node not found\n");
854 return -ENODEV;
855 }
856
857 priv = devm_kzalloc(dev, sizeof(priv), GFP_KERNEL);
858 if (!priv) {
859 dev_err(dev, "could not allocate memory for private data\n");
860 return -ENOMEM;
861 }
862
863 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
864 if (!res) {
865 dev_err(dev, "cannot find IO resource\n");
866 return -ENOENT;
867 }
868
869 priv->reg_base = devm_request_and_ioremap(&pdev->dev, res);
870 if (!priv->reg_base) {
871 dev_err(dev, "ioremap failed\n");
872 return -ENODEV;
873 }
874
875 ret = exynos5440_gpiolib_register(pdev, priv);
876 if (ret)
877 return ret;
878
879 ret = exynos5440_pinctrl_register(pdev, priv);
880 if (ret) {
881 exynos5440_gpiolib_unregister(pdev, priv);
882 return ret;
883 }
884
885 platform_set_drvdata(pdev, priv);
886 dev_info(dev, "EXYNOS5440 pinctrl driver registered\n");
887 return 0;
888}
889
890static const struct of_device_id exynos5440_pinctrl_dt_match[] = {
891 { .compatible = "samsung,exynos5440-pinctrl" },
892 {},
893};
894MODULE_DEVICE_TABLE(of, exynos5440_pinctrl_dt_match);
895
896static struct platform_driver exynos5440_pinctrl_driver = {
897 .probe = exynos5440_pinctrl_probe,
898 .driver = {
899 .name = "exynos5440-pinctrl",
900 .owner = THIS_MODULE,
901 .of_match_table = of_match_ptr(exynos5440_pinctrl_dt_match),
902 },
903};
904
905static int __init exynos5440_pinctrl_drv_register(void)
906{
907 return platform_driver_register(&exynos5440_pinctrl_driver);
908}
909postcore_initcall(exynos5440_pinctrl_drv_register);
910
911static void __exit exynos5440_pinctrl_drv_unregister(void)
912{
913 platform_driver_unregister(&exynos5440_pinctrl_driver);
914}
915module_exit(exynos5440_pinctrl_drv_unregister);
916
917MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>");
918MODULE_DESCRIPTION("Samsung EXYNOS5440 SoC pinctrl driver");
919MODULE_LICENSE("GPL v2");