PageRenderTime 16ms CodeModel.GetById 1ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/arch/ppc/platforms/pmac_backlight.c

https://bitbucket.org/evzijst/gittest
C | 202 lines | 168 code | 23 blank | 11 comment | 40 complexity | 747af1d2841f1091a61ec71b14e2a025 MD5 | raw file
  1/*
  2 * Miscellaneous procedures for dealing with the PowerMac hardware.
  3 * Contains support for the backlight.
  4 *
  5 *   Copyright (C) 2000 Benjamin Herrenschmidt
  6 *
  7 */
  8
  9#include <linux/config.h>
 10#include <linux/kernel.h>
 11#include <linux/module.h>
 12#include <linux/stddef.h>
 13#include <linux/reboot.h>
 14#include <linux/nvram.h>
 15#include <linux/console.h>
 16#include <asm/sections.h>
 17#include <asm/ptrace.h>
 18#include <asm/io.h>
 19#include <asm/pgtable.h>
 20#include <asm/system.h>
 21#include <asm/prom.h>
 22#include <asm/machdep.h>
 23#include <asm/nvram.h>
 24#include <asm/backlight.h>
 25
 26#include <linux/adb.h>
 27#include <linux/pmu.h>
 28
 29static struct backlight_controller *backlighter;
 30static void* backlighter_data;
 31static int backlight_autosave;
 32static int backlight_level = BACKLIGHT_MAX;
 33static int backlight_enabled = 1;
 34static int backlight_req_level = -1;
 35static int backlight_req_enable = -1;
 36
 37static void backlight_callback(void *);
 38static DECLARE_WORK(backlight_work, backlight_callback, NULL);
 39
 40void __pmac register_backlight_controller(struct backlight_controller *ctrler,
 41					  void *data, char *type)
 42{
 43	struct device_node* bk_node;
 44	char *prop;
 45	int valid = 0;
 46
 47	/* There's already a matching controller, bail out */
 48	if (backlighter != NULL)
 49		return;
 50
 51	bk_node = find_devices("backlight");
 52
 53#ifdef CONFIG_ADB_PMU
 54	/* Special case for the old PowerBook since I can't test on it */
 55	backlight_autosave = machine_is_compatible("AAPL,3400/2400")
 56		|| machine_is_compatible("AAPL,3500");
 57	if ((backlight_autosave
 58	     || machine_is_compatible("AAPL,PowerBook1998")
 59	     || machine_is_compatible("PowerBook1,1"))
 60	    && !strcmp(type, "pmu"))
 61		valid = 1;
 62#endif
 63	if (bk_node) {
 64		prop = get_property(bk_node, "backlight-control", NULL);
 65		if (prop && !strncmp(prop, type, strlen(type)))
 66			valid = 1;
 67	}
 68	if (!valid)
 69		return;
 70	backlighter = ctrler;
 71	backlighter_data = data;
 72
 73	if (bk_node && !backlight_autosave)
 74		prop = get_property(bk_node, "bklt", NULL);
 75	else
 76		prop = NULL;
 77	if (prop) {
 78		backlight_level = ((*prop)+1) >> 1;
 79		if (backlight_level > BACKLIGHT_MAX)
 80			backlight_level = BACKLIGHT_MAX;
 81	}
 82
 83#ifdef CONFIG_ADB_PMU
 84	if (backlight_autosave) {
 85		struct adb_request req;
 86		pmu_request(&req, NULL, 2, 0xd9, 0);
 87		while (!req.complete)
 88			pmu_poll();
 89		backlight_level = req.reply[0] >> 4;
 90	}
 91#endif
 92	acquire_console_sem();
 93	if (!backlighter->set_enable(1, backlight_level, data))
 94		backlight_enabled = 1;
 95	release_console_sem();
 96
 97	printk(KERN_INFO "Registered \"%s\" backlight controller,"
 98	       "level: %d/15\n", type, backlight_level);
 99}
100EXPORT_SYMBOL(register_backlight_controller);
101
102void __pmac unregister_backlight_controller(struct backlight_controller
103					    *ctrler, void *data)
104{
105	/* We keep the current backlight level (for now) */
106	if (ctrler == backlighter && data == backlighter_data)
107		backlighter = NULL;
108}
109EXPORT_SYMBOL(unregister_backlight_controller);
110
111static int __pmac __set_backlight_enable(int enable)
112{
113	int rc;
114
115	if (!backlighter)
116		return -ENODEV;
117	acquire_console_sem();
118	rc = backlighter->set_enable(enable, backlight_level,
119				     backlighter_data);
120	if (!rc)
121		backlight_enabled = enable;
122	release_console_sem();
123	return rc;
124}
125int __pmac set_backlight_enable(int enable)
126{
127	if (!backlighter)
128		return -ENODEV;
129	backlight_req_enable = enable;
130	schedule_work(&backlight_work);
131	return 0;
132}
133
134EXPORT_SYMBOL(set_backlight_enable);
135
136int __pmac get_backlight_enable(void)
137{
138	if (!backlighter)
139		return -ENODEV;
140	return backlight_enabled;
141}
142EXPORT_SYMBOL(get_backlight_enable);
143
144static int __pmac __set_backlight_level(int level)
145{
146	int rc = 0;
147
148	if (!backlighter)
149		return -ENODEV;
150	if (level < BACKLIGHT_MIN)
151		level = BACKLIGHT_OFF;
152	if (level > BACKLIGHT_MAX)
153		level = BACKLIGHT_MAX;
154	acquire_console_sem();
155	if (backlight_enabled)
156		rc = backlighter->set_level(level, backlighter_data);
157	if (!rc)
158		backlight_level = level;
159	release_console_sem();
160	if (!rc && !backlight_autosave) {
161		level <<=1;
162		if (level & 0x10)
163			level |= 0x01;
164		// -- todo: save to property "bklt"
165	}
166	return rc;
167}
168int __pmac set_backlight_level(int level)
169{
170	if (!backlighter)
171		return -ENODEV;
172	backlight_req_level = level;
173	schedule_work(&backlight_work);
174	return 0;
175}
176
177EXPORT_SYMBOL(set_backlight_level);
178
179int __pmac get_backlight_level(void)
180{
181	if (!backlighter)
182		return -ENODEV;
183	return backlight_level;
184}
185EXPORT_SYMBOL(get_backlight_level);
186
187static void backlight_callback(void *dummy)
188{
189	int level, enable;
190
191	do {
192		level = backlight_req_level;
193		enable = backlight_req_enable;
194		mb();
195
196		if (level >= 0)
197			__set_backlight_level(level);
198		if (enable >= 0)
199			__set_backlight_enable(enable);
200	} while(cmpxchg(&backlight_req_level, level, -1) != level ||
201		cmpxchg(&backlight_req_enable, enable, -1) != enable);
202}