mirror of
https://github.com/torvalds/linux.git
synced 2024-12-14 15:13:52 +00:00
eeepc-wmi: support backlight power (bl_power) attribute
Signed-off-by: Corentin Chary <corentincj@iksaif.net> Signed-off-by: Matthew Garrett <mjg@redhat.com>
This commit is contained in:
parent
54c799a50f
commit
b71872650f
@ -73,13 +73,16 @@ MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
|
||||
#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;
|
||||
|
||||
@ -262,7 +265,7 @@ static acpi_status eeepc_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
|
||||
}
|
||||
|
||||
/* 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;
|
||||
@ -275,7 +278,12 @@ static int eeepc_wmi_get_devstate_simple(u32 dev_id)
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -770,34 +778,53 @@ exit:
|
||||
/*
|
||||
* 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 = {
|
||||
@ -827,9 +854,29 @@ static int eeepc_wmi_backlight_init(struct eeepc_wmi *eeepc)
|
||||
{
|
||||
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);
|
||||
@ -841,7 +888,7 @@ static int eeepc_wmi_backlight_init(struct eeepc_wmi *eeepc)
|
||||
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;
|
||||
@ -1202,7 +1249,7 @@ static int __init eeepc_wmi_add(struct platform_device *pdev)
|
||||
|
||||
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");
|
||||
|
Loading…
Reference in New Issue
Block a user