pms7003.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Plantower PMS7003 particulate matter sensor driver
  4. *
  5. * Copyright (c) Tomasz Duszynski <[email protected]>
  6. */
  7. #include <asm/unaligned.h>
  8. #include <linux/completion.h>
  9. #include <linux/device.h>
  10. #include <linux/errno.h>
  11. #include <linux/iio/buffer.h>
  12. #include <linux/iio/iio.h>
  13. #include <linux/iio/trigger_consumer.h>
  14. #include <linux/iio/triggered_buffer.h>
  15. #include <linux/jiffies.h>
  16. #include <linux/kernel.h>
  17. #include <linux/mod_devicetable.h>
  18. #include <linux/module.h>
  19. #include <linux/mutex.h>
  20. #include <linux/serdev.h>
  21. #define PMS7003_DRIVER_NAME "pms7003"
  22. #define PMS7003_MAGIC 0x424d
  23. /* last 2 data bytes hold frame checksum */
  24. #define PMS7003_MAX_DATA_LENGTH 28
  25. #define PMS7003_CHECKSUM_LENGTH 2
  26. #define PMS7003_PM10_OFFSET 10
  27. #define PMS7003_PM2P5_OFFSET 8
  28. #define PMS7003_PM1_OFFSET 6
  29. #define PMS7003_TIMEOUT msecs_to_jiffies(6000)
  30. #define PMS7003_CMD_LENGTH 7
  31. #define PMS7003_PM_MAX 1000
  32. #define PMS7003_PM_MIN 0
  33. enum {
  34. PM1,
  35. PM2P5,
  36. PM10,
  37. };
  38. enum pms7003_cmd {
  39. CMD_WAKEUP,
  40. CMD_ENTER_PASSIVE_MODE,
  41. CMD_READ_PASSIVE,
  42. CMD_SLEEP,
  43. };
  44. /*
  45. * commands have following format:
  46. *
  47. * +------+------+-----+------+-----+-----------+-----------+
  48. * | 0x42 | 0x4d | cmd | 0x00 | arg | cksum msb | cksum lsb |
  49. * +------+------+-----+------+-----+-----------+-----------+
  50. */
  51. static const u8 pms7003_cmd_tbl[][PMS7003_CMD_LENGTH] = {
  52. [CMD_WAKEUP] = { 0x42, 0x4d, 0xe4, 0x00, 0x01, 0x01, 0x74 },
  53. [CMD_ENTER_PASSIVE_MODE] = { 0x42, 0x4d, 0xe1, 0x00, 0x00, 0x01, 0x70 },
  54. [CMD_READ_PASSIVE] = { 0x42, 0x4d, 0xe2, 0x00, 0x00, 0x01, 0x71 },
  55. [CMD_SLEEP] = { 0x42, 0x4d, 0xe4, 0x00, 0x00, 0x01, 0x73 },
  56. };
  57. struct pms7003_frame {
  58. u8 data[PMS7003_MAX_DATA_LENGTH];
  59. u16 expected_length;
  60. u16 length;
  61. };
  62. struct pms7003_state {
  63. struct serdev_device *serdev;
  64. struct pms7003_frame frame;
  65. struct completion frame_ready;
  66. struct mutex lock; /* must be held whenever state gets touched */
  67. /* Used to construct scan to push to the IIO buffer */
  68. struct {
  69. u16 data[3]; /* PM1, PM2P5, PM10 */
  70. s64 ts;
  71. } scan;
  72. };
  73. static int pms7003_do_cmd(struct pms7003_state *state, enum pms7003_cmd cmd)
  74. {
  75. int ret;
  76. ret = serdev_device_write(state->serdev, pms7003_cmd_tbl[cmd],
  77. PMS7003_CMD_LENGTH, PMS7003_TIMEOUT);
  78. if (ret < PMS7003_CMD_LENGTH)
  79. return ret < 0 ? ret : -EIO;
  80. ret = wait_for_completion_interruptible_timeout(&state->frame_ready,
  81. PMS7003_TIMEOUT);
  82. if (!ret)
  83. ret = -ETIMEDOUT;
  84. return ret < 0 ? ret : 0;
  85. }
  86. static u16 pms7003_get_pm(const u8 *data)
  87. {
  88. return clamp_val(get_unaligned_be16(data),
  89. PMS7003_PM_MIN, PMS7003_PM_MAX);
  90. }
  91. static irqreturn_t pms7003_trigger_handler(int irq, void *p)
  92. {
  93. struct iio_poll_func *pf = p;
  94. struct iio_dev *indio_dev = pf->indio_dev;
  95. struct pms7003_state *state = iio_priv(indio_dev);
  96. struct pms7003_frame *frame = &state->frame;
  97. int ret;
  98. mutex_lock(&state->lock);
  99. ret = pms7003_do_cmd(state, CMD_READ_PASSIVE);
  100. if (ret) {
  101. mutex_unlock(&state->lock);
  102. goto err;
  103. }
  104. state->scan.data[PM1] =
  105. pms7003_get_pm(frame->data + PMS7003_PM1_OFFSET);
  106. state->scan.data[PM2P5] =
  107. pms7003_get_pm(frame->data + PMS7003_PM2P5_OFFSET);
  108. state->scan.data[PM10] =
  109. pms7003_get_pm(frame->data + PMS7003_PM10_OFFSET);
  110. mutex_unlock(&state->lock);
  111. iio_push_to_buffers_with_timestamp(indio_dev, &state->scan,
  112. iio_get_time_ns(indio_dev));
  113. err:
  114. iio_trigger_notify_done(indio_dev->trig);
  115. return IRQ_HANDLED;
  116. }
  117. static int pms7003_read_raw(struct iio_dev *indio_dev,
  118. struct iio_chan_spec const *chan,
  119. int *val, int *val2, long mask)
  120. {
  121. struct pms7003_state *state = iio_priv(indio_dev);
  122. struct pms7003_frame *frame = &state->frame;
  123. int ret;
  124. switch (mask) {
  125. case IIO_CHAN_INFO_PROCESSED:
  126. switch (chan->type) {
  127. case IIO_MASSCONCENTRATION:
  128. mutex_lock(&state->lock);
  129. ret = pms7003_do_cmd(state, CMD_READ_PASSIVE);
  130. if (ret) {
  131. mutex_unlock(&state->lock);
  132. return ret;
  133. }
  134. *val = pms7003_get_pm(frame->data + chan->address);
  135. mutex_unlock(&state->lock);
  136. return IIO_VAL_INT;
  137. default:
  138. return -EINVAL;
  139. }
  140. }
  141. return -EINVAL;
  142. }
  143. static const struct iio_info pms7003_info = {
  144. .read_raw = pms7003_read_raw,
  145. };
  146. #define PMS7003_CHAN(_index, _mod, _addr) { \
  147. .type = IIO_MASSCONCENTRATION, \
  148. .modified = 1, \
  149. .channel2 = IIO_MOD_ ## _mod, \
  150. .address = _addr, \
  151. .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \
  152. .scan_index = _index, \
  153. .scan_type = { \
  154. .sign = 'u', \
  155. .realbits = 10, \
  156. .storagebits = 16, \
  157. .endianness = IIO_CPU, \
  158. }, \
  159. }
  160. static const struct iio_chan_spec pms7003_channels[] = {
  161. PMS7003_CHAN(0, PM1, PMS7003_PM1_OFFSET),
  162. PMS7003_CHAN(1, PM2P5, PMS7003_PM2P5_OFFSET),
  163. PMS7003_CHAN(2, PM10, PMS7003_PM10_OFFSET),
  164. IIO_CHAN_SOFT_TIMESTAMP(3),
  165. };
  166. static u16 pms7003_calc_checksum(struct pms7003_frame *frame)
  167. {
  168. u16 checksum = (PMS7003_MAGIC >> 8) + (u8)(PMS7003_MAGIC & 0xff) +
  169. (frame->length >> 8) + (u8)frame->length;
  170. int i;
  171. for (i = 0; i < frame->length - PMS7003_CHECKSUM_LENGTH; i++)
  172. checksum += frame->data[i];
  173. return checksum;
  174. }
  175. static bool pms7003_frame_is_okay(struct pms7003_frame *frame)
  176. {
  177. int offset = frame->length - PMS7003_CHECKSUM_LENGTH;
  178. u16 checksum = get_unaligned_be16(frame->data + offset);
  179. return checksum == pms7003_calc_checksum(frame);
  180. }
  181. static int pms7003_receive_buf(struct serdev_device *serdev,
  182. const unsigned char *buf, size_t size)
  183. {
  184. struct iio_dev *indio_dev = serdev_device_get_drvdata(serdev);
  185. struct pms7003_state *state = iio_priv(indio_dev);
  186. struct pms7003_frame *frame = &state->frame;
  187. int num;
  188. if (!frame->expected_length) {
  189. u16 magic;
  190. /* wait for SOF and data length */
  191. if (size < 4)
  192. return 0;
  193. magic = get_unaligned_be16(buf);
  194. if (magic != PMS7003_MAGIC)
  195. return 2;
  196. num = get_unaligned_be16(buf + 2);
  197. if (num <= PMS7003_MAX_DATA_LENGTH) {
  198. frame->expected_length = num;
  199. frame->length = 0;
  200. }
  201. return 4;
  202. }
  203. num = min(size, (size_t)(frame->expected_length - frame->length));
  204. memcpy(frame->data + frame->length, buf, num);
  205. frame->length += num;
  206. if (frame->length == frame->expected_length) {
  207. if (pms7003_frame_is_okay(frame))
  208. complete(&state->frame_ready);
  209. frame->expected_length = 0;
  210. }
  211. return num;
  212. }
  213. static const struct serdev_device_ops pms7003_serdev_ops = {
  214. .receive_buf = pms7003_receive_buf,
  215. .write_wakeup = serdev_device_write_wakeup,
  216. };
  217. static void pms7003_stop(void *data)
  218. {
  219. struct pms7003_state *state = data;
  220. pms7003_do_cmd(state, CMD_SLEEP);
  221. }
  222. static const unsigned long pms7003_scan_masks[] = { 0x07, 0x00 };
  223. static int pms7003_probe(struct serdev_device *serdev)
  224. {
  225. struct pms7003_state *state;
  226. struct iio_dev *indio_dev;
  227. int ret;
  228. indio_dev = devm_iio_device_alloc(&serdev->dev, sizeof(*state));
  229. if (!indio_dev)
  230. return -ENOMEM;
  231. state = iio_priv(indio_dev);
  232. serdev_device_set_drvdata(serdev, indio_dev);
  233. state->serdev = serdev;
  234. indio_dev->info = &pms7003_info;
  235. indio_dev->name = PMS7003_DRIVER_NAME;
  236. indio_dev->channels = pms7003_channels;
  237. indio_dev->num_channels = ARRAY_SIZE(pms7003_channels);
  238. indio_dev->modes = INDIO_DIRECT_MODE;
  239. indio_dev->available_scan_masks = pms7003_scan_masks;
  240. mutex_init(&state->lock);
  241. init_completion(&state->frame_ready);
  242. serdev_device_set_client_ops(serdev, &pms7003_serdev_ops);
  243. ret = devm_serdev_device_open(&serdev->dev, serdev);
  244. if (ret)
  245. return ret;
  246. serdev_device_set_baudrate(serdev, 9600);
  247. serdev_device_set_flow_control(serdev, false);
  248. ret = serdev_device_set_parity(serdev, SERDEV_PARITY_NONE);
  249. if (ret)
  250. return ret;
  251. ret = pms7003_do_cmd(state, CMD_WAKEUP);
  252. if (ret) {
  253. dev_err(&serdev->dev, "failed to wakeup sensor\n");
  254. return ret;
  255. }
  256. ret = pms7003_do_cmd(state, CMD_ENTER_PASSIVE_MODE);
  257. if (ret) {
  258. dev_err(&serdev->dev, "failed to enter passive mode\n");
  259. return ret;
  260. }
  261. ret = devm_add_action_or_reset(&serdev->dev, pms7003_stop, state);
  262. if (ret)
  263. return ret;
  264. ret = devm_iio_triggered_buffer_setup(&serdev->dev, indio_dev, NULL,
  265. pms7003_trigger_handler, NULL);
  266. if (ret)
  267. return ret;
  268. return devm_iio_device_register(&serdev->dev, indio_dev);
  269. }
  270. static const struct of_device_id pms7003_of_match[] = {
  271. { .compatible = "plantower,pms1003" },
  272. { .compatible = "plantower,pms3003" },
  273. { .compatible = "plantower,pms5003" },
  274. { .compatible = "plantower,pms6003" },
  275. { .compatible = "plantower,pms7003" },
  276. { .compatible = "plantower,pmsa003" },
  277. { }
  278. };
  279. MODULE_DEVICE_TABLE(of, pms7003_of_match);
  280. static struct serdev_device_driver pms7003_driver = {
  281. .driver = {
  282. .name = PMS7003_DRIVER_NAME,
  283. .of_match_table = pms7003_of_match,
  284. },
  285. .probe = pms7003_probe,
  286. };
  287. module_serdev_device_driver(pms7003_driver);
  288. MODULE_AUTHOR("Tomasz Duszynski <[email protected]>");
  289. MODULE_DESCRIPTION("Plantower PMS7003 particulate matter sensor driver");
  290. MODULE_LICENSE("GPL v2");