85d089e9dcdb217e26b792843ae4707cf404a5dc
[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                 schedule_delayed_work(&info->usb_detect_work, 0); //no delay
258
259         new_chgval = (chgstatval&RT5025_CHGSTAT_MASK)>>RT5025_CHGSTAT_SHIFT;
260         
261         if (new_acval || new_usbval)
262         {
263                 //if (old_chgval != new_chgval)
264                 //{
265                         ret = rt5025_chgstat_changed(info, new_chgval);
266                 //}
267         }
268         else
269         {
270                 #if 0
271                 rt5025_set_charging_buck(info->i2c, 0);
272                 rt5025_set_charging_current_switch(info->i2c, 0);
273                 #endif
274                 info->chg_stat = RT5025_CHGSTAT_UNKNOWN;
275                 if (info->chip->jeita_info)
276                         rt5025_notify_charging_cable(info->chip->jeita_info, JEITA_NO_CHARGE);
277                 #if 1
278                 if (info->chip->battery_info)
279                         rt5025_gauge_set_status(info->chip->battery_info, POWER_SUPPLY_STATUS_DISCHARGING);
280                 #else
281                 if (info->event_callback)
282                         info->event_callback->rt5025_gauge_set_status(POWER_SUPPLY_STATUS_NOT_CHARGING);
283                 #endif
284         }
285
286         return ret;
287 }
288 EXPORT_SYMBOL(rt5025_power_charge_detect);
289
290 static int rt5025_adap_get_props(struct power_supply *psy,
291                                 enum power_supply_property psp,
292                                 union power_supply_propval *val)
293 {
294         struct rt5025_power_info *info = dev_get_drvdata(psy->dev->parent);
295         switch(psp)
296         {
297                 case POWER_SUPPLY_PROP_ONLINE:
298                         if (psy->type == POWER_SUPPLY_TYPE_MAINS)
299                                 val->intval = info->ac_online;
300                         else if (psy->type == POWER_SUPPLY_TYPE_USB)
301                                 val->intval = info->usb_online;
302                         else
303                                 return -EINVAL;
304                         break;
305                 default:
306                         return -EINVAL;
307         }
308         return 0;
309 }
310
311
312 extern int dwc_vbus_status(void);
313
314
315 static void usb_detect_work_func(struct work_struct *work)
316 {
317         struct delayed_work *delayed_work = (struct delayed_work *)container_of(work, struct delayed_work, work);
318         struct rt5025_power_info *pi = (struct rt5025_power_info *)container_of(delayed_work, struct rt5025_power_info, usb_detect_work);
319         
320         RTINFO("rt5025: %s ++", __func__);
321
322         mutex_lock(&pi->var_lock);
323         if (pi->ac_online)
324         {
325                 rt5025_set_charging_current(pi->i2c, 2000);
326                 rt5025_notify_charging_cable(pi->chip->jeita_info, JEITA_AC_ADAPTER);
327                 pi->usb_cnt = 0;
328         }
329         else if (pi->usb_online)
330         {
331                 RTINFO("%s: usb_cnt %d\n", __func__, pi->usb_cnt);
332                 switch(dwc_vbus_status())
333                 {
334                         case 2: // USB Wall charger
335                                 rt5025_set_charging_current(pi->i2c, 2000);
336                                 rt5025_notify_charging_cable(pi->chip->jeita_info, JEITA_USB_TA);
337                                 RTINFO("rt5025: detect usb wall charger\n");
338                                 break;
339                         case 1: //normal USB
340                         default:
341                                 rt5025_set_charging_current(pi->i2c, 2000);
342                                 rt5025_notify_charging_cable(pi->chip->jeita_info, JEITA_NORMAL_USB);
343                                 RTINFO("rt5025: detect normal usb\n");
344                                 break;
345                 }
346                 if (pi->usb_cnt++ < 60)
347                         schedule_delayed_work(&pi->usb_detect_work, 1*HZ);
348         }
349         else
350         {
351                 //default to prevent over current charging
352                 rt5025_set_charging_current(pi->i2c, 500);
353                 rt5025_notify_charging_cable(pi->chip->jeita_info, JEITA_NO_CHARGE);
354                 //reset usb_cnt;
355                 pi->usb_cnt = 0;
356         }
357         mutex_unlock(&pi->var_lock);
358
359         RTINFO("rt5025: %s --", __func__);
360 }
361
362 static int __devinit rt5025_init_charger(struct rt5025_power_info *info, struct rt5025_power_data* pd)
363 {
364         //unsigned char data;
365         info->ac_online = 0;
366         info->usb_online =0;
367         //init charger buckck & charger current en to disable stat
368         info->chg_stat = RT5025_CHGSTAT_UNKNOWN;
369         #if 0
370         if (info->event_callback)
371                 info->event_callback->rt5025_gauge_set_status(POWER_SUPPLY_STATUS_DISCHARGING);
372         #endif
373         //rt5025_set_bits(info->i2c, RT5025_REG_CHGCTL4, RT5025_CHGRST_MASK);
374         //udelay(200);
375         //init register setting
376         rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL2, pd->CHGControl2.val);
377         rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL3, pd->CHGControl3.val);
378         rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL4, pd->CHGControl4.val);
379         rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL5, pd->CHGControl5.val);
380         rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL6, pd->CHGControl6.val);
381         //rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL7, pd->CHGControl7.val);
382         rt5025_assign_bits(info->i2c, RT5025_REG_CHGCTL7, 0xEF, pd->CHGControl7.val);
383         rt5025_reg_write(info->i2c, 0xA9, 0x60 );
384         //Special buck setting
385         #if 0
386         //Buck 1
387         data = rt5025_reg_read(info->i2c, 0x47);
388         data ^=0xc2;
389         rt5025_reg_write(info->i2c, 0x47, data);
390         //Buck 2
391         data = rt5025_reg_read(info->i2c, 0x48);
392         data ^=0xc2;
393         rt5025_reg_write(info->i2c, 0x48, data);
394         //Buck 3
395         data = rt5025_reg_read(info->i2c, 0x49);
396         data ^=0xc2;
397         rt5025_reg_write(info->i2c, 0x49, data);
398         #endif  //#if 0
399         
400         rt5025_power_charge_detect(info);
401
402         return 0;
403 }
404
405 static int __devinit rt5025_power_probe(struct platform_device *pdev)
406 {
407         struct rt5025_chip *chip = dev_get_drvdata(pdev->dev.parent);
408         struct rt5025_platform_data *pdata = chip->dev->platform_data;
409         struct rt5025_power_info *pi;
410         int ret = 0;
411         
412         pi = kzalloc(sizeof(*pi), GFP_KERNEL);
413         if (!pi)
414                 return -ENOMEM;
415
416         pi->i2c = chip->i2c;
417         pi->dev = &pdev->dev;
418         pi->chip = chip;
419         mutex_init(&pi->var_lock);
420         INIT_DELAYED_WORK(&pi->usb_detect_work, usb_detect_work_func);
421
422         #if 0
423         ret = rt5025_gauge_init(pi);
424         if (ret)
425                 goto out;
426         #endif
427
428         platform_set_drvdata(pdev, pi);
429         dev_ptr = pdev;
430
431         pi->ac.name = "rt5025-dc";
432         pi->ac.type = POWER_SUPPLY_TYPE_MAINS;
433         pi->ac.supplied_to = rt5025_supply_list;
434         pi->ac.properties = rt5025_adap_props;
435         pi->ac.num_properties = ARRAY_SIZE(rt5025_adap_props);
436         pi->ac.get_property = rt5025_adap_get_props;
437         ret = power_supply_register(&pdev->dev, &pi->ac);
438         if (ret)
439                 goto out;
440
441         pi->usb.name = "rt5025-usb";
442         pi->usb.type = POWER_SUPPLY_TYPE_USB;
443         pi->ac.supplied_to = rt5025_supply_list;
444         pi->usb.properties = rt5025_adap_props;
445         pi->usb.num_properties = ARRAY_SIZE(rt5025_adap_props);
446         pi->usb.get_property = rt5025_adap_get_props;
447         ret = power_supply_register(&pdev->dev, &pi->usb);
448         if (ret)
449                 goto out_usb;
450
451         rt5025_init_charger(pi, pdata->power_data);
452         chip->power_info = pi;
453
454         pr_info("rt5025-power driver is successfully loaded\n");
455
456         return ret;
457 out_usb:
458         power_supply_unregister(&pi->ac);
459 out:
460         kfree(pi);
461
462         return ret;
463 }
464
465 static int rt5025_power_suspend(struct platform_device *pdev, pm_message_t state)
466 {
467         #if 0
468         struct rt5025_power_info *pi = platform_get_drvdata(pdev);
469
470         if (pi->event_callback)
471                 pi->event_callback->rt5025_gauge_suspend();
472         #endif
473         RTINFO("\n");
474         return 0;
475 }
476
477 static int rt5025_power_resume(struct platform_device *pdev)
478 {
479         #if 0
480         struct rt5025_power_info *pi = platform_get_drvdata(pdev);
481
482         if (pi->event_callback)
483                 pi->event_callback->rt5025_gauge_resume();
484         #endif
485         RTINFO("\n");
486         return 0;
487 }
488
489 static int __devexit rt5025_power_remove(struct platform_device *pdev)
490 {
491         struct rt5025_power_info *pi = platform_get_drvdata(pdev);
492         struct rt5025_chip *chip = dev_get_drvdata(pdev->dev.parent);
493
494         #if 0
495         if (pi->event_callback)
496                 pi->event_callback->rt5025_gauge_remove();
497         #endif
498         power_supply_unregister(&pi->usb);
499         power_supply_unregister(&pi->ac);
500         chip->power_info = NULL;
501         kfree(pi);
502         RTINFO("\n");
503
504         return 0;
505 }
506
507 static struct platform_driver rt5025_power_driver = 
508 {
509         .driver = {
510                 .name = RT5025_DEVICE_NAME "-power",
511                 .owner = THIS_MODULE,
512         },
513         .probe = rt5025_power_probe,
514         .remove = __devexit_p(rt5025_power_remove),
515         .suspend = rt5025_power_suspend,
516         .resume = rt5025_power_resume,
517 };
518
519 static int __init rt5025_power_init(void)
520 {
521         return platform_driver_register(&rt5025_power_driver);
522 }
523 late_initcall_sync(rt5025_power_init);
524
525 static void __exit rt5025_power_exit(void)
526 {
527         platform_driver_unregister(&rt5025_power_driver);
528 }
529 module_exit(rt5025_power_exit);
530
531
532 MODULE_LICENSE("GPL v2");
533 MODULE_AUTHOR("CY Huang <cy_huang@richtek.com");
534 MODULE_DESCRIPTION("Power/Gauge driver for RT5025");
535 MODULE_ALIAS("platform:" RT5025_DEVICE_NAME "-power");
536 MODULE_VERSION(RT5025_DRV_VER);