Initial commit
[kernel/linux-3.0.git] / drivers / power / smb136_charger_q1.c
1 /*
2  *  smb136_charger.c
3  *
4  *  Copyright (C) 2011 Samsung Electronics
5  *  Ikkeun Kim <iks.kim@samsung.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11
12 #include <linux/power/smb136_charger_q1.h>
13 #define DEBUG
14
15 enum cable_type_t {
16         CABLE_TYPE_NONE = 0,
17         CABLE_TYPE_USB,
18         CABLE_TYPE_AC,
19         CABLE_TYPE_MISC,
20 };
21
22 static int smb136_i2c_read(struct i2c_client *client, u8 reg, u8 *data)
23 {
24         int ret = 0;
25
26         if (!client)
27                 return -ENODEV;
28
29         ret = i2c_smbus_read_byte_data(client, reg);
30         if (ret < 0)
31                 return -EIO;
32
33         *data = ret & 0xff;
34         return 0;
35 }
36
37 static int smb136_i2c_write(struct i2c_client *client, u8 reg, u8 data)
38 {
39         if (!client)
40                 return -ENODEV;
41
42         return i2c_smbus_write_byte_data(client, reg, data);
43 }
44
45 static void smb136_test_read(struct i2c_client *client)
46 {
47         struct smb136_chip *chg = i2c_get_clientdata(client);
48         u8 data = 0;
49         u32 addr = 0;
50
51         for (addr = 0; addr < 0x0c; addr++) {
52                 smb136_i2c_read(chg->client, addr, &data);
53                 dev_info(&client->dev,
54                         "SMB136 addr : 0x%02x data : 0x%02x\n", addr, data);
55         }
56
57         for (addr = 0x31; addr < 0x3D; addr++) {
58                 smb136_i2c_read(chg->client, addr, &data);
59                 dev_info(&client->dev,
60                         "SMB136 addr : 0x%02x data : 0x%02x\n", addr, data);
61         }
62 }
63
64 static int smb136_get_charging_status(struct i2c_client *client)
65 {
66         struct smb136_chip *chg = i2c_get_clientdata(client);
67         int status = POWER_SUPPLY_STATUS_UNKNOWN;
68         u8 data1 = 0;
69         u8 data2 = 0;
70
71         smb136_i2c_read(chg->client, 0x36, &data1);
72         smb136_i2c_read(chg->client, 0x39, &data2);
73         dev_info(&client->dev, "%s : 0x36h(0x%02x), 0x39h(0x%02x)\n",
74                 __func__, data1, data2);
75
76         if (data2 & 0x01)
77                 status = POWER_SUPPLY_STATUS_CHARGING;
78         else {
79                 if ((data1 & 0x08) == 0x08) {
80                         /* if error bit check,
81                                 ignore the status of charger-ic */
82                         status = POWER_SUPPLY_STATUS_NOT_CHARGING;
83                 } else if ((data1 & 0xc0) == 0xc0) {
84                         /* At least one charge cycle terminated,
85                                 Charge current < Termination Current */
86                         status = POWER_SUPPLY_STATUS_FULL;
87                 }
88         }
89
90         return (int)status;
91 }
92
93 static int smb136_charging(struct i2c_client *client)
94 {
95         struct smb136_chip *chg = i2c_get_clientdata(client);
96         u8 data = 0;
97         int gpio = 0;
98
99         dev_info(&client->dev, "%s : enable(%d), cable(%d)\n",
100                 __func__, chg->is_enable, chg->cable_type);
101
102         if (chg->is_enable) {
103                 switch (chg->cable_type) {
104                 case CABLE_TYPE_AC:
105                         /* 1. HC mode */
106                         data = 0x8c;
107
108                         smb136_i2c_write(chg->client, SMB_CommandA, data);
109                         udelay(10);
110
111                         /* 2. Change USB5/1/HC Control from Pin to I2C */
112                         /* 2. EN pin control - active low */
113                         smb136_i2c_write(chg->client, SMB_PinControl, 0x8);
114                         udelay(10);
115
116                         smb136_i2c_write(chg->client, SMB_CommandA, 0x8c);
117                         udelay(10);
118
119                         /* 3. Set charge current to 950mA,
120                                 termination current to 150mA */
121                         data = 0x94;
122
123                         smb136_i2c_write(chg->client, SMB_ChargeCurrent, data);
124                         udelay(10);
125                         break;
126                 case CABLE_TYPE_USB:
127                 default:
128                         /* 1. USBIN 500mA mode */
129                         data = 0x88;
130
131                         smb136_i2c_write(chg->client, SMB_CommandA, data);
132                         udelay(10);
133
134                         /* 2. Change USB5/1/HC Control from Pin to I2C */
135                         /* 2. EN pin control - active low */
136                         smb136_i2c_write(chg->client, SMB_PinControl, 0x8);
137                         udelay(10);
138
139                         smb136_i2c_write(chg->client, SMB_CommandA, 0x88);
140                         udelay(10);
141
142                         /* 3. Set charge current to 500mA,
143                                 termination current to 150mA */
144                         data = 0x14;
145
146                         smb136_i2c_write(chg->client, SMB_ChargeCurrent, data);
147                         udelay(10);
148                         break;
149                 }
150
151                 /* 3. Enable Automatic Input Current Limit to 1000mA
152                         (threshold 4.25V) */
153                 data = 0x60;
154                 smb136_i2c_write(chg->client, SMB_InputCurrentLimit, data);
155                 udelay(10);
156
157                 /* 4. Automatic Recharge Disabed */
158                 data = 0x8c;
159                 smb136_i2c_write(chg->client, SMB_ControlA, data);
160                 udelay(10);
161
162                 /* 5. Safety timer Disabled */
163                 data = 0x28;
164                 smb136_i2c_write(chg->client, SMB_ControlB, data);
165                 udelay(10);
166
167                 /* 6. Disable USB D+/D- Detection */
168                 data = 0x28;
169                 smb136_i2c_write(chg->client, SMB_OTGControl, data);
170                 udelay(10);
171
172                 /* 7. Set Output Polarity for STAT */
173                 /* 7. Set float voltage to 4.2V */
174                 data = 0x4a;
175                 smb136_i2c_write(chg->client, SMB_FloatVoltage, data);
176                 udelay(10);
177
178                 /* 8. Re-load Enable */
179                 data = 0x4b;
180                 smb136_i2c_write(chg->client, SMB_SafetyTimer, data);
181                 udelay(10);
182         } else {
183                 /* do nothing... */
184         }
185
186         /* CHG_EN pin control - active low */
187         gpio = gpio_request(chg->pdata->gpio_chg_en, "CHG_EN");
188         if (!gpio) {
189                 gpio_direction_output(chg->pdata->gpio_chg_en,
190                         !(chg->is_enable));
191                 dev_info(&client->dev, "gpio(CHG_EN)is %d\n",
192                         gpio_get_value(chg->pdata->gpio_chg_en));
193                 gpio_free(chg->pdata->gpio_chg_en);
194         } else
195                 dev_err(&client->dev,
196                         "faile to request gpio(CHG_EN)\n");
197
198         /* smb136_test_read(client); */
199
200         return 0;
201 }
202
203 static int smb136_get_property(struct power_supply *psy,
204                             enum power_supply_property psp,
205                             union power_supply_propval *val)
206 {
207         struct smb136_chip *chip = container_of(psy,
208                                                   struct smb136_chip,
209                                                   charger);
210         u8 data;
211
212         switch (psp) {
213         case POWER_SUPPLY_PROP_STATUS:
214                 val->intval = smb136_get_charging_status(chip->client);
215                 break;
216         case POWER_SUPPLY_PROP_CHARGE_TYPE:
217                 val->intval = chip->cable_type;
218                 break;
219         case POWER_SUPPLY_PROP_ONLINE:
220                 val->intval = chip->is_enable;
221                 break;
222         case POWER_SUPPLY_PROP_CURRENT_NOW:
223                 smb136_i2c_read(chip->client, SMB_ChargeCurrent, &data);
224                 switch (data >> 5) {
225                 case 0:
226                         val->intval = 500;
227                         break;
228                 case 1:
229                         val->intval = 650;
230                         break;
231                 case 2:
232                         val->intval = 750;
233                         break;
234                 case 3:
235                         val->intval = 850;
236                         break;
237                 case 4:
238                         val->intval = 950;
239                         break;
240                 case 5:
241                         val->intval = 1100;
242                         break;
243                 case 6:
244                         val->intval = 1300;
245                         break;
246                 case 7:
247                         val->intval = 1500;
248                         break;
249                 }
250                 break;
251         default:
252                 return -EINVAL;
253         }
254
255         dev_info(&chip->client->dev, "%s: smb136_get_property (%d,%d)\n",
256                 __func__, psp, val->intval);
257
258         return 0;
259 }
260
261 static int smb136_set_property(struct power_supply *psy,
262                             enum power_supply_property psp,
263                             const union power_supply_propval *val)
264 {
265         struct smb136_chip *chip = container_of(psy,
266                                                   struct smb136_chip,
267                                                   charger);
268
269         dev_info(&chip->client->dev, "%s: smb136_set_property (%d,%d)\n",
270                 __func__, psp, val->intval);
271
272         switch (psp) {
273         case POWER_SUPPLY_PROP_STATUS:
274                 chip->is_enable = (val->intval == POWER_SUPPLY_STATUS_CHARGING);
275                 smb136_charging(chip->client);
276                 break;
277         case POWER_SUPPLY_PROP_CHARGE_TYPE:
278                 switch (val->intval) {
279                 case CABLE_TYPE_USB:
280                 case CABLE_TYPE_AC:
281                         chip->cable_type = val->intval;
282                         break;
283                 default:
284                         dev_err(&chip->client->dev, "cable type NOT supported!\n");
285                         chip->cable_type = CABLE_TYPE_NONE;
286                         break;
287                 }
288                 break;
289         case POWER_SUPPLY_PROP_ONLINE:
290                 chip->is_enable = (bool)val->intval;
291                 smb136_charging(chip->client);
292                 break;
293         case POWER_SUPPLY_PROP_CURRENT_NOW:
294                 if (val->intval <= 450)
295                         chip->cable_type = CABLE_TYPE_USB;      /* USB */
296                 else
297                         chip->cable_type = CABLE_TYPE_AC;       /* TA */
298                 break;
299         default:
300                 return -EINVAL;
301         }
302         return 0;
303 }
304
305 #if defined(CONFIG_MACH_Q1_CHN) && defined(CONFIG_SMB136_CHARGER_Q1)
306 static bool is_ovp_status;
307 #endif
308
309 static irqreturn_t smb136_irq_thread(int irq, void *data)
310 {
311         struct smb136_chip *chip = data;
312 #if defined(CONFIG_MACH_Q1_CHN) && defined(CONFIG_SMB136_CHARGER_Q1)
313         int ret = 0;
314         u8 data1 = 0;
315 #endif
316
317         dev_info(&chip->client->dev, "%s\n", __func__);
318
319         smb136_test_read(chip->client);
320 #if defined(CONFIG_MACH_Q1_CHN) && defined(CONFIG_SMB136_CHARGER_Q1)
321         smb136_i2c_read(chip->client, 0x33, &data1);
322
323         if (data1 & 0x02) {
324                 if (is_ovp_status == false) {
325                         is_ovp_status = true;
326                         if (chip->pdata->ovp_cb)
327                                 ret = chip->pdata->ovp_cb(true);
328                         dev_info(&chip->client->dev, "$s OVP!!\n");
329                 }
330         } else {
331                 if (is_ovp_status == true) {
332                         is_ovp_status = false;
333                         if (chip->pdata->ovp_cb)
334                                 ret = chip->pdata->ovp_cb(false);
335                         dev_info(&chip->client->dev,
336                                 "$s ovp status released!!\n");
337                 }
338         }
339 #endif
340
341         return IRQ_HANDLED;
342 }
343
344 static int smb136_irq_init(struct smb136_chip *chip)
345 {
346         struct i2c_client *client = chip->client;
347         int ret;
348
349         if (client->irq) {
350                 ret = request_threaded_irq(client->irq, NULL,
351 #if defined(CONFIG_MACH_Q1_CHN) && defined(CONFIG_SMB136_CHARGER_Q1)
352                         smb136_irq_thread, IRQ_TYPE_EDGE_BOTH,
353 #else
354                         smb136_irq_thread, IRQ_TYPE_EDGE_FALLING,
355 #endif
356                         "SMB136 charger", chip);
357                 if (ret) {
358                         dev_err(&client->dev, "failed to reqeust IRQ\n");
359                         return ret;
360                 }
361
362                 ret = enable_irq_wake(client->irq);
363                 if (ret < 0)
364                         dev_err(&client->dev,
365                                 "failed to enable wakeup src %d\n", ret);
366         }
367
368         return 0;
369 }
370
371 static int smb136_probe(struct i2c_client *client,
372         const struct i2c_device_id *id)
373 {
374         struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
375         struct smb136_chip *chip;
376         int ret = 0;
377         int gpio = 0;
378         u8 data;
379
380         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
381                 return -EIO;
382
383         if (smb136_i2c_read(client, 0x36, &data) < 0)   /* check HW */
384                 return -EIO;
385
386         dev_info(&client->dev,
387                 "%s : SMB136 Charger Driver Loading\n", __func__);
388
389         chip = kzalloc(sizeof(struct smb136_chip), GFP_KERNEL);
390         if (!chip)
391                 return -ENOMEM;
392
393         chip->client = client;
394         chip->pdata = client->dev.platform_data;
395
396         i2c_set_clientdata(client, chip);
397
398         if (!chip->pdata) {
399                 dev_err(&client->dev,
400                         "%s : No platform data supplied\n", __func__);
401                 ret = -EINVAL;
402                 goto err_pdata;
403         }
404
405         if (chip->pdata->set_charger_name)
406                 chip->pdata->set_charger_name();
407
408         chip->is_enable = false;
409         chip->cable_type = CABLE_TYPE_NONE;
410
411         chip->charger.name              = "smb136-charger";
412         chip->charger.type              = POWER_SUPPLY_TYPE_BATTERY;
413         chip->charger.get_property      = smb136_get_property;
414         chip->charger.set_property      = smb136_set_property;
415         chip->charger.properties        = smb136_charger_props;
416         chip->charger.num_properties    = ARRAY_SIZE(smb136_charger_props);
417
418         ret = power_supply_register(&client->dev, &chip->charger);
419         if (ret) {
420                 dev_err(&client->dev,
421                         "failed: power supply register\n");
422                 kfree(chip);
423                 return ret;
424         }
425
426         /* CHG_EN pin control - active low */
427         if (chip->pdata->gpio_chg_en) {
428                 s3c_gpio_cfgpin(chip->pdata->gpio_chg_en, S3C_GPIO_OUTPUT);
429                 s3c_gpio_setpull(chip->pdata->gpio_chg_en, S3C_GPIO_PULL_NONE);
430
431                 gpio = gpio_request(chip->pdata->gpio_chg_en, "CHG_EN");
432                 if (!gpio) {
433                         gpio_direction_output(chip->pdata->gpio_chg_en,
434                                 GPIO_LEVEL_HIGH);
435                         gpio_free(chip->pdata->gpio_chg_en);
436                 } else
437                         dev_err(&client->dev,
438                         "faile to request gpio(CHG_EN)\n");
439         }
440
441         if (chip->pdata->gpio_otg_en) {
442                 s3c_gpio_cfgpin(chip->pdata->gpio_otg_en, S3C_GPIO_OUTPUT);
443                 s3c_gpio_setpull(chip->pdata->gpio_otg_en, S3C_GPIO_PULL_NONE);
444
445                 gpio = gpio_request(chip->pdata->gpio_otg_en, "OTG_EN");
446                 if (!gpio) {
447                         gpio_direction_output(chip->pdata->gpio_otg_en,
448                                 GPIO_LEVEL_LOW);
449                         gpio_free(chip->pdata->gpio_otg_en);
450                 } else
451                         dev_err(&client->dev,
452                         "faile to request gpio(OTG_EN)\n");
453         }
454
455         if (chip->pdata->gpio_ta_nconnected) {
456                 s3c_gpio_cfgpin(chip->pdata->gpio_ta_nconnected,
457                         S3C_GPIO_INPUT);
458                 s3c_gpio_setpull(chip->pdata->gpio_ta_nconnected,
459                         S3C_GPIO_PULL_NONE);
460         }
461
462         if (chip->pdata->gpio_chg_ing) {
463 #if 1
464 #if defined(CONFIG_MACH_Q1_CHN) && defined(CONFIG_SMB136_CHARGER_Q1)
465                 s3c_gpio_cfgpin(chip->pdata->gpio_chg_ing, S3C_GPIO_SFN(0xf));
466 #endif
467                 client->irq = gpio_to_irq(chip->pdata->gpio_chg_ing);
468                 ret = smb136_irq_init(chip);
469                 if (ret)
470                         goto err_pdata;
471 #else
472                 s3c_gpio_cfgpin(chip->pdata->gpio_chg_ing, S3C_GPIO_INPUT);
473                 s3c_gpio_setpull(chip->pdata->gpio_chg_ing, S3C_GPIO_PULL_NONE);
474 #endif
475         }
476
477 #if defined(CONFIG_MACH_Q1_CHN) && defined(CONFIG_SMB136_CHARGER_Q1)
478         is_ovp_status = false;
479 #endif
480
481         smb136_test_read(client);
482
483         return 0;
484
485 err_pdata:
486         kfree(chip);
487         return ret;
488 }
489
490 static int __devexit smb136_remove(struct i2c_client *client)
491 {
492         struct smb136_chip *chip = i2c_get_clientdata(client);
493
494         kfree(chip);
495         return 0;
496 }
497
498 static const struct i2c_device_id smb136_id[] = {
499         {"smb136-charger", 0},
500         {}
501 };
502
503 MODULE_DEVICE_TABLE(i2c, smb136_id);
504
505 static struct i2c_driver smb136_i2c_driver = {
506         .driver = {
507                 .owner  = THIS_MODULE,
508                 .name   = "smb136-charger",
509         },
510         .probe  = smb136_probe,
511         .remove = __devexit_p(smb136_remove),
512         .command = NULL,
513         .id_table       = smb136_id,
514 };
515
516 static int __init smb136_init(void)
517 {
518         return i2c_add_driver(&smb136_i2c_driver);
519 }
520
521 static void __exit smb136_exit(void)
522 {
523         i2c_del_driver(&smb136_i2c_driver);
524 }
525
526 module_init(smb136_init);
527 module_exit(smb136_exit);
528
529 MODULE_AUTHOR("Ikkeun Kim <iks.kim@samsung.com>");
530 MODULE_DESCRIPTION("smb136 charger driver");
531 MODULE_LICENSE("GPL");