All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Renamed company name. - Removed cm32181_reg. - Removed white space. - Removed unused include files. - Updated macro definitions. - Renamed cm32181_chip pointer to chip.
@ 2015-05-22  0:30 ` Kevin Tsai
  0 siblings, 0 replies; 20+ messages in thread
From: Kevin Tsai @ 2015-05-22  0:30 UTC (permalink / raw)
  To: Kevin Tsai, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald, Andrew Morton, Greg KH, David S. Miller,
	Mauro Carvalho Chehab, Arnd Bergmann, Joe Perches, Jingoo Han,
	Daniel Baluta, Roberta Dobrescu, Kuppuswamy Sathyanarayanan
  Cc: devicetree, linux-kernel, linux-iio

Signed-off-by: Kevin Tsai <ktsai@capellamicro.com>
---
Renamed company name.
Removed cm32181_reg.
Removed white space.
Removed unused include files.
Updated macro definitions.
Renamed cm32181_chip pointer to chip.

 drivers/iio/light/Kconfig   |   4 +-
 drivers/iio/light/cm32181.c | 126 +++++++++++++++++++++++---------------------
 2 files changed, 67 insertions(+), 63 deletions(-)

diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
index a437bad..583aa6a 100644
--- a/drivers/iio/light/Kconfig
+++ b/drivers/iio/light/Kconfig
@@ -39,11 +39,11 @@ config APDS9300
 
 config CM32181
 	depends on I2C
-	tristate "CM32181 driver"
+	tristate "Vishay Capella CM32181 driver"
 	help
 	 Say Y here if you use cm32181.
 	 This option enables ambient light sensor using
-	 Capella cm32181 device driver.
+	 Vishay Capella cm32181 device driver.
 
 	 To compile this driver as a module, choose M here:
 	 the module will be called cm32181.
diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c
index 5d12ae54..0491d73 100644
--- a/drivers/iio/light/cm32181.c
+++ b/drivers/iio/light/cm32181.c
@@ -1,19 +1,15 @@
 /*
- * Copyright (C) 2013 Capella Microsystems Inc.
- * Author: Kevin Tsai <ktsai@capellamicro.com>
+ * Copyright (C) 2013-2015 Vishay Capella
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2, as published
  * by the Free Software Foundation.
  */
 
-#include <linux/delay.h>
-#include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
-#include <linux/regulator/consumer.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 #include <linux/iio/events.h>
@@ -21,36 +17,43 @@
 
 /* Registers Address */
 #define CM32181_REG_ADDR_CMD		0x00
+#define CM32181_REG_ADDR_ALS_WH		0x01
+#define CM32181_REG_ADDR_ALS_WL		0x02
 #define CM32181_REG_ADDR_ALS		0x04
 #define CM32181_REG_ADDR_STATUS		0x06
 #define CM32181_REG_ADDR_ID		0x07
 
 /* Number of Configurable Registers */
-#define CM32181_CONF_REG_NUM		0x01
+#define CM32181_CONF_REG_NUM		3
 
 /* CMD register */
-#define CM32181_CMD_ALS_ENABLE		0x00
-#define CM32181_CMD_ALS_DISABLE		0x01
-#define CM32181_CMD_ALS_INT_EN		0x02
+#define CM32181_CMD_ALS_DISABLE		BIT(0)
+#define CM32181_CMD_ALS_INT_EN		BIT(1)
 
 #define CM32181_CMD_ALS_IT_SHIFT	6
-#define CM32181_CMD_ALS_IT_MASK		(0x0F << CM32181_CMD_ALS_IT_SHIFT)
+#define CM32181_CMD_ALS_IT_MASK		(BIT(6) | BIT(7) | BIT(8) | BIT(9))
 #define CM32181_CMD_ALS_IT_DEFAULT	(0x00 << CM32181_CMD_ALS_IT_SHIFT)
 
 #define CM32181_CMD_ALS_SM_SHIFT	11
-#define CM32181_CMD_ALS_SM_MASK		(0x03 << CM32181_CMD_ALS_SM_SHIFT)
+#define CM32181_CMD_ALS_SM_MASK		(BIT(11) | BIT(12))
 #define CM32181_CMD_ALS_SM_DEFAULT	(0x01 << CM32181_CMD_ALS_SM_SHIFT)
 
+#define CM32181_CMD_DEFAULT		(CM32181_CMD_ALS_IT_DEFAULT | \
+					CM32181_CMD_ALS_SM_DEFAULT)
+
+/* ALS_WH register */
+#define CM32181_ALS_WH_DEFAULT		0xFFFF
+
+/* ALS_WL register */
+#define CM32181_ALS_WL_DEFAULT		0x0000
+
+/* Software parameters */
 #define CM32181_MLUX_PER_BIT		5	/* ALS_SM=01 IT=800ms */
 #define CM32181_MLUX_PER_BIT_BASE_IT	800000	/* Based on IT=800ms */
 #define	CM32181_CALIBSCALE_DEFAULT	1000
 #define CM32181_CALIBSCALE_RESOLUTION	1000
 #define MLUX_PER_LUX			1000
 
-static const u8 cm32181_reg[CM32181_CONF_REG_NUM] = {
-	CM32181_REG_ADDR_CMD,
-};
-
 static const int als_it_bits[] = {12, 8, 0, 1, 2, 3};
 static const int als_it_value[] = {25000, 50000, 100000, 200000, 400000,
 	800000};
@@ -64,15 +67,15 @@ struct cm32181_chip {
 
 /**
  * cm32181_reg_init() - Initialize CM32181 registers
- * @cm32181:	pointer of struct cm32181.
+ * @chip:	pointer of struct cm32181_chip
  *
  * Initialize CM32181 ambient light sensor register to default values.
  *
  * Return: 0 for success; otherwise for error code.
  */
-static int cm32181_reg_init(struct cm32181_chip *cm32181)
+static int cm32181_reg_init(struct cm32181_chip *chip)
 {
-	struct i2c_client *client = cm32181->client;
+	struct i2c_client *client = chip->client;
 	int i;
 	s32 ret;
 
@@ -85,14 +88,15 @@ static int cm32181_reg_init(struct cm32181_chip *cm32181)
 		return -ENODEV;
 
 	/* Default Values */
-	cm32181->conf_regs[CM32181_REG_ADDR_CMD] = CM32181_CMD_ALS_ENABLE |
-			CM32181_CMD_ALS_IT_DEFAULT | CM32181_CMD_ALS_SM_DEFAULT;
-	cm32181->calibscale = CM32181_CALIBSCALE_DEFAULT;
+	chip->conf_regs[CM32181_REG_ADDR_CMD] = CM32181_CMD_DEFAULT;
+	chip->conf_regs[CM32181_REG_ADDR_ALS_WH] = CM32181_ALS_WH_DEFAULT;
+	chip->conf_regs[CM32181_REG_ADDR_ALS_WL] = CM32181_ALS_WL_DEFAULT;
+	chip->calibscale = CM32181_CALIBSCALE_DEFAULT;
 
 	/* Initialize registers*/
 	for (i = 0; i < CM32181_CONF_REG_NUM; i++) {
-		ret = i2c_smbus_write_word_data(client, cm32181_reg[i],
-			cm32181->conf_regs[i]);
+		ret = i2c_smbus_write_word_data(client, i,
+			chip->conf_regs[i]);
 		if (ret < 0)
 			return ret;
 	}
@@ -101,20 +105,20 @@ static int cm32181_reg_init(struct cm32181_chip *cm32181)
 }
 
 /**
- *  cm32181_read_als_it() - Get sensor integration time (ms)
- *  @cm32181:	pointer of struct cm32181
- *  @val2:	pointer of int to load the als_it value.
+ * cm32181_read_als_it() - Get sensor integration time (ms)
+ * @chip:	pointer of struct cm32181_chip
+ * @val2:	pointer of int to load the als_it value.
  *
- *  Report the current integartion time by millisecond.
+ * Report the current integartion time by millisecond.
  *
- *  Return: IIO_VAL_INT_PLUS_MICRO for success, otherwise -EINVAL.
+ * Return: IIO_VAL_INT_PLUS_MICRO for success, otherwise -EINVAL.
  */
-static int cm32181_read_als_it(struct cm32181_chip *cm32181, int *val2)
+static int cm32181_read_als_it(struct cm32181_chip *chip, int *val2)
 {
 	u16 als_it;
 	int i;
 
-	als_it = cm32181->conf_regs[CM32181_REG_ADDR_CMD];
+	als_it = chip->conf_regs[CM32181_REG_ADDR_CMD];
 	als_it &= CM32181_CMD_ALS_IT_MASK;
 	als_it >>= CM32181_CMD_ALS_IT_SHIFT;
 	for (i = 0; i < ARRAY_SIZE(als_it_bits); i++) {
@@ -129,16 +133,16 @@ static int cm32181_read_als_it(struct cm32181_chip *cm32181, int *val2)
 
 /**
  * cm32181_write_als_it() - Write sensor integration time
- * @cm32181:	pointer of struct cm32181.
+ * @chip:	pointer of struct cm32181_chip.
  * @val:	integration time by millisecond.
  *
  * Convert integration time (ms) to sensor value.
  *
  * Return: i2c_smbus_write_word_data command return value.
  */
-static int cm32181_write_als_it(struct cm32181_chip *cm32181, int val)
+static int cm32181_write_als_it(struct cm32181_chip *chip, int val)
 {
-	struct i2c_client *client = cm32181->client;
+	struct i2c_client *client = chip->client;
 	u16 als_it;
 	int ret, i, n;
 
@@ -152,35 +156,35 @@ static int cm32181_write_als_it(struct cm32181_chip *cm32181, int val)
 	als_it = als_it_bits[i];
 	als_it <<= CM32181_CMD_ALS_IT_SHIFT;
 
-	mutex_lock(&cm32181->lock);
-	cm32181->conf_regs[CM32181_REG_ADDR_CMD] &=
+	mutex_lock(&chip->lock);
+	chip->conf_regs[CM32181_REG_ADDR_CMD] &=
 		~CM32181_CMD_ALS_IT_MASK;
-	cm32181->conf_regs[CM32181_REG_ADDR_CMD] |=
+	chip->conf_regs[CM32181_REG_ADDR_CMD] |=
 		als_it;
 	ret = i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
-			cm32181->conf_regs[CM32181_REG_ADDR_CMD]);
-	mutex_unlock(&cm32181->lock);
+			chip->conf_regs[CM32181_REG_ADDR_CMD]);
+	mutex_unlock(&chip->lock);
 
 	return ret;
 }
 
 /**
  * cm32181_get_lux() - report current lux value
- * @cm32181:	pointer of struct cm32181.
+ * @chip:	pointer of struct cm32181_chip
  *
  * Convert sensor raw data to lux.  It depends on integration
  * time and calibscale variable.
  *
  * Return: Positive value is lux, otherwise is error code.
  */
-static int cm32181_get_lux(struct cm32181_chip *cm32181)
+static int cm32181_get_lux(struct cm32181_chip *chip)
 {
-	struct i2c_client *client = cm32181->client;
+	struct i2c_client *client = chip->client;
 	int ret;
 	int als_it;
 	unsigned long lux;
 
-	ret = cm32181_read_als_it(cm32181, &als_it);
+	ret = cm32181_read_als_it(chip, &als_it);
 	if (ret < 0)
 		return -EINVAL;
 
@@ -193,7 +197,7 @@ static int cm32181_get_lux(struct cm32181_chip *cm32181)
 		return ret;
 
 	lux *= ret;
-	lux *= cm32181->calibscale;
+	lux *= chip->calibscale;
 	lux /= CM32181_CALIBSCALE_RESOLUTION;
 	lux /= MLUX_PER_LUX;
 
@@ -204,25 +208,25 @@ static int cm32181_get_lux(struct cm32181_chip *cm32181)
 }
 
 static int cm32181_read_raw(struct iio_dev *indio_dev,
-			    struct iio_chan_spec const *chan,
-			    int *val, int *val2, long mask)
+			struct iio_chan_spec const *chan,
+			int *val, int *val2, long mask)
 {
-	struct cm32181_chip *cm32181 = iio_priv(indio_dev);
+	struct cm32181_chip *chip = iio_priv(indio_dev);
 	int ret;
 
 	switch (mask) {
 	case IIO_CHAN_INFO_PROCESSED:
-		ret = cm32181_get_lux(cm32181);
+		ret = cm32181_get_lux(chip);
 		if (ret < 0)
 			return ret;
 		*val = ret;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_CALIBSCALE:
-		*val = cm32181->calibscale;
+		*val = chip->calibscale;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_INT_TIME:
 		*val = 0;
-		ret = cm32181_read_als_it(cm32181, val2);
+		ret = cm32181_read_als_it(chip, val2);
 		return ret;
 	}
 
@@ -230,18 +234,18 @@ static int cm32181_read_raw(struct iio_dev *indio_dev,
 }
 
 static int cm32181_write_raw(struct iio_dev *indio_dev,
-			     struct iio_chan_spec const *chan,
-			     int val, int val2, long mask)
+			struct iio_chan_spec const *chan,
+			int val, int val2, long mask)
 {
-	struct cm32181_chip *cm32181 = iio_priv(indio_dev);
+	struct cm32181_chip *chip = iio_priv(indio_dev);
 	int ret;
 
 	switch (mask) {
 	case IIO_CHAN_INFO_CALIBSCALE:
-		cm32181->calibscale = val;
+		chip->calibscale = val;
 		return val;
 	case IIO_CHAN_INFO_INT_TIME:
-		ret = cm32181_write_als_it(cm32181, val2);
+		ret = cm32181_write_als_it(chip, val2);
 		return ret;
 	}
 
@@ -301,21 +305,21 @@ static const struct iio_info cm32181_info = {
 static int cm32181_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
-	struct cm32181_chip *cm32181;
+	struct cm32181_chip *chip;
 	struct iio_dev *indio_dev;
 	int ret;
 
-	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*cm32181));
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
 	if (!indio_dev) {
 		dev_err(&client->dev, "devm_iio_device_alloc failed\n");
 		return -ENOMEM;
 	}
 
-	cm32181 = iio_priv(indio_dev);
+	chip = iio_priv(indio_dev);
 	i2c_set_clientdata(client, indio_dev);
-	cm32181->client = client;
+	chip->client = client;
 
-	mutex_init(&cm32181->lock);
+	mutex_init(&chip->lock);
 	indio_dev->dev.parent = &client->dev;
 	indio_dev->channels = cm32181_channels;
 	indio_dev->num_channels = ARRAY_SIZE(cm32181_channels);
@@ -323,7 +327,7 @@ static int cm32181_probe(struct i2c_client *client,
 	indio_dev->name = id->name;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
-	ret = cm32181_reg_init(cm32181);
+	ret = cm32181_reg_init(chip);
 	if (ret) {
 		dev_err(&client->dev,
 			"%s: register init failed\n",
@@ -360,7 +364,7 @@ static struct i2c_driver cm32181_driver = {
 		.of_match_table = of_match_ptr(cm32181_of_match),
 		.owner	= THIS_MODULE,
 	},
-	.id_table       = cm32181_id,
+	.id_table	= cm32181_id,
 	.probe		= cm32181_probe,
 };
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 1/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Renamed company name. - Removed cm32181_reg. - Removed white space. - Removed unused include files. - Updated macro definitions. - Renamed cm32181_chip pointer to chip.
@ 2015-05-22  0:30 ` Kevin Tsai
  0 siblings, 0 replies; 20+ messages in thread
From: Kevin Tsai @ 2015-05-22  0:30 UTC (permalink / raw)
  To: Kevin Tsai, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald, Andrew Morton, Greg KH, David S. Miller,
	Mauro Carvalho Chehab, Arnd Bergmann, Joe Perches, Jingoo Han,
	Daniel Baluta, Roberta Dobrescu, Kuppuswamy Sathyanarayanan
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-iio-u79uwXL29TY76Z2rM5mHXA

Signed-off-by: Kevin Tsai <ktsai-GubuWUlQtMwciDkP5Hr2oA@public.gmane.org>
---
Renamed company name.
Removed cm32181_reg.
Removed white space.
Removed unused include files.
Updated macro definitions.
Renamed cm32181_chip pointer to chip.

 drivers/iio/light/Kconfig   |   4 +-
 drivers/iio/light/cm32181.c | 126 +++++++++++++++++++++++---------------------
 2 files changed, 67 insertions(+), 63 deletions(-)

diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
index a437bad..583aa6a 100644
--- a/drivers/iio/light/Kconfig
+++ b/drivers/iio/light/Kconfig
@@ -39,11 +39,11 @@ config APDS9300
 
 config CM32181
 	depends on I2C
-	tristate "CM32181 driver"
+	tristate "Vishay Capella CM32181 driver"
 	help
 	 Say Y here if you use cm32181.
 	 This option enables ambient light sensor using
-	 Capella cm32181 device driver.
+	 Vishay Capella cm32181 device driver.
 
 	 To compile this driver as a module, choose M here:
 	 the module will be called cm32181.
diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c
index 5d12ae54..0491d73 100644
--- a/drivers/iio/light/cm32181.c
+++ b/drivers/iio/light/cm32181.c
@@ -1,19 +1,15 @@
 /*
- * Copyright (C) 2013 Capella Microsystems Inc.
- * Author: Kevin Tsai <ktsai-GubuWUlQtMwciDkP5Hr2oA@public.gmane.org>
+ * Copyright (C) 2013-2015 Vishay Capella
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2, as published
  * by the Free Software Foundation.
  */
 
-#include <linux/delay.h>
-#include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
-#include <linux/regulator/consumer.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 #include <linux/iio/events.h>
@@ -21,36 +17,43 @@
 
 /* Registers Address */
 #define CM32181_REG_ADDR_CMD		0x00
+#define CM32181_REG_ADDR_ALS_WH		0x01
+#define CM32181_REG_ADDR_ALS_WL		0x02
 #define CM32181_REG_ADDR_ALS		0x04
 #define CM32181_REG_ADDR_STATUS		0x06
 #define CM32181_REG_ADDR_ID		0x07
 
 /* Number of Configurable Registers */
-#define CM32181_CONF_REG_NUM		0x01
+#define CM32181_CONF_REG_NUM		3
 
 /* CMD register */
-#define CM32181_CMD_ALS_ENABLE		0x00
-#define CM32181_CMD_ALS_DISABLE		0x01
-#define CM32181_CMD_ALS_INT_EN		0x02
+#define CM32181_CMD_ALS_DISABLE		BIT(0)
+#define CM32181_CMD_ALS_INT_EN		BIT(1)
 
 #define CM32181_CMD_ALS_IT_SHIFT	6
-#define CM32181_CMD_ALS_IT_MASK		(0x0F << CM32181_CMD_ALS_IT_SHIFT)
+#define CM32181_CMD_ALS_IT_MASK		(BIT(6) | BIT(7) | BIT(8) | BIT(9))
 #define CM32181_CMD_ALS_IT_DEFAULT	(0x00 << CM32181_CMD_ALS_IT_SHIFT)
 
 #define CM32181_CMD_ALS_SM_SHIFT	11
-#define CM32181_CMD_ALS_SM_MASK		(0x03 << CM32181_CMD_ALS_SM_SHIFT)
+#define CM32181_CMD_ALS_SM_MASK		(BIT(11) | BIT(12))
 #define CM32181_CMD_ALS_SM_DEFAULT	(0x01 << CM32181_CMD_ALS_SM_SHIFT)
 
+#define CM32181_CMD_DEFAULT		(CM32181_CMD_ALS_IT_DEFAULT | \
+					CM32181_CMD_ALS_SM_DEFAULT)
+
+/* ALS_WH register */
+#define CM32181_ALS_WH_DEFAULT		0xFFFF
+
+/* ALS_WL register */
+#define CM32181_ALS_WL_DEFAULT		0x0000
+
+/* Software parameters */
 #define CM32181_MLUX_PER_BIT		5	/* ALS_SM=01 IT=800ms */
 #define CM32181_MLUX_PER_BIT_BASE_IT	800000	/* Based on IT=800ms */
 #define	CM32181_CALIBSCALE_DEFAULT	1000
 #define CM32181_CALIBSCALE_RESOLUTION	1000
 #define MLUX_PER_LUX			1000
 
-static const u8 cm32181_reg[CM32181_CONF_REG_NUM] = {
-	CM32181_REG_ADDR_CMD,
-};
-
 static const int als_it_bits[] = {12, 8, 0, 1, 2, 3};
 static const int als_it_value[] = {25000, 50000, 100000, 200000, 400000,
 	800000};
@@ -64,15 +67,15 @@ struct cm32181_chip {
 
 /**
  * cm32181_reg_init() - Initialize CM32181 registers
- * @cm32181:	pointer of struct cm32181.
+ * @chip:	pointer of struct cm32181_chip
  *
  * Initialize CM32181 ambient light sensor register to default values.
  *
  * Return: 0 for success; otherwise for error code.
  */
-static int cm32181_reg_init(struct cm32181_chip *cm32181)
+static int cm32181_reg_init(struct cm32181_chip *chip)
 {
-	struct i2c_client *client = cm32181->client;
+	struct i2c_client *client = chip->client;
 	int i;
 	s32 ret;
 
@@ -85,14 +88,15 @@ static int cm32181_reg_init(struct cm32181_chip *cm32181)
 		return -ENODEV;
 
 	/* Default Values */
-	cm32181->conf_regs[CM32181_REG_ADDR_CMD] = CM32181_CMD_ALS_ENABLE |
-			CM32181_CMD_ALS_IT_DEFAULT | CM32181_CMD_ALS_SM_DEFAULT;
-	cm32181->calibscale = CM32181_CALIBSCALE_DEFAULT;
+	chip->conf_regs[CM32181_REG_ADDR_CMD] = CM32181_CMD_DEFAULT;
+	chip->conf_regs[CM32181_REG_ADDR_ALS_WH] = CM32181_ALS_WH_DEFAULT;
+	chip->conf_regs[CM32181_REG_ADDR_ALS_WL] = CM32181_ALS_WL_DEFAULT;
+	chip->calibscale = CM32181_CALIBSCALE_DEFAULT;
 
 	/* Initialize registers*/
 	for (i = 0; i < CM32181_CONF_REG_NUM; i++) {
-		ret = i2c_smbus_write_word_data(client, cm32181_reg[i],
-			cm32181->conf_regs[i]);
+		ret = i2c_smbus_write_word_data(client, i,
+			chip->conf_regs[i]);
 		if (ret < 0)
 			return ret;
 	}
@@ -101,20 +105,20 @@ static int cm32181_reg_init(struct cm32181_chip *cm32181)
 }
 
 /**
- *  cm32181_read_als_it() - Get sensor integration time (ms)
- *  @cm32181:	pointer of struct cm32181
- *  @val2:	pointer of int to load the als_it value.
+ * cm32181_read_als_it() - Get sensor integration time (ms)
+ * @chip:	pointer of struct cm32181_chip
+ * @val2:	pointer of int to load the als_it value.
  *
- *  Report the current integartion time by millisecond.
+ * Report the current integartion time by millisecond.
  *
- *  Return: IIO_VAL_INT_PLUS_MICRO for success, otherwise -EINVAL.
+ * Return: IIO_VAL_INT_PLUS_MICRO for success, otherwise -EINVAL.
  */
-static int cm32181_read_als_it(struct cm32181_chip *cm32181, int *val2)
+static int cm32181_read_als_it(struct cm32181_chip *chip, int *val2)
 {
 	u16 als_it;
 	int i;
 
-	als_it = cm32181->conf_regs[CM32181_REG_ADDR_CMD];
+	als_it = chip->conf_regs[CM32181_REG_ADDR_CMD];
 	als_it &= CM32181_CMD_ALS_IT_MASK;
 	als_it >>= CM32181_CMD_ALS_IT_SHIFT;
 	for (i = 0; i < ARRAY_SIZE(als_it_bits); i++) {
@@ -129,16 +133,16 @@ static int cm32181_read_als_it(struct cm32181_chip *cm32181, int *val2)
 
 /**
  * cm32181_write_als_it() - Write sensor integration time
- * @cm32181:	pointer of struct cm32181.
+ * @chip:	pointer of struct cm32181_chip.
  * @val:	integration time by millisecond.
  *
  * Convert integration time (ms) to sensor value.
  *
  * Return: i2c_smbus_write_word_data command return value.
  */
-static int cm32181_write_als_it(struct cm32181_chip *cm32181, int val)
+static int cm32181_write_als_it(struct cm32181_chip *chip, int val)
 {
-	struct i2c_client *client = cm32181->client;
+	struct i2c_client *client = chip->client;
 	u16 als_it;
 	int ret, i, n;
 
@@ -152,35 +156,35 @@ static int cm32181_write_als_it(struct cm32181_chip *cm32181, int val)
 	als_it = als_it_bits[i];
 	als_it <<= CM32181_CMD_ALS_IT_SHIFT;
 
-	mutex_lock(&cm32181->lock);
-	cm32181->conf_regs[CM32181_REG_ADDR_CMD] &=
+	mutex_lock(&chip->lock);
+	chip->conf_regs[CM32181_REG_ADDR_CMD] &=
 		~CM32181_CMD_ALS_IT_MASK;
-	cm32181->conf_regs[CM32181_REG_ADDR_CMD] |=
+	chip->conf_regs[CM32181_REG_ADDR_CMD] |=
 		als_it;
 	ret = i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
-			cm32181->conf_regs[CM32181_REG_ADDR_CMD]);
-	mutex_unlock(&cm32181->lock);
+			chip->conf_regs[CM32181_REG_ADDR_CMD]);
+	mutex_unlock(&chip->lock);
 
 	return ret;
 }
 
 /**
  * cm32181_get_lux() - report current lux value
- * @cm32181:	pointer of struct cm32181.
+ * @chip:	pointer of struct cm32181_chip
  *
  * Convert sensor raw data to lux.  It depends on integration
  * time and calibscale variable.
  *
  * Return: Positive value is lux, otherwise is error code.
  */
-static int cm32181_get_lux(struct cm32181_chip *cm32181)
+static int cm32181_get_lux(struct cm32181_chip *chip)
 {
-	struct i2c_client *client = cm32181->client;
+	struct i2c_client *client = chip->client;
 	int ret;
 	int als_it;
 	unsigned long lux;
 
-	ret = cm32181_read_als_it(cm32181, &als_it);
+	ret = cm32181_read_als_it(chip, &als_it);
 	if (ret < 0)
 		return -EINVAL;
 
@@ -193,7 +197,7 @@ static int cm32181_get_lux(struct cm32181_chip *cm32181)
 		return ret;
 
 	lux *= ret;
-	lux *= cm32181->calibscale;
+	lux *= chip->calibscale;
 	lux /= CM32181_CALIBSCALE_RESOLUTION;
 	lux /= MLUX_PER_LUX;
 
@@ -204,25 +208,25 @@ static int cm32181_get_lux(struct cm32181_chip *cm32181)
 }
 
 static int cm32181_read_raw(struct iio_dev *indio_dev,
-			    struct iio_chan_spec const *chan,
-			    int *val, int *val2, long mask)
+			struct iio_chan_spec const *chan,
+			int *val, int *val2, long mask)
 {
-	struct cm32181_chip *cm32181 = iio_priv(indio_dev);
+	struct cm32181_chip *chip = iio_priv(indio_dev);
 	int ret;
 
 	switch (mask) {
 	case IIO_CHAN_INFO_PROCESSED:
-		ret = cm32181_get_lux(cm32181);
+		ret = cm32181_get_lux(chip);
 		if (ret < 0)
 			return ret;
 		*val = ret;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_CALIBSCALE:
-		*val = cm32181->calibscale;
+		*val = chip->calibscale;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_INT_TIME:
 		*val = 0;
-		ret = cm32181_read_als_it(cm32181, val2);
+		ret = cm32181_read_als_it(chip, val2);
 		return ret;
 	}
 
@@ -230,18 +234,18 @@ static int cm32181_read_raw(struct iio_dev *indio_dev,
 }
 
 static int cm32181_write_raw(struct iio_dev *indio_dev,
-			     struct iio_chan_spec const *chan,
-			     int val, int val2, long mask)
+			struct iio_chan_spec const *chan,
+			int val, int val2, long mask)
 {
-	struct cm32181_chip *cm32181 = iio_priv(indio_dev);
+	struct cm32181_chip *chip = iio_priv(indio_dev);
 	int ret;
 
 	switch (mask) {
 	case IIO_CHAN_INFO_CALIBSCALE:
-		cm32181->calibscale = val;
+		chip->calibscale = val;
 		return val;
 	case IIO_CHAN_INFO_INT_TIME:
-		ret = cm32181_write_als_it(cm32181, val2);
+		ret = cm32181_write_als_it(chip, val2);
 		return ret;
 	}
 
@@ -301,21 +305,21 @@ static const struct iio_info cm32181_info = {
 static int cm32181_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
-	struct cm32181_chip *cm32181;
+	struct cm32181_chip *chip;
 	struct iio_dev *indio_dev;
 	int ret;
 
-	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*cm32181));
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
 	if (!indio_dev) {
 		dev_err(&client->dev, "devm_iio_device_alloc failed\n");
 		return -ENOMEM;
 	}
 
-	cm32181 = iio_priv(indio_dev);
+	chip = iio_priv(indio_dev);
 	i2c_set_clientdata(client, indio_dev);
-	cm32181->client = client;
+	chip->client = client;
 
-	mutex_init(&cm32181->lock);
+	mutex_init(&chip->lock);
 	indio_dev->dev.parent = &client->dev;
 	indio_dev->channels = cm32181_channels;
 	indio_dev->num_channels = ARRAY_SIZE(cm32181_channels);
