hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/hwmon/shtc1.c
....@@ -1,18 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* Sensirion SHTC1 humidity and temperature sensor driver
23 *
34 * Copyright (C) 2014 Sensirion AG, Switzerland
45 * Author: Johannes Winkelmann <johannes.winkelmann@sensirion.com>
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
15
- *
166 */
177
188 #include <linux/module.h>
....@@ -24,6 +14,7 @@
2414 #include <linux/err.h>
2515 #include <linux/delay.h>
2616 #include <linux/platform_data/shtc1.h>
17
+#include <linux/of.h>
2718
2819 /* commands (high precision mode) */
2920 static const unsigned char shtc1_cmd_measure_blocking_hpm[] = { 0x7C, 0xA2 };
....@@ -34,18 +25,32 @@
3425 static const unsigned char shtc1_cmd_measure_nonblocking_lpm[] = { 0x60, 0x9c };
3526
3627 /* command for reading the ID register */
37
-static const unsigned char shtc1_cmd_read_id_reg[] = { 0xef, 0xc8 };
28
+static const unsigned char shtc1_cmd_read_id_reg[] = { 0xef, 0xc8 };
3829
39
-/* constants for reading the ID register */
40
-#define SHTC1_ID 0x07
41
-#define SHTC1_ID_REG_MASK 0x3f
30
+/*
31
+ * constants for reading the ID register
32
+ * SHTC1: 0x0007 with mask 0x003f
33
+ * SHTW1: 0x0007 with mask 0x003f
34
+ * SHTC3: 0x0807 with mask 0x083f
35
+ */
36
+#define SHTC3_ID 0x0807
37
+#define SHTC3_ID_MASK 0x083f
38
+#define SHTC1_ID 0x0007
39
+#define SHTC1_ID_MASK 0x003f
4240
4341 /* delays for non-blocking i2c commands, both in us */
4442 #define SHTC1_NONBLOCKING_WAIT_TIME_HPM 14400
4543 #define SHTC1_NONBLOCKING_WAIT_TIME_LPM 1000
44
+#define SHTC3_NONBLOCKING_WAIT_TIME_HPM 12100
45
+#define SHTC3_NONBLOCKING_WAIT_TIME_LPM 800
4646
4747 #define SHTC1_CMD_LENGTH 2
4848 #define SHTC1_RESPONSE_LENGTH 6
49
+
50
+enum shtcx_chips {
51
+ shtc1,
52
+ shtc3,
53
+};
4954
5055 struct shtc1_data {
5156 struct i2c_client *client;
....@@ -57,6 +62,7 @@
5762 unsigned int nonblocking_wait_time; /* in us */
5863
5964 struct shtc1_platform_data setup;
65
+ enum shtcx_chips chip;
6066
6167 int temperature; /* 1000 * temperature in dgr C */
6268 int humidity; /* 1000 * relative humidity in %RH */
....@@ -167,25 +173,32 @@
167173 data->command = data->setup.blocking_io ?
168174 shtc1_cmd_measure_blocking_hpm :
169175 shtc1_cmd_measure_nonblocking_hpm;
170
- data->nonblocking_wait_time = SHTC1_NONBLOCKING_WAIT_TIME_HPM;
171
-
176
+ data->nonblocking_wait_time = (data->chip == shtc1) ?
177
+ SHTC1_NONBLOCKING_WAIT_TIME_HPM :
178
+ SHTC3_NONBLOCKING_WAIT_TIME_HPM;
172179 } else {
173180 data->command = data->setup.blocking_io ?
174181 shtc1_cmd_measure_blocking_lpm :
175182 shtc1_cmd_measure_nonblocking_lpm;
176
- data->nonblocking_wait_time = SHTC1_NONBLOCKING_WAIT_TIME_LPM;
183
+ data->nonblocking_wait_time = (data->chip == shtc1) ?
184
+ SHTC1_NONBLOCKING_WAIT_TIME_LPM :
185
+ SHTC3_NONBLOCKING_WAIT_TIME_LPM;
177186 }
178187 }
179188
180
-static int shtc1_probe(struct i2c_client *client,
181
- const struct i2c_device_id *id)
189
+static const struct i2c_device_id shtc1_id[];
190
+
191
+static int shtc1_probe(struct i2c_client *client)
182192 {
183193 int ret;
184
- char id_reg[2];
194
+ u16 id_reg;
195
+ char id_reg_buf[2];
185196 struct shtc1_data *data;
186197 struct device *hwmon_dev;
198
+ enum shtcx_chips chip = i2c_match_id(shtc1_id, client)->driver_data;
187199 struct i2c_adapter *adap = client->adapter;
188200 struct device *dev = &client->dev;
201
+ struct device_node *np = dev->of_node;
189202
190203 if (!i2c_check_functionality(adap, I2C_FUNC_I2C)) {
191204 dev_err(dev, "plain i2c transactions not supported\n");
....@@ -197,13 +210,20 @@
197210 dev_err(dev, "could not send read_id_reg command: %d\n", ret);
198211 return ret < 0 ? ret : -ENODEV;
199212 }
200
- ret = i2c_master_recv(client, id_reg, sizeof(id_reg));
201
- if (ret != sizeof(id_reg)) {
213
+ ret = i2c_master_recv(client, id_reg_buf, sizeof(id_reg_buf));
214
+ if (ret != sizeof(id_reg_buf)) {
202215 dev_err(dev, "could not read ID register: %d\n", ret);
203216 return -ENODEV;
204217 }
205
- if ((id_reg[1] & SHTC1_ID_REG_MASK) != SHTC1_ID) {
206
- dev_err(dev, "ID register doesn't match\n");
218
+
219
+ id_reg = be16_to_cpup((__be16 *)id_reg_buf);
220
+ if (chip == shtc3) {
221
+ if ((id_reg & SHTC3_ID_MASK) != SHTC3_ID) {
222
+ dev_err(dev, "SHTC3 ID register does not match\n");
223
+ return -ENODEV;
224
+ }
225
+ } else if ((id_reg & SHTC1_ID_MASK) != SHTC1_ID) {
226
+ dev_err(dev, "SHTC1 ID register does not match\n");
207227 return -ENODEV;
208228 }
209229
....@@ -214,9 +234,16 @@
214234 data->setup.blocking_io = false;
215235 data->setup.high_precision = true;
216236 data->client = client;
237
+ data->chip = chip;
217238
218
- if (client->dev.platform_data)
219
- data->setup = *(struct shtc1_platform_data *)dev->platform_data;
239
+ if (np) {
240
+ data->setup.blocking_io = of_property_read_bool(np, "sensirion,blocking-io");
241
+ data->setup.high_precision = !of_property_read_bool(np, "sensicon,low-precision");
242
+ } else {
243
+ if (client->dev.platform_data)
244
+ data->setup = *(struct shtc1_platform_data *)dev->platform_data;
245
+ }
246
+
220247 shtc1_select_command(data);
221248 mutex_init(&data->update_lock);
222249
....@@ -232,15 +259,27 @@
232259
233260 /* device ID table */
234261 static const struct i2c_device_id shtc1_id[] = {
235
- { "shtc1", 0 },
236
- { "shtw1", 0 },
262
+ { "shtc1", shtc1 },
263
+ { "shtw1", shtc1 },
264
+ { "shtc3", shtc3 },
237265 { }
238266 };
239267 MODULE_DEVICE_TABLE(i2c, shtc1_id);
240268
269
+static const struct of_device_id shtc1_of_match[] = {
270
+ { .compatible = "sensirion,shtc1" },
271
+ { .compatible = "sensirion,shtw1" },
272
+ { .compatible = "sensirion,shtc3" },
273
+ { }
274
+};
275
+MODULE_DEVICE_TABLE(of, shtc1_of_match);
276
+
241277 static struct i2c_driver shtc1_i2c_driver = {
242
- .driver.name = "shtc1",
243
- .probe = shtc1_probe,
278
+ .driver = {
279
+ .name = "shtc1",
280
+ .of_match_table = shtc1_of_match,
281
+ },
282
+ .probe_new = shtc1_probe,
244283 .id_table = shtc1_id,
245284 };
246285