25 #include <linux/module.h>
27 #include <linux/slab.h>
31 #include <linux/input.h>
37 #define DRV_NAME "lpc32xx_keys"
42 #define LPC32XX_KS_DEB(x) ((x) + 0x00)
43 #define LPC32XX_KS_STATE_COND(x) ((x) + 0x04)
44 #define LPC32XX_KS_IRQ(x) ((x) + 0x08)
45 #define LPC32XX_KS_SCAN_CTL(x) ((x) + 0x0C)
46 #define LPC32XX_KS_FAST_TST(x) ((x) + 0x10)
47 #define LPC32XX_KS_MATRIX_DIM(x) ((x) + 0x14)
48 #define LPC32XX_KS_DATA(x, y) ((x) + 0x40 + ((y) << 2))
50 #define LPC32XX_KSCAN_DEB_NUM_DEB_PASS(n) ((n) & 0xFF)
52 #define LPC32XX_KSCAN_SCOND_IN_IDLE 0x0
53 #define LPC32XX_KSCAN_SCOND_IN_SCANONCE 0x1
54 #define LPC32XX_KSCAN_SCOND_IN_IRQGEN 0x2
55 #define LPC32XX_KSCAN_SCOND_IN_SCAN_MATRIX 0x3
57 #define LPC32XX_KSCAN_IRQ_PENDING_CLR 0x1
59 #define LPC32XX_KSCAN_SCTRL_SCAN_DELAY(n) ((n) & 0xFF)
61 #define LPC32XX_KSCAN_FTST_FORCESCANONCE 0x1
62 #define LPC32XX_KSCAN_FTST_USE32K_CLK 0x2
64 #define LPC32XX_KSCAN_MSEL_SELECT(n) ((n) & 0xF)
93 for (row = 0;
changed; row++, changed >>= 1) {
98 keycode = kscandat->
keymap[scancode];
100 input_report_key(input, keycode, key & (1 << row));
110 for (i = 0; i < kscandat->
matrix_sz; i++)
111 lpc32xx_mod_states(kscandat, i);
115 input_sync(kscandat->
input);
120 static int lpc32xx_kscan_open(
struct input_dev *
dev)
125 error = clk_prepare_enable(kscandat->
clk);
134 static void lpc32xx_kscan_close(
struct input_dev *dev)
139 clk_disable_unprepare(kscandat->
clk);
148 of_property_read_u32(np,
"keypad,num-rows", &rows);
149 of_property_read_u32(np,
"keypad,num-columns", &columns);
150 if (!rows || rows != columns) {
152 "rows and columns must be specified and be equal!\n");
157 kscandat->
row_shift = get_count_order(columns);
159 of_property_read_u32(np,
"nxp,debounce-delay-ms", &kscandat->
deb_clks);
160 of_property_read_u32(np,
"nxp,scan-delay-ms", &kscandat->
scan_delay);
162 dev_err(dev,
"debounce or scan delay not specified\n");
172 struct input_dev *
input;
180 dev_err(&pdev->
dev,
"failed to get platform I/O memory\n");
185 if (irq < 0 || irq >=
NR_IRQS) {
186 dev_err(&pdev->
dev,
"failed to get platform irq\n");
192 dev_err(&pdev->
dev,
"failed to allocate memory\n");
196 error = lpc32xx_parse_dt(&pdev->
dev, kscandat);
198 dev_err(&pdev->
dev,
"failed to parse device tree\n");
202 keymap_size =
sizeof(kscandat->
keymap[0]) *
206 dev_err(&pdev->
dev,
"could not allocate memory for keymap\n");
211 kscandat->
input = input = input_allocate_device();
213 dev_err(&pdev->
dev,
"failed to allocate input device\n");
215 goto err_free_keymap;
219 input->name = pdev->
name;
220 input->phys =
"lpc32xx/input0";
221 input->id.vendor = 0x0001;
222 input->id.product = 0x0001;
223 input->id.version = 0x0100;
224 input->open = lpc32xx_kscan_open;
225 input->close = lpc32xx_kscan_close;
226 input->dev.parent = &pdev->
dev;
235 dev_err(&pdev->
dev,
"failed to build keymap\n");
239 input_set_drvdata(kscandat->
input, kscandat);
243 if (!kscandat->
iores) {
244 dev_err(&pdev->
dev,
"failed to request I/O memory\n");
250 resource_size(kscandat->
iores));
252 dev_err(&pdev->
dev,
"failed to remap I/O memory\n");
254 goto err_release_memregion;
259 if (IS_ERR(kscandat->
clk)) {
261 error = PTR_ERR(kscandat->
clk);
266 error = clk_prepare_enable(kscandat->
clk);
277 clk_disable_unprepare(kscandat->
clk);
281 dev_err(&pdev->
dev,
"failed to request irq\n");
285 error = input_register_device(kscandat->
input);
287 dev_err(&pdev->
dev,
"failed to register input device\n");
291 platform_set_drvdata(pdev, kscandat);
300 err_release_memregion:
302 resource_size(kscandat->
iores));
304 input_free_device(kscandat->
input);
321 resource_size(kscandat->
iores));
322 input_unregister_device(kscandat->
input);
329 #ifdef CONFIG_PM_SLEEP
330 static int lpc32xx_kscan_suspend(
struct device *dev)
334 struct input_dev *input = kscandat->
input;
341 clk_disable_unprepare(kscandat->
clk);
348 static int lpc32xx_kscan_resume(
struct device *dev)
352 struct input_dev *input = kscandat->
input;
359 retval = clk_prepare_enable(kscandat->
clk);
370 lpc32xx_kscan_resume);
372 static const struct of_device_id lpc32xx_kscan_match[] = {
373 { .compatible =
"nxp,lpc3220-key" },
379 .probe = lpc32xx_kscan_probe,
384 .pm = &lpc32xx_kscan_pm_ops,