diff options
Diffstat (limited to 'drivers/gpio/gpio-mmio.c')
-rw-r--r-- | drivers/gpio/gpio-mmio.c | 108 |
1 files changed, 63 insertions, 45 deletions
diff --git a/drivers/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c index 7b14d6280e44..935292a30c99 100644 --- a/drivers/gpio/gpio-mmio.c +++ b/drivers/gpio/gpio-mmio.c | |||
@@ -136,8 +136,20 @@ static unsigned long bgpio_line2mask(struct gpio_chip *gc, unsigned int line) | |||
136 | static int bgpio_get_set(struct gpio_chip *gc, unsigned int gpio) | 136 | static int bgpio_get_set(struct gpio_chip *gc, unsigned int gpio) |
137 | { | 137 | { |
138 | unsigned long pinmask = bgpio_line2mask(gc, gpio); | 138 | unsigned long pinmask = bgpio_line2mask(gc, gpio); |
139 | bool dir = !!(gc->bgpio_dir & pinmask); | ||
139 | 140 | ||
140 | if (gc->bgpio_dir & pinmask) | 141 | /* |
142 | * If the direction is OUT we read the value from the SET | ||
143 | * register, and if the direction is IN we read the value | ||
144 | * from the DAT register. | ||
145 | * | ||
146 | * If the direction bits are inverted, naturally this gets | ||
147 | * inverted too. | ||
148 | */ | ||
149 | if (gc->bgpio_dir_inverted) | ||
150 | dir = !dir; | ||
151 | |||
152 | if (dir) | ||
141 | return !!(gc->read_reg(gc->reg_set) & pinmask); | 153 | return !!(gc->read_reg(gc->reg_set) & pinmask); |
142 | else | 154 | else |
143 | return !!(gc->read_reg(gc->reg_dat) & pinmask); | 155 | return !!(gc->read_reg(gc->reg_dat) & pinmask); |
@@ -157,8 +169,13 @@ static int bgpio_get_set_multiple(struct gpio_chip *gc, unsigned long *mask, | |||
157 | *bits &= ~*mask; | 169 | *bits &= ~*mask; |
158 | 170 | ||
159 | /* Exploit the fact that we know which directions are set */ | 171 | /* Exploit the fact that we know which directions are set */ |
160 | set_mask = *mask & gc->bgpio_dir; | 172 | if (gc->bgpio_dir_inverted) { |
161 | get_mask = *mask & ~gc->bgpio_dir; | 173 | set_mask = *mask & ~gc->bgpio_dir; |
174 | get_mask = *mask & gc->bgpio_dir; | ||
175 | } else { | ||
176 | set_mask = *mask & gc->bgpio_dir; | ||
177 | get_mask = *mask & ~gc->bgpio_dir; | ||
178 | } | ||
162 | 179 | ||
163 | if (set_mask) | 180 | if (set_mask) |
164 | *bits |= gc->read_reg(gc->reg_set) & set_mask; | 181 | *bits |= gc->read_reg(gc->reg_set) & set_mask; |
@@ -359,7 +376,10 @@ static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) | |||
359 | 376 | ||
360 | spin_lock_irqsave(&gc->bgpio_lock, flags); | 377 | spin_lock_irqsave(&gc->bgpio_lock, flags); |
361 | 378 | ||
362 | gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio); | 379 | if (gc->bgpio_dir_inverted) |
380 | gc->bgpio_dir |= bgpio_line2mask(gc, gpio); | ||
381 | else | ||
382 | gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio); | ||
363 | gc->write_reg(gc->reg_dir, gc->bgpio_dir); | 383 | gc->write_reg(gc->reg_dir, gc->bgpio_dir); |
364 | 384 | ||
365 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); | 385 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); |
@@ -370,7 +390,10 @@ static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) | |||
370 | static int bgpio_get_dir(struct gpio_chip *gc, unsigned int gpio) | 390 | static int bgpio_get_dir(struct gpio_chip *gc, unsigned int gpio) |
371 | { | 391 | { |
372 | /* Return 0 if output, 1 of input */ | 392 | /* Return 0 if output, 1 of input */ |
373 | return !(gc->read_reg(gc->reg_dir) & bgpio_line2mask(gc, gpio)); | 393 | if (gc->bgpio_dir_inverted) |
394 | return !!(gc->read_reg(gc->reg_dir) & bgpio_line2mask(gc, gpio)); | ||
395 | else | ||
396 | return !(gc->read_reg(gc->reg_dir) & bgpio_line2mask(gc, gpio)); | ||
374 | } | 397 | } |
375 | 398 | ||
376 | static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | 399 | static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) |
@@ -381,37 +404,10 @@ static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | |||
381 | 404 | ||
382 | spin_lock_irqsave(&gc->bgpio_lock, flags); | 405 | spin_lock_irqsave(&gc->bgpio_lock, flags); |
383 | 406 | ||
384 | gc->bgpio_dir |= bgpio_line2mask(gc, gpio); | 407 | if (gc->bgpio_dir_inverted) |
385 | gc->write_reg(gc->reg_dir, gc->bgpio_dir); | 408 | gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio); |
386 | 409 | else | |
387 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); | 410 | gc->bgpio_dir |= bgpio_line2mask(gc, gpio); |
388 | |||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | static int bgpio_dir_in_inv(struct gpio_chip *gc, unsigned int gpio) | ||
393 | { | ||
394 | unsigned long flags; | ||
395 | |||
396 | spin_lock_irqsave(&gc->bgpio_lock, flags); | ||
397 | |||
398 | gc->bgpio_dir |= bgpio_line2mask(gc, gpio); | ||
399 | gc->write_reg(gc->reg_dir, gc->bgpio_dir); | ||
400 | |||
401 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); | ||
402 | |||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | static int bgpio_dir_out_inv(struct gpio_chip *gc, unsigned int gpio, int val) | ||
407 | { | ||
408 | unsigned long flags; | ||
409 | |||
410 | gc->set(gc, gpio, val); | ||
411 | |||
412 | spin_lock_irqsave(&gc->bgpio_lock, flags); | ||
413 | |||
414 | gc->bgpio_dir &= ~bgpio_line2mask(gc, gpio); | ||
415 | gc->write_reg(gc->reg_dir, gc->bgpio_dir); | 411 | gc->write_reg(gc->reg_dir, gc->bgpio_dir); |
416 | 412 | ||
417 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); | 413 | spin_unlock_irqrestore(&gc->bgpio_lock, flags); |
@@ -419,12 +415,6 @@ static int bgpio_dir_out_inv(struct gpio_chip *gc, unsigned int gpio, int val) | |||
419 | return 0; | 415 | return 0; |
420 | } | 416 | } |
421 | 417 | ||
422 | static int bgpio_get_dir_inv(struct gpio_chip *gc, unsigned int gpio) | ||
423 | { | ||
424 | /* Return 0 if output, 1 if input */ | ||
425 | return !!(gc->read_reg(gc->reg_dir) & bgpio_line2mask(gc, gpio)); | ||
426 | } | ||
427 | |||
428 | static int bgpio_setup_accessors(struct device *dev, | 418 | static int bgpio_setup_accessors(struct device *dev, |
429 | struct gpio_chip *gc, | 419 | struct gpio_chip *gc, |
430 | bool byte_be) | 420 | bool byte_be) |
@@ -560,9 +550,10 @@ static int bgpio_setup_direction(struct gpio_chip *gc, | |||
560 | gc->get_direction = bgpio_get_dir; | 550 | gc->get_direction = bgpio_get_dir; |
561 | } else if (dirin) { | 551 | } else if (dirin) { |
562 | gc->reg_dir = dirin; | 552 | gc->reg_dir = dirin; |
563 | gc->direction_output = bgpio_dir_out_inv; | 553 | gc->direction_output = bgpio_dir_out; |
564 | gc->direction_input = bgpio_dir_in_inv; | 554 | gc->direction_input = bgpio_dir_in; |
565 | gc->get_direction = bgpio_get_dir_inv; | 555 | gc->get_direction = bgpio_get_dir; |
556 | gc->bgpio_dir_inverted = true; | ||
566 | } else { | 557 | } else { |
567 | if (flags & BGPIOF_NO_OUTPUT) | 558 | if (flags & BGPIOF_NO_OUTPUT) |
568 | gc->direction_output = bgpio_dir_out_err; | 559 | gc->direction_output = bgpio_dir_out_err; |
@@ -582,6 +573,33 @@ static int bgpio_request(struct gpio_chip *chip, unsigned gpio_pin) | |||
582 | return -EINVAL; | 573 | return -EINVAL; |
583 | } | 574 | } |
584 | 575 | ||
576 | /** | ||
577 | * bgpio_init() - Initialize generic GPIO accessor functions | ||
578 | * @gc: the GPIO chip to set up | ||
579 | * @dev: the parent device of the new GPIO chip (compulsory) | ||
580 | * @sz: the size (width) of the MMIO registers in bytes, typically 1, 2 or 4 | ||
581 | * @dat: MMIO address for the register to READ the value of the GPIO lines, it | ||
582 | * is expected that a 1 in the corresponding bit in this register means the | ||
583 | * line is asserted | ||
584 | * @set: MMIO address for the register to SET the value of the GPIO lines, it is | ||
585 | * expected that we write the line with 1 in this register to drive the GPIO line | ||
586 | * high. | ||
587 | * @clr: MMIO address for the register to CLEAR the value of the GPIO lines, it is | ||
588 | * expected that we write the line with 1 in this register to drive the GPIO line | ||
589 | * low. It is allowed to leave this address as NULL, in that case the SET register | ||
590 | * will be assumed to also clear the GPIO lines, by actively writing the line | ||
591 | * with 0. | ||
592 | * @dirout: MMIO address for the register to set the line as OUTPUT. It is assumed | ||
593 | * that setting a line to 1 in this register will turn that line into an | ||
594 | * output line. Conversely, setting the line to 0 will turn that line into | ||
595 | * an input. Either this or @dirin can be defined, but never both. | ||
596 | * @dirin: MMIO address for the register to set this line as INPUT. It is assumed | ||
597 | * that setting a line to 1 in this register will turn that line into an | ||
598 | * input line. Conversely, setting the line to 0 will turn that line into | ||
599 | * an output. Either this or @dirout can be defined, but never both. | ||
600 | * @flags: Different flags that will affect the behaviour of the device, such as | ||
601 | * endianness etc. | ||
602 | */ | ||
585 | int bgpio_init(struct gpio_chip *gc, struct device *dev, | 603 | int bgpio_init(struct gpio_chip *gc, struct device *dev, |
586 | unsigned long sz, void __iomem *dat, void __iomem *set, | 604 | unsigned long sz, void __iomem *dat, void __iomem *set, |
587 | void __iomem *clr, void __iomem *dirout, void __iomem *dirin, | 605 | void __iomem *clr, void __iomem *dirout, void __iomem *dirin, |