^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * mb1232.c - Support for MaxBotix I2CXL-MaxSonar-EZ series ultrasonic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * ranger with i2c interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * actually tested with mb1232 type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 2019 Andreas Klinger <ak@it-klinger.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * For details about the device see:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * https://www.maxbotix.com/documents/I2CXL-MaxSonar-EZ_Datasheet.pdf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/iio/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/iio/buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/iio/trigger_consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/iio/triggered_buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* registers of MaxSonar device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define MB1232_RANGE_COMMAND 0x51 /* Command for reading range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define MB1232_ADDR_UNLOCK_1 0xAA /* Command 1 for changing address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define MB1232_ADDR_UNLOCK_2 0xA5 /* Command 2 for changing address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct mb1232_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * optionally a gpio can be used to announce when ranging has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * finished
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * since we are just using the falling trigger of it we request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * only the interrupt for announcing when data is ready to be read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct completion ranging;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) int irqnr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* Ensure correct alignment of data to push to IIO buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) s16 distance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) s64 ts __aligned(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) } scan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static irqreturn_t mb1232_handle_irq(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct iio_dev *indio_dev = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct mb1232_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) complete(&data->ranging);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static s16 mb1232_read_distance(struct mb1232_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) s16 distance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) __be16 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) reinit_completion(&data->ranging);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) ret = i2c_smbus_write_byte(client, MB1232_RANGE_COMMAND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) dev_err(&client->dev, "write command - err: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) goto error_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (data->irqnr >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* it cannot take more than 100 ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) ret = wait_for_completion_killable_timeout(&data->ranging,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) HZ/10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) goto error_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) else if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) goto error_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /* use simple sleep if announce irq is not connected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) msleep(15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ret = i2c_master_recv(client, (char *)&buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) dev_err(&client->dev, "i2c_master_recv: ret=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) goto error_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) distance = __be16_to_cpu(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /* check for not returning misleading error codes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (distance < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) dev_err(&client->dev, "distance=%d\n", distance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) goto error_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return distance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) error_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static irqreturn_t mb1232_trigger_handler(int irq, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct iio_poll_func *pf = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct iio_dev *indio_dev = pf->indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct mb1232_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) data->scan.distance = mb1232_read_distance(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (data->scan.distance < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) pf->timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) iio_trigger_notify_done(indio_dev->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static int mb1232_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct iio_chan_spec const *channel, int *val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) int *val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct mb1232_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (channel->type != IIO_DISTANCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) ret = mb1232_read_distance(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) *val = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /* 1 LSB is 1 cm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) *val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) *val2 = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static const struct iio_chan_spec mb1232_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .type = IIO_DISTANCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) BIT(IIO_CHAN_INFO_SCALE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) .scan_index = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) .scan_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) .sign = 's',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) .realbits = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) .storagebits = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) .endianness = IIO_CPU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) IIO_CHAN_SOFT_TIMESTAMP(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static const struct iio_info mb1232_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .read_raw = mb1232_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static int mb1232_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct mb1232_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (!i2c_check_functionality(client->adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) I2C_FUNC_SMBUS_READ_BYTE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) I2C_FUNC_SMBUS_WRITE_BYTE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (!indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) i2c_set_clientdata(client, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) data->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) indio_dev->info = &mb1232_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) indio_dev->name = id->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) indio_dev->channels = mb1232_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) indio_dev->num_channels = ARRAY_SIZE(mb1232_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) mutex_init(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) init_completion(&data->ranging);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) data->irqnr = irq_of_parse_and_map(dev->of_node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (data->irqnr <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* usage of interrupt is optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) data->irqnr = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) ret = devm_request_irq(dev, data->irqnr, mb1232_handle_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) IRQF_TRIGGER_FALLING, id->name, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) dev_err(dev, "request_irq: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) iio_pollfunc_store_time, mb1232_trigger_handler, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) dev_err(dev, "setup of iio triggered buffer failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return devm_iio_device_register(dev, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) static const struct of_device_id of_mb1232_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) { .compatible = "maxbotix,mb1202", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) { .compatible = "maxbotix,mb1212", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) { .compatible = "maxbotix,mb1222", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) { .compatible = "maxbotix,mb1232", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) { .compatible = "maxbotix,mb1242", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) { .compatible = "maxbotix,mb7040", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) { .compatible = "maxbotix,mb7137", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) MODULE_DEVICE_TABLE(of, of_mb1232_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static const struct i2c_device_id mb1232_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) { "maxbotix-mb1202", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) { "maxbotix-mb1212", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) { "maxbotix-mb1222", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) { "maxbotix-mb1232", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) { "maxbotix-mb1242", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) { "maxbotix-mb7040", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) { "maxbotix-mb7137", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) MODULE_DEVICE_TABLE(i2c, mb1232_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static struct i2c_driver mb1232_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) .name = "maxbotix-mb1232",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) .of_match_table = of_mb1232_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) .probe = mb1232_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) .id_table = mb1232_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) module_i2c_driver(mb1232_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) MODULE_DESCRIPTION("Maxbotix I2CXL-MaxSonar i2c ultrasonic ranger driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) MODULE_LICENSE("GPL");