@@ -323,7 +327,7 @@ static int cm32181_probe(struct i2c_client *client,
 	indio_dev->name = id->name;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
-	ret = cm32181_reg_init(cm32181);
+	ret = cm32181_reg_init(chip);
 	if (ret) {
 		dev_err(&client->dev,
 			"%s: register init failed\n",
@@ -360,7 +364,7 @@ static struct i2c_driver cm32181_driver = {
 		.of_match_table = of_match_ptr(cm32181_of_match),
 		.owner	= THIS_MODULE,
 	},
-	.id_table       = cm32181_id,
+	.id_table	= cm32181_id,
 	.probe		= cm32181_probe,
 };
 
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 1/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Renamed company name. - Removed cm32181_reg. - Removed white space. - Removed unused include files. - Updated macro definitions. - Renamed cm32181_chip pointer to chip.
@ 2015-05-22  0:30 ` Kevin Tsai
  0 siblings, 0 replies; 20+ messages in thread
From: Kevin Tsai @ 2015-05-22  0:30 UTC (permalink / raw)
  To: Kevin Tsai, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald, Andrew Morton, Greg KH, David S. Miller,
	Mauro Carvalho Chehab, Arnd Bergmann, Joe Perches, Jingoo Han,
	Daniel Baluta, Roberta Dobrescu, Kuppuswamy Sathyanarayanan
  Cc: devicetree, linux-kernel, linux-iio

Signed-off-by: Kevin Tsai <ktsai@capellamicro.com>
---
Renamed company name.
Removed cm32181_reg.
Removed white space.
Removed unused include files.
Updated macro definitions.
Renamed cm32181_chip pointer to chip.

 drivers/iio/light/Kconfig   |   4 +-
 drivers/iio/light/cm32181.c | 126 +++++++++++++++++++++++---------------------
 2 files changed, 67 insertions(+), 63 deletions(-)

diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
index a437bad..583aa6a 100644
--- a/drivers/iio/light/Kconfig
+++ b/drivers/iio/light/Kconfig
@@ -39,11 +39,11 @@ config APDS9300
 
 config CM32181
 	depends on I2C
-	tristate "CM32181 driver"
+	tristate "Vishay Capella CM32181 driver"
 	help
 	 Say Y here if you use cm32181.
 	 This option enables ambient light sensor using
-	 Capella cm32181 device driver.
+	 Vishay Capella cm32181 device driver.
 
 	 To compile this driver as a module, choose M here:
 	 the module will be called cm32181.
diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c
index 5d12ae54..0491d73 100644
--- a/drivers/iio/light/cm32181.c
+++ b/drivers/iio/light/cm32181.c
@@ -1,19 +1,15 @@
 /*
- * Copyright (C) 2013 Capella Microsystems Inc.
- * Author: Kevin Tsai <ktsai@capellamicro.com>
+ * Copyright (C) 2013-2015 Vishay Capella
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2, as published
  * by the Free Software Foundation.
  */
 
-#include <linux/delay.h>
-#include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
-#include <linux/regulator/consumer.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 #include <linux/iio/events.h>
@@ -21,36 +17,43 @@
 
 /* Registers Address */
 #define CM32181_REG_ADDR_CMD		0x00
+#define CM32181_REG_ADDR_ALS_WH		0x01
+#define CM32181_REG_ADDR_ALS_WL		0x02
 #define CM32181_REG_ADDR_ALS		0x04
 #define CM32181_REG_ADDR_STATUS		0x06
 #define CM32181_REG_ADDR_ID		0x07
 
 /* Number of Configurable Registers */
-#define CM32181_CONF_REG_NUM		0x01
+#define CM32181_CONF_REG_NUM		3
 
 /* CMD register */
-#define CM32181_CMD_ALS_ENABLE		0x00
-#define CM32181_CMD_ALS_DISABLE		0x01
-#define CM32181_CMD_ALS_INT_EN		0x02
+#define CM32181_CMD_ALS_DISABLE		BIT(0)
+#define CM32181_CMD_ALS_INT_EN		BIT(1)
 
 #define CM32181_CMD_ALS_IT_SHIFT	6
-#define CM32181_CMD_ALS_IT_MASK		(0x0F << CM32181_CMD_ALS_IT_SHIFT)
+#define CM32181_CMD_ALS_IT_MASK		(BIT(6) | BIT(7) | BIT(8) | BIT(9))
 #define CM32181_CMD_ALS_IT_DEFAULT	(0x00 << CM32181_CMD_ALS_IT_SHIFT)
 
 #define CM32181_CMD_ALS_SM_SHIFT	11
-#define CM32181_CMD_ALS_SM_MASK		(0x03 << CM32181_CMD_ALS_SM_SHIFT)
+#define CM32181_CMD_ALS_SM_MASK		(BIT(11) | BIT(12))
 #define CM32181_CMD_ALS_SM_DEFAULT	(0x01 << CM32181_CMD_ALS_SM_SHIFT)
 
+#define CM32181_CMD_DEFAULT		(CM32181_CMD_ALS_IT_DEFAULT | \
+					CM32181_CMD_ALS_SM_DEFAULT)
+
+/* ALS_WH register */
+#define CM32181_ALS_WH_DEFAULT		0xFFFF
+
+/* ALS_WL register */
+#define CM32181_ALS_WL_DEFAULT		0x0000
+
+/* Software parameters */
 #define CM32181_MLUX_PER_BIT		5	/* ALS_SM=01 IT=800ms */
 #define CM32181_MLUX_PER_BIT_BASE_IT	800000	/* Based on IT=800ms */
 #define	CM32181_CALIBSCALE_DEFAULT	1000
 #define CM32181_CALIBSCALE_RESOLUTION	1000
 #define MLUX_PER_LUX			1000
 
-static const u8 cm32181_reg[CM32181_CONF_REG_NUM] = {
-	CM32181_REG_ADDR_CMD,
-};
-
 static const int als_it_bits[] = {12, 8, 0, 1, 2, 3};
 static const int als_it_value[] = {25000, 50000, 100000, 200000, 400000,
 	800000};
@@ -64,15 +67,15 @@ struct cm32181_chip {
 
 /**
  * cm32181_reg_init() - Initialize CM32181 registers
- * @cm32181:	pointer of struct cm32181.
+ * @chip:	pointer of struct cm32181_chip
  *
  * Initialize CM32181 ambient light sensor register to default values.
  *
  * Return: 0 for success; otherwise for error code.
  */
-static int cm32181_reg_init(struct cm32181_chip *cm32181)
+static int cm32181_reg_init(struct cm32181_chip *chip)
 {
-	struct i2c_client *client = cm32181->client;
+	struct i2c_client *client = chip->client;
 	int i;
 	s32 ret;
 
@@ -85,14 +88,15 @@ static int cm32181_reg_init(struct cm32181_chip *cm32181)
 		return -ENODEV;
 
 	/* Default Values */
-	cm32181->conf_regs[CM32181_REG_ADDR_CMD] = CM32181_CMD_ALS_ENABLE |
-			CM32181_CMD_ALS_IT_DEFAULT | CM32181_CMD_ALS_SM_DEFAULT;
-	cm32181->calibscale = CM32181_CALIBSCALE_DEFAULT;
+	chip->conf_regs[CM32181_REG_ADDR_CMD] = CM32181_CMD_DEFAULT;
+	chip->conf_regs[CM32181_REG_ADDR_ALS_WH] = CM32181_ALS_WH_DEFAULT;
+	chip->conf_regs[CM32181_REG_ADDR_ALS_WL] = CM32181_ALS_WL_DEFAULT;
+	chip->calibscale = CM32181_CALIBSCALE_DEFAULT;
 
 	/* Initialize registers*/
 	for (i = 0; i < CM32181_CONF_REG_NUM; i++) {
-		ret = i2c_smbus_write_word_data(client, cm32181_reg[i],
-			cm32181->conf_regs[i]);
+		ret = i2c_smbus_write_word_data(client, i,
+			chip->conf_regs[i]);
 		if (ret < 0)
 			return ret;
 	}
@@ -101,20 +105,20 @@ static int cm32181_reg_init(struct cm32181_chip *cm32181)
 }
 
 /**
- *  cm32181_read_als_it() - Get sensor integration time (ms)
- *  @cm32181:	pointer of struct cm32181
- *  @val2:	pointer of int to load the als_it value.
+ * cm32181_read_als_it() - Get sensor integration time (ms)
+ * @chip:	pointer of struct cm32181_chip
+ * @val2:	pointer of int to load the als_it value.
  *
- *  Report the current integartion time by millisecond.
+ * Report the current integartion time by millisecond.
  *
- *  Return: IIO_VAL_INT_PLUS_MICRO for success, otherwise -EINVAL.
+ * Return: IIO_VAL_INT_PLUS_MICRO for success, otherwise -EINVAL.
  */
-static int cm32181_read_als_it(struct cm32181_chip *cm32181, int *val2)
+static int cm32181_read_als_it(struct cm32181_chip *chip, int *val2)
 {
 	u16 als_it;
 	int i;
 
-	als_it = cm32181->conf_regs[CM32181_REG_ADDR_CMD];
+	als_it = chip->conf_regs[CM32181_REG_ADDR_CMD];
 	als_it &= CM32181_CMD_ALS_IT_MASK;
 	als_it >>= CM32181_CMD_ALS_IT_SHIFT;
 	for (i = 0; i < ARRAY_SIZE(als_it_bits); i++) {
@@ -129,16 +133,16 @@ static int cm32181_read_als_it(struct cm32181_chip *cm32181, int *val2)
 
 /**
  * cm32181_write_als_it() - Write sensor integration time
- * @cm32181:	pointer of struct cm32181.
+ * @chip:	pointer of struct cm32181_chip.
  * @val:	integration time by millisecond.
  *
  * Convert integration time (ms) to sensor value.
  *
  * Return: i2c_smbus_write_word_data command return value.
  */
-static int cm32181_write_als_it(struct cm32181_chip *cm32181, int val)
+static int cm32181_write_als_it(struct cm32181_chip *chip, int val)
 {
-	struct i2c_client *client = cm32181->client;
+	struct i2c_client *client = chip->client;
 	u16 als_it;
 	int ret, i, n;
 
@@ -152,35 +156,35 @@ static int cm32181_write_als_it(struct cm32181_chip *cm32181, int val)
 	als_it = als_it_bits[i];
 	als_it <<= CM32181_CMD_ALS_IT_SHIFT;
 
-	mutex_lock(&cm32181->lock);
-	cm32181->conf_regs[CM32181_REG_ADDR_CMD] &=
+	mutex_lock(&chip->lock);
+	chip->conf_regs[CM32181_REG_ADDR_CMD] &=
 		~CM32181_CMD_ALS_IT_MASK;
-	cm32181->conf_regs[CM32181_REG_ADDR_CMD] |=
+	chip->conf_regs[CM32181_REG_ADDR_CMD] |=
 		als_it;
 	ret = i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
-			cm32181->conf_regs[CM32181_REG_ADDR_CMD]);
-	mutex_unlock(&cm32181->lock);
+			chip->conf_regs[CM32181_REG_ADDR_CMD]);
+	mutex_unlock(&chip->lock);
 
 	return ret;
 }
 
 /**
  * cm32181_get_lux() - report current lux value
- * @cm32181:	pointer of struct cm32181.
+ * @chip:	pointer of struct cm32181_chip
  *
  * Convert sensor raw data to lux.  It depends on integration
  * time and calibscale variable.
  *
  * Return: Positive value is lux, otherwise is error code.
  */
-static int cm32181_get_lux(struct cm32181_chip *cm32181)
+static int cm32181_get_lux(struct cm32181_chip *chip)
 {
-	struct i2c_client *client = cm32181->client;
+	struct i2c_client *client = chip->client;
 	int ret;
 	int als_it;
 	unsigned long lux;
 
-	ret = cm32181_read_als_it(cm32181, &als_it);
+	ret = cm32181_read_als_it(chip, &als_it);
 	if (ret < 0)
 		return -EINVAL;
 
@@ -193,7 +197,7 @@ static int cm32181_get_lux(struct cm32181_chip *cm32181)
 		return ret;
 
 	lux *= ret;
-	lux *= cm32181->calibscale;
+	lux *= chip->calibscale;
 	lux /= CM32181_CALIBSCALE_RESOLUTION;
 	lux /= MLUX_PER_LUX;
 
@@ -204,25 +208,25 @@ static int cm32181_get_lux(struct cm32181_chip *cm32181)
 }
 
 static int cm32181_read_raw(struct iio_dev *indio_dev,
-			    struct iio_chan_spec const *chan,
-			    int *val, int *val2, long mask)
+			struct iio_chan_spec const *chan,
+			int *val, int *val2, long mask)
 {
-	struct cm32181_chip *cm32181 = iio_priv(indio_dev);
+	struct cm32181_chip *chip = iio_priv(indio_dev);
 	int ret;
 
 	switch (mask) {
 	case IIO_CHAN_INFO_PROCESSED:
-		ret = cm32181_get_lux(cm32181);
+		ret = cm32181_get_lux(chip);
 		if (ret < 0)
 			return ret;
 		*val = ret;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_CALIBSCALE:
-		*val = cm32181->calibscale;
+		*val = chip->calibscale;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_INT_TIME:
 		*val = 0;
-		ret = cm32181_read_als_it(cm32181, val2);
+		ret = cm32181_read_als_it(chip, val2);
 		return ret;
 	}
 
@@ -230,18 +234,18 @@ static int cm32181_read_raw(struct iio_dev *indio_dev,
 }
 
 static int cm32181_write_raw(struct iio_dev *indio_dev,
-			     struct iio_chan_spec const *chan,
-			     int val, int val2, long mask)
+			struct iio_chan_spec const *chan,
+			int val, int val2, long mask)
 {
-	struct cm32181_chip *cm32181 = iio_priv(indio_dev);
+	struct cm32181_chip *chip = iio_priv(indio_dev);
 	int ret;
 
 	switch (mask) {
 	case IIO_CHAN_INFO_CALIBSCALE:
-		cm32181->calibscale = val;
+		chip->calibscale = val;
 		return val;
 	case IIO_CHAN_INFO_INT_TIME:
-		ret = cm32181_write_als_it(cm32181, val2);
+		ret = cm32181_write_als_it(chip, val2);
 		return ret;
 	}
 
@@ -301,21 +305,21 @@ static const struct iio_info cm32181_info = {
 static int cm32181_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
-	struct cm32181_chip *cm32181;
+	struct cm32181_chip *chip;
 	struct iio_dev *indio_dev;
 	int ret;
 
-	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*cm32181));
+	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
 	if (!indio_dev) {
 		dev_err(&client->dev, "devm_iio_device_alloc failed\n");
 		return -ENOMEM;
 	}
 
-	cm32181 = iio_priv(indio_dev);
+	chip = iio_priv(indio_dev);
 	i2c_set_clientdata(client, indio_dev);
-	cm32181->client = client;
+	chip->client = client;
 
-	mutex_init(&cm32181->lock);
+	mutex_init(&chip->lock);
 	indio_dev->dev.parent = &client->dev;
 	indio_dev->channels = cm32181_channels;
 	indio_dev->num_channels = ARRAY_SIZE(cm32181_channels);
@@ -323,7 +327,7 @@ static int cm32181_probe(struct i2c_client *client,
 	indio_dev->name = id->name;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 
-	ret = cm32181_reg_init(cm32181);
+	ret = cm32181_reg_init(chip);
 	if (ret) {
 		dev_err(&client->dev,
 			"%s: register init failed\n",
@@ -360,7 +364,7 @@ static struct i2c_driver cm32181_driver = {
 		.of_match_table = of_match_ptr(cm32181_of_match),
 		.owner	= THIS_MODULE,
 	},
-	.id_table       = cm32181_id,
+	.id_table	= cm32181_id,
 	.probe		= cm32181_probe,
 };
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 2/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Added cm32181_als_info structure.
  2015-05-22  0:30 ` Kevin Tsai
@ 2015-05-22  0:30   ` Kevin Tsai
  -1 siblings, 0 replies; 20+ messages in thread
From: Kevin Tsai @ 2015-05-22  0:30 UTC (permalink / raw)
  To: Kevin Tsai, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald, Andrew Morton, Greg KH, David S. Miller,
	Mauro Carvalho Chehab, Arnd Bergmann, Joe Perches, Jingoo Han,
	Daniel Baluta, Roberta Dobrescu, Kuppuswamy Sathyanarayanan
  Cc: devicetree, linux-kernel, linux-iio

Signed-off-by: Kevin Tsai <ktsai@capellamicro.com>
---
Added cm32181_als_info structure.

 drivers/iio/light/cm32181.c | 42 +++++++++++++++++++++++++++++++++---------
 1 file changed, 33 insertions(+), 9 deletions(-)

diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c
index 0491d73..6b11145 100644
--- a/drivers/iio/light/cm32181.c
+++ b/drivers/iio/light/cm32181.c
@@ -48,6 +48,7 @@
 #define CM32181_ALS_WL_DEFAULT		0x0000
 
 /* Software parameters */
+#define CM32181_HW_ID			0x81
 #define CM32181_MLUX_PER_BIT		5	/* ALS_SM=01 IT=800ms */
 #define CM32181_MLUX_PER_BIT_BASE_IT	800000	/* Based on IT=800ms */
 #define	CM32181_CALIBSCALE_DEFAULT	1000
@@ -58,11 +59,31 @@ static const int als_it_bits[] = {12, 8, 0, 1, 2, 3};
 static const int als_it_value[] = {25000, 50000, 100000, 200000, 400000,
 	800000};
 
+struct cm32181_als_info {
+	u8 hw_id;
+	u16 reg_cmd;
+	u16 reg_als_wh;
+	u16 reg_als_wl;
+	int calibscale;
+	int mlux_per_bit;
+	int mlux_per_bit_base_it;
+};
+
+static struct cm32181_als_info cm32181_als_info_default = {
+	.hw_id = CM32181_HW_ID,
+	.reg_cmd = CM32181_CMD_DEFAULT,
+	.reg_als_wh = CM32181_ALS_WH_DEFAULT,
+	.reg_als_wl = CM32181_ALS_WL_DEFAULT,
+	.calibscale = CM32181_CALIBSCALE_DEFAULT,
+	.mlux_per_bit = CM32181_MLUX_PER_BIT,
+	.mlux_per_bit_base_it = CM32181_MLUX_PER_BIT_BASE_IT,
+};
+
 struct cm32181_chip {
 	struct i2c_client *client;
 	struct mutex lock;
+	struct cm32181_als_info *als_info;
 	u16 conf_regs[CM32181_CONF_REG_NUM];
-	int calibscale;
 };
 
 /**
@@ -76,22 +97,25 @@ struct cm32181_chip {
 static int cm32181_reg_init(struct cm32181_chip *chip)
 {
 	struct i2c_client *client = chip->client;
+	struct cm32181_als_info *als_info;
 	int i;
 	s32 ret;
 
+	chip->als_info = &cm32181_als_info_default;
+	als_info = chip->als_info;
+
 	ret = i2c_smbus_read_word_data(client, CM32181_REG_ADDR_ID);
 	if (ret < 0)
 		return ret;
 
 	/* check device ID */
-	if ((ret & 0xFF) != 0x81)
+	if ((ret & 0xFF) != als_info->hw_id)
 		return -ENODEV;
 
 	/* Default Values */
-	chip->conf_regs[CM32181_REG_ADDR_CMD] = CM32181_CMD_DEFAULT;
-	chip->conf_regs[CM32181_REG_ADDR_ALS_WH] = CM32181_ALS_WH_DEFAULT;
-	chip->conf_regs[CM32181_REG_ADDR_ALS_WL] = CM32181_ALS_WL_DEFAULT;
-	chip->calibscale = CM32181_CALIBSCALE_DEFAULT;
+	chip->conf_regs[CM32181_REG_ADDR_CMD] = als_info->reg_cmd;
+	chip->conf_regs[CM32181_REG_ADDR_ALS_WH] = als_info->reg_als_wh;
+	chip->conf_regs[CM32181_REG_ADDR_ALS_WL] = als_info->reg_als_wl;
 
 	/* Initialize registers*/
 	for (i = 0; i < CM32181_CONF_REG_NUM; i++) {
@@ -197,7 +221,7 @@ static int cm32181_get_lux(struct cm32181_chip *chip)
 		return ret;
 
 	lux *= ret;
-	lux *= chip->calibscale;
+	lux *= chip->als_info->calibscale;
 	lux /= CM32181_CALIBSCALE_RESOLUTION;
 	lux /= MLUX_PER_LUX;
 
@@ -222,7 +246,7 @@ static int cm32181_read_raw(struct iio_dev *indio_dev,
 		*val = ret;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_CALIBSCALE:
-		*val = chip->calibscale;
+		*val = chip->als_info->calibscale;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_INT_TIME:
 		*val = 0;
@@ -242,7 +266,7 @@ static int cm32181_write_raw(struct iio_dev *indio_dev,
 
 	switch (mask) {
 	case IIO_CHAN_INFO_CALIBSCALE:
-		chip->calibscale = val;
+		chip->als_info->calibscale = val;
 		return val;
 	case IIO_CHAN_INFO_INT_TIME:
 		ret = cm32181_write_als_it(chip, val2);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 2/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Added cm32181_als_info structure.
@ 2015-05-22  0:30   ` Kevin Tsai
  0 siblings, 0 replies; 20+ messages in thread
From: Kevin Tsai @ 2015-05-22  0:30 UTC (permalink / raw)
  To: Kevin Tsai, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald, Andrew Morton, Greg KH, David S. Miller,
	Mauro Carvalho Chehab, Arnd Bergmann, Joe Perches, Jingoo Han,
	Daniel Baluta, Roberta Dobrescu, Kuppuswamy Sathyanarayanan
  Cc: devicetree, linux-kernel, linux-iio

Signed-off-by: Kevin Tsai <ktsai@capellamicro.com>
---
Added cm32181_als_info structure.

 drivers/iio/light/cm32181.c | 42 +++++++++++++++++++++++++++++++++---------
 1 file changed, 33 insertions(+), 9 deletions(-)

diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c
index 0491d73..6b11145 100644
--- a/drivers/iio/light/cm32181.c
+++ b/drivers/iio/light/cm32181.c
@@ -48,6 +48,7 @@
 #define CM32181_ALS_WL_DEFAULT		0x0000
 
 /* Software parameters */
+#define CM32181_HW_ID			0x81
 #define CM32181_MLUX_PER_BIT		5	/* ALS_SM=01 IT=800ms */
 #define CM32181_MLUX_PER_BIT_BASE_IT	800000	/* Based on IT=800ms */
 #define	CM32181_CALIBSCALE_DEFAULT	1000
@@ -58,11 +59,31 @@ static const int als_it_bits[] = {12, 8, 0, 1, 2, 3};
 static const int als_it_value[] = {25000, 50000, 100000, 200000, 400000,
 	800000};
 
+struct cm32181_als_info {
+	u8 hw_id;
+	u16 reg_cmd;
+	u16 reg_als_wh;
+	u16 reg_als_wl;
+	int calibscale;
+	int mlux_per_bit;
+	int mlux_per_bit_base_it;
+};
+
+static struct cm32181_als_info cm32181_als_info_default = {
+	.hw_id = CM32181_HW_ID,
+	.reg_cmd = CM32181_CMD_DEFAULT,
+	.reg_als_wh = CM32181_ALS_WH_DEFAULT,
+	.reg_als_wl = CM32181_ALS_WL_DEFAULT,
+	.calibscale = CM32181_CALIBSCALE_DEFAULT,
+	.mlux_per_bit = CM32181_MLUX_PER_BIT,
+	.mlux_per_bit_base_it = CM32181_MLUX_PER_BIT_BASE_IT,
+};
+
 struct cm32181_chip {
 	struct i2c_client *client;
 	struct mutex lock;
+	struct cm32181_als_info *als_info;
 	u16 conf_regs[CM32181_CONF_REG_NUM];
-	int calibscale;
 };
 
 /**
@@ -76,22 +97,25 @@ struct cm32181_chip {
 static int cm32181_reg_init(struct cm32181_chip *chip)
 {
 	struct i2c_client *client = chip->client;
+	struct cm32181_als_info *als_info;
 	int i;
 	s32 ret;
 
+	chip->als_info = &cm32181_als_info_default;
+	als_info = chip->als_info;
+
 	ret = i2c_smbus_read_word_data(client, CM32181_REG_ADDR_ID);
 	if (ret < 0)
 		return ret;
 
 	/* check device ID */
-	if ((ret & 0xFF) != 0x81)
+	if ((ret & 0xFF) != als_info->hw_id)
 		return -ENODEV;
 
 	/* Default Values */
-	chip->conf_regs[CM32181_REG_ADDR_CMD] = CM32181_CMD_DEFAULT;
-	chip->conf_regs[CM32181_REG_ADDR_ALS_WH] = CM32181_ALS_WH_DEFAULT;
-	chip->conf_regs[CM32181_REG_ADDR_ALS_WL] = CM32181_ALS_WL_DEFAULT;
-	chip->calibscale = CM32181_CALIBSCALE_DEFAULT;
+	chip->conf_regs[CM32181_REG_ADDR_CMD] = als_info->reg_cmd;
+	chip->conf_regs[CM32181_REG_ADDR_ALS_WH] = als_info->reg_als_wh;
+	chip->conf_regs[CM32181_REG_ADDR_ALS_WL] = als_info->reg_als_wl;
 
 	/* Initialize registers*/
 	for (i = 0; i < CM32181_CONF_REG_NUM; i++) {
@@ -197,7 +221,7 @@ static int cm32181_get_lux(struct cm32181_chip *chip)
 		return ret;
 
 	lux *= ret;
-	lux *= chip->calibscale;
+	lux *= chip->als_info->calibscale;
 	lux /= CM32181_CALIBSCALE_RESOLUTION;
 	lux /= MLUX_PER_LUX;
 
@@ -222,7 +246,7 @@ static int cm32181_read_raw(struct iio_dev *indio_dev,
 		*val = ret;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_CALIBSCALE:
-		*val = chip->calibscale;
+		*val = chip->als_info->calibscale;
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_INT_TIME:
 		*val = 0;
@@ -242,7 +266,7 @@ static int cm32181_write_raw(struct iio_dev *indio_dev,
 
 	switch (mask) {
 	case IIO_CHAN_INFO_CALIBSCALE:
-		chip->calibscale = val;
+		chip->als_info->calibscale = val;
 		return val;
 	case IIO_CHAN_INFO_INT_TIME:
 		ret = cm32181_write_als_it(chip, val2);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 3/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Added Power Management support. - Added driver remove routine.
@ 2015-05-22  0:30   ` Kevin Tsai
  0 siblings, 0 replies; 20+ messages in thread
From: Kevin Tsai @ 2015-05-22  0:30 UTC (permalink / raw)
  To: Kevin Tsai, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald, Andrew Morton, Greg KH, David S. Miller,
	Mauro Carvalho Chehab, Arnd Bergmann, Joe Perches, Jingoo Han,
	Daniel Baluta, Roberta Dobrescu, Kuppuswamy Sathyanarayanan
  Cc: devicetree, linux-kernel, linux-iio

Signed-off-by: Kevin Tsai <ktsai@capellamicro.com>
---
Added Power Management support.
Added remove routine.

 drivers/iio/light/cm32181.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c
index 6b11145..9bc3e1f 100644
--- a/drivers/iio/light/cm32181.c
+++ b/drivers/iio/light/cm32181.c
@@ -370,11 +370,51 @@ static int cm32181_probe(struct i2c_client *client,
 	return 0;
 }
 
+static int cm32181_remove(struct i2c_client *client)
+{
+	i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
+		CM32181_CMD_ALS_DISABLE);
+
+	return 0;
+}
+
 static const struct i2c_device_id cm32181_id[] = {
 	{ "cm32181", 0 },
 	{ }
 };
 
+#ifdef CONFIG_PM_SLEEP
+static int cm32181_suspend(struct device *dev)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct cm32181_chip *chip = iio_priv(indio_dev);
+	struct i2c_client *client = chip->client;
+	int ret;
+
+	ret = i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
+					CM32181_CMD_ALS_DISABLE);
+
+	return ret;
+}
+
+static int cm32181_resume(struct device *dev)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct cm32181_chip *chip = iio_priv(indio_dev);
+	struct i2c_client *client = chip->client;
+	int ret;
+
+	chip->conf_regs[CM32181_REG_ADDR_CMD] &= ~CM32181_CMD_ALS_DISABLE;
+	ret = i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
+				chip->conf_regs[CM32181_REG_ADDR_CMD]);
+
+	return ret;
+}
+
+static const struct dev_pm_ops cm32181_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(cm32181_suspend, cm32181_resume)};
+#endif
+
 MODULE_DEVICE_TABLE(i2c, cm32181_id);
 
 static const struct of_device_id cm32181_of_match[] = {
@@ -387,9 +427,13 @@ static struct i2c_driver cm32181_driver = {
 		.name	= "cm32181",
 		.of_match_table = of_match_ptr(cm32181_of_match),
 		.owner	= THIS_MODULE,
+#ifdef CONFIG_PM_SLEEP
+		.pm     = &cm32181_pm_ops,
+#endif
 	},
 	.id_table	= cm32181_id,
 	.probe		= cm32181_probe,
+	.remove		= cm32181_remove,
 };
 
 module_i2c_driver(cm32181_driver);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 3/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Added Power Management support. - Added driver remove routine.
@ 2015-05-22  0:30   ` Kevin Tsai
  0 siblings, 0 replies; 20+ messages in thread
From: Kevin Tsai @ 2015-05-22  0:30 UTC (permalink / raw)
  To: Kevin Tsai, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald, Andrew Morton, Greg KH, David S. Miller,
	Mauro Carvalho Chehab, Arnd Bergmann, Joe Perches, Jingoo Han,
	Daniel Baluta, Roberta Dobrescu, Kuppuswamy Sathyanarayanan
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-iio-u79uwXL29TY76Z2rM5mHXA

Signed-off-by: Kevin Tsai <ktsai-GubuWUlQtMwciDkP5Hr2oA@public.gmane.org>
---
Added Power Management support.
Added remove routine.

 drivers/iio/light/cm32181.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c
index 6b11145..9bc3e1f 100644
--- a/drivers/iio/light/cm32181.c
+++ b/drivers/iio/light/cm32181.c
@@ -370,11 +370,51 @@ static int cm32181_probe(struct i2c_client *client,
 	return 0;
 }
 
+static int cm32181_remove(struct i2c_client *client)
+{
+	i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
+		CM32181_CMD_ALS_DISABLE);
+
+	return 0;
+}
+
 static const struct i2c_device_id cm32181_id[] = {
 	{ "cm32181", 0 },
 	{ }
 };
 
+#ifdef CONFIG_PM_SLEEP
+static int cm32181_suspend(struct device *dev)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct cm32181_chip *chip = iio_priv(indio_dev);
+	struct i2c_client *client = chip->client;
+	int ret;
+
+	ret = i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
+					CM32181_CMD_ALS_DISABLE);
+
+	return ret;
+}
+
+static int cm32181_resume(struct device *dev)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct cm32181_chip *chip = iio_priv(indio_dev);
+	struct i2c_client *client = chip->client;
+	int ret;
+
+	chip->conf_regs[CM32181_REG_ADDR_CMD] &= ~CM32181_CMD_ALS_DISABLE;
+	ret = i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
+				chip->conf_regs[CM32181_REG_ADDR_CMD]);
+
+	return ret;
+}
+
+static const struct dev_pm_ops cm32181_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(cm32181_suspend, cm32181_resume)};
+#endif
+
 MODULE_DEVICE_TABLE(i2c, cm32181_id);
 
 static const struct of_device_id cm32181_of_match[] = {
@@ -387,9 +427,13 @@ static struct i2c_driver cm32181_driver = {
 		.name	= "cm32181",
 		.of_match_table = of_match_ptr(cm32181_of_match),
 		.owner	= THIS_MODULE,
+#ifdef CONFIG_PM_SLEEP
+		.pm     = &cm32181_pm_ops,
+#endif
 	},
 	.id_table	= cm32181_id,
 	.probe		= cm32181_probe,
+	.remove		= cm32181_remove,
 };
 
 module_i2c_driver(cm32181_driver);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 3/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Added Power Management support. - Added driver remove routine.
