Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: Add stmpe auto sleep feature

Some STMPE devices support entering sleep mode automatically on a
specified timeout of inactivity on the I2C bus with the host system.

Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Acked-by: Rabin Vincent <rabin.vincent@stericsson.com>
Signed-off-by: Sundar R Iyer <sundar.iyer@stericsson.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

authored by

Sundar R Iyer and committed by
Samuel Ortiz
5981f4e6 3faeb35c

+81
+70
drivers/mfd/stmpe.c
··· 455 455 }, 456 456 }; 457 457 458 + /* supported autosleep timeout delay (in msecs) */ 459 + static const int stmpe_autosleep_delay[] = { 460 + 4, 16, 32, 64, 128, 256, 512, 1024, 461 + }; 462 + 463 + static int stmpe_round_timeout(int timeout) 464 + { 465 + int i; 466 + 467 + for (i = 0; i < ARRAY_SIZE(stmpe_autosleep_delay); i++) { 468 + if (stmpe_autosleep_delay[i] >= timeout) 469 + return i; 470 + } 471 + 472 + /* 473 + * requests for delays longer than supported should not return the 474 + * longest supported delay 475 + */ 476 + return -EINVAL; 477 + } 478 + 479 + static int stmpe_autosleep(struct stmpe *stmpe, int autosleep_timeout) 480 + { 481 + int ret; 482 + 483 + if (!stmpe->variant->enable_autosleep) 484 + return -ENOSYS; 485 + 486 + mutex_lock(&stmpe->lock); 487 + ret = stmpe->variant->enable_autosleep(stmpe, autosleep_timeout); 488 + mutex_unlock(&stmpe->lock); 489 + 490 + return ret; 491 + } 492 + 493 + /* 494 + * Both stmpe 1601/2403 support same layout for autosleep 495 + */ 496 + static int stmpe1601_autosleep(struct stmpe *stmpe, 497 + int autosleep_timeout) 498 + { 499 + int ret, timeout; 500 + 501 + /* choose the best available timeout */ 502 + timeout = stmpe_round_timeout(autosleep_timeout); 503 + if (timeout < 0) { 504 + dev_err(stmpe->dev, "invalid timeout\n"); 505 + return timeout; 506 + } 507 + 508 + ret = __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL2, 509 + STMPE1601_AUTOSLEEP_TIMEOUT_MASK, 510 + timeout); 511 + if (ret < 0) 512 + return ret; 513 + 514 + return __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL2, 515 + STPME1601_AUTOSLEEP_ENABLE, 516 + STPME1601_AUTOSLEEP_ENABLE); 517 + } 518 + 458 519 static int stmpe1601_enable(struct stmpe *stmpe, unsigned int blocks, 459 520 bool enable) 460 521 { ··· 558 497 .num_irqs = STMPE1601_NR_INTERNAL_IRQS, 559 498 .enable = stmpe1601_enable, 560 499 .get_altfunc = stmpe1601_get_altfunc, 500 + .enable_autosleep = stmpe1601_autosleep, 561 501 }; 562 502 563 503 /* ··· 651 589 .num_irqs = STMPE24XX_NR_INTERNAL_IRQS, 652 590 .enable = stmpe24xx_enable, 653 591 .get_altfunc = stmpe24xx_get_altfunc, 592 + .enable_autosleep = stmpe1601_autosleep, /* same as stmpe1601 */ 654 593 }; 655 594 656 595 static struct stmpe_variant_info *stmpe_variant_info[] = { ··· 794 731 static int __devinit stmpe_chip_init(struct stmpe *stmpe) 795 732 { 796 733 unsigned int irq_trigger = stmpe->pdata->irq_trigger; 734 + int autosleep_timeout = stmpe->pdata->autosleep_timeout; 797 735 struct stmpe_variant_info *variant = stmpe->variant; 798 736 u8 icr = STMPE_ICR_LSB_GIM; 799 737 unsigned int id; ··· 829 765 830 766 if (stmpe->pdata->irq_invert_polarity) 831 767 icr ^= STMPE_ICR_LSB_HIGH; 768 + 769 + if (stmpe->pdata->autosleep) { 770 + ret = stmpe_autosleep(stmpe, autosleep_timeout); 771 + if (ret) 772 + return ret; 773 + } 832 774 833 775 return stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_ICR_LSB], icr); 834 776 }
+7
drivers/mfd/stmpe.h
··· 49 49 * Called with the I/O lock held. 50 50 * @get_altfunc: callback to get the alternate function number for the 51 51 * specific block 52 + * @enable_autosleep: callback to configure autosleep with specified timeout 52 53 */ 53 54 struct stmpe_variant_info { 54 55 const char *name; ··· 63 62 int num_irqs; 64 63 int (*enable)(struct stmpe *stmpe, unsigned int blocks, bool enable); 65 64 int (*get_altfunc)(struct stmpe *stmpe, enum stmpe_block block); 65 + int (*enable_autosleep)(struct stmpe *stmpe, int autosleep_timeout); 66 66 }; 67 67 68 68 #define STMPE_ICR_LSB_HIGH (1 << 2) ··· 120 118 #define STMPE1601_NR_INTERNAL_IRQS 9 121 119 122 120 #define STMPE1601_REG_SYS_CTRL 0x02 121 + #define STMPE1601_REG_SYS_CTRL2 0x03 123 122 #define STMPE1601_REG_ICR_LSB 0x11 124 123 #define STMPE1601_REG_IER_LSB 0x13 125 124 #define STMPE1601_REG_ISR_MSB 0x14 ··· 139 136 #define STMPE1601_SYS_CTRL_ENABLE_GPIO (1 << 3) 140 137 #define STMPE1601_SYS_CTRL_ENABLE_KPC (1 << 1) 141 138 #define STMPE1601_SYSCON_ENABLE_SPWM (1 << 0) 139 + 140 + /* The 1601/2403 share the same masks */ 141 + #define STMPE1601_AUTOSLEEP_TIMEOUT_MASK (0x7) 142 + #define STPME1601_AUTOSLEEP_ENABLE (1 << 3) 142 143 143 144 /* 144 145 * STMPE24xx
+4
include/linux/mfd/stmpe.h
··· 170 170 * @blocks: bitmask of blocks to enable (use STMPE_BLOCK_*) 171 171 * @irq_trigger: IRQ trigger to use for the interrupt to the host 172 172 * @irq_invert_polarity: IRQ line is connected with reversed polarity 173 + * @autosleep: bool to enable/disable stmpe autosleep 174 + * @autosleep_timeout: inactivity timeout in milliseconds for autosleep 173 175 * @irq_base: base IRQ number. %STMPE_NR_IRQS irqs will be used, or 174 176 * %STMPE_NR_INTERNAL_IRQS if the GPIO driver is not used. 175 177 * @gpio: GPIO-specific platform data ··· 184 182 int irq_base; 185 183 unsigned int irq_trigger; 186 184 bool irq_invert_polarity; 185 + bool autosleep; 186 + int autosleep_timeout; 187 187 188 188 struct stmpe_gpio_platform_data *gpio; 189 189 struct stmpe_keypad_platform_data *keypad;