1 // SPDX-License-Identifier: GPL-2.0-only
3 * Driver for the Cirrus EP93xx matrix keypad controller.
5 * Copyright (c) 2008 H Hartley Sweeten <hsweeten@visionengravers.com>
7 * Based on the pxa27x matrix keypad controller by Rodolfo Giometti.
11 #include <linux/bits.h>
12 #include <linux/mod_devicetable.h>
13 #include <linux/module.h>
14 #include <linux/platform_device.h>
15 #include <linux/property.h>
16 #include <linux/interrupt.h>
17 #include <linux/clk.h>
19 #include <linux/input.h>
20 #include <linux/input/matrix_keypad.h>
21 #include <linux/slab.h>
22 #include <linux/soc/cirrus/ep93xx.h>
23 #include <linux/pm_wakeirq.h>
26 * Keypad Interface Register offsets
28 #define KEY_INIT 0x00 /* Key Scan Initialization register */
29 #define KEY_DIAG 0x04 /* Key Scan Diagnostic register */
30 #define KEY_REG 0x08 /* Key Value Capture register */
32 /* Key Scan Initialization Register bit defines */
33 #define KEY_INIT_DBNC_MASK GENMASK(23, 16)
34 #define KEY_INIT_DBNC_SHIFT 16
35 #define KEY_INIT_DIS3KY BIT(15)
36 #define KEY_INIT_DIAG BIT(14)
37 #define KEY_INIT_BACK BIT(13)
38 #define KEY_INIT_T2 BIT(12)
39 #define KEY_INIT_PRSCL_MASK GENMASK(9, 0)
40 #define KEY_INIT_PRSCL_SHIFT 0
42 /* Key Scan Diagnostic Register bit defines */
43 #define KEY_DIAG_MASK GENMASK(5, 0)
44 #define KEY_DIAG_SHIFT 0
46 /* Key Value Capture Register bit defines */
47 #define KEY_REG_K BIT(15)
48 #define KEY_REG_INT BIT(14)
49 #define KEY_REG_2KEYS BIT(13)
50 #define KEY_REG_1KEY BIT(12)
51 #define KEY_REG_KEY2_MASK GENMASK(11, 6)
52 #define KEY_REG_KEY2_SHIFT 6
53 #define KEY_REG_KEY1_MASK GENMASK(5, 0)
54 #define KEY_REG_KEY1_SHIFT 0
56 #define EP93XX_MATRIX_ROWS (8)
57 #define EP93XX_MATRIX_COLS (8)
59 #define EP93XX_MATRIX_SIZE (EP93XX_MATRIX_ROWS * EP93XX_MATRIX_COLS)
61 struct ep93xx_keypad
{
62 struct input_dev
*input_dev
;
64 unsigned int debounce
;
67 void __iomem
*mmio_base
;
69 unsigned short keycodes
[EP93XX_MATRIX_SIZE
];
79 static irqreturn_t
ep93xx_keypad_irq_handler(int irq
, void *dev_id
)
81 struct ep93xx_keypad
*keypad
= dev_id
;
82 struct input_dev
*input_dev
= keypad
->input_dev
;
84 int keycode
, key1
, key2
;
86 status
= __raw_readl(keypad
->mmio_base
+ KEY_REG
);
88 keycode
= (status
& KEY_REG_KEY1_MASK
) >> KEY_REG_KEY1_SHIFT
;
89 key1
= keypad
->keycodes
[keycode
];
91 keycode
= (status
& KEY_REG_KEY2_MASK
) >> KEY_REG_KEY2_SHIFT
;
92 key2
= keypad
->keycodes
[keycode
];
94 if (status
& KEY_REG_2KEYS
) {
95 if (keypad
->key1
&& key1
!= keypad
->key1
&& key2
!= keypad
->key1
)
96 input_report_key(input_dev
, keypad
->key1
, 0);
98 if (keypad
->key2
&& key1
!= keypad
->key2
&& key2
!= keypad
->key2
)
99 input_report_key(input_dev
, keypad
->key2
, 0);
101 input_report_key(input_dev
, key1
, 1);
102 input_report_key(input_dev
, key2
, 1);
107 } else if (status
& KEY_REG_1KEY
) {
108 if (keypad
->key1
&& key1
!= keypad
->key1
)
109 input_report_key(input_dev
, keypad
->key1
, 0);
111 if (keypad
->key2
&& key1
!= keypad
->key2
)
112 input_report_key(input_dev
, keypad
->key2
, 0);
114 input_report_key(input_dev
, key1
, 1);
120 input_report_key(input_dev
, keypad
->key1
, 0);
121 input_report_key(input_dev
, keypad
->key2
, 0);
123 keypad
->key1
= keypad
->key2
= 0;
125 input_sync(input_dev
);
130 static void ep93xx_keypad_config(struct ep93xx_keypad
*keypad
)
132 unsigned int val
= 0;
134 val
|= (keypad
->debounce
<< KEY_INIT_DBNC_SHIFT
) & KEY_INIT_DBNC_MASK
;
136 val
|= (keypad
->prescale
<< KEY_INIT_PRSCL_SHIFT
) & KEY_INIT_PRSCL_MASK
;
138 __raw_writel(val
, keypad
->mmio_base
+ KEY_INIT
);
141 static int ep93xx_keypad_open(struct input_dev
*pdev
)
143 struct ep93xx_keypad
*keypad
= input_get_drvdata(pdev
);
145 if (!keypad
->enabled
) {
146 ep93xx_keypad_config(keypad
);
147 clk_prepare_enable(keypad
->clk
);
148 keypad
->enabled
= true;
154 static void ep93xx_keypad_close(struct input_dev
*pdev
)
156 struct ep93xx_keypad
*keypad
= input_get_drvdata(pdev
);
158 if (keypad
->enabled
) {
159 clk_disable_unprepare(keypad
->clk
);
160 keypad
->enabled
= false;
165 static int ep93xx_keypad_suspend(struct device
*dev
)
167 struct platform_device
*pdev
= to_platform_device(dev
);
168 struct ep93xx_keypad
*keypad
= platform_get_drvdata(pdev
);
169 struct input_dev
*input_dev
= keypad
->input_dev
;
171 guard(mutex
)(&input_dev
->mutex
);
173 if (keypad
->enabled
) {
174 clk_disable(keypad
->clk
);
175 keypad
->enabled
= false;
181 static int ep93xx_keypad_resume(struct device
*dev
)
183 struct platform_device
*pdev
= to_platform_device(dev
);
184 struct ep93xx_keypad
*keypad
= platform_get_drvdata(pdev
);
185 struct input_dev
*input_dev
= keypad
->input_dev
;
187 guard(mutex
)(&input_dev
->mutex
);
189 if (input_device_enabled(input_dev
)) {
190 if (!keypad
->enabled
) {
191 ep93xx_keypad_config(keypad
);
192 clk_enable(keypad
->clk
);
193 keypad
->enabled
= true;
200 static DEFINE_SIMPLE_DEV_PM_OPS(ep93xx_keypad_pm_ops
,
201 ep93xx_keypad_suspend
, ep93xx_keypad_resume
);
203 static int ep93xx_keypad_probe(struct platform_device
*pdev
)
205 struct device
*dev
= &pdev
->dev
;
206 struct ep93xx_keypad
*keypad
;
207 struct input_dev
*input_dev
;
210 keypad
= devm_kzalloc(&pdev
->dev
, sizeof(*keypad
), GFP_KERNEL
);
214 keypad
->irq
= platform_get_irq(pdev
, 0);
218 keypad
->mmio_base
= devm_platform_ioremap_resource(pdev
, 0);
219 if (IS_ERR(keypad
->mmio_base
))
220 return PTR_ERR(keypad
->mmio_base
);
222 keypad
->clk
= devm_clk_get(&pdev
->dev
, NULL
);
223 if (IS_ERR(keypad
->clk
))
224 return PTR_ERR(keypad
->clk
);
226 device_property_read_u32(dev
, "debounce-delay-ms", &keypad
->debounce
);
227 device_property_read_u16(dev
, "cirrus,prescale", &keypad
->prescale
);
229 input_dev
= devm_input_allocate_device(&pdev
->dev
);
233 keypad
->input_dev
= input_dev
;
235 input_dev
->name
= pdev
->name
;
236 input_dev
->id
.bustype
= BUS_HOST
;
237 input_dev
->open
= ep93xx_keypad_open
;
238 input_dev
->close
= ep93xx_keypad_close
;
240 err
= matrix_keypad_build_keymap(NULL
, NULL
,
241 EP93XX_MATRIX_ROWS
, EP93XX_MATRIX_COLS
,
242 keypad
->keycodes
, input_dev
);
246 if (device_property_read_bool(&pdev
->dev
, "autorepeat"))
247 __set_bit(EV_REP
, input_dev
->evbit
);
248 input_set_drvdata(input_dev
, keypad
);
250 err
= devm_request_irq(&pdev
->dev
, keypad
->irq
,
251 ep93xx_keypad_irq_handler
,
252 0, pdev
->name
, keypad
);
256 err
= input_register_device(input_dev
);
260 platform_set_drvdata(pdev
, keypad
);
262 device_init_wakeup(&pdev
->dev
, 1);
263 err
= dev_pm_set_wake_irq(&pdev
->dev
, keypad
->irq
);
265 dev_warn(&pdev
->dev
, "failed to set up wakeup irq: %d\n", err
);
270 static void ep93xx_keypad_remove(struct platform_device
*pdev
)
272 dev_pm_clear_wake_irq(&pdev
->dev
);
275 static const struct of_device_id ep93xx_keypad_of_ids
[] = {
276 { .compatible
= "cirrus,ep9307-keypad" },
279 MODULE_DEVICE_TABLE(of
, ep93xx_keypad_of_ids
);
281 static struct platform_driver ep93xx_keypad_driver
= {
283 .name
= "ep93xx-keypad",
284 .pm
= pm_sleep_ptr(&ep93xx_keypad_pm_ops
),
285 .of_match_table
= ep93xx_keypad_of_ids
,
287 .probe
= ep93xx_keypad_probe
,
288 .remove
= ep93xx_keypad_remove
,
290 module_platform_driver(ep93xx_keypad_driver
);
292 MODULE_LICENSE("GPL");
293 MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
294 MODULE_DESCRIPTION("EP93xx Matrix Keypad Controller");
295 MODULE_ALIAS("platform:ep93xx-keypad");