File Index
Files and directories
Sign in
FILE

hdc100x.c

File preview with syntax highlighting.

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