aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/toshiba_acpi.c
diff options
context:
space:
mode:
authorSeth Forshee <seth.forshee@canonical.com>2012-04-19 12:23:50 -0400
committerMatthew Garrett <mjg@redhat.com>2012-05-31 14:26:04 -0400
commit62cce7526629e164513d3c67a06845953910f818 (patch)
treeaedddfe36ac78f94466192a02e47502d65c974b6 /drivers/platform/x86/toshiba_acpi.c
parent20a769c1c6671d3b8d18a7358eff15e3dd29e94b (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.c80
1 files changed, 56 insertions, 24 deletions
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index 57787d87d9a..1bb128bbcfc 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
481static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ; 481static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ;
482 482
483static int get_lcd(struct backlight_device *bd) 483static 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
495static 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
496static int lcd_proc_show(struct seq_file *m, void *v) 501static 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
521static int set_lcd(struct toshiba_acpi_dev *dev, int value) 526static 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)
530static int set_lcd_status(struct backlight_device *bd) 535static 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
536static ssize_t lcd_proc_write(struct file *file, const char __user *buf, 541static 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
862static const struct backlight_ops toshiba_backlight_data = { 867static 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
867static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str, 872static 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
1028static 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
1023static int toshiba_acpi_remove(struct acpi_device *acpi_dev, int type) 1069static 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) {