• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  // SPDX-License-Identifier: GPL-2.0-or-later
2  /* Sensirion SHTC1 humidity and temperature sensor driver
3   *
4   * Copyright (C) 2014 Sensirion AG, Switzerland
5   * Author: Johannes Winkelmann <johannes.winkelmann@sensirion.com>
6   */
7  
8  #include <linux/module.h>
9  #include <linux/init.h>
10  #include <linux/slab.h>
11  #include <linux/i2c.h>
12  #include <linux/hwmon.h>
13  #include <linux/hwmon-sysfs.h>
14  #include <linux/err.h>
15  #include <linux/delay.h>
16  #include <linux/platform_data/shtc1.h>
17  #include <linux/of.h>
18  
19  /* commands (high precision mode) */
20  static const unsigned char shtc1_cmd_measure_blocking_hpm[]    = { 0x7C, 0xA2 };
21  static const unsigned char shtc1_cmd_measure_nonblocking_hpm[] = { 0x78, 0x66 };
22  
23  /* commands (low precision mode) */
24  static const unsigned char shtc1_cmd_measure_blocking_lpm[]    = { 0x64, 0x58 };
25  static const unsigned char shtc1_cmd_measure_nonblocking_lpm[] = { 0x60, 0x9c };
26  
27  /* command for reading the ID register */
28  static const unsigned char shtc1_cmd_read_id_reg[]             = { 0xef, 0xc8 };
29  
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
40  
41  /* delays for non-blocking i2c commands, both in us */
42  #define SHTC1_NONBLOCKING_WAIT_TIME_HPM  14400
43  #define SHTC1_NONBLOCKING_WAIT_TIME_LPM   1000
44  #define SHTC3_NONBLOCKING_WAIT_TIME_HPM  12100
45  #define SHTC3_NONBLOCKING_WAIT_TIME_LPM    800
46  
47  #define SHTC1_CMD_LENGTH      2
48  #define SHTC1_RESPONSE_LENGTH 6
49  
50  enum shtcx_chips {
51  	shtc1,
52  	shtc3,
53  };
54  
55  struct shtc1_data {
56  	struct i2c_client *client;
57  	struct mutex update_lock;
58  	bool valid;
59  	unsigned long last_updated; /* in jiffies */
60  
61  	const unsigned char *command;
62  	unsigned int nonblocking_wait_time; /* in us */
63  
64  	struct shtc1_platform_data setup;
65  	enum shtcx_chips chip;
66  
67  	int temperature; /* 1000 * temperature in dgr C */
68  	int humidity; /* 1000 * relative humidity in %RH */
69  };
70  
shtc1_update_values(struct i2c_client * client,struct shtc1_data * data,char * buf,int bufsize)71  static int shtc1_update_values(struct i2c_client *client,
72  			       struct shtc1_data *data,
73  			       char *buf, int bufsize)
74  {
75  	int ret = i2c_master_send(client, data->command, SHTC1_CMD_LENGTH);
76  	if (ret != SHTC1_CMD_LENGTH) {
77  		dev_err(&client->dev, "failed to send command: %d\n", ret);
78  		return ret < 0 ? ret : -EIO;
79  	}
80  
81  	/*
82  	 * In blocking mode (clock stretching mode) the I2C bus
83  	 * is blocked for other traffic, thus the call to i2c_master_recv()
84  	 * will wait until the data is ready. For non blocking mode, we
85  	 * have to wait ourselves.
86  	 */
87  	if (!data->setup.blocking_io)
88  		usleep_range(data->nonblocking_wait_time,
89  			     data->nonblocking_wait_time + 1000);
90  
91  	ret = i2c_master_recv(client, buf, bufsize);
92  	if (ret != bufsize) {
93  		dev_err(&client->dev, "failed to read values: %d\n", ret);
94  		return ret < 0 ? ret : -EIO;
95  	}
96  
97  	return 0;
98  }
99  
100  /* sysfs attributes */
shtc1_update_client(struct device * dev)101  static struct shtc1_data *shtc1_update_client(struct device *dev)
102  {
103  	struct shtc1_data *data = dev_get_drvdata(dev);
104  	struct i2c_client *client = data->client;
105  	unsigned char buf[SHTC1_RESPONSE_LENGTH];
106  	int val;
107  	int ret = 0;
108  
109  	mutex_lock(&data->update_lock);
110  
111  	if (time_after(jiffies, data->last_updated + HZ / 10) || !data->valid) {
112  		ret = shtc1_update_values(client, data, buf, sizeof(buf));
113  		if (ret)
114  			goto out;
115  
116  		/*
117  		 * From datasheet:
118  		 * T = -45 + 175 * ST / 2^16
119  		 * RH = 100 * SRH / 2^16
120  		 *
121  		 * Adapted for integer fixed point (3 digit) arithmetic.
122  		 */
123  		val = be16_to_cpup((__be16 *)buf);
124  		data->temperature = ((21875 * val) >> 13) - 45000;
125  		val = be16_to_cpup((__be16 *)(buf + 3));
126  		data->humidity = ((12500 * val) >> 13);
127  
128  		data->last_updated = jiffies;
129  		data->valid = true;
130  	}
131  
132  out:
133  	mutex_unlock(&data->update_lock);
134  
135  	return ret == 0 ? data : ERR_PTR(ret);
136  }
137  
temp1_input_show(struct device * dev,struct device_attribute * attr,char * buf)138  static ssize_t temp1_input_show(struct device *dev,
139  				struct device_attribute *attr,
140  				char *buf)
141  {
142  	struct shtc1_data *data = shtc1_update_client(dev);
143  	if (IS_ERR(data))
144  		return PTR_ERR(data);
145  
146  	return sprintf(buf, "%d\n", data->temperature);
147  }
148  
humidity1_input_show(struct device * dev,struct device_attribute * attr,char * buf)149  static ssize_t humidity1_input_show(struct device *dev,
150  				    struct device_attribute *attr, char *buf)
151  {
152  	struct shtc1_data *data = shtc1_update_client(dev);
153  	if (IS_ERR(data))
154  		return PTR_ERR(data);
155  
156  	return sprintf(buf, "%d\n", data->humidity);
157  }
158  
159  static DEVICE_ATTR_RO(temp1_input);
160  static DEVICE_ATTR_RO(humidity1_input);
161  
162  static struct attribute *shtc1_attrs[] = {
163  	&dev_attr_temp1_input.attr,
164  	&dev_attr_humidity1_input.attr,
165  	NULL
166  };
167  
168  ATTRIBUTE_GROUPS(shtc1);
169  
shtc1_select_command(struct shtc1_data * data)170  static void shtc1_select_command(struct shtc1_data *data)
171  {
172  	if (data->setup.high_precision) {
173  		data->command = data->setup.blocking_io ?
174  				shtc1_cmd_measure_blocking_hpm :
175  				shtc1_cmd_measure_nonblocking_hpm;
176  		data->nonblocking_wait_time = (data->chip == shtc1) ?
177  				SHTC1_NONBLOCKING_WAIT_TIME_HPM :
178  				SHTC3_NONBLOCKING_WAIT_TIME_HPM;
179  	} else {
180  		data->command = data->setup.blocking_io ?
181  				shtc1_cmd_measure_blocking_lpm :
182  				shtc1_cmd_measure_nonblocking_lpm;
183  		data->nonblocking_wait_time = (data->chip == shtc1) ?
184  				SHTC1_NONBLOCKING_WAIT_TIME_LPM :
185  				SHTC3_NONBLOCKING_WAIT_TIME_LPM;
186  	}
187  }
188  
189  static const struct i2c_device_id shtc1_id[];
190  
shtc1_probe(struct i2c_client * client)191  static int shtc1_probe(struct i2c_client *client)
192  {
193  	int ret;
194  	u16 id_reg;
195  	char id_reg_buf[2];
196  	struct shtc1_data *data;
197  	struct device *hwmon_dev;
198  	enum shtcx_chips chip = i2c_match_id(shtc1_id, client)->driver_data;
199  	struct i2c_adapter *adap = client->adapter;
200  	struct device *dev = &client->dev;
201  	struct device_node *np = dev->of_node;
202  
203  	if (!i2c_check_functionality(adap, I2C_FUNC_I2C)) {
204  		dev_err(dev, "plain i2c transactions not supported\n");
205  		return -ENODEV;
206  	}
207  
208  	ret = i2c_master_send(client, shtc1_cmd_read_id_reg, SHTC1_CMD_LENGTH);
209  	if (ret != SHTC1_CMD_LENGTH) {
210  		dev_err(dev, "could not send read_id_reg command: %d\n", ret);
211  		return ret < 0 ? ret : -ENODEV;
212  	}
213  	ret = i2c_master_recv(client, id_reg_buf, sizeof(id_reg_buf));
214  	if (ret != sizeof(id_reg_buf)) {
215  		dev_err(dev, "could not read ID register: %d\n", ret);
216  		return -ENODEV;
217  	}
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");
227  		return -ENODEV;
228  	}
229  
230  	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
231  	if (!data)
232  		return -ENOMEM;
233  
234  	data->setup.blocking_io = false;
235  	data->setup.high_precision = true;
236  	data->client = client;
237  	data->chip = chip;
238  
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  
247  	shtc1_select_command(data);
248  	mutex_init(&data->update_lock);
249  
250  	hwmon_dev = devm_hwmon_device_register_with_groups(dev,
251  							   client->name,
252  							   data,
253  							   shtc1_groups);
254  	if (IS_ERR(hwmon_dev))
255  		dev_dbg(dev, "unable to register hwmon device\n");
256  
257  	return PTR_ERR_OR_ZERO(hwmon_dev);
258  }
259  
260  /* device ID table */
261  static const struct i2c_device_id shtc1_id[] = {
262  	{ "shtc1", shtc1 },
263  	{ "shtw1", shtc1 },
264  	{ "shtc3", shtc3 },
265  	{ }
266  };
267  MODULE_DEVICE_TABLE(i2c, shtc1_id);
268  
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  
277  static struct i2c_driver shtc1_i2c_driver = {
278  	.driver = {
279  		.name = "shtc1",
280  		.of_match_table = shtc1_of_match,
281  	},
282  	.probe_new    = shtc1_probe,
283  	.id_table     = shtc1_id,
284  };
285  
286  module_i2c_driver(shtc1_i2c_driver);
287  
288  MODULE_AUTHOR("Johannes Winkelmann <johannes.winkelmann@sensirion.com>");
289  MODULE_DESCRIPTION("Sensirion SHTC1 humidity and temperature sensor driver");
290  MODULE_LICENSE("GPL");
291