Commit 201cf052810d20814a77ca0e0045a2c1a3508a1f

Authored by Laxman Dewangan
Committed by Samuel Ortiz
1 parent 58d114b669

mfd: Add support for tps65910 device sleep

Adding support for device sleep through the external input control
signal "SLEEP".
Changing the SLEEP signal state can switch the device into SLEEP and
ACTIVE state.
Also adding sleep configuration for different resources so that they
should be keep on during sleep state of device.

Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

Showing 2 changed files with 76 additions and 0 deletions Side-by-side Diff

drivers/mfd/tps65910.c
... ... @@ -90,6 +90,66 @@
90 90 .cache_type = REGCACHE_RBTREE,
91 91 };
92 92  
  93 +static int __init tps65910_sleepinit(struct tps65910 *tps65910,
  94 + struct tps65910_board *pmic_pdata)
  95 +{
  96 + struct device *dev = NULL;
  97 + int ret = 0;
  98 +
  99 + dev = tps65910->dev;
  100 +
  101 + if (!pmic_pdata->en_dev_slp)
  102 + return 0;
  103 +
  104 + /* enabling SLEEP device state */
  105 + ret = tps65910_set_bits(tps65910, TPS65910_DEVCTRL,
  106 + DEVCTRL_DEV_SLP_MASK);
  107 + if (ret < 0) {
  108 + dev_err(dev, "set dev_slp failed: %d\n", ret);
  109 + goto err_sleep_init;
  110 + }
  111 +
  112 + /* Return if there is no sleep keepon data. */
  113 + if (!pmic_pdata->slp_keepon)
  114 + return 0;
  115 +
  116 + if (pmic_pdata->slp_keepon->therm_keepon) {
  117 + ret = tps65910_set_bits(tps65910, TPS65910_SLEEP_KEEP_RES_ON,
  118 + SLEEP_KEEP_RES_ON_THERM_KEEPON_MASK);
  119 + if (ret < 0) {
  120 + dev_err(dev, "set therm_keepon failed: %d\n", ret);
  121 + goto disable_dev_slp;
  122 + }
  123 + }
  124 +
  125 + if (pmic_pdata->slp_keepon->clkout32k_keepon) {
  126 + ret = tps65910_set_bits(tps65910, TPS65910_SLEEP_KEEP_RES_ON,
  127 + SLEEP_KEEP_RES_ON_CLKOUT32K_KEEPON_MASK);
  128 + if (ret < 0) {
  129 + dev_err(dev, "set clkout32k_keepon failed: %d\n", ret);
  130 + goto disable_dev_slp;
  131 + }
  132 + }
  133 +
  134 + if (pmic_pdata->slp_keepon->i2chs_keepon) {
  135 + ret = tps65910_set_bits(tps65910, TPS65910_SLEEP_KEEP_RES_ON,
  136 + SLEEP_KEEP_RES_ON_I2CHS_KEEPON_MASK);
  137 + if (ret < 0) {
  138 + dev_err(dev, "set i2chs_keepon failed: %d\n", ret);
  139 + goto disable_dev_slp;
  140 + }
  141 + }
  142 +
  143 + return 0;
  144 +
  145 +disable_dev_slp:
  146 + tps65910_clear_bits(tps65910, TPS65910_DEVCTRL, DEVCTRL_DEV_SLP_MASK);
  147 +
  148 +err_sleep_init:
  149 + return ret;
  150 +}
  151 +
  152 +
93 153 static int tps65910_i2c_probe(struct i2c_client *i2c,
94 154 const struct i2c_device_id *id)
95 155 {
... ... @@ -139,6 +199,8 @@
139 199 tps65910_gpio_init(tps65910, pmic_plat_data->gpio_base);
140 200  
141 201 tps65910_irq_init(tps65910, init_data->irq, init_data);
  202 +
  203 + tps65910_sleepinit(tps65910, pmic_plat_data);
142 204  
143 205 kfree(init_data);
144 206 return ret;
include/linux/mfd/tps65910.h
... ... @@ -783,6 +783,18 @@
783 783 #define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3 0x4
784 784 #define TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP 0x8
785 785  
  786 +/*
  787 + * Sleep keepon data: Maintains the state in sleep mode
  788 + * @therm_keepon: Keep on the thermal monitoring in sleep state.
  789 + * @clkout32k_keepon: Keep on the 32KHz clock output in sleep state.
  790 + * @i2chs_keepon: Keep on high speed internal clock in sleep state.
  791 + */
  792 +struct tps65910_sleep_keepon_data {
  793 + unsigned therm_keepon:1;
  794 + unsigned clkout32k_keepon:1;
  795 + unsigned i2chs_keepon:1;
  796 +};
  797 +
786 798 /**
787 799 * struct tps65910_board
788 800 * Board platform data may be used to initialize regulators.
... ... @@ -794,6 +806,8 @@
794 806 int irq_base;
795 807 int vmbch_threshold;
796 808 int vmbch2_threshold;
  809 + bool en_dev_slp;
  810 + struct tps65910_sleep_keepon_data *slp_keepon;
797 811 bool en_gpio_sleep[TPS6591X_MAX_NUM_GPIO];
798 812 unsigned long regulator_ext_sleep_control[TPS65910_NUM_REGS];
799 813 struct regulator_init_data *tps65910_pmic_init_data[TPS65910_NUM_REGS];