1 /* 2 * OMAP4 Keypad Driver 3 * 4 * Copyright (C) 2010 Texas Instruments 5 * 6 * Author: Abraham Arce <x0066660@ti.com> 7 * Initial Code: Syed Rafiuddin <rafiuddin.syed@ti.com> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 */ 23 24 #include <linux/module.h> 25 #include <linux/interrupt.h> 26 #include <linux/platform_device.h> 27 #include <linux/errno.h> 28 #include <linux/io.h> 29 #include <linux/of.h> 30 #include <linux/input.h> 31 #include <linux/slab.h> 32 #include <linux/pm_runtime.h> 33 34 #include <linux/platform_data/omap4-keypad.h> 35 36 /* OMAP4 registers */ 37 #define OMAP4_KBD_REVISION 0x00 38 #define OMAP4_KBD_SYSCONFIG 0x10 39 #define OMAP4_KBD_SYSSTATUS 0x14 40 #define OMAP4_KBD_IRQSTATUS 0x18 41 #define OMAP4_KBD_IRQENABLE 0x1C 42 #define OMAP4_KBD_WAKEUPENABLE 0x20 43 #define OMAP4_KBD_PENDING 0x24 44 #define OMAP4_KBD_CTRL 0x28 45 #define OMAP4_KBD_DEBOUNCINGTIME 0x2C 46 #define OMAP4_KBD_LONGKEYTIME 0x30 47 #define OMAP4_KBD_TIMEOUT 0x34 48 #define OMAP4_KBD_STATEMACHINE 0x38 49 #define OMAP4_KBD_ROWINPUTS 0x3C 50 #define OMAP4_KBD_COLUMNOUTPUTS 0x40 51 #define OMAP4_KBD_FULLCODE31_0 0x44 52 #define OMAP4_KBD_FULLCODE63_32 0x48 53 54 /* OMAP4 bit definitions */ 55 #define OMAP4_DEF_IRQENABLE_EVENTEN BIT(0) 56 #define OMAP4_DEF_IRQENABLE_LONGKEY BIT(1) 57 #define OMAP4_DEF_WUP_EVENT_ENA BIT(0) 58 #define OMAP4_DEF_WUP_LONG_KEY_ENA BIT(1) 59 #define OMAP4_DEF_CTRL_NOSOFTMODE BIT(1) 60 #define OMAP4_DEF_CTRL_PTV_SHIFT 2 61 62 /* OMAP4 values */ 63 #define OMAP4_VAL_IRQDISABLE 0x0 64 #define OMAP4_VAL_DEBOUNCINGTIME 0x7 65 #define OMAP4_VAL_PVT 0x7 66 67 enum { 68 KBD_REVISION_OMAP4 = 0, 69 KBD_REVISION_OMAP5, 70 }; 71 72 struct omap4_keypad { 73 struct input_dev *input; 74 75 void __iomem *base; 76 bool irq_wake_enabled; 77 unsigned int irq; 78 79 unsigned int rows; 80 unsigned int cols; 81 u32 reg_offset; 82 u32 irqreg_offset; 83 unsigned int row_shift; 84 bool no_autorepeat; 85 unsigned char key_state[8]; 86 unsigned short *keymap; 87 }; 88 89 static int kbd_readl(struct omap4_keypad *keypad_data, u32 offset) 90 { 91 return __raw_readl(keypad_data->base + 92 keypad_data->reg_offset + offset); 93 } 94 95 static void kbd_writel(struct omap4_keypad *keypad_data, u32 offset, u32 value) 96 { 97 __raw_writel(value, 98 keypad_data->base + keypad_data->reg_offset + offset); 99 } 100 101 static int kbd_read_irqreg(struct omap4_keypad *keypad_data, u32 offset) 102 { 103 return __raw_readl(keypad_data->base + 104 keypad_data->irqreg_offset + offset); 105 } 106 107 static void kbd_write_irqreg(struct omap4_keypad *keypad_data, 108 u32 offset, u32 value) 109 { 110 __raw_writel(value, 111 keypad_data->base + keypad_data->irqreg_offset + offset); 112 } 113 114 115 /* Interrupt handlers */ 116 static irqreturn_t omap4_keypad_irq_handler(int irq, void *dev_id) 117 { 118 struct omap4_keypad *keypad_data = dev_id; 119 120 if (kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)) { 121 /* Disable interrupts */ 122 kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, 123 OMAP4_VAL_IRQDISABLE); 124 return IRQ_WAKE_THREAD; 125 } 126 127 return IRQ_NONE; 128 } 129 130 static irqreturn_t omap4_keypad_irq_thread_fn(int irq, void *dev_id) 131 { 132 struct omap4_keypad *keypad_data = dev_id; 133 struct input_dev *input_dev = keypad_data->input; 134 unsigned char key_state[ARRAY_SIZE(keypad_data->key_state)]; 135 unsigned int col, row, code, changed; 136 u32 *new_state = (u32 *) key_state; 137 138 *new_state = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE31_0); 139 *(new_state + 1) = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE63_32); 140 141 for (row = 0; row < keypad_data->rows; row++) { 142 changed = key_state[row] ^ keypad_data->key_state[row]; 143 if (!changed) 144 continue; 145 146 for (col = 0; col < keypad_data->cols; col++) { 147 if (changed & (1 << col)) { 148 code = MATRIX_SCAN_CODE(row, col, 149 keypad_data->row_shift); 150 input_event(input_dev, EV_MSC, MSC_SCAN, code); 151 input_report_key(input_dev, 152 keypad_data->keymap[code], 153 key_state[row] & (1 << col)); 154 } 155 } 156 } 157 158 input_sync(input_dev); 159 160 memcpy(keypad_data->key_state, key_state, 161 sizeof(keypad_data->key_state)); 162 163 /* clear pending interrupts */ 164 kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS, 165 kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)); 166 167 /* enable interrupts */ 168 kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, 169 OMAP4_DEF_IRQENABLE_EVENTEN | 170 OMAP4_DEF_IRQENABLE_LONGKEY); 171 172 return IRQ_HANDLED; 173 } 174 175 static int omap4_keypad_open(struct input_dev *input) 176 { 177 struct omap4_keypad *keypad_data = input_get_drvdata(input); 178 179 pm_runtime_get_sync(input->dev.parent); 180 181 disable_irq(keypad_data->irq); 182 183 kbd_writel(keypad_data, OMAP4_KBD_CTRL, 184 OMAP4_DEF_CTRL_NOSOFTMODE | 185 (OMAP4_VAL_PVT << OMAP4_DEF_CTRL_PTV_SHIFT)); 186 kbd_writel(keypad_data, OMAP4_KBD_DEBOUNCINGTIME, 187 OMAP4_VAL_DEBOUNCINGTIME); 188 /* clear pending interrupts */ 189 kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS, 190 kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)); 191 kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, 192 OMAP4_DEF_IRQENABLE_EVENTEN | 193 OMAP4_DEF_IRQENABLE_LONGKEY); 194 kbd_writel(keypad_data, OMAP4_KBD_WAKEUPENABLE, 195 OMAP4_DEF_WUP_EVENT_ENA | OMAP4_DEF_WUP_LONG_KEY_ENA); 196 197 enable_irq(keypad_data->irq); 198 199 return 0; 200 } 201 202 static void omap4_keypad_close(struct input_dev *input) 203 { 204 struct omap4_keypad *keypad_data = input_get_drvdata(input); 205 206 disable_irq(keypad_data->irq); 207 208 /* Disable interrupts */ 209 kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, 210 OMAP4_VAL_IRQDISABLE); 211 212 /* clear pending interrupts */ 213 kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS, 214 kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)); 215 216 enable_irq(keypad_data->irq); 217 218 pm_runtime_put_sync(input->dev.parent); 219 } 220 221 #ifdef CONFIG_OF 222 static int omap4_keypad_parse_dt(struct device *dev, 223 struct omap4_keypad *keypad_data) 224 { 225 struct device_node *np = dev->of_node; 226 int err; 227 228 err = matrix_keypad_parse_of_params(dev, &keypad_data->rows, 229 &keypad_data->cols); 230 if (err) 231 return err; 232 233 if (of_get_property(np, "linux,input-no-autorepeat", NULL)) 234 keypad_data->no_autorepeat = true; 235 236 return 0; 237 } 238 #else 239 static inline int omap4_keypad_parse_dt(struct device *dev, 240 struct omap4_keypad *keypad_data) 241 { 242 return -ENOSYS; 243 } 244 #endif 245 246 static int omap4_keypad_probe(struct platform_device *pdev) 247 { 248 const struct omap4_keypad_platform_data *pdata = 249 dev_get_platdata(&pdev->dev); 250 const struct matrix_keymap_data *keymap_data = 251 pdata ? pdata->keymap_data : NULL; 252 struct omap4_keypad *keypad_data; 253 struct input_dev *input_dev; 254 struct resource *res; 255 unsigned int max_keys; 256 int rev; 257 int irq; 258 int error; 259 260 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 261 if (!res) { 262 dev_err(&pdev->dev, "no base address specified\n"); 263 return -EINVAL; 264 } 265 266 irq = platform_get_irq(pdev, 0); 267 if (!irq) { 268 dev_err(&pdev->dev, "no keyboard irq assigned\n"); 269 return -EINVAL; 270 } 271 272 keypad_data = kzalloc(sizeof(struct omap4_keypad), GFP_KERNEL); 273 if (!keypad_data) { 274 dev_err(&pdev->dev, "keypad_data memory allocation failed\n"); 275 return -ENOMEM; 276 } 277 278 keypad_data->irq = irq; 279 280 if (pdata) { 281 keypad_data->rows = pdata->rows; 282 keypad_data->cols = pdata->cols; 283 } else { 284 error = omap4_keypad_parse_dt(&pdev->dev, keypad_data); 285 if (error) 286 return error; 287 } 288 289 res = request_mem_region(res->start, resource_size(res), pdev->name); 290 if (!res) { 291 dev_err(&pdev->dev, "can't request mem region\n"); 292 error = -EBUSY; 293 goto err_free_keypad; 294 } 295 296 keypad_data->base = ioremap(res->start, resource_size(res)); 297 if (!keypad_data->base) { 298 dev_err(&pdev->dev, "can't ioremap mem resource\n"); 299 error = -ENOMEM; 300 goto err_release_mem; 301 } 302 303 304 /* 305 * Enable clocks for the keypad module so that we can read 306 * revision register. 307 */ 308 pm_runtime_enable(&pdev->dev); 309 error = pm_runtime_get_sync(&pdev->dev); 310 if (error) { 311 dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n"); 312 goto err_unmap; 313 } 314 rev = __raw_readl(keypad_data->base + OMAP4_KBD_REVISION); 315 rev &= 0x03 << 30; 316 rev >>= 30; 317 switch (rev) { 318 case KBD_REVISION_OMAP4: 319 keypad_data->reg_offset = 0x00; 320 keypad_data->irqreg_offset = 0x00; 321 break; 322 case KBD_REVISION_OMAP5: 323 keypad_data->reg_offset = 0x10; 324 keypad_data->irqreg_offset = 0x0c; 325 break; 326 default: 327 dev_err(&pdev->dev, 328 "Keypad reports unsupported revision %d", rev); 329 error = -EINVAL; 330 goto err_pm_put_sync; 331 } 332 333 /* input device allocation */ 334 keypad_data->input = input_dev = input_allocate_device(); 335 if (!input_dev) { 336 error = -ENOMEM; 337 goto err_pm_put_sync; 338 } 339 340 input_dev->name = pdev->name; 341 input_dev->dev.parent = &pdev->dev; 342 input_dev->id.bustype = BUS_HOST; 343 input_dev->id.vendor = 0x0001; 344 input_dev->id.product = 0x0001; 345 input_dev->id.version = 0x0001; 346 347 input_dev->open = omap4_keypad_open; 348 input_dev->close = omap4_keypad_close; 349 350 input_set_capability(input_dev, EV_MSC, MSC_SCAN); 351 if (!keypad_data->no_autorepeat) 352 __set_bit(EV_REP, input_dev->evbit); 353 354 input_set_drvdata(input_dev, keypad_data); 355 356 keypad_data->row_shift = get_count_order(keypad_data->cols); 357 max_keys = keypad_data->rows << keypad_data->row_shift; 358 keypad_data->keymap = kzalloc(max_keys * sizeof(keypad_data->keymap[0]), 359 GFP_KERNEL); 360 if (!keypad_data->keymap) { 361 dev_err(&pdev->dev, "Not enough memory for keymap\n"); 362 error = -ENOMEM; 363 goto err_free_input; 364 } 365 366 error = matrix_keypad_build_keymap(keymap_data, NULL, 367 keypad_data->rows, keypad_data->cols, 368 keypad_data->keymap, input_dev); 369 if (error) { 370 dev_err(&pdev->dev, "failed to build keymap\n"); 371 goto err_free_keymap; 372 } 373 374 error = request_threaded_irq(keypad_data->irq, omap4_keypad_irq_handler, 375 omap4_keypad_irq_thread_fn, 0, 376 "omap4-keypad", keypad_data); 377 if (error) { 378 dev_err(&pdev->dev, "failed to register interrupt\n"); 379 goto err_free_input; 380 } 381 382 device_init_wakeup(&pdev->dev, true); 383 pm_runtime_put_sync(&pdev->dev); 384 385 error = input_register_device(keypad_data->input); 386 if (error < 0) { 387 dev_err(&pdev->dev, "failed to register input device\n"); 388 goto err_pm_disable; 389 } 390 391 platform_set_drvdata(pdev, keypad_data); 392 return 0; 393 394 err_pm_disable: 395 pm_runtime_disable(&pdev->dev); 396 device_init_wakeup(&pdev->dev, false); 397 free_irq(keypad_data->irq, keypad_data); 398 err_free_keymap: 399 kfree(keypad_data->keymap); 400 err_free_input: 401 input_free_device(input_dev); 402 err_pm_put_sync: 403 pm_runtime_put_sync(&pdev->dev); 404 err_unmap: 405 iounmap(keypad_data->base); 406 err_release_mem: 407 release_mem_region(res->start, resource_size(res)); 408 err_free_keypad: 409 kfree(keypad_data); 410 return error; 411 } 412 413 static int omap4_keypad_remove(struct platform_device *pdev) 414 { 415 struct omap4_keypad *keypad_data = platform_get_drvdata(pdev); 416 struct resource *res; 417 418 free_irq(keypad_data->irq, keypad_data); 419 420 pm_runtime_disable(&pdev->dev); 421 422 device_init_wakeup(&pdev->dev, false); 423 424 input_unregister_device(keypad_data->input); 425 426 iounmap(keypad_data->base); 427 428 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 429 release_mem_region(res->start, resource_size(res)); 430 431 kfree(keypad_data->keymap); 432 kfree(keypad_data); 433 434 return 0; 435 } 436 437 #ifdef CONFIG_OF 438 static const struct of_device_id omap_keypad_dt_match[] = { 439 { .compatible = "ti,omap4-keypad" }, 440 {}, 441 }; 442 MODULE_DEVICE_TABLE(of, omap_keypad_dt_match); 443 #endif 444 445 #ifdef CONFIG_PM_SLEEP 446 static int omap4_keypad_suspend(struct device *dev) 447 { 448 struct platform_device *pdev = to_platform_device(dev); 449 struct omap4_keypad *keypad_data = platform_get_drvdata(pdev); 450 int error; 451 452 if (device_may_wakeup(&pdev->dev)) { 453 error = enable_irq_wake(keypad_data->irq); 454 if (!error) 455 keypad_data->irq_wake_enabled = true; 456 } 457 458 return 0; 459 } 460 461 static int omap4_keypad_resume(struct device *dev) 462 { 463 struct platform_device *pdev = to_platform_device(dev); 464 struct omap4_keypad *keypad_data = platform_get_drvdata(pdev); 465 466 if (device_may_wakeup(&pdev->dev) && keypad_data->irq_wake_enabled) { 467 disable_irq_wake(keypad_data->irq); 468 keypad_data->irq_wake_enabled = false; 469 } 470 471 return 0; 472 } 473 #endif 474 475 static SIMPLE_DEV_PM_OPS(omap4_keypad_pm_ops, 476 omap4_keypad_suspend, omap4_keypad_resume); 477 478 static struct platform_driver omap4_keypad_driver = { 479 .probe = omap4_keypad_probe, 480 .remove = omap4_keypad_remove, 481 .driver = { 482 .name = "omap4-keypad", 483 .owner = THIS_MODULE, 484 .pm = &omap4_keypad_pm_ops, 485 .of_match_table = of_match_ptr(omap_keypad_dt_match), 486 }, 487 }; 488 module_platform_driver(omap4_keypad_driver); 489 490 MODULE_AUTHOR("Texas Instruments"); 491 MODULE_DESCRIPTION("OMAP4 Keypad Driver"); 492 MODULE_LICENSE("GPL"); 493 MODULE_ALIAS("platform:omap4-keypad"); 494