136edc939SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 278f83902SAndreas Klinger /* 3c5bf4a04SAndreas Klinger * srf08.c - Support for Devantech SRFxx ultrasonic ranger 4c5bf4a04SAndreas Klinger * with i2c interface 5dc2696baSAndreas Klinger * actually supported are srf02, srf08, srf10 678f83902SAndreas Klinger * 7dc2696baSAndreas Klinger * Copyright (c) 2016, 2017 Andreas Klinger <ak@it-klinger.de> 878f83902SAndreas Klinger * 978f83902SAndreas Klinger * For details about the device see: 103593cd53SAlexander A. Klimov * https://www.robot-electronics.co.uk/htm/srf08tech.html 113593cd53SAlexander A. Klimov * https://www.robot-electronics.co.uk/htm/srf10tech.htm 123593cd53SAlexander A. Klimov * https://www.robot-electronics.co.uk/htm/srf02tech.htm 1378f83902SAndreas Klinger */ 1478f83902SAndreas Klinger 1578f83902SAndreas Klinger #include <linux/err.h> 1678f83902SAndreas Klinger #include <linux/i2c.h> 1778f83902SAndreas Klinger #include <linux/delay.h> 1878f83902SAndreas Klinger #include <linux/module.h> 1978f83902SAndreas Klinger #include <linux/bitops.h> 2078f83902SAndreas Klinger #include <linux/iio/iio.h> 2178f83902SAndreas Klinger #include <linux/iio/sysfs.h> 22a8319593SAndreas Klinger #include <linux/iio/buffer.h> 23a8319593SAndreas Klinger #include <linux/iio/trigger_consumer.h> 24a8319593SAndreas Klinger #include <linux/iio/triggered_buffer.h> 2578f83902SAndreas Klinger 2678f83902SAndreas Klinger /* registers of SRF08 device */ 2778f83902SAndreas Klinger #define SRF08_WRITE_COMMAND 0x00 /* Command Register */ 2878f83902SAndreas Klinger #define SRF08_WRITE_MAX_GAIN 0x01 /* Max Gain Register: 0 .. 31 */ 2978f83902SAndreas Klinger #define SRF08_WRITE_RANGE 0x02 /* Range Register: 0 .. 255 */ 3078f83902SAndreas Klinger #define SRF08_READ_SW_REVISION 0x00 /* Software Revision */ 3178f83902SAndreas Klinger #define SRF08_READ_LIGHT 0x01 /* Light Sensor during last echo */ 3278f83902SAndreas Klinger #define SRF08_READ_ECHO_1_HIGH 0x02 /* Range of first echo received */ 3378f83902SAndreas Klinger #define SRF08_READ_ECHO_1_LOW 0x03 /* Range of first echo received */ 3478f83902SAndreas Klinger 3578f83902SAndreas Klinger #define SRF08_CMD_RANGING_CM 0x51 /* Ranging Mode - Result in cm */ 3678f83902SAndreas Klinger 37c5bf4a04SAndreas Klinger enum srf08_sensor_type { 38dc2696baSAndreas Klinger SRF02, 39c5bf4a04SAndreas Klinger SRF08, 40c5bf4a04SAndreas Klinger SRF10, 41c5bf4a04SAndreas Klinger SRF_MAX_TYPE 42c5bf4a04SAndreas Klinger }; 43c5bf4a04SAndreas Klinger 44c5bf4a04SAndreas Klinger struct srf08_chip_info { 45c5bf4a04SAndreas Klinger const int *sensitivity_avail; 46c5bf4a04SAndreas Klinger int num_sensitivity_avail; 47c5bf4a04SAndreas Klinger int sensitivity_default; 48dc2696baSAndreas Klinger 49dc2696baSAndreas Klinger /* default value of Range in mm */ 50dc2696baSAndreas Klinger int range_default; 51c5bf4a04SAndreas Klinger }; 52c5bf4a04SAndreas Klinger 5378f83902SAndreas Klinger struct srf08_data { 5478f83902SAndreas Klinger struct i2c_client *client; 55a8319593SAndreas Klinger 56a8319593SAndreas Klinger /* 57a8319593SAndreas Klinger * Gain in the datasheet is called sensitivity here to distinct it 58a8319593SAndreas Klinger * from the gain used with amplifiers of adc's 59a8319593SAndreas Klinger */ 60a8319593SAndreas Klinger int sensitivity; 61a8319593SAndreas Klinger 62a8319593SAndreas Klinger /* max. Range in mm */ 63a8319593SAndreas Klinger int range_mm; 6478f83902SAndreas Klinger struct mutex lock; 65a8319593SAndreas Klinger 66a8319593SAndreas Klinger /* 67a8319593SAndreas Klinger * triggered buffer 68a8319593SAndreas Klinger * 1x16-bit channel + 3x16 padding + 4x16 timestamp 69a8319593SAndreas Klinger */ 70a8319593SAndreas Klinger s16 buffer[8]; 71c5bf4a04SAndreas Klinger 72c5bf4a04SAndreas Klinger /* Sensor-Type */ 73c5bf4a04SAndreas Klinger enum srf08_sensor_type sensor_type; 74c5bf4a04SAndreas Klinger 75c5bf4a04SAndreas Klinger /* Chip-specific information */ 76c5bf4a04SAndreas Klinger const struct srf08_chip_info *chip_info; 7778f83902SAndreas Klinger }; 7878f83902SAndreas Klinger 7978f83902SAndreas Klinger /* 8078f83902SAndreas Klinger * in the documentation one can read about the "Gain" of the device 8178f83902SAndreas Klinger * which is used here for amplifying the signal and filtering out unwanted 8278f83902SAndreas Klinger * ones. 8378f83902SAndreas Klinger * But with ADC's this term is already used differently and that's why it 8478f83902SAndreas Klinger * is called "Sensitivity" here. 8578f83902SAndreas Klinger */ 86dc2696baSAndreas Klinger static const struct srf08_chip_info srf02_chip_info = { 87dc2696baSAndreas Klinger .sensitivity_avail = NULL, 88dc2696baSAndreas Klinger .num_sensitivity_avail = 0, 89dc2696baSAndreas Klinger .sensitivity_default = 0, 90dc2696baSAndreas Klinger 91dc2696baSAndreas Klinger .range_default = 0, 92dc2696baSAndreas Klinger }; 93dc2696baSAndreas Klinger 94c5bf4a04SAndreas Klinger static const int srf08_sensitivity_avail[] = { 9578f83902SAndreas Klinger 94, 97, 100, 103, 107, 110, 114, 118, 9678f83902SAndreas Klinger 123, 128, 133, 139, 145, 152, 159, 168, 9778f83902SAndreas Klinger 177, 187, 199, 212, 227, 245, 265, 288, 98c5bf4a04SAndreas Klinger 317, 352, 395, 450, 524, 626, 777, 1025 99c5bf4a04SAndreas Klinger }; 100c5bf4a04SAndreas Klinger 101c5bf4a04SAndreas Klinger static const struct srf08_chip_info srf08_chip_info = { 102c5bf4a04SAndreas Klinger .sensitivity_avail = srf08_sensitivity_avail, 103c5bf4a04SAndreas Klinger .num_sensitivity_avail = ARRAY_SIZE(srf08_sensitivity_avail), 104c5bf4a04SAndreas Klinger .sensitivity_default = 1025, 105dc2696baSAndreas Klinger 106dc2696baSAndreas Klinger .range_default = 6020, 107c5bf4a04SAndreas Klinger }; 108c5bf4a04SAndreas Klinger 109c5bf4a04SAndreas Klinger static const int srf10_sensitivity_avail[] = { 110c5bf4a04SAndreas Klinger 40, 40, 50, 60, 70, 80, 100, 120, 111c5bf4a04SAndreas Klinger 140, 200, 250, 300, 350, 400, 500, 600, 112c5bf4a04SAndreas Klinger 700, 113c5bf4a04SAndreas Klinger }; 114c5bf4a04SAndreas Klinger 115c5bf4a04SAndreas Klinger static const struct srf08_chip_info srf10_chip_info = { 116c5bf4a04SAndreas Klinger .sensitivity_avail = srf10_sensitivity_avail, 117c5bf4a04SAndreas Klinger .num_sensitivity_avail = ARRAY_SIZE(srf10_sensitivity_avail), 118c5bf4a04SAndreas Klinger .sensitivity_default = 700, 119dc2696baSAndreas Klinger 120dc2696baSAndreas Klinger .range_default = 6020, 121c5bf4a04SAndreas Klinger }; 12278f83902SAndreas Klinger 12378f83902SAndreas Klinger static int srf08_read_ranging(struct srf08_data *data) 12478f83902SAndreas Klinger { 12578f83902SAndreas Klinger struct i2c_client *client = data->client; 12678f83902SAndreas Klinger int ret, i; 12778f83902SAndreas Klinger int waittime; 12878f83902SAndreas Klinger 12978f83902SAndreas Klinger mutex_lock(&data->lock); 13078f83902SAndreas Klinger 13178f83902SAndreas Klinger ret = i2c_smbus_write_byte_data(data->client, 13278f83902SAndreas Klinger SRF08_WRITE_COMMAND, SRF08_CMD_RANGING_CM); 13378f83902SAndreas Klinger if (ret < 0) { 13478f83902SAndreas Klinger dev_err(&client->dev, "write command - err: %d\n", ret); 13578f83902SAndreas Klinger mutex_unlock(&data->lock); 13678f83902SAndreas Klinger return ret; 13778f83902SAndreas Klinger } 13878f83902SAndreas Klinger 13978f83902SAndreas Klinger /* 14078f83902SAndreas Klinger * we read here until a correct version number shows up as 14178f83902SAndreas Klinger * suggested by the documentation 14278f83902SAndreas Klinger * 14378f83902SAndreas Klinger * with an ultrasonic speed of 343 m/s and a roundtrip of it 14478f83902SAndreas Klinger * sleep the expected duration and try to read from the device 14578f83902SAndreas Klinger * if nothing useful is read try it in a shorter grid 14678f83902SAndreas Klinger * 14778f83902SAndreas Klinger * polling for not more than 20 ms should be enough 14878f83902SAndreas Klinger */ 14978f83902SAndreas Klinger waittime = 1 + data->range_mm / 172; 15078f83902SAndreas Klinger msleep(waittime); 15178f83902SAndreas Klinger for (i = 0; i < 4; i++) { 15278f83902SAndreas Klinger ret = i2c_smbus_read_byte_data(data->client, 15378f83902SAndreas Klinger SRF08_READ_SW_REVISION); 15478f83902SAndreas Klinger 15578f83902SAndreas Klinger /* check if a valid version number is read */ 15678f83902SAndreas Klinger if (ret < 255 && ret > 0) 15778f83902SAndreas Klinger break; 15878f83902SAndreas Klinger msleep(5); 15978f83902SAndreas Klinger } 16078f83902SAndreas Klinger 16178f83902SAndreas Klinger if (ret >= 255 || ret <= 0) { 16278f83902SAndreas Klinger dev_err(&client->dev, "device not ready\n"); 16378f83902SAndreas Klinger mutex_unlock(&data->lock); 16478f83902SAndreas Klinger return -EIO; 16578f83902SAndreas Klinger } 16678f83902SAndreas Klinger 16778f83902SAndreas Klinger ret = i2c_smbus_read_word_swapped(data->client, 16878f83902SAndreas Klinger SRF08_READ_ECHO_1_HIGH); 16978f83902SAndreas Klinger if (ret < 0) { 17078f83902SAndreas Klinger dev_err(&client->dev, "cannot read distance: ret=%d\n", ret); 17178f83902SAndreas Klinger mutex_unlock(&data->lock); 17278f83902SAndreas Klinger return ret; 17378f83902SAndreas Klinger } 17478f83902SAndreas Klinger 17578f83902SAndreas Klinger mutex_unlock(&data->lock); 17678f83902SAndreas Klinger 17778f83902SAndreas Klinger return ret; 17878f83902SAndreas Klinger } 17978f83902SAndreas Klinger 180a8319593SAndreas Klinger static irqreturn_t srf08_trigger_handler(int irq, void *p) 181a8319593SAndreas Klinger { 182a8319593SAndreas Klinger struct iio_poll_func *pf = p; 183a8319593SAndreas Klinger struct iio_dev *indio_dev = pf->indio_dev; 184a8319593SAndreas Klinger struct srf08_data *data = iio_priv(indio_dev); 185a8319593SAndreas Klinger s16 sensor_data; 186a8319593SAndreas Klinger 187a8319593SAndreas Klinger sensor_data = srf08_read_ranging(data); 188a8319593SAndreas Klinger if (sensor_data < 0) 189a8319593SAndreas Klinger goto err; 190a8319593SAndreas Klinger 191a8319593SAndreas Klinger mutex_lock(&data->lock); 192a8319593SAndreas Klinger 193a8319593SAndreas Klinger data->buffer[0] = sensor_data; 194a8319593SAndreas Klinger iio_push_to_buffers_with_timestamp(indio_dev, 195a8319593SAndreas Klinger data->buffer, pf->timestamp); 196a8319593SAndreas Klinger 197a8319593SAndreas Klinger mutex_unlock(&data->lock); 198a8319593SAndreas Klinger err: 199a8319593SAndreas Klinger iio_trigger_notify_done(indio_dev->trig); 200a8319593SAndreas Klinger return IRQ_HANDLED; 201a8319593SAndreas Klinger } 202a8319593SAndreas Klinger 20378f83902SAndreas Klinger static int srf08_read_raw(struct iio_dev *indio_dev, 20478f83902SAndreas Klinger struct iio_chan_spec const *channel, int *val, 20578f83902SAndreas Klinger int *val2, long mask) 20678f83902SAndreas Klinger { 20778f83902SAndreas Klinger struct srf08_data *data = iio_priv(indio_dev); 20878f83902SAndreas Klinger int ret; 20978f83902SAndreas Klinger 21078f83902SAndreas Klinger if (channel->type != IIO_DISTANCE) 21178f83902SAndreas Klinger return -EINVAL; 21278f83902SAndreas Klinger 21378f83902SAndreas Klinger switch (mask) { 21478f83902SAndreas Klinger case IIO_CHAN_INFO_RAW: 21578f83902SAndreas Klinger ret = srf08_read_ranging(data); 21678f83902SAndreas Klinger if (ret < 0) 21778f83902SAndreas Klinger return ret; 21878f83902SAndreas Klinger *val = ret; 21978f83902SAndreas Klinger return IIO_VAL_INT; 22078f83902SAndreas Klinger case IIO_CHAN_INFO_SCALE: 22178f83902SAndreas Klinger /* 1 LSB is 1 cm */ 22278f83902SAndreas Klinger *val = 0; 22378f83902SAndreas Klinger *val2 = 10000; 22478f83902SAndreas Klinger return IIO_VAL_INT_PLUS_MICRO; 22578f83902SAndreas Klinger default: 22678f83902SAndreas Klinger return -EINVAL; 22778f83902SAndreas Klinger } 22878f83902SAndreas Klinger } 22978f83902SAndreas Klinger 23078f83902SAndreas Klinger static ssize_t srf08_show_range_mm_available(struct device *dev, 23178f83902SAndreas Klinger struct device_attribute *attr, char *buf) 23278f83902SAndreas Klinger { 23378f83902SAndreas Klinger return sprintf(buf, "[0.043 0.043 11.008]\n"); 23478f83902SAndreas Klinger } 23578f83902SAndreas Klinger 23678f83902SAndreas Klinger static IIO_DEVICE_ATTR(sensor_max_range_available, S_IRUGO, 23778f83902SAndreas Klinger srf08_show_range_mm_available, NULL, 0); 23878f83902SAndreas Klinger 23978f83902SAndreas Klinger static ssize_t srf08_show_range_mm(struct device *dev, 24078f83902SAndreas Klinger struct device_attribute *attr, char *buf) 24178f83902SAndreas Klinger { 24278f83902SAndreas Klinger struct iio_dev *indio_dev = dev_to_iio_dev(dev); 24378f83902SAndreas Klinger struct srf08_data *data = iio_priv(indio_dev); 24478f83902SAndreas Klinger 24578f83902SAndreas Klinger return sprintf(buf, "%d.%03d\n", data->range_mm / 1000, 24678f83902SAndreas Klinger data->range_mm % 1000); 24778f83902SAndreas Klinger } 24878f83902SAndreas Klinger 24978f83902SAndreas Klinger /* 25078f83902SAndreas Klinger * set the range of the sensor to an even multiple of 43 mm 25178f83902SAndreas Klinger * which corresponds to 1 LSB in the register 25278f83902SAndreas Klinger * 25378f83902SAndreas Klinger * register value corresponding range 25478f83902SAndreas Klinger * 0x00 43 mm 25578f83902SAndreas Klinger * 0x01 86 mm 25678f83902SAndreas Klinger * 0x02 129 mm 25778f83902SAndreas Klinger * ... 25878f83902SAndreas Klinger * 0xFF 11008 mm 25978f83902SAndreas Klinger */ 26078f83902SAndreas Klinger static ssize_t srf08_write_range_mm(struct srf08_data *data, unsigned int val) 26178f83902SAndreas Klinger { 26278f83902SAndreas Klinger int ret; 26378f83902SAndreas Klinger struct i2c_client *client = data->client; 26478f83902SAndreas Klinger unsigned int mod; 26578f83902SAndreas Klinger u8 regval; 26678f83902SAndreas Klinger 26778f83902SAndreas Klinger ret = val / 43 - 1; 26878f83902SAndreas Klinger mod = val % 43; 26978f83902SAndreas Klinger 27078f83902SAndreas Klinger if (mod || (ret < 0) || (ret > 255)) 27178f83902SAndreas Klinger return -EINVAL; 27278f83902SAndreas Klinger 27378f83902SAndreas Klinger regval = ret; 27478f83902SAndreas Klinger 27578f83902SAndreas Klinger mutex_lock(&data->lock); 27678f83902SAndreas Klinger 27778f83902SAndreas Klinger ret = i2c_smbus_write_byte_data(client, SRF08_WRITE_RANGE, regval); 27878f83902SAndreas Klinger if (ret < 0) { 27978f83902SAndreas Klinger dev_err(&client->dev, "write_range - err: %d\n", ret); 28078f83902SAndreas Klinger mutex_unlock(&data->lock); 28178f83902SAndreas Klinger return ret; 28278f83902SAndreas Klinger } 28378f83902SAndreas Klinger 28478f83902SAndreas Klinger data->range_mm = val; 28578f83902SAndreas Klinger 28678f83902SAndreas Klinger mutex_unlock(&data->lock); 28778f83902SAndreas Klinger 28878f83902SAndreas Klinger return 0; 28978f83902SAndreas Klinger } 29078f83902SAndreas Klinger 29178f83902SAndreas Klinger static ssize_t srf08_store_range_mm(struct device *dev, 29278f83902SAndreas Klinger struct device_attribute *attr, 29378f83902SAndreas Klinger const char *buf, size_t len) 29478f83902SAndreas Klinger { 29578f83902SAndreas Klinger struct iio_dev *indio_dev = dev_to_iio_dev(dev); 29678f83902SAndreas Klinger struct srf08_data *data = iio_priv(indio_dev); 29778f83902SAndreas Klinger int ret; 29878f83902SAndreas Klinger int integer, fract; 29978f83902SAndreas Klinger 30078f83902SAndreas Klinger ret = iio_str_to_fixpoint(buf, 100, &integer, &fract); 30178f83902SAndreas Klinger if (ret) 30278f83902SAndreas Klinger return ret; 30378f83902SAndreas Klinger 30478f83902SAndreas Klinger ret = srf08_write_range_mm(data, integer * 1000 + fract); 30578f83902SAndreas Klinger if (ret < 0) 30678f83902SAndreas Klinger return ret; 30778f83902SAndreas Klinger 30878f83902SAndreas Klinger return len; 30978f83902SAndreas Klinger } 31078f83902SAndreas Klinger 31178f83902SAndreas Klinger static IIO_DEVICE_ATTR(sensor_max_range, S_IRUGO | S_IWUSR, 31278f83902SAndreas Klinger srf08_show_range_mm, srf08_store_range_mm, 0); 31378f83902SAndreas Klinger 31478f83902SAndreas Klinger static ssize_t srf08_show_sensitivity_available(struct device *dev, 31578f83902SAndreas Klinger struct device_attribute *attr, char *buf) 31678f83902SAndreas Klinger { 31778f83902SAndreas Klinger int i, len = 0; 318c5bf4a04SAndreas Klinger struct iio_dev *indio_dev = dev_to_iio_dev(dev); 319c5bf4a04SAndreas Klinger struct srf08_data *data = iio_priv(indio_dev); 32078f83902SAndreas Klinger 321c5bf4a04SAndreas Klinger for (i = 0; i < data->chip_info->num_sensitivity_avail; i++) 322c5bf4a04SAndreas Klinger if (data->chip_info->sensitivity_avail[i]) 323c5bf4a04SAndreas Klinger len += sprintf(buf + len, "%d ", 324c5bf4a04SAndreas Klinger data->chip_info->sensitivity_avail[i]); 32578f83902SAndreas Klinger 32678f83902SAndreas Klinger len += sprintf(buf + len, "\n"); 32778f83902SAndreas Klinger 32878f83902SAndreas Klinger return len; 32978f83902SAndreas Klinger } 33078f83902SAndreas Klinger 33178f83902SAndreas Klinger static IIO_DEVICE_ATTR(sensor_sensitivity_available, S_IRUGO, 33278f83902SAndreas Klinger srf08_show_sensitivity_available, NULL, 0); 33378f83902SAndreas Klinger 33478f83902SAndreas Klinger static ssize_t srf08_show_sensitivity(struct device *dev, 33578f83902SAndreas Klinger struct device_attribute *attr, char *buf) 33678f83902SAndreas Klinger { 33778f83902SAndreas Klinger struct iio_dev *indio_dev = dev_to_iio_dev(dev); 33878f83902SAndreas Klinger struct srf08_data *data = iio_priv(indio_dev); 33978f83902SAndreas Klinger int len; 34078f83902SAndreas Klinger 34178f83902SAndreas Klinger len = sprintf(buf, "%d\n", data->sensitivity); 34278f83902SAndreas Klinger 34378f83902SAndreas Klinger return len; 34478f83902SAndreas Klinger } 34578f83902SAndreas Klinger 34678f83902SAndreas Klinger static ssize_t srf08_write_sensitivity(struct srf08_data *data, 34778f83902SAndreas Klinger unsigned int val) 34878f83902SAndreas Klinger { 34978f83902SAndreas Klinger struct i2c_client *client = data->client; 35078f83902SAndreas Klinger int ret, i; 35178f83902SAndreas Klinger u8 regval; 35278f83902SAndreas Klinger 353c5bf4a04SAndreas Klinger if (!val) 354c5bf4a04SAndreas Klinger return -EINVAL; 355c5bf4a04SAndreas Klinger 356c5bf4a04SAndreas Klinger for (i = 0; i < data->chip_info->num_sensitivity_avail; i++) 357c5bf4a04SAndreas Klinger if (val && (val == data->chip_info->sensitivity_avail[i])) { 35878f83902SAndreas Klinger regval = i; 35978f83902SAndreas Klinger break; 36078f83902SAndreas Klinger } 36178f83902SAndreas Klinger 362c5bf4a04SAndreas Klinger if (i >= data->chip_info->num_sensitivity_avail) 36378f83902SAndreas Klinger return -EINVAL; 36478f83902SAndreas Klinger 36578f83902SAndreas Klinger mutex_lock(&data->lock); 36678f83902SAndreas Klinger 367c5bf4a04SAndreas Klinger ret = i2c_smbus_write_byte_data(client, SRF08_WRITE_MAX_GAIN, regval); 36878f83902SAndreas Klinger if (ret < 0) { 36978f83902SAndreas Klinger dev_err(&client->dev, "write_sensitivity - err: %d\n", ret); 37078f83902SAndreas Klinger mutex_unlock(&data->lock); 37178f83902SAndreas Klinger return ret; 37278f83902SAndreas Klinger } 37378f83902SAndreas Klinger 37478f83902SAndreas Klinger data->sensitivity = val; 37578f83902SAndreas Klinger 37678f83902SAndreas Klinger mutex_unlock(&data->lock); 37778f83902SAndreas Klinger 37878f83902SAndreas Klinger return 0; 37978f83902SAndreas Klinger } 38078f83902SAndreas Klinger 38178f83902SAndreas Klinger static ssize_t srf08_store_sensitivity(struct device *dev, 38278f83902SAndreas Klinger struct device_attribute *attr, 38378f83902SAndreas Klinger const char *buf, size_t len) 38478f83902SAndreas Klinger { 38578f83902SAndreas Klinger struct iio_dev *indio_dev = dev_to_iio_dev(dev); 38678f83902SAndreas Klinger struct srf08_data *data = iio_priv(indio_dev); 38778f83902SAndreas Klinger int ret; 38878f83902SAndreas Klinger unsigned int val; 38978f83902SAndreas Klinger 39078f83902SAndreas Klinger ret = kstrtouint(buf, 10, &val); 39178f83902SAndreas Klinger if (ret) 39278f83902SAndreas Klinger return ret; 39378f83902SAndreas Klinger 39478f83902SAndreas Klinger ret = srf08_write_sensitivity(data, val); 39578f83902SAndreas Klinger if (ret < 0) 39678f83902SAndreas Klinger return ret; 39778f83902SAndreas Klinger 39878f83902SAndreas Klinger return len; 39978f83902SAndreas Klinger } 40078f83902SAndreas Klinger 40178f83902SAndreas Klinger static IIO_DEVICE_ATTR(sensor_sensitivity, S_IRUGO | S_IWUSR, 40278f83902SAndreas Klinger srf08_show_sensitivity, srf08_store_sensitivity, 0); 40378f83902SAndreas Klinger 40478f83902SAndreas Klinger static struct attribute *srf08_attributes[] = { 40578f83902SAndreas Klinger &iio_dev_attr_sensor_max_range.dev_attr.attr, 40678f83902SAndreas Klinger &iio_dev_attr_sensor_max_range_available.dev_attr.attr, 40778f83902SAndreas Klinger &iio_dev_attr_sensor_sensitivity.dev_attr.attr, 40878f83902SAndreas Klinger &iio_dev_attr_sensor_sensitivity_available.dev_attr.attr, 40978f83902SAndreas Klinger NULL, 41078f83902SAndreas Klinger }; 41178f83902SAndreas Klinger 41278f83902SAndreas Klinger static const struct attribute_group srf08_attribute_group = { 41378f83902SAndreas Klinger .attrs = srf08_attributes, 41478f83902SAndreas Klinger }; 41578f83902SAndreas Klinger 41678f83902SAndreas Klinger static const struct iio_chan_spec srf08_channels[] = { 41778f83902SAndreas Klinger { 41878f83902SAndreas Klinger .type = IIO_DISTANCE, 41978f83902SAndreas Klinger .info_mask_separate = 42078f83902SAndreas Klinger BIT(IIO_CHAN_INFO_RAW) | 42178f83902SAndreas Klinger BIT(IIO_CHAN_INFO_SCALE), 422a8319593SAndreas Klinger .scan_index = 0, 423a8319593SAndreas Klinger .scan_type = { 424a8319593SAndreas Klinger .sign = 's', 425a8319593SAndreas Klinger .realbits = 16, 426a8319593SAndreas Klinger .storagebits = 16, 427a8319593SAndreas Klinger .endianness = IIO_CPU, 42878f83902SAndreas Klinger }, 429a8319593SAndreas Klinger }, 430a8319593SAndreas Klinger IIO_CHAN_SOFT_TIMESTAMP(1), 43178f83902SAndreas Klinger }; 43278f83902SAndreas Klinger 43378f83902SAndreas Klinger static const struct iio_info srf08_info = { 43478f83902SAndreas Klinger .read_raw = srf08_read_raw, 43578f83902SAndreas Klinger .attrs = &srf08_attribute_group, 43678f83902SAndreas Klinger }; 43778f83902SAndreas Klinger 438dc2696baSAndreas Klinger /* 439dc2696baSAndreas Klinger * srf02 don't have an adjustable range or sensitivity, 440dc2696baSAndreas Klinger * so we don't need attributes at all 441dc2696baSAndreas Klinger */ 442dc2696baSAndreas Klinger static const struct iio_info srf02_info = { 443dc2696baSAndreas Klinger .read_raw = srf08_read_raw, 444dc2696baSAndreas Klinger }; 445dc2696baSAndreas Klinger 44678f83902SAndreas Klinger static int srf08_probe(struct i2c_client *client, 44778f83902SAndreas Klinger const struct i2c_device_id *id) 44878f83902SAndreas Klinger { 44978f83902SAndreas Klinger struct iio_dev *indio_dev; 45078f83902SAndreas Klinger struct srf08_data *data; 45178f83902SAndreas Klinger int ret; 45278f83902SAndreas Klinger 45378f83902SAndreas Klinger if (!i2c_check_functionality(client->adapter, 45478f83902SAndreas Klinger I2C_FUNC_SMBUS_READ_BYTE_DATA | 45578f83902SAndreas Klinger I2C_FUNC_SMBUS_WRITE_BYTE_DATA | 45678f83902SAndreas Klinger I2C_FUNC_SMBUS_READ_WORD_DATA)) 45778f83902SAndreas Klinger return -ENODEV; 45878f83902SAndreas Klinger 45978f83902SAndreas Klinger indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 46078f83902SAndreas Klinger if (!indio_dev) 46178f83902SAndreas Klinger return -ENOMEM; 46278f83902SAndreas Klinger 46378f83902SAndreas Klinger data = iio_priv(indio_dev); 46478f83902SAndreas Klinger i2c_set_clientdata(client, indio_dev); 46578f83902SAndreas Klinger data->client = client; 466c5bf4a04SAndreas Klinger data->sensor_type = (enum srf08_sensor_type)id->driver_data; 46778f83902SAndreas Klinger 468c5bf4a04SAndreas Klinger switch (data->sensor_type) { 469dc2696baSAndreas Klinger case SRF02: 470dc2696baSAndreas Klinger data->chip_info = &srf02_chip_info; 471dc2696baSAndreas Klinger indio_dev->info = &srf02_info; 472dc2696baSAndreas Klinger break; 473c5bf4a04SAndreas Klinger case SRF08: 474c5bf4a04SAndreas Klinger data->chip_info = &srf08_chip_info; 475dc2696baSAndreas Klinger indio_dev->info = &srf08_info; 476c5bf4a04SAndreas Klinger break; 477c5bf4a04SAndreas Klinger case SRF10: 478c5bf4a04SAndreas Klinger data->chip_info = &srf10_chip_info; 479dc2696baSAndreas Klinger indio_dev->info = &srf08_info; 480c5bf4a04SAndreas Klinger break; 481c5bf4a04SAndreas Klinger default: 482c5bf4a04SAndreas Klinger return -EINVAL; 483c5bf4a04SAndreas Klinger } 484c5bf4a04SAndreas Klinger 485c5bf4a04SAndreas Klinger indio_dev->name = id->name; 48678f83902SAndreas Klinger indio_dev->modes = INDIO_DIRECT_MODE; 48778f83902SAndreas Klinger indio_dev->channels = srf08_channels; 48878f83902SAndreas Klinger indio_dev->num_channels = ARRAY_SIZE(srf08_channels); 48978f83902SAndreas Klinger 49078f83902SAndreas Klinger mutex_init(&data->lock); 49178f83902SAndreas Klinger 492a8319593SAndreas Klinger ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev, 493a8319593SAndreas Klinger iio_pollfunc_store_time, srf08_trigger_handler, NULL); 494a8319593SAndreas Klinger if (ret < 0) { 495a8319593SAndreas Klinger dev_err(&client->dev, "setup of iio triggered buffer failed\n"); 496a8319593SAndreas Klinger return ret; 497a8319593SAndreas Klinger } 498a8319593SAndreas Klinger 499dc2696baSAndreas Klinger if (data->chip_info->range_default) { 50078f83902SAndreas Klinger /* 501dc2696baSAndreas Klinger * set default range of device in mm here 50278f83902SAndreas Klinger * these register values cannot be read from the hardware 50378f83902SAndreas Klinger * therefore set driver specific default values 504dc2696baSAndreas Klinger * 505dc2696baSAndreas Klinger * srf02 don't have a default value so it'll be omitted 50678f83902SAndreas Klinger */ 507dc2696baSAndreas Klinger ret = srf08_write_range_mm(data, 508dc2696baSAndreas Klinger data->chip_info->range_default); 50978f83902SAndreas Klinger if (ret < 0) 51078f83902SAndreas Klinger return ret; 511dc2696baSAndreas Klinger } 51278f83902SAndreas Klinger 513dc2696baSAndreas Klinger if (data->chip_info->sensitivity_default) { 514dc2696baSAndreas Klinger /* 515dc2696baSAndreas Klinger * set default sensitivity of device here 516dc2696baSAndreas Klinger * these register values cannot be read from the hardware 517dc2696baSAndreas Klinger * therefore set driver specific default values 518dc2696baSAndreas Klinger * 519dc2696baSAndreas Klinger * srf02 don't have a default value so it'll be omitted 520dc2696baSAndreas Klinger */ 521c5bf4a04SAndreas Klinger ret = srf08_write_sensitivity(data, 522c5bf4a04SAndreas Klinger data->chip_info->sensitivity_default); 52378f83902SAndreas Klinger if (ret < 0) 52478f83902SAndreas Klinger return ret; 525dc2696baSAndreas Klinger } 52678f83902SAndreas Klinger 52778f83902SAndreas Klinger return devm_iio_device_register(&client->dev, indio_dev); 52878f83902SAndreas Klinger } 52978f83902SAndreas Klinger 530c02b3a11SAndreas Klinger static const struct of_device_id of_srf08_match[] = { 531dc2696baSAndreas Klinger { .compatible = "devantech,srf02", (void *)SRF02}, 532c5bf4a04SAndreas Klinger { .compatible = "devantech,srf08", (void *)SRF08}, 533c5bf4a04SAndreas Klinger { .compatible = "devantech,srf10", (void *)SRF10}, 534c02b3a11SAndreas Klinger {}, 535c02b3a11SAndreas Klinger }; 536c02b3a11SAndreas Klinger 537c02b3a11SAndreas Klinger MODULE_DEVICE_TABLE(of, of_srf08_match); 538c02b3a11SAndreas Klinger 53978f83902SAndreas Klinger static const struct i2c_device_id srf08_id[] = { 540dc2696baSAndreas Klinger { "srf02", SRF02 }, 541c5bf4a04SAndreas Klinger { "srf08", SRF08 }, 542c5bf4a04SAndreas Klinger { "srf10", SRF10 }, 54378f83902SAndreas Klinger { } 54478f83902SAndreas Klinger }; 54578f83902SAndreas Klinger MODULE_DEVICE_TABLE(i2c, srf08_id); 54678f83902SAndreas Klinger 54778f83902SAndreas Klinger static struct i2c_driver srf08_driver = { 54878f83902SAndreas Klinger .driver = { 54978f83902SAndreas Klinger .name = "srf08", 550c02b3a11SAndreas Klinger .of_match_table = of_srf08_match, 55178f83902SAndreas Klinger }, 55278f83902SAndreas Klinger .probe = srf08_probe, 55378f83902SAndreas Klinger .id_table = srf08_id, 55478f83902SAndreas Klinger }; 55578f83902SAndreas Klinger module_i2c_driver(srf08_driver); 55678f83902SAndreas Klinger 55778f83902SAndreas Klinger MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>"); 558dc2696baSAndreas Klinger MODULE_DESCRIPTION("Devantech SRF02/SRF08/SRF10 i2c ultrasonic ranger driver"); 55978f83902SAndreas Klinger MODULE_LICENSE("GPL"); 560