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