mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Brian Masney <masneyb@onstation.org>
To: jic23@kernel.org, linux-iio@vger.kernel.org
Cc: devel@driverdev.osuosl.org, gregkh@linuxfoundation.org,
	lars@metafoo.de, pmeerw@pmeerw.net, knaack.h@gmx.de,
	linux-kernel@vger.kernel.org, Jon.Brenner@ams.com
Subject: [PATCH 7/9] staging: iio: tsl2583: fix issue with changes to calibscale and int_time not being set on the chip
Date: Thu,  3 Nov 2016 08:56:18 -0400	[thread overview]
Message-ID: <1478177780-28699-8-git-send-email-masneyb@onstation.org> (raw)
In-Reply-To: <1478177780-28699-1-git-send-email-masneyb@onstation.org>

When updating the in_illuminance_calibscale and
in_illuminance_integration_time sysfs attributes, these values were not
actually written to the chip. The chip would continue to use the old
parameters. Extracted out tsl2583_set_als_gain() and
tsl2583_set_als_time() functions that are now called when these sysfs
attributes are updated. The chip initialization now calls these these
new functions.

Rename taos_chip_on() to tsl2583_chip_init() since it is now only called
during device probing and when the power management code wakes the
device back up. tsl2583_chip_init() was refactored to use the new
functions mentioned above.

Previously, the current chip state was represented as a tristate
(working, suspended, and unknown). The unknown state was not used. The
chip state is now represented with a single boolean value (suspended).

Signed-off-by: Brian Masney <masneyb@onstation.org>
---
 drivers/staging/iio/light/tsl2583.c | 172 ++++++++++++++++--------------------
 1 file changed, 78 insertions(+), 94 deletions(-)

diff --git a/drivers/staging/iio/light/tsl2583.c b/drivers/staging/iio/light/tsl2583.c
index 7eab17f..1ff90b3 100644
--- a/drivers/staging/iio/light/tsl2583.c
+++ b/drivers/staging/iio/light/tsl2583.c
@@ -48,6 +48,8 @@
 #define TSL258X_TMR_LO			0x18
 #define TSL258X_TMR_HI			0x19
 
+#define TSL2583_INTERRUPT_DISABLED	0x00
+
 /* tsl2583 cmd reg masks */
 #define TSL258X_CMD_REG			0x80
 #define TSL258X_CMD_SPL_FN		0x60
@@ -55,6 +57,7 @@
 
 /* tsl2583 cntrl reg masks */
 #define TSL258X_CNTL_ADC_ENBL	0x02
+#define TSL258X_CNTL_PWR_OFF		0x00
 #define TSL258X_CNTL_PWR_ON		0x01
 
 /* tsl2583 status reg masks */
@@ -67,12 +70,6 @@
 #define TSL2583_CHIP_ID			0x90
 #define TSL2583_CHIP_ID_MASK		0xf0
 
