Commit a253aaef60a37bddfa84846353edeb62a6acf5b3

Authored by Samu Onkalo
Committed by Linus Torvalds
1 parent 539954120b

lis3: sysfs entry for setting chip measurement rate

It is possible to read position information at the chip measurement rate
via sysfs.  This patch adds possibility to configure chip measurement
rate.

Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com>
Signed-off-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 46 additions and 7 deletions Side-by-side Diff

drivers/hwmon/lis3lv02d.c
... ... @@ -121,18 +121,35 @@
121 121 static int lis3_12_rates[4] = {40, 160, 640, 2560};
122 122 static int lis3_8_rates[2] = {100, 400};
123 123  
  124 +/* ODR is Output Data Rate */
124 125 static int lis3lv02d_get_odr(void)
125 126 {
126 127 u8 ctrl;
127   - int val;
  128 + int shift;
128 129  
129 130 lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl);
  131 + ctrl &= lis3_dev.odr_mask;
  132 + shift = ffs(lis3_dev.odr_mask) - 1;
  133 + return lis3_dev.odrs[(ctrl >> shift)];
  134 +}
130 135  
131   - if (lis3_dev.whoami == WAI_12B)
132   - val = lis3_12_rates[(ctrl & (CTRL1_DF0 | CTRL1_DF1)) >> 4];
133   - else
134   - val = lis3_8_rates[(ctrl & CTRL1_DR) >> 7];
135   - return val;
  136 +static int lis3lv02d_set_odr(int rate)
  137 +{
  138 + u8 ctrl;
  139 + int i, len, shift;
  140 +
  141 + lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl);
  142 + ctrl &= ~lis3_dev.odr_mask;
  143 + len = 1 << hweight_long(lis3_dev.odr_mask); /* # of possible values */
  144 + shift = ffs(lis3_dev.odr_mask) - 1;
  145 +
  146 + for (i = 0; i < len; i++)
  147 + if (lis3_dev.odrs[i] == rate) {
  148 + lis3_dev.write(&lis3_dev, CTRL_REG1,
  149 + ctrl | (i << shift));
  150 + return 0;
  151 + }
  152 + return -EINVAL;
136 153 }
137 154  
138 155 static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
139 156  
... ... @@ -433,9 +450,25 @@
433 450 return sprintf(buf, "%d\n", lis3lv02d_get_odr());
434 451 }
435 452  
  453 +static ssize_t lis3lv02d_rate_set(struct device *dev,
  454 + struct device_attribute *attr, const char *buf,
  455 + size_t count)
  456 +{
  457 + unsigned long rate;
  458 +
  459 + if (strict_strtoul(buf, 0, &rate))
  460 + return -EINVAL;
  461 +
  462 + if (lis3lv02d_set_odr(rate))
  463 + return -EINVAL;
  464 +
  465 + return count;
  466 +}
  467 +
436 468 static DEVICE_ATTR(selftest, S_IRUSR, lis3lv02d_selftest_show, NULL);
437 469 static DEVICE_ATTR(position, S_IRUGO, lis3lv02d_position_show, NULL);
438   -static DEVICE_ATTR(rate, S_IRUGO, lis3lv02d_rate_show, NULL);
  470 +static DEVICE_ATTR(rate, S_IRUGO | S_IWUSR, lis3lv02d_rate_show,
  471 + lis3lv02d_rate_set);
439 472  
440 473 static struct attribute *lis3lv02d_attributes[] = {
441 474 &dev_attr_selftest.attr,
442 475  
... ... @@ -480,12 +513,16 @@
480 513 dev->read_data = lis3lv02d_read_12;
481 514 dev->mdps_max_val = 2048;
482 515 dev->pwron_delay = LIS3_PWRON_DELAY_WAI_12B;
  516 + dev->odrs = lis3_12_rates;
  517 + dev->odr_mask = CTRL1_DF0 | CTRL1_DF1;
483 518 break;
484 519 case WAI_8B:
485 520 printk(KERN_INFO DRIVER_NAME ": 8 bits sensor found\n");
486 521 dev->read_data = lis3lv02d_read_8;
487 522 dev->mdps_max_val = 128;
488 523 dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B;
  524 + dev->odrs = lis3_8_rates;
  525 + dev->odr_mask = CTRL1_DR;
489 526 break;
490 527 default:
491 528 printk(KERN_ERR DRIVER_NAME
drivers/hwmon/lis3lv02d.h
... ... @@ -208,6 +208,8 @@
208 208 int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
209 209 int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
210 210  
  211 + int *odrs; /* Supported output data rates */
  212 + u8 odr_mask; /* ODR bit mask */
211 213 u8 whoami; /* indicates measurement precision */
212 214 s16 (*read_data) (struct lis3lv02d *lis3, int reg);
213 215 int mdps_max_val;