diff options
| -rw-r--r-- | drivers/macintosh/via-pmu-backlight.c | 95 | ||||
| -rw-r--r-- | drivers/macintosh/via-pmu.c | 12 |
2 files changed, 57 insertions, 50 deletions
diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c index d3f8d75bcbb4..4397fac55ba0 100644 --- a/drivers/macintosh/via-pmu-backlight.c +++ b/drivers/macintosh/via-pmu-backlight.c | |||
| @@ -18,17 +18,48 @@ | |||
| 18 | static struct backlight_properties pmu_backlight_data; | 18 | static struct backlight_properties pmu_backlight_data; |
| 19 | static spinlock_t pmu_backlight_lock; | 19 | static spinlock_t pmu_backlight_lock; |
| 20 | static int sleeping; | 20 | static int sleeping; |
| 21 | static u8 bl_curve[FB_BACKLIGHT_LEVELS]; | ||
| 21 | 22 | ||
| 22 | static int pmu_backlight_get_level_brightness(struct fb_info *info, | 23 | static void pmu_backlight_init_curve(u8 off, u8 min, u8 max) |
| 23 | int level) | 24 | { |
| 25 | unsigned int i, flat, count, range = (max - min); | ||
| 26 | |||
| 27 | bl_curve[0] = off; | ||
| 28 | |||
| 29 | for (flat = 1; flat < (FB_BACKLIGHT_LEVELS / 16); ++flat) | ||
| 30 | bl_curve[flat] = min; | ||
| 31 | |||
| 32 | count = FB_BACKLIGHT_LEVELS * 15 / 16; | ||
| 33 | for (i = 0; i < count; ++i) | ||
| 34 | bl_curve[flat + i] = min + (range * (i + 1) / count); | ||
| 35 | } | ||
| 36 | |||
| 37 | static int pmu_backlight_curve_lookup(int value) | ||
| 38 | { | ||
| 39 | int level = (FB_BACKLIGHT_LEVELS - 1); | ||
| 40 | int i, max = 0; | ||
| 41 | |||
| 42 | /* Look for biggest value */ | ||
| 43 | for (i = 0; i < FB_BACKLIGHT_LEVELS; i++) | ||
| 44 | max = max((int)bl_curve[i], max); | ||
| 45 | |||
| 46 | /* Look for nearest value */ | ||
| 47 | for (i = 0; i < FB_BACKLIGHT_LEVELS; i++) { | ||
| 48 | int diff = abs(bl_curve[i] - value); | ||
| 49 | if (diff < max) { | ||
| 50 | max = diff; | ||
| 51 | level = i; | ||
| 52 | } | ||
| 53 | } | ||
| 54 | return level; | ||
| 55 | } | ||
| 56 | |||
| 57 | static int pmu_backlight_get_level_brightness(int level) | ||
| 24 | { | 58 | { |
| 25 | int pmulevel; | 59 | int pmulevel; |
| 26 | 60 | ||
| 27 | /* Get and convert the value */ | 61 | /* Get and convert the value */ |
| 28 | mutex_lock(&info->bl_mutex); | 62 | pmulevel = bl_curve[level] * FB_BACKLIGHT_MAX / MAX_PMU_LEVEL; |
| 29 | pmulevel = info->bl_curve[level] * FB_BACKLIGHT_MAX / MAX_PMU_LEVEL; | ||
| 30 | mutex_unlock(&info->bl_mutex); | ||
| 31 | |||
| 32 | if (pmulevel < 0) | 63 | if (pmulevel < 0) |
| 33 | pmulevel = 0; | 64 | pmulevel = 0; |
| 34 | else if (pmulevel > MAX_PMU_LEVEL) | 65 | else if (pmulevel > MAX_PMU_LEVEL) |
| @@ -39,7 +70,6 @@ static int pmu_backlight_get_level_brightness(struct fb_info *info, | |||
| 39 | 70 | ||
| 40 | static int pmu_backlight_update_status(struct backlight_device *bd) | 71 | static int pmu_backlight_update_status(struct backlight_device *bd) |
| 41 | { | 72 | { |
| 42 | struct fb_info *info = class_get_devdata(&bd->class_dev); | ||
| 43 | struct adb_request req; | 73 | struct adb_request req; |
| 44 | unsigned long flags; | 74 | unsigned long flags; |
| 45 | int level = bd->props->brightness; | 75 | int level = bd->props->brightness; |
| @@ -55,7 +85,7 @@ static int pmu_backlight_update_status(struct backlight_device *bd) | |||
| 55 | level = 0; | 85 | level = 0; |
| 56 | 86 | ||
| 57 | if (level > 0) { | 87 | if (level > 0) { |
| 58 | int pmulevel = pmu_backlight_get_level_brightness(info, level); | 88 | int pmulevel = pmu_backlight_get_level_brightness(level); |
| 59 | 89 | ||
| 60 | pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT, pmulevel); | 90 | pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT, pmulevel); |
| 61 | pmu_wait_complete(&req); | 91 | pmu_wait_complete(&req); |
| @@ -88,35 +118,19 @@ static struct backlight_properties pmu_backlight_data = { | |||
| 88 | }; | 118 | }; |
| 89 | 119 | ||
| 90 | #ifdef CONFIG_PM | 120 | #ifdef CONFIG_PM |
| 91 | static int pmu_backlight_sleep_call(struct pmu_sleep_notifier *self, int when) | 121 | void pmu_backlight_set_sleep(int sleep) |
| 92 | { | 122 | { |
| 93 | unsigned long flags; | 123 | unsigned long flags; |
| 94 | 124 | ||
| 95 | spin_lock_irqsave(&pmu_backlight_lock, flags); | 125 | spin_lock_irqsave(&pmu_backlight_lock, flags); |
| 96 | 126 | sleeping = sleep; | |
| 97 | switch (when) { | ||
| 98 | case PBOOK_SLEEP_REQUEST: | ||
| 99 | sleeping = 1; | ||
| 100 | break; | ||
| 101 | case PBOOK_WAKE: | ||
| 102 | sleeping = 0; | ||
| 103 | break; | ||
| 104 | } | ||
| 105 | |||
| 106 | spin_unlock_irqrestore(&pmu_backlight_lock, flags); | 127 | spin_unlock_irqrestore(&pmu_backlight_lock, flags); |
| 107 | |||
| 108 | return PBOOK_SLEEP_OK; | ||
| 109 | } | 128 | } |
| 110 | 129 | #endif /* CONFIG_PM */ | |
| 111 | static struct pmu_sleep_notifier pmu_backlight_sleep_notif = { | ||
| 112 | .notifier_call = pmu_backlight_sleep_call, | ||
| 113 | }; | ||
| 114 | #endif | ||
| 115 | 130 | ||
| 116 | void __init pmu_backlight_init() | 131 | void __init pmu_backlight_init() |
| 117 | { | 132 | { |
| 118 | struct backlight_device *bd; | 133 | struct backlight_device *bd; |
| 119 | struct fb_info *info; | ||
| 120 | char name[10]; | 134 | char name[10]; |
| 121 | int level, autosave; | 135 | int level, autosave; |
| 122 | 136 | ||
| @@ -131,27 +145,14 @@ void __init pmu_backlight_init() | |||
| 131 | !machine_is_compatible("PowerBook1,1")) | 145 | !machine_is_compatible("PowerBook1,1")) |
| 132 | return; | 146 | return; |
| 133 | 147 | ||
| 134 | /* Actually, this is a hack, but I don't know of a better way | 148 | snprintf(name, sizeof(name), "pmubl"); |
| 135 | * to get the first framebuffer device. | ||
| 136 | */ | ||
| 137 | info = registered_fb[0]; | ||
| 138 | if (!info) { | ||
| 139 | printk("pmubl: No framebuffer found\n"); | ||
| 140 | goto error; | ||
| 141 | } | ||
| 142 | |||
| 143 | snprintf(name, sizeof(name), "pmubl%d", info->node); | ||
| 144 | 149 | ||
| 145 | bd = backlight_device_register(name, info, &pmu_backlight_data); | 150 | bd = backlight_device_register(name, NULL, &pmu_backlight_data); |
| 146 | if (IS_ERR(bd)) { | 151 | if (IS_ERR(bd)) { |
| 147 | printk("pmubl: Backlight registration failed\n"); | 152 | printk("pmubl: Backlight registration failed\n"); |
| 148 | goto error; | 153 | goto error; |
| 149 | } | 154 | } |
| 150 | 155 | pmu_backlight_init_curve(0x7F, 0x46, 0x0E); | |
| 151 | mutex_lock(&info->bl_mutex); | ||
| 152 | info->bl_dev = bd; | ||
| 153 | fb_bl_default_curve(info, 0x7F, 0x46, 0x0E); | ||
| 154 | mutex_unlock(&info->bl_mutex); | ||
| 155 | 156 | ||
| 156 | level = pmu_backlight_data.max_brightness; | 157 | level = pmu_backlight_data.max_brightness; |
| 157 | 158 | ||
| @@ -161,11 +162,9 @@ void __init pmu_backlight_init() | |||
| 161 | pmu_request(&req, NULL, 2, 0xd9, 0); | 162 | pmu_request(&req, NULL, 2, 0xd9, 0); |
| 162 | pmu_wait_complete(&req); | 163 | pmu_wait_complete(&req); |
| 163 | 164 | ||
| 164 | mutex_lock(&info->bl_mutex); | 165 | level = pmu_backlight_curve_lookup( |
| 165 | level = pmac_backlight_curve_lookup(info, | ||
| 166 | (req.reply[0] >> 4) * | 166 | (req.reply[0] >> 4) * |
| 167 | pmu_backlight_data.max_brightness / 15); | 167 | pmu_backlight_data.max_brightness / 15); |
| 168 | mutex_unlock(&info->bl_mutex); | ||
| 169 | } | 168 | } |
| 170 | 169 | ||
| 171 | up(&bd->sem); | 170 | up(&bd->sem); |
| @@ -179,10 +178,6 @@ void __init pmu_backlight_init() | |||
| 179 | pmac_backlight = bd; | 178 | pmac_backlight = bd; |
| 180 | mutex_unlock(&pmac_backlight_mutex); | 179 | mutex_unlock(&pmac_backlight_mutex); |
| 181 | 180 | ||
| 182 | #ifdef CONFIG_PM | ||
| 183 | pmu_register_sleep_notifier(&pmu_backlight_sleep_notif); | ||
| 184 | #endif | ||
| 185 | |||
| 186 | printk("pmubl: Backlight initialized (%s)\n", name); | 181 | printk("pmubl: Backlight initialized (%s)\n", name); |
| 187 | 182 | ||
| 188 | return; | 183 | return; |
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index ea386801e215..14610a63f580 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c | |||
| @@ -1995,6 +1995,8 @@ restore_via_state(void) | |||
| 1995 | out_8(&via[IER], IER_SET | SR_INT | CB1_INT); | 1995 | out_8(&via[IER], IER_SET | SR_INT | CB1_INT); |
| 1996 | } | 1996 | } |
| 1997 | 1997 | ||
| 1998 | extern void pmu_backlight_set_sleep(int sleep); | ||
| 1999 | |||
| 1998 | static int | 2000 | static int |
| 1999 | pmac_suspend_devices(void) | 2001 | pmac_suspend_devices(void) |
| 2000 | { | 2002 | { |
| @@ -2032,6 +2034,11 @@ pmac_suspend_devices(void) | |||
| 2032 | return -EBUSY; | 2034 | return -EBUSY; |
| 2033 | } | 2035 | } |
| 2034 | 2036 | ||
| 2037 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
| 2038 | /* Tell backlight code not to muck around with the chip anymore */ | ||
| 2039 | pmu_backlight_set_sleep(1); | ||
| 2040 | #endif | ||
| 2041 | |||
| 2035 | /* Call platform functions marked "on sleep" */ | 2042 | /* Call platform functions marked "on sleep" */ |
| 2036 | pmac_pfunc_i2c_suspend(); | 2043 | pmac_pfunc_i2c_suspend(); |
| 2037 | pmac_pfunc_base_suspend(); | 2044 | pmac_pfunc_base_suspend(); |
| @@ -2090,6 +2097,11 @@ pmac_wakeup_devices(void) | |||
| 2090 | { | 2097 | { |
| 2091 | mdelay(100); | 2098 | mdelay(100); |
| 2092 | 2099 | ||
| 2100 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
| 2101 | /* Tell backlight code it can use the chip again */ | ||
| 2102 | pmu_backlight_set_sleep(0); | ||
| 2103 | #endif | ||
| 2104 | |||
| 2093 | /* Power back up system devices (including the PIC) */ | 2105 | /* Power back up system devices (including the PIC) */ |
| 2094 | device_power_up(); | 2106 | device_power_up(); |
| 2095 | 2107 | ||
