Add patches accepted for 2.6.22-rc4
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / releases / upstream / 2.6.20-rc2 / 0002-ACPI-ibm_acpi-Add-support-for-the-generic-backlight-device.txt
bloba72559ae61ab322e235c25779d643a90c107e33f
1 From 8acb025085aa88c41063bfa0f2c3b4d0a3f2ef11 Mon Sep 17 00:00:00 2001
2 From: Holger Macht <hmacht@suse.de>
3 Date: Fri, 20 Oct 2006 14:30:28 -0700
4 Subject: [PATCH 2/28] ACPI: ibm_acpi: Add support for the generic backlight device
6 Add support for the generic backlight interface below /sys/class/backlight.
7 The patch keeps the procfs brightness handling for backward compatibility.
9 Add two generic functions brightness_get and brightness_set
10 to be used both by the procfs related and the sysfs related methods.
12 [apw@shadowen.org: backlight users need to select BACKLIGHT_CLASS_DEVICE]
14 Signed-off-by: Holger Macht <hmacht@suse.de>
15 Signed-off-by: Andy Whitcroft <apw@shadowen.org>
16 Signed-off-by: Andrew Morton <akpm@osdl.org>
17 Signed-off-by: Len Brown <len.brown@intel.com>
18 ---
19  drivers/acpi/Kconfig    |    1 +
20  drivers/acpi/ibm_acpi.c |   75 ++++++++++++++++++++++++++++++++++++++---------
21  2 files changed, 62 insertions(+), 14 deletions(-)
23 diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
24 index 0f9d4be..bc58a3b 100644
25 --- a/drivers/acpi/Kconfig
26 +++ b/drivers/acpi/Kconfig
27 @@ -200,6 +200,7 @@ config ACPI_ASUS
28  config ACPI_IBM
29         tristate "IBM ThinkPad Laptop Extras"
30         depends on X86
31 +       select BACKLIGHT_CLASS_DEVICE
32         ---help---
33           This is a Linux ACPI driver for the IBM ThinkPad laptops. It adds
34           support for Fn-Fx key combinations, Bluetooth control, video
35 diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
36 index 003a987..cd8722e 100644
37 --- a/drivers/acpi/ibm_acpi.c
38 +++ b/drivers/acpi/ibm_acpi.c
39 @@ -78,6 +78,7 @@
40  #include <linux/init.h>
41  #include <linux/types.h>
42  #include <linux/proc_fs.h>
43 +#include <linux/backlight.h>
44  #include <asm/uaccess.h>
46  #include <acpi/acpi_drivers.h>
47 @@ -243,6 +244,8 @@ struct ibm_struct {
49  static struct proc_dir_entry *proc_dir = NULL;
51 +static struct backlight_device *ibm_backlight_device;
53  #define onoff(status,bit) ((status) & (1 << (bit)) ? "on" : "off")
54  #define enabled(status,bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
55  #define strlencmp(a,b) (strncmp((a), (b), strlen(b)))
56 @@ -1381,12 +1384,22 @@ static int ecdump_write(char *buf)
58  static int brightness_offset = 0x31;
60 +static int brightness_get(struct backlight_device *bd)
62 +       u8 level;
63 +       if (!acpi_ec_read(brightness_offset, &level))
64 +               return -EIO;
66 +       level &= 0x7;
67 +       return level;
70  static int brightness_read(char *p)
71  {
72         int len = 0;
73 -       u8 level;
74 +       int level;
76 -       if (!acpi_ec_read(brightness_offset, &level)) {
77 +       if ((level = brightness_get(NULL)) < 0) {
78                 len += sprintf(p + len, "level:\t\tunreadable\n");
79         } else {
80                 len += sprintf(p + len, "level:\t\t%d\n", level & 0x7);
81 @@ -1401,16 +1414,34 @@ static int brightness_read(char *p)
82  #define BRIGHTNESS_UP  4
83  #define BRIGHTNESS_DOWN        5
85 -static int brightness_write(char *buf)
86 +static int brightness_set(int value)
87  {
88         int cmos_cmd, inc, i;
89 -       u8 level;
90 +       int current_value = brightness_get(NULL);
92 +       value &= 7;
94 +       cmos_cmd = value > current_value ? BRIGHTNESS_UP : BRIGHTNESS_DOWN;
95 +       inc = value > current_value ? 1 : -1;
96 +       for (i = current_value; i != value; i += inc) {
97 +               if (!cmos_eval(cmos_cmd))
98 +                       return -EIO;
99 +               if (!acpi_ec_write(brightness_offset, i + inc))
100 +                       return -EIO;
101 +       }
103 +       return 0;
106 +static int brightness_write(char *buf)
108 +       int level;
109         int new_level;
110         char *cmd;
112         while ((cmd = next_cmd(&buf))) {
113 -               if (!acpi_ec_read(brightness_offset, &level))
114 -                       return -EIO;
115 +               if ((level = brightness_get(NULL)) < 0)
116 +                       return level;
117                 level &= 7;
119                 if (strlencmp(cmd, "up") == 0) {
120 @@ -1423,19 +1454,17 @@ static int brightness_write(char *buf)
121                 } else
122                         return -EINVAL;
124 -               cmos_cmd = new_level > level ? BRIGHTNESS_UP : BRIGHTNESS_DOWN;
125 -               inc = new_level > level ? 1 : -1;
126 -               for (i = level; i != new_level; i += inc) {
127 -                       if (!cmos_eval(cmos_cmd))
128 -                               return -EIO;
129 -                       if (!acpi_ec_write(brightness_offset, i + inc))
130 -                               return -EIO;
131 -               }
132 +               brightness_set(new_level);
133         }
135         return 0;
138 +static int brightness_update_status(struct backlight_device *bd)
140 +       return brightness_set(bd->props->brightness);
143  static int volume_offset = 0x30;
145  static int volume_read(char *p)
146 @@ -1963,10 +1992,20 @@ IBM_PARAM(brightness);
147  IBM_PARAM(volume);
148  IBM_PARAM(fan);
150 +static struct backlight_properties ibm_backlight_data = {
151 +        .owner          = THIS_MODULE,
152 +        .get_brightness = brightness_get,
153 +        .update_status  = brightness_update_status,
154 +        .max_brightness = 7,
157  static void acpi_ibm_exit(void)
159         int i;
161 +       if (ibm_backlight_device)
162 +               backlight_device_unregister(ibm_backlight_device);
164         for (i = ARRAY_SIZE(ibms) - 1; i >= 0; i--)
165                 ibm_exit(&ibms[i]);
167 @@ -2034,6 +2073,14 @@ static int __init acpi_ibm_init(void)
168                 }
169         }
171 +       ibm_backlight_device = backlight_device_register("ibm", NULL,
172 +                                                        &ibm_backlight_data);
173 +        if (IS_ERR(ibm_backlight_device)) {
174 +               printk(IBM_ERR "Could not register ibm backlight device\n");
175 +               ibm_backlight_device = NULL;
176 +               acpi_ibm_exit();
177 +       }
179         return 0;
182 -- 
183 1.4.4.3