aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iio/imu
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2013-01-16 07:48:00 -0500
committerJonathan Cameron <jic23@kernel.org>2013-01-26 05:07:50 -0500
commitb24150e31ab27ffcd2aa9b33dca42c2070526054 (patch)
treebc1470fd716896505245e8b8307ab02b2be3dc37 /drivers/iio/imu
parentd6b09bd85d57752395c6407bd8a9b32eb7b279ff (diff)
iio:adis16400: Increase samplerate precession
The devices supported by this drivers support sample rates with less than one sample per second. To support this increase the samplerate precession to allow setting (and reading) the samplerate with a milli-HZ precession. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio/imu')
-rw-r--r--drivers/iio/imu/adis16400_core.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/drivers/iio/imu/adis16400_core.c b/drivers/iio/imu/adis16400_core.c
index 1bbe5eed0139..8551fde90563 100644
--- a/drivers/iio/imu/adis16400_core.c
+++ b/drivers/iio/imu/adis16400_core.c
@@ -53,16 +53,15 @@ static int adis16334_get_freq(struct adis16400_state *st)
53 53
54 t >>= ADIS16334_RATE_DIV_SHIFT; 54 t >>= ADIS16334_RATE_DIV_SHIFT;
55 55
56 return (8192 >> t) / 10; 56 return 819200 >> t;
57} 57}
58 58
59static int adis16334_set_freq(struct adis16400_state *st, unsigned int freq) 59static int adis16334_set_freq(struct adis16400_state *st, unsigned int freq)
60{ 60{
61 unsigned int t; 61 unsigned int t;
62 62
63 freq *= 10; 63 if (freq < 819200)
64 if (freq < 8192) 64 t = ilog2(819200 / freq);
65 t = ilog2(8192 / freq);
66 else 65 else
67 t = 0; 66 t = 0;
68 67
@@ -84,7 +83,7 @@ static int adis16400_get_freq(struct adis16400_state *st)
84 if (ret < 0) 83 if (ret < 0)
85 return ret; 84 return ret;
86 85
87 sps = (t & ADIS16400_SMPL_PRD_TIME_BASE) ? 53 : 1638; 86 sps = (t & ADIS16400_SMPL_PRD_TIME_BASE) ? 52851 : 1638404;
88 sps /= (t & ADIS16400_SMPL_PRD_DIV_MASK) + 1; 87 sps /= (t & ADIS16400_SMPL_PRD_DIV_MASK) + 1;
89 88
90 return sps; 89 return sps;
@@ -94,7 +93,7 @@ static int adis16400_set_freq(struct adis16400_state *st, unsigned int freq)
94{ 93{
95 unsigned int t; 94 unsigned int t;
96 95
97 t = 1638 / freq; 96 t = 1638404 / freq;
98 if (t > 0) 97 if (t > 0)
99 t--; 98 t--;
100 t &= ADIS16400_SMPL_PRD_DIV_MASK; 99 t &= ADIS16400_SMPL_PRD_DIV_MASK;
@@ -119,7 +118,7 @@ static ssize_t adis16400_read_frequency(struct device *dev,
119 if (ret < 0) 118 if (ret < 0)
120 return ret; 119 return ret;
121 120
122 return sprintf(buf, "%d\n", ret); 121 return sprintf(buf, "%d.%.3d\n", ret / 1000, ret % 1000);
123} 122}
124 123
125static const unsigned adis16400_3db_divisors[] = { 124static const unsigned adis16400_3db_divisors[] = {
@@ -158,14 +157,16 @@ static ssize_t adis16400_write_frequency(struct device *dev,
158{ 157{
159 struct iio_dev *indio_dev = dev_to_iio_dev(dev); 158 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
160 struct adis16400_state *st = iio_priv(indio_dev); 159 struct adis16400_state *st = iio_priv(indio_dev);
161 long val; 160 int i, f, val;
162 int ret; 161 int ret;
163 162
164 ret = kstrtol(buf, 10, &val); 163 ret = iio_str_to_fixpoint(buf, 100, &i, &f);
165 if (ret) 164 if (ret)
166 return ret; 165 return ret;
167 166
168 if (val == 0) 167 val = i * 1000 + f;
168
169 if (val <= 0)
169 return -EINVAL; 170 return -EINVAL;
170 171
171 mutex_lock(&indio_dev->mlock); 172 mutex_lock(&indio_dev->mlock);
@@ -281,7 +282,8 @@ static int adis16400_write_raw(struct iio_dev *indio_dev,
281 return sps; 282 return sps;
282 } 283 }
283 284
284 ret = adis16400_set_filter(indio_dev, sps, val); 285 ret = adis16400_set_filter(indio_dev, sps,
286 val * 1000 + val2 / 1000);
285 mutex_unlock(&indio_dev->mlock); 287 mutex_unlock(&indio_dev->mlock);
286 return ret; 288 return ret;
287 default: 289 default:
@@ -355,9 +357,11 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
355 return ret; 357 return ret;
356 } 358 }
357 ret = st->variant->get_freq(st); 359 ret = st->variant->get_freq(st);
358 if (ret >= 0) 360 if (ret >= 0) {
359 *val = ret / adis16400_3db_divisors[val16 & 0x07]; 361 ret /= adis16400_3db_divisors[val16 & 0x07];
360 *val2 = 0; 362 *val = ret / 1000;
363 *val2 = (ret % 1000) * 1000;
364 }
361 mutex_unlock(&indio_dev->mlock); 365 mutex_unlock(&indio_dev->mlock);
362 if (ret < 0) 366 if (ret < 0)
363 return ret; 367 return ret;