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