diff options
author | Sri Krishna chowdary <schowdary@nvidia.com> | 2012-12-26 13:53:33 +0530 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2012-12-27 11:09:47 -0800 |
commit | 86270778ccbf007612b109f18f50037165a1b69a (patch) | |
tree | 4d92ff7651fde58b4f00df74ca7b9fb0be8bfee0 /drivers/staging | |
parent | 36ca15853ae4eca9bbe4d7fb5a28a8ecc65d6702 (diff) |
staging: iio: light: isl29028: enable regulator
Bug 1181726
Change-Id: I65639ec6d246aa6b9162dd7f54a9ca7357256e88
Signed-off-by: Sri Krishna chowdary <schowdary@nvidia.com>
Reviewed-on: http://git-master/r/173075
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Sachin Nikam <snikam@nvidia.com>
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/iio/light/isl29028.c | 70 |
1 files changed, 57 insertions, 13 deletions
diff --git a/drivers/staging/iio/light/isl29028.c b/drivers/staging/iio/light/isl29028.c index 806445d3f8e4..46e165b20d54 100644 --- a/drivers/staging/iio/light/isl29028.c +++ b/drivers/staging/iio/light/isl29028.c @@ -29,6 +29,7 @@ #include <linux/slab.h> #include <linux/completion.h> #include <linux/interrupt.h> +#include <linux/regulator/consumer.h> #include "../iio.h" #include "../sysfs.h" @@ -105,6 +106,7 @@ enum { struct isl29028_chip { struct i2c_client *client; struct mutex lock; + struct regulator *isl_reg; int irq; int prox_period; @@ -451,7 +453,7 @@ static ssize_t store_prox_enable(struct device *dev, struct iio_dev *indio_dev = dev_get_drvdata(dev); struct isl29028_chip *chip = iio_priv(indio_dev); struct i2c_client *client = chip->client; - bool st; + bool st = true; unsigned long lval; dev_vdbg(dev, "%s()\n", __func__); @@ -470,12 +472,28 @@ static ssize_t store_prox_enable(struct device *dev, return count; } - if (lval == 1) - st = isl29028_set_proxim_period(client, true, + if (lval) { + switch (chip->als_ir_mode) { + case MODE_NONE: + if (chip->isl_reg) + regulator_enable(chip->isl_reg); + case MODE_ALS: + case MODE_IR: + st = isl29028_set_proxim_period(client, true, chip->prox_period); - else - st = isl29028_set_proxim_period(client, false, + } + } else { + switch (chip->als_ir_mode) { + case MODE_ALS: + case MODE_IR: + st = isl29028_set_proxim_period(client, false, chip->prox_period); + break; + case MODE_NONE: + if (chip->isl_reg) + regulator_disable(chip->isl_reg); + } + } if (st) chip->is_prox_enable = (lval) ? true : false; else @@ -503,7 +521,7 @@ static ssize_t store_als_ir_mode(struct device *dev, struct iio_dev *indio_dev = dev_get_drvdata(dev); struct isl29028_chip *chip = iio_priv(indio_dev); struct i2c_client *client = chip->client; - bool st; + bool st = true; unsigned long lval; dev_vdbg(dev, "%s()\n", __func__); @@ -517,17 +535,25 @@ static ssize_t store_als_ir_mode(struct device *dev, mutex_lock(&chip->lock); - if (lval == chip->als_ir_mode) { + if (lval == chip->is_prox_enable) { mutex_unlock(&chip->lock); return count; } - if (lval == 0) - st = isl29028_set_als_ir_mode(client, false, false); - else if (lval == 1) - st = isl29028_set_als_ir_mode(client, true, true); - else - st = isl29028_set_als_ir_mode(client, true, false); + switch (lval) { + case MODE_NONE: + if (chip->is_prox_enable) + st = isl29028_set_als_ir_mode(client, false, false); + else if (chip->isl_reg) + regulator_disable(chip->isl_reg); + break; + case MODE_ALS: + case MODE_IR: + if (!chip->is_prox_enable && chip->isl_reg) + regulator_enable(chip->isl_reg); + st = isl29028_set_als_ir_mode(client, true, (lval == MODE_ALS)); + } + if (st) chip->als_ir_mode = (int)lval; else @@ -1117,6 +1143,12 @@ static int isl29028_chip_init(struct i2c_client *client) chip->is_proxim_int_waiting = false; chip->is_als_int_waiting = false; + /* if regulator is not available, then proceed with i2c write or + * if regulator is turned on then proceed with i2c write + */ + if (chip->isl_reg && !regulator_is_enabled(chip->isl_reg)) + return 0; + st = isl29028_write_data(client, ISL29028_REG_ADD_TEST1_MODE, 0x0, 0xFF, 0); if (st) @@ -1178,10 +1210,17 @@ static int __devinit isl29028_probe(struct i2c_client *client, { struct isl29028_chip *chip; struct iio_dev *indio_dev; + struct regulator *isl_reg = regulator_get(&client->dev, "vdd"); int err; dev_dbg(&client->dev, "%s() called\n", __func__); + if (IS_ERR_OR_NULL(isl_reg)) { + dev_info(&client->dev, "no regulator found," \ + "continue without regulator\n"); + isl_reg = NULL; + } + indio_dev = iio_allocate_device(sizeof(*chip)); if (indio_dev == NULL) { dev_err(&client->dev, "iio allocation fails\n"); @@ -1193,6 +1232,7 @@ static int __devinit isl29028_probe(struct i2c_client *client, i2c_set_clientdata(client, indio_dev); chip->client = client; chip->irq = client->irq; + chip->isl_reg = isl_reg; mutex_init(&chip->lock); @@ -1229,6 +1269,8 @@ exit_irq: if (chip->irq > 0) free_irq(chip->irq, chip); exit_iio_free: + if (chip->isl_reg) + regulator_put(chip->isl_reg); iio_free_device(indio_dev); exit: return err; @@ -1242,6 +1284,8 @@ static int __devexit isl29028_remove(struct i2c_client *client) dev_dbg(&client->dev, "%s()\n", __func__); if (chip->irq > 0) free_irq(chip->irq, chip); + if (chip->isl_reg) + regulator_put(chip->isl_reg); iio_device_unregister(indio_dev); return 0; } |