2 * STMicroelectronics Key Scanning driver
4 * Copyright (c) 2014 STMicroelectonics Ltd.
5 * Author: Stuart Menefy <stuart.menefy@st.com>
7 * Based on sh_keysc.c, copyright 2008 Magnus Damm
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
14 #include <linux/module.h>
15 #include <linux/interrupt.h>
16 #include <linux/platform_device.h>
17 #include <linux/clk.h>
19 #include <linux/input/matrix_keypad.h>
21 #define ST_KEYSCAN_MAXKEYS 16
23 #define KEYSCAN_CONFIG_OFF 0x0
24 #define KEYSCAN_CONFIG_ENABLE 0x1
25 #define KEYSCAN_DEBOUNCE_TIME_OFF 0x4
26 #define KEYSCAN_MATRIX_STATE_OFF 0x8
27 #define KEYSCAN_MATRIX_DIM_OFF 0xc
28 #define KEYSCAN_MATRIX_DIM_X_SHIFT 0x0
29 #define KEYSCAN_MATRIX_DIM_Y_SHIFT 0x2
35 struct input_dev
*input_dev
;
36 unsigned long last_state
;
39 unsigned int debounce_us
;
42 static irqreturn_t
keyscan_isr(int irq
, void *dev_id
)
44 struct st_keyscan
*keypad
= dev_id
;
45 unsigned short *keycode
= keypad
->input_dev
->keycode
;
46 unsigned long state
, change
;
49 state
= readl(keypad
->base
+ KEYSCAN_MATRIX_STATE_OFF
) & 0xffff;
50 change
= keypad
->last_state
^ state
;
51 keypad
->last_state
= state
;
53 for_each_set_bit(bit_nr
, &change
, BITS_PER_LONG
)
54 input_report_key(keypad
->input_dev
,
55 keycode
[bit_nr
], state
& BIT(bit_nr
));
57 input_sync(keypad
->input_dev
);
62 static int keyscan_start(struct st_keyscan
*keypad
)
66 error
= clk_enable(keypad
->clk
);
70 writel(keypad
->debounce_us
* (clk_get_rate(keypad
->clk
) / 1000000),
71 keypad
->base
+ KEYSCAN_DEBOUNCE_TIME_OFF
);
73 writel(((keypad
->n_cols
- 1) << KEYSCAN_MATRIX_DIM_X_SHIFT
) |
74 ((keypad
->n_rows
- 1) << KEYSCAN_MATRIX_DIM_Y_SHIFT
),
75 keypad
->base
+ KEYSCAN_MATRIX_DIM_OFF
);
77 writel(KEYSCAN_CONFIG_ENABLE
, keypad
->base
+ KEYSCAN_CONFIG_OFF
);
82 static void keyscan_stop(struct st_keyscan
*keypad
)
84 writel(0, keypad
->base
+ KEYSCAN_CONFIG_OFF
);
86 clk_disable(keypad
->clk
);
89 static int keyscan_open(struct input_dev
*dev
)
91 struct st_keyscan
*keypad
= input_get_drvdata(dev
);
93 return keyscan_start(keypad
);
96 static void keyscan_close(struct input_dev
*dev
)
98 struct st_keyscan
*keypad
= input_get_drvdata(dev
);
100 keyscan_stop(keypad
);
103 static int keypad_matrix_key_parse_dt(struct st_keyscan
*keypad_data
)
105 struct device
*dev
= keypad_data
->input_dev
->dev
.parent
;
106 struct device_node
*np
= dev
->of_node
;
109 error
= matrix_keypad_parse_properties(dev
, &keypad_data
->n_rows
,
110 &keypad_data
->n_cols
);
112 dev_err(dev
, "failed to parse keypad params\n");
116 of_property_read_u32(np
, "st,debounce-us", &keypad_data
->debounce_us
);
118 dev_dbg(dev
, "n_rows=%d n_col=%d debounce=%d\n",
119 keypad_data
->n_rows
, keypad_data
->n_cols
,
120 keypad_data
->debounce_us
);
125 static int keyscan_probe(struct platform_device
*pdev
)
127 struct st_keyscan
*keypad_data
;
128 struct input_dev
*input_dev
;
129 struct resource
*res
;
132 if (!pdev
->dev
.of_node
) {
133 dev_err(&pdev
->dev
, "no DT data present\n");
137 keypad_data
= devm_kzalloc(&pdev
->dev
, sizeof(*keypad_data
),
142 input_dev
= devm_input_allocate_device(&pdev
->dev
);
144 dev_err(&pdev
->dev
, "failed to allocate the input device\n");
148 input_dev
->name
= pdev
->name
;
149 input_dev
->phys
= "keyscan-keys/input0";
150 input_dev
->dev
.parent
= &pdev
->dev
;
151 input_dev
->open
= keyscan_open
;
152 input_dev
->close
= keyscan_close
;
154 input_dev
->id
.bustype
= BUS_HOST
;
156 error
= keypad_matrix_key_parse_dt(keypad_data
);
160 error
= matrix_keypad_build_keymap(NULL
, NULL
,
165 dev_err(&pdev
->dev
, "failed to build keymap\n");
169 input_set_drvdata(input_dev
, keypad_data
);
171 keypad_data
->input_dev
= input_dev
;
173 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
174 keypad_data
->base
= devm_ioremap_resource(&pdev
->dev
, res
);
175 if (IS_ERR(keypad_data
->base
))
176 return PTR_ERR(keypad_data
->base
);
178 keypad_data
->clk
= devm_clk_get(&pdev
->dev
, NULL
);
179 if (IS_ERR(keypad_data
->clk
)) {
180 dev_err(&pdev
->dev
, "cannot get clock\n");
181 return PTR_ERR(keypad_data
->clk
);
184 error
= clk_enable(keypad_data
->clk
);
186 dev_err(&pdev
->dev
, "failed to enable clock\n");
190 keyscan_stop(keypad_data
);
192 keypad_data
->irq
= platform_get_irq(pdev
, 0);
193 if (keypad_data
->irq
< 0) {
194 dev_err(&pdev
->dev
, "no IRQ specified\n");
198 error
= devm_request_irq(&pdev
->dev
, keypad_data
->irq
, keyscan_isr
, 0,
199 pdev
->name
, keypad_data
);
201 dev_err(&pdev
->dev
, "failed to request IRQ\n");
205 error
= input_register_device(input_dev
);
207 dev_err(&pdev
->dev
, "failed to register input device\n");
211 platform_set_drvdata(pdev
, keypad_data
);
213 device_set_wakeup_capable(&pdev
->dev
, 1);
218 #ifdef CONFIG_PM_SLEEP
219 static int keyscan_suspend(struct device
*dev
)
221 struct platform_device
*pdev
= to_platform_device(dev
);
222 struct st_keyscan
*keypad
= platform_get_drvdata(pdev
);
223 struct input_dev
*input
= keypad
->input_dev
;
225 mutex_lock(&input
->mutex
);
227 if (device_may_wakeup(dev
))
228 enable_irq_wake(keypad
->irq
);
229 else if (input
->users
)
230 keyscan_stop(keypad
);
232 mutex_unlock(&input
->mutex
);
236 static int keyscan_resume(struct device
*dev
)
238 struct platform_device
*pdev
= to_platform_device(dev
);
239 struct st_keyscan
*keypad
= platform_get_drvdata(pdev
);
240 struct input_dev
*input
= keypad
->input_dev
;
243 mutex_lock(&input
->mutex
);
245 if (device_may_wakeup(dev
))
246 disable_irq_wake(keypad
->irq
);
247 else if (input
->users
)
248 retval
= keyscan_start(keypad
);
250 mutex_unlock(&input
->mutex
);
255 static SIMPLE_DEV_PM_OPS(keyscan_dev_pm_ops
, keyscan_suspend
, keyscan_resume
);
257 static const struct of_device_id keyscan_of_match
[] = {
258 { .compatible
= "st,sti-keyscan" },
261 MODULE_DEVICE_TABLE(of
, keyscan_of_match
);
263 static struct platform_driver keyscan_device_driver
= {
264 .probe
= keyscan_probe
,
266 .name
= "st-keyscan",
267 .pm
= &keyscan_dev_pm_ops
,
268 .of_match_table
= of_match_ptr(keyscan_of_match
),
272 module_platform_driver(keyscan_device_driver
);
274 MODULE_AUTHOR("Stuart Menefy <stuart.menefy@st.com>");
275 MODULE_DESCRIPTION("STMicroelectronics keyscan device driver");
276 MODULE_LICENSE("GPL");