Commit | Line | Data |
---|---|---|
39325b59 TS |
1 | /* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved. |
2 | * | |
3 | * This program is free software; you can redistribute it and/or modify | |
4 | * it under the terms of the GNU General Public License version 2 and | |
5 | * only version 2 as published by the Free Software Foundation. | |
6 | * | |
7 | * This program is distributed in the hope that it will be useful, | |
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
10 | * GNU General Public License for more details. | |
11 | */ | |
12 | ||
13 | #include <linux/module.h> | |
14 | #include <linux/platform_device.h> | |
15 | #include <linux/kernel.h> | |
16 | #include <linux/interrupt.h> | |
17 | #include <linux/slab.h> | |
18 | #include <linux/input.h> | |
19 | #include <linux/bitops.h> | |
20 | #include <linux/delay.h> | |
21 | #include <linux/mutex.h> | |
a5dde0c7 | 22 | #include <linux/regmap.h> |
39325b59 | 23 | |
39325b59 TS |
24 | #include <linux/input/pmic8xxx-keypad.h> |
25 | ||
26 | #define PM8XXX_MAX_ROWS 18 | |
27 | #define PM8XXX_MAX_COLS 8 | |
28 | #define PM8XXX_ROW_SHIFT 3 | |
29 | #define PM8XXX_MATRIX_MAX_SIZE (PM8XXX_MAX_ROWS * PM8XXX_MAX_COLS) | |
30 | ||
31 | #define PM8XXX_MIN_ROWS 5 | |
32 | #define PM8XXX_MIN_COLS 5 | |
33 | ||
34 | #define MAX_SCAN_DELAY 128 | |
35 | #define MIN_SCAN_DELAY 1 | |
36 | ||
37 | /* in nanoseconds */ | |
38 | #define MAX_ROW_HOLD_DELAY 122000 | |
39 | #define MIN_ROW_HOLD_DELAY 30500 | |
40 | ||
41 | #define MAX_DEBOUNCE_TIME 20 | |
42 | #define MIN_DEBOUNCE_TIME 5 | |
43 | ||
44 | #define KEYP_CTRL 0x148 | |
45 | ||
46 | #define KEYP_CTRL_EVNTS BIT(0) | |
47 | #define KEYP_CTRL_EVNTS_MASK 0x3 | |
48 | ||
49 | #define KEYP_CTRL_SCAN_COLS_SHIFT 5 | |
50 | #define KEYP_CTRL_SCAN_COLS_MIN 5 | |
51 | #define KEYP_CTRL_SCAN_COLS_BITS 0x3 | |
52 | ||
53 | #define KEYP_CTRL_SCAN_ROWS_SHIFT 2 | |
54 | #define KEYP_CTRL_SCAN_ROWS_MIN 5 | |
55 | #define KEYP_CTRL_SCAN_ROWS_BITS 0x7 | |
56 | ||
57 | #define KEYP_CTRL_KEYP_EN BIT(7) | |
58 | ||
59 | #define KEYP_SCAN 0x149 | |
60 | ||
61 | #define KEYP_SCAN_READ_STATE BIT(0) | |
62 | #define KEYP_SCAN_DBOUNCE_SHIFT 1 | |
63 | #define KEYP_SCAN_PAUSE_SHIFT 3 | |
64 | #define KEYP_SCAN_ROW_HOLD_SHIFT 6 | |
65 | ||
66 | #define KEYP_TEST 0x14A | |
67 | ||
68 | #define KEYP_TEST_CLEAR_RECENT_SCAN BIT(6) | |
69 | #define KEYP_TEST_CLEAR_OLD_SCAN BIT(5) | |
70 | #define KEYP_TEST_READ_RESET BIT(4) | |
71 | #define KEYP_TEST_DTEST_EN BIT(3) | |
72 | #define KEYP_TEST_ABORT_READ BIT(0) | |
73 | ||
74 | #define KEYP_TEST_DBG_SELECT_SHIFT 1 | |
75 | ||
76 | /* bits of these registers represent | |
77 | * '0' for key press | |
78 | * '1' for key release | |
79 | */ | |
80 | #define KEYP_RECENT_DATA 0x14B | |
81 | #define KEYP_OLD_DATA 0x14C | |
82 | ||
83 | #define KEYP_CLOCK_FREQ 32768 | |
84 | ||
85 | /** | |
86 | * struct pmic8xxx_kp - internal keypad data structure | |
87 | * @pdata - keypad platform data pointer | |
88 | * @input - input device pointer for keypad | |
a5dde0c7 | 89 | * @regmap - regmap handle |
39325b59 TS |
90 | * @key_sense_irq - key press/release irq number |
91 | * @key_stuck_irq - key stuck notification irq number | |
92 | * @keycodes - array to hold the key codes | |
93 | * @dev - parent device pointer | |
94 | * @keystate - present key press/release state | |
95 | * @stuckstate - present state when key stuck irq | |
96 | * @ctrl_reg - control register value | |
97 | */ | |
98 | struct pmic8xxx_kp { | |
99 | const struct pm8xxx_keypad_platform_data *pdata; | |
100 | struct input_dev *input; | |
a5dde0c7 | 101 | struct regmap *regmap; |
39325b59 TS |
102 | int key_sense_irq; |
103 | int key_stuck_irq; | |
104 | ||
105 | unsigned short keycodes[PM8XXX_MATRIX_MAX_SIZE]; | |
106 | ||
107 | struct device *dev; | |
108 | u16 keystate[PM8XXX_MAX_ROWS]; | |
109 | u16 stuckstate[PM8XXX_MAX_ROWS]; | |
110 | ||
111 | u8 ctrl_reg; | |
112 | }; | |
113 | ||
39325b59 TS |
114 | static u8 pmic8xxx_col_state(struct pmic8xxx_kp *kp, u8 col) |
115 | { | |
116 | /* all keys pressed on that particular row? */ | |
117 | if (col == 0x00) | |
118 | return 1 << kp->pdata->num_cols; | |
119 | else | |
120 | return col & ((1 << kp->pdata->num_cols) - 1); | |
121 | } | |
122 | ||
123 | /* | |
124 | * Synchronous read protocol for RevB0 onwards: | |
125 | * | |
126 | * 1. Write '1' to ReadState bit in KEYP_SCAN register | |
127 | * 2. Wait 2*32KHz clocks, so that HW can successfully enter read mode | |
128 | * synchronously | |
129 | * 3. Read rows in old array first if events are more than one | |
130 | * 4. Read rows in recent array | |
131 | * 5. Wait 4*32KHz clocks | |
132 | * 6. Write '0' to ReadState bit of KEYP_SCAN register so that hw can | |
133 | * synchronously exit read mode. | |
134 | */ | |
135 | static int pmic8xxx_chk_sync_read(struct pmic8xxx_kp *kp) | |
136 | { | |
137 | int rc; | |
a5dde0c7 | 138 | unsigned int scan_val; |
39325b59 | 139 | |
a5dde0c7 | 140 | rc = regmap_read(kp->regmap, KEYP_SCAN, &scan_val); |
39325b59 TS |
141 | if (rc < 0) { |
142 | dev_err(kp->dev, "Error reading KEYP_SCAN reg, rc=%d\n", rc); | |
143 | return rc; | |
144 | } | |
145 | ||
146 | scan_val |= 0x1; | |
147 | ||
a5dde0c7 | 148 | rc = regmap_write(kp->regmap, KEYP_SCAN, scan_val); |
39325b59 TS |
149 | if (rc < 0) { |
150 | dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); | |
151 | return rc; | |
152 | } | |
153 | ||
154 | /* 2 * 32KHz clocks */ | |
155 | udelay((2 * DIV_ROUND_UP(USEC_PER_SEC, KEYP_CLOCK_FREQ)) + 1); | |
156 | ||
157 | return rc; | |
158 | } | |
159 | ||
160 | static int pmic8xxx_kp_read_data(struct pmic8xxx_kp *kp, u16 *state, | |
161 | u16 data_reg, int read_rows) | |
162 | { | |
163 | int rc, row; | |
a5dde0c7 | 164 | unsigned int val; |
39325b59 | 165 | |
a5dde0c7 SB |
166 | for (row = 0; row < read_rows; row++) { |
167 | rc = regmap_read(kp->regmap, data_reg, &val); | |
168 | if (rc) | |
169 | return rc; | |
170 | dev_dbg(kp->dev, "%d = %d\n", row, val); | |
171 | state[row] = pmic8xxx_col_state(kp, val); | |
39325b59 TS |
172 | } |
173 | ||
a5dde0c7 | 174 | return 0; |
39325b59 TS |
175 | } |
176 | ||
177 | static int pmic8xxx_kp_read_matrix(struct pmic8xxx_kp *kp, u16 *new_state, | |
178 | u16 *old_state) | |
179 | { | |
180 | int rc, read_rows; | |
a5dde0c7 | 181 | unsigned int scan_val; |
39325b59 TS |
182 | |
183 | if (kp->pdata->num_rows < PM8XXX_MIN_ROWS) | |
184 | read_rows = PM8XXX_MIN_ROWS; | |
185 | else | |
186 | read_rows = kp->pdata->num_rows; | |
187 | ||
188 | pmic8xxx_chk_sync_read(kp); | |
189 | ||
190 | if (old_state) { | |
191 | rc = pmic8xxx_kp_read_data(kp, old_state, KEYP_OLD_DATA, | |
192 | read_rows); | |
193 | if (rc < 0) { | |
194 | dev_err(kp->dev, | |
195 | "Error reading KEYP_OLD_DATA, rc=%d\n", rc); | |
196 | return rc; | |
197 | } | |
198 | } | |
199 | ||
200 | rc = pmic8xxx_kp_read_data(kp, new_state, KEYP_RECENT_DATA, | |
201 | read_rows); | |
202 | if (rc < 0) { | |
203 | dev_err(kp->dev, | |
204 | "Error reading KEYP_RECENT_DATA, rc=%d\n", rc); | |
205 | return rc; | |
206 | } | |
207 | ||
208 | /* 4 * 32KHz clocks */ | |
209 | udelay((4 * DIV_ROUND_UP(USEC_PER_SEC, KEYP_CLOCK_FREQ)) + 1); | |
210 | ||
a5dde0c7 | 211 | rc = regmap_read(kp->regmap, KEYP_SCAN, &scan_val); |
39325b59 TS |
212 | if (rc < 0) { |
213 | dev_err(kp->dev, "Error reading KEYP_SCAN reg, rc=%d\n", rc); | |
214 | return rc; | |
215 | } | |
216 | ||
217 | scan_val &= 0xFE; | |
a5dde0c7 | 218 | rc = regmap_write(kp->regmap, KEYP_SCAN, scan_val); |
39325b59 TS |
219 | if (rc < 0) |
220 | dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); | |
221 | ||
222 | return rc; | |
223 | } | |
224 | ||
225 | static void __pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, u16 *new_state, | |
226 | u16 *old_state) | |
227 | { | |
228 | int row, col, code; | |
229 | ||
230 | for (row = 0; row < kp->pdata->num_rows; row++) { | |
231 | int bits_changed = new_state[row] ^ old_state[row]; | |
232 | ||
233 | if (!bits_changed) | |
234 | continue; | |
235 | ||
236 | for (col = 0; col < kp->pdata->num_cols; col++) { | |
237 | if (!(bits_changed & (1 << col))) | |
238 | continue; | |
239 | ||
240 | dev_dbg(kp->dev, "key [%d:%d] %s\n", row, col, | |
241 | !(new_state[row] & (1 << col)) ? | |
242 | "pressed" : "released"); | |
243 | ||
244 | code = MATRIX_SCAN_CODE(row, col, PM8XXX_ROW_SHIFT); | |
245 | ||
246 | input_event(kp->input, EV_MSC, MSC_SCAN, code); | |
247 | input_report_key(kp->input, | |
248 | kp->keycodes[code], | |
249 | !(new_state[row] & (1 << col))); | |
250 | ||
251 | input_sync(kp->input); | |
252 | } | |
253 | } | |
254 | } | |
255 | ||
256 | static bool pmic8xxx_detect_ghost_keys(struct pmic8xxx_kp *kp, u16 *new_state) | |
257 | { | |
258 | int row, found_first = -1; | |
259 | u16 check, row_state; | |
260 | ||
261 | check = 0; | |
262 | for (row = 0; row < kp->pdata->num_rows; row++) { | |
263 | row_state = (~new_state[row]) & | |
264 | ((1 << kp->pdata->num_cols) - 1); | |
265 | ||
266 | if (hweight16(row_state) > 1) { | |
267 | if (found_first == -1) | |
268 | found_first = row; | |
269 | if (check & row_state) { | |
270 | dev_dbg(kp->dev, "detected ghost key on row[%d]" | |
271 | " and row[%d]\n", found_first, row); | |
272 | return true; | |
273 | } | |
274 | } | |
275 | check |= row_state; | |
276 | } | |
277 | return false; | |
278 | } | |
279 | ||
280 | static int pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, unsigned int events) | |
281 | { | |
282 | u16 new_state[PM8XXX_MAX_ROWS]; | |
283 | u16 old_state[PM8XXX_MAX_ROWS]; | |
284 | int rc; | |
285 | ||
286 | switch (events) { | |
287 | case 0x1: | |
288 | rc = pmic8xxx_kp_read_matrix(kp, new_state, NULL); | |
289 | if (rc < 0) | |
290 | return rc; | |
291 | ||
292 | /* detecting ghost key is not an error */ | |
293 | if (pmic8xxx_detect_ghost_keys(kp, new_state)) | |
294 | return 0; | |
295 | __pmic8xxx_kp_scan_matrix(kp, new_state, kp->keystate); | |
296 | memcpy(kp->keystate, new_state, sizeof(new_state)); | |
297 | break; | |
298 | case 0x3: /* two events - eventcounter is gray-coded */ | |
299 | rc = pmic8xxx_kp_read_matrix(kp, new_state, old_state); | |
300 | if (rc < 0) | |
301 | return rc; | |
302 | ||
303 | __pmic8xxx_kp_scan_matrix(kp, old_state, kp->keystate); | |
304 | __pmic8xxx_kp_scan_matrix(kp, new_state, old_state); | |
305 | memcpy(kp->keystate, new_state, sizeof(new_state)); | |
306 | break; | |
307 | case 0x2: | |
308 | dev_dbg(kp->dev, "Some key events were lost\n"); | |
309 | rc = pmic8xxx_kp_read_matrix(kp, new_state, old_state); | |
310 | if (rc < 0) | |
311 | return rc; | |
312 | __pmic8xxx_kp_scan_matrix(kp, old_state, kp->keystate); | |
313 | __pmic8xxx_kp_scan_matrix(kp, new_state, old_state); | |
314 | memcpy(kp->keystate, new_state, sizeof(new_state)); | |
315 | break; | |
316 | default: | |
317 | rc = -EINVAL; | |
318 | } | |
319 | return rc; | |
320 | } | |
321 | ||
322 | /* | |
323 | * NOTE: We are reading recent and old data registers blindly | |
324 | * whenever key-stuck interrupt happens, because events counter doesn't | |
325 | * get updated when this interrupt happens due to key stuck doesn't get | |
326 | * considered as key state change. | |
327 | * | |
328 | * We are not using old data register contents after they are being read | |
329 | * because it might report the key which was pressed before the key being stuck | |
330 | * as stuck key because it's pressed status is stored in the old data | |
331 | * register. | |
332 | */ | |
333 | static irqreturn_t pmic8xxx_kp_stuck_irq(int irq, void *data) | |
334 | { | |
335 | u16 new_state[PM8XXX_MAX_ROWS]; | |
336 | u16 old_state[PM8XXX_MAX_ROWS]; | |
337 | int rc; | |
338 | struct pmic8xxx_kp *kp = data; | |
339 | ||
340 | rc = pmic8xxx_kp_read_matrix(kp, new_state, old_state); | |
341 | if (rc < 0) { | |
342 | dev_err(kp->dev, "failed to read keypad matrix\n"); | |
343 | return IRQ_HANDLED; | |
344 | } | |
345 | ||
346 | __pmic8xxx_kp_scan_matrix(kp, new_state, kp->stuckstate); | |
347 | ||
348 | return IRQ_HANDLED; | |
349 | } | |
350 | ||
351 | static irqreturn_t pmic8xxx_kp_irq(int irq, void *data) | |
352 | { | |
353 | struct pmic8xxx_kp *kp = data; | |
a5dde0c7 | 354 | unsigned int ctrl_val, events; |
39325b59 TS |
355 | int rc; |
356 | ||
a5dde0c7 | 357 | rc = regmap_read(kp->regmap, KEYP_CTRL, &ctrl_val); |
39325b59 TS |
358 | if (rc < 0) { |
359 | dev_err(kp->dev, "failed to read keyp_ctrl register\n"); | |
360 | return IRQ_HANDLED; | |
361 | } | |
362 | ||
363 | events = ctrl_val & KEYP_CTRL_EVNTS_MASK; | |
364 | ||
365 | rc = pmic8xxx_kp_scan_matrix(kp, events); | |
366 | if (rc < 0) | |
367 | dev_err(kp->dev, "failed to scan matrix\n"); | |
368 | ||
369 | return IRQ_HANDLED; | |
370 | } | |
371 | ||
5298cc4c | 372 | static int pmic8xxx_kpd_init(struct pmic8xxx_kp *kp) |
39325b59 TS |
373 | { |
374 | int bits, rc, cycles; | |
375 | u8 scan_val = 0, ctrl_val = 0; | |
376 | static const u8 row_bits[] = { | |
377 | 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, | |
378 | }; | |
379 | ||
380 | /* Find column bits */ | |
381 | if (kp->pdata->num_cols < KEYP_CTRL_SCAN_COLS_MIN) | |
382 | bits = 0; | |
383 | else | |
384 | bits = kp->pdata->num_cols - KEYP_CTRL_SCAN_COLS_MIN; | |
385 | ctrl_val = (bits & KEYP_CTRL_SCAN_COLS_BITS) << | |
386 | KEYP_CTRL_SCAN_COLS_SHIFT; | |
387 | ||
388 | /* Find row bits */ | |
389 | if (kp->pdata->num_rows < KEYP_CTRL_SCAN_ROWS_MIN) | |
390 | bits = 0; | |
391 | else | |
392 | bits = row_bits[kp->pdata->num_rows - KEYP_CTRL_SCAN_ROWS_MIN]; | |
393 | ||
394 | ctrl_val |= (bits << KEYP_CTRL_SCAN_ROWS_SHIFT); | |
395 | ||
a5dde0c7 | 396 | rc = regmap_write(kp->regmap, KEYP_CTRL, ctrl_val); |
39325b59 TS |
397 | if (rc < 0) { |
398 | dev_err(kp->dev, "Error writing KEYP_CTRL reg, rc=%d\n", rc); | |
399 | return rc; | |
400 | } | |
401 | ||
402 | bits = (kp->pdata->debounce_ms / 5) - 1; | |
403 | ||
404 | scan_val |= (bits << KEYP_SCAN_DBOUNCE_SHIFT); | |
405 | ||
406 | bits = fls(kp->pdata->scan_delay_ms) - 1; | |
407 | scan_val |= (bits << KEYP_SCAN_PAUSE_SHIFT); | |
408 | ||
409 | /* Row hold time is a multiple of 32KHz cycles. */ | |
410 | cycles = (kp->pdata->row_hold_ns * KEYP_CLOCK_FREQ) / NSEC_PER_SEC; | |
411 | ||
412 | scan_val |= (cycles << KEYP_SCAN_ROW_HOLD_SHIFT); | |
413 | ||
a5dde0c7 | 414 | rc = regmap_write(kp->regmap, KEYP_SCAN, scan_val); |
39325b59 TS |
415 | if (rc) |
416 | dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc); | |
417 | ||
418 | return rc; | |
419 | ||
420 | } | |
421 | ||
39325b59 TS |
422 | static int pmic8xxx_kp_enable(struct pmic8xxx_kp *kp) |
423 | { | |
424 | int rc; | |
425 | ||
426 | kp->ctrl_reg |= KEYP_CTRL_KEYP_EN; | |
427 | ||
a5dde0c7 | 428 | rc = regmap_write(kp->regmap, KEYP_CTRL, kp->ctrl_reg); |
39325b59 TS |
429 | if (rc < 0) |
430 | dev_err(kp->dev, "Error writing KEYP_CTRL reg, rc=%d\n", rc); | |
431 | ||
432 | return rc; | |
433 | } | |
434 | ||
435 | static int pmic8xxx_kp_disable(struct pmic8xxx_kp *kp) | |
436 | { | |
437 | int rc; | |
438 | ||
439 | kp->ctrl_reg &= ~KEYP_CTRL_KEYP_EN; | |
440 | ||
a5dde0c7 | 441 | rc = regmap_write(kp->regmap, KEYP_CTRL, kp->ctrl_reg); |
39325b59 TS |
442 | if (rc < 0) |
443 | return rc; | |
444 | ||
445 | return rc; | |
446 | } | |
447 | ||
448 | static int pmic8xxx_kp_open(struct input_dev *dev) | |
449 | { | |
450 | struct pmic8xxx_kp *kp = input_get_drvdata(dev); | |
451 | ||
452 | return pmic8xxx_kp_enable(kp); | |
453 | } | |
454 | ||
455 | static void pmic8xxx_kp_close(struct input_dev *dev) | |
456 | { | |
457 | struct pmic8xxx_kp *kp = input_get_drvdata(dev); | |
458 | ||
459 | pmic8xxx_kp_disable(kp); | |
460 | } | |
461 | ||
462 | /* | |
463 | * keypad controller should be initialized in the following sequence | |
464 | * only, otherwise it might get into FSM stuck state. | |
465 | * | |
466 | * - Initialize keypad control parameters, like no. of rows, columns, | |
467 | * timing values etc., | |
468 | * - configure rows and column gpios pull up/down. | |
469 | * - set irq edge type. | |
470 | * - enable the keypad controller. | |
471 | */ | |
5298cc4c | 472 | static int pmic8xxx_kp_probe(struct platform_device *pdev) |
39325b59 | 473 | { |
1d08382a SO |
474 | const struct pm8xxx_keypad_platform_data *pdata = |
475 | dev_get_platdata(&pdev->dev); | |
39325b59 TS |
476 | const struct matrix_keymap_data *keymap_data; |
477 | struct pmic8xxx_kp *kp; | |
478 | int rc; | |
a5dde0c7 | 479 | unsigned int ctrl_val; |
39325b59 | 480 | |
39325b59 TS |
481 | if (!pdata || !pdata->num_cols || !pdata->num_rows || |
482 | pdata->num_cols > PM8XXX_MAX_COLS || | |
483 | pdata->num_rows > PM8XXX_MAX_ROWS || | |
484 | pdata->num_cols < PM8XXX_MIN_COLS) { | |
485 | dev_err(&pdev->dev, "invalid platform data\n"); | |
486 | return -EINVAL; | |
487 | } | |
488 | ||
489 | if (!pdata->scan_delay_ms || | |
490 | pdata->scan_delay_ms > MAX_SCAN_DELAY || | |
491 | pdata->scan_delay_ms < MIN_SCAN_DELAY || | |
492 | !is_power_of_2(pdata->scan_delay_ms)) { | |
493 | dev_err(&pdev->dev, "invalid keypad scan time supplied\n"); | |
494 | return -EINVAL; | |
495 | } | |
496 | ||
497 | if (!pdata->row_hold_ns || | |
498 | pdata->row_hold_ns > MAX_ROW_HOLD_DELAY || | |
499 | pdata->row_hold_ns < MIN_ROW_HOLD_DELAY || | |
500 | ((pdata->row_hold_ns % MIN_ROW_HOLD_DELAY) != 0)) { | |
501 | dev_err(&pdev->dev, "invalid keypad row hold time supplied\n"); | |
502 | return -EINVAL; | |
503 | } | |
504 | ||
505 | if (!pdata->debounce_ms || | |
506 | ((pdata->debounce_ms % 5) != 0) || | |
507 | pdata->debounce_ms > MAX_DEBOUNCE_TIME || | |
508 | pdata->debounce_ms < MIN_DEBOUNCE_TIME) { | |
509 | dev_err(&pdev->dev, "invalid debounce time supplied\n"); | |
510 | return -EINVAL; | |
511 | } | |
512 | ||
513 | keymap_data = pdata->keymap_data; | |
514 | if (!keymap_data) { | |
515 | dev_err(&pdev->dev, "no keymap data supplied\n"); | |
516 | return -EINVAL; | |
517 | } | |
518 | ||
c7f6ee26 | 519 | kp = devm_kzalloc(&pdev->dev, sizeof(*kp), GFP_KERNEL); |
39325b59 TS |
520 | if (!kp) |
521 | return -ENOMEM; | |
522 | ||
a5dde0c7 SB |
523 | kp->regmap = dev_get_regmap(pdev->dev.parent, NULL); |
524 | if (!kp->regmap) | |
525 | return -ENODEV; | |
526 | ||
39325b59 TS |
527 | platform_set_drvdata(pdev, kp); |
528 | ||
529 | kp->pdata = pdata; | |
530 | kp->dev = &pdev->dev; | |
531 | ||
c7f6ee26 | 532 | kp->input = devm_input_allocate_device(&pdev->dev); |
39325b59 TS |
533 | if (!kp->input) { |
534 | dev_err(&pdev->dev, "unable to allocate input device\n"); | |
c7f6ee26 | 535 | return -ENOMEM; |
39325b59 TS |
536 | } |
537 | ||
538 | kp->key_sense_irq = platform_get_irq(pdev, 0); | |
539 | if (kp->key_sense_irq < 0) { | |
540 | dev_err(&pdev->dev, "unable to get keypad sense irq\n"); | |
c7f6ee26 | 541 | return kp->key_sense_irq; |
39325b59 TS |
542 | } |
543 | ||
544 | kp->key_stuck_irq = platform_get_irq(pdev, 1); | |
545 | if (kp->key_stuck_irq < 0) { | |
546 | dev_err(&pdev->dev, "unable to get keypad stuck irq\n"); | |
c7f6ee26 | 547 | return kp->key_stuck_irq; |
39325b59 TS |
548 | } |
549 | ||
550 | kp->input->name = pdata->input_name ? : "PMIC8XXX keypad"; | |
551 | kp->input->phys = pdata->input_phys_device ? : "pmic8xxx_keypad/input0"; | |
552 | ||
39325b59 TS |
553 | kp->input->id.bustype = BUS_I2C; |
554 | kp->input->id.version = 0x0001; | |
555 | kp->input->id.product = 0x0001; | |
556 | kp->input->id.vendor = 0x0001; | |
557 | ||
39325b59 TS |
558 | kp->input->open = pmic8xxx_kp_open; |
559 | kp->input->close = pmic8xxx_kp_close; | |
560 | ||
1932811f DT |
561 | rc = matrix_keypad_build_keymap(keymap_data, NULL, |
562 | PM8XXX_MAX_ROWS, PM8XXX_MAX_COLS, | |
563 | kp->keycodes, kp->input); | |
564 | if (rc) { | |
565 | dev_err(&pdev->dev, "failed to build keymap\n"); | |
c7f6ee26 | 566 | return rc; |
1932811f | 567 | } |
39325b59 | 568 | |
1932811f DT |
569 | if (pdata->rep) |
570 | __set_bit(EV_REP, kp->input->evbit); | |
39325b59 | 571 | input_set_capability(kp->input, EV_MSC, MSC_SCAN); |
1932811f | 572 | |
39325b59 TS |
573 | input_set_drvdata(kp->input, kp); |
574 | ||
575 | /* initialize keypad state */ | |
576 | memset(kp->keystate, 0xff, sizeof(kp->keystate)); | |
577 | memset(kp->stuckstate, 0xff, sizeof(kp->stuckstate)); | |
578 | ||
579 | rc = pmic8xxx_kpd_init(kp); | |
580 | if (rc < 0) { | |
581 | dev_err(&pdev->dev, "unable to initialize keypad controller\n"); | |
c7f6ee26 | 582 | return rc; |
39325b59 TS |
583 | } |
584 | ||
c7f6ee26 SB |
585 | rc = devm_request_any_context_irq(&pdev->dev, kp->key_sense_irq, |
586 | pmic8xxx_kp_irq, IRQF_TRIGGER_RISING, "pmic-keypad", | |
587 | kp); | |
39325b59 TS |
588 | if (rc < 0) { |
589 | dev_err(&pdev->dev, "failed to request keypad sense irq\n"); | |
c7f6ee26 | 590 | return rc; |
39325b59 TS |
591 | } |
592 | ||
c7f6ee26 SB |
593 | rc = devm_request_any_context_irq(&pdev->dev, kp->key_stuck_irq, |
594 | pmic8xxx_kp_stuck_irq, IRQF_TRIGGER_RISING, | |
595 | "pmic-keypad-stuck", kp); | |
39325b59 TS |
596 | if (rc < 0) { |
597 | dev_err(&pdev->dev, "failed to request keypad stuck irq\n"); | |
c7f6ee26 | 598 | return rc; |
39325b59 TS |
599 | } |
600 | ||
a5dde0c7 | 601 | rc = regmap_read(kp->regmap, KEYP_CTRL, &ctrl_val); |
39325b59 TS |
602 | if (rc < 0) { |
603 | dev_err(&pdev->dev, "failed to read KEYP_CTRL register\n"); | |
c7f6ee26 | 604 | return rc; |
39325b59 TS |
605 | } |
606 | ||
607 | kp->ctrl_reg = ctrl_val; | |
608 | ||
609 | rc = input_register_device(kp->input); | |
610 | if (rc < 0) { | |
611 | dev_err(&pdev->dev, "unable to register keypad input device\n"); | |
c7f6ee26 | 612 | return rc; |
39325b59 TS |
613 | } |
614 | ||
615 | device_init_wakeup(&pdev->dev, pdata->wakeup); | |
616 | ||
39325b59 TS |
617 | return 0; |
618 | } | |
619 | ||
620 | #ifdef CONFIG_PM_SLEEP | |
621 | static int pmic8xxx_kp_suspend(struct device *dev) | |
622 | { | |
623 | struct platform_device *pdev = to_platform_device(dev); | |
624 | struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); | |
625 | struct input_dev *input_dev = kp->input; | |
626 | ||
627 | if (device_may_wakeup(dev)) { | |
628 | enable_irq_wake(kp->key_sense_irq); | |
629 | } else { | |
630 | mutex_lock(&input_dev->mutex); | |
631 | ||
632 | if (input_dev->users) | |
633 | pmic8xxx_kp_disable(kp); | |
634 | ||
635 | mutex_unlock(&input_dev->mutex); | |
636 | } | |
637 | ||
638 | return 0; | |
639 | } | |
640 | ||
641 | static int pmic8xxx_kp_resume(struct device *dev) | |
642 | { | |
643 | struct platform_device *pdev = to_platform_device(dev); | |
644 | struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); | |
645 | struct input_dev *input_dev = kp->input; | |
646 | ||
647 | if (device_may_wakeup(dev)) { | |
648 | disable_irq_wake(kp->key_sense_irq); | |
649 | } else { | |
650 | mutex_lock(&input_dev->mutex); | |
651 | ||
652 | if (input_dev->users) | |
653 | pmic8xxx_kp_enable(kp); | |
654 | ||
655 | mutex_unlock(&input_dev->mutex); | |
656 | } | |
657 | ||
658 | return 0; | |
659 | } | |
660 | #endif | |
661 | ||
662 | static SIMPLE_DEV_PM_OPS(pm8xxx_kp_pm_ops, | |
663 | pmic8xxx_kp_suspend, pmic8xxx_kp_resume); | |
664 | ||
665 | static struct platform_driver pmic8xxx_kp_driver = { | |
666 | .probe = pmic8xxx_kp_probe, | |
39325b59 TS |
667 | .driver = { |
668 | .name = PM8XXX_KEYPAD_DEV_NAME, | |
669 | .owner = THIS_MODULE, | |
670 | .pm = &pm8xxx_kp_pm_ops, | |
671 | }, | |
672 | }; | |
5146c84f | 673 | module_platform_driver(pmic8xxx_kp_driver); |
39325b59 TS |
674 | |
675 | MODULE_LICENSE("GPL v2"); | |
676 | MODULE_DESCRIPTION("PMIC8XXX keypad driver"); | |
677 | MODULE_VERSION("1.0"); | |
678 | MODULE_ALIAS("platform:pmic8xxx_keypad"); | |
679 | MODULE_AUTHOR("Trilok Soni <tsoni@codeaurora.org>"); |