1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Sensirion SPS30 particulate matter sensor serial driver 4 * 5 * Copyright (c) 2021 Tomasz Duszynski <tomasz.duszynski@octakon.com> 6 */ 7 #include <linux/completion.h> 8 #include <linux/device.h> 9 #include <linux/errno.h> 10 #include <linux/iio/iio.h> 11 #include <linux/minmax.h> 12 #include <linux/mod_devicetable.h> 13 #include <linux/module.h> 14 #include <linux/serdev.h> 15 #include <linux/types.h> 16 17 #include "sps30.h" 18 19 #define SPS30_SERIAL_DEV_NAME "sps30" 20 21 #define SPS30_SERIAL_SOF_EOF 0x7e 22 #define SPS30_SERIAL_TIMEOUT msecs_to_jiffies(20) 23 #define SPS30_SERIAL_MAX_BUF_SIZE 263 24 #define SPS30_SERIAL_ESCAPE_CHAR 0x7d 25 26 #define SPS30_SERIAL_FRAME_MIN_SIZE 7 27 #define SPS30_SERIAL_FRAME_ADR_OFFSET 1 28 #define SPS30_SERIAL_FRAME_CMD_OFFSET 2 29 #define SPS30_SERIAL_FRAME_MOSI_LEN_OFFSET 3 30 #define SPS30_SERIAL_FRAME_MISO_STATE_OFFSET 3 31 #define SPS30_SERIAL_FRAME_MISO_LEN_OFFSET 4 32 #define SPS30_SERIAL_FRAME_MISO_DATA_OFFSET 5 33 34 #define SPS30_SERIAL_START_MEAS 0x00 35 #define SPS30_SERIAL_STOP_MEAS 0x01 36 #define SPS30_SERIAL_READ_MEAS 0x03 37 #define SPS30_SERIAL_RESET 0xd3 38 #define SPS30_SERIAL_CLEAN_FAN 0x56 39 #define SPS30_SERIAL_PERIOD 0x80 40 #define SPS30_SERIAL_DEV_INFO 0xd0 41 #define SPS30_SERIAL_READ_VERSION 0xd1 42 43 struct sps30_serial_priv { 44 struct completion new_frame; 45 unsigned char buf[SPS30_SERIAL_MAX_BUF_SIZE]; 46 size_t num; 47 bool escaped; 48 bool done; 49 }; 50 51 static int sps30_serial_xfer(struct sps30_state *state, const unsigned char *buf, size_t size) 52 { 53 struct serdev_device *serdev = to_serdev_device(state->dev); 54 struct sps30_serial_priv *priv = state->priv; 55 int ret; 56 57 priv->num = 0; 58 priv->escaped = false; 59 priv->done = false; 60 61 ret = serdev_device_write(serdev, buf, size, SPS30_SERIAL_TIMEOUT); 62 if (ret < 0) 63 return ret; 64 if (ret != size) 65 return -EIO; 66 67 ret = wait_for_completion_interruptible_timeout(&priv->new_frame, SPS30_SERIAL_TIMEOUT); 68 if (ret < 0) 69 return ret; 70 if (!ret) 71 return -ETIMEDOUT; 72 73 return 0; 74 } 75 76 static const struct { 77 unsigned char byte; 78 unsigned char byte2; 79 } sps30_serial_bytes[] = { 80 { 0x11, 0x31 }, 81 { 0x13, 0x33 }, 82 { 0x7e, 0x5e }, 83 { 0x7d, 0x5d }, 84 }; 85 86 static int sps30_serial_put_byte(unsigned char *buf, unsigned char byte) 87 { 88 int i; 89 90 for (i = 0; i < ARRAY_SIZE(sps30_serial_bytes); i++) { 91 if (sps30_serial_bytes[i].byte != byte) 92 continue; 93 94 buf[0] = SPS30_SERIAL_ESCAPE_CHAR; 95 buf[1] = sps30_serial_bytes[i].byte2; 96 97 return 2; 98 } 99 100 buf[0] = byte; 101 102 return 1; 103 } 104 105 static char sps30_serial_get_byte(bool escaped, unsigned char byte2) 106 { 107 int i; 108 109 if (!escaped) 110 return byte2; 111 112 for (i = 0; i < ARRAY_SIZE(sps30_serial_bytes); i++) { 113 if (sps30_serial_bytes[i].byte2 != byte2) 114 continue; 115 116 return sps30_serial_bytes[i].byte; 117 } 118 119 return 0; 120 } 121 122 static unsigned char sps30_serial_calc_chksum(const unsigned char *buf, size_t num) 123 { 124 unsigned int chksum = 0; 125 size_t i; 126 127 for (i = 0; i < num; i++) 128 chksum += buf[i]; 129 130 return ~chksum; 131 } 132 133 static int sps30_serial_prep_frame(unsigned char *buf, unsigned char cmd, 134 const unsigned char *arg, size_t arg_size) 135 { 136 unsigned char chksum; 137 int num = 0; 138 size_t i; 139 140 buf[num++] = SPS30_SERIAL_SOF_EOF; 141 buf[num++] = 0; 142 num += sps30_serial_put_byte(buf + num, cmd); 143 num += sps30_serial_put_byte(buf + num, arg_size); 144 145 for (i = 0; i < arg_size; i++) 146 num += sps30_serial_put_byte(buf + num, arg[i]); 147 148 /* SOF isn't checksummed */ 149 chksum = sps30_serial_calc_chksum(buf + 1, num - 1); 150 num += sps30_serial_put_byte(buf + num, chksum); 151 buf[num++] = SPS30_SERIAL_SOF_EOF; 152 153 return num; 154 } 155 156 static bool sps30_serial_frame_valid(struct sps30_state *state, const unsigned char *buf) 157 { 158 struct sps30_serial_priv *priv = state->priv; 159 unsigned char chksum; 160 161 if ((priv->num < SPS30_SERIAL_FRAME_MIN_SIZE) || 162 (priv->num != SPS30_SERIAL_FRAME_MIN_SIZE + 163 priv->buf[SPS30_SERIAL_FRAME_MISO_LEN_OFFSET])) { 164 dev_err(state->dev, "frame has invalid number of bytes\n"); 165 return false; 166 } 167 168 if ((priv->buf[SPS30_SERIAL_FRAME_ADR_OFFSET] != buf[SPS30_SERIAL_FRAME_ADR_OFFSET]) || 169 (priv->buf[SPS30_SERIAL_FRAME_CMD_OFFSET] != buf[SPS30_SERIAL_FRAME_CMD_OFFSET])) { 170 dev_err(state->dev, "frame has wrong ADR and CMD bytes\n"); 171 return false; 172 } 173 174 if (priv->buf[SPS30_SERIAL_FRAME_MISO_STATE_OFFSET]) { 175 dev_err(state->dev, "frame with non-zero state received (0x%02x)\n", 176 priv->buf[SPS30_SERIAL_FRAME_MISO_STATE_OFFSET]); 177 return false; 178 } 179 180 /* SOF, checksum and EOF are not checksummed */ 181 chksum = sps30_serial_calc_chksum(priv->buf + 1, priv->num - 3); 182 if (priv->buf[priv->num - 2] != chksum) { 183 dev_err(state->dev, "frame integrity check failed\n"); 184 return false; 185 } 186 187 return true; 188 } 189 190 static int sps30_serial_command(struct sps30_state *state, unsigned char cmd, 191 const void *arg, size_t arg_size, void *rsp, size_t rsp_size) 192 { 193 struct sps30_serial_priv *priv = state->priv; 194 unsigned char buf[SPS30_SERIAL_MAX_BUF_SIZE]; 195 int ret, size; 196 197 size = sps30_serial_prep_frame(buf, cmd, arg, arg_size); 198 ret = sps30_serial_xfer(state, buf, size); 199 if (ret) 200 return ret; 201 202 if (!sps30_serial_frame_valid(state, buf)) 203 return -EIO; 204 205 if (rsp) { 206 rsp_size = min_t(size_t, priv->buf[SPS30_SERIAL_FRAME_MISO_LEN_OFFSET], rsp_size); 207 memcpy(rsp, &priv->buf[SPS30_SERIAL_FRAME_MISO_DATA_OFFSET], rsp_size); 208 } 209 210 return rsp_size; 211 } 212 213 static int sps30_serial_receive_buf(struct serdev_device *serdev, 214 const unsigned char *buf, size_t size) 215 { 216 struct iio_dev *indio_dev = dev_get_drvdata(&serdev->dev); 217 struct sps30_serial_priv *priv; 218 struct sps30_state *state; 219 unsigned char byte; 220 size_t i; 221 222 if (!indio_dev) 223 return 0; 224 225 state = iio_priv(indio_dev); 226 priv = state->priv; 227 228 /* just in case device put some unexpected data on the bus */ 229 if (priv->done) 230 return size; 231 232 /* wait for the start of frame */ 233 if (!priv->num && size && buf[0] != SPS30_SERIAL_SOF_EOF) 234 return 1; 235 236 if (priv->num + size >= ARRAY_SIZE(priv->buf)) 237 size = ARRAY_SIZE(priv->buf) - priv->num; 238 239 for (i = 0; i < size; i++) { 240 byte = buf[i]; 241 /* remove stuffed bytes on-the-fly */ 242 if (byte == SPS30_SERIAL_ESCAPE_CHAR) { 243 priv->escaped = true; 244 continue; 245 } 246 247 byte = sps30_serial_get_byte(priv->escaped, byte); 248 if (priv->escaped && !byte) 249 dev_warn(state->dev, "unrecognized escaped char (0x%02x)\n", byte); 250 251 priv->buf[priv->num++] = byte; 252 253 /* EOF received */ 254 if (!priv->escaped && byte == SPS30_SERIAL_SOF_EOF) { 255 if (priv->num < SPS30_SERIAL_FRAME_MIN_SIZE) 256 continue; 257 258 priv->done = true; 259 complete(&priv->new_frame); 260 i++; 261 break; 262 } 263 264 priv->escaped = false; 265 } 266 267 return i; 268 } 269 270 static const struct serdev_device_ops sps30_serial_device_ops = { 271 .receive_buf = sps30_serial_receive_buf, 272 .write_wakeup = serdev_device_write_wakeup, 273 }; 274 275 static int sps30_serial_start_meas(struct sps30_state *state) 276 { 277 /* request BE IEEE754 formatted data */ 278 unsigned char buf[] = { 0x01, 0x03 }; 279 280 return sps30_serial_command(state, SPS30_SERIAL_START_MEAS, buf, sizeof(buf), NULL, 0); 281 } 282 283 static int sps30_serial_stop_meas(struct sps30_state *state) 284 { 285 return sps30_serial_command(state, SPS30_SERIAL_STOP_MEAS, NULL, 0, NULL, 0); 286 } 287 288 static int sps30_serial_reset(struct sps30_state *state) 289 { 290 int ret; 291 292 ret = sps30_serial_command(state, SPS30_SERIAL_RESET, NULL, 0, NULL, 0); 293 msleep(500); 294 295 return ret; 296 } 297 298 static int sps30_serial_read_meas(struct sps30_state *state, __be32 *meas, size_t num) 299 { 300 int ret; 301 302 /* measurements are ready within a second */ 303 if (msleep_interruptible(1000)) 304 return -EINTR; 305 306 ret = sps30_serial_command(state, SPS30_SERIAL_READ_MEAS, NULL, 0, meas, num * sizeof(num)); 307 if (ret < 0) 308 return ret; 309 /* if measurements aren't ready sensor returns empty frame */ 310 if (ret == SPS30_SERIAL_FRAME_MIN_SIZE) 311 return -ETIMEDOUT; 312 if (ret != num * sizeof(*meas)) 313 return -EIO; 314 315 return 0; 316 } 317 318 static int sps30_serial_clean_fan(struct sps30_state *state) 319 { 320 return sps30_serial_command(state, SPS30_SERIAL_CLEAN_FAN, NULL, 0, NULL, 0); 321 } 322 323 static int sps30_serial_read_cleaning_period(struct sps30_state *state, __be32 *period) 324 { 325 unsigned char buf[] = { 0x00 }; 326 int ret; 327 328 ret = sps30_serial_command(state, SPS30_SERIAL_PERIOD, buf, sizeof(buf), 329 period, sizeof(*period)); 330 if (ret < 0) 331 return ret; 332 if (ret != sizeof(*period)) 333 return -EIO; 334 335 return 0; 336 } 337 338 static int sps30_serial_write_cleaning_period(struct sps30_state *state, __be32 period) 339 { 340 unsigned char buf[5] = { 0x00 }; 341 342 memcpy(buf + 1, &period, sizeof(period)); 343 344 return sps30_serial_command(state, SPS30_SERIAL_PERIOD, buf, sizeof(buf), NULL, 0); 345 } 346 347 static int sps30_serial_show_info(struct sps30_state *state) 348 { 349 /* 350 * tell device do return serial number and add extra nul byte just in case 351 * serial number isn't a valid string 352 */ 353 unsigned char buf[32 + 1] = { 0x03 }; 354 struct device *dev = state->dev; 355 int ret; 356 357 ret = sps30_serial_command(state, SPS30_SERIAL_DEV_INFO, buf, 1, buf, sizeof(buf) - 1); 358 if (ret < 0) 359 return ret; 360 if (ret != sizeof(buf) - 1) 361 return -EIO; 362 363 dev_info(dev, "serial number: %s\n", buf); 364 365 ret = sps30_serial_command(state, SPS30_SERIAL_READ_VERSION, NULL, 0, buf, sizeof(buf) - 1); 366 if (ret < 0) 367 return ret; 368 if (ret < 2) 369 return -EIO; 370 371 dev_info(dev, "fw version: %u.%u\n", buf[0], buf[1]); 372 373 return 0; 374 } 375 376 static const struct sps30_ops sps30_serial_ops = { 377 .start_meas = sps30_serial_start_meas, 378 .stop_meas = sps30_serial_stop_meas, 379 .read_meas = sps30_serial_read_meas, 380 .reset = sps30_serial_reset, 381 .clean_fan = sps30_serial_clean_fan, 382 .read_cleaning_period = sps30_serial_read_cleaning_period, 383 .write_cleaning_period = sps30_serial_write_cleaning_period, 384 .show_info = sps30_serial_show_info, 385 }; 386 387 static int sps30_serial_probe(struct serdev_device *serdev) 388 { 389 struct device *dev = &serdev->dev; 390 struct sps30_serial_priv *priv; 391 int ret; 392 393 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 394 if (!priv) 395 return -ENOMEM; 396 397 init_completion(&priv->new_frame); 398 serdev_device_set_client_ops(serdev, &sps30_serial_device_ops); 399 400 ret = devm_serdev_device_open(dev, serdev); 401 if (ret) 402 return ret; 403 404 serdev_device_set_baudrate(serdev, 115200); 405 serdev_device_set_flow_control(serdev, false); 406 407 ret = serdev_device_set_parity(serdev, SERDEV_PARITY_NONE); 408 if (ret) 409 return ret; 410 411 return sps30_probe(dev, SPS30_SERIAL_DEV_NAME, priv, &sps30_serial_ops); 412 } 413 414 static const struct of_device_id sps30_serial_of_match[] = { 415 { .compatible = "sensirion,sps30" }, 416 { } 417 }; 418 MODULE_DEVICE_TABLE(of, sps30_serial_of_match); 419 420 static struct serdev_device_driver sps30_serial_driver = { 421 .driver = { 422 .name = KBUILD_MODNAME, 423 .of_match_table = sps30_serial_of_match, 424 }, 425 .probe = sps30_serial_probe, 426 }; 427 module_serdev_device_driver(sps30_serial_driver); 428 429 MODULE_AUTHOR("Tomasz Duszynski <tomasz.duszynski@octakon.com>"); 430 MODULE_DESCRIPTION("Sensirion SPS30 particulate matter sensor serial driver"); 431 MODULE_LICENSE("GPL v2"); 432 MODULE_IMPORT_NS(IIO_SPS30); 433