]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/sh/kernel/gpio.c
dock: make dock driver not a module
[linux-2.6-omap-h63xx.git] / arch / sh / kernel / gpio.c
1 /*
2  * Pinmuxed GPIO support for SuperH.
3  *
4  * Copyright (C) 2008 Magnus Damm
5  *
6  * This file is subject to the terms and conditions of the GNU General Public
7  * License.  See the file "COPYING" in the main directory of this archive
8  * for more details.
9  */
10
11 #include <linux/errno.h>
12 #include <linux/kernel.h>
13 #include <linux/list.h>
14 #include <linux/module.h>
15 #include <linux/clk.h>
16 #include <linux/err.h>
17 #include <linux/io.h>
18 #include <linux/irq.h>
19 #include <linux/bitops.h>
20 #include <linux/gpio.h>
21
22 static struct pinmux_info *registered_gpio;
23
24 static struct pinmux_info *gpio_controller(unsigned gpio)
25 {
26         if (!registered_gpio)
27                 return NULL;
28
29         if (gpio < registered_gpio->first_gpio)
30                 return NULL;
31
32         if (gpio > registered_gpio->last_gpio)
33                 return NULL;
34
35         return registered_gpio;
36 }
37
38 static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
39 {
40         if (enum_id < r->begin)
41                 return 0;
42
43         if (enum_id > r->end)
44                 return 0;
45
46         return 1;
47 }
48
49 static int read_write_reg(unsigned long reg, unsigned long reg_width,
50                           unsigned long field_width, unsigned long in_pos,
51                           unsigned long value, int do_write)
52 {
53         unsigned long data, mask, pos;
54
55         data = 0;
56         mask = (1 << field_width) - 1;
57         pos = reg_width - ((in_pos + 1) * field_width);
58
59 #ifdef DEBUG
60         pr_info("%s, addr = %lx, value = %ld, pos = %ld, "
61                 "r_width = %ld, f_width = %ld\n",
62                 do_write ? "write" : "read", reg, value, pos,
63                 reg_width, field_width);
64 #endif
65
66         switch (reg_width) {
67         case 8:
68                 data = ctrl_inb(reg);
69                 break;
70         case 16:
71                 data = ctrl_inw(reg);
72                 break;
73         case 32:
74                 data = ctrl_inl(reg);
75                 break;
76         }
77
78         if (!do_write)
79                 return (data >> pos) & mask;
80
81         data &= ~(mask << pos);
82         data |= value << pos;
83
84         switch (reg_width) {
85         case 8:
86                 ctrl_outb(data, reg);
87                 break;
88         case 16:
89                 ctrl_outw(data, reg);
90                 break;
91         case 32:
92                 ctrl_outl(data, reg);
93                 break;
94         }
95         return 0;
96 }
97
98 static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio,
99                         struct pinmux_data_reg **drp, int *bitp)
100 {
101         pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id;
102         struct pinmux_data_reg *data_reg;
103         int k, n;
104
105         if (!enum_in_range(enum_id, &gpioc->data))
106                 return -1;
107
108         k = 0;
109         while (1) {
110                 data_reg = gpioc->data_regs + k;
111
112                 if (!data_reg->reg_width)
113                         break;
114
115                 for (n = 0; n < data_reg->reg_width; n++) {
116                         if (data_reg->enum_ids[n] == enum_id) {
117                                 *drp = data_reg;
118                                 *bitp = n;
119                                 return 0;
120
121                         }
122                 }
123                 k++;
124         }
125
126         return -1;
127 }
128
129 static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id,
130                           struct pinmux_cfg_reg **crp, int *indexp,
131                           unsigned long **cntp)
132 {
133         struct pinmux_cfg_reg *config_reg;
134         unsigned long r_width, f_width;
135         int k, n;
136
137         k = 0;
138         while (1) {
139                 config_reg = gpioc->cfg_regs + k;
140
141                 r_width = config_reg->reg_width;
142                 f_width = config_reg->field_width;
143
144                 if (!r_width)
145                         break;
146                 for (n = 0; n < (r_width / f_width) * 1 << f_width; n++) {
147                         if (config_reg->enum_ids[n] == enum_id) {
148                                 *crp = config_reg;
149                                 *indexp = n;
150                                 *cntp = &config_reg->cnt[n / (1 << f_width)];
151                                 return 0;
152                         }
153                 }
154                 k++;
155         }
156
157         return -1;
158 }
159
160 static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio,
161                             int pos, pinmux_enum_t *enum_idp)
162 {
163         pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id;
164         pinmux_enum_t *data = gpioc->gpio_data;
165         int k;
166
167         if (!enum_in_range(enum_id, &gpioc->data)) {
168                 if (!enum_in_range(enum_id, &gpioc->mark)) {
169                         pr_err("non data/mark enum_id for gpio %d\n", gpio);
170                         return -1;
171                 }
172         }
173
174         if (pos) {
175                 *enum_idp = data[pos + 1];
176                 return pos + 1;
177         }
178
179         for (k = 0; k < gpioc->gpio_data_size; k++) {
180                 if (data[k] == enum_id) {
181                         *enum_idp = data[k + 1];
182                         return k + 1;
183                 }
184         }
185
186         pr_err("cannot locate data/mark enum_id for gpio %d\n", gpio);
187         return -1;
188 }
189
190 static int write_config_reg(struct pinmux_info *gpioc,
191                             struct pinmux_cfg_reg *crp,
192                             int index)
193 {
194         unsigned long ncomb, pos, value;
195
196         ncomb = 1 << crp->field_width;
197         pos = index / ncomb;
198         value = index % ncomb;
199
200         return read_write_reg(crp->reg, crp->reg_width,
201                               crp->field_width, pos, value, 1);
202 }
203
204 static int check_config_reg(struct pinmux_info *gpioc,
205                             struct pinmux_cfg_reg *crp,
206                             int index)
207 {
208         unsigned long ncomb, pos, value;
209
210         ncomb = 1 << crp->field_width;
211         pos = index / ncomb;
212         value = index % ncomb;
213
214         if (read_write_reg(crp->reg, crp->reg_width,
215                            crp->field_width, pos, 0, 0) == value)
216                 return 0;
217
218         return -1;
219 }
220
221 enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE };
222
223 int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
224                        int pinmux_type, int cfg_mode)
225 {
226         struct pinmux_cfg_reg *cr = NULL;
227         pinmux_enum_t enum_id;
228         struct pinmux_range *range;
229         int in_range, pos, index;
230         unsigned long *cntp;
231
232         switch (pinmux_type) {
233
234         case PINMUX_TYPE_FUNCTION:
235                 range = NULL;
236                 break;
237
238         case PINMUX_TYPE_OUTPUT:
239                 range = &gpioc->output;
240                 break;
241
242         case PINMUX_TYPE_INPUT:
243                 range = &gpioc->input;
244                 break;
245
246         case PINMUX_TYPE_INPUT_PULLUP:
247                 range = &gpioc->input_pu;
248                 break;
249
250         case PINMUX_TYPE_INPUT_PULLDOWN:
251                 range = &gpioc->input_pd;
252                 break;
253
254         default:
255                 goto out_err;
256         }
257
258         pos = 0;
259         enum_id = 0;
260         index = 0;
261         while (1) {
262                 pos = get_gpio_enum_id(gpioc, gpio, pos, &enum_id);
263                 if (pos <= 0)
264                         goto out_err;
265
266                 if (!enum_id)
267                         break;
268
269                 in_range = enum_in_range(enum_id, &gpioc->function);
270                 if (!in_range && range)
271                         in_range = enum_in_range(enum_id, range);
272
273                 if (!in_range)
274                         continue;
275
276                 if (get_config_reg(gpioc, enum_id, &cr, &index, &cntp) != 0)
277                         goto out_err;
278
279                 switch (cfg_mode) {
280                 case GPIO_CFG_DRYRUN:
281                         if (!*cntp || !check_config_reg(gpioc, cr, index))
282                                 continue;
283                         break;
284
285                 case GPIO_CFG_REQ:
286                         if (write_config_reg(gpioc, cr, index) != 0)
287                                 goto out_err;
288                         *cntp = *cntp + 1;
289                         break;
290
291                 case GPIO_CFG_FREE:
292                         *cntp = *cntp - 1;
293                         break;
294                 }
295         }
296
297         return 0;
298  out_err:
299         return -1;
300 }
301
302 static DEFINE_SPINLOCK(gpio_lock);
303
304 int __gpio_request(unsigned gpio)
305 {
306         struct pinmux_info *gpioc = gpio_controller(gpio);
307         struct pinmux_data_reg *dummy;
308         unsigned long flags;
309         int i, ret, pinmux_type;
310
311         ret = -EINVAL;
312
313         if (!gpioc)
314                 goto err_out;
315
316         spin_lock_irqsave(&gpio_lock, flags);
317
318         if ((gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE)
319                 goto err_unlock;
320
321         /* setup pin function here if no data is associated with pin */
322
323         if (get_data_reg(gpioc, gpio, &dummy, &i) != 0)
324                 pinmux_type = PINMUX_TYPE_FUNCTION;
325         else
326                 pinmux_type = PINMUX_TYPE_GPIO;
327
328         if (pinmux_type == PINMUX_TYPE_FUNCTION) {
329                 if (pinmux_config_gpio(gpioc, gpio,
330                                        pinmux_type,
331                                        GPIO_CFG_DRYRUN) != 0)
332                         goto err_unlock;
333
334                 if (pinmux_config_gpio(gpioc, gpio,
335                                        pinmux_type,
336                                        GPIO_CFG_REQ) != 0)
337                         BUG();
338         }
339
340         gpioc->gpios[gpio].flags = pinmux_type;
341
342         ret = 0;
343  err_unlock:
344         spin_unlock_irqrestore(&gpio_lock, flags);
345  err_out:
346         return ret;
347 }
348 EXPORT_SYMBOL(__gpio_request);
349
350 void gpio_free(unsigned gpio)
351 {
352         struct pinmux_info *gpioc = gpio_controller(gpio);
353         unsigned long flags;
354         int pinmux_type;
355
356         if (!gpioc)
357                 return;
358
359         spin_lock_irqsave(&gpio_lock, flags);
360
361         pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
362         pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE);
363         gpioc->gpios[gpio].flags = PINMUX_TYPE_NONE;
364
365         spin_unlock_irqrestore(&gpio_lock, flags);
366 }
367 EXPORT_SYMBOL(gpio_free);
368
369 static int pinmux_direction(struct pinmux_info *gpioc,
370                             unsigned gpio, int new_pinmux_type)
371 {
372         int ret, pinmux_type;
373
374         ret = -EINVAL;
375         pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
376
377         switch (pinmux_type) {
378         case PINMUX_TYPE_GPIO:
379                 break;
380         case PINMUX_TYPE_OUTPUT:
381         case PINMUX_TYPE_INPUT:
382         case PINMUX_TYPE_INPUT_PULLUP:
383         case PINMUX_TYPE_INPUT_PULLDOWN:
384                 pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE);
385                 break;
386         default:
387                 goto err_out;
388         }
389
390         if (pinmux_config_gpio(gpioc, gpio,
391                                new_pinmux_type,
392                                GPIO_CFG_DRYRUN) != 0)
393                 goto err_out;
394
395         if (pinmux_config_gpio(gpioc, gpio,
396                                new_pinmux_type,
397                                GPIO_CFG_REQ) != 0)
398                 BUG();
399
400         gpioc->gpios[gpio].flags = new_pinmux_type;
401
402         ret = 0;
403  err_out:
404         return ret;
405 }
406
407 int gpio_direction_input(unsigned gpio)
408 {
409         struct pinmux_info *gpioc = gpio_controller(gpio);
410         unsigned long flags;
411         int ret = -EINVAL;
412
413         if (!gpioc)
414                 goto err_out;
415
416         spin_lock_irqsave(&gpio_lock, flags);
417         ret = pinmux_direction(gpioc, gpio, PINMUX_TYPE_INPUT);
418         spin_unlock_irqrestore(&gpio_lock, flags);
419  err_out:
420         return ret;
421 }
422 EXPORT_SYMBOL(gpio_direction_input);
423
424 static int __gpio_get_set_value(struct pinmux_info *gpioc,
425                                 unsigned gpio, int value,
426                                 int do_write)
427 {
428         struct pinmux_data_reg *dr = NULL;
429         int bit = 0;
430
431         if (get_data_reg(gpioc, gpio, &dr, &bit) != 0)
432                 BUG();
433         else
434                 value = read_write_reg(dr->reg, dr->reg_width,
435                                        1, bit, value, do_write);
436
437         return value;
438 }
439
440 int gpio_direction_output(unsigned gpio, int value)
441 {
442         struct pinmux_info *gpioc = gpio_controller(gpio);
443         unsigned long flags;
444         int ret = -EINVAL;
445
446         if (!gpioc)
447                 goto err_out;
448
449         spin_lock_irqsave(&gpio_lock, flags);
450         __gpio_get_set_value(gpioc, gpio, value, 1);
451         ret = pinmux_direction(gpioc, gpio, PINMUX_TYPE_OUTPUT);
452         spin_unlock_irqrestore(&gpio_lock, flags);
453  err_out:
454         return ret;
455 }
456 EXPORT_SYMBOL(gpio_direction_output);
457
458 int gpio_get_value(unsigned gpio)
459 {
460         struct pinmux_info *gpioc = gpio_controller(gpio);
461         unsigned long flags;
462         int value = 0;
463
464         if (!gpioc)
465                 BUG();
466         else {
467                 spin_lock_irqsave(&gpio_lock, flags);
468                 value = __gpio_get_set_value(gpioc, gpio, 0, 0);
469                 spin_unlock_irqrestore(&gpio_lock, flags);
470         }
471
472         return value;
473 }
474 EXPORT_SYMBOL(gpio_get_value);
475
476 void gpio_set_value(unsigned gpio, int value)
477 {
478         struct pinmux_info *gpioc = gpio_controller(gpio);
479         unsigned long flags;
480
481         if (!gpioc)
482                 BUG();
483         else {
484                 spin_lock_irqsave(&gpio_lock, flags);
485                 __gpio_get_set_value(gpioc, gpio, value, 1);
486                 spin_unlock_irqrestore(&gpio_lock, flags);
487         }
488 }
489 EXPORT_SYMBOL(gpio_set_value);
490
491 int register_pinmux(struct pinmux_info *pip)
492 {
493         registered_gpio = pip;
494         pr_info("pinmux: %s handling gpio %d -> %d\n",
495                 pip->name, pip->first_gpio, pip->last_gpio);
496
497         return 0;
498 }