aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorentin Chary <corentincj@iksaif.net>2011-02-06 07:28:39 -0500
committerMatthew Garrett <mjg@redhat.com>2011-03-28 06:05:18 -0400
commitb71872650fe967eb0a38aa0d7dcbe9c60d160032 (patch)
treeefaf18d28433d1cba20352538329c1d9bd8c2306
parent54c799a50f58285f5f6a93d87470cba1847943a3 (diff)
eeepc-wmi: support backlight power (bl_power) attribute
Signed-off-by: Corentin Chary <corentincj@iksaif.net> Signed-off-by: Matthew Garrett <mjg@redhat.com>
-rw-r--r--drivers/platform/x86/eeepc-wmi.c75
1 files changed, 61 insertions, 14 deletions
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 75dd692d31ee..910eb00fb13e 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -73,13 +73,16 @@ MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
73#define EEEPC_WMI_DEVID_BLUETOOTH 0x00010013 73#define EEEPC_WMI_DEVID_BLUETOOTH 0x00010013
74#define EEEPC_WMI_DEVID_WIMAX 0x00010017 74#define EEEPC_WMI_DEVID_WIMAX 0x00010017
75#define EEEPC_WMI_DEVID_WWAN3G 0x00010019 75#define EEEPC_WMI_DEVID_WWAN3G 0x00010019
76#define EEEPC_WMI_DEVID_BACKLIGHT 0x00050012 76#define EEEPC_WMI_DEVID_BACKLIGHT 0x00050011
77#define EEEPC_WMI_DEVID_BRIGHTNESS 0x00050012
77#define EEEPC_WMI_DEVID_CAMERA 0x00060013 78#define EEEPC_WMI_DEVID_CAMERA 0x00060013
78#define EEEPC_WMI_DEVID_CARDREADER 0x00080013 79#define EEEPC_WMI_DEVID_CARDREADER 0x00080013
79#define EEEPC_WMI_DEVID_TPDLED 0x00100011 80#define EEEPC_WMI_DEVID_TPDLED 0x00100011
80 81
81#define EEEPC_WMI_DSTS_STATUS_BIT 0x00000001 82#define EEEPC_WMI_DSTS_STATUS_BIT 0x00000001
82#define EEEPC_WMI_DSTS_PRESENCE_BIT 0x00010000 83#define EEEPC_WMI_DSTS_PRESENCE_BIT 0x00010000
84#define EEEPC_WMI_DSTS_BRIGHTNESS_MASK 0x000000FF
85#define EEEPC_WMI_DSTS_MAX_BRIGTH_MASK 0x0000FF00
83 86
84static bool hotplug_wireless; 87static bool hotplug_wireless;
85 88
@@ -262,7 +265,7 @@ static acpi_status eeepc_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
262} 265}
263 266
264/* Helper for special devices with magic return codes */ 267/* Helper for special devices with magic return codes */
265static int eeepc_wmi_get_devstate_simple(u32 dev_id) 268static int eeepc_wmi_get_devstate_bits(u32 dev_id, u32 mask)
266{ 269{
267 u32 retval = 0; 270 u32 retval = 0;
268 acpi_status status; 271 acpi_status status;
@@ -275,7 +278,12 @@ static int eeepc_wmi_get_devstate_simple(u32 dev_id)
275 if (!(retval & EEEPC_WMI_DSTS_PRESENCE_BIT)) 278 if (!(retval & EEEPC_WMI_DSTS_PRESENCE_BIT))
276 return -ENODEV; 279 return -ENODEV;
277 280
278 return retval & EEEPC_WMI_DSTS_STATUS_BIT; 281 return retval & mask;
282}
283
284static int eeepc_wmi_get_devstate_simple(u32 dev_id)
285{
286 return eeepc_wmi_get_devstate_bits(dev_id, EEEPC_WMI_DSTS_STATUS_BIT);
279} 287}
280 288
281/* 289/*
@@ -770,34 +778,53 @@ exit:
770/* 778/*
771 * Backlight 779 * Backlight
772 */ 780 */
781static int read_backlight_power(void)
782{
783 int ret = eeepc_wmi_get_devstate_simple(EEEPC_WMI_DEVID_BACKLIGHT);
784
785 if (ret < 0)
786 return ret;
787
788 return ret ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
789}
790
773static int read_brightness(struct backlight_device *bd) 791static int read_brightness(struct backlight_device *bd)
774{ 792{
775 u32 retval; 793 u32 retval;
776 acpi_status status; 794 acpi_status status;
777 795
778 status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BACKLIGHT, &retval); 796 status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BRIGHTNESS, &retval);
779 797
780 if (ACPI_FAILURE(status)) 798 if (ACPI_FAILURE(status))
781 return -1; 799 return -EIO;
782 else 800 else
783 return retval & 0xFF; 801 return retval & EEEPC_WMI_DSTS_BRIGHTNESS_MASK;
784} 802}
785 803
786static int update_bl_status(struct backlight_device *bd) 804static int update_bl_status(struct backlight_device *bd)
787{ 805{
788
789 u32 ctrl_param; 806 u32 ctrl_param;
790 acpi_status status; 807 acpi_status status;
808 int power;
791 809
792 ctrl_param = bd->props.brightness; 810 ctrl_param = bd->props.brightness;
793 811
794 status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT, 812 status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BRIGHTNESS,
795 ctrl_param, NULL); 813 ctrl_param, NULL);
796 814
797 if (ACPI_FAILURE(status)) 815 if (ACPI_FAILURE(status))
798 return -1; 816 return -EIO;
799 else 817
800 return 0; 818 power = read_backlight_power();
819 if (power != -ENODEV && bd->props.power != power) {
820 ctrl_param = !!(bd->props.power == FB_BLANK_UNBLANK);
821 status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT,
822 ctrl_param, NULL);
823
824 if (ACPI_FAILURE(status))
825 return -EIO;
826 }
827 return 0;
801} 828}
802 829
803static const struct backlight_ops eeepc_wmi_bl_ops = { 830static const struct backlight_ops eeepc_wmi_bl_ops = {
@@ -827,9 +854,29 @@ static int eeepc_wmi_backlight_init(struct eeepc_wmi *eeepc)
827{ 854{
828 struct backlight_device *bd; 855 struct backlight_device *bd;
829 struct backlight_properties props; 856 struct backlight_properties props;
857 int max;
858 int power;
859
860 max = eeepc_wmi_get_devstate_bits(EEEPC_WMI_DEVID_BRIGHTNESS,
861 EEEPC_WMI_DSTS_MAX_BRIGTH_MASK);
862 power = read_backlight_power();
863
864 if (max < 0 && power < 0) {
865 /* Try to keep the original error */
866 if (max == -ENODEV && power == -ENODEV)
867 return -ENODEV;
868 if (max != -ENODEV)
869 return max;
870 else
871 return power;
872 }
873 if (max == -ENODEV)
874 max = 0;
875 if (power == -ENODEV)
876 power = FB_BLANK_UNBLANK;
830 877
831 memset(&props, 0, sizeof(struct backlight_properties)); 878 memset(&props, 0, sizeof(struct backlight_properties));
832 props.max_brightness = 15; 879 props.max_brightness = max;
833 bd = backlight_device_register(EEEPC_WMI_FILE, 880 bd = backlight_device_register(EEEPC_WMI_FILE,
834 &eeepc->platform_device->dev, eeepc, 881 &eeepc->platform_device->dev, eeepc,
835 &eeepc_wmi_bl_ops, &props); 882 &eeepc_wmi_bl_ops, &props);
@@ -841,7 +888,7 @@ static int eeepc_wmi_backlight_init(struct eeepc_wmi *eeepc)
841 eeepc->backlight_device = bd; 888 eeepc->backlight_device = bd;
842 889
843 bd->props.brightness = read_brightness(bd); 890 bd->props.brightness = read_brightness(bd);
844 bd->props.power = FB_BLANK_UNBLANK; 891 bd->props.power = power;
845 backlight_update_status(bd); 892 backlight_update_status(bd);
846 893
847 return 0; 894 return 0;
@@ -1202,7 +1249,7 @@ static int __init eeepc_wmi_add(struct platform_device *pdev)
1202 1249
1203 if (!acpi_video_backlight_support()) { 1250 if (!acpi_video_backlight_support()) {
1204 err = eeepc_wmi_backlight_init(eeepc); 1251 err = eeepc_wmi_backlight_init(eeepc);
1205 if (err) 1252 if (err && err != -ENODEV)
1206 goto fail_backlight; 1253 goto fail_backlight;
1207 } else 1254 } else
1208 pr_info("Backlight controlled by ACPI video driver\n"); 1255 pr_info("Backlight controlled by ACPI video driver\n");