Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Backlight Driver for Sharp Corgi | |
3 | * | |
4 | * Copyright (c) 2004-2005 Richard Purdie | |
5 | * | |
6 | * Based on Sharp's 2.4 Backlight Driver | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License version 2 as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | */ | |
13 | ||
14 | #include <linux/module.h> | |
15 | #include <linux/kernel.h> | |
16 | #include <linux/init.h> | |
d052d1be | 17 | #include <linux/platform_device.h> |
1da177e4 LT |
18 | #include <linux/spinlock.h> |
19 | #include <linux/fb.h> | |
20 | #include <linux/backlight.h> | |
21 | ||
12e87808 | 22 | #include <asm/arch/sharpsl.h> |
b7557de4 | 23 | #include <asm/hardware/sharpsl_pm.h> |
1da177e4 | 24 | |
1da177e4 | 25 | #define CORGI_DEFAULT_INTENSITY 0x1f |
12e87808 | 26 | #define CORGI_LIMIT_MASK 0x0b |
1da177e4 | 27 | |
6ca01765 | 28 | static int corgibl_intensity; |
12e87808 | 29 | static void (*corgibl_mach_set_intensity)(int intensity); |
1da177e4 | 30 | static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED; |
12e87808 | 31 | static struct backlight_properties corgibl_data; |
6ca01765 RP |
32 | static struct backlight_device *corgi_backlight_device; |
33 | ||
34 | static unsigned long corgibl_flags; | |
35 | #define CORGIBL_SUSPENDED 0x01 | |
36 | #define CORGIBL_BATTLOW 0x02 | |
1da177e4 | 37 | |
6ca01765 | 38 | static int corgibl_send_intensity(struct backlight_device *bd) |
1da177e4 LT |
39 | { |
40 | unsigned long flags; | |
41 | void (*corgi_kick_batt)(void); | |
6ca01765 | 42 | int intensity = bd->props->brightness; |
1da177e4 | 43 | |
6ca01765 RP |
44 | if (bd->props->power != FB_BLANK_UNBLANK) |
45 | intensity = 0; | |
46 | if (bd->props->fb_blank != FB_BLANK_UNBLANK) | |
1da177e4 | 47 | intensity = 0; |
6ca01765 RP |
48 | if (corgibl_flags & CORGIBL_SUSPENDED) |
49 | intensity = 0; | |
50 | if (corgibl_flags & CORGIBL_BATTLOW) | |
51 | intensity &= CORGI_LIMIT_MASK; | |
1da177e4 | 52 | |
1da177e4 | 53 | spin_lock_irqsave(&bl_lock, flags); |
1351e6e0 RP |
54 | |
55 | corgibl_mach_set_intensity(intensity); | |
56 | ||
1da177e4 | 57 | spin_unlock_irqrestore(&bl_lock, flags); |
078abcf9 | 58 | |
6ca01765 RP |
59 | corgibl_intensity = intensity; |
60 | ||
078abcf9 RP |
61 | corgi_kick_batt = symbol_get(sharpsl_battery_kick); |
62 | if (corgi_kick_batt) { | |
63 | corgi_kick_batt(); | |
64 | symbol_put(sharpsl_battery_kick); | |
65 | } | |
1da177e4 | 66 | |
6ca01765 | 67 | return 0; |
1da177e4 LT |
68 | } |
69 | ||
70 | #ifdef CONFIG_PM | |
3ae5eaec | 71 | static int corgibl_suspend(struct platform_device *dev, pm_message_t state) |
1da177e4 | 72 | { |
6ca01765 RP |
73 | corgibl_flags |= CORGIBL_SUSPENDED; |
74 | corgibl_send_intensity(corgi_backlight_device); | |
1da177e4 LT |
75 | return 0; |
76 | } | |
77 | ||
3ae5eaec | 78 | static int corgibl_resume(struct platform_device *dev) |
1da177e4 | 79 | { |
6ca01765 RP |
80 | corgibl_flags &= ~CORGIBL_SUSPENDED; |
81 | corgibl_send_intensity(corgi_backlight_device); | |
1da177e4 LT |
82 | return 0; |
83 | } | |
84 | #else | |
85 | #define corgibl_suspend NULL | |
86 | #define corgibl_resume NULL | |
87 | #endif | |
88 | ||
6ca01765 | 89 | static int corgibl_get_intensity(struct backlight_device *bd) |
1da177e4 | 90 | { |
6ca01765 | 91 | return corgibl_intensity; |
1da177e4 LT |
92 | } |
93 | ||
6ca01765 | 94 | static int corgibl_set_intensity(struct backlight_device *bd) |
1da177e4 | 95 | { |
6ca01765 | 96 | corgibl_send_intensity(corgi_backlight_device); |
1da177e4 LT |
97 | return 0; |
98 | } | |
99 | ||
1da177e4 LT |
100 | /* |
101 | * Called when the battery is low to limit the backlight intensity. | |
102 | * If limit==0 clear any limit, otherwise limit the intensity | |
103 | */ | |
104 | void corgibl_limit_intensity(int limit) | |
105 | { | |
6ca01765 RP |
106 | if (limit) |
107 | corgibl_flags |= CORGIBL_BATTLOW; | |
108 | else | |
109 | corgibl_flags &= ~CORGIBL_BATTLOW; | |
110 | corgibl_send_intensity(corgi_backlight_device); | |
1da177e4 LT |
111 | } |
112 | EXPORT_SYMBOL(corgibl_limit_intensity); | |
113 | ||
114 | ||
115 | static struct backlight_properties corgibl_data = { | |
6ca01765 | 116 | .owner = THIS_MODULE, |
1da177e4 | 117 | .get_brightness = corgibl_get_intensity, |
6ca01765 | 118 | .update_status = corgibl_set_intensity, |
1da177e4 LT |
119 | }; |
120 | ||
3ae5eaec | 121 | static int __init corgibl_probe(struct platform_device *pdev) |
1da177e4 | 122 | { |
3ae5eaec | 123 | struct corgibl_machinfo *machinfo = pdev->dev.platform_data; |
1351e6e0 RP |
124 | |
125 | corgibl_data.max_brightness = machinfo->max_intensity; | |
126 | corgibl_mach_set_intensity = machinfo->set_bl_intensity; | |
127 | ||
1da177e4 LT |
128 | corgi_backlight_device = backlight_device_register ("corgi-bl", |
129 | NULL, &corgibl_data); | |
130 | if (IS_ERR (corgi_backlight_device)) | |
131 | return PTR_ERR (corgi_backlight_device); | |
132 | ||
6ca01765 RP |
133 | corgibl_data.power = FB_BLANK_UNBLANK; |
134 | corgibl_data.brightness = CORGI_DEFAULT_INTENSITY; | |
135 | corgibl_send_intensity(corgi_backlight_device); | |
1da177e4 LT |
136 | |
137 | printk("Corgi Backlight Driver Initialized.\n"); | |
138 | return 0; | |
139 | } | |
140 | ||
3ae5eaec | 141 | static int corgibl_remove(struct platform_device *dev) |
1da177e4 LT |
142 | { |
143 | backlight_device_unregister(corgi_backlight_device); | |
144 | ||
1da177e4 LT |
145 | printk("Corgi Backlight Driver Unloaded\n"); |
146 | return 0; | |
147 | } | |
148 | ||
3ae5eaec | 149 | static struct platform_driver corgibl_driver = { |
1da177e4 LT |
150 | .probe = corgibl_probe, |
151 | .remove = corgibl_remove, | |
152 | .suspend = corgibl_suspend, | |
153 | .resume = corgibl_resume, | |
3ae5eaec RK |
154 | .driver = { |
155 | .name = "corgi-bl", | |
156 | }, | |
1da177e4 LT |
157 | }; |
158 | ||
159 | static int __init corgibl_init(void) | |
160 | { | |
3ae5eaec | 161 | return platform_driver_register(&corgibl_driver); |
1da177e4 LT |
162 | } |
163 | ||
164 | static void __exit corgibl_exit(void) | |
165 | { | |
3ae5eaec | 166 | platform_driver_unregister(&corgibl_driver); |
1da177e4 LT |
167 | } |
168 | ||
169 | module_init(corgibl_init); | |
170 | module_exit(corgibl_exit); | |
171 | ||
172 | MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>"); | |
173 | MODULE_DESCRIPTION("Corgi Backlight Driver"); | |
174 | MODULE_LICENSE("GPLv2"); |