diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2012-06-14 00:58:08 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2012-07-12 07:40:17 -0400 |
commit | 0c65ddd460086084079eeeb14d062c9a0c437ca0 (patch) | |
tree | 060be558f2ec6c792cc5d9f9cd3195ec96141765 /drivers/gpio | |
parent | da03d7400adfe56e2a54d0e38aa12704ab2a0e13 (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.c | 93 |
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 | ||
70 | static int pcf857x_input8(struct gpio_chip *chip, unsigned offset) | 73 | static 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 | |||
83 | static 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 | |||
92 | static 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 | ||
109 | static void pcf857x_set8(struct gpio_chip *chip, unsigned offset, int value) | 78 | static 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 | ||
118 | static int i2c_write_le16(struct i2c_client *client, u16 word) | 85 | static 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 | ||
138 | static int pcf857x_input16(struct gpio_chip *chip, unsigned offset) | 105 | /*-------------------------------------------------------------------------*/ |
106 | |||
107 | static 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 | ||
151 | static int pcf857x_get16(struct gpio_chip *chip, unsigned offset) | 120 | static 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 | ||
160 | static int pcf857x_output16(struct gpio_chip *chip, unsigned offset, int value) | 129 | static 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 | ||
177 | static void pcf857x_set16(struct gpio_chip *chip, unsigned offset, int value) | 146 | static 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; |