diff options
author | Dan Robertson <dan@dlrobertson.com> | 2019-09-04 21:45:53 -0400 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2019-09-10 14:42:56 -0400 |
commit | ffd96868ac5d4c22bba1ba2175d124cb2775f3f7 (patch) | |
tree | 4b2b792cbca4348f17f33700d0410028cc9b71cd | |
parent | fdc7d8e829ec755c5cfb2f5a8d8c0cdfb664f895 (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.rst | 19 | ||||
-rw-r--r-- | drivers/hwmon/Kconfig | 4 | ||||
-rw-r--r-- | drivers/hwmon/shtc1.c | 57 |
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: | |||
30 | Description | 40 | Description |
31 | ----------- | 41 | ----------- |
32 | 42 | ||
33 | This driver implements support for the Sensirion SHTC1 chip, a humidity and | 43 | This driver implements support for the Sensirion SHTC1, SHTW1, and SHTC3 |
34 | temperature sensor. Temperature is measured in degrees celsius, relative | 44 | chips, a humidity and temperature sensor. Temperature is measured in degrees |
35 | humidity is expressed as a percentage. Driver can be used as well for SHTW1 | 45 | celsius, relative humidity is expressed as a percentage. |
36 | chip, which has the same electrical interface. | ||
37 | 46 | ||
38 | The device communicates with the I2C protocol. All sensors are set to I2C | 47 | The device communicates with the I2C protocol. All sensors are set to I2C |
39 | address 0x70. See Documentation/i2c/instantiating-devices for methods to | 48 | address 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 }; | |||
24 | static const unsigned char shtc1_cmd_measure_nonblocking_lpm[] = { 0x60, 0x9c }; | 24 | static 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 */ |
27 | static const unsigned char shtc1_cmd_read_id_reg[] = { 0xef, 0xc8 }; | 27 | static 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 | ||
49 | enum shtcx_chips { | ||
50 | shtc1, | ||
51 | shtc3, | ||
52 | }; | ||
53 | |||
40 | struct shtc1_data { | 54 | struct 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 */ |
224 | static const struct i2c_device_id shtc1_id[] = { | 252 | static 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 | }; |
229 | MODULE_DEVICE_TABLE(i2c, shtc1_id); | 258 | MODULE_DEVICE_TABLE(i2c, shtc1_id); |