File: /usr/src/linux/arch/ppc/kernel/pmac_backlight.c

1     /*
2      * BK Id: SCCS/s.pmac_backlight.c 1.8 09/08/01 15:47:42 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[1] >> 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     }
151