Merge git://git.kernel.org/pub/scm/linux/kernel/git/pkl/squashfs-linus
[pandora-kernel.git] / drivers / gpio / cs5535-gpio.c
1 /*
2  * AMD CS5535/CS5536 GPIO driver
3  * Copyright (C) 2006  Advanced Micro Devices, Inc.
4  * Copyright (C) 2007-2009  Andres Salomon <dilinger@collabora.co.uk>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of version 2 of the GNU General Public License
8  * as published by the Free Software Foundation.
9  */
10
11 #include <linux/kernel.h>
12 #include <linux/spinlock.h>
13 #include <linux/module.h>
14 #include <linux/pci.h>
15 #include <linux/gpio.h>
16 #include <linux/io.h>
17 #include <linux/cs5535.h>
18
19 #define DRV_NAME "cs5535-gpio"
20 #define GPIO_BAR 1
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
41 static ulong mask = GPIO_DEFAULT_MASK;
42 module_param_named(mask, mask, ulong, 0444);
43 MODULE_PARM_DESC(mask, "GPIO channel mask.");
44
45 static struct cs5535_gpio_chip {
46         struct gpio_chip chip;
47         resource_size_t base;
48
49         struct pci_dev *pdev;
50         spinlock_t lock;
51 } cs5535_gpio_chip;
52
53 /*
54  * The CS5535/CS5536 GPIOs support a number of extra features not defined
55  * by the gpio_chip API, so these are exported.  For a full list of the
56  * registers, see include/linux/cs5535.h.
57  */
58
59 static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset,
60                 unsigned int reg)
61 {
62         if (offset < 16)
63                 /* low bank register */
64                 outl(1 << offset, chip->base + reg);
65         else
66                 /* high bank register */
67                 outl(1 << (offset - 16), chip->base + 0x80 + reg);
68 }
69
70 void cs5535_gpio_set(unsigned offset, unsigned int reg)
71 {
72         struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
73         unsigned long flags;
74
75         spin_lock_irqsave(&chip->lock, flags);
76         __cs5535_gpio_set(chip, offset, reg);
77         spin_unlock_irqrestore(&chip->lock, flags);
78 }
79 EXPORT_SYMBOL_GPL(cs5535_gpio_set);
80
81 static void __cs5535_gpio_clear(struct cs5535_gpio_chip *chip, unsigned offset,
82                 unsigned int reg)
83 {
84         if (offset < 16)
85                 /* low bank register */
86                 outl(1 << (offset + 16), chip->base + reg);
87         else
88                 /* high bank register */
89                 outl(1 << offset, chip->base + 0x80 + reg);
90 }
91
92 void cs5535_gpio_clear(unsigned offset, unsigned int reg)
93 {
94         struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
95         unsigned long flags;
96
97         spin_lock_irqsave(&chip->lock, flags);
98         __cs5535_gpio_clear(chip, offset, reg);
99         spin_unlock_irqrestore(&chip->lock, flags);
100 }
101 EXPORT_SYMBOL_GPL(cs5535_gpio_clear);
102
103 int cs5535_gpio_isset(unsigned offset, unsigned int reg)
104 {
105         struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
106         unsigned long flags;
107         long val;
108
109         spin_lock_irqsave(&chip->lock, flags);
110         if (offset < 16)
111                 /* low bank register */
112                 val = inl(chip->base + reg);
113         else {
114                 /* high bank register */
115                 val = inl(chip->base + 0x80 + reg);
116                 offset -= 16;
117         }
118         spin_unlock_irqrestore(&chip->lock, flags);
119
120         return (val & (1 << offset)) ? 1 : 0;
121 }
122 EXPORT_SYMBOL_GPL(cs5535_gpio_isset);
123
124 /*
125  * Generic gpio_chip API support.
126  */
127
128 static 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
155 static int chip_gpio_get(struct gpio_chip *chip, unsigned offset)
156 {
157         return cs5535_gpio_isset(offset, GPIO_READ_BACK);
158 }
159
160 static void chip_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
161 {
162         if (val)
163                 cs5535_gpio_set(offset, GPIO_OUTPUT_VAL);
164         else
165                 cs5535_gpio_clear(offset, GPIO_OUTPUT_VAL);
166 }
167
168 static int chip_direction_input(struct gpio_chip *c, unsigned offset)
169 {
170         struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c;
171         unsigned long flags;
172
173         spin_lock_irqsave(&chip->lock, flags);
174         __cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
175         __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_ENABLE);
176         spin_unlock_irqrestore(&chip->lock, flags);
177
178         return 0;
179 }
180
181 static int chip_direction_output(struct gpio_chip *c, unsigned offset, int val)
182 {
183         struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c;
184         unsigned long flags;
185
186         spin_lock_irqsave(&chip->lock, flags);
187
188         __cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
189         __cs5535_gpio_set(chip, offset, GPIO_OUTPUT_ENABLE);
190         if (val)
191                 __cs5535_gpio_set(chip, offset, GPIO_OUTPUT_VAL);
192         else
193                 __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_VAL);
194
195         spin_unlock_irqrestore(&chip->lock, flags);
196
197         return 0;
198 }
199
200 static const char * const cs5535_gpio_names[] = {
201         "GPIO0", "GPIO1", "GPIO2", "GPIO3",
202         "GPIO4", "GPIO5", "GPIO6", "GPIO7",
203         "GPIO8", "GPIO9", "GPIO10", "GPIO11",
204         "GPIO12", "GPIO13", "GPIO14", "GPIO15",
205         "GPIO16", "GPIO17", "GPIO18", "GPIO19",
206         "GPIO20", "GPIO21", "GPIO22", NULL,
207         "GPIO24", "GPIO25", "GPIO26", "GPIO27",
208         "GPIO28", NULL, NULL, NULL,
209 };
210
211 static struct cs5535_gpio_chip cs5535_gpio_chip = {
212         .chip = {
213                 .owner = THIS_MODULE,
214                 .label = DRV_NAME,
215
216                 .base = 0,
217                 .ngpio = 32,
218                 .names = cs5535_gpio_names,
219                 .request = chip_gpio_request,
220
221                 .get = chip_gpio_get,
222                 .set = chip_gpio_set,
223
224                 .direction_input = chip_direction_input,
225                 .direction_output = chip_direction_output,
226         },
227 };
228
229 static int __init cs5535_gpio_probe(struct pci_dev *pdev,
230                 const struct pci_device_id *pci_id)
231 {
232         int err;
233         ulong mask_orig = mask;
234
235         /* There are two ways to get the GPIO base address; one is by
236          * fetching it from MSR_LBAR_GPIO, the other is by reading the
237          * PCI BAR info.  The latter method is easier (especially across
238          * different architectures), so we'll stick with that for now.  If
239          * it turns out to be unreliable in the face of crappy BIOSes, we
240          * can always go back to using MSRs.. */
241
242         err = pci_enable_device_io(pdev);
243         if (err) {
244                 dev_err(&pdev->dev, "can't enable device IO\n");
245                 goto done;
246         }
247
248         err = pci_request_region(pdev, GPIO_BAR, DRV_NAME);
249         if (err) {
250                 dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", GPIO_BAR);
251                 goto done;
252         }
253
254         /* set up the driver-specific struct */
255         cs5535_gpio_chip.base = pci_resource_start(pdev, GPIO_BAR);
256         cs5535_gpio_chip.pdev = pdev;
257         spin_lock_init(&cs5535_gpio_chip.lock);
258
259         dev_info(&pdev->dev, "allocated PCI BAR #%d: base 0x%llx\n", GPIO_BAR,
260                         (unsigned long long) cs5535_gpio_chip.base);
261
262         /* mask out reserved pins */
263         mask &= 0x1F7FFFFF;
264
265         /* do not allow pin 28, Power Button, as there's special handling
266          * in the PMC needed. (note 12, p. 48) */
267         mask &= ~(1 << 28);
268
269         if (mask_orig != mask)
270                 dev_info(&pdev->dev, "mask changed from 0x%08lX to 0x%08lX\n",
271                                 mask_orig, mask);
272
273         /* finally, register with the generic GPIO API */
274         err = gpiochip_add(&cs5535_gpio_chip.chip);
275         if (err)
276                 goto release_region;
277
278         dev_info(&pdev->dev, DRV_NAME ": GPIO support successfully loaded.\n");
279         return 0;
280
281 release_region:
282         pci_release_region(pdev, GPIO_BAR);
283 done:
284         return err;
285 }
286
287 static void __exit cs5535_gpio_remove(struct pci_dev *pdev)
288 {
289         int err;
290
291         err = gpiochip_remove(&cs5535_gpio_chip.chip);
292         if (err) {
293                 /* uhh? */
294                 dev_err(&pdev->dev, "unable to remove gpio_chip?\n");
295         }
296         pci_release_region(pdev, GPIO_BAR);
297 }
298
299 static struct pci_device_id cs5535_gpio_pci_tbl[] = {
300         { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) },
301         { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) },
302         { 0, },
303 };
304 MODULE_DEVICE_TABLE(pci, cs5535_gpio_pci_tbl);
305
306 /*
307  * We can't use the standard PCI driver registration stuff here, since
308  * that allows only one driver to bind to each PCI device (and we want
309  * multiple drivers to be able to bind to the device).  Instead, manually
310  * scan for the PCI device, request a single region, and keep track of the
311  * devices that we're using.
312  */
313
314 static int __init cs5535_gpio_scan_pci(void)
315 {
316         struct pci_dev *pdev;
317         int err = -ENODEV;
318         int i;
319
320         for (i = 0; i < ARRAY_SIZE(cs5535_gpio_pci_tbl); i++) {
321                 pdev = pci_get_device(cs5535_gpio_pci_tbl[i].vendor,
322                                 cs5535_gpio_pci_tbl[i].device, NULL);
323                 if (pdev) {
324                         err = cs5535_gpio_probe(pdev, &cs5535_gpio_pci_tbl[i]);
325                         if (err)
326                                 pci_dev_put(pdev);
327
328                         /* we only support a single CS5535/6 southbridge */
329                         break;
330                 }
331         }
332
333         return err;
334 }
335
336 static void __exit cs5535_gpio_free_pci(void)
337 {
338         cs5535_gpio_remove(cs5535_gpio_chip.pdev);
339         pci_dev_put(cs5535_gpio_chip.pdev);
340 }
341
342 static int __init cs5535_gpio_init(void)
343 {
344         return cs5535_gpio_scan_pci();
345 }
346
347 static void __exit cs5535_gpio_exit(void)
348 {
349         cs5535_gpio_free_pci();
350 }
351
352 module_init(cs5535_gpio_init);
353 module_exit(cs5535_gpio_exit);
354
355 MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>");
356 MODULE_DESCRIPTION("AMD CS5535/CS5536 GPIO driver");
357 MODULE_LICENSE("GPL");