aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamu Onkalo <samu.p.onkalo@nokia.com>2009-12-14 21:01:44 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-15 11:53:36 -0500
commita253aaef60a37bddfa84846353edeb62a6acf5b3 (patch)
tree758d470210df046bbc2ba3a7980fb366953f78ec
parent539954120b84c44521df6d1997e340a04418db6d (diff)
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>
-rw-r--r--drivers/hwmon/lis3lv02d.c51
-rw-r--r--drivers/hwmon/lis3lv02d.h2
2 files changed, 46 insertions, 7 deletions
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index 02ac5fa5a05c..ba97ed8516bf 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -121,18 +121,35 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
121static int lis3_12_rates[4] = {40, 160, 640, 2560}; 121static int lis3_12_rates[4] = {40, 160, 640, 2560};
122static int lis3_8_rates[2] = {100, 400}; 122static int lis3_8_rates[2] = {100, 400};
123 123
124/* ODR is Output Data Rate */
124static int lis3lv02d_get_odr(void) 125static int lis3lv02d_get_odr(void)
125{ 126{
126 u8 ctrl; 127 u8 ctrl;
127 int val; 128 int shift;
128 129
129 lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl); 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) 136static int lis3lv02d_set_odr(int rate)
132 val = lis3_12_rates[(ctrl & (CTRL1_DF0 | CTRL1_DF1)) >> 4]; 137{
133 else 138 u8 ctrl;
134 val = lis3_8_rates[(ctrl & CTRL1_DR) >> 7]; 139 int i, len, shift;
135 return val; 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
138static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) 155static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
@@ -433,9 +450,25 @@ static ssize_t lis3lv02d_rate_show(struct device *dev,
433 return sprintf(buf, "%d\n", lis3lv02d_get_odr()); 450 return sprintf(buf, "%d\n", lis3lv02d_get_odr());
434} 451}
435 452
453static 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
436static DEVICE_ATTR(selftest, S_IRUSR, lis3lv02d_selftest_show, NULL); 468static DEVICE_ATTR(selftest, S_IRUSR, lis3lv02d_selftest_show, NULL);
437static DEVICE_ATTR(position, S_IRUGO, lis3lv02d_position_show, NULL); 469static DEVICE_ATTR(position, S_IRUGO, lis3lv02d_position_show, NULL);
438static DEVICE_ATTR(rate, S_IRUGO, lis3lv02d_rate_show, NULL); 470static DEVICE_ATTR(rate, S_IRUGO | S_IWUSR, lis3lv02d_rate_show,
471 lis3lv02d_rate_set);
439 472
440static struct attribute *lis3lv02d_attributes[] = { 473static struct attribute *lis3lv02d_attributes[] = {
441 &dev_attr_selftest.attr, 474 &dev_attr_selftest.attr,
@@ -480,12 +513,16 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
480 dev->read_data = lis3lv02d_read_12; 513 dev->read_data = lis3lv02d_read_12;
481 dev->mdps_max_val = 2048; 514 dev->mdps_max_val = 2048;
482 dev->pwron_delay = LIS3_PWRON_DELAY_WAI_12B; 515 dev->pwron_delay = LIS3_PWRON_DELAY_WAI_12B;
516 dev->odrs = lis3_12_rates;
517 dev->odr_mask = CTRL1_DF0 | CTRL1_DF1;
483 break; 518 break;
484 case WAI_8B: 519 case WAI_8B:
485 printk(KERN_INFO DRIVER_NAME ": 8 bits sensor found\n"); 520 printk(KERN_INFO DRIVER_NAME ": 8 bits sensor found\n");
486 dev->read_data = lis3lv02d_read_8; 521 dev->read_data = lis3lv02d_read_8;
487 dev->mdps_max_val = 128; 522 dev->mdps_max_val = 128;
488 dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; 523 dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B;
524 dev->odrs = lis3_8_rates;
525 dev->odr_mask = CTRL1_DR;
489 break; 526 break;
490 default: 527 default:
491 printk(KERN_ERR DRIVER_NAME 528 printk(KERN_ERR DRIVER_NAME
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 1e9fb03dcd59..f73c78603732 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -208,6 +208,8 @@ struct lis3lv02d {
208 int (*write) (struct lis3lv02d *lis3, int reg, u8 val); 208 int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
209 int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret); 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 u8 whoami; /* indicates measurement precision */ 213 u8 whoami; /* indicates measurement precision */
212 s16 (*read_data) (struct lis3lv02d *lis3, int reg); 214 s16 (*read_data) (struct lis3lv02d *lis3, int reg);
213 int mdps_max_val; 215 int mdps_max_val;