Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Sensirion SPS30 particulate matter sensor driver
0004  *
0005  * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com>
0006  */
0007 
0008 #include <linux/crc8.h>
0009 #include <linux/delay.h>
0010 #include <linux/i2c.h>
0011 #include <linux/iio/buffer.h>
0012 #include <linux/iio/iio.h>
0013 #include <linux/iio/sysfs.h>
0014 #include <linux/iio/trigger_consumer.h>
0015 #include <linux/iio/triggered_buffer.h>
0016 #include <linux/kernel.h>
0017 #include <linux/module.h>
0018 
0019 #include "sps30.h"
0020 
0021 /* sensor measures reliably up to 3000 ug / m3 */
0022 #define SPS30_MAX_PM 3000
0023 /* minimum and maximum self cleaning periods in seconds */
0024 #define SPS30_AUTO_CLEANING_PERIOD_MIN 0
0025 #define SPS30_AUTO_CLEANING_PERIOD_MAX 604800
0026 
0027 enum {
0028     PM1,
0029     PM2P5,
0030     PM4,
0031     PM10,
0032 };
0033 
0034 enum {
0035     RESET,
0036     MEASURING,
0037 };
0038 
0039 static s32 sps30_float_to_int_clamped(__be32 *fp)
0040 {
0041     int val = be32_to_cpup(fp);
0042     int mantissa = val & GENMASK(22, 0);
0043     /* this is fine since passed float is always non-negative */
0044     int exp = val >> 23;
0045     int fraction, shift;
0046 
0047     /* special case 0 */
0048     if (!exp && !mantissa)
0049         return 0;
0050 
0051     exp -= 127;
0052     if (exp < 0) {
0053         /* return values ranging from 1 to 99 */
0054         return ((((1 << 23) + mantissa) * 100) >> 23) >> (-exp);
0055     }
0056 
0057     /* return values ranging from 100 to 300000 */
0058     shift = 23 - exp;
0059     val = (1 << exp) + (mantissa >> shift);
0060     if (val >= SPS30_MAX_PM)
0061         return SPS30_MAX_PM * 100;
0062 
0063     fraction = mantissa & GENMASK(shift - 1, 0);
0064 
0065     return val * 100 + ((fraction * 100) >> shift);
0066 }
0067 
0068 static int sps30_do_meas(struct sps30_state *state, s32 *data, int size)
0069 {
0070     int i, ret;
0071 
0072     if (state->state == RESET) {
0073         ret = state->ops->start_meas(state);
0074         if (ret)
0075             return ret;
0076 
0077         state->state = MEASURING;
0078     }
0079 
0080     ret = state->ops->read_meas(state, (__be32 *)data, size);
0081     if (ret)
0082         return ret;
0083 
0084     for (i = 0; i < size; i++)
0085         data[i] = sps30_float_to_int_clamped((__be32 *)&data[i]);
0086 
0087     return 0;
0088 }
0089 
0090 static int sps30_do_reset(struct sps30_state *state)
0091 {
0092     int ret;
0093 
0094     ret = state->ops->reset(state);
0095     if (ret)
0096         return ret;
0097 
0098     state->state = RESET;
0099 
0100     return 0;
0101 }
0102 
0103 static irqreturn_t sps30_trigger_handler(int irq, void *p)
0104 {
0105     struct iio_poll_func *pf = p;
0106     struct iio_dev *indio_dev = pf->indio_dev;
0107     struct sps30_state *state = iio_priv(indio_dev);
0108     int ret;
0109     struct {
0110         s32 data[4]; /* PM1, PM2P5, PM4, PM10 */
0111         s64 ts;
0112     } scan;
0113 
0114     mutex_lock(&state->lock);
0115     ret = sps30_do_meas(state, scan.data, ARRAY_SIZE(scan.data));
0116     mutex_unlock(&state->lock);
0117     if (ret)
0118         goto err;
0119 
0120     iio_push_to_buffers_with_timestamp(indio_dev, &scan,
0121                        iio_get_time_ns(indio_dev));
0122 err:
0123     iio_trigger_notify_done(indio_dev->trig);
0124 
0125     return IRQ_HANDLED;
0126 }
0127 
0128 static int sps30_read_raw(struct iio_dev *indio_dev,
0129               struct iio_chan_spec const *chan,
0130               int *val, int *val2, long mask)
0131 {
0132     struct sps30_state *state = iio_priv(indio_dev);
0133     int data[4], ret = -EINVAL;
0134 
0135     switch (mask) {
0136     case IIO_CHAN_INFO_PROCESSED:
0137         switch (chan->type) {
0138         case IIO_MASSCONCENTRATION:
0139             mutex_lock(&state->lock);
0140             /* read up to the number of bytes actually needed */
0141             switch (chan->channel2) {
0142             case IIO_MOD_PM1:
0143                 ret = sps30_do_meas(state, data, 1);
0144                 break;
0145             case IIO_MOD_PM2P5:
0146                 ret = sps30_do_meas(state, data, 2);
0147                 break;
0148             case IIO_MOD_PM4:
0149                 ret = sps30_do_meas(state, data, 3);
0150                 break;
0151             case IIO_MOD_PM10:
0152                 ret = sps30_do_meas(state, data, 4);
0153                 break;
0154             }
0155             mutex_unlock(&state->lock);
0156             if (ret)
0157                 return ret;
0158 
0159             *val = data[chan->address] / 100;
0160             *val2 = (data[chan->address] % 100) * 10000;
0161 
0162             return IIO_VAL_INT_PLUS_MICRO;
0163         default:
0164             return -EINVAL;
0165         }
0166     case IIO_CHAN_INFO_SCALE:
0167         switch (chan->type) {
0168         case IIO_MASSCONCENTRATION:
0169             switch (chan->channel2) {
0170             case IIO_MOD_PM1:
0171             case IIO_MOD_PM2P5:
0172             case IIO_MOD_PM4:
0173             case IIO_MOD_PM10:
0174                 *val = 0;
0175                 *val2 = 10000;
0176 
0177                 return IIO_VAL_INT_PLUS_MICRO;
0178             default:
0179                 return -EINVAL;
0180             }
0181         default:
0182             return -EINVAL;
0183         }
0184     }
0185 
0186     return -EINVAL;
0187 }
0188 
0189 static ssize_t start_cleaning_store(struct device *dev,
0190                     struct device_attribute *attr,
0191                     const char *buf, size_t len)
0192 {
0193     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0194     struct sps30_state *state = iio_priv(indio_dev);
0195     int val, ret;
0196 
0197     if (kstrtoint(buf, 0, &val) || val != 1)
0198         return -EINVAL;
0199 
0200     mutex_lock(&state->lock);
0201     ret = state->ops->clean_fan(state);
0202     mutex_unlock(&state->lock);
0203     if (ret)
0204         return ret;
0205 
0206     return len;
0207 }
0208 
0209 static ssize_t cleaning_period_show(struct device *dev,
0210                     struct device_attribute *attr,
0211                     char *buf)
0212 {
0213     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0214     struct sps30_state *state = iio_priv(indio_dev);
0215     __be32 val;
0216     int ret;
0217 
0218     mutex_lock(&state->lock);
0219     ret = state->ops->read_cleaning_period(state, &val);
0220     mutex_unlock(&state->lock);
0221     if (ret)
0222         return ret;
0223 
0224     return sysfs_emit(buf, "%d\n", be32_to_cpu(val));
0225 }
0226 
0227 static ssize_t cleaning_period_store(struct device *dev, struct device_attribute *attr,
0228                      const char *buf, size_t len)
0229 {
0230     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0231     struct sps30_state *state = iio_priv(indio_dev);
0232     int val, ret;
0233 
0234     if (kstrtoint(buf, 0, &val))
0235         return -EINVAL;
0236 
0237     if ((val < SPS30_AUTO_CLEANING_PERIOD_MIN) ||
0238         (val > SPS30_AUTO_CLEANING_PERIOD_MAX))
0239         return -EINVAL;
0240 
0241     mutex_lock(&state->lock);
0242     ret = state->ops->write_cleaning_period(state, cpu_to_be32(val));
0243     if (ret) {
0244         mutex_unlock(&state->lock);
0245         return ret;
0246     }
0247 
0248     msleep(20);
0249 
0250     /*
0251      * sensor requires reset in order to return up to date self cleaning
0252      * period
0253      */
0254     ret = sps30_do_reset(state);
0255     if (ret)
0256         dev_warn(dev,
0257              "period changed but reads will return the old value\n");
0258 
0259     mutex_unlock(&state->lock);
0260 
0261     return len;
0262 }
0263 
0264 static ssize_t cleaning_period_available_show(struct device *dev,
0265                           struct device_attribute *attr,
0266                           char *buf)
0267 {
0268     return sysfs_emit(buf, "[%d %d %d]\n",
0269               SPS30_AUTO_CLEANING_PERIOD_MIN, 1,
0270               SPS30_AUTO_CLEANING_PERIOD_MAX);
0271 }
0272 
0273 static IIO_DEVICE_ATTR_WO(start_cleaning, 0);
0274 static IIO_DEVICE_ATTR_RW(cleaning_period, 0);
0275 static IIO_DEVICE_ATTR_RO(cleaning_period_available, 0);
0276 
0277 static struct attribute *sps30_attrs[] = {
0278     &iio_dev_attr_start_cleaning.dev_attr.attr,
0279     &iio_dev_attr_cleaning_period.dev_attr.attr,
0280     &iio_dev_attr_cleaning_period_available.dev_attr.attr,
0281     NULL
0282 };
0283 
0284 static const struct attribute_group sps30_attr_group = {
0285     .attrs = sps30_attrs,
0286 };
0287 
0288 static const struct iio_info sps30_info = {
0289     .attrs = &sps30_attr_group,
0290     .read_raw = sps30_read_raw,
0291 };
0292 
0293 #define SPS30_CHAN(_index, _mod) { \
0294     .type = IIO_MASSCONCENTRATION, \
0295     .modified = 1, \
0296     .channel2 = IIO_MOD_ ## _mod, \
0297     .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \
0298     .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
0299     .address = _mod, \
0300     .scan_index = _index, \
0301     .scan_type = { \
0302         .sign = 'u', \
0303         .realbits = 19, \
0304         .storagebits = 32, \
0305         .endianness = IIO_CPU, \
0306     }, \
0307 }
0308 
0309 static const struct iio_chan_spec sps30_channels[] = {
0310     SPS30_CHAN(0, PM1),
0311     SPS30_CHAN(1, PM2P5),
0312     SPS30_CHAN(2, PM4),
0313     SPS30_CHAN(3, PM10),
0314     IIO_CHAN_SOFT_TIMESTAMP(4),
0315 };
0316 
0317 static void sps30_devm_stop_meas(void *data)
0318 {
0319     struct sps30_state *state = data;
0320 
0321     if (state->state == MEASURING)
0322         state->ops->stop_meas(state);
0323 }
0324 
0325 static const unsigned long sps30_scan_masks[] = { 0x0f, 0x00 };
0326 
0327 int sps30_probe(struct device *dev, const char *name, void *priv, const struct sps30_ops *ops)
0328 {
0329     struct iio_dev *indio_dev;
0330     struct sps30_state *state;
0331     int ret;
0332 
0333     indio_dev = devm_iio_device_alloc(dev, sizeof(*state));
0334     if (!indio_dev)
0335         return -ENOMEM;
0336 
0337     dev_set_drvdata(dev, indio_dev);
0338 
0339     state = iio_priv(indio_dev);
0340     state->dev = dev;
0341     state->priv = priv;
0342     state->ops = ops;
0343     mutex_init(&state->lock);
0344 
0345     indio_dev->info = &sps30_info;
0346     indio_dev->name = name;
0347     indio_dev->channels = sps30_channels;
0348     indio_dev->num_channels = ARRAY_SIZE(sps30_channels);
0349     indio_dev->modes = INDIO_DIRECT_MODE;
0350     indio_dev->available_scan_masks = sps30_scan_masks;
0351 
0352     ret = sps30_do_reset(state);
0353     if (ret) {
0354         dev_err(dev, "failed to reset device\n");
0355         return ret;
0356     }
0357 
0358     ret = state->ops->show_info(state);
0359     if (ret) {
0360         dev_err(dev, "failed to read device info\n");
0361         return ret;
0362     }
0363 
0364     ret = devm_add_action_or_reset(dev, sps30_devm_stop_meas, state);
0365     if (ret)
0366         return ret;
0367 
0368     ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
0369                           sps30_trigger_handler, NULL);
0370     if (ret)
0371         return ret;
0372 
0373     return devm_iio_device_register(dev, indio_dev);
0374 }
0375 EXPORT_SYMBOL_NS_GPL(sps30_probe, IIO_SPS30);
0376 
0377 MODULE_AUTHOR("Tomasz Duszynski <tduszyns@gmail.com>");
0378 MODULE_DESCRIPTION("Sensirion SPS30 particulate matter sensor driver");
0379 MODULE_LICENSE("GPL v2");