rk31:pmu:rt5025:modify some irq error
[firefly-linux-kernel-4.4.55.git] / drivers / power / rt5025-power.c
1 /* drivers/power/rt5025-power.c
2  * I2C Driver for Richtek RT5025 PMIC
3  * Multi function device - multi functional baseband PMIC Power part
4  *
5  * Copyright (C) 2013
6  * Author: CY Huang <cy_huang@richtek.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/init.h>
16 #include <linux/i2c.h>
17 #include <linux/power_supply.h>
18 #include <linux/platform_device.h>
19 #include <linux/err.h>
20 #include <linux/version.h>
21 #include <linux/slab.h>
22 #include <linux/workqueue.h>
23 #include <linux/mfd/rt5025.h>
24 #include <linux/power/rt5025-power.h>
25 #include <linux/delay.h>
26
27 static struct platform_device *dev_ptr;
28
29
30 static enum power_supply_property rt5025_adap_props[] = {
31         POWER_SUPPLY_PROP_ONLINE,
32 };
33
34 static char *rt5025_supply_list[] = {
35         "rt5025-battery",
36 };
37
38
39 int rt5025_set_charging_current_switch (struct i2c_client *i2c, int onoff)
40 {
41         int ret;
42         if (onoff)
43                 ret = rt5025_set_bits(i2c, RT5025_REG_CHGCTL7, RT5025_CHGCEN_MASK);
44         else
45                 ret = rt5025_clr_bits(i2c, RT5025_REG_CHGCTL7, RT5025_CHGCEN_MASK);
46         return ret;
47 }
48 EXPORT_SYMBOL(rt5025_set_charging_current_switch);
49
50 int rt5025_set_charging_buck(struct i2c_client *i2c, int onoff)
51 {
52         int ret;
53         if (onoff)
54                 ret = rt5025_set_bits(i2c, RT5025_REG_CHGCTL2, RT5025_CHGBUCKEN_MASK);
55         else
56                 ret = rt5025_clr_bits(i2c, RT5025_REG_CHGCTL2, RT5025_CHGBUCKEN_MASK);
57         return ret;
58 }
59 EXPORT_SYMBOL(rt5025_set_charging_buck);
60
61 int rt5025_ext_set_charging_buck(int onoff)
62 {
63         struct rt5025_power_info *pi = platform_get_drvdata(dev_ptr);
64         int ret;
65         if (onoff)
66         {
67                 pi->otg_en = 0;
68                 ret = rt5025_set_bits(pi->i2c, RT5025_REG_CHGCTL2, RT5025_CHGBUCKEN_MASK);
69                 msleep(100);
70         }
71         else
72         {
73                 pi->otg_en = 1;
74                 ret = rt5025_clr_bits(pi->i2c, RT5025_REG_CHGCTL2, RT5025_CHGBUCKEN_MASK);
75                 msleep(100);
76         }
77         return ret;
78 }
79 EXPORT_SYMBOL(rt5025_ext_set_charging_buck);
80
81 static int rt5025_set_charging_current(struct i2c_client *i2c, int cur_value)
82 {
83         int ret = 0;
84         u8 data = 0;
85
86         //ICC Setting
87         #if 0
88         if (cur_value > 2000)
89                 data |= 0x0f<<3;
90         else if (cur_value >= 500 && cur_value <= 2000)
91         {
92                 data = (cur_value-500)/100;
93                 data<<=3;
94         }
95         #endif
96
97         //AICR Setting
98         if (cur_value > 1000)
99                 data |= 0x03<<1;
100         else if (cur_value > 500 && cur_value <= 1000)
101                 data |= 0x02<<1;
102         else if (cur_value > 100 && cur_value >= 500)
103                 data |= 0x01<<1;
104
105         rt5025_assign_bits(i2c, RT5025_REG_CHGCTL4, RT5025_CHGAICR_MASK, data);
106         return ret;
107 }
108
109 static int rt5025_chgstat_changed(struct rt5025_power_info *info, unsigned new_val)
110 {
111         int ret = 0;
112         switch (new_val)
113         {
114                 case 0x00:
115                         #if 0
116                         rt5025_set_charging_current_switch(info->i2c, 1);
117                         rt5025_set_charging_buck(info->i2c, 1);
118                         #endif
119                         info->chg_stat = 0x00;
120                         #if 1
121                         if (info->chip->battery_info)
122                         {
123                                 if (info->chg_term <= 1)
124                                         rt5025_gauge_set_status(info->chip->battery_info, POWER_SUPPLY_STATUS_CHARGING);
125                                 else if (info->chg_term == 2)
126                                 {
127                                         rt5025_gauge_set_status(info->chip->battery_info, POWER_SUPPLY_STATUS_FULL);
128                                         //info->chg_term = 0;
129                                 }
130                                 else if (info->chg_term > 2)
131                                         ;
132                         }
133                         #else
134                         if (info->event_callback)
135                                 info->event_callback->rt5025_gauge_set_status(POWER_SUPPLY_STATUS_CHARGING);
136                         #endif
137                         break;
138                 case 0x01:
139                         //rt5025_set_charging_current_switch(info->i2c, 1);
140                         info->chg_stat = 0x01;
141                         #if 1
142                         if (info->chip->battery_info)
143                         {
144                                 rt5025_gauge_set_status(info->chip->battery_info, POWER_SUPPLY_STATUS_CHARGING);
145                                 info->chg_term = 0;
146                         }
147                         #else
148                         if (info->event_callback)
149                                 info->event_callback->rt5025_gauge_set_status(POWER_SUPPLY_STATUS_CHARGING);
150                         #endif
151                         break;
152                 case 0x02:
153                         #if 0
154                         rt5025_set_charging_current_switch(info->i2c, 0);
155                         #endif
156                         info->chg_stat = 0x02;
157                         #if 1
158                         if (info->chip->battery_info)
159                         {
160                                 rt5025_gauge_set_status(info->chip->battery_info, POWER_SUPPLY_STATUS_FULL);
161                                 info->chg_term = 0;
162                         }
163                         #else
164                         if (info->event_callback)
165                                 info->event_callback->rt5025_gauge_set_status(POWER_SUPPLY_STATUS_FULL);
166                         #endif
167                         break;
168                 case 0x03:
169                         #if 0
170                         rt5025_set_charging_buck(info->i2c, 0);
171                         rt5025_set_charging_current_switch(info->i2c, 0);
172                         #endif
173                         info->chg_stat = 0x03;
174                         #if 1
175                         if (info->chip->battery_info)
176                         {
177                                 if (info->chg_term <= 1)
178                                         rt5025_gauge_set_status(info->chip->battery_info, POWER_SUPPLY_STATUS_CHARGING);
179                                 else if (info->chg_term == 2)
180                                 {
181                                         rt5025_gauge_set_status(info->chip->battery_info, POWER_SUPPLY_STATUS_FULL);
182                                         //info->chg_term = 0;
183                                 }
184                                 else if (info->chg_term > 2)
185                                         ;
186                         }
187                         #else
188                         if (info->event_callback)
189                                 info->event_callback->rt5025_gauge_set_status(POWER_SUPPLY_STATUS_DISCHARGING);
190                         #endif
191                         break;
192                 default:
193                         break;
194         }
195         return ret;
196 }
197
198 #if 0
199 int rt5025_power_passirq_to_gauge(struct rt5025_power_info *info)
200 {
201         if (info->event_callback)
202                 info->event_callback->rt5025_gauge_irq_handler();
203         return 0;
204 }
205 EXPORT_SYMBOL(rt5025_power_passirq_to_gauge);
206 #endif
207
208 int rt5025_power_charge_detect(struct rt5025_power_info *info)
209 {
210         int ret = 0;
211         unsigned char chgstatval = 0;
212         unsigned old_usbval, old_acval, old_chgval, new_usbval, new_acval, new_chgval;
213
214         old_acval = info->ac_online;
215         old_usbval = info->usb_online;
216         old_chgval = info->chg_stat;
217
218         mdelay(50);
219         
220         ret = rt5025_reg_read(info->i2c, RT5025_REG_CHGSTAT);
221         if (ret<0)
222         {
223                 dev_err(info->dev, "read chg stat reg fail\n");
224                 return ret;
225         }
226         chgstatval = ret;
227         RTINFO("chgstat = 0x%02x\n", chgstatval);
228
229         if (info->otg_en)
230         {
231                 ret = rt5025_set_bits(info->i2c, RT5025_REG_CHGCTL2, RT5025_CHGBUCKEN_MASK);
232                 msleep(100);
233         }
234
235         new_acval = (chgstatval&RT5025_CHG_ACONLINE)>>RT5025_CHG_ACSHIFT;
236         if (old_acval != new_acval)
237         {
238                 info->ac_online = new_acval;
239                 power_supply_changed(&info->ac);
240         }
241
242         new_usbval = (info->otg_en? \
243                 0:(chgstatval&RT5025_CHG_USBONLINE)>>RT5025_CHG_USBSHIFT);
244         if (old_usbval != new_usbval)
245         {
246                 info->usb_online = new_usbval;
247                 power_supply_changed(&info->usb);
248         }
249
250         if (info->otg_en && new_acval == 0)
251         {
252                 ret = rt5025_clr_bits(info->i2c, RT5025_REG_CHGCTL2, RT5025_CHGBUCKEN_MASK);
253                 msleep(100);
254         }
255
256         //if (old_acval != new_acval || old_usbval != new_usbval)
257         if (new_acval || new_usbval)
258                 schedule_delayed_work(&info->usb_detect_work, 0); //no delay
259
260         new_chgval = (chgstatval&RT5025_CHGSTAT_MASK)>>RT5025_CHGSTAT_SHIFT;
261         
262         if (new_acval || new_usbval)
263         {
264                 //if (old_chgval != new_chgval)
265                 //{
266                         ret = rt5025_chgstat_changed(info, new_chgval);
267                 //}
268         }
269         else
270         {
271                 #if 0
272                 rt5025_set_charging_buck(info->i2c, 0);
273                 rt5025_set_charging_current_switch(info->i2c, 0);
274                 #endif
275                 info->chg_stat = RT5025_CHGSTAT_UNKNOWN;
276                 if (info->chip->jeita_info)
277                         rt5025_notify_charging_cable(info->chip->jeita_info, JEITA_NO_CHARGE);
278                 #if 1
279                 if (info->chip->battery_info)
280                         rt5025_gauge_set_status(info->chip->battery_info, POWER_SUPPLY_STATUS_DISCHARGING);
281                 #else
282                 if (info->event_callback)
283                         info->event_callback->rt5025_gauge_set_status(POWER_SUPPLY_STATUS_NOT_CHARGING);
284                 #endif
285         }
286
287         return ret;
288 }
289 EXPORT_SYMBOL(rt5025_power_charge_detect);
290
291 static int rt5025_adap_get_props(struct power_supply *psy,
292                                 enum power_supply_property psp,
293                                 union power_supply_propval *val)
294 {
295         struct rt5025_power_info *info = dev_get_drvdata(psy->dev->parent);
296         switch(psp)
297         {
298                 case POWER_SUPPLY_PROP_ONLINE:
299                         if (psy->type == POWER_SUPPLY_TYPE_MAINS)
300                                 val->intval = info->ac_online;
301                         else if (psy->type == POWER_SUPPLY_TYPE_USB)
302                                 val->intval = info->usb_online;
303                         else
304                                 return -EINVAL;
305                         break;
306                 default:
307                         return -EINVAL;
308         }
309         return 0;
310 }
311
312
313 extern int dwc_vbus_status(void);
314
315
316 static void usb_detect_work_func(struct work_struct *work)
317 {
318         struct delayed_work *delayed_work = (struct delayed_work *)container_of(work, struct delayed_work, work);
319         struct rt5025_power_info *pi = (struct rt5025_power_info *)container_of(delayed_work, struct rt5025_power_info, usb_detect_work);
320         
321         RTINFO("rt5025: %s ++", __func__);
322
323         mutex_lock(&pi->var_lock);
324         if (pi->ac_online)
325         {
326                 rt5025_set_charging_current(pi->i2c, 2000);
327                 rt5025_notify_charging_cable(pi->chip->jeita_info, JEITA_AC_ADAPTER);
328                 pi->usb_cnt = 0;
329         }
330         else if (pi->usb_online)
331         {
332                 RTINFO("%s: usb_cnt %d\n", __func__, pi->usb_cnt);
333                 switch(dwc_vbus_status())
334                 {
335                         case 2: // USB Wall charger
336                                 rt5025_set_charging_current(pi->i2c, 2000);
337                                 rt5025_notify_charging_cable(pi->chip->jeita_info, JEITA_USB_TA);
338                                 RTINFO("rt5025: detect usb wall charger\n");
339                                 break;
340                         case 1: //normal USB
341                         default:
342                                 rt5025_set_charging_current(pi->i2c, 2000);
343                                 rt5025_notify_charging_cable(pi->chip->jeita_info, JEITA_NORMAL_USB);
344                                 RTINFO("rt5025: detect normal usb\n");
345                                 break;
346                 }
347                 if (pi->usb_cnt++ < 60)
348                         schedule_delayed_work(&pi->usb_detect_work, 1*HZ);
349         }
350         else
351         {
352                 //default to prevent over current charging
353                 rt5025_set_charging_current(pi->i2c, 500);
354                 rt5025_notify_charging_cable(pi->chip->jeita_info, JEITA_NO_CHARGE);
355                 //reset usb_cnt;
356                 pi->usb_cnt = 0;
357         }
358         mutex_unlock(&pi->var_lock);
359
360         RTINFO("rt5025: %s --", __func__);
361 }
362
363 static int __devinit rt5025_init_charger(struct rt5025_power_info *info, struct rt5025_power_data* pd)
364 {
365         //unsigned char data;
366         info->ac_online = 0;
367         info->usb_online =0;
368         //init charger buckck & charger current en to disable stat
369         info->chg_stat = RT5025_CHGSTAT_UNKNOWN;
370         #if 0
371         if (info->event_callback)
372                 info->event_callback->rt5025_gauge_set_status(POWER_SUPPLY_STATUS_DISCHARGING);
373         #endif
374         //rt5025_set_bits(info->i2c, RT5025_REG_CHGCTL4, RT5025_CHGRST_MASK);
375         //udelay(200);
376         //init register setting
377         rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL2, pd->CHGControl2.val);
378         rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL3, pd->CHGControl3.val);
379         rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL4, pd->CHGControl4.val);
380         rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL5, pd->CHGControl5.val);
381         rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL6, pd->CHGControl6.val);
382         //rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL7, pd->CHGControl7.val);
383         rt5025_assign_bits(info->i2c, RT5025_REG_CHGCTL7, 0xEF, pd->CHGControl7.val);
384         rt5025_reg_write(info->i2c, 0xA9, 0x60 );
385         //Special buck setting
386         #if 0
387         //Buck 1
388         data = rt5025_reg_read(info->i2c, 0x47);
389         data ^=0xc2;
390         rt5025_reg_write(info->i2c, 0x47, data);
391         //Buck 2
392         data = rt5025_reg_read(info->i2c, 0x48);
393         data ^=0xc2;
394         rt5025_reg_write(info->i2c, 0x48, data);
395         //Buck 3
396         data = rt5025_reg_read(info->i2c, 0x49);
397         data ^=0xc2;
398         rt5025_reg_write(info->i2c, 0x49, data);
399         #endif  //#if 0
400         
401         rt5025_power_charge_detect(info);
402
403         return 0;
404 }
405
406 static int __devinit rt5025_power_probe(struct platform_device *pdev)
407 {
408         struct rt5025_chip *chip = dev_get_drvdata(pdev->dev.parent);
409         struct rt5025_platform_data *pdata = chip->dev->platform_data;
410         struct rt5025_power_info *pi;
411         int ret = 0;
412         
413         pi = kzalloc(sizeof(*pi), GFP_KERNEL);
414         if (!pi)
415                 return -ENOMEM;
416
417         pi->i2c = chip->i2c;
418         pi->dev = &pdev->dev;
419         pi->chip = chip;
420         mutex_init(&pi->var_lock);
421         INIT_DELAYED_WORK(&pi->usb_detect_work, usb_detect_work_func);
422
423         #if 0
424         ret = rt5025_gauge_init(pi);
425         if (ret)
426                 goto out;
427         #endif
428
429         platform_set_drvdata(pdev, pi);
430         dev_ptr = pdev;
431
432         pi->ac.name = "rt5025-dc";
433         pi->ac.type = POWER_SUPPLY_TYPE_MAINS;
434         pi->ac.supplied_to = rt5025_supply_list;
435         pi->ac.properties = rt5025_adap_props;
436         pi->ac.num_properties = ARRAY_SIZE(rt5025_adap_props);
437         pi->ac.get_property = rt5025_adap_get_props;
438         ret = power_supply_register(&pdev->dev, &pi->ac);
439         if (ret)
440                 goto out;
441
442         pi->usb.name = "rt5025-usb";
443         pi->usb.type = POWER_SUPPLY_TYPE_USB;
444         pi->ac.supplied_to = rt5025_supply_list;
445         pi->usb.properties = rt5025_adap_props;
446         pi->usb.num_properties = ARRAY_SIZE(rt5025_adap_props);
447         pi->usb.get_property = rt5025_adap_get_props;
448         ret = power_supply_register(&pdev->dev, &pi->usb);
449         if (ret)
450                 goto out_usb;
451
452         rt5025_init_charger(pi, pdata->power_data);
453         chip->power_info = pi;
454
455         pr_info("rt5025-power driver is successfully loaded\n");
456
457         return ret;
458 out_usb:
459         power_supply_unregister(&pi->ac);
460 out:
461         kfree(pi);
462
463         return ret;
464 }
465
466 static int rt5025_power_suspend(struct platform_device *pdev, pm_message_t state)
467 {
468         #if 0
469         struct rt5025_power_info *pi = platform_get_drvdata(pdev);
470
471         if (pi->event_callback)
472                 pi->event_callback->rt5025_gauge_suspend();
473         #endif
474         RTINFO("\n");
475         return 0;
476 }
477
478 static int rt5025_power_resume(struct platform_device *pdev)
479 {
480         #if 0
481         struct rt5025_power_info *pi = platform_get_drvdata(pdev);
482
483         if (pi->event_callback)
484                 pi->event_callback->rt5025_gauge_resume();
485         #endif
486         RTINFO("\n");
487         return 0;
488 }
489
490 static int __devexit rt5025_power_remove(struct platform_device *pdev)
491 {
492         struct rt5025_power_info *pi = platform_get_drvdata(pdev);
493         struct rt5025_chip *chip = dev_get_drvdata(pdev->dev.parent);
494
495         #if 0
496         if (pi->event_callback)
497                 pi->event_callback->rt5025_gauge_remove();
498         #endif
499         power_supply_unregister(&pi->usb);
500         power_supply_unregister(&pi->ac);
501         chip->power_info = NULL;
502         kfree(pi);
503         RTINFO("\n");
504
505         return 0;
506 }
507
508 static struct platform_driver rt5025_power_driver = 
509 {
510         .driver = {
511                 .name = RT5025_DEVICE_NAME "-power",
512                 .owner = THIS_MODULE,
513         },
514         .probe = rt5025_power_probe,
515         .remove = __devexit_p(rt5025_power_remove),
516         .suspend = rt5025_power_suspend,
517         .resume = rt5025_power_resume,
518 };
519
520 static int __init rt5025_power_init(void)
521 {
522         return platform_driver_register(&rt5025_power_driver);
523 }
524 late_initcall_sync(rt5025_power_init);
525
526 static void __exit rt5025_power_exit(void)
527 {
528         platform_driver_unregister(&rt5025_power_driver);
529 }
530 module_exit(rt5025_power_exit);
531
532
533 MODULE_LICENSE("GPL v2");
534 MODULE_AUTHOR("CY Huang <cy_huang@richtek.com");
535 MODULE_DESCRIPTION("Power/Gauge driver for RT5025");
536 MODULE_ALIAS("platform:" RT5025_DEVICE_NAME "-power");
537 MODULE_VERSION(RT5025_DRV_VER);