1 /* 2 * NXP LPC32xx SoC Key Scan Interface 3 * 4 * Authors: 5 * Kevin Wells <kevin.wells@nxp.com> 6 * Roland Stigge <stigge@antcom.de> 7 * 8 * Copyright (C) 2010 NXP Semiconductors 9 * Copyright (C) 2012 Roland Stigge 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * 22 * This controller supports square key matrices from 1x1 up to 8x8 23 */ 24 25 #include <linux/module.h> 26 #include <linux/interrupt.h> 27 #include <linux/slab.h> 28 #include <linux/irq.h> 29 #include <linux/pm.h> 30 #include <linux/platform_device.h> 31 #include <linux/input.h> 32 #include <linux/clk.h> 33 #include <linux/io.h> 34 #include <linux/of.h> 35 #include <linux/input/matrix_keypad.h> 36 37 #define DRV_NAME "lpc32xx_keys" 38 39 /* 40 * Key scanner register offsets 41 */ 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) /* 1..8 */ 48 #define LPC32XX_KS_DATA(x, y) ((x) + 0x40 + ((y) << 2)) 49 50 #define LPC32XX_KSCAN_DEB_NUM_DEB_PASS(n) ((n) & 0xFF) 51 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 56 57 #define LPC32XX_KSCAN_IRQ_PENDING_CLR 0x1 58 59 #define LPC32XX_KSCAN_SCTRL_SCAN_DELAY(n) ((n) & 0xFF) 60 61 #define LPC32XX_KSCAN_FTST_FORCESCANONCE 0x1 62 #define LPC32XX_KSCAN_FTST_USE32K_CLK 0x2 63 64 #define LPC32XX_KSCAN_MSEL_SELECT(n) ((n) & 0xF) 65 66 struct lpc32xx_kscan_drv { 67 struct input_dev *input; 68 struct clk *clk; 69 struct resource *iores; 70 void __iomem *kscan_base; 71 unsigned int irq; 72 73 u32 matrix_sz; /* Size of matrix in XxY, ie. 3 = 3x3 */ 74 u32 deb_clks; /* Debounce clocks (based on 32KHz clock) */ 75 u32 scan_delay; /* Scan delay (based on 32KHz clock) */ 76 77 unsigned short *keymap; /* Pointer to key map for the scan matrix */ 78 unsigned int row_shift; 79 80 u8 lastkeystates[8]; 81 }; 82 83 static void lpc32xx_mod_states(struct lpc32xx_kscan_drv *kscandat, int col) 84 { 85 struct input_dev *input = kscandat->input; 86 unsigned row, changed, scancode, keycode; 87 u8 key; 88 89 key = readl(LPC32XX_KS_DATA(kscandat->kscan_base, col)); 90 changed = key ^ kscandat->lastkeystates[col]; 91 kscandat->lastkeystates[col] = key; 92 93 for (row = 0; changed; row++, changed >>= 1) { 94 if (changed & 1) { 95 /* Key state changed, signal an event */ 96 scancode = MATRIX_SCAN_CODE(row, col, 97 kscandat->row_shift); 98 keycode = kscandat->keymap[scancode]; 99 input_event(input, EV_MSC, MSC_SCAN, scancode); 100 input_report_key(input, keycode, key & (1 << row)); 101 } 102 } 103 } 104 105 static irqreturn_t lpc32xx_kscan_irq(int irq, void *dev_id) 106 { 107 struct lpc32xx_kscan_drv *kscandat = dev_id; 108 int i; 109 110 for (i = 0; i < kscandat->matrix_sz; i++) 111 lpc32xx_mod_states(kscandat, i); 112 113 writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); 114 115 input_sync(kscandat->input); 116 117 return IRQ_HANDLED; 118 } 119 120 static int lpc32xx_kscan_open(struct input_dev *dev) 121 { 122 struct lpc32xx_kscan_drv *kscandat = input_get_drvdata(dev); 123 int error; 124 125 error = clk_prepare_enable(kscandat->clk); 126 if (error) 127 return error; 128 129 writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); 130 131 return 0; 132 } 133 134 static void lpc32xx_kscan_close(struct input_dev *dev) 135 { 136 struct lpc32xx_kscan_drv *kscandat = input_get_drvdata(dev); 137 138 writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); 139 clk_disable_unprepare(kscandat->clk); 140 } 141 142 static int lpc32xx_parse_dt(struct device *dev, 143 struct lpc32xx_kscan_drv *kscandat) 144 { 145 struct device_node *np = dev->of_node; 146 u32 rows = 0, columns = 0; 147 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) { 151 dev_err(dev, 152 "rows and columns must be specified and be equal!\n"); 153 return -EINVAL; 154 } 155 156 kscandat->matrix_sz = rows; 157 kscandat->row_shift = get_count_order(columns); 158 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); 161 if (!kscandat->deb_clks || !kscandat->scan_delay) { 162 dev_err(dev, "debounce or scan delay not specified\n"); 163 return -EINVAL; 164 } 165 166 return 0; 167 } 168 169 static int lpc32xx_kscan_probe(struct platform_device *pdev) 170 { 171 struct lpc32xx_kscan_drv *kscandat; 172 struct input_dev *input; 173 struct resource *res; 174 size_t keymap_size; 175 int error; 176 int irq; 177 178 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 179 if (!res) { 180 dev_err(&pdev->dev, "failed to get platform I/O memory\n"); 181 return -EINVAL; 182 } 183 184 irq = platform_get_irq(pdev, 0); 185 if (irq < 0 || irq >= NR_IRQS) { 186 dev_err(&pdev->dev, "failed to get platform irq\n"); 187 return -EINVAL; 188 } 189 190 kscandat = kzalloc(sizeof(struct lpc32xx_kscan_drv), GFP_KERNEL); 191 if (!kscandat) { 192 dev_err(&pdev->dev, "failed to allocate memory\n"); 193 return -ENOMEM; 194 } 195 196 error = lpc32xx_parse_dt(&pdev->dev, kscandat); 197 if (error) { 198 dev_err(&pdev->dev, "failed to parse device tree\n"); 199 goto err_free_mem; 200 } 201 202 keymap_size = sizeof(kscandat->keymap[0]) * 203 (kscandat->matrix_sz << kscandat->row_shift); 204 kscandat->keymap = kzalloc(keymap_size, GFP_KERNEL); 205 if (!kscandat->keymap) { 206 dev_err(&pdev->dev, "could not allocate memory for keymap\n"); 207 error = -ENOMEM; 208 goto err_free_mem; 209 } 210 211 kscandat->input = input = input_allocate_device(); 212 if (!input) { 213 dev_err(&pdev->dev, "failed to allocate input device\n"); 214 error = -ENOMEM; 215 goto err_free_keymap; 216 } 217 218 /* Setup key input */ 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; 227 228 input_set_capability(input, EV_MSC, MSC_SCAN); 229 230 error = matrix_keypad_build_keymap(NULL, NULL, 231 kscandat->matrix_sz, 232 kscandat->matrix_sz, 233 kscandat->keymap, kscandat->input); 234 if (error) { 235 dev_err(&pdev->dev, "failed to build keymap\n"); 236 goto err_free_input; 237 } 238 239 input_set_drvdata(kscandat->input, kscandat); 240 241 kscandat->iores = request_mem_region(res->start, resource_size(res), 242 pdev->name); 243 if (!kscandat->iores) { 244 dev_err(&pdev->dev, "failed to request I/O memory\n"); 245 error = -EBUSY; 246 goto err_free_input; 247 } 248 249 kscandat->kscan_base = ioremap(kscandat->iores->start, 250 resource_size(kscandat->iores)); 251 if (!kscandat->kscan_base) { 252 dev_err(&pdev->dev, "failed to remap I/O memory\n"); 253 error = -EBUSY; 254 goto err_release_memregion; 255 } 256 257 /* Get the key scanner clock */ 258 kscandat->clk = clk_get(&pdev->dev, NULL); 259 if (IS_ERR(kscandat->clk)) { 260 dev_err(&pdev->dev, "failed to get clock\n"); 261 error = PTR_ERR(kscandat->clk); 262 goto err_unmap; 263 } 264 265 /* Configure the key scanner */ 266 error = clk_prepare_enable(kscandat->clk); 267 if (error) 268 goto err_clk_put; 269 270 writel(kscandat->deb_clks, LPC32XX_KS_DEB(kscandat->kscan_base)); 271 writel(kscandat->scan_delay, LPC32XX_KS_SCAN_CTL(kscandat->kscan_base)); 272 writel(LPC32XX_KSCAN_FTST_USE32K_CLK, 273 LPC32XX_KS_FAST_TST(kscandat->kscan_base)); 274 writel(kscandat->matrix_sz, 275 LPC32XX_KS_MATRIX_DIM(kscandat->kscan_base)); 276 writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); 277 clk_disable_unprepare(kscandat->clk); 278 279 error = request_irq(irq, lpc32xx_kscan_irq, 0, pdev->name, kscandat); 280 if (error) { 281 dev_err(&pdev->dev, "failed to request irq\n"); 282 goto err_clk_put; 283 } 284 285 error = input_register_device(kscandat->input); 286 if (error) { 287 dev_err(&pdev->dev, "failed to register input device\n"); 288 goto err_free_irq; 289 } 290 291 platform_set_drvdata(pdev, kscandat); 292 return 0; 293 294 err_free_irq: 295 free_irq(irq, kscandat); 296 err_clk_put: 297 clk_put(kscandat->clk); 298 err_unmap: 299 iounmap(kscandat->kscan_base); 300 err_release_memregion: 301 release_mem_region(kscandat->iores->start, 302 resource_size(kscandat->iores)); 303 err_free_input: 304 input_free_device(kscandat->input); 305 err_free_keymap: 306 kfree(kscandat->keymap); 307 err_free_mem: 308 kfree(kscandat); 309 310 return error; 311 } 312 313 static int lpc32xx_kscan_remove(struct platform_device *pdev) 314 { 315 struct lpc32xx_kscan_drv *kscandat = platform_get_drvdata(pdev); 316 317 free_irq(platform_get_irq(pdev, 0), kscandat); 318 clk_put(kscandat->clk); 319 iounmap(kscandat->kscan_base); 320 release_mem_region(kscandat->iores->start, 321 resource_size(kscandat->iores)); 322 input_unregister_device(kscandat->input); 323 kfree(kscandat->keymap); 324 kfree(kscandat); 325 326 return 0; 327 } 328 329 #ifdef CONFIG_PM_SLEEP 330 static int lpc32xx_kscan_suspend(struct device *dev) 331 { 332 struct platform_device *pdev = to_platform_device(dev); 333 struct lpc32xx_kscan_drv *kscandat = platform_get_drvdata(pdev); 334 struct input_dev *input = kscandat->input; 335 336 mutex_lock(&input->mutex); 337 338 if (input->users) { 339 /* Clear IRQ and disable clock */ 340 writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); 341 clk_disable_unprepare(kscandat->clk); 342 } 343 344 mutex_unlock(&input->mutex); 345 return 0; 346 } 347 348 static int lpc32xx_kscan_resume(struct device *dev) 349 { 350 struct platform_device *pdev = to_platform_device(dev); 351 struct lpc32xx_kscan_drv *kscandat = platform_get_drvdata(pdev); 352 struct input_dev *input = kscandat->input; 353 int retval = 0; 354 355 mutex_lock(&input->mutex); 356 357 if (input->users) { 358 /* Enable clock and clear IRQ */ 359 retval = clk_prepare_enable(kscandat->clk); 360 if (retval == 0) 361 writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); 362 } 363 364 mutex_unlock(&input->mutex); 365 return retval; 366 } 367 #endif 368 369 static SIMPLE_DEV_PM_OPS(lpc32xx_kscan_pm_ops, lpc32xx_kscan_suspend, 370 lpc32xx_kscan_resume); 371 372 static const struct of_device_id lpc32xx_kscan_match[] = { 373 { .compatible = "nxp,lpc3220-key" }, 374 {}, 375 }; 376 MODULE_DEVICE_TABLE(of, lpc32xx_kscan_match); 377 378 static struct platform_driver lpc32xx_kscan_driver = { 379 .probe = lpc32xx_kscan_probe, 380 .remove = lpc32xx_kscan_remove, 381 .driver = { 382 .name = DRV_NAME, 383 .owner = THIS_MODULE, 384 .pm = &lpc32xx_kscan_pm_ops, 385 .of_match_table = of_match_ptr(lpc32xx_kscan_match), 386 } 387 }; 388 389 module_platform_driver(lpc32xx_kscan_driver); 390 391 MODULE_LICENSE("GPL"); 392 MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com>"); 393 MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>"); 394 MODULE_DESCRIPTION("Key scanner driver for LPC32XX devices"); 395