diff options
author | Takashi Iwai <tiwai@suse.de> | 2010-09-23 13:01:39 -0400 |
---|---|---|
committer | Guenter Roeck <guenter.roeck@ericsson.com> | 2010-10-25 17:11:20 -0400 |
commit | 78537c3b6ffcb69bf4fd43a74ba57928fcefce95 (patch) | |
tree | 3e30c553acb84389c075c7f94bdd369c4efc2b41 /drivers/hwmon/lis3lv02d.c | |
parent | 9401ba13281f9cf36c85d4f8d3a52f9655e69b58 (diff) |
hwmon: (lis3) Add support for new LIS3DC / HP3DC chip
A new version of LIS3 chip has slight incompatibilities from former
versions. This patch adds the minimal support for it.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
Diffstat (limited to 'drivers/hwmon/lis3lv02d.c')
-rw-r--r-- | drivers/hwmon/lis3lv02d.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index fc591ae53107..ef7510d83603 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c | |||
@@ -138,6 +138,7 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z) | |||
138 | /* conversion btw sampling rate and the register values */ | 138 | /* conversion btw sampling rate and the register values */ |
139 | static int lis3_12_rates[4] = {40, 160, 640, 2560}; | 139 | static int lis3_12_rates[4] = {40, 160, 640, 2560}; |
140 | static int lis3_8_rates[2] = {100, 400}; | 140 | static int lis3_8_rates[2] = {100, 400}; |
141 | static int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000}; | ||
141 | 142 | ||
142 | /* ODR is Output Data Rate */ | 143 | /* ODR is Output Data Rate */ |
143 | static int lis3lv02d_get_odr(void) | 144 | static int lis3lv02d_get_odr(void) |
@@ -156,6 +157,9 @@ static int lis3lv02d_set_odr(int rate) | |||
156 | u8 ctrl; | 157 | u8 ctrl; |
157 | int i, len, shift; | 158 | int i, len, shift; |
158 | 159 | ||
160 | if (!rate) | ||
161 | return -EINVAL; | ||
162 | |||
159 | lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl); | 163 | lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl); |
160 | ctrl &= ~lis3_dev.odr_mask; | 164 | ctrl &= ~lis3_dev.odr_mask; |
161 | len = 1 << hweight_long(lis3_dev.odr_mask); /* # of possible values */ | 165 | len = 1 << hweight_long(lis3_dev.odr_mask); /* # of possible values */ |
@@ -172,19 +176,25 @@ static int lis3lv02d_set_odr(int rate) | |||
172 | 176 | ||
173 | static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) | 177 | static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) |
174 | { | 178 | { |
175 | u8 reg; | 179 | u8 ctlreg, reg; |
176 | s16 x, y, z; | 180 | s16 x, y, z; |
177 | u8 selftest; | 181 | u8 selftest; |
178 | int ret; | 182 | int ret; |
179 | 183 | ||
180 | mutex_lock(&lis3->mutex); | 184 | mutex_lock(&lis3->mutex); |
181 | if (lis3_dev.whoami == WAI_12B) | 185 | if (lis3_dev.whoami == WAI_3DC) { |
182 | selftest = CTRL1_ST; | 186 | ctlreg = CTRL_REG4; |
183 | else | 187 | selftest = CTRL4_ST0; |
184 | selftest = CTRL1_STP; | 188 | } else { |
189 | ctlreg = CTRL_REG1; | ||
190 | if (lis3_dev.whoami == WAI_12B) | ||
191 | selftest = CTRL1_ST; | ||
192 | else | ||
193 | selftest = CTRL1_STP; | ||
194 | } | ||
185 | 195 | ||
186 | lis3->read(lis3, CTRL_REG1, ®); | 196 | lis3->read(lis3, ctlreg, ®); |
187 | lis3->write(lis3, CTRL_REG1, (reg | selftest)); | 197 | lis3->write(lis3, ctlreg, (reg | selftest)); |
188 | msleep(lis3->pwron_delay / lis3lv02d_get_odr()); | 198 | msleep(lis3->pwron_delay / lis3lv02d_get_odr()); |
189 | 199 | ||
190 | /* Read directly to avoid axis remap */ | 200 | /* Read directly to avoid axis remap */ |
@@ -193,7 +203,7 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) | |||
193 | z = lis3->read_data(lis3, OUTZ); | 203 | z = lis3->read_data(lis3, OUTZ); |
194 | 204 | ||
195 | /* back to normal settings */ | 205 | /* back to normal settings */ |
196 | lis3->write(lis3, CTRL_REG1, reg); | 206 | lis3->write(lis3, ctlreg, reg); |
197 | msleep(lis3->pwron_delay / lis3lv02d_get_odr()); | 207 | msleep(lis3->pwron_delay / lis3lv02d_get_odr()); |
198 | 208 | ||
199 | results[0] = x - lis3->read_data(lis3, OUTX); | 209 | results[0] = x - lis3->read_data(lis3, OUTX); |
@@ -674,6 +684,15 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) | |||
674 | dev->odr_mask = CTRL1_DR; | 684 | dev->odr_mask = CTRL1_DR; |
675 | dev->scale = LIS3_SENSITIVITY_8B; | 685 | dev->scale = LIS3_SENSITIVITY_8B; |
676 | break; | 686 | break; |
687 | case WAI_3DC: | ||
688 | printk(KERN_INFO DRIVER_NAME ": 8 bits 3DC sensor found\n"); | ||
689 | dev->read_data = lis3lv02d_read_8; | ||
690 | dev->mdps_max_val = 128; | ||
691 | dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; | ||
692 | dev->odrs = lis3_3dc_rates; | ||
693 | dev->odr_mask = CTRL1_ODR0|CTRL1_ODR1|CTRL1_ODR2|CTRL1_ODR3; | ||
694 | dev->scale = LIS3_SENSITIVITY_8B; | ||
695 | break; | ||
677 | default: | 696 | default: |
678 | printk(KERN_ERR DRIVER_NAME | 697 | printk(KERN_ERR DRIVER_NAME |
679 | ": unknown sensor type 0x%X\n", dev->whoami); | 698 | ": unknown sensor type 0x%X\n", dev->whoami); |