Commit 32496c76b777752ba84b125bebfb0cc498f5602c

Authored by Samu Onkalo
Committed by Linus Torvalds
1 parent a253aaef60

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>

Showing 2 changed files with 31 additions and 3 deletions Side-by-side Diff

drivers/hwmon/lis3lv02d.c
... ... @@ -53,6 +53,20 @@
53 53 #define LIS3_PWRON_DELAY_WAI_12B (5000)
54 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 +
56 70 struct lis3lv02d lis3_dev = {
57 71 .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(lis3_dev.misc_wait),
58 72 };
... ... @@ -105,6 +119,7 @@
105 119 static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
106 120 {
107 121 int position[3];
  122 + int i;
108 123  
109 124 mutex_lock(&lis3->mutex);
110 125 position[0] = lis3->read_data(lis3, OUTX);
... ... @@ -112,6 +127,9 @@
112 127 position[2] = lis3->read_data(lis3, OUTZ);
113 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 133 *x = lis3lv02d_get_axis(lis3->ac.x, position);
116 134 *y = lis3lv02d_get_axis(lis3->ac.y, position);
117 135 *z = lis3lv02d_get_axis(lis3->ac.z, position);
... ... @@ -377,6 +395,7 @@
377 395 {
378 396 struct input_dev *input_dev;
379 397 int err;
  398 + int max_val, fuzz, flat;
380 399  
381 400 if (lis3_dev.idev)
382 401 return -EINVAL;
... ... @@ -396,9 +415,12 @@
396 415 input_dev->dev.parent = &lis3_dev.pdev->dev;
397 416  
398 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);
400   - input_set_abs_params(input_dev, ABS_Y, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3);
401   - input_set_abs_params(input_dev, ABS_Z, -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;
  419 + fuzz = (LIS3_DEFAULT_FUZZ * lis3_dev.scale) / LIS3_ACCURACY;
  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 425 err = input_register_polled_device(lis3_dev.idev);
404 426 if (err) {
... ... @@ -515,6 +537,7 @@
515 537 dev->pwron_delay = LIS3_PWRON_DELAY_WAI_12B;
516 538 dev->odrs = lis3_12_rates;
517 539 dev->odr_mask = CTRL1_DF0 | CTRL1_DF1;
  540 + dev->scale = LIS3_SENSITIVITY_12B;
518 541 break;
519 542 case WAI_8B:
520 543 printk(KERN_INFO DRIVER_NAME ": 8 bits sensor found\n");
... ... @@ -523,6 +546,7 @@
523 546 dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B;
524 547 dev->odrs = lis3_8_rates;
525 548 dev->odr_mask = CTRL1_DR;
  549 + dev->scale = LIS3_SENSITIVITY_8B;
526 550 break;
527 551 default:
528 552 printk(KERN_ERR DRIVER_NAME
drivers/hwmon/lis3lv02d.h
... ... @@ -214,6 +214,10 @@
214 214 s16 (*read_data) (struct lis3lv02d *lis3, int reg);
215 215 int mdps_max_val;
216 216 int pwron_delay;
  217 + int scale; /*
  218 + * relationship between 1 LBS and mG
  219 + * (1/1000th of earth gravity)
  220 + */
217 221  
218 222 struct input_polled_dev *idev; /* input device */
219 223 struct platform_device *pdev; /* platform device */