diff options
author | Giuseppe Bilotta <giuseppe.bilotta@gmail.com> | 2009-02-18 17:48:24 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-02-18 18:37:54 -0500 |
commit | 137bad32342a613586347341d1307c2b9812ef44 (patch) | |
tree | 3ed900e263388a72f92930a8d91a9d2eb7f0a39b /drivers/hwmon/hp_accel.c | |
parent | ef2cfc790bf5f0ff189b01eabc0f4feb5e8524df (diff) |
lis3lv02d: support both one- and two-byte sensors
Sensors responding with 0x3B to WHO_AM_I only have one data register per
direction, thus returning a signed byte from the position which is
occupied by the MSB in sensors responding with 0x3A.
Since multiple sensors share the reply to WHO_AM_I, we rename the defines
to better indicate what they identify (family of single and double
precision sensors).
We support both kind of sensors by checking for the sensor type on init
and defining appropriate data-access routines and sensor limits (for the
joystick) depending on what we find.
[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
Acked-by: Eric Piel <Eric.Piel@tremplin-utc.net>
Cc: Pavel Machek <pavel@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/hwmon/hp_accel.c')
-rw-r--r-- | drivers/hwmon/hp_accel.c | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c index dcefe1d2adbd..6b16566c4e6c 100644 --- a/drivers/hwmon/hp_accel.c +++ b/drivers/hwmon/hp_accel.c | |||
@@ -237,9 +237,25 @@ static void lis3lv02d_enum_resources(struct acpi_device *device) | |||
237 | printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n"); | 237 | printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n"); |
238 | } | 238 | } |
239 | 239 | ||
240 | static s16 lis3lv02d_read_16(acpi_handle handle, int reg) | ||
241 | { | ||
242 | u8 lo, hi; | ||
243 | |||
244 | adev.read(handle, reg - 1, &lo); | ||
245 | adev.read(handle, reg, &hi); | ||
246 | /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */ | ||
247 | return (s16)((hi << 8) | lo); | ||
248 | } | ||
249 | |||
250 | static s16 lis3lv02d_read_8(acpi_handle handle, int reg) | ||
251 | { | ||
252 | s8 lo; | ||
253 | adev.read(handle, reg, &lo); | ||
254 | return lo; | ||
255 | } | ||
256 | |||
240 | static int lis3lv02d_add(struct acpi_device *device) | 257 | static int lis3lv02d_add(struct acpi_device *device) |
241 | { | 258 | { |
242 | u8 val; | ||
243 | int ret; | 259 | int ret; |
244 | 260 | ||
245 | if (!device) | 261 | if (!device) |
@@ -253,10 +269,22 @@ static int lis3lv02d_add(struct acpi_device *device) | |||
253 | strcpy(acpi_device_class(device), ACPI_MDPS_CLASS); | 269 | strcpy(acpi_device_class(device), ACPI_MDPS_CLASS); |
254 | device->driver_data = &adev; | 270 | device->driver_data = &adev; |
255 | 271 | ||
256 | lis3lv02d_acpi_read(device->handle, WHO_AM_I, &val); | 272 | lis3lv02d_acpi_read(device->handle, WHO_AM_I, &adev.whoami); |
257 | if ((val != LIS3LV02DL_ID) && (val != LIS302DL_ID)) { | 273 | switch (adev.whoami) { |
274 | case LIS_DOUBLE_ID: | ||
275 | printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n"); | ||
276 | adev.read_data = lis3lv02d_read_16; | ||
277 | adev.mdps_max_val = 2048; | ||
278 | break; | ||
279 | case LIS_SINGLE_ID: | ||
280 | printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n"); | ||
281 | adev.read_data = lis3lv02d_read_8; | ||
282 | adev.mdps_max_val = 128; | ||
283 | break; | ||
284 | default: | ||
258 | printk(KERN_ERR DRIVER_NAME | 285 | printk(KERN_ERR DRIVER_NAME |
259 | ": Accelerometer chip not LIS3LV02D{L,Q}\n"); | 286 | ": unknown sensor type 0x%X\n", adev.whoami); |
287 | return -EINVAL; | ||
260 | } | 288 | } |
261 | 289 | ||
262 | /* If possible use a "standard" axes order */ | 290 | /* If possible use a "standard" axes order */ |