xref: /linux/drivers/input/keyboard/ep93xx_keypad.c (revision 3e51108c72e8adbcf3180ed40527a2a9d2d0123b)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Driver for the Cirrus EP93xx matrix keypad controller.
4  *
5  * Copyright (c) 2008 H Hartley Sweeten <hsweeten@visionengravers.com>
6  *
7  * Based on the pxa27x matrix keypad controller by Rodolfo Giometti.
8  *
9  */
10 
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>
18 #include <linux/io.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>
24 
25 /*
26  * Keypad Interface Register offsets
27  */
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 */
31 
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
41 
42 /* Key Scan Diagnostic Register bit defines */
43 #define KEY_DIAG_MASK		GENMASK(5, 0)
44 #define KEY_DIAG_SHIFT		0
45 
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
55 
56 #define EP93XX_MATRIX_ROWS		(8)
57 #define EP93XX_MATRIX_COLS		(8)
58 
59 #define EP93XX_MATRIX_SIZE	(EP93XX_MATRIX_ROWS * EP93XX_MATRIX_COLS)
60 
61 struct ep93xx_keypad {
62 	struct input_dev *input_dev;
63 	struct clk *clk;
64 	unsigned int debounce;
65 	u16 prescale;
66 
67 	void __iomem *mmio_base;
68 
69 	unsigned short keycodes[EP93XX_MATRIX_SIZE];
70 
71 	int key1;
72 	int key2;
73 
74 	int irq;
75 
76 	bool enabled;
77 };
78 
ep93xx_keypad_irq_handler(int irq,void * dev_id)79 static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id)
80 {
81 	struct ep93xx_keypad *keypad = dev_id;
82 	struct input_dev *input_dev = keypad->input_dev;
83 	unsigned int status;
84 	int keycode, key1, key2;
85 
86 	status = __raw_readl(keypad->mmio_base + KEY_REG);
87 
88 	keycode = (status & KEY_REG_KEY1_MASK) >> KEY_REG_KEY1_SHIFT;
89 	key1 = keypad->keycodes[keycode];
90 
91 	keycode = (status & KEY_REG_KEY2_MASK) >> KEY_REG_KEY2_SHIFT;
92 	key2 = keypad->keycodes[keycode];
93 
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);
97 
98 		if (keypad->key2 && key1 != keypad->key2 && key2 != keypad->key2)
99 			input_report_key(input_dev, keypad->key2, 0);
100 
101 		input_report_key(input_dev, key1, 1);
102 		input_report_key(input_dev, key2, 1);
103 
104 		keypad->key1 = key1;
105 		keypad->key2 = key2;
106 
107 	} else if (status & KEY_REG_1KEY) {
108 		if (keypad->key1 && key1 != keypad->key1)
109 			input_report_key(input_dev, keypad->key1, 0);
110 
111 		if (keypad->key2 && key1 != keypad->key2)
112 			input_report_key(input_dev, keypad->key2, 0);
113 
114 		input_report_key(input_dev, key1, 1);
115 
116 		keypad->key1 = key1;
117 		keypad->key2 = 0;
118 
119 	} else {
120 		input_report_key(input_dev, keypad->key1, 0);
121 		input_report_key(input_dev, keypad->key2, 0);
122 
123 		keypad->key1 = keypad->key2 = 0;
124 	}
125 	input_sync(input_dev);
126 
127 	return IRQ_HANDLED;
128 }
129 
ep93xx_keypad_config(struct ep93xx_keypad * keypad)130 static void ep93xx_keypad_config(struct ep93xx_keypad *keypad)
131 {
132 	unsigned int val = 0;
133 
134 	val |= (keypad->debounce << KEY_INIT_DBNC_SHIFT) & KEY_INIT_DBNC_MASK;
135 
136 	val |= (keypad->prescale << KEY_INIT_PRSCL_SHIFT) & KEY_INIT_PRSCL_MASK;
137 
138 	__raw_writel(val, keypad->mmio_base + KEY_INIT);
139 }
140 
ep93xx_keypad_open(struct input_dev * pdev)141 static int ep93xx_keypad_open(struct input_dev *pdev)
142 {
143 	struct ep93xx_keypad *keypad = input_get_drvdata(pdev);
144 
145 	if (!keypad->enabled) {
146 		ep93xx_keypad_config(keypad);
147 		clk_prepare_enable(keypad->clk);
148 		keypad->enabled = true;
149 	}
150 
151 	return 0;
152 }
153 
ep93xx_keypad_close(struct input_dev * pdev)154 static void ep93xx_keypad_close(struct input_dev *pdev)
155 {
156 	struct ep93xx_keypad *keypad = input_get_drvdata(pdev);
157 
158 	if (keypad->enabled) {
159 		clk_disable_unprepare(keypad->clk);
160 		keypad->enabled = false;
161 	}
162 }
163 
164 
ep93xx_keypad_suspend(struct device * dev)165 static int ep93xx_keypad_suspend(struct device *dev)
166 {
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;
170 
171 	guard(mutex)(&input_dev->mutex);
172 
173 	if (keypad->enabled) {
174 		clk_disable(keypad->clk);
175 		keypad->enabled = false;
176 	}
177 
178 	return 0;
179 }
180 
ep93xx_keypad_resume(struct device * dev)181 static int ep93xx_keypad_resume(struct device *dev)
182 {
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;
186 
187 	guard(mutex)(&input_dev->mutex);
188 
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;
194 		}
195 	}
196 
197 	return 0;
198 }
199 
200 static DEFINE_SIMPLE_DEV_PM_OPS(ep93xx_keypad_pm_ops,
201 				ep93xx_keypad_suspend, ep93xx_keypad_resume);
202 
ep93xx_keypad_probe(struct platform_device * pdev)203 static int ep93xx_keypad_probe(struct platform_device *pdev)
204 {
205 	struct device *dev = &pdev->dev;
206 	struct ep93xx_keypad *keypad;
207 	struct input_dev *input_dev;
208 	int err;
209 
210 	keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL);
211 	if (!keypad)
212 		return -ENOMEM;
213 
214 	keypad->irq = platform_get_irq(pdev, 0);
215 	if (keypad->irq < 0)
216 		return keypad->irq;
217 
218 	keypad->mmio_base = devm_platform_ioremap_resource(pdev, 0);
219 	if (IS_ERR(keypad->mmio_base))
220 		return PTR_ERR(keypad->mmio_base);
221 
222 	keypad->clk = devm_clk_get(&pdev->dev, NULL);
223 	if (IS_ERR(keypad->clk))
224 		return PTR_ERR(keypad->clk);
225 
226 	device_property_read_u32(dev, "debounce-delay-ms", &keypad->debounce);
227 	device_property_read_u16(dev, "cirrus,prescale", &keypad->prescale);
228 
229 	input_dev = devm_input_allocate_device(&pdev->dev);
230 	if (!input_dev)
231 		return -ENOMEM;
232 
233 	keypad->input_dev = input_dev;
234 
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;
239 
240 	err = matrix_keypad_build_keymap(NULL, NULL,
241 					 EP93XX_MATRIX_ROWS, EP93XX_MATRIX_COLS,
242 					 keypad->keycodes, input_dev);
243 	if (err)
244 		return err;
245 
246 	if (device_property_read_bool(&pdev->dev, "autorepeat"))
247 		__set_bit(EV_REP, input_dev->evbit);
248 	input_set_drvdata(input_dev, keypad);
249 
250 	err = devm_request_irq(&pdev->dev, keypad->irq,
251 			       ep93xx_keypad_irq_handler,
252 			       0, pdev->name, keypad);
253 	if (err)
254 		return err;
255 
256 	err = input_register_device(input_dev);
257 	if (err)
258 		return err;
259 
260 	platform_set_drvdata(pdev, keypad);
261 
262 	device_init_wakeup(&pdev->dev, 1);
263 	err = dev_pm_set_wake_irq(&pdev->dev, keypad->irq);
264 	if (err)
265 		dev_warn(&pdev->dev, "failed to set up wakeup irq: %d\n", err);
266 
267 	return 0;
268 }
269 
ep93xx_keypad_remove(struct platform_device * pdev)270 static void ep93xx_keypad_remove(struct platform_device *pdev)
271 {
272 	dev_pm_clear_wake_irq(&pdev->dev);
273 }
274 
275 static const struct of_device_id ep93xx_keypad_of_ids[] = {
276 	{ .compatible = "cirrus,ep9307-keypad" },
277 	{ /* sentinel */ }
278 };
279 MODULE_DEVICE_TABLE(of, ep93xx_keypad_of_ids);
280 
281 static struct platform_driver ep93xx_keypad_driver = {
282 	.driver		= {
283 		.name	= "ep93xx-keypad",
284 		.pm	= pm_sleep_ptr(&ep93xx_keypad_pm_ops),
285 		.of_match_table = ep93xx_keypad_of_ids,
286 	},
287 	.probe		= ep93xx_keypad_probe,
288 	.remove		= ep93xx_keypad_remove,
289 };
290 module_platform_driver(ep93xx_keypad_driver);
291 
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");
296