GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / gpio / cs5535-gpio.c
blobe918855372c7477235ad090147637ba2d6e5b93d
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>
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 */
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>
19 #define DRV_NAME "cs5535-gpio"
20 #define GPIO_BAR 1
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
36 * If a mask was not specified, allow all except
37 * reserved and Power Button
39 #define GPIO_DEFAULT_MASK 0x0F7FFFFF
41 static ulong mask = GPIO_DEFAULT_MASK;
42 module_param_named(mask, mask, ulong, 0444);
43 MODULE_PARM_DESC(mask, "GPIO channel mask.");
45 static struct cs5535_gpio_chip {
46 struct gpio_chip chip;
47 resource_size_t base;
49 struct pci_dev *pdev;
50 spinlock_t lock;
51 } cs5535_gpio_chip;
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.
59 static void errata_outl(struct cs5535_gpio_chip *chip, u32 val,
60 unsigned int reg)
62 unsigned long addr = chip->base + 0x80 + reg;
64 if (reg != GPIO_POSITIVE_EDGE_STS && reg != GPIO_NEGATIVE_EDGE_STS) {
65 if (val & 0xffff)
66 val |= (inl(addr) & 0xffff); /* ignore the high bits */
67 else
68 val |= (inl(addr) ^ (val >> 16));
70 outl(val, addr);
73 static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset,
74 unsigned int reg)
76 if (offset < 16)
77 /* low bank register */
78 outl(1 << offset, chip->base + reg);
79 else
80 /* high bank register */
81 errata_outl(chip, 1 << (offset - 16), reg);
84 void cs5535_gpio_set(unsigned offset, unsigned int reg)
86 struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
87 unsigned long flags;
89 spin_lock_irqsave(&chip->lock, flags);
90 __cs5535_gpio_set(chip, offset, reg);
91 spin_unlock_irqrestore(&chip->lock, flags);
93 EXPORT_SYMBOL_GPL(cs5535_gpio_set);
95 static void __cs5535_gpio_clear(struct cs5535_gpio_chip *chip, unsigned offset,
96 unsigned int reg)
98 if (offset < 16)
99 /* low bank register */
100 outl(1 << (offset + 16), chip->base + reg);
101 else
102 /* high bank register */
103 errata_outl(chip, 1 << offset, reg);
106 void cs5535_gpio_clear(unsigned offset, unsigned int reg)
108 struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
109 unsigned long flags;
111 spin_lock_irqsave(&chip->lock, flags);
112 __cs5535_gpio_clear(chip, offset, reg);
113 spin_unlock_irqrestore(&chip->lock, flags);
115 EXPORT_SYMBOL_GPL(cs5535_gpio_clear);
117 int cs5535_gpio_isset(unsigned offset, unsigned int reg)
119 struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
120 unsigned long flags;
121 long val;
123 spin_lock_irqsave(&chip->lock, flags);
124 if (offset < 16)
125 /* low bank register */
126 val = inl(chip->base + reg);
127 else {
128 /* high bank register */
129 val = inl(chip->base + 0x80 + reg);
130 offset -= 16;
132 spin_unlock_irqrestore(&chip->lock, flags);
134 return (val & (1 << offset)) ? 1 : 0;
136 EXPORT_SYMBOL_GPL(cs5535_gpio_isset);
139 * Generic gpio_chip API support.
142 static int chip_gpio_request(struct gpio_chip *c, unsigned offset)
144 struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c;
145 unsigned long flags;
147 spin_lock_irqsave(&chip->lock, flags);
149 /* check if this pin is available */
150 if ((mask & (1 << offset)) == 0) {
151 dev_info(&chip->pdev->dev,
152 "pin %u is not available (check mask)\n", offset);
153 spin_unlock_irqrestore(&chip->lock, flags);
154 return -EINVAL;
157 /* disable output aux 1 & 2 on this pin */
158 __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_AUX1);
159 __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_AUX2);
161 /* disable input aux 1 on this pin */
162 __cs5535_gpio_clear(chip, offset, GPIO_INPUT_AUX1);
164 spin_unlock_irqrestore(&chip->lock, flags);
166 return 0;
169 static int chip_gpio_get(struct gpio_chip *chip, unsigned offset)
171 return cs5535_gpio_isset(offset, GPIO_READ_BACK);
174 static void chip_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
176 if (val)
177 cs5535_gpio_set(offset, GPIO_OUTPUT_VAL);
178 else
179 cs5535_gpio_clear(offset, GPIO_OUTPUT_VAL);
182 static int chip_direction_input(struct gpio_chip *c, unsigned offset)
184 struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c;
185 unsigned long flags;
187 spin_lock_irqsave(&chip->lock, flags);
188 __cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
189 __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_ENABLE);
190 spin_unlock_irqrestore(&chip->lock, flags);
192 return 0;
195 static int chip_direction_output(struct gpio_chip *c, unsigned offset, int val)
197 struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c;
198 unsigned long flags;
200 spin_lock_irqsave(&chip->lock, flags);
202 __cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
203 __cs5535_gpio_set(chip, offset, GPIO_OUTPUT_ENABLE);
204 if (val)
205 __cs5535_gpio_set(chip, offset, GPIO_OUTPUT_VAL);
206 else
207 __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_VAL);
209 spin_unlock_irqrestore(&chip->lock, flags);
211 return 0;
214 static const char * const cs5535_gpio_names[] = {
215 "GPIO0", "GPIO1", "GPIO2", "GPIO3",
216 "GPIO4", "GPIO5", "GPIO6", "GPIO7",
217 "GPIO8", "GPIO9", "GPIO10", "GPIO11",
218 "GPIO12", "GPIO13", "GPIO14", "GPIO15",
219 "GPIO16", "GPIO17", "GPIO18", "GPIO19",
220 "GPIO20", "GPIO21", "GPIO22", NULL,
221 "GPIO24", "GPIO25", "GPIO26", "GPIO27",
222 "GPIO28", NULL, NULL, NULL,
225 static struct cs5535_gpio_chip cs5535_gpio_chip = {
226 .chip = {
227 .owner = THIS_MODULE,
228 .label = DRV_NAME,
230 .base = 0,
231 .ngpio = 32,
232 .names = cs5535_gpio_names,
233 .request = chip_gpio_request,
235 .get = chip_gpio_get,
236 .set = chip_gpio_set,
238 .direction_input = chip_direction_input,
239 .direction_output = chip_direction_output,
243 static int __init cs5535_gpio_probe(struct pci_dev *pdev,
244 const struct pci_device_id *pci_id)
246 int err;
247 ulong mask_orig = mask;
249 /* There are two ways to get the GPIO base address; one is by
250 * fetching it from MSR_LBAR_GPIO, the other is by reading the
251 * PCI BAR info. The latter method is easier (especially across
252 * different architectures), so we'll stick with that for now. If
253 * it turns out to be unreliable in the face of crappy BIOSes, we
254 * can always go back to using MSRs.. */
256 err = pci_enable_device_io(pdev);
257 if (err) {
258 dev_err(&pdev->dev, "can't enable device IO\n");
259 goto done;
262 err = pci_request_region(pdev, GPIO_BAR, DRV_NAME);
263 if (err) {
264 dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", GPIO_BAR);
265 goto done;
268 /* set up the driver-specific struct */
269 cs5535_gpio_chip.base = pci_resource_start(pdev, GPIO_BAR);
270 cs5535_gpio_chip.pdev = pdev;
271 spin_lock_init(&cs5535_gpio_chip.lock);
273 dev_info(&pdev->dev, "allocated PCI BAR #%d: base 0x%llx\n", GPIO_BAR,
274 (unsigned long long) cs5535_gpio_chip.base);
276 /* mask out reserved pins */
277 mask &= 0x1F7FFFFF;
279 /* do not allow pin 28, Power Button, as there's special handling
280 * in the PMC needed. (note 12, p. 48) */
281 mask &= ~(1 << 28);
283 if (mask_orig != mask)
284 dev_info(&pdev->dev, "mask changed from 0x%08lX to 0x%08lX\n",
285 mask_orig, mask);
287 /* finally, register with the generic GPIO API */
288 err = gpiochip_add(&cs5535_gpio_chip.chip);
289 if (err)
290 goto release_region;
292 dev_info(&pdev->dev, DRV_NAME ": GPIO support successfully loaded.\n");
293 return 0;
295 release_region:
296 pci_release_region(pdev, GPIO_BAR);
297 done:
298 return err;
301 static void __exit cs5535_gpio_remove(struct pci_dev *pdev)
303 int err;
305 err = gpiochip_remove(&cs5535_gpio_chip.chip);
306 if (err) {
307 /* uhh? */
308 dev_err(&pdev->dev, "unable to remove gpio_chip?\n");
310 pci_release_region(pdev, GPIO_BAR);
313 static struct pci_device_id cs5535_gpio_pci_tbl[] = {
314 { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) },
315 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) },
316 { 0, },
318 MODULE_DEVICE_TABLE(pci, cs5535_gpio_pci_tbl);
321 * We can't use the standard PCI driver registration stuff here, since
322 * that allows only one driver to bind to each PCI device (and we want
323 * multiple drivers to be able to bind to the device). Instead, manually
324 * scan for the PCI device, request a single region, and keep track of the
325 * devices that we're using.
328 static int __init cs5535_gpio_scan_pci(void)
330 struct pci_dev *pdev;
331 int err = -ENODEV;
332 int i;
334 for (i = 0; i < ARRAY_SIZE(cs5535_gpio_pci_tbl); i++) {
335 pdev = pci_get_device(cs5535_gpio_pci_tbl[i].vendor,
336 cs5535_gpio_pci_tbl[i].device, NULL);
337 if (pdev) {
338 err = cs5535_gpio_probe(pdev, &cs5535_gpio_pci_tbl[i]);
339 if (err)
340 pci_dev_put(pdev);
342 /* we only support a single CS5535/6 southbridge */
343 break;
347 return err;
350 static void __exit cs5535_gpio_free_pci(void)
352 cs5535_gpio_remove(cs5535_gpio_chip.pdev);
353 pci_dev_put(cs5535_gpio_chip.pdev);
356 static int __init cs5535_gpio_init(void)
358 return cs5535_gpio_scan_pci();
361 static void __exit cs5535_gpio_exit(void)
363 cs5535_gpio_free_pci();
366 module_init(cs5535_gpio_init);
367 module_exit(cs5535_gpio_exit);
369 MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>");
370 MODULE_DESCRIPTION("AMD CS5535/CS5536 GPIO driver");
371 MODULE_LICENSE("GPL");