packaging: release out (3.8.3)
[profile/ivi/kernel-adaptation-intel-automotive.git] / drivers / staging / vme / devices / vme_pio2_gpio.c
1 /*
2  * GE PIO2 GPIO Driver
3  *
4  * Author: Martyn Welch <martyn.welch@ge.com>
5  * Copyright 2009 GE Intelligent Platforms Embedded Systems, Inc.
6  *
7  * This program is free software; you can redistribute  it and/or modify it
8  * under  the terms of  the GNU General  Public License as published by the
9  * Free Software Foundation;  either version 2 of the  License, or (at your
10  * option) any later version.
11  */
12
13 #include <linux/module.h>
14 #include <linux/moduleparam.h>
15 #include <linux/types.h>
16 #include <linux/kernel.h>
17 #include <linux/errno.h>
18 #include <linux/device.h>
19 #include <linux/platform_device.h>
20 #include <linux/ctype.h>
21 #include <linux/gpio.h>
22 #include <linux/slab.h>
23 #include <linux/vme.h>
24
25 #include "vme_pio2.h"
26
27 static const char driver_name[] = "pio2_gpio";
28
29 static struct pio2_card *gpio_to_pio2_card(struct gpio_chip *chip)
30 {
31         return container_of(chip, struct pio2_card, gc);
32 }
33
34 static int pio2_gpio_get(struct gpio_chip *chip, unsigned int offset)
35 {
36         u8 reg;
37         int retval;
38         struct pio2_card *card = gpio_to_pio2_card(chip);
39
40         if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == OUTPUT) |
41                 (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {
42
43                 dev_err(&card->vdev->dev, "Channel not available as input\n");
44                 return 0;
45         }
46
47         retval = vme_master_read(card->window, &reg, 1,
48                 PIO2_REGS_DATA[PIO2_CHANNEL_BANK[offset]]);
49         if (retval < 0) {
50                 dev_err(&card->vdev->dev, "Unable to read from GPIO\n");
51                 return 0;
52         }
53
54         /*
55          * Remember, input on channels configured as both input and output
56          * are inverted!
57          */
58         if (reg & PIO2_CHANNEL_BIT[offset]) {
59                 if (card->bank[PIO2_CHANNEL_BANK[offset]].config != BOTH)
60                         return 0;
61                 else
62                         return 1;
63         } else {
64                 if (card->bank[PIO2_CHANNEL_BANK[offset]].config != BOTH)
65                         return 1;
66                 else
67                         return 0;
68         }
69 }
70
71 static void pio2_gpio_set(struct gpio_chip *chip, unsigned int offset,
72         int value)
73 {
74         u8 reg;
75         int retval;
76         struct pio2_card *card = gpio_to_pio2_card(chip);
77
78         if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == INPUT) |
79                 (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {
80
81                 dev_err(&card->vdev->dev, "Channel not available as output\n");
82                 return;
83         }
84
85         if (value)
86                 reg = card->bank[PIO2_CHANNEL_BANK[offset]].value |
87                         PIO2_CHANNEL_BIT[offset];
88         else
89                 reg = card->bank[PIO2_CHANNEL_BANK[offset]].value &
90                         ~PIO2_CHANNEL_BIT[offset];
91
92         retval = vme_master_write(card->window, &reg, 1,
93                 PIO2_REGS_DATA[PIO2_CHANNEL_BANK[offset]]);
94         if (retval < 0) {
95                 dev_err(&card->vdev->dev, "Unable to write to GPIO\n");
96                 return;
97         }
98
99         card->bank[PIO2_CHANNEL_BANK[offset]].value = reg;
100 }
101
102 /* Directionality configured at board build - send appropriate response */
103 static int pio2_gpio_dir_in(struct gpio_chip *chip, unsigned offset)
104 {
105         int data;
106         struct pio2_card *card = gpio_to_pio2_card(chip);
107
108         if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == OUTPUT) |
109                 (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {
110                 dev_err(&card->vdev->dev,
111                         "Channel directionality not configurable at runtine\n");
112
113                 data = -EINVAL;
114         } else {
115                 data = 0;
116         }
117
118         return data;
119 }
120
121 /* Directionality configured at board build - send appropriate response */
122 static int pio2_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int value)
123 {
124         int data;
125         struct pio2_card *card = gpio_to_pio2_card(chip);
126
127         if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == INPUT) |
128                 (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {
129                 dev_err(&card->vdev->dev,
130                         "Channel directionality not configurable at runtine\n");
131
132                 data = -EINVAL;
133         } else {
134                 data = 0;
135         }
136
137         return data;
138 }
139
140 /*
141  * We return whether this has been successful - this is used in the probe to
142  * ensure we have a valid card.
143  */
144 int pio2_gpio_reset(struct pio2_card *card)
145 {
146         int retval = 0;
147         int i, j;
148
149         u8 data = 0;
150
151         /* Zero output registers */
152         for (i = 0; i < 4; i++) {
153                 retval = vme_master_write(card->window, &data, 1,
154                         PIO2_REGS_DATA[i]);
155                 if (retval < 0)
156                         return retval;
157                 card->bank[i].value = 0;
158         }
159
160         /* Set input interrupt masks */
161         for (i = 0; i < 4; i++) {
162                 retval = vme_master_write(card->window, &data, 1,
163                         PIO2_REGS_INT_MASK[i * 2]);
164                 if (retval < 0)
165                         return retval;
166
167                 retval = vme_master_write(card->window, &data, 1,
168                         PIO2_REGS_INT_MASK[(i * 2) + 1]);
169                 if (retval < 0)
170                         return retval;
171
172                 for (j = 0; j < 8; j++)
173                         card->bank[i].irq[j] = NONE;
174         }
175
176         /* Ensure all I/O interrupts are cleared */
177         for (i = 0; i < 4; i++) {
178                 do {
179                         retval = vme_master_read(card->window, &data, 1,
180                                 PIO2_REGS_INT_STAT[i]);
181                         if (retval < 0)
182                                 return retval;
183                 } while (data != 0);
184         }
185
186         return 0;
187 }
188
189 int pio2_gpio_init(struct pio2_card *card)
190 {
191         int retval = 0;
192         char *label;
193
194         label = kmalloc(PIO2_NUM_CHANNELS, GFP_KERNEL);
195         if (label == NULL) {
196                 dev_err(&card->vdev->dev, "Unable to allocate GPIO label\n");
197                 return -ENOMEM;
198         }
199
200         sprintf(label, "%s@%s", driver_name, dev_name(&card->vdev->dev));
201         card->gc.label = label;
202
203         card->gc.ngpio = PIO2_NUM_CHANNELS;
204         /* Dynamic allocation of base */
205         card->gc.base = -1;
206         /* Setup pointers to chip functions */
207         card->gc.direction_input = pio2_gpio_dir_in;
208         card->gc.direction_output = pio2_gpio_dir_out;
209         card->gc.get = pio2_gpio_get;
210         card->gc.set = pio2_gpio_set;
211
212         /* This function adds a memory mapped GPIO chip */
213         retval = gpiochip_add(&(card->gc));
214         if (retval) {
215                 dev_err(&card->vdev->dev, "Unable to register GPIO\n");
216                 kfree(card->gc.label);
217         }
218
219         return retval;
220 };
221
222 void pio2_gpio_exit(struct pio2_card *card)
223 {
224         const char *label = card->gc.label;
225
226         if (gpiochip_remove(&(card->gc)))
227                 dev_err(&card->vdev->dev, "Failed to remove GPIO");
228
229         kfree(label);
230 }
231