]> git.sur5r.net Git - u-boot/blob - drivers/gpio/sh_pfc.c
pci: correct a function description
[u-boot] / drivers / gpio / sh_pfc.c
1 /*
2  * Pinmuxed GPIO support for SuperH.
3  * Copy from linux kernel driver/sh/pfc.c
4  *
5  * Copyright (C) 2008 Magnus Damm
6  *
7  * This file is subject to the terms and conditions of the GNU General Public
8  * License.  See the file "COPYING" in the main directory of this archive
9  * for more details.
10  */
11
12 #include <common.h>
13 #include <asm/bitops.h>
14 #include <asm/io.h>
15 #include <sh_pfc.h>
16
17 static struct pinmux_info *gpioc;
18
19 #define pfc_phys_to_virt(p, a) ((void *)a)
20
21 static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
22 {
23         if (enum_id < r->begin)
24                 return 0;
25
26         if (enum_id > r->end)
27                 return 0;
28
29         return 1;
30 }
31
32 static unsigned long gpio_read_raw_reg(void *mapped_reg,
33                                        unsigned long reg_width)
34 {
35         switch (reg_width) {
36
37         case 8:
38                 return readb(mapped_reg);
39         case 16:
40                 return readw(mapped_reg);
41         case 32:
42                 return readl(mapped_reg);
43         }
44
45         BUG();
46         return 0;
47 }
48
49 static void gpio_write_raw_reg(void *mapped_reg,
50                                unsigned long reg_width,
51                                unsigned long data)
52 {
53         switch (reg_width) {
54         case 8:
55                 writeb(data, mapped_reg);
56                 return;
57         case 16:
58                 writew(data, mapped_reg);
59                 return;
60         case 32:
61                 writel(data, mapped_reg);
62                 return;
63         }
64
65         BUG();
66 }
67
68 static int gpio_read_bit(struct pinmux_data_reg *dr,
69                          unsigned long in_pos)
70 {
71         unsigned long pos;
72
73         pos = dr->reg_width - (in_pos + 1);
74
75         debug("read_bit: addr = %lx, pos = %ld, "
76                  "r_width = %ld\n", dr->reg, pos, dr->reg_width);
77
78         return
79             (gpio_read_raw_reg(dr->mapped_reg + 0x4, dr->reg_width) >> pos) & 1;
80 }
81
82 static void gpio_write_bit(struct pinmux_data_reg *dr,
83                            unsigned long in_pos, unsigned long value)
84 {
85         unsigned long pos;
86
87         pos = dr->reg_width - (in_pos + 1);
88
89         debug("write_bit addr = %lx, value = %d, pos = %ld, "
90                  "r_width = %ld\n",
91                  dr->reg, !!value, pos, dr->reg_width);
92
93         if (value)
94                 __set_bit(pos, &dr->reg_shadow);
95         else
96                 __clear_bit(pos, &dr->reg_shadow);
97
98         gpio_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow);
99 }
100
101 static void config_reg_helper(struct pinmux_info *gpioc,
102                               struct pinmux_cfg_reg *crp,
103                               unsigned long in_pos,
104 #if 0
105                               void __iomem **mapped_regp,
106 #else
107                               void **mapped_regp,
108 #endif
109                               unsigned long *maskp,
110                               unsigned long *posp)
111 {
112         int k;
113
114         *mapped_regp = pfc_phys_to_virt(gpioc, crp->reg);
115
116         if (crp->field_width) {
117                 *maskp = (1 << crp->field_width) - 1;
118                 *posp = crp->reg_width - ((in_pos + 1) * crp->field_width);
119         } else {
120                 *maskp = (1 << crp->var_field_width[in_pos]) - 1;
121                 *posp = crp->reg_width;
122                 for (k = 0; k <= in_pos; k++)
123                         *posp -= crp->var_field_width[k];
124         }
125 }
126
127 static int read_config_reg(struct pinmux_info *gpioc,
128                            struct pinmux_cfg_reg *crp,
129                            unsigned long field)
130 {
131         void *mapped_reg;
132
133         unsigned long mask, pos;
134
135         config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos);
136
137         debug("read_reg: addr = %lx, field = %ld, "
138                  "r_width = %ld, f_width = %ld\n",
139                  crp->reg, field, crp->reg_width, crp->field_width);
140
141         return (gpio_read_raw_reg(mapped_reg, crp->reg_width) >> pos) & mask;
142 }
143
144 static void write_config_reg(struct pinmux_info *gpioc,
145                              struct pinmux_cfg_reg *crp,
146                              unsigned long field, unsigned long value)
147 {
148         void *mapped_reg;
149         unsigned long mask, pos, data;
150
151         config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos);
152
153         debug("write_reg addr = %lx, value = %ld, field = %ld, "
154                  "r_width = %ld, f_width = %ld\n",
155                  crp->reg, value, field, crp->reg_width, crp->field_width);
156
157         mask = ~(mask << pos);
158         value = value << pos;
159
160         data = gpio_read_raw_reg(mapped_reg, crp->reg_width);
161         data &= mask;
162         data |= value;
163
164         if (gpioc->unlock_reg)
165                 gpio_write_raw_reg(pfc_phys_to_virt(gpioc, gpioc->unlock_reg),
166                                    32, ~data);
167
168         gpio_write_raw_reg(mapped_reg, crp->reg_width, data);
169 }
170
171 static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio)
172 {
173         struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
174         struct pinmux_data_reg *data_reg;
175         int k, n;
176
177         if (!enum_in_range(gpiop->enum_id, &gpioc->data))
178                 return -1;
179
180         k = 0;
181         while (1) {
182                 data_reg = gpioc->data_regs + k;
183
184                 if (!data_reg->reg_width)
185                         break;
186
187                 data_reg->mapped_reg = pfc_phys_to_virt(gpioc, data_reg->reg);
188
189                 for (n = 0; n < data_reg->reg_width; n++) {
190                         if (data_reg->enum_ids[n] == gpiop->enum_id) {
191                                 gpiop->flags &= ~PINMUX_FLAG_DREG;
192                                 gpiop->flags |= (k << PINMUX_FLAG_DREG_SHIFT);
193                                 gpiop->flags &= ~PINMUX_FLAG_DBIT;
194                                 gpiop->flags |= (n << PINMUX_FLAG_DBIT_SHIFT);
195                                 return 0;
196                         }
197                 }
198                 k++;
199         }
200
201         BUG();
202
203         return -1;
204 }
205
206 static void setup_data_regs(struct pinmux_info *gpioc)
207 {
208         struct pinmux_data_reg *drp;
209         int k;
210
211         for (k = gpioc->first_gpio; k <= gpioc->last_gpio; k++)
212                 setup_data_reg(gpioc, k);
213
214         k = 0;
215         while (1) {
216                 drp = gpioc->data_regs + k;
217
218                 if (!drp->reg_width)
219                         break;
220
221                 drp->reg_shadow = gpio_read_raw_reg(drp->mapped_reg,
222                                                     drp->reg_width);
223                 k++;
224         }
225 }
226
227 static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio,
228                         struct pinmux_data_reg **drp, int *bitp)
229 {
230         struct pinmux_gpio *gpiop = &gpioc->gpios[gpio];
231         int k, n;
232
233         if (!enum_in_range(gpiop->enum_id, &gpioc->data))
234                 return -1;
235
236         k = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT;
237         n = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT;
238         *drp = gpioc->data_regs + k;
239         *bitp = n;
240         return 0;
241 }
242
243 static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id,
244                           struct pinmux_cfg_reg **crp,
245                           int *fieldp, int *valuep,
246                           unsigned long **cntp)
247 {
248         struct pinmux_cfg_reg *config_reg;
249         unsigned long r_width, f_width, curr_width, ncomb;
250         int k, m, n, pos, bit_pos;
251
252         k = 0;
253         while (1) {
254                 config_reg = gpioc->cfg_regs + k;
255
256                 r_width = config_reg->reg_width;
257                 f_width = config_reg->field_width;
258
259                 if (!r_width)
260                         break;
261
262                 pos = 0;
263                 m = 0;
264                 for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width) {
265                         if (f_width)
266                                 curr_width = f_width;
267                         else
268                                 curr_width = config_reg->var_field_width[m];
269
270                         ncomb = 1 << curr_width;
271                         for (n = 0; n < ncomb; n++) {
272                                 if (config_reg->enum_ids[pos + n] == enum_id) {
273                                         *crp = config_reg;
274                                         *fieldp = m;
275                                         *valuep = n;
276                                         *cntp = &config_reg->cnt[m];
277                                         return 0;
278                                 }
279                         }
280                         pos += ncomb;
281                         m++;
282                 }
283                 k++;
284         }
285
286         return -1;
287 }
288
289 static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio,
290                             int pos, pinmux_enum_t *enum_idp)
291 {
292         pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id;
293         pinmux_enum_t *data = gpioc->gpio_data;
294         int k;
295
296         if (!enum_in_range(enum_id, &gpioc->data)) {
297                 if (!enum_in_range(enum_id, &gpioc->mark)) {
298                         debug("non data/mark enum_id for gpio %d\n", gpio);
299                         return -1;
300                 }
301         }
302
303         if (pos) {
304                 *enum_idp = data[pos + 1];
305                 return pos + 1;
306         }
307
308         for (k = 0; k < gpioc->gpio_data_size; k++) {
309                 if (data[k] == enum_id) {
310                         *enum_idp = data[k + 1];
311                         return k + 1;
312                 }
313         }
314
315         debug("cannot locate data/mark enum_id for gpio %d\n", gpio);
316         return -1;
317 }
318
319 enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE };
320
321 static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
322                               int pinmux_type, int cfg_mode)
323 {
324         struct pinmux_cfg_reg *cr = NULL;
325         pinmux_enum_t enum_id;
326         struct pinmux_range *range;
327         int in_range, pos, field, value;
328         unsigned long *cntp;
329
330         switch (pinmux_type) {
331
332         case PINMUX_TYPE_FUNCTION:
333                 range = NULL;
334                 break;
335
336         case PINMUX_TYPE_OUTPUT:
337                 range = &gpioc->output;
338                 break;
339
340         case PINMUX_TYPE_INPUT:
341                 range = &gpioc->input;
342                 break;
343
344         case PINMUX_TYPE_INPUT_PULLUP:
345                 range = &gpioc->input_pu;
346                 break;
347
348         case PINMUX_TYPE_INPUT_PULLDOWN:
349                 range = &gpioc->input_pd;
350                 break;
351
352         default:
353                 goto out_err;
354         }
355
356         pos = 0;
357         enum_id = 0;
358         field = 0;
359         value = 0;
360         while (1) {
361                 pos = get_gpio_enum_id(gpioc, gpio, pos, &enum_id);
362                 if (pos <= 0)
363                         goto out_err;
364
365                 if (!enum_id)
366                         break;
367
368                 /* first check if this is a function enum */
369                 in_range = enum_in_range(enum_id, &gpioc->function);
370                 if (!in_range) {
371                         /* not a function enum */
372                         if (range) {
373                                 /*
374                                  * other range exists, so this pin is
375                                  * a regular GPIO pin that now is being
376                                  * bound to a specific direction.
377                                  *
378                                  * for this case we only allow function enums
379                                  * and the enums that match the other range.
380                                  */
381                                 in_range = enum_in_range(enum_id, range);
382
383                                 /*
384                                  * special case pass through for fixed
385                                  * input-only or output-only pins without
386                                  * function enum register association.
387                                  */
388                                 if (in_range && enum_id == range->force)
389                                         continue;
390                         } else {
391                                 /*
392                                  * no other range exists, so this pin
393                                  * must then be of the function type.
394                                  *
395                                  * allow function type pins to select
396                                  * any combination of function/in/out
397                                  * in their MARK lists.
398                                  */
399                                 in_range = 1;
400                         }
401                 }
402
403                 if (!in_range)
404                         continue;
405
406                 if (get_config_reg(gpioc, enum_id, &cr,
407                                    &field, &value, &cntp) != 0)
408                         goto out_err;
409
410                 switch (cfg_mode) {
411                 case GPIO_CFG_DRYRUN:
412                         if (!*cntp ||
413                             (read_config_reg(gpioc, cr, field) != value))
414                                 continue;
415                         break;
416
417                 case GPIO_CFG_REQ:
418                         write_config_reg(gpioc, cr, field, value);
419                         *cntp = *cntp + 1;
420                         break;
421
422                 case GPIO_CFG_FREE:
423                         *cntp = *cntp - 1;
424                         break;
425                 }
426         }
427
428         return 0;
429  out_err:
430         return -1;
431 }
432
433 #if 0
434 static DEFINE_SPINLOCK(gpio_lock);
435 static struct pinmux_info *chip_to_pinmux(struct gpio_chip *chip)
436 {
437         return container_of(chip, struct pinmux_info, chip);
438 }
439 #endif
440
441 static int sh_gpio_request(unsigned offset)
442 {
443         struct pinmux_data_reg *dummy;
444         int i, ret, pinmux_type;
445
446         ret = -1;
447
448         if (!gpioc)
449                 goto err_out;
450
451         if ((gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE)
452                 goto err_out;
453
454         /* setup pin function here if no data is associated with pin */
455
456         if (get_data_reg(gpioc, offset, &dummy, &i) != 0)
457                 pinmux_type = PINMUX_TYPE_FUNCTION;
458         else
459                 pinmux_type = PINMUX_TYPE_GPIO;
460
461         if (pinmux_type == PINMUX_TYPE_FUNCTION) {
462                 if (pinmux_config_gpio(gpioc, offset,
463                                        pinmux_type,
464                                        GPIO_CFG_DRYRUN) != 0)
465                         goto err_out;
466
467                 if (pinmux_config_gpio(gpioc, offset,
468                                        pinmux_type,
469                                        GPIO_CFG_REQ) != 0)
470                         BUG();
471         }
472
473         gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
474         gpioc->gpios[offset].flags |= pinmux_type;
475
476         ret = 0;
477 err_out:
478         return ret;
479 }
480
481 static void sh_gpio_free(unsigned offset)
482 {
483         int pinmux_type;
484
485         if (!gpioc)
486                 return;
487
488         pinmux_type = gpioc->gpios[offset].flags & PINMUX_FLAG_TYPE;
489         pinmux_config_gpio(gpioc, offset, pinmux_type, GPIO_CFG_FREE);
490         gpioc->gpios[offset].flags &= ~PINMUX_FLAG_TYPE;
491         gpioc->gpios[offset].flags |= PINMUX_TYPE_NONE;
492 }
493
494 static int pinmux_direction(struct pinmux_info *gpioc,
495                             unsigned gpio, int new_pinmux_type)
496 {
497         int pinmux_type;
498         int ret = -1;
499
500         if (!gpioc)
501                 goto err_out;
502
503         pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
504
505         switch (pinmux_type) {
506         case PINMUX_TYPE_GPIO:
507                 break;
508         case PINMUX_TYPE_OUTPUT:
509         case PINMUX_TYPE_INPUT:
510         case PINMUX_TYPE_INPUT_PULLUP:
511         case PINMUX_TYPE_INPUT_PULLDOWN:
512                 pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE);
513                 break;
514         default:
515                 goto err_out;
516         }
517
518         if (pinmux_config_gpio(gpioc, gpio,
519                                new_pinmux_type,
520                                GPIO_CFG_DRYRUN) != 0)
521                 goto err_out;
522
523         if (pinmux_config_gpio(gpioc, gpio,
524                                new_pinmux_type,
525                                GPIO_CFG_REQ) != 0)
526                 BUG();
527
528         gpioc->gpios[gpio].flags &= ~PINMUX_FLAG_TYPE;
529         gpioc->gpios[gpio].flags |= new_pinmux_type;
530
531         ret = 0;
532  err_out:
533         return ret;
534 }
535
536 static int sh_gpio_direction_input(unsigned offset)
537 {
538         return pinmux_direction(gpioc, offset, PINMUX_TYPE_INPUT);
539 }
540
541 static void sh_gpio_set_value(struct pinmux_info *gpioc,
542                              unsigned gpio, int value)
543 {
544         struct pinmux_data_reg *dr = NULL;
545         int bit = 0;
546
547         if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
548                 BUG();
549         else
550                 gpio_write_bit(dr, bit, value);
551 }
552
553 static int sh_gpio_direction_output(unsigned offset, int value)
554 {
555         sh_gpio_set_value(gpioc, offset, value);
556         return pinmux_direction(gpioc, offset, PINMUX_TYPE_OUTPUT);
557 }
558
559 static int sh_gpio_get_value(struct pinmux_info *gpioc, unsigned gpio)
560 {
561         struct pinmux_data_reg *dr = NULL;
562         int bit = 0;
563
564         if (!gpioc || get_data_reg(gpioc, gpio, &dr, &bit) != 0)
565                 return -1;
566
567         return gpio_read_bit(dr, bit);
568 }
569
570 static int sh_gpio_get(unsigned offset)
571 {
572         return sh_gpio_get_value(gpioc, offset);
573 }
574
575 static void sh_gpio_set(unsigned offset, int value)
576 {
577         sh_gpio_set_value(gpioc, offset, value);
578 }
579
580 int register_pinmux(struct pinmux_info *pip)
581 {
582         if (pip != NULL) {
583                 gpioc = pip;
584                 debug("%s deregistering\n", pip->name);
585                 setup_data_regs(gpioc);
586         }
587         return 0;
588 }
589
590 int unregister_pinmux(struct pinmux_info *pip)
591 {
592         debug("%s deregistering\n", pip->name);
593         if (gpioc != pip)
594                 return -1;
595
596         gpioc = NULL;
597         return 0;
598 }
599
600 int gpio_request(unsigned gpio, const char *label)
601 {
602         sh_gpio_request(gpio);
603         return 0;
604 }
605
606 int gpio_free(unsigned gpio)
607 {
608         sh_gpio_free(gpio);
609         return 0;
610 }
611
612 int gpio_direction_input(unsigned gpio)
613 {
614         return sh_gpio_direction_input(gpio);
615 }
616
617 int gpio_direction_output(unsigned gpio, int value)
618 {
619         return sh_gpio_direction_output(gpio, value);
620 }
621
622 void gpio_set_value(unsigned gpio, int value)
623 {
624         sh_gpio_set(gpio, value);
625 }
626
627 int gpio_get_value(unsigned gpio)
628 {
629         return sh_gpio_get(gpio);
630 }