aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTobias Mueller <Tobias_Mueller@twam.info>2009-12-14 21:00:35 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-15 11:53:27 -0500
commit1ea3fa7bbfbe81cfbdcc35748a57c35f9b32c5d6 (patch)
treee6a6100062ddfd2c55576243998ac5299376a187 /drivers
parent5f0a96b044d8edaee20f4a32ef6c393599ca55f8 (diff)
cs5535-gpio: request function, mask & names added
Changed number of gpio pins to 32 (according to datasheet) Added mask to disable some pins Added gpio_request for checking mask and disabling special pin functions Added pin names [dilinger@collabora.co.uk: make printk usage consistent] Signed-off-by: Tobias Mueller <Tobias_Mueller@twam.info> Signed-off-by: Andres Salomon <dilinger@collabora.co.uk> Cc: Takashi Iwai <tiwai@suse.de> Cc: Jordan Crouse <jordan@cosmicpenguin.net> Cc: David Brownell <david-b@pacbell.net> Cc: Alessandro Zummo <alessandro.zummo@towertech.it> Signed-off-by: Andres Salomon <dilinger@collabora.co.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/cs5535-gpio.c83
1 files changed, 78 insertions, 5 deletions
diff --git a/drivers/gpio/cs5535-gpio.c b/drivers/gpio/cs5535-gpio.c
index 56138893819a..0fdbe94f24a3 100644
--- a/drivers/gpio/cs5535-gpio.c
+++ b/drivers/gpio/cs5535-gpio.c
@@ -19,6 +19,29 @@
19#define DRV_NAME "cs5535-gpio" 19#define DRV_NAME "cs5535-gpio"
20#define GPIO_BAR 1 20#define GPIO_BAR 1
21 21
22/*
23 * Some GPIO pins
24 * 31-29,23 : reserved (always mask out)
25 * 28 : Power Button
26 * 26 : PME#
27 * 22-16 : LPC
28 * 14,15 : SMBus
29 * 9,8 : UART1
30 * 7 : PCI INTB
31 * 3,4 : UART2/DDC
32 * 2 : IDE_IRQ0
33 * 1 : AC_BEEP
34 * 0 : PCI INTA
35 *
36 * If a mask was not specified, allow all except
37 * reserved and Power Button
38 */
39#define GPIO_DEFAULT_MASK 0x0F7FFFFF
40
41static ulong mask = GPIO_DEFAULT_MASK;
42module_param_named(mask, mask, ulong, 0444);
43MODULE_PARM_DESC(mask, "GPIO channel mask.");
44
22static struct cs5535_gpio_chip { 45static struct cs5535_gpio_chip {
23 struct gpio_chip chip; 46 struct gpio_chip chip;
24 resource_size_t base; 47 resource_size_t base;
@@ -102,6 +125,33 @@ EXPORT_SYMBOL_GPL(cs5535_gpio_isset);
102 * Generic gpio_chip API support. 125 * Generic gpio_chip API support.
103 */ 126 */
104 127
128static int chip_gpio_request(struct gpio_chip *c, unsigned offset)
129{
130 struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c;
131 unsigned long flags;
132
133 spin_lock_irqsave(&chip->lock, flags);
134
135 /* check if this pin is available */
136 if ((mask & (1 << offset)) == 0) {
137 dev_info(&chip->pdev->dev,
138 "pin %u is not available (check mask)\n", offset);
139 spin_unlock_irqrestore(&chip->lock, flags);
140 return -EINVAL;
141 }
142
143 /* disable output aux 1 & 2 on this pin */
144 __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_AUX1);
145 __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_AUX2);
146
147 /* disable input aux 1 on this pin */
148 __cs5535_gpio_clear(chip, offset, GPIO_INPUT_AUX1);
149
150 spin_unlock_irqrestore(&chip->lock, flags);
151
152 return 0;
153}
154
105static int chip_gpio_get(struct gpio_chip *chip, unsigned offset) 155static int chip_gpio_get(struct gpio_chip *chip, unsigned offset)
106{ 156{
107 return cs5535_gpio_isset(offset, GPIO_OUTPUT_VAL); 157 return cs5535_gpio_isset(offset, GPIO_OUTPUT_VAL);
@@ -145,13 +195,26 @@ static int chip_direction_output(struct gpio_chip *c, unsigned offset, int val)
145 return 0; 195 return 0;
146} 196}
147 197
198static char *cs5535_gpio_names[] = {
199 "GPIO0", "GPIO1", "GPIO2", "GPIO3",
200 "GPIO4", "GPIO5", "GPIO6", "GPIO7",
201 "GPIO8", "GPIO9", "GPIO10", "GPIO11",
202 "GPIO12", "GPIO13", "GPIO14", "GPIO15",
203 "GPIO16", "GPIO17", "GPIO18", "GPIO19",
204 "GPIO20", "GPIO21", "GPIO22", NULL,
205 "GPIO24", "GPIO25", "GPIO26", "GPIO27",
206 "GPIO28", NULL, NULL, NULL,
207};
208
148static struct cs5535_gpio_chip cs5535_gpio_chip = { 209static struct cs5535_gpio_chip cs5535_gpio_chip = {
149 .chip = { 210 .chip = {
150 .owner = THIS_MODULE, 211 .owner = THIS_MODULE,
151 .label = DRV_NAME, 212 .label = DRV_NAME,
152 213
153 .base = 0, 214 .base = 0,
154 .ngpio = 28, 215 .ngpio = 32,
216 .names = cs5535_gpio_names,
217 .request = chip_gpio_request,
155 218
156 .get = chip_gpio_get, 219 .get = chip_gpio_get,
157 .set = chip_gpio_set, 220 .set = chip_gpio_set,
@@ -165,6 +228,7 @@ static int __init cs5535_gpio_probe(struct pci_dev *pdev,
165 const struct pci_device_id *pci_id) 228 const struct pci_device_id *pci_id)
166{ 229{
167 int err; 230 int err;
231 ulong mask_orig = mask;
168 232
169 /* There are two ways to get the GPIO base address; one is by 233 /* There are two ways to get the GPIO base address; one is by
170 * fetching it from MSR_LBAR_GPIO, the other is by reading the 234 * fetching it from MSR_LBAR_GPIO, the other is by reading the
@@ -193,14 +257,23 @@ static int __init cs5535_gpio_probe(struct pci_dev *pdev,
193 dev_info(&pdev->dev, "allocated PCI BAR #%d: base 0x%llx\n", GPIO_BAR, 257 dev_info(&pdev->dev, "allocated PCI BAR #%d: base 0x%llx\n", GPIO_BAR,
194 (unsigned long long) cs5535_gpio_chip.base); 258 (unsigned long long) cs5535_gpio_chip.base);
195 259
260 /* mask out reserved pins */
261 mask &= 0x1F7FFFFF;
262
263 /* do not allow pin 28, Power Button, as there's special handling
264 * in the PMC needed. (note 12, p. 48) */
265 mask &= ~(1 << 28);
266
267 if (mask_orig != mask)
268 dev_info(&pdev->dev, "mask changed from 0x%08lX to 0x%08lX\n",
269 mask_orig, mask);
270
196 /* finally, register with the generic GPIO API */ 271 /* finally, register with the generic GPIO API */
197 err = gpiochip_add(&cs5535_gpio_chip.chip); 272 err = gpiochip_add(&cs5535_gpio_chip.chip);
198 if (err) { 273 if (err)
199 dev_err(&pdev->dev, "failed to register gpio chip\n");
200 goto release_region; 274 goto release_region;
201 }
202 275
203 printk(KERN_INFO DRV_NAME ": GPIO support successfully loaded.\n"); 276 dev_info(&pdev->dev, DRV_NAME ": GPIO support successfully loaded.\n");
204 return 0; 277 return 0;
205 278
206release_region: 279release_region: