1 // SPDX-License-Identifier: GPL-2.0-only
3 * STMicroelectronics Key Scanning driver
5 * Copyright (c) 2014 STMicroelectonics Ltd.
6 * Author: Stuart Menefy <stuart.menefy@st.com>
8 * Based on sh_keysc.c, copyright 2008 Magnus Damm
11 #include <linux/clk.h>
12 #include <linux/input.h>
13 #include <linux/input/matrix_keypad.h>
15 #include <linux/interrupt.h>
16 #include <linux/module.h>
18 #include <linux/platform_device.h>
20 #define ST_KEYSCAN_MAXKEYS 16
22 #define KEYSCAN_CONFIG_OFF 0x0
23 #define KEYSCAN_CONFIG_ENABLE 0x1
24 #define KEYSCAN_DEBOUNCE_TIME_OFF 0x4
25 #define KEYSCAN_MATRIX_STATE_OFF 0x8
26 #define KEYSCAN_MATRIX_DIM_OFF 0xc
27 #define KEYSCAN_MATRIX_DIM_X_SHIFT 0x0
28 #define KEYSCAN_MATRIX_DIM_Y_SHIFT 0x2
34 struct input_dev
*input_dev
;
35 unsigned long last_state
;
38 unsigned int debounce_us
;
41 static irqreturn_t
keyscan_isr(int irq
, void *dev_id
)
43 struct st_keyscan
*keypad
= dev_id
;
44 unsigned short *keycode
= keypad
->input_dev
->keycode
;
45 unsigned long state
, change
;
48 state
= readl(keypad
->base
+ KEYSCAN_MATRIX_STATE_OFF
) & 0xffff;
49 change
= keypad
->last_state
^ state
;
50 keypad
->last_state
= state
;
52 for_each_set_bit(bit_nr
, &change
, BITS_PER_LONG
)
53 input_report_key(keypad
->input_dev
,
54 keycode
[bit_nr
], state
& BIT(bit_nr
));
56 input_sync(keypad
->input_dev
);
61 static int keyscan_start(struct st_keyscan
*keypad
)
65 error
= clk_enable(keypad
->clk
);
69 writel(keypad
->debounce_us
* (clk_get_rate(keypad
->clk
) / 1000000),
70 keypad
->base
+ KEYSCAN_DEBOUNCE_TIME_OFF
);
72 writel(((keypad
->n_cols
- 1) << KEYSCAN_MATRIX_DIM_X_SHIFT
) |
73 ((keypad
->n_rows
- 1) << KEYSCAN_MATRIX_DIM_Y_SHIFT
),
74 keypad
->base
+ KEYSCAN_MATRIX_DIM_OFF
);
76 writel(KEYSCAN_CONFIG_ENABLE
, keypad
->base
+ KEYSCAN_CONFIG_OFF
);
81 static void keyscan_stop(struct st_keyscan
*keypad
)
83 writel(0, keypad
->base
+ KEYSCAN_CONFIG_OFF
);
85 clk_disable(keypad
->clk
);
88 static int keyscan_open(struct input_dev
*dev
)
90 struct st_keyscan
*keypad
= input_get_drvdata(dev
);
92 return keyscan_start(keypad
);
95 static void keyscan_close(struct input_dev
*dev
)
97 struct st_keyscan
*keypad
= input_get_drvdata(dev
);
102 static int keypad_matrix_key_parse_dt(struct st_keyscan
*keypad_data
)
104 struct device
*dev
= keypad_data
->input_dev
->dev
.parent
;
105 struct device_node
*np
= dev
->of_node
;
108 error
= matrix_keypad_parse_properties(dev
, &keypad_data
->n_rows
,
109 &keypad_data
->n_cols
);
111 dev_err(dev
, "failed to parse keypad params\n");
115 of_property_read_u32(np
, "st,debounce-us", &keypad_data
->debounce_us
);
117 dev_dbg(dev
, "n_rows=%d n_col=%d debounce=%d\n",
118 keypad_data
->n_rows
, keypad_data
->n_cols
,
119 keypad_data
->debounce_us
);
124 static int keyscan_probe(struct platform_device
*pdev
)
126 struct st_keyscan
*keypad_data
;
127 struct input_dev
*input_dev
;
130 if (!pdev
->dev
.of_node
) {
131 dev_err(&pdev
->dev
, "no DT data present\n");
135 keypad_data
= devm_kzalloc(&pdev
->dev
, sizeof(*keypad_data
),
140 input_dev
= devm_input_allocate_device(&pdev
->dev
);
142 dev_err(&pdev
->dev
, "failed to allocate the input device\n");
146 input_dev
->name
= pdev
->name
;
147 input_dev
->phys
= "keyscan-keys/input0";
148 input_dev
->dev
.parent
= &pdev
->dev
;
149 input_dev
->open
= keyscan_open
;
150 input_dev
->close
= keyscan_close
;
152 input_dev
->id
.bustype
= BUS_HOST
;
154 keypad_data
->input_dev
= input_dev
;
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
->base
= devm_platform_get_and_ioremap_resource(pdev
, 0, NULL
);
172 if (IS_ERR(keypad_data
->base
))
173 return PTR_ERR(keypad_data
->base
);
175 keypad_data
->clk
= devm_clk_get(&pdev
->dev
, NULL
);
176 if (IS_ERR(keypad_data
->clk
)) {
177 dev_err(&pdev
->dev
, "cannot get clock\n");
178 return PTR_ERR(keypad_data
->clk
);
181 error
= clk_enable(keypad_data
->clk
);
183 dev_err(&pdev
->dev
, "failed to enable clock\n");
187 keyscan_stop(keypad_data
);
189 keypad_data
->irq
= platform_get_irq(pdev
, 0);
190 if (keypad_data
->irq
< 0)
193 error
= devm_request_irq(&pdev
->dev
, keypad_data
->irq
, keyscan_isr
, 0,
194 pdev
->name
, keypad_data
);
196 dev_err(&pdev
->dev
, "failed to request IRQ\n");
200 error
= input_register_device(input_dev
);
202 dev_err(&pdev
->dev
, "failed to register input device\n");
206 platform_set_drvdata(pdev
, keypad_data
);
208 device_set_wakeup_capable(&pdev
->dev
, 1);
213 static int keyscan_suspend(struct device
*dev
)
215 struct platform_device
*pdev
= to_platform_device(dev
);
216 struct st_keyscan
*keypad
= platform_get_drvdata(pdev
);
217 struct input_dev
*input
= keypad
->input_dev
;
219 guard(mutex
)(&input
->mutex
);
221 if (device_may_wakeup(dev
))
222 enable_irq_wake(keypad
->irq
);
223 else if (input_device_enabled(input
))
224 keyscan_stop(keypad
);
229 static int keyscan_resume(struct device
*dev
)
231 struct platform_device
*pdev
= to_platform_device(dev
);
232 struct st_keyscan
*keypad
= platform_get_drvdata(pdev
);
233 struct input_dev
*input
= keypad
->input_dev
;
236 guard(mutex
)(&input
->mutex
);
238 if (device_may_wakeup(dev
)) {
239 disable_irq_wake(keypad
->irq
);
240 } else if (input_device_enabled(input
)) {
241 error
= keyscan_start(keypad
);
249 static DEFINE_SIMPLE_DEV_PM_OPS(keyscan_dev_pm_ops
,
250 keyscan_suspend
, keyscan_resume
);
252 static const struct of_device_id keyscan_of_match
[] = {
253 { .compatible
= "st,sti-keyscan" },
256 MODULE_DEVICE_TABLE(of
, keyscan_of_match
);
258 static struct platform_driver keyscan_device_driver
= {
259 .probe
= keyscan_probe
,
261 .name
= "st-keyscan",
262 .pm
= pm_sleep_ptr(&keyscan_dev_pm_ops
),
263 .of_match_table
= keyscan_of_match
,
267 module_platform_driver(keyscan_device_driver
);
269 MODULE_AUTHOR("Stuart Menefy <stuart.menefy@st.com>");
270 MODULE_DESCRIPTION("STMicroelectronics keyscan device driver");
271 MODULE_LICENSE("GPL");