aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-clps711x.c
diff options
context:
space:
mode:
authorAlexander Shiyan <shc_work@mail.ru>2012-10-24 04:34:46 -0400
committerLinus Walleij <linus.walleij@linaro.org>2012-10-26 03:16:15 -0400
commitd6a2fa0424aefe97289aa561444ec3ae09bdbba0 (patch)
tree0fea81d789d6a74ecf97fdacf1261c7ffe2b09a5 /drivers/gpio/gpio-clps711x.c
parent41b3996e3b6825bd3a0624d62fde53fbad092ed0 (diff)
GPIO: clps711x: Fix direction logic for PORTD
PORTD have different direction logic, i.e. "0" is output and "1" is input. This patch fix this issue. Signed-off-by: Alexander Shiyan <shc_work@mail.ru> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio/gpio-clps711x.c')
-rw-r--r--drivers/gpio/gpio-clps711x.c65
1 files changed, 51 insertions, 14 deletions
diff --git a/drivers/gpio/gpio-clps711x.c b/drivers/gpio/gpio-clps711x.c
index 0753b3a9a34d..ad181db79508 100644
--- a/drivers/gpio/gpio-clps711x.c
+++ b/drivers/gpio/gpio-clps711x.c
@@ -65,7 +65,7 @@ static void gpio_clps711x_set(struct gpio_chip *chip, unsigned offset,
65 spin_unlock_irqrestore(&gpio->lock, flags); 65 spin_unlock_irqrestore(&gpio->lock, flags);
66} 66}
67 67
68static int gpio_clps711x_direction_in(struct gpio_chip *chip, unsigned offset) 68static int gpio_clps711x_dir_in(struct gpio_chip *chip, unsigned offset)
69{ 69{
70 int tmp; 70 int tmp;
71 unsigned long flags; 71 unsigned long flags;
@@ -79,8 +79,8 @@ static int gpio_clps711x_direction_in(struct gpio_chip *chip, unsigned offset)
79 return 0; 79 return 0;
80} 80}
81 81
82static int gpio_clps711x_direction_out(struct gpio_chip *chip, unsigned offset, 82static int gpio_clps711x_dir_out(struct gpio_chip *chip, unsigned offset,
83 int value) 83 int value)
84{ 84{
85 int tmp; 85 int tmp;
86 unsigned long flags; 86 unsigned long flags;
@@ -98,17 +98,49 @@ static int gpio_clps711x_direction_out(struct gpio_chip *chip, unsigned offset,
98 return 0; 98 return 0;
99} 99}
100 100
101struct clps711x_gpio_port { 101static int gpio_clps711x_dir_in_inv(struct gpio_chip *chip, unsigned offset)
102{
103 int tmp;
104 unsigned long flags;
105 struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);
106
107 spin_lock_irqsave(&gpio->lock, flags);
108 tmp = readb(clps711x_pdir(chip)) | (1 << offset);
109 writeb(tmp, clps711x_pdir(chip));
110 spin_unlock_irqrestore(&gpio->lock, flags);
111
112 return 0;
113}
114
115static int gpio_clps711x_dir_out_inv(struct gpio_chip *chip, unsigned offset,
116 int value)
117{
118 int tmp;
119 unsigned long flags;
120 struct clps711x_gpio *gpio = dev_get_drvdata(chip->dev);
121
122 spin_lock_irqsave(&gpio->lock, flags);
123 tmp = readb(clps711x_pdir(chip)) & ~(1 << offset);
124 writeb(tmp, clps711x_pdir(chip));
125 tmp = readb(clps711x_port(chip)) & ~(1 << offset);
126 if (value)
127 tmp |= 1 << offset;
128 writeb(tmp, clps711x_port(chip));
129 spin_unlock_irqrestore(&gpio->lock, flags);
130
131 return 0;
132}
133
134static struct {
102 char *name; 135 char *name;
103 int nr; 136 int nr;
104}; 137 int inv_dir;
105 138} clps711x_gpio_ports[] __initconst = {
106static const struct clps711x_gpio_port clps711x_gpio_ports[] __initconst = { 139 { "PORTA", 8, 0, },
107 { "PORTA", 8, }, 140 { "PORTB", 8, 0, },
108 { "PORTB", 8, }, 141 { "PORTC", 8, 0, },
109 { "PORTC", 8, }, 142 { "PORTD", 8, 1, },
110 { "PORTD", 8, }, 143 { "PORTE", 3, 0, },
111 { "PORTE", 3, },
112}; 144};
113 145
114static int __init gpio_clps711x_init(void) 146static int __init gpio_clps711x_init(void)
@@ -145,10 +177,15 @@ static int __init gpio_clps711x_init(void)
145 gpio->chip[i].label = clps711x_gpio_ports[i].name; 177 gpio->chip[i].label = clps711x_gpio_ports[i].name;
146 gpio->chip[i].base = i * 8; 178 gpio->chip[i].base = i * 8;
147 gpio->chip[i].ngpio = clps711x_gpio_ports[i].nr; 179 gpio->chip[i].ngpio = clps711x_gpio_ports[i].nr;
148 gpio->chip[i].direction_input = gpio_clps711x_direction_in;
149 gpio->chip[i].get = gpio_clps711x_get; 180 gpio->chip[i].get = gpio_clps711x_get;
150 gpio->chip[i].direction_output = gpio_clps711x_direction_out;
151 gpio->chip[i].set = gpio_clps711x_set; 181 gpio->chip[i].set = gpio_clps711x_set;
182 if (!clps711x_gpio_ports[i].inv_dir) {
183 gpio->chip[i].direction_input = gpio_clps711x_dir_in;
184 gpio->chip[i].direction_output = gpio_clps711x_dir_out;
185 } else {
186 gpio->chip[i].direction_input = gpio_clps711x_dir_in_inv;
187 gpio->chip[i].direction_output = gpio_clps711x_dir_out_inv;
188 }
152 WARN_ON(gpiochip_add(&gpio->chip[i])); 189 WARN_ON(gpiochip_add(&gpio->chip[i]));
153 } 190 }
154 191