Commit | Line | Data |
---|---|---|
1da177e4 | 1 | /* |
2c0f5fb0 | 2 | * Backlight Driver for Sharp Zaurus Handhelds (various models) |
1da177e4 | 3 | * |
2c0f5fb0 | 4 | * Copyright (c) 2004-2006 Richard Purdie |
1da177e4 LT |
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> |
2c0f5fb0 | 18 | #include <linux/mutex.h> |
1da177e4 LT |
19 | #include <linux/fb.h> |
20 | #include <linux/backlight.h> | |
12e87808 | 21 | #include <asm/arch/sharpsl.h> |
b7557de4 | 22 | #include <asm/hardware/sharpsl_pm.h> |
1da177e4 | 23 | |
6ca01765 | 24 | static int corgibl_intensity; |
2c0f5fb0 | 25 | static DEFINE_MUTEX(bl_mutex); |
12e87808 | 26 | static struct backlight_properties corgibl_data; |
6ca01765 | 27 | static struct backlight_device *corgi_backlight_device; |
2c0f5fb0 | 28 | static struct corgibl_machinfo *bl_machinfo; |
6ca01765 RP |
29 | |
30 | static unsigned long corgibl_flags; | |
31 | #define CORGIBL_SUSPENDED 0x01 | |
32 | #define CORGIBL_BATTLOW 0x02 | |
1da177e4 | 33 | |
6ca01765 | 34 | static int corgibl_send_intensity(struct backlight_device *bd) |
1da177e4 | 35 | { |
1da177e4 | 36 | void (*corgi_kick_batt)(void); |
599a52d1 | 37 | int intensity = bd->props.brightness; |
1da177e4 | 38 | |
599a52d1 | 39 | if (bd->props.power != FB_BLANK_UNBLANK) |
6ca01765 | 40 | intensity = 0; |
599a52d1 | 41 | if (bd->props.fb_blank != FB_BLANK_UNBLANK) |
1da177e4 | 42 | intensity = 0; |
6ca01765 RP |
43 | if (corgibl_flags & CORGIBL_SUSPENDED) |
44 | intensity = 0; | |
45 | if (corgibl_flags & CORGIBL_BATTLOW) | |
2c0f5fb0 | 46 | intensity &= bl_machinfo->limit_mask; |
1351e6e0 | 47 | |
2c0f5fb0 RP |
48 | mutex_lock(&bl_mutex); |
49 | bl_machinfo->set_bl_intensity(intensity); | |
50 | mutex_unlock(&bl_mutex); | |
078abcf9 | 51 | |
6ca01765 RP |
52 | corgibl_intensity = intensity; |
53 | ||
078abcf9 RP |
54 | corgi_kick_batt = symbol_get(sharpsl_battery_kick); |
55 | if (corgi_kick_batt) { | |
56 | corgi_kick_batt(); | |
57 | symbol_put(sharpsl_battery_kick); | |
58 | } | |
1da177e4 | 59 | |
6ca01765 | 60 | return 0; |
1da177e4 LT |
61 | } |
62 | ||
63 | #ifdef CONFIG_PM | |
da7a7471 | 64 | static int corgibl_suspend(struct platform_device *pdev, pm_message_t state) |
1da177e4 | 65 | { |
da7a7471 RP |
66 | struct backlight_device *bd = platform_get_drvdata(pdev); |
67 | ||
6ca01765 | 68 | corgibl_flags |= CORGIBL_SUSPENDED; |
da7a7471 | 69 | corgibl_send_intensity(bd); |
1da177e4 LT |
70 | return 0; |
71 | } | |
72 | ||
da7a7471 | 73 | static int corgibl_resume(struct platform_device *pdev) |
1da177e4 | 74 | { |
da7a7471 RP |
75 | struct backlight_device *bd = platform_get_drvdata(pdev); |
76 | ||
6ca01765 | 77 | corgibl_flags &= ~CORGIBL_SUSPENDED; |
da7a7471 | 78 | corgibl_send_intensity(bd); |
1da177e4 LT |
79 | return 0; |
80 | } | |
81 | #else | |
82 | #define corgibl_suspend NULL | |
83 | #define corgibl_resume NULL | |
84 | #endif | |
85 | ||
6ca01765 | 86 | static int corgibl_get_intensity(struct backlight_device *bd) |
1da177e4 | 87 | { |
6ca01765 | 88 | return corgibl_intensity; |
1da177e4 LT |
89 | } |
90 | ||
1da177e4 LT |
91 | /* |
92 | * Called when the battery is low to limit the backlight intensity. | |
93 | * If limit==0 clear any limit, otherwise limit the intensity | |
94 | */ | |
95 | void corgibl_limit_intensity(int limit) | |
96 | { | |
6ca01765 RP |
97 | if (limit) |
98 | corgibl_flags |= CORGIBL_BATTLOW; | |
99 | else | |
100 | corgibl_flags &= ~CORGIBL_BATTLOW; | |
101 | corgibl_send_intensity(corgi_backlight_device); | |
1da177e4 LT |
102 | } |
103 | EXPORT_SYMBOL(corgibl_limit_intensity); | |
104 | ||
105 | ||
599a52d1 | 106 | static struct backlight_ops corgibl_ops = { |
1da177e4 | 107 | .get_brightness = corgibl_get_intensity, |
da7a7471 | 108 | .update_status = corgibl_send_intensity, |
1da177e4 LT |
109 | }; |
110 | ||
f586fbd0 | 111 | static int corgibl_probe(struct platform_device *pdev) |
1da177e4 | 112 | { |
3ae5eaec | 113 | struct corgibl_machinfo *machinfo = pdev->dev.platform_data; |
1351e6e0 | 114 | |
2c0f5fb0 | 115 | bl_machinfo = machinfo; |
2c0f5fb0 RP |
116 | if (!machinfo->limit_mask) |
117 | machinfo->limit_mask = -1; | |
1351e6e0 | 118 | |
1da177e4 | 119 | corgi_backlight_device = backlight_device_register ("corgi-bl", |
599a52d1 | 120 | &pdev->dev, NULL, &corgibl_ops); |
1da177e4 LT |
121 | if (IS_ERR (corgi_backlight_device)) |
122 | return PTR_ERR (corgi_backlight_device); | |
123 | ||
da7a7471 RP |
124 | platform_set_drvdata(pdev, corgi_backlight_device); |
125 | ||
599a52d1 RP |
126 | corgi_backlight_device->props.max_brightness = machinfo->max_intensity; |
127 | corgi_backlight_device->props.power = FB_BLANK_UNBLANK; | |
128 | corgi_backlight_device->props.brightness = machinfo->default_intensity; | |
6ca01765 | 129 | corgibl_send_intensity(corgi_backlight_device); |
1da177e4 LT |
130 | |
131 | printk("Corgi Backlight Driver Initialized.\n"); | |
132 | return 0; | |
133 | } | |
134 | ||
da7a7471 | 135 | static int corgibl_remove(struct platform_device *pdev) |
1da177e4 | 136 | { |
da7a7471 RP |
137 | struct backlight_device *bd = platform_get_drvdata(pdev); |
138 | ||
4437cd1e HMH |
139 | corgibl_data.power = 0; |
140 | corgibl_data.brightness = 0; | |
da7a7471 | 141 | corgibl_send_intensity(bd); |
4437cd1e | 142 | |
da7a7471 | 143 | backlight_device_unregister(bd); |
1da177e4 | 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"); | |
62c877b9 | 174 | MODULE_LICENSE("GPL"); |