aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio/gpio-viperboard.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-16 21:55:20 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-16 21:55:20 -0500
commit2dfea3803dcf70983d14ce1dcbb3e97a7459a28b (patch)
tree59bffc7389ff554585f79d7cc06021790dc2b317 /drivers/gpio/gpio-viperboard.c
parentaed606e3bc1f10753254db308d3fd8c053c41328 (diff)
parent1881b68b8961a86d40c3c5c205e533515a2dc9c6 (diff)
Merge tag 'mfd-3.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6
Pull MFS update from Samuel Ortiz: "This is the MFD patch set for the 3.8 merge window. We have several new drivers, most of the time coming with their sub devices drivers: - Austria Microsystem's AS3711 - Nano River's viperboard - TI's TPS80031, AM335x TS/ADC, - Realtek's MMC/memstick card reader - Nokia's retu We also got some notable cleanups and improvements: - tps6586x got converted to IRQ domains. - tps65910 and tps65090 moved to the regmap IRQ API. - STMPE is now Device Tree aware. - A general twl6040 and twl-core cleanup, with moves to the regmap I/O and IRQ APIs and a conversion to the recently added PWM framework. - sta2x11 gained regmap support. Then the rest is mostly tiny cleanups and fixes, among which we have Mark's wm5xxx and wm8xxx patchset." Far amount of annoying but largely trivial conflicts. Many due to __devinit/exit removal, others due to one or two of the new drivers also having come in through another tree. * tag 'mfd-3.8-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6: (119 commits) mfd: tps6507x: Convert to devm_kzalloc mfd: stmpe: Update DT support for stmpe driver mfd: wm5102: Add readback of DSP status 3 register mfd: arizona: Log if we fail to create the primary IRQ domain mfd: tps80031: MFD_TPS80031 needs to select REGMAP_IRQ mfd: tps80031: Add terminating entry for tps80031_id_table mfd: sta2x11: Fix potential NULL pointer dereference in __sta2x11_mfd_mask() mfd: wm5102: Add tuning for revision B mfd: arizona: Defer patch initialistation until after first device boot mfd: tps65910: Fix wrong ack_base register mfd: tps65910: Remove unused data mfd: stmpe: Get rid of irq_invert_polarity mfd: ab8500-core: Fix invalid free of devm_ allocated data mfd: wm5102: Mark DSP memory regions as volatile mfd: wm5102: Correct default for LDO1_CONTROL_2 mfd: arizona: Register haptics devices mfd: wm8994: Make current device behaviour the default mfd: tps65090: MFD_TPS65090 needs to select REGMAP_IRQ mfd: Fix stmpe.c build when OF is not enabled mfd: jz4740-adc: Use devm_kzalloc ...
Diffstat (limited to 'drivers/gpio/gpio-viperboard.c')
-rw-r--r--drivers/gpio/gpio-viperboard.c517
1 files changed, 517 insertions, 0 deletions
diff --git a/drivers/gpio/gpio-viperboard.c b/drivers/gpio/gpio-viperboard.c
new file mode 100644
index 00000000000..13772996cf2
--- /dev/null
+++ b/drivers/gpio/gpio-viperboard.c
@@ -0,0 +1,517 @@
1/*
2 * Nano River Technologies viperboard GPIO lib driver
3 *
4 * (C) 2012 by Lemonage GmbH
5 * Author: Lars Poeschel <poeschel@lemonage.de>
6 * All rights reserved.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/errno.h>
17#include <linux/module.h>
18#include <linux/slab.h>
19#include <linux/types.h>
20#include <linux/mutex.h>
21#include <linux/platform_device.h>
22
23#include <linux/usb.h>
24#include <linux/gpio.h>
25
26#include <linux/mfd/viperboard.h>
27
28#define VPRBRD_GPIOA_CLK_1MHZ 0
29#define VPRBRD_GPIOA_CLK_100KHZ 1
30#define VPRBRD_GPIOA_CLK_10KHZ 2
31#define VPRBRD_GPIOA_CLK_1KHZ 3
32#define VPRBRD_GPIOA_CLK_100HZ 4
33#define VPRBRD_GPIOA_CLK_10HZ 5
34
35#define VPRBRD_GPIOA_FREQ_DEFAULT 1000
36
37#define VPRBRD_GPIOA_CMD_CONT 0x00
38#define VPRBRD_GPIOA_CMD_PULSE 0x01
39#define VPRBRD_GPIOA_CMD_PWM 0x02
40#define VPRBRD_GPIOA_CMD_SETOUT 0x03
41#define VPRBRD_GPIOA_CMD_SETIN 0x04
42#define VPRBRD_GPIOA_CMD_SETINT 0x05
43#define VPRBRD_GPIOA_CMD_GETIN 0x06
44
45#define VPRBRD_GPIOB_CMD_SETDIR 0x00
46#define VPRBRD_GPIOB_CMD_SETVAL 0x01
47
48struct vprbrd_gpioa_msg {
49 u8 cmd;
50 u8 clk;
51 u8 offset;
52 u8 t1;
53 u8 t2;
54 u8 invert;
55 u8 pwmlevel;
56 u8 outval;
57 u8 risefall;
58 u8 answer;
59 u8 __fill;
60} __packed;
61
62struct vprbrd_gpiob_msg {
63 u8 cmd;
64 u16 val;
65 u16 mask;
66} __packed;
67
68struct vprbrd_gpio {
69 struct gpio_chip gpioa; /* gpio a related things */
70 u32 gpioa_out;
71 u32 gpioa_val;
72 struct gpio_chip gpiob; /* gpio b related things */
73 u32 gpiob_out;
74 u32 gpiob_val;
75 struct vprbrd *vb;
76};
77
78/* gpioa sampling clock module parameter */
79static unsigned char gpioa_clk;
80static unsigned int gpioa_freq = VPRBRD_GPIOA_FREQ_DEFAULT;
81module_param(gpioa_freq, uint, 0);
82MODULE_PARM_DESC(gpioa_freq,
83 "gpio-a sampling freq in Hz (default is 1000Hz) valid values: 10, 100, 1000, 10000, 100000, 1000000");
84
85/* ----- begin of gipo a chip -------------------------------------------- */
86
87static int vprbrd_gpioa_get(struct gpio_chip *chip,
88 unsigned offset)
89{
90 int ret, answer, error = 0;
91 struct vprbrd_gpio *gpio =
92 container_of(chip, struct vprbrd_gpio, gpioa);
93 struct vprbrd *vb = gpio->vb;
94 struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf;
95
96 /* if io is set to output, just return the saved value */
97 if (gpio->gpioa_out & (1 << offset))
98 return gpio->gpioa_val & (1 << offset);
99
100 mutex_lock(&vb->lock);
101
102 gamsg->cmd = VPRBRD_GPIOA_CMD_GETIN;
103 gamsg->clk = 0x00;
104 gamsg->offset = offset;
105 gamsg->t1 = 0x00;
106 gamsg->t2 = 0x00;
107 gamsg->invert = 0x00;
108 gamsg->pwmlevel = 0x00;
109 gamsg->outval = 0x00;
110 gamsg->risefall = 0x00;
111 gamsg->answer = 0x00;
112 gamsg->__fill = 0x00;
113
114 ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0),
115 VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT, 0x0000,
116 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg),
117 VPRBRD_USB_TIMEOUT_MS);
118 if (ret != sizeof(struct vprbrd_gpioa_msg))
119 error = -EREMOTEIO;
120
121 ret = usb_control_msg(vb->usb_dev, usb_rcvctrlpipe(vb->usb_dev, 0),
122 VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_IN, 0x0000,
123 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg),
124 VPRBRD_USB_TIMEOUT_MS);
125 answer = gamsg->answer & 0x01;
126
127 mutex_unlock(&vb->lock);
128
129 if (ret != sizeof(struct vprbrd_gpioa_msg))
130 error = -EREMOTEIO;
131
132 if (error)
133 return error;
134
135 return answer;
136}
137
138static void vprbrd_gpioa_set(struct gpio_chip *chip,
139 unsigned offset, int value)
140{
141 int ret;
142 struct vprbrd_gpio *gpio =
143 container_of(chip, struct vprbrd_gpio, gpioa);
144 struct vprbrd *vb = gpio->vb;
145 struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf;
146
147 if (gpio->gpioa_out & (1 << offset)) {
148 if (value)
149 gpio->gpioa_val |= (1 << offset);
150 else
151 gpio->gpioa_val &= ~(1 << offset);
152
153 mutex_lock(&vb->lock);
154
155 gamsg->cmd = VPRBRD_GPIOA_CMD_SETOUT;
156 gamsg->clk = 0x00;
157 gamsg->offset = offset;
158 gamsg->t1 = 0x00;
159 gamsg->t2 = 0x00;
160 gamsg->invert = 0x00;
161 gamsg->pwmlevel = 0x00;
162 gamsg->outval = value;
163 gamsg->risefall = 0x00;
164 gamsg->answer = 0x00;
165 gamsg->__fill = 0x00;
166
167 ret = usb_control_msg(vb->usb_dev,
168 usb_sndctrlpipe(vb->usb_dev, 0),
169 VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT,
170 0x0000, 0x0000, gamsg,
171 sizeof(struct vprbrd_gpioa_msg), VPRBRD_USB_TIMEOUT_MS);
172
173 mutex_unlock(&vb->lock);
174
175 if (ret != sizeof(struct vprbrd_gpioa_msg))
176 dev_err(chip->dev, "usb error setting pin value\n");
177 }
178}
179
180static int vprbrd_gpioa_direction_input(struct gpio_chip *chip,
181 unsigned offset)
182{
183 int ret;
184 struct vprbrd_gpio *gpio =
185 container_of(chip, struct vprbrd_gpio, gpioa);
186 struct vprbrd *vb = gpio->vb;
187 struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf;
188
189 gpio->gpioa_out &= ~(1 << offset);
190
191 mutex_lock(&vb->lock);
192
193 gamsg->cmd = VPRBRD_GPIOA_CMD_SETIN;
194 gamsg->clk = gpioa_clk;
195 gamsg->offset = offset;
196 gamsg->t1 = 0x00;
197 gamsg->t2 = 0x00;
198 gamsg->invert = 0x00;
199 gamsg->pwmlevel = 0x00;
200 gamsg->outval = 0x00;
201 gamsg->risefall = 0x00;
202 gamsg->answer = 0x00;
203 gamsg->__fill = 0x00;
204
205 ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0),
206 VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT, 0x0000,
207 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg),
208 VPRBRD_USB_TIMEOUT_MS);
209
210 mutex_unlock(&vb->lock);
211
212 if (ret != sizeof(struct vprbrd_gpioa_msg))
213 return -EREMOTEIO;
214
215 return 0;
216}
217
218static int vprbrd_gpioa_direction_output(struct gpio_chip *chip,
219 unsigned offset, int value)
220{
221 int ret;
222 struct vprbrd_gpio *gpio =
223 container_of(chip, struct vprbrd_gpio, gpioa);
224 struct vprbrd *vb = gpio->vb;
225 struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf;
226
227 gpio->gpioa_out |= (1 << offset);
228 if (value)
229 gpio->gpioa_val |= (1 << offset);
230 else
231 gpio->gpioa_val &= ~(1 << offset);
232
233 mutex_lock(&vb->lock);
234
235 gamsg->cmd = VPRBRD_GPIOA_CMD_SETOUT;
236 gamsg->clk = 0x00;
237 gamsg->offset = offset;
238 gamsg->t1 = 0x00;
239 gamsg->t2 = 0x00;
240 gamsg->invert = 0x00;
241 gamsg->pwmlevel = 0x00;
242 gamsg->outval = value;
243 gamsg->risefall = 0x00;
244 gamsg->answer = 0x00;
245 gamsg->__fill = 0x00;
246
247 ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0),
248 VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT, 0x0000,
249 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg),
250 VPRBRD_USB_TIMEOUT_MS);
251
252 mutex_unlock(&vb->lock);
253
254 if (ret != sizeof(struct vprbrd_gpioa_msg))
255 return -EREMOTEIO;
256
257 return 0;
258}
259
260/* ----- end of gpio a chip ---------------------------------------------- */
261
262/* ----- begin of gipo b chip -------------------------------------------- */
263
264static int vprbrd_gpiob_setdir(struct vprbrd *vb, unsigned offset,
265 unsigned dir)
266{
267 struct vprbrd_gpiob_msg *gbmsg = (struct vprbrd_gpiob_msg *)vb->buf;
268 int ret;
269
270 gbmsg->cmd = VPRBRD_GPIOB_CMD_SETDIR;
271 gbmsg->val = cpu_to_be16(dir << offset);
272 gbmsg->mask = cpu_to_be16(0x0001 << offset);
273
274 ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0),
275 VPRBRD_USB_REQUEST_GPIOB, VPRBRD_USB_TYPE_OUT, 0x0000,
276 0x0000, gbmsg, sizeof(struct vprbrd_gpiob_msg),
277 VPRBRD_USB_TIMEOUT_MS);
278
279 if (ret != sizeof(struct vprbrd_gpiob_msg))
280 return -EREMOTEIO;
281
282 return 0;
283}
284
285static int vprbrd_gpiob_get(struct gpio_chip *chip,
286 unsigned offset)
287{
288 int ret;
289 u16 val;
290 struct vprbrd_gpio *gpio =
291 container_of(chip, struct vprbrd_gpio, gpiob);
292 struct vprbrd *vb = gpio->vb;
293 struct vprbrd_gpiob_msg *gbmsg = (struct vprbrd_gpiob_msg *)vb->buf;
294
295 /* if io is set to output, just return the saved value */
296 if (gpio->gpiob_out & (1 << offset))
297 return gpio->gpiob_val & (1 << offset);
298
299 mutex_lock(&vb->lock);
300
301 ret = usb_control_msg(vb->usb_dev, usb_rcvctrlpipe(vb->usb_dev, 0),
302 VPRBRD_USB_REQUEST_GPIOB, VPRBRD_USB_TYPE_IN, 0x0000,
303 0x0000, gbmsg, sizeof(struct vprbrd_gpiob_msg),
304 VPRBRD_USB_TIMEOUT_MS);
305 val = gbmsg->val;
306
307 mutex_unlock(&vb->lock);
308
309 if (ret != sizeof(struct vprbrd_gpiob_msg))
310 return ret;
311
312 /* cache the read values */
313 gpio->gpiob_val = be16_to_cpu(val);
314
315 return (gpio->gpiob_val >> offset) & 0x1;
316}
317
318static void vprbrd_gpiob_set(struct gpio_chip *chip,
319 unsigned offset, int value)
320{
321 int ret;
322 struct vprbrd_gpio *gpio =
323 container_of(chip, struct vprbrd_gpio, gpiob);
324 struct vprbrd *vb = gpio->vb;
325 struct vprbrd_gpiob_msg *gbmsg = (struct vprbrd_gpiob_msg *)vb->buf;
326
327 if (gpio->gpiob_out & (1 << offset)) {
328 if (value)
329 gpio->gpiob_val |= (1 << offset);
330 else
331 gpio->gpiob_val &= ~(1 << offset);
332
333 mutex_lock(&vb->lock);
334
335 gbmsg->cmd = VPRBRD_GPIOB_CMD_SETVAL;
336 gbmsg->val = cpu_to_be16(value << offset);
337 gbmsg->mask = cpu_to_be16(0x0001 << offset);
338
339 ret = usb_control_msg(vb->usb_dev,
340 usb_sndctrlpipe(vb->usb_dev, 0),
341 VPRBRD_USB_REQUEST_GPIOB, VPRBRD_USB_TYPE_OUT,
342 0x0000, 0x0000, gbmsg,
343 sizeof(struct vprbrd_gpiob_msg), VPRBRD_USB_TIMEOUT_MS);
344
345 mutex_unlock(&vb->lock);
346
347 if (ret != sizeof(struct vprbrd_gpiob_msg))
348 dev_err(chip->dev, "usb error setting pin value\n");
349 }
350}
351
352static int vprbrd_gpiob_direction_input(struct gpio_chip *chip,
353 unsigned offset)
354{
355 int ret;
356 struct vprbrd_gpio *gpio =
357 container_of(chip, struct vprbrd_gpio, gpiob);
358 struct vprbrd *vb = gpio->vb;
359
360 gpio->gpiob_out &= ~(1 << offset);
361
362 mutex_lock(&vb->lock);
363
364 ret = vprbrd_gpiob_setdir(vb, offset, 0);
365
366 mutex_unlock(&vb->lock);
367
368 if (ret)
369 dev_err(chip->dev, "usb error setting pin to input\n");
370
371 return ret;
372}
373
374static int vprbrd_gpiob_direction_output(struct gpio_chip *chip,
375 unsigned offset, int value)
376{
377 int ret;
378 struct vprbrd_gpio *gpio =
379 container_of(chip, struct vprbrd_gpio, gpiob);
380 struct vprbrd *vb = gpio->vb;
381
382 gpio->gpiob_out |= (1 << offset);
383 if (value)
384 gpio->gpiob_val |= (1 << offset);
385 else
386 gpio->gpiob_val &= ~(1 << offset);
387
388 mutex_lock(&vb->lock);
389
390 ret = vprbrd_gpiob_setdir(vb, offset, 1);
391 if (ret)
392 dev_err(chip->dev, "usb error setting pin to output\n");
393
394 mutex_unlock(&vb->lock);
395
396 vprbrd_gpiob_set(chip, offset, value);
397
398 return ret;
399}
400
401/* ----- end of gpio b chip ---------------------------------------------- */
402
403static int __devinit vprbrd_gpio_probe(struct platform_device *pdev)
404{
405 struct vprbrd *vb = dev_get_drvdata(pdev->dev.parent);
406 struct vprbrd_gpio *vb_gpio;
407 int ret;
408
409 vb_gpio = devm_kzalloc(&pdev->dev, sizeof(*vb_gpio), GFP_KERNEL);
410 if (vb_gpio == NULL)
411 return -ENOMEM;
412
413 vb_gpio->vb = vb;
414 /* registering gpio a */
415 vb_gpio->gpioa.label = "viperboard gpio a";
416 vb_gpio->gpioa.dev = &pdev->dev;
417 vb_gpio->gpioa.owner = THIS_MODULE;
418 vb_gpio->gpioa.base = -1;
419 vb_gpio->gpioa.ngpio = 16;
420 vb_gpio->gpioa.can_sleep = 1;
421 vb_gpio->gpioa.set = vprbrd_gpioa_set;
422 vb_gpio->gpioa.get = vprbrd_gpioa_get;
423 vb_gpio->gpioa.direction_input = vprbrd_gpioa_direction_input;
424 vb_gpio->gpioa.direction_output = vprbrd_gpioa_direction_output;
425 ret = gpiochip_add(&vb_gpio->gpioa);
426 if (ret < 0) {
427 dev_err(vb_gpio->gpioa.dev, "could not add gpio a");
428 goto err_gpioa;
429 }
430
431 /* registering gpio b */
432 vb_gpio->gpiob.label = "viperboard gpio b";
433 vb_gpio->gpiob.dev = &pdev->dev;
434 vb_gpio->gpiob.owner = THIS_MODULE;
435 vb_gpio->gpiob.base = -1;
436 vb_gpio->gpiob.ngpio = 16;
437 vb_gpio->gpiob.can_sleep = 1;
438 vb_gpio->gpiob.set = vprbrd_gpiob_set;
439 vb_gpio->gpiob.get = vprbrd_gpiob_get;
440 vb_gpio->gpiob.direction_input = vprbrd_gpiob_direction_input;
441 vb_gpio->gpiob.direction_output = vprbrd_gpiob_direction_output;
442 ret = gpiochip_add(&vb_gpio->gpiob);
443 if (ret < 0) {
444 dev_err(vb_gpio->gpiob.dev, "could not add gpio b");
445 goto err_gpiob;
446 }
447
448 platform_set_drvdata(pdev, vb_gpio);
449
450 return ret;
451
452err_gpiob:
453 ret = gpiochip_remove(&vb_gpio->gpioa);
454
455err_gpioa:
456 return ret;
457}
458
459static int __devexit vprbrd_gpio_remove(struct platform_device *pdev)
460{
461 struct vprbrd_gpio *vb_gpio = platform_get_drvdata(pdev);
462 int ret;
463
464 ret = gpiochip_remove(&vb_gpio->gpiob);
465 if (ret == 0)
466 ret = gpiochip_remove(&vb_gpio->gpioa);
467
468 return ret;
469}
470
471static struct platform_driver vprbrd_gpio_driver = {
472 .driver.name = "viperboard-gpio",
473 .driver.owner = THIS_MODULE,
474 .probe = vprbrd_gpio_probe,
475 .remove = __devexit_p(vprbrd_gpio_remove),
476};
477
478static int __init vprbrd_gpio_init(void)
479{
480 switch (gpioa_freq) {
481 case 1000000:
482 gpioa_clk = VPRBRD_GPIOA_CLK_1MHZ;
483 break;
484 case 100000:
485 gpioa_clk = VPRBRD_GPIOA_CLK_100KHZ;
486 break;
487 case 10000:
488 gpioa_clk = VPRBRD_GPIOA_CLK_10KHZ;
489 break;
490 case 1000:
491 gpioa_clk = VPRBRD_GPIOA_CLK_1KHZ;
492 break;
493 case 100:
494 gpioa_clk = VPRBRD_GPIOA_CLK_100HZ;
495 break;
496 case 10:
497 gpioa_clk = VPRBRD_GPIOA_CLK_10HZ;
498 break;
499 default:
500 pr_warn("invalid gpioa_freq (%d)\n", gpioa_freq);
501 gpioa_clk = VPRBRD_GPIOA_CLK_1KHZ;
502 }
503
504 return platform_driver_register(&vprbrd_gpio_driver);
505}
506subsys_initcall(vprbrd_gpio_init);
507
508static void __exit vprbrd_gpio_exit(void)
509{
510 platform_driver_unregister(&vprbrd_gpio_driver);
511}
512module_exit(vprbrd_gpio_exit);
513
514MODULE_AUTHOR("Lars Poeschel <poeschel@lemonage.de>");
515MODULE_DESCRIPTION("GPIO driver for Nano River Techs Viperboard");
516MODULE_LICENSE("GPL");
517MODULE_ALIAS("platform:viperboard-gpio");