@ 2015-05-22  0:30   ` Kevin Tsai
  0 siblings, 0 replies; 20+ messages in thread
From: Kevin Tsai @ 2015-05-22  0:30 UTC (permalink / raw)
  To: Kevin Tsai, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald, Andrew Morton, Greg KH, David S. Miller,
	Mauro Carvalho Chehab, Arnd Bergmann, Joe Perches, Jingoo Han,
	Daniel Baluta, Roberta Dobrescu, Kuppuswamy Sathyanarayanan
  Cc: devicetree, linux-kernel, linux-iio

Signed-off-by: Kevin Tsai <ktsai@capellamicro.com>
---
Added Power Management support.
Added remove routine.

 drivers/iio/light/cm32181.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c
index 6b11145..9bc3e1f 100644
--- a/drivers/iio/light/cm32181.c
+++ b/drivers/iio/light/cm32181.c
@@ -370,11 +370,51 @@ static int cm32181_probe(struct i2c_client *client,
 	return 0;
 }
 
+static int cm32181_remove(struct i2c_client *client)
+{
+	i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
+		CM32181_CMD_ALS_DISABLE);
+
+	return 0;
+}
+
 static const struct i2c_device_id cm32181_id[] = {
 	{ "cm32181", 0 },
 	{ }
 };
 
+#ifdef CONFIG_PM_SLEEP
+static int cm32181_suspend(struct device *dev)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct cm32181_chip *chip = iio_priv(indio_dev);
+	struct i2c_client *client = chip->client;
+	int ret;
+
+	ret = i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
+					CM32181_CMD_ALS_DISABLE);
+
+	return ret;
+}
+
+static int cm32181_resume(struct device *dev)
+{
+	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
+	struct cm32181_chip *chip = iio_priv(indio_dev);
+	struct i2c_client *client = chip->client;
+	int ret;
+
+	chip->conf_regs[CM32181_REG_ADDR_CMD] &= ~CM32181_CMD_ALS_DISABLE;
+	ret = i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
+				chip->conf_regs[CM32181_REG_ADDR_CMD]);
+
+	return ret;
+}
+
+static const struct dev_pm_ops cm32181_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(cm32181_suspend, cm32181_resume)};
+#endif
+
 MODULE_DEVICE_TABLE(i2c, cm32181_id);
 
 static const struct of_device_id cm32181_of_match[] = {
@@ -387,9 +427,13 @@ static struct i2c_driver cm32181_driver = {
 		.name	= "cm32181",
 		.of_match_table = of_match_ptr(cm32181_of_match),
 		.owner	= THIS_MODULE,
+#ifdef CONFIG_PM_SLEEP
+		.pm     = &cm32181_pm_ops,
+#endif
 	},
 	.id_table	= cm32181_id,
 	.probe		= cm32181_probe,
+	.remove		= cm32181_remove,
 };
 
 module_i2c_driver(cm32181_driver);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 4/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Replaced als_it_bits and als_it_value by cm32181_als_it_scale.
  2015-05-22  0:30 ` Kevin Tsai
