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 return IRQ_WAKE_THREAD; 131 132 return IRQ_NONE; 133 } 134 135 static irqreturn_t omap4_keypad_irq_thread_fn(int irq, void *dev_id) 136 { 137 struct omap4_keypad *keypad_data = dev_id; 138 struct input_dev *input_dev = keypad_data->input; 139 unsigned char key_state[ARRAY_SIZE(keypad_data->key_state)]; 140 unsigned int col, row, code, changed; 141 u32 *new_state = (u32 *) key_state; 142 143 *new_state = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE31_0); 144 *(new_state + 1) = kbd_readl(keypad_data, OMAP4_KBD_FULLCODE63_32); 145 146 for (row = 0; row < keypad_data->rows; row++) { 147 changed = key_state[row] ^ keypad_data->key_state[row]; 148 if (!changed) 149 continue; 150 151 for (col = 0; col < keypad_data->cols; col++) { 152 if (changed & (1 << col)) { 153 code = MATRIX_SCAN_CODE(row, col, 154 keypad_data->row_shift); 155 input_event(input_dev, EV_MSC, MSC_SCAN, code); 156 input_report_key(input_dev, 157 keypad_data->keymap[code], 158 key_state[row] & (1 << col)); 159 } 160 } 161 } 162 163 input_sync(input_dev); 164 165 memcpy(keypad_data->key_state, key_state, 166 sizeof(keypad_data->key_state)); 167 168 /* clear pending interrupts */ 169 kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS, 170 kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)); 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_KEYPAD_PTV_DIV_128 << OMAP4_DEF_CTRL_PTV_SHIFT)); 186 kbd_writel(keypad_data, OMAP4_KBD_DEBOUNCINGTIME, 187 OMAP4_VAL_DEBOUNCINGTIME_16MS); 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 and wake-up events */ 209 kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQENABLE, 210 OMAP4_VAL_IRQDISABLE); 211 kbd_writel(keypad_data, OMAP4_KBD_WAKEUPENABLE, 0); 212 213 /* clear pending interrupts */ 214 kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS, 215 kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)); 216 217 enable_irq(keypad_data->irq); 218 219 pm_runtime_put_sync(input->dev.parent); 220 } 221 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_properties(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 239 static int omap4_keypad_probe(struct platform_device *pdev) 240 { 241 struct omap4_keypad *keypad_data; 242 struct input_dev *input_dev; 243 struct resource *res; 244 unsigned int max_keys; 245 int rev; 246 int irq; 247 int error; 248 249 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 250 if (!res) { 251 dev_err(&pdev->dev, "no base address specified\n"); 252 return -EINVAL; 253 } 254 255 irq = platform_get_irq(pdev, 0); 256 if (!irq) { 257 dev_err(&pdev->dev, "no keyboard irq assigned\n"); 258 return -EINVAL; 259 } 260 261 keypad_data = kzalloc(sizeof(struct omap4_keypad), GFP_KERNEL); 262 if (!keypad_data) { 263 dev_err(&pdev->dev, "keypad_data memory allocation failed\n"); 264 return -ENOMEM; 265 } 266 267 keypad_data->irq = irq; 268 269 error = omap4_keypad_parse_dt(&pdev->dev, keypad_data); 270 if (error) 271 goto err_free_keypad; 272 273 res = request_mem_region(res->start, resource_size(res), pdev->name); 274 if (!res) { 275 dev_err(&pdev->dev, "can't request mem region\n"); 276 error = -EBUSY; 277 goto err_free_keypad; 278 } 279 280 keypad_data->base = ioremap(res->start, resource_size(res)); 281 if (!keypad_data->base) { 282 dev_err(&pdev->dev, "can't ioremap mem resource\n"); 283 error = -ENOMEM; 284 goto err_release_mem; 285 } 286 287 288 /* 289 * Enable clocks for the keypad module so that we can read 290 * revision register. 291 */ 292 pm_runtime_enable(&pdev->dev); 293 error = pm_runtime_get_sync(&pdev->dev); 294 if (error) { 295 dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n"); 296 goto err_unmap; 297 } 298 rev = __raw_readl(keypad_data->base + OMAP4_KBD_REVISION); 299 rev &= 0x03 << 30; 300 rev >>= 30; 301 switch (rev) { 302 case KBD_REVISION_OMAP4: 303 keypad_data->reg_offset = 0x00; 304 keypad_data->irqreg_offset = 0x00; 305 break; 306 case KBD_REVISION_OMAP5: 307 keypad_data->reg_offset = 0x10; 308 keypad_data->irqreg_offset = 0x0c; 309 break; 310 default: 311 dev_err(&pdev->dev, 312 "Keypad reports unsupported revision %d", rev); 313 error = -EINVAL; 314 goto err_pm_put_sync; 315 } 316 317 /* input device allocation */ 318 keypad_data->input = input_dev = input_allocate_device(); 319 if (!input_dev) { 320 error = -ENOMEM; 321 goto err_pm_put_sync; 322 } 323 324 input_dev->name = pdev->name; 325 input_dev->dev.parent = &pdev->dev; 326 input_dev->id.bustype = BUS_HOST; 327 input_dev->id.vendor = 0x0001; 328 input_dev->id.product = 0x0001; 329 input_dev->id.version = 0x0001; 330 331 input_dev->open = omap4_keypad_open; 332 input_dev->close = omap4_keypad_close; 333 334 input_set_capability(input_dev, EV_MSC, MSC_SCAN); 335 if (!keypad_data->no_autorepeat) 336 __set_bit(EV_REP, input_dev->evbit); 337 338 input_set_drvdata(input_dev, keypad_data); 339 340 keypad_data->row_shift = get_count_order(keypad_data->cols); 341 max_keys = keypad_data->rows << keypad_data->row_shift; 342 keypad_data->keymap = kcalloc(max_keys, 343 sizeof(keypad_data->keymap[0]), 344 GFP_KERNEL); 345 if (!keypad_data->keymap) { 346 dev_err(&pdev->dev, "Not enough memory for keymap\n"); 347 error = -ENOMEM; 348 goto err_free_input; 349 } 350 351 error = matrix_keypad_build_keymap(NULL, NULL, 352 keypad_data->rows, keypad_data->cols, 353 keypad_data->keymap, input_dev); 354 if (error) { 355 dev_err(&pdev->dev, "failed to build keymap\n"); 356 goto err_free_keymap; 357 } 358 359 error = request_threaded_irq(keypad_data->irq, omap4_keypad_irq_handler, 360 omap4_keypad_irq_thread_fn, IRQF_ONESHOT, 361 "omap4-keypad", keypad_data); 362 if (error) { 363 dev_err(&pdev->dev, "failed to register interrupt\n"); 364 goto err_free_keymap; 365 } 366 367 device_init_wakeup(&pdev->dev, true); 368 pm_runtime_put_sync(&pdev->dev); 369 370 error = input_register_device(keypad_data->input); 371 if (error < 0) { 372 dev_err(&pdev->dev, "failed to register input device\n"); 373 goto err_pm_disable; 374 } 375 376 platform_set_drvdata(pdev, keypad_data); 377 return 0; 378 379 err_pm_disable: 380 pm_runtime_disable(&pdev->dev); 381 free_irq(keypad_data->irq, keypad_data); 382 err_free_keymap: 383 kfree(keypad_data->keymap); 384 err_free_input: 385 input_free_device(input_dev); 386 err_pm_put_sync: 387 pm_runtime_put_sync(&pdev->dev); 388 err_unmap: 389 iounmap(keypad_data->base); 390 err_release_mem: 391 release_mem_region(res->start, resource_size(res)); 392 err_free_keypad: 393 kfree(keypad_data); 394 return error; 395 } 396 397 static int omap4_keypad_remove(struct platform_device *pdev) 398 { 399 struct omap4_keypad *keypad_data = platform_get_drvdata(pdev); 400 struct resource *res; 401 402 free_irq(keypad_data->irq, keypad_data); 403 404 pm_runtime_disable(&pdev->dev); 405 406 input_unregister_device(keypad_data->input); 407 408 iounmap(keypad_data->base); 409 410 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 411 release_mem_region(res->start, resource_size(res)); 412 413 kfree(keypad_data->keymap); 414 kfree(keypad_data); 415 416 return 0; 417 } 418 419 static const struct of_device_id omap_keypad_dt_match[] = { 420 { .compatible = "ti,omap4-keypad" }, 421 {}, 422 }; 423 MODULE_DEVICE_TABLE(of, omap_keypad_dt_match); 424 425 #ifdef CONFIG_PM_SLEEP 426 static int omap4_keypad_suspend(struct device *dev) 427 { 428 struct platform_device *pdev = to_platform_device(dev); 429 struct omap4_keypad *keypad_data = platform_get_drvdata(pdev); 430 int error; 431 432 if (device_may_wakeup(&pdev->dev)) { 433 error = enable_irq_wake(keypad_data->irq); 434 if (!error) 435 keypad_data->irq_wake_enabled = true; 436 } 437 438 return 0; 439 } 440 441 static int omap4_keypad_resume(struct device *dev) 442 { 443 struct platform_device *pdev = to_platform_device(dev); 444 struct omap4_keypad *keypad_data = platform_get_drvdata(pdev); 445 446 if (device_may_wakeup(&pdev->dev) && keypad_data->irq_wake_enabled) { 447 disable_irq_wake(keypad_data->irq); 448 keypad_data->irq_wake_enabled = false; 449 } 450 451 return 0; 452 } 453 #endif 454 455 static SIMPLE_DEV_PM_OPS(omap4_keypad_pm_ops, 456 omap4_keypad_suspend, omap4_keypad_resume); 457 458 static struct platform_driver omap4_keypad_driver = { 459 .probe = omap4_keypad_probe, 460 .remove = omap4_keypad_remove, 461 .driver = { 462 .name = "omap4-keypad", 463 .pm = &omap4_keypad_pm_ops, 464 .of_match_table = omap_keypad_dt_match, 465 }, 466 }; 467 module_platform_driver(omap4_keypad_driver); 468 469 MODULE_AUTHOR("Texas Instruments"); 470 MODULE_DESCRIPTION("OMAP4 Keypad Driver"); 471 MODULE_LICENSE("GPL"); 472 MODULE_ALIAS("platform:omap4-keypad"); 473