aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpio
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2012-06-14 00:58:08 -0400
committerLinus Walleij <linus.walleij@linaro.org>2012-07-12 07:40:17 -0400
commit0c65ddd460086084079eeeb14d062c9a0c437ca0 (patch)
tree060be558f2ec6c792cc5d9f9cd3195ec96141765 /drivers/gpio
parentda03d7400adfe56e2a54d0e38aa12704ab2a0e13 (diff)
gpio: pcf857x: share 8/16 bit access functions
This patch adds 8/16 bit write/read functions, and shared gpio input/output/set/get functions. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r--drivers/gpio/gpio-pcf857x.c93
1 files changed, 31 insertions, 62 deletions
diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c
index 2d1de9e7e9bd..076e236d0da7 100644
--- a/drivers/gpio/gpio-pcf857x.c
+++ b/drivers/gpio/gpio-pcf857x.c
@@ -61,61 +61,28 @@ struct pcf857x {
61 struct i2c_client *client; 61 struct i2c_client *client;
62 struct mutex lock; /* protect 'out' */ 62 struct mutex lock; /* protect 'out' */
63 unsigned out; /* software latch */ 63 unsigned out; /* software latch */
64
65 int (*write)(struct i2c_client *client, unsigned data);
66 int (*read)(struct i2c_client *client);
64}; 67};
65 68
66/*-------------------------------------------------------------------------*/ 69/*-------------------------------------------------------------------------*/
67 70
68/* Talk to 8-bit I/O expander */ 71/* Talk to 8-bit I/O expander */
69 72
70static int pcf857x_input8(struct gpio_chip *chip, unsigned offset) 73static int i2c_write_le8(struct i2c_client *client, unsigned data)
71{
72 struct pcf857x *gpio = container_of(chip, struct pcf857x, chip);
73 int status;
74
75 mutex_lock(&gpio->lock);
76 gpio->out |= (1 << offset);
77 status = i2c_smbus_write_byte(gpio->client, gpio->out);
78 mutex_unlock(&gpio->lock);
79
80 return status;
81}
82
83static int pcf857x_get8(struct gpio_chip *chip, unsigned offset)
84{
85 struct pcf857x *gpio = container_of(chip, struct pcf857x, chip);
86 s32 value;
87
88 value = i2c_smbus_read_byte(gpio->client);
89 return (value < 0) ? 0 : (value & (1 << offset));
90}
91
92static int pcf857x_output8(struct gpio_chip *chip, unsigned offset, int value)
93{ 74{
94 struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); 75 return i2c_smbus_write_byte(client, data);
95 unsigned bit = 1 << offset;
96 int status;
97
98 mutex_lock(&gpio->lock);
99 if (value)
100 gpio->out |= bit;
101 else
102 gpio->out &= ~bit;
103 status = i2c_smbus_write_byte(gpio->client, gpio->out);
104 mutex_unlock(&gpio->lock);
105
106 return status;
107} 76}
108 77
109static void pcf857x_set8(struct gpio_chip *chip, unsigned offset, int value) 78static int i2c_read_le8(struct i2c_client *client)
110{ 79{
111 pcf857x_output8(chip, offset, value); 80 return (int)i2c_smbus_read_byte(client);
112} 81}
113 82
114/*-------------------------------------------------------------------------*/
115
116/* Talk to 16-bit I/O expander */ 83/* Talk to 16-bit I/O expander */
117 84
118static int i2c_write_le16(struct i2c_client *client, u16 word) 85static int i2c_write_le16(struct i2c_client *client, unsigned word)
119{ 86{
120 u8 buf[2] = { word & 0xff, word >> 8, }; 87 u8 buf[2] = { word & 0xff, word >> 8, };
121 int status; 88 int status;
@@ -135,29 +102,31 @@ static int i2c_read_le16(struct i2c_client *client)
135 return (buf[1] << 8) | buf[0]; 102 return (buf[1] << 8) | buf[0];
136} 103}
137 104
138static int pcf857x_input16(struct gpio_chip *chip, unsigned offset) 105/*-------------------------------------------------------------------------*/
106
107static int pcf857x_input(struct gpio_chip *chip, unsigned offset)
139{ 108{
140 struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); 109 struct pcf857x *gpio = container_of(chip, struct pcf857x, chip);
141 int status; 110 int status;
142 111
143 mutex_lock(&gpio->lock); 112 mutex_lock(&gpio->lock);
144 gpio->out |= (1 << offset); 113 gpio->out |= (1 << offset);
145 status = i2c_write_le16(gpio->client, gpio->out); 114 status = gpio->write(gpio->client, gpio->out);
146 mutex_unlock(&gpio->lock); 115 mutex_unlock(&gpio->lock);
147 116
148 return status; 117 return status;
149} 118}
150 119
151static int pcf857x_get16(struct gpio_chip *chip, unsigned offset) 120static int pcf857x_get(struct gpio_chip *chip, unsigned offset)
152{ 121{
153 struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); 122 struct pcf857x *gpio = container_of(chip, struct pcf857x, chip);
154 int value; 123 int value;
155 124
156 value = i2c_read_le16(gpio->client); 125 value = gpio->read(gpio->client);
157 return (value < 0) ? 0 : (value & (1 << offset)); 126 return (value < 0) ? 0 : (value & (1 << offset));
158} 127}
159 128
160static int pcf857x_output16(struct gpio_chip *chip, unsigned offset, int value) 129static int pcf857x_output(struct gpio_chip *chip, unsigned offset, int value)
161{ 130{
162 struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); 131 struct pcf857x *gpio = container_of(chip, struct pcf857x, chip);
163 unsigned bit = 1 << offset; 132 unsigned bit = 1 << offset;
@@ -168,15 +137,15 @@ static int pcf857x_output16(struct gpio_chip *chip, unsigned offset, int value)
168 gpio->out |= bit; 137 gpio->out |= bit;
169 else 138 else
170 gpio->out &= ~bit; 139 gpio->out &= ~bit;
171 status = i2c_write_le16(gpio->client, gpio->out); 140 status = gpio->write(gpio->client, gpio->out);
172 mutex_unlock(&gpio->lock); 141 mutex_unlock(&gpio->lock);
173 142
174 return status; 143 return status;
175} 144}
176 145
177static void pcf857x_set16(struct gpio_chip *chip, unsigned offset, int value) 146static void pcf857x_set(struct gpio_chip *chip, unsigned offset, int value)
178{ 147{
179 pcf857x_output16(chip, offset, value); 148 pcf857x_output(chip, offset, value);
180} 149}
181 150
182/*-------------------------------------------------------------------------*/ 151/*-------------------------------------------------------------------------*/
@@ -200,10 +169,15 @@ static int pcf857x_probe(struct i2c_client *client,
200 169
201 mutex_init(&gpio->lock); 170 mutex_init(&gpio->lock);
202 171
203 gpio->chip.base = pdata ? pdata->gpio_base : -1; 172 gpio->chip.base = pdata ? pdata->gpio_base : -1;
204 gpio->chip.can_sleep = 1; 173 gpio->chip.can_sleep = 1;
205 gpio->chip.dev = &client->dev; 174 gpio->chip.dev = &client->dev;
206 gpio->chip.owner = THIS_MODULE; 175 gpio->chip.owner = THIS_MODULE;
176 gpio->chip.get = pcf857x_get;
177 gpio->chip.set = pcf857x_set;
178 gpio->chip.direction_input = pcf857x_input;
179 gpio->chip.direction_output = pcf857x_output;
180 gpio->chip.ngpio = id->driver_data;
207 181
208 /* NOTE: the OnSemi jlc1562b is also largely compatible with 182 /* NOTE: the OnSemi jlc1562b is also largely compatible with
209 * these parts, notably for output. It has a low-resolution 183 * these parts, notably for output. It has a low-resolution
@@ -216,12 +190,9 @@ static int pcf857x_probe(struct i2c_client *client,
216 * 190 *
217 * NOTE: we don't distinguish here between *4 and *4a parts. 191 * NOTE: we don't distinguish here between *4 and *4a parts.
218 */ 192 */
219 gpio->chip.ngpio = id->driver_data;
220 if (gpio->chip.ngpio == 8) { 193 if (gpio->chip.ngpio == 8) {
221 gpio->chip.direction_input = pcf857x_input8; 194 gpio->write = i2c_write_le8;
222 gpio->chip.get = pcf857x_get8; 195 gpio->read = i2c_read_le8;
223 gpio->chip.direction_output = pcf857x_output8;
224 gpio->chip.set = pcf857x_set8;
225 196
226 if (!i2c_check_functionality(client->adapter, 197 if (!i2c_check_functionality(client->adapter,
227 I2C_FUNC_SMBUS_BYTE)) 198 I2C_FUNC_SMBUS_BYTE))
@@ -238,10 +209,8 @@ static int pcf857x_probe(struct i2c_client *client,
238 * NOTE: we don't distinguish here between '75 and '75c parts. 209 * NOTE: we don't distinguish here between '75 and '75c parts.
239 */ 210 */
240 } else if (gpio->chip.ngpio == 16) { 211 } else if (gpio->chip.ngpio == 16) {
241 gpio->chip.direction_input = pcf857x_input16; 212 gpio->write = i2c_write_le16;
242 gpio->chip.get = pcf857x_get16; 213 gpio->read = i2c_read_le16;
243 gpio->chip.direction_output = pcf857x_output16;
244 gpio->chip.set = pcf857x_set16;
245 214
246 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 215 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
247 status = -EIO; 216 status = -EIO;