dell-laptop: Fix build error by making buffer_mutex static
[safe/jmp/linux-2.6] / drivers / leds / leds-lt3593.c
1 /*
2  * LEDs driver for LT3593 controllers
3  *
4  * See the datasheet at http://cds.linear.com/docs/Datasheet/3593f.pdf
5  *
6  * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
7  *
8  * Based on leds-gpio.c,
9  *
10  *   Copyright (C) 2007 8D Technologies inc.
11  *   Raphael Assenat <raph@8d.com>
12  *   Copyright (C) 2008 Freescale Semiconductor, Inc.
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License version 2 as
16  * published by the Free Software Foundation.
17  */
18
19 #include <linux/kernel.h>
20 #include <linux/init.h>
21 #include <linux/platform_device.h>
22 #include <linux/leds.h>
23 #include <linux/workqueue.h>
24 #include <linux/delay.h>
25 #include <linux/gpio.h>
26
27 struct lt3593_led_data {
28         struct led_classdev cdev;
29         unsigned gpio;
30         struct work_struct work;
31         u8 new_level;
32 };
33
34 static void lt3593_led_work(struct work_struct *work)
35 {
36         int pulses;
37         struct lt3593_led_data *led_dat =
38                 container_of(work, struct lt3593_led_data, work);
39
40         /*
41          * The LT3593 resets its internal current level register to the maximum
42          * level on the first falling edge on the control pin. Each following
43          * falling edge decreases the current level by 625uA. Up to 32 pulses
44          * can be sent, so the maximum power reduction is 20mA.
45          * After a timeout of 128us, the value is taken from the register and
46          * applied is to the output driver.
47          */
48
49         if (led_dat->new_level == 0) {
50                 gpio_set_value_cansleep(led_dat->gpio, 0);
51                 return;
52         }
53
54         pulses = 32 - (led_dat->new_level * 32) / 255;
55
56         if (pulses == 0) {
57                 gpio_set_value_cansleep(led_dat->gpio, 0);
58                 mdelay(1);
59                 gpio_set_value_cansleep(led_dat->gpio, 1);
60                 return;
61         }
62
63         gpio_set_value_cansleep(led_dat->gpio, 1);
64
65         while (pulses--) {
66                 gpio_set_value_cansleep(led_dat->gpio, 0);
67                 udelay(1);
68                 gpio_set_value_cansleep(led_dat->gpio, 1);
69                 udelay(1);
70         }
71 }
72
73 static void lt3593_led_set(struct led_classdev *led_cdev,
74         enum led_brightness value)
75 {
76         struct lt3593_led_data *led_dat =
77                 container_of(led_cdev, struct lt3593_led_data, cdev);
78
79         led_dat->new_level = value;
80         schedule_work(&led_dat->work);
81 }
82
83 static int __devinit create_lt3593_led(const struct gpio_led *template,
84         struct lt3593_led_data *led_dat, struct device *parent)
85 {
86         int ret, state;
87
88         /* skip leds on GPIOs that aren't available */
89         if (!gpio_is_valid(template->gpio)) {
90                 printk(KERN_INFO "%s: skipping unavailable LT3593 LED at gpio %d (%s)\n",
91                                 KBUILD_MODNAME, template->gpio, template->name);
92                 return 0;
93         }
94
95         ret = gpio_request(template->gpio, template->name);
96         if (ret < 0)
97                 return ret;
98
99         led_dat->cdev.name = template->name;
100         led_dat->cdev.default_trigger = template->default_trigger;
101         led_dat->gpio = template->gpio;
102
103         led_dat->cdev.brightness_set = lt3593_led_set;
104
105         state = (template->default_state == LEDS_GPIO_DEFSTATE_ON);
106         led_dat->cdev.brightness = state ? LED_FULL : LED_OFF;
107
108         if (!template->retain_state_suspended)
109                 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
110
111         ret = gpio_direction_output(led_dat->gpio, state);
112         if (ret < 0)
113                 goto err;
114
115         INIT_WORK(&led_dat->work, lt3593_led_work);
116
117         ret = led_classdev_register(parent, &led_dat->cdev);
118         if (ret < 0)
119                 goto err;
120
121         printk(KERN_INFO "%s: registered LT3593 LED '%s' at GPIO %d\n",
122                 KBUILD_MODNAME, template->name, template->gpio);
123
124         return 0;
125
126 err:
127         gpio_free(led_dat->gpio);
128         return ret;
129 }
130
131 static void delete_lt3593_led(struct lt3593_led_data *led)
132 {
133         if (!gpio_is_valid(led->gpio))
134                 return;
135
136         led_classdev_unregister(&led->cdev);
137         cancel_work_sync(&led->work);
138         gpio_free(led->gpio);
139 }
140
141 static int __devinit lt3593_led_probe(struct platform_device *pdev)
142 {
143         struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
144         struct lt3593_led_data *leds_data;
145         int i, ret = 0;
146
147         if (!pdata)
148                 return -EBUSY;
149
150         leds_data = kzalloc(sizeof(struct lt3593_led_data) * pdata->num_leds,
151                                 GFP_KERNEL);
152         if (!leds_data)
153                 return -ENOMEM;
154
155         for (i = 0; i < pdata->num_leds; i++) {
156                 ret = create_lt3593_led(&pdata->leds[i], &leds_data[i],
157                                       &pdev->dev);
158                 if (ret < 0)
159                         goto err;
160         }
161
162         platform_set_drvdata(pdev, leds_data);
163
164         return 0;
165
166 err:
167         for (i = i - 1; i >= 0; i--)
168                 delete_lt3593_led(&leds_data[i]);
169
170         kfree(leds_data);
171
172         return ret;
173 }
174
175 static int __devexit lt3593_led_remove(struct platform_device *pdev)
176 {
177         int i;
178         struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
179         struct lt3593_led_data *leds_data;
180
181         leds_data = platform_get_drvdata(pdev);
182
183         for (i = 0; i < pdata->num_leds; i++)
184                 delete_lt3593_led(&leds_data[i]);
185
186         kfree(leds_data);
187
188         return 0;
189 }
190
191 static struct platform_driver lt3593_led_driver = {
192         .probe          = lt3593_led_probe,
193         .remove         = __devexit_p(lt3593_led_remove),
194         .driver         = {
195                 .name   = "leds-lt3593",
196                 .owner  = THIS_MODULE,
197         },
198 };
199
200 MODULE_ALIAS("platform:leds-lt3593");
201
202 static int __init lt3593_led_init(void)
203 {
204         return platform_driver_register(&lt3593_led_driver);
205 }
206
207 static void __exit lt3593_led_exit(void)
208 {
209         platform_driver_unregister(&lt3593_led_driver);
210 }
211
212 module_init(lt3593_led_init);
213 module_exit(lt3593_led_exit);
214
215 MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
216 MODULE_DESCRIPTION("LED driver for LT3593 controllers");
217 MODULE_LICENSE("GPL");