1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/module.h>
14#include <linux/types.h>
15#include <linux/kernel.h>
16#include <linux/errno.h>
17#include <linux/device.h>
18#include <linux/platform_device.h>
19#include <linux/ctype.h>
20#include <linux/gpio/driver.h>
21#include <linux/slab.h>
22#include <linux/vme.h>
23
24#include "vme_pio2.h"
25
26static const char driver_name[] = "pio2_gpio";
27
28static int pio2_gpio_get(struct gpio_chip *chip, unsigned int offset)
29{
30 u8 reg;
31 int retval;
32 struct pio2_card *card = gpiochip_get_data(chip);
33
34 if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == OUTPUT) |
35 (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {
36 dev_err(&card->vdev->dev, "Channel not available as input\n");
37 return 0;
38 }
39
40 retval = vme_master_read(card->window, ®, 1,
41 PIO2_REGS_DATA[PIO2_CHANNEL_BANK[offset]]);
42 if (retval < 0) {
43 dev_err(&card->vdev->dev, "Unable to read from GPIO\n");
44 return 0;
45 }
46
47
48
49
50
51 if (reg & PIO2_CHANNEL_BIT[offset]) {
52 if (card->bank[PIO2_CHANNEL_BANK[offset]].config != BOTH)
53 return 0;
54
55 return 1;
56 }
57
58 if (card->bank[PIO2_CHANNEL_BANK[offset]].config != BOTH)
59 return 1;
60
61 return 0;
62}
63
64static void pio2_gpio_set(struct gpio_chip *chip,
65 unsigned int offset, int value)
66{
67 u8 reg;
68 int retval;
69 struct pio2_card *card = gpiochip_get_data(chip);
70
71 if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == INPUT) |
72 (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {
73 dev_err(&card->vdev->dev, "Channel not available as output\n");
74 return;
75 }
76
77 if (value)
78 reg = card->bank[PIO2_CHANNEL_BANK[offset]].value |
79 PIO2_CHANNEL_BIT[offset];
80 else
81 reg = card->bank[PIO2_CHANNEL_BANK[offset]].value &
82 ~PIO2_CHANNEL_BIT[offset];
83
84 retval = vme_master_write(card->window, ®, 1,
85 PIO2_REGS_DATA[PIO2_CHANNEL_BANK[offset]]);
86 if (retval < 0) {
87 dev_err(&card->vdev->dev, "Unable to write to GPIO\n");
88 return;
89 }
90
91 card->bank[PIO2_CHANNEL_BANK[offset]].value = reg;
92}
93
94
95static int pio2_gpio_dir_in(struct gpio_chip *chip, unsigned int offset)
96{
97 int data;
98 struct pio2_card *card = gpiochip_get_data(chip);
99
100 if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == OUTPUT) |
101 (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {
102 dev_err(&card->vdev->dev,
103 "Channel directionality not configurable at runtime\n");
104
105 data = -EINVAL;
106 } else {
107 data = 0;
108 }
109
110 return data;
111}
112
113
114static int pio2_gpio_dir_out(struct gpio_chip *chip,
115 unsigned int offset, int value)
116{
117 int data;
118 struct pio2_card *card = gpiochip_get_data(chip);
119
120 if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == INPUT) |
121 (card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {
122 dev_err(&card->vdev->dev,
123 "Channel directionality not configurable at runtime\n");
124
125 data = -EINVAL;
126 } else {
127 data = 0;
128 }
129
130 return data;
131}
132
133
134
135
136
137int pio2_gpio_reset(struct pio2_card *card)
138{
139 int retval = 0;
140 int i, j;
141
142 u8 data = 0;
143
144
145 for (i = 0; i < 4; i++) {
146 retval = vme_master_write(card->window, &data, 1,
147 PIO2_REGS_DATA[i]);
148 if (retval < 0)
149 return retval;
150 card->bank[i].value = 0;
151 }
152
153
154 for (i = 0; i < 4; i++) {
155 retval = vme_master_write(card->window, &data, 1,
156 PIO2_REGS_INT_MASK[i * 2]);
157 if (retval < 0)
158 return retval;
159
160 retval = vme_master_write(card->window, &data, 1,
161 PIO2_REGS_INT_MASK[(i * 2) + 1]);
162 if (retval < 0)
163 return retval;
164
165 for (j = 0; j < 8; j++)
166 card->bank[i].irq[j] = NONE;
167 }
168
169
170 for (i = 0; i < 4; i++) {
171 do {
172 retval = vme_master_read(card->window, &data, 1,
173 PIO2_REGS_INT_STAT[i]);
174 if (retval < 0)
175 return retval;
176 } while (data != 0);
177 }
178
179 return 0;
180}
181
182int pio2_gpio_init(struct pio2_card *card)
183{
184 int retval = 0;
185 char *label;
186
187 label = kasprintf(GFP_KERNEL,
188 "%s@%s", driver_name, dev_name(&card->vdev->dev));
189 if (!label)
190 return -ENOMEM;
191
192 card->gc.label = label;
193
194 card->gc.ngpio = PIO2_NUM_CHANNELS;
195
196 card->gc.base = -1;
197
198 card->gc.direction_input = pio2_gpio_dir_in;
199 card->gc.direction_output = pio2_gpio_dir_out;
200 card->gc.get = pio2_gpio_get;
201 card->gc.set = pio2_gpio_set;
202
203
204 retval = gpiochip_add_data(&card->gc, card);
205 if (retval) {
206 dev_err(&card->vdev->dev, "Unable to register GPIO\n");
207 kfree(card->gc.label);
208 }
209
210 return retval;
211};
212
213void pio2_gpio_exit(struct pio2_card *card)
214{
215 const char *label = card->gc.label;
216
217 gpiochip_remove(&card->gc);
218 kfree(label);
219}
220
221