Commit 0c65ddd460086084079eeeb14d062c9a0c437ca0
Committed by
Linus Walleij
1 parent
da03d7400a
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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>
Showing 1 changed file with 31 additions and 62 deletions Side-by-side Diff
drivers/gpio/gpio-pcf857x.c
... | ... | @@ -61,61 +61,28 @@ |
61 | 61 | struct i2c_client *client; |
62 | 62 | struct mutex lock; /* protect 'out' */ |
63 | 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 | 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 | 74 | { |
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; | |
75 | + return i2c_smbus_write_byte(client, data); | |
81 | 76 | } |
82 | 77 | |
83 | -static int pcf857x_get8(struct gpio_chip *chip, unsigned offset) | |
78 | +static int i2c_read_le8(struct i2c_client *client) | |
84 | 79 | { |
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)); | |
80 | + return (int)i2c_smbus_read_byte(client); | |
90 | 81 | } |
91 | 82 | |
92 | -static int pcf857x_output8(struct gpio_chip *chip, unsigned offset, int value) | |
93 | -{ | |
94 | - struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); | |
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 | -} | |
108 | - | |
109 | -static void pcf857x_set8(struct gpio_chip *chip, unsigned offset, int value) | |
110 | -{ | |
111 | - pcf857x_output8(chip, offset, value); | |
112 | -} | |
113 | - | |
114 | -/*-------------------------------------------------------------------------*/ | |
115 | - | |
116 | 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 | 87 | u8 buf[2] = { word & 0xff, word >> 8, }; |
121 | 88 | int status; |
122 | 89 | |
123 | 90 | |
124 | 91 | |
125 | 92 | |
... | ... | @@ -135,29 +102,31 @@ |
135 | 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 | 109 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); |
141 | 110 | int status; |
142 | 111 | |
143 | 112 | mutex_lock(&gpio->lock); |
144 | 113 | gpio->out |= (1 << offset); |
145 | - status = i2c_write_le16(gpio->client, gpio->out); | |
114 | + status = gpio->write(gpio->client, gpio->out); | |
146 | 115 | mutex_unlock(&gpio->lock); |
147 | 116 | |
148 | 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 | 122 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); |
154 | 123 | int value; |
155 | 124 | |
156 | - value = i2c_read_le16(gpio->client); | |
125 | + value = gpio->read(gpio->client); | |
157 | 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 | 131 | struct pcf857x *gpio = container_of(chip, struct pcf857x, chip); |
163 | 132 | unsigned bit = 1 << offset; |
164 | 133 | |
165 | 134 | |
... | ... | @@ -168,15 +137,15 @@ |
168 | 137 | gpio->out |= bit; |
169 | 138 | else |
170 | 139 | gpio->out &= ~bit; |
171 | - status = i2c_write_le16(gpio->client, gpio->out); | |
140 | + status = gpio->write(gpio->client, gpio->out); | |
172 | 141 | mutex_unlock(&gpio->lock); |
173 | 142 | |
174 | 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 @@ |
200 | 169 | |
201 | 170 | mutex_init(&gpio->lock); |
202 | 171 | |
203 | - gpio->chip.base = pdata ? pdata->gpio_base : -1; | |
204 | - gpio->chip.can_sleep = 1; | |
205 | - gpio->chip.dev = &client->dev; | |
206 | - gpio->chip.owner = THIS_MODULE; | |
172 | + gpio->chip.base = pdata ? pdata->gpio_base : -1; | |
173 | + gpio->chip.can_sleep = 1; | |
174 | + gpio->chip.dev = &client->dev; | |
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 | 182 | /* NOTE: the OnSemi jlc1562b is also largely compatible with |
209 | 183 | * these parts, notably for output. It has a low-resolution |
210 | 184 | |
... | ... | @@ -216,12 +190,9 @@ |
216 | 190 | * |
217 | 191 | * NOTE: we don't distinguish here between *4 and *4a parts. |
218 | 192 | */ |
219 | - gpio->chip.ngpio = id->driver_data; | |
220 | 193 | if (gpio->chip.ngpio == 8) { |
221 | - gpio->chip.direction_input = pcf857x_input8; | |
222 | - gpio->chip.get = pcf857x_get8; | |
223 | - gpio->chip.direction_output = pcf857x_output8; | |
224 | - gpio->chip.set = pcf857x_set8; | |
194 | + gpio->write = i2c_write_le8; | |
195 | + gpio->read = i2c_read_le8; | |
225 | 196 | |
226 | 197 | if (!i2c_check_functionality(client->adapter, |
227 | 198 | I2C_FUNC_SMBUS_BYTE)) |
... | ... | @@ -238,10 +209,8 @@ |
238 | 209 | * NOTE: we don't distinguish here between '75 and '75c parts. |
239 | 210 | */ |
240 | 211 | } else if (gpio->chip.ngpio == 16) { |
241 | - gpio->chip.direction_input = pcf857x_input16; | |
242 | - gpio->chip.get = pcf857x_get16; | |
243 | - gpio->chip.direction_output = pcf857x_output16; | |
244 | - gpio->chip.set = pcf857x_set16; | |
212 | + gpio->write = i2c_write_le16; | |
213 | + gpio->read = i2c_read_le16; | |
245 | 214 | |
246 | 215 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) |
247 | 216 | status = -EIO; |