aboutsummaryrefslogtreecommitdiffstats
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:47 -0500
commitbdb20bdb8c1ea55c9a2f744cc5b2c7f66148a41b (patch)
tree12d0edec2bf890cf954000715e7e50221317961f
parent06220b89f2284f910f925676d757fd3331138dc6 (diff)
staging:iio:adis16400: Fix and cleanup 3db filter setting
The 3db divisors table is partially wrong and incomplete. Also the code rounds up to the next higher frequency if the requested frequency would matches one of the available frequencies. These two issues are fixed by this patch. The patch also changes the driver to round down the filter frequency if it is larger than the largest supported frequency instead of rejecting it as an invalid value. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
-rw-r--r--drivers/staging/iio/imu/adis16400_core.c41
1 files changed, 20 insertions, 21 deletions
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c
index cb6622578e9b..7114de94f412 100644
--- a/drivers/staging/iio/imu/adis16400_core.c
+++ b/drivers/staging/iio/imu/adis16400_core.c
@@ -242,33 +242,32 @@ static ssize_t adis16400_read_frequency(struct device *dev,
242 242
243static const unsigned adis16400_3db_divisors[] = { 243static const unsigned adis16400_3db_divisors[] = {
244 [0] = 2, /* Special case */ 244 [0] = 2, /* Special case */
245 [1] = 5, 245 [1] = 6,
246 [2] = 10, 246 [2] = 12,
247 [3] = 50, 247 [3] = 25,
248 [4] = 200, 248 [4] = 50,
249 [5] = 100,
250 [6] = 200,
251 [7] = 200, /* Not a valid setting */
249}; 252};
250 253
251static int adis16400_set_filter(struct iio_dev *indio_dev, int sps, int val) 254static int adis16400_set_filter(struct iio_dev *indio_dev, int sps, int val)
252{ 255{
253 int i, ret; 256 int i, ret;
254 u16 val16; 257 u16 val16;
255 for (i = ARRAY_SIZE(adis16400_3db_divisors) - 1; i >= 0; i--) 258
256 if (sps/adis16400_3db_divisors[i] > val) 259 for (i = ARRAY_SIZE(adis16400_3db_divisors) - 1; i >= 1; i--) {
260 if (sps / adis16400_3db_divisors[i] >= val)
257 break; 261 break;
258 if (i == -1) 262 }
259 ret = -EINVAL; 263
260 else { 264 ret = adis16400_spi_read_reg_16(indio_dev, ADIS16400_SENS_AVG,
261 ret = adis16400_spi_read_reg_16(indio_dev,
262 ADIS16400_SENS_AVG,
263 &val16); 265 &val16);
264 if (ret < 0) 266 if (ret < 0)
265 goto error_ret; 267 return ret;
266 268
267 ret = adis16400_spi_write_reg_16(indio_dev, 269 ret = adis16400_spi_write_reg_16(indio_dev, ADIS16400_SENS_AVG,
268 ADIS16400_SENS_AVG, 270 (val16 & ~0x07) | i);
269 (val16 & ~0x03) | i);
270 }
271error_ret:
272 return ret; 271 return ret;
273} 272}
274 273
@@ -653,9 +652,9 @@ static int adis16400_read_raw(struct iio_dev *indio_dev,
653 mutex_unlock(&indio_dev->mlock); 652 mutex_unlock(&indio_dev->mlock);
654 return ret; 653 return ret;
655 } 654 }
656 val16 = st->variant->get_freq(indio_dev); 655 ret = st->variant->get_freq(indio_dev);
657 if (ret > 0) 656 if (ret >= 0)
658 *val = ret/adis16400_3db_divisors[val16 & 0x03]; 657 *val = ret / adis16400_3db_divisors[val16 & 0x07];
659 *val2 = 0; 658 *val2 = 0;
660 mutex_unlock(&indio_dev->mlock); 659 mutex_unlock(&indio_dev->mlock);
661 if (ret < 0) 660 if (ret < 0)