UPSTREAM: PCI: rockchip: remove the pointer to L1 substate cap
[firefly-linux-kernel-4.4.55.git] / drivers / power / wm831x_charger_display.c
1 /* drivers/power/wm831x_charger_display.c
2  *
3  * battery detect driver for the rk2818 
4  *
5  * This software is licensed under the terms of the GNU General Public
6  * License version 2, as published by the Free Software Foundation, and
7  * may be copied, distributed, and modified under those terms.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  */
15 #include <linux/module.h>
16 #include <linux/init.h>
17 #include <linux/slab.h>
18 #include <linux/kernel.h>
19 #include <linux/errno.h>
20 #include <linux/input.h>
21 #include <linux/interrupt.h>
22 #include <linux/fb.h>
23 #include <linux/delay.h>
24 #include <linux/suspend.h>
25 #include <linux/linux_logo.h>
26 #include <linux/regulator/consumer.h>
27 #include <linux/platform_device.h>
28 #include <linux/workqueue.h>
29 #include <linux/mfd/wm831x/core.h>
30 #include <mach/gpio.h>
31 #include <mach/iomux.h>
32 #include <mach/rk29_iomap.h>
33
34 #include <linux/mfd/wm831x/core.h>
35 #include <linux/mfd/wm831x/auxadc.h>
36 #include <linux/mfd/wm831x/pmu.h>
37 #include <linux/mfd/wm831x/pdata.h>
38 #include <linux/mfd/wm831x/irq.h>
39 #include <linux/power_supply.h>
40
41 #define READ_ON_PIN_CNT 20/*11*/
42 #define BACKLIGHT_CNT   2
43 #define OPEN_CNT                18
44 #define MC_OPEN 7/*10*/ 
45 #define BAT_CHARGING    1
46 #define BAT_DISCHARGING 0
47 #define BL_DELAY_TIME   (8*1000)
48
49
50 #define SET_BACKLIGHT_ON        1
51 #define OPEN_SYSTEM                     2
52 #define SUSPEND_SYSTEM          3
53
54 #if 0
55 #define DBG(x...)   printk(x)
56 #else
57 #define DBG(x...)
58 #endif 
59
60 extern void request_suspend_state(suspend_state_t new_state);
61 extern void kernel_restart(char *cmd);
62 extern void kernel_power_off(void);
63
64 extern unsigned g_vbus_status_register;
65 extern unsigned long *g_pcd_for_charger;
66
67 extern int rk29_backlight_ctrl(int open);
68
69 extern void fb_show_charge_logo(struct linux_logo *logo);
70
71 extern void kernel_restart_prepare(char *cmd);
72 extern int dwc_vbus_status( void );
73 extern int dwc_otg_pcd_check_vbus_detech( unsigned long pdata );
74
75 #if defined(CONFIG_LOGO_CHARGER_CLUT224)
76 extern struct linux_logo logo_charger01_clut224;
77 extern struct linux_logo logo_charger02_clut224;
78 extern struct linux_logo logo_charger03_clut224;
79 extern struct linux_logo logo_charger04_clut224;
80 extern struct linux_logo logo_charger05_clut224;
81 extern struct linux_logo logo_charger06_clut224;
82 extern struct linux_logo logo_charger07_clut224;
83 extern struct linux_logo logo_charger08_clut224;
84 #endif
85
86 extern struct fb_info *g_fb0_inf;
87
88 static struct linux_logo* g_chargerlogo[8]= {
89 #if defined(CONFIG_LOGO_CHARGER_CLUT224)
90         &logo_charger01_clut224,&logo_charger02_clut224,&logo_charger03_clut224,&logo_charger04_clut224,
91                 &logo_charger05_clut224,&logo_charger06_clut224,&logo_charger07_clut224,&logo_charger08_clut224
92 #endif
93 };
94
95 #if 1
96 struct wm831x_chg {
97         struct wm831x *wm831x;
98         int logo_id;
99         int flag_chg;
100         int bat_vol;
101         int cnt_on;
102         int cnt_disp;
103         int flag_bl;
104         int flag_suspend;
105         
106 };
107
108 static int charger_logo_display(struct linux_logo *logo)
109 {
110         fb_show_charge_logo(logo);
111         fb_show_logo(g_fb0_inf, 0);
112         return 0;
113 }
114
115 extern int charger_suspend(void);//xsf
116
117 static int charger_backlight_ctrl(int open)
118 {
119         DBG("%s:open=%d\n",__FUNCTION__,open);
120         int ret;
121
122 #ifdef CONFIG_RK29_CHARGE_EARLYSUSPEND
123         charger_suspend();
124         return 0;
125 #else
126         return rk29_backlight_ctrl(open);
127 #endif
128
129
130 }
131
132 static int wm831x_read_on_pin_status(struct wm831x_chg *wm831x_chg)
133 {
134         int ret;
135         
136         if(!wm831x_chg)
137         {
138                 printk("err:%s:wm831x_chg address is 0\n",__FUNCTION__);
139                 return -1;
140         }
141         
142         ret = wm831x_reg_read(wm831x_chg->wm831x, WM831X_ON_PIN_CONTROL);
143         if (ret < 0)
144                 return ret;
145
146         return !(ret & WM831X_ON_PIN_STS) ? 1 : 0;
147 }
148
149
150 static int wm831x_read_chg_status(struct wm831x_chg *wm831x_chg)
151 {
152         int ret, usb_chg = 0, wall_chg = 0;
153         
154         if(!wm831x_chg)
155         {
156                 printk("err:%s:wm831x_chg address is 0\n",__FUNCTION__);
157                 return -1;
158         }
159         
160         ret = wm831x_reg_read(wm831x_chg->wm831x, WM831X_SYSTEM_STATUS);
161         if (ret < 0)
162                 return ret;
163
164         if (ret & WM831X_PWR_USB)
165                 usb_chg = 1;
166         if (ret & WM831X_PWR_WALL)
167                 wall_chg = 1;
168
169         return ((usb_chg | wall_chg) ? 1 : 0);
170 }
171
172 static int wm831x_bat_check_status(struct wm831x *wm831x, int *status)
173 {
174         int ret;
175
176         ret = wm831x_reg_read(wm831x, WM831X_SYSTEM_STATUS);
177         if (ret < 0)
178                 return ret;
179
180         if (ret & WM831X_PWR_SRC_BATT) {
181                 *status = POWER_SUPPLY_STATUS_DISCHARGING;
182                 return 0;
183         }
184
185         ret = wm831x_reg_read(wm831x, WM831X_CHARGER_STATUS);
186         if (ret < 0)
187                 return ret;
188
189         
190         switch (ret & WM831X_CHG_STATE_MASK) {
191         case WM831X_CHG_STATE_OFF:
192                 *status = POWER_SUPPLY_STATUS_NOT_CHARGING;
193                 break;
194         case WM831X_CHG_STATE_TRICKLE:
195         case WM831X_CHG_STATE_FAST:
196                 *status = POWER_SUPPLY_STATUS_CHARGING;
197                 break;
198
199         default:
200                 *status = POWER_SUPPLY_STATUS_UNKNOWN;
201                 break;
202         }
203
204         return 0;
205 }
206
207 static int wm831x_read_bat_charging_status(struct wm831x_chg *wm831x_chg)
208 {
209         int ret, status;
210         
211         if(!wm831x_chg)
212         {
213                 printk("err:%s:g_wm831x_power address is 0\n",__FUNCTION__);
214                 return -1;
215         }
216         
217         ret = wm831x_bat_check_status(wm831x_chg->wm831x, &status);
218         if (ret < 0)
219                 return ret;
220         if (status == POWER_SUPPLY_STATUS_CHARGING) 
221                 return 1;
222         return 0;
223 }
224
225 static int wm831x_read_batt_voltage(struct wm831x_chg *wm831x_chg)
226 {
227         int ret = 0;
228         
229         if(!wm831x_chg)
230         {
231                 printk("err:%s:wm831x_chg address is 0\n",__FUNCTION__);
232                 return -1;
233         }
234         
235         ret = wm831x_auxadc_read_uv(wm831x_chg->wm831x, WM831X_AUX_BATT);
236         return ret / 1000;
237 }
238
239
240 static int get_charger_logo_start_num(struct wm831x_chg *wm831x_chg)
241 {
242         int rlogonum, bat_vol;
243
244         /*check charger voltage*/
245         bat_vol = wm831x_read_batt_voltage(wm831x_chg);
246         if(bat_vol <= 3610) {
247                 rlogonum = 0;
248         }
249         else if(bat_vol <= 3700) {
250                 rlogonum = 1;
251         }
252         else if(bat_vol <= 3760) {
253                 rlogonum = 2;
254         }
255         else if(bat_vol <= 3840) {
256                 rlogonum = 3;
257         }
258         else if(bat_vol <= 3900) {
259                 rlogonum = 4;
260         }
261         else if(bat_vol <= 3990) {
262                 rlogonum = 5;
263         }
264         else if(bat_vol <= 4130) {
265                 rlogonum = 6;
266         }
267         else if(bat_vol <= 4200) {
268                 rlogonum = 7;
269         }
270         else{
271                 rlogonum = 7;
272         }
273                 
274         return rlogonum;
275 }
276
277 static int wm831x_check_on_pin(struct wm831x_chg *wm831x_chg)
278 {
279         int ret;
280         ret = wm831x_read_on_pin_status(wm831x_chg);
281         if(ret)
282         {
283                 if(wm831x_chg->cnt_on++ > 1000)
284                         wm831x_chg->cnt_on = 1000;
285         }
286         else
287         {
288                 //control backlight if press on pin
289                 if(wm831x_chg->cnt_on >= 1)
290                 {
291                         wm831x_chg->flag_bl = !wm831x_chg->flag_bl;
292                         charger_backlight_ctrl(wm831x_chg->flag_bl);
293                         wm831x_chg->cnt_on = 0; 
294                         if(wm831x_chg->flag_bl)
295                         {
296                                 wm831x_chg->flag_suspend = 0;
297                                 wm831x_chg->cnt_disp = 0;
298                         }
299                 }
300         }
301
302         return 0;
303 }
304
305 static int rk29_charger_display(struct wm831x_chg *wm831x_chg)
306 {
307         int status;
308         struct linux_logo* chargerlogo[8];
309         int ret,i;
310         int count = 0;
311         
312         wm831x_chg->flag_chg = wm831x_read_chg_status(wm831x_chg);
313         if(!wm831x_chg->flag_chg)
314                 return -1;
315
316         while(1)
317         {
318                 wm831x_chg->flag_chg = wm831x_read_chg_status(wm831x_chg);
319                 if(!wm831x_chg->flag_chg)
320                         kernel_power_off();
321
322                 status = wm831x_read_bat_charging_status(wm831x_chg);
323
324                 for(i=0; i<8; i++)
325                 chargerlogo[i] = g_chargerlogo[i];
326         
327                 if(status == BAT_CHARGING)
328                 {       
329                         for(i=get_charger_logo_start_num(wm831x_chg); i<8; i++ )
330                         {
331                                 wm831x_chg->flag_chg = wm831x_read_chg_status(wm831x_chg);
332                                 if(!wm831x_chg->flag_chg)
333                                 kernel_power_off();
334                         #ifdef CONFIG_RK29_CHARGE_EARLYSUSPEND
335                                 ret = charger_logo_display(chargerlogo[i]);
336                         #else
337                                 if(wm831x_chg->flag_bl != 0)
338                                 ret = charger_logo_display(chargerlogo[i]);
339                         #endif
340                                 DBG("%s:i=%d\n",__FUNCTION__,i);
341
342                                 msleep(200);    
343                                 wm831x_check_on_pin(wm831x_chg);
344                                 msleep(200);
345                                 wm831x_check_on_pin(wm831x_chg);
346
347                         }
348                                         
349                 }
350                 else if(status == BAT_DISCHARGING)
351                 {
352
353                 #ifdef CONFIG_RK29_CHARGE_EARLYSUSPEND
354                         charger_logo_display(chargerlogo[7]);
355                 #else
356                         if(wm831x_chg->flag_bl != 0)
357                         charger_logo_display(chargerlogo[7]);
358                 #endif
359                         msleep(200);
360                         wm831x_check_on_pin(wm831x_chg);
361                         msleep(200);
362                         wm831x_check_on_pin(wm831x_chg);
363                 }
364                 
365                 //suspend when timeout(about 50*200ms)
366                 if(wm831x_chg->cnt_disp++ > 50)
367                 {
368                         if(wm831x_chg->flag_suspend == 0)
369                         {
370                                 wm831x_chg->flag_suspend = 1;
371                                 wm831x_chg->cnt_disp = 0;
372                                 wm831x_chg->flag_bl = 0;
373                                 charger_backlight_ctrl(wm831x_chg->flag_bl);
374                 #ifdef CONFIG_RK29_CHARGE_EARLYSUSPEND
375                                 wm831x_chg->flag_suspend = 0;
376                 #endif
377
378                         }
379                         wm831x_chg->cnt_disp = 0;
380                 }
381
382                 printk("%s,status=%d,cnt_on=%d,cnt_disp=%d\n",__FUNCTION__,status,wm831x_chg->cnt_on,wm831x_chg->cnt_disp);
383
384                 //open system if long time press
385                 if(wm831x_chg->cnt_on > 4)
386                 {
387                         wm831x_chg->cnt_on = 0;
388                         wm831x_chg->flag_bl = 1;
389                         charger_backlight_ctrl(wm831x_chg->flag_bl);
390                         wm831x_chg->flag_suspend = 0;
391                         wm831x_chg->cnt_disp = 0;
392                         break;
393                 }       
394                 
395         }
396
397         return 0;
398
399 }
400 int charge_status;
401 static irqreturn_t wm831x_charge_irq(int irq, void *data)
402 {
403
404         printk("wm831x_charge_irqxxaddxsf\n");
405         return IRQ_HANDLED;
406
407
408 }
409 extern struct wm831x_on *g_wm831x_on;
410  irqreturn_t wm831x_on_irq(int irq, void *data);
411
412 static int __devinit wm831x_chg_probe(struct platform_device *pdev)
413 {
414         struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);;
415         struct wm831x_chg *wm831x_chg;
416
417 //      struct wm831x_on *wm831x_on = container_of(wm831x,struct wm831x_on,*(wm831x));
418
419
420         int ret;
421         
422         wm831x_chg = kzalloc(sizeof(struct wm831x_chg), GFP_KERNEL);
423         if (!wm831x_chg) {
424                 dev_err(&pdev->dev, "Can't allocate data\n");
425                 return -ENOMEM;
426         }
427         charge_status = 1;
428         printk("%s:start\n",__FUNCTION__);
429         wm831x_chg->wm831x = wm831x;
430         wm831x_chg->flag_chg = 0;
431         wm831x_chg->logo_id = 0;
432         wm831x_chg->flag_bl = 1;
433         wm831x_chg->cnt_on = 0;
434         wm831x_chg->flag_suspend = 0;
435         platform_set_drvdata(pdev, wm831x_chg);
436
437 #ifdef CONFIG_RK29_CHARGE_EARLYSUSPEND
438         wm831x_chg->flag_chg = wm831x_read_chg_status(wm831x_chg);
439         if(wm831x_chg->flag_chg != 0)
440         {
441                 free_irq(wm831x_chg->wm831x->irq_base + WM831X_IRQ_ON,g_wm831x_on);
442                 request_threaded_irq(wm831x_chg->wm831x->irq_base + WM831X_IRQ_ON,
443                                                 NULL, wm831x_charge_irq,IRQF_TRIGGER_RISING, "wm831x_charge",
444                                            wm831x_chg);
445
446                 ret = rk29_charger_display(wm831x_chg);
447
448
449                 free_irq(wm831x_chg->wm831x->irq_base + WM831X_IRQ_ON,wm831x_chg);
450                 request_threaded_irq(wm831x_chg->wm831x->irq_base + WM831X_IRQ_ON,
451                         NULL, wm831x_on_irq,IRQF_TRIGGER_RISING, "wm831x_on",  g_wm831x_on);
452         }
453 #else
454         disable_irq_nosync(wm831x_chg->wm831x->irq_base + WM831X_IRQ_ON);
455         ret = rk29_charger_display(wm831x_chg);
456         enable_irq(wm831x_chg->wm831x->irq_base + WM831X_IRQ_ON);
457 #endif
458         wm831x_chg->flag_chg = 0;
459         wm831x_chg->flag_bl = 1;
460         wm831x_chg->cnt_on = 0;
461         wm831x_chg->flag_suspend = 0;
462         charge_status = 0;
463         printk("%s:exit\n",__FUNCTION__);
464         return 0;
465
466 }
467
468
469 static int __devexit wm831x_chg_remove(struct platform_device *pdev)
470 {
471         struct wm831x_chg *wm831x_chg = platform_get_drvdata(pdev);
472
473         kfree(wm831x_chg);
474
475         return 0;
476 }
477
478 static struct platform_driver wm831x_chg_driver = {
479         .probe          = wm831x_chg_probe,
480         .remove         = __devexit_p(wm831x_chg_remove),
481         .driver         = {
482                 .name   = "wm831x_charger_display",
483                 .owner  = THIS_MODULE,
484         },
485 };
486
487 static int __init wm831x_chg_init(void)
488 {
489         return platform_driver_register(&wm831x_chg_driver);
490 }
491 late_initcall(wm831x_chg_init);
492
493 static void __exit wm831x_chg_exit(void)
494 {
495         platform_driver_unregister(&wm831x_chg_driver);
496 }
497 module_exit(wm831x_chg_exit);
498 #endif
499
500
501 MODULE_LICENSE("GPL");
502 MODULE_AUTHOR("linjh<linjh@rock-chips.com>");
503 MODULE_DESCRIPTION("charger display");