aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;