UPSTREAM: PCI: rockchip: remove the pointer to L1 substate cap
[firefly-linux-kernel-4.4.55.git] / drivers / power / bq24296_charger.c
1 /*
2  * BQ24296 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 <linux/proc_fs.h>
25 #include <asm/uaccess.h>
26 #include <linux/power/bq24296_charger.h>
27 #include <linux/interrupt.h>
28 #include <linux/module.h>
29 #include <linux/of_irq.h>
30 #include <linux/of_gpio.h>
31 #include <linux/of.h>
32 #include <linux/of_device.h>
33
34 struct bq24296_device_info *bq24296_di;
35 struct bq24296_board *bq24296_pdata;
36 static int bq24296_int = 0;
37 int bq24296_mode = 0;
38 int bq24296_chag_down ;
39 #if 0
40 #define DBG(x...) printk(KERN_INFO x)
41 #else
42 #define DBG(x...) do { } while (0)
43 #endif
44
45 /*
46  * Common code for BQ24296 devices read
47  */
48 static int bq24296_i2c_reg8_read(const struct i2c_client *client, const char reg, char *buf, int count, int scl_rate)
49 {
50         struct i2c_adapter *adap=client->adapter;
51         struct i2c_msg msgs[2];
52         int ret;
53         char reg_buf = reg;
54         
55         msgs[0].addr = client->addr;
56         msgs[0].flags = client->flags;
57         msgs[0].len = 1;
58         msgs[0].buf = &reg_buf;
59         msgs[0].scl_rate = scl_rate;
60 //      msgs[0].udelay = client->udelay;
61
62         msgs[1].addr = client->addr;
63         msgs[1].flags = client->flags | I2C_M_RD;
64         msgs[1].len = count;
65         msgs[1].buf = (char *)buf;
66         msgs[1].scl_rate = scl_rate;
67 //      msgs[1].udelay = client->udelay;
68
69         ret = i2c_transfer(adap, msgs, 2);
70
71         return (ret == 2)? count : ret;
72 }
73 EXPORT_SYMBOL(bq24296_i2c_reg8_read);
74
75 static int bq24296_i2c_reg8_write(const struct i2c_client *client, const char reg, const char *buf, int count, int scl_rate)
76 {
77         struct i2c_adapter *adap=client->adapter;
78         struct i2c_msg msg;
79         int ret;
80         char *tx_buf = (char *)kmalloc(count + 1, GFP_KERNEL);
81         if(!tx_buf)
82                 return -ENOMEM;
83         tx_buf[0] = reg;
84         memcpy(tx_buf+1, buf, count); 
85
86         msg.addr = client->addr;
87         msg.flags = client->flags;
88         msg.len = count + 1;
89         msg.buf = (char *)tx_buf;
90         msg.scl_rate = scl_rate;
91 //      msg.udelay = client->udelay;
92
93         ret = i2c_transfer(adap, &msg, 1);
94         kfree(tx_buf);
95         return (ret == 1) ? count : ret;
96
97 }
98 EXPORT_SYMBOL(bq24296_i2c_reg8_write);
99
100 static int bq24296_read(struct i2c_client *client, u8 reg, u8 buf[], unsigned len)
101 {
102         int ret;
103         ret = bq24296_i2c_reg8_read(client, reg, buf, len, BQ24296_SPEED);
104         return ret; 
105 }
106
107 static int bq24296_write(struct i2c_client *client, u8 reg, u8 const buf[], unsigned len)
108 {
109         int ret; 
110         ret = bq24296_i2c_reg8_write(client, reg, buf, (int)len, BQ24296_SPEED);
111         return ret;
112 }
113
114 static ssize_t bat_param_read(struct device *dev,struct device_attribute *attr, char *buf)
115 {
116         int i;
117         u8 buffer;
118         struct bq24296_device_info *di=bq24296_di;
119
120         for(i=0;i<11;i++)
121         {
122                 bq24296_read(di->client,i,&buffer,1);
123                 DBG("reg %d value %x\n",i,buffer);              
124         }
125         return 0;
126 }
127 DEVICE_ATTR(battparam, 0664, bat_param_read,NULL);
128
129 static int bq24296_update_reg(struct i2c_client *client, int reg, u8 value, u8 mask )
130 {
131         int ret =0;
132         u8 retval = 0;
133
134         ret = bq24296_read(client, reg, &retval, 1);
135         if (ret < 0) {
136                 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
137                 return ret;
138         }
139
140         if ((retval & mask) != value) {
141                 retval = ((retval & ~mask) | value) | value;
142                 ret = bq24296_write(client, reg, &retval, 1);
143                 if (ret < 0) {
144                         dev_err(&client->dev, "%s: err %d\n", __func__, ret);
145                         return ret;
146                 }
147         }
148
149         return ret;
150 }
151
152 static int bq24296_init_registers(void)
153 {
154         int ret = 0;
155
156         /* reset the register */
157         /*
158         ret = bq24296_update_reg(bq24296_di->client,
159                                 POWE_ON_CONFIGURATION_REGISTER,
160                                 REGISTER_RESET_ENABLE << REGISTER_RESET_OFFSET,
161                                 REGISTER_RESET_MASK << REGISTER_RESET_OFFSET);
162         if (ret < 0) {
163                 dev_err(&bq24296_di->client->dev, "%s(): Failed to reset the register \n",
164                                 __func__);
165                 goto final;
166         }
167
168         mdelay(5);
169 */
170         /* Disable the watchdog */
171         ret = bq24296_update_reg(bq24296_di->client,
172                                 TERMINATION_TIMER_CONTROL_REGISTER,
173                                 WATCHDOG_DISABLE << WATCHDOG_OFFSET,
174                                 WATCHDOG_MASK << WATCHDOG_OFFSET);
175         if (ret < 0) {
176                 dev_err(&bq24296_di->client->dev, "%s(): Failed to disable the watchdog \n",
177                                 __func__);
178                 goto final;
179         }
180
181         /* Set Pre-Charge Current Limit as 128mA */
182         ret = bq24296_update_reg(bq24296_di->client,
183                                 PRE_CHARGE_TERMINATION_CURRENT_CONTROL_REGISTER,
184                                 PRE_CHARGE_CURRENT_LIMIT_128MA << PRE_CHARGE_CURRENT_LIMIT_OFFSET,
185                                 PRE_CHARGE_CURRENT_LIMIT_MASK << PRE_CHARGE_CURRENT_LIMIT_OFFSET);
186         if (ret < 0) {
187                 dev_err(&bq24296_di->client->dev, "%s(): Failed to set pre-charge limit 128mA \n",
188                                 __func__);
189                 goto final;
190         }
191
192         /* Set Termination Current Limit as 128mA */
193         ret = bq24296_update_reg(bq24296_di->client,
194                                 PRE_CHARGE_TERMINATION_CURRENT_CONTROL_REGISTER,
195                                 TERMINATION_CURRENT_LIMIT_128MA << TERMINATION_CURRENT_LIMIT_OFFSET,
196                                 TERMINATION_CURRENT_LIMIT_MASK << TERMINATION_CURRENT_LIMIT_OFFSET);
197         if (ret < 0) {
198                 dev_err(&bq24296_di->client->dev, "%s(): Failed to set termination limit 128mA \n",
199                                 __func__);
200                 goto final;
201         }
202
203 final:
204         return ret;
205 }
206
207 static int bq24296_get_limit_current(int value)
208 {
209         u8 data;
210         if (value < 120)
211                 data = 0;
212         else if(value < 400)
213                 data = 1;
214         else if(value < 700)
215                 data = 2;
216         else if(value < 1000)
217                 data = 3;
218         else if(value < 1200)
219                 data = 4;
220         else if(value < 1800)
221                 data = 6;
222         else
223                 data = 7;
224         return data;
225         
226 }
227
228 static int bq24296_get_chg_current(int value)
229 {
230         u8 data;
231                 
232         data = (value)/64;
233         data &= 0xff;
234         return data;    
235 }
236 static int bq24296_update_input_current_limit(u8 value)
237 {
238         int ret = 0;
239         ret = bq24296_update_reg(bq24296_di->client,
240                                 INPUT_SOURCE_CONTROL_REGISTER,
241                                 ((value << IINLIM_OFFSET) | (EN_HIZ_DISABLE << EN_HIZ_OFFSET)),
242                                 ((IINLIM_MASK << IINLIM_OFFSET) | (EN_HIZ_MASK << EN_HIZ_OFFSET)));
243         if (ret < 0) {
244                 dev_err(&bq24296_di->client->dev, "%s(): Failed to set input current limit (0x%x) \n",
245                                 __func__, value);
246         }
247         
248         return ret;
249 }
250  static int bq24296_set_charge_current(u8 value)
251 {
252         int ret = 0;
253
254         ret = bq24296_update_reg(bq24296_di->client,
255                                 CHARGE_CURRENT_CONTROL_REGISTER,
256                                 (value << CHARGE_CURRENT_OFFSET) ,(CHARGE_CURRENT_MASK <<CHARGE_CURRENT_OFFSET ));
257         if (ret < 0) {
258                 dev_err(&bq24296_di->client->dev, "%s(): Failed to set charge current limit (0x%x) \n",
259                                 __func__, value);
260         }
261         return ret;
262 }
263         
264 static int bq24296_update_en_hiz_disable(void)
265 {
266         int ret = 0;
267
268         ret = bq24296_update_reg(bq24296_di->client,
269                                 INPUT_SOURCE_CONTROL_REGISTER,
270                                 EN_HIZ_DISABLE << EN_HIZ_OFFSET,
271                                 EN_HIZ_MASK << EN_HIZ_OFFSET);
272         if (ret < 0) {
273                 dev_err(&bq24296_di->client->dev, "%s(): Failed to set en_hiz_disable\n",
274                                 __func__);
275         }
276         return ret;
277 }
278
279 int bq24296_set_input_current(int on)
280 {
281         if(!bq24296_int)
282                 return 0;
283
284         if(1 == on){
285 #ifdef CONFIG_BATTERY_RK30_USB_AND_CHARGE
286                 bq24296_update_input_current_limit(IINLIM_3000MA);
287 #else
288                 bq24296_update_input_current_limit(IINLIM_3000MA);
289 #endif
290         }else{
291                 bq24296_update_input_current_limit(IINLIM_500MA);
292         }
293         DBG("bq24296_set_input_current %s\n", on ? "3000mA" : "500mA");
294
295         return 0;
296 }
297 EXPORT_SYMBOL_GPL(bq24296_set_input_current);
298
299 static int bq24296_update_charge_mode(u8 value)
300 {
301         int ret = 0;
302
303         ret = bq24296_update_reg(bq24296_di->client,
304                                 POWE_ON_CONFIGURATION_REGISTER,
305                                 value << CHARGE_MODE_CONFIG_OFFSET,
306                                 CHARGE_MODE_CONFIG_MASK << CHARGE_MODE_CONFIG_OFFSET);
307         if (ret < 0) {
308                 dev_err(&bq24296_di->client->dev, "%s(): Failed to set charge mode(0x%x) \n",
309                                 __func__, value);
310         }
311
312         return ret;
313 }
314
315 static int bq24296_update_otg_mode_current(u8 value)
316 {
317         int ret = 0;
318
319         ret = bq24296_update_reg(bq24296_di->client,
320                                 POWE_ON_CONFIGURATION_REGISTER,
321                                 value << OTG_MODE_CURRENT_CONFIG_OFFSET,
322                                 OTG_MODE_CURRENT_CONFIG_MASK << OTG_MODE_CURRENT_CONFIG_OFFSET);
323         if (ret < 0) {
324                 dev_err(&bq24296_di->client->dev, "%s(): Failed to set otg current mode(0x%x) \n",
325                                 __func__, value);
326         }
327         return ret;
328 }
329
330 static int bq24296_charge_mode_config(int on)
331 {
332
333         if(!bq24296_int)
334                 return 0;
335
336         if(1 == on)
337         {
338                 bq24296_update_en_hiz_disable();
339                 mdelay(5);
340                 bq24296_update_charge_mode(CHARGE_MODE_CONFIG_OTG_OUTPUT);
341                 mdelay(10);
342                 bq24296_update_otg_mode_current(OTG_MODE_CURRENT_CONFIG_1300MA);
343         }else{
344                 bq24296_update_charge_mode(CHARGE_MODE_CONFIG_CHARGE_BATTERY);
345         }
346
347         DBG("bq24296_charge_mode_config is %s\n", on ? "OTG Mode" : "Charge Mode");
348
349         return 0;
350 }
351  int bq24296_charge_otg_en(int chg_en,int otg_en)
352 {
353         int ret = 0;
354
355         if ((chg_en ==0) && (otg_en ==0)){
356                 ret = bq24296_update_reg(bq24296_di->client,POWE_ON_CONFIGURATION_REGISTER,0x00 << 4,0x03 << 4);
357         }
358         else if ((chg_en ==0) && (otg_en ==1))
359                 bq24296_charge_mode_config(1);
360         else 
361                 bq24296_charge_mode_config(0);
362         return ret;
363 }
364
365 extern int dwc_otg_check_dpdm(bool wait);
366 //extern int get_gadget_connect_flag(void);
367
368 static void usb_detect_work_func(struct work_struct *work)
369 {
370         struct delayed_work *delayed_work = (struct delayed_work *)container_of(work, struct delayed_work, work);
371         struct bq24296_device_info *pi = (struct bq24296_device_info *)container_of(delayed_work, struct bq24296_device_info, usb_detect_work);
372         u8 retval = 0;
373         int ret ;
374
375         ret = bq24296_read(bq24296_di->client, 0x08, &retval, 1);
376         if (ret < 0) {
377                 dev_err(&bq24296_di->client->dev, "%s: err %d\n", __func__, ret);
378         }
379         if ((retval & 0x30) ==0x30){
380                 bq24296_chag_down =1;
381         }else
382                 bq24296_chag_down =0;
383
384         DBG("%s: retval = %08x bq24296_chag_down = %d\n", __func__,retval,bq24296_chag_down);
385
386         mutex_lock(&pi->var_lock);
387         
388         if (gpio_is_valid(bq24296_pdata->dc_det_pin)){
389                         ret = gpio_request(bq24296_pdata->dc_det_pin, "bq24296_dc_det");
390                         if (ret < 0) {
391                                 DBG("Failed to request gpio %d with ret:""%d\n",bq24296_pdata->dc_det_pin, ret);
392                         }
393                         gpio_direction_input(bq24296_pdata->dc_det_pin);
394                         ret = gpio_get_value(bq24296_pdata->dc_det_pin);
395                         if (ret ==0){
396                                 bq24296_update_input_current_limit(bq24296_di->adp_input_current);
397                                 bq24296_set_charge_current(CHARGE_CURRENT_2048MA);
398                                 bq24296_charge_mode_config(0);
399                         }
400                         else {
401                                 bq24296_update_input_current_limit(IINLIM_500MA);
402                                 bq24296_set_charge_current(CHARGE_CURRENT_512MA);
403                         }
404                         gpio_free(bq24296_pdata->dc_det_pin);
405                         DBG("%s: bq24296_di->dc_det_pin=%x\n", __func__, ret);
406         }
407         else{
408                         DBG("%s: dwc_otg_check_dpdm %d\n", __func__, dwc_otg_check_dpdm(0));
409                         switch(dwc_otg_check_dpdm(0))
410                         {
411                                 case 2: // USB Wall charger
412                                 bq24296_update_input_current_limit(bq24296_di->usb_input_current);
413                                 bq24296_set_charge_current(CHARGE_CURRENT_2048MA);
414                                 bq24296_charge_mode_config(0);
415                                 DBG("bq24296: detect usb wall charger\n");
416                                 break;
417                                 case 1: //normal USB
418                                 #if 0
419                                 if (0 == get_gadget_connect_flag()){  // non-standard AC charger
420                                 bq24296_update_input_current_limit((bq24296_di->usb_input_current);
421                                 bq24296_set_charge_current(CHARGE_CURRENT_2048MA);
422                                 bq24296_charge_mode_config(0);;
423                                 }else{
424                                 #endif
425                                 // connect to pc        
426                                 bq24296_update_input_current_limit(bq24296_di->usb_input_current);
427                                 bq24296_set_charge_current(CHARGE_CURRENT_512MA);
428                                 bq24296_charge_mode_config(0);
429                                 DBG("bq24296: detect normal usb charger\n");
430                                 //      }
431                                 break;
432                                 default:
433                                 bq24296_update_input_current_limit(IINLIM_500MA);
434                                 bq24296_set_charge_current(CHARGE_CURRENT_512MA);
435                                 DBG("bq24296: detect no usb \n");                       
436                                 break;
437                                 }
438                 }
439
440         mutex_unlock(&pi->var_lock);
441         
442         schedule_delayed_work(&pi->usb_detect_work, 1*HZ);
443 }
444
445 static void irq_work_func(struct work_struct *work)
446 {
447 //      struct bq24296_device_info *info= container_of(work, struct bq24296_device_info, irq_work);
448 }
449
450 static irqreturn_t chg_irq_func(int irq, void *dev_id)
451 {
452 //      struct bq24296_device_info *info = dev_id;
453         DBG("%s\n", __func__);
454
455 //      queue_work(info->workqueue, &info->irq_work);
456
457         return IRQ_HANDLED;
458 }
459
460 #ifdef CONFIG_OF
461 static struct bq24296_board *bq24296_parse_dt(struct bq24296_device_info *di)
462 {
463         struct bq24296_board *pdata;
464         struct device_node *bq24296_np;
465         
466         DBG("%s,line=%d\n", __func__,__LINE__);
467         bq24296_np = of_node_get(di->dev->of_node);
468         if (!bq24296_np) {
469                 printk("could not find bq24296-node\n");
470                 return NULL;
471         }
472         pdata = devm_kzalloc(di->dev, sizeof(*pdata), GFP_KERNEL);
473         if (!pdata)
474                 return NULL;
475         if (of_property_read_u32_array(bq24296_np,"bq24296,chg_current",pdata->chg_current, 3)) {
476                 printk("dcdc sleep voltages not specified\n");
477                 return NULL;
478         }
479         
480         pdata->chg_irq_pin = of_get_named_gpio(bq24296_np,"gpios",0);
481         if (!gpio_is_valid(pdata->chg_irq_pin)) {
482                 printk("invalid gpio: %d\n",  pdata->chg_irq_pin);
483         }
484
485         pdata->dc_det_pin = of_get_named_gpio(bq24296_np,"gpios",1);
486         if (!gpio_is_valid(pdata->dc_det_pin)) {
487                 printk("invalid gpio: %d\n",  pdata->dc_det_pin);
488         }
489         
490         return pdata;
491 }
492
493 #else
494 static struct rk808_board *bq24296_parse_dt(struct bq24296_device_info *di)
495 {
496         return NULL;
497 }
498 #endif
499
500 #ifdef CONFIG_OF
501 static struct of_device_id bq24296_battery_of_match[] = {
502         { .compatible = "ti,bq24296"},
503         { },
504 };
505 MODULE_DEVICE_TABLE(of, bq24296_battery_of_match);
506 #endif
507
508 static int bq24296_battery_suspend(struct i2c_client *client, pm_message_t mesg)
509 {
510         cancel_delayed_work_sync(&bq24296_di->usb_detect_work);
511         return 0;
512 }
513
514 static int bq24296_battery_resume(struct i2c_client *client)
515 {
516         schedule_delayed_work(&bq24296_di->usb_detect_work, msecs_to_jiffies(50));
517         return 0;
518 }
519
520 static int bq24296_battery_probe(struct i2c_client *client,const struct i2c_device_id *id)
521 {
522         struct bq24296_device_info *di;
523         u8 retval = 0;
524         struct bq24296_board *pdev;
525         struct device_node *bq24296_node;
526         int ret = -EINVAL;
527         
528          DBG("%s,line=%d\n", __func__,__LINE__);
529          
530          bq24296_node = of_node_get(client->dev.of_node);
531         if (!bq24296_node) {
532                 printk("could not find bq24296-node\n");
533         }
534          
535         di = devm_kzalloc(&client->dev,sizeof(*di), GFP_KERNEL);
536         if (!di) {
537                 dev_err(&client->dev, "failed to allocate device info data\n");
538                 ret = -ENOMEM;
539                 goto batt_failed_2;
540         }
541         i2c_set_clientdata(client, di);
542         di->dev = &client->dev;
543         di->client = client;    
544         if (bq24296_node)
545                 pdev = bq24296_parse_dt(di);
546         
547         bq24296_pdata = pdev;
548         
549          DBG("%s,line=%d chg_current =%d usb_input_current = %d adp_input_current =%d \n", __func__,__LINE__,
550                 pdev->chg_current[0],pdev->chg_current[1],pdev->chg_current[2]);
551          
552          /******************get set current******/
553         if (pdev->chg_current[0] && pdev->chg_current[1] && pdev->chg_current[2]){
554                 di->chg_current = bq24296_get_chg_current(pdev->chg_current[0] );
555                 di->usb_input_current  = bq24296_get_limit_current(pdev->chg_current[1]);
556                 di->adp_input_current  = bq24296_get_limit_current(pdev->chg_current[2]);
557         }
558         else {
559                 di->chg_current = bq24296_get_chg_current(1000);
560                 di->usb_input_current  = bq24296_get_limit_current(500);
561                 di->adp_input_current  = bq24296_get_limit_current(2000);
562         }
563         /****************************************/
564         bq24296_di = di;
565         /* get the vendor id */
566         ret = bq24296_read(di->client, VENDOR_STATS_REGISTER, &retval, 1);
567         if (ret < 0) {
568                 dev_err(&di->client->dev, "%s(): Failed in reading register"
569                                 "0x%02x\n", __func__, VENDOR_STATS_REGISTER);
570                 goto batt_failed_2;
571         }
572         di->workqueue = create_singlethread_workqueue("bq24296_irq");
573         INIT_WORK(&di->irq_work, irq_work_func);
574         mutex_init(&di->var_lock);
575         INIT_DELAYED_WORK(&di->usb_detect_work, usb_detect_work_func);
576         schedule_delayed_work(&di->usb_detect_work, 0);
577         bq24296_init_registers();
578
579
580         if (gpio_is_valid(pdev->chg_irq_pin)){
581                 pdev->chg_irq = gpio_to_irq(pdev->chg_irq_pin);
582                 ret = request_threaded_irq(pdev->chg_irq, NULL, chg_irq_func, IRQF_TRIGGER_FALLING| IRQF_ONESHOT, "bq24296_chg_irq", di);
583                 if (ret) {
584                         ret = -EINVAL;
585                         printk("failed to request bq24296_chg_irq\n");
586                         goto err_chgirq_failed;
587                 }
588         }
589
590         bq24296_int =1;
591
592         DBG("bq24296_battery_probe ok");
593         return 0;
594
595 err_chgirq_failed:
596         free_irq(gpio_to_irq(pdev->chg_irq_pin), NULL);
597 batt_failed_2:
598         return ret;
599 }
600
601 static void bq24296_battery_shutdown(struct i2c_client *client)
602 {
603         struct bq24296_device_info *di = i2c_get_clientdata(client);
604
605         if (bq24296_pdata->chg_irq)
606                 free_irq(bq24296_pdata->chg_irq, di);
607 }
608
609 static int bq24296_battery_remove(struct i2c_client *client)
610 {
611
612         return 0;
613 }
614
615 static const struct i2c_device_id bq24296_id[] = {
616         { "bq24296", 0 },
617 };
618
619 static struct i2c_driver bq24296_battery_driver = {
620         .driver = {
621                 .name = "bq24296",
622                 .owner = THIS_MODULE,
623                 .of_match_table =of_match_ptr(bq24296_battery_of_match),
624         },
625         .probe = bq24296_battery_probe,
626         .remove = bq24296_battery_remove,
627         .shutdown = bq24296_battery_shutdown,
628         .suspend = bq24296_battery_suspend,
629         .resume = bq24296_battery_resume,
630         .id_table = bq24296_id,
631 };
632
633 static int __init bq24296_battery_init(void)
634 {
635         int ret;
636         
637         ret = i2c_add_driver(&bq24296_battery_driver);
638         if (ret)
639                 printk(KERN_ERR "Unable to register BQ24296 driver\n");
640         
641         return ret;
642 }
643 subsys_initcall(bq24296_battery_init);
644
645 static void __exit bq24296_battery_exit(void)
646 {
647         i2c_del_driver(&bq24296_battery_driver);
648 }
649 module_exit(bq24296_battery_exit);
650
651 MODULE_AUTHOR("Rockchip");
652 MODULE_DESCRIPTION("BQ24296 battery monitor driver");
653 MODULE_LICENSE("GPL");