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