cleanup
[linux-2.4.21-pre4.git] / arch / ppc / platforms / pmac_backlight.c
1 /*
2  * BK Id: SCCS/s.pmac_backlight.c 1.14 08/13/02 21:52:54 paulus
3  */
4 /*
5  * Miscellaneous procedures for dealing with the PowerMac hardware.
6  * Contains support for the backlight.
7  * 
8  *   Copyright (C) 2000 Benjamin Herrenschmidt
9  *
10  */
11
12 #include <linux/config.h>
13 #include <linux/kernel.h>
14 #include <linux/stddef.h>
15 #include <linux/reboot.h>
16 #include <linux/nvram.h>
17 #include <asm/sections.h>
18 #include <asm/ptrace.h>
19 #include <asm/io.h>
20 #include <asm/pgtable.h>
21 #include <asm/system.h>
22 #include <asm/prom.h>
23 #include <asm/machdep.h>
24 #include <asm/nvram.h>
25 #include <asm/backlight.h>
26
27 #include <linux/adb.h>
28 #include <linux/pmu.h>
29
30 static struct backlight_controller *backlighter = NULL;
31 static void* backlighter_data = NULL;
32 static int backlight_autosave = 0;
33 static int backlight_level = BACKLIGHT_MAX;
34 static int backlight_enabled = 1;
35
36 void __pmac
37 register_backlight_controller(struct backlight_controller *ctrler, void *data, char *type)
38 {
39         struct device_node* bk_node;
40         char *prop;
41         int valid = 0;
42
43         bk_node = find_devices("backlight");
44         
45 #ifdef CONFIG_ADB_PMU
46         /* Special case for the old PowerBook since I can't test on it */
47         backlight_autosave = machine_is_compatible("AAPL,3400/2400")
48                 || machine_is_compatible("AAPL,3500");
49         if ((backlight_autosave
50              || machine_is_compatible("AAPL,PowerBook1998")
51              || machine_is_compatible("PowerBook1,1"))
52             && !strcmp(type, "pmu"))
53                 valid = 1;
54 #endif
55         if (bk_node) {
56                 prop = get_property(bk_node, "backlight-control", NULL);
57                 if (prop && !strncmp(prop, type, strlen(type)))
58                         valid = 1;
59         }
60         if (!valid)
61                 return;
62         backlighter = ctrler;
63         backlighter_data = data;
64         
65         if (bk_node && !backlight_autosave)
66                 prop = get_property(bk_node, "bklt", NULL);
67         else
68                 prop = NULL;
69         if (prop) {
70                 backlight_level = ((*prop)+1) >> 1;
71                 if (backlight_level > BACKLIGHT_MAX)
72                         backlight_level = BACKLIGHT_MAX;
73         }
74         
75 #ifdef CONFIG_ADB_PMU
76         if (backlight_autosave) {
77                 struct adb_request req;
78                 pmu_request(&req, NULL, 2, 0xd9, 0);
79                 while (!req.complete)
80                         pmu_poll();
81                 backlight_level = req.reply[0] >> 4;
82         }
83 #endif
84         if (!backlighter->set_enable(1, backlight_level, data))
85                 backlight_enabled = 1;
86
87         printk(KERN_INFO "Registered \"%s\" backlight controller, level: %d/15\n",
88                 type, backlight_level);
89 }
90
91 void __pmac
92 unregister_backlight_controller(struct backlight_controller *ctrler, void *data)
93 {
94         /* We keep the current backlight level (for now) */
95         if (ctrler == backlighter && data == backlighter_data)
96                 backlighter = NULL;
97 }
98
99 int __pmac
100 set_backlight_enable(int enable)
101 {
102         int rc;
103         
104         if (!backlighter)
105                 return -ENODEV;
106         rc = backlighter->set_enable(enable, backlight_level, backlighter_data);
107         if (!rc)
108                 backlight_enabled = enable;
109         return rc;
110 }
111
112 int __pmac
113 get_backlight_enable(void)
114 {
115         if (!backlighter)
116                 return -ENODEV;
117         return backlight_enabled;
118 }
119
120 int __pmac
121 set_backlight_level(int level)
122 {
123         int rc = 0;
124         
125         if (!backlighter)
126                 return -ENODEV;
127         if (level < BACKLIGHT_MIN)
128                 level = BACKLIGHT_OFF;
129         if (level > BACKLIGHT_MAX)
130                 level = BACKLIGHT_MAX;
131         if (backlight_enabled)
132                 rc = backlighter->set_level(level, backlighter_data);
133         if (!rc)
134                 backlight_level = level;
135         if (!rc && !backlight_autosave) {
136                 level <<=1;
137                 if (level & 0x10)
138                         level |= 0x01;
139                 // -- todo: save to property "bklt"
140         }
141         return rc;
142 }
143
144 int __pmac
145 get_backlight_level(void)
146 {
147         if (!backlighter)
148                 return -ENODEV;
149         return backlight_level;
150 }