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 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 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 */ 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 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 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 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 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 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 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 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 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 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