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

Archive Download this file



interactive