diff options
Diffstat (limited to 'drivers/platform')
-rw-r--r-- | drivers/platform/x86/sony-laptop.c | 109 |
1 files changed, 79 insertions, 30 deletions
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 326a4600fad1..d28a4a58a497 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -938,11 +938,39 @@ static int sony_backlight_get_brightness(struct backlight_device *bd) | |||
938 | return value - 1; | 938 | return value - 1; |
939 | } | 939 | } |
940 | 940 | ||
941 | static struct backlight_device *sony_backlight_device; | 941 | static int sony_nc_get_brightness_ng(struct backlight_device *bd) |
942 | { | ||
943 | int result; | ||
944 | int *handle = (int *)bl_get_data(bd); | ||
945 | |||
946 | sony_call_snc_handle(*handle, 0x0200, &result); | ||
947 | |||
948 | return result & 0xff; | ||
949 | } | ||
950 | |||
951 | static int sony_nc_update_status_ng(struct backlight_device *bd) | ||
952 | { | ||
953 | int value, result; | ||
954 | int *handle = (int *)bl_get_data(bd); | ||
955 | |||
956 | value = bd->props.brightness; | ||
957 | sony_call_snc_handle(*handle, 0x0100 | (value << 16), &result); | ||
958 | |||
959 | return sony_nc_get_brightness_ng(bd); | ||
960 | } | ||
961 | |||
942 | static const struct backlight_ops sony_backlight_ops = { | 962 | static const struct backlight_ops sony_backlight_ops = { |
963 | .options = BL_CORE_SUSPENDRESUME, | ||
943 | .update_status = sony_backlight_update_status, | 964 | .update_status = sony_backlight_update_status, |
944 | .get_brightness = sony_backlight_get_brightness, | 965 | .get_brightness = sony_backlight_get_brightness, |
945 | }; | 966 | }; |
967 | static const struct backlight_ops sony_backlight_ng_ops = { | ||
968 | .options = BL_CORE_SUSPENDRESUME, | ||
969 | .update_status = sony_nc_update_status_ng, | ||
970 | .get_brightness = sony_nc_get_brightness_ng, | ||
971 | }; | ||
972 | static int backlight_ng_handle; | ||
973 | static struct backlight_device *sony_backlight_device; | ||
946 | 974 | ||
947 | /* | 975 | /* |
948 | * New SNC-only Vaios event mapping to driver known keys | 976 | * New SNC-only Vaios event mapping to driver known keys |
@@ -1135,11 +1163,6 @@ static int sony_nc_resume(struct acpi_device *device) | |||
1135 | sony_nc_function_setup(device); | 1163 | sony_nc_function_setup(device); |
1136 | } | 1164 | } |
1137 | 1165 | ||
1138 | /* set the last requested brightness level */ | ||
1139 | if (sony_backlight_device && | ||
1140 | sony_backlight_update_status(sony_backlight_device) < 0) | ||
1141 | pr_warn(DRV_PFX "unable to restore brightness level\n"); | ||
1142 | |||
1143 | /* re-read rfkill state */ | 1166 | /* re-read rfkill state */ |
1144 | sony_nc_rfkill_update(); | 1167 | sony_nc_rfkill_update(); |
1145 | 1168 | ||
@@ -1477,6 +1500,52 @@ static int sony_nc_kbd_backlight_cleanup(struct platform_device *pd) | |||
1477 | return 0; | 1500 | return 0; |
1478 | } | 1501 | } |
1479 | 1502 | ||
1503 | static void sony_nc_backlight_setup(void) | ||
1504 | { | ||
1505 | acpi_handle unused; | ||
1506 | int max_brightness = 0; | ||
1507 | const struct backlight_ops *ops = NULL; | ||
1508 | struct backlight_properties props; | ||
1509 | |||
1510 | if (sony_find_snc_handle(0x12f) != -1) { | ||
1511 | backlight_ng_handle = 0x12f; | ||
1512 | ops = &sony_backlight_ng_ops; | ||
1513 | max_brightness = 0xff; | ||
1514 | |||
1515 | } else if (sony_find_snc_handle(0x137) != -1) { | ||
1516 | backlight_ng_handle = 0x137; | ||
1517 | ops = &sony_backlight_ng_ops; | ||
1518 | max_brightness = 0xff; | ||
1519 | |||
1520 | } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", | ||
1521 | &unused))) { | ||
1522 | ops = &sony_backlight_ops; | ||
1523 | max_brightness = SONY_MAX_BRIGHTNESS - 1; | ||
1524 | |||
1525 | } else | ||
1526 | return; | ||
1527 | |||
1528 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
1529 | props.type = BACKLIGHT_PLATFORM; | ||
1530 | props.max_brightness = max_brightness; | ||
1531 | sony_backlight_device = backlight_device_register("sony", NULL, | ||
1532 | &backlight_ng_handle, | ||
1533 | ops, &props); | ||
1534 | |||
1535 | if (IS_ERR(sony_backlight_device)) { | ||
1536 | pr_warning(DRV_PFX "unable to register backlight device\n"); | ||
1537 | sony_backlight_device = NULL; | ||
1538 | } else | ||
1539 | sony_backlight_device->props.brightness = | ||
1540 | ops->get_brightness(sony_backlight_device); | ||
1541 | } | ||
1542 | |||
1543 | static void sony_nc_backlight_cleanup(void) | ||
1544 | { | ||
1545 | if (sony_backlight_device) | ||
1546 | backlight_device_unregister(sony_backlight_device); | ||
1547 | } | ||
1548 | |||
1480 | static int sony_nc_add(struct acpi_device *device) | 1549 | static int sony_nc_add(struct acpi_device *device) |
1481 | { | 1550 | { |
1482 | acpi_status status; | 1551 | acpi_status status; |
@@ -1543,26 +1612,8 @@ static int sony_nc_add(struct acpi_device *device) | |||
1543 | if (acpi_video_backlight_support()) { | 1612 | if (acpi_video_backlight_support()) { |
1544 | pr_info(DRV_PFX "brightness ignored, must be " | 1613 | pr_info(DRV_PFX "brightness ignored, must be " |
1545 | "controlled by ACPI video driver\n"); | 1614 | "controlled by ACPI video driver\n"); |
1546 | } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", | 1615 | } else { |
1547 | &handle))) { | 1616 | sony_nc_backlight_setup(); |
1548 | struct backlight_properties props; | ||
1549 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
1550 | props.type = BACKLIGHT_PLATFORM; | ||
1551 | props.max_brightness = SONY_MAX_BRIGHTNESS - 1; | ||
1552 | sony_backlight_device = backlight_device_register("sony", NULL, | ||
1553 | NULL, | ||
1554 | &sony_backlight_ops, | ||
1555 | &props); | ||
1556 | |||
1557 | if (IS_ERR(sony_backlight_device)) { | ||
1558 | pr_warning(DRV_PFX "unable to register backlight device\n"); | ||
1559 | sony_backlight_device = NULL; | ||
1560 | } else { | ||
1561 | sony_backlight_device->props.brightness = | ||
1562 | sony_backlight_get_brightness | ||
1563 | (sony_backlight_device); | ||
1564 | } | ||
1565 | |||
1566 | } | 1617 | } |
1567 | 1618 | ||
1568 | /* create sony_pf sysfs attributes related to the SNC device */ | 1619 | /* create sony_pf sysfs attributes related to the SNC device */ |
@@ -1610,8 +1661,7 @@ static int sony_nc_add(struct acpi_device *device) | |||
1610 | for (item = sony_nc_values; item->name; ++item) { | 1661 | for (item = sony_nc_values; item->name; ++item) { |
1611 | device_remove_file(&sony_pf_device->dev, &item->devattr); | 1662 | device_remove_file(&sony_pf_device->dev, &item->devattr); |
1612 | } | 1663 | } |
1613 | if (sony_backlight_device) | 1664 | sony_nc_backlight_cleanup(); |
1614 | backlight_device_unregister(sony_backlight_device); | ||
1615 | 1665 | ||
1616 | sony_laptop_remove_input(); | 1666 | sony_laptop_remove_input(); |
1617 | 1667 | ||
@@ -1633,8 +1683,7 @@ static int sony_nc_remove(struct acpi_device *device, int type) | |||
1633 | { | 1683 | { |
1634 | struct sony_nc_value *item; | 1684 | struct sony_nc_value *item; |
1635 | 1685 | ||
1636 | if (sony_backlight_device) | 1686 | sony_nc_backlight_cleanup(); |
1637 | backlight_device_unregister(sony_backlight_device); | ||
1638 | 1687 | ||
1639 | sony_nc_acpi_device = NULL; | 1688 | sony_nc_acpi_device = NULL; |
1640 | 1689 | ||