hh.org updates
[hh.org.git] / arch / arm / mach-pxa / htcuniversal / htcuniversal_leds.c
blob93b8d675147f1d114408d5b2d1cbc3c26cbdb25a
1 /*
2 * LED interface for Himalaya, the HTC PocketPC.
4 * License: GPL
6 * Author: Luke Kenneth Casson Leighton, Copyright(C) 2004
8 * Copyright(C) 2004, Luke Kenneth Casson Leighton.
10 * History:
12 * 2004-02-19 Luke Kenneth Casson Leighton created.
16 #include <linux/module.h>
17 #include <linux/delay.h>
18 #include <linux/platform_device.h>
19 #include <linux/leds.h>
20 #include <linux/soc/asic3_base.h>
22 #include <asm/io.h>
23 #include <asm/hardware/ipaq-asic3.h>
24 #include <asm/arch/htcuniversal-gpio.h>
25 #include <asm/arch/htcuniversal-asic.h>
26 #include <asm/mach-types.h>
28 #include "htcuniversal_leds.h"
30 #ifdef DEBUG
31 #define dprintk(x...) printk(x)
32 #else
33 #define dprintk(x...)
34 #endif
36 struct htcuniversal_led_data {
37 int hw_num;
38 int duty_time;
39 int cycle_time;
40 int registered;
41 int brightness;
42 int color;
43 struct led_properties props;
46 #define to_htcuniversal_led_data(d) container_of(d, struct htcuniversal_led_data, props)
48 void htcuniversal_set_led (int led, int brightness, int duty_time, int cycle_time)
50 dprintk("htcuniversal_set__asic3_led\n");
51 if (led == HTC_RED_LED || led == HTC_GREENR_LED || led == HTC_YELLOW_LED) {
52 if (brightness) {
53 duty_time=(duty_time*128+500)/1000;
54 cycle_time=(cycle_time*128+500)/1000;
55 } else {
56 duty_time=0;
57 cycle_time=1;
61 switch(led) {
62 case HTC_RED_LED:
63 asic3_set_led(&htcuniversal_asic3.dev, 1, duty_time, cycle_time);
64 break;
65 case HTC_GREENR_LED:
66 asic3_set_led(&htcuniversal_asic3.dev, 2, duty_time, cycle_time);
67 break;
68 case HTC_YELLOW_LED:
69 asic3_set_led(&htcuniversal_asic3.dev, 1, duty_time, cycle_time);
70 asic3_set_led(&htcuniversal_asic3.dev, 2, duty_time, cycle_time);
71 break;
72 case HTC_BLUETOOTH_LED:
73 case HTC_WIFI_LED:
74 asic3_set_led(&htcuniversal_asic3.dev, 0, duty_time, cycle_time);
75 break;
79 EXPORT_SYMBOL(htcuniversal_set_led);
82 int htcuniversal_led_brightness_get(struct device *dev, struct led_properties *props)
84 struct htcuniversal_led_data *data = to_htcuniversal_led_data(props);
86 return data->brightness;
89 void htcuniversal_led_brightness_set(struct device *dev, struct led_properties *props, int value)
91 /* Brightness levels supported by the hardware: 0 (off) and 100 (on)*/
94 struct htcuniversal_led_data *data = to_htcuniversal_led_data(props);
96 data->brightness = value > 0 ? 100 : 0;
97 if (! data->brightness &&
98 (data->hw_num == HTC_RED_LED || data->hw_num == HTC_GREENR_LED || data->hw_num == HTC_YELLOW_LED )) {
99 data->duty_time=1000;
100 data->cycle_time=1000;
102 switch (data->hw_num) {
103 case HTC_RED_LED:
104 case HTC_GREENR_LED:
105 case HTC_YELLOW_LED:
106 htcuniversal_set_led(data->hw_num, data->brightness, data->duty_time, data->cycle_time);
107 break;
108 case HTC_PHONE_BL_LED:
109 asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_BL_KEYP_PWR_ON, (value > 0) ? (1<<GPIOD_BL_KEYP_PWR_ON) : 0);
110 break;
111 case HTC_KEYBD_BL_LED:
112 asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_BL_KEYB_PWR_ON, (value > 0) ? (1<<GPIOD_BL_KEYB_PWR_ON) : 0);
113 break;
114 case HTC_VIBRA:
115 asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_VIBRA_PWR_ON, (value > 0) ? (1<<GPIOD_VIBRA_PWR_ON) : 0);
116 break;
117 case HTC_CAM_FLASH_LED:
118 asic3_set_gpio_out_a(&htcuniversal_asic3.dev, 1<<GPIOA_FLASHLIGHT, (value > 0) ? (1<<GPIOA_FLASHLIGHT) : 0);
119 break;
120 case HTC_BLUETOOTH_LED:
121 if (value > 0)
122 htcuniversal_egpio_enable(EGPIO5_BT_3V3_ON);
123 else
124 htcuniversal_egpio_disable(EGPIO5_BT_3V3_ON);
125 break;
126 case HTC_WIFI_LED:
127 if (value > 0)
128 htcuniversal_egpio_enable(EGPIO6_WIFI_ON);
129 else
130 htcuniversal_egpio_disable(EGPIO6_WIFI_ON);
131 break;
133 printk("brightness=%d for the led=%d\n",value, data->hw_num);
137 htcuniversal_led_cycle_get(struct device *dev, struct led_properties *props)
139 struct htcuniversal_led_data *data = to_htcuniversal_led_data(props);
141 return data->cycle_time;
144 void
145 htcuniversal_led_cycle_set(struct device *dev, struct led_properties *props, int value)
147 struct htcuniversal_led_data *data = to_htcuniversal_led_data(props);
149 data->cycle_time=value;
150 if (data->brightness)
151 htcuniversal_set_led(data->hw_num, data->brightness, data->duty_time, data->cycle_time);
156 htcuniversal_led_duty_get(struct device *dev, struct led_properties *props)
158 struct htcuniversal_led_data *data = to_htcuniversal_led_data(props);
160 return data->duty_time;
163 void
164 htcuniversal_led_duty_set(struct device *dev, struct led_properties *props, int value)
166 struct htcuniversal_led_data *data = to_htcuniversal_led_data(props);
168 data->duty_time=value;
169 if (data->brightness)
170 htcuniversal_set_led(data->hw_num, data->brightness, data->duty_time, data->cycle_time);
173 static struct htcuniversal_led_data leds[] = {
175 .hw_num=HTC_RED_LED,
176 .duty_time=1000,
177 .cycle_time=1000,
178 .props = {
179 .owner = THIS_MODULE,
180 .name = "red",
181 .color = "red",
182 .brightness_get = htcuniversal_led_brightness_get,
183 .brightness_set = htcuniversal_led_brightness_set,
187 .hw_num=HTC_GREENR_LED,
188 .duty_time=1000,
189 .cycle_time=1000,
190 .props = {
191 .owner = THIS_MODULE,
192 .name = "green",
193 .color = "green",
194 .brightness_get = htcuniversal_led_brightness_get,
195 .brightness_set = htcuniversal_led_brightness_set,
199 .hw_num=HTC_YELLOW_LED,
200 .duty_time=1000,
201 .cycle_time=1000,
202 .props = {
203 .owner = THIS_MODULE,
204 .name = "yellow",
205 .color = "yellow",
206 .brightness_get = htcuniversal_led_brightness_get,
207 .brightness_set = htcuniversal_led_brightness_set,
211 .hw_num=HTC_PHONE_BL_LED,
212 .brightness=100,
213 .props = {
214 .owner = THIS_MODULE,
215 .name = "phone",
216 .brightness_get = htcuniversal_led_brightness_get,
217 .brightness_set = htcuniversal_led_brightness_set,
221 .hw_num=HTC_KEYBD_BL_LED,
222 .brightness=0,
223 .props = {
224 .owner = THIS_MODULE,
225 .name = "keyboard",
226 .color = "rosa",
227 .brightness_get = htcuniversal_led_brightness_get,
228 .brightness_set = htcuniversal_led_brightness_set,
232 .hw_num=HTC_VIBRA,
233 .brightness=0,
234 .props = {
235 .owner = THIS_MODULE,
236 .name = "vibra",
237 .brightness_get = htcuniversal_led_brightness_get,
238 .brightness_set = htcuniversal_led_brightness_set,
242 .hw_num=HTC_BLUETOOTH_LED,
243 .duty_time=1000,
244 .cycle_time=500,
245 .props = {
246 .owner = THIS_MODULE,
247 .name = "bluetooth",
248 .color = "bt_blue",
249 .brightness_get = htcuniversal_led_brightness_get,
250 .brightness_set = htcuniversal_led_brightness_set,
254 .hw_num=HTC_WIFI_LED,
255 .duty_time=1000,
256 .cycle_time=500,
257 .props = {
258 .owner = THIS_MODULE,
259 .name = "wifi",
260 .color = "wifi_green",
261 .brightness_get = htcuniversal_led_brightness_get,
262 .brightness_set = htcuniversal_led_brightness_set,
266 .hw_num=HTC_CAM_FLASH_LED,
267 .props = {
268 .owner = THIS_MODULE,
269 .name = "flashlight",
270 .color = "white",
271 .brightness_get = htcuniversal_led_brightness_get,
272 .brightness_set = htcuniversal_led_brightness_set,
277 static int htcuniversal_led_probe(struct device *dev)
279 int i,ret=0;
281 dprintk("htcuniversal_led_probe\n");
282 /* Turn on the LED controllers in CDEX */
283 asic3_set_clock_cdex(&htcuniversal_asic3.dev,
284 CLOCK_CDEX_LED0 | CLOCK_CDEX_LED1 | CLOCK_CDEX_LED2,
285 CLOCK_CDEX_LED0 | CLOCK_CDEX_LED1 | CLOCK_CDEX_LED2
288 htcuniversal_set_led(HTC_RED_LED, 0, 0, 0);
289 htcuniversal_set_led(HTC_GREENR_LED, 0, 0, 0);
290 htcuniversal_set_led(HTC_YELLOW_LED, 0, 0, 0);
291 htcuniversal_set_led(HTC_PHONE_BL_LED, 0, 0, 0);
292 htcuniversal_set_led(HTC_KEYBD_BL_LED, 0, 0, 0);
293 htcuniversal_set_led(HTC_VIBRA, 0, 0, 0);
294 htcuniversal_set_led(HTC_BLUETOOTH_LED, 0, 0, 0);
295 htcuniversal_set_led(HTC_WIFI_LED, 0, 0, 0);
296 htcuniversal_set_led(HTC_CAM_FLASH_LED, 0, 0, 0);
298 for (i = 0; i < ARRAY_SIZE(leds); i++) {
299 ret = leds_device_register(dev, &leds[i].props);
300 leds[i].registered = 1;
301 if (unlikely(ret)) {
302 printk(KERN_WARNING "Unable to register htcuniversal led %s\n", leds[i].props.color);
303 leds[i].registered = 0;
306 return ret;
309 static int htcuniversal_led_remove(struct device *dev)
311 int i;
313 dprintk("htcuniversal_led_remove\n");
315 for (i = 0; i < ARRAY_SIZE(leds); i++) {
316 if (leds[i].registered) {
317 leds_device_unregister(&leds[i].props);
320 return 0;
323 static int
324 htcuniversal_led_suspend(struct device *dev, u32 state, u32 level)
326 /* Turn off the LED controllers in CDEX */
327 asic3_set_clock_cdex(&htcuniversal_asic3.dev,
328 ~CLOCK_CDEX_LED0 & ~CLOCK_CDEX_LED1 & ~CLOCK_CDEX_LED2,
329 ~CLOCK_CDEX_LED0 & ~CLOCK_CDEX_LED1 & ~CLOCK_CDEX_LED2
331 asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_BL_KEYP_PWR_ON, 0);
332 asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_BL_KEYB_PWR_ON, 0);
333 asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_VIBRA_PWR_ON, 0);
335 return 0;
338 static int
339 htcuniversal_led_resume(struct device *dev, u32 level)
341 /* Turn on the LED controllers in CDEX */
342 asic3_set_clock_cdex(&htcuniversal_asic3.dev,
343 CLOCK_CDEX_LED0 | CLOCK_CDEX_LED1 | CLOCK_CDEX_LED2,
344 CLOCK_CDEX_LED0 | CLOCK_CDEX_LED1 | CLOCK_CDEX_LED2
347 asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_BL_KEYP_PWR_ON, leds[HTC_PHONE_BL_LED].brightness ? (1<<GPIOD_BL_KEYP_PWR_ON) : 0);
348 asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_BL_KEYB_PWR_ON, leds[HTC_KEYBD_BL_LED].brightness ? (1<<GPIOD_BL_KEYB_PWR_ON) : 0);
349 asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_VIBRA_PWR_ON, leds[HTC_VIBRA].brightness ? (1<<GPIOD_VIBRA_PWR_ON) : 0);
351 return 0;
355 static struct device_driver htcuniversal_led_driver = {
356 .name = "htcuniversal_led",
357 .probe = htcuniversal_led_probe,
358 .remove = htcuniversal_led_remove,
359 .suspend = htcuniversal_led_suspend,
360 .resume = htcuniversal_led_resume,
361 .bus = &platform_bus_type,
365 static struct platform_device htcuniversal_led_dev = {
366 .name = "htcuniversal_led",
370 static int htcuniversal_led_init (void)
372 int ret = 0;
374 if (! machine_is_htcuniversal() )
375 return -ENODEV;
377 ret=driver_register(&htcuniversal_led_driver);
378 if (! ret)
379 ret=platform_device_register(&htcuniversal_led_dev);
380 return ret;
383 static void htcuniversal_led_exit (void)
385 platform_device_unregister(&htcuniversal_led_dev);
386 driver_unregister(&htcuniversal_led_driver);
389 module_init (htcuniversal_led_init);
390 module_exit (htcuniversal_led_exit);
392 MODULE_LICENSE("GPL");