aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl
diff options
context:
space:
mode:
authorJohn Crispin <blogic@openwrt.org>2012-08-28 06:44:59 -0400
committerJohn Crispin <blogic@openwrt.org>2012-09-13 04:30:49 -0400
commit3f8c50c9b110dad4136ea7226cd87b0c4cdb70c8 (patch)
treebd2dc11535f5102ca56edc10e4674d1e13908f20 /drivers/pinctrl
parent30404aec4d093942ba67ded8e1926cbf4472d4f7 (diff)
OF: pinctrl: MIPS: lantiq: implement lantiq/xway pinctrl support
Implement support for pinctrl on lantiq/xway socs. The IO core found on these socs has the registers for pinctrl, pinconf and gpio mixed up in the same register range. As the gpio_chip handling is only a few lines, the driver also implements the gpio functionality. This obseletes the old gpio driver that was located in the arch/ folder. Signed-off-by: John Crispin <blogic@openwrt.org> Acked-by: Linus Walleij <linus.walleij@linaro.org> Cc: devicetree-discuss@lists.ozlabs.org Cc: linux-kernel@vger.kernel.org
Diffstat (limited to 'drivers/pinctrl')
-rw-r--r--drivers/pinctrl/Kconfig11
-rw-r--r--drivers/pinctrl/Makefile2
-rw-r--r--drivers/pinctrl/pinctrl-lantiq.c342
-rw-r--r--drivers/pinctrl/pinctrl-lantiq.h194
-rw-r--r--drivers/pinctrl/pinctrl-xway.c781
5 files changed, 1330 insertions, 0 deletions
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 54e3588bef62..f77dce0b1011 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -55,6 +55,12 @@ config PINCTRL_IMX6Q
55 help 55 help
56 Say Y here to enable the imx6q pinctrl driver 56 Say Y here to enable the imx6q pinctrl driver
57 57
58config PINCTRL_LANTIQ
59 bool
60 depends on LANTIQ
61 select PINMUX
62 select PINCONF
63
58config PINCTRL_PXA3xx 64config PINCTRL_PXA3xx
59 bool 65 bool
60 select PINMUX 66 select PINMUX
@@ -147,6 +153,11 @@ config PINCTRL_COH901
147 153
148source "drivers/pinctrl/spear/Kconfig" 154source "drivers/pinctrl/spear/Kconfig"
149 155
156config PINCTRL_XWAY
157 bool
158 depends on SOC_TYPE_XWAY
159 depends on PINCTRL_LANTIQ
160
150endmenu 161endmenu
151 162
152endif 163endif
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index f40b1f81ff2c..e19e2077a795 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -29,5 +29,7 @@ obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
29obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o 29obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o
30obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o 30obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o
31obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o 31obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o
32obj-$(CONFIG_PINCTRL_XWAY) += pinctrl-xway.o
33obj-$(CONFIG_PINCTRL_LANTIQ) += pinctrl-lantiq.o
32 34
33obj-$(CONFIG_PLAT_SPEAR) += spear/ 35obj-$(CONFIG_PLAT_SPEAR) += spear/
diff --git a/drivers/pinctrl/pinctrl-lantiq.c b/drivers/pinctrl/pinctrl-lantiq.c
new file mode 100644
index 000000000000..07ba7682cf22
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-lantiq.c
@@ -0,0 +1,342 @@
1/*
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
49void ltq_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
50 struct pinctrl_map *map, unsigned num_maps)
51{
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
131int 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)
135{
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
278static void ltq_pmx_disable(struct pinctrl_dev *pctrldev,
279 unsigned func,
280 unsigned group)
281{
282 /*
283 * Nothing to do here. However, pinconf_check_ops() requires this
284 * callback to be defined.
285 */
286}
287
288static int ltq_pmx_gpio_request_enable(struct pinctrl_dev *pctrldev,
289 struct pinctrl_gpio_range *range,
290 unsigned pin)
291{
292 struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
293 int mfp = match_mfp(info, pin + (range->id * 32));
294 int pin_func;
295
296 if (mfp < 0) {
297 dev_err(info->dev, "could not find mfp for pin %d\n", pin);
298 return -EINVAL;
299 }
300
301 pin_func = match_mux(&info->mfp[mfp], 0);
302 if (pin_func < 0) {
303 dev_err(info->dev, "No GPIO function on pin%d\n", mfp);
304 return -EINVAL;
305 }
306
307 return info->apply_mux(pctrldev, mfp, pin_func);
308}
309
310static struct pinmux_ops ltq_pmx_ops = {
311 .get_functions_count = ltq_pmx_func_count,
312 .get_function_name = ltq_pmx_func_name,
313 .get_function_groups = ltq_pmx_get_groups,
314 .enable = ltq_pmx_enable,
315 .disable = ltq_pmx_disable,
316 .gpio_request_enable = ltq_pmx_gpio_request_enable,
317};
318
319/*
320 * allow different socs to register with the generic part of the lanti
321 * pinctrl code
322 */
323int ltq_pinctrl_register(struct platform_device *pdev,
324 struct ltq_pinmux_info *info)
325{
326 struct pinctrl_desc *desc;
327
328 if (!info)
329 return -EINVAL;
330 desc = info->desc;
331 desc->pctlops = &ltq_pctrl_ops;
332 desc->pmxops = &ltq_pmx_ops;
333 info->dev = &pdev->dev;
334
335 info->pctrl = pinctrl_register(desc, &pdev->dev, info);
336 if (!info->pctrl) {
337 dev_err(&pdev->dev, "failed to register LTQ pinmux driver\n");
338 return -EINVAL;
339 }
340 platform_set_drvdata(pdev, info);
341 return 0;
342}
diff --git a/drivers/pinctrl/pinctrl-lantiq.h b/drivers/pinctrl/pinctrl-lantiq.h
new file mode 100644
index 000000000000..4419d32a0ade
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-lantiq.h
@@ -0,0 +1,194 @@
1/*
2 * linux/drivers/pinctrl/pinctrl-lantiq.h
3 * based on linux/drivers/pinctrl/pinctrl-pxa3xx.h
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#ifndef __PINCTRL_LANTIQ_H
13
14#include <linux/clkdev.h>
15#include <linux/pinctrl/pinctrl.h>
16#include <linux/pinctrl/pinconf.h>
17#include <linux/pinctrl/pinmux.h>
18#include <linux/pinctrl/consumer.h>
19#include <linux/pinctrl/machine.h>
20
21#include "core.h"
22
23#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
24
25#define LTQ_MAX_MUX 4
26#define MFPR_FUNC_MASK 0x3
27
28#define LTQ_PINCONF_PACK(param, arg) ((param) << 16 | (arg))
29#define LTQ_PINCONF_UNPACK_PARAM(conf) ((conf) >> 16)
30#define LTQ_PINCONF_UNPACK_ARG(conf) ((conf) & 0xffff)
31
32enum ltq_pinconf_param {
33 LTQ_PINCONF_PARAM_PULL,
34 LTQ_PINCONF_PARAM_OPEN_DRAIN,
35 LTQ_PINCONF_PARAM_DRIVE_CURRENT,
36 LTQ_PINCONF_PARAM_SLEW_RATE,
37};
38
39struct ltq_cfg_param {
40 const char *property;
41 enum ltq_pinconf_param param;
42};
43
44struct ltq_mfp_pin {
45 const char *name;
46 const unsigned int pin;
47 const unsigned short func[LTQ_MAX_MUX];
48};
49
50struct ltq_pin_group {
51 const char *name;
52 const unsigned mux;
53 const unsigned *pins;
54 const unsigned npins;
55};
56
57struct ltq_pmx_func {
58 const char *name;
59 const char * const *groups;
60 const unsigned num_groups;
61};
62
63struct ltq_pinmux_info {
64 struct device *dev;
65 struct pinctrl_dev *pctrl;
66
67 /* we need to manage up to 5 pad controllers */
68 void __iomem *membase[5];
69
70 /* the descriptor for the subsystem */
71 struct pinctrl_desc *desc;
72
73 /* we expose our pads to the subsystem */
74 struct pinctrl_pin_desc *pads;
75
76 /* the number of pads. this varies between socs */
77 unsigned int num_pads;
78
79 /* these are our multifunction pins */
80 const struct ltq_mfp_pin *mfp;
81 unsigned int num_mfp;
82
83 /* a number of multifunction pins can be grouped together */
84 const struct ltq_pin_group *grps;
85 unsigned int num_grps;
86
87 /* a mapping between function string and id */
88 const struct ltq_pmx_func *funcs;
89 unsigned int num_funcs;
90
91 /* the pinconf options that we are able to read from the DT */
92 const struct ltq_cfg_param *params;
93 unsigned int num_params;
94
95 /* the pad controller can have a irq mapping */
96 const unsigned *exin;
97 unsigned int num_exin;
98
99 /* we need 5 clocks max */
100 struct clk *clk[5];
101
102 /* soc specific callback used to apply muxing */
103 int (*apply_mux)(struct pinctrl_dev *pctrldev, int pin, int mux);
104};
105
106enum ltq_pin {
107 GPIO0 = 0,
108 GPIO1,
109 GPIO2,
110 GPIO3,
111 GPIO4,
112 GPIO5,
113 GPIO6,
114 GPIO7,
115 GPIO8,
116 GPIO9,
117 GPIO10, /* 10 */
118 GPIO11,
119 GPIO12,
120 GPIO13,
121 GPIO14,
122 GPIO15,
123 GPIO16,
124 GPIO17,
125 GPIO18,
126 GPIO19,
127 GPIO20, /* 20 */
128 GPIO21,
129 GPIO22,
130 GPIO23,
131 GPIO24,
132 GPIO25,
133 GPIO26,
134 GPIO27,
135 GPIO28,
136 GPIO29,
137 GPIO30, /* 30 */
138 GPIO31,
139 GPIO32,
140 GPIO33,
141 GPIO34,
142 GPIO35,
143 GPIO36,
144 GPIO37,
145 GPIO38,
146 GPIO39,
147 GPIO40, /* 40 */
148 GPIO41,
149 GPIO42,
150 GPIO43,
151 GPIO44,
152 GPIO45,
153 GPIO46,
154 GPIO47,
155 GPIO48,
156 GPIO49,
157 GPIO50, /* 50 */
158 GPIO51,
159 GPIO52,
160 GPIO53,
161 GPIO54,
162 GPIO55,
163
164 GPIO64,
165 GPIO65,
166 GPIO66,
167 GPIO67,
168 GPIO68,
169 GPIO69,
170 GPIO70,
171 GPIO71,
172 GPIO72,
173 GPIO73,
174 GPIO74,
175 GPIO75,
176 GPIO76,
177 GPIO77,
178 GPIO78,
179 GPIO79,
180 GPIO80,
181 GPIO81,
182 GPIO82,
183 GPIO83,
184 GPIO84,
185 GPIO85,
186 GPIO86,
187 GPIO87,
188 GPIO88,
189};
190
191extern int ltq_pinctrl_register(struct platform_device *pdev,
192 struct ltq_pinmux_info *info);
193extern int ltq_pinctrl_unregister(struct platform_device *pdev);
194#endif /* __PINCTRL_PXA3XX_H */
diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c
new file mode 100644
index 000000000000..f8d917d40c92
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-xway.c
@@ -0,0 +1,781 @@
1/*
2 * linux/drivers/pinctrl/pinmux-xway.c
3 * based on linux/drivers/pinctrl/pinmux-pxa910.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/slab.h>
13#include <linux/module.h>
14#include <linux/of_platform.h>
15#include <linux/of_address.h>
16#include <linux/of_gpio.h>
17#include <linux/ioport.h>
18#include <linux/io.h>
19#include <linux/device.h>
20#include <linux/module.h>
21#include <linux/io.h>
22#include <linux/platform_device.h>
23
24#include "pinctrl-lantiq.h"
25
26#include <lantiq_soc.h>
27
28/* we have 3 1/2 banks of 16 bit each */
29#define PINS 16
30#define PORT3 3
31#define PORT(x) (x / PINS)
32#define PORT_PIN(x) (x % PINS)
33
34/* we have 2 mux bits that can be set for each pin */
35#define MUX_ALT0 0x1
36#define MUX_ALT1 0x2
37
38/*
39 * each bank has this offset apart from the 1/2 bank that is mixed into the
40 * other 3 ranges
41 */
42#define REG_OFF 0x30
43
44/* these are the offsets to our registers */
45#define GPIO_BASE(p) (REG_OFF * PORT(p))
46#define GPIO_OUT(p) GPIO_BASE(p)
47#define GPIO_IN(p) (GPIO_BASE(p) + 0x04)
48#define GPIO_DIR(p) (GPIO_BASE(p) + 0x08)
49#define GPIO_ALT0(p) (GPIO_BASE(p) + 0x0C)
50#define GPIO_ALT1(p) (GPIO_BASE(p) + 0x10)
51#define GPIO_OD(p) (GPIO_BASE(p) + 0x14)
52#define GPIO_PUDSEL(p) (GPIO_BASE(p) + 0x1c)
53#define GPIO_PUDEN(p) (GPIO_BASE(p) + 0x20)
54
55/* the 1/2 port needs special offsets for some registers */
56#define GPIO3_OD (GPIO_BASE(0) + 0x24)
57#define GPIO3_PUDSEL (GPIO_BASE(0) + 0x28)
58#define GPIO3_PUDEN (GPIO_BASE(0) + 0x2C)
59#define GPIO3_ALT1 (GPIO_BASE(PINS) + 0x24)
60
61/* macros to help us access the registers */
62#define gpio_getbit(m, r, p) (!!(ltq_r32(m + r) & BIT(p)))
63#define gpio_setbit(m, r, p) ltq_w32_mask(0, BIT(p), m + r)
64#define gpio_clearbit(m, r, p) ltq_w32_mask(BIT(p), 0, m + r)
65
66#define MFP_XWAY(a, f0, f1, f2, f3) \
67 { \
68 .name = #a, \
69 .pin = a, \
70 .func = { \
71 XWAY_MUX_##f0, \
72 XWAY_MUX_##f1, \
73 XWAY_MUX_##f2, \
74 XWAY_MUX_##f3, \
75 }, \
76 }
77
78#define GRP_MUX(a, m, p) \
79 { .name = a, .mux = XWAY_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), }
80
81#define FUNC_MUX(f, m) \
82 { .func = f, .mux = XWAY_MUX_##m, }
83
84#define XWAY_MAX_PIN 32
85#define XR9_MAX_PIN 56
86
87enum xway_mux {
88 XWAY_MUX_GPIO = 0,
89 XWAY_MUX_SPI,
90 XWAY_MUX_ASC,
91 XWAY_MUX_PCI,
92 XWAY_MUX_CGU,
93 XWAY_MUX_EBU,
94 XWAY_MUX_JTAG,
95 XWAY_MUX_EXIN,
96 XWAY_MUX_TDM,
97 XWAY_MUX_STP,
98 XWAY_MUX_SIN,
99 XWAY_MUX_GPT,
100 XWAY_MUX_NMI,
101 XWAY_MUX_MDIO,
102 XWAY_MUX_MII,
103 XWAY_MUX_EPHY,
104 XWAY_MUX_DFE,
105 XWAY_MUX_SDIO,
106 XWAY_MUX_NONE = 0xffff,
107};
108
109static const struct ltq_mfp_pin xway_mfp[] = {
110 /* pin f0 f1 f2 f3 */
111 MFP_XWAY(GPIO0, GPIO, EXIN, NONE, TDM),
112 MFP_XWAY(GPIO1, GPIO, EXIN, NONE, NONE),
113 MFP_XWAY(GPIO2, GPIO, CGU, EXIN, NONE),
114 MFP_XWAY(GPIO3, GPIO, CGU, NONE, PCI),
115 MFP_XWAY(GPIO4, GPIO, STP, NONE, ASC),
116 MFP_XWAY(GPIO5, GPIO, STP, NONE, NONE),
117 MFP_XWAY(GPIO6, GPIO, STP, GPT, ASC),
118 MFP_XWAY(GPIO7, GPIO, CGU, PCI, NONE),
119 MFP_XWAY(GPIO8, GPIO, CGU, NMI, NONE),
120 MFP_XWAY(GPIO9, GPIO, ASC, SPI, EXIN),
121 MFP_XWAY(GPIO10, GPIO, ASC, SPI, NONE),
122 MFP_XWAY(GPIO11, GPIO, ASC, PCI, SPI),
123 MFP_XWAY(GPIO12, GPIO, ASC, NONE, NONE),
124 MFP_XWAY(GPIO13, GPIO, EBU, SPI, NONE),
125 MFP_XWAY(GPIO14, GPIO, CGU, PCI, NONE),
126 MFP_XWAY(GPIO15, GPIO, SPI, JTAG, NONE),
127 MFP_XWAY(GPIO16, GPIO, SPI, NONE, JTAG),
128 MFP_XWAY(GPIO17, GPIO, SPI, NONE, JTAG),
129 MFP_XWAY(GPIO18, GPIO, SPI, NONE, JTAG),
130 MFP_XWAY(GPIO19, GPIO, PCI, NONE, NONE),
131 MFP_XWAY(GPIO20, GPIO, JTAG, NONE, NONE),
132 MFP_XWAY(GPIO21, GPIO, PCI, EBU, GPT),
133 MFP_XWAY(GPIO22, GPIO, SPI, NONE, NONE),
134 MFP_XWAY(GPIO23, GPIO, EBU, PCI, STP),
135 MFP_XWAY(GPIO24, GPIO, EBU, TDM, PCI),
136 MFP_XWAY(GPIO25, GPIO, TDM, NONE, ASC),
137 MFP_XWAY(GPIO26, GPIO, EBU, NONE, TDM),
138 MFP_XWAY(GPIO27, GPIO, TDM, NONE, ASC),
139 MFP_XWAY(GPIO28, GPIO, GPT, NONE, NONE),
140 MFP_XWAY(GPIO29, GPIO, PCI, NONE, NONE),
141 MFP_XWAY(GPIO30, GPIO, PCI, NONE, NONE),
142 MFP_XWAY(GPIO31, GPIO, EBU, PCI, NONE),
143 MFP_XWAY(GPIO32, GPIO, NONE, NONE, EBU),
144 MFP_XWAY(GPIO33, GPIO, NONE, NONE, EBU),
145 MFP_XWAY(GPIO34, GPIO, NONE, NONE, EBU),
146 MFP_XWAY(GPIO35, GPIO, NONE, NONE, EBU),
147 MFP_XWAY(GPIO36, GPIO, SIN, NONE, EBU),
148 MFP_XWAY(GPIO37, GPIO, PCI, NONE, NONE),
149 MFP_XWAY(GPIO38, GPIO, PCI, NONE, NONE),
150 MFP_XWAY(GPIO39, GPIO, EXIN, NONE, NONE),
151 MFP_XWAY(GPIO40, GPIO, NONE, NONE, NONE),
152 MFP_XWAY(GPIO41, GPIO, NONE, NONE, NONE),
153 MFP_XWAY(GPIO42, GPIO, MDIO, NONE, NONE),
154 MFP_XWAY(GPIO43, GPIO, MDIO, NONE, NONE),
155 MFP_XWAY(GPIO44, GPIO, NONE, NONE, SIN),
156 MFP_XWAY(GPIO45, GPIO, NONE, NONE, SIN),
157 MFP_XWAY(GPIO46, GPIO, NONE, NONE, EXIN),
158 MFP_XWAY(GPIO47, GPIO, NONE, NONE, SIN),
159 MFP_XWAY(GPIO48, GPIO, EBU, NONE, NONE),
160 MFP_XWAY(GPIO49, GPIO, EBU, NONE, NONE),
161 MFP_XWAY(GPIO50, GPIO, NONE, NONE, NONE),
162 MFP_XWAY(GPIO51, GPIO, NONE, NONE, NONE),
163 MFP_XWAY(GPIO52, GPIO, NONE, NONE, NONE),
164 MFP_XWAY(GPIO53, GPIO, NONE, NONE, NONE),
165 MFP_XWAY(GPIO54, GPIO, NONE, NONE, NONE),
166 MFP_XWAY(GPIO55, GPIO, NONE, NONE, NONE),
167};
168
169static const struct ltq_mfp_pin ase_mfp[] = {
170 /* pin f0 f1 f2 f3 */
171 MFP_XWAY(GPIO0, GPIO, EXIN, MII, TDM),
172 MFP_XWAY(GPIO1, GPIO, STP, DFE, EBU),
173 MFP_XWAY(GPIO2, GPIO, STP, DFE, EPHY),
174 MFP_XWAY(GPIO3, GPIO, STP, EPHY, EBU),
175 MFP_XWAY(GPIO4, GPIO, GPT, EPHY, MII),
176 MFP_XWAY(GPIO5, GPIO, MII, ASC, GPT),
177 MFP_XWAY(GPIO6, GPIO, MII, ASC, EXIN),
178 MFP_XWAY(GPIO7, GPIO, SPI, MII, JTAG),
179 MFP_XWAY(GPIO8, GPIO, SPI, MII, JTAG),
180 MFP_XWAY(GPIO9, GPIO, SPI, MII, JTAG),
181 MFP_XWAY(GPIO10, GPIO, SPI, MII, JTAG),
182 MFP_XWAY(GPIO11, GPIO, EBU, CGU, JTAG),
183 MFP_XWAY(GPIO12, GPIO, EBU, MII, SDIO),
184 MFP_XWAY(GPIO13, GPIO, EBU, MII, CGU),
185 MFP_XWAY(GPIO14, GPIO, EBU, SPI, CGU),
186 MFP_XWAY(GPIO15, GPIO, EBU, SPI, SDIO),
187 MFP_XWAY(GPIO16, GPIO, NONE, NONE, NONE),
188 MFP_XWAY(GPIO17, GPIO, NONE, NONE, NONE),
189 MFP_XWAY(GPIO18, GPIO, NONE, NONE, NONE),
190 MFP_XWAY(GPIO19, GPIO, EBU, MII, SDIO),
191 MFP_XWAY(GPIO20, GPIO, EBU, MII, SDIO),
192 MFP_XWAY(GPIO21, GPIO, EBU, MII, SDIO),
193 MFP_XWAY(GPIO22, GPIO, EBU, MII, CGU),
194 MFP_XWAY(GPIO23, GPIO, EBU, MII, CGU),
195 MFP_XWAY(GPIO24, GPIO, EBU, NONE, MII),
196 MFP_XWAY(GPIO25, GPIO, EBU, MII, GPT),
197 MFP_XWAY(GPIO26, GPIO, EBU, MII, SDIO),
198 MFP_XWAY(GPIO27, GPIO, EBU, NONE, MII),
199 MFP_XWAY(GPIO28, GPIO, MII, EBU, SDIO),
200 MFP_XWAY(GPIO29, GPIO, EBU, MII, EXIN),
201 MFP_XWAY(GPIO30, GPIO, NONE, NONE, NONE),
202 MFP_XWAY(GPIO31, GPIO, NONE, NONE, NONE),
203};
204
205static const unsigned pins_jtag[] = {GPIO15, GPIO16, GPIO17, GPIO19, GPIO35};
206static const unsigned pins_asc0[] = {GPIO11, GPIO12};
207static const unsigned pins_asc0_cts_rts[] = {GPIO9, GPIO10};
208static const unsigned pins_stp[] = {GPIO4, GPIO5, GPIO6};
209static const unsigned pins_nmi[] = {GPIO8};
210static const unsigned pins_mdio[] = {GPIO42, GPIO43};
211
212static const unsigned pins_ebu_a24[] = {GPIO13};
213static const unsigned pins_ebu_clk[] = {GPIO21};
214static const unsigned pins_ebu_cs1[] = {GPIO23};
215static const unsigned pins_ebu_a23[] = {GPIO24};
216static const unsigned pins_ebu_wait[] = {GPIO26};
217static const unsigned pins_ebu_a25[] = {GPIO31};
218static const unsigned pins_ebu_rdy[] = {GPIO48};
219static const unsigned pins_ebu_rd[] = {GPIO49};
220
221static const unsigned pins_nand_ale[] = {GPIO13};
222static const unsigned pins_nand_cs1[] = {GPIO23};
223static const unsigned pins_nand_cle[] = {GPIO24};
224static const unsigned pins_nand_rdy[] = {GPIO48};
225static const unsigned pins_nand_rd[] = {GPIO49};
226
227static const unsigned pins_exin0[] = {GPIO0};
228static const unsigned pins_exin1[] = {GPIO1};
229static const unsigned pins_exin2[] = {GPIO2};
230static const unsigned pins_exin3[] = {GPIO39};
231static const unsigned pins_exin4[] = {GPIO46};
232static const unsigned pins_exin5[] = {GPIO9};
233
234static const unsigned pins_spi[] = {GPIO16, GPIO17, GPIO18};
235static const unsigned pins_spi_cs1[] = {GPIO15};
236static const unsigned pins_spi_cs2[] = {GPIO21};
237static const unsigned pins_spi_cs3[] = {GPIO13};
238static const unsigned pins_spi_cs4[] = {GPIO10};
239static const unsigned pins_spi_cs5[] = {GPIO9};
240static const unsigned pins_spi_cs6[] = {GPIO11};
241
242static const unsigned pins_gpt1[] = {GPIO28};
243static const unsigned pins_gpt2[] = {GPIO21};
244static const unsigned pins_gpt3[] = {GPIO6};
245
246static const unsigned pins_clkout0[] = {GPIO8};
247static const unsigned pins_clkout1[] = {GPIO7};
248static const unsigned pins_clkout2[] = {GPIO3};
249static const unsigned pins_clkout3[] = {GPIO2};
250
251static const unsigned pins_pci_gnt1[] = {GPIO30};
252static const unsigned pins_pci_gnt2[] = {GPIO23};
253static const unsigned pins_pci_gnt3[] = {GPIO19};
254static const unsigned pins_pci_gnt4[] = {GPIO38};
255static const unsigned pins_pci_req1[] = {GPIO29};
256static const unsigned pins_pci_req2[] = {GPIO31};
257static const unsigned pins_pci_req3[] = {GPIO3};
258static const unsigned pins_pci_req4[] = {GPIO37};
259
260static const unsigned ase_pins_jtag[] = {GPIO7, GPIO8, GPIO9, GPIO10, GPIO11};
261static const unsigned ase_pins_asc[] = {GPIO5, GPIO6};
262static const unsigned ase_pins_stp[] = {GPIO1, GPIO2, GPIO3};
263static const unsigned ase_pins_ephy[] = {GPIO2, GPIO3, GPIO4};
264static const unsigned ase_pins_dfe[] = {GPIO1, GPIO2};
265
266static const unsigned ase_pins_spi[] = {GPIO8, GPIO9, GPIO10};
267static const unsigned ase_pins_spi_cs1[] = {GPIO7};
268static const unsigned ase_pins_spi_cs2[] = {GPIO15};
269static const unsigned ase_pins_spi_cs3[] = {GPIO14};
270
271static const unsigned ase_pins_exin0[] = {GPIO6};
272static const unsigned ase_pins_exin1[] = {GPIO29};
273static const unsigned ase_pins_exin2[] = {GPIO0};
274
275static const unsigned ase_pins_gpt1[] = {GPIO5};
276static const unsigned ase_pins_gpt2[] = {GPIO4};
277static const unsigned ase_pins_gpt3[] = {GPIO25};
278
279static const struct ltq_pin_group xway_grps[] = {
280 GRP_MUX("exin0", EXIN, pins_exin0),
281 GRP_MUX("exin1", EXIN, pins_exin1),
282 GRP_MUX("exin2", EXIN, pins_exin2),
283 GRP_MUX("jtag", JTAG, pins_jtag),
284 GRP_MUX("ebu a23", EBU, pins_ebu_a23),
285 GRP_MUX("ebu a24", EBU, pins_ebu_a24),
286 GRP_MUX("ebu a25", EBU, pins_ebu_a25),
287 GRP_MUX("ebu clk", EBU, pins_ebu_clk),
288 GRP_MUX("ebu cs1", EBU, pins_ebu_cs1),
289 GRP_MUX("ebu wait", EBU, pins_ebu_wait),
290 GRP_MUX("nand ale", EBU, pins_nand_ale),
291 GRP_MUX("nand cs1", EBU, pins_nand_cs1),
292 GRP_MUX("nand cle", EBU, pins_nand_cle),
293 GRP_MUX("spi", SPI, pins_spi),
294 GRP_MUX("spi_cs1", SPI, pins_spi_cs1),
295 GRP_MUX("spi_cs2", SPI, pins_spi_cs2),
296 GRP_MUX("spi_cs3", SPI, pins_spi_cs3),
297 GRP_MUX("spi_cs4", SPI, pins_spi_cs4),
298 GRP_MUX("spi_cs5", SPI, pins_spi_cs5),
299 GRP_MUX("spi_cs6", SPI, pins_spi_cs6),
300 GRP_MUX("asc0", ASC, pins_asc0),
301 GRP_MUX("asc0 cts rts", ASC, pins_asc0_cts_rts),
302 GRP_MUX("stp", STP, pins_stp),
303 GRP_MUX("nmi", NMI, pins_nmi),
304 GRP_MUX("gpt1", GPT, pins_gpt1),
305 GRP_MUX("gpt2", GPT, pins_gpt2),
306 GRP_MUX("gpt3", GPT, pins_gpt3),
307 GRP_MUX("clkout0", CGU, pins_clkout0),
308 GRP_MUX("clkout1", CGU, pins_clkout1),
309 GRP_MUX("clkout2", CGU, pins_clkout2),
310 GRP_MUX("clkout3", CGU, pins_clkout3),
311 GRP_MUX("gnt1", PCI, pins_pci_gnt1),
312 GRP_MUX("gnt2", PCI, pins_pci_gnt2),
313 GRP_MUX("gnt3", PCI, pins_pci_gnt3),
314 GRP_MUX("req1", PCI, pins_pci_req1),
315 GRP_MUX("req2", PCI, pins_pci_req2),
316 GRP_MUX("req3", PCI, pins_pci_req3),
317/* xrx only */
318 GRP_MUX("nand rdy", EBU, pins_nand_rdy),
319 GRP_MUX("nand rd", EBU, pins_nand_rd),
320 GRP_MUX("exin3", EXIN, pins_exin3),
321 GRP_MUX("exin4", EXIN, pins_exin4),
322 GRP_MUX("exin5", EXIN, pins_exin5),
323 GRP_MUX("gnt4", PCI, pins_pci_gnt4),
324 GRP_MUX("req4", PCI, pins_pci_gnt4),
325 GRP_MUX("mdio", MDIO, pins_mdio),
326};
327
328static const struct ltq_pin_group ase_grps[] = {
329 GRP_MUX("exin0", EXIN, ase_pins_exin0),
330 GRP_MUX("exin1", EXIN, ase_pins_exin1),
331 GRP_MUX("exin2", EXIN, ase_pins_exin2),
332 GRP_MUX("jtag", JTAG, ase_pins_jtag),
333 GRP_MUX("stp", STP, ase_pins_stp),
334 GRP_MUX("asc", ASC, ase_pins_asc),
335 GRP_MUX("gpt1", GPT, ase_pins_gpt1),
336 GRP_MUX("gpt2", GPT, ase_pins_gpt2),
337 GRP_MUX("gpt3", GPT, ase_pins_gpt3),
338 GRP_MUX("ephy", EPHY, ase_pins_ephy),
339 GRP_MUX("dfe", DFE, ase_pins_dfe),
340 GRP_MUX("spi", SPI, ase_pins_spi),
341 GRP_MUX("spi_cs1", SPI, ase_pins_spi_cs1),
342 GRP_MUX("spi_cs2", SPI, ase_pins_spi_cs2),
343 GRP_MUX("spi_cs3", SPI, ase_pins_spi_cs3),
344};
345
346static const char * const xway_pci_grps[] = {"gnt1", "gnt2",
347 "gnt3", "req1",
348 "req2", "req3"};
349static const char * const xway_spi_grps[] = {"spi", "spi_cs1",
350 "spi_cs2", "spi_cs3",
351 "spi_cs4", "spi_cs5",
352 "spi_cs6"};
353static const char * const xway_cgu_grps[] = {"clkout0", "clkout1",
354 "clkout2", "clkout3"};
355static const char * const xway_ebu_grps[] = {"ebu a23", "ebu a24",
356 "ebu a25", "ebu cs1",
357 "ebu wait", "ebu clk",
358 "nand ale", "nand cs1",
359 "nand cle"};
360static const char * const xway_exin_grps[] = {"exin0", "exin1", "exin2"};
361static const char * const xway_gpt_grps[] = {"gpt1", "gpt2", "gpt3"};
362static const char * const xway_asc_grps[] = {"asc0", "asc0 cts rts"};
363static const char * const xway_jtag_grps[] = {"jtag"};
364static const char * const xway_stp_grps[] = {"stp"};
365static const char * const xway_nmi_grps[] = {"nmi"};
366
367/* ar9/vr9/gr9 */
368static const char * const xrx_mdio_grps[] = {"mdio"};
369static const char * const xrx_ebu_grps[] = {"ebu a23", "ebu a24",
370 "ebu a25", "ebu cs1",
371 "ebu wait", "ebu clk",
372 "nand ale", "nand cs1",
373 "nand cle", "nand rdy",
374 "nand rd"};
375static const char * const xrx_exin_grps[] = {"exin0", "exin1", "exin2",
376 "exin3", "exin4", "exin5"};
377static const char * const xrx_pci_grps[] = {"gnt1", "gnt2",
378 "gnt3", "gnt4",
379 "req1", "req2",
380 "req3", "req4"};
381
382/* ase */
383static const char * const ase_exin_grps[] = {"exin0", "exin1", "exin2"};
384static const char * const ase_gpt_grps[] = {"gpt1", "gpt2", "gpt3"};
385static const char * const ase_dfe_grps[] = {"dfe"};
386static const char * const ase_ephy_grps[] = {"ephy"};
387static const char * const ase_asc_grps[] = {"asc"};
388static const char * const ase_jtag_grps[] = {"jtag"};
389static const char * const ase_stp_grps[] = {"stp"};
390static const char * const ase_spi_grps[] = {"spi", "spi_cs1",
391 "spi_cs2", "spi_cs3"};
392
393static const struct ltq_pmx_func danube_funcs[] = {
394 {"spi", ARRAY_AND_SIZE(xway_spi_grps)},
395 {"asc", ARRAY_AND_SIZE(xway_asc_grps)},
396 {"cgu", ARRAY_AND_SIZE(xway_cgu_grps)},
397 {"jtag", ARRAY_AND_SIZE(xway_jtag_grps)},
398 {"exin", ARRAY_AND_SIZE(xway_exin_grps)},
399 {"stp", ARRAY_AND_SIZE(xway_stp_grps)},
400 {"gpt", ARRAY_AND_SIZE(xway_gpt_grps)},
401 {"nmi", ARRAY_AND_SIZE(xway_nmi_grps)},
402 {"pci", ARRAY_AND_SIZE(xway_pci_grps)},
403 {"ebu", ARRAY_AND_SIZE(xway_ebu_grps)},
404};
405
406static const struct ltq_pmx_func xrx_funcs[] = {
407 {"spi", ARRAY_AND_SIZE(xway_spi_grps)},
408 {"asc", ARRAY_AND_SIZE(xway_asc_grps)},
409 {"cgu", ARRAY_AND_SIZE(xway_cgu_grps)},
410 {"jtag", ARRAY_AND_SIZE(xway_jtag_grps)},
411 {"exin", ARRAY_AND_SIZE(xrx_exin_grps)},
412 {"stp", ARRAY_AND_SIZE(xway_stp_grps)},
413 {"gpt", ARRAY_AND_SIZE(xway_gpt_grps)},
414 {"nmi", ARRAY_AND_SIZE(xway_nmi_grps)},
415 {"pci", ARRAY_AND_SIZE(xrx_pci_grps)},
416 {"ebu", ARRAY_AND_SIZE(xrx_ebu_grps)},
417 {"mdio", ARRAY_AND_SIZE(xrx_mdio_grps)},
418};
419
420static const struct ltq_pmx_func ase_funcs[] = {
421 {"spi", ARRAY_AND_SIZE(ase_spi_grps)},
422 {"asc", ARRAY_AND_SIZE(ase_asc_grps)},
423 {"jtag", ARRAY_AND_SIZE(ase_jtag_grps)},
424 {"exin", ARRAY_AND_SIZE(ase_exin_grps)},
425 {"stp", ARRAY_AND_SIZE(ase_stp_grps)},
426 {"gpt", ARRAY_AND_SIZE(ase_gpt_grps)},
427 {"ephy", ARRAY_AND_SIZE(ase_ephy_grps)},
428 {"dfe", ARRAY_AND_SIZE(ase_dfe_grps)},
429};
430
431/* --------- pinconf related code --------- */
432static int xway_pinconf_get(struct pinctrl_dev *pctldev,
433 unsigned pin,
434 unsigned long *config)
435{
436 struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
437 enum ltq_pinconf_param param = LTQ_PINCONF_UNPACK_PARAM(*config);
438 int port = PORT(pin);
439 u32 reg;
440
441 switch (param) {
442 case LTQ_PINCONF_PARAM_OPEN_DRAIN:
443 if (port == PORT3)
444 reg = GPIO3_OD;
445 else
446 reg = GPIO_OD(port);
447 *config = LTQ_PINCONF_PACK(param,
448 !!gpio_getbit(info->membase[0], reg, PORT_PIN(port)));
449 break;
450
451 case LTQ_PINCONF_PARAM_PULL:
452 if (port == PORT3)
453 reg = GPIO3_PUDEN;
454 else
455 reg = GPIO_PUDEN(port);
456 if (!gpio_getbit(info->membase[0], reg, PORT_PIN(port))) {
457 *config = LTQ_PINCONF_PACK(param, 0);
458 break;
459 }
460
461 if (port == PORT3)
462 reg = GPIO3_PUDSEL;
463 else
464 reg = GPIO_PUDSEL(port);
465 if (!gpio_getbit(info->membase[0], reg, PORT_PIN(port)))
466 *config = LTQ_PINCONF_PACK(param, 2);
467 else
468 *config = LTQ_PINCONF_PACK(param, 1);
469 break;
470
471 default:
472 dev_err(pctldev->dev, "Invalid config param %04x\n", param);
473 return -ENOTSUPP;
474 }
475 return 0;
476}
477
478static int xway_pinconf_set(struct pinctrl_dev *pctldev,
479 unsigned pin,
480 unsigned long config)
481{
482 struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
483 enum ltq_pinconf_param param = LTQ_PINCONF_UNPACK_PARAM(config);
484 int arg = LTQ_PINCONF_UNPACK_ARG(config);
485 int port = PORT(pin);
486 u32 reg;
487
488 switch (param) {
489 case LTQ_PINCONF_PARAM_OPEN_DRAIN:
490 if (port == PORT3)
491 reg = GPIO3_OD;
492 else
493 reg = GPIO_OD(port);
494 gpio_setbit(info->membase[0], reg, PORT_PIN(port));
495 break;
496
497 case LTQ_PINCONF_PARAM_PULL:
498 if (port == PORT3)
499 reg = GPIO3_PUDEN;
500 else
501 reg = GPIO_PUDEN(port);
502 if (arg == 0) {
503 gpio_clearbit(info->membase[0], reg, PORT_PIN(port));
504 break;
505 }
506 gpio_setbit(info->membase[0], reg, PORT_PIN(port));
507
508 if (port == PORT3)
509 reg = GPIO3_PUDSEL;
510 else
511 reg = GPIO_PUDSEL(port);
512 if (arg == 1)
513 gpio_clearbit(info->membase[0], reg, PORT_PIN(port));
514 else if (arg == 2)
515 gpio_setbit(info->membase[0], reg, PORT_PIN(port));
516 else
517 dev_err(pctldev->dev, "Invalid pull value %d\n", arg);
518 break;
519
520 default:
521 dev_err(pctldev->dev, "Invalid config param %04x\n", param);
522 return -ENOTSUPP;
523 }
524 return 0;
525}
526
527struct pinconf_ops xway_pinconf_ops = {
528 .pin_config_get = xway_pinconf_get,
529 .pin_config_set = xway_pinconf_set,
530};
531
532static struct pinctrl_desc xway_pctrl_desc = {
533 .owner = THIS_MODULE,
534 .confops = &xway_pinconf_ops,
535};
536
537static inline int xway_mux_apply(struct pinctrl_dev *pctrldev,
538 int pin, int mux)
539{
540 struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
541 int port = PORT(pin);
542 u32 alt1_reg = GPIO_ALT1(pin);
543
544 if (port == PORT3)
545 alt1_reg = GPIO3_ALT1;
546
547 if (mux & MUX_ALT0)
548 gpio_setbit(info->membase[0], GPIO_ALT0(pin), PORT_PIN(pin));
549 else
550 gpio_clearbit(info->membase[0], GPIO_ALT0(pin), PORT_PIN(pin));
551
552 if (mux & MUX_ALT1)
553 gpio_setbit(info->membase[0], alt1_reg, PORT_PIN(pin));
554 else
555 gpio_clearbit(info->membase[0], alt1_reg, PORT_PIN(pin));
556
557 return 0;
558}
559
560static const struct ltq_cfg_param xway_cfg_params[] = {
561 {"lantiq,pull", LTQ_PINCONF_PARAM_PULL},
562 {"lantiq,open-drain", LTQ_PINCONF_PARAM_OPEN_DRAIN},
563};
564
565static struct ltq_pinmux_info xway_info = {
566 .desc = &xway_pctrl_desc,
567 .apply_mux = xway_mux_apply,
568 .params = xway_cfg_params,
569 .num_params = ARRAY_SIZE(xway_cfg_params),
570};
571
572/* --------- gpio_chip related code --------- */
573static void xway_gpio_set(struct gpio_chip *chip, unsigned int pin, int val)
574{
575 struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev);
576
577 if (val)
578 gpio_setbit(info->membase[0], GPIO_OUT(pin), PORT_PIN(pin));
579 else
580 gpio_clearbit(info->membase[0], GPIO_OUT(pin), PORT_PIN(pin));
581}
582
583static int xway_gpio_get(struct gpio_chip *chip, unsigned int pin)
584{
585 struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev);
586
587 return gpio_getbit(info->membase[0], GPIO_IN(pin), PORT_PIN(pin));
588}
589
590static int xway_gpio_dir_in(struct gpio_chip *chip, unsigned int pin)
591{
592 struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev);
593
594 gpio_clearbit(info->membase[0], GPIO_DIR(pin), PORT_PIN(pin));
595
596 return 0;
597}
598
599static int xway_gpio_dir_out(struct gpio_chip *chip, unsigned int pin, int val)
600{
601 struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev);
602
603 gpio_setbit(info->membase[0], GPIO_DIR(pin), PORT_PIN(pin));
604 xway_gpio_set(chip, pin, val);
605
606 return 0;
607}
608
609static int xway_gpio_req(struct gpio_chip *chip, unsigned offset)
610{
611 int gpio = chip->base + offset;
612
613 return pinctrl_request_gpio(gpio);
614}
615
616static void xway_gpio_free(struct gpio_chip *chip, unsigned offset)
617{
618 int gpio = chip->base + offset;
619
620 pinctrl_free_gpio(gpio);
621}
622
623static struct gpio_chip xway_chip = {
624 .label = "gpio-xway",
625 .direction_input = xway_gpio_dir_in,
626 .direction_output = xway_gpio_dir_out,
627 .get = xway_gpio_get,
628 .set = xway_gpio_set,
629 .request = xway_gpio_req,
630 .free = xway_gpio_free,
631 .base = -1,
632};
633
634
635/* --------- register the pinctrl layer --------- */
636static const unsigned xway_exin_pin_map[] = {GPIO0, GPIO1, GPIO2, GPIO39, GPIO46, GPIO9};
637static const unsigned ase_exin_pins_map[] = {GPIO6, GPIO29, GPIO0};
638
639static struct pinctrl_xway_soc {
640 int pin_count;
641 const struct ltq_mfp_pin *mfp;
642 const struct ltq_pin_group *grps;
643 unsigned int num_grps;
644 const struct ltq_pmx_func *funcs;
645 unsigned int num_funcs;
646 const unsigned *exin;
647 unsigned int num_exin;
648} soc_cfg[] = {
649 /* legacy xway */
650 {XWAY_MAX_PIN, xway_mfp,
651 xway_grps, ARRAY_SIZE(xway_grps),
652 danube_funcs, ARRAY_SIZE(danube_funcs),
653 xway_exin_pin_map, 3},
654 /* xway xr9 series */
655 {XR9_MAX_PIN, xway_mfp,
656 xway_grps, ARRAY_SIZE(xway_grps),
657 xrx_funcs, ARRAY_SIZE(xrx_funcs),
658 xway_exin_pin_map, 6},
659 /* xway ase series */
660 {XWAY_MAX_PIN, ase_mfp,
661 ase_grps, ARRAY_SIZE(ase_grps),
662 ase_funcs, ARRAY_SIZE(ase_funcs),
663 ase_exin_pins_map, 3},
664};
665
666static struct pinctrl_gpio_range xway_gpio_range = {
667 .name = "XWAY GPIO",
668 .gc = &xway_chip,
669};
670
671static const struct of_device_id xway_match[] = {
672 { .compatible = "lantiq,pinctrl-xway", .data = &soc_cfg[0]},
673 { .compatible = "lantiq,pinctrl-xr9", .data = &soc_cfg[1]},
674 { .compatible = "lantiq,pinctrl-ase", .data = &soc_cfg[2]},
675 {},
676};
677MODULE_DEVICE_TABLE(of, xway_match);
678
679static int __devinit pinmux_xway_probe(struct platform_device *pdev)
680{
681 const struct of_device_id *match;
682 const struct pinctrl_xway_soc *xway_soc;
683 struct resource *res;
684 int ret, i;
685
686 /* get and remap our register range */
687 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
688 if (!res) {
689 dev_err(&pdev->dev, "Failed to get resource\n");
690 return -ENOENT;
691 }
692 xway_info.membase[0] = devm_request_and_ioremap(&pdev->dev, res);
693 if (!xway_info.membase[0]) {
694 dev_err(&pdev->dev, "Failed to remap resource\n");
695 return -ENOMEM;
696 }
697
698 match = of_match_device(xway_match, &pdev->dev);
699 if (match)
700 xway_soc = (const struct pinctrl_xway_soc *) match->data;
701 else
702 xway_soc = &soc_cfg[0];
703
704 /* find out how many pads we have */
705 xway_chip.ngpio = xway_soc->pin_count;
706
707 /* load our pad descriptors */
708 xway_info.pads = devm_kzalloc(&pdev->dev,
709 sizeof(struct pinctrl_pin_desc) * xway_chip.ngpio,
710 GFP_KERNEL);
711 if (!xway_info.pads) {
712 dev_err(&pdev->dev, "Failed to allocate pads\n");
713 return -ENOMEM;
714 }
715 for (i = 0; i < xway_chip.ngpio; i++) {
716 /* strlen("ioXY") + 1 = 5 */
717 char *name = devm_kzalloc(&pdev->dev, 5, GFP_KERNEL);
718
719 if (!name) {
720 dev_err(&pdev->dev, "Failed to allocate pad name\n");
721 return -ENOMEM;
722 }
723 snprintf(name, 5, "io%d", i);
724 xway_info.pads[i].number = GPIO0 + i;
725 xway_info.pads[i].name = name;
726 }
727 xway_pctrl_desc.pins = xway_info.pads;
728
729 /* load the gpio chip */
730 xway_chip.dev = &pdev->dev;
731 of_gpiochip_add(&xway_chip);
732 ret = gpiochip_add(&xway_chip);
733 if (ret) {
734 dev_err(&pdev->dev, "Failed to register gpio chip\n");
735 return ret;
736 }
737
738 /* setup the data needed by pinctrl */
739 xway_pctrl_desc.name = dev_name(&pdev->dev);
740 xway_pctrl_desc.npins = xway_chip.ngpio;
741
742 xway_info.num_pads = xway_chip.ngpio;
743 xway_info.num_mfp = xway_chip.ngpio;
744 xway_info.mfp = xway_soc->mfp;
745 xway_info.grps = xway_soc->grps;
746 xway_info.num_grps = xway_soc->num_grps;
747 xway_info.funcs = xway_soc->funcs;
748 xway_info.num_funcs = xway_soc->num_funcs;
749 xway_info.exin = xway_soc->exin;
750 xway_info.num_exin = xway_soc->num_exin;
751
752 /* register with the generic lantiq layer */
753 ret = ltq_pinctrl_register(pdev, &xway_info);
754 if (ret) {
755 dev_err(&pdev->dev, "Failed to register pinctrl driver\n");
756 return ret;
757 }
758
759 /* finish with registering the gpio range in pinctrl */
760 xway_gpio_range.npins = xway_chip.ngpio;
761 xway_gpio_range.base = xway_chip.base;
762 pinctrl_add_gpio_range(xway_info.pctrl, &xway_gpio_range);
763 dev_info(&pdev->dev, "Init done\n");
764 return 0;
765}
766
767static struct platform_driver pinmux_xway_driver = {
768 .probe = pinmux_xway_probe,
769 .driver = {
770 .name = "pinctrl-xway",
771 .owner = THIS_MODULE,
772 .of_match_table = xway_match,
773 },
774};
775
776static int __init pinmux_xway_init(void)
777{
778 return platform_driver_register(&pinmux_xway_driver);
779}
780
781core_initcall_sync(pinmux_xway_init);