diff options
author | Seth Forshee <seth.forshee@canonical.com> | 2012-04-19 12:23:50 -0400 |
---|---|---|
committer | Matthew Garrett <mjg@redhat.com> | 2012-05-31 14:26:04 -0400 |
commit | 62cce7526629e164513d3c67a06845953910f818 (patch) | |
tree | aedddfe36ac78f94466192a02e47502d65c974b6 /drivers/platform/x86/toshiba_acpi.c | |
parent | 20a769c1c6671d3b8d18a7358eff15e3dd29e94b (diff) |
toshiba_acpi: Only register backlight device when interface is read/write
Currently the backlight device is registered unconditionally, but many
(probably most) Toshibas either don't support HCI_LCD_BRIGHTNESS or only
support reading from it. This patch adds a test of HCI_LCD_BRIGHTNESS
during initialization and only registers the backlight device if this
interface supports both reads and writes.
Cc: Akio Idehara <zbe64533@gmail.com>
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Diffstat (limited to 'drivers/platform/x86/toshiba_acpi.c')
-rw-r--r-- | drivers/platform/x86/toshiba_acpi.c | 80 |
1 files changed, 56 insertions, 24 deletions
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 57787d87d9a4..1bb128bbcfc9 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
@@ -480,9 +480,8 @@ static const struct rfkill_ops toshiba_rfk_ops = { | |||
480 | 480 | ||
481 | static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ; | 481 | static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ; |
482 | 482 | ||
483 | static int get_lcd(struct backlight_device *bd) | 483 | static int __get_lcd_brightness(struct toshiba_acpi_dev *dev) |
484 | { | 484 | { |
485 | struct toshiba_acpi_dev *dev = bl_get_data(bd); | ||
486 | u32 hci_result; | 485 | u32 hci_result; |
487 | u32 value; | 486 | u32 value; |
488 | 487 | ||
@@ -493,6 +492,12 @@ static int get_lcd(struct backlight_device *bd) | |||
493 | return -EIO; | 492 | return -EIO; |
494 | } | 493 | } |
495 | 494 | ||
495 | static int get_lcd_brightness(struct backlight_device *bd) | ||
496 | { | ||
497 | struct toshiba_acpi_dev *dev = bl_get_data(bd); | ||
498 | return __get_lcd_brightness(dev); | ||
499 | } | ||
500 | |||
496 | static int lcd_proc_show(struct seq_file *m, void *v) | 501 | static int lcd_proc_show(struct seq_file *m, void *v) |
497 | { | 502 | { |
498 | struct toshiba_acpi_dev *dev = m->private; | 503 | struct toshiba_acpi_dev *dev = m->private; |
@@ -501,7 +506,7 @@ static int lcd_proc_show(struct seq_file *m, void *v) | |||
501 | if (!dev->backlight_dev) | 506 | if (!dev->backlight_dev) |
502 | return -ENODEV; | 507 | return -ENODEV; |
503 | 508 | ||
504 | value = get_lcd(dev->backlight_dev); | 509 | value = get_lcd_brightness(dev->backlight_dev); |
505 | if (value >= 0) { | 510 | if (value >= 0) { |
506 | seq_printf(m, "brightness: %d\n", value); | 511 | seq_printf(m, "brightness: %d\n", value); |
507 | seq_printf(m, "brightness_levels: %d\n", | 512 | seq_printf(m, "brightness_levels: %d\n", |
@@ -518,7 +523,7 @@ static int lcd_proc_open(struct inode *inode, struct file *file) | |||
518 | return single_open(file, lcd_proc_show, PDE(inode)->data); | 523 | return single_open(file, lcd_proc_show, PDE(inode)->data); |
519 | } | 524 | } |
520 | 525 | ||
521 | static int set_lcd(struct toshiba_acpi_dev *dev, int value) | 526 | static int set_lcd_brightness(struct toshiba_acpi_dev *dev, int value) |
522 | { | 527 | { |
523 | u32 hci_result; | 528 | u32 hci_result; |
524 | 529 | ||
@@ -530,7 +535,7 @@ static int set_lcd(struct toshiba_acpi_dev *dev, int value) | |||
530 | static int set_lcd_status(struct backlight_device *bd) | 535 | static int set_lcd_status(struct backlight_device *bd) |
531 | { | 536 | { |
532 | struct toshiba_acpi_dev *dev = bl_get_data(bd); | 537 | struct toshiba_acpi_dev *dev = bl_get_data(bd); |
533 | return set_lcd(dev, bd->props.brightness); | 538 | return set_lcd_brightness(dev, bd->props.brightness); |
534 | } | 539 | } |
535 | 540 | ||
536 | static ssize_t lcd_proc_write(struct file *file, const char __user *buf, | 541 | static ssize_t lcd_proc_write(struct file *file, const char __user *buf, |
@@ -549,7 +554,7 @@ static ssize_t lcd_proc_write(struct file *file, const char __user *buf, | |||
549 | 554 | ||
550 | if (sscanf(cmd, " brightness : %i", &value) == 1 && | 555 | if (sscanf(cmd, " brightness : %i", &value) == 1 && |
551 | value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) { | 556 | value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) { |
552 | ret = set_lcd(dev, value); | 557 | ret = set_lcd_brightness(dev, value); |
553 | if (ret == 0) | 558 | if (ret == 0) |
554 | ret = count; | 559 | ret = count; |
555 | } else { | 560 | } else { |
@@ -860,8 +865,8 @@ static void remove_toshiba_proc_entries(struct toshiba_acpi_dev *dev) | |||
860 | } | 865 | } |
861 | 866 | ||
862 | static const struct backlight_ops toshiba_backlight_data = { | 867 | static const struct backlight_ops toshiba_backlight_data = { |
863 | .get_brightness = get_lcd, | 868 | .get_brightness = get_lcd_brightness, |
864 | .update_status = set_lcd_status, | 869 | .update_status = set_lcd_status, |
865 | }; | 870 | }; |
866 | 871 | ||
867 | static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str, | 872 | static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str, |
@@ -1020,6 +1025,47 @@ static int __devinit toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) | |||
1020 | return error; | 1025 | return error; |
1021 | } | 1026 | } |
1022 | 1027 | ||
1028 | static int __devinit toshiba_acpi_setup_backlight(struct toshiba_acpi_dev *dev) | ||
1029 | { | ||
1030 | struct backlight_properties props; | ||
1031 | int brightness; | ||
1032 | int ret; | ||
1033 | |||
1034 | /* | ||
1035 | * Some machines don't support the backlight methods at all, and | ||
1036 | * others support it read-only. Either of these is pretty useless, | ||
1037 | * so only register the backlight device if the backlight method | ||
1038 | * supports both reads and writes. | ||
1039 | */ | ||
1040 | brightness = __get_lcd_brightness(dev); | ||
1041 | if (brightness < 0) | ||
1042 | return 0; | ||
1043 | ret = set_lcd_brightness(dev, brightness); | ||
1044 | if (ret) { | ||
1045 | pr_debug("Backlight method is read-only, disabling backlight support\n"); | ||
1046 | return 0; | ||
1047 | } | ||
1048 | |||
1049 | props.type = BACKLIGHT_PLATFORM; | ||
1050 | props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; | ||
1051 | memset(&props, 0, sizeof(props)); | ||
1052 | |||
1053 | dev->backlight_dev = backlight_device_register("toshiba", | ||
1054 | &dev->acpi_dev->dev, | ||
1055 | dev, | ||
1056 | &toshiba_backlight_data, | ||
1057 | &props); | ||
1058 | if (IS_ERR(dev->backlight_dev)) { | ||
1059 | ret = PTR_ERR(dev->backlight_dev); | ||
1060 | pr_err("Could not register toshiba backlight device\n"); | ||
1061 | dev->backlight_dev = NULL; | ||
1062 | return ret; | ||
1063 | } | ||
1064 | |||
1065 | dev->backlight_dev->props.brightness = brightness; | ||
1066 | return 0; | ||
1067 | } | ||
1068 | |||
1023 | static int toshiba_acpi_remove(struct acpi_device *acpi_dev, int type) | 1069 | static int toshiba_acpi_remove(struct acpi_device *acpi_dev, int type) |
1024 | { | 1070 | { |
1025 | struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); | 1071 | struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); |
@@ -1078,7 +1124,6 @@ static int __devinit toshiba_acpi_add(struct acpi_device *acpi_dev) | |||
1078 | u32 dummy; | 1124 | u32 dummy; |
1079 | bool bt_present; | 1125 | bool bt_present; |
1080 | int ret = 0; | 1126 | int ret = 0; |
1081 | struct backlight_properties props; | ||
1082 | 1127 | ||
1083 | if (toshiba_acpi) | 1128 | if (toshiba_acpi) |
1084 | return -EBUSY; | 1129 | return -EBUSY; |
@@ -1104,22 +1149,9 @@ static int __devinit toshiba_acpi_add(struct acpi_device *acpi_dev) | |||
1104 | 1149 | ||
1105 | mutex_init(&dev->mutex); | 1150 | mutex_init(&dev->mutex); |
1106 | 1151 | ||
1107 | memset(&props, 0, sizeof(props)); | 1152 | ret = toshiba_acpi_setup_backlight(dev); |
1108 | props.type = BACKLIGHT_PLATFORM; | 1153 | if (ret) |
1109 | props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; | ||
1110 | dev->backlight_dev = backlight_device_register("toshiba", | ||
1111 | &acpi_dev->dev, | ||
1112 | dev, | ||
1113 | &toshiba_backlight_data, | ||
1114 | &props); | ||
1115 | if (IS_ERR(dev->backlight_dev)) { | ||
1116 | ret = PTR_ERR(dev->backlight_dev); | ||
1117 | |||
1118 | pr_err("Could not register toshiba backlight device\n"); | ||
1119 | dev->backlight_dev = NULL; | ||
1120 | goto error; | 1154 | goto error; |
1121 | } | ||
1122 | dev->backlight_dev->props.brightness = get_lcd(dev->backlight_dev); | ||
1123 | 1155 | ||
1124 | /* Register rfkill switch for Bluetooth */ | 1156 | /* Register rfkill switch for Bluetooth */ |
1125 | if (hci_get_bt_present(dev, &bt_present) == HCI_SUCCESS && bt_present) { | 1157 | if (hci_get_bt_present(dev, &bt_present) == HCI_SUCCESS && bt_present) { |