^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * srf08.c - Support for Devantech SRFxx ultrasonic ranger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * with i2c interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * actually supported are srf02, srf08, srf10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 2016, 2017 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.robot-electronics.co.uk/htm/srf08tech.html
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * https://www.robot-electronics.co.uk/htm/srf10tech.htm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * https://www.robot-electronics.co.uk/htm/srf02tech.htm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/iio/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/iio/buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/iio/trigger_consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/iio/triggered_buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /* registers of SRF08 device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define SRF08_WRITE_COMMAND 0x00 /* Command Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define SRF08_WRITE_MAX_GAIN 0x01 /* Max Gain Register: 0 .. 31 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define SRF08_WRITE_RANGE 0x02 /* Range Register: 0 .. 255 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define SRF08_READ_SW_REVISION 0x00 /* Software Revision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define SRF08_READ_LIGHT 0x01 /* Light Sensor during last echo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define SRF08_READ_ECHO_1_HIGH 0x02 /* Range of first echo received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define SRF08_READ_ECHO_1_LOW 0x03 /* Range of first echo received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define SRF08_CMD_RANGING_CM 0x51 /* Ranging Mode - Result in cm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) enum srf08_sensor_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) SRF02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) SRF08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) SRF10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) SRF_MAX_TYPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct srf08_chip_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) const int *sensitivity_avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) int num_sensitivity_avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) int sensitivity_default;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* default value of Range in mm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) int range_default;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct srf08_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * Gain in the datasheet is called sensitivity here to distinct it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * from the gain used with amplifiers of adc's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int sensitivity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* max. Range in mm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int range_mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* Ensure timestamp is naturally aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) s16 chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) s64 timestamp __aligned(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) } scan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* Sensor-Type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) enum srf08_sensor_type sensor_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* Chip-specific information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) const struct srf08_chip_info *chip_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * in the documentation one can read about the "Gain" of the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * which is used here for amplifying the signal and filtering out unwanted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * ones.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * But with ADC's this term is already used differently and that's why it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * is called "Sensitivity" here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static const struct srf08_chip_info srf02_chip_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) .sensitivity_avail = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .num_sensitivity_avail = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .sensitivity_default = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) .range_default = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static const int srf08_sensitivity_avail[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) 94, 97, 100, 103, 107, 110, 114, 118,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) 123, 128, 133, 139, 145, 152, 159, 168,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) 177, 187, 199, 212, 227, 245, 265, 288,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) 317, 352, 395, 450, 524, 626, 777, 1025
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static const struct srf08_chip_info srf08_chip_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .sensitivity_avail = srf08_sensitivity_avail,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .num_sensitivity_avail = ARRAY_SIZE(srf08_sensitivity_avail),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .sensitivity_default = 1025,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) .range_default = 6020,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static const int srf10_sensitivity_avail[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 40, 40, 50, 60, 70, 80, 100, 120,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 140, 200, 250, 300, 350, 400, 500, 600,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 700,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static const struct srf08_chip_info srf10_chip_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) .sensitivity_avail = srf10_sensitivity_avail,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) .num_sensitivity_avail = ARRAY_SIZE(srf10_sensitivity_avail),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) .sensitivity_default = 700,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .range_default = 6020,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static int srf08_read_ranging(struct srf08_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int waittime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) ret = i2c_smbus_write_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) SRF08_WRITE_COMMAND, SRF08_CMD_RANGING_CM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) dev_err(&client->dev, "write command - err: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * we read here until a correct version number shows up as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * suggested by the documentation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * with an ultrasonic speed of 343 m/s and a roundtrip of it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * sleep the expected duration and try to read from the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * if nothing useful is read try it in a shorter grid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * polling for not more than 20 ms should be enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) waittime = 1 + data->range_mm / 172;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) msleep(waittime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ret = i2c_smbus_read_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) SRF08_READ_SW_REVISION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* check if a valid version number is read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (ret < 255 && ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) msleep(5);
^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) if (ret >= 255 || ret <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) dev_err(&client->dev, "device not ready\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) ret = i2c_smbus_read_word_swapped(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) SRF08_READ_ECHO_1_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) dev_err(&client->dev, "cannot read distance: ret=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static irqreturn_t srf08_trigger_handler(int irq, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct iio_poll_func *pf = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct iio_dev *indio_dev = pf->indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct srf08_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) s16 sensor_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) sensor_data = srf08_read_ranging(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (sensor_data < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) data->scan.chan = sensor_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) iio_push_to_buffers_with_timestamp(indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) &data->scan, pf->timestamp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) iio_trigger_notify_done(indio_dev->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static int srf08_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct iio_chan_spec const *channel, int *val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) int *val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct srf08_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (channel->type != IIO_DISTANCE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) ret = srf08_read_ranging(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) *val = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /* 1 LSB is 1 cm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) *val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) *val2 = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static ssize_t srf08_show_range_mm_available(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return sprintf(buf, "[0.043 0.043 11.008]\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static IIO_DEVICE_ATTR(sensor_max_range_available, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) srf08_show_range_mm_available, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static ssize_t srf08_show_range_mm(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct iio_dev *indio_dev = dev_to_iio_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct srf08_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return sprintf(buf, "%d.%03d\n", data->range_mm / 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) data->range_mm % 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * set the range of the sensor to an even multiple of 43 mm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * which corresponds to 1 LSB in the register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * register value corresponding range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * 0x00 43 mm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * 0x01 86 mm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * 0x02 129 mm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * 0xFF 11008 mm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static ssize_t srf08_write_range_mm(struct srf08_data *data, unsigned int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) unsigned int mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) u8 regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ret = val / 43 - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) mod = val % 43;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (mod || (ret < 0) || (ret > 255))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) regval = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) ret = i2c_smbus_write_byte_data(client, SRF08_WRITE_RANGE, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) dev_err(&client->dev, "write_range - err: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) data->range_mm = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static ssize_t srf08_store_range_mm(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct iio_dev *indio_dev = dev_to_iio_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct srf08_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) int integer, fract;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) ret = iio_str_to_fixpoint(buf, 100, &integer, &fract);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ret = srf08_write_range_mm(data, integer * 1000 + fract);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static IIO_DEVICE_ATTR(sensor_max_range, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) srf08_show_range_mm, srf08_store_range_mm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static ssize_t srf08_show_sensitivity_available(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) int i, len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct iio_dev *indio_dev = dev_to_iio_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct srf08_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) for (i = 0; i < data->chip_info->num_sensitivity_avail; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (data->chip_info->sensitivity_avail[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) len += sprintf(buf + len, "%d ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) data->chip_info->sensitivity_avail[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) len += sprintf(buf + len, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static IIO_DEVICE_ATTR(sensor_sensitivity_available, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) srf08_show_sensitivity_available, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static ssize_t srf08_show_sensitivity(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) struct iio_dev *indio_dev = dev_to_iio_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) struct srf08_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) len = sprintf(buf, "%d\n", data->sensitivity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static ssize_t srf08_write_sensitivity(struct srf08_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) unsigned int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) u8 regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) for (i = 0; i < data->chip_info->num_sensitivity_avail; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (val && (val == data->chip_info->sensitivity_avail[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) regval = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (i >= data->chip_info->num_sensitivity_avail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) ret = i2c_smbus_write_byte_data(client, SRF08_WRITE_MAX_GAIN, regval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) dev_err(&client->dev, "write_sensitivity - err: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) data->sensitivity = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static ssize_t srf08_store_sensitivity(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct iio_dev *indio_dev = dev_to_iio_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct srf08_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ret = kstrtouint(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) ret = srf08_write_sensitivity(data, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) static IIO_DEVICE_ATTR(sensor_sensitivity, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) srf08_show_sensitivity, srf08_store_sensitivity, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static struct attribute *srf08_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) &iio_dev_attr_sensor_max_range.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) &iio_dev_attr_sensor_max_range_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) &iio_dev_attr_sensor_sensitivity.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) &iio_dev_attr_sensor_sensitivity_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static const struct attribute_group srf08_attribute_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) .attrs = srf08_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) static const struct iio_chan_spec srf08_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) .type = IIO_DISTANCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) .info_mask_separate =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) BIT(IIO_CHAN_INFO_RAW) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) BIT(IIO_CHAN_INFO_SCALE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) .scan_index = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) .scan_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) .sign = 's',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) .realbits = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) .storagebits = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) .endianness = IIO_CPU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) IIO_CHAN_SOFT_TIMESTAMP(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static const struct iio_info srf08_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) .read_raw = srf08_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) .attrs = &srf08_attribute_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) * srf02 don't have an adjustable range or sensitivity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * so we don't need attributes at all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static const struct iio_info srf02_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) .read_raw = srf08_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static int srf08_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) struct srf08_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (!i2c_check_functionality(client->adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) I2C_FUNC_SMBUS_READ_BYTE_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) I2C_FUNC_SMBUS_READ_WORD_DATA))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (!indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) i2c_set_clientdata(client, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) data->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) data->sensor_type = (enum srf08_sensor_type)id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) switch (data->sensor_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) case SRF02:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) data->chip_info = &srf02_chip_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) indio_dev->info = &srf02_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) case SRF08:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) data->chip_info = &srf08_chip_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) indio_dev->info = &srf08_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) case SRF10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) data->chip_info = &srf10_chip_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) indio_dev->info = &srf08_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) indio_dev->name = id->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) indio_dev->channels = srf08_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) indio_dev->num_channels = ARRAY_SIZE(srf08_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) mutex_init(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) iio_pollfunc_store_time, srf08_trigger_handler, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) dev_err(&client->dev, "setup of iio triggered buffer failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (data->chip_info->range_default) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) * set default range of device in mm here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) * these register values cannot be read from the hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) * therefore set driver specific default values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * srf02 don't have a default value so it'll be omitted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) ret = srf08_write_range_mm(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) data->chip_info->range_default);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (data->chip_info->sensitivity_default) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * set default sensitivity of device here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * these register values cannot be read from the hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * therefore set driver specific default values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * srf02 don't have a default value so it'll be omitted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) ret = srf08_write_sensitivity(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) data->chip_info->sensitivity_default);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return devm_iio_device_register(&client->dev, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) static const struct of_device_id of_srf08_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) { .compatible = "devantech,srf02", (void *)SRF02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) { .compatible = "devantech,srf08", (void *)SRF08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) { .compatible = "devantech,srf10", (void *)SRF10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) MODULE_DEVICE_TABLE(of, of_srf08_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static const struct i2c_device_id srf08_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) { "srf02", SRF02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) { "srf08", SRF08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) { "srf10", SRF10 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) MODULE_DEVICE_TABLE(i2c, srf08_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static struct i2c_driver srf08_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) .name = "srf08",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .of_match_table = of_srf08_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) .probe = srf08_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) .id_table = srf08_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) module_i2c_driver(srf08_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) MODULE_DESCRIPTION("Devantech SRF02/SRF08/SRF10 i2c ultrasonic ranger driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) MODULE_LICENSE("GPL");