xref: /linux/drivers/input/keyboard/tc3589x-keypad.c (revision b85d45947951d23cb22d90caecf4c1eb81342c96)
1 /*
2  * Copyright (C) ST-Ericsson SA 2010
3  *
4  * Author: Jayeeta Banerjee <jayeeta.banerjee@stericsson.com>
5  * Author: Sundar Iyer <sundar.iyer@stericsson.com>
6  *
7  * License Terms: GNU General Public License, version 2
8  *
9  * TC35893 MFD Keypad Controller driver
10  */
11 
12 #include <linux/module.h>
13 #include <linux/interrupt.h>
14 #include <linux/input.h>
15 #include <linux/platform_device.h>
16 #include <linux/input/matrix_keypad.h>
17 #include <linux/i2c.h>
18 #include <linux/slab.h>
19 #include <linux/mfd/tc3589x.h>
20 #include <linux/device.h>
21 
22 /* Maximum supported keypad matrix row/columns size */
23 #define TC3589x_MAX_KPROW               8
24 #define TC3589x_MAX_KPCOL               12
25 
26 /* keypad related Constants */
27 #define TC3589x_MAX_DEBOUNCE_SETTLE     0xFF
28 #define DEDICATED_KEY_VAL		0xFF
29 
30 /* Pull up/down masks */
31 #define TC3589x_NO_PULL_MASK		0x0
32 #define TC3589x_PULL_DOWN_MASK		0x1
33 #define TC3589x_PULL_UP_MASK		0x2
34 #define TC3589x_PULLUP_ALL_MASK		0xAA
35 #define TC3589x_IO_PULL_VAL(index, mask)	((mask)<<((index)%4)*2))
36 
37 /* Bit masks for IOCFG register */
38 #define IOCFG_BALLCFG		0x01
39 #define IOCFG_IG		0x08
40 
41 #define KP_EVCODE_COL_MASK	0x0F
42 #define KP_EVCODE_ROW_MASK	0x70
43 #define KP_RELEASE_EVT_MASK	0x80
44 
45 #define KP_ROW_SHIFT		4
46 
47 #define KP_NO_VALID_KEY_MASK	0x7F
48 
49 /* bit masks for RESTCTRL register */
50 #define TC3589x_KBDRST		0x2
51 #define TC3589x_IRQRST		0x10
52 #define TC3589x_RESET_ALL	0x1B
53 
54 /* KBDMFS register bit mask */
55 #define TC3589x_KBDMFS_EN	0x1
56 
57 /* CLKEN register bitmask */
58 #define KPD_CLK_EN		0x1
59 
60 /* RSTINTCLR register bit mask */
61 #define IRQ_CLEAR		0x1
62 
63 /* bit masks for keyboard interrupts*/
64 #define TC3589x_EVT_LOSS_INT	0x8
65 #define TC3589x_EVT_INT		0x4
66 #define TC3589x_KBD_LOSS_INT	0x2
67 #define TC3589x_KBD_INT		0x1
68 
69 /* bit masks for keyboard interrupt clear*/
70 #define TC3589x_EVT_INT_CLR	0x2
71 #define TC3589x_KBD_INT_CLR	0x1
72 
73 /**
74  * struct tc35893_keypad_platform_data - platform specific keypad data
75  * @keymap_data:        matrix scan code table for keycodes
76  * @krow:               mask for available rows, value is 0xFF
77  * @kcol:               mask for available columns, value is 0xFF
78  * @debounce_period:    platform specific debounce time
79  * @settle_time:        platform specific settle down time
80  * @irqtype:            type of interrupt, falling or rising edge
81  * @enable_wakeup:      specifies if keypad event can wake up system from sleep
82  * @no_autorepeat:      flag for auto repetition
83  */
84 struct tc3589x_keypad_platform_data {
85 	const struct matrix_keymap_data *keymap_data;
86 	u8                      krow;
87 	u8                      kcol;
88 	u8                      debounce_period;
89 	u8                      settle_time;
90 	unsigned long           irqtype;
91 	bool                    enable_wakeup;
92 	bool                    no_autorepeat;
93 };
94 
95 /**
96  * struct tc_keypad - data structure used by keypad driver
97  * @tc3589x:    pointer to tc35893
98  * @input:      pointer to input device object
99  * @board:      keypad platform device
100  * @krow:	number of rows
101  * @kcol:	number of columns
102  * @keymap:     matrix scan code table for keycodes
103  * @keypad_stopped: holds keypad status
104  */
105 struct tc_keypad {
106 	struct tc3589x *tc3589x;
107 	struct input_dev *input;
108 	const struct tc3589x_keypad_platform_data *board;
109 	unsigned int krow;
110 	unsigned int kcol;
111 	unsigned short *keymap;
112 	bool keypad_stopped;
113 };
114 
115 static int tc3589x_keypad_init_key_hardware(struct tc_keypad *keypad)
116 {
117 	int ret;
118 	struct tc3589x *tc3589x = keypad->tc3589x;
119 	const struct tc3589x_keypad_platform_data *board = keypad->board;
120 
121 	/* validate platform configuration */
122 	if (board->kcol > TC3589x_MAX_KPCOL || board->krow > TC3589x_MAX_KPROW)
123 		return -EINVAL;
124 
125 	/* configure KBDSIZE 4 LSbits for cols and 4 MSbits for rows */
126 	ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSIZE,
127 			(board->krow << KP_ROW_SHIFT) | board->kcol);
128 	if (ret < 0)
129 		return ret;
130 
131 	/* configure dedicated key config, no dedicated key selected */
132 	ret = tc3589x_reg_write(tc3589x, TC3589x_KBCFG_LSB, DEDICATED_KEY_VAL);
133 	if (ret < 0)
134 		return ret;
135 
136 	ret = tc3589x_reg_write(tc3589x, TC3589x_KBCFG_MSB, DEDICATED_KEY_VAL);
137 	if (ret < 0)
138 		return ret;
139 
140 	/* Configure settle time */
141 	ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSETTLE_REG,
142 				board->settle_time);
143 	if (ret < 0)
144 		return ret;
145 
146 	/* Configure debounce time */
147 	ret = tc3589x_reg_write(tc3589x, TC3589x_KBDBOUNCE,
148 				board->debounce_period);
149 	if (ret < 0)
150 		return ret;
151 
152 	/* Start of initialise keypad GPIOs */
153 	ret = tc3589x_set_bits(tc3589x, TC3589x_IOCFG, 0x0, IOCFG_IG);
154 	if (ret < 0)
155 		return ret;
156 
157 	/* Configure pull-up resistors for all row GPIOs */
158 	ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG0_LSB,
159 					TC3589x_PULLUP_ALL_MASK);
160 	if (ret < 0)
161 		return ret;
162 
163 	ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG0_MSB,
164 					TC3589x_PULLUP_ALL_MASK);
165 	if (ret < 0)
166 		return ret;
167 
168 	/* Configure pull-up resistors for all column GPIOs */
169 	ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG1_LSB,
170 			TC3589x_PULLUP_ALL_MASK);
171 	if (ret < 0)
172 		return ret;
173 
174 	ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG1_MSB,
175 			TC3589x_PULLUP_ALL_MASK);
176 	if (ret < 0)
177 		return ret;
178 
179 	ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG2_LSB,
180 			TC3589x_PULLUP_ALL_MASK);
181 
182 	return ret;
183 }
184 
185 #define TC35893_DATA_REGS		4
186 #define TC35893_KEYCODE_FIFO_EMPTY	0x7f
187 #define TC35893_KEYCODE_FIFO_CLEAR	0xff
188 #define TC35893_KEYPAD_ROW_SHIFT	0x3
189 
190 static irqreturn_t tc3589x_keypad_irq(int irq, void *dev)
191 {
192 	struct tc_keypad *keypad = dev;
193 	struct tc3589x *tc3589x = keypad->tc3589x;
194 	u8 i, row_index, col_index, kbd_code, up;
195 	u8 code;
196 
197 	for (i = 0; i < TC35893_DATA_REGS * 2; i++) {
198 		kbd_code = tc3589x_reg_read(tc3589x, TC3589x_EVTCODE_FIFO);
199 
200 		/* loop till fifo is empty and no more keys are pressed */
201 		if (kbd_code == TC35893_KEYCODE_FIFO_EMPTY ||
202 				kbd_code == TC35893_KEYCODE_FIFO_CLEAR)
203 			continue;
204 
205 		/* valid key is found */
206 		col_index = kbd_code & KP_EVCODE_COL_MASK;
207 		row_index = (kbd_code & KP_EVCODE_ROW_MASK) >> KP_ROW_SHIFT;
208 		code = MATRIX_SCAN_CODE(row_index, col_index,
209 						TC35893_KEYPAD_ROW_SHIFT);
210 		up = kbd_code & KP_RELEASE_EVT_MASK;
211 
212 		input_event(keypad->input, EV_MSC, MSC_SCAN, code);
213 		input_report_key(keypad->input, keypad->keymap[code], !up);
214 		input_sync(keypad->input);
215 	}
216 
217 	/* clear IRQ */
218 	tc3589x_set_bits(tc3589x, TC3589x_KBDIC,
219 			0x0, TC3589x_EVT_INT_CLR | TC3589x_KBD_INT_CLR);
220 	/* enable IRQ */
221 	tc3589x_set_bits(tc3589x, TC3589x_KBDMSK,
222 			0x0, TC3589x_EVT_LOSS_INT | TC3589x_EVT_INT);
223 
224 	return IRQ_HANDLED;
225 }
226 
227 static int tc3589x_keypad_enable(struct tc_keypad *keypad)
228 {
229 	struct tc3589x *tc3589x = keypad->tc3589x;
230 	int ret;
231 
232 	/* pull the keypad module out of reset */
233 	ret = tc3589x_set_bits(tc3589x, TC3589x_RSTCTRL, TC3589x_KBDRST, 0x0);
234 	if (ret < 0)
235 		return ret;
236 
237 	/* configure KBDMFS */
238 	ret = tc3589x_set_bits(tc3589x, TC3589x_KBDMFS, 0x0, TC3589x_KBDMFS_EN);
239 	if (ret < 0)
240 		return ret;
241 
242 	/* enable the keypad clock */
243 	ret = tc3589x_set_bits(tc3589x, TC3589x_CLKEN, 0x0, KPD_CLK_EN);
244 	if (ret < 0)
245 		return ret;
246 
247 	/* clear pending IRQs */
248 	ret =  tc3589x_set_bits(tc3589x, TC3589x_RSTINTCLR, 0x0, 0x1);
249 	if (ret < 0)
250 		return ret;
251 
252 	/* enable the IRQs */
253 	ret = tc3589x_set_bits(tc3589x, TC3589x_KBDMSK, 0x0,
254 					TC3589x_EVT_LOSS_INT | TC3589x_EVT_INT);
255 	if (ret < 0)
256 		return ret;
257 
258 	keypad->keypad_stopped = false;
259 
260 	return ret;
261 }
262 
263 static int tc3589x_keypad_disable(struct tc_keypad *keypad)
264 {
265 	struct tc3589x *tc3589x = keypad->tc3589x;
266 	int ret;
267 
268 	/* clear IRQ */
269 	ret = tc3589x_set_bits(tc3589x, TC3589x_KBDIC,
270 			0x0, TC3589x_EVT_INT_CLR | TC3589x_KBD_INT_CLR);
271 	if (ret < 0)
272 		return ret;
273 
274 	/* disable all interrupts */
275 	ret = tc3589x_set_bits(tc3589x, TC3589x_KBDMSK,
276 			~(TC3589x_EVT_LOSS_INT | TC3589x_EVT_INT), 0x0);
277 	if (ret < 0)
278 		return ret;
279 
280 	/* disable the keypad module */
281 	ret = tc3589x_set_bits(tc3589x, TC3589x_CLKEN, 0x1, 0x0);
282 	if (ret < 0)
283 		return ret;
284 
285 	/* put the keypad module into reset */
286 	ret = tc3589x_set_bits(tc3589x, TC3589x_RSTCTRL, TC3589x_KBDRST, 0x1);
287 
288 	keypad->keypad_stopped = true;
289 
290 	return ret;
291 }
292 
293 static int tc3589x_keypad_open(struct input_dev *input)
294 {
295 	int error;
296 	struct tc_keypad *keypad = input_get_drvdata(input);
297 
298 	/* enable the keypad module */
299 	error = tc3589x_keypad_enable(keypad);
300 	if (error < 0) {
301 		dev_err(&input->dev, "failed to enable keypad module\n");
302 		return error;
303 	}
304 
305 	error = tc3589x_keypad_init_key_hardware(keypad);
306 	if (error < 0) {
307 		dev_err(&input->dev, "failed to configure keypad module\n");
308 		return error;
309 	}
310 
311 	return 0;
312 }
313 
314 static void tc3589x_keypad_close(struct input_dev *input)
315 {
316 	struct tc_keypad *keypad = input_get_drvdata(input);
317 
318 	/* disable the keypad module */
319 	tc3589x_keypad_disable(keypad);
320 }
321 
322 static const struct tc3589x_keypad_platform_data *
323 tc3589x_keypad_of_probe(struct device *dev)
324 {
325 	struct device_node *np = dev->of_node;
326 	struct tc3589x_keypad_platform_data *plat;
327 	u32 cols, rows;
328 	u32 debounce_ms;
329 	int proplen;
330 
331 	if (!np)
332 		return ERR_PTR(-ENODEV);
333 
334 	plat = devm_kzalloc(dev, sizeof(*plat), GFP_KERNEL);
335 	if (!plat)
336 		return ERR_PTR(-ENOMEM);
337 
338 	of_property_read_u32(np, "keypad,num-columns", &cols);
339 	of_property_read_u32(np, "keypad,num-rows", &rows);
340 	plat->kcol = (u8) cols;
341 	plat->krow = (u8) rows;
342 	if (!plat->krow || !plat->kcol ||
343 	     plat->krow > TC_KPD_ROWS || plat->kcol > TC_KPD_COLUMNS) {
344 		dev_err(dev,
345 			"keypad columns/rows not properly specified (%ux%u)\n",
346 			plat->kcol, plat->krow);
347 		return ERR_PTR(-EINVAL);
348 	}
349 
350 	if (!of_get_property(np, "linux,keymap", &proplen)) {
351 		dev_err(dev, "property linux,keymap not found\n");
352 		return ERR_PTR(-ENOENT);
353 	}
354 
355 	plat->no_autorepeat = of_property_read_bool(np, "linux,no-autorepeat");
356 
357 	plat->enable_wakeup = of_property_read_bool(np, "wakeup-source") ||
358 			      /* legacy name */
359 			      of_property_read_bool(np, "linux,wakeup");
360 
361 	/* The custom delay format is ms/16 */
362 	of_property_read_u32(np, "debounce-delay-ms", &debounce_ms);
363 	if (debounce_ms)
364 		plat->debounce_period = debounce_ms * 16;
365 	else
366 		plat->debounce_period = TC_KPD_DEBOUNCE_PERIOD;
367 
368 	plat->settle_time = TC_KPD_SETTLE_TIME;
369 	/* FIXME: should be property of the IRQ resource? */
370 	plat->irqtype = IRQF_TRIGGER_FALLING;
371 
372 	return plat;
373 }
374 
375 static int tc3589x_keypad_probe(struct platform_device *pdev)
376 {
377 	struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent);
378 	struct tc_keypad *keypad;
379 	struct input_dev *input;
380 	const struct tc3589x_keypad_platform_data *plat;
381 	int error, irq;
382 
383 	plat = tc3589x_keypad_of_probe(&pdev->dev);
384 	if (IS_ERR(plat)) {
385 		dev_err(&pdev->dev, "invalid keypad platform data\n");
386 		return PTR_ERR(plat);
387 	}
388 
389 	irq = platform_get_irq(pdev, 0);
390 	if (irq < 0)
391 		return irq;
392 
393 	keypad = devm_kzalloc(&pdev->dev, sizeof(struct tc_keypad),
394 			      GFP_KERNEL);
395 	if (!keypad)
396 		return -ENOMEM;
397 
398 	input = devm_input_allocate_device(&pdev->dev);
399 	if (!input) {
400 		dev_err(&pdev->dev, "failed to allocate input device\n");
401 		return -ENOMEM;
402 	}
403 
404 	keypad->board = plat;
405 	keypad->input = input;
406 	keypad->tc3589x = tc3589x;
407 
408 	input->id.bustype = BUS_I2C;
409 	input->name = pdev->name;
410 	input->dev.parent = &pdev->dev;
411 
412 	input->open = tc3589x_keypad_open;
413 	input->close = tc3589x_keypad_close;
414 
415 	error = matrix_keypad_build_keymap(plat->keymap_data, NULL,
416 					   TC3589x_MAX_KPROW, TC3589x_MAX_KPCOL,
417 					   NULL, input);
418 	if (error) {
419 		dev_err(&pdev->dev, "Failed to build keymap\n");
420 		return error;
421 	}
422 
423 	keypad->keymap = input->keycode;
424 
425 	input_set_capability(input, EV_MSC, MSC_SCAN);
426 	if (!plat->no_autorepeat)
427 		__set_bit(EV_REP, input->evbit);
428 
429 	input_set_drvdata(input, keypad);
430 
431 	tc3589x_keypad_disable(keypad);
432 
433 	error = devm_request_threaded_irq(&pdev->dev, irq,
434 					  NULL, tc3589x_keypad_irq,
435 					  plat->irqtype | IRQF_ONESHOT,
436 					  "tc3589x-keypad", keypad);
437 	if (error) {
438 		dev_err(&pdev->dev,
439 				"Could not allocate irq %d,error %d\n",
440 				irq, error);
441 		return error;
442 	}
443 
444 	error = input_register_device(input);
445 	if (error) {
446 		dev_err(&pdev->dev, "Could not register input device\n");
447 		return error;
448 	}
449 
450 	/* let platform decide if keypad is a wakeup source or not */
451 	device_init_wakeup(&pdev->dev, plat->enable_wakeup);
452 	device_set_wakeup_capable(&pdev->dev, plat->enable_wakeup);
453 
454 	platform_set_drvdata(pdev, keypad);
455 
456 	return 0;
457 }
458 
459 #ifdef CONFIG_PM_SLEEP
460 static int tc3589x_keypad_suspend(struct device *dev)
461 {
462 	struct platform_device *pdev = to_platform_device(dev);
463 	struct tc_keypad *keypad = platform_get_drvdata(pdev);
464 	int irq = platform_get_irq(pdev, 0);
465 
466 	/* keypad is already off; we do nothing */
467 	if (keypad->keypad_stopped)
468 		return 0;
469 
470 	/* if device is not a wakeup source, disable it for powersave */
471 	if (!device_may_wakeup(&pdev->dev))
472 		tc3589x_keypad_disable(keypad);
473 	else
474 		enable_irq_wake(irq);
475 
476 	return 0;
477 }
478 
479 static int tc3589x_keypad_resume(struct device *dev)
480 {
481 	struct platform_device *pdev = to_platform_device(dev);
482 	struct tc_keypad *keypad = platform_get_drvdata(pdev);
483 	int irq = platform_get_irq(pdev, 0);
484 
485 	if (!keypad->keypad_stopped)
486 		return 0;
487 
488 	/* enable the device to resume normal operations */
489 	if (!device_may_wakeup(&pdev->dev))
490 		tc3589x_keypad_enable(keypad);
491 	else
492 		disable_irq_wake(irq);
493 
494 	return 0;
495 }
496 #endif
497 
498 static SIMPLE_DEV_PM_OPS(tc3589x_keypad_dev_pm_ops,
499 			 tc3589x_keypad_suspend, tc3589x_keypad_resume);
500 
501 static struct platform_driver tc3589x_keypad_driver = {
502 	.driver	= {
503 		.name	= "tc3589x-keypad",
504 		.pm	= &tc3589x_keypad_dev_pm_ops,
505 	},
506 	.probe	= tc3589x_keypad_probe,
507 };
508 module_platform_driver(tc3589x_keypad_driver);
509 
510 MODULE_LICENSE("GPL v2");
511 MODULE_AUTHOR("Jayeeta Banerjee/Sundar Iyer");
512 MODULE_DESCRIPTION("TC35893 Keypad Driver");
513 MODULE_ALIAS("platform:tc3589x-keypad");
514