aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Abraham <thomas.abraham@linaro.org>2011-11-02 06:37:22 -0400
committerKukjin Kim <kgene.kim@samsung.com>2011-12-22 20:07:10 -0500
commitb3d6ac3e5f937440a362c0fa187257fa1197f5b9 (patch)
treef9d535987acc864a3948174e893077b5f6543138
parent8742e0441d6530d40d85d65a6bcc5a6c0c4eab13 (diff)
input: samsung-keypad: Add device tree support
Add device tree based discovery support for Samsung's keypad controller. Cc: Joonyoung Shim <jy0922.shim@samsung.com> Cc: Donghwa Lee <dh09.lee@samsung.com> Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org> Acked-by: Grant Likely <grant.likely@secretlab.ca> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
-rw-r--r--Documentation/devicetree/bindings/input/samsung-keypad.txt88
-rw-r--r--drivers/input/keyboard/samsung-keypad.c174
2 files changed, 250 insertions, 12 deletions
diff --git a/Documentation/devicetree/bindings/input/samsung-keypad.txt b/Documentation/devicetree/bindings/input/samsung-keypad.txt
new file mode 100644
index 000000000000..ce3e394c0e64
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/samsung-keypad.txt
@@ -0,0 +1,88 @@
1* Samsung's Keypad Controller device tree bindings
2
3Samsung's Keypad controller is used to interface a SoC with a matrix-type
4keypad device. The keypad controller supports multiple row and column lines.
5A key can be placed at each intersection of a unique row and a unique column.
6The keypad controller can sense a key-press and key-release and report the
7event using a interrupt to the cpu.
8
9Required SoC Specific Properties:
10- compatible: should be one of the following
11 - "samsung,s3c6410-keypad": For controllers compatible with s3c6410 keypad
12 controller.
13 - "samsung,s5pv210-keypad": For controllers compatible with s5pv210 keypad
14 controller.
15
16- reg: physical base address of the controller and length of memory mapped
17 region.
18
19- interrupts: The interrupt number to the cpu.
20
21Required Board Specific Properties:
22- samsung,keypad-num-rows: Number of row lines connected to the keypad
23 controller.
24
25- samsung,keypad-num-columns: Number of column lines connected to the
26 keypad controller.
27
28- row-gpios: List of gpios used as row lines. The gpio specifier for
29 this property depends on the gpio controller to which these row lines
30 are connected.
31
32- col-gpios: List of gpios used as column lines. The gpio specifier for
33 this property depends on the gpio controller to which these column
34 lines are connected.
35
36- Keys represented as child nodes: Each key connected to the keypad
37 controller is represented as a child node to the keypad controller
38 device node and should include the following properties.
39 - keypad,row: the row number to which the key is connected.
40 - keypad,column: the column number to which the key is connected.
41 - linux,code: the key-code to be reported when the key is pressed
42 and released.
43
44Optional Properties specific to linux:
45- linux,keypad-no-autorepeat: do no enable autorepeat feature.
46- linux,keypad-wakeup: use any event on keypad as wakeup event.
47
48
49Example:
50 keypad@100A0000 {
51 compatible = "samsung,s5pv210-keypad";
52 reg = <0x100A0000 0x100>;
53 interrupts = <173>;
54 samsung,keypad-num-rows = <2>;
55 samsung,keypad-num-columns = <8>;
56 linux,input-no-autorepeat;
57 linux,input-wakeup;
58
59 row-gpios = <&gpx2 0 3 3 0
60 &gpx2 1 3 3 0>;
61
62 col-gpios = <&gpx1 0 3 0 0
63 &gpx1 1 3 0 0
64 &gpx1 2 3 0 0
65 &gpx1 3 3 0 0
66 &gpx1 4 3 0 0
67 &gpx1 5 3 0 0
68 &gpx1 6 3 0 0
69 &gpx1 7 3 0 0>;
70
71 key_1 {
72 keypad,row = <0>;
73 keypad,column = <3>;
74 linux,code = <2>;
75 };
76
77 key_2 {
78 keypad,row = <0>;
79 keypad,column = <4>;
80 linux,code = <3>;
81 };
82
83 key_3 {
84 keypad,row = <0>;
85 keypad,column = <5>;
86 linux,code = <4>;
87 };
88 };
diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c
index f689f49e3109..8a0060cd3982 100644
--- a/drivers/input/keyboard/samsung-keypad.c
+++ b/drivers/input/keyboard/samsung-keypad.c
@@ -21,6 +21,8 @@
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/of.h>
25#include <linux/of_gpio.h>
24#include <linux/sched.h> 26#include <linux/sched.h>
25#include <plat/keypad.h> 27#include <plat/keypad.h>
26 28
@@ -68,31 +70,26 @@ struct samsung_keypad {
68 wait_queue_head_t wait; 70 wait_queue_head_t wait;
69 bool stopped; 71 bool stopped;
70 int irq; 72 int irq;
73 enum samsung_keypad_type type;
71 unsigned int row_shift; 74 unsigned int row_shift;
72 unsigned int rows; 75 unsigned int rows;
73 unsigned int cols; 76 unsigned int cols;
74 unsigned int row_state[SAMSUNG_MAX_COLS]; 77 unsigned int row_state[SAMSUNG_MAX_COLS];
78#ifdef CONFIG_OF
79 int row_gpios[SAMSUNG_MAX_ROWS];
80 int col_gpios[SAMSUNG_MAX_COLS];
81#endif
75 unsigned short keycodes[]; 82 unsigned short keycodes[];
76}; 83};
77 84
78static int samsung_keypad_is_s5pv210(struct device *dev)
79{
80 struct platform_device *pdev = to_platform_device(dev);
81 enum samsung_keypad_type type =
82 platform_get_device_id(pdev)->driver_data;
83
84 return type == KEYPAD_TYPE_S5PV210;
85}
86
87static void samsung_keypad_scan(struct samsung_keypad *keypad, 85static void samsung_keypad_scan(struct samsung_keypad *keypad,
88 unsigned int *row_state) 86 unsigned int *row_state)
89{ 87{
90 struct device *dev = keypad->input_dev->dev.parent;
91 unsigned int col; 88 unsigned int col;
92 unsigned int val; 89 unsigned int val;
93 90
94 for (col = 0; col < keypad->cols; col++) { 91 for (col = 0; col < keypad->cols; col++) {
95 if (samsung_keypad_is_s5pv210(dev)) { 92 if (keypad->type == KEYPAD_TYPE_S5PV210) {
96 val = S5PV210_KEYIFCOLEN_MASK; 93 val = S5PV210_KEYIFCOLEN_MASK;
97 val &= ~(1 << col) << 8; 94 val &= ~(1 << col) << 8;
98 } else { 95 } else {
@@ -235,6 +232,126 @@ static void samsung_keypad_close(struct input_dev *input_dev)
235 samsung_keypad_stop(keypad); 232 samsung_keypad_stop(keypad);
236} 233}
237 234
235#ifdef CONFIG_OF
236static struct samsung_keypad_platdata *samsung_keypad_parse_dt(
237 struct device *dev)
238{
239 struct samsung_keypad_platdata *pdata;
240 struct matrix_keymap_data *keymap_data;
241 uint32_t *keymap, num_rows = 0, num_cols = 0;
242 struct device_node *np = dev->of_node, *key_np;
243 unsigned int key_count = 0;
244
245 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
246 if (!pdata) {
247 dev_err(dev, "could not allocate memory for platform data\n");
248 return NULL;
249 }
250
251 of_property_read_u32(np, "samsung,keypad-num-rows", &num_rows);
252 of_property_read_u32(np, "samsung,keypad-num-columns", &num_cols);
253 if (!num_rows || !num_cols) {
254 dev_err(dev, "number of keypad rows/columns not specified\n");
255 return NULL;
256 }
257 pdata->rows = num_rows;