aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Klinger <ak@it-klinger.de>2017-08-16 15:34:23 -0400
committerJonathan Cameron <Jonathan.Cameron@huawei.com>2017-08-18 03:01:58 -0400
commitc5bf4a04467dca050784c9faef492ce17d268be9 (patch)
tree949366c7bd0b2ac54ce08b19fc4e3af78534b745
parenta83195937151036d9114154970f1cbf44114d43e (diff)
iio: srf08: add sensor type srf10
Ultrasonic sensor srf10 is quite similar to srf08 and now also supported by the driver as device tree compatible string. It was necessary to prepare the source for supplementary sensors. This is done by enum srf08_sensor_type. The most significiant difference between srf08 and srf10 is another range and values of register gain (in the driver it's call sensitivity). Therefore the array of it is extended and dependent of the sensor type. Signed-off-by: Andreas Klinger <ak@it-klinger.de> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
-rw-r--r--drivers/iio/proximity/Kconfig4
-rw-r--r--drivers/iio/proximity/srf08.c90
2 files changed, 77 insertions, 17 deletions
diff --git a/drivers/iio/proximity/Kconfig b/drivers/iio/proximity/Kconfig
index 5b81a8c9d438..df33ccc0d035 100644
--- a/drivers/iio/proximity/Kconfig
+++ b/drivers/iio/proximity/Kconfig
@@ -57,10 +57,10 @@ config SX9500
57 module will be called sx9500. 57 module will be called sx9500.
58 58
59config SRF08 59config SRF08
60 tristate "Devantech SRF08 ultrasonic ranger sensor" 60 tristate "Devantech SRF08/SRF10 ultrasonic ranger sensor"
61 depends on I2C 61 depends on I2C
62 help 62 help
63 Say Y here to build a driver for Devantech SRF08 ultrasonic 63 Say Y here to build a driver for Devantech SRF08/SRF10 ultrasonic
64 ranger sensor. This driver can be used to measure the distance 64 ranger sensor. This driver can be used to measure the distance
65 of objects. 65 of objects.
66 66
diff --git a/drivers/iio/proximity/srf08.c b/drivers/iio/proximity/srf08.c
index de699d67310a..1f9b03944da4 100644
--- a/drivers/iio/proximity/srf08.c
+++ b/drivers/iio/proximity/srf08.c
@@ -1,5 +1,7 @@
1/* 1/*
2 * srf08.c - Support for Devantech SRF08 ultrasonic ranger 2 * srf08.c - Support for Devantech SRFxx ultrasonic ranger
3 * with i2c interface
4 * actually supported are srf08, srf10
3 * 5 *
4 * Copyright (c) 2016 Andreas Klinger <ak@it-klinger.de> 6 * Copyright (c) 2016 Andreas Klinger <ak@it-klinger.de>
5 * 7 *
@@ -9,6 +11,7 @@
9 * 11 *
10 * For details about the device see: 12 * For details about the device see:
11 * http://www.robot-electronics.co.uk/htm/srf08tech.html 13 * http://www.robot-electronics.co.uk/htm/srf08tech.html
14 * http://www.robot-electronics.co.uk/htm/srf10tech.htm
12 */ 15 */
13 16
14#include <linux/err.h> 17#include <linux/err.h>
@@ -33,9 +36,20 @@
33 36
34#define SRF08_CMD_RANGING_CM 0x51 /* Ranging Mode - Result in cm */ 37#define SRF08_CMD_RANGING_CM 0x51 /* Ranging Mode - Result in cm */
35 38
36#define SRF08_DEFAULT_GAIN 1025 /* default analogue value of Gain */
37#define SRF08_DEFAULT_RANGE 6020 /* default value of Range in mm */ 39#define SRF08_DEFAULT_RANGE 6020 /* default value of Range in mm */
38 40
41enum srf08_sensor_type {
42 SRF08,
43 SRF10,
44 SRF_MAX_TYPE
45};
46
47struct srf08_chip_info {
48 const int *sensitivity_avail;
49 int num_sensitivity_avail;
50 int sensitivity_default;
51};
52
39struct srf08_data { 53struct srf08_data {
40 struct i2c_client *client; 54 struct i2c_client *client;
41 55
@@ -54,6 +68,12 @@ struct srf08_data {
54 * 1x16-bit channel + 3x16 padding + 4x16 timestamp 68 * 1x16-bit channel + 3x16 padding + 4x16 timestamp
55 */ 69 */
56 s16 buffer[8]; 70 s16 buffer[8];
71
72 /* Sensor-Type */
73 enum srf08_sensor_type sensor_type;
74
75 /* Chip-specific information */
76 const struct srf08_chip_info *chip_info;
57}; 77};
58 78
59/* 79/*
@@ -63,11 +83,30 @@ struct srf08_data {
63 * But with ADC's this term is already used differently and that's why it 83 * But with ADC's this term is already used differently and that's why it
64 * is called "Sensitivity" here. 84 * is called "Sensitivity" here.
65 */ 85 */
66static const int srf08_sensitivity[] = { 86static const int srf08_sensitivity_avail[] = {
67 94, 97, 100, 103, 107, 110, 114, 118, 87 94, 97, 100, 103, 107, 110, 114, 118,
68 123, 128, 133, 139, 145, 152, 159, 168, 88 123, 128, 133, 139, 145, 152, 159, 168,
69 177, 187, 199, 212, 227, 245, 265, 288, 89 177, 187, 199, 212, 227, 245, 265, 288,
70 317, 352, 395, 450, 524, 626, 777, 1025 }; 90 317, 352, 395, 450, 524, 626, 777, 1025
91 };
92
93static const struct srf08_chip_info srf08_chip_info = {
94 .sensitivity_avail = srf08_sensitivity_avail,
95 .num_sensitivity_avail = ARRAY_SIZE(srf08_sensitivity_avail),
96 .sensitivity_default = 1025,
97};
98
99static const int srf10_sensitivity_avail[] = {
100 40, 40, 50, 60, 70, 80, 100, 120,
101 140, 200, 250, 300, 350, 400, 500, 600,
102 700,
103 };
104
105static const struct srf08_chip_info srf10_chip_info = {
106 .sensitivity_avail = srf10_sensitivity_avail,
107 .num_sensitivity_avail = ARRAY_SIZE(srf10_sensitivity_avail),
108 .sensitivity_default = 700,
109};
71 110
72static int srf08_read_ranging(struct srf08_data *data) 111static int srf08_read_ranging(struct srf08_data *data)
73{ 112{
@@ -264,9 +303,13 @@ static ssize_t srf08_show_sensitivity_available(struct device *dev,
264 struct device_attribute *attr, char *buf) 303 struct device_attribute *attr, char *buf)
265{ 304{
266 int i, len = 0; 305 int i, len = 0;
306 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
307 struct srf08_data *data = iio_priv(indio_dev);
267 308
268 for (i = 0; i < ARRAY_SIZE(srf08_sensitivity); i++) 309 for (i = 0; i < data->chip_info->num_sensitivity_avail; i++)
269 len += sprintf(buf + len, "%d ", srf08_sensitivity[i]); 310 if (data->chip_info->sensitivity_avail[i])
311 len += sprintf(buf + len, "%d ",
312 data->chip_info->sensitivity_avail[i]);
270 313
271 len += sprintf(buf + len, "\n"); 314 len += sprintf(buf + len, "\n");
272 315
@@ -295,19 +338,21 @@ static ssize_t srf08_write_sensitivity(struct srf08_data *data,
295 int ret, i; 338 int ret, i;
296 u8 regval; 339 u8 regval;
297 340
298 for (i = 0; i < ARRAY_SIZE(srf08_sensitivity); i++) 341 if (!val)
299 if (val == srf08_sensitivity[i]) { 342 return -EINVAL;
343
344 for (i = 0; i < data->chip_info->num_sensitivity_avail; i++)
345 if (val && (val == data->chip_info->sensitivity_avail[i])) {
300 regval = i; 346 regval = i;
301 break; 347 break;
302 } 348 }
303 349
304 if (i >= ARRAY_SIZE(srf08_sensitivity)) 350 if (i >= data->chip_info->num_sensitivity_avail)
305 return -EINVAL; 351 return -EINVAL;
306 352
307 mutex_lock(&data->lock); 353 mutex_lock(&data->lock);
308 354
309 ret = i2c_smbus_write_byte_data(client, 355 ret = i2c_smbus_write_byte_data(client, SRF08_WRITE_MAX_GAIN, regval);
310 SRF08_WRITE_MAX_GAIN, regval);
311 if (ret < 0) { 356 if (ret < 0) {
312 dev_err(&client->dev, "write_sensitivity - err: %d\n", ret); 357 dev_err(&client->dev, "write_sensitivity - err: %d\n", ret);
313 mutex_unlock(&data->lock); 358 mutex_unlock(&data->lock);
@@ -399,8 +444,20 @@ static int srf08_probe(struct i2c_client *client,
399 data = iio_priv(indio_dev); 444 data = iio_priv(indio_dev);
400 i2c_set_clientdata(client, indio_dev); 445 i2c_set_clientdata(client, indio_dev);
401 data->client = client; 446 data->client = client;
447 data->sensor_type = (enum srf08_sensor_type)id->driver_data;
448
449 switch (data->sensor_type) {
450 case SRF08:
451 data->chip_info = &srf08_chip_info;
452 break;
453 case SRF10:
454 data->chip_info = &srf10_chip_info;
455 break;
456 default:
457 return -EINVAL;
458 }
402 459
403 indio_dev->name = "srf08"; 460 indio_dev->name = id->name;
404 indio_dev->dev.parent = &client->dev; 461 indio_dev->dev.parent = &client->dev;
405 indio_dev->modes = INDIO_DIRECT_MODE; 462 indio_dev->modes = INDIO_DIRECT_MODE;
406 indio_dev->info = &srf08_info; 463 indio_dev->info = &srf08_info;
@@ -425,7 +482,8 @@ static int srf08_probe(struct i2c_client *client,
425 if (ret < 0) 482 if (ret < 0)
426 return ret; 483 return ret;
427 484
428 ret = srf08_write_sensitivity(data, SRF08_DEFAULT_GAIN); 485 ret = srf08_write_sensitivity(data,
486 data->chip_info->sensitivity_default);
429 if (ret < 0) 487 if (ret < 0)
430 return ret; 488 return ret;
431 489
@@ -433,14 +491,16 @@ static int srf08_probe(struct i2c_client *client,
433} 491}
434 492
435static const struct of_device_id of_srf08_match[] = { 493static const struct of_device_id of_srf08_match[] = {
436 { .compatible = "devantech,srf08", 0}, 494 { .compatible = "devantech,srf08", (void *)SRF08},
495 { .compatible = "devantech,srf10", (void *)SRF10},
437 {}, 496 {},
438}; 497};
439 498
440MODULE_DEVICE_TABLE(of, of_srf08_match); 499MODULE_DEVICE_TABLE(of, of_srf08_match);
441 500
442static const struct i2c_device_id srf08_id[] = { 501static const struct i2c_device_id srf08_id[] = {
443 { "srf08", 0 }, 502 { "srf08", SRF08 },
503 { "srf10", SRF10 },
444 { } 504 { }
445}; 505};
446MODULE_DEVICE_TABLE(i2c, srf08_id); 506MODULE_DEVICE_TABLE(i2c, srf08_id);