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/platform_device.h>
15 #include <linux/gpio.h>
17 #include <linux/cs5535.h>
20 #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.");
46 * FIXME: convert this singleton driver to use the state container
47 * design pattern, see Documentation/driver-model/design-patterns.txt
49 static struct cs5535_gpio_chip
{
50 struct gpio_chip chip
;
53 struct platform_device
*pdev
;
58 * The CS5535/CS5536 GPIOs support a number of extra features not defined
59 * by the gpio_chip API, so these are exported. For a full list of the
60 * registers, see include/linux/cs5535.h.
63 static void errata_outl(struct cs5535_gpio_chip
*chip
, u32 val
,
66 unsigned long addr
= chip
->base
+ 0x80 + reg
;
69 * According to the CS5536 errata (#36), after suspend
70 * a write to the high bank GPIO register will clear all
71 * non-selected bits; the recommended workaround is a
72 * read-modify-write operation.
74 * Don't apply this errata to the edge status GPIOs, as writing
75 * to their lower bits will clear them.
77 if (reg
!= GPIO_POSITIVE_EDGE_STS
&& reg
!= GPIO_NEGATIVE_EDGE_STS
) {
79 val
|= (inl(addr
) & 0xffff); /* ignore the high bits */
81 val
|= (inl(addr
) ^ (val
>> 16));
86 static void __cs5535_gpio_set(struct cs5535_gpio_chip
*chip
, unsigned offset
,
90 /* low bank register */
91 outl(1 << offset
, chip
->base
+ reg
);
93 /* high bank register */
94 errata_outl(chip
, 1 << (offset
- 16), reg
);
97 void cs5535_gpio_set(unsigned offset
, unsigned int reg
)
99 struct cs5535_gpio_chip
*chip
= &cs5535_gpio_chip
;
102 spin_lock_irqsave(&chip
->lock
, flags
);
103 __cs5535_gpio_set(chip
, offset
, reg
);
104 spin_unlock_irqrestore(&chip
->lock
, flags
);
106 EXPORT_SYMBOL_GPL(cs5535_gpio_set
);
108 static void __cs5535_gpio_clear(struct cs5535_gpio_chip
*chip
, unsigned offset
,
112 /* low bank register */
113 outl(1 << (offset
+ 16), chip
->base
+ reg
);
115 /* high bank register */
116 errata_outl(chip
, 1 << offset
, reg
);
119 void cs5535_gpio_clear(unsigned offset
, unsigned int reg
)
121 struct cs5535_gpio_chip
*chip
= &cs5535_gpio_chip
;
124 spin_lock_irqsave(&chip
->lock
, flags
);
125 __cs5535_gpio_clear(chip
, offset
, reg
);
126 spin_unlock_irqrestore(&chip
->lock
, flags
);
128 EXPORT_SYMBOL_GPL(cs5535_gpio_clear
);
130 int cs5535_gpio_isset(unsigned offset
, unsigned int reg
)
132 struct cs5535_gpio_chip
*chip
= &cs5535_gpio_chip
;
136 spin_lock_irqsave(&chip
->lock
, flags
);
138 /* low bank register */
139 val
= inl(chip
->base
+ reg
);
141 /* high bank register */
142 val
= inl(chip
->base
+ 0x80 + reg
);
145 spin_unlock_irqrestore(&chip
->lock
, flags
);
147 return (val
& (1 << offset
)) ? 1 : 0;
149 EXPORT_SYMBOL_GPL(cs5535_gpio_isset
);
151 int cs5535_gpio_set_irq(unsigned group
, unsigned irq
)
155 if (group
> 7 || irq
> 15)
158 rdmsr(MSR_PIC_ZSEL_HIGH
, lo
, hi
);
160 lo
&= ~(0xF << (group
* 4));
161 lo
|= (irq
& 0xF) << (group
* 4);
163 wrmsr(MSR_PIC_ZSEL_HIGH
, lo
, hi
);
166 EXPORT_SYMBOL_GPL(cs5535_gpio_set_irq
);
168 void cs5535_gpio_setup_event(unsigned offset
, int pair
, int pme
)
170 struct cs5535_gpio_chip
*chip
= &cs5535_gpio_chip
;
171 uint32_t shift
= (offset
% 8) * 4;
177 else if (offset
>= 16)
179 else if (offset
>= 8)
184 spin_lock_irqsave(&chip
->lock
, flags
);
185 val
= inl(chip
->base
+ offset
);
187 /* Clear whatever was there before */
188 val
&= ~(0xF << shift
);
190 /* Set the new value */
191 val
|= ((pair
& 7) << shift
);
193 /* Set the PME bit if this is a PME event */
195 val
|= (1 << (shift
+ 3));
197 outl(val
, chip
->base
+ offset
);
198 spin_unlock_irqrestore(&chip
->lock
, flags
);
200 EXPORT_SYMBOL_GPL(cs5535_gpio_setup_event
);
203 * Generic gpio_chip API support.
206 static int chip_gpio_request(struct gpio_chip
*c
, unsigned offset
)
208 struct cs5535_gpio_chip
*chip
= gpiochip_get_data(c
);
211 spin_lock_irqsave(&chip
->lock
, flags
);
213 /* check if this pin is available */
214 if ((mask
& (1 << offset
)) == 0) {
215 dev_info(&chip
->pdev
->dev
,
216 "pin %u is not available (check mask)\n", offset
);
217 spin_unlock_irqrestore(&chip
->lock
, flags
);
221 /* disable output aux 1 & 2 on this pin */
222 __cs5535_gpio_clear(chip
, offset
, GPIO_OUTPUT_AUX1
);
223 __cs5535_gpio_clear(chip
, offset
, GPIO_OUTPUT_AUX2
);
225 /* disable input aux 1 on this pin */
226 __cs5535_gpio_clear(chip
, offset
, GPIO_INPUT_AUX1
);
228 spin_unlock_irqrestore(&chip
->lock
, flags
);
233 static int chip_gpio_get(struct gpio_chip
*chip
, unsigned offset
)
235 return cs5535_gpio_isset(offset
, GPIO_READ_BACK
);
238 static void chip_gpio_set(struct gpio_chip
*chip
, unsigned offset
, int val
)
241 cs5535_gpio_set(offset
, GPIO_OUTPUT_VAL
);
243 cs5535_gpio_clear(offset
, GPIO_OUTPUT_VAL
);
246 static int chip_direction_input(struct gpio_chip
*c
, unsigned offset
)
248 struct cs5535_gpio_chip
*chip
= gpiochip_get_data(c
);
251 spin_lock_irqsave(&chip
->lock
, flags
);
252 __cs5535_gpio_set(chip
, offset
, GPIO_INPUT_ENABLE
);
253 __cs5535_gpio_clear(chip
, offset
, GPIO_OUTPUT_ENABLE
);
254 spin_unlock_irqrestore(&chip
->lock
, flags
);
259 static int chip_direction_output(struct gpio_chip
*c
, unsigned offset
, int val
)
261 struct cs5535_gpio_chip
*chip
= gpiochip_get_data(c
);
264 spin_lock_irqsave(&chip
->lock
, flags
);
266 __cs5535_gpio_set(chip
, offset
, GPIO_INPUT_ENABLE
);
267 __cs5535_gpio_set(chip
, offset
, GPIO_OUTPUT_ENABLE
);
269 __cs5535_gpio_set(chip
, offset
, GPIO_OUTPUT_VAL
);
271 __cs5535_gpio_clear(chip
, offset
, GPIO_OUTPUT_VAL
);
273 spin_unlock_irqrestore(&chip
->lock
, flags
);
278 static const char * const cs5535_gpio_names
[] = {
279 "GPIO0", "GPIO1", "GPIO2", "GPIO3",
280 "GPIO4", "GPIO5", "GPIO6", "GPIO7",
281 "GPIO8", "GPIO9", "GPIO10", "GPIO11",
282 "GPIO12", "GPIO13", "GPIO14", "GPIO15",
283 "GPIO16", "GPIO17", "GPIO18", "GPIO19",
284 "GPIO20", "GPIO21", "GPIO22", NULL
,
285 "GPIO24", "GPIO25", "GPIO26", "GPIO27",
286 "GPIO28", NULL
, NULL
, NULL
,
289 static struct cs5535_gpio_chip cs5535_gpio_chip
= {
291 .owner
= THIS_MODULE
,
296 .names
= cs5535_gpio_names
,
297 .request
= chip_gpio_request
,
299 .get
= chip_gpio_get
,
300 .set
= chip_gpio_set
,
302 .direction_input
= chip_direction_input
,
303 .direction_output
= chip_direction_output
,
307 static int cs5535_gpio_probe(struct platform_device
*pdev
)
309 struct resource
*res
;
311 ulong mask_orig
= mask
;
313 /* There are two ways to get the GPIO base address; one is by
314 * fetching it from MSR_LBAR_GPIO, the other is by reading the
315 * PCI BAR info. The latter method is easier (especially across
316 * different architectures), so we'll stick with that for now. If
317 * it turns out to be unreliable in the face of crappy BIOSes, we
318 * can always go back to using MSRs.. */
320 res
= platform_get_resource(pdev
, IORESOURCE_IO
, 0);
322 dev_err(&pdev
->dev
, "can't fetch device resource info\n");
326 if (!devm_request_region(&pdev
->dev
, res
->start
, resource_size(res
),
328 dev_err(&pdev
->dev
, "can't request region\n");
332 /* set up the driver-specific struct */
333 cs5535_gpio_chip
.base
= res
->start
;
334 cs5535_gpio_chip
.pdev
= pdev
;
335 spin_lock_init(&cs5535_gpio_chip
.lock
);
337 dev_info(&pdev
->dev
, "reserved resource region %pR\n", res
);
339 /* mask out reserved pins */
342 /* do not allow pin 28, Power Button, as there's special handling
343 * in the PMC needed. (note 12, p. 48) */
346 if (mask_orig
!= mask
)
347 dev_info(&pdev
->dev
, "mask changed from 0x%08lX to 0x%08lX\n",
350 /* finally, register with the generic GPIO API */
351 err
= devm_gpiochip_add_data(&pdev
->dev
, &cs5535_gpio_chip
.chip
,
359 static struct platform_driver cs5535_gpio_driver
= {
363 .probe
= cs5535_gpio_probe
,
366 module_platform_driver(cs5535_gpio_driver
);
368 MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>");
369 MODULE_DESCRIPTION("AMD CS5535/CS5536 GPIO driver");
370 MODULE_LICENSE("GPL");
371 MODULE_ALIAS("platform:" DRV_NAME
);