diff options
-rw-r--r-- | drivers/iio/imu/adis16480.c | 82 |
1 files changed, 22 insertions, 60 deletions
diff --git a/drivers/iio/imu/adis16480.c b/drivers/iio/imu/adis16480.c index dd4206cac62d..989605dd6f78 100644 --- a/drivers/iio/imu/adis16480.c +++ b/drivers/iio/imu/adis16480.c | |||
@@ -257,11 +257,16 @@ static int adis16480_debugfs_init(struct iio_dev *indio_dev) | |||
257 | 257 | ||
258 | #endif | 258 | #endif |
259 | 259 | ||
260 | static int adis16480_set_freq(struct adis16480 *st, unsigned int freq) | 260 | static int adis16480_set_freq(struct iio_dev *indio_dev, int val, int val2) |
261 | { | 261 | { |
262 | struct adis16480 *st = iio_priv(indio_dev); | ||
262 | unsigned int t; | 263 | unsigned int t; |
263 | 264 | ||
264 | t = 2460000 / freq; | 265 | t = val * 1000 + val2 / 1000; |
266 | if (t <= 0) | ||
267 | return -EINVAL; | ||
268 | |||
269 | t = 2460000 / t; | ||
265 | if (t > 2048) | 270 | if (t > 2048) |
266 | t = 2048; | 271 | t = 2048; |
267 | 272 | ||
@@ -271,65 +276,24 @@ static int adis16480_set_freq(struct adis16480 *st, unsigned int freq) | |||
271 | return adis_write_reg_16(&st->adis, ADIS16480_REG_DEC_RATE, t); | 276 | return adis_write_reg_16(&st->adis, ADIS16480_REG_DEC_RATE, t); |
272 | } | 277 | } |
273 | 278 | ||
274 | static int adis16480_get_freq(struct adis16480 *st, unsigned int *freq) | 279 | static int adis16480_get_freq(struct iio_dev *indio_dev, int *val, int *val2) |
275 | { | 280 | { |
281 | struct adis16480 *st = iio_priv(indio_dev); | ||
276 | uint16_t t; | 282 | uint16_t t; |
277 | int ret; | 283 | int ret; |
284 | unsigned freq; | ||
278 | 285 | ||
279 | ret = adis_read_reg_16(&st->adis, ADIS16480_REG_DEC_RATE, &t); | 286 | ret = adis_read_reg_16(&st->adis, ADIS16480_REG_DEC_RATE, &t); |
280 | if (ret < 0) | 287 | if (ret < 0) |
281 | return ret; | 288 | return ret; |
282 | 289 | ||
283 | *freq = 2460000 / (t + 1); | 290 | freq = 2460000 / (t + 1); |
291 | *val = freq / 1000; | ||
292 | *val2 = (freq % 1000) * 1000; | ||
284 | 293 | ||
285 | return 0; | 294 | return IIO_VAL_INT_PLUS_MICRO; |
286 | } | 295 | } |
287 | 296 | ||
288 | static ssize_t adis16480_read_frequency(struct device *dev, | ||
289 | struct device_attribute *attr, | ||
290 | char *buf) | ||
291 | { | ||
292 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); | ||
293 | struct adis16480 *st = iio_priv(indio_dev); | ||
294 | unsigned int freq; | ||
295 | int ret; | ||
296 | |||
297 | ret = adis16480_get_freq(st, &freq); | ||
298 | if (ret < 0) | ||
299 | return ret; | ||
300 | |||
301 | return sprintf(buf, "%d.%.3d\n", freq / 1000, freq % 1000); | ||
302 | } | ||
303 | |||
304 | static ssize_t adis16480_write_frequency(struct device *dev, | ||
305 | struct device_attribute *attr, | ||
306 | const char *buf, | ||
307 | size_t len) | ||
308 | { | ||
309 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); | ||
310 | struct adis16480 *st = iio_priv(indio_dev); | ||
311 | int freq_int, freq_fract; | ||
312 | long val; | ||
313 | int ret; | ||
314 | |||
315 | ret = iio_str_to_fixpoint(buf, 100, &freq_int, &freq_fract); | ||
316 | if (ret) | ||
317 | return ret; | ||
318 | |||
319 | val = freq_int * 1000 + freq_fract; | ||
320 | |||
321 | if (val <= 0) | ||
322 | return -EINVAL; | ||
323 | |||
324 | ret = adis16480_set_freq(st, val); | ||
325 | |||
326 | return ret ? ret : len; | ||
327 | } | ||
328 | |||
329 | static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, | ||
330 | adis16480_read_frequency, | ||
331 | adis16480_write_frequency); | ||
332 | |||
333 | enum { | 297 | enum { |
334 | ADIS16480_SCAN_GYRO_X, | 298 | ADIS16480_SCAN_GYRO_X, |
335 | ADIS16480_SCAN_GYRO_Y, | 299 | ADIS16480_SCAN_GYRO_Y, |
@@ -571,6 +535,8 @@ static int adis16480_read_raw(struct iio_dev *indio_dev, | |||
571 | return adis16480_get_calibscale(indio_dev, chan, val); | 535 | return adis16480_get_calibscale(indio_dev, chan, val); |
572 | case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: | 536 | case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: |
573 | return adis16480_get_filter_freq(indio_dev, chan, val); | 537 | return adis16480_get_filter_freq(indio_dev, chan, val); |
538 | case IIO_CHAN_INFO_SAMP_FREQ: | ||
539 | return adis16480_get_freq(indio_dev, val, val2); | ||
574 | default: | 540 | default: |
575 | return -EINVAL; | 541 | return -EINVAL; |
576 | } | 542 | } |
@@ -586,6 +552,9 @@ static int adis16480_write_raw(struct iio_dev *indio_dev, | |||
586 | return adis16480_set_calibscale(indio_dev, chan, val); | 552 | return adis16480_set_calibscale(indio_dev, chan, val); |
587 | case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: | 553 | case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: |
588 | return adis16480_set_filter_freq(indio_dev, chan, val); | 554 | return adis16480_set_filter_freq(indio_dev, chan, val); |
555 | case IIO_CHAN_INFO_SAMP_FREQ: | ||
556 | return adis16480_set_freq(indio_dev, val, val2); | ||
557 | |||
589 | default: | 558 | default: |
590 | return -EINVAL; | 559 | return -EINVAL; |
591 | } | 560 | } |
@@ -600,6 +569,7 @@ static int adis16480_write_raw(struct iio_dev *indio_dev, | |||
600 | BIT(IIO_CHAN_INFO_CALIBBIAS) | \ | 569 | BIT(IIO_CHAN_INFO_CALIBBIAS) | \ |
601 | _info_sep, \ | 570 | _info_sep, \ |
602 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ | 571 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ |
572 | .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ | ||
603 | .address = (_address), \ | 573 | .address = (_address), \ |
604 | .scan_index = (_si), \ | 574 | .scan_index = (_si), \ |
605 | .scan_type = { \ | 575 | .scan_type = { \ |
@@ -638,6 +608,7 @@ static int adis16480_write_raw(struct iio_dev *indio_dev, | |||
638 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ | 608 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
639 | BIT(IIO_CHAN_INFO_CALIBBIAS) | \ | 609 | BIT(IIO_CHAN_INFO_CALIBBIAS) | \ |
640 | BIT(IIO_CHAN_INFO_SCALE), \ | 610 | BIT(IIO_CHAN_INFO_SCALE), \ |
611 | .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ | ||
641 | .address = ADIS16480_REG_BAROM_OUT, \ | 612 | .address = ADIS16480_REG_BAROM_OUT, \ |
642 | .scan_index = ADIS16480_SCAN_BARO, \ | 613 | .scan_index = ADIS16480_SCAN_BARO, \ |
643 | .scan_type = { \ | 614 | .scan_type = { \ |
@@ -655,6 +626,7 @@ static int adis16480_write_raw(struct iio_dev *indio_dev, | |||
655 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ | 626 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
656 | BIT(IIO_CHAN_INFO_SCALE) | \ | 627 | BIT(IIO_CHAN_INFO_SCALE) | \ |
657 | BIT(IIO_CHAN_INFO_OFFSET), \ | 628 | BIT(IIO_CHAN_INFO_OFFSET), \ |
629 | .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ | ||
658 | .address = ADIS16480_REG_TEMP_OUT, \ | 630 | .address = ADIS16480_REG_TEMP_OUT, \ |
659 | .scan_index = ADIS16480_SCAN_TEMP, \ | 631 | .scan_index = ADIS16480_SCAN_TEMP, \ |
660 | .scan_type = { \ | 632 | .scan_type = { \ |
@@ -717,17 +689,7 @@ static const struct adis16480_chip_info adis16480_chip_info[] = { | |||
717 | }, | 689 | }, |
718 | }; | 690 | }; |
719 | 691 | ||
720 | static struct attribute *adis16480_attributes[] = { | ||
721 | &iio_dev_attr_sampling_frequency.dev_attr.attr, | ||
722 | NULL | ||
723 | }; | ||
724 | |||
725 | static const struct attribute_group adis16480_attribute_group = { | ||
726 | .attrs = adis16480_attributes, | ||
727 | }; | ||
728 | |||
729 | static const struct iio_info adis16480_info = { | 692 | static const struct iio_info adis16480_info = { |
730 | .attrs = &adis16480_attribute_group, | ||
731 | .read_raw = &adis16480_read_raw, | 693 | .read_raw = &adis16480_read_raw, |
732 | .write_raw = &adis16480_write_raw, | 694 | .write_raw = &adis16480_write_raw, |
733 | .update_scan_mode = adis_update_scan_mode, | 695 | .update_scan_mode = adis_update_scan_mode, |