aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/hp_accel.c36
-rw-r--r--drivers/hwmon/lis3lv02d.c25
-rw-r--r--drivers/hwmon/lis3lv02d.h16
3 files changed, 51 insertions, 26 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
240static 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
250static s16 lis3lv02d_read_8(acpi_handle handle, int reg)
251{
252 s8 lo;
253 adev.read(handle, reg, &lo);
254 return lo;
255}
256
240static int lis3lv02d_add(struct acpi_device *device) 257static 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 */
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index 3afa3afc77f3..8bb2158f0453 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -53,9 +53,6 @@
53 * joystick. 53 * joystick.
54 */ 54 */
55 55
56/* Maximum value our axis may get for the input device (signed 12 bits) */
57#define MDPS_MAX_VAL 2048
58
59struct acpi_lis3lv02d adev = { 56struct acpi_lis3lv02d adev = {
60 .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(adev.misc_wait), 57 .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(adev.misc_wait),
61}; 58};
@@ -64,16 +61,6 @@ EXPORT_SYMBOL_GPL(adev);
64 61
65static int lis3lv02d_add_fs(struct acpi_device *device); 62static int lis3lv02d_add_fs(struct acpi_device *device);
66 63
67static s16 lis3lv02d_read_16(acpi_handle handle, int reg)
68{
69 u8 lo, hi;
70
71 adev.read(handle, reg, &lo);
72 adev.read(handle, reg + 1, &hi);
73 /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
74 return (s16)((hi << 8) | lo);
75}
76
77/** 64/**
78 * lis3lv02d_get_axis - For the given axis, give the value converted 65 * lis3lv02d_get_axis - For the given axis, give the value converted
79 * @axis: 1,2,3 - can also be negative 66 * @axis: 1,2,3 - can also be negative
@@ -102,9 +89,9 @@ static void lis3lv02d_get_xyz(acpi_handle handle, int *x, int *y, int *z)
102{ 89{
103 int position[3]; 90 int position[3];
104 91
105 position[0] = lis3lv02d_read_16(handle, OUTX_L); 92 position[0] = adev.read_data(handle, OUTX);
106 position[1] = lis3lv02d_read_16(handle, OUTY_L); 93 position[1] = adev.read_data(handle, OUTY);
107 position[2] = lis3lv02d_read_16(handle, OUTZ_L); 94 position[2] = adev.read_data(handle, OUTZ);
108 95
109 *x = lis3lv02d_get_axis(adev.ac.x, position); 96 *x = lis3lv02d_get_axis(adev.ac.x, position);
110 *y = lis3lv02d_get_axis(adev.ac.y, position); 97 *y = lis3lv02d_get_axis(adev.ac.y, position);
@@ -355,9 +342,9 @@ int lis3lv02d_joystick_enable(void)
355 adev.idev->close = lis3lv02d_joystick_close; 342 adev.idev->close = lis3lv02d_joystick_close;
356 343
357 set_bit(EV_ABS, adev.idev->evbit); 344 set_bit(EV_ABS, adev.idev->evbit);
358 input_set_abs_params(adev.idev, ABS_X, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3); 345 input_set_abs_params(adev.idev, ABS_X, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
359 input_set_abs_params(adev.idev, ABS_Y, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3); 346 input_set_abs_params(adev.idev, ABS_Y, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
360 input_set_abs_params(adev.idev, ABS_Z, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3); 347 input_set_abs_params(adev.idev, ABS_Z, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
361 348
362 err = input_register_device(adev.idev); 349 err = input_register_device(adev.idev);
363 if (err) { 350 if (err) {
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 2e7597c42d80..75972bf372ff 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -22,12 +22,15 @@
22/* 22/*
23 * The actual chip is STMicroelectronics LIS3LV02DL or LIS3LV02DQ that seems to 23 * The actual chip is STMicroelectronics LIS3LV02DL or LIS3LV02DQ that seems to
24 * be connected via SPI. There exists also several similar chips (such as LIS302DL or 24 * be connected via SPI. There exists also several similar chips (such as LIS302DL or
25 * LIS3L02DQ) but not in the HP laptops and they have slightly different registers. 25 * LIS3L02DQ) and they have slightly different registers, but we can provide a
26 * common interface for all of them.
26 * They can also be connected via I²C. 27 * They can also be connected via I²C.
27 */ 28 */
28 29
29#define LIS3LV02DL_ID 0x3A /* Also the LIS3LV02DQ */ 30/* 2-byte registers */
30#define LIS302DL_ID 0x3B /* Also the LIS202DL! */ 31#define LIS_DOUBLE_ID 0x3A /* LIS3LV02D[LQ] */
32/* 1-byte registers */
33#define LIS_SINGLE_ID 0x3B /* LIS[32]02DL and others */
31 34
32enum lis3lv02d_reg { 35enum lis3lv02d_reg {
33 WHO_AM_I = 0x0F, 36 WHO_AM_I = 0x0F,
@@ -44,10 +47,13 @@ enum lis3lv02d_reg {
44 STATUS_REG = 0x27, 47 STATUS_REG = 0x27,
45 OUTX_L = 0x28, 48 OUTX_L = 0x28,
46 OUTX_H = 0x29, 49 OUTX_H = 0x29,
50 OUTX = 0x29,
47 OUTY_L = 0x2A, 51 OUTY_L = 0x2A,
48 OUTY_H = 0x2B, 52 OUTY_H = 0x2B,
53 OUTY = 0x2B,
49 OUTZ_L = 0x2C, 54 OUTZ_L = 0x2C,
50 OUTZ_H = 0x2D, 55 OUTZ_H = 0x2D,
56 OUTZ = 0x2D,
51 FF_WU_CFG = 0x30, 57 FF_WU_CFG = 0x30,
52 FF_WU_SRC = 0x31, 58 FF_WU_SRC = 0x31,
53 FF_WU_ACK = 0x32, 59 FF_WU_ACK = 0x32,
@@ -159,6 +165,10 @@ struct acpi_lis3lv02d {
159 acpi_status (*write) (acpi_handle handle, int reg, u8 val); 165 acpi_status (*write) (acpi_handle handle, int reg, u8 val);
160 acpi_status (*read) (acpi_handle handle, int reg, u8 *ret); 166 acpi_status (*read) (acpi_handle handle, int reg, u8 *ret);
161 167
168 u8 whoami; /* 3Ah: 2-byte registries, 3Bh: 1-byte registries */
169 s16 (*read_data) (acpi_handle handle, int reg);
170 int mdps_max_val;
171
162 struct input_dev *idev; /* input device */ 172 struct input_dev *idev; /* input device */
163 struct task_struct *kthread; /* kthread for input */ 173 struct task_struct *kthread; /* kthread for input */
164 struct mutex lock; 174 struct mutex lock;