aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio
diff options
context:
space:
mode:
authorPeter Meerwald <pmeerw@pmeerw.net>2014-02-05 11:57:00 -0500
committerJonathan Cameron <jic23@kernel.org>2014-05-03 06:38:13 -0400
commit474fe212e669b6c1698982041028f7727c879970 (patch)
tree5e3c5606c8d759914630c31abba98fe6993177d7 /drivers/iio
parent888c9c7366cef902531f27f6aa5fb787c86810d4 (diff)
iio: Add Melexis mlx90614 contact-less infrared temperature sensor driver
I2C-controlled sensor measures ambient and object temperatuer see http://www.melexis.com/Infrared-Thermometer-Sensors/Infrared-Thermometer-Sensors/MLX90614-615.aspx Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/temperature/Kconfig10
-rw-r--r--drivers/iio/temperature/Makefile1
-rw-r--r--drivers/iio/temperature/mlx90614.c150
3 files changed, 161 insertions, 0 deletions
diff --git a/drivers/iio/temperature/Kconfig b/drivers/iio/temperature/Kconfig
index 372f8fb3085f..21feaa4661b4 100644
--- a/drivers/iio/temperature/Kconfig
+++ b/drivers/iio/temperature/Kconfig
@@ -3,6 +3,16 @@
3# 3#
4menu "Temperature sensors" 4menu "Temperature sensors"
5 5
6config MLX90614
7 tristate "MLX90614 contact-less infrared sensor"
8 depends on I2C
9 help
10 If you say yes here you get support for the Melexis
11 MLX90614 contact-less infrared sensor connected with I2C.
12
13 This driver can also be built as a module. If so, the module will
14 be called mlx90614.
15
6config TMP006 16config TMP006
7 tristate "TMP006 infrared thermopile sensor" 17 tristate "TMP006 infrared thermopile sensor"
8 depends on I2C 18 depends on I2C
diff --git a/drivers/iio/temperature/Makefile b/drivers/iio/temperature/Makefile
index 24d7b602db3e..40710a81158e 100644
--- a/drivers/iio/temperature/Makefile
+++ b/drivers/iio/temperature/Makefile
@@ -2,4 +2,5 @@
2# Makefile for industrial I/O temperature drivers 2# Makefile for industrial I/O temperature drivers
3# 3#
4 4
5obj-$(CONFIG_MLX90614) += mlx90614.o
5obj-$(CONFIG_TMP006) += tmp006.o 6obj-$(CONFIG_TMP006) += tmp006.o
diff --git a/drivers/iio/temperature/mlx90614.c b/drivers/iio/temperature/mlx90614.c
new file mode 100644
index 000000000000..c8b6ac8b2d69
--- /dev/null
+++ b/drivers/iio/temperature/mlx90614.c
@@ -0,0 +1,150 @@
1/*
2 * mlx90614.c - Support for Melexis MLX90614 contactless IR temperature sensor
3 *
4 * Copyright (c) 2014 Peter Meerwald <pmeerw@pmeerw.net>
5 *
6 * This file is subject to the terms and conditions of version 2 of
7 * the GNU General Public License. See the file COPYING in the main
8 * directory of this archive for more details.
9 *
10 * Driver for the Melexis MLX90614 I2C 16-bit IR thermopile sensor
11 *
12 * (7-bit I2C slave address 0x5a, 100KHz bus speed only!)
13 *
14 * TODO: sleep mode, configuration EEPROM
15 */
16
17#include <linux/err.h>
18#include <linux/i2c.h>
19#include <linux/module.h>
20
21#include <linux/iio/iio.h>
22
23#define MLX90614_OP_RAM 0x00
24
25/* RAM offsets with 16-bit data, MSB first */
26#define MLX90614_TA 0x06 /* ambient temperature */
27#define MLX90614_TOBJ1 0x07 /* object temperature */
28
29struct mlx90614_data {
30 struct i2c_client *client;
31};
32
33static int mlx90614_read_raw(struct iio_dev *indio_dev,
34 struct iio_chan_spec const *channel, int *val,
35 int *val2, long mask)
36{
37 struct mlx90614_data *data = iio_priv(indio_dev);
38 s32 ret;
39
40 switch (mask) {
41 case IIO_CHAN_INFO_RAW: /* 0.02K / LSB */
42 switch (channel->channel2) {
43 case IIO_MOD_TEMP_AMBIENT:
44 ret = i2c_smbus_read_word_data(data->client,
45 MLX90614_OP_RAM | MLX90614_TA);
46 if (ret < 0)
47 return ret;
48 break;
49 case IIO_MOD_TEMP_OBJECT:
50 ret = i2c_smbus_read_word_data(data->client,
51 MLX90614_OP_RAM | MLX90614_TOBJ1);
52 if (ret < 0)
53 return ret;
54 break;
55 default:
56 return -EINVAL;
57 }
58 *val = ret;
59 return IIO_VAL_INT;
60 case IIO_CHAN_INFO_OFFSET:
61 *val = 13657;
62 *val2 = 500000;
63 return IIO_VAL_INT_PLUS_MICRO;
64 case IIO_CHAN_INFO_SCALE:
65 *val = 20;
66 return IIO_VAL_INT;
67 default:
68 return -EINVAL;
69 }
70}
71
72static const struct iio_chan_spec mlx90614_channels[] = {
73 {
74 .type = IIO_TEMP,
75 .modified = 1,
76 .channel2 = IIO_MOD_TEMP_AMBIENT,
77 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
78 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
79 BIT(IIO_CHAN_INFO_SCALE),
80 },
81 {
82 .type = IIO_TEMP,
83 .modified = 1,
84 .channel2 = IIO_MOD_TEMP_OBJECT,
85 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
86 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
87 BIT(IIO_CHAN_INFO_SCALE),
88 },
89};
90
91static const struct iio_info mlx90614_info = {
92 .read_raw = mlx90614_read_raw,
93 .driver_module = THIS_MODULE,
94};
95
96static int mlx90614_probe(struct i2c_client *client,
97 const struct i2c_device_id *id)
98{
99 struct iio_dev *indio_dev;
100 struct mlx90614_data *data;
101
102 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
103 return -ENODEV;
104
105 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
106 if (!indio_dev)
107 return -ENOMEM;
108
109 data = iio_priv(indio_dev);
110 i2c_set_clientdata(client, indio_dev);
111 data->client = client;
112
113 indio_dev->dev.parent = &client->dev;
114 indio_dev->name = id->name;
115 indio_dev->modes = INDIO_DIRECT_MODE;
116 indio_dev->info = &mlx90614_info;
117
118 indio_dev->channels = mlx90614_channels;
119 indio_dev->num_channels = ARRAY_SIZE(mlx90614_channels);
120
121 return iio_device_register(indio_dev);
122}
123
124static int mlx90614_remove(struct i2c_client *client)
125{
126 iio_device_unregister(i2c_get_clientdata(client));
127
128 return 0;
129}
130
131static const struct i2c_device_id mlx90614_id[] = {
132 { "mlx90614", 0 },
133 { }
134};
135MODULE_DEVICE_TABLE(i2c, mlx90614_id);
136
137static struct i2c_driver mlx90614_driver = {
138 .driver = {
139 .name = "mlx90614",
140 .owner = THIS_MODULE,
141 },
142 .probe = mlx90614_probe,
143 .remove = mlx90614_remove,
144 .id_table = mlx90614_id,
145};
146module_i2c_driver(mlx90614_driver);
147
148MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
149MODULE_DESCRIPTION("Melexis MLX90614 contactless IR temperature sensor driver");
150MODULE_LICENSE("GPL");