diff options
author | Neil Armstrong <narmstrong@baylibre.com> | 2016-10-21 05:09:58 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2016-10-24 10:30:40 -0400 |
commit | 9e80f9064e73f9f82679884ddf8b03ac3606cf4a (patch) | |
tree | 1a4f670cb7785bca6de38ad7069b0db0af880181 /drivers/gpio | |
parent | 07d9a380680d1c0eb51ef87ff2eab5c994949e69 (diff) |
pinctrl: Add SX150X GPIO Extender Pinctrl Driver
Since the I2C sx150x GPIO expander driver uses platform_data to manage
the pins configurations, rewrite the driver as a pinctrl driver using
pinconf to get/set pin configurations from DT or debugfs.
The pinctrl driver is functionnally equivalent as the gpio-only driver
and can use DT for pinconf. The platform_data confirmation is dropped.
This patchset removed the gpio-only driver and selects the Pinctrl driver
config instead. This patchset also migrates the gpio dt-bindings to pinctrl
and add the pinctrl optional properties.
The driver was tested with a SX1509 device on a BeagleBone black with
interrupt support and on an X86_64 machine over an I2C to USB converter.
This is a fixed version that builds and runs on non-OF platforms and on
arm based OF. The GPIO version is removed and the bindings are also moved
to the pinctrl bindings.
Changes since v2
- rebased on v4.9-rc1
- removed MODULE_DEVICE_TABLE as in upstream bb411e771b0e
("gpio: sx150x: fix implicit assumption module.h is present")
Changes since v1
- Fix Kconfig descriptions on pinctrl and gpio
- Fix Kconfig dependency
- Remove oscio support for non-789 devices
- correct typo in dt bindings
- remove probe reset for non-789 devices
Changes since RFC
- Put #ifdef CONFIG_OF/CONFIG_OF_GPIO to remove OF code for non-of platforms
- No more rely on OF_GPIO config
- Moved and enhanced bindings to pinctrl bindings
- Removed gpio-sx150x.c
- Temporary select PINCTRL_SX150X when GPIO_SX150X
- Temporary mark GPIO_SX150X as deprecated
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Tested-by: Peter Rosin <peda@axentia.se>
Acked-by: Rob Herring <robh@kernel.org>
ested-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/Kconfig | 13 | ||||
-rw-r--r-- | drivers/gpio/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpio/gpio-sx150x.c | 792 |
3 files changed, 5 insertions, 801 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 26ee00f6bd58..db3f7aab4160 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -781,16 +781,13 @@ config GPIO_PCF857X | |||
781 | platform-neutral GPIO calls. | 781 | platform-neutral GPIO calls. |
782 | 782 | ||
783 | config GPIO_SX150X | 783 | config GPIO_SX150X |
784 | bool "Semtech SX150x I2C GPIO expander" | 784 | bool "Semtech SX150x I2C GPIO expander (deprecated)" |
785 | depends on I2C=y | 785 | depends on PINCTRL && I2C=y |
786 | select GPIOLIB_IRQCHIP | 786 | select PINCTRL_SX150X |
787 | default n | 787 | default n |
788 | help | 788 | help |
789 | Say yes here to provide support for Semtech SX150-series I2C | 789 | Say yes here to provide support for Semtech SX150x-series I2C |
790 | GPIO expanders. Compatible models include: | 790 | GPIO expanders. The GPIO driver was replaced by a Pinctrl version. |
791 | |||
792 | 8 bits: sx1508q | ||
793 | 16 bits: sx1509q | ||
794 | 791 | ||
795 | config GPIO_TPIC2810 | 792 | config GPIO_TPIC2810 |
796 | tristate "TPIC2810 8-Bit I2C GPO expander" | 793 | tristate "TPIC2810 8-Bit I2C GPO expander" |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index ab28a2daeacc..76c7af6c5839 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -102,7 +102,6 @@ obj-$(CONFIG_GPIO_SPEAR_SPICS) += gpio-spear-spics.o | |||
102 | obj-$(CONFIG_GPIO_STA2X11) += gpio-sta2x11.o | 102 | obj-$(CONFIG_GPIO_STA2X11) += gpio-sta2x11.o |
103 | obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o | 103 | obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o |
104 | obj-$(CONFIG_GPIO_STP_XWAY) += gpio-stp-xway.o | 104 | obj-$(CONFIG_GPIO_STP_XWAY) += gpio-stp-xway.o |
105 | obj-$(CONFIG_GPIO_SX150X) += gpio-sx150x.o | ||
106 | obj-$(CONFIG_GPIO_SYSCON) += gpio-syscon.o | 105 | obj-$(CONFIG_GPIO_SYSCON) += gpio-syscon.o |
107 | obj-$(CONFIG_GPIO_TB10X) += gpio-tb10x.o | 106 | obj-$(CONFIG_GPIO_TB10X) += gpio-tb10x.o |
108 | obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o | 107 | obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o |
diff --git a/drivers/gpio/gpio-sx150x.c b/drivers/gpio/gpio-sx150x.c deleted file mode 100644 index af95de89db01..000000000000 --- a/drivers/gpio/gpio-sx150x.c +++ /dev/null | |||
@@ -1,792 +0,0 @@ | |||
1 | /* Copyright (c) 2010, Code Aurora Forum. All rights reserved. | ||
2 | * | ||
3 | * Driver for Semtech SX150X I2C GPIO Expanders | ||
4 | * | ||
5 | * Author: Gregory Bean <gbean@codeaurora.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 and | ||
9 | * only version 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
19 | * 02110-1301, USA. | ||
20 | */ | ||
21 | #include <linux/gpio.h> | ||
22 | #include <linux/i2c.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/irq.h> | ||
26 | #include <linux/mutex.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/of.h> | ||
29 | #include <linux/of_address.h> | ||
30 | #include <linux/of_irq.h> | ||
31 | #include <linux/of_gpio.h> | ||
32 | #include <linux/of_device.h> | ||
33 | |||
34 | #define NO_UPDATE_PENDING -1 | ||
35 | |||
36 | /* The chip models of sx150x */ | ||
37 | #define SX150X_123 0 | ||
38 | #define SX150X_456 1 | ||
39 | #define SX150X_789 2 | ||
40 | |||
41 | struct sx150x_123_pri { | ||
42 | u8 reg_pld_mode; | ||
43 | u8 reg_pld_table0; | ||
44 | u8 reg_pld_table1; | ||
45 | u8 reg_pld_table2; | ||
46 | u8 reg_pld_table3; | ||
47 | u8 reg_pld_table4; | ||
48 | u8 reg_advance; | ||
49 | }; | ||
50 | |||
51 | struct sx150x_456_pri { | ||
52 | u8 reg_pld_mode; | ||
53 | u8 reg_pld_table0; | ||
54 | u8 reg_pld_table1; | ||
55 | u8 reg_pld_table2; | ||
56 | u8 reg_pld_table3; | ||
57 | u8 reg_pld_table4; | ||
58 | u8 reg_advance; | ||
59 | }; | ||
60 | |||
61 | struct sx150x_789_pri { | ||
62 | u8 reg_drain; | ||
63 | u8 reg_polarity; | ||
64 | u8 reg_clock; | ||
65 | u8 reg_misc; | ||
66 | u8 reg_reset; | ||
67 | u8 ngpios; | ||
68 | }; | ||
69 | |||
70 | struct sx150x_device_data { | ||
71 | u8 model; | ||
72 | u8 reg_pullup; | ||
73 | u8 reg_pulldn; | ||
74 | u8 reg_dir; | ||
75 | u8 reg_data; | ||
76 | u8 reg_irq_mask; | ||
77 | u8 reg_irq_src; | ||
78 | u8 reg_sense; | ||
79 | u8 ngpios; | ||
80 | union { | ||
81 | struct sx150x_123_pri x123; | ||
82 | struct sx150x_456_pri x456; | ||
83 | struct sx150x_789_pri x789; | ||
84 | } pri; | ||
85 | }; | ||
86 | |||
87 | /** | ||
88 | * struct sx150x_platform_data - config data for SX150x driver | ||
89 | * @gpio_base: The index number of the first GPIO assigned to this | ||
90 | * GPIO expander. The expander will create a block of | ||
91 | * consecutively numbered gpios beginning at the given base, | ||
92 | * with the size of the block depending on the model of the | ||
93 | * expander chip. | ||
94 | * @oscio_is_gpo: If set to true, the driver will configure OSCIO as a GPO | ||
95 | * instead of as an oscillator, increasing the size of the | ||
96 | * GP(I)O pool created by this expander by one. The | ||
97 | * output-only GPO pin will be added at the end of the block. | ||
98 | * @io_pullup_ena: A bit-mask which enables or disables the pull-up resistor | ||
99 | * for each IO line in the expander. Setting the bit at | ||
100 | * position n will enable the pull-up for the IO at | ||
101 | * the corresponding offset. For chips with fewer than | ||
102 | * 16 IO pins, high-end bits are ignored. | ||
103 | * @io_pulldn_ena: A bit-mask which enables-or disables the pull-down | ||
104 | * resistor for each IO line in the expander. Setting the | ||
105 | * bit at position n will enable the pull-down for the IO at | ||
106 | * the corresponding offset. For chips with fewer than | ||
107 | * 16 IO pins, high-end bits are ignored. | ||
108 | * @io_polarity: A bit-mask which enables polarity inversion for each IO line | ||
109 | * in the expander. Setting the bit at position n inverts | ||
110 | * the polarity of that IO line, while clearing it results | ||
111 | * in normal polarity. For chips with fewer than 16 IO pins, | ||
112 | * high-end bits are ignored. | ||
113 | * @irq_summary: The 'summary IRQ' line to which the GPIO expander's INT line | ||
114 | * is connected, via which it reports interrupt events | ||
115 | * across all GPIO lines. This must be a real, | ||
116 | * pre-existing IRQ line. | ||
117 | * Setting this value < 0 disables the irq_chip functionality | ||
118 | * of the driver. | ||
119 | * @irq_base: The first 'virtual IRQ' line at which our block of GPIO-based | ||
120 | * IRQ lines will appear. Similarly to gpio_base, the expander | ||
121 | * will create a block of irqs beginning at this number. | ||
122 | * This value is ignored if irq_summary is < 0. | ||
123 | * @reset_during_probe: If set to true, the driver will trigger a full | ||
124 | * reset of the chip at the beginning of the probe | ||
125 | * in order to place it in a known state. | ||
126 | */ | ||
127 | struct sx150x_platform_data { | ||
128 | unsigned gpio_base; | ||
129 | bool oscio_is_gpo; | ||
130 | u16 io_pullup_ena; | ||
131 | u16 io_pulldn_ena; | ||
132 | u16 io_polarity; | ||
133 | int irq_summary; | ||
134 | unsigned irq_base; | ||
135 | bool reset_during_probe; | ||
136 | }; | ||
137 | |||
138 | struct sx150x_chip { | ||
139 | struct gpio_chip gpio_chip; | ||
140 | struct i2c_client *client; | ||
141 | const struct sx150x_device_data *dev_cfg; | ||
142 | int irq_summary; | ||
143 | int irq_base; | ||
144 | int irq_update; | ||
145 | u32 irq_sense; | ||
146 | u32 irq_masked; | ||
147 | u32 dev_sense; | ||
148 | u32 dev_masked; | ||
149 | struct irq_chip irq_chip; | ||
150 | struct mutex lock; | ||
151 | }; | ||
152 | |||
153 | static const struct sx150x_device_data sx150x_devices[] = { | ||
154 | [0] = { /* sx1508q */ | ||
155 | .model = SX150X_789, | ||
156 | .reg_pullup = 0x03, | ||
157 | .reg_pulldn = 0x04, | ||
158 | .reg_dir = 0x07, | ||
159 | .reg_data = 0x08, | ||
160 | .reg_irq_mask = 0x09, | ||
161 | .reg_irq_src = 0x0c, | ||
162 | .reg_sense = 0x0b, | ||
163 | .pri.x789 = { | ||
164 | .reg_drain = 0x05, | ||
165 | .reg_polarity = 0x06, | ||
166 | .reg_clock = 0x0f, | ||
167 | .reg_misc = 0x10, | ||
168 | .reg_reset = 0x7d, | ||
169 | }, | ||
170 | .ngpios = 8, | ||
171 | }, | ||
172 | [1] = { /* sx1509q */ | ||
173 | .model = SX150X_789, | ||
174 | .reg_pullup = 0x07, | ||
175 | .reg_pulldn = 0x09, | ||
176 | .reg_dir = 0x0f, | ||
177 | .reg_data = 0x11, | ||
178 | .reg_irq_mask = 0x13, | ||
179 | .reg_irq_src = 0x19, | ||
180 | .reg_sense = 0x17, | ||
181 | .pri.x789 = { | ||
182 | .reg_drain = 0x0b, | ||
183 | .reg_polarity = 0x0d, | ||
184 | .reg_clock = 0x1e, | ||
185 | .reg_misc = 0x1f, | ||
186 | .reg_reset = 0x7d, | ||
187 | }, | ||
188 | .ngpios = 16 | ||
189 | }, | ||
190 | [2] = { /* sx1506q */ | ||
191 | .model = SX150X_456, | ||
192 | .reg_pullup = 0x05, | ||
193 | .reg_pulldn = 0x07, | ||
194 | .reg_dir = 0x03, | ||
195 | .reg_data = 0x01, | ||
196 | .reg_irq_mask = 0x09, | ||
197 | .reg_irq_src = 0x0f, | ||
198 | .reg_sense = 0x0d, | ||
199 | .pri.x456 = { | ||
200 | .reg_pld_mode = 0x21, | ||
201 | .reg_pld_table0 = 0x23, | ||
202 | .reg_pld_table1 = 0x25, | ||
203 | .reg_pld_table2 = 0x27, | ||
204 | .reg_pld_table3 = 0x29, | ||
205 | .reg_pld_table4 = 0x2b, | ||
206 | .reg_advance = 0xad, | ||
207 | }, | ||
208 | .ngpios = 16 | ||
209 | }, | ||
210 | [3] = { /* sx1502q */ | ||
211 | .model = SX150X_123, | ||
212 | .reg_pullup = 0x02, | ||
213 | .reg_pulldn = 0x03, | ||
214 | .reg_dir = 0x01, | ||
215 | .reg_data = 0x00, | ||
216 | .reg_irq_mask = 0x05, | ||
217 | .reg_irq_src = 0x08, | ||
218 | .reg_sense = 0x07, | ||
219 | .pri.x123 = { | ||
220 | .reg_pld_mode = 0x10, | ||
221 | .reg_pld_table0 = 0x11, | ||
222 | .reg_pld_table1 = 0x12, | ||
223 | .reg_pld_table2 = 0x13, | ||
224 | .reg_pld_table3 = 0x14, | ||
225 | .reg_pld_table4 = 0x15, | ||
226 | .reg_advance = 0xad, | ||
227 | }, | ||
228 | .ngpios = 8, | ||
229 | }, | ||
230 | }; | ||
231 | |||
232 | static const struct i2c_device_id sx150x_id[] = { | ||
233 | {"sx1508q", 0}, | ||
234 | {"sx1509q", 1}, | ||
235 | {"sx1506q", 2}, | ||
236 | {"sx1502q", 3}, | ||
237 | {} | ||
238 | }; | ||
239 | |||
240 | static const struct of_device_id sx150x_of_match[] = { | ||
241 | { .compatible = "semtech,sx1508q" }, | ||
242 | { .compatible = "semtech,sx1509q" }, | ||
243 | { .compatible = "semtech,sx1506q" }, | ||
244 | { .compatible = "semtech,sx1502q" }, | ||
245 | {}, | ||
246 | }; | ||
247 | |||
248 | static s32 sx150x_i2c_write(struct i2c_client *client, u8 reg, u8 val) | ||
249 | { | ||
250 | s32 err = i2c_smbus_write_byte_data(client, reg, val); | ||
251 | |||
252 | if (err < 0) | ||
253 | dev_warn(&client->dev, | ||
254 | "i2c write fail: can't write %02x to %02x: %d\n", | ||
255 | val, reg, err); | ||
256 | return err; | ||
257 | } | ||
258 | |||
259 | static s32 sx150x_i2c_read(struct i2c_client *client, u8 reg, u8 *val) | ||
260 | { | ||
261 | s32 err = i2c_smbus_read_byte_data(client, reg); | ||
262 | |||
263 | if (err >= 0) | ||
264 | *val = err; | ||
265 | else | ||
266 | dev_warn(&client->dev, | ||
267 | "i2c read fail: can't read from %02x: %d\n", | ||
268 | reg, err); | ||
269 | return err; | ||
270 | } | ||
271 | |||
272 | static inline bool offset_is_oscio(struct sx150x_chip *chip, unsigned offset) | ||
273 | { | ||
274 | return (chip->dev_cfg->ngpios == offset); | ||
275 | } | ||
276 | |||
277 | /* | ||
278 | * These utility functions solve the common problem of locating and setting | ||
279 | * configuration bits. Configuration bits are grouped into registers | ||
280 | * whose indexes increase downwards. For example, with eight-bit registers, | ||
281 | * sixteen gpios would have their config bits grouped in the following order: | ||
282 | * REGISTER N-1 [ f e d c b a 9 8 ] | ||
283 | * N [ 7 6 5 4 3 2 1 0 ] | ||
284 | * | ||
285 | * For multi-bit configurations, the pattern gets wider: | ||
286 | * REGISTER N-3 [ f f e e d d c c ] | ||
287 | * N-2 [ b b a a 9 9 8 8 ] | ||
288 | * N-1 [ 7 7 6 6 5 5 4 4 ] | ||
289 | * N [ 3 3 2 2 1 1 0 0 ] | ||
290 | * | ||
291 | * Given the address of the starting register 'N', the index of the gpio | ||
292 | * whose configuration we seek to change, and the width in bits of that | ||
293 | * configuration, these functions allow us to locate the correct | ||
294 | * register and mask the correct bits. | ||
295 | */ | ||
296 | static inline void sx150x_find_cfg(u8 offset, u8 width, | ||
297 | u8 *reg, u8 *mask, u8 *shift) | ||
298 | { | ||
299 | *reg -= offset * width / 8; | ||
300 | *mask = (1 << width) - 1; | ||
301 | *shift = (offset * width) % 8; | ||
302 | *mask <<= *shift; | ||
303 | } | ||
304 | |||
305 | static s32 sx150x_write_cfg(struct sx150x_chip *chip, | ||
306 | u8 offset, u8 width, u8 reg, u8 val) | ||
307 | { | ||
308 | u8 mask; | ||
309 | u8 data; | ||
310 | u8 shift; | ||
311 | s32 err; | ||
312 | |||
313 | sx150x_find_cfg(offset, width, ®, &mask, &shift); | ||
314 | err = sx150x_i2c_read(chip->client, reg, &data); | ||
315 | if (err < 0) | ||
316 | return err; | ||
317 | |||
318 | data &= ~mask; | ||
319 | data |= (val << shift) & mask; | ||
320 | return sx150x_i2c_write(chip->client, reg, data); | ||
321 | } | ||
322 | |||
323 | static int sx150x_get_io(struct sx150x_chip *chip, unsigned offset) | ||
324 | { | ||
325 | u8 reg = chip->dev_cfg->reg_data; | ||
326 | u8 mask; | ||
327 | u8 data; | ||
328 | u8 shift; | ||
329 | s32 err; | ||
330 | |||
331 | sx150x_find_cfg(offset, 1, ®, &mask, &shift); | ||
332 | err = sx150x_i2c_read(chip->client, reg, &data); | ||
333 | if (err >= 0) | ||
334 | err = (data & mask) != 0 ? 1 : 0; | ||
335 | |||
336 | return err; | ||
337 | } | ||
338 | |||
339 | static void sx150x_set_oscio(struct sx150x_chip *chip, int val) | ||
340 | { | ||
341 | sx150x_i2c_write(chip->client, | ||
342 | chip->dev_cfg->pri.x789.reg_clock, | ||
343 | (val ? 0x1f : 0x10)); | ||
344 | } | ||
345 | |||
346 | static void sx150x_set_io(struct sx150x_chip *chip, unsigned offset, int val) | ||
347 | { | ||
348 | sx150x_write_cfg(chip, | ||
349 | offset, | ||
350 | 1, | ||
351 | chip->dev_cfg->reg_data, | ||
352 | (val ? 1 : 0)); | ||
353 | } | ||
354 | |||
355 | static int sx150x_io_input(struct sx150x_chip *chip, unsigned offset) | ||
356 | { | ||
357 | return sx150x_write_cfg(chip, | ||
358 | offset, | ||
359 | 1, | ||
360 | chip->dev_cfg->reg_dir, | ||
361 | 1); | ||
362 | } | ||
363 | |||
364 | static int sx150x_io_output(struct sx150x_chip *chip, unsigned offset, int val) | ||
365 | { | ||
366 | int err; | ||
367 | |||
368 | err = sx150x_write_cfg(chip, | ||
369 | offset, | ||
370 | 1, | ||
371 | chip->dev_cfg->reg_data, | ||
372 | (val ? 1 : 0)); | ||
373 | if (err >= 0) | ||
374 | err = sx150x_write_cfg(chip, | ||
375 | offset, | ||
376 | 1, | ||
377 | chip->dev_cfg->reg_dir, | ||
378 | 0); | ||
379 | return err; | ||
380 | } | ||
381 | |||
382 | static int sx150x_gpio_get(struct gpio_chip *gc, unsigned offset) | ||
383 | { | ||
384 | struct sx150x_chip *chip = gpiochip_get_data(gc); | ||
385 | int status = -EINVAL; | ||
386 | |||
387 | if (!offset_is_oscio(chip, offset)) { | ||
388 | mutex_lock(&chip->lock); | ||
389 | status = sx150x_get_io(chip, offset); | ||
390 | mutex_unlock(&chip->lock); | ||
391 | } | ||
392 | |||
393 | return (status < 0) ? status : !!status; | ||
394 | } | ||
395 | |||
396 | static void sx150x_gpio_set(struct gpio_chip *gc, unsigned offset, int val) | ||
397 | { | ||
398 | struct sx150x_chip *chip = gpiochip_get_data(gc); | ||
399 | |||
400 | mutex_lock(&chip->lock); | ||
401 | if (offset_is_oscio(chip, offset)) | ||
402 | sx150x_set_oscio(chip, val); | ||
403 | else | ||
404 | sx150x_set_io(chip, offset, val); | ||
405 | mutex_unlock(&chip->lock); | ||
406 | } | ||
407 | |||
408 | static int sx150x_gpio_set_single_ended(struct gpio_chip *gc, | ||
409 | unsigned offset, | ||
410 | enum single_ended_mode mode) | ||
411 | { | ||
412 | struct sx150x_chip *chip = gpiochip_get_data(gc); | ||
413 | |||
414 | /* On the SX160X 789 we can set open drain */ | ||
415 | if (chip->dev_cfg->model != SX150X_789) | ||
416 | return -ENOTSUPP; | ||
417 | |||
418 | if (mode == LINE_MODE_PUSH_PULL) | ||
419 | return sx150x_write_cfg(chip, | ||
420 | offset, | ||
421 | 1, | ||
422 | chip->dev_cfg->pri.x789.reg_drain, | ||
423 | 0); | ||
424 | |||
425 | if (mode == LINE_MODE_OPEN_DRAIN) | ||
426 | return sx150x_write_cfg(chip, | ||
427 | offset, | ||
428 | 1, | ||
429 | chip->dev_cfg->pri.x789.reg_drain, | ||
430 | 1); | ||
431 | return -ENOTSUPP; | ||
432 | } | ||
433 | |||
434 | static int sx150x_gpio_direction_input(struct gpio_chip *gc, unsigned offset) | ||
435 | { | ||
436 | struct sx150x_chip *chip = gpiochip_get_data(gc); | ||
437 | int status = -EINVAL; | ||
438 | |||
439 | if (!offset_is_oscio(chip, offset)) { | ||
440 | mutex_lock(&chip->lock); | ||
441 | status = sx150x_io_input(chip, offset); | ||
442 | mutex_unlock(&chip->lock); | ||
443 | } | ||
444 | return status; | ||
445 | } | ||
446 | |||
447 | static int sx150x_gpio_direction_output(struct gpio_chip *gc, | ||
448 | unsigned offset, | ||
449 | int val) | ||
450 | { | ||
451 | struct sx150x_chip *chip = gpiochip_get_data(gc); | ||
452 | int status = 0; | ||
453 | |||
454 | if (!offset_is_oscio(chip, offset)) { | ||
455 | mutex_lock(&chip->lock); | ||
456 | status = sx150x_io_output(chip, offset, val); | ||
457 | mutex_unlock(&chip->lock); | ||
458 | } | ||
459 | return status; | ||
460 | } | ||
461 | |||
462 | static void sx150x_irq_mask(struct irq_data *d) | ||
463 | { | ||
464 | struct sx150x_chip *chip = gpiochip_get_data(irq_data_get_irq_chip_data(d)); | ||
465 | unsigned n = d->hwirq; | ||
466 | |||
467 | chip->irq_masked |= (1 << n); | ||
468 | chip->irq_update = n; | ||
469 | } | ||
470 | |||
471 | static void sx150x_irq_unmask(struct irq_data *d) | ||
472 | { | ||
473 | struct sx150x_chip *chip = gpiochip_get_data(irq_data_get_irq_chip_data(d)); | ||
474 | unsigned n = d->hwirq; | ||
475 | |||
476 | chip->irq_masked &= ~(1 << n); | ||
477 | chip->irq_update = n; | ||
478 | } | ||
479 | |||
480 | static int sx150x_irq_set_type(struct irq_data *d, unsigned int flow_type) | ||
481 | { | ||
482 | struct sx150x_chip *chip = gpiochip_get_data(irq_data_get_irq_chip_data(d)); | ||
483 | unsigned n, val = 0; | ||
484 | |||
485 | if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) | ||
486 | return -EINVAL; | ||
487 | |||
488 | n = d->hwirq; | ||
489 | |||
490 | if (flow_type & IRQ_TYPE_EDGE_RISING) | ||
491 | val |= 0x1; | ||
492 | if (flow_type & IRQ_TYPE_EDGE_FALLING) | ||
493 | val |= 0x2; | ||
494 | |||
495 | chip->irq_sense &= ~(3UL << (n * 2)); | ||
496 | chip->irq_sense |= val << (n * 2); | ||
497 | chip->irq_update = n; | ||
498 | return 0; | ||
499 | } | ||
500 | |||
501 | static irqreturn_t sx150x_irq_thread_fn(int irq, void *dev_id) | ||
502 | { | ||
503 | struct sx150x_chip *chip = (struct sx150x_chip *)dev_id; | ||
504 | unsigned nhandled = 0; | ||
505 | unsigned sub_irq; | ||
506 | unsigned n; | ||
507 | s32 err; | ||
508 | u8 val; | ||
509 | int i; | ||
510 | |||
511 | for (i = (chip->dev_cfg->ngpios / 8) - 1; i >= 0; --i) { | ||
512 | err = sx150x_i2c_read(chip->client, | ||
513 | chip->dev_cfg->reg_irq_src - i, | ||
514 | &val); | ||
515 | if (err < 0) | ||
516 | continue; | ||
517 | |||
518 | sx150x_i2c_write(chip->client, | ||
519 | chip->dev_cfg->reg_irq_src - i, | ||
520 | val); | ||
521 | for (n = 0; n < 8; ++n) { | ||
522 | if (val & (1 << n)) { | ||
523 | sub_irq = irq_find_mapping( | ||
524 | chip->gpio_chip.irqdomain, | ||
525 | (i * 8) + n); | ||
526 | handle_nested_irq(sub_irq); | ||
527 | ++nhandled; | ||
528 | } | ||
529 | } | ||
530 | } | ||
531 | |||
532 | return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE); | ||
533 | } | ||
534 | |||
535 | static void sx150x_irq_bus_lock(struct irq_data *d) | ||
536 | { | ||
537 | struct sx150x_chip *chip = gpiochip_get_data(irq_data_get_irq_chip_data(d)); | ||
538 | |||
539 | mutex_lock(&chip->lock); | ||
540 | } | ||
541 | |||
542 | static void sx150x_irq_bus_sync_unlock(struct irq_data *d) | ||
543 | { | ||
544 | struct sx150x_chip *chip = gpiochip_get_data(irq_data_get_irq_chip_data(d)); | ||
545 | unsigned n; | ||
546 | |||
547 | if (chip->irq_update == NO_UPDATE_PENDING) | ||
548 | goto out; | ||
549 | |||
550 | n = chip->irq_update; | ||
551 | chip->irq_update = NO_UPDATE_PENDING; | ||
552 | |||
553 | /* Avoid updates if nothing changed */ | ||
554 | if (chip->dev_sense == chip->irq_sense && | ||
555 | chip->dev_masked == chip->irq_masked) | ||
556 | goto out; | ||
557 | |||
558 | chip->dev_sense = chip->irq_sense; | ||
559 | chip->dev_masked = chip->irq_masked; | ||
560 | |||
561 | if (chip->irq_masked & (1 << n)) { | ||
562 | sx150x_write_cfg(chip, n, 1, chip->dev_cfg->reg_irq_mask, 1); | ||
563 | sx150x_write_cfg(chip, n, 2, chip->dev_cfg->reg_sense, 0); | ||
564 | } else { | ||
565 | sx150x_write_cfg(chip, n, 1, chip->dev_cfg->reg_irq_mask, 0); | ||
566 | sx150x_write_cfg(chip, n, 2, chip->dev_cfg->reg_sense, | ||
567 | chip->irq_sense >> (n * 2)); | ||
568 | } | ||
569 | out: | ||
570 | mutex_unlock(&chip->lock); | ||
571 | } | ||
572 | |||
573 | static void sx150x_init_chip(struct sx150x_chip *chip, | ||
574 | struct i2c_client *client, | ||
575 | kernel_ulong_t driver_data, | ||
576 | struct sx150x_platform_data *pdata) | ||
577 | { | ||
578 | mutex_init(&chip->lock); | ||
579 | |||
580 | chip->client = client; | ||
581 | chip->dev_cfg = &sx150x_devices[driver_data]; | ||
582 | chip->gpio_chip.parent = &client->dev; | ||
583 | chip->gpio_chip.label = client->name; | ||
584 | chip->gpio_chip.direction_input = sx150x_gpio_direction_input; | ||
585 | chip->gpio_chip.direction_output = sx150x_gpio_direction_output; | ||
586 | chip->gpio_chip.get = sx150x_gpio_get; | ||
587 | chip->gpio_chip.set = sx150x_gpio_set; | ||
588 | chip->gpio_chip.set_single_ended = sx150x_gpio_set_single_ended; | ||
589 | chip->gpio_chip.base = pdata->gpio_base; | ||
590 | chip->gpio_chip.can_sleep = true; | ||
591 | chip->gpio_chip.ngpio = chip->dev_cfg->ngpios; | ||
592 | #ifdef CONFIG_OF_GPIO | ||
593 | chip->gpio_chip.of_node = client->dev.of_node; | ||
594 | chip->gpio_chip.of_gpio_n_cells = 2; | ||
595 | #endif | ||
596 | if (pdata->oscio_is_gpo) | ||
597 | ++chip->gpio_chip.ngpio; | ||
598 | |||
599 | chip->irq_chip.name = client->name; | ||
600 | chip->irq_chip.irq_mask = sx150x_irq_mask; | ||
601 | chip->irq_chip.irq_unmask = sx150x_irq_unmask; | ||
602 | chip->irq_chip.irq_set_type = sx150x_irq_set_type; | ||
603 | chip->irq_chip.irq_bus_lock = sx150x_irq_bus_lock; | ||
604 | chip->irq_chip.irq_bus_sync_unlock = sx150x_irq_bus_sync_unlock; | ||
605 | chip->irq_summary = -1; | ||
606 | chip->irq_base = -1; | ||
607 | chip->irq_masked = ~0; | ||
608 | chip->irq_sense = 0; | ||
609 | chip->dev_masked = ~0; | ||
610 | chip->dev_sense = 0; | ||
611 | chip->irq_update = NO_UPDATE_PENDING; | ||
612 | } | ||
613 | |||
614 | static int sx150x_init_io(struct sx150x_chip *chip, u8 base, u16 cfg) | ||
615 | { | ||
616 | int err = 0; | ||
617 | unsigned n; | ||
618 | |||
619 | for (n = 0; err >= 0 && n < (chip->dev_cfg->ngpios / 8); ++n) | ||
620 | err = sx150x_i2c_write(chip->client, base - n, cfg >> (n * 8)); | ||
621 | return err; | ||
622 | } | ||
623 | |||
624 | static int sx150x_reset(struct sx150x_chip *chip) | ||
625 | { | ||
626 | int err; | ||
627 | |||
628 | err = i2c_smbus_write_byte_data(chip->client, | ||
629 | chip->dev_cfg->pri.x789.reg_reset, | ||
630 | 0x12); | ||
631 | if (err < 0) | ||
632 | return err; | ||
633 | |||
634 | err = i2c_smbus_write_byte_data(chip->client, | ||
635 | chip->dev_cfg->pri.x789.reg_reset, | ||
636 | 0x34); | ||
637 | return err; | ||
638 | } | ||
639 | |||
640 | static int sx150x_init_hw(struct sx150x_chip *chip, | ||
641 | struct sx150x_platform_data *pdata) | ||
642 | { | ||
643 | int err = 0; | ||
644 | |||
645 | if (pdata->reset_during_probe) { | ||
646 | err = sx150x_reset(chip); | ||
647 | if (err < 0) | ||
648 | return err; | ||
649 | } | ||
650 | |||
651 | if (chip->dev_cfg->model == SX150X_789) | ||
652 | err = sx150x_i2c_write(chip->client, | ||
653 | chip->dev_cfg->pri.x789.reg_misc, | ||
654 | 0x01); | ||
655 | else if (chip->dev_cfg->model == SX150X_456) | ||
656 | err = sx150x_i2c_write(chip->client, | ||
657 | chip->dev_cfg->pri.x456.reg_advance, | ||
658 | 0x04); | ||
659 | else | ||
660 | err = sx150x_i2c_write(chip->client, | ||
661 | chip->dev_cfg->pri.x123.reg_advance, | ||
662 | 0x00); | ||
663 | if (err < 0) | ||
664 | return err; | ||
665 | |||
666 | err = sx150x_init_io(chip, chip->dev_cfg->reg_pullup, | ||
667 | pdata->io_pullup_ena); | ||
668 | if (err < 0) | ||
669 | return err; | ||
670 | |||
671 | err = sx150x_init_io(chip, chip->dev_cfg->reg_pulldn, | ||
672 | pdata->io_pulldn_ena); | ||
673 | if (err < 0) | ||
674 | return err; | ||
675 | |||
676 | if (chip->dev_cfg->model == SX150X_789) { | ||
677 | err = sx150x_init_io(chip, | ||
678 | chip->dev_cfg->pri.x789.reg_polarity, | ||
679 | pdata->io_polarity); | ||
680 | if (err < 0) | ||
681 | return err; | ||
682 | } else if (chip->dev_cfg->model == SX150X_456) { | ||
683 | /* Set all pins to work in normal mode */ | ||
684 | err = sx150x_init_io(chip, | ||
685 | chip->dev_cfg->pri.x456.reg_pld_mode, | ||
686 | 0); | ||
687 | if (err < 0) | ||
688 | return err; | ||
689 | } else { | ||
690 | /* Set all pins to work in normal mode */ | ||
691 | err = sx150x_init_io(chip, | ||
692 | chip->dev_cfg->pri.x123.reg_pld_mode, | ||
693 | 0); | ||
694 | if (err < 0) | ||
695 | return err; | ||
696 | } | ||
697 | |||
698 | |||
699 | if (pdata->oscio_is_gpo) | ||
700 | sx150x_set_oscio(chip, 0); | ||
701 | |||
702 | return err; | ||
703 | } | ||
704 | |||
705 | static int sx150x_install_irq_chip(struct sx150x_chip *chip, | ||
706 | int irq_summary, | ||
707 | int irq_base) | ||
708 | { | ||
709 | int err; | ||
710 | |||
711 | chip->irq_summary = irq_summary; | ||
712 | chip->irq_base = irq_base; | ||
713 | |||
714 | /* Add gpio chip to irq subsystem */ | ||
715 | err = gpiochip_irqchip_add(&chip->gpio_chip, | ||
716 | &chip->irq_chip, chip->irq_base, | ||
717 | handle_edge_irq, IRQ_TYPE_EDGE_BOTH); | ||
718 | if (err) { | ||
719 | dev_err(&chip->client->dev, | ||
720 | "could not connect irqchip to gpiochip\n"); | ||
721 | return err; | ||
722 | } | ||
723 | |||
724 | err = devm_request_threaded_irq(&chip->client->dev, | ||
725 | irq_summary, NULL, sx150x_irq_thread_fn, | ||
726 | IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_FALLING, | ||
727 | chip->irq_chip.name, chip); | ||
728 | if (err < 0) { | ||
729 | chip->irq_summary = -1; | ||
730 | chip->irq_base = -1; | ||
731 | } | ||
732 | |||
733 | return err; | ||
734 | } | ||
735 | |||
736 | static int sx150x_probe(struct i2c_client *client, | ||
737 | const struct i2c_device_id *id) | ||
738 | { | ||
739 | static const u32 i2c_funcs = I2C_FUNC_SMBUS_BYTE_DATA | | ||
740 | I2C_FUNC_SMBUS_WRITE_WORD_DATA; | ||
741 | struct sx150x_platform_data *pdata; | ||
742 | struct sx150x_chip *chip; | ||
743 | int rc; | ||
744 | |||
745 | pdata = dev_get_platdata(&client->dev); | ||
746 | if (!pdata) | ||
747 | return -EINVAL; | ||
748 | |||
749 | if (!i2c_check_functionality(client->adapter, i2c_funcs)) | ||
750 | return -ENOSYS; | ||
751 | |||
752 | chip = devm_kzalloc(&client->dev, | ||
753 | sizeof(struct sx150x_chip), GFP_KERNEL); | ||
754 | if (!chip) | ||
755 | return -ENOMEM; | ||
756 | |||
757 | sx150x_init_chip(chip, client, id->driver_data, pdata); | ||
758 | rc = sx150x_init_hw(chip, pdata); | ||
759 | if (rc < 0) | ||
760 | return rc; | ||
761 | |||
762 | rc = devm_gpiochip_add_data(&client->dev, &chip->gpio_chip, chip); | ||
763 | if (rc) | ||
764 | return rc; | ||
765 | |||
766 | if (pdata->irq_summary >= 0) { | ||
767 | rc = sx150x_install_irq_chip(chip, | ||
768 | pdata->irq_summary, | ||
769 | pdata->irq_base); | ||
770 | if (rc < 0) | ||
771 | return rc; | ||
772 | } | ||
773 | |||
774 | i2c_set_clientdata(client, chip); | ||
775 | |||
776 | return 0; | ||
777 | } | ||
778 | |||
779 | static struct i2c_driver sx150x_driver = { | ||
780 | .driver = { | ||
781 | .name = "sx150x", | ||
782 | .of_match_table = of_match_ptr(sx150x_of_match), | ||
783 | }, | ||
784 | .probe = sx150x_probe, | ||
785 | .id_table = sx150x_id, | ||
786 | }; | ||
787 | |||
788 | static int __init sx150x_init(void) | ||
789 | { | ||
790 | return i2c_add_driver(&sx150x_driver); | ||
791 | } | ||
792 | subsys_initcall(sx150x_init); | ||