sunrise_co2.c 13 KB

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