aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/shtc1.c
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 /drivers/hwmon/shtc1.c
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>
Diffstat (limited to 'drivers/hwmon/shtc1.c')
-rw-r--r--drivers/hwmon/shtc1.c57
1 files changed, 43 insertions, 14 deletions
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);