Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * mb1232.c - Support for MaxBotix I2CXL-MaxSonar-EZ series ultrasonic
0004  *   ranger with i2c interface
0005  * actually tested with mb1232 type
0006  *
0007  * Copyright (c) 2019 Andreas Klinger <ak@it-klinger.de>
0008  *
0009  * For details about the device see:
0010  * https://www.maxbotix.com/documents/I2CXL-MaxSonar-EZ_Datasheet.pdf
0011  */
0012 
0013 #include <linux/bitops.h>
0014 #include <linux/err.h>
0015 #include <linux/i2c.h>
0016 #include <linux/delay.h>
0017 #include <linux/mod_devicetable.h>
0018 #include <linux/module.h>
0019 #include <linux/property.h>
0020 
0021 #include <linux/iio/iio.h>
0022 #include <linux/iio/sysfs.h>
0023 #include <linux/iio/buffer.h>
0024 #include <linux/iio/trigger_consumer.h>
0025 #include <linux/iio/triggered_buffer.h>
0026 
0027 /* registers of MaxSonar device */
0028 #define MB1232_RANGE_COMMAND    0x51    /* Command for reading range */
0029 #define MB1232_ADDR_UNLOCK_1    0xAA    /* Command 1 for changing address */
0030 #define MB1232_ADDR_UNLOCK_2    0xA5    /* Command 2 for changing address */
0031 
0032 struct mb1232_data {
0033     struct i2c_client   *client;
0034 
0035     struct mutex        lock;
0036 
0037     /*
0038      * optionally a gpio can be used to announce when ranging has
0039      * finished
0040      * since we are just using the falling trigger of it we request
0041      * only the interrupt for announcing when data is ready to be read
0042      */
0043     struct completion   ranging;
0044     int         irqnr;
0045     /* Ensure correct alignment of data to push to IIO buffer */
0046     struct {
0047         s16 distance;
0048         s64 ts __aligned(8);
0049     } scan;
0050 };
0051 
0052 static irqreturn_t mb1232_handle_irq(int irq, void *dev_id)
0053 {
0054     struct iio_dev *indio_dev = dev_id;
0055     struct mb1232_data *data = iio_priv(indio_dev);
0056 
0057     complete(&data->ranging);
0058 
0059     return IRQ_HANDLED;
0060 }
0061 
0062 static s16 mb1232_read_distance(struct mb1232_data *data)
0063 {
0064     struct i2c_client *client = data->client;
0065     int ret;
0066     s16 distance;
0067     __be16 buf;
0068 
0069     mutex_lock(&data->lock);
0070 
0071     reinit_completion(&data->ranging);
0072 
0073     ret = i2c_smbus_write_byte(client, MB1232_RANGE_COMMAND);
0074     if (ret < 0) {
0075         dev_err(&client->dev, "write command - err: %d\n", ret);
0076         goto error_unlock;
0077     }
0078 
0079     if (data->irqnr >= 0) {
0080         /* it cannot take more than 100 ms */
0081         ret = wait_for_completion_killable_timeout(&data->ranging,
0082                                     HZ/10);
0083         if (ret < 0)
0084             goto error_unlock;
0085         else if (ret == 0) {
0086             ret = -ETIMEDOUT;
0087             goto error_unlock;
0088         }
0089     } else {
0090         /* use simple sleep if announce irq is not connected */
0091         msleep(15);
0092     }
0093 
0094     ret = i2c_master_recv(client, (char *)&buf, sizeof(buf));
0095     if (ret < 0) {
0096         dev_err(&client->dev, "i2c_master_recv: ret=%d\n", ret);
0097         goto error_unlock;
0098     }
0099 
0100     distance = __be16_to_cpu(buf);
0101     /* check for not returning misleading error codes */
0102     if (distance < 0) {
0103         dev_err(&client->dev, "distance=%d\n", distance);
0104         ret = -EINVAL;
0105         goto error_unlock;
0106     }
0107 
0108     mutex_unlock(&data->lock);
0109 
0110     return distance;
0111 
0112 error_unlock:
0113     mutex_unlock(&data->lock);
0114 
0115     return ret;
0116 }
0117 
0118 static irqreturn_t mb1232_trigger_handler(int irq, void *p)
0119 {
0120     struct iio_poll_func *pf = p;
0121     struct iio_dev *indio_dev = pf->indio_dev;
0122     struct mb1232_data *data = iio_priv(indio_dev);
0123 
0124     data->scan.distance = mb1232_read_distance(data);
0125     if (data->scan.distance < 0)
0126         goto err;
0127 
0128     iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
0129                        pf->timestamp);
0130 
0131 err:
0132     iio_trigger_notify_done(indio_dev->trig);
0133     return IRQ_HANDLED;
0134 }
0135 
0136 static int mb1232_read_raw(struct iio_dev *indio_dev,
0137                 struct iio_chan_spec const *channel, int *val,
0138                 int *val2, long mask)
0139 {
0140     struct mb1232_data *data = iio_priv(indio_dev);
0141     int ret;
0142 
0143     if (channel->type != IIO_DISTANCE)
0144         return -EINVAL;
0145 
0146     switch (mask) {
0147     case IIO_CHAN_INFO_RAW:
0148         ret = mb1232_read_distance(data);
0149         if (ret < 0)
0150             return ret;
0151         *val = ret;
0152         return IIO_VAL_INT;
0153     case IIO_CHAN_INFO_SCALE:
0154         /* 1 LSB is 1 cm */
0155         *val = 0;
0156         *val2 = 10000;
0157         return IIO_VAL_INT_PLUS_MICRO;
0158     default:
0159         return -EINVAL;
0160     }
0161 }
0162 
0163 static const struct iio_chan_spec mb1232_channels[] = {
0164     {
0165         .type = IIO_DISTANCE,
0166         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
0167                       BIT(IIO_CHAN_INFO_SCALE),
0168         .scan_index = 0,
0169         .scan_type = {
0170             .sign = 's',
0171             .realbits = 16,
0172             .storagebits = 16,
0173             .endianness = IIO_CPU,
0174         },
0175     },
0176     IIO_CHAN_SOFT_TIMESTAMP(1),
0177 };
0178 
0179 static const struct iio_info mb1232_info = {
0180     .read_raw = mb1232_read_raw,
0181 };
0182 
0183 static int mb1232_probe(struct i2c_client *client,
0184                      const struct i2c_device_id *id)
0185 {
0186     struct iio_dev *indio_dev;
0187     struct mb1232_data *data;
0188     int ret;
0189     struct device *dev = &client->dev;
0190 
0191     if (!i2c_check_functionality(client->adapter,
0192                     I2C_FUNC_SMBUS_READ_BYTE |
0193                     I2C_FUNC_SMBUS_WRITE_BYTE))
0194         return -ENODEV;
0195 
0196     indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
0197     if (!indio_dev)
0198         return -ENOMEM;
0199 
0200     data = iio_priv(indio_dev);
0201     i2c_set_clientdata(client, indio_dev);
0202     data->client = client;
0203 
0204     indio_dev->info = &mb1232_info;
0205     indio_dev->name = id->name;
0206     indio_dev->modes = INDIO_DIRECT_MODE;
0207     indio_dev->channels = mb1232_channels;
0208     indio_dev->num_channels = ARRAY_SIZE(mb1232_channels);
0209 
0210     mutex_init(&data->lock);
0211 
0212     init_completion(&data->ranging);
0213 
0214     data->irqnr = fwnode_irq_get(dev_fwnode(&client->dev), 0);
0215     if (data->irqnr <= 0) {
0216         /* usage of interrupt is optional */
0217         data->irqnr = -1;
0218     } else {
0219         ret = devm_request_irq(dev, data->irqnr, mb1232_handle_irq,
0220                 IRQF_TRIGGER_FALLING, id->name, indio_dev);
0221         if (ret < 0) {
0222             dev_err(dev, "request_irq: %d\n", ret);
0223             return ret;
0224         }
0225     }
0226 
0227     ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
0228             iio_pollfunc_store_time, mb1232_trigger_handler, NULL);
0229     if (ret < 0) {
0230         dev_err(dev, "setup of iio triggered buffer failed\n");
0231         return ret;
0232     }
0233 
0234     return devm_iio_device_register(dev, indio_dev);
0235 }
0236 
0237 static const struct of_device_id of_mb1232_match[] = {
0238     { .compatible = "maxbotix,mb1202", },
0239     { .compatible = "maxbotix,mb1212", },
0240     { .compatible = "maxbotix,mb1222", },
0241     { .compatible = "maxbotix,mb1232", },
0242     { .compatible = "maxbotix,mb1242", },
0243     { .compatible = "maxbotix,mb7040", },
0244     { .compatible = "maxbotix,mb7137", },
0245     {},
0246 };
0247 
0248 MODULE_DEVICE_TABLE(of, of_mb1232_match);
0249 
0250 static const struct i2c_device_id mb1232_id[] = {
0251     { "maxbotix-mb1202", },
0252     { "maxbotix-mb1212", },
0253     { "maxbotix-mb1222", },
0254     { "maxbotix-mb1232", },
0255     { "maxbotix-mb1242", },
0256     { "maxbotix-mb7040", },
0257     { "maxbotix-mb7137", },
0258     { }
0259 };
0260 MODULE_DEVICE_TABLE(i2c, mb1232_id);
0261 
0262 static struct i2c_driver mb1232_driver = {
0263     .driver = {
0264         .name   = "maxbotix-mb1232",
0265         .of_match_table = of_mb1232_match,
0266     },
0267     .probe = mb1232_probe,
0268     .id_table = mb1232_id,
0269 };
0270 module_i2c_driver(mb1232_driver);
0271 
0272 MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
0273 MODULE_DESCRIPTION("Maxbotix I2CXL-MaxSonar i2c ultrasonic ranger driver");
0274 MODULE_LICENSE("GPL");