e4c6d27727175f96fb758834e77997567db512b2
[linux-3.10.git] / drivers / video / backlight / pwm_bl.c
1 /*
2  * linux/drivers/video/backlight/pwm_bl.c
3  *
4  * Copyright (c) 2013, NVIDIA CORPORATION, All rights reserved.
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * simple PWM based backlight control, board code has to setup
16  * 1) pin configuration so PWM waveforms can output
17  * 2) platform_data being correctly configured
18  *
19  * This program is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License version 2 as
21  * published by the Free Software Foundation.
22  */
23
24 #include <linux/module.h>
25 #include <linux/kernel.h>
26 #include <linux/init.h>
27 #include <linux/platform_device.h>
28 #include <linux/fb.h>
29 #include <linux/backlight.h>
30 #include <linux/err.h>
31 #include <linux/gpio.h>
32 #include <linux/pwm.h>
33 #include <linux/pwm_backlight.h>
34 #include <linux/slab.h>
35 #include <linux/edp.h>
36
37 struct pwm_bl_data {
38         struct pwm_device       *pwm;
39         struct device           *dev;
40         unsigned int            period;
41         unsigned int            lth_brightness;
42         unsigned int            *levels;
43         unsigned int            pwm_gpio;
44         int                     (*notify)(struct device *,
45                                           int brightness);
46         void                    (*notify_after)(struct device *,
47                                         int brightness);
48         int                     (*check_fb)(struct device *, struct fb_info *);
49         void                    (*exit)(struct device *);
50         struct edp_client *pwm_bl_edp_client;
51         int *edp_brightness_states;
52 };
53
54 static int pwm_backlight_set(struct backlight_device *bl, int brightness)
55 {
56         struct pwm_bl_data *pb = bl_get_data(bl);
57         int max = bl->props.max_brightness;
58
59         if (bl->props.power != FB_BLANK_UNBLANK ||
60             bl->props.fb_blank != FB_BLANK_UNBLANK ||
61             bl->props.state & BL_CORE_FBBLANK)
62                 brightness = 0;
63
64         if (pb->notify)
65                 brightness = pb->notify(pb->dev, brightness);
66
67         if (brightness == 0) {
68                 pwm_config(pb->pwm, 0, pb->period);
69                 pwm_disable(pb->pwm);
70         } else {
71                 int duty_cycle;
72
73                 if (pb->levels) {
74                         duty_cycle = pb->levels[brightness];
75                         max = pb->levels[max];
76                 } else {
77                         duty_cycle = brightness;
78                 }
79
80                 duty_cycle = pb->lth_brightness +
81                      (duty_cycle * (pb->period - pb->lth_brightness) / max);
82                 pwm_config(pb->pwm, duty_cycle, pb->period);
83                 pwm_enable(pb->pwm);
84         }
85
86         if (pb->notify_after)
87                 pb->notify_after(pb->dev, brightness);
88
89         return 0;
90 }
91
92 static int pwm_backlight_set_with_edp(struct backlight_device *bl,
93         int brightness)
94 {
95         struct pwm_bl_data *data = bl_get_data(bl);
96         unsigned int approved;
97         int ret;
98         unsigned int edp_state;
99         unsigned int i;
100         if (data->pwm_bl_edp_client) {
101                 for (i = 0; i < PWM_BL_EDP_NUM_STATES; i++) {
102                         if (brightness >= data->edp_brightness_states[i])
103                                 break;
104                 }
105                 edp_state = i;
106                 ret = edp_update_client_request(data->pwm_bl_edp_client,
107                                                         edp_state, &approved);
108                 if (ret) {
109                         dev_err(data->dev, "E state transition failed\n");
110                         return ret;
111                 }
112                 pwm_backlight_set(bl, data->edp_brightness_states[approved]);
113         } else {
114                 pwm_backlight_set(bl, brightness);
115         }
116         return 0;
117 }
118
119 static int pwm_backlight_update_status(struct backlight_device *bl)
120 {
121         int brightness = bl->props.brightness;
122         return pwm_backlight_set_with_edp(bl, brightness);
123 }
124
125 static void pwm_backlight_edpcb(unsigned int new_state, void *priv_data)
126 {
127         struct backlight_device *bl_device =
128                 (struct backlight_device *) priv_data;
129         struct pwm_bl_data *data = bl_get_data(bl_device);
130         pwm_backlight_set(bl_device, data->edp_brightness_states[new_state]);
131 }
132
133 static int pwm_backlight_get_brightness(struct backlight_device *bl)
134 {
135         return bl->props.brightness;
136 }
137
138 static int pwm_backlight_check_fb(struct backlight_device *bl,
139                                   struct fb_info *info)
140 {
141         struct pwm_bl_data *pb = bl_get_data(bl);
142
143         return !pb->check_fb || pb->check_fb(pb->dev, info);
144 }
145
146 static const struct backlight_ops pwm_backlight_ops = {
147         .update_status  = pwm_backlight_update_status,
148         .get_brightness = pwm_backlight_get_brightness,
149         .check_fb       = pwm_backlight_check_fb,
150 };
151
152 #ifdef CONFIG_OF
153 static int pwm_backlight_parse_dt(struct device *dev,
154                                   struct platform_pwm_backlight_data *data)
155 {
156         struct device_node *node = dev->of_node;
157         struct property *prop;
158         int length;
159         u32 value;
160         int ret;
161
162         if (!node)
163                 return -ENODEV;
164
165         memset(data, 0, sizeof(*data));
166
167         /* determine the number of brightness levels */
168         prop = of_find_property(node, "brightness-levels", &length);
169         if (!prop)
170                 return -EINVAL;
171
172         data->max_brightness = length / sizeof(u32);
173
174         /* read brightness levels from DT property */
175         if (data->max_brightness > 0) {
176                 size_t size = sizeof(*data->levels) * data->max_brightness;
177
178                 data->levels = devm_kzalloc(dev, size, GFP_KERNEL);
179                 if (!data->levels)
180                         return -ENOMEM;
181
182                 ret = of_property_read_u32_array(node, "brightness-levels",
183                                                  data->levels,
184                                                  data->max_brightness);
185                 if (ret < 0)
186                         return ret;
187
188                 ret = of_property_read_u32(node, "default-brightness-level",
189                                            &value);
190                 if (ret < 0)
191                         return ret;
192
193                 if (value >= data->max_brightness) {
194                         dev_warn(dev, "invalid default brightness level: %u, using %u\n",
195                                  value, data->max_brightness - 1);
196                         value = data->max_brightness - 1;
197                 }
198
199                 data->dft_brightness = value;
200                 data->max_brightness--;
201         }
202
203         /*
204          * TODO: Most users of this driver use a number of GPIOs to control
205          *       backlight power. Support for specifying these needs to be
206          *       added.
207          */
208
209         return 0;
210 }
211
212 static struct of_device_id pwm_backlight_of_match[] = {
213         { .compatible = "pwm-backlight" },
214         { }
215 };
216
217 MODULE_DEVICE_TABLE(of, pwm_backlight_of_match);
218 #else
219 static int pwm_backlight_parse_dt(struct device *dev,
220                                   struct platform_pwm_backlight_data *data)
221 {
222         return -ENODEV;
223 }
224 #endif
225
226 static int pwm_backlight_probe(struct platform_device *pdev)
227 {
228         struct platform_pwm_backlight_data *data = pdev->dev.platform_data;
229         struct platform_pwm_backlight_data defdata;
230         struct backlight_properties props;
231         struct backlight_device *bl;
232         struct pwm_bl_data *pb;
233         struct edp_manager *battery_manager = NULL;
234         unsigned int max;
235         int ret;
236
237         if (!data) {
238                 ret = pwm_backlight_parse_dt(&pdev->dev, &defdata);
239                 if (ret < 0) {
240                         dev_err(&pdev->dev, "failed to find platform data\n");
241                         return ret;
242                 }
243
244                 data = &defdata;
245         }
246
247         if (data->init) {
248                 ret = data->init(&pdev->dev);
249                 if (ret < 0)
250                         return ret;
251         }
252
253         pb = devm_kzalloc(&pdev->dev, sizeof(*pb), GFP_KERNEL);
254         if (!pb) {
255                 dev_err(&pdev->dev, "no memory for state\n");
256                 ret = -ENOMEM;
257                 goto err_alloc;
258         }
259
260         if (data->levels) {
261                 max = data->levels[data->max_brightness];
262                 pb->levels = data->levels;
263         } else
264                 max = data->max_brightness;
265
266         pb->notify = data->notify;
267         pb->notify_after = data->notify_after;
268         pb->check_fb = data->check_fb;
269         pb->exit = data->exit;
270         pb->dev = &pdev->dev;
271         pb->pwm_gpio = data->pwm_gpio;
272         pb->edp_brightness_states = data->edp_brightness;
273
274         pb->pwm = devm_pwm_get(&pdev->dev, NULL);
275         if (IS_ERR(pb->pwm)) {
276                 dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n");
277
278                 pb->pwm = pwm_request(data->pwm_id, "pwm-backlight");
279                 if (IS_ERR(pb->pwm)) {
280                         dev_err(&pdev->dev, "unable to request legacy PWM\n");
281                         ret = PTR_ERR(pb->pwm);
282                         goto err_alloc;
283                 }
284         }
285
286         dev_dbg(&pdev->dev, "got pwm for backlight\n");
287
288         /*
289          * The DT case will set the pwm_period_ns field to 0 and store the
290          * period, parsed from the DT, in the PWM device. For the non-DT case,
291          * set the period from platform data.
292          */
293         if (data->pwm_period_ns > 0)
294                 pwm_set_period(pb->pwm, data->pwm_period_ns);
295
296         pb->period = pwm_get_period(pb->pwm);
297         pb->lth_brightness = data->lth_brightness * (pb->period / max);
298
299         memset(&props, 0, sizeof(struct backlight_properties));
300         props.type = BACKLIGHT_RAW;
301         props.max_brightness = data->max_brightness;
302
303         if (gpio_is_valid(pb->pwm_gpio)) {
304                 ret = gpio_request(pb->pwm_gpio, "disp_bl");
305                 if (ret)
306                         dev_err(&pdev->dev, "backlight gpio request failed\n");
307         }
308
309         bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb,
310                                        &pwm_backlight_ops, &props);
311         if (IS_ERR(bl)) {
312                 dev_err(&pdev->dev, "failed to register backlight\n");
313                 ret = PTR_ERR(bl);
314                 goto err_alloc;
315         }
316
317         if (pb->edp_brightness_states) {
318                 pb->pwm_bl_edp_client = devm_kzalloc(&pdev->dev,
319                                 sizeof(struct edp_client), GFP_KERNEL);
320                 if (IS_ERR_OR_NULL(pb->pwm_bl_edp_client)) {
321                         dev_err(&pdev->dev, "could not allocate edp client\n");
322                         return PTR_ERR(pb->pwm_bl_edp_client);
323                 }
324
325                 strncpy(pb->pwm_bl_edp_client->name,
326                                                 "backlight", EDP_NAME_LEN - 1);
327                 pb->pwm_bl_edp_client->name[EDP_NAME_LEN - 1] = '\0';
328                 pb->pwm_bl_edp_client->states = data->edp_states;
329                 pb->pwm_bl_edp_client->num_states = PWM_BL_EDP_NUM_STATES;
330                 pb->pwm_bl_edp_client->e0_index = PWM_BL_EDP_ZERO;
331                 pb->pwm_bl_edp_client->private_data = bl;
332                 pb->pwm_bl_edp_client->priority = EDP_MAX_PRIO + 2;
333                 pb->pwm_bl_edp_client->throttle = pwm_backlight_edpcb;
334                 pb->pwm_bl_edp_client->notify_promotion = pwm_backlight_edpcb;
335
336                 battery_manager = edp_get_manager("battery");
337                 if (!battery_manager) {
338                         dev_err(&pdev->dev, "unable to get edp manager\n");
339                         goto err_edp_init;
340                 } else {
341                         ret = edp_register_client(battery_manager,
342                                                 pb->pwm_bl_edp_client);
343                         if (ret) {
344                                 dev_err(&pdev->dev, "unable to register edp client\n");
345                                 goto err_edp_init;
346                         } else {
347                                 ret = edp_update_client_request(
348                                                 pb->pwm_bl_edp_client,
349                                                         PWM_BL_EDP_ZERO, NULL);
350                                 if (ret) {
351                                         dev_err(&pdev->dev,
352                                                 "unable to set E0 EDP state\n");
353                                         edp_unregister_client(
354                                                 pb->pwm_bl_edp_client);
355                                         goto err_edp_init;
356                                 }
357                                 goto success_edp_init;
358                         }
359                 }
360 err_edp_init:
361                 devm_kfree(&pdev->dev, pb->pwm_bl_edp_client);
362                 pb->pwm_bl_edp_client = NULL;
363 success_edp_init:;
364         } else {
365                 dev_info(&pdev->dev, "edp manager not supported\n");
366         }
367
368         if (data->dft_brightness > data->max_brightness) {
369                 dev_warn(&pdev->dev,
370                          "invalid default brightness level: %u, using %u\n",
371                          data->dft_brightness, data->max_brightness);
372                 data->dft_brightness = data->max_brightness;
373         }
374
375         bl->props.brightness = data->dft_brightness;
376         backlight_update_status(bl);
377
378         if (gpio_is_valid(pb->pwm_gpio))
379                 gpio_free(pb->pwm_gpio);
380
381         platform_set_drvdata(pdev, bl);
382         return 0;
383
384 err_alloc:
385         if (data->exit)
386                 data->exit(&pdev->dev);
387         return ret;
388 }
389
390 static int pwm_backlight_remove(struct platform_device *pdev)
391 {
392         struct backlight_device *bl = platform_get_drvdata(pdev);
393         struct pwm_bl_data *pb = bl_get_data(bl);
394
395         backlight_device_unregister(bl);
396         pwm_config(pb->pwm, 0, pb->period);
397         pwm_disable(pb->pwm);
398         if (pb->exit)
399                 pb->exit(&pdev->dev);
400         return 0;
401 }
402
403 #ifdef CONFIG_PM_SLEEP
404 static int pwm_backlight_suspend(struct device *dev)
405 {
406         struct backlight_device *bl = dev_get_drvdata(dev);
407
408         return pwm_backlight_set_with_edp(bl, 0);
409 }
410
411 static int pwm_backlight_resume(struct device *dev)
412 {
413         struct backlight_device *bl = dev_get_drvdata(dev);
414
415         backlight_update_status(bl);
416         return 0;
417 }
418
419 static SIMPLE_DEV_PM_OPS(pwm_backlight_pm_ops, pwm_backlight_suspend,
420                          pwm_backlight_resume);
421
422 #endif
423
424 static struct platform_driver pwm_backlight_driver = {
425         .driver         = {
426                 .name           = "pwm-backlight",
427                 .owner          = THIS_MODULE,
428 #ifdef CONFIG_PM_SLEEP
429                 .pm             = &pwm_backlight_pm_ops,
430 #endif
431                 .of_match_table = of_match_ptr(pwm_backlight_of_match),
432         },
433         .probe          = pwm_backlight_probe,
434         .remove         = pwm_backlight_remove,
435 };
436
437 module_platform_driver(pwm_backlight_driver);
438
439 MODULE_DESCRIPTION("PWM based Backlight Driver");
440 MODULE_LICENSE("GPL");
441 MODULE_ALIAS("platform:pwm-backlight");
442