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/init.h> 14 #include <linux/interrupt.h> 15 #include <linux/input.h> 16 #include <linux/platform_device.h> 17 #include <linux/input/matrix_keypad.h> 18 #include <linux/i2c.h> 19 #include <linux/slab.h> 20 #include <linux/mfd/tc3589x.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 #define TC3589x_KBD_KEYMAP_SIZE 64 74 75 /** 76 * struct tc_keypad - data structure used by keypad driver 77 * @tc3589x: pointer to tc35893 78 * @input: pointer to input device object 79 * @board: keypad platform device 80 * @krow: number of rows 81 * @kcol: number of coloumns 82 * @keymap: matrix scan code table for keycodes 83 * @keypad_stopped: holds keypad status 84 */ 85 struct tc_keypad { 86 struct tc3589x *tc3589x; 87 struct input_dev *input; 88 const struct tc3589x_keypad_platform_data *board; 89 unsigned int krow; 90 unsigned int kcol; 91 unsigned short keymap[TC3589x_KBD_KEYMAP_SIZE]; 92 bool keypad_stopped; 93 }; 94 95 static int tc3589x_keypad_init_key_hardware(struct tc_keypad *keypad) 96 { 97 int ret; 98 struct tc3589x *tc3589x = keypad->tc3589x; 99 u8 settle_time = keypad->board->settle_time; 100 u8 dbounce_period = keypad->board->debounce_period; 101 u8 rows = keypad->board->krow & 0xf; /* mask out the nibble */ 102 u8 column = keypad->board->kcol & 0xf; /* mask out the nibble */ 103 104 /* validate platform configurations */ 105 if (keypad->board->kcol > TC3589x_MAX_KPCOL || 106 keypad->board->krow > TC3589x_MAX_KPROW || 107 keypad->board->debounce_period > TC3589x_MAX_DEBOUNCE_SETTLE || 108 keypad->board->settle_time > TC3589x_MAX_DEBOUNCE_SETTLE) 109 return -EINVAL; 110 111 /* configure KBDSIZE 4 LSbits for cols and 4 MSbits for rows */ 112 ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSIZE, 113 (rows << KP_ROW_SHIFT) | column); 114 if (ret < 0) 115 return ret; 116 117 /* configure dedicated key config, no dedicated key selected */ 118 ret = tc3589x_reg_write(tc3589x, TC3589x_KBCFG_LSB, DEDICATED_KEY_VAL); 119 if (ret < 0) 120 return ret; 121 122 ret = tc3589x_reg_write(tc3589x, TC3589x_KBCFG_MSB, DEDICATED_KEY_VAL); 123 if (ret < 0) 124 return ret; 125 126 /* Configure settle time */ 127 ret = tc3589x_reg_write(tc3589x, TC3589x_KBDSETTLE_REG, settle_time); 128 if (ret < 0) 129 return ret; 130 131 /* Configure debounce time */ 132 ret = tc3589x_reg_write(tc3589x, TC3589x_KBDBOUNCE, dbounce_period); 133 if (ret < 0) 134 return ret; 135 136 /* Start of initialise keypad GPIOs */ 137 ret = tc3589x_set_bits(tc3589x, TC3589x_IOCFG, 0x0, IOCFG_IG); 138 if (ret < 0) 139 return ret; 140 141 /* Configure pull-up resistors for all row GPIOs */ 142 ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG0_LSB, 143 TC3589x_PULLUP_ALL_MASK); 144 if (ret < 0) 145 return ret; 146 147 ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG0_MSB, 148 TC3589x_PULLUP_ALL_MASK); 149 if (ret < 0) 150 return ret; 151 152 /* Configure pull-up resistors for all column GPIOs */ 153 ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG1_LSB, 154 TC3589x_PULLUP_ALL_MASK); 155 if (ret < 0) 156 return ret; 157 158 ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG1_MSB, 159 TC3589x_PULLUP_ALL_MASK); 160 if (ret < 0) 161 return ret; 162 163 ret = tc3589x_reg_write(tc3589x, TC3589x_IOPULLCFG2_LSB, 164 TC3589x_PULLUP_ALL_MASK); 165 166 return ret; 167 } 168 169 #define TC35893_DATA_REGS 4 170 #define TC35893_KEYCODE_FIFO_EMPTY 0x7f 171 #define TC35893_KEYCODE_FIFO_CLEAR 0xff 172 #define TC35893_KEYPAD_ROW_SHIFT 0x3 173 174 static irqreturn_t tc3589x_keypad_irq(int irq, void *dev) 175 { 176 struct tc_keypad *keypad = dev; 177 struct tc3589x *tc3589x = keypad->tc3589x; 178 u8 i, row_index, col_index, kbd_code, up; 179 u8 code; 180 181 for (i = 0; i < TC35893_DATA_REGS * 2; i++) { 182 kbd_code = tc3589x_reg_read(tc3589x, TC3589x_EVTCODE_FIFO); 183 184 /* loop till fifo is empty and no more keys are pressed */ 185 if (kbd_code == TC35893_KEYCODE_FIFO_EMPTY || 186 kbd_code == TC35893_KEYCODE_FIFO_CLEAR) 187 continue; 188 189 /* valid key is found */ 190 col_index = kbd_code & KP_EVCODE_COL_MASK; 191 row_index = (kbd_code & KP_EVCODE_ROW_MASK) >> KP_ROW_SHIFT; 192 code = MATRIX_SCAN_CODE(row_index, col_index, 193 TC35893_KEYPAD_ROW_SHIFT); 194 up = kbd_code & KP_RELEASE_EVT_MASK; 195 196 input_event(keypad->input, EV_MSC, MSC_SCAN, code); 197 input_report_key(keypad->input, keypad->keymap[code], !up); 198 input_sync(keypad->input); 199 } 200 201 /* clear IRQ */ 202 tc3589x_set_bits(tc3589x, TC3589x_KBDIC, 203 0x0, TC3589x_EVT_INT_CLR | TC3589x_KBD_INT_CLR); 204 /* enable IRQ */ 205 tc3589x_set_bits(tc3589x, TC3589x_KBDMSK, 206 0x0, TC3589x_EVT_LOSS_INT | TC3589x_EVT_INT); 207 208 return IRQ_HANDLED; 209 } 210 211 static int tc3589x_keypad_enable(struct tc_keypad *keypad) 212 { 213 struct tc3589x *tc3589x = keypad->tc3589x; 214 int ret; 215 216 /* pull the keypad module out of reset */ 217 ret = tc3589x_set_bits(tc3589x, TC3589x_RSTCTRL, TC3589x_KBDRST, 0x0); 218 if (ret < 0) 219 return ret; 220 221 /* configure KBDMFS */ 222 ret = tc3589x_set_bits(tc3589x, TC3589x_KBDMFS, 0x0, TC3589x_KBDMFS_EN); 223 if (ret < 0) 224 return ret; 225 226 /* enable the keypad clock */ 227 ret = tc3589x_set_bits(tc3589x, TC3589x_CLKEN, 0x0, KPD_CLK_EN); 228 if (ret < 0) 229 return ret; 230 231 /* clear pending IRQs */ 232 ret = tc3589x_set_bits(tc3589x, TC3589x_RSTINTCLR, 0x0, 0x1); 233 if (ret < 0) 234 return ret; 235 236 /* enable the IRQs */ 237 ret = tc3589x_set_bits(tc3589x, TC3589x_KBDMSK, 0x0, 238 TC3589x_EVT_LOSS_INT | TC3589x_EVT_INT); 239 if (ret < 0) 240 return ret; 241 242 keypad->keypad_stopped = false; 243 244 return ret; 245 } 246 247 static int tc3589x_keypad_disable(struct tc_keypad *keypad) 248 { 249 struct tc3589x *tc3589x = keypad->tc3589x; 250 int ret; 251 252 /* clear IRQ */ 253 ret = tc3589x_set_bits(tc3589x, TC3589x_KBDIC, 254 0x0, TC3589x_EVT_INT_CLR | TC3589x_KBD_INT_CLR); 255 if (ret < 0) 256 return ret; 257 258 /* disable all interrupts */ 259 ret = tc3589x_set_bits(tc3589x, TC3589x_KBDMSK, 260 ~(TC3589x_EVT_LOSS_INT | TC3589x_EVT_INT), 0x0); 261 if (ret < 0) 262 return ret; 263 264 /* disable the keypad module */ 265 ret = tc3589x_set_bits(tc3589x, TC3589x_CLKEN, 0x1, 0x0); 266 if (ret < 0) 267 return ret; 268 269 /* put the keypad module into reset */ 270 ret = tc3589x_set_bits(tc3589x, TC3589x_RSTCTRL, TC3589x_KBDRST, 0x1); 271 272 keypad->keypad_stopped = true; 273 274 return ret; 275 } 276 277 static int tc3589x_keypad_open(struct input_dev *input) 278 { 279 int error; 280 struct tc_keypad *keypad = input_get_drvdata(input); 281 282 /* enable the keypad module */ 283 error = tc3589x_keypad_enable(keypad); 284 if (error < 0) { 285 dev_err(&input->dev, "failed to enable keypad module\n"); 286 return error; 287 } 288 289 error = tc3589x_keypad_init_key_hardware(keypad); 290 if (error < 0) { 291 dev_err(&input->dev, "failed to configure keypad module\n"); 292 return error; 293 } 294 295 return 0; 296 } 297 298 static void tc3589x_keypad_close(struct input_dev *input) 299 { 300 struct tc_keypad *keypad = input_get_drvdata(input); 301 302 /* disable the keypad module */ 303 tc3589x_keypad_disable(keypad); 304 } 305 306 static int __devinit tc3589x_keypad_probe(struct platform_device *pdev) 307 { 308 struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent); 309 struct tc_keypad *keypad; 310 struct input_dev *input; 311 const struct tc3589x_keypad_platform_data *plat; 312 int error, irq; 313 314 plat = tc3589x->pdata->keypad; 315 if (!plat) { 316 dev_err(&pdev->dev, "invalid keypad platform data\n"); 317 return -EINVAL; 318 } 319 320 irq = platform_get_irq(pdev, 0); 321 if (irq < 0) 322 return irq; 323 324 keypad = kzalloc(sizeof(struct tc_keypad), GFP_KERNEL); 325 input = input_allocate_device(); 326 if (!keypad || !input) { 327 dev_err(&pdev->dev, "failed to allocate keypad memory\n"); 328 error = -ENOMEM; 329 goto err_free_mem; 330 } 331 332 keypad->board = plat; 333 keypad->input = input; 334 keypad->tc3589x = tc3589x; 335 336 input->id.bustype = BUS_I2C; 337 input->name = pdev->name; 338 input->dev.parent = &pdev->dev; 339 340 input->keycode = keypad->keymap; 341 input->keycodesize = sizeof(keypad->keymap[0]); 342 input->keycodemax = ARRAY_SIZE(keypad->keymap); 343 344 input->open = tc3589x_keypad_open; 345 input->close = tc3589x_keypad_close; 346 347 input_set_drvdata(input, keypad); 348 349 input_set_capability(input, EV_MSC, MSC_SCAN); 350 351 __set_bit(EV_KEY, input->evbit); 352 if (!plat->no_autorepeat) 353 __set_bit(EV_REP, input->evbit); 354 355 matrix_keypad_build_keymap(plat->keymap_data, 0x3, 356 input->keycode, input->keybit); 357 358 error = request_threaded_irq(irq, NULL, 359 tc3589x_keypad_irq, plat->irqtype, 360 "tc3589x-keypad", keypad); 361 if (error < 0) { 362 dev_err(&pdev->dev, 363 "Could not allocate irq %d,error %d\n", 364 irq, error); 365 goto err_free_mem; 366 } 367 368 error = input_register_device(input); 369 if (error) { 370 dev_err(&pdev->dev, "Could not register input device\n"); 371 goto err_free_irq; 372 } 373 374 /* let platform decide if keypad is a wakeup source or not */ 375 device_init_wakeup(&pdev->dev, plat->enable_wakeup); 376 device_set_wakeup_capable(&pdev->dev, plat->enable_wakeup); 377 378 platform_set_drvdata(pdev, keypad); 379 380 return 0; 381 382 err_free_irq: 383 free_irq(irq, keypad); 384 err_free_mem: 385 input_free_device(input); 386 kfree(keypad); 387 return error; 388 } 389 390 static int __devexit tc3589x_keypad_remove(struct platform_device *pdev) 391 { 392 struct tc_keypad *keypad = platform_get_drvdata(pdev); 393 int irq = platform_get_irq(pdev, 0); 394 395 if (!keypad->keypad_stopped) 396 tc3589x_keypad_disable(keypad); 397 398 free_irq(irq, keypad); 399 400 input_unregister_device(keypad->input); 401 402 kfree(keypad); 403 404 return 0; 405 } 406 407 #ifdef CONFIG_PM_SLEEP 408 static int tc3589x_keypad_suspend(struct device *dev) 409 { 410 struct platform_device *pdev = to_platform_device(dev); 411 struct tc_keypad *keypad = platform_get_drvdata(pdev); 412 int irq = platform_get_irq(pdev, 0); 413 414 /* keypad is already off; we do nothing */ 415 if (keypad->keypad_stopped) 416 return 0; 417 418 /* if device is not a wakeup source, disable it for powersave */ 419 if (!device_may_wakeup(&pdev->dev)) 420 tc3589x_keypad_disable(keypad); 421 else 422 enable_irq_wake(irq); 423 424 return 0; 425 } 426 427 static int tc3589x_keypad_resume(struct device *dev) 428 { 429 struct platform_device *pdev = to_platform_device(dev); 430 struct tc_keypad *keypad = platform_get_drvdata(pdev); 431 int irq = platform_get_irq(pdev, 0); 432 433 if (!keypad->keypad_stopped) 434 return 0; 435 436 /* enable the device to resume normal operations */ 437 if (!device_may_wakeup(&pdev->dev)) 438 tc3589x_keypad_enable(keypad); 439 else 440 disable_irq_wake(irq); 441 442 return 0; 443 } 444 #endif 445 446 static SIMPLE_DEV_PM_OPS(tc3589x_keypad_dev_pm_ops, 447 tc3589x_keypad_suspend, tc3589x_keypad_resume); 448 449 static struct platform_driver tc3589x_keypad_driver = { 450 .driver = { 451 .name = "tc3589x-keypad", 452 .owner = THIS_MODULE, 453 .pm = &tc3589x_keypad_dev_pm_ops, 454 }, 455 .probe = tc3589x_keypad_probe, 456 .remove = __devexit_p(tc3589x_keypad_remove), 457 }; 458 module_platform_driver(tc3589x_keypad_driver); 459 460 MODULE_LICENSE("GPL v2"); 461 MODULE_AUTHOR("Jayeeta Banerjee/Sundar Iyer"); 462 MODULE_DESCRIPTION("TC35893 Keypad Driver"); 463 MODULE_ALIAS("platform:tc3589x-keypad"); 464