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/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.h>
21 #include <linux/slab.h>
22 #include <linux/vme.h>
23 
24 #include "vme_pio2.h"
25 
26 static const char driver_name[] = "pio2_gpio";
27 
gpio_to_pio2_card(struct gpio_chip * chip)28 static struct pio2_card *gpio_to_pio2_card(struct gpio_chip *chip)
29 {
30 	return container_of(chip, struct pio2_card, gc);
31 }
32 
pio2_gpio_get(struct gpio_chip * chip,unsigned int offset)33 static int pio2_gpio_get(struct gpio_chip *chip, unsigned int offset)
34 {
35 	u8 reg;
36 	int retval;
37 	struct pio2_card *card = gpio_to_pio2_card(chip);
38 
39 	if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == OUTPUT) |
40 		(card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {
41 
42 		dev_err(&card->vdev->dev, "Channel not available as input\n");
43 		return 0;
44 	}
45 
46 	retval = vme_master_read(card->window, &reg, 1,
47 		PIO2_REGS_DATA[PIO2_CHANNEL_BANK[offset]]);
48 	if (retval < 0) {
49 		dev_err(&card->vdev->dev, "Unable to read from GPIO\n");
50 		return 0;
51 	}
52 
53 	/*
54 	 * Remember, input on channels configured as both input and output
55 	 * are inverted!
56 	 */
57 	if (reg & PIO2_CHANNEL_BIT[offset]) {
58 		if (card->bank[PIO2_CHANNEL_BANK[offset]].config != BOTH)
59 			return 0;
60 
61 		return 1;
62 	}
63 
64 	if (card->bank[PIO2_CHANNEL_BANK[offset]].config != BOTH)
65 		return 1;
66 
67 	return 0;
68 }
69 
pio2_gpio_set(struct gpio_chip * chip,unsigned int offset,int value)70 static void pio2_gpio_set(struct gpio_chip *chip, unsigned int offset,
71 	int value)
72 {
73 	u8 reg;
74 	int retval;
75 	struct pio2_card *card = gpio_to_pio2_card(chip);
76 
77 	if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == INPUT) |
78 		(card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {
79 
80 		dev_err(&card->vdev->dev, "Channel not available as output\n");
81 		return;
82 	}
83 
84 	if (value)
85 		reg = card->bank[PIO2_CHANNEL_BANK[offset]].value |
86 			PIO2_CHANNEL_BIT[offset];
87 	else
88 		reg = card->bank[PIO2_CHANNEL_BANK[offset]].value &
89 			~PIO2_CHANNEL_BIT[offset];
90 
91 	retval = vme_master_write(card->window, &reg, 1,
92 		PIO2_REGS_DATA[PIO2_CHANNEL_BANK[offset]]);
93 	if (retval < 0) {
94 		dev_err(&card->vdev->dev, "Unable to write to GPIO\n");
95 		return;
96 	}
97 
98 	card->bank[PIO2_CHANNEL_BANK[offset]].value = reg;
99 }
100 
101 /* Directionality configured at board build - send appropriate response */
pio2_gpio_dir_in(struct gpio_chip * chip,unsigned offset)102 static int pio2_gpio_dir_in(struct gpio_chip *chip, unsigned offset)
103 {
104 	int data;
105 	struct pio2_card *card = gpio_to_pio2_card(chip);
106 
107 	if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == OUTPUT) |
108 		(card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {
109 		dev_err(&card->vdev->dev,
110 			"Channel directionality not configurable at runtime\n");
111 
112 		data = -EINVAL;
113 	} else {
114 		data = 0;
115 	}
116 
117 	return data;
118 }
119 
120 /* Directionality configured at board build - send appropriate response */
pio2_gpio_dir_out(struct gpio_chip * chip,unsigned offset,int value)121 static int pio2_gpio_dir_out(struct gpio_chip *chip, unsigned offset, int value)
122 {
123 	int data;
124 	struct pio2_card *card = gpio_to_pio2_card(chip);
125 
126 	if ((card->bank[PIO2_CHANNEL_BANK[offset]].config == INPUT) |
127 		(card->bank[PIO2_CHANNEL_BANK[offset]].config == NOFIT)) {
128 		dev_err(&card->vdev->dev,
129 			"Channel directionality not configurable at runtime\n");
130 
131 		data = -EINVAL;
132 	} else {
133 		data = 0;
134 	}
135 
136 	return data;
137 }
138 
139 /*
140  * We return whether this has been successful - this is used in the probe to
141  * ensure we have a valid card.
142  */
pio2_gpio_reset(struct pio2_card * card)143 int pio2_gpio_reset(struct pio2_card *card)
144 {
145 	int retval = 0;
146 	int i, j;
147 
148 	u8 data = 0;
149 
150 	/* Zero output registers */
151 	for (i = 0; i < 4; i++) {
152 		retval = vme_master_write(card->window, &data, 1,
153 			PIO2_REGS_DATA[i]);
154 		if (retval < 0)
155 			return retval;
156 		card->bank[i].value = 0;
157 	}
158 
159 	/* Set input interrupt masks */
160 	for (i = 0; i < 4; i++) {
161 		retval = vme_master_write(card->window, &data, 1,
162 			PIO2_REGS_INT_MASK[i * 2]);
163 		if (retval < 0)
164 			return retval;
165 
166 		retval = vme_master_write(card->window, &data, 1,
167 			PIO2_REGS_INT_MASK[(i * 2) + 1]);
168 		if (retval < 0)
169 			return retval;
170 
171 		for (j = 0; j < 8; j++)
172 			card->bank[i].irq[j] = NONE;
173 	}
174 
175 	/* Ensure all I/O interrupts are cleared */
176 	for (i = 0; i < 4; i++) {
177 		do {
178 			retval = vme_master_read(card->window, &data, 1,
179 				PIO2_REGS_INT_STAT[i]);
180 			if (retval < 0)
181 				return retval;
182 		} while (data != 0);
183 	}
184 
185 	return 0;
186 }
187 
pio2_gpio_init(struct pio2_card * card)188 int pio2_gpio_init(struct pio2_card *card)
189 {
190 	int retval = 0;
191 	char *label;
192 
193 	label = kasprintf(GFP_KERNEL,
194 			  "%s@%s", driver_name, dev_name(&card->vdev->dev));
195 	if (label == NULL)
196 		return -ENOMEM;
197 
198 	card->gc.label = label;
199 
200 	card->gc.ngpio = PIO2_NUM_CHANNELS;
201 	/* Dynamic allocation of base */
202 	card->gc.base = -1;
203 	/* Setup pointers to chip functions */
204 	card->gc.direction_input = pio2_gpio_dir_in;
205 	card->gc.direction_output = pio2_gpio_dir_out;
206 	card->gc.get = pio2_gpio_get;
207 	card->gc.set = pio2_gpio_set;
208 
209 	/* This function adds a memory mapped GPIO chip */
210 	retval = gpiochip_add(&(card->gc));
211 	if (retval) {
212 		dev_err(&card->vdev->dev, "Unable to register GPIO\n");
213 		kfree(card->gc.label);
214 	}
215 
216 	return retval;
217 };
218 
pio2_gpio_exit(struct pio2_card * card)219 void pio2_gpio_exit(struct pio2_card *card)
220 {
221 	const char *label = card->gc.label;
222 
223 	gpiochip_remove(&(card->gc));
224 	kfree(label);
225 }
226 
227