#define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen"
 
+enum {
+       TP_EC_BACKLIGHT = 0x31,
+
+       /* TP_EC_BACKLIGHT bitmasks */
+       TP_EC_BACKLIGHT_LVLMSK = 0x1F,
+       TP_EC_BACKLIGHT_CMDMSK = 0xE0,
+       TP_EC_BACKLIGHT_MAPSW = 0x20,
+};
+
 static struct backlight_device *ibm_backlight_device;
-static int brightness_offset = 0x31;
 static int brightness_mode;
 static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */
 
 /*
  * ThinkPads can read brightness from two places: EC 0x31, or
  * CMOS NVRAM byte 0x5E, bits 0-3.
+ *
+ * EC 0x31 has the following layout
+ *   Bit 7: unknown function
+ *   Bit 6: unknown function
+ *   Bit 5: Z: honour scale changes, NZ: ignore scale changes
+ *   Bit 4: must be set to zero to avoid problems
+ *   Bit 3-0: backlight brightness level
+ *
+ * brightness_get_raw returns status data in the EC 0x31 layout
  */
-static int brightness_get(struct backlight_device *bd)
+static int brightness_get_raw(int *status)
 {
        u8 lec = 0, lcmos = 0, level = 0;
 
        if (brightness_mode & 1) {
-               if (!acpi_ec_read(brightness_offset, &lec))
+               if (!acpi_ec_read(TP_EC_BACKLIGHT, &lec))
                        return -EIO;
-               lec &= (tp_features.bright_16levels)? 0x0f : 0x07;
-               level = lec;
+               level = lec & TP_EC_BACKLIGHT_LVLMSK;
        };
        if (brightness_mode & 2) {
                lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
        }
 
        if (brightness_mode == 3) {
+               *status = lec;  /* Prefer EC, CMOS is just a backing store */
+               lec &= TP_EC_BACKLIGHT_LVLMSK;
                if (lec == lcmos)
                        tp_warned.bright_cmos_ec_unsync = 0;
                else {
                        }
                        return -EIO;
                }
+       } else {
+               *status = level;
        }
 
-       return level;
+       return 0;
 }
 
 /* May return EINTR which can always be mapped to ERESTARTSYS */
 {
        int cmos_cmd, inc, i, res;
        int current_value;
+       int command_bits;
 
-       if (value > ((tp_features.bright_16levels)? 15 : 7))
+       if (value > ((tp_features.bright_16levels)? 15 : 7) ||
+           value < 0)
                return -EINVAL;
 
        res = mutex_lock_interruptible(&brightness_mutex);
        if (res < 0)
                return res;
 
-       current_value = brightness_get(NULL);
-       if (current_value < 0) {
-               res = current_value;
+       res = brightness_get_raw(¤t_value);
+       if (res < 0)
                goto errout;
-       }
+
+       command_bits = current_value & TP_EC_BACKLIGHT_CMDMSK;
+       current_value &= TP_EC_BACKLIGHT_LVLMSK;
 
        cmos_cmd = value > current_value ?
                        TP_CMOS_BRIGHTNESS_UP :
                        goto errout;
                }
                if ((brightness_mode & 1) &&
-                   !acpi_ec_write(brightness_offset, i + inc)) {
+                   !acpi_ec_write(TP_EC_BACKLIGHT,
+                                  (i + inc) | command_bits)) {
                        res = -EIO;
                        goto errout;;
                }
                                bd->props.brightness : 0);
 }
 
+static int brightness_get(struct backlight_device *bd)
+{
+       int status, res;
+
+       res = brightness_get_raw(&status);
+       if (res < 0)
+               return 0; /* FIXME: teach backlight about error handling */
+
+       return status & TP_EC_BACKLIGHT_LVLMSK;
+}
+
 static struct backlight_ops ibm_backlight_data = {
        .get_brightness = brightness_get,
        .update_status  = brightness_update_status,
        if (brightness_mode > 3)
                return -EINVAL;
 
-       b = brightness_get(NULL);
-       if (b < 0)
+       if (brightness_get_raw(&b) < 0)
                return 1;
 
        if (tp_features.bright_16levels)
 
        ibm_backlight_device->props.max_brightness =
                                (tp_features.bright_16levels)? 15 : 7;
-       ibm_backlight_device->props.brightness = b;
+       ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK;
        backlight_update_status(ibm_backlight_device);
 
        return 0;