xref: /openbmc/linux/drivers/iio/proximity/srf08.c (revision 78f83902)
178f83902SAndreas Klinger /*
278f83902SAndreas Klinger  * srf08.c - Support for Devantech SRF08 ultrasonic ranger
378f83902SAndreas Klinger  *
478f83902SAndreas Klinger  * Copyright (c) 2016 Andreas Klinger <ak@it-klinger.de>
578f83902SAndreas Klinger  *
678f83902SAndreas Klinger  * This file is subject to the terms and conditions of version 2 of
778f83902SAndreas Klinger  * the GNU General Public License.  See the file COPYING in the main
878f83902SAndreas Klinger  * directory of this archive for more details.
978f83902SAndreas Klinger  *
1078f83902SAndreas Klinger  * For details about the device see:
1178f83902SAndreas Klinger  * http://www.robot-electronics.co.uk/htm/srf08tech.html
1278f83902SAndreas Klinger  */
1378f83902SAndreas Klinger 
1478f83902SAndreas Klinger #include <linux/err.h>
1578f83902SAndreas Klinger #include <linux/i2c.h>
1678f83902SAndreas Klinger #include <linux/delay.h>
1778f83902SAndreas Klinger #include <linux/module.h>
1878f83902SAndreas Klinger #include <linux/bitops.h>
1978f83902SAndreas Klinger #include <linux/iio/iio.h>
2078f83902SAndreas Klinger #include <linux/iio/sysfs.h>
2178f83902SAndreas Klinger 
2278f83902SAndreas Klinger /* registers of SRF08 device */
2378f83902SAndreas Klinger #define SRF08_WRITE_COMMAND	0x00	/* Command Register */
2478f83902SAndreas Klinger #define SRF08_WRITE_MAX_GAIN	0x01	/* Max Gain Register: 0 .. 31 */
2578f83902SAndreas Klinger #define SRF08_WRITE_RANGE	0x02	/* Range Register: 0 .. 255 */
2678f83902SAndreas Klinger #define SRF08_READ_SW_REVISION	0x00	/* Software Revision */
2778f83902SAndreas Klinger #define SRF08_READ_LIGHT	0x01	/* Light Sensor during last echo */
2878f83902SAndreas Klinger #define SRF08_READ_ECHO_1_HIGH	0x02	/* Range of first echo received */
2978f83902SAndreas Klinger #define SRF08_READ_ECHO_1_LOW	0x03	/* Range of first echo received */
3078f83902SAndreas Klinger 
3178f83902SAndreas Klinger #define SRF08_CMD_RANGING_CM	0x51	/* Ranging Mode - Result in cm */
3278f83902SAndreas Klinger 
3378f83902SAndreas Klinger #define SRF08_DEFAULT_GAIN	1025	/* default analogue value of Gain */
3478f83902SAndreas Klinger #define SRF08_DEFAULT_RANGE	6020	/* default value of Range in mm */
3578f83902SAndreas Klinger 
3678f83902SAndreas Klinger struct srf08_data {
3778f83902SAndreas Klinger 	struct i2c_client	*client;
3878f83902SAndreas Klinger 	int			sensitivity;		/* Gain */
3978f83902SAndreas Klinger 	int			range_mm;		/* max. Range in mm */
4078f83902SAndreas Klinger 	struct mutex		lock;
4178f83902SAndreas Klinger };
4278f83902SAndreas Klinger 
4378f83902SAndreas Klinger /*
4478f83902SAndreas Klinger  * in the documentation one can read about the "Gain" of the device
4578f83902SAndreas Klinger  * which is used here for amplifying the signal and filtering out unwanted
4678f83902SAndreas Klinger  * ones.
4778f83902SAndreas Klinger  * But with ADC's this term is already used differently and that's why it
4878f83902SAndreas Klinger  * is called "Sensitivity" here.
4978f83902SAndreas Klinger  */
5078f83902SAndreas Klinger static const int srf08_sensitivity[] = {
5178f83902SAndreas Klinger 	 94,  97, 100, 103, 107, 110, 114, 118,
5278f83902SAndreas Klinger 	123, 128, 133, 139, 145, 152, 159, 168,
5378f83902SAndreas Klinger 	177, 187, 199, 212, 227, 245, 265, 288,
5478f83902SAndreas Klinger 	317, 352, 395, 450, 524, 626, 777, 1025 };
5578f83902SAndreas Klinger 
5678f83902SAndreas Klinger static int srf08_read_ranging(struct srf08_data *data)
5778f83902SAndreas Klinger {
5878f83902SAndreas Klinger 	struct i2c_client *client = data->client;
5978f83902SAndreas Klinger 	int ret, i;
6078f83902SAndreas Klinger 	int waittime;
6178f83902SAndreas Klinger 
6278f83902SAndreas Klinger 	mutex_lock(&data->lock);
6378f83902SAndreas Klinger 
6478f83902SAndreas Klinger 	ret = i2c_smbus_write_byte_data(data->client,
6578f83902SAndreas Klinger 			SRF08_WRITE_COMMAND, SRF08_CMD_RANGING_CM);
6678f83902SAndreas Klinger 	if (ret < 0) {
6778f83902SAndreas Klinger 		dev_err(&client->dev, "write command - err: %d\n", ret);
6878f83902SAndreas Klinger 		mutex_unlock(&data->lock);
6978f83902SAndreas Klinger 		return ret;
7078f83902SAndreas Klinger 	}
7178f83902SAndreas Klinger 
7278f83902SAndreas Klinger 	/*
7378f83902SAndreas Klinger 	 * we read here until a correct version number shows up as
7478f83902SAndreas Klinger 	 * suggested by the documentation
7578f83902SAndreas Klinger 	 *
7678f83902SAndreas Klinger 	 * with an ultrasonic speed of 343 m/s and a roundtrip of it
7778f83902SAndreas Klinger 	 * sleep the expected duration and try to read from the device
7878f83902SAndreas Klinger 	 * if nothing useful is read try it in a shorter grid
7978f83902SAndreas Klinger 	 *
8078f83902SAndreas Klinger 	 * polling for not more than 20 ms should be enough
8178f83902SAndreas Klinger 	 */
8278f83902SAndreas Klinger 	waittime = 1 + data->range_mm / 172;
8378f83902SAndreas Klinger 	msleep(waittime);
8478f83902SAndreas Klinger 	for (i = 0; i < 4; i++) {
8578f83902SAndreas Klinger 		ret = i2c_smbus_read_byte_data(data->client,
8678f83902SAndreas Klinger 						SRF08_READ_SW_REVISION);
8778f83902SAndreas Klinger 
8878f83902SAndreas Klinger 		/* check if a valid version number is read */
8978f83902SAndreas Klinger 		if (ret < 255 && ret > 0)
9078f83902SAndreas Klinger 			break;
9178f83902SAndreas Klinger 		msleep(5);
9278f83902SAndreas Klinger 	}
9378f83902SAndreas Klinger 
9478f83902SAndreas Klinger 	if (ret >= 255 || ret <= 0) {
9578f83902SAndreas Klinger 		dev_err(&client->dev, "device not ready\n");
9678f83902SAndreas Klinger 		mutex_unlock(&data->lock);
9778f83902SAndreas Klinger 		return -EIO;
9878f83902SAndreas Klinger 	}
9978f83902SAndreas Klinger 
10078f83902SAndreas Klinger 	ret = i2c_smbus_read_word_swapped(data->client,
10178f83902SAndreas Klinger 						SRF08_READ_ECHO_1_HIGH);
10278f83902SAndreas Klinger 	if (ret < 0) {
10378f83902SAndreas Klinger 		dev_err(&client->dev, "cannot read distance: ret=%d\n", ret);
10478f83902SAndreas Klinger 		mutex_unlock(&data->lock);
10578f83902SAndreas Klinger 		return ret;
10678f83902SAndreas Klinger 	}
10778f83902SAndreas Klinger 
10878f83902SAndreas Klinger 	mutex_unlock(&data->lock);
10978f83902SAndreas Klinger 
11078f83902SAndreas Klinger 	return ret;
11178f83902SAndreas Klinger }
11278f83902SAndreas Klinger 
11378f83902SAndreas Klinger static int srf08_read_raw(struct iio_dev *indio_dev,
11478f83902SAndreas Klinger 			    struct iio_chan_spec const *channel, int *val,
11578f83902SAndreas Klinger 			    int *val2, long mask)
11678f83902SAndreas Klinger {
11778f83902SAndreas Klinger 	struct srf08_data *data = iio_priv(indio_dev);
11878f83902SAndreas Klinger 	int ret;
11978f83902SAndreas Klinger 
12078f83902SAndreas Klinger 	if (channel->type != IIO_DISTANCE)
12178f83902SAndreas Klinger 		return -EINVAL;
12278f83902SAndreas Klinger 
12378f83902SAndreas Klinger 	switch (mask) {
12478f83902SAndreas Klinger 	case IIO_CHAN_INFO_RAW:
12578f83902SAndreas Klinger 		ret = srf08_read_ranging(data);
12678f83902SAndreas Klinger 		if (ret < 0)
12778f83902SAndreas Klinger 			return ret;
12878f83902SAndreas Klinger 		*val = ret;
12978f83902SAndreas Klinger 		return IIO_VAL_INT;
13078f83902SAndreas Klinger 	case IIO_CHAN_INFO_SCALE:
13178f83902SAndreas Klinger 		/* 1 LSB is 1 cm */
13278f83902SAndreas Klinger 		*val = 0;
13378f83902SAndreas Klinger 		*val2 = 10000;
13478f83902SAndreas Klinger 		return IIO_VAL_INT_PLUS_MICRO;
13578f83902SAndreas Klinger 	default:
13678f83902SAndreas Klinger 		return -EINVAL;
13778f83902SAndreas Klinger 	}
13878f83902SAndreas Klinger }
13978f83902SAndreas Klinger 
14078f83902SAndreas Klinger static ssize_t srf08_show_range_mm_available(struct device *dev,
14178f83902SAndreas Klinger 				struct device_attribute *attr, char *buf)
14278f83902SAndreas Klinger {
14378f83902SAndreas Klinger 	return sprintf(buf, "[0.043 0.043 11.008]\n");
14478f83902SAndreas Klinger }
14578f83902SAndreas Klinger 
14678f83902SAndreas Klinger static IIO_DEVICE_ATTR(sensor_max_range_available, S_IRUGO,
14778f83902SAndreas Klinger 				srf08_show_range_mm_available, NULL, 0);
14878f83902SAndreas Klinger 
14978f83902SAndreas Klinger static ssize_t srf08_show_range_mm(struct device *dev,
15078f83902SAndreas Klinger 				struct device_attribute *attr, char *buf)
15178f83902SAndreas Klinger {
15278f83902SAndreas Klinger 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
15378f83902SAndreas Klinger 	struct srf08_data *data = iio_priv(indio_dev);
15478f83902SAndreas Klinger 
15578f83902SAndreas Klinger 	return sprintf(buf, "%d.%03d\n", data->range_mm / 1000,
15678f83902SAndreas Klinger 						data->range_mm % 1000);
15778f83902SAndreas Klinger }
15878f83902SAndreas Klinger 
15978f83902SAndreas Klinger /*
16078f83902SAndreas Klinger  * set the range of the sensor to an even multiple of 43 mm
16178f83902SAndreas Klinger  * which corresponds to 1 LSB in the register
16278f83902SAndreas Klinger  *
16378f83902SAndreas Klinger  * register value    corresponding range
16478f83902SAndreas Klinger  *         0x00             43 mm
16578f83902SAndreas Klinger  *         0x01             86 mm
16678f83902SAndreas Klinger  *         0x02            129 mm
16778f83902SAndreas Klinger  *         ...
16878f83902SAndreas Klinger  *         0xFF          11008 mm
16978f83902SAndreas Klinger  */
17078f83902SAndreas Klinger static ssize_t srf08_write_range_mm(struct srf08_data *data, unsigned int val)
17178f83902SAndreas Klinger {
17278f83902SAndreas Klinger 	int ret;
17378f83902SAndreas Klinger 	struct i2c_client *client = data->client;
17478f83902SAndreas Klinger 	unsigned int mod;
17578f83902SAndreas Klinger 	u8 regval;
17678f83902SAndreas Klinger 
17778f83902SAndreas Klinger 	ret = val / 43 - 1;
17878f83902SAndreas Klinger 	mod = val % 43;
17978f83902SAndreas Klinger 
18078f83902SAndreas Klinger 	if (mod || (ret < 0) || (ret > 255))
18178f83902SAndreas Klinger 		return -EINVAL;
18278f83902SAndreas Klinger 
18378f83902SAndreas Klinger 	regval = ret;
18478f83902SAndreas Klinger 
18578f83902SAndreas Klinger 	mutex_lock(&data->lock);
18678f83902SAndreas Klinger 
18778f83902SAndreas Klinger 	ret = i2c_smbus_write_byte_data(client, SRF08_WRITE_RANGE, regval);
18878f83902SAndreas Klinger 	if (ret < 0) {
18978f83902SAndreas Klinger 		dev_err(&client->dev, "write_range - err: %d\n", ret);
19078f83902SAndreas Klinger 		mutex_unlock(&data->lock);
19178f83902SAndreas Klinger 		return ret;
19278f83902SAndreas Klinger 	}
19378f83902SAndreas Klinger 
19478f83902SAndreas Klinger 	data->range_mm = val;
19578f83902SAndreas Klinger 
19678f83902SAndreas Klinger 	mutex_unlock(&data->lock);
19778f83902SAndreas Klinger 
19878f83902SAndreas Klinger 	return 0;
19978f83902SAndreas Klinger }
20078f83902SAndreas Klinger 
20178f83902SAndreas Klinger static ssize_t srf08_store_range_mm(struct device *dev,
20278f83902SAndreas Klinger 					struct device_attribute *attr,
20378f83902SAndreas Klinger 					const char *buf, size_t len)
20478f83902SAndreas Klinger {
20578f83902SAndreas Klinger 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
20678f83902SAndreas Klinger 	struct srf08_data *data = iio_priv(indio_dev);
20778f83902SAndreas Klinger 	int ret;
20878f83902SAndreas Klinger 	int integer, fract;
20978f83902SAndreas Klinger 
21078f83902SAndreas Klinger 	ret = iio_str_to_fixpoint(buf, 100, &integer, &fract);
21178f83902SAndreas Klinger 	if (ret)
21278f83902SAndreas Klinger 		return ret;
21378f83902SAndreas Klinger 
21478f83902SAndreas Klinger 	ret = srf08_write_range_mm(data, integer * 1000 + fract);
21578f83902SAndreas Klinger 	if (ret < 0)
21678f83902SAndreas Klinger 		return ret;
21778f83902SAndreas Klinger 
21878f83902SAndreas Klinger 	return len;
21978f83902SAndreas Klinger }
22078f83902SAndreas Klinger 
22178f83902SAndreas Klinger static IIO_DEVICE_ATTR(sensor_max_range, S_IRUGO | S_IWUSR,
22278f83902SAndreas Klinger 			srf08_show_range_mm, srf08_store_range_mm, 0);
22378f83902SAndreas Klinger 
22478f83902SAndreas Klinger static ssize_t srf08_show_sensitivity_available(struct device *dev,
22578f83902SAndreas Klinger 				struct device_attribute *attr, char *buf)
22678f83902SAndreas Klinger {
22778f83902SAndreas Klinger 	int i, len = 0;
22878f83902SAndreas Klinger 
22978f83902SAndreas Klinger 	for (i = 0; i < ARRAY_SIZE(srf08_sensitivity); i++)
23078f83902SAndreas Klinger 		len += sprintf(buf + len, "%d ", srf08_sensitivity[i]);
23178f83902SAndreas Klinger 
23278f83902SAndreas Klinger 	len += sprintf(buf + len, "\n");
23378f83902SAndreas Klinger 
23478f83902SAndreas Klinger 	return len;
23578f83902SAndreas Klinger }
23678f83902SAndreas Klinger 
23778f83902SAndreas Klinger static IIO_DEVICE_ATTR(sensor_sensitivity_available, S_IRUGO,
23878f83902SAndreas Klinger 				srf08_show_sensitivity_available, NULL, 0);
23978f83902SAndreas Klinger 
24078f83902SAndreas Klinger static ssize_t srf08_show_sensitivity(struct device *dev,
24178f83902SAndreas Klinger 				struct device_attribute *attr, char *buf)
24278f83902SAndreas Klinger {
24378f83902SAndreas Klinger 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
24478f83902SAndreas Klinger 	struct srf08_data *data = iio_priv(indio_dev);
24578f83902SAndreas Klinger 	int len;
24678f83902SAndreas Klinger 
24778f83902SAndreas Klinger 	len = sprintf(buf, "%d\n", data->sensitivity);
24878f83902SAndreas Klinger 
24978f83902SAndreas Klinger 	return len;
25078f83902SAndreas Klinger }
25178f83902SAndreas Klinger 
25278f83902SAndreas Klinger static ssize_t srf08_write_sensitivity(struct srf08_data *data,
25378f83902SAndreas Klinger 							unsigned int val)
25478f83902SAndreas Klinger {
25578f83902SAndreas Klinger 	struct i2c_client *client = data->client;
25678f83902SAndreas Klinger 	int ret, i;
25778f83902SAndreas Klinger 	u8 regval;
25878f83902SAndreas Klinger 
25978f83902SAndreas Klinger 	for (i = 0; i < ARRAY_SIZE(srf08_sensitivity); i++)
26078f83902SAndreas Klinger 		if (val == srf08_sensitivity[i]) {
26178f83902SAndreas Klinger 			regval = i;
26278f83902SAndreas Klinger 			break;
26378f83902SAndreas Klinger 		}
26478f83902SAndreas Klinger 
26578f83902SAndreas Klinger 	if (i >= ARRAY_SIZE(srf08_sensitivity))
26678f83902SAndreas Klinger 		return -EINVAL;
26778f83902SAndreas Klinger 
26878f83902SAndreas Klinger 	mutex_lock(&data->lock);
26978f83902SAndreas Klinger 
27078f83902SAndreas Klinger 	ret = i2c_smbus_write_byte_data(client,
27178f83902SAndreas Klinger 						SRF08_WRITE_MAX_GAIN, regval);
27278f83902SAndreas Klinger 	if (ret < 0) {
27378f83902SAndreas Klinger 		dev_err(&client->dev, "write_sensitivity - err: %d\n", ret);
27478f83902SAndreas Klinger 		mutex_unlock(&data->lock);
27578f83902SAndreas Klinger 		return ret;
27678f83902SAndreas Klinger 	}
27778f83902SAndreas Klinger 
27878f83902SAndreas Klinger 	data->sensitivity = val;
27978f83902SAndreas Klinger 
28078f83902SAndreas Klinger 	mutex_unlock(&data->lock);
28178f83902SAndreas Klinger 
28278f83902SAndreas Klinger 	return 0;
28378f83902SAndreas Klinger }
28478f83902SAndreas Klinger 
28578f83902SAndreas Klinger static ssize_t srf08_store_sensitivity(struct device *dev,
28678f83902SAndreas Klinger 						struct device_attribute *attr,
28778f83902SAndreas Klinger 						const char *buf, size_t len)
28878f83902SAndreas Klinger {
28978f83902SAndreas Klinger 	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
29078f83902SAndreas Klinger 	struct srf08_data *data = iio_priv(indio_dev);
29178f83902SAndreas Klinger 	int ret;
29278f83902SAndreas Klinger 	unsigned int val;
29378f83902SAndreas Klinger 
29478f83902SAndreas Klinger 	ret = kstrtouint(buf, 10, &val);
29578f83902SAndreas Klinger 	if (ret)
29678f83902SAndreas Klinger 		return ret;
29778f83902SAndreas Klinger 
29878f83902SAndreas Klinger 	ret = srf08_write_sensitivity(data, val);
29978f83902SAndreas Klinger 	if (ret < 0)
30078f83902SAndreas Klinger 		return ret;
30178f83902SAndreas Klinger 
30278f83902SAndreas Klinger 	return len;
30378f83902SAndreas Klinger }
30478f83902SAndreas Klinger 
30578f83902SAndreas Klinger static IIO_DEVICE_ATTR(sensor_sensitivity, S_IRUGO | S_IWUSR,
30678f83902SAndreas Klinger 			srf08_show_sensitivity, srf08_store_sensitivity, 0);
30778f83902SAndreas Klinger 
30878f83902SAndreas Klinger static struct attribute *srf08_attributes[] = {
30978f83902SAndreas Klinger 	&iio_dev_attr_sensor_max_range.dev_attr.attr,
31078f83902SAndreas Klinger 	&iio_dev_attr_sensor_max_range_available.dev_attr.attr,
31178f83902SAndreas Klinger 	&iio_dev_attr_sensor_sensitivity.dev_attr.attr,
31278f83902SAndreas Klinger 	&iio_dev_attr_sensor_sensitivity_available.dev_attr.attr,
31378f83902SAndreas Klinger 	NULL,
31478f83902SAndreas Klinger };
31578f83902SAndreas Klinger 
31678f83902SAndreas Klinger static const struct attribute_group srf08_attribute_group = {
31778f83902SAndreas Klinger 	.attrs = srf08_attributes,
31878f83902SAndreas Klinger };
31978f83902SAndreas Klinger 
32078f83902SAndreas Klinger static const struct iio_chan_spec srf08_channels[] = {
32178f83902SAndreas Klinger 	{
32278f83902SAndreas Klinger 		.type = IIO_DISTANCE,
32378f83902SAndreas Klinger 		.info_mask_separate =
32478f83902SAndreas Klinger 				BIT(IIO_CHAN_INFO_RAW) |
32578f83902SAndreas Klinger 				BIT(IIO_CHAN_INFO_SCALE),
32678f83902SAndreas Klinger 	},
32778f83902SAndreas Klinger };
32878f83902SAndreas Klinger 
32978f83902SAndreas Klinger static const struct iio_info srf08_info = {
33078f83902SAndreas Klinger 	.read_raw = srf08_read_raw,
33178f83902SAndreas Klinger 	.attrs = &srf08_attribute_group,
33278f83902SAndreas Klinger 	.driver_module = THIS_MODULE,
33378f83902SAndreas Klinger };
33478f83902SAndreas Klinger 
33578f83902SAndreas Klinger static int srf08_probe(struct i2c_client *client,
33678f83902SAndreas Klinger 					 const struct i2c_device_id *id)
33778f83902SAndreas Klinger {
33878f83902SAndreas Klinger 	struct iio_dev *indio_dev;
33978f83902SAndreas Klinger 	struct srf08_data *data;
34078f83902SAndreas Klinger 	int ret;
34178f83902SAndreas Klinger 
34278f83902SAndreas Klinger 	if (!i2c_check_functionality(client->adapter,
34378f83902SAndreas Klinger 					I2C_FUNC_SMBUS_READ_BYTE_DATA |
34478f83902SAndreas Klinger 					I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
34578f83902SAndreas Klinger 					I2C_FUNC_SMBUS_READ_WORD_DATA))
34678f83902SAndreas Klinger 		return -ENODEV;
34778f83902SAndreas Klinger 
34878f83902SAndreas Klinger 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
34978f83902SAndreas Klinger 	if (!indio_dev)
35078f83902SAndreas Klinger 		return -ENOMEM;
35178f83902SAndreas Klinger 
35278f83902SAndreas Klinger 	data = iio_priv(indio_dev);
35378f83902SAndreas Klinger 	i2c_set_clientdata(client, indio_dev);
35478f83902SAndreas Klinger 	data->client = client;
35578f83902SAndreas Klinger 
35678f83902SAndreas Klinger 	indio_dev->name = "srf08";
35778f83902SAndreas Klinger 	indio_dev->dev.parent = &client->dev;
35878f83902SAndreas Klinger 	indio_dev->modes = INDIO_DIRECT_MODE;
35978f83902SAndreas Klinger 	indio_dev->info = &srf08_info;
36078f83902SAndreas Klinger 	indio_dev->channels = srf08_channels;
36178f83902SAndreas Klinger 	indio_dev->num_channels = ARRAY_SIZE(srf08_channels);
36278f83902SAndreas Klinger 
36378f83902SAndreas Klinger 	mutex_init(&data->lock);
36478f83902SAndreas Klinger 
36578f83902SAndreas Klinger 	/*
36678f83902SAndreas Klinger 	 * set default values of device here
36778f83902SAndreas Klinger 	 * these register values cannot be read from the hardware
36878f83902SAndreas Klinger 	 * therefore set driver specific default values
36978f83902SAndreas Klinger 	 */
37078f83902SAndreas Klinger 	ret = srf08_write_range_mm(data, SRF08_DEFAULT_RANGE);
37178f83902SAndreas Klinger 	if (ret < 0)
37278f83902SAndreas Klinger 		return ret;
37378f83902SAndreas Klinger 
37478f83902SAndreas Klinger 	ret = srf08_write_sensitivity(data, SRF08_DEFAULT_GAIN);
37578f83902SAndreas Klinger 	if (ret < 0)
37678f83902SAndreas Klinger 		return ret;
37778f83902SAndreas Klinger 
37878f83902SAndreas Klinger 	return devm_iio_device_register(&client->dev, indio_dev);
37978f83902SAndreas Klinger }
38078f83902SAndreas Klinger 
38178f83902SAndreas Klinger static const struct i2c_device_id srf08_id[] = {
38278f83902SAndreas Klinger 	{ "srf08", 0 },
38378f83902SAndreas Klinger 	{ }
38478f83902SAndreas Klinger };
38578f83902SAndreas Klinger MODULE_DEVICE_TABLE(i2c, srf08_id);
38678f83902SAndreas Klinger 
38778f83902SAndreas Klinger static struct i2c_driver srf08_driver = {
38878f83902SAndreas Klinger 	.driver = {
38978f83902SAndreas Klinger 		.name	= "srf08",
39078f83902SAndreas Klinger 	},
39178f83902SAndreas Klinger 	.probe = srf08_probe,
39278f83902SAndreas Klinger 	.id_table = srf08_id,
39378f83902SAndreas Klinger };
39478f83902SAndreas Klinger module_i2c_driver(srf08_driver);
39578f83902SAndreas Klinger 
39678f83902SAndreas Klinger MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
39778f83902SAndreas Klinger MODULE_DESCRIPTION("Devantech SRF08 ultrasonic ranger driver");
39878f83902SAndreas Klinger MODULE_LICENSE("GPL");
399