summaryrefslogtreecommitdiff
path: root/drivers/staging
diff options
context:
space:
mode:
authorSri Krishna chowdary <schowdary@nvidia.com>2012-12-26 13:53:33 +0530
committerVarun Colbert <vcolbert@nvidia.com>2012-12-27 11:09:47 -0800
commit86270778ccbf007612b109f18f50037165a1b69a (patch)
tree4d92ff7651fde58b4f00df74ca7b9fb0be8bfee0 /drivers/staging
parent36ca15853ae4eca9bbe4d7fb5a28a8ecc65d6702 (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.c70
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;
}