xref: /openbmc/linux/drivers/gpio/gpio-cs5535.c (revision 0da85d1e)
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/platform_device.h>
15 #include <linux/gpio.h>
16 #include <linux/io.h>
17 #include <linux/cs5535.h>
18 #include <asm/msr.h>
19 
20 #define DRV_NAME "cs5535-gpio"
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 platform_device *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 errata_outl(struct cs5535_gpio_chip *chip, u32 val,
60 		unsigned int reg)
61 {
62 	unsigned long addr = chip->base + 0x80 + reg;
63 
64 	/*
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.
69 	 *
70 	 * Don't apply this errata to the edge status GPIOs, as writing
71 	 * to their lower bits will clear them.
72 	 */
73 	if (reg != GPIO_POSITIVE_EDGE_STS && reg != GPIO_NEGATIVE_EDGE_STS) {
74 		if (val & 0xffff)
75 			val |= (inl(addr) & 0xffff); /* ignore the high bits */
76 		else
77 			val |= (inl(addr) ^ (val >> 16));
78 	}
79 	outl(val, addr);
80 }
81 
82 static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset,
83 		unsigned int reg)
84 {
85 	if (offset < 16)
86 		/* low bank register */
87 		outl(1 << offset, chip->base + reg);
88 	else
89 		/* high bank register */
90 		errata_outl(chip, 1 << (offset - 16), reg);
91 }
92 
93 void cs5535_gpio_set(unsigned offset, unsigned int reg)
94 {
95 	struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
96 	unsigned long flags;
97 
98 	spin_lock_irqsave(&chip->lock, flags);
99 	__cs5535_gpio_set(chip, offset, reg);
100 	spin_unlock_irqrestore(&chip->lock, flags);
101 }
102 EXPORT_SYMBOL_GPL(cs5535_gpio_set);
103 
104 static void __cs5535_gpio_clear(struct cs5535_gpio_chip *chip, unsigned offset,
105 		unsigned int reg)
106 {
107 	if (offset < 16)
108 		/* low bank register */
109 		outl(1 << (offset + 16), chip->base + reg);
110 	else
111 		/* high bank register */
112 		errata_outl(chip, 1 << offset, reg);
113 }
114 
115 void cs5535_gpio_clear(unsigned offset, unsigned int reg)
116 {
117 	struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
118 	unsigned long flags;
119 
120 	spin_lock_irqsave(&chip->lock, flags);
121 	__cs5535_gpio_clear(chip, offset, reg);
122 	spin_unlock_irqrestore(&chip->lock, flags);
123 }
124 EXPORT_SYMBOL_GPL(cs5535_gpio_clear);
125 
126 int cs5535_gpio_isset(unsigned offset, unsigned int reg)
127 {
128 	struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
129 	unsigned long flags;
130 	long val;
131 
132 	spin_lock_irqsave(&chip->lock, flags);
133 	if (offset < 16)
134 		/* low bank register */
135 		val = inl(chip->base + reg);
136 	else {
137 		/* high bank register */
138 		val = inl(chip->base + 0x80 + reg);
139 		offset -= 16;
140 	}
141 	spin_unlock_irqrestore(&chip->lock, flags);
142 
143 	return (val & (1 << offset)) ? 1 : 0;
144 }
145 EXPORT_SYMBOL_GPL(cs5535_gpio_isset);
146 
147 int cs5535_gpio_set_irq(unsigned group, unsigned irq)
148 {
149 	uint32_t lo, hi;
150 
151 	if (group > 7 || irq > 15)
152 		return -EINVAL;
153 
154 	rdmsr(MSR_PIC_ZSEL_HIGH, lo, hi);
155 
156 	lo &= ~(0xF << (group * 4));
157 	lo |= (irq & 0xF) << (group * 4);
158 
159 	wrmsr(MSR_PIC_ZSEL_HIGH, lo, hi);
160 	return 0;
161 }
162 EXPORT_SYMBOL_GPL(cs5535_gpio_set_irq);
163 
164 void cs5535_gpio_setup_event(unsigned offset, int pair, int pme)
165 {
166 	struct cs5535_gpio_chip *chip = &cs5535_gpio_chip;
167 	uint32_t shift = (offset % 8) * 4;
168 	unsigned long flags;
169 	uint32_t val;
170 
171 	if (offset >= 24)
172 		offset = GPIO_MAP_W;
173 	else if (offset >= 16)
174 		offset = GPIO_MAP_Z;
175 	else if (offset >= 8)
176 		offset = GPIO_MAP_Y;
177 	else
178 		offset = GPIO_MAP_X;
179 
180 	spin_lock_irqsave(&chip->lock, flags);
181 	val = inl(chip->base + offset);
182 
183 	/* Clear whatever was there before */
184 	val &= ~(0xF << shift);
185 
186 	/* Set the new value */
187 	val |= ((pair & 7) << shift);
188 
189 	/* Set the PME bit if this is a PME event */
190 	if (pme)
191 		val |= (1 << (shift + 3));
192 
193 	outl(val, chip->base + offset);
194 	spin_unlock_irqrestore(&chip->lock, flags);
195 }
196 EXPORT_SYMBOL_GPL(cs5535_gpio_setup_event);
197 
198 /*
199  * Generic gpio_chip API support.
200  */
201 
202 static int chip_gpio_request(struct gpio_chip *c, unsigned offset)
203 {
204 	struct cs5535_gpio_chip *chip =
205 		container_of(c, struct cs5535_gpio_chip, chip);
206 	unsigned long flags;
207 
208 	spin_lock_irqsave(&chip->lock, flags);
209 
210 	/* check if this pin is available */
211 	if ((mask & (1 << offset)) == 0) {
212 		dev_info(&chip->pdev->dev,
213 			"pin %u is not available (check mask)\n", offset);
214 		spin_unlock_irqrestore(&chip->lock, flags);
215 		return -EINVAL;
216 	}
217 
218 	/* disable output aux 1 & 2 on this pin */
219 	__cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_AUX1);
220 	__cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_AUX2);
221 
222 	/* disable input aux 1 on this pin */
223 	__cs5535_gpio_clear(chip, offset, GPIO_INPUT_AUX1);
224 
225 	spin_unlock_irqrestore(&chip->lock, flags);
226 
227 	return 0;
228 }
229 
230 static int chip_gpio_get(struct gpio_chip *chip, unsigned offset)
231 {
232 	return cs5535_gpio_isset(offset, GPIO_READ_BACK);
233 }
234 
235 static void chip_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
236 {
237 	if (val)
238 		cs5535_gpio_set(offset, GPIO_OUTPUT_VAL);
239 	else
240 		cs5535_gpio_clear(offset, GPIO_OUTPUT_VAL);
241 }
242 
243 static int chip_direction_input(struct gpio_chip *c, unsigned offset)
244 {
245 	struct cs5535_gpio_chip *chip =
246 		container_of(c, struct cs5535_gpio_chip, chip);
247 	unsigned long flags;
248 
249 	spin_lock_irqsave(&chip->lock, flags);
250 	__cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
251 	__cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_ENABLE);
252 	spin_unlock_irqrestore(&chip->lock, flags);
253 
254 	return 0;
255 }
256 
257 static int chip_direction_output(struct gpio_chip *c, unsigned offset, int val)
258 {
259 	struct cs5535_gpio_chip *chip =
260 		container_of(c, struct cs5535_gpio_chip, chip);
261 	unsigned long flags;
262 
263 	spin_lock_irqsave(&chip->lock, flags);
264 
265 	__cs5535_gpio_set(chip, offset, GPIO_INPUT_ENABLE);
266 	__cs5535_gpio_set(chip, offset, GPIO_OUTPUT_ENABLE);
267 	if (val)
268 		__cs5535_gpio_set(chip, offset, GPIO_OUTPUT_VAL);
269 	else
270 		__cs5535_gpio_clear(chip, offset, GPIO_OUTPUT_VAL);
271 
272 	spin_unlock_irqrestore(&chip->lock, flags);
273 
274 	return 0;
275 }
276 
277 static const char * const cs5535_gpio_names[] = {
278 	"GPIO0", "GPIO1", "GPIO2", "GPIO3",
279 	"GPIO4", "GPIO5", "GPIO6", "GPIO7",
280 	"GPIO8", "GPIO9", "GPIO10", "GPIO11",
281 	"GPIO12", "GPIO13", "GPIO14", "GPIO15",
282 	"GPIO16", "GPIO17", "GPIO18", "GPIO19",
283 	"GPIO20", "GPIO21", "GPIO22", NULL,
284 	"GPIO24", "GPIO25", "GPIO26", "GPIO27",
285 	"GPIO28", NULL, NULL, NULL,
286 };
287 
288 static struct cs5535_gpio_chip cs5535_gpio_chip = {
289 	.chip = {
290 		.owner = THIS_MODULE,
291 		.label = DRV_NAME,
292 
293 		.base = 0,
294 		.ngpio = 32,
295 		.names = cs5535_gpio_names,
296 		.request = chip_gpio_request,
297 
298 		.get = chip_gpio_get,
299 		.set = chip_gpio_set,
300 
301 		.direction_input = chip_direction_input,
302 		.direction_output = chip_direction_output,
303 	},
304 };
305 
306 static int cs5535_gpio_probe(struct platform_device *pdev)
307 {
308 	struct resource *res;
309 	int err = -EIO;
310 	ulong mask_orig = mask;
311 
312 	/* There are two ways to get the GPIO base address; one is by
313 	 * fetching it from MSR_LBAR_GPIO, the other is by reading the
314 	 * PCI BAR info.  The latter method is easier (especially across
315 	 * different architectures), so we'll stick with that for now.  If
316 	 * it turns out to be unreliable in the face of crappy BIOSes, we
317 	 * can always go back to using MSRs.. */
318 
319 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
320 	if (!res) {
321 		dev_err(&pdev->dev, "can't fetch device resource info\n");
322 		goto done;
323 	}
324 
325 	if (!devm_request_region(&pdev->dev, res->start, resource_size(res),
326 				 pdev->name)) {
327 		dev_err(&pdev->dev, "can't request region\n");
328 		goto done;
329 	}
330 
331 	/* set up the driver-specific struct */
332 	cs5535_gpio_chip.base = res->start;
333 	cs5535_gpio_chip.pdev = pdev;
334 	spin_lock_init(&cs5535_gpio_chip.lock);
335 
336 	dev_info(&pdev->dev, "reserved resource region %pR\n", res);
337 
338 	/* mask out reserved pins */
339 	mask &= 0x1F7FFFFF;
340 
341 	/* do not allow pin 28, Power Button, as there's special handling
342 	 * in the PMC needed. (note 12, p. 48) */
343 	mask &= ~(1 << 28);
344 
345 	if (mask_orig != mask)
346 		dev_info(&pdev->dev, "mask changed from 0x%08lX to 0x%08lX\n",
347 				mask_orig, mask);
348 
349 	/* finally, register with the generic GPIO API */
350 	err = gpiochip_add(&cs5535_gpio_chip.chip);
351 	if (err)
352 		goto done;
353 
354 	return 0;
355 
356 done:
357 	return err;
358 }
359 
360 static int cs5535_gpio_remove(struct platform_device *pdev)
361 {
362 	gpiochip_remove(&cs5535_gpio_chip.chip);
363 
364 	return 0;
365 }
366 
367 static struct platform_driver cs5535_gpio_driver = {
368 	.driver = {
369 		.name = DRV_NAME,
370 	},
371 	.probe = cs5535_gpio_probe,
372 	.remove = cs5535_gpio_remove,
373 };
374 
375 module_platform_driver(cs5535_gpio_driver);
376 
377 MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>");
378 MODULE_DESCRIPTION("AMD CS5535/CS5536 GPIO driver");
379 MODULE_LICENSE("GPL");
380 MODULE_ALIAS("platform:" DRV_NAME);
381