1 /* 2 * Copyright (C) ST-Ericsson SA 2010 3 * 4 * Author: Jayeeta Banerjee <jayeeta.banerjee@stericsson.com> 5 * Author: Sundar Iyer <sundar.iyer@stericsson.com> 6 * 7 * License Terms: GNU General Public License, version 2 8 * 9 * TC35893 MFD Keypad Controller driver 10 */ 11 12 #include <linux/module.h> 13 #include <linux/interrupt.h> 14 #include <linux/input.h> 15 #include <linux/platform_device.h> 16 #include <linux/input/matrix_keypad.h> 17 #include <linux/i2c.h> 18 #include <linux/slab.h> 19 #include <linux/mfd/tc3589x.h> 20 #include <linux/device.h> 21 22 /* Maximum supported keypad matrix row/columns size */ 23 #define TC3589x_MAX_KPROW 8 24 #define TC3589x_MAX_KPCOL 12 25 26 /* keypad related Constants */ 27 #define TC3589x_MAX_DEBOUNCE_SETTLE 0xFF 28 #define DEDICATED_KEY_VAL 0xFF 29 30 /* Pull up/down masks */ 31 #define TC3589x_NO_PULL_MASK 0x0 32 #define TC3589x_PULL_DOWN_MASK 0x1 33 #define TC3589x_PULL_UP_MASK 0x2 34 #define TC3589x_PULLUP_ALL_MASK 0xAA 35 #define TC3589x_IO_PULL_VAL(index, mask) ((mask)<<((index)%4)*2) 36 37 /* Bit masks for IOCFG register */ 38 #define IOCFG_BALLCFG 0x01 39 #define IOCFG_IG 0x08 40 41 #define KP_EVCODE_COL_MASK 0x0F 42 #define KP_EVCODE_ROW_MASK 0x70 43 #define KP_RELEASE_EVT_MASK 0x80 44 45 #define KP_ROW_SHIFT 4 46 47 #define KP_NO_VALID_KEY_MASK 0x7F 48 49 /* bit masks for RESTCTRL register */ 50 #define TC3589x_KBDRST 0x2 51 #define TC3589x_IRQRST 0x10 52 #define TC3589x_RESET_ALL 0x1B 53 54 /* KBDMFS register bit mask */ 55 #define TC3589x_KBDMFS_EN 0x1 56 57 /* CLKEN register bitmask */ 58 #define KPD_CLK_EN 0x1 59 60 /* RSTINTCLR register bit mask */ 61 #define IRQ_CLEAR 0x1 62 63 /* bit masks for keyboard interrupts*/ 64 #define TC3589x_EVT_LOSS_INT 0x8 65 #define TC3589x_EVT_INT 0x4 66 #define TC3589x_KBD_LOSS_INT 0x2 67 #define TC3589x_KBD_INT 0x1 68 69 /* bit masks for keyboard interrupt clear*/ 70 #define TC3589x_EVT_INT_CLR 0x2 71 #define TC3589x_KBD_INT_CLR 0x1 72 73 /** 74 * struct tc35893_keypad_platform_data - platform specific keypad data 75 * @keymap_data: matrix scan code table for keycodes 76 * @krow: mask for available rows, value is 0xFF 77 * @kcol: mask for available columns, value is 0xFF 78 * @debounce_period: platform specific debounce time 79 * @settle_time: platform specific settle down time 80 * @irqtype: type of interrupt, falling or rising edge 81 * @enable_wakeup: specifies if keypad event can wake up system from sleep 82 * @no_autorepeat: flag for auto repetition 83 */ 84 struct tc3589x_keypad_platform_data { 85 const struct matrix_keymap_data *keymap_data; 86 u8 krow; 87 u8 kcol; 88 u8 debounce_period; 89 u8 settle_time; 90 unsigned long irqtype; 91 bool enable_wakeup; 92 bool no_autorepeat; 93 }; 94 95 /** 96 * struct tc_keypad - data structure used by keypad driver 97 * @tc3589x: pointer to tc35893 98 * @input: pointer to input device object 99 * @board: keypad platform device 100 * @krow: number of rows 101 * @kcol: number of columns 102 * @keymap: matrix scan code table for keycodes 103 * @keypad_stopped: holds keypad status 104 */ 105 struct tc_keypad { 106 struct tc3589x *tc3589x; 107 struct input_dev *input; 108 const struct tc3589x_keypad_platform_data *board; 109 unsigned int krow; 110 unsigned int kcol; 111 unsigned short *keymap; 112 bool keypad_stopped; 113 }; 114 115 static int tc3589x_keypad_init_key_hardware(struct tc_keypad *keypad) 116 { 117 int ret; 118 struct tc3589x *tc3589x = keypad->tc3589x; 119 const struct tc3589x_keypad_platform_data *board = keypad->board; 120 121 /* validate platform configuration */ 122 if (board->kcol > TC3589x_MAX_KPCOL || board->krow > TC3589x_MAX_KPROW) 123 return -EINVAL; 124 125 /* configure KBDSIZE 4 LSbits for cols and 4 MSbits for rows */ 126 ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSIZE, 127 (board->krow << KP_ROW_SHIFT) | board->kcol); 128 if (ret < 0) 129 return ret; 130 131 /* configure dedicated key config, no dedicated key selected */ 132 ret = tc3589x_reg_write(tc3589x, TC3589x_KBCFG_LSB, DEDICATED_KEY_VAL); 133 if (ret < 0) 134 return ret; 135 136 ret = tc3589x_reg_write(tc3589x, TC3589x_KBCFG_MSB, DEDICATED_KEY_VAL); 137 if (ret < 0) 138 return ret; 139 140 /* Configure settle time */ 141 ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSETTLE_REG, 142 board->settle_time); 143 if (ret < 0) 144 return ret; 145 146 /* Configure debounce time */ 147 ret = tc3589x_reg_write(tc3589x, TC3589x_KBDBOUNCE, 148 board->debounce_period); 149 if (ret < 0) 150 return ret; 151 152 /* Start of initialise keypad GPIOs */ 153 ret = tc3589x_set_bits(tc3589x, TC3589x_IOCFG, 0x0, IOCFG_IG); 154 if (ret < 0) 155 return ret; 156 157 /* Configure pull-up resistors for all row GPIOs */ 158 ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG0_LSB, 159 TC3589x_PULLUP_ALL_MASK); 160 if (ret < 0) 161 return ret; 162 163 ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG0_MSB, 164 TC3589x_PULLUP_ALL_MASK); 165 if (ret < 0) 166 return ret; 167 168 /* Configure pull-up resistors for all column GPIOs */ 169 ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG1_LSB, 170 TC3589x_PULLUP_ALL_MASK); 171 if (ret < 0) 172 return ret; 173 174 ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG1_MSB, 175 TC3589x_PULLUP_ALL_MASK); 176 if (ret < 0) 177 return ret; 178 179 ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG2_LSB, 180 TC3589x_PULLUP_ALL_MASK); 181 182 return ret; 183 } 184 185 #define TC35893_DATA_REGS 4 186 #define TC35893_KEYCODE_FIFO_EMPTY 0x7f 187 #define TC35893_KEYCODE_FIFO_CLEAR 0xff 188 #define TC35893_KEYPAD_ROW_SHIFT 0x3 189 190 static irqreturn_t tc3589x_keypad_irq(int irq, void *dev) 191 { 192 struct tc_keypad *keypad = dev; 193 struct tc3589x *tc3589x = keypad->tc3589x; 194 u8 i, row_index, col_index, kbd_code, up; 195 u8 code; 196 197 for (i = 0; i < TC35893_DATA_REGS * 2; i++) { 198 kbd_code = tc3589x_reg_read(tc3589x, TC3589x_EVTCODE_FIFO); 199 200 /* loop till fifo is empty and no more keys are pressed */ 201 if (kbd_code == TC35893_KEYCODE_FIFO_EMPTY || 202 kbd_code == TC35893_KEYCODE_FIFO_CLEAR) 203 continue; 204 205 /* valid key is found */ 206 col_index = kbd_code & KP_EVCODE_COL_MASK; 207 row_index = (kbd_code & KP_EVCODE_ROW_MASK) >> KP_ROW_SHIFT; 208 code = MATRIX_SCAN_CODE(row_index, col_index, 209 TC35893_KEYPAD_ROW_SHIFT); 210 up = kbd_code & KP_RELEASE_EVT_MASK; 211 212 input_event(keypad->input, EV_MSC, MSC_SCAN, code); 213 input_report_key(keypad->input, keypad->keymap[code], !up); 214 input_sync(keypad->input); 215 } 216 217 /* clear IRQ */ 218 tc3589x_set_bits(tc3589x, TC3589x_KBDIC, 219 0x0, TC3589x_EVT_INT_CLR | TC3589x_KBD_INT_CLR); 220 /* enable IRQ */ 221 tc3589x_set_bits(tc3589x, TC3589x_KBDMSK, 222 0x0, TC3589x_EVT_LOSS_INT | TC3589x_EVT_INT); 223 224 return IRQ_HANDLED; 225 } 226 227 static int tc3589x_keypad_enable(struct tc_keypad *keypad) 228 { 229 struct tc3589x *tc3589x = keypad->tc3589x; 230 int ret; 231 232 /* pull the keypad module out of reset */ 233 ret = tc3589x_set_bits(tc3589x, TC3589x_RSTCTRL, TC3589x_KBDRST, 0x0); 234 if (ret < 0) 235 return ret; 236 237 /* configure KBDMFS */ 238 ret = tc3589x_set_bits(tc3589x, TC3589x_KBDMFS, 0x0, TC3589x_KBDMFS_EN); 239 if (ret < 0) 240 return ret; 241 242 /* enable the keypad clock */ 243 ret = tc3589x_set_bits(tc3589x, TC3589x_CLKEN, 0x0, KPD_CLK_EN); 244 if (ret < 0) 245 return ret; 246 247 /* clear pending IRQs */ 248 ret = tc3589x_set_bits(tc3589x, TC3589x_RSTINTCLR, 0x0, 0x1); 249 if (ret < 0) 250 return ret; 251 252 /* enable the IRQs */ 253 ret = tc3589x_set_bits(tc3589x, TC3589x_KBDMSK, 0x0, 254 TC3589x_EVT_LOSS_INT | TC3589x_EVT_INT); 255 if (ret < 0) 256 return ret; 257 258 keypad->keypad_stopped = false; 259 260 return ret; 261 } 262 263 static int tc3589x_keypad_disable(struct tc_keypad *keypad) 264 { 265 struct tc3589x *tc3589x = keypad->tc3589x; 266 int ret; 267 268 /* clear IRQ */ 269 ret = tc3589x_set_bits(tc3589x, TC3589x_KBDIC, 270 0x0, TC3589x_EVT_INT_CLR | TC3589x_KBD_INT_CLR); 271 if (ret < 0) 272 return ret; 273 274 /* disable all interrupts */ 275 ret = tc3589x_set_bits(tc3589x, TC3589x_KBDMSK, 276 ~(TC3589x_EVT_LOSS_INT | TC3589x_EVT_INT), 0x0); 277 if (ret < 0) 278 return ret; 279 280 /* disable the keypad module */ 281 ret = tc3589x_set_bits(tc3589x, TC3589x_CLKEN, 0x1, 0x0); 282 if (ret < 0) 283 return ret; 284 285 /* put the keypad module into reset */ 286 ret = tc3589x_set_bits(tc3589x, TC3589x_RSTCTRL, TC3589x_KBDRST, 0x1); 287 288 keypad->keypad_stopped = true; 289 290 return ret; 291 } 292 293 static int tc3589x_keypad_open(struct input_dev *input) 294 { 295 int error; 296 struct tc_keypad *keypad = input_get_drvdata(input); 297 298 /* enable the keypad module */ 299 error = tc3589x_keypad_enable(keypad); 300 if (error < 0) { 301 dev_err(&input->dev, "failed to enable keypad module\n"); 302 return error; 303 } 304 305 error = tc3589x_keypad_init_key_hardware(keypad); 306 if (error < 0) { 307 dev_err(&input->dev, "failed to configure keypad module\n"); 308 return error; 309 } 310 311 return 0; 312 } 313 314 static void tc3589x_keypad_close(struct input_dev *input) 315 { 316 struct tc_keypad *keypad = input_get_drvdata(input); 317 318 /* disable the keypad module */ 319 tc3589x_keypad_disable(keypad); 320 } 321 322 static const struct tc3589x_keypad_platform_data * 323 tc3589x_keypad_of_probe(struct device *dev) 324 { 325 struct device_node *np = dev->of_node; 326 struct tc3589x_keypad_platform_data *plat; 327 u32 cols, rows; 328 u32 debounce_ms; 329 int proplen; 330 331 if (!np) 332 return ERR_PTR(-ENODEV); 333 334 plat = devm_kzalloc(dev, sizeof(*plat), GFP_KERNEL); 335 if (!plat) 336 return ERR_PTR(-ENOMEM); 337 338 of_property_read_u32(np, "keypad,num-columns", &cols); 339 of_property_read_u32(np, "keypad,num-rows", &rows); 340 plat->kcol = (u8) cols; 341 plat->krow = (u8) rows; 342 if (!plat->krow || !plat->kcol || 343 plat->krow > TC_KPD_ROWS || plat->kcol > TC_KPD_COLUMNS) { 344 dev_err(dev, 345 "keypad columns/rows not properly specified (%ux%u)\n", 346 plat->kcol, plat->krow); 347 return ERR_PTR(-EINVAL); 348 } 349 350 if (!of_get_property(np, "linux,keymap", &proplen)) { 351 dev_err(dev, "property linux,keymap not found\n"); 352 return ERR_PTR(-ENOENT); 353 } 354 355 plat->no_autorepeat = of_property_read_bool(np, "linux,no-autorepeat"); 356 357 plat->enable_wakeup = of_property_read_bool(np, "wakeup-source") || 358 /* legacy name */ 359 of_property_read_bool(np, "linux,wakeup"); 360 361 /* The custom delay format is ms/16 */ 362 of_property_read_u32(np, "debounce-delay-ms", &debounce_ms); 363 if (debounce_ms) 364 plat->debounce_period = debounce_ms * 16; 365 else 366 plat->debounce_period = TC_KPD_DEBOUNCE_PERIOD; 367 368 plat->settle_time = TC_KPD_SETTLE_TIME; 369 /* FIXME: should be property of the IRQ resource? */ 370 plat->irqtype = IRQF_TRIGGER_FALLING; 371 372 return plat; 373 } 374 375 static int tc3589x_keypad_probe(struct platform_device *pdev) 376 { 377 struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent); 378 struct tc_keypad *keypad; 379 struct input_dev *input; 380 const struct tc3589x_keypad_platform_data *plat; 381 int error, irq; 382 383 plat = tc3589x_keypad_of_probe(&pdev->dev); 384 if (IS_ERR(plat)) { 385 dev_err(&pdev->dev, "invalid keypad platform data\n"); 386 return PTR_ERR(plat); 387 } 388 389 irq = platform_get_irq(pdev, 0); 390 if (irq < 0) 391 return irq; 392 393 keypad = devm_kzalloc(&pdev->dev, sizeof(struct tc_keypad), 394 GFP_KERNEL); 395 if (!keypad) 396 return -ENOMEM; 397 398 input = devm_input_allocate_device(&pdev->dev); 399 if (!input) { 400 dev_err(&pdev->dev, "failed to allocate input device\n"); 401 return -ENOMEM; 402 } 403 404 keypad->board = plat; 405 keypad->input = input; 406 keypad->tc3589x = tc3589x; 407 408 input->id.bustype = BUS_I2C; 409 input->name = pdev->name; 410 input->dev.parent = &pdev->dev; 411 412 input->open = tc3589x_keypad_open; 413 input->close = tc3589x_keypad_close; 414 415 error = matrix_keypad_build_keymap(plat->keymap_data, NULL, 416 TC3589x_MAX_KPROW, TC3589x_MAX_KPCOL, 417 NULL, input); 418 if (error) { 419 dev_err(&pdev->dev, "Failed to build keymap\n"); 420 return error; 421 } 422 423 keypad->keymap = input->keycode; 424 425 input_set_capability(input, EV_MSC, MSC_SCAN); 426 if (!plat->no_autorepeat) 427 __set_bit(EV_REP, input->evbit); 428 429 input_set_drvdata(input, keypad); 430 431 tc3589x_keypad_disable(keypad); 432 433 error = devm_request_threaded_irq(&pdev->dev, irq, 434 NULL, tc3589x_keypad_irq, 435 plat->irqtype | IRQF_ONESHOT, 436 "tc3589x-keypad", keypad); 437 if (error) { 438 dev_err(&pdev->dev, 439 "Could not allocate irq %d,error %d\n", 440 irq, error); 441 return error; 442 } 443 444 error = input_register_device(input); 445 if (error) { 446 dev_err(&pdev->dev, "Could not register input device\n"); 447 return error; 448 } 449 450 /* let platform decide if keypad is a wakeup source or not */ 451 device_init_wakeup(&pdev->dev, plat->enable_wakeup); 452 device_set_wakeup_capable(&pdev->dev, plat->enable_wakeup); 453 454 platform_set_drvdata(pdev, keypad); 455 456 return 0; 457 } 458 459 #ifdef CONFIG_PM_SLEEP 460 static int tc3589x_keypad_suspend(struct device *dev) 461 { 462 struct platform_device *pdev = to_platform_device(dev); 463 struct tc_keypad *keypad = platform_get_drvdata(pdev); 464 int irq = platform_get_irq(pdev, 0); 465 466 /* keypad is already off; we do nothing */ 467 if (keypad->keypad_stopped) 468 return 0; 469 470 /* if device is not a wakeup source, disable it for powersave */ 471 if (!device_may_wakeup(&pdev->dev)) 472 tc3589x_keypad_disable(keypad); 473 else 474 enable_irq_wake(irq); 475 476 return 0; 477 } 478 479 static int tc3589x_keypad_resume(struct device *dev) 480 { 481 struct platform_device *pdev = to_platform_device(dev); 482 struct tc_keypad *keypad = platform_get_drvdata(pdev); 483 int irq = platform_get_irq(pdev, 0); 484 485 if (!keypad->keypad_stopped) 486 return 0; 487 488 /* enable the device to resume normal operations */ 489 if (!device_may_wakeup(&pdev->dev)) 490 tc3589x_keypad_enable(keypad); 491 else 492 disable_irq_wake(irq); 493 494 return 0; 495 } 496 #endif 497 498 static SIMPLE_DEV_PM_OPS(tc3589x_keypad_dev_pm_ops, 499 tc3589x_keypad_suspend, tc3589x_keypad_resume); 500 501 static struct platform_driver tc3589x_keypad_driver = { 502 .driver = { 503 .name = "tc3589x-keypad", 504 .pm = &tc3589x_keypad_dev_pm_ops, 505 }, 506 .probe = tc3589x_keypad_probe, 507 }; 508 module_platform_driver(tc3589x_keypad_driver); 509 510 MODULE_LICENSE("GPL v2"); 511 MODULE_AUTHOR("Jayeeta Banerjee/Sundar Iyer"); 512 MODULE_DESCRIPTION("TC35893 Keypad Driver"); 513 MODULE_ALIAS("platform:tc3589x-keypad"); 514