Linux-Hwmon Archive on lore.kernel.org
 help / color / Atom feed
From: Dan Robertson <dan@dlrobertson.com>
To: linux-hwmon@vger.kernel.org
Cc: Jean Delvare <jdelvare@suse.com>,
	Guenter Roeck <linux@roeck-us.net>,
	Dan Robertson <dan@dlrobertson.com>
Subject: [PATCH] hwmon: (shtc1) add support for the SHTC3 sensor
Date: Thu,  5 Sep 2019 01:01:30 +0000
Message-ID: <20190905010130.15019-2-dan@dlrobertson.com> (raw)
In-Reply-To: <20190905010130.15019-1-dan@dlrobertson.com>

Add support for the Sensirion SHTC3 humidity and temperature sensor to
the shtc1 module.

Signed-off-by: Dan Robertson <dan@dlrobertson.com>
---
 Documentation/hwmon/shtc1.rst | 19 +++++++++----
 drivers/hwmon/Kconfig         |  4 +--
 drivers/hwmon/shtc1.c         | 50 ++++++++++++++++++++++++++---------
 3 files changed, 53 insertions(+), 20 deletions(-)

diff --git a/Documentation/hwmon/shtc1.rst b/Documentation/hwmon/shtc1.rst
index aa116332ba26..9b0f1eee5bf2 100644
--- a/Documentation/hwmon/shtc1.rst
+++ b/Documentation/hwmon/shtc1.rst
@@ -19,7 +19,17 @@ Supported chips:
 
     Addresses scanned: none
 
-    Datasheet: Not publicly available
+    Datasheet: http://www.sensirion.com/file/datasheet_shtw1
+
+
+
+  * Sensirion SHTC3
+
+    Prefix: 'shtc3'
+
+    Addresses scanned: none
+
+    Datasheet: http://www.sensirion.com/file/datasheet_shtc3
 
 
 
@@ -30,10 +40,9 @@ Author:
 Description
 -----------
 
-This driver implements support for the Sensirion SHTC1 chip, a humidity and
-temperature sensor. Temperature is measured in degrees celsius, relative
-humidity is expressed as a percentage. Driver can be used as well for SHTW1
-chip, which has the same electrical interface.
+This driver implements support for the Sensirion SHTC1, SHTW1, and SHTC3
+chips, a humidity and temperature sensor. Temperature is measured in degrees
+celsius, relative humidity is expressed as a percentage.
 
 The device communicates with the I2C protocol. All sensors are set to I2C
 address 0x70. See Documentation/i2c/instantiating-devices for methods to
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 650dd71f9724..e8b9b172ed9d 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1382,8 +1382,8 @@ config SENSORS_SHTC1
 	tristate "Sensiron humidity and temperature sensors. SHTC1 and compat."
 	depends on I2C
 	help
-	  If you say yes here you get support for the Sensiron SHTC1 and SHTW1
-	  humidity and temperature sensors.
+	  If you say yes here you get support for the Sensiron SHTC1, SHTW1,
+	  and SHTC3 humidity and temperature sensors.
 
 	  This driver can also be built as a module. If so, the module
 	  will be called shtc1.
diff --git a/drivers/hwmon/shtc1.c b/drivers/hwmon/shtc1.c
index 83fe08185ac7..d361030b07ab 100644
--- a/drivers/hwmon/shtc1.c
+++ b/drivers/hwmon/shtc1.c
@@ -24,19 +24,32 @@ static const unsigned char shtc1_cmd_measure_blocking_lpm[]    = { 0x64, 0x58 };
 static const unsigned char shtc1_cmd_measure_nonblocking_lpm[] = { 0x60, 0x9c };
 
 /* command for reading the ID register */
-static const unsigned char shtc1_cmd_read_id_reg[]	       = { 0xef, 0xc8 };
+static const unsigned char shtc1_cmd_read_id_reg[]             = { 0xef, 0xc8 };
 
-/* constants for reading the ID register */
-#define SHTC1_ID	  0x07
-#define SHTC1_ID_REG_MASK 0x1f
+/* constants for reading the ID register
+ * SHTC1: 0x0007 with mask 0x003f
+ * SHTW1: 0x0007 with mask 0x001f
+ * SHTC3: 0x0807 with mask 0x081f
+ */
+#define SHTC3_ID      0x0807
+#define SHTC3_ID_MASK 0x083f
+#define SHTC1_ID      0x0007
+#define SHTC1_ID_MASK 0x001f
 
 /* delays for non-blocking i2c commands, both in us */
 #define SHTC1_NONBLOCKING_WAIT_TIME_HPM  14400
 #define SHTC1_NONBLOCKING_WAIT_TIME_LPM   1000
+#define SHTC3_NONBLOCKING_WAIT_TIME_HPM  12100
+#define SHTC3_NONBLOCKING_WAIT_TIME_LPM    800
 
 #define SHTC1_CMD_LENGTH      2
 #define SHTC1_RESPONSE_LENGTH 6
 
