1 // SPDX-License-Identifier: GPL-2.0+
3 * atlas-ezo-sensor.c - Support for Atlas Scientific EZO sensors
5 * Copyright (C) 2020 Konsulko Group
6 * Author: Matt Ranostay <matt.ranostay@konsulko.com>
9 #include <linux/module.h>
10 #include <linux/init.h>
11 #include <linux/delay.h>
12 #include <linux/mutex.h>
13 #include <linux/err.h>
14 #include <linux/i2c.h>
15 #include <linux/of_device.h>
16 #include <linux/iio/iio.h>
18 #define ATLAS_EZO_DRV_NAME "atlas-ezo-sensor"
19 #define ATLAS_CO2_INT_TIME_IN_MS 950
25 struct atlas_ezo_device {
26 const struct iio_chan_spec *channels;
31 struct atlas_ezo_data {
32 struct i2c_client *client;
33 struct atlas_ezo_device *chip;
35 /* lock to avoid multiple concurrent read calls */
41 static const struct iio_chan_spec atlas_co2_ezo_channels[] = {
43 .type = IIO_CONCENTRATION,
45 .channel2 = IIO_MOD_CO2,
47 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
53 .endianness = IIO_CPU,
58 static struct atlas_ezo_device atlas_ezo_devices[] = {
60 .channels = atlas_co2_ezo_channels,
62 .delay = ATLAS_CO2_INT_TIME_IN_MS,
66 static int atlas_ezo_read_raw(struct iio_dev *indio_dev,
67 struct iio_chan_spec const *chan,
68 int *val, int *val2, long mask)
70 struct atlas_ezo_data *data = iio_priv(indio_dev);
71 struct i2c_client *client = data->client;
73 if (chan->type != IIO_CONCENTRATION)
77 case IIO_CHAN_INFO_RAW: {
81 mutex_lock(&data->lock);
83 tmp = i2c_smbus_write_byte(client, 'R');
86 mutex_unlock(&data->lock);
90 msleep(data->chip->delay);
92 tmp = i2c_master_recv(client, data->buffer, sizeof(data->buffer));
94 if (tmp < 0 || data->buffer[0] != 1) {
95 mutex_unlock(&data->lock);
99 ret = kstrtol(data->buffer + 1, 10, &tmp);
103 mutex_unlock(&data->lock);
105 return ret ? ret : IIO_VAL_INT;
107 case IIO_CHAN_INFO_SCALE:
109 *val2 = 100; /* 0.0001 */
110 return IIO_VAL_INT_PLUS_MICRO;
116 static const struct iio_info atlas_info = {
117 .read_raw = atlas_ezo_read_raw,
120 static const struct i2c_device_id atlas_ezo_id[] = {
121 { "atlas-co2-ezo", ATLAS_CO2_EZO },
124 MODULE_DEVICE_TABLE(i2c, atlas_ezo_id);
126 static const struct of_device_id atlas_ezo_dt_ids[] = {
127 { .compatible = "atlas,co2-ezo", .data = (void *)ATLAS_CO2_EZO, },
130 MODULE_DEVICE_TABLE(of, atlas_ezo_dt_ids);
132 static int atlas_ezo_probe(struct i2c_client *client,
133 const struct i2c_device_id *id)
135 struct atlas_ezo_data *data;
136 struct atlas_ezo_device *chip;
137 const struct of_device_id *of_id;
138 struct iio_dev *indio_dev;
140 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
144 of_id = of_match_device(atlas_ezo_dt_ids, &client->dev);
146 chip = &atlas_ezo_devices[id->driver_data];
148 chip = &atlas_ezo_devices[(unsigned long)of_id->data];
150 indio_dev->info = &atlas_info;
151 indio_dev->name = ATLAS_EZO_DRV_NAME;
152 indio_dev->channels = chip->channels;
153 indio_dev->num_channels = chip->num_channels;
154 indio_dev->modes = INDIO_DIRECT_MODE;
156 data = iio_priv(indio_dev);
157 data->client = client;
159 mutex_init(&data->lock);
161 return devm_iio_device_register(&client->dev, indio_dev);
164 static struct i2c_driver atlas_ezo_driver = {
166 .name = ATLAS_EZO_DRV_NAME,
167 .of_match_table = atlas_ezo_dt_ids,
169 .probe = atlas_ezo_probe,
170 .id_table = atlas_ezo_id,
172 module_i2c_driver(atlas_ezo_driver);
174 MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>");
175 MODULE_DESCRIPTION("Atlas Scientific EZO sensors");
176 MODULE_LICENSE("GPL");