xref: /linux/drivers/iio/temperature/tmp006.c (revision 7f71507851fc7764b36a3221839607d3a45c2025)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * tmp006.c - Support for TI TMP006 IR thermopile sensor
4  *
5  * Copyright (c) 2013 Peter Meerwald <pmeerw@pmeerw.net>
6  *
7  * Driver for the Texas Instruments I2C 16-bit IR thermopile sensor
8  *
9  * (7-bit I2C slave address 0x40, changeable via ADR pins)
10  */
11 
12 #include <linux/err.h>
13 #include <linux/i2c.h>
14 #include <linux/delay.h>
15 #include <linux/module.h>
16 #include <linux/mod_devicetable.h>
17 #include <linux/pm.h>
18 #include <linux/bitops.h>
19 
20 #include <linux/iio/iio.h>
21 #include <linux/iio/sysfs.h>
22 #include <linux/iio/trigger.h>
23 #include <linux/iio/triggered_buffer.h>
24 #include <linux/iio/trigger_consumer.h>
25 
26 #define TMP006_VOBJECT 0x00
27 #define TMP006_TAMBIENT 0x01
28 #define TMP006_CONFIG 0x02
29 #define TMP006_MANUFACTURER_ID 0xfe
30 #define TMP006_DEVICE_ID 0xff
31 
32 #define TMP006_TAMBIENT_SHIFT 2
33 
34 #define TMP006_CONFIG_RESET BIT(15)
35 #define TMP006_CONFIG_DRDY_EN BIT(8)
36 #define TMP006_CONFIG_DRDY BIT(7)
37 
38 #define TMP006_CONFIG_MOD_MASK GENMASK(14, 12)
39 
40 #define TMP006_CONFIG_CR_MASK GENMASK(11, 9)
41 #define TMP006_CONFIG_CR_SHIFT 9
42 
43 #define TMP006_MANUFACTURER_MAGIC 0x5449
44 #define TMP006_DEVICE_MAGIC 0x0067
45 
46 struct tmp006_data {
47 	struct i2c_client *client;
48 	u16 config;
49 	struct iio_trigger *drdy_trig;
50 };
51 
52 static int tmp006_read_measurement(struct tmp006_data *data, u8 reg)
53 {
54 	s32 ret;
55 	int tries = 50;
56 
57 	while (tries-- > 0) {
58 		ret = i2c_smbus_read_word_swapped(data->client,
59 			TMP006_CONFIG);
60 		if (ret < 0)
61 			return ret;
62 		if (ret & TMP006_CONFIG_DRDY)
63 			break;
64 		msleep(100);
65 	}
66 
67 	if (tries < 0)
68 		return -EIO;
69 
70 	return i2c_smbus_read_word_swapped(data->client, reg);
71 }
72 
73 static const int tmp006_freqs[5][2] = { {4, 0}, {2, 0}, {1, 0},
74 					{0, 500000}, {0, 250000} };
75 
76 static int tmp006_read_raw(struct iio_dev *indio_dev,
77 			    struct iio_chan_spec const *channel, int *val,
78 			    int *val2, long mask)
79 {
80 	struct tmp006_data *data = iio_priv(indio_dev);
81 	s32 ret;
82 	int cr;
83 
84 	switch (mask) {
85 	case IIO_CHAN_INFO_RAW:
86 		if (channel->type == IIO_VOLTAGE) {
87 			/* LSB is 156.25 nV */
88 			iio_device_claim_direct_scoped(return -EBUSY, indio_dev) {
89 				ret = tmp006_read_measurement(data, TMP006_VOBJECT);
90 				if (ret < 0)
91 					return ret;
92 			}
93 			*val = sign_extend32(ret, 15);
94 		} else if (channel->type == IIO_TEMP) {
95 			/* LSB is 0.03125 degrees Celsius */
96 			iio_device_claim_direct_scoped(return -EBUSY, indio_dev) {
97 				ret = tmp006_read_measurement(data, TMP006_TAMBIENT);
98 				if (ret < 0)
99 					return ret;
100 			}
101 			*val = sign_extend32(ret, 15) >> TMP006_TAMBIENT_SHIFT;
102 		} else {
103 			break;
104 		}
105 		return IIO_VAL_INT;
106 	case IIO_CHAN_INFO_SCALE:
107 		if (channel->type == IIO_VOLTAGE) {
108 			*val = 0;
109 			*val2 = 156250;
110 		} else if (channel->type == IIO_TEMP) {
111 			*val = 31;
112 			*val2 = 250000;
113 		} else {
114 			break;
115 		}
116 		return IIO_VAL_INT_PLUS_MICRO;
117 	case IIO_CHAN_INFO_SAMP_FREQ:
118 		cr = (data->config & TMP006_CONFIG_CR_MASK)
119 			>> TMP006_CONFIG_CR_SHIFT;
120 		*val = tmp006_freqs[cr][0];
121 		*val2 = tmp006_freqs[cr][1];
122 		return IIO_VAL_INT_PLUS_MICRO;
123 	default:
124 		break;
125 	}
126 
127 	return -EINVAL;
128 }
129 
130 static int tmp006_write_raw(struct iio_dev *indio_dev,
131 			    struct iio_chan_spec const *chan,
132 			    int val,
133 			    int val2,
134 			    long mask)
135 {
136 	struct tmp006_data *data = iio_priv(indio_dev);
137 	int ret, i;
138 
139 	if (mask != IIO_CHAN_INFO_SAMP_FREQ)
140 		return -EINVAL;
141 
142 	for (i = 0; i < ARRAY_SIZE(tmp006_freqs); i++)
143 		if ((val == tmp006_freqs[i][0]) &&
144 		    (val2 == tmp006_freqs[i][1])) {
145 			ret = iio_device_claim_direct_mode(indio_dev);
146 			if (ret)
147 				return ret;
148 
149 			data->config &= ~TMP006_CONFIG_CR_MASK;
150 			data->config |= i << TMP006_CONFIG_CR_SHIFT;
151 
152 			ret = i2c_smbus_write_word_swapped(data->client,
153 							   TMP006_CONFIG,
154 							   data->config);
155 
156 			iio_device_release_direct_mode(indio_dev);
157 			return ret;
158 		}
159 	return -EINVAL;
160 }
161 
162 static IIO_CONST_ATTR(sampling_frequency_available, "4 2 1 0.5 0.25");
163 
164 static struct attribute *tmp006_attributes[] = {
165 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
166 	NULL
167 };
168 
169 static const struct attribute_group tmp006_attribute_group = {
170 	.attrs = tmp006_attributes,
171 };
172 
173 static const struct iio_chan_spec tmp006_channels[] = {
174 	{
175 		.type = IIO_VOLTAGE,
176 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
177 			BIT(IIO_CHAN_INFO_SCALE),
178 		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
179 		.scan_index = 0,
180 		.scan_type = {
181 			.sign = 's',
182 			.realbits = 16,
183 			.storagebits = 16,
184 			.endianness = IIO_BE,
185 		}
186 	},
187 	{
188 		.type = IIO_TEMP,
189 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
190 			BIT(IIO_CHAN_INFO_SCALE),
191 		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
192 		.scan_index = 1,
193 		.scan_type = {
194 			.sign = 's',
195 			.realbits = 14,
196 			.storagebits = 16,
197 			.shift = TMP006_TAMBIENT_SHIFT,
198 			.endianness = IIO_BE,
199 		}
200 	},
201 	IIO_CHAN_SOFT_TIMESTAMP(2),
202 };
203 
204 static const struct iio_info tmp006_info = {
205 	.read_raw = tmp006_read_raw,
206 	.write_raw = tmp006_write_raw,
207 	.attrs = &tmp006_attribute_group,
208 };
209 
210 static bool tmp006_check_identification(struct i2c_client *client)
211 {
212 	int mid, did;
213 
214 	mid = i2c_smbus_read_word_swapped(client, TMP006_MANUFACTURER_ID);
215 	if (mid < 0)
216 		return false;
217 
218 	did = i2c_smbus_read_word_swapped(client, TMP006_DEVICE_ID);
219 	if (did < 0)
220 		return false;
221 
222 	return mid == TMP006_MANUFACTURER_MAGIC && did == TMP006_DEVICE_MAGIC;
223 }
224 
225 static int tmp006_power(struct device *dev, bool up)
226 {
227 	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
228 	struct tmp006_data *data = iio_priv(indio_dev);
229 
230 	if (up)
231 		data->config |= TMP006_CONFIG_MOD_MASK;
232 	else
233 		data->config &= ~TMP006_CONFIG_MOD_MASK;
234 
235 	return i2c_smbus_write_word_swapped(data->client, TMP006_CONFIG,
236 		data->config);
237 }
238 
239 static void tmp006_powerdown_cleanup(void *dev)
240 {
241 	tmp006_power(dev, false);
242 }
243 
244 static irqreturn_t tmp006_trigger_handler(int irq, void *p)
245 {
246 	struct iio_poll_func *pf = p;
247 	struct iio_dev *indio_dev = pf->indio_dev;
248 	struct tmp006_data *data = iio_priv(indio_dev);
249 	struct {
250 		s16 channels[2];
251 		s64 ts __aligned(8);
252 	} scan;
253 	s32 ret;
254 
255 	ret = i2c_smbus_read_word_data(data->client, TMP006_VOBJECT);
256 	if (ret < 0)
257 		goto err;
258 	scan.channels[0] = ret;
259 
260 	ret = i2c_smbus_read_word_data(data->client, TMP006_TAMBIENT);
261 	if (ret < 0)
262 		goto err;
263 	scan.channels[1] = ret;
264 
265 	iio_push_to_buffers_with_timestamp(indio_dev, &scan,
266 					   iio_get_time_ns(indio_dev));
267 err:
268 	iio_trigger_notify_done(indio_dev->trig);
269 	return IRQ_HANDLED;
270 }
271 
272 static int tmp006_set_trigger_state(struct iio_trigger *trig, bool state)
273 {
274 	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
275 	struct tmp006_data *data = iio_priv(indio_dev);
276 
277 	if (state)
278 		data->config |= TMP006_CONFIG_DRDY_EN;
279 	else
280 		data->config &= ~TMP006_CONFIG_DRDY_EN;
281 
282 	return i2c_smbus_write_word_swapped(data->client, TMP006_CONFIG,
283 					    data->config);
284 }
285 
286 static const struct iio_trigger_ops tmp006_trigger_ops = {
287 	.set_trigger_state = tmp006_set_trigger_state,
288 };
289 
290 static const unsigned long tmp006_scan_masks[] = { 0x3, 0 };
291 
292 static int tmp006_probe(struct i2c_client *client)
293 {
294 	struct iio_dev *indio_dev;
295 	struct tmp006_data *data;
296 	int ret;
297 
298 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
299 		return -EOPNOTSUPP;
300 
301 	if (!tmp006_check_identification(client)) {
302 		dev_err(&client->dev, "no TMP006 sensor\n");
303 		return -ENODEV;
304 	}
305 
306 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
307 	if (!indio_dev)
308 		return -ENOMEM;
309 
310 	data = iio_priv(indio_dev);
311 	i2c_set_clientdata(client, indio_dev);
312 	data->client = client;
313 
314 	indio_dev->name = dev_name(&client->dev);
315 	indio_dev->modes = INDIO_DIRECT_MODE;
316 	indio_dev->info = &tmp006_info;
317 
318 	indio_dev->channels = tmp006_channels;
319 	indio_dev->num_channels = ARRAY_SIZE(tmp006_channels);
320 	indio_dev->available_scan_masks = tmp006_scan_masks;
321 
322 	ret = i2c_smbus_read_word_swapped(data->client, TMP006_CONFIG);
323 	if (ret < 0)
324 		return ret;
325 	data->config = ret;
326 
327 	if ((ret & TMP006_CONFIG_MOD_MASK) != TMP006_CONFIG_MOD_MASK) {
328 		ret = tmp006_power(&client->dev, true);
329 		if (ret < 0)
330 			return ret;
331 	}
332 
333 	ret = devm_add_action_or_reset(&client->dev, tmp006_powerdown_cleanup,
334 				       &client->dev);
335 	if (ret < 0)
336 		return ret;
337 
338 	if (client->irq > 0) {
339 		data->drdy_trig = devm_iio_trigger_alloc(&client->dev,
340 							 "%s-dev%d",
341 							 indio_dev->name,
342 							 iio_device_id(indio_dev));
343 		if (!data->drdy_trig)
344 			return -ENOMEM;
345 
346 		data->drdy_trig->ops = &tmp006_trigger_ops;
347 		iio_trigger_set_drvdata(data->drdy_trig, indio_dev);
348 		ret = iio_trigger_register(data->drdy_trig);
349 		if (ret)
350 			return ret;
351 
352 		indio_dev->trig = iio_trigger_get(data->drdy_trig);
353 
354 		ret = devm_request_threaded_irq(&client->dev, client->irq,
355 						iio_trigger_generic_data_rdy_poll,
356 						NULL,
357 						IRQF_ONESHOT,
358 						"tmp006_irq",
359 						data->drdy_trig);
360 		if (ret < 0)
361 			return ret;
362 	}
363 
364 	ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev, NULL,
365 					      tmp006_trigger_handler, NULL);
366 	if (ret < 0)
367 		return ret;
368 
369 	return devm_iio_device_register(&client->dev, indio_dev);
370 }
371 
372 static int tmp006_suspend(struct device *dev)
373 {
374 	return tmp006_power(dev, false);
375 }
376 
377 static int tmp006_resume(struct device *dev)
378 {
379 	return tmp006_power(dev, true);
380 }
381 
382 static DEFINE_SIMPLE_DEV_PM_OPS(tmp006_pm_ops, tmp006_suspend, tmp006_resume);
383 
384 static const struct of_device_id tmp006_of_match[] = {
385 	{ .compatible = "ti,tmp006" },
386 	{ }
387 };
388 MODULE_DEVICE_TABLE(of, tmp006_of_match);
389 
390 static const struct i2c_device_id tmp006_id[] = {
391 	{ "tmp006" },
392 	{ }
393 };
394 MODULE_DEVICE_TABLE(i2c, tmp006_id);
395 
396 static struct i2c_driver tmp006_driver = {
397 	.driver = {
398 		.name	= "tmp006",
399 		.of_match_table = tmp006_of_match,
400 		.pm	= pm_sleep_ptr(&tmp006_pm_ops),
401 	},
402 	.probe = tmp006_probe,
403 	.id_table = tmp006_id,
404 };
405 module_i2c_driver(tmp006_driver);
406 
407 MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
408 MODULE_DESCRIPTION("TI TMP006 IR thermopile sensor driver");
409 MODULE_LICENSE("GPL");
410