aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamu Onkalo <samu.p.onkalo@nokia.com>2009-12-14 21:01:46 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-15 11:53:36 -0500
commit32496c76b777752ba84b125bebfb0cc498f5602c (patch)
tree199a2e71fca6e19c5b7075965856a8934c7b9db6
parenta253aaef60a37bddfa84846353edeb62a6acf5b3 (diff)
lis3: scale output values to mg
Report output values as 1/1000 of earth gravity. Output values from lis3 can be read from sysfs position entry and from input device. Input device can be accessed as event device and as joystick device. Joystick device can be in two modes. Meaning of the output values varies from case to case depending on the chip type and configuration (scale). Only joystick interface in JS_CORR_BROKEN mode returned somehow similar output values in different configurations. Joystick device is in that state by default in case of lis3. Position sysfs entry, input event device and raw joystick device have been little bit broken since meaning of the output values has been varied between 12 and 8 bit devices. Applications which relayed on those methods failed if the chip is different than the expected one. This patch converts output values to mean similar thing in different configurations. Both 8 and 12 bit devices reports now same acceleration values. If somebody implements full scale support to the driver, output values will still mean the same. Scaling factor and input device range must be updated in that case. Joystick interface in JS_CORR_BROKEN mode is not touched by this patch. All other interfaces have different scale after this change. For 12 bit device scaling factor is 0.977 which keeps scaled and unscaled values are quite close to each others. For 8 bit device, scaled values are 18 times bigger than unscaled values. Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com> Acked-by: Éric Piel <Eric.Piel@tremplin-utc.net> Cc: Pavel Machek <pavel@ucw.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/hwmon/lis3lv02d.c30
-rw-r--r--drivers/hwmon/lis3lv02d.h4
2 files changed, 31 insertions, 3 deletions
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index ba97ed8516bf..b2f2277cad3c 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -53,6 +53,20 @@
53#define LIS3_PWRON_DELAY_WAI_12B (5000) 53#define LIS3_PWRON_DELAY_WAI_12B (5000)
54#define LIS3_PWRON_DELAY_WAI_8B (3000) 54#define LIS3_PWRON_DELAY_WAI_8B (3000)
55 55
56/*
57 * LIS3LV02D spec says 1024 LSBs corresponds 1 G -> 1LSB is 1000/1024 mG
58 * LIS302D spec says: 18 mG / digit
59 * LIS3_ACCURACY is used to increase accuracy of the intermediate
60 * calculation results.
61 */
62#define LIS3_ACCURACY 1024
63/* Sensitivity values for -2G +2G scale */
64#define LIS3_SENSITIVITY_12B ((LIS3_ACCURACY * 1000) / 1024)
65#define LIS3_SENSITIVITY_8B (18 * LIS3_ACCURACY)
66
67#define LIS3_DEFAULT_FUZZ 3
68#define LIS3_DEFAULT_FLAT 3
69
56struct lis3lv02d lis3_dev = { 70struct lis3lv02d lis3_dev = {
57 .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(lis3_dev.misc_wait), 71 .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(lis3_dev.misc_wait),
58}; 72};
@@ -105,6 +119,7 @@ static inline int lis3lv02d_get_axis(s8 axis, int hw_values[3])
105static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z) 119static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
106{ 120{
107 int position[3]; 121 int position[3];
122 int i;
108 123
109 mutex_lock(&lis3->mutex); 124 mutex_lock(&lis3->mutex);
110 position[0] = lis3->read_data(lis3, OUTX); 125 position[0] = lis3->read_data(lis3, OUTX);
@@ -112,6 +127,9 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
112 position[2] = lis3->read_data(lis3, OUTZ); 127 position[2] = lis3->read_data(lis3, OUTZ);
113 mutex_unlock(&lis3->mutex); 128 mutex_unlock(&lis3->mutex);
114 129
130 for (i = 0; i < 3; i++)
131 position[i] = (position[i] * lis3->scale) / LIS3_ACCURACY;
132
115 *x = lis3lv02d_get_axis(lis3->ac.x, position); 133 *x = lis3lv02d_get_axis(lis3->ac.x, position);
116 *y = lis3lv02d_get_axis(lis3->ac.y, position); 134 *y = lis3lv02d_get_axis(lis3->ac.y, position);
117 *z = lis3lv02d_get_axis(lis3->ac.z, position); 135 *z = lis3lv02d_get_axis(lis3->ac.z, position);
@@ -377,6 +395,7 @@ int lis3lv02d_joystick_enable(void)
377{ 395{
378 struct input_dev *input_dev; 396 struct input_dev *input_dev;
379 int err; 397 int err;
398 int max_val, fuzz, flat;
380 399
381 if (lis3_dev.idev) 400 if (lis3_dev.idev)
382 return -EINVAL; 401 return -EINVAL;
@@ -396,9 +415,12 @@ int lis3lv02d_joystick_enable(void)
396 input_dev->dev.parent = &lis3_dev.pdev->dev; 415 input_dev->dev.parent = &lis3_dev.pdev->dev;
397 416
398 set_bit(EV_ABS, input_dev->evbit); 417 set_bit(EV_ABS, input_dev->evbit);
399 input_set_abs_params(input_dev, ABS_X, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3); 418 max_val = (lis3_dev.mdps_max_val * lis3_dev.scale) / LIS3_ACCURACY;
400 input_set_abs_params(input_dev, ABS_Y, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3); 419 fuzz = (LIS3_DEFAULT_FUZZ * lis3_dev.scale) / LIS3_ACCURACY;
401 input_set_abs_params(input_dev, ABS_Z, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3); 420 flat = (LIS3_DEFAULT_FLAT * lis3_dev.scale) / LIS3_ACCURACY;
421 input_set_abs_params(input_dev, ABS_X, -max_val, max_val, fuzz, flat);
422 input_set_abs_params(input_dev, ABS_Y, -max_val, max_val, fuzz, flat);
423 input_set_abs_params(input_dev, ABS_Z, -max_val, max_val, fuzz, flat);
402 424
403 err = input_register_polled_device(lis3_dev.idev); 425 err = input_register_polled_device(lis3_dev.idev);
404 if (err) { 426 if (err) {
@@ -515,6 +537,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
515 dev->pwron_delay = LIS3_PWRON_DELAY_WAI_12B; 537 dev->pwron_delay = LIS3_PWRON_DELAY_WAI_12B;
516 dev->odrs = lis3_12_rates; 538 dev->odrs = lis3_12_rates;
517 dev->odr_mask = CTRL1_DF0 | CTRL1_DF1; 539 dev->odr_mask = CTRL1_DF0 | CTRL1_DF1;
540 dev->scale = LIS3_SENSITIVITY_12B;
518 break; 541 break;
519 case WAI_8B: 542 case WAI_8B:
520 printk(KERN_INFO DRIVER_NAME ": 8 bits sensor found\n"); 543 printk(KERN_INFO DRIVER_NAME ": 8 bits sensor found\n");
@@ -523,6 +546,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
523 dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; 546 dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B;
524 dev->odrs = lis3_8_rates; 547 dev->odrs = lis3_8_rates;
525 dev->odr_mask = CTRL1_DR; 548 dev->odr_mask = CTRL1_DR;
549 dev->scale = LIS3_SENSITIVITY_8B;
526 break; 550 break;
527 default: 551 default:
528 printk(KERN_ERR DRIVER_NAME 552 printk(KERN_ERR DRIVER_NAME
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index f73c78603732..e6a01f44709b 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -214,6 +214,10 @@ struct lis3lv02d {
214 s16 (*read_data) (struct lis3lv02d *lis3, int reg); 214 s16 (*read_data) (struct lis3lv02d *lis3, int reg);
215 int mdps_max_val; 215 int mdps_max_val;
216 int pwron_delay; 216 int pwron_delay;
217 int scale; /*
218 * relationship between 1 LBS and mG
219 * (1/1000th of earth gravity)
220 */
217 221
218 struct input_polled_dev *idev; /* input device */ 222 struct input_polled_dev *idev; /* input device */
219 struct platform_device *pdev; /* platform device */ 223 struct platform_device *pdev; /* platform device */