printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n");
 }
 
+static s16 lis3lv02d_read_16(acpi_handle handle, int reg)
+{
+       u8 lo, hi;
+
+       adev.read(handle, reg - 1, &lo);
+       adev.read(handle, reg, &hi);
+       /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
+       return (s16)((hi << 8) | lo);
+}
+
+static s16 lis3lv02d_read_8(acpi_handle handle, int reg)
+{
+       s8 lo;
+       adev.read(handle, reg, &lo);
+       return lo;
+}
+
 static int lis3lv02d_add(struct acpi_device *device)
 {
-       u8 val;
        int ret;
 
        if (!device)
        strcpy(acpi_device_class(device), ACPI_MDPS_CLASS);
        device->driver_data = &adev;
 
-       lis3lv02d_acpi_read(device->handle, WHO_AM_I, &val);
-       if ((val != LIS3LV02DL_ID) && (val != LIS302DL_ID)) {
+       lis3lv02d_acpi_read(device->handle, WHO_AM_I, &adev.whoami);
+       switch (adev.whoami) {
+       case LIS_DOUBLE_ID:
+               printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n");
+               adev.read_data = lis3lv02d_read_16;
+               adev.mdps_max_val = 2048;
+               break;
+       case LIS_SINGLE_ID:
+               printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n");
+               adev.read_data = lis3lv02d_read_8;
+               adev.mdps_max_val = 128;
+               break;
+       default:
                printk(KERN_ERR DRIVER_NAME
-                               ": Accelerometer chip not LIS3LV02D{L,Q}\n");
+                       ": unknown sensor type 0x%X\n", adev.whoami);
+               return -EINVAL;
        }
 
        /* If possible use a "standard" axes order */
 
  * joystick.
  */
 
-/* Maximum value our axis may get for the input device (signed 12 bits) */
-#define MDPS_MAX_VAL 2048
-
 struct acpi_lis3lv02d adev = {
        .misc_wait   = __WAIT_QUEUE_HEAD_INITIALIZER(adev.misc_wait),
 };
 
 static int lis3lv02d_add_fs(struct acpi_device *device);
 
-static s16 lis3lv02d_read_16(acpi_handle handle, int reg)
-{
-       u8 lo, hi;
-
-       adev.read(handle, reg, &lo);
-       adev.read(handle, reg + 1, &hi);
-       /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
-       return (s16)((hi << 8) | lo);
-}
-
 /**
  * lis3lv02d_get_axis - For the given axis, give the value converted
  * @axis:      1,2,3 - can also be negative
 {
        int position[3];
 
-       position[0] = lis3lv02d_read_16(handle, OUTX_L);
-       position[1] = lis3lv02d_read_16(handle, OUTY_L);
-       position[2] = lis3lv02d_read_16(handle, OUTZ_L);
+       position[0] = adev.read_data(handle, OUTX);
+       position[1] = adev.read_data(handle, OUTY);
+       position[2] = adev.read_data(handle, OUTZ);
 
        *x = lis3lv02d_get_axis(adev.ac.x, position);
        *y = lis3lv02d_get_axis(adev.ac.y, position);
        adev.idev->close      = lis3lv02d_joystick_close;
 
        set_bit(EV_ABS, adev.idev->evbit);
-       input_set_abs_params(adev.idev, ABS_X, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3);
-       input_set_abs_params(adev.idev, ABS_Y, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3);
-       input_set_abs_params(adev.idev, ABS_Z, -MDPS_MAX_VAL, MDPS_MAX_VAL, 3, 3);
+       input_set_abs_params(adev.idev, ABS_X, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
+       input_set_abs_params(adev.idev, ABS_Y, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
+       input_set_abs_params(adev.idev, ABS_Z, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
 
        err = input_register_device(adev.idev);
        if (err) {
 
 /*
  * The actual chip is STMicroelectronics LIS3LV02DL or LIS3LV02DQ that seems to
  * be connected via SPI. There exists also several similar chips (such as LIS302DL or
- * LIS3L02DQ) but not in the HP laptops and they have slightly different registers.
+ * LIS3L02DQ) and they have slightly different registers, but we can provide a
+ * common interface for all of them.
  * They can also be connected via I²C.
  */
 
-#define LIS3LV02DL_ID  0x3A /* Also the LIS3LV02DQ */
-#define LIS302DL_ID    0x3B /* Also the LIS202DL! */
+/* 2-byte registers */
+#define LIS_DOUBLE_ID  0x3A /* LIS3LV02D[LQ] */
+/* 1-byte registers */
+#define LIS_SINGLE_ID  0x3B /* LIS[32]02DL and others */
 
 enum lis3lv02d_reg {
        WHO_AM_I        = 0x0F,
        STATUS_REG      = 0x27,
        OUTX_L          = 0x28,
        OUTX_H          = 0x29,
+       OUTX            = 0x29,
        OUTY_L          = 0x2A,
        OUTY_H          = 0x2B,
+       OUTY            = 0x2B,
        OUTZ_L          = 0x2C,
        OUTZ_H          = 0x2D,
+       OUTZ            = 0x2D,
        FF_WU_CFG       = 0x30,
        FF_WU_SRC       = 0x31,
        FF_WU_ACK       = 0x32,
        acpi_status (*write) (acpi_handle handle, int reg, u8 val);
        acpi_status (*read) (acpi_handle handle, int reg, u8 *ret);
 
+       u8                      whoami;    /* 3Ah: 2-byte registries, 3Bh: 1-byte registries */
+       s16 (*read_data) (acpi_handle handle, int reg);
+       int                     mdps_max_val;
+
        struct input_dev        *idev;     /* input device */
        struct task_struct      *kthread;  /* kthread for input */
        struct mutex            lock;