summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Robertson <dan@dlrobertson.com>2019-09-04 21:45:53 -0400
committerGuenter Roeck <linux@roeck-us.net>2019-09-10 14:42:56 -0400
commitffd96868ac5d4c22bba1ba2175d124cb2775f3f7 (patch)
tree4b2b792cbca4348f17f33700d0410028cc9b71cd
parentfdc7d8e829ec755c5cfb2f5a8d8c0cdfb664f895 (diff)
hwmon: (shtc1) add support for the SHTC3 sensor
Add support for the Sensirion SHTC3 humidity and temperature sensor to the shtc1 module. Signed-off-by: Dan Robertson <dan@dlrobertson.com> Link: https://lore.kernel.org/r/20190905014554.21658-2-dan@dlrobertson.com Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r--Documentation/hwmon/shtc1.rst19
-rw-r--r--drivers/hwmon/Kconfig4
-rw-r--r--drivers/hwmon/shtc1.c57
3 files changed, 59 insertions, 21 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:
19 19
20 Addresses scanned: none 20 Addresses scanned: none
21 21
22 Datasheet: Not publicly available 22 Datasheet: http://www.sensirion.com/file/datasheet_shtw1
23
24
25
26 * Sensirion SHTC3
27
28 Prefix: 'shtc3'
29
30 Addresses scanned: none
31
32 Datasheet: http://www.sensirion.com/file/datasheet_shtc3
23 33
24 34
25 35
@@ -30,10 +40,9 @@ Author:
30Description 40Description
31----------- 41-----------
32 42
33This driver implements support for the Sensirion SHTC1 chip, a humidity and 43This driver implements support for the Sensirion SHTC1, SHTW1, and SHTC3
34temperature sensor. Temperature is measured in degrees celsius, relative 44chips, a humidity and temperature sensor. Temperature is measured in degrees
35humidity is expressed as a percentage. Driver can be used as well for SHTW1 45celsius, relative humidity is expressed as a percentage.
36chip, which has the same electrical interface.
37 46
38The device communicates with the I2C protocol. All sensors are set to I2C 47The device communicates with the I2C protocol. All sensors are set to I2C
39address 0x70. See Documentation/i2c/instantiating-devices for methods to 48address 0x70. See Documentation/i2c/instantiating-devices for methods to
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index c823b662adc9..2ca5668bdb62 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1392,8 +1392,8 @@ config SENSORS_SHTC1
1392 tristate "Sensiron humidity and temperature sensors. SHTC1 and compat." 1392 tristate "Sensiron humidity and temperature sensors. SHTC1 and compat."
1393 depends on I2C 1393 depends on I2C
1394 help 1394 help
1395 If you say yes here you get support for the Sensiron SHTC1 and SHTW1 1395 If you say yes here you get support for the Sensiron SHTC1, SHTW1,
1396 humidity and temperature sensors. 1396 and SHTC3 humidity and temperature sensors.
1397 1397
1398 This driver can also be built as a module. If so, the module 1398 This driver can also be built as a module. If so, the module
1399 will be called shtc1. 1399 will be called shtc1.
diff --git a/drivers/hwmon/shtc1.c b/drivers/hwmon/shtc1.c
index b267cf2a9817..a0078ccede03 100644
--- a/drivers/hwmon/shtc1.c
+++ b/drivers/hwmon/shtc1.c
@@ -24,19 +24,33 @@ static const unsigned char shtc1_cmd_measure_blocking_lpm[] = { 0x64, 0x58 };
24static const unsigned char shtc1_cmd_measure_nonblocking_lpm[] = { 0x60, 0x9c }; 24static const unsigned char shtc1_cmd_measure_nonblocking_lpm[] = { 0x60, 0x9c };
25 25
26/* command for reading the ID register */ 26/* command for reading the ID register */
27static const unsigned char shtc1_cmd_read_id_reg[] = { 0xef, 0xc8 }; 27static const unsigned char shtc1_cmd_read_id_reg[] = { 0xef, 0xc8 };
28 28
29/* constants for reading the ID register */ 29/*
30#define SHTC1_ID 0x07 30 * constants for reading the ID register
31#define SHTC1_ID_REG_MASK 0x3f 31 * SHTC1: 0x0007 with mask 0x003f
32 * SHTW1: 0x0007 with mask 0x003f
33 * SHTC3: 0x0807 with mask 0x083f
34 */
35#define SHTC3_ID 0x0807
36#define SHTC3_ID_MASK 0x083f
37#define SHTC1_ID 0x0007
38#define SHTC1_ID_MASK 0x003f
32 39
33/* delays for non-blocking i2c commands, both in us */ 40/* delays for non-blocking i2c commands, both in us */
34#define SHTC1_NONBLOCKING_WAIT_TIME_HPM 14400 41#define SHTC1_NONBLOCKING_WAIT_TIME_HPM 14400
35#define SHTC1_NONBLOCKING_WAIT_TIME_LPM 1000 42#define SHTC1_NONBLOCKING_WAIT_TIME_LPM 1000
43#define SHTC3_NONBLOCKING_WAIT_TIME_HPM 12100
44#define SHTC3_NONBLOCKING_WAIT_TIME_LPM 800
36 45
37#define SHTC1_CMD_LENGTH 2 46#define SHTC1_CMD_LENGTH 2
38#define SHTC1_RESPONSE_LENGTH 6 47#define SHTC1_RESPONSE_LENGTH 6
39 48
49enum shtcx_chips {
50 shtc1,
51 shtc3,
52};
53
40struct shtc1_data { 54struct shtc1_data {
41 struct i2c_client *client; 55 struct i2c_client *client;
42 struct mutex update_lock; 56 struct mutex update_lock;
@@ -47,6 +61,7 @@ struct shtc1_data {
47 unsigned int nonblocking_wait_time; /* in us */ 61 unsigned int nonblocking_wait_time; /* in us */
48 62
49 struct shtc1_platform_data setup; 63 struct shtc1_platform_data setup;
64 enum shtcx_chips chip;
50 65
51 int temperature; /* 1000 * temperature in dgr C */ 66 int temperature; /* 1000 * temperature in dgr C */
52 int humidity; /* 1000 * relative humidity in %RH */ 67 int humidity; /* 1000 * relative humidity in %RH */
@@ -157,13 +172,16 @@ static void shtc1_select_command(struct shtc1_data *data)
157 data->command = data->setup.blocking_io ? 172 data->command = data->setup.blocking_io ?
158 shtc1_cmd_measure_blocking_hpm : 173 shtc1_cmd_measure_blocking_hpm :
159 shtc1_cmd_measure_nonblocking_hpm; 174 shtc1_cmd_measure_nonblocking_hpm;
160 data->nonblocking_wait_time = SHTC1_NONBLOCKING_WAIT_TIME_HPM; 175 data->nonblocking_wait_time = (data->chip == shtc1) ?
161 176 SHTC1_NONBLOCKING_WAIT_TIME_HPM :
177 SHTC3_NONBLOCKING_WAIT_TIME_HPM;
162 } else { 178 } else {
163 data->command = data->setup.blocking_io ? 179 data->command = data->setup.blocking_io ?
164 shtc1_cmd_measure_blocking_lpm : 180 shtc1_cmd_measure_blocking_lpm :
165 shtc1_cmd_measure_nonblocking_lpm; 181 shtc1_cmd_measure_nonblocking_lpm;
166 data->nonblocking_wait_time = SHTC1_NONBLOCKING_WAIT_TIME_LPM; 182 data->nonblocking_wait_time = (data->chip == shtc1) ?
183 SHTC1_NONBLOCKING_WAIT_TIME_LPM :
184 SHTC3_NONBLOCKING_WAIT_TIME_LPM;
167 } 185 }
168} 186}
169 187
@@ -171,9 +189,11 @@ static int shtc1_probe(struct i2c_client *client,
171 const struct i2c_device_id *id) 189 const struct i2c_device_id *id)
172{ 190{
173 int ret; 191 int ret;
174 char id_reg[2]; 192 u16 id_reg;
193 char id_reg_buf[2];
175 struct shtc1_data *data; 194 struct shtc1_data *data;
176 struct device *hwmon_dev; 195 struct device *hwmon_dev;
196 enum shtcx_chips chip = id->driver_data;
177 struct i2c_adapter *adap = client->adapter; 197 struct i2c_adapter *adap = client->adapter;
178 struct device *dev = &client->dev; 198 struct device *dev = &client->dev;
179 199
@@ -187,13 +207,20 @@ static int shtc1_probe(struct i2c_client *client,
187 dev_err(dev, "could not send read_id_reg command: %d\n", ret); 207 dev_err(dev, "could not send read_id_reg command: %d\n", ret);
188 return ret < 0 ? ret : -ENODEV; 208 return ret < 0 ? ret : -ENODEV;
189 } 209 }
190 ret = i2c_master_recv(client, id_reg, sizeof(id_reg)); 210 ret = i2c_master_recv(client, id_reg_buf, sizeof(id_reg_buf));
191 if (ret != sizeof(id_reg)) { 211 if (ret != sizeof(id_reg_buf)) {
192 dev_err(dev, "could not read ID register: %d\n", ret); 212 dev_err(dev, "could not read ID register: %d\n", ret);
193 return -ENODEV; 213 return -ENODEV;
194 } 214 }
195 if ((id_reg[1] & SHTC1_ID_REG_MASK) != SHTC1_ID) { 215
196 dev_err(dev, "ID register doesn't match\n"); 216 id_reg = be16_to_cpup((__be16 *)id_reg_buf);
217 if (chip == shtc3) {
218 if ((id_reg & SHTC3_ID_MASK) != SHTC3_ID) {
219 dev_err(dev, "SHTC3 ID register does not match\n");
220 return -ENODEV;
221 }
222 } else if ((id_reg & SHTC1_ID_MASK) != SHTC1_ID) {
223 dev_err(dev, "SHTC1 ID register does not match\n");
197 return -ENODEV; 224 return -ENODEV;
198 } 225 }
199 226
@@ -204,6 +231,7 @@ static int shtc1_probe(struct i2c_client *client,
204 data->setup.blocking_io = false; 231 data->setup.blocking_io = false;
205 data->setup.high_precision = true; 232 data->setup.high_precision = true;
206 data->client = client; 233 data->client = client;
234 data->chip = chip;
207 235
208 if (client->dev.platform_data) 236 if (client->dev.platform_data)
209 data->setup = *(struct shtc1_platform_data *)dev->platform_data; 237 data->setup = *(struct shtc1_platform_data *)dev->platform_data;
@@ -222,8 +250,9 @@ static int shtc1_probe(struct i2c_client *client,
222 250
223/* device ID table */ 251/* device ID table */
224static const struct i2c_device_id shtc1_id[] = { 252static const struct i2c_device_id shtc1_id[] = {
225 { "shtc1", 0 }, 253 { "shtc1", shtc1 },
226 { "shtw1", 0 }, 254 { "shtw1", shtc1 },
255 { "shtc3", shtc3 },
227 { } 256 { }
228}; 257};
229MODULE_DEVICE_TABLE(i2c, shtc1_id); 258MODULE_DEVICE_TABLE(i2c, shtc1_id);