diff options
author | Holger Macht <hmacht@suse.de> | 2006-10-20 17:30:28 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2006-10-21 01:34:48 -0400 |
commit | 8acb025085aa88c41063bfa0f2c3b4d0a3f2ef11 (patch) | |
tree | 3bc37ab8a95ff4f5d1878c2fd2553b46a3e08d02 | |
parent | c7a3bd177f248d01ee18a01d22048c80e071c331 (diff) |
ACPI: ibm_acpi: Add support for the generic backlight device
Add support for the generic backlight interface below /sys/class/backlight.
The patch keeps the procfs brightness handling for backward compatibility.
Add two generic functions brightness_get and brightness_set
to be used both by the procfs related and the sysfs related methods.
[apw@shadowen.org: backlight users need to select BACKLIGHT_CLASS_DEVICE]
Signed-off-by: Holger Macht <hmacht@suse.de>
Signed-off-by: Andy Whitcroft <apw@shadowen.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r-- | drivers/acpi/Kconfig | 1 | ||||
-rw-r--r-- | drivers/acpi/ibm_acpi.c | 75 |
2 files changed, 62 insertions, 14 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 0f9d4be7ed75..bc58a3b18e06 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -200,6 +200,7 @@ config ACPI_ASUS | |||
200 | config ACPI_IBM | 200 | config ACPI_IBM |
201 | tristate "IBM ThinkPad Laptop Extras" | 201 | tristate "IBM ThinkPad Laptop Extras" |
202 | depends on X86 | 202 | depends on X86 |
203 | select BACKLIGHT_CLASS_DEVICE | ||
203 | ---help--- | 204 | ---help--- |
204 | This is a Linux ACPI driver for the IBM ThinkPad laptops. It adds | 205 | This is a Linux ACPI driver for the IBM ThinkPad laptops. It adds |
205 | support for Fn-Fx key combinations, Bluetooth control, video | 206 | support for Fn-Fx key combinations, Bluetooth control, video |
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c index 003a9876c968..cd8722e4157e 100644 --- a/drivers/acpi/ibm_acpi.c +++ b/drivers/acpi/ibm_acpi.c | |||
@@ -78,6 +78,7 @@ | |||
78 | #include <linux/init.h> | 78 | #include <linux/init.h> |
79 | #include <linux/types.h> | 79 | #include <linux/types.h> |
80 | #include <linux/proc_fs.h> | 80 | #include <linux/proc_fs.h> |
81 | #include <linux/backlight.h> | ||
81 | #include <asm/uaccess.h> | 82 | #include <asm/uaccess.h> |
82 | 83 | ||
83 | #include <acpi/acpi_drivers.h> | 84 | #include <acpi/acpi_drivers.h> |
@@ -243,6 +244,8 @@ struct ibm_struct { | |||
243 | 244 | ||
244 | static struct proc_dir_entry *proc_dir = NULL; | 245 | static struct proc_dir_entry *proc_dir = NULL; |
245 | 246 | ||
247 | static struct backlight_device *ibm_backlight_device; | ||
248 | |||
246 | #define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off") | 249 | #define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off") |
247 | #define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") | 250 | #define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled") |
248 | #define strlencmp(a,b) (strncmp((a), (b), strlen(b))) | 251 | #define strlencmp(a,b) (strncmp((a), (b), strlen(b))) |
@@ -1381,12 +1384,22 @@ static int ecdump_write(char *buf) | |||
1381 | 1384 | ||
1382 | static int brightness_offset = 0x31; | 1385 | static int brightness_offset = 0x31; |
1383 | 1386 | ||
1387 | static int brightness_get(struct backlight_device *bd) | ||
1388 | { | ||
1389 | u8 level; | ||
1390 | if (!acpi_ec_read(brightness_offset, &level)) | ||
1391 | return -EIO; | ||
1392 | |||
1393 | level &= 0x7; | ||
1394 | return level; | ||
1395 | } | ||
1396 | |||
1384 | static int brightness_read(char *p) | 1397 | static int brightness_read(char *p) |
1385 | { | 1398 | { |
1386 | int len = 0; | 1399 | int len = 0; |
1387 | u8 level; | 1400 | int level; |
1388 | 1401 | ||
1389 | if (!acpi_ec_read(brightness_offset, &level)) { | 1402 | if ((level = brightness_get(NULL)) < 0) { |
1390 | len += sprintf(p + len, "level:\t\tunreadable\n"); | 1403 | len += sprintf(p + len, "level:\t\tunreadable\n"); |
1391 | } else { | 1404 | } else { |
1392 | len += sprintf(p + len, "level:\t\t%d\n", level & 0x7); | 1405 | len += sprintf(p + len, "level:\t\t%d\n", level & 0x7); |
@@ -1401,16 +1414,34 @@ static int brightness_read(char *p) | |||
1401 | #define BRIGHTNESS_UP 4 | 1414 | #define BRIGHTNESS_UP 4 |
1402 | #define BRIGHTNESS_DOWN 5 | 1415 | #define BRIGHTNESS_DOWN 5 |
1403 | 1416 | ||
1404 | static int brightness_write(char *buf) | 1417 | static int brightness_set(int value) |
1405 | { | 1418 | { |
1406 | int cmos_cmd, inc, i; | 1419 | int cmos_cmd, inc, i; |
1407 | u8 level; | 1420 | int current_value = brightness_get(NULL); |
1421 | |||
1422 | value &= 7; | ||
1423 | |||
1424 | cmos_cmd = value > current_value ? BRIGHTNESS_UP : BRIGHTNESS_DOWN; | ||
1425 | inc = value > current_value ? 1 : -1; | ||
1426 | for (i = current_value; i != value; i += inc) { | ||
1427 | if (!cmos_eval(cmos_cmd)) | ||
1428 | return -EIO; | ||
1429 | if (!acpi_ec_write(brightness_offset, i + inc)) | ||
1430 | return -EIO; | ||
1431 | } | ||
1432 | |||
1433 | return 0; | ||
1434 | } | ||
1435 | |||
1436 | static int brightness_write(char *buf) | ||
1437 | { | ||
1438 | int level; | ||
1408 | int new_level; | 1439 | int new_level; |
1409 | char *cmd; | 1440 | char *cmd; |
1410 | 1441 | ||
1411 | while ((cmd = next_cmd(&buf))) { | 1442 | while ((cmd = next_cmd(&buf))) { |
1412 | if (!acpi_ec_read(brightness_offset, &level)) | 1443 | if ((level = brightness_get(NULL)) < 0) |
1413 | return -EIO; | 1444 | return level; |
1414 | level &= 7; | 1445 | level &= 7; |
1415 | 1446 | ||
1416 | if (strlencmp(cmd, "up") == 0) { | 1447 | if (strlencmp(cmd, "up") == 0) { |
@@ -1423,19 +1454,17 @@ static int brightness_write(char *buf) | |||
1423 | } else | 1454 | } else |
1424 | return -EINVAL; | 1455 | return -EINVAL; |
1425 | 1456 | ||
1426 | cmos_cmd = new_level > level ? BRIGHTNESS_UP : BRIGHTNESS_DOWN; | 1457 | brightness_set(new_level); |
1427 | inc = new_level > level ? 1 : -1; | ||
1428 | for (i = level; i != new_level; i += inc) { | ||
1429 | if (!cmos_eval(cmos_cmd)) | ||
1430 | return -EIO; | ||
1431 | if (!acpi_ec_write(brightness_offset, i + inc)) | ||
1432 | return -EIO; | ||
1433 | } | ||
1434 | } | 1458 | } |
1435 | 1459 | ||
1436 | return 0; | 1460 | return 0; |
1437 | } | 1461 | } |
1438 | 1462 | ||
1463 | static int brightness_update_status(struct backlight_device *bd) | ||
1464 | { | ||
1465 | return brightness_set(bd->props->brightness); | ||
1466 | } | ||
1467 | |||
1439 | static int volume_offset = 0x30; | 1468 | static int volume_offset = 0x30; |
1440 | 1469 | ||
1441 | static int volume_read(char *p) | 1470 | static int volume_read(char *p) |
@@ -1963,10 +1992,20 @@ IBM_PARAM(brightness); | |||
1963 | IBM_PARAM(volume); | 1992 | IBM_PARAM(volume); |
1964 | IBM_PARAM(fan); | 1993 | IBM_PARAM(fan); |
1965 | 1994 | ||
1995 | static struct backlight_properties ibm_backlight_data = { | ||
1996 | .owner = THIS_MODULE, | ||
1997 | .get_brightness = brightness_get, | ||
1998 | .update_status = brightness_update_status, | ||
1999 | .max_brightness = 7, | ||
2000 | }; | ||
2001 | |||
1966 | static void acpi_ibm_exit(void) | 2002 | static void acpi_ibm_exit(void) |
1967 | { | 2003 | { |
1968 | int i; | 2004 | int i; |
1969 | 2005 | ||
2006 | if (ibm_backlight_device) | ||
2007 | backlight_device_unregister(ibm_backlight_device); | ||
2008 | |||
1970 | for (i = ARRAY_SIZE(ibms) - 1; i >= 0; i--) | 2009 | for (i = ARRAY_SIZE(ibms) - 1; i >= 0; i--) |
1971 | ibm_exit(&ibms[i]); | 2010 | ibm_exit(&ibms[i]); |
1972 | 2011 | ||
@@ -2034,6 +2073,14 @@ static int __init acpi_ibm_init(void) | |||
2034 | } | 2073 | } |
2035 | } | 2074 | } |
2036 | 2075 | ||
2076 | ibm_backlight_device = backlight_device_register("ibm", NULL, | ||
2077 | &ibm_backlight_data); | ||
2078 | if (IS_ERR(ibm_backlight_device)) { | ||
2079 | printk(IBM_ERR "Could not register ibm backlight device\n"); | ||
2080 | ibm_backlight_device = NULL; | ||
2081 | acpi_ibm_exit(); | ||
2082 | } | ||
2083 | |||
2037 | return 0; | 2084 | return 0; |
2038 | } | 2085 | } |
2039 | 2086 | ||