aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/wm831x-gpio.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/gpio/wm831x-gpio.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/gpio/wm831x-gpio.c')
-rw-r--r--drivers/gpio/wm831x-gpio.c59
1 files changed, 46 insertions, 13 deletions
diff --git a/drivers/gpio/wm831x-gpio.c b/drivers/gpio/wm831x-gpio.c
index f9c09a54ec7f..1fa449a1a4cb 100644
--- a/drivers/gpio/wm831x-gpio.c
+++ b/drivers/gpio/wm831x-gpio.c
@@ -13,6 +13,7 @@
13 */ 13 */
14 14
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/slab.h>
16#include <linux/module.h> 17#include <linux/module.h>
17#include <linux/gpio.h> 18#include <linux/gpio.h>
18#include <linux/mfd/core.h> 19#include <linux/mfd/core.h>
@@ -22,8 +23,7 @@
22#include <linux/mfd/wm831x/core.h> 23#include <linux/mfd/wm831x/core.h>
23#include <linux/mfd/wm831x/pdata.h> 24#include <linux/mfd/wm831x/pdata.h>
24#include <linux/mfd/wm831x/gpio.h> 25#include <linux/mfd/wm831x/gpio.h>
25 26#include <linux/mfd/wm831x/irq.h>
26#define WM831X_GPIO_MAX 16
27 27
28struct wm831x_gpio { 28struct wm831x_gpio {
29 struct wm831x *wm831x; 29 struct wm831x *wm831x;
@@ -39,10 +39,14 @@ static int wm831x_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
39{ 39{
40 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); 40 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
41 struct wm831x *wm831x = wm831x_gpio->wm831x; 41 struct wm831x *wm831x = wm831x_gpio->wm831x;
42 int val = WM831X_GPN_DIR;
43
44 if (wm831x->has_gpio_ena)
45 val |= WM831X_GPN_TRI;
42 46
43 return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset, 47 return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset,
44 WM831X_GPN_DIR | WM831X_GPN_TRI, 48 WM831X_GPN_DIR | WM831X_GPN_TRI |
45 WM831X_GPN_DIR); 49 WM831X_GPN_FN_MASK, val);
46} 50}
47 51
48static int wm831x_gpio_get(struct gpio_chip *chip, unsigned offset) 52static int wm831x_gpio_get(struct gpio_chip *chip, unsigned offset)
@@ -61,23 +65,47 @@ static int wm831x_gpio_get(struct gpio_chip *chip, unsigned offset)
61 return 0; 65 return 0;
62} 66}
63 67
68static void wm831x_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
69{
70 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
71 struct wm831x *wm831x = wm831x_gpio->wm831x;
72
73 wm831x_set_bits(wm831x, WM831X_GPIO_LEVEL, 1 << offset,
74 value << offset);
75}
76
64static int wm831x_gpio_direction_out(struct gpio_chip *chip, 77static int wm831x_gpio_direction_out(struct gpio_chip *chip,
65 unsigned offset, int value) 78 unsigned offset, int value)
66{ 79{
67 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); 80 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
68 struct wm831x *wm831x = wm831x_gpio->wm831x; 81 struct wm831x *wm831x = wm831x_gpio->wm831x;
82 int val = 0;
83 int ret;
69 84
70 return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset, 85 if (wm831x->has_gpio_ena)
71 WM831X_GPN_DIR | WM831X_GPN_TRI, 0); 86 val |= WM831X_GPN_TRI;
87
88 ret = wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + offset,
89 WM831X_GPN_DIR | WM831X_GPN_TRI |
90 WM831X_GPN_FN_MASK, val);
91 if (ret < 0)
92 return ret;
93
94 /* Can only set GPIO state once it's in output mode */
95 wm831x_gpio_set(chip, offset, value);
96
97 return 0;
72} 98}
73 99
74static void wm831x_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 100static int wm831x_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
75{ 101{
76 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); 102 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
77 struct wm831x *wm831x = wm831x_gpio->wm831x; 103 struct wm831x *wm831x = wm831x_gpio->wm831x;
78 104
79 wm831x_set_bits(wm831x, WM831X_GPIO_LEVEL, 1 << offset, 105 if (!wm831x->irq_base)
80 value << offset); 106 return -EINVAL;
107
108 return wm831x->irq_base + WM831X_IRQ_GPIO_1 + offset;
81} 109}
82 110
83#ifdef CONFIG_DEBUG_FS 111#ifdef CONFIG_DEBUG_FS
@@ -85,7 +113,7 @@ static void wm831x_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
85{ 113{
86 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); 114 struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
87 struct wm831x *wm831x = wm831x_gpio->wm831x; 115 struct wm831x *wm831x = wm831x_gpio->wm831x;
88 int i; 116 int i, tristated;
89 117
90 for (i = 0; i < chip->ngpio; i++) { 118 for (i = 0; i < chip->ngpio; i++) {
91 int gpio = i + chip->base; 119 int gpio = i + chip->base;
@@ -152,15 +180,19 @@ static void wm831x_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
152 break; 180 break;
153 } 181 }
154 182
183 tristated = reg & WM831X_GPN_TRI;
184 if (wm831x->has_gpio_ena)
185 tristated = !tristated;
186
155 seq_printf(s, " %s %s %s %s%s\n" 187 seq_printf(s, " %s %s %s %s%s\n"
156 " %s%s (0x%4x)\n", 188 " %s%s (0x%4x)\n",
157 reg & WM831X_GPN_DIR ? "in" : "out", 189 reg & WM831X_GPN_DIR ? "in" : "out",
158 wm831x_gpio_get(chip, i) ? "high" : "low", 190 wm831x_gpio_get(chip, i) ? "high" : "low",
159 pull, 191 pull,
160 powerdomain, 192 powerdomain,
161 reg & WM831X_GPN_POL ? " inverted" : "", 193 reg & WM831X_GPN_POL ? "" : " inverted",
162 reg & WM831X_GPN_OD ? "open-drain" : "CMOS", 194 reg & WM831X_GPN_OD ? "open-drain" : "CMOS",
163 reg & WM831X_GPN_TRI ? " tristated" : "", 195 tristated ? " tristated" : "",
164 reg); 196 reg);
165 } 197 }
166} 198}
@@ -175,6 +207,7 @@ static struct gpio_chip template_chip = {
175 .get = wm831x_gpio_get, 207 .get = wm831x_gpio_get,
176 .direction_output = wm831x_gpio_direction_out, 208 .direction_output = wm831x_gpio_direction_out,
177 .set = wm831x_gpio_set, 209 .set = wm831x_gpio_set,
210 .to_irq = wm831x_gpio_to_irq,
178 .dbg_show = wm831x_gpio_dbg_show, 211 .dbg_show = wm831x_gpio_dbg_show,
179 .can_sleep = 1, 212 .can_sleep = 1,
180}; 213};
@@ -192,7 +225,7 @@ static int __devinit wm831x_gpio_probe(struct platform_device *pdev)
192 225
193 wm831x_gpio->wm831x = wm831x; 226 wm831x_gpio->wm831x = wm831x;
194 wm831x_gpio->gpio_chip = template_chip; 227 wm831x_gpio->gpio_chip = template_chip;
195 wm831x_gpio->gpio_chip.ngpio = WM831X_GPIO_MAX; 228 wm831x_gpio->gpio_chip.ngpio = wm831x->num_gpio;
196 wm831x_gpio->gpio_chip.dev = &pdev->dev; 229 wm831x_gpio->gpio_chip.dev = &pdev->dev;
197 if (pdata && pdata->gpio_base) 230 if (pdata && pdata->gpio_base)
198 wm831x_gpio->gpio_chip.base = pdata->gpio_base; 231 wm831x_gpio->gpio_chip.base = pdata->gpio_base;