diff options
author | Patrice Chotard <patrice.chotard@st.com> | 2016-08-10 03:39:08 -0400 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2016-08-10 04:23:40 -0400 |
commit | 287849cb3814a5077c79a2489bef055c9f5e656c (patch) | |
tree | 534417dce8ef21700992b2e66d53ca10c1491327 /drivers/gpio/gpio-stmpe.c | |
parent | c4dd1ba355aae2bc3d1213da6c66c53e3c31e028 (diff) |
gpio: stmpe: Fix edge and rising/falling edge detection
By cross-checking STMPE 610/801/811/1601/2401/2403 datasheets,
it appears that edge detection and rising/falling edge detection
is not supported by all STMPE variant:
GPIO GPIO
Edge detection rising/falling
edge detection
610 | X | X |
801 | | |
811 | X | X |
1600 | | |
1601 | X | X |
1801 | | X |
2401 | X | X |
2403 | X | X |
Rework stmpe_dbg_show_one() and stmpe_gpio_irq to correctly
take these cases into account.
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers/gpio/gpio-stmpe.c')
-rw-r--r-- | drivers/gpio/gpio-stmpe.c | 85 |
1 files changed, 60 insertions, 25 deletions
diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index f675132de10e..fdac5d9e5b8d 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c | |||
@@ -247,39 +247,74 @@ static void stmpe_dbg_show_one(struct seq_file *s, | |||
247 | gpio, label ?: "(none)", | 247 | gpio, label ?: "(none)", |
248 | val ? "hi" : "lo"); | 248 | val ? "hi" : "lo"); |
249 | } else { | 249 | } else { |
250 | u8 edge_det_reg = stmpe->regs[STMPE_IDX_GPEDR_MSB] + num_banks - 1 - (offset / 8); | 250 | u8 edge_det_reg; |
251 | u8 rise_reg = stmpe->regs[STMPE_IDX_GPRER_LSB] - (offset / 8); | 251 | u8 rise_reg; |
252 | u8 fall_reg = stmpe->regs[STMPE_IDX_GPFER_LSB] - (offset / 8); | 252 | u8 fall_reg; |
253 | u8 irqen_reg = stmpe->regs[STMPE_IDX_IEGPIOR_LSB] - (offset / 8); | 253 | u8 irqen_reg; |
254 | bool edge_det; | 254 | |
255 | bool rise; | 255 | char *edge_det_values[] = {"edge-inactive", |
256 | bool fall; | 256 | "edge-asserted", |
257 | "not-supported"}; | ||
258 | char *rise_values[] = {"no-rising-edge-detection", | ||
259 | "rising-edge-detection", | ||
260 | "not-supported"}; | ||
261 | char *fall_values[] = {"no-falling-edge-detection", | ||
262 | "falling-edge-detection", | ||
263 | "not-supported"}; | ||
264 | #define NOT_SUPPORTED_IDX 2 | ||
265 | u8 edge_det = NOT_SUPPORTED_IDX; | ||
266 | u8 rise = NOT_SUPPORTED_IDX; | ||
267 | u8 fall = NOT_SUPPORTED_IDX; | ||
257 | bool irqen; | 268 | bool irqen; |
258 | 269 | ||
259 | ret = stmpe_reg_read(stmpe, edge_det_reg); | 270 | switch (stmpe->partnum) { |
260 | if (ret < 0) | 271 | case STMPE610: |
261 | return; | 272 | case STMPE811: |
262 | edge_det = !!(ret & mask); | 273 | case STMPE1601: |
263 | ret = stmpe_reg_read(stmpe, rise_reg); | 274 | case STMPE2401: |
264 | if (ret < 0) | 275 | case STMPE2403: |
276 | edge_det_reg = stmpe->regs[STMPE_IDX_GPEDR_MSB] + | ||
277 | num_banks - 1 - (offset / 8); | ||
278 | ret = stmpe_reg_read(stmpe, edge_det_reg); | ||
279 | if (ret < 0) | ||
280 | return; | ||
281 | edge_det = !!(ret & mask); | ||
282 | |||
283 | case STMPE1801: | ||
284 | rise_reg = stmpe->regs[STMPE_IDX_GPRER_LSB] - | ||
285 | (offset / 8); | ||
286 | fall_reg = stmpe->regs[STMPE_IDX_GPFER_LSB] - | ||
287 | (offset / 8); | ||
288 | ret = stmpe_reg_read(stmpe, rise_reg); | ||
289 | if (ret < 0) | ||
290 | return; | ||
291 | rise = !!(ret & mask); | ||
292 | ret = stmpe_reg_read(stmpe, fall_reg); | ||
293 | if (ret < 0) | ||
294 | return; | ||
295 | fall = !!(ret & mask); | ||
296 | |||
297 | case STMPE801: | ||
298 | irqen_reg = stmpe->regs[STMPE_IDX_IEGPIOR_LSB] - | ||
299 | (offset / 8); | ||
300 | break; | ||
301 | |||
302 | default: | ||
265 | return; | 303 | return; |
266 | rise = !!(ret & mask); | 304 | } |
267 | ret = stmpe_reg_read(stmpe, fall_reg); | 305 | |
268 | if (ret < 0) | ||
269 | return; | ||
270 | fall = !!(ret & mask); | ||
271 | ret = stmpe_reg_read(stmpe, irqen_reg); | 306 | ret = stmpe_reg_read(stmpe, irqen_reg); |
272 | if (ret < 0) | 307 | if (ret < 0) |
273 | return; | 308 | return; |
274 | irqen = !!(ret & mask); | 309 | irqen = !!(ret & mask); |
275 | 310 | ||
276 | seq_printf(s, " gpio-%-3d (%-20.20s) in %s %s %s%s%s", | 311 | seq_printf(s, " gpio-%-3d (%-20.20s) in %s %13s %13s %25s %25s", |
277 | gpio, label ?: "(none)", | 312 | gpio, label ?: "(none)", |
278 | val ? "hi" : "lo", | 313 | val ? "hi" : "lo", |
279 | edge_det ? "edge-asserted" : "edge-inactive", | 314 | edge_det_values[edge_det], |
280 | irqen ? "IRQ-enabled" : "", | 315 | irqen ? "IRQ-enabled" : "IRQ-disabled", |
281 | rise ? " rising-edge-detection" : "", | 316 | rise_values[rise], |
282 | fall ? " falling-edge-detection" : ""); | 317 | fall_values[fall]); |
283 | } | 318 | } |
284 | } | 319 | } |
285 | 320 | ||
@@ -338,8 +373,8 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) | |||
338 | 373 | ||
339 | stmpe_reg_write(stmpe, statmsbreg + i, status[i]); | 374 | stmpe_reg_write(stmpe, statmsbreg + i, status[i]); |
340 | 375 | ||
341 | /* Edge detect register is not present on 801 */ | 376 | /* Edge detect register is not present on 801 and 1801 */ |
342 | if (stmpe->partnum != STMPE801) | 377 | if (stmpe->partnum != STMPE801 || stmpe->partnum != STMPE1801) |
343 | stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_GPEDR_MSB] | 378 | stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_GPEDR_MSB] |
344 | + i, status[i]); | 379 | + i, status[i]); |
345 | } | 380 | } |