aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>2014-04-28 19:51:00 -0400
committerJonathan Cameron <jic23@kernel.org>2014-04-29 17:05:32 -0400
commit9fbfb4b37ed23f71aa9484484266381c6c6964cb (patch)
tree441b1f942d51a1729d10a3237c7a28853f482ff9
parent3046365bb470f0ec2f7cf5cb07a8ee7e4b490103 (diff)
IIO: core: Introduce read_raw_multi
This callback is introduced to overcome some limitations of existing read_raw callback. The functionality of both existing read_raw and read_raw_multi is similar, both are used to request values from the device. The current read_raw callback allows only two return values. The new read_raw_multi allows returning multiple values. Instead of passing just address of val and val2, it passes length and pointer to values. Depending on the type and length of passed buffer, iio client drivers can return multiple values. Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
-rw-r--r--drivers/iio/iio_core.h2
-rw-r--r--drivers/iio/industrialio-core.c65
-rw-r--r--drivers/iio/industrialio-event.c6
-rw-r--r--drivers/iio/inkern.c16
-rw-r--r--include/linux/iio/iio.h17
-rw-r--r--include/linux/iio/types.h1
6 files changed, 80 insertions, 27 deletions
diff --git a/drivers/iio/iio_core.h b/drivers/iio/iio_core.h
index f6db6af36ba6..5f0ea77fe717 100644
--- a/drivers/iio/iio_core.h
+++ b/drivers/iio/iio_core.h
@@ -35,7 +35,7 @@ int __iio_add_chan_devattr(const char *postfix,
35 struct list_head *attr_list); 35 struct list_head *attr_list);
36void iio_free_chan_devattr_list(struct list_head *attr_list); 36void iio_free_chan_devattr_list(struct list_head *attr_list);
37 37
38ssize_t iio_format_value(char *buf, unsigned int type, int val, int val2); 38ssize_t iio_format_value(char *buf, unsigned int type, int size, int *vals);
39 39
40/* Event interface flags */ 40/* Event interface flags */
41#define IIO_BUSY_BIT_POS 1 41#define IIO_BUSY_BIT_POS 1
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index 184444db62ac..59540859bfae 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -373,41 +373,53 @@ EXPORT_SYMBOL_GPL(iio_enum_write);
373 * @buf: The buffer to which the formated value gets written 373 * @buf: The buffer to which the formated value gets written
374 * @type: One of the IIO_VAL_... constants. This decides how the val and val2 374 * @type: One of the IIO_VAL_... constants. This decides how the val and val2
375 * parameters are formatted. 375 * parameters are formatted.
376 * @val: First part of the value, exact meaning depends on the type parameter. 376 * @vals: pointer to the values, exact meaning depends on the type parameter.
377 * @val2: Second part of the value, exact meaning depends on the type parameter.
378 */ 377 */
379ssize_t iio_format_value(char *buf, unsigned int type, int val, int val2) 378ssize_t iio_format_value(char *buf, unsigned int type, int size, int *vals)
380{ 379{
381 unsigned long long tmp; 380 unsigned long long tmp;
382 bool scale_db = false; 381 bool scale_db = false;
383 382
384 switch (type) { 383 switch (type) {
385 case IIO_VAL_INT: 384 case IIO_VAL_INT:
386 return sprintf(buf, "%d\n", val); 385 return sprintf(buf, "%d\n", vals[0]);
387 case IIO_VAL_INT_PLUS_MICRO_DB: 386 case IIO_VAL_INT_PLUS_MICRO_DB:
388 scale_db = true; 387 scale_db = true;
389 case IIO_VAL_INT_PLUS_MICRO: 388 case IIO_VAL_INT_PLUS_MICRO:
390 if (val2 < 0) 389 if (vals[1] < 0)
391 return sprintf(buf, "-%ld.%06u%s\n", abs(val), -val2, 390 return sprintf(buf, "-%ld.%06u%s\n", abs(vals[0]),
391 -vals[1],
392 scale_db ? " dB" : ""); 392 scale_db ? " dB" : "");
393 else 393 else
394 return sprintf(buf, "%d.%06u%s\n", val, val2, 394 return sprintf(buf, "%d.%06u%s\n", vals[0], vals[1],
395 scale_db ? " dB" : ""); 395 scale_db ? " dB" : "");
396 case IIO_VAL_INT_PLUS_NANO: 396 case IIO_VAL_INT_PLUS_NANO:
397 if (val2 < 0) 397 if (vals[1] < 0)
398 return sprintf(buf, "-%ld.%09u\n", abs(val), -val2); 398 return sprintf(buf, "-%ld.%09u\n", abs(vals[0]),
399 -vals[1]);
399 else 400 else
400 return sprintf(buf, "%d.%09u\n", val, val2); 401 return sprintf(buf, "%d.%09u\n", vals[0], vals[1]);
401 case IIO_VAL_FRACTIONAL: 402 case IIO_VAL_FRACTIONAL:
402 tmp = div_s64((s64)val * 1000000000LL, val2); 403 tmp = div_s64((s64)vals[0] * 1000000000LL, vals[1]);
403 val2 = do_div(tmp, 1000000000LL); 404 vals[1] = do_div(tmp, 1000000000LL);
404 val = tmp; 405 vals[0] = tmp;
405 return sprintf(buf, "%d.%09u\n", val, val2); 406 return sprintf(buf, "%d.%09u\n", vals[0], vals[1]);
406 case IIO_VAL_FRACTIONAL_LOG2: 407 case IIO_VAL_FRACTIONAL_LOG2:
407 tmp = (s64)val * 1000000000LL >> val2; 408 tmp = (s64)vals[0] * 1000000000LL >> vals[1];
408 val2 = do_div(tmp, 1000000000LL); 409 vals[1] = do_div(tmp, 1000000000LL);
409 val = tmp; 410 vals[0] = tmp;
410 return sprintf(buf, "%d.%09u\n", val, val2); 411 return sprintf(buf, "%d.%09u\n", vals[0], vals[1]);
412 case IIO_VAL_INT_MULTIPLE:
413 {
414 int i;
415 int len = 0;
416
417 for (i = 0; i < size; ++i)
418 len += snprintf(&buf[len], PAGE_SIZE - len, "%d ",
419 vals[i]);
420 len += snprintf(&buf[len], PAGE_SIZE - len, "\n");
421 return len;
422 }
411 default: 423 default:
412 return 0; 424 return 0;
413 } 425 }
@@ -419,14 +431,23 @@ static ssize_t iio_read_channel_info(struct device *dev,
419{ 431{
420 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 432 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
421 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 433 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
422 int val, val2; 434 int vals[INDIO_MAX_RAW_ELEMENTS];
423 int ret = indio_dev->info->read_raw(indio_dev, this_attr->c, 435 int ret;
424 &val, &val2, this_attr->address); 436 int val_len = 2;
437
438 if (indio_dev->info->read_raw_multi)
439 ret = indio_dev->info->read_raw_multi(indio_dev, this_attr->c,
440 INDIO_MAX_RAW_ELEMENTS,
441 vals, &val_len,
442 this_attr->address);
443 else
444 ret = indio_dev->info->read_raw(indio_dev, this_attr->c,
445 &vals[0], &vals[1], this_attr->address);
425 446
426 if (ret < 0) 447 if (ret < 0)
427 return ret; 448 return ret;
428 449
429 return iio_format_value(buf, ret, val, val2); 450 return iio_format_value(buf, ret, val_len, vals);
430} 451}
431 452
432/** 453/**
diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c
index dddfb0f90d34..258a973a1fb8 100644
--- a/drivers/iio/industrialio-event.c
+++ b/drivers/iio/industrialio-event.c
@@ -270,7 +270,7 @@ static ssize_t iio_ev_value_show(struct device *dev,
270{ 270{
271 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 271 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
272 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); 272 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
273 int val, val2; 273 int val, val2, val_arr[2];
274 int ret; 274 int ret;
275 275
276 ret = indio_dev->info->read_event_value(indio_dev, 276 ret = indio_dev->info->read_event_value(indio_dev,
@@ -279,7 +279,9 @@ static ssize_t iio_ev_value_show(struct device *dev,
279 &val, &val2); 279 &val, &val2);
280 if (ret < 0) 280 if (ret < 0)
281 return ret; 281 return ret;
282 return iio_format_value(buf, ret, val, val2); 282 val_arr[0] = val;
283 val_arr[1] = val2;
284 return iio_format_value(buf, ret, 2, val_arr);
283} 285}
284 286
285static ssize_t iio_ev_value_store(struct device *dev, 287static ssize_t iio_ev_value_store(struct device *dev,
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index adeba5a0ecf7..d833d55052ea 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -417,12 +417,24 @@ static int iio_channel_read(struct iio_channel *chan, int *val, int *val2,
417 enum iio_chan_info_enum info) 417 enum iio_chan_info_enum info)
418{ 418{
419 int unused; 419 int unused;
420 int vals[INDIO_MAX_RAW_ELEMENTS];
421 int ret;
422 int val_len = 2;
420 423
421 if (val2 == NULL) 424 if (val2 == NULL)
422 val2 = &unused; 425 val2 = &unused;
423 426
424 return chan->indio_dev->info->read_raw(chan->indio_dev, chan->channel, 427 if (chan->indio_dev->info->read_raw_multi) {
425 val, val2, info); 428 ret = chan->indio_dev->info->read_raw_multi(chan->indio_dev,
429 chan->channel, INDIO_MAX_RAW_ELEMENTS,
430 vals, &val_len, info);
431 *val = vals[0];
432 *val2 = vals[1];
433 } else
434 ret = chan->indio_dev->info->read_raw(chan->indio_dev,
435 chan->channel, val, val2, info);
436
437 return ret;
426} 438}
427 439
428int iio_read_channel_raw(struct iio_channel *chan, int *val) 440int iio_read_channel_raw(struct iio_channel *chan, int *val)
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h
index 5f2d00e7e488..5629c92eeadf 100644
--- a/include/linux/iio/iio.h
+++ b/include/linux/iio/iio.h
@@ -288,6 +288,8 @@ static inline s64 iio_get_time_ns(void)
288#define INDIO_ALL_BUFFER_MODES \ 288#define INDIO_ALL_BUFFER_MODES \
289 (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE) 289 (INDIO_BUFFER_TRIGGERED | INDIO_BUFFER_HARDWARE)
290 290
291#define INDIO_MAX_RAW_ELEMENTS 4
292
291struct iio_trigger; /* forward declaration */ 293struct iio_trigger; /* forward declaration */
292struct iio_dev; 294struct iio_dev;
293 295
@@ -302,6 +304,14 @@ struct iio_dev;
302 * the channel in question. Return value will specify the 304 * the channel in question. Return value will specify the
303 * type of value returned by the device. val and val2 will 305 * type of value returned by the device. val and val2 will
304 * contain the elements making up the returned value. 306 * contain the elements making up the returned value.
307 * @read_raw_multi: function to return values from the device.
308 * mask specifies which value. Note 0 means a reading of
309 * the channel in question. Return value will specify the
310 * type of value returned by the device. vals pointer
311 * contain the elements making up the returned value.
312 * max_len specifies maximum number of elements
313 * vals pointer can contain. val_len is used to return
314 * length of valid elements in vals.
305 * @write_raw: function to write a value to the device. 315 * @write_raw: function to write a value to the device.
306 * Parameters are the same as for read_raw. 316 * Parameters are the same as for read_raw.
307 * @write_raw_get_fmt: callback function to query the expected 317 * @write_raw_get_fmt: callback function to query the expected
@@ -328,6 +338,13 @@ struct iio_info {
328 int *val2, 338 int *val2,
329 long mask); 339 long mask);
330 340
341 int (*read_raw_multi)(struct iio_dev *indio_dev,
342 struct iio_chan_spec const *chan,
343 int max_len,
344 int *vals,
345 int *val_len,
346 long mask);
347
331 int (*write_raw)(struct iio_dev *indio_dev, 348 int (*write_raw)(struct iio_dev *indio_dev,
332 struct iio_chan_spec const *chan, 349 struct iio_chan_spec const *chan,
333 int val, 350 int val,
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index 084d882fe01b..a13c2241abce 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -79,6 +79,7 @@ enum iio_event_direction {
79#define IIO_VAL_INT_PLUS_MICRO 2 79#define IIO_VAL_INT_PLUS_MICRO 2
80#define IIO_VAL_INT_PLUS_NANO 3 80#define IIO_VAL_INT_PLUS_NANO 3
81#define IIO_VAL_INT_PLUS_MICRO_DB 4 81#define IIO_VAL_INT_PLUS_MICRO_DB 4
82#define IIO_VAL_INT_MULTIPLE 5
82#define IIO_VAL_FRACTIONAL 10 83#define IIO_VAL_FRACTIONAL 10
83#define IIO_VAL_FRACTIONAL_LOG2 11 84#define IIO_VAL_FRACTIONAL_LOG2 11
84 85