-enum {
-	TSL258X_CHIP_UNKNOWN = 0,
-	TSL258X_CHIP_WORKING = 1,
-	TSL258X_CHIP_SUSPENDED = 2
-};
-
 /* Per-device data */
 struct taos_als_info {
 	u16 als_ch0;
@@ -94,19 +91,9 @@ struct tsl2583_chip {
 	struct taos_settings taos_settings;
 	int als_time_scale;
 	int als_saturation;
-	int taos_chip_status;
-	u8 taos_config[8];
+	bool suspended;
 };
 
-/*
- * Initial values for device - this values can/will be changed by driver.
- * and applications as needed.
- * These values are dynamic.
- */
-static const u8 taos_config[8] = {
-		0x00, 0xee, 0x00, 0x03, 0x00, 0xFF, 0xFF, 0x00
-}; /*	cntrl atime intC  Athl0 Athl1 Athh0 Athh1 gain */
-
 struct taos_lux {
 	unsigned int ratio;
 	unsigned int ch0;
@@ -188,13 +175,6 @@ static int taos_get_lux(struct iio_dev *indio_dev)
 	u32 ch0lux = 0;
 	u32 ch1lux = 0;
 
-	if (chip->taos_chip_status != TSL258X_CHIP_WORKING) {
-		/* device is not enabled */
-		dev_err(&chip->client->dev, "taos_get_lux device is not enabled\n");
-		ret = -EBUSY;
-		goto done;
-	}
-
 	ret = i2c_smbus_read_byte_data(chip->client, TSL258X_CMD_REG);
 	if (ret < 0) {
 		dev_err(&chip->client->dev, "taos_get_lux failed to read CMD_REG\n");
@@ -362,26 +342,10 @@ static int taos_als_calibrate(struct iio_dev *indio_dev)
 	return (int)gain_trim_val;
 }
 
-/*
- * Turn the device on.
- * Configuration must be set before calling this function.
- */
-static int taos_chip_on(struct iio_dev *indio_dev)
+static int tsl2583_set_als_time(struct tsl2583_chip *chip)
 {
-	int i;
-	int ret;
-	u8 *uP;
-	u8 utmp;
-	int als_count;
-	int als_time;
-	struct tsl2583_chip *chip = iio_priv(indio_dev);
-
-	/* and make sure we're not already on */
-	if (chip->taos_chip_status == TSL258X_CHIP_WORKING) {
-		/* if forcing a register update - turn off, then on */
-		dev_info(&chip->client->dev, "device is already enabled\n");
-		return -EINVAL;
-	}
+	int als_count, als_time, ret;
+	u8 val;
 
 	/* determine als integration register */
 	als_count = (chip->taos_settings.als_time * 100 + 135) / 270;
@@ -390,60 +354,82 @@ static int taos_chip_on(struct iio_dev *indio_dev)
 
 	/* convert back to time (encompasses overrides) */
 	als_time = (als_count * 27 + 5) / 10;
-	chip->taos_config[TSL258X_ALS_TIME] = 256 - als_count;
 
-	/* Set the gain based on taos_settings struct */
-	chip->taos_config[TSL258X_GAIN] = chip->taos_settings.als_gain;
+	val = 256 - als_count;
+	ret = i2c_smbus_write_byte_data(chip->client,
+					TSL258X_CMD_REG | TSL258X_ALS_TIME,
+					val);
+	if (ret < 0) {
+		dev_err(&chip->client->dev,
+			"%s failed to set the als time to %d\n",
+			__func__, val);
+		return ret;
+	}
 
 	/* set chip struct re scaling and saturation */
 	chip->als_saturation = als_count * 922; /* 90% of full scale */
 	chip->als_time_scale = (als_time + 25) / 50;
 
-	/* Power on the device; ADC off. */
-	chip->taos_config[TSL258X_CNTRL] = TSL258X_CNTL_PWR_ON;
+	return ret;
+}
 
-	/*
-	 * Use the following shadow copy for our delay before enabling ADC.
-	 * Write all the registers.
-	 */
-	for (i = 0, uP = chip->taos_config; i < TSL258X_REG_MAX; i++) {
-		ret = i2c_smbus_write_byte_data(chip->client,
-						TSL258X_CMD_REG + i,
-						*uP++);
-		if (ret < 0) {
-			dev_err(&chip->client->dev,
-				"taos_chip_on failed on reg %d.\n", i);
-			return ret;
-		}
-	}
+static int tsl2583_set_als_gain(struct tsl2583_chip *chip)
+{
+	int ret;
 
-	usleep_range(3000, 3500);
-	/*
-	 * NOW enable the ADC
-	 * initialize the desired mode of operation
-	 */
-	utmp = TSL258X_CNTL_PWR_ON | TSL258X_CNTL_ADC_ENBL;
 	ret = i2c_smbus_write_byte_data(chip->client,
-					TSL258X_CMD_REG | TSL258X_CNTRL,
-					utmp);
-	if (ret < 0) {
-		dev_err(&chip->client->dev, "taos_chip_on failed on 2nd CTRL reg.\n");
-		return ret;
-	}
-	chip->taos_chip_status = TSL258X_CHIP_WORKING;
+					TSL258X_CMD_REG | TSL258X_GAIN,
+					chip->taos_settings.als_gain);
+	if (ret < 0)
+		dev_err(&chip->client->dev, "%s failed to set the gain to %d\n",
+			__func__, chip->taos_settings.als_gain);
 
 	return ret;
 }
 
-static int taos_chip_off(struct iio_dev *indio_dev)
+static int tsl2583_set_power_state(struct tsl2583_chip *chip, u8 state)
 {
-	struct tsl2583_chip *chip = iio_priv(indio_dev);
+	int ret;
+
+	ret = i2c_smbus_write_byte_data(chip->client,
+					TSL258X_CMD_REG | TSL258X_CNTRL, state);
+	if (ret < 0)
+		dev_err(&chip->client->dev, "%s failed to set the power state to %d\n",
+			__func__, state);
 
-	/* turn device off */
-	chip->taos_chip_status = TSL258X_CHIP_SUSPENDED;
-	return i2c_smbus_write_byte_data(chip->client,
-					TSL258X_CMD_REG | TSL258X_CNTRL,
-					0x00);
+	return ret;
+}
+
+static int tsl2583_chip_init(struct tsl2583_chip *chip)
+{
+	int ret;
+
+	ret = tsl2583_set_power_state(chip, TSL258X_CNTL_PWR_ON);
+	if (ret < 0)
+		return ret;
+
+	ret = i2c_smbus_write_byte_data(chip->client,
+					TSL258X_CMD_REG | TSL258X_INTERRUPT,
+					TSL2583_INTERRUPT_DISABLED);
+	if (ret < 0) {
+		dev_err(&chip->client->dev, "%s failed to disable interrupts\n",
+			__func__);
+		return ret;
+	}
+
+	ret = tsl2583_set_als_time(chip);
+	if (ret < 0)
+		return ret;
+
+	ret = tsl2583_set_als_gain(chip);
+	if (ret < 0)
+		return ret;
+
+	usleep_range(3000, 3500);
+
+	/* Enable the ADC and initialize the desired mode of operation */
+	return tsl2583_set_power_state(chip, TSL258X_CNTL_PWR_ON |
+					     TSL258X_CNTL_ADC_ENBL);
 }
 
 /* Sysfs Interface Functions */
@@ -616,7 +602,7 @@ static int tsl2583_read_raw(struct iio_dev *indio_dev,
 
 	mutex_lock(&chip->als_mutex);
 
-	if (chip->taos_chip_status != TSL258X_CHIP_WORKING) {
+	if (chip->suspended) {
 		ret = -EBUSY;
 		goto read_done;
 	}
@@ -693,7 +679,7 @@ static int tsl2583_write_raw(struct iio_dev *indio_dev,
 
 	mutex_lock(&chip->als_mutex);
 
-	if (chip->taos_chip_status != TSL258X_CHIP_WORKING) {
+	if (chip->suspended) {
 		ret = -EBUSY;
 		goto write_done;
 	}
@@ -716,13 +702,14 @@ static int tsl2583_write_raw(struct iio_dev *indio_dev,
 					break;
 				}
 			}
+			ret = tsl2583_set_als_gain(chip);
 		}
 		break;
 	case IIO_CHAN_INFO_INT_TIME:
 		if (chan->type == IIO_LIGHT && !val && val2 >= 50 &&
 		    val2 <= 650 && !(val2 % 50)) {
 			chip->taos_settings.als_time = val2;
-			ret = 0;
+			ret = tsl2583_set_als_time(chip);
 		}
 		break;
 	default:
@@ -767,8 +754,7 @@ static int taos_probe(struct i2c_client *clientp,
 	i2c_set_clientdata(clientp, indio_dev);
 
 	mutex_init(&chip->als_mutex);
-	chip->taos_chip_status = TSL258X_CHIP_UNKNOWN;
-	memcpy(chip->taos_config, taos_config, sizeof(chip->taos_config));
+	chip->suspended = false;
 
 	ret = i2c_smbus_read_byte_data(clientp,
 				       TSL258X_CMD_REG | TSL258X_CHIPID);
@@ -808,7 +794,7 @@ static int taos_probe(struct i2c_client *clientp,
 	taos_defaults(chip);
 
 	/* Make sure the chip is on */
-	ret = taos_chip_on(indio_dev);
+	ret = tsl2583_chip_init(chip);
 	if (ret < 0)
 		return ret;
 
@@ -825,10 +811,8 @@ static int taos_suspend(struct device *dev)
 
 	mutex_lock(&chip->als_mutex);
 
-	if (chip->taos_chip_status == TSL258X_CHIP_WORKING) {
-		ret = taos_chip_off(indio_dev);
-		chip->taos_chip_status = TSL258X_CHIP_SUSPENDED;
-	}
+	chip->suspended = true;
+	ret = tsl2583_set_power_state(chip, TSL258X_CNTL_PWR_OFF);
 
 	mutex_unlock(&chip->als_mutex);
 	return ret;
@@ -842,8 +826,8 @@ static int taos_resume(struct device *dev)
 
 	mutex_lock(&chip->als_mutex);
 
-	if (chip->taos_chip_status == TSL258X_CHIP_SUSPENDED)
-		ret = taos_chip_on(indio_dev);
+	chip->suspended = false;
+	ret = tsl2583_chip_init(chip);
 
 	mutex_unlock(&chip->als_mutex);
 	return ret;
-- 
2.5.5

  parent reply	other threads:[~2016-11-03 12:58 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-11-03 12:56 [PATCH 0/9] staging: iio: tsl2583: i2c cleanups Brian Masney
2016-11-03 12:56 ` [PATCH 1/9] staging: iio: tsl2583: i2c_smbus_write_byte() / i2c_smbus_read_byte() migration Brian Masney
2016-11-06 11:33   ` Jonathan Cameron
2016-11-06 11:35   ` Jonathan Cameron
2016-11-03 12:56 ` [PATCH 2/9] staging: iio: tsl2583: removed unused code from device probing Brian Masney
2016-11-06 11:46   ` Jonathan Cameron
2016-11-03 12:56 ` [PATCH 3/9] staging: iio: tsl2583: fixed ordering of comments Brian Masney
2016-11-06 11:48   ` Jonathan Cameron
2016-11-03 12:56 ` [PATCH 4/9] staging: iio: tsl2583: remove redundant power off sequence in taos_chip_on() Brian Masney
2016-11-06 11:51   ` Jonathan Cameron
2016-11-03 12:56 ` [PATCH 5/9] staging: iio: tsl2583: don't shutdown chip when updating the lux table Brian Masney
2016-11-06 11:53   ` Jonathan Cameron
2016-11-03 12:56 ` [PATCH 6/9] staging: iio: tsl2583: remove redudant i2c call in taos_als_calibrate() Brian Masney
2016-11-06 11:54   ` Jonathan Cameron
2016-11-03 12:56 ` Brian Masney [this message]
2016-11-06 12:03   ` [PATCH 7/9] staging: iio: tsl2583: fix issue with changes to calibscale and int_time not being set on the chip Jonathan Cameron
2016-11-06 14:23     ` Brian Masney
2016-11-06 17:55       ` Jonathan Cameron
2016-11-03 12:56 ` [PATCH 8/9] staging: iio: tsl2583: check if chip is suspended in in_illuminance_calibrate_store Brian Masney
2016-11-06 12:04   ` Jonathan Cameron
2016-11-03 12:56 ` [PATCH 9/9] staging: iio: tsl2583: remove redundant write to the control register in taos_probe() Brian Masney
2016-11-06 12:05   ` Jonathan Cameron

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1478177780-28699-8-git-send-email-masneyb@onstation.org \
    --to=masneyb@onstation.org \
    --cc=Jon.Brenner@ams.com \
    --cc=devel@driverdev.osuosl.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=jic23@kernel.org \
    --cc=knaack.h@gmx.de \
    --cc=lars@metafoo.de \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pmeerw@pmeerw.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®