1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Senseair Sunrise 006-0-0007 CO2 sensor driver.
4 *
5 * Copyright (C) 2021 Jacopo Mondi
6 *
7 * List of features not yet supported by the driver:
8 * - controllable EN pin
9 * - single-shot operations using the nDRY pin.
10 * - ABC/target calibration
11 */
12
13 #include <linux/bitops.h>
14 #include <linux/i2c.h>
15 #include <linux/kernel.h>
16 #include <linux/mod_devicetable.h>
17 #include <linux/module.h>
18 #include <linux/mutex.h>
19 #include <linux/regmap.h>
20 #include <linux/time64.h>
21
22 #include <linux/iio/iio.h>
23
24 #define DRIVER_NAME "sunrise_co2"
25
26 #define SUNRISE_ERROR_STATUS_REG 0x00
27 #define SUNRISE_CO2_FILTERED_COMP_REG 0x06
28 #define SUNRISE_CHIP_TEMPERATURE_REG 0x08
29 #define SUNRISE_CALIBRATION_STATUS_REG 0x81
30 #define SUNRISE_CALIBRATION_COMMAND_REG 0x82
31 #define SUNRISE_CALIBRATION_FACTORY_CMD 0x7c02
32 #define SUNRISE_CALIBRATION_BACKGROUND_CMD 0x7c06
33 /*
34 * The calibration timeout is not characterized in the datasheet.
35 * Use 30 seconds as a reasonable upper limit.
36 */
37 #define SUNRISE_CALIBRATION_TIMEOUT_US (30 * USEC_PER_SEC)
38
39 struct sunrise_dev {
40 struct i2c_client *client;
41 struct regmap *regmap;
42 /* Protects access to IIO attributes. */
43 struct mutex lock;
44 bool ignore_nak;
45 };
46
47 /* Custom regmap read/write operations: perform unlocked access to the i2c bus. */
48
sunrise_regmap_read(void * context,const void * reg_buf,size_t reg_size,void * val_buf,size_t val_size)49 static int sunrise_regmap_read(void *context, const void *reg_buf,
50 size_t reg_size, void *val_buf, size_t val_size)
51 {
52 struct i2c_client *client = context;
53 struct sunrise_dev *sunrise = i2c_get_clientdata(client);
54 union i2c_smbus_data data = { };
55 int ret;
56
57 if (reg_size != 1 || !val_size)
58 return -EINVAL;
59
60 data.block[0] = val_size;
61
62 /*
63 * Wake up sensor by sending sensor address: START, sensor address,
64 * STOP. Sensor will not ACK this byte.
65 *
66 * The chip enters a low power state after 15ms without
67 * communications or after a complete read/write sequence.
68 */
69 __i2c_smbus_xfer(client->adapter, client->addr,
70 sunrise->ignore_nak ? I2C_M_IGNORE_NAK : 0,
71 I2C_SMBUS_WRITE, 0, I2C_SMBUS_BYTE_DATA, &data);
72
73 usleep_range(500, 1500);
74
75 ret = __i2c_smbus_xfer(client->adapter, client->addr, client->flags,
76 I2C_SMBUS_READ, ((u8 *)reg_buf)[0],
77 I2C_SMBUS_I2C_BLOCK_DATA, &data);
78 if (ret < 0)
79 return ret;
80
81 memcpy(val_buf, &data.block[1], data.block[0]);
82
83 return 0;
84 }
85
sunrise_regmap_write(void * context,const void * val_buf,size_t count)86 static int sunrise_regmap_write(void *context, const void *val_buf, size_t count)
87 {
88 struct i2c_client *client = context;
89 struct sunrise_dev *sunrise = i2c_get_clientdata(client);
90 union i2c_smbus_data data = { };
91
92 /* Discard reg address from values count. */
93 if (!count)
94 return -EINVAL;
95 count--;
96
97 data.block[0] = count;
98 memcpy(&data.block[1], (u8 *)val_buf + 1, count);
99
100 __i2c_smbus_xfer(client->adapter, client->addr,
101 sunrise->ignore_nak ? I2C_M_IGNORE_NAK : 0,
102 I2C_SMBUS_WRITE, 0, I2C_SMBUS_BYTE_DATA, &data);
103
104 usleep_range(500, 1500);
105
106 return __i2c_smbus_xfer(client->adapter, client->addr, client->flags,
107 I2C_SMBUS_WRITE, ((u8 *)val_buf)[0],
108 I2C_SMBUS_I2C_BLOCK_DATA, &data);
109 }
110
111 /*
112 * Sunrise i2c read/write operations: lock the i2c segment to avoid losing the
113 * wake up session. Use custom regmap operations that perform unlocked access to
114 * the i2c bus.
115 */
sunrise_read_byte(struct sunrise_dev * sunrise,u8 reg)116 static int sunrise_read_byte(struct sunrise_dev *sunrise, u8 reg)
117 {
118 const struct i2c_client *client = sunrise->client;
119 const struct device *dev = &client->dev;
120 unsigned int val;
121 int ret;
122
123 i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT);
124 ret = regmap_read(sunrise->regmap, reg, &val);
125 i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT);
126 if (ret) {
127 dev_err(dev, "Read byte failed: reg 0x%02x (%d)\n", reg, ret);
128 return ret;
129 }
130
131 return val;
132 }
133
sunrise_read_word(struct sunrise_dev * sunrise,u8 reg,u16 * val)134 static int sunrise_read_word(struct sunrise_dev *sunrise, u8 reg, u16 *val)
135 {
136 const struct i2c_client *client = sunrise->client;
137 const struct device *dev = &client->dev;
138 __be16 be_val;
139 int ret;
140
141 i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT);
142 ret = regmap_bulk_read(sunrise->regmap, reg, &be_val, sizeof(be_val));
143 i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT);
144 if (ret) {
145 dev_err(dev, "Read word failed: reg 0x%02x (%d)\n", reg, ret);
146 return ret;
147 }
148
149 *val = be16_to_cpu(be_val);
150
151 return 0;
152 }
153
sunrise_write_byte(struct sunrise_dev * sunrise,u8 reg,u8 val)154 static int sunrise_write_byte(struct sunrise_dev *sunrise, u8 reg, u8 val)
155 {
156 const struct i2c_client *client = sunrise->client;
157 const struct device *dev = &client->dev;
158 int ret;
159
160 i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT);
161 ret = regmap_write(sunrise->regmap, reg, val);
162 i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT);
163 if (ret)
164 dev_err(dev, "Write byte failed: reg 0x%02x (%d)\n", reg, ret);
165
166 return ret;
167 }
168
sunrise_write_word(struct sunrise_dev * sunrise,u8 reg,u16 data)169 static int sunrise_write_word(struct sunrise_dev *sunrise, u8 reg, u16 data)
170 {
171 const struct i2c_client *client = sunrise->client;
172 const struct device *dev = &client->dev;
173 __be16 be_data = cpu_to_be16(data);
174 int ret;
175
176 i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT);
177 ret = regmap_bulk_write(sunrise->regmap, reg, &be_data, sizeof(be_data));
178 i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT);
179 if (ret)
180 dev_err(dev, "Write word failed: reg 0x%02x (%d)\n", reg, ret);
181
182 return ret;
183 }
184
185 /* Trigger a calibration cycle. */
186
187 enum {
188 SUNRISE_CALIBRATION_FACTORY,
189 SUNRISE_CALIBRATION_BACKGROUND,
190 };
191
192 static const struct sunrise_calib_data {
193 u16 cmd;
194 u8 bit;
195 const char * const name;
196 } calib_data[] = {
197 [SUNRISE_CALIBRATION_FACTORY] = {
198 SUNRISE_CALIBRATION_FACTORY_CMD,
199 BIT(2),
200 "factory_calibration",
201 },
202 [SUNRISE_CALIBRATION_BACKGROUND] = {
203 SUNRISE_CALIBRATION_BACKGROUND_CMD,
204 BIT(5),
205 "background_calibration",
206 },
207 };
208
sunrise_calibrate(struct sunrise_dev * sunrise,const struct sunrise_calib_data * data)209 static int sunrise_calibrate(struct sunrise_dev *sunrise,
210 const struct sunrise_calib_data *data)
211 {
212 unsigned int status;
213 int ret;
214
215 /* Reset the calibration status reg. */
216 ret = sunrise_write_byte(sunrise, SUNRISE_CALIBRATION_STATUS_REG, 0x00);
217 if (ret)
218 return ret;
219
220 /* Write a calibration command and poll the calibration status bit. */
221 ret = sunrise_write_word(sunrise, SUNRISE_CALIBRATION_COMMAND_REG, data->cmd);
222 if (ret)
223 return ret;
224
225 dev_dbg(&sunrise->client->dev, "%s in progress\n", data->name);
226
227 /*
228 * Calibration takes several seconds, so the sleep time between reads
229 * can be pretty relaxed.
230 */
231 return read_poll_timeout(sunrise_read_byte, status, status & data->bit,
232 200000, SUNRISE_CALIBRATION_TIMEOUT_US, false,
233 sunrise, SUNRISE_CALIBRATION_STATUS_REG);
234 }
235
sunrise_cal_factory_write(struct iio_dev * iiodev,uintptr_t private,const struct iio_chan_spec * chan,const char * buf,size_t len)236 static ssize_t sunrise_cal_factory_write(struct iio_dev *iiodev,
237 uintptr_t private,
238 const struct iio_chan_spec *chan,
239 const char *buf, size_t len)
240 {
241 struct sunrise_dev *sunrise = iio_priv(iiodev);
242 bool enable;
243 int ret;
244
245 ret = kstrtobool(buf, &enable);
246 if (ret)
247 return ret;
248
249 if (!enable)
250 return len;
251
252 mutex_lock(&sunrise->lock);
253 ret = sunrise_calibrate(sunrise, &calib_data[SUNRISE_CALIBRATION_FACTORY]);
254 mutex_unlock(&sunrise->lock);
255 if (ret)
256 return ret;
257
258 return len;
259 }
260
sunrise_cal_background_write(struct iio_dev * iiodev,uintptr_t private,const struct iio_chan_spec * chan,const char * buf,size_t len)261 static ssize_t sunrise_cal_background_write(struct iio_dev *iiodev,
262 uintptr_t private,
263 const struct iio_chan_spec *chan,
264 const char *buf, size_t len)
265 {
266 struct sunrise_dev *sunrise = iio_priv(iiodev);
267 bool enable;
268 int ret;
269
270 ret = kstrtobool(buf, &enable);
271 if (ret)
272 return ret;
273
274 if (!enable)
275 return len;
276
277 mutex_lock(&sunrise->lock);
278 ret = sunrise_calibrate(sunrise, &calib_data[SUNRISE_CALIBRATION_BACKGROUND]);
279 mutex_unlock(&sunrise->lock);
280 if (ret)
281 return ret;
282
283 return len;
284 }
285
286 /* Enumerate and retrieve the chip error status. */
287 enum {
288 SUNRISE_ERROR_FATAL,
289 SUNRISE_ERROR_I2C,
290 SUNRISE_ERROR_ALGORITHM,
291 SUNRISE_ERROR_CALIBRATION,
292 SUNRISE_ERROR_SELF_DIAGNOSTIC,
293 SUNRISE_ERROR_OUT_OF_RANGE,
294 SUNRISE_ERROR_MEMORY,
295 SUNRISE_ERROR_NO_MEASUREMENT,
296 SUNRISE_ERROR_LOW_VOLTAGE,
297 SUNRISE_ERROR_MEASUREMENT_TIMEOUT,
298 };
299
300 static const char * const sunrise_error_statuses[] = {
301 [SUNRISE_ERROR_FATAL] = "error_fatal",
302 [SUNRISE_ERROR_I2C] = "error_i2c",
303 [SUNRISE_ERROR_ALGORITHM] = "error_algorithm",
304 [SUNRISE_ERROR_CALIBRATION] = "error_calibration",
305 [SUNRISE_ERROR_SELF_DIAGNOSTIC] = "error_self_diagnostic",
306 [SUNRISE_ERROR_OUT_OF_RANGE] = "error_out_of_range",
307 [SUNRISE_ERROR_MEMORY] = "error_memory",
308 [SUNRISE_ERROR_NO_MEASUREMENT] = "error_no_measurement",
309 [SUNRISE_ERROR_LOW_VOLTAGE] = "error_low_voltage",
310 [SUNRISE_ERROR_MEASUREMENT_TIMEOUT] = "error_measurement_timeout",
311 };
312
313 static const struct iio_enum sunrise_error_statuses_enum = {
314 .items = sunrise_error_statuses,
315 .num_items = ARRAY_SIZE(sunrise_error_statuses),
316 };
317
sunrise_error_status_read(struct iio_dev * iiodev,uintptr_t private,const struct iio_chan_spec * chan,char * buf)318 static ssize_t sunrise_error_status_read(struct iio_dev *iiodev,
319 uintptr_t private,
320 const struct iio_chan_spec *chan,
321 char *buf)
322 {
323 struct sunrise_dev *sunrise = iio_priv(iiodev);
324 unsigned long errors;
325 ssize_t len = 0;
326 u16 value;
327 int ret;
328 u8 i;
329
330 mutex_lock(&sunrise->lock);
331 ret = sunrise_read_word(sunrise, SUNRISE_ERROR_STATUS_REG, &value);
332 if (ret) {
333 mutex_unlock(&sunrise->lock);
334 return ret;
335 }
336
337 errors = value;
338 for_each_set_bit(i, &errors, ARRAY_SIZE(sunrise_error_statuses))
339 len += sysfs_emit_at(buf, len, "%s ", sunrise_error_statuses[i]);
340
341 if (len)
342 buf[len - 1] = '\n';
343
344 mutex_unlock(&sunrise->lock);
345
346 return len;
347 }
348
349 static const struct iio_chan_spec_ext_info sunrise_concentration_ext_info[] = {
350 /* Calibration triggers. */
351 {
352 .name = "calibration_factory",
353 .write = sunrise_cal_factory_write,
354 .shared = IIO_SEPARATE,
355 },
356 {
357 .name = "calibration_background",
358 .write = sunrise_cal_background_write,
359 .shared = IIO_SEPARATE,
360 },
361
362 /* Error statuses. */
363 {
364 .name = "error_status",
365 .read = sunrise_error_status_read,
366 .shared = IIO_SHARED_BY_ALL,
367 },
368 {
369 .name = "error_status_available",
370 .shared = IIO_SHARED_BY_ALL,
371 .read = iio_enum_available_read,
372 .private = (uintptr_t)&sunrise_error_statuses_enum,
373 },
374 { }
375 };
376
377 static const struct iio_chan_spec sunrise_channels[] = {
378 {
379 .type = IIO_CONCENTRATION,
380 .modified = 1,
381 .channel2 = IIO_MOD_CO2,
382 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
383 BIT(IIO_CHAN_INFO_SCALE),
384 .ext_info = sunrise_concentration_ext_info,
385 },
386 {
387 .type = IIO_TEMP,
388 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
389 BIT(IIO_CHAN_INFO_SCALE),
390 },
391 };
392
sunrise_read_raw(struct iio_dev * iio_dev,const struct iio_chan_spec * chan,int * val,int * val2,long mask)393 static int sunrise_read_raw(struct iio_dev *iio_dev,
394 const struct iio_chan_spec *chan,
395 int *val, int *val2, long mask)
396 {
397 struct sunrise_dev *sunrise = iio_priv(iio_dev);
398 u16 value;
399 int ret;
400
401 switch (mask) {
402 case IIO_CHAN_INFO_RAW:
403 switch (chan->type) {
404 case IIO_CONCENTRATION:
405 mutex_lock(&sunrise->lock);
406 ret = sunrise_read_word(sunrise, SUNRISE_CO2_FILTERED_COMP_REG,
407 &value);
408 mutex_unlock(&sunrise->lock);
409
410 if (ret)
411 return ret;
412
413 *val = value;
414 return IIO_VAL_INT;
415
416 case IIO_TEMP:
417 mutex_lock(&sunrise->lock);
418 ret = sunrise_read_word(sunrise, SUNRISE_CHIP_TEMPERATURE_REG,
419 &value);
420 mutex_unlock(&sunrise->lock);
421
422 if (ret)
423 return ret;
424
425 *val = value;
426 return IIO_VAL_INT;
427
428 default:
429 return -EINVAL;
430 }
431
432 case IIO_CHAN_INFO_SCALE:
433 switch (chan->type) {
434 case IIO_CONCENTRATION:
435 /*
436 * 1 / 10^4 to comply with IIO scale for CO2
437 * (percentage). The chip CO2 reading range is [400 -
438 * 5000] ppm which corresponds to [0,004 - 0,5] %.
439 */
440 *val = 1;
441 *val2 = 10000;
442 return IIO_VAL_FRACTIONAL;
443
444 case IIO_TEMP:
445 /* x10 to comply with IIO scale (millidegrees celsius). */
446 *val = 10;
447 return IIO_VAL_INT;
448
449 default:
450 return -EINVAL;
451 }
452
453 default:
454 return -EINVAL;
455 }
456 }
457
458 static const struct iio_info sunrise_info = {
459 .read_raw = sunrise_read_raw,
460 };
461
462 static const struct regmap_bus sunrise_regmap_bus = {
463 .read = sunrise_regmap_read,
464 .write = sunrise_regmap_write,
465 };
466
467 static const struct regmap_config sunrise_regmap_config = {
468 .reg_bits = 8,
469 .val_bits = 8,
470 };
471
sunrise_probe(struct i2c_client * client)472 static int sunrise_probe(struct i2c_client *client)
473 {
474 struct sunrise_dev *sunrise;
475 struct iio_dev *iio_dev;
476
477 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
478 I2C_FUNC_SMBUS_BLOCK_DATA)) {
479 dev_err(&client->dev,
480 "Adapter does not support required functionalities\n");
481 return -EOPNOTSUPP;
482 }
483
484 iio_dev = devm_iio_device_alloc(&client->dev, sizeof(*sunrise));
485 if (!iio_dev)
486 return -ENOMEM;
487
488 sunrise = iio_priv(iio_dev);
489 sunrise->client = client;
490 mutex_init(&sunrise->lock);
491
492 i2c_set_clientdata(client, sunrise);
493
494 sunrise->regmap = devm_regmap_init(&client->dev, &sunrise_regmap_bus,
495 client, &sunrise_regmap_config);
496 if (IS_ERR(sunrise->regmap)) {
497 dev_err(&client->dev, "Failed to initialize regmap\n");
498 return PTR_ERR(sunrise->regmap);
499 }
500
501 /*
502 * The chip nacks the wake up message. If the adapter does not support
503 * protocol mangling do not set the I2C_M_IGNORE_NAK flag at the expense
504 * of possible cruft in the logs.
505 */
506 if (i2c_check_functionality(client->adapter, I2C_FUNC_PROTOCOL_MANGLING))
507 sunrise->ignore_nak = true;
508
509 iio_dev->info = &sunrise_info;
510 iio_dev->name = DRIVER_NAME;
511 iio_dev->channels = sunrise_channels;
512 iio_dev->num_channels = ARRAY_SIZE(sunrise_channels);
513 iio_dev->modes = INDIO_DIRECT_MODE;
514
515 return devm_iio_device_register(&client->dev, iio_dev);
516 }
517
518 static const struct of_device_id sunrise_of_match[] = {
519 { .compatible = "senseair,sunrise-006-0-0007" },
520 { }
521 };
522 MODULE_DEVICE_TABLE(of, sunrise_of_match);
523
524 static struct i2c_driver sunrise_driver = {
525 .driver = {
526 .name = DRIVER_NAME,
527 .of_match_table = sunrise_of_match,
528 },
529 .probe = sunrise_probe,
530 };
531 module_i2c_driver(sunrise_driver);
532
533 MODULE_AUTHOR("Jacopo Mondi <jacopo@jmondi.org>");
534 MODULE_DESCRIPTION("Senseair Sunrise 006-0-0007 CO2 sensor IIO driver");
535 MODULE_LICENSE("GPL v2");
536