@ 2015-05-22  0:30   ` Kevin Tsai
  -1 siblings, 0 replies; 20+ messages in thread
From: Kevin Tsai @ 2015-05-22  0:30 UTC (permalink / raw)
  To: Kevin Tsai, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald, Andrew Morton, Greg KH, David S. Miller,
	Mauro Carvalho Chehab, Arnd Bergmann, Joe Perches, Jingoo Han,
	Daniel Baluta, Roberta Dobrescu, Kuppuswamy Sathyanarayanan
  Cc: devicetree, linux-kernel, linux-iio

Signed-off-by: Kevin Tsai <ktsai@capellamicro.com>
---
Replaced als_it_bits and als_it_value by cm32181_als_it_scale.

 drivers/iio/light/cm32181.c | 95 ++++++++++++++++++++++++++++++++++++---------
 1 file changed, 76 insertions(+), 19 deletions(-)

diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c
index 9bc3e1f..54bf0cb 100644
--- a/drivers/iio/light/cm32181.c
+++ b/drivers/iio/light/cm32181.c
@@ -53,12 +53,25 @@
 #define CM32181_MLUX_PER_BIT_BASE_IT	800000	/* Based on IT=800ms */
 #define	CM32181_CALIBSCALE_DEFAULT	1000
 #define CM32181_CALIBSCALE_RESOLUTION	1000
-#define MLUX_PER_LUX			1000
+#define CM32181_MLUX_PER_LUX		1000
 
 static const int als_it_bits[] = {12, 8, 0, 1, 2, 3};
 static const int als_it_value[] = {25000, 50000, 100000, 200000, 400000,
 	800000};
 
+static const struct {
+	int val;
+	int val2;
+	u16 it;
+} cm32181_als_it_scales[] = {
+	{0, 25000, 12},	/* 0.025000 */
+	{0, 50000, 8},	/* 0.050000 */
+	{0, 100000, 0},	/* 0.100000 */
+	{0, 200000, 1},	/* 0.200000 */
+	{0, 400000, 2},	/* 0.400000 */
+	{0, 800000, 3},	/* 0.800000 */
+};
+
 struct cm32181_als_info {
 	u8 hw_id;
 	u16 reg_cmd;
@@ -129,15 +142,16 @@ static int cm32181_reg_init(struct cm32181_chip *chip)
 }
 
 /**
- * cm32181_read_als_it() - Get sensor integration time (ms)
+ * cm32181_read_als_it() - Get sensor integration time
  * @chip:	pointer of struct cm32181_chip
- * @val2:	pointer of int to load the als_it value.
+ * @val:	pointer of int to load the integration (sec)
+ * @val2:	pointer of int to load the integration time (microsecond)
  *
  * Report the current integartion time by millisecond.
  *
  * Return: IIO_VAL_INT_PLUS_MICRO for success, otherwise -EINVAL.
  */
-static int cm32181_read_als_it(struct cm32181_chip *chip, int *val2)
+static int cm32181_read_als_it(struct cm32181_chip *chip, int *val, int *val2)
 {
 	u16 als_it;
 	int i;
@@ -145,9 +159,10 @@ static int cm32181_read_als_it(struct cm32181_chip *chip, int *val2)
 	als_it = chip->conf_regs[CM32181_REG_ADDR_CMD];
 	als_it &= CM32181_CMD_ALS_IT_MASK;
 	als_it >>= CM32181_CMD_ALS_IT_SHIFT;
-	for (i = 0; i < ARRAY_SIZE(als_it_bits); i++) {
-		if (als_it == als_it_bits[i]) {
-			*val2 = als_it_value[i];
+	for (i = 0; i < ARRAY_SIZE(cm32181_als_it_scales); i++) {
+		if (als_it == cm32181_als_it_scales[i].it) {
+			*val = cm32181_als_it_scales[i].val;
+			*val2 = cm32181_als_it_scales[i].val2;
 			return IIO_VAL_INT_PLUS_MICRO;
 		}
 	}
@@ -158,15 +173,44 @@ static int cm32181_read_als_it(struct cm32181_chip *chip, int *val2)
 /**
  * cm32181_write_als_it() - Write sensor integration time
  * @chip:	pointer of struct cm32181_chip.
- * @val:	integration time by millisecond.
+ * @val:	integration time in second.
+ * @val2:	integration time in microsecond.
  *
  * Convert integration time (ms) to sensor value.
  *
  * Return: i2c_smbus_write_word_data command return value.
  */
-static int cm32181_write_als_it(struct cm32181_chip *chip, int val)
+static int cm32181_write_als_it(struct cm32181_chip *chip, int val, int val2)
 {
 	struct i2c_client *client = chip->client;
+	u16 als_it, cmd;
+	int i;
+	s32 ret;
+
+	for (i = 0; i < ARRAY_SIZE(cm32181_als_it_scales); i++) {
+		if (val == cm32181_als_it_scales[i].val &&
+			val2 == cm32181_als_it_scales[i].val2) {
+
+			als_it = cm32181_als_it_scales[i].it;
+			als_it <<= CM32181_CMD_ALS_IT_SHIFT;
+
+			cmd = chip->conf_regs[CM32181_REG_ADDR_CMD];
+			cmd &= ~CM32181_CMD_ALS_IT_MASK;
+			cmd |= als_it;
+			ret = i2c_smbus_write_word_data(client,
+						CM32181_REG_ADDR_CMD,
+						cmd);
+			if (ret < 0)
+				return ret;
+
+			chip->conf_regs[CM32181_REG_ADDR_CMD] = cmd;
+			return 0;
+		}
+	}
+	return -EINVAL;
+
+/*
+	struct i2c_client *client = chip->client;
 	u16 als_it;
 	int ret, i, n;
 
@@ -190,6 +234,7 @@ static int cm32181_write_als_it(struct cm32181_chip *chip, int val)
 	mutex_unlock(&chip->lock);
 
 	return ret;
+*/
 }
 
 /**
@@ -204,26 +249,29 @@ static int cm32181_write_als_it(struct cm32181_chip *chip, int val)
 static int cm32181_get_lux(struct cm32181_chip *chip)
 {
 	struct i2c_client *client = chip->client;
+	struct cm32181_als_info *als_info = chip->als_info;
 	int ret;
+	int val, val2;
 	int als_it;
-	unsigned long lux;
+	u64 lux;
 
-	ret = cm32181_read_als_it(chip, &als_it);
+	ret = cm32181_read_als_it(chip, &val, &val2);
 	if (ret < 0)
 		return -EINVAL;
+	als_it = val * 1000000 + val2;
 
-	lux = CM32181_MLUX_PER_BIT;
-	lux *= CM32181_MLUX_PER_BIT_BASE_IT;
-	lux /= als_it;
+	lux = (__force u64)als_info->mlux_per_bit;
+	lux *= als_info->mlux_per_bit_base_it;
+	lux = div_u64(lux, als_it);
 
 	ret = i2c_smbus_read_word_data(client, CM32181_REG_ADDR_ALS);
 	if (ret < 0)
 		return ret;
 
 	lux *= ret;
-	lux *= chip->als_info->calibscale;
-	lux /= CM32181_CALIBSCALE_RESOLUTION;
-	lux /= MLUX_PER_LUX;
+	lux *= als_info->calibscale;
+	lux = div_u64(lux, CM32181_CALIBSCALE_RESOLUTION);
+	lux = div_u64(lux, CM32181_MLUX_PER_LUX);
 
 	if (lux > 0xFFFF)
 		lux = 0xFFFF;
@@ -250,7 +298,7 @@ static int cm32181_read_raw(struct iio_dev *indio_dev,
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_INT_TIME:
 		*val = 0;
-		ret = cm32181_read_als_it(chip, val2);
+		ret = cm32181_read_als_it(chip, val, val2);
 		return ret;
 	}
 
@@ -269,7 +317,7 @@ static int cm32181_write_raw(struct iio_dev *indio_dev,
 		chip->als_info->calibscale = val;
 		return val;
 	case IIO_CHAN_INFO_INT_TIME:
-		ret = cm32181_write_als_it(chip, val2);
+		ret = cm32181_write_als_it(chip, val, val2);
 		return ret;
 	}
 
@@ -289,12 +337,21 @@ static int cm32181_write_raw(struct iio_dev *indio_dev,
 static ssize_t cm32181_get_it_available(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
+	int i, len;
+
+	for (i = 0, len = 0; i < ARRAY_SIZE(cm32181_als_it_scales); i++)
+		len += scnprintf(buf + len, PAGE_SIZE - len, "%u.%06u ",
+			cm32181_als_it_scales[i].val,
+			cm32181_als_it_scales[i].val2);
+	return len + scnprintf(buf + len, PAGE_SIZE - len, "\n");
+/*
 	int i, n, len;
 
 	n = ARRAY_SIZE(als_it_value);
 	for (i = 0, len = 0; i < n; i++)
 		len += sprintf(buf + len, "0.%06u ", als_it_value[i]);
 	return len + sprintf(buf + len, "\n");
+*/
 }
 
 static const struct iio_chan_spec cm32181_channels[] = {
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 4/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Replaced als_it_bits and als_it_value by cm32181_als_it_scale.
@ 2015-05-22  0:30   ` Kevin Tsai
  0 siblings, 0 replies; 20+ messages in thread
From: Kevin Tsai @ 2015-05-22  0:30 UTC (permalink / raw)
  To: Kevin Tsai, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald, Andrew Morton, Greg KH, David S. Miller,
	Mauro Carvalho Chehab, Arnd Bergmann, Joe Perches, Jingoo Han,
	Daniel Baluta, Roberta Dobrescu, Kuppuswamy Sathyanarayanan
  Cc: devicetree, linux-kernel, linux-iio

Signed-off-by: Kevin Tsai <ktsai@capellamicro.com>
---
Replaced als_it_bits and als_it_value by cm32181_als_it_scale.

 drivers/iio/light/cm32181.c | 95 ++++++++++++++++++++++++++++++++++++---------
 1 file changed, 76 insertions(+), 19 deletions(-)

diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c
index 9bc3e1f..54bf0cb 100644
--- a/drivers/iio/light/cm32181.c
+++ b/drivers/iio/light/cm32181.c
@@ -53,12 +53,25 @@
 #define CM32181_MLUX_PER_BIT_BASE_IT	800000	/* Based on IT=800ms */
 #define	CM32181_CALIBSCALE_DEFAULT	1000
 #define CM32181_CALIBSCALE_RESOLUTION	1000
-#define MLUX_PER_LUX			1000
+#define CM32181_MLUX_PER_LUX		1000
 
 static const int als_it_bits[] = {12, 8, 0, 1, 2, 3};
 static const int als_it_value[] = {25000, 50000, 100000, 200000, 400000,
 	800000};
 
+static const struct {
+	int val;
+	int val2;
+	u16 it;
+} cm32181_als_it_scales[] = {
+	{0, 25000, 12},	/* 0.025000 */
+	{0, 50000, 8},	/* 0.050000 */
+	{0, 100000, 0},	/* 0.100000 */
+	{0, 200000, 1},	/* 0.200000 */
+	{0, 400000, 2},	/* 0.400000 */
+	{0, 800000, 3},	/* 0.800000 */
+};
+
 struct cm32181_als_info {
 	u8 hw_id;
 	u16 reg_cmd;
@@ -129,15 +142,16 @@ static int cm32181_reg_init(struct cm32181_chip *chip)
 }
 
 /**
- * cm32181_read_als_it() - Get sensor integration time (ms)
+ * cm32181_read_als_it() - Get sensor integration time
  * @chip:	pointer of struct cm32181_chip
- * @val2:	pointer of int to load the als_it value.
+ * @val:	pointer of int to load the integration (sec)
+ * @val2:	pointer of int to load the integration time (microsecond)
  *
  * Report the current integartion time by millisecond.
  *
  * Return: IIO_VAL_INT_PLUS_MICRO for success, otherwise -EINVAL.
  */
