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.
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>
17 #include <linux/cs5535.h>
19 #define DRV_NAME "cs5535-gpio"
24 * 31-29,23 : reserved (always mask out)
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;
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,
62 unsigned long addr = chip->base + 0x80 + reg;
65 * According to the CS5536 errata (#36), after suspend
66 * a write to the high bank GPIO register will clear all
67 * non-selected bits; the recommended workaround is a
68 * read-modify-write operation.
70 * Don't apply this errata to the edge status GPIOs, as writing
71 * to their lower bits will clear them.
73 if (reg != GPIO_POSITIVE_EDGE_STS && reg != GPIO_NEGATIVE_EDGE_STS)
78 static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset,
82 /* low bank register */
83 outl(1 << offset, chip->base + reg);
85 /* high bank register */
86 errata_outl(chip, 1 << (offset - 16), reg);
89 void cs5535_gpio_set(unsigned offset, unsigned int reg)
91 struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
94 spin_lock_irqsave(&chip->lock, flags);
95 __cs5535_gpio_set(chip, offset, reg);
96 spin_unlock_irqrestore(&chip->lock, flags);
98 EXPORT_SYMBOL_GPL(cs5535_gpio_set);
100 static void __cs5535_gpio_clear(struct cs5535_gpio_chip *chip, unsigned offset,
104 /* low bank register */
105 outl(1 << (offset + 16), chip->base + reg);
107 /* high bank register */
108 errata_outl(chip, 1 << offset, reg);
111 void cs5535_gpio_clear(unsigned offset, unsigned int reg)
113 struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
116 spin_lock_irqsave(&chip->lock, flags);
117 __cs5535_gpio_clear(chip, offset, reg);
118 spin_unlock_irqrestore(&chip->lock, flags);
120 EXPORT_SYMBOL_GPL(cs5535_gpio_clear);
122 int cs5535_gpio_isset(unsigned offset, unsigned int reg)
124 struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
128 spin_lock_irqsave(&chip->lock, flags);
130 /* low bank register */
131 val = inl(chip->base + reg);
133 /* high bank register */
134 val = inl(chip->base + 0x80 + reg);
137 spin_unlock_irqrestore(&chip->lock, flags);
139 return (val & (1 << offset)) ? 1 : 0;
141 EXPORT_SYMBOL_GPL(cs5535_gpio_isset);
144 * Generic gpio_chip API support.
147 static int chip_gpio_request(struct gpio_chip *c, unsigned offset)
149 struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c;
152 spin_lock_irqsave(&chip->lock, flags);
154 /* check if this pin is available */
155 if ((mask & (1 << offset)) == 0) {
156 dev_info(&chip->pdev->dev,
157 "pin %u is not available (check mask)\n", offset);
158 spin_unlock_irqrestore(&chip->lock, flags);
162 /* disable output aux 1 & 2 on this pin */
163 __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_AUX1);
164 __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_AUX2);
166 /* disable input aux 1 on this pin */
167 __cs5535_gpio_clear(chip, offset, GPIO_INPUT_AUX1);
169 spin_unlock_irqrestore(&chip->lock, flags);
174 static int chip_gpio_get(struct gpio_chip *chip, unsigned offset)
176 return cs5535_gpio_isset(offset, GPIO_READ_BACK);
179 static void chip_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
182 cs5535_gpio_set(offset, GPIO_OUTPUT_VAL);
184 cs5535_gpio_clear(offset, GPIO_OUTPUT_VAL);
187 static int chip_direction_input(struct gpio_chip *c, unsigned offset)
189 struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c;
192 spin_lock_irqsave(&chip->lock, flags);
193 __cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
194 __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_ENABLE);
195 spin_unlock_irqrestore(&chip->lock, flags);
200 static int chip_direction_output(struct gpio_chip *c, unsigned offset, int val)
202 struct cs5535_gpio_chip *chip = (struct cs5535_gpio_chip *) c;
205 spin_lock_irqsave(&chip->lock, flags);
207 __cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
208 __cs5535_gpio_set(chip, offset, GPIO_OUTPUT_ENABLE);
210 __cs5535_gpio_set(chip, offset, GPIO_OUTPUT_VAL);
212 __cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_VAL);
214 spin_unlock_irqrestore(&chip->lock, flags);
219 static const char * const cs5535_gpio_names[] = {
220 "GPIO0", "GPIO1", "GPIO2", "GPIO3",
221 "GPIO4", "GPIO5", "GPIO6", "GPIO7",
222 "GPIO8", "GPIO9", "GPIO10", "GPIO11",
223 "GPIO12", "GPIO13", "GPIO14", "GPIO15",
224 "GPIO16", "GPIO17", "GPIO18", "GPIO19",
225 "GPIO20", "GPIO21", "GPIO22", NULL,
226 "GPIO24", "GPIO25", "GPIO26", "GPIO27",
227 "GPIO28", NULL, NULL, NULL,
230 static struct cs5535_gpio_chip cs5535_gpio_chip = {
232 .owner = THIS_MODULE,
237 .names = cs5535_gpio_names,
238 .request = chip_gpio_request,
240 .get = chip_gpio_get,
241 .set = chip_gpio_set,
243 .direction_input = chip_direction_input,
244 .direction_output = chip_direction_output,
248 static int __init cs5535_gpio_probe(struct pci_dev *pdev,
249 const struct pci_device_id *pci_id)
252 ulong mask_orig = mask;
254 /* There are two ways to get the GPIO base address; one is by
255 * fetching it from MSR_LBAR_GPIO, the other is by reading the
256 * PCI BAR info. The latter method is easier (especially across
257 * different architectures), so we'll stick with that for now. If
258 * it turns out to be unreliable in the face of crappy BIOSes, we
259 * can always go back to using MSRs.. */
261 err = pci_enable_device_io(pdev);
263 dev_err(&pdev->dev, "can't enable device IO\n");
267 err = pci_request_region(pdev, GPIO_BAR, DRV_NAME);
269 dev_err(&pdev->dev, "can't alloc PCI BAR #%d\n", GPIO_BAR);
273 /* set up the driver-specific struct */
274 cs5535_gpio_chip.base = pci_resource_start(pdev, GPIO_BAR);
275 cs5535_gpio_chip.pdev = pdev;
276 spin_lock_init(&cs5535_gpio_chip.lock);
278 dev_info(&pdev->dev, "allocated PCI BAR #%d: base 0x%llx\n", GPIO_BAR,
279 (unsigned long long) cs5535_gpio_chip.base);
281 /* mask out reserved pins */
284 /* do not allow pin 28, Power Button, as there's special handling
285 * in the PMC needed. (note 12, p. 48) */
288 if (mask_orig != mask)
289 dev_info(&pdev->dev, "mask changed from 0x%08lX to 0x%08lX\n",
292 /* finally, register with the generic GPIO API */
293 err = gpiochip_add(&cs5535_gpio_chip.chip);
297 dev_info(&pdev->dev, DRV_NAME ": GPIO support successfully loaded.\n");
301 pci_release_region(pdev, GPIO_BAR);
306 static void __exit cs5535_gpio_remove(struct pci_dev *pdev)
310 err = gpiochip_remove(&cs5535_gpio_chip.chip);
313 dev_err(&pdev->dev, "unable to remove gpio_chip?\n");
315 pci_release_region(pdev, GPIO_BAR);
318 static struct pci_device_id cs5535_gpio_pci_tbl[] = {
319 { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) },
320 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) },
323 MODULE_DEVICE_TABLE(pci, cs5535_gpio_pci_tbl);
326 * We can't use the standard PCI driver registration stuff here, since
327 * that allows only one driver to bind to each PCI device (and we want
328 * multiple drivers to be able to bind to the device). Instead, manually
329 * scan for the PCI device, request a single region, and keep track of the
330 * devices that we're using.
333 static int __init cs5535_gpio_scan_pci(void)
335 struct pci_dev *pdev;
339 for (i = 0; i < ARRAY_SIZE(cs5535_gpio_pci_tbl); i++) {
340 pdev = pci_get_device(cs5535_gpio_pci_tbl[i].vendor,
341 cs5535_gpio_pci_tbl[i].device, NULL);
343 err = cs5535_gpio_probe(pdev, &cs5535_gpio_pci_tbl[i]);
347 /* we only support a single CS5535/6 southbridge */
355 static void __exit cs5535_gpio_free_pci(void)
357 cs5535_gpio_remove(cs5535_gpio_chip.pdev);
358 pci_dev_put(cs5535_gpio_chip.pdev);
361 static int __init cs5535_gpio_init(void)
363 return cs5535_gpio_scan_pci();
366 static void __exit cs5535_gpio_exit(void)
368 cs5535_gpio_free_pci();
371 module_init(cs5535_gpio_init);
372 module_exit(cs5535_gpio_exit);
374 MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>");
375 MODULE_DESCRIPTION("AMD CS5535/CS5536 GPIO driver");
376 MODULE_LICENSE("GPL");