aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Stigge <stigge@antcom.de>2012-03-05 17:01:11 -0500
committerGrant Likely <grant.likely@secretlab.ca>2012-03-12 13:25:30 -0400
commit46158aad96b0a90b52fd345f89951a50b3d1a81f (patch)
treeb6ce41ea7ece7c0833fd42120a14e96455b1fd5f
parent8e5fb37b9873eacb2381f2931d252b6db6e2cb16 (diff)
GPIO: LPC32xx: Add output reading to GPO P3
The chip offers the function to detect the current state of output of the GPO P3 pins. Useful for reading GPIO output state in Linux' GPIO API, e.g. via sysfs. Please note that this only reads back the currently programmed output state, not the actual electrical level in terms of a GPI function. Finally, GPO3 is still just an output. Signed-off-by: Roland Stigge <stigge@antcom.de> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
-rw-r--r--drivers/gpio/gpio-lpc32xx.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/gpio/gpio-lpc32xx.c b/drivers/gpio/gpio-lpc32xx.c
index 14a2f297a0b4..61c2d08d37b6 100644
--- a/drivers/gpio/gpio-lpc32xx.c
+++ b/drivers/gpio/gpio-lpc32xx.c
@@ -62,9 +62,11 @@
62#define GPIO3_PIN_IN_SEL(x, y) (((x) >> GPIO3_PIN_IN_SHIFT(y)) & 1) 62#define GPIO3_PIN_IN_SEL(x, y) (((x) >> GPIO3_PIN_IN_SHIFT(y)) & 1)
63#define GPIO3_PIN5_IN_SEL(x) (((x) >> 24) & 1) 63#define GPIO3_PIN5_IN_SEL(x) (((x) >> 24) & 1)
64#define GPI3_PIN_IN_SEL(x, y) (((x) >> (y)) & 1) 64#define GPI3_PIN_IN_SEL(x, y) (((x) >> (y)) & 1)
65#define GPO3_PIN_IN_SEL(x, y) (((x) >> (y)) & 1)
65 66
66struct gpio_regs { 67struct gpio_regs {
67 void __iomem *inp_state; 68 void __iomem *inp_state;
69 void __iomem *outp_state;
68 void __iomem *outp_set; 70 void __iomem *outp_set;
69 void __iomem *outp_clr; 71 void __iomem *outp_clr;
70 void __iomem *dir_set; 72 void __iomem *dir_set;
@@ -145,6 +147,7 @@ static struct gpio_regs gpio_grp_regs_p2 = {
145 147
146static struct gpio_regs gpio_grp_regs_p3 = { 148static struct gpio_regs gpio_grp_regs_p3 = {
147 .inp_state = LPC32XX_GPIO_P3_INP_STATE, 149 .inp_state = LPC32XX_GPIO_P3_INP_STATE,
150 .outp_state = LPC32XX_GPIO_P3_OUTP_STATE,
148 .outp_set = LPC32XX_GPIO_P3_OUTP_SET, 151 .outp_set = LPC32XX_GPIO_P3_OUTP_SET,
149 .outp_clr = LPC32XX_GPIO_P3_OUTP_CLR, 152 .outp_clr = LPC32XX_GPIO_P3_OUTP_CLR,
150 .dir_set = LPC32XX_GPIO_P2_DIR_SET, 153 .dir_set = LPC32XX_GPIO_P2_DIR_SET,
@@ -240,6 +243,12 @@ static int __get_gpi_state_p3(struct lpc32xx_gpio_chip *group,
240 return GPI3_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state), pin); 243 return GPI3_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state), pin);
241} 244}
242 245
246static int __get_gpo_state_p3(struct lpc32xx_gpio_chip *group,
247 unsigned pin)
248{
249 return GPO3_PIN_IN_SEL(__raw_readl(group->gpio_grp->outp_state), pin);
250}
251
243/* 252/*
244 * GENERIC_GPIO primitives. 253 * GENERIC_GPIO primitives.
245 */ 254 */
@@ -340,6 +349,13 @@ static void lpc32xx_gpo_set_value(struct gpio_chip *chip, unsigned pin,
340 __set_gpo_level_p3(group, pin, value); 349 __set_gpo_level_p3(group, pin, value);
341} 350}
342 351
352static int lpc32xx_gpo_get_value(struct gpio_chip *chip, unsigned pin)
353{
354 struct lpc32xx_gpio_chip *group = to_lpc32xx_gpio(chip);
355
356 return __get_gpo_state_p3(group, pin);
357}
358
343static int lpc32xx_gpio_request(struct gpio_chip *chip, unsigned pin) 359static int lpc32xx_gpio_request(struct gpio_chip *chip, unsigned pin)
344{ 360{
345 if (pin < chip->ngpio) 361 if (pin < chip->ngpio)
@@ -427,6 +443,7 @@ static struct lpc32xx_gpio_chip lpc32xx_gpiochip[] = {
427 .label = "gpo_p3", 443 .label = "gpo_p3",
428 .direction_output = lpc32xx_gpio_dir_out_always, 444 .direction_output = lpc32xx_gpio_dir_out_always,
429 .set = lpc32xx_gpo_set_value, 445 .set = lpc32xx_gpo_set_value,
446 .get = lpc32xx_gpo_get_value,
430 .request = lpc32xx_gpio_request, 447 .request = lpc32xx_gpio_request,
431 .base = LPC32XX_GPO_P3_GRP, 448 .base = LPC32XX_GPO_P3_GRP,
432 .ngpio = LPC32XX_GPO_P3_MAX, 449 .ngpio = LPC32XX_GPO_P3_MAX,