mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
input: sensors: lis3dh driver get regulator multiple times
Device driver does not need to request regulator each time it power on the device, it only need to vote on/off regulators and release regulators before exit. Change-Id: I01c4e1a9ee48495cdab965a4fb99dae3b01b57a3 Signed-off-by: Bingzhe Cai <bingzhec@codeaurora.org>
This commit is contained in:
parent
07692d5703
commit
202bfbb2d7
1 changed files with 63 additions and 32 deletions
|
@ -298,10 +298,11 @@ static int lis3dh_acc_config_regulator(struct lis3dh_acc_data *acc, bool on)
|
|||
lis3dh_acc_vreg[i].name);
|
||||
if (IS_ERR(lis3dh_acc_vreg[i].vreg)) {
|
||||
rc = PTR_ERR(lis3dh_acc_vreg[i].vreg);
|
||||
pr_err("%s:regulator get failed rc=%d\n",
|
||||
__func__, rc);
|
||||
dev_err(&acc->client->dev,
|
||||
"Regulator(%s) get failed rc=%d\n",
|
||||
lis3dh_acc_vreg[i].name, rc);
|
||||
lis3dh_acc_vreg[i].vreg = NULL;
|
||||
goto error_vdd;
|
||||
goto deinit_vregs;
|
||||
}
|
||||
|
||||
if (regulator_count_voltages(
|
||||
|
@ -311,43 +312,24 @@ static int lis3dh_acc_config_regulator(struct lis3dh_acc_data *acc, bool on)
|
|||
lis3dh_acc_vreg[i].min_uV,
|
||||
lis3dh_acc_vreg[i].max_uV);
|
||||
if (rc) {
|
||||
pr_err("%s: set voltage failed rc=%d\n",
|
||||
__func__, rc);
|
||||
dev_err(&acc->client->dev,
|
||||
"Regulator(%s)Set voltage failed rc=%d\n",
|
||||
lis3dh_acc_vreg[i].name, rc);
|
||||
regulator_put(lis3dh_acc_vreg[i].vreg);
|
||||
lis3dh_acc_vreg[i].vreg = NULL;
|
||||
goto error_vdd;
|
||||
goto deinit_vregs;
|
||||
}
|
||||
}
|
||||
|
||||
rc = regulator_enable(lis3dh_acc_vreg[i].vreg);
|
||||
if (rc) {
|
||||
pr_err("%s: regulator_enable failed rc =%d\n",
|
||||
__func__, rc);
|
||||
if (regulator_count_voltages(
|
||||
lis3dh_acc_vreg[i].vreg) > 0) {
|
||||
regulator_set_voltage(
|
||||
lis3dh_acc_vreg[i].vreg, 0,
|
||||
lis3dh_acc_vreg[i].max_uV);
|
||||
}
|
||||
regulator_put(lis3dh_acc_vreg[i].vreg);
|
||||
lis3dh_acc_vreg[i].vreg = NULL;
|
||||
goto error_vdd;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
} else {
|
||||
i = num_reg;
|
||||
goto deinit_vregs;
|
||||
}
|
||||
|
||||
error_vdd:
|
||||
deinit_vregs:
|
||||
while (--i >= 0) {
|
||||
if (!IS_ERR_OR_NULL(lis3dh_acc_vreg[i].vreg)) {
|
||||
if (regulator_count_voltages(
|
||||
lis3dh_acc_vreg[i].vreg) > 0) {
|
||||
regulator_set_voltage(lis3dh_acc_vreg[i].vreg,
|
||||
0, lis3dh_acc_vreg[i].max_uV);
|
||||
}
|
||||
regulator_disable(lis3dh_acc_vreg[i].vreg);
|
||||
regulator_put(lis3dh_acc_vreg[i].vreg);
|
||||
lis3dh_acc_vreg[i].vreg = NULL;
|
||||
}
|
||||
|
@ -355,6 +337,45 @@ error_vdd:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int lis3dh_acc_set_regulator(struct lis3dh_acc_data *acc, bool on)
|
||||
{
|
||||
int rc = 0, i;
|
||||
int num_reg = sizeof(lis3dh_acc_vreg) / sizeof(struct sensor_regulator);
|
||||
|
||||
if (on) {
|
||||
for (i = 0; i < num_reg; i++) {
|
||||
if (!IS_ERR_OR_NULL(lis3dh_acc_vreg[i].vreg)) {
|
||||
rc = regulator_enable(lis3dh_acc_vreg[i].vreg);
|
||||
if (rc) {
|
||||
dev_err(&acc->client->dev,
|
||||
"Enable regulator(%s) failed rc=%d\n",
|
||||
lis3dh_acc_vreg[i].name, rc);
|
||||
goto disable_regulator;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
} else {
|
||||
for (i = (num_reg - 1); i >= 0; i--) {
|
||||
if (!IS_ERR_OR_NULL(lis3dh_acc_vreg[i].vreg)) {
|
||||
rc = regulator_disable(lis3dh_acc_vreg[i].vreg);
|
||||
if (rc)
|
||||
dev_err(&acc->client->dev,
|
||||
"Disable regulator(%s) failed rc=%d\n",
|
||||
lis3dh_acc_vreg[i].name, rc);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
disable_regulator:
|
||||
while (--i >= 0) {
|
||||
if (!IS_ERR_OR_NULL(lis3dh_acc_vreg[i].vreg))
|
||||
regulator_disable(lis3dh_acc_vreg[i].vreg);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int lis3dh_acc_i2c_read(struct lis3dh_acc_data *acc,
|
||||
u8 *buf, int len)
|
||||
{
|
||||
|
@ -520,7 +541,7 @@ static void lis3dh_acc_device_power_off(struct lis3dh_acc_data *acc)
|
|||
if (err < 0)
|
||||
dev_err(&acc->client->dev, "soft power off failed: %d\n", err);
|
||||
|
||||
lis3dh_acc_config_regulator(acc, false);
|
||||
lis3dh_acc_set_regulator(acc, false);
|
||||
|
||||
if (acc->hw_initialized) {
|
||||
if (gpio_is_valid(acc->pdata->gpio_int1)
|
||||
|
@ -539,7 +560,7 @@ static int lis3dh_acc_device_power_on(struct lis3dh_acc_data *acc)
|
|||
{
|
||||
int err = -1;
|
||||
|
||||
err = lis3dh_acc_config_regulator(acc, true);
|
||||
err = lis3dh_acc_set_regulator(acc, true);
|
||||
if (err < 0) {
|
||||
dev_err(&acc->client->dev,
|
||||
"power_on failed: %d\n", err);
|
||||
|
@ -552,7 +573,7 @@ static int lis3dh_acc_device_power_on(struct lis3dh_acc_data *acc)
|
|||
if (!acc->hw_initialized) {
|
||||
err = lis3dh_acc_hw_init(acc);
|
||||
if (acc->hw_working == 1 && err < 0) {
|
||||
lis3dh_acc_device_power_off(acc);
|
||||
lis3dh_acc_set_regulator(acc, false);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
@ -1535,10 +1556,17 @@ static int lis3dh_acc_probe(struct i2c_client *client,
|
|||
acc->resume_state[RES_CTRL_REG3] = CONFIG_IRQ_DRDY1;
|
||||
acc->resume_state[RES_CTRL_REG4] = CONFIG_BLOCK_READ;
|
||||
}
|
||||
|
||||
err = lis3dh_acc_config_regulator(acc, true);
|
||||
if (err < 0) {
|
||||
dev_err(&client->dev, "Configure power failed: %d\n", err);
|
||||
goto err_pdata_init;
|
||||
}
|
||||
|
||||
err = lis3dh_acc_device_power_on(acc);
|
||||
if (err < 0) {
|
||||
dev_err(&client->dev, "power on failed: %d\n", err);
|
||||
goto err_pdata_init;
|
||||
goto err_regulator_init;
|
||||
}
|
||||
|
||||
atomic_set(&acc->enabled, 1);
|
||||
|
@ -1628,6 +1656,8 @@ err_input_cleanup:
|
|||
lis3dh_acc_input_cleanup(acc);
|
||||
err_power_off:
|
||||
lis3dh_acc_device_power_off(acc);
|
||||
err_regulator_init:
|
||||
lis3dh_acc_config_regulator(acc, false);
|
||||
err_pdata_init:
|
||||
if (acc->pdata->exit)
|
||||
acc->pdata->exit();
|
||||
|
@ -1658,6 +1688,7 @@ static int lis3dh_acc_remove(struct i2c_client *client)
|
|||
sensors_classdev_unregister(&acc->cdev);
|
||||
lis3dh_acc_input_cleanup(acc);
|
||||
lis3dh_acc_device_power_off(acc);
|
||||
lis3dh_acc_config_regulator(acc, false);
|
||||
remove_sysfs_interfaces(&client->dev);
|
||||
|
||||
if (acc->pdata->exit)
|
||||
|
|
Loading…
Reference in a new issue