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