-static int cm32181_read_als_it(struct cm32181_chip *chip, int *val2)
+static int cm32181_read_als_it(struct cm32181_chip *chip, int *val, int *val2)
 {
 	u16 als_it;
 	int i;
@@ -145,9 +159,10 @@ static int cm32181_read_als_it(struct cm32181_chip *chip, int *val2)
 	als_it = chip->conf_regs[CM32181_REG_ADDR_CMD];
 	als_it &= CM32181_CMD_ALS_IT_MASK;
 	als_it >>= CM32181_CMD_ALS_IT_SHIFT;
-	for (i = 0; i < ARRAY_SIZE(als_it_bits); i++) {
-		if (als_it == als_it_bits[i]) {
-			*val2 = als_it_value[i];
+	for (i = 0; i < ARRAY_SIZE(cm32181_als_it_scales); i++) {
+		if (als_it == cm32181_als_it_scales[i].it) {
+			*val = cm32181_als_it_scales[i].val;
+			*val2 = cm32181_als_it_scales[i].val2;
 			return IIO_VAL_INT_PLUS_MICRO;
 		}
 	}
@@ -158,15 +173,44 @@ static int cm32181_read_als_it(struct cm32181_chip *chip, int *val2)
 /**
  * cm32181_write_als_it() - Write sensor integration time
  * @chip:	pointer of struct cm32181_chip.
- * @val:	integration time by millisecond.
+ * @val:	integration time in second.
+ * @val2:	integration time in microsecond.
  *
  * Convert integration time (ms) to sensor value.
  *
  * Return: i2c_smbus_write_word_data command return value.
  */
-static int cm32181_write_als_it(struct cm32181_chip *chip, int val)
+static int cm32181_write_als_it(struct cm32181_chip *chip, int val, int val2)
 {
 	struct i2c_client *client = chip->client;
+	u16 als_it, cmd;
+	int i;
+	s32 ret;
+
+	for (i = 0; i < ARRAY_SIZE(cm32181_als_it_scales); i++) {
+		if (val == cm32181_als_it_scales[i].val &&
+			val2 == cm32181_als_it_scales[i].val2) {
+
+			als_it = cm32181_als_it_scales[i].it;
+			als_it <<= CM32181_CMD_ALS_IT_SHIFT;
+
+			cmd = chip->conf_regs[CM32181_REG_ADDR_CMD];
+			cmd &= ~CM32181_CMD_ALS_IT_MASK;
+			cmd |= als_it;
+			ret = i2c_smbus_write_word_data(client,
+						CM32181_REG_ADDR_CMD,
+						cmd);
+			if (ret < 0)
+				return ret;
+
+			chip->conf_regs[CM32181_REG_ADDR_CMD] = cmd;
+			return 0;
+		}
+	}
+	return -EINVAL;
+
+/*
+	struct i2c_client *client = chip->client;
 	u16 als_it;
 	int ret, i, n;
 
@@ -190,6 +234,7 @@ static int cm32181_write_als_it(struct cm32181_chip *chip, int val)
 	mutex_unlock(&chip->lock);
 
 	return ret;
+*/
 }
 
 /**
@@ -204,26 +249,29 @@ static int cm32181_write_als_it(struct cm32181_chip *chip, int val)
 static int cm32181_get_lux(struct cm32181_chip *chip)
 {
 	struct i2c_client *client = chip->client;
+	struct cm32181_als_info *als_info = chip->als_info;
 	int ret;
+	int val, val2;
 	int als_it;
-	unsigned long lux;
+	u64 lux;
 
-	ret = cm32181_read_als_it(chip, &als_it);
+	ret = cm32181_read_als_it(chip, &val, &val2);
 	if (ret < 0)
 		return -EINVAL;
+	als_it = val * 1000000 + val2;
 
-	lux = CM32181_MLUX_PER_BIT;
-	lux *= CM32181_MLUX_PER_BIT_BASE_IT;
-	lux /= als_it;
+	lux = (__force u64)als_info->mlux_per_bit;
+	lux *= als_info->mlux_per_bit_base_it;
+	lux = div_u64(lux, als_it);
 
 	ret = i2c_smbus_read_word_data(client, CM32181_REG_ADDR_ALS);
 	if (ret < 0)
 		return ret;
 
 	lux *= ret;
-	lux *= chip->als_info->calibscale;
-	lux /= CM32181_CALIBSCALE_RESOLUTION;
-	lux /= MLUX_PER_LUX;
+	lux *= als_info->calibscale;
+	lux = div_u64(lux, CM32181_CALIBSCALE_RESOLUTION);
+	lux = div_u64(lux, CM32181_MLUX_PER_LUX);
 
 	if (lux > 0xFFFF)
 		lux = 0xFFFF;
@@ -250,7 +298,7 @@ static int cm32181_read_raw(struct iio_dev *indio_dev,
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_INT_TIME:
 		*val = 0;
-		ret = cm32181_read_als_it(chip, val2);
+		ret = cm32181_read_als_it(chip, val, val2);
 		return ret;
 	}
 
@@ -269,7 +317,7 @@ static int cm32181_write_raw(struct iio_dev *indio_dev,
 		chip->als_info->calibscale = val;
 		return val;
 	case IIO_CHAN_INFO_INT_TIME:
-		ret = cm32181_write_als_it(chip, val2);
+		ret = cm32181_write_als_it(chip, val, val2);
 		return ret;
 	}
 
@@ -289,12 +337,21 @@ static int cm32181_write_raw(struct iio_dev *indio_dev,
 static ssize_t cm32181_get_it_available(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
+	int i, len;
+
+	for (i = 0, len = 0; i < ARRAY_SIZE(cm32181_als_it_scales); i++)
+		len += scnprintf(buf + len, PAGE_SIZE - len, "%u.%06u ",
+			cm32181_als_it_scales[i].val,
+			cm32181_als_it_scales[i].val2);
+	return len + scnprintf(buf + len, PAGE_SIZE - len, "\n");
+/*
 	int i, n, len;
 
 	n = ARRAY_SIZE(als_it_value);
 	for (i = 0, len = 0; i < n; i++)
 		len += sprintf(buf + len, "0.%06u ", als_it_value[i]);
 	return len + sprintf(buf + len, "\n");
+*/
 }
 
 static const struct iio_chan_spec cm32181_channels[] = {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 5/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Added Device Tree support.
  2015-05-22  0:30 ` Kevin Tsai
@ 2015-05-22  0:30   ` Kevin Tsai
  -1 siblings, 0 replies; 20+ messages in thread
From: Kevin Tsai @ 2015-05-22  0:30 UTC (permalink / raw)
  To: Kevin Tsai, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald, Andrew Morton, Greg KH, David S. Miller,
	Mauro Carvalho Chehab, Arnd Bergmann, Joe Perches, Jingoo Han,
	Daniel Baluta, Roberta Dobrescu, Kuppuswamy Sathyanarayanan
  Cc: devicetree, linux-kernel, linux-iio

Signed-off-by: Kevin Tsai <ktsai@capellamicro.com>
---
Added Device Tree support.

 .../devicetree/bindings/iio/light/cm32181.txt      | 33 +++++++++++
 MAINTAINERS                                        | 13 +++--
 drivers/iio/light/cm32181.c                        | 66 ++++++++++------------
 3 files changed, 71 insertions(+), 41 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/iio/light/cm32181.txt

diff --git a/Documentation/devicetree/bindings/iio/light/cm32181.txt b/Documentation/devicetree/bindings/iio/light/cm32181.txt
new file mode 100644
index 0000000..b81a3e3
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/light/cm32181.txt
@@ -0,0 +1,33 @@
+* Vishay Capella CM32181 Ambient Light sensor
+
+Required properties:
+- compatible: must be "capella,cm32181"
+- reg: the I2C address of the device
+
+Optional properties:
+- capella,hw_id: hardware device id.
+- capella,reg_cmd: command register initialization.
+- capella,reg_als_wh: high threshold register initialization.
+- capella,reg_als_wl: low threshold register initialization.
+- capella,calibscale: calibrated factor with 10^-5 notation.
+- capella,hw_id: hardware device id.
+- capella,mlux_per_bit: millilux per bit under the default IT.
+- capella,thd_percent: threshold percentage change to trigger.
+
+Example:
+
+cm32181@10 {
+	compatible = "capella,cm32181";
+	reg = <0x10>;
+	interrupt-parent = <&gpio1>;
+	interrupts = <17 0>;
+
+	capella,hw_id = <0x81>;
+	capella,reg_cmd = <0x04>;
+	capella,reg_als_wh = <0xFFFF>;
+	capella,reg_als_wl = <0x0000>;
+	capella,calibscale = <10000>;
+	capella,mlux_per_bit = <5>;
+	capella,thd_percent = <5>;
+};
+
diff --git a/MAINTAINERS b/MAINTAINERS
index f8e0afb..3af7eda 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2431,12 +2431,6 @@ F:	security/capability.c
 F:	security/commoncap.c
 F:	kernel/capability.c
 
-CAPELLA MICROSYSTEMS LIGHT SENSOR DRIVER
-M:	Kevin Tsai <ktsai@capellamicro.com>
-S:	Maintained
-F:	drivers/iio/light/cm*
-F:	Documentation/devicetree/bindings/i2c/trivial-devices.txt
-
 CC2520 IEEE-802.15.4 RADIO DRIVER
 M:	Varka Bhadram <varkabhadram@gmail.com>
 L:	linux-wpan@vger.kernel.org
@@ -10610,6 +10604,13 @@ L:	netdev@vger.kernel.org
 S:	Maintained
 F:	drivers/net/ethernet/via/via-velocity.*
 
+VISHAY CAPELLA LIGHT SENSOR DRIVER
+M:	Kevin Tsai <ktsai@capellamicro.com>
+S:	Maintained
+F:	drivers/iio/light/cm*
+F:	Documentation/devicetree/bindings/i2c/trivial-devices.txt
+F:	Documentation/devicetree/bindings/iio/light/cm*
+
 VIVID VIRTUAL VIDEO DRIVER
 M:	Hans Verkuil <hverkuil@xs4all.nl>
 L:	linux-media@vger.kernel.org
diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c
index 54bf0cb..b7abd46 100644
--- a/drivers/iio/light/cm32181.c
+++ b/drivers/iio/light/cm32181.c
@@ -51,6 +51,7 @@
 #define CM32181_HW_ID			0x81
 #define CM32181_MLUX_PER_BIT		5	/* ALS_SM=01 IT=800ms */
 #define CM32181_MLUX_PER_BIT_BASE_IT	800000	/* Based on IT=800ms */
+#define CM32181_THD_PERCENT		5	/* 0 for polling mode */
 #define	CM32181_CALIBSCALE_DEFAULT	1000
 #define CM32181_CALIBSCALE_RESOLUTION	1000
 #define CM32181_MLUX_PER_LUX		1000
@@ -80,6 +81,7 @@ struct cm32181_als_info {
 	int calibscale;
 	int mlux_per_bit;
 	int mlux_per_bit_base_it;
+	int thd_percent;
 };
 
 static struct cm32181_als_info cm32181_als_info_default = {
@@ -90,6 +92,7 @@ static struct cm32181_als_info cm32181_als_info_default = {
 	.calibscale = CM32181_CALIBSCALE_DEFAULT,
 	.mlux_per_bit = CM32181_MLUX_PER_BIT,
 	.mlux_per_bit_base_it = CM32181_MLUX_PER_BIT_BASE_IT,
+	.thd_percent = CM32181_THD_PERCENT,
 };
 
 struct cm32181_chip {
@@ -99,6 +102,30 @@ struct cm32181_chip {
 	u16 conf_regs[CM32181_CONF_REG_NUM];
 };
 
+#ifdef CONFIG_OF
+void cm32181_parse_dt(struct cm32181_chip *chip)
+{
+	struct device_node *dn = chip->client->dev.of_node;
+	struct cm32181_als_info *als_info = chip->als_info;
+	u32 temp_val;
+
+	if (!of_property_read_u32(dn, "capella,hw_id", &temp_val))
+		als_info->hw_id = (uint8_t)temp_val;
+	if (!of_property_read_u32(dn, "capella,reg_cmd", &temp_val))
+		als_info->reg_cmd = (uint16_t)temp_val;
+	if (!of_property_read_u32(dn, "capella,reg_als_wh", &temp_val))
+		als_info->reg_als_wh = (uint16_t)temp_val;
+	if (!of_property_read_u32(dn, "capella,reg_als_wl", &temp_val))
+		als_info->reg_als_wl = (uint16_t)temp_val;
+	if (!of_property_read_u32(dn, "capella,calibscale", &temp_val))
+		als_info->calibscale = (int)temp_val;
+	if (!of_property_read_u32(dn, "capella,mlux_per_bit", &temp_val))
+		als_info->mlux_per_bit = (int)temp_val;
+	if (!of_property_read_u32(dn, "capella,thd_percent", &temp_val))
+		als_info->thd_percent = (int)temp_val;
+}
+#endif
+
 /**
  * cm32181_reg_init() - Initialize CM32181 registers
  * @chip:	pointer of struct cm32181_chip
@@ -116,6 +143,10 @@ static int cm32181_reg_init(struct cm32181_chip *chip)
 
 	chip->als_info = &cm32181_als_info_default;
 	als_info = chip->als_info;
+#ifdef CONFIG_OF
+	if (client->dev.of_node)
+		cm32181_parse_dt(chip);
+#endif
 
 	ret = i2c_smbus_read_word_data(client, CM32181_REG_ADDR_ID);
 	if (ret < 0)
@@ -208,33 +239,6 @@ static int cm32181_write_als_it(struct cm32181_chip *chip, int val, int val2)
 		}
 	}
 	return -EINVAL;
-
-/*
-	struct i2c_client *client = chip->client;
-	u16 als_it;
-	int ret, i, n;
-
-	n = ARRAY_SIZE(als_it_value);
-	for (i = 0; i < n; i++)
-		if (val <= als_it_value[i])
-			break;
-	if (i >= n)
-		i = n - 1;
-
-	als_it = als_it_bits[i];
-	als_it <<= CM32181_CMD_ALS_IT_SHIFT;
-
-	mutex_lock(&chip->lock);
-	chip->conf_regs[CM32181_REG_ADDR_CMD] &=
-		~CM32181_CMD_ALS_IT_MASK;
-	chip->conf_regs[CM32181_REG_ADDR_CMD] |=
-		als_it;
-	ret = i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
-			chip->conf_regs[CM32181_REG_ADDR_CMD]);
-	mutex_unlock(&chip->lock);
-
-	return ret;
-*/
 }
 
 /**
@@ -344,14 +348,6 @@ static ssize_t cm32181_get_it_available(struct device *dev,
 			cm32181_als_it_scales[i].val,
 			cm32181_als_it_scales[i].val2);
 	return len + scnprintf(buf + len, PAGE_SIZE - len, "\n");
-/*
-	int i, n, len;
-
-	n = ARRAY_SIZE(als_it_value);
-	for (i = 0, len = 0; i < n; i++)
-		len += sprintf(buf + len, "0.%06u ", als_it_value[i]);
-	return len + sprintf(buf + len, "\n");
-*/
 }
 
 static const struct iio_chan_spec cm32181_channels[] = {
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 5/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Added Device Tree support.
@ 2015-05-22  0:30   ` Kevin Tsai
  0 siblings, 0 replies; 20+ messages in thread
From: Kevin Tsai @ 2015-05-22  0:30 UTC (permalink / raw)
  To: Kevin Tsai, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald, Andrew Morton, Greg KH, David S. Miller,
	Mauro Carvalho Chehab, Arnd Bergmann, Joe Perches, Jingoo Han,
	Daniel Baluta, Roberta Dobrescu, Kuppuswamy Sathyanarayanan
  Cc: devicetree, linux-kernel, linux-iio

Signed-off-by: Kevin Tsai <ktsai@capellamicro.com>
---
Added Device Tree support.

 .../devicetree/bindings/iio/light/cm32181.txt      | 33 +++++++++++
 MAINTAINERS                                        | 13 +++--
 drivers/iio/light/cm32181.c                        | 66 ++++++++++------------
 3 files changed, 71 insertions(+), 41 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/iio/light/cm32181.txt

diff --git a/Documentation/devicetree/bindings/iio/light/cm32181.txt b/Documentation/devicetree/bindings/iio/light/cm32181.txt
new file mode 100644
index 0000000..b81a3e3
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/light/cm32181.txt
@@ -0,0 +1,33 @@
+* Vishay Capella CM32181 Ambient Light sensor
+
+Required properties:
+- compatible: must be "capella,cm32181"
+- reg: the I2C address of the device
+
+Optional properties:
+- capella,hw_id: hardware device id.
+- capella,reg_cmd: command register initialization.
+- capella,reg_als_wh: high threshold register initialization.
+- capella,reg_als_wl: low threshold register initialization.
+- capella,calibscale: calibrated factor with 10^-5 notation.
+- capella,hw_id: hardware device id.
+- capella,mlux_per_bit: millilux per bit under the default IT.
+- capella,thd_percent: threshold percentage change to trigger.
+
+Example:
+
+cm32181@10 {
+	compatible = "capella,cm32181";
+	reg = <0x10>;
+	interrupt-parent = <&gpio1>;
+	interrupts = <17 0>;
+
+	capella,hw_id = <0x81>;
+	capella,reg_cmd = <0x04>;
+	capella,reg_als_wh = <0xFFFF>;
+	capella,reg_als_wl = <0x0000>;
+	capella,calibscale = <10000>;
+	capella,mlux_per_bit = <5>;
+	capella,thd_percent = <5>;
+};
+
diff --git a/MAINTAINERS b/MAINTAINERS
index f8e0afb..3af7eda 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2431,12 +2431,6 @@ F:	security/capability.c
 F:	security/commoncap.c
 F:	kernel/capability.c
 
-CAPELLA MICROSYSTEMS LIGHT SENSOR DRIVER
-M:	Kevin Tsai <ktsai@capellamicro.com>
-S:	Maintained
-F:	drivers/iio/light/cm*
-F:	Documentation/devicetree/bindings/i2c/trivial-devices.txt
-
 CC2520 IEEE-802.15.4 RADIO DRIVER
 M:	Varka Bhadram <varkabhadram@gmail.com>
 L:	linux-wpan@vger.kernel.org
@@ -10610,6 +10604,13 @@ L:	netdev@vger.kernel.org
 S:	Maintained
 F:	drivers/net/ethernet/via/via-velocity.*
 
+VISHAY CAPELLA LIGHT SENSOR DRIVER
+M:	Kevin Tsai <ktsai@capellamicro.com>
+S:	Maintained
+F:	drivers/iio/light/cm*
+F:	Documentation/devicetree/bindings/i2c/trivial-devices.txt
+F:	Documentation/devicetree/bindings/iio/light/cm*
+
 VIVID VIRTUAL VIDEO DRIVER
 M:	Hans Verkuil <hverkuil@xs4all.nl>
 L:	linux-media@vger.kernel.org
diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c
index 54bf0cb..b7abd46 100644
--- a/drivers/iio/light/cm32181.c
+++ b/drivers/iio/light/cm32181.c
@@ -51,6 +51,7 @@
 #define CM32181_HW_ID			0x81
 #define CM32181_MLUX_PER_BIT		5	/* ALS_SM=01 IT=800ms */
 #define CM32181_MLUX_PER_BIT_BASE_IT	800000	/* Based on IT=800ms */
+#define CM32181_THD_PERCENT		5	/* 0 for polling mode */
 #define	CM32181_CALIBSCALE_DEFAULT	1000
 #define CM32181_CALIBSCALE_RESOLUTION	1000
 #define CM32181_MLUX_PER_LUX		1000
@@ -80,6 +81,7 @@ struct cm32181_als_info {
 	int calibscale;
 	int mlux_per_bit;
 	int mlux_per_bit_base_it;
+	int thd_percent;
 };
 
 static struct cm32181_als_info cm32181_als_info_default = {
@@ -90,6 +92,7 @@ static struct cm32181_als_info cm32181_als_info_default = {
 	.calibscale = CM32181_CALIBSCALE_DEFAULT,
 	.mlux_per_bit = CM32181_MLUX_PER_BIT,
 	.mlux_per_bit_base_it = CM32181_MLUX_PER_BIT_BASE_IT,
+	.thd_percent = CM32181_THD_PERCENT,
 };
 
 struct cm32181_chip {
@@ -99,6 +102,30 @@ struct cm32181_chip {
 	u16 conf_regs[CM32181_CONF_REG_NUM];
 };
 
+#ifdef CONFIG_OF
+void cm32181_parse_dt(struct cm32181_chip *chip)
+{
+	struct device_node *dn = chip->client->dev.of_node;
+	struct cm32181_als_info *als_info = chip->als_info;
+	u32 temp_val;
+
+	if (!of_property_read_u32(dn, "capella,hw_id", &temp_val))
+		als_info->hw_id = (uint8_t)temp_val;
+	if (!of_property_read_u32(dn, "capella,reg_cmd", &temp_val))
+		als_info->reg_cmd = (uint16_t)temp_val;
+	if (!of_property_read_u32(dn, "capella,reg_als_wh", &temp_val))
+		als_info->reg_als_wh = (uint16_t)temp_val;
+	if (!of_property_read_u32(dn, "capella,reg_als_wl", &temp_val))
+		als_info->reg_als_wl = (uint16_t)temp_val;
+	if (!of_property_read_u32(dn, "capella,calibscale", &temp_val))
+		als_info->calibscale = (int)temp_val;
+	if (!of_property_read_u32(dn, "capella,mlux_per_bit", &temp_val))
+		als_info->mlux_per_bit = (int)temp_val;
+	if (!of_property_read_u32(dn, "capella,thd_percent", &temp_val))
+		als_info->thd_percent = (int)temp_val;
+}
+#endif
+
 /**
  * cm32181_reg_init() - Initialize CM32181 registers
  * @chip:	pointer of struct cm32181_chip
@@ -116,6 +143,10 @@ static int cm32181_reg_init(struct cm32181_chip *chip)
 
 	chip->als_info = &cm32181_als_info_default;
 	als_info = chip->als_info;
+#ifdef CONFIG_OF
+	if (client->dev.of_node)
+		cm32181_parse_dt(chip);
+#endif
 
 	ret = i2c_smbus_read_word_data(client, CM32181_REG_ADDR_ID);
 	if (ret < 0)
@@ -208,33 +239,6 @@ static int cm32181_write_als_it(struct cm32181_chip *chip, int val, int val2)
 		}
 	}
 	return -EINVAL;
-
-/*
-	struct i2c_client *client = chip->client;
-	u16 als_it;
-	int ret, i, n;
-
-	n = ARRAY_SIZE(als_it_value);
-	for (i = 0; i < n; i++)
-		if (val <= als_it_value[i])
-			break;
-	if (i >= n)
-		i = n - 1;
-
-	als_it = als_it_bits[i];
-	als_it <<= CM32181_CMD_ALS_IT_SHIFT;
-
-	mutex_lock(&chip->lock);
-	chip->conf_regs[CM32181_REG_ADDR_CMD] &=
-		~CM32181_CMD_ALS_IT_MASK;
-	chip->conf_regs[CM32181_REG_ADDR_CMD] |=
-		als_it;
-	ret = i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
-			chip->conf_regs[CM32181_REG_ADDR_CMD]);
-	mutex_unlock(&chip->lock);
-
-	return ret;
-*/
 }
 
 /**
@@ -344,14 +348,6 @@ static ssize_t cm32181_get_it_available(struct device *dev,
 			cm32181_als_it_scales[i].val,
 			cm32181_als_it_scales[i].val2);
 	return len + scnprintf(buf + len, PAGE_SIZE - len, "\n");
-/*
-	int i, n, len;
-
-	n = ARRAY_SIZE(als_it_value);
-	for (i = 0, len = 0; i < n; i++)
-		len += sprintf(buf + len, "0.%06u ", als_it_value[i]);
-	return len + sprintf(buf + len, "\n");
-*/
 }
 
 static const struct iio_chan_spec cm32181_channels[] = {
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 6/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Added Interrupt support.
  2015-05-22  0:30 ` Kevin Tsai
@ 2015-05-22  0:30   ` Kevin Tsai
  -1 siblings, 0 replies; 20+ messages in thread
From: Kevin Tsai @ 2015-05-22  0:30 UTC (permalink / raw)
  To: Kevin Tsai, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald, Andrew Morton, Greg KH, David S. Miller,
	Mauro Carvalho Chehab, Arnd Bergmann, Joe Perches, Jingoo Han,
	Daniel Baluta, Roberta Dobrescu, Kuppuswamy Sathyanarayanan
  Cc: devicetree, linux-kernel, linux-iio

Signed-off-by: Kevin Tsai <ktsai@capellamicro.com>
---
Added Interrupt support.

 drivers/iio/light/cm32181.c | 156 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 153 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c
index b7abd46..1ae32a0 100644
--- a/drivers/iio/light/cm32181.c
+++ b/drivers/iio/light/cm32181.c
@@ -47,6 +47,10 @@
 /* ALS_WL register */
 #define CM32181_ALS_WL_DEFAULT		0x0000
 
+/* STATUS register */
+#define CM32181_STATUS_ALS_IF_L		BIT(15)
+#define CM32181_STATUS_ALS_IF_H		BIT(14)
+
 /* Software parameters */
 #define CM32181_HW_ID			0x81
 #define CM32181_MLUX_PER_BIT		5	/* ALS_SM=01 IT=800ms */
@@ -122,7 +126,8 @@ void cm32181_parse_dt(struct cm32181_chip *chip)
 	if (!of_property_read_u32(dn, "capella,mlux_per_bit", &temp_val))
 		als_info->mlux_per_bit = (int)temp_val;
 	if (!of_property_read_u32(dn, "capella,thd_percent", &temp_val))
-		als_info->thd_percent = (int)temp_val;
+		if (((int)temp_val >= 0) && ((int)temp_val < 100))
+			als_info->thd_percent = (int)temp_val;
 }
 #endif
 
@@ -173,6 +178,63 @@ static int cm32181_reg_init(struct cm32181_chip *chip)
 }
 
 /**
+ * cm32181_interrupt() - enable/disable interrupt
+ * @chip:       pointer of struct cm32181_chip
+ * @ int_en:	truen for enable; false for disable
+ *
+ * Enable/disable interrupt mode
+ *
+ * Return: 0 for success; otherwise for error code.
+ */
+static int cm32181_interrupt(struct cm32181_chip *cm32181, bool int_en)
+{
+	int ret;
+
+	mutex_lock(&cm32181->lock);
+	if (int_en)
+		cm32181->conf_regs[CM32181_REG_ADDR_CMD] |=
+			CM32181_CMD_ALS_INT_EN;
+	else
+		cm32181->conf_regs[CM32181_REG_ADDR_CMD] &=
+			~CM32181_CMD_ALS_INT_EN;
+
+	ret = i2c_smbus_write_word_data(cm32181->client,
+			CM32181_REG_ADDR_CMD,
+			cm32181->conf_regs[CM32181_REG_ADDR_CMD]);
+	mutex_unlock(&cm32181->lock);
+	return ret;
+}
+
+static irqreturn_t cm32181_irq_handler(int irq, void *data)
+{
+	struct iio_dev *indio_dev = data;
+	struct cm32181_chip *cm32181 = iio_priv(indio_dev);
+	struct i2c_client *client = cm32181->client;
+	int ret;
+	u64 ev_code;
+
+	ret = i2c_smbus_read_word_data(cm32181->client,
+			CM32181_REG_ADDR_STATUS);
+	if (ret < 0) {
+		dev_err(&client->dev,
+			"%s: Data read failed: %d\n", __func__, ret);
+		return IRQ_NONE;
+	}
+
+	if (!(ret & (CM32181_STATUS_ALS_IF_H | CM32181_STATUS_ALS_IF_L)))
+		return IRQ_NONE;
+
+	ev_code = IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
+				0,
+				IIO_EV_TYPE_THRESH,
+				IIO_EV_DIR_EITHER);
+
+	iio_push_event(indio_dev, ev_code, iio_get_time_ns());
+
+	return IRQ_HANDLED;
+}
+
+/**
  * cm32181_read_als_it() - Get sensor integration time
  * @chip:	pointer of struct cm32181_chip
  * @val:	pointer of int to load the integration (sec)
@@ -242,6 +304,51 @@ static int cm32181_write_als_it(struct cm32181_chip *chip, int val, int val2)
 }
 
 /**
+ * cm32181_ials_read() - read ALS raw data
+ * @chip:       pointer of struct cm32181_chip
+ *
+ * Read the ALS raw data and update the interrupt threshold windows.
+ *
+ * Return: Positive value is ALS raw data, otherwise is error code.
+ */
+static int cm32181_als_read(struct cm32181_chip *chip)
+{
+	struct i2c_client *client = chip->client;
+	struct cm32181_als_info *als_info = chip->als_info;
+	u16 als, wh, wl, delta;
+	int ret;
+
+	ret = i2c_smbus_read_word_data(client, CM32181_REG_ADDR_ALS);
+	if (ret < 0)
+		return ret;
+
+	als = (u16)ret;
+
+	if (als_info->thd_percent) {
+		delta = als * als_info->thd_percent / 100;
+		if (delta < 3)
+			delta = 3;
+		wh = (als + delta > 0xFFFF) ? 0xFFFF : (als + delta);
+		wl = (als < delta) ? 0 : (als - delta);
+
+		ret = i2c_smbus_write_word_data(client,
+			CM32181_REG_ADDR_ALS_WH, wh);
+		if (ret < 0)
+			return ret;
+		chip->conf_regs[CM32181_REG_ADDR_ALS_WH] = wh;
+
+		ret = i2c_smbus_write_word_data(client,
+			CM32181_REG_ADDR_ALS_WL, wl);
+		if (ret < 0)
+			return ret;
+		chip->conf_regs[CM32181_REG_ADDR_ALS_WL] = wl;
+		ret = als;
+	}
+
+	return ret;
+}
+
+/**
  * cm32181_get_lux() - report current lux value
  * @chip:	pointer of struct cm32181_chip
  *
@@ -252,7 +359,6 @@ static int cm32181_write_als_it(struct cm32181_chip *chip, int val, int val2)
  */
 static int cm32181_get_lux(struct cm32181_chip *chip)
 {
-	struct i2c_client *client = chip->client;
 	struct cm32181_als_info *als_info = chip->als_info;
 	int ret;
 	int val, val2;
@@ -268,7 +374,7 @@ static int cm32181_get_lux(struct cm32181_chip *chip)
 	lux *= als_info->mlux_per_bit_base_it;
 	lux = div_u64(lux, als_it);
 
-	ret = i2c_smbus_read_word_data(client, CM32181_REG_ADDR_ALS);
+	ret = cm32181_als_read(chip);
 	if (ret < 0)
 		return ret;
 
@@ -350,6 +456,15 @@ static ssize_t cm32181_get_it_available(struct device *dev,
 	return len + scnprintf(buf + len, PAGE_SIZE - len, "\n");
 }
 
+static const struct iio_event_spec cm32181_event_spec[] = {
+	{
+		.type = IIO_EV_TYPE_THRESH,
+		.dir = IIO_EV_DIR_EITHER,
+		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
+				BIT(IIO_EV_INFO_ENABLE),
+	}
+};
+
 static const struct iio_chan_spec cm32181_channels[] = {
 	{
 		.type = IIO_LIGHT,
@@ -357,6 +472,8 @@ static const struct iio_chan_spec cm32181_channels[] = {
 			BIT(IIO_CHAN_INFO_PROCESSED) |
 			BIT(IIO_CHAN_INFO_CALIBSCALE) |
 			BIT(IIO_CHAN_INFO_INT_TIME),
+		.event_spec = cm32181_event_spec,
+		.num_event_specs = ARRAY_SIZE(cm32181_event_spec),
 	}
 };
 
@@ -383,6 +500,7 @@ static int cm32181_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
 	struct cm32181_chip *chip;
+	struct cm32181_als_info *als_info;
 	struct iio_dev *indio_dev;
 	int ret;
 
@@ -412,11 +530,35 @@ static int cm32181_probe(struct i2c_client *client,
 		return ret;
 	}
 
+	als_info = chip->als_info;
+	if (als_info->thd_percent && client->irq) {
+		ret = request_threaded_irq(client->irq, NULL,
+					cm32181_irq_handler,
+					IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+					indio_dev->name, indio_dev);
+		if (ret < 0) {
+			dev_err(&client->dev, "%s: request irq failed\n",
+				__func__);
+			return ret;
+		}
+
+		ret = cm32181_interrupt(chip, true);
+		if (ret) {
+			als_info->thd_percent = 0;
+			dev_err(&client->dev,
+				"%s: failed to enable interrupt\n", __func__);
+		}
+	} else {
+		als_info->thd_percent = 0;	/* Polling Mode */
+	}
+
 	ret = devm_iio_device_register(&client->dev, indio_dev);
 	if (ret) {
 		dev_err(&client->dev,
 			"%s: regist device failed\n",
 			__func__);
+		if (als_info->thd_percent)
+			free_irq(client->irq, indio_dev);
 		return ret;
 	}
 
@@ -425,9 +567,17 @@ static int cm32181_probe(struct i2c_client *client,
 
 static int cm32181_remove(struct i2c_client *client)
 {
+	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+	struct cm32181_chip *chip = iio_priv(indio_dev);
+	struct cm32181_als_info *als_info = chip->als_info;
+
+	cm32181_interrupt(chip, false);
 	i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
 		CM32181_CMD_ALS_DISABLE);
 
+	if (als_info->thd_percent)
+		free_irq(client->irq, indio_dev);
+
 	return 0;
 }
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 6/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Added Interrupt support.
@ 2015-05-22  0:30   ` Kevin Tsai
  0 siblings, 0 replies; 20+ messages in thread
From: Kevin Tsai @ 2015-05-22  0:30 UTC (permalink / raw)
  To: Kevin Tsai, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald, Andrew Morton, Greg KH, David S. Miller,
	Mauro Carvalho Chehab, Arnd Bergmann, Joe Perches, Jingoo Han,
	Daniel Baluta, Roberta Dobrescu, Kuppuswamy Sathyanarayanan
  Cc: devicetree, linux-kernel, linux-iio

Signed-off-by: Kevin Tsai <ktsai@capellamicro.com>
---
Added Interrupt support.

 drivers/iio/light/cm32181.c | 156 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 153 insertions(+), 3 deletions(-)

diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c
index b7abd46..1ae32a0 100644
--- a/drivers/iio/light/cm32181.c
+++ b/drivers/iio/light/cm32181.c
@@ -47,6 +47,10 @@
 /* ALS_WL register */
 #define CM32181_ALS_WL_DEFAULT		0x0000
 
+/* STATUS register */
+#define CM32181_STATUS_ALS_IF_L		BIT(15)
+#define CM32181_STATUS_ALS_IF_H		BIT(14)
+
 /* Software parameters */
 #define CM32181_HW_ID			0x81
 #define CM32181_MLUX_PER_BIT		5	/* ALS_SM=01 IT=800ms */
@@ -122,7 +126,8 @@ void cm32181_parse_dt(struct cm32181_chip *chip)
 	if (!of_property_read_u32(dn, "capella,mlux_per_bit", &temp_val))
 		als_info->mlux_per_bit = (int)temp_val;
 	if (!of_property_read_u32(dn, "capella,thd_percent", &temp_val))
-		als_info->thd_percent = (int)temp_val;
+		if (((int)temp_val >= 0) && ((int)temp_val < 100))
+			als_info->thd_percent = (int)temp_val;
 }
 #endif
 
@@ -173,6 +178,63 @@ static int cm32181_reg_init(struct cm32181_chip *chip)
 }
 
 /**
+ * cm32181_interrupt() - enable/disable interrupt
+ * @chip:       pointer of struct cm32181_chip
+ * @ int_en:	truen for enable; false for disable
+ *
+ * Enable/disable interrupt mode
+ *
+ * Return: 0 for success; otherwise for error code.
+ */
+static int cm32181_interrupt(struct cm32181_chip *cm32181, bool int_en)
+{
+	int ret;
+
+	mutex_lock(&cm32181->lock);
+	if (int_en)
+		cm32181->conf_regs[CM32181_REG_ADDR_CMD] |=
+			CM32181_CMD_ALS_INT_EN;
+	else
+		cm32181->conf_regs[CM32181_REG_ADDR_CMD] &=
+			~CM32181_CMD_ALS_INT_EN;
+
+	ret = i2c_smbus_write_word_data(cm32181->client,
+			CM32181_REG_ADDR_CMD,
+			cm32181->conf_regs[CM32181_REG_ADDR_CMD]);
+	mutex_unlock(&cm32181->lock);
+	return ret;
+}
+
+static irqreturn_t cm32181_irq_handler(int irq, void *data)
+{
+	struct iio_dev *indio_dev = data;
+	struct cm32181_chip *cm32181 = iio_priv(indio_dev);
+	struct i2c_client *client = cm32181->client;
+	int ret;
+	u64 ev_code;
+
+	ret = i2c_smbus_read_word_data(cm32181->client,
+			CM32181_REG_ADDR_STATUS);
+	if (ret < 0) {
+		dev_err(&client->dev,
+			"%s: Data read failed: %d\n", __func__, ret);
+		return IRQ_NONE;
+	}
+
+	if (!(ret & (CM32181_STATUS_ALS_IF_H | CM32181_STATUS_ALS_IF_L)))
+		return IRQ_NONE;
+
+	ev_code = IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
+				0,
+				IIO_EV_TYPE_THRESH,
+				IIO_EV_DIR_EITHER);
+
+	iio_push_event(indio_dev, ev_code, iio_get_time_ns());
+
+	return IRQ_HANDLED;
+}
+
+/**
  * cm32181_read_als_it() - Get sensor integration time
  * @chip:	pointer of struct cm32181_chip
  * @val:	pointer of int to load the integration (sec)
@@ -242,6 +304,51 @@ static int cm32181_write_als_it(struct cm32181_chip *chip, int val, int val2)
 }
 
 /**
+ * cm32181_ials_read() - read ALS raw data
+ * @chip:       pointer of struct cm32181_chip
+ *
+ * Read the ALS raw data and update the interrupt threshold windows.
+ *
+ * Return: Positive value is ALS raw data, otherwise is error code.
+ */
+static int cm32181_als_read(struct cm32181_chip *chip)
+{
+	struct i2c_client *client = chip->client;
+	struct cm32181_als_info *als_info = chip->als_info;
+	u16 als, wh, wl, delta;
+	int ret;
+
+	ret = i2c_smbus_read_word_data(client, CM32181_REG_ADDR_ALS);
+	if (ret < 0)
+		return ret;
+
+	als = (u16)ret;
+
+	if (als_info->thd_percent) {
+		delta = als * als_info->thd_percent / 100;
+		if (delta < 3)
+			delta = 3;
+		wh = (als + delta > 0xFFFF) ? 0xFFFF : (als + delta);
+		wl = (als < delta) ? 0 : (als - delta);
+
+		ret = i2c_smbus_write_word_data(client,
+			CM32181_REG_ADDR_ALS_WH, wh);
+		if (ret < 0)
+			return ret;
+		chip->conf_regs[CM32181_REG_ADDR_ALS_WH] = wh;
+
+		ret = i2c_smbus_write_word_data(client,
+			CM32181_REG_ADDR_ALS_WL, wl);
+		if (ret < 0)
+			return ret;
+		chip->conf_regs[CM32181_REG_ADDR_ALS_WL] = wl;
+		ret = als;
+	}
+
+	return ret;
+}
+
+/**
  * cm32181_get_lux() - report current lux value
  * @chip:	pointer of struct cm32181_chip
  *
@@ -252,7 +359,6 @@ static int cm32181_write_als_it(struct cm32181_chip *chip, int val, int val2)
  */
 static int cm32181_get_lux(struct cm32181_chip *chip)
 {
-	struct i2c_client *client = chip->client;
 	struct cm32181_als_info *als_info = chip->als_info;
 	int ret;
 	int val, val2;
@@ -268,7 +374,7 @@ static int cm32181_get_lux(struct cm32181_chip *chip)
 	lux *= als_info->mlux_per_bit_base_it;
 	lux = div_u64(lux, als_it);
 
-	ret = i2c_smbus_read_word_data(client, CM32181_REG_ADDR_ALS);
+	ret = cm32181_als_read(chip);
 	if (ret < 0)
 		return ret;
 
@@ -350,6 +456,15 @@ static ssize_t cm32181_get_it_available(struct device *dev,
 	return len + scnprintf(buf + len, PAGE_SIZE - len, "\n");
 }
 
+static const struct iio_event_spec cm32181_event_spec[] = {
+	{
+		.type = IIO_EV_TYPE_THRESH,
+		.dir = IIO_EV_DIR_EITHER,
+		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
+				BIT(IIO_EV_INFO_ENABLE),
+	}
+};
+
 static const struct iio_chan_spec cm32181_channels[] = {
 	{
 		.type = IIO_LIGHT,
@@ -357,6 +472,8 @@ static const struct iio_chan_spec cm32181_channels[] = {
 			BIT(IIO_CHAN_INFO_PROCESSED) |
 			BIT(IIO_CHAN_INFO_CALIBSCALE) |
 			BIT(IIO_CHAN_INFO_INT_TIME),
+		.event_spec = cm32181_event_spec,
+		.num_event_specs = ARRAY_SIZE(cm32181_event_spec),
 	}
 };
 
@@ -383,6 +500,7 @@ static int cm32181_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
 	struct cm32181_chip *chip;
+	struct cm32181_als_info *als_info;
 	struct iio_dev *indio_dev;
 	int ret;
 
@@ -412,11 +530,35 @@ static int cm32181_probe(struct i2c_client *client,
 		return ret;
 	}
 
+	als_info = chip->als_info;
+	if (als_info->thd_percent && client->irq) {
+		ret = request_threaded_irq(client->irq, NULL,
+					cm32181_irq_handler,
+					IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+					indio_dev->name, indio_dev);
+		if (ret < 0) {
+			dev_err(&client->dev, "%s: request irq failed\n",
+				__func__);
+			return ret;
+		}
+
+		ret = cm32181_interrupt(chip, true);
+		if (ret) {
+			als_info->thd_percent = 0;
+			dev_err(&client->dev,
+				"%s: failed to enable interrupt\n", __func__);
+		}
+	} else {
+		als_info->thd_percent = 0;	/* Polling Mode */
+	}
+
 	ret = devm_iio_device_register(&client->dev, indio_dev);
 	if (ret) {
 		dev_err(&client->dev,
 			"%s: regist device failed\n",
 			__func__);
+		if (als_info->thd_percent)
+			free_irq(client->irq, indio_dev);
 		return ret;
 	}
 
@@ -425,9 +567,17 @@ static int cm32181_probe(struct i2c_client *client,
 
 static int cm32181_remove(struct i2c_client *client)
 {
+	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+	struct cm32181_chip *chip = iio_priv(indio_dev);
+	struct cm32181_als_info *als_info = chip->als_info;
+
+	cm32181_interrupt(chip, false);
 	i2c_smbus_write_word_data(client, CM32181_REG_ADDR_CMD,
 		CM32181_CMD_ALS_DISABLE);
 
+	if (als_info->thd_percent)
+		free_irq(client->irq, indio_dev);
+
 	return 0;
 }
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Renamed company name. - Removed cm32181_reg. - Removed white space. - Removed unused include files. - Updated macro definitions. - Renamed cm32181_chip pointer to chip.
@ 2015-05-22  1:56   ` Greg KH
  0 siblings, 0 replies; 20+ messages in thread
From: Greg KH @ 2015-05-22  1:56 UTC (permalink / raw)
  To: Kevin Tsai
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald, Andrew Morton, David S. Miller,
	Mauro Carvalho Chehab, Arnd Bergmann, Joe Perches, Jingoo Han,
	Daniel Baluta, Roberta Dobrescu, Kuppuswamy Sathyanarayanan,
	devicetree, linux-kernel, linux-iio

On Thu, May 21, 2015 at 05:30:40PM -0700, Kevin Tsai wrote:
> Signed-off-by: Kevin Tsai <ktsai@capellamicro.com>
> ---

Your whole changelog ended up in the Subject line :(

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Renamed company name. - Removed cm32181_reg. - Removed white space. - Removed unused include files. - Updated macro definitions. - Renamed cm32181_chip pointer to chip.
@ 2015-05-22  1:56   ` Greg KH
  0 siblings, 0 replies; 20+ messages in thread
From: Greg KH @ 2015-05-22  1:56 UTC (permalink / raw)
  To: Kevin Tsai
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald, Andrew Morton, David S. Miller,
	Mauro Carvalho Chehab, Arnd Bergmann, Joe Perches, Jingoo Han,
	Daniel Baluta, Roberta Dobrescu, Kuppuswamy Sathyanarayanan,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-iio-u79uwXL29TY76Z2rM5mHXA

On Thu, May 21, 2015 at 05:30:40PM -0700, Kevin Tsai wrote:
> Signed-off-by: Kevin Tsai <ktsai-GubuWUlQtMwciDkP5Hr2oA@public.gmane.org>
> ---

Your whole changelog ended up in the Subject line :(

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Renamed company name. - Removed cm32181_reg. - Removed white space. - Removed unused include files. - Updated macro definitions. - Renamed cm32181_chip pointer to chip.
@ 2015-05-22  1:56   ` Greg KH
  0 siblings, 0 replies; 20+ messages in thread
From: Greg KH @ 2015-05-22  1:56 UTC (permalink / raw)
  To: Kevin Tsai
  Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
	Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald, Andrew Morton, David S. Miller,
	Mauro Carvalho Chehab, Arnd Bergmann, Joe Perches, Jingoo Han,
	Daniel Baluta, Roberta Dobrescu, Kuppuswamy Sathyanarayanan,
	devicetree, linux-kernel, linux-iio

On Thu, May 21, 2015 at 05:30:40PM -0700, Kevin Tsai wrote:
> Signed-off-by: Kevin Tsai <ktsai@capellamicro.com>
> ---

Your whole changelog ended up in the Subject line :(

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Renamed company name. - Removed cm32181_reg. - Removed white space. - Removed unused include files. - Updated macro definitions. - Renamed cm32181_chip pointer to chip.
@ 2015-05-22  6:57     ` Daniel Baluta
  0 siblings, 0 replies; 20+ messages in thread
From: Daniel Baluta @ 2015-05-22  6:57 UTC (permalink / raw)
  To: Greg KH
  Cc: Kevin Tsai, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald, Andrew Morton, David S. Miller,
	Mauro Carvalho Chehab, Arnd Bergmann, Joe Perches, Jingoo Han,
	Daniel Baluta, Roberta Dobrescu, Kuppuswamy Sathyanarayanan,
	devicetree, Linux Kernel Mailing List, linux-iio

On Fri, May 22, 2015 at 4:56 AM, Greg KH <gregkh@linuxfoundation.org> wrote:
> On Thu, May 21, 2015 at 05:30:40PM -0700, Kevin Tsai wrote:
>> Signed-off-by: Kevin Tsai <ktsai@capellamicro.com>
>> ---
>
> Your whole changelog ended up in the Subject line :(

Hi Kevin,

Few comments:

1) Please also add a cover letter. Use --cover-letter parameter of git
format-patch.
2) Please create a patch for each logical change. Your current 1/6
patch should be
split in several small patches:
 * 1/6 iio: light: cm32181: Update company name
 * 2/6 iio: light: cm32181: Remove unused include files
 * etc.
3) Please use specific wordings for commit subject. A subject like this:

"Updated Vishay Capella cm32181 ambient light sensor driver" doesn't say much.

thanks,
Daniel.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Renamed company name. - Removed cm32181_reg. - Removed white space. - Removed unused include files. - Updated macro definitions. - Renamed cm32181_chip pointer to chip.
@ 2015-05-22  6:57     ` Daniel Baluta
  0 siblings, 0 replies; 20+ messages in thread
From: Daniel Baluta @ 2015-05-22  6:57 UTC (permalink / raw)
  To: Greg KH
  Cc: Kevin Tsai, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald, Andrew Morton, David S. Miller,
	Mauro Carvalho Chehab, Arnd Bergmann, Joe Perches, Jingoo Han,
	Daniel Baluta, Roberta Dobrescu, Kuppuswamy Sathyanarayanan,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Linux Kernel Mailing List

On Fri, May 22, 2015 at 4:56 AM, Greg KH <gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org> wrote:
> On Thu, May 21, 2015 at 05:30:40PM -0700, Kevin Tsai wrote:
>> Signed-off-by: Kevin Tsai <ktsai-GubuWUlQtMwciDkP5Hr2oA@public.gmane.org>
>> ---
>
> Your whole changelog ended up in the Subject line :(

Hi Kevin,

Few comments:

1) Please also add a cover letter. Use --cover-letter parameter of git
format-patch.
2) Please create a patch for each logical change. Your current 1/6
patch should be
split in several small patches:
 * 1/6 iio: light: cm32181: Update company name
 * 2/6 iio: light: cm32181: Remove unused include files
 * etc.
3) Please use specific wordings for commit subject. A subject like this:

"Updated Vishay Capella cm32181 ambient light sensor driver" doesn't say much.

thanks,
Daniel.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 1/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Renamed company name. - Removed cm32181_reg. - Removed white space. - Removed unused include files. - Updated macro definitions. - Renamed cm32181_chip pointer to chip.
@ 2015-05-22  6:57     ` Daniel Baluta
  0 siblings, 0 replies; 20+ messages in thread
From: Daniel Baluta @ 2015-05-22  6:57 UTC (permalink / raw)
  To: Greg KH
  Cc: Kevin Tsai, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
	Kumar Gala, Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
	Peter Meerwald, Andrew Morton, David S. Miller,
	Mauro Carvalho Chehab, Arnd Bergmann, Joe Perches, Jingoo Han,
	Daniel Baluta, Roberta Dobrescu, Kuppuswamy Sathyanarayanan,
	devicetree, Linux Kernel Mailing List, linux-iio

On Fri, May 22, 2015 at 4:56 AM, Greg KH <gregkh@linuxfoundation.org> wrote:
> On Thu, May 21, 2015 at 05:30:40PM -0700, Kevin Tsai wrote:
>> Signed-off-by: Kevin Tsai <ktsai@capellamicro.com>
>> ---
>
> Your whole changelog ended up in the Subject line :(

Hi Kevin,

Few comments:

1) Please also add a cover letter. Use --cover-letter parameter of git
format-patch.
2) Please create a patch for each logical change. Your current 1/6
patch should be
split in several small patches:
 * 1/6 iio: light: cm32181: Update company name
 * 2/6 iio: light: cm32181: Remove unused include files
 * etc.
3) Please use specific wordings for commit subject. A subject like this:

"Updated Vishay Capella cm32181 ambient light sensor driver" doesn't say much.

thanks,
Daniel.

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2015-05-22  6:57 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-22  0:30 [PATCH 1/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Renamed company name. - Removed cm32181_reg. - Removed white space. - Removed unused include files. - Updated macro definitions. - Renamed cm32181_chip pointer to chip Kevin Tsai
2015-05-22  0:30 ` Kevin Tsai
2015-05-22  0:30 ` Kevin Tsai
2015-05-22  0:30 ` [PATCH 2/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Added cm32181_als_info structure Kevin Tsai
2015-05-22  0:30   ` Kevin Tsai
2015-05-22  0:30 ` [PATCH 3/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Added Power Management support. - Added driver remove routine Kevin Tsai
2015-05-22  0:30   ` Kevin Tsai
2015-05-22  0:30   ` Kevin Tsai
2015-05-22  0:30 ` [PATCH 4/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Replaced als_it_bits and als_it_value by cm32181_als_it_scale Kevin Tsai
2015-05-22  0:30   ` Kevin Tsai
2015-05-22  0:30 ` [PATCH 5/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Added Device Tree support Kevin Tsai
2015-05-22  0:30   ` Kevin Tsai
2015-05-22  0:30 ` [PATCH 6/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Added Interrupt support Kevin Tsai
2015-05-22  0:30   ` Kevin Tsai
2015-05-22  1:56 ` [PATCH 1/6] iio: light: Updated Vishay Capella cm32181 ambient light sensor driver. - Renamed company name. - Removed cm32181_reg. - Removed white space. - Removed unused include files. - Updated macro definitions. - Renamed cm32181_chip pointer to chip Greg KH
2015-05-22  1:56   ` Greg KH
2015-05-22  1:56   ` Greg KH
2015-05-22  6:57   ` Daniel Baluta
2015-05-22  6:57     ` Daniel Baluta
2015-05-22  6:57     ` Daniel Baluta

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.