diff options
author | Linus Walleij <linus.walleij@linaro.org> | 2014-12-16 01:23:40 -0500 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2014-12-16 01:25:38 -0500 |
commit | 7c12a5b19e13ee78c3acb759f264df87ad984ffa (patch) | |
tree | 04a8e8de26f3db29ef1bf85f8189fb3843732673 /drivers/input | |
parent | a4164863e150c4991d2ac965e3fc52f9d8df3d7e (diff) |
Input: stmpe - bias keypad columns properly
All keypad column pins used as inputs should be pulled up on the STMPE24xx,
but this is not done by the current driver. Add some logic that will do
this properly. The STMPE1601 also has a keypad controller, but explicitly
does *NOT* require you to set up any pull-ups.
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/keyboard/stmpe-keypad.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/drivers/input/keyboard/stmpe-keypad.c b/drivers/input/keyboard/stmpe-keypad.c index 8d1e7af3c5b1..64514e64d557 100644 --- a/drivers/input/keyboard/stmpe-keypad.c +++ b/drivers/input/keyboard/stmpe-keypad.c | |||
@@ -52,6 +52,7 @@ | |||
52 | * struct stmpe_keypad_variant - model-specific attributes | 52 | * struct stmpe_keypad_variant - model-specific attributes |
53 | * @auto_increment: whether the KPC_DATA_BYTE register address | 53 | * @auto_increment: whether the KPC_DATA_BYTE register address |
54 | * auto-increments on multiple read | 54 | * auto-increments on multiple read |
55 | * @set_pullup: whether the pins need to have their pull-ups set | ||
55 | * @num_data: number of data bytes | 56 | * @num_data: number of data bytes |
56 | * @num_normal_data: number of normal keys' data bytes | 57 | * @num_normal_data: number of normal keys' data bytes |
57 | * @max_cols: maximum number of columns supported | 58 | * @max_cols: maximum number of columns supported |
@@ -61,6 +62,7 @@ | |||
61 | */ | 62 | */ |
62 | struct stmpe_keypad_variant { | 63 | struct stmpe_keypad_variant { |
63 | bool auto_increment; | 64 | bool auto_increment; |
65 | bool set_pullup; | ||
64 | int num_data; | 66 | int num_data; |
65 | int num_normal_data; | 67 | int num_normal_data; |
66 | int max_cols; | 68 | int max_cols; |
@@ -81,6 +83,7 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = { | |||
81 | }, | 83 | }, |
82 | [STMPE2401] = { | 84 | [STMPE2401] = { |
83 | .auto_increment = false, | 85 | .auto_increment = false, |
86 | .set_pullup = true, | ||
84 | .num_data = 3, | 87 | .num_data = 3, |
85 | .num_normal_data = 2, | 88 | .num_normal_data = 2, |
86 | .max_cols = 8, | 89 | .max_cols = 8, |
@@ -90,6 +93,7 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = { | |||
90 | }, | 93 | }, |
91 | [STMPE2403] = { | 94 | [STMPE2403] = { |
92 | .auto_increment = true, | 95 | .auto_increment = true, |
96 | .set_pullup = true, | ||
93 | .num_data = 5, | 97 | .num_data = 5, |
94 | .num_normal_data = 3, | 98 | .num_normal_data = 3, |
95 | .max_cols = 8, | 99 | .max_cols = 8, |
@@ -185,7 +189,10 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad) | |||
185 | unsigned int col_gpios = variant->col_gpios; | 189 | unsigned int col_gpios = variant->col_gpios; |
186 | unsigned int row_gpios = variant->row_gpios; | 190 | unsigned int row_gpios = variant->row_gpios; |
187 | struct stmpe *stmpe = keypad->stmpe; | 191 | struct stmpe *stmpe = keypad->stmpe; |
192 | u8 pureg = stmpe->regs[STMPE_IDX_GPPUR_LSB]; | ||
188 | unsigned int pins = 0; | 193 | unsigned int pins = 0; |
194 | unsigned int pu_pins = 0; | ||
195 | int ret; | ||
189 | int i; | 196 | int i; |
190 | 197 | ||
191 | /* | 198 | /* |
@@ -202,8 +209,10 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad) | |||
202 | for (i = 0; i < variant->max_cols; i++) { | 209 | for (i = 0; i < variant->max_cols; i++) { |
203 | int num = __ffs(col_gpios); | 210 | int num = __ffs(col_gpios); |
204 | 211 | ||
205 | if (keypad->cols & (1 << i)) | 212 | if (keypad->cols & (1 << i)) { |
206 | pins |= 1 << num; | 213 | pins |= 1 << num; |
214 | pu_pins |= 1 << num; | ||
215 | } | ||
207 | 216 | ||
208 | col_gpios &= ~(1 << num); | 217 | col_gpios &= ~(1 << num); |
209 | } | 218 | } |
@@ -217,7 +226,31 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad) | |||
217 | row_gpios &= ~(1 << num); | 226 | row_gpios &= ~(1 << num); |
218 | } | 227 | } |
219 | 228 | ||
220 | return stmpe_set_altfunc(stmpe, pins, STMPE_BLOCK_KEYPAD); | 229 | ret = stmpe_set_altfunc(stmpe, pins, STMPE_BLOCK_KEYPAD); |
230 | if (ret) | ||
231 | return ret; | ||
232 | |||
233 | /* | ||
234 | * On STMPE24xx, set pin bias to pull-up on all keypad input | ||
235 | * pins (columns), this incidentally happen to be maximum 8 pins | ||
236 | * and placed at GPIO0-7 so only the LSB of the pull up register | ||
237 | * ever needs to be written. | ||
238 | */ | ||
239 | if (variant->set_pullup) { | ||
240 | u8 val; | ||
241 | |||
242 | ret = stmpe_reg_read(stmpe, pureg); | ||
243 | if (ret) | ||
244 | return ret; | ||
245 | |||
246 | /* Do not touch unused pins, may be used for GPIO */ | ||
247 | val = ret & ~pu_pins; | ||
248 | val |= pu_pins; | ||
249 | |||
250 | ret = stmpe_reg_write(stmpe, pureg, val); | ||
251 | } | ||
252 | |||
253 | return 0; | ||
221 | } | 254 | } |
222 | 255 | ||
223 | static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad) | 256 | static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad) |