#define EEEPC_WMI_DEVID_BLUETOOTH 0x00010013
#define EEEPC_WMI_DEVID_WIMAX 0x00010017
#define EEEPC_WMI_DEVID_WWAN3G 0x00010019
-#define EEEPC_WMI_DEVID_BACKLIGHT 0x00050012
+#define EEEPC_WMI_DEVID_BACKLIGHT 0x00050011
+#define EEEPC_WMI_DEVID_BRIGHTNESS 0x00050012
#define EEEPC_WMI_DEVID_CAMERA 0x00060013
#define EEEPC_WMI_DEVID_CARDREADER 0x00080013
#define EEEPC_WMI_DEVID_TPDLED 0x00100011
#define EEEPC_WMI_DSTS_STATUS_BIT 0x00000001
#define EEEPC_WMI_DSTS_PRESENCE_BIT 0x00010000
+#define EEEPC_WMI_DSTS_BRIGHTNESS_MASK 0x000000FF
+#define EEEPC_WMI_DSTS_MAX_BRIGTH_MASK 0x0000FF00
static bool hotplug_wireless;
}
/* Helper for special devices with magic return codes */
-static int eeepc_wmi_get_devstate_simple(u32 dev_id)
+static int eeepc_wmi_get_devstate_bits(u32 dev_id, u32 mask)
{
u32 retval = 0;
acpi_status status;
if (!(retval & EEEPC_WMI_DSTS_PRESENCE_BIT))
return -ENODEV;
- return retval & EEEPC_WMI_DSTS_STATUS_BIT;
+ return retval & mask;
+}
+
+static int eeepc_wmi_get_devstate_simple(u32 dev_id)
+{
+ return eeepc_wmi_get_devstate_bits(dev_id, EEEPC_WMI_DSTS_STATUS_BIT);
}
/*
/*
* Backlight
*/
+static int read_backlight_power(void)
+{
+ int ret = eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_BACKLIGHT);
+
+ if (ret < 0)
+ return ret;
+
+ return ret ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
+}
+
static int read_brightness(struct backlight_device *bd)
{
u32 retval;
acpi_status status;
- status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BACKLIGHT, &retval);
+ status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BRIGHTNESS, &retval);
if (ACPI_FAILURE(status))
- return -1;
+ return -EIO;
else
- return retval & 0xFF;
+ return retval & EEEPC_WMI_DSTS_BRIGHTNESS_MASK;
}
static int update_bl_status(struct backlight_device *bd)
{
-
u32 ctrl_param;
acpi_status status;
+ int power;
ctrl_param = bd->props.brightness;
- status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT,
+ status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BRIGHTNESS,
ctrl_param, NULL);
if (ACPI_FAILURE(status))
- return -1;
- else
- return 0;
+ return -EIO;
+
+ power = read_backlight_power();
+ if (power != -ENODEV && bd->props.power != power) {
+ ctrl_param = !!(bd->props.power == FB_BLANK_UNBLANK);
+ status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT,
+ ctrl_param, NULL);
+
+ if (ACPI_FAILURE(status))
+ return -EIO;
+ }
+ return 0;
}
static const struct backlight_ops eeepc_wmi_bl_ops = {
{
struct backlight_device *bd;
struct backlight_properties props;
+ int max;
+ int power;
+
+ max = eeepc_wmi_get_devstate_bits(EEEPC_WMI_DEVID_BRIGHTNESS,
+ EEEPC_WMI_DSTS_MAX_BRIGTH_MASK);
+ power = read_backlight_power();
+
+ if (max < 0 && power < 0) {
+ /* Try to keep the original error */
+ if (max == -ENODEV && power == -ENODEV)
+ return -ENODEV;
+ if (max != -ENODEV)
+ return max;
+ else
+ return power;
+ }
+ if (max == -ENODEV)
+ max = 0;
+ if (power == -ENODEV)
+ power = FB_BLANK_UNBLANK;
memset(&props, 0, sizeof(struct backlight_properties));
- props.max_brightness = 15;
+ props.max_brightness = max;
bd = backlight_device_register(EEEPC_WMI_FILE,
&eeepc->platform_device->dev, eeepc,
&eeepc_wmi_bl_ops, &props);
eeepc->backlight_device = bd;
bd->props.brightness = read_brightness(bd);
- bd->props.power = FB_BLANK_UNBLANK;
+ bd->props.power = power;
backlight_update_status(bd);
return 0;
if (!acpi_video_backlight_support()) {
err = eeepc_wmi_backlight_init(eeepc);
- if (err)
+ if (err && err != -ENODEV)
goto fail_backlight;
} else
pr_info("Backlight controlled by ACPI video driver\n");