diff options
author | Michael Hanselmann <linux-kernel@hansmi.ch> | 2006-06-25 08:47:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-25 13:00:59 -0400 |
commit | 5474c120aafe78ca54bf272f7a01107c42da2b21 (patch) | |
tree | c1b002a27703ce92c816bfb9844752186e33d403 /drivers/macintosh/via-pmu.c | |
parent | 17660bdd5c1f1a165273c1a59cb5b87670a81cc4 (diff) |
[PATCH] Rewritten backlight infrastructure for portable Apple computers
This patch contains a total rewrite of the backlight infrastructure for
portable Apple computers. Backward compatibility is retained. A sysfs
interface allows userland to control the brightness with more steps than
before. Userland is allowed to upload a brightness curve for different
monitors, similar to Mac OS X.
[akpm@osdl.org: add needed exports]
Signed-off-by: Michael Hanselmann <linux-kernel@hansmi.ch>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Richard Purdie <rpurdie@rpsys.net>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/macintosh/via-pmu.c')
-rw-r--r-- | drivers/macintosh/via-pmu.c | 120 |
1 files changed, 29 insertions, 91 deletions
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index c63d4e7984be..2a355ae59562 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c | |||
@@ -144,7 +144,6 @@ static int data_index; | |||
144 | static int data_len; | 144 | static int data_len; |
145 | static volatile int adb_int_pending; | 145 | static volatile int adb_int_pending; |
146 | static volatile int disable_poll; | 146 | static volatile int disable_poll; |
147 | static struct adb_request bright_req_1, bright_req_2; | ||
148 | static struct device_node *vias; | 147 | static struct device_node *vias; |
149 | static int pmu_kind = PMU_UNKNOWN; | 148 | static int pmu_kind = PMU_UNKNOWN; |
150 | static int pmu_fully_inited = 0; | 149 | static int pmu_fully_inited = 0; |
@@ -161,7 +160,7 @@ static int drop_interrupts; | |||
161 | #if defined(CONFIG_PM) && defined(CONFIG_PPC32) | 160 | #if defined(CONFIG_PM) && defined(CONFIG_PPC32) |
162 | static int option_lid_wakeup = 1; | 161 | static int option_lid_wakeup = 1; |
163 | #endif /* CONFIG_PM && CONFIG_PPC32 */ | 162 | #endif /* CONFIG_PM && CONFIG_PPC32 */ |
164 | #if (defined(CONFIG_PM)&&defined(CONFIG_PPC32))||defined(CONFIG_PMAC_BACKLIGHT) | 163 | #if (defined(CONFIG_PM)&&defined(CONFIG_PPC32))||defined(CONFIG_PMAC_BACKLIGHT_LEGACY) |
165 | static int sleep_in_progress; | 164 | static int sleep_in_progress; |
166 | #endif | 165 | #endif |
167 | static unsigned long async_req_locks; | 166 | static unsigned long async_req_locks; |
@@ -208,10 +207,6 @@ static int proc_get_info(char *page, char **start, off_t off, | |||
208 | int count, int *eof, void *data); | 207 | int count, int *eof, void *data); |
209 | static int proc_get_irqstats(char *page, char **start, off_t off, | 208 | static int proc_get_irqstats(char *page, char **start, off_t off, |
210 | int count, int *eof, void *data); | 209 | int count, int *eof, void *data); |
211 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
212 | static int pmu_set_backlight_level(int level, void* data); | ||
213 | static int pmu_set_backlight_enable(int on, int level, void* data); | ||
214 | #endif /* CONFIG_PMAC_BACKLIGHT */ | ||
215 | static void pmu_pass_intr(unsigned char *data, int len); | 210 | static void pmu_pass_intr(unsigned char *data, int len); |
216 | static int proc_get_batt(char *page, char **start, off_t off, | 211 | static int proc_get_batt(char *page, char **start, off_t off, |
217 | int count, int *eof, void *data); | 212 | int count, int *eof, void *data); |
@@ -292,13 +287,6 @@ static char *pbook_type[] = { | |||
292 | "Core99" | 287 | "Core99" |
293 | }; | 288 | }; |
294 | 289 | ||
295 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
296 | static struct backlight_controller pmu_backlight_controller = { | ||
297 | pmu_set_backlight_enable, | ||
298 | pmu_set_backlight_level | ||
299 | }; | ||
300 | #endif /* CONFIG_PMAC_BACKLIGHT */ | ||
301 | |||
302 | int __init find_via_pmu(void) | 290 | int __init find_via_pmu(void) |
303 | { | 291 | { |
304 | u64 taddr; | 292 | u64 taddr; |
@@ -417,8 +405,6 @@ static int __init via_pmu_start(void) | |||
417 | if (vias == NULL) | 405 | if (vias == NULL) |
418 | return -ENODEV; | 406 | return -ENODEV; |
419 | 407 | ||
420 | bright_req_1.complete = 1; | ||
421 | bright_req_2.complete = 1; | ||
422 | batt_req.complete = 1; | 408 | batt_req.complete = 1; |
423 | 409 | ||
424 | #ifndef CONFIG_PPC_MERGE | 410 | #ifndef CONFIG_PPC_MERGE |
@@ -483,9 +469,9 @@ static int __init via_pmu_dev_init(void) | |||
483 | return -ENODEV; | 469 | return -ENODEV; |
484 | 470 | ||
485 | #ifdef CONFIG_PMAC_BACKLIGHT | 471 | #ifdef CONFIG_PMAC_BACKLIGHT |
486 | /* Enable backlight */ | 472 | /* Initialize backlight */ |
487 | register_backlight_controller(&pmu_backlight_controller, NULL, "pmu"); | 473 | pmu_backlight_init(vias); |
488 | #endif /* CONFIG_PMAC_BACKLIGHT */ | 474 | #endif |
489 | 475 | ||
490 | #ifdef CONFIG_PPC32 | 476 | #ifdef CONFIG_PPC32 |
491 | if (machine_is_compatible("AAPL,3400/2400") || | 477 | if (machine_is_compatible("AAPL,3400/2400") || |
@@ -1424,7 +1410,7 @@ next: | |||
1424 | #ifdef CONFIG_INPUT_ADBHID | 1410 | #ifdef CONFIG_INPUT_ADBHID |
1425 | if (!disable_kernel_backlight) | 1411 | if (!disable_kernel_backlight) |
1426 | #endif /* CONFIG_INPUT_ADBHID */ | 1412 | #endif /* CONFIG_INPUT_ADBHID */ |
1427 | set_backlight_level(data[1] >> 4); | 1413 | pmac_backlight_set_legacy_brightness(data[1] >> 4); |
1428 | #endif /* CONFIG_PMAC_BACKLIGHT */ | 1414 | #endif /* CONFIG_PMAC_BACKLIGHT */ |
1429 | } | 1415 | } |
1430 | /* Tick interrupt */ | 1416 | /* Tick interrupt */ |
@@ -1674,61 +1660,6 @@ gpio1_interrupt(int irq, void *arg, struct pt_regs *regs) | |||
1674 | return IRQ_NONE; | 1660 | return IRQ_NONE; |
1675 | } | 1661 | } |
1676 | 1662 | ||
1677 | #ifdef CONFIG_PMAC_BACKLIGHT | ||
1678 | static int backlight_to_bright[] = { | ||
1679 | 0x7f, 0x46, 0x42, 0x3e, 0x3a, 0x36, 0x32, 0x2e, | ||
1680 | 0x2a, 0x26, 0x22, 0x1e, 0x1a, 0x16, 0x12, 0x0e | ||
1681 | }; | ||
1682 | |||
1683 | static int | ||
1684 | pmu_set_backlight_enable(int on, int level, void* data) | ||
1685 | { | ||
1686 | struct adb_request req; | ||
1687 | |||
1688 | if (vias == NULL) | ||
1689 | return -ENODEV; | ||
1690 | |||
1691 | if (on) { | ||
1692 | pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT, | ||
1693 | backlight_to_bright[level]); | ||
1694 | pmu_wait_complete(&req); | ||
1695 | } | ||
1696 | pmu_request(&req, NULL, 2, PMU_POWER_CTRL, | ||
1697 | PMU_POW_BACKLIGHT | (on ? PMU_POW_ON : PMU_POW_OFF)); | ||
1698 | pmu_wait_complete(&req); | ||
1699 | |||
1700 | return 0; | ||
1701 | } | ||
1702 | |||
1703 | static void | ||
1704 | pmu_bright_complete(struct adb_request *req) | ||
1705 | { | ||
1706 | if (req == &bright_req_1) | ||
1707 | clear_bit(1, &async_req_locks); | ||
1708 | if (req == &bright_req_2) | ||
1709 | clear_bit(2, &async_req_locks); | ||
1710 | } | ||
1711 | |||
1712 | static int | ||
1713 | pmu_set_backlight_level(int level, void* data) | ||
1714 | { | ||
1715 | if (vias == NULL) | ||
1716 | return -ENODEV; | ||
1717 | |||
1718 | if (test_and_set_bit(1, &async_req_locks)) | ||
1719 | return -EAGAIN; | ||
1720 | pmu_request(&bright_req_1, pmu_bright_complete, 2, PMU_BACKLIGHT_BRIGHT, | ||
1721 | backlight_to_bright[level]); | ||
1722 | if (test_and_set_bit(2, &async_req_locks)) | ||
1723 | return -EAGAIN; | ||
1724 | pmu_request(&bright_req_2, pmu_bright_complete, 2, PMU_POWER_CTRL, | ||
1725 | PMU_POW_BACKLIGHT | (level > BACKLIGHT_OFF ? | ||
1726 | PMU_POW_ON : PMU_POW_OFF)); | ||
1727 | |||
1728 | return 0; | ||
1729 | } | ||
1730 | #endif /* CONFIG_PMAC_BACKLIGHT */ | ||
1731 | |||
1732 | void | 1663 | void |
1733 | pmu_enable_irled(int on) | 1664 | pmu_enable_irled(int on) |
1734 | { | 1665 | { |
@@ -2145,9 +2076,8 @@ pmac_suspend_devices(void) | |||
2145 | return -EBUSY; | 2076 | return -EBUSY; |
2146 | } | 2077 | } |
2147 | 2078 | ||
2148 | /* Wait for completion of async backlight requests */ | 2079 | /* Wait for completion of async requests */ |
2149 | while (!bright_req_1.complete || !bright_req_2.complete || | 2080 | while (!batt_req.complete) |
2150 | !batt_req.complete) | ||
2151 | pmu_poll(); | 2081 | pmu_poll(); |
2152 | 2082 | ||
2153 | /* Giveup the lazy FPU & vec so we don't have to back them | 2083 | /* Giveup the lazy FPU & vec so we don't have to back them |
@@ -2678,26 +2608,34 @@ pmu_ioctl(struct inode * inode, struct file *filp, | |||
2678 | return put_user(1, argp); | 2608 | return put_user(1, argp); |
2679 | #endif /* CONFIG_PM && CONFIG_PPC32 */ | 2609 | #endif /* CONFIG_PM && CONFIG_PPC32 */ |
2680 | 2610 | ||
2681 | #ifdef CONFIG_PMAC_BACKLIGHT | 2611 | #ifdef CONFIG_PMAC_BACKLIGHT_LEGACY |
2682 | /* Backlight should have its own device or go via | 2612 | /* Compatibility ioctl's for backlight */ |
2683 | * the fbdev | ||
2684 | */ | ||
2685 | case PMU_IOC_GET_BACKLIGHT: | 2613 | case PMU_IOC_GET_BACKLIGHT: |
2614 | { | ||
2615 | int brightness; | ||
2616 | |||
2686 | if (sleep_in_progress) | 2617 | if (sleep_in_progress) |
2687 | return -EBUSY; | 2618 | return -EBUSY; |
2688 | error = get_backlight_level(); | 2619 | |
2689 | if (error < 0) | 2620 | brightness = pmac_backlight_get_legacy_brightness(); |
2690 | return error; | 2621 | if (brightness < 0) |
2691 | return put_user(error, argp); | 2622 | return brightness; |
2623 | else | ||
2624 | return put_user(brightness, argp); | ||
2625 | |||
2626 | } | ||
2692 | case PMU_IOC_SET_BACKLIGHT: | 2627 | case PMU_IOC_SET_BACKLIGHT: |
2693 | { | 2628 | { |
2694 | __u32 value; | 2629 | int brightness; |
2630 | |||
2695 | if (sleep_in_progress) | 2631 | if (sleep_in_progress) |
2696 | return -EBUSY; | 2632 | return -EBUSY; |
2697 | error = get_user(value, argp); | 2633 | |
2698 | if (!error) | 2634 | error = get_user(brightness, argp); |
2699 | error = set_backlight_level(value); | 2635 | if (error) |
2700 | break; | 2636 | return error; |
2637 | |||
2638 | return pmac_backlight_set_legacy_brightness(brightness); | ||
2701 | } | 2639 | } |
2702 | #ifdef CONFIG_INPUT_ADBHID | 2640 | #ifdef CONFIG_INPUT_ADBHID |
2703 | case PMU_IOC_GRAB_BACKLIGHT: { | 2641 | case PMU_IOC_GRAB_BACKLIGHT: { |
@@ -2713,7 +2651,7 @@ pmu_ioctl(struct inode * inode, struct file *filp, | |||
2713 | return 0; | 2651 | return 0; |
2714 | } | 2652 | } |
2715 | #endif /* CONFIG_INPUT_ADBHID */ | 2653 | #endif /* CONFIG_INPUT_ADBHID */ |
2716 | #endif /* CONFIG_PMAC_BACKLIGHT */ | 2654 | #endif /* CONFIG_PMAC_BACKLIGHT_LEGACY */ |
2717 | case PMU_IOC_GET_MODEL: | 2655 | case PMU_IOC_GET_MODEL: |
2718 | return put_user(pmu_kind, argp); | 2656 | return put_user(pmu_kind, argp); |
2719 | case PMU_IOC_HAS_ADB: | 2657 | case PMU_IOC_HAS_ADB: |