diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/gpio/wm831x-gpio.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (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.c | 59 |
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 | ||
28 | struct wm831x_gpio { | 28 | struct 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 | ||
48 | static int wm831x_gpio_get(struct gpio_chip *chip, unsigned offset) | 52 | static 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 | ||
68 | static 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 | |||
64 | static int wm831x_gpio_direction_out(struct gpio_chip *chip, | 77 | static 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 | ||
74 | static void wm831x_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | 100 | static 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; |