+enum shtcx_chips {
+	shtc1,
+	shtc3,
+};
+
 struct shtc1_data {
 	struct i2c_client *client;
 	struct mutex update_lock;
@@ -47,6 +60,7 @@ struct shtc1_data {
 	unsigned int nonblocking_wait_time; /* in us */
 
 	struct shtc1_platform_data setup;
+	enum shtcx_chips chip;
 
 	int temperature; /* 1000 * temperature in dgr C */
 	int humidity; /* 1000 * relative humidity in %RH */
@@ -157,13 +171,16 @@ static void shtc1_select_command(struct shtc1_data *data)
 		data->command = data->setup.blocking_io ?
 				shtc1_cmd_measure_blocking_hpm :
 				shtc1_cmd_measure_nonblocking_hpm;
-		data->nonblocking_wait_time = SHTC1_NONBLOCKING_WAIT_TIME_HPM;
-
+		data->nonblocking_wait_time = (data->chip == shtc1) ?
+				SHTC1_NONBLOCKING_WAIT_TIME_HPM :
+				SHTC3_NONBLOCKING_WAIT_TIME_HPM;
 	} else {
 		data->command = data->setup.blocking_io ?
 				shtc1_cmd_measure_blocking_lpm :
 				shtc1_cmd_measure_nonblocking_lpm;
-		data->nonblocking_wait_time = SHTC1_NONBLOCKING_WAIT_TIME_LPM;
+		data->nonblocking_wait_time = (data->chip == shtc1) ?
+				SHTC1_NONBLOCKING_WAIT_TIME_LPM :
+				SHTC3_NONBLOCKING_WAIT_TIME_LPM;
 	}
 }
 
@@ -171,9 +188,11 @@ static int shtc1_probe(struct i2c_client *client,
 		       const struct i2c_device_id *id)
 {
 	int ret;
-	char id_reg[2];
+	u16 id_reg;
+	char id_reg_buf[2];
 	struct shtc1_data *data;
 	struct device *hwmon_dev;
+	enum shtcx_chips chip = id->driver_data;
 	struct i2c_adapter *adap = client->adapter;
 	struct device *dev = &client->dev;
 
@@ -187,12 +206,15 @@ static int shtc1_probe(struct i2c_client *client,
 		dev_err(dev, "could not send read_id_reg command: %d\n", ret);
 		return ret < 0 ? ret : -ENODEV;
 	}
-	ret = i2c_master_recv(client, id_reg, sizeof(id_reg));
-	if (ret != sizeof(id_reg)) {
+	ret = i2c_master_recv(client, id_reg_buf, sizeof(id_reg_buf));
+	if (ret != sizeof(id_reg_buf)) {
 		dev_err(dev, "could not read ID register: %d\n", ret);
 		return -ENODEV;
 	}
-	if ((id_reg[1] & SHTC1_ID_REG_MASK) != SHTC1_ID) {
+
+	id_reg = be16_to_cpup((__be16 *)id_reg_buf);
+	if ((chip == shtc3 && (id_reg & SHTC3_ID_MASK) != SHTC3_ID) ||
+	    ((id_reg & SHTC1_ID_MASK) != SHTC1_ID)) {
 		dev_err(dev, "ID register doesn't match\n");
 		return -ENODEV;
 	}
@@ -204,6 +226,7 @@ static int shtc1_probe(struct i2c_client *client,
 	data->setup.blocking_io = false;
 	data->setup.high_precision = true;
 	data->client = client;
+	data->chip = chip;
 
 	if (client->dev.platform_data)
 		data->setup = *(struct shtc1_platform_data *)dev->platform_data;
@@ -222,8 +245,9 @@ static int shtc1_probe(struct i2c_client *client,
 
 /* device ID table */
 static const struct i2c_device_id shtc1_id[] = {
-	{ "shtc1", 0 },
-	{ "shtw1", 0 },
+	{ "shtc1", shtc1 },
+	{ "shtw1", shtc1 },
+	{ "shtc3", shtc3 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, shtc1_id);
-- 
2.23.0




  reply index

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-05  1:01 [PATCH 0/1] " Dan Robertson
2019-09-05  1:01 ` Dan Robertson [this message]
2019-09-05  1:45   ` [PATCH 0/2] " Dan Robertson
2019-09-05  1:45     ` [PATCH 1/2] " Dan Robertson
2019-09-10 18:14       ` Guenter Roeck
2019-09-05  1:45     ` [PATCH 2/2] hwmon: (shtc1) fix shtc1 and shtw1 id mask Dan Robertson
2019-09-10 18:43       ` Guenter Roeck
2019-09-10 18:57         ` Dan Robertson

Reply instructions:

You may reply publically 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=20190905010130.15019-2-dan@dlrobertson.com \
    --to=dan@dlrobertson.com \
    --cc=jdelvare@suse.com \
    --cc=linux-hwmon@vger.kernel.org \
    --cc=linux@roeck-us.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

Linux-Hwmon Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-hwmon/0 linux-hwmon/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-hwmon linux-hwmon/ https://lore.kernel.org/linux-hwmon \
		linux-hwmon@vger.kernel.org linux-hwmon@archiver.kernel.org
	public-inbox-index linux-hwmon

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-hwmon


AGPL code for this site: git clone https://public-inbox.org/ public-inbox