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