2 * Backlight driver for Wolfson Microelectronics WM831x PMICs
4 * Copyright 2009 Wolfson Microelectonics plc
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/platform_device.h>
15 #include <linux/backlight.h>
16 #include <linux/slab.h>
17 #include <mach/gpio.h>
18 #ifdef CONFIG_HAS_EARLYSUSPEND
19 #include <linux/earlysuspend.h>
21 #include <linux/delay.h>
22 #include <linux/ktime.h>
23 #include "aw9364_bl.h"
29 #define DBG(x...) printk(KERN_INFO x)
35 #define BL_INIT_VALUE 102
36 struct aw9364_backlight_data {
38 int current_brightness;
39 #ifdef CONFIG_HAS_EARLYSUSPEND
40 struct early_suspend early_suspend;
41 struct delayed_work work;
49 #ifdef CONFIG_HAS_EARLYSUSPEND
50 static struct backlight_device *g_aw9364_bl;
51 static struct aw9364_backlight_data *g_aw9364_data;
54 static int aw9364_backlight_set(struct backlight_device *bl, int brightness)
56 struct aw9364_backlight_data *data = bl_get_data(bl);
57 int i,num_clk, num_clk_to, num_clk_from;
60 brightness = brightness & 0xff; //0-256
62 num_clk_from = 16 -(data->current_brightness>>4);
63 num_clk_to = 16 -(brightness>>4);
64 num_clk = (16 + num_clk_to - num_clk_from)%16;
69 gpio_direction_output(data->pin_en, GPIO_LOW);
73 spin_lock_irqsave(&data->bl_lock, flags);
74 for(i=0; i<num_clk; i++) //the wave should not be intterupted
76 gpio_set_value(data->pin_en, GPIO_LOW);
77 gpio_set_value(data->pin_en, GPIO_HIGH);
81 spin_unlock_irqrestore(&data->bl_lock, flags);
84 DBG("%s:current_bl=%d,bl=%d,num_clk_to=%d,num_clk_from=%d,num_clk=%d\n",__FUNCTION__,
85 data->current_brightness,brightness,num_clk_to,num_clk_from,num_clk);
87 if((num_clk) || (brightness < 16))
88 data->current_brightness = brightness;
95 static int aw9364_backlight_update_status(struct backlight_device *bl)
98 int brightness = bl->props.brightness;
100 if(g_aw9364_data->suspend_flag == 1)
103 if (g_aw9364_data->shutdown_flag == 1)
106 if (bl->props.power != FB_BLANK_UNBLANK)
109 if (bl->props.fb_blank != FB_BLANK_UNBLANK)
112 if (bl->props.state & BL_CORE_SUSPENDED)
115 DBG("backlight brightness=%d\n", brightness);
117 return aw9364_backlight_set(bl, brightness);
120 static int aw9364_backlight_get_brightness(struct backlight_device *bl)
122 struct aw9364_backlight_data *data = bl_get_data(bl);
123 return data->current_brightness;
126 static struct backlight_ops aw9364_backlight_ops = {
127 .options = BL_CORE_SUSPENDRESUME,
128 .update_status = aw9364_backlight_update_status,
129 .get_brightness = aw9364_backlight_get_brightness,
131 #ifdef CONFIG_HAS_EARLYSUSPEND
132 static void aw9364_bl_work(struct work_struct *work)
134 //struct aw9364_backlight_data *aw9364_data = container_of(work, struct aw9364_backlight_data,
136 backlight_update_status(g_aw9364_bl);
139 static void aw9364_bl_suspend(struct early_suspend *h)
141 struct aw9364_backlight_data *aw9364_data;
142 aw9364_data = container_of(h, struct aw9364_backlight_data, early_suspend);
143 aw9364_data->suspend_flag = 1;
145 schedule_delayed_work(&aw9364_data->work, msecs_to_jiffies(100));
149 static void aw9364_bl_resume(struct early_suspend *h)
151 struct aw9364_backlight_data *aw9364_data;
152 aw9364_data = container_of(h, struct aw9364_backlight_data, early_suspend);
153 aw9364_data->suspend_flag = 0;
155 schedule_delayed_work(&aw9364_data->work, msecs_to_jiffies(100));
162 int rk29_backlight_ctrl(int open)
165 g_aw9364_data->suspend_flag = 0;
167 g_aw9364_data->suspend_flag = 1;
169 backlight_update_status(g_aw9364_bl);
173 static int aw9364_backlight_probe(struct platform_device *pdev)
175 struct aw9364_backlight_data *data;
176 struct aw9364_platform_data *pdata = pdev->dev.platform_data;
177 struct backlight_device *bl;
179 data = kzalloc(sizeof(*data), GFP_KERNEL);
183 if(pdata && pdata->io_init)
186 data->current_brightness = 0;
187 data->pin_en = pdata->pin_en;
190 bl = backlight_device_register("wm831x", &pdev->dev, data,
191 &aw9364_backlight_ops, NULL);
193 dev_err(&pdev->dev, "failed to register backlight\n");
198 bl->props.brightness = BL_INIT_VALUE;
199 bl->props.max_brightness= BL_SET;
201 if(data && data->pin_en)
202 gpio_request(data->pin_en, NULL);
206 spin_lock_init(&data->bl_lock);
208 platform_set_drvdata(pdev, bl);
210 #ifdef CONFIG_HAS_EARLYSUSPEND
211 data->early_suspend.level = ~0x0;
212 data->early_suspend.suspend = aw9364_bl_suspend;
213 data->early_suspend.resume = aw9364_bl_resume;
214 register_early_suspend(&data->early_suspend);
215 INIT_DELAYED_WORK(&data->work, aw9364_bl_work);
217 g_aw9364_data = data;
220 gpio_direction_output(data->pin_en, GPIO_LOW);
223 backlight_update_status(bl);
224 schedule_delayed_work(&data->work, msecs_to_jiffies(100));
226 printk("%s\n",__FUNCTION__);
231 static int aw9364_backlight_remove(struct platform_device *pdev)
233 struct backlight_device *bl = platform_get_drvdata(pdev);
234 struct aw9364_backlight_data *data = bl_get_data(bl);
236 backlight_device_unregister(bl);
237 #ifdef CONFIG_HAS_EARLYSUSPEND
238 unregister_early_suspend(&data->early_suspend);
244 static void aw9364_backlight_shutdown(struct platform_device *pdev)
246 struct backlight_device *bl = platform_get_drvdata(pdev);
247 struct aw9364_backlight_data *data = bl_get_data(bl);
249 printk("%s\n",__FUNCTION__);
250 data->shutdown_flag = 1;
251 aw9364_backlight_update_status(bl);
255 static struct platform_driver aw9364_backlight_driver = {
257 .name = "aw9364_backlight",
258 .owner = THIS_MODULE,
260 .probe = aw9364_backlight_probe,
261 .remove = aw9364_backlight_remove,
262 .shutdown = aw9364_backlight_shutdown,
265 static int __init aw9364_backlight_init(void)
267 return platform_driver_register(&aw9364_backlight_driver);
269 module_init(aw9364_backlight_init);
271 static void __exit aw9364_backlight_exit(void)
273 platform_driver_unregister(&aw9364_backlight_driver);
275 module_exit(aw9364_backlight_exit);
277 MODULE_DESCRIPTION("Backlight Driver for AW9364");
278 MODULE_AUTHOR("luo wei <lw@rock-chips.com");
279 MODULE_LICENSE("GPL");
280 MODULE_ALIAS("platform:aw9364-backlight");