aboutsummaryrefslogtreecommitdiff
path: root/drivers/macintosh
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/macintosh')
-rw-r--r--drivers/macintosh/via-pmu-backlight.c99
-rw-r--r--drivers/macintosh/via-pmu.c12
2 files changed, 59 insertions, 52 deletions
diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c
index d3f8d75bcbb..a82f313d9dc 100644
--- a/drivers/macintosh/via-pmu-backlight.c
+++ b/drivers/macintosh/via-pmu-backlight.c
@@ -18,17 +18,48 @@
static struct backlight_properties pmu_backlight_data;
static spinlock_t pmu_backlight_lock;
static int sleeping;
+static u8 bl_curve[FB_BACKLIGHT_LEVELS];
-static int pmu_backlight_get_level_brightness(struct fb_info *info,
- int level)
+static void pmu_backlight_init_curve(u8 off, u8 min, u8 max)
+{
+ unsigned int i, flat, count, range = (max - min);
+
+ bl_curve[0] = off;
+
+ for (flat = 1; flat < (FB_BACKLIGHT_LEVELS / 16); ++flat)
+ bl_curve[flat] = min;
+
+ count = FB_BACKLIGHT_LEVELS * 15 / 16;
+ for (i = 0; i < count; ++i)
+ bl_curve[flat + i] = min + (range * (i + 1) / count);
+}
+
+static int pmu_backlight_curve_lookup(int value)
+{
+ int level = (FB_BACKLIGHT_LEVELS - 1);
+ int i, max = 0;
+
+ /* Look for biggest value */
+ for (i = 0; i < FB_BACKLIGHT_LEVELS; i++)
+ max = max((int)bl_curve[i], max);
+
+ /* Look for nearest value */
+ for (i = 0; i < FB_BACKLIGHT_LEVELS; i++) {
+ int diff = abs(bl_curve[i] - value);
+ if (diff < max) {
+ max = diff;
+ level = i;
+ }
+ }
+ return level;
+}
+
+static int pmu_backlight_get_level_brightness(int level)
{
int pmulevel;
/* Get and convert the value */
- mutex_lock(&info->bl_mutex);
- pmulevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_PMU_LEVEL;
- mutex_unlock(&info->bl_mutex);
-
+ pmulevel = bl_curve[level] * FB_BACKLIGHT_MAX / MAX_PMU_LEVEL;
if (pmulevel < 0)
pmulevel = 0;
else if (pmulevel > MAX_PMU_LEVEL)
@@ -39,7 +70,6 @@ static int pmu_backlight_get_level_brightness(struct fb_info *info,
static int pmu_backlight_update_status(struct backlight_device *bd)
{
- struct fb_info *info = class_get_devdata(&bd->class_dev);
struct adb_request req;
unsigned long flags;
int level = bd->props->brightness;
@@ -55,7 +85,7 @@ static int pmu_backlight_update_status(struct backlight_device *bd)
level = 0;
if (level > 0) {
- int pmulevel = pmu_backlight_get_level_brightness(info, level);
+ int pmulevel = pmu_backlight_get_level_brightness(level);
pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT, pmulevel);
pmu_wait_complete(&req);
@@ -88,35 +118,19 @@ static struct backlight_properties pmu_backlight_data = {
};
#ifdef CONFIG_PM
-static int pmu_backlight_sleep_call(struct pmu_sleep_notifier *self, int when)
+void pmu_backlight_set_sleep(int sleep)
{
unsigned long flags;
spin_lock_irqsave(&pmu_backlight_lock, flags);
-
- switch (when) {
- case PBOOK_SLEEP_REQUEST:
- sleeping = 1;
- break;
- case PBOOK_WAKE:
- sleeping = 0;
- break;
- }
-
+ sleeping = sleep;
spin_unlock_irqrestore(&pmu_backlight_lock, flags);
-
- return PBOOK_SLEEP_OK;
}
-
-static struct pmu_sleep_notifier pmu_backlight_sleep_notif = {
- .notifier_call = pmu_backlight_sleep_call,
-};
-#endif
+#endif /* CONFIG_PM */
void __init pmu_backlight_init()
{
struct backlight_device *bd;
- struct fb_info *info;
char name[10];
int level, autosave;
@@ -131,27 +145,14 @@ void __init pmu_backlight_init()
!machine_is_compatible("PowerBook1,1"))
return;
- /* Actually, this is a hack, but I don't know of a better way
- * to get the first framebuffer device.
- */
- info = registered_fb[0];
- if (!info) {
- printk("pmubl: No framebuffer found\n");
- goto error;
- }
-
- snprintf(name, sizeof(name), "pmubl%d", info->node);
+ snprintf(name, sizeof(name), "pmubl");
- bd = backlight_device_register(name, info, &pmu_backlight_data);
+ bd = backlight_device_register(name, NULL, &pmu_backlight_data);
if (IS_ERR(bd)) {
printk("pmubl: Backlight registration failed\n");
goto error;
}
-
- mutex_lock(&info->bl_mutex);
- info->bl_dev = bd;
- fb_bl_default_curve(info, 0x7F, 0x46, 0x0E);
- mutex_unlock(&info->bl_mutex);
+ pmu_backlight_init_curve(0x7F, 0x46, 0x0E);
level = pmu_backlight_data.max_brightness;
@@ -161,28 +162,22 @@ void __init pmu_backlight_init()
pmu_request(&req, NULL, 2, 0xd9, 0);
pmu_wait_complete(&req);
- mutex_lock(&info->bl_mutex);
- level = pmac_backlight_curve_lookup(info,
+ level = pmu_backlight_curve_lookup(
(req.reply[0] >> 4) *
pmu_backlight_data.max_brightness / 15);
- mutex_unlock(&info->bl_mutex);
}
- up(&bd->sem);
+ down(&bd->sem);
bd->props->brightness = level;
bd->props->power = FB_BLANK_UNBLANK;
bd->props->update_status(bd);
- down(&bd->sem);
+ up(&bd->sem);
mutex_lock(&pmac_backlight_mutex);
if (!pmac_backlight)
pmac_backlight = bd;
mutex_unlock(&pmac_backlight_mutex);
-#ifdef CONFIG_PM
- pmu_register_sleep_notifier(&pmu_backlight_sleep_notif);
-#endif
-
printk("pmubl: Backlight initialized (%s)\n", name);
return;
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index ea386801e21..14610a63f58 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -1995,6 +1995,8 @@ restore_via_state(void)
out_8(&via[IER], IER_SET | SR_INT | CB1_INT);
}
+extern void pmu_backlight_set_sleep(int sleep);
+
static int
pmac_suspend_devices(void)
{
@@ -2032,6 +2034,11 @@ pmac_suspend_devices(void)
return -EBUSY;
}
+#ifdef CONFIG_PMAC_BACKLIGHT
+ /* Tell backlight code not to muck around with the chip anymore */
+ pmu_backlight_set_sleep(1);
+#endif
+
/* Call platform functions marked "on sleep" */
pmac_pfunc_i2c_suspend();
pmac_pfunc_base_suspend();
@@ -2090,6 +2097,11 @@ pmac_wakeup_devices(void)
{
mdelay(100);
+#ifdef CONFIG_PMAC_BACKLIGHT
+ /* Tell backlight code it can use the chip again */
+ pmu_backlight_set_sleep(0);
+#endif
+
/* Power back up system devices (including the PIC) */
device_power_up();