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 int err; 148 149 err = matrix_keypad_parse_of_params(dev, &rows, &columns); 150 if (err) 151 return err; 152 if (rows != columns) { 153 dev_err(dev, "rows and columns must be equal!\n"); 154 return -EINVAL; 155 } 156 157 kscandat->matrix_sz = rows; 158 kscandat->row_shift = get_count_order(columns); 159 160 of_property_read_u32(np, "nxp,debounce-delay-ms", &kscandat->deb_clks); 161 of_property_read_u32(np, "nxp,scan-delay-ms", &kscandat->scan_delay); 162 if (!kscandat->deb_clks || !kscandat->scan_delay) { 163 dev_err(dev, "debounce or scan delay not specified\n"); 164 return -EINVAL; 165 } 166 167 return 0; 168 } 169 170 static int lpc32xx_kscan_probe(struct platform_device *pdev) 171 { 172 struct lpc32xx_kscan_drv *kscandat; 173 struct input_dev *input; 174 struct resource *res; 175 size_t keymap_size; 176 int error; 177 int irq; 178 179 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 180 if (!res) { 181 dev_err(&pdev->dev, "failed to get platform I/O memory\n"); 182 return -EINVAL; 183 } 184 185 irq = platform_get_irq(pdev, 0); 186 if (irq < 0 || irq >= NR_IRQS) { 187 dev_err(&pdev->dev, "failed to get platform irq\n"); 188 return -EINVAL; 189 } 190 191 kscandat = kzalloc(sizeof(struct lpc32xx_kscan_drv), GFP_KERNEL); 192 if (!kscandat) { 193 dev_err(&pdev->dev, "failed to allocate memory\n"); 194 return -ENOMEM; 195 } 196 197 error = lpc32xx_parse_dt(&pdev->dev, kscandat); 198 if (error) { 199 dev_err(&pdev->dev, "failed to parse device tree\n"); 200 goto err_free_mem; 201 } 202 203 keymap_size = sizeof(kscandat->keymap[0]) * 204 (kscandat->matrix_sz << kscandat->row_shift); 205 kscandat->keymap = kzalloc(keymap_size, GFP_KERNEL); 206 if (!kscandat->keymap) { 207 dev_err(&pdev->dev, "could not allocate memory for keymap\n"); 208 error = -ENOMEM; 209 goto err_free_mem; 210 } 211 212 kscandat->input = input = input_allocate_device(); 213 if (!input) { 214 dev_err(&pdev->dev, "failed to allocate input device\n"); 215 error = -ENOMEM; 216 goto err_free_keymap; 217 } 218 219 /* Setup key input */ 220 input->name = pdev->name; 221 input->phys = "lpc32xx/input0"; 222 input->id.vendor = 0x0001; 223 input->id.product = 0x0001; 224 input->id.version = 0x0100; 225 input->open = lpc32xx_kscan_open; 226 input->close = lpc32xx_kscan_close; 227 input->dev.parent = &pdev->dev; 228 229 input_set_capability(input, EV_MSC, MSC_SCAN); 230 231 error = matrix_keypad_build_keymap(NULL, NULL, 232 kscandat->matrix_sz, 233 kscandat->matrix_sz, 234 kscandat->keymap, kscandat->input); 235 if (error) { 236 dev_err(&pdev->dev, "failed to build keymap\n"); 237 goto err_free_input; 238 } 239 240 input_set_drvdata(kscandat->input, kscandat); 241 242 kscandat->iores = request_mem_region(res->start, resource_size(res), 243 pdev->name); 244 if (!kscandat->iores) { 245 dev_err(&pdev->dev, "failed to request I/O memory\n"); 246 error = -EBUSY; 247 goto err_free_input; 248 } 249 250 kscandat->kscan_base = ioremap(kscandat->iores->start, 251 resource_size(kscandat->iores)); 252 if (!kscandat->kscan_base) { 253 dev_err(&pdev->dev, "failed to remap I/O memory\n"); 254 error = -EBUSY; 255 goto err_release_memregion; 256 } 257 258 /* Get the key scanner clock */ 259 kscandat->clk = clk_get(&pdev->dev, NULL); 260 if (IS_ERR(kscandat->clk)) { 261 dev_err(&pdev->dev, "failed to get clock\n"); 262 error = PTR_ERR(kscandat->clk); 263 goto err_unmap; 264 } 265 266 /* Configure the key scanner */ 267 error = clk_prepare_enable(kscandat->clk); 268 if (error) 269 goto err_clk_put; 270 271 writel(kscandat->deb_clks, LPC32XX_KS_DEB(kscandat->kscan_base)); 272 writel(kscandat->scan_delay, LPC32XX_KS_SCAN_CTL(kscandat->kscan_base)); 273 writel(LPC32XX_KSCAN_FTST_USE32K_CLK, 274 LPC32XX_KS_FAST_TST(kscandat->kscan_base)); 275 writel(kscandat->matrix_sz, 276 LPC32XX_KS_MATRIX_DIM(kscandat->kscan_base)); 277 writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); 278 clk_disable_unprepare(kscandat->clk); 279 280 error = request_irq(irq, lpc32xx_kscan_irq, 0, pdev->name, kscandat); 281 if (error) { 282 dev_err(&pdev->dev, "failed to request irq\n"); 283 goto err_clk_put; 284 } 285 286 error = input_register_device(kscandat->input); 287 if (error) { 288 dev_err(&pdev->dev, "failed to register input device\n"); 289 goto err_free_irq; 290 } 291 292 platform_set_drvdata(pdev, kscandat); 293 return 0; 294 295 err_free_irq: 296 free_irq(irq, kscandat); 297 err_clk_put: 298 clk_put(kscandat->clk); 299 err_unmap: 300 iounmap(kscandat->kscan_base); 301 err_release_memregion: 302 release_mem_region(kscandat->iores->start, 303 resource_size(kscandat->iores)); 304 err_free_input: 305 input_free_device(kscandat->input); 306 err_free_keymap: 307 kfree(kscandat->keymap); 308 err_free_mem: 309 kfree(kscandat); 310 311 return error; 312 } 313 314 static int lpc32xx_kscan_remove(struct platform_device *pdev) 315 { 316 struct lpc32xx_kscan_drv *kscandat = platform_get_drvdata(pdev); 317 318 free_irq(platform_get_irq(pdev, 0), kscandat); 319 clk_put(kscandat->clk); 320 iounmap(kscandat->kscan_base); 321 release_mem_region(kscandat->iores->start, 322 resource_size(kscandat->iores)); 323 input_unregister_device(kscandat->input); 324 kfree(kscandat->keymap); 325 kfree(kscandat); 326 327 return 0; 328 } 329 330 #ifdef CONFIG_PM_SLEEP 331 static int lpc32xx_kscan_suspend(struct device *dev) 332 { 333 struct platform_device *pdev = to_platform_device(dev); 334 struct lpc32xx_kscan_drv *kscandat = platform_get_drvdata(pdev); 335 struct input_dev *input = kscandat->input; 336 337 mutex_lock(&input->mutex); 338 339 if (input->users) { 340 /* Clear IRQ and disable clock */ 341 writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); 342 clk_disable_unprepare(kscandat->clk); 343 } 344 345 mutex_unlock(&input->mutex); 346 return 0; 347 } 348 349 static int lpc32xx_kscan_resume(struct device *dev) 350 { 351 struct platform_device *pdev = to_platform_device(dev); 352 struct lpc32xx_kscan_drv *kscandat = platform_get_drvdata(pdev); 353 struct input_dev *input = kscandat->input; 354 int retval = 0; 355 356 mutex_lock(&input->mutex); 357 358 if (input->users) { 359 /* Enable clock and clear IRQ */ 360 retval = clk_prepare_enable(kscandat->clk); 361 if (retval == 0) 362 writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base)); 363 } 364 365 mutex_unlock(&input->mutex); 366 return retval; 367 } 368 #endif 369 370 static SIMPLE_DEV_PM_OPS(lpc32xx_kscan_pm_ops, lpc32xx_kscan_suspend, 371 lpc32xx_kscan_resume); 372 373 static const struct of_device_id lpc32xx_kscan_match[] = { 374 { .compatible = "nxp,lpc3220-key" }, 375 {}, 376 }; 377 MODULE_DEVICE_TABLE(of, lpc32xx_kscan_match); 378 379 static struct platform_driver lpc32xx_kscan_driver = { 380 .probe = lpc32xx_kscan_probe, 381 .remove = lpc32xx_kscan_remove, 382 .driver = { 383 .name = DRV_NAME, 384 .owner = THIS_MODULE, 385 .pm = &lpc32xx_kscan_pm_ops, 386 .of_match_table = of_match_ptr(lpc32xx_kscan_match), 387 } 388 }; 389 390 module_platform_driver(lpc32xx_kscan_driver); 391 392 MODULE_LICENSE("GPL"); 393 MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com>"); 394 MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>"); 395 MODULE_DESCRIPTION("Key scanner driver for LPC32XX devices"); 396