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