blob: 273eb0612a5d3ad5986f0e56832eceb3798f9e0c [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2 * hdc100x.c - Support for the TI HDC100x temperature + humidity sensors
3 *
4 * Copyright (C) 2015 Matt Ranostay <mranostay@gmail.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 *
16 * Datasheets:
17 * http://www.ti.com/product/HDC1000/datasheet
18 * http://www.ti.com/product/HDC1008/datasheet
19 * http://www.ti.com/product/HDC1010/datasheet
20 * http://www.ti.com/product/HDC1050/datasheet
21 * http://www.ti.com/product/HDC1080/datasheet
22 */
23
24#include <linux/delay.h>
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/i2c.h>
28
29#include <linux/iio/iio.h>
30#include <linux/iio/sysfs.h>
31#include <linux/iio/buffer.h>
32#include <linux/iio/trigger_consumer.h>
33#include <linux/iio/triggered_buffer.h>
34
35#define HDC100X_REG_TEMP 0x00
36#define HDC100X_REG_HUMIDITY 0x01
37
38#define HDC100X_REG_CONFIG 0x02
39#define HDC100X_REG_CONFIG_ACQ_MODE BIT(12)
40#define HDC100X_REG_CONFIG_HEATER_EN BIT(13)
41
42struct hdc100x_data {
43 struct i2c_client *client;
44 struct mutex lock;
45 u16 config;
46
47 /* integration time of the sensor */
48 int adc_int_us[2];
49 /* Ensure natural alignment of timestamp */
50 struct {
51 __be16 channels[2];
52 s64 ts __aligned(8);
53 } scan;
54};
55
56/* integration time in us */
57static const int hdc100x_int_time[][3] = {
58 { 6350, 3650, 0 }, /* IIO_TEMP channel*/
59 { 6500, 3850, 2500 }, /* IIO_HUMIDITYRELATIVE channel */
60};
61
62/* HDC100X_REG_CONFIG shift and mask values */
63static const struct {
64 int shift;
65 int mask;
66} hdc100x_resolution_shift[2] = {
67 { /* IIO_TEMP channel */
68 .shift = 10,
69 .mask = 1
70 },
71 { /* IIO_HUMIDITYRELATIVE channel */
72 .shift = 8,
73 .mask = 3,
74 },
75};
76
77static IIO_CONST_ATTR(temp_integration_time_available,
78 "0.00365 0.00635");
79
80static IIO_CONST_ATTR(humidityrelative_integration_time_available,
81 "0.0025 0.00385 0.0065");
82
83static IIO_CONST_ATTR(out_current_heater_raw_available,
84 "0 1");
85
86static struct attribute *hdc100x_attributes[] = {
87 &iio_const_attr_temp_integration_time_available.dev_attr.attr,
88 &iio_const_attr_humidityrelative_integration_time_available.dev_attr.attr,
89 &iio_const_attr_out_current_heater_raw_available.dev_attr.attr,
90 NULL
91};
92
93static const struct attribute_group hdc100x_attribute_group = {
94 .attrs = hdc100x_attributes,
95};
96
97static const struct iio_chan_spec hdc100x_channels[] = {
98 {
99 .type = IIO_TEMP,
100 .address = HDC100X_REG_TEMP,
101 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
102 BIT(IIO_CHAN_INFO_SCALE) |
103 BIT(IIO_CHAN_INFO_INT_TIME) |
104 BIT(IIO_CHAN_INFO_OFFSET),
105 .scan_index = 0,
106 .scan_type = {
107 .sign = 's',
108 .realbits = 16,
109 .storagebits = 16,
110 .endianness = IIO_BE,
111 },
112 },
113 {
114 .type = IIO_HUMIDITYRELATIVE,
115 .address = HDC100X_REG_HUMIDITY,
116 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
117 BIT(IIO_CHAN_INFO_SCALE) |
118 BIT(IIO_CHAN_INFO_INT_TIME),
119 .scan_index = 1,
120 .scan_type = {
121 .sign = 'u',
122 .realbits = 16,
123 .storagebits = 16,
124 .endianness = IIO_BE,
125 },
126 },
127 {
128 .type = IIO_CURRENT,
129 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
130 .extend_name = "heater",
131 .output = 1,
132 .scan_index = -1,
133 },
134 IIO_CHAN_SOFT_TIMESTAMP(2),
135};
136
137static const unsigned long hdc100x_scan_masks[] = {0x3, 0};
138
139static int hdc100x_update_config(struct hdc100x_data *data, int mask, int val)
140{
141 int tmp = (~mask & data->config) | val;
142 int ret;
143
144 ret = i2c_smbus_write_word_swapped(data->client,
145 HDC100X_REG_CONFIG, tmp);
146 if (!ret)
147 data->config = tmp;
148
149 return ret;
150}
151
152static int hdc100x_set_it_time(struct hdc100x_data *data, int chan, int val2)
153{
154 int shift = hdc100x_resolution_shift[chan].shift;
155 int ret = -EINVAL;
156 int i;
157
158 for (i = 0; i < ARRAY_SIZE(hdc100x_int_time[chan]); i++) {
159 if (val2 && val2 == hdc100x_int_time[chan][i]) {
160 ret = hdc100x_update_config(data,
161 hdc100x_resolution_shift[chan].mask << shift,
162 i << shift);
163 if (!ret)
164 data->adc_int_us[chan] = val2;
165 break;
166 }
167 }
168
169 return ret;
170}
171
172static int hdc100x_get_measurement(struct hdc100x_data *data,
173 struct iio_chan_spec const *chan)
174{
175 struct i2c_client *client = data->client;
176 int delay = data->adc_int_us[chan->address];
177 int ret;
178 __be16 val;
179
180 /* start measurement */
181 ret = i2c_smbus_write_byte(client, chan->address);
182 if (ret < 0) {
183 dev_err(&client->dev, "cannot start measurement");
184 return ret;
185 }
186
187 /* wait for integration time to pass */
188 usleep_range(delay, delay + 1000);
189
190 /* read measurement */
191 ret = i2c_master_recv(data->client, (char *)&val, sizeof(val));
192 if (ret < 0) {
193 dev_err(&client->dev, "cannot read sensor data\n");
194 return ret;
195 }
196 return be16_to_cpu(val);
197}
198
199static int hdc100x_get_heater_status(struct hdc100x_data *data)
200{
201 return !!(data->config & HDC100X_REG_CONFIG_HEATER_EN);
202}
203
204static int hdc100x_read_raw(struct iio_dev *indio_dev,
205 struct iio_chan_spec const *chan, int *val,
206 int *val2, long mask)
207{
208 struct hdc100x_data *data = iio_priv(indio_dev);
209
210 switch (mask) {
211 case IIO_CHAN_INFO_RAW: {
212 int ret;
213
214 mutex_lock(&data->lock);
215 if (chan->type == IIO_CURRENT) {
216 *val = hdc100x_get_heater_status(data);
217 ret = IIO_VAL_INT;
218 } else {
219 ret = iio_device_claim_direct_mode(indio_dev);
220 if (ret) {
221 mutex_unlock(&data->lock);
222 return ret;
223 }
224
225 ret = hdc100x_get_measurement(data, chan);
226 iio_device_release_direct_mode(indio_dev);
227 if (ret >= 0) {
228 *val = ret;
229 ret = IIO_VAL_INT;
230 }
231 }
232 mutex_unlock(&data->lock);
233 return ret;
234 }
235 case IIO_CHAN_INFO_INT_TIME:
236 *val = 0;
237 *val2 = data->adc_int_us[chan->address];
238 return IIO_VAL_INT_PLUS_MICRO;
239 case IIO_CHAN_INFO_SCALE:
240 if (chan->type == IIO_TEMP) {
241 *val = 165000;
242 *val2 = 65536;
243 return IIO_VAL_FRACTIONAL;
244 } else {
245 *val = 100000;
246 *val2 = 65536;
247 return IIO_VAL_FRACTIONAL;
248 }
249 break;
250 case IIO_CHAN_INFO_OFFSET:
251 *val = -15887;
252 *val2 = 515151;
253 return IIO_VAL_INT_PLUS_MICRO;
254 default:
255 return -EINVAL;
256 }
257}
258
259static int hdc100x_write_raw(struct iio_dev *indio_dev,
260 struct iio_chan_spec const *chan,
261 int val, int val2, long mask)
262{
263 struct hdc100x_data *data = iio_priv(indio_dev);
264 int ret = -EINVAL;
265
266 switch (mask) {
267 case IIO_CHAN_INFO_INT_TIME:
268 if (val != 0)
269 return -EINVAL;
270
271 mutex_lock(&data->lock);
272 ret = hdc100x_set_it_time(data, chan->address, val2);
273 mutex_unlock(&data->lock);
274 return ret;
275 case IIO_CHAN_INFO_RAW:
276 if (chan->type != IIO_CURRENT || val2 != 0)
277 return -EINVAL;
278
279 mutex_lock(&data->lock);
280 ret = hdc100x_update_config(data, HDC100X_REG_CONFIG_HEATER_EN,
281 val ? HDC100X_REG_CONFIG_HEATER_EN : 0);
282 mutex_unlock(&data->lock);
283 return ret;
284 default:
285 return -EINVAL;
286 }
287}
288
289static int hdc100x_buffer_postenable(struct iio_dev *indio_dev)
290{
291 struct hdc100x_data *data = iio_priv(indio_dev);
292 int ret;
293
294 /* Buffer is enabled. First set ACQ Mode, then attach poll func */
295 mutex_lock(&data->lock);
296 ret = hdc100x_update_config(data, HDC100X_REG_CONFIG_ACQ_MODE,
297 HDC100X_REG_CONFIG_ACQ_MODE);
298 mutex_unlock(&data->lock);
299 if (ret)
300 return ret;
301
302 return iio_triggered_buffer_postenable(indio_dev);
303}
304
305static int hdc100x_buffer_predisable(struct iio_dev *indio_dev)
306{
307 struct hdc100x_data *data = iio_priv(indio_dev);
308 int ret;
309
310 /* First detach poll func, then reset ACQ mode. OK to disable buffer */
311 ret = iio_triggered_buffer_predisable(indio_dev);
312 if (ret)
313 return ret;
314
315 mutex_lock(&data->lock);
316 ret = hdc100x_update_config(data, HDC100X_REG_CONFIG_ACQ_MODE, 0);
317 mutex_unlock(&data->lock);
318
319 return ret;
320}
321
322static const struct iio_buffer_setup_ops hdc_buffer_setup_ops = {
323 .postenable = hdc100x_buffer_postenable,
324 .predisable = hdc100x_buffer_predisable,
325};
326
327static irqreturn_t hdc100x_trigger_handler(int irq, void *p)
328{
329 struct iio_poll_func *pf = p;
330 struct iio_dev *indio_dev = pf->indio_dev;
331 struct hdc100x_data *data = iio_priv(indio_dev);
332 struct i2c_client *client = data->client;
333 int delay = data->adc_int_us[0] + data->adc_int_us[1];
334 int ret;
335
336 /* dual read starts at temp register */
337 mutex_lock(&data->lock);
338 ret = i2c_smbus_write_byte(client, HDC100X_REG_TEMP);
339 if (ret < 0) {
340 dev_err(&client->dev, "cannot start measurement\n");
341 goto err;
342 }
343 usleep_range(delay, delay + 1000);
344
345 ret = i2c_master_recv(client, (u8 *)data->scan.channels, 4);
346 if (ret < 0) {
347 dev_err(&client->dev, "cannot read sensor data\n");
348 goto err;
349 }
350
351 iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
352 iio_get_time_ns(indio_dev));
353err:
354 mutex_unlock(&data->lock);
355 iio_trigger_notify_done(indio_dev->trig);
356
357 return IRQ_HANDLED;
358}
359
360static const struct iio_info hdc100x_info = {
361 .read_raw = hdc100x_read_raw,
362 .write_raw = hdc100x_write_raw,
363 .attrs = &hdc100x_attribute_group,
364 .driver_module = THIS_MODULE,
365};
366
367static int hdc100x_probe(struct i2c_client *client,
368 const struct i2c_device_id *id)
369{
370 struct iio_dev *indio_dev;
371 struct hdc100x_data *data;
372 int ret;
373
374 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA |
375 I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
376 return -EOPNOTSUPP;
377
378 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
379 if (!indio_dev)
380 return -ENOMEM;
381
382 data = iio_priv(indio_dev);
383 i2c_set_clientdata(client, indio_dev);
384 data->client = client;
385 mutex_init(&data->lock);
386
387 indio_dev->dev.parent = &client->dev;
388 indio_dev->name = dev_name(&client->dev);
389 indio_dev->modes = INDIO_DIRECT_MODE;
390 indio_dev->info = &hdc100x_info;
391
392 indio_dev->channels = hdc100x_channels;
393 indio_dev->num_channels = ARRAY_SIZE(hdc100x_channels);
394 indio_dev->available_scan_masks = hdc100x_scan_masks;
395
396 /* be sure we are in a known state */
397 hdc100x_set_it_time(data, 0, hdc100x_int_time[0][0]);
398 hdc100x_set_it_time(data, 1, hdc100x_int_time[1][0]);
399 hdc100x_update_config(data, HDC100X_REG_CONFIG_ACQ_MODE, 0);
400
401 ret = iio_triggered_buffer_setup(indio_dev, NULL,
402 hdc100x_trigger_handler,
403 &hdc_buffer_setup_ops);
404 if (ret < 0) {
405 dev_err(&client->dev, "iio triggered buffer setup failed\n");
406 return ret;
407 }
408 ret = iio_device_register(indio_dev);
409 if (ret < 0)
410 iio_triggered_buffer_cleanup(indio_dev);
411
412 return ret;
413}
414
415static int hdc100x_remove(struct i2c_client *client)
416{
417 struct iio_dev *indio_dev = i2c_get_clientdata(client);
418
419 iio_device_unregister(indio_dev);
420 iio_triggered_buffer_cleanup(indio_dev);
421
422 return 0;
423}
424
425static const struct i2c_device_id hdc100x_id[] = {
426 { "hdc100x", 0 },
427 { "hdc1000", 0 },
428 { "hdc1008", 0 },
429 { "hdc1010", 0 },
430 { "hdc1050", 0 },
431 { "hdc1080", 0 },
432 { }
433};
434MODULE_DEVICE_TABLE(i2c, hdc100x_id);
435
436static const struct of_device_id hdc100x_dt_ids[] = {
437 { .compatible = "ti,hdc1000" },
438 { .compatible = "ti,hdc1008" },
439 { .compatible = "ti,hdc1010" },
440 { .compatible = "ti,hdc1050" },
441 { .compatible = "ti,hdc1080" },
442 { }
443};
444MODULE_DEVICE_TABLE(of, hdc100x_dt_ids);
445
446static struct i2c_driver hdc100x_driver = {
447 .driver = {
448 .name = "hdc100x",
449 .of_match_table = of_match_ptr(hdc100x_dt_ids),
450 },
451 .probe = hdc100x_probe,
452 .remove = hdc100x_remove,
453 .id_table = hdc100x_id,
454};
455module_i2c_driver(hdc100x_driver);
456
457MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>");
458MODULE_DESCRIPTION("TI HDC100x humidity and temperature sensor driver");
459MODULE_LICENSE("GPL");