Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * srf08.c - Support for Devantech SRFxx ultrasonic ranger
0004  *           with i2c interface
0005  * actually supported are srf02, srf08, srf10
0006  *
0007  * Copyright (c) 2016, 2017 Andreas Klinger <ak@it-klinger.de>
0008  *
0009  * For details about the device see:
0010  * https://www.robot-electronics.co.uk/htm/srf08tech.html
0011  * https://www.robot-electronics.co.uk/htm/srf10tech.htm
0012  * https://www.robot-electronics.co.uk/htm/srf02tech.htm
0013  */
0014 
0015 #include <linux/err.h>
0016 #include <linux/i2c.h>
0017 #include <linux/delay.h>
0018 #include <linux/module.h>
0019 #include <linux/bitops.h>
0020 #include <linux/iio/iio.h>
0021 #include <linux/iio/sysfs.h>
0022 #include <linux/iio/buffer.h>
0023 #include <linux/iio/trigger_consumer.h>
0024 #include <linux/iio/triggered_buffer.h>
0025 
0026 /* registers of SRF08 device */
0027 #define SRF08_WRITE_COMMAND 0x00    /* Command Register */
0028 #define SRF08_WRITE_MAX_GAIN    0x01    /* Max Gain Register: 0 .. 31 */
0029 #define SRF08_WRITE_RANGE   0x02    /* Range Register: 0 .. 255 */
0030 #define SRF08_READ_SW_REVISION  0x00    /* Software Revision */
0031 #define SRF08_READ_LIGHT    0x01    /* Light Sensor during last echo */
0032 #define SRF08_READ_ECHO_1_HIGH  0x02    /* Range of first echo received */
0033 #define SRF08_READ_ECHO_1_LOW   0x03    /* Range of first echo received */
0034 
0035 #define SRF08_CMD_RANGING_CM    0x51    /* Ranging Mode - Result in cm */
0036 
0037 enum srf08_sensor_type {
0038     SRF02,
0039     SRF08,
0040     SRF10,
0041     SRF_MAX_TYPE
0042 };
0043 
0044 struct srf08_chip_info {
0045     const int       *sensitivity_avail;
0046     int         num_sensitivity_avail;
0047     int         sensitivity_default;
0048 
0049     /* default value of Range in mm */
0050     int         range_default;
0051 };
0052 
0053 struct srf08_data {
0054     struct i2c_client   *client;
0055 
0056     /*
0057      * Gain in the datasheet is called sensitivity here to distinct it
0058      * from the gain used with amplifiers of adc's
0059      */
0060     int         sensitivity;
0061 
0062     /* max. Range in mm */
0063     int         range_mm;
0064     struct mutex        lock;
0065 
0066     /* Ensure timestamp is naturally aligned */
0067     struct {
0068         s16 chan;
0069         s64 timestamp __aligned(8);
0070     } scan;
0071 
0072     /* Sensor-Type */
0073     enum srf08_sensor_type  sensor_type;
0074 
0075     /* Chip-specific information */
0076     const struct srf08_chip_info    *chip_info;
0077 };
0078 
0079 /*
0080  * in the documentation one can read about the "Gain" of the device
0081  * which is used here for amplifying the signal and filtering out unwanted
0082  * ones.
0083  * But with ADC's this term is already used differently and that's why it
0084  * is called "Sensitivity" here.
0085  */
0086 static const struct srf08_chip_info srf02_chip_info = {
0087     .sensitivity_avail  = NULL,
0088     .num_sensitivity_avail  = 0,
0089     .sensitivity_default    = 0,
0090 
0091     .range_default      = 0,
0092 };
0093 
0094 static const int srf08_sensitivity_avail[] = {
0095      94,  97, 100, 103, 107, 110, 114, 118,
0096     123, 128, 133, 139, 145, 152, 159, 168,
0097     177, 187, 199, 212, 227, 245, 265, 288,
0098     317, 352, 395, 450, 524, 626, 777, 1025
0099     };
0100 
0101 static const struct srf08_chip_info srf08_chip_info = {
0102     .sensitivity_avail  = srf08_sensitivity_avail,
0103     .num_sensitivity_avail  = ARRAY_SIZE(srf08_sensitivity_avail),
0104     .sensitivity_default    = 1025,
0105 
0106     .range_default      = 6020,
0107 };
0108 
0109 static const int srf10_sensitivity_avail[] = {
0110      40,  40,  50,  60,  70,  80, 100, 120,
0111     140, 200, 250, 300, 350, 400, 500, 600,
0112     700,
0113     };
0114 
0115 static const struct srf08_chip_info srf10_chip_info = {
0116     .sensitivity_avail  = srf10_sensitivity_avail,
0117     .num_sensitivity_avail  = ARRAY_SIZE(srf10_sensitivity_avail),
0118     .sensitivity_default    = 700,
0119 
0120     .range_default      = 6020,
0121 };
0122 
0123 static int srf08_read_ranging(struct srf08_data *data)
0124 {
0125     struct i2c_client *client = data->client;
0126     int ret, i;
0127     int waittime;
0128 
0129     mutex_lock(&data->lock);
0130 
0131     ret = i2c_smbus_write_byte_data(data->client,
0132             SRF08_WRITE_COMMAND, SRF08_CMD_RANGING_CM);
0133     if (ret < 0) {
0134         dev_err(&client->dev, "write command - err: %d\n", ret);
0135         mutex_unlock(&data->lock);
0136         return ret;
0137     }
0138 
0139     /*
0140      * we read here until a correct version number shows up as
0141      * suggested by the documentation
0142      *
0143      * with an ultrasonic speed of 343 m/s and a roundtrip of it
0144      * sleep the expected duration and try to read from the device
0145      * if nothing useful is read try it in a shorter grid
0146      *
0147      * polling for not more than 20 ms should be enough
0148      */
0149     waittime = 1 + data->range_mm / 172;
0150     msleep(waittime);
0151     for (i = 0; i < 4; i++) {
0152         ret = i2c_smbus_read_byte_data(data->client,
0153                         SRF08_READ_SW_REVISION);
0154 
0155         /* check if a valid version number is read */
0156         if (ret < 255 && ret > 0)
0157             break;
0158         msleep(5);
0159     }
0160 
0161     if (ret >= 255 || ret <= 0) {
0162         dev_err(&client->dev, "device not ready\n");
0163         mutex_unlock(&data->lock);
0164         return -EIO;
0165     }
0166 
0167     ret = i2c_smbus_read_word_swapped(data->client,
0168                         SRF08_READ_ECHO_1_HIGH);
0169     if (ret < 0) {
0170         dev_err(&client->dev, "cannot read distance: ret=%d\n", ret);
0171         mutex_unlock(&data->lock);
0172         return ret;
0173     }
0174 
0175     mutex_unlock(&data->lock);
0176 
0177     return ret;
0178 }
0179 
0180 static irqreturn_t srf08_trigger_handler(int irq, void *p)
0181 {
0182     struct iio_poll_func *pf = p;
0183     struct iio_dev *indio_dev = pf->indio_dev;
0184     struct srf08_data *data = iio_priv(indio_dev);
0185     s16 sensor_data;
0186 
0187     sensor_data = srf08_read_ranging(data);
0188     if (sensor_data < 0)
0189         goto err;
0190 
0191     mutex_lock(&data->lock);
0192 
0193     data->scan.chan = sensor_data;
0194     iio_push_to_buffers_with_timestamp(indio_dev,
0195                        &data->scan, pf->timestamp);
0196 
0197     mutex_unlock(&data->lock);
0198 err:
0199     iio_trigger_notify_done(indio_dev->trig);
0200     return IRQ_HANDLED;
0201 }
0202 
0203 static int srf08_read_raw(struct iio_dev *indio_dev,
0204                 struct iio_chan_spec const *channel, int *val,
0205                 int *val2, long mask)
0206 {
0207     struct srf08_data *data = iio_priv(indio_dev);
0208     int ret;
0209 
0210     if (channel->type != IIO_DISTANCE)
0211         return -EINVAL;
0212 
0213     switch (mask) {
0214     case IIO_CHAN_INFO_RAW:
0215         ret = srf08_read_ranging(data);
0216         if (ret < 0)
0217             return ret;
0218         *val = ret;
0219         return IIO_VAL_INT;
0220     case IIO_CHAN_INFO_SCALE:
0221         /* 1 LSB is 1 cm */
0222         *val = 0;
0223         *val2 = 10000;
0224         return IIO_VAL_INT_PLUS_MICRO;
0225     default:
0226         return -EINVAL;
0227     }
0228 }
0229 
0230 static ssize_t srf08_show_range_mm_available(struct device *dev,
0231                 struct device_attribute *attr, char *buf)
0232 {
0233     return sprintf(buf, "[0.043 0.043 11.008]\n");
0234 }
0235 
0236 static IIO_DEVICE_ATTR(sensor_max_range_available, S_IRUGO,
0237                 srf08_show_range_mm_available, NULL, 0);
0238 
0239 static ssize_t srf08_show_range_mm(struct device *dev,
0240                 struct device_attribute *attr, char *buf)
0241 {
0242     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0243     struct srf08_data *data = iio_priv(indio_dev);
0244 
0245     return sprintf(buf, "%d.%03d\n", data->range_mm / 1000,
0246                         data->range_mm % 1000);
0247 }
0248 
0249 /*
0250  * set the range of the sensor to an even multiple of 43 mm
0251  * which corresponds to 1 LSB in the register
0252  *
0253  * register value    corresponding range
0254  *         0x00             43 mm
0255  *         0x01             86 mm
0256  *         0x02            129 mm
0257  *         ...
0258  *         0xFF          11008 mm
0259  */
0260 static ssize_t srf08_write_range_mm(struct srf08_data *data, unsigned int val)
0261 {
0262     int ret;
0263     struct i2c_client *client = data->client;
0264     unsigned int mod;
0265     u8 regval;
0266 
0267     ret = val / 43 - 1;
0268     mod = val % 43;
0269 
0270     if (mod || (ret < 0) || (ret > 255))
0271         return -EINVAL;
0272 
0273     regval = ret;
0274 
0275     mutex_lock(&data->lock);
0276 
0277     ret = i2c_smbus_write_byte_data(client, SRF08_WRITE_RANGE, regval);
0278     if (ret < 0) {
0279         dev_err(&client->dev, "write_range - err: %d\n", ret);
0280         mutex_unlock(&data->lock);
0281         return ret;
0282     }
0283 
0284     data->range_mm = val;
0285 
0286     mutex_unlock(&data->lock);
0287 
0288     return 0;
0289 }
0290 
0291 static ssize_t srf08_store_range_mm(struct device *dev,
0292                     struct device_attribute *attr,
0293                     const char *buf, size_t len)
0294 {
0295     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0296     struct srf08_data *data = iio_priv(indio_dev);
0297     int ret;
0298     int integer, fract;
0299 
0300     ret = iio_str_to_fixpoint(buf, 100, &integer, &fract);
0301     if (ret)
0302         return ret;
0303 
0304     ret = srf08_write_range_mm(data, integer * 1000 + fract);
0305     if (ret < 0)
0306         return ret;
0307 
0308     return len;
0309 }
0310 
0311 static IIO_DEVICE_ATTR(sensor_max_range, S_IRUGO | S_IWUSR,
0312             srf08_show_range_mm, srf08_store_range_mm, 0);
0313 
0314 static ssize_t srf08_show_sensitivity_available(struct device *dev,
0315                 struct device_attribute *attr, char *buf)
0316 {
0317     int i, len = 0;
0318     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0319     struct srf08_data *data = iio_priv(indio_dev);
0320 
0321     for (i = 0; i < data->chip_info->num_sensitivity_avail; i++)
0322         if (data->chip_info->sensitivity_avail[i])
0323             len += sprintf(buf + len, "%d ",
0324                 data->chip_info->sensitivity_avail[i]);
0325 
0326     len += sprintf(buf + len, "\n");
0327 
0328     return len;
0329 }
0330 
0331 static IIO_DEVICE_ATTR(sensor_sensitivity_available, S_IRUGO,
0332                 srf08_show_sensitivity_available, NULL, 0);
0333 
0334 static ssize_t srf08_show_sensitivity(struct device *dev,
0335                 struct device_attribute *attr, char *buf)
0336 {
0337     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0338     struct srf08_data *data = iio_priv(indio_dev);
0339     int len;
0340 
0341     len = sprintf(buf, "%d\n", data->sensitivity);
0342 
0343     return len;
0344 }
0345 
0346 static ssize_t srf08_write_sensitivity(struct srf08_data *data,
0347                             unsigned int val)
0348 {
0349     struct i2c_client *client = data->client;
0350     int ret, i;
0351     u8 regval;
0352 
0353     if (!val)
0354         return -EINVAL;
0355 
0356     for (i = 0; i < data->chip_info->num_sensitivity_avail; i++)
0357         if (val == data->chip_info->sensitivity_avail[i]) {
0358             regval = i;
0359             break;
0360         }
0361 
0362     if (i >= data->chip_info->num_sensitivity_avail)
0363         return -EINVAL;
0364 
0365     mutex_lock(&data->lock);
0366 
0367     ret = i2c_smbus_write_byte_data(client, SRF08_WRITE_MAX_GAIN, regval);
0368     if (ret < 0) {
0369         dev_err(&client->dev, "write_sensitivity - err: %d\n", ret);
0370         mutex_unlock(&data->lock);
0371         return ret;
0372     }
0373 
0374     data->sensitivity = val;
0375 
0376     mutex_unlock(&data->lock);
0377 
0378     return 0;
0379 }
0380 
0381 static ssize_t srf08_store_sensitivity(struct device *dev,
0382                         struct device_attribute *attr,
0383                         const char *buf, size_t len)
0384 {
0385     struct iio_dev *indio_dev = dev_to_iio_dev(dev);
0386     struct srf08_data *data = iio_priv(indio_dev);
0387     int ret;
0388     unsigned int val;
0389 
0390     ret = kstrtouint(buf, 10, &val);
0391     if (ret)
0392         return ret;
0393 
0394     ret = srf08_write_sensitivity(data, val);
0395     if (ret < 0)
0396         return ret;
0397 
0398     return len;
0399 }
0400 
0401 static IIO_DEVICE_ATTR(sensor_sensitivity, S_IRUGO | S_IWUSR,
0402             srf08_show_sensitivity, srf08_store_sensitivity, 0);
0403 
0404 static struct attribute *srf08_attributes[] = {
0405     &iio_dev_attr_sensor_max_range.dev_attr.attr,
0406     &iio_dev_attr_sensor_max_range_available.dev_attr.attr,
0407     &iio_dev_attr_sensor_sensitivity.dev_attr.attr,
0408     &iio_dev_attr_sensor_sensitivity_available.dev_attr.attr,
0409     NULL,
0410 };
0411 
0412 static const struct attribute_group srf08_attribute_group = {
0413     .attrs = srf08_attributes,
0414 };
0415 
0416 static const struct iio_chan_spec srf08_channels[] = {
0417     {
0418         .type = IIO_DISTANCE,
0419         .info_mask_separate =
0420                 BIT(IIO_CHAN_INFO_RAW) |
0421                 BIT(IIO_CHAN_INFO_SCALE),
0422         .scan_index = 0,
0423         .scan_type = {
0424             .sign = 's',
0425             .realbits = 16,
0426             .storagebits = 16,
0427             .endianness = IIO_CPU,
0428         },
0429     },
0430     IIO_CHAN_SOFT_TIMESTAMP(1),
0431 };
0432 
0433 static const struct iio_info srf08_info = {
0434     .read_raw = srf08_read_raw,
0435     .attrs = &srf08_attribute_group,
0436 };
0437 
0438 /*
0439  * srf02 don't have an adjustable range or sensitivity,
0440  * so we don't need attributes at all
0441  */
0442 static const struct iio_info srf02_info = {
0443     .read_raw = srf08_read_raw,
0444 };
0445 
0446 static int srf08_probe(struct i2c_client *client,
0447                      const struct i2c_device_id *id)
0448 {
0449     struct iio_dev *indio_dev;
0450     struct srf08_data *data;
0451     int ret;
0452 
0453     if (!i2c_check_functionality(client->adapter,
0454                     I2C_FUNC_SMBUS_READ_BYTE_DATA |
0455                     I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
0456                     I2C_FUNC_SMBUS_READ_WORD_DATA))
0457         return -ENODEV;
0458 
0459     indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
0460     if (!indio_dev)
0461         return -ENOMEM;
0462 
0463     data = iio_priv(indio_dev);
0464     i2c_set_clientdata(client, indio_dev);
0465     data->client = client;
0466     data->sensor_type = (enum srf08_sensor_type)id->driver_data;
0467 
0468     switch (data->sensor_type) {
0469     case SRF02:
0470         data->chip_info = &srf02_chip_info;
0471         indio_dev->info = &srf02_info;
0472         break;
0473     case SRF08:
0474         data->chip_info = &srf08_chip_info;
0475         indio_dev->info = &srf08_info;
0476         break;
0477     case SRF10:
0478         data->chip_info = &srf10_chip_info;
0479         indio_dev->info = &srf08_info;
0480         break;
0481     default:
0482         return -EINVAL;
0483     }
0484 
0485     indio_dev->name = id->name;
0486     indio_dev->modes = INDIO_DIRECT_MODE;
0487     indio_dev->channels = srf08_channels;
0488     indio_dev->num_channels = ARRAY_SIZE(srf08_channels);
0489 
0490     mutex_init(&data->lock);
0491 
0492     ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev,
0493             iio_pollfunc_store_time, srf08_trigger_handler, NULL);
0494     if (ret < 0) {
0495         dev_err(&client->dev, "setup of iio triggered buffer failed\n");
0496         return ret;
0497     }
0498 
0499     if (data->chip_info->range_default) {
0500         /*
0501          * set default range of device in mm here
0502          * these register values cannot be read from the hardware
0503          * therefore set driver specific default values
0504          *
0505          * srf02 don't have a default value so it'll be omitted
0506          */
0507         ret = srf08_write_range_mm(data,
0508                     data->chip_info->range_default);
0509         if (ret < 0)
0510             return ret;
0511     }
0512 
0513     if (data->chip_info->sensitivity_default) {
0514         /*
0515          * set default sensitivity of device here
0516          * these register values cannot be read from the hardware
0517          * therefore set driver specific default values
0518          *
0519          * srf02 don't have a default value so it'll be omitted
0520          */
0521         ret = srf08_write_sensitivity(data,
0522                 data->chip_info->sensitivity_default);
0523         if (ret < 0)
0524             return ret;
0525     }
0526 
0527     return devm_iio_device_register(&client->dev, indio_dev);
0528 }
0529 
0530 static const struct of_device_id of_srf08_match[] = {
0531     { .compatible = "devantech,srf02", (void *)SRF02 },
0532     { .compatible = "devantech,srf08", (void *)SRF08 },
0533     { .compatible = "devantech,srf10", (void *)SRF10 },
0534     {},
0535 };
0536 
0537 MODULE_DEVICE_TABLE(of, of_srf08_match);
0538 
0539 static const struct i2c_device_id srf08_id[] = {
0540     { "srf02", SRF02 },
0541     { "srf08", SRF08 },
0542     { "srf10", SRF10 },
0543     { }
0544 };
0545 MODULE_DEVICE_TABLE(i2c, srf08_id);
0546 
0547 static struct i2c_driver srf08_driver = {
0548     .driver = {
0549         .name   = "srf08",
0550         .of_match_table = of_srf08_match,
0551     },
0552     .probe = srf08_probe,
0553     .id_table = srf08_id,
0554 };
0555 module_i2c_driver(srf08_driver);
0556 
0557 MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
0558 MODULE_DESCRIPTION("Devantech SRF02/SRF08/SRF10 i2c ultrasonic ranger driver");
0559 MODULE_LICENSE("GPL");