rk3066 add phone pad modem support
[firefly-linux-kernel-4.4.55.git] / drivers / power / smb347-charger.c
1 /*
2  * smb347 battery driver
3  *
4  * This package is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
9  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
10  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11  *
12  */
13 #include <linux/module.h>
14 #include <linux/param.h>
15 #include <linux/jiffies.h>
16 #include <linux/workqueue.h>
17 #include <linux/delay.h>
18 #include <linux/platform_device.h>
19 #include <linux/power_supply.h>
20 #include <linux/idr.h>
21 #include <linux/i2c.h>
22 #include <linux/slab.h>
23 #include <asm/unaligned.h>
24 #include <mach/gpio.h>
25 #include <linux/proc_fs.h>
26 #include <asm/uaccess.h>
27 #include <mach/board.h>
28 #include <mach/iomux.h>
29 #include <linux/power/smb347-charger.h>
30
31 #include <linux/interrupt.h>
32 #include "../usb/dwc_otg/dwc_otg_driver.h"
33
34 #if 1
35 #define xhc_printk(format, ...)       printk(format, ## __VA_ARGS__)
36 #else 
37 #define xhc_printk(format, ...)
38 #endif
39
40 #define SMB347_STATUS_D                 0x3d
41 #define SMB347_SPEED                    (300 * 1000) 
42 #define MAX_REG_INDEX                   0x3f  
43
44 struct workqueue_struct *wq;
45 struct smb347_device{
46         struct i2c_client *client;
47         struct delayed_work work;
48         struct smb347_info *info;
49         struct work_struct full_power_work_struct;
50         int usb_host_in;
51 };
52
53
54 /* Input current limit in mA */
55 static const unsigned int icl_tbl[] = {
56         300,
57         500,
58         700,
59         900,
60         1200,
61         1500,
62         1800,
63         2000,
64         2200,
65         2500,
66 };
67
68 extern dwc_otg_device_t* g_otgdev;
69 struct smb347_device * g_smb347_dev;
70 static void smb347_init(struct i2c_client *client);
71
72 static int smb347_read(struct i2c_client *client, const char reg, char *buf, int len)
73 {
74         int ret;
75         ret = i2c_master_reg8_recv(client, reg, buf, len, SMB347_SPEED);
76         return ret; 
77 }
78
79 static int smb347_write(struct i2c_client *client,const char reg, char *buf, int len)
80 {
81         int ret; 
82         ret = i2c_master_reg8_send(client, reg, buf, len, SMB347_SPEED);
83         return ret;
84 }
85
86 static int dump_smb347_reg(struct smb347_device *dev)
87 {
88         int ret = 0;
89         char buf = 0;
90         int reg = 0;
91         if(!dev)
92         {
93                 xhc_printk("dev is null");
94                 return -1;
95         }
96         for(reg = 0; reg <= MAX_REG_INDEX; reg++)
97         {
98                 ret = i2c_master_reg8_recv(dev->client, reg, &buf, 1, SMB347_SPEED);
99                 
100                 if(ret < 0)
101                 {
102                         printk("read smb137 reg error:%d\n",ret);
103                 }
104                 else
105                 {
106                         printk("reg 0x%x:0x%x\n",reg,buf);
107                 }
108         }
109
110         return 0;
111
112 }
113
114 static ssize_t smb_debug_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t _count)
115 {
116         int temp;
117         u8 reg;
118         u8 val;
119         struct smb347_device *smb347_dev = dev_get_drvdata(dev);
120         if (sscanf(buf, "%x", &temp) != 1)
121                 return -EINVAL;
122         val = temp & 0x00ff;
123         reg = temp >> 8;
124         smb347_write(smb347_dev->client, reg, &val,1);
125         
126         return _count;
127 }
128
129 static ssize_t smb_debug_show(struct device *dev, struct device_attribute *attr,
130                         char *buf)
131 {
132         struct smb347_device *smb347_dev = dev_get_drvdata(dev);
133         dump_smb347_reg(smb347_dev);
134         return 0;
135 }
136
137 static struct device_attribute smb_debug = 
138         __ATTR(smb_debug, S_IRUGO | S_IWUSR, smb_debug_show, smb_debug_store);
139
140 int smb347_is_chg_ok(void)
141 {
142         u8 reg = 0;
143         int ret = 0;
144
145         smb347_read(g_smb347_dev->client, 0x37, &reg, 1);
146         ret = (reg & 0x03);
147
148         return ret;
149 }
150
151
152 EXPORT_SYMBOL(smb347_is_chg_ok);
153
154 int smb347_is_charging(void)
155 {
156         int status = 0;//POWER_SUPPLY_STATUS_UNKNOWN;
157         u8 data = 0;
158
159         smb347_read(g_smb347_dev->client, SMB347_STATUS_D, &data, 1);
160         if (data & 0x06)
161                 status = 1;
162         
163         return status;
164 }
165
166 EXPORT_SYMBOL(smb347_is_charging);
167
168 void smb347_set_something(void)
169 {
170         u8 reg;
171
172         smb347_init(g_smb347_dev->client);
173         return;
174 }
175
176 EXPORT_SYMBOL(smb347_set_something);
177
178 void smb347_set_charging(void)
179 {
180         u8 val;
181
182         val = 0x26;
183         smb347_write(g_smb347_dev->client, 0x03, &val, 1);
184
185         smb347_read(g_smb347_dev->client, 0x04, &val, 1);
186         val &= 0x7f;
187         smb347_write(g_smb347_dev->client, 0x04, &val, 1);
188
189         return;
190 }
191
192 EXPORT_SYMBOL(smb347_set_charging);
193
194 void smb347_set_discharging(void)
195 {
196         u8 val;
197
198         val = 0x20;
199         smb347_write(g_smb347_dev->client, 0x03, &val, 1);
200
201         smb347_read(g_smb347_dev->client, 0x04, &val, 1);
202         val |= 0x80;
203         smb347_write(g_smb347_dev->client, 0x04, &val, 1);
204
205         return;
206 }
207
208 EXPORT_SYMBOL(smb347_set_discharging);
209
210 /* Convert current to register value using lookup table */
211 static int current_to_hw(const unsigned int *tbl, size_t size, unsigned int val)
212 {
213         size_t i;
214         for (i = 0; i < size; i++) {
215                 if (val < tbl[i]) {
216                         break;
217                 }
218         }
219
220         return i > 0 ? i - 1 : -EINVAL;
221 }
222
223 static int smb347_set_current_limits(struct smb347_device *smb_dev)
224 {
225         char ret;
226         if (smb_dev->info->max_current) {
227                 xhc_printk("xhc_test_smb_dev->info->max_current = %d\n", smb_dev->info->max_current);
228                 ret = current_to_hw (icl_tbl, ARRAY_SIZE(icl_tbl),
229                                 smb_dev->info->max_current);
230                 if (ret < 0) {
231                         return ret;
232                 }
233                 ret = (ret << 4) + ret;
234                 ret = 0x77; //Hardcode 2000mA 2012-11-06
235                 xhc_printk("ret = %x\n", ret);
236                 ret = smb347_write(smb_dev->client, 0x01, &ret, 1);
237                 xhc_printk("ret = %x\n", ret);
238                 if (ret < 0) {
239                         return ret;
240                 }
241         } 
242         return 0;
243 }
244
245 static void suspend_smb347(struct smb347_device *smb347_dev)
246 {
247         u8 reg;
248         reg = 0x80;
249         smb347_write(smb347_dev->client,0x30,&reg,1);
250         smb347_read(smb347_dev->client, 0x02, &reg, 1);
251         reg = (reg&0x7f);
252         smb347_write(smb347_dev->client,0x02,&reg,1);
253         xhc_printk("%s\n", __func__);
254 }
255
256 static void active_smb347(struct smb347_device *smb347_dev)
257 {
258         u8 reg;
259         reg = 0x80;
260         smb347_write(smb347_dev->client,0x30,&reg,1);
261         smb347_read(smb347_dev->client, 0x02, &reg, 1);
262         reg = (reg | 0x80);
263         smb347_write(smb347_dev->client,0x02,&reg,1);
264         xhc_printk("%s\n", __func__);
265 }
266
267 static int smb347_set_otg_control(struct smb347_device *smb_dev)
268 {
269         char ret;
270         char reg;
271         if (smb_dev->info->otg_power_form_smb == 1) {
272                 ret = smb347_read(smb_dev->client, 0x09, &reg, 1);
273                 if (ret < 0) {
274                         xhc_printk("error,ret = %x\n", ret);
275                         return ret;
276                 }
277                 reg &= 0xef;  
278                 reg |= 0x40; 
279                 reg |= 0x20;  
280                 ret = smb347_write(smb_dev->client,0x09,&reg,1);        
281                 if (ret < 0) {
282                         xhc_printk("error,ret = %x\n", ret);
283                         return ret;
284                 }
285                 reg = 0x76;
286                 smb347_write(smb_dev->client,0x0a,&reg,1);
287                 if (ret < 0) {
288                         xhc_printk("error,ret = %x\n", ret);
289                         return ret;
290                 }
291         }
292         return 0;
293 }
294
295
296 static void smb347_init(struct i2c_client *client)  
297 {
298         u8 reg;
299         reg = 0x80;
300         smb347_write(client, 0x30, &reg, 1);
301
302         reg = 0xfd;
303         smb347_write(client, 0x00, &reg, 1);
304
305         reg = 0x77;
306         smb347_write(client, 0x01, &reg, 1);
307
308         reg = 0x26;
309         smb347_write(client, 0x03, &reg, 1);
310
311         smb347_read(client, 0x05, &reg, 1);
312         reg |= 0x80;
313         smb347_write(client, 0x05, &reg, 1);
314
315         /* close interrupt */
316         smb347_read(client, 0x38, &reg, 1);
317         smb347_read(client, 0x3a, &reg, 1);
318         reg = 0x0;
319         smb347_write(client, 0x0c, &reg, 1);
320         smb347_write(client, 0x0d, &reg, 1);
321         
322         /* set dc charge when bosh inser dc and usb */
323         smb347_read(client, 0x02, &reg, 1);
324         reg = reg & 0xfb;
325         smb347_write(client, 0x02, &reg, 1);
326
327
328         smb347_set_otg_control(g_smb347_dev);
329         smb347_set_current_limits(g_smb347_dev);
330         
331         dump_smb347_reg(g_smb347_dev);
332 }
333
334 static void smb347_set_current_work(struct work_struct *work)
335 {
336         struct smb347_device *smb347_dev = container_of(to_delayed_work(work), struct smb347_device, work);
337         u8 reg;
338         if (g_otgdev->core_if->op_state == A_HOST && smb347_dev->usb_host_in == 0) {
339
340                 xhc_printk("otg_dev->core_if->op_state = %d\n", g_otgdev->core_if->op_state);
341                 if (g_smb347_dev->info->otg_power_form_smb == 1) {
342
343                         reg = 0x7e;
344                         smb347_write(smb347_dev->client,0x0a,&reg,1);
345                 } else {
346                         suspend_smb347(smb347_dev);        
347                 }
348                 smb347_dev->usb_host_in = 1;
349         } else if (g_otgdev->core_if->op_state != A_HOST && smb347_dev->usb_host_in == 1) {
350
351                 xhc_printk("otg_dev->core_if->op_state = %d\n", g_otgdev->core_if->op_state);
352                 if (g_smb347_dev->info->otg_power_form_smb == 1) {
353                         reg = 0x76;
354                         smb347_write(smb347_dev->client,0x0a,&reg,1);
355                 } else {
356                         active_smb347(smb347_dev);        
357                 }
358                 smb347_dev->usb_host_in = 0;
359         }
360         schedule_delayed_work(&smb347_dev->work, 100);       
361 }
362
363 static int smb347_battery_probe(struct i2c_client *client,
364                                  const struct i2c_device_id *id)
365 {
366         int ret;
367         struct smb347_device *smb347_dev;
368         struct smb347_info *info = client->dev.platform_data;;
369         
370         xhc_printk("__xhc__%s, line = %d\n", __func__, __LINE__);
371         smb347_dev = kzalloc(sizeof(struct smb347_device), GFP_KERNEL);
372         smb347_dev->usb_host_in = 0;
373         if (!smb347_dev) {
374                 dev_err(&client->dev, "failed to allocate device info data\n");
375                 ret = -ENOMEM;
376                 return ret;
377         }
378
379         xhc_printk("__xhc__%s, line = %d\n", __func__, __LINE__);
380         i2c_set_clientdata(client, smb347_dev);
381         dev_set_drvdata(&client->dev,smb347_dev);
382         smb347_dev->client = client;
383         smb347_dev->info = info;
384         g_smb347_dev = smb347_dev;
385         wq = create_singlethread_workqueue("smb347_det");
386
387         if(info->chg_susp_pin) {
388                 rk30_mux_api_set(GPIO4D1_SMCDATA9_TRACEDATA9_NAME, 0);
389                 ret = gpio_request(info->chg_susp_pin, "chg susp pin");
390                 if (ret != 0) {
391                         gpio_free(info->chg_susp_pin);
392                         xhc_printk("smb347 gpio_request chg_susp_pin error\n");
393                         return -EIO;
394                 }
395                 gpio_direction_output(info->chg_susp_pin, 0);
396                 gpio_set_value(info->chg_susp_pin, GPIO_HIGH);
397         }
398         //msleep(200);
399         if(info->chg_ctl_pin) {
400                 ret = gpio_request(info->chg_ctl_pin, "chg ctl pin");
401                 if (ret != 0) {
402                         gpio_free(info->chg_ctl_pin);
403                         xhc_printk("smb347 gpio_request chg_ctl_pin error\n");
404                         return -EIO;
405                 }
406                 xhc_printk("__xhc__%s, line = %d\n", __func__, __LINE__);
407                 gpio_direction_output(info->chg_ctl_pin, 0);
408                 // gpio_set_value(info->chg_ctl_pin, GPIO_HIGH);
409         }
410
411         if(info->chg_en_pin)
412         {
413                 rk30_mux_api_set(GPIO4D5_SMCDATA13_TRACEDATA13_NAME, 0);
414                 ret = gpio_request(info->chg_en_pin, "chg en pin");
415                 if (ret != 0) {
416                         gpio_free(info->chg_en_pin);
417                         xhc_printk("smb347 gpio_request chg_en_pin error\n");
418                         return -EIO;
419                 }
420                 gpio_direction_output(info->chg_en_pin, 0);
421                 gpio_set_value(info->chg_en_pin, GPIO_LOW);
422         }
423         mdelay(100);
424         smb347_init(client);
425
426         INIT_DELAYED_WORK(&smb347_dev->work,smb347_set_current_work);
427         schedule_delayed_work(&smb347_dev->work, msecs_to_jiffies(3*1000));     
428
429         ret = device_create_file(&client->dev,&smb_debug);
430         if(ret) {
431                 dev_err(&client->dev, "failed to create sysfs file\n");
432                 return ret;
433         }
434         
435         return 0;
436 }
437
438 static int smb347_battery_remove(struct i2c_client *client)
439 {
440         return 0;
441 }
442
443 static int smb347_battery_suspend(struct i2c_client *client, pm_message_t mesg)
444 {
445         xhc_printk("__xhc__%s,", __func__);
446         return 0; 
447 }
448
449 static int smb347_battery_resume(struct i2c_client *client)
450 {
451         xhc_printk("__xhc__%s,", __func__);
452         return 0;
453 }
454 static  void smb347_battery_shutdown(struct i2c_client *client)
455 {
456         u8 reg = 0x0e;
457         smb347_write(client,0x09,&reg,1);
458         xhc_printk("%s,----xhc----\n", __func__);
459 }
460 static const struct i2c_device_id smb347_id[] = {
461         { "smb347", 0 },
462         {}
463 };
464
465 static struct i2c_driver smb347_battery_driver = {
466         .probe   = smb347_battery_probe,
467         .remove  = smb347_battery_remove,
468         .suspend = smb347_battery_suspend,
469         .resume  = smb347_battery_resume,
470         .shutdown = smb347_battery_shutdown,
471
472         .id_table = smb347_id,
473         .driver = {
474                 .name = "smb347",
475         },
476 };
477
478 static int __init smb347_battery_init(void)
479 {
480         int ret;
481         
482         ret = i2c_add_driver(&smb347_battery_driver);
483         if (ret)
484                 xhc_printk(KERN_ERR "Unable to register smb347 driver\n");
485         
486         return ret;
487 }
488
489 static void __exit smb347_battery_exit(void)
490 {
491         if (g_smb347_dev->info->otg_power_form_smb != 1) {
492                 active_smb347(g_smb347_dev);
493         }
494         i2c_del_driver(&smb347_battery_driver);   
495 }
496
497 //subsys_initcall_sync(smb347_battery_init);
498 subsys_initcall(smb347_battery_init);
499 module_exit(smb347_battery_exit);
500
501 /*
502    delay 500ms to fix the problam 
503    that sometime limit 500ma when startup when insert the hc charger 
504  */
505 static int __init delay_for_smb347(void)
506 {
507         xhc_printk("function: %s\n", __func__);
508         mdelay(500);
509         return 0;
510 }
511 core_initcall(delay_for_smb347);
512
513 MODULE_AUTHOR("xhc@rock-chips.com");
514 MODULE_DESCRIPTION("smb347 battery monitor driver");
515 MODULE_LICENSE("GPL");