diff options
-rw-r--r-- | drivers/hwmon/lis3lv02d.c | 51 | ||||
-rw-r--r-- | drivers/hwmon/lis3lv02d.h | 2 |
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) | |||
121 | static int lis3_12_rates[4] = {40, 160, 640, 2560}; | 121 | static int lis3_12_rates[4] = {40, 160, 640, 2560}; |
122 | static int lis3_8_rates[2] = {100, 400}; | 122 | static int lis3_8_rates[2] = {100, 400}; |
123 | 123 | ||
124 | /* ODR is Output Data Rate */ | ||
124 | static int lis3lv02d_get_odr(void) | 125 | static 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) | 136 | static 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 | ||
138 | static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) | 155 | static 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 | ||
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 | static DEVICE_ATTR(selftest, S_IRUSR, lis3lv02d_selftest_show, NULL); | 468 | static DEVICE_ATTR(selftest, S_IRUSR, lis3lv02d_selftest_show, NULL); |
437 | static DEVICE_ATTR(position, S_IRUGO, lis3lv02d_position_show, NULL); | 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 | static struct attribute *lis3lv02d_attributes[] = { | 473 | static 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; |