blob: 9e72408c37ea859fe531e87c9a039edfe6aaa21e [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/*
2 * Driver for the TI zx234502 battery charger.
3 *
4 * Author: Mark A. Greer <mgreer@animalcreek.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/interrupt.h>
13#include <linux/delay.h>
14#include <linux/of_irq.h>
15#include <linux/of_device.h>
16#include <linux/pm_runtime.h>
17#include <linux/power_supply.h>
18#include <linux/gpio.h>
19#include <linux/i2c.h>
20#include <linux/irq.h>
21#include <linux/kthread.h>
22//#include <linux/mutex.h>
23#include <linux/semaphore.h>
24
25#include <linux/power/zx234502_charger.h>
26#include <linux/mfd/zx234290.h>
27
28#include <mach/gpio.h>
29#include <mach/pcu.h>
30#include <mach/zx29_usb.h>
31#include <linux/workqueue.h>
32
33#include <linux/slab.h>
34#include <linux/debugfs.h>
35#include <asm/uaccess.h>
36
37/*
38 * The FAULT register is latched by the zx234502 (except for NTC_FAULT)
39 * so the first read after a fault returns the latched value and subsequent
40 * reads return the current value. In order to return the fault status
41 * to the user, have the interrupt handler save the reg's value and retrieve
42 * it in the appropriate health/status routine. Each routine has its own
43 * flag indicating whether it should use the value stored by the last run
44 * of the interrupt handler or do an actual reg read. That way each routine
45 * can report back whatever fault may have occured.
46 */
47struct zx234502_dev_info {
48 struct i2c_client *client;
49 struct device *dev;
50 struct power_supply charger;
51 struct power_supply battery;
52 struct power_supply boost;
53 char model_name[I2C_NAME_SIZE];
54 kernel_ulong_t model;
55 unsigned int gpio_int;
56 unsigned int irq;
57 struct mutex bs_reg_lock;
58 bool first_time; /*let the first reset do not ask mmi*/
59 bool charger_health_valid;
60 bool battery_health_valid;
61 bool battery_status_valid;
62 u8 ciis_curr_reg;
63 u8 cbis_curr_reg;
64 u8 pis_curr_reg;
65 u8 cfis_curr_reg;
66
67 u8 ciis_pre_reg;
68 u8 cbis_pre_reg;
69 u8 pis_pre_reg;
70 u8 cfis_pre_reg;
71 u8 watchdog;
72 u8 boost_online_flag;
73 struct delayed_work boostWorkStruct ;
74 struct workqueue_struct *boostQueue;
75 struct semaphore chgirq_sem;
76 struct task_struct *chg_irq_thread;
77 u16 boostcount;
78
79 struct zx234502_platform_data *pdata;
80 //unsigned int chg_type;
81};
82
83//struct zx234502_platform_data *g_platform_data = NULL;
84struct zx234502_dev_info *g_bdi = NULL;
85
86/* REG01[2:0] (ISET_DCIN) in mAh */
87static const int zx234502_in_ilimit_values[] = {
88 150, 450, 850, 1000, 1500, 2000, 2500, 3000
89};
90/* REG01[6:3] (VINDPM) in mVh */
91static const int zx234502_vindpm_values[] = {
92 3880, 3960, 4040, 4120,
93 4200,4280, 4360, 4440,
94 4520,4600, 4680, 4760,
95 4840,4920, 5000, 5080,
96};
97
98/*
99 * The tables below provide a 2-way mapping for the value that goes in
100 * the register field and the real-world value that it represents.
101 * The index of the array is the value that goes in the register; the
102 * number at that index in the array is the real-world value that it
103 * represents.
104 */
105/* REG02[7:2] (ISETA) in mAh */
106static const int zx234502_isc_ichg_values[] = {
107 512, 576, 640, 704, 768, 832, 896, 960,
108 1024, 1088, 1152, 1216, 1280, 1344, 1408, 1472,
109 1536, 1600, 1664, 1728, 1792, 1856, 1920, 1984,
110 2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496,
111 2560, 2624, 2688, 2752, 2816, 2880, 2944, 3008,
112 3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520,
113 3584, 3648, 3712, 3776, 3840, 3904, 3968, 4032,
114 4096, 4160, 4224, 4288, 4352, 4416, 4480, 4544
115};
116
117/* REG04[3:1] (VSETA) in mV */
118static const int zx234502_cvc_vseta_values[] = {
119 4100, 4150, 4200, 4250, 4300, 4350, 4400, 4450,
120};
121
122/* REG02[7:5] (VSYS_MIN) in mV */
123static const int zx234502_vsc_sysmin_values[] = {
124 3100, 3200, 3300, 3400, 3500, 3600, 3700,3800
125};
126static int stopchg_flag = 0;
127/*
128 * Return the index in 'tbl' of greatest value that is less than or equal to
129 * 'val'. The index range returned is 0 to 'tbl_size' - 1. Assumes that
130 * the values in 'tbl' are sorted from smallest to largest and 'tbl_size'
131 * is less than 2^8.
132 */
133static u8 zx234502_find_idx(const int tbl[], int tbl_size, int v)
134{
135 int i;
136
137 for (i = 1; i < tbl_size; i++)
138 if (v < tbl[i])
139 break;
140
141 return i - 1;
142}
143
144/* Basic driver I/O routines */
145
146static int zx234502_read(struct zx234502_dev_info *bdi, u8 reg, u8 *data)
147{
148 int ret;
149
150 ret = i2c_smbus_read_byte_data(bdi->client, reg);
151 if (ret < 0)
152 return ret;
153
154 *data = ret;
155 return 0;
156}
157
158static int zx234502_write(struct zx234502_dev_info *bdi, u8 reg, u8 data)
159{
160 return i2c_smbus_write_byte_data(bdi->client, reg, data);
161}
162
163static int zx234502_read_mask(struct zx234502_dev_info *bdi, u8 reg,
164 u8 mask, u8 shift, u8 *data)
165{
166 u8 v;
167 int ret;
168
169 ret = zx234502_read(bdi, reg, &v);
170 if (ret < 0)
171 return ret;
172
173 v &= mask;
174 v >>= shift;
175 *data = v;
176
177 return 0;
178}
179
180static int zx234502_write_mask(struct zx234502_dev_info *bdi, u8 reg,
181 u8 mask, u8 shift, u8 data)
182{
183 u8 v;
184 int ret;
185
186 ret = zx234502_read(bdi, reg, &v);
187 if (ret < 0)
188 return ret;
189
190 v &= ~mask;
191 v |= ((data << shift) & mask);
192
193 return zx234502_write(bdi, reg, v);
194}
195
196static int zx234502_get_field_val(struct zx234502_dev_info *bdi,
197 u8 reg, u8 mask, u8 shift,
198 const int tbl[], int tbl_size,
199 int *val)
200{
201 u8 v;
202 int ret;
203
204 ret = zx234502_read_mask(bdi, reg, mask, shift, &v);
205 if (ret < 0)
206 return ret;
207
208 v = (v >= tbl_size) ? (tbl_size - 1) : v;
209 *val = tbl[v];
210
211 return 0;
212}
213
214static int zx234502_set_field_val(struct zx234502_dev_info *bdi,
215 u8 reg, u8 mask, u8 shift,
216 const int tbl[], int tbl_size,
217 int val)
218{
219 u8 idx;
220
221 idx = zx234502_find_idx(tbl, tbl_size, val);
222
223 return zx234502_write_mask(bdi, reg, mask, shift, idx);
224}
225
226//#ifdef CONFIG_SYSFS
227#if 0
228/*
229 * There are a numerous options that are configurable on the zx234502
230 * that go well beyond what the power_supply properties provide access to.
231 * Provide sysfs access to them so they can be examined and possibly modified
232 * on the fly. They will be provided for the charger power_supply object only
233 * and will be prefixed by 'f_' to make them easier to recognize.
234 */
235
236struct zx234502_sysfs_field_info {
237 struct device_attribute attr;
238 u8 reg;
239 u8 mask;
240 u8 shift;
241};
242
243
244#define ZX234502_SYSFS_FIELD(_name, r, f, m, store) \
245{ \
246 .attr = __ATTR(f_##_name, m, zx234502_sysfs_show, store), \
247 .reg = ZX234502_REG_##r, \
248 .mask = ZX234502_REG_##r##_##f##_MASK, \
249 .shift = ZX234502_REG_##r##_##f##_SHIFT, \
250}
251
252#define ZX234502_SYSFS_FIELD_RW(_name, r, f) \
253 ZX234502_SYSFS_FIELD(_name, r, f, S_IWUSR | S_IRUGO, \
254 zx234502_sysfs_store)
255
256#define ZX234502_SYSFS_FIELD_RO(_name, r, f) \
257 ZX234502_SYSFS_FIELD(_name, r, f, S_IRUGO, NULL)
258
259static ssize_t zx234502_sysfs_show(struct device *dev,
260 struct device_attribute *attr, char *buf);
261static ssize_t zx234502_sysfs_store(struct device *dev,
262 struct device_attribute *attr, const char *buf, size_t count);
263
264
265/* On i386 ptrace-abi.h defines SS that breaks the macro calls below. */
266//#undef SS
267
268static struct zx234502_sysfs_field_info zx234502_sysfs_field_tbl[] = {
269 /* sysfs name reg field in reg */
270 ZX234502_SYSFS_FIELD_RW(chg_reset, MS, CHGRST),
271 ZX234502_SYSFS_FIELD_RW(pmuon, MS, PMUON),
272 ZX234502_SYSFS_FIELD_RW(en_ship, MS, ENSHIP),
273 ZX234502_SYSFS_FIELD_RW(en_otg, MS, ENOTG),
274 ZX234502_SYSFS_FIELD_RW(chg_config, MS, ENCHG),
275 ZX234502_SYSFS_FIELD_RW(en_powerbank, MS, PWRBNK),
276 ZX234502_SYSFS_FIELD_RW(insus, MS, INSUS),
277 ZX234502_SYSFS_FIELD_RW(in_limit, ISC, ISET_DCIN),
278 ZX234502_SYSFS_FIELD_RW(vsys_min, VSC, VSYS_MIN),
279 ZX234502_SYSFS_FIELD_RW(ichg, CCC, ISETA),
280 ZX234502_SYSFS_FIELD_RW(force_ichg_50pct, CCC, ICHG_50PCT),
281 ZX234502_SYSFS_FIELD_RW(iprechg, CVC, IPRECHG),
282 ZX234502_SYSFS_FIELD_RW(vbat_full, CVC, VBAT),
283 ZX234502_SYSFS_FIELD_RW(vpre_to_fast, CVC, VBATFC),
284 ZX234502_SYSFS_FIELD_RW(en_timer, CTC, EN_TIMER),
285 ZX234502_SYSFS_FIELD_RW(en_2timer, CTC, EN_2XTIMER),
286 ZX234502_SYSFS_FIELD_RW(stopchg_flag, OTGC, OTGV),
287 ZX234502_SYSFS_FIELD_RW(iotg_limit, OTGC, OTGI_LIM),
288 ZX234502_SYSFS_FIELD_RW(ents_otg, OTGC, ENTS_OTG),
289 ZX234502_SYSFS_FIELD_RO(en_therm, THR, EN_THERM),
290 ZX234502_SYSFS_FIELD_RW(therm_threshold, THR, THERM_THLD),
291 ZX234502_SYSFS_FIELD_RW(en_2det, THR, EN_2DET),
292 ZX234502_SYSFS_FIELD_RW(en_1det, THR, EN_1DET),
293 ZX234502_SYSFS_FIELD_RW(en_jeita, THR, EN_JEITA),
294 ZX234502_SYSFS_FIELD_RW(en_ilimitdj, THR, EN_ILIMITDJ),
295 ZX234502_SYSFS_FIELD_RW(tscold, TS, COLD),
296 ZX234502_SYSFS_FIELD_RW(tscool, TS, COOL),
297 ZX234502_SYSFS_FIELD_RW(tswarm, TS, WARM),
298 ZX234502_SYSFS_FIELD_RW(tshot, TS, HOT),
299 ZX234502_SYSFS_FIELD_RW(ntcdet, PTS,NTCDET),
300 ZX234502_SYSFS_FIELD_RW(int_clear, CIIS, INT),
301 ZX234502_SYSFS_FIELD_RO(ciis_reg, CIIS, ALL),
302 ZX234502_SYSFS_FIELD_RW(mask_chgrun, CIIM, MASK_CHGRUN),
303 ZX234502_SYSFS_FIELD_RW(mask_inlimit, CIIM, MASK_INLIMIT),
304 ZX234502_SYSFS_FIELD_RW(mask_thr, CIIM, MASK_THR),
305 ZX234502_SYSFS_FIELD_RW(mask_ts, CIIM, MASK_TS),
306 ZX234502_SYSFS_FIELD_RW(mask_dcdet, CIIM, MASK_DCDET),
307 ZX234502_SYSFS_FIELD_RO(cbis_reg, CBIS, ALL),
308 ZX234502_SYSFS_FIELD_RW(mask_pg, CBIM, MASK_DCIN_PG),
309 ZX234502_SYSFS_FIELD_RW(mask_batlow, CBIM, MASK_BATLOW),
310 ZX234502_SYSFS_FIELD_RW(mask_nobat, CBIM, MASK_NOBAT),
311 ZX234502_SYSFS_FIELD_RW(mask_eoc, CBIM, MASK_EOC),
312 ZX234502_SYSFS_FIELD_RW(mask_timer, CBIM, MASK_SAFE_TIMER),
313 ZX234502_SYSFS_FIELD_RW(mask_otg_fault, CBIM, MASK_OTG_FAULT),
314 ZX234502_SYSFS_FIELD_RO(pis_reg, PIS, ALL),
315 ZX234502_SYSFS_FIELD_RW(mask_pwron_it, PIM, MASK_POWERON_IT),
316 ZX234502_SYSFS_FIELD_RW(mask_pwron_lp, PIM, MASK_POWERON_LP),
317 ZX234502_SYSFS_FIELD_RO(cfis_reg, CFIS, ALL),
318 ZX234502_SYSFS_FIELD_RO(version_info, VER, INFO),
319};
320
321static struct attribute *
322 zx234502_sysfs_attrs[ARRAY_SIZE(zx234502_sysfs_field_tbl) + 1];
323
324static const struct attribute_group zx234502_sysfs_attr_group = {
325 .attrs = zx234502_sysfs_attrs,
326};
327
328static void zx234502_sysfs_init_attrs(void)
329{
330 int i, limit = ARRAY_SIZE(zx234502_sysfs_field_tbl);
331
332 for (i = 0; i < limit; i++)
333 zx234502_sysfs_attrs[i] = &zx234502_sysfs_field_tbl[i].attr.attr;
334
335 zx234502_sysfs_attrs[limit] = NULL; /* Has additional entry for this */
336}
337
338static struct zx234502_sysfs_field_info *zx234502_sysfs_field_lookup(
339 const char *name)
340{
341 int i, limit = ARRAY_SIZE(zx234502_sysfs_field_tbl);
342
343 for (i = 0; i < limit; i++)
344 if (!strcmp(name, zx234502_sysfs_field_tbl[i].attr.attr.name))
345 break;
346
347 if (i >= limit)
348 return NULL;
349
350 return &zx234502_sysfs_field_tbl[i];
351}
352
353static ssize_t zx234502_sysfs_show(struct device *dev,
354 struct device_attribute *attr, char *buf)
355{
356 struct power_supply *psy = dev_get_drvdata(dev);
357 struct zx234502_dev_info *bdi =
358 container_of(psy, struct zx234502_dev_info, charger);
359 struct zx234502_sysfs_field_info *info;
360 int ret;
361 u8 v;
362
363 info = zx234502_sysfs_field_lookup(attr->attr.name);
364 if (!info)
365 return -EINVAL;
366
367 ret = zx234502_read_mask(bdi, info->reg, info->mask, info->shift, &v);
368 if (ret)
369 return ret;
370
371 return scnprintf(buf, PAGE_SIZE, "%hhx\n", v);
372}
373
374static ssize_t zx234502_sysfs_store(struct device *dev,
375 struct device_attribute *attr, const char *buf, size_t count)
376{
377 struct power_supply *psy = dev_get_drvdata(dev);
378 struct zx234502_dev_info *bdi =
379 container_of(psy, struct zx234502_dev_info, charger);
380 struct zx234502_sysfs_field_info *info;
381 int ret;
382 u8 v;
383
384 info = zx234502_sysfs_field_lookup(attr->attr.name);
385 if (!info)
386 return -EINVAL;
387
388 ret = kstrtou8(buf, 0, &v);
389 if (ret < 0)
390 return ret;
391
392 ret = zx234502_write_mask(bdi, info->reg, info->mask, info->shift, v);
393 if (ret)
394 return ret;
395
396 return count;
397}
398
399static int zx234502_sysfs_create_group(struct zx234502_dev_info *bdi)
400{
401 zx234502_sysfs_init_attrs();
402
403 return sysfs_create_group(&bdi->charger.dev->kobj,
404 &zx234502_sysfs_attr_group);
405}
406
407static void zx234502_sysfs_remove_group(struct zx234502_dev_info *bdi)
408{
409 sysfs_remove_group(&bdi->charger.dev->kobj, &zx234502_sysfs_attr_group);
410}
411#else
412static int zx234502_sysfs_create_group(struct zx234502_dev_info *bdi)
413{
414 return 0;
415}
416
417static inline void zx234502_sysfs_remove_group(struct zx234502_dev_info *bdi) {}
418#endif
419
420#if 0
421/*set the Vsys min*/
422static int zx234502_set_vsys_min(struct zx234502_dev_info *bdi,const union power_supply_propval *val)
423{
424 return zx234502_set_field_val(bdi, ZX234502_REG_VSC,
425 ZX234502_REG_VSC_VSYS_MIN_MASK, ZX234502_REG_VSC_VSYS_MIN_SHIFT,
426 zx234502_cvc_vseta_values,
427 ARRAY_SIZE(zx234502_cvc_vseta_values), val->intval);
428 //return 0
429}
430#endif
431static int zx234502_register_reset(struct zx234502_dev_info *bdi)
432{
433 int ret, limit = 100;
434 u8 v;
435
436 /* Reset the registers */
437 ret = zx234502_write_mask(bdi, ZX234502_REG_MS,ZX234502_REG_MS_CHGRST_MASK,ZX234502_REG_MS_CHGRST_SHIFT,0x1);
438 if (ret < 0)
439 return ret;
440
441 /* Reset bit will be cleared by hardware so poll until it is */
442 do
443 {
444 ret = zx234502_read_mask(bdi, ZX234502_REG_MS,ZX234502_REG_MS_CHGRST_MASK,ZX234502_REG_MS_CHGRST_SHIFT,&v);
445 if (ret < 0)
446 return ret;
447
448 if (!v)
449 break;
450
451 udelay(10);
452 } while (--limit);
453
454 if (!limit)
455 return -EIO;
456
457 return 0;
458}
459
460
461/* Charger power supply property routines */
462
463static int zx234502_charger_get_charge_type(struct zx234502_dev_info *bdi,union power_supply_propval *val)
464{
465 val->intval = bdi->charger.type;
466 return 0;
467}
468
469static int zx234502_charger_get_status(struct zx234502_dev_info *bdi,union power_supply_propval *val)
470{
471 u8 cbis_reg=0,ms_reg=0;
472 int status=POWER_SUPPLY_STATUS_UNKNOWN;
473 int ret=0;
474
475 mutex_lock(&bdi->bs_reg_lock);
476
477 if (bdi->battery_status_valid) {
478 cbis_reg = bdi->cbis_curr_reg;
479 bdi->battery_status_valid = false;
480 mutex_unlock(&bdi->bs_reg_lock);
481 } else {
482 mutex_unlock(&bdi->bs_reg_lock);
483
484 ret = zx234502_read(bdi, ZX234502_REG_CBIS, &cbis_reg);
485 if (ret < 0)
486 return ret;
487 }
488
489 ret = zx234502_read(bdi, ZX234502_REG_MS, &ms_reg);
490 if (ret < 0)
491 return ret;
492
493 /*
494 * The battery must be discharging when any of these are true:
495 * - there is no good power source;
496 * - there is a charge fault.
497 * Could also be discharging when in "supplement mode" but
498 * there is no way to tell when its in that mode.
499 */
500 if (!(cbis_reg & ZX234502_REG_CBIS_DCIN_PG_MASK )||(cbis_reg & ZX234502_REG_CBIS_NOBAT_MASK )) {
501 status = POWER_SUPPLY_STATUS_DISCHARGING;
502 }
503 else if (ms_reg & ZX234502_REG_MS_ENCHG_MASK){
504 status = POWER_SUPPLY_STATUS_NOT_CHARGING;
505 }
506 // disable or full
507 else if(ms_reg & ZX234502_REG_MS_INSUS_MASK)
508 {
509 if (((cbis_reg & ZX234502_REG_CBIS_CHGSTAT_MASK) >> ZX234502_REG_CBIS_CHGSTAT_SHIFT)== 3)
510 {
511 status = POWER_SUPPLY_STATUS_FULL;
512 }
513 else
514 status = POWER_SUPPLY_STATUS_NOT_CHARGING;
515 }
516 else {
517 cbis_reg &= ZX234502_REG_CBIS_CHGSTAT_MASK;
518 cbis_reg >>= ZX234502_REG_CBIS_CHGSTAT_SHIFT;
519
520 switch (cbis_reg) {
521 case 0x0: /* Charging */
522 case 0x2: /* ReCharging frome THERM */
523 status = POWER_SUPPLY_STATUS_CHARGING;
524 break;
525 case 0x3: /* Charge Termination Done */
526 status = POWER_SUPPLY_STATUS_FULL;
527 break;
528 default:
529 ret = -EIO;
530 }
531 }
532
533 if (!ret)
534 val->intval = status;
535
536 return ret;
537}
538
539static int zx234502_charger_get_health(struct zx234502_dev_info *bdi,union power_supply_propval *val)
540{
541 u8 ciis_reg=0, cbis_reg=0, cfis_reg=0;
542 int health=0, ret=0;
543
544 mutex_lock(&bdi->bs_reg_lock);
545
546 if (bdi->charger_health_valid) {
547 bdi->charger_health_valid = false;
548 cbis_reg = bdi->cbis_curr_reg;
549 ciis_reg = bdi->ciis_curr_reg;
550 cfis_reg = bdi->cfis_curr_reg;
551 mutex_unlock(&bdi->bs_reg_lock);
552 } else {
553 mutex_unlock(&bdi->bs_reg_lock);
554
555 ret = zx234502_read(bdi, ZX234502_REG_CIIS, &ciis_reg);
556 if (ret < 0)
557 return ret;
558 ret = zx234502_read(bdi, ZX234502_REG_CBIS, &cbis_reg);
559 if (ret < 0)
560 return ret;
561 ret = zx234502_read(bdi, ZX234502_REG_CFIS, &cfis_reg);
562 if (ret < 0)
563 return ret;
564
565 printk(KERN_INFO "zx234502_charger_get_health REG_0xa=0x%x,REG_0xc=0x%x,REG_0x10=0x%x.\n",ciis_reg,cbis_reg,cfis_reg);
566
567 }
568
569 if (cbis_reg & ZX234502_REG_CBIS_OTG_FAULT_MASK) {
570 /*
571 * This could be over-current or over-voltage but there's
572 * no way to tell which. Return 'OVERVOLTAGE' since there
573 * isn't an 'OVERCURRENT' value defined that we can return
574 * even if it was over-current.
575 */
576 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
577 }
578 else if(cbis_reg & ZX234502_REG_CBIS_SAFE_TIMER_MASK) {
579 health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
580 }
581 else if(cbis_reg & ZX234502_REG_CBIS_DCIN_PG_MASK) {
582 health = POWER_SUPPLY_HEALTH_GOOD;
583 }
584 else if(ciis_reg & (ZX234502_REG_CIIS_INLIMIT_MASK|ZX234502_REG_CIIS_THERM_MASK)) {
585 health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
586 }
587 else if(cfis_reg & ZX234502_REG_CFIS_THSD_MASK){
588 health = POWER_SUPPLY_HEALTH_OVERHEAT; /*the chip hot error*/
589 }
590 else{
591 health = POWER_SUPPLY_HEALTH_UNKNOWN;
592 }
593
594 val->intval = health;
595
596 return 0;
597}
598
599int zx234502_charger_get_online(struct zx234502_dev_info *bdi,union power_supply_propval *val)
600{
601 u8 v;
602 int ret;
603
604 ret = zx234502_read_mask(bdi, ZX234502_REG_CBIS,ZX234502_REG_CBIS_DCIN_PG_MASK,
605 ZX234502_REG_CBIS_DCIN_PG_SHIFT, &v);
606 if (ret < 0)
607 return ret;
608
609 val->intval = v;
610 return 0;
611}EXPORT_SYMBOL (zx234502_charger_get_online);
612#if 0
613static int zx234502_charger_get_current(struct zx234502_dev_info *bdi,union power_supply_propval *val)
614{
615 int curr, ret;
616
617 ret = zx234502_get_field_val(bdi, ZX234502_REG_ISC,
618 ZX234502_REG_ISC_ISET_DCIN_MASK, ZX234502_REG_ISC_ISET_DCIN_SHIFT,
619 zx234502_in_ilimit_values,
620 ARRAY_SIZE(zx234502_in_ilimit_values), &curr);
621 if (ret < 0)
622 return ret;
623
624 val->intval = curr;
625 return 0;
626}
627
628static int zx234502_charger_get_current_max(struct zx234502_dev_info *bdi,union power_supply_propval *val)
629{
630 int idx = ARRAY_SIZE(zx234502_in_ilimit_values) - 1;
631
632 val->intval = zx234502_in_ilimit_values[idx];
633 return 0;
634}
635
636static int zx234502_charger_get_voltage(struct zx234502_dev_info *bdi,union power_supply_propval *val)
637{
638#if 0
639 int voltage, ret;
640 ret = zx234502_get_field_val(bdi, ZX234502_REG_CVC,
641 ZX234502_REG_CVC_VBAT_MASK, ZX234502_REG_CVC_VBAT_SHIFT,
642 zx234502_cvc_vseta_values,
643 ARRAY_SIZE(zx234502_cvc_vseta_values), &voltage);
644 if (ret < 0)
645 return ret;
646
647 val->intval = voltage;
648#endif
649return 0;
650}
651#endif
652
653static int zx234502_charger_get_charger_enabled(struct zx234502_dev_info *bdi,union power_supply_propval *val)
654{
655 u8 charger_enabled;
656 int ret;
657
658 ret = zx234502_read_mask(bdi, ZX234502_REG_MS,
659 ZX234502_REG_MS_INSUS_MASK,
660 ZX234502_REG_MS_INSUS_SHIFT, &charger_enabled);
661 if (ret < 0)
662 return ret;
663
664 val->intval = !charger_enabled;
665 return 0;
666}
667static int zx234502_charger_get_voltage_max(struct zx234502_dev_info *bdi,union power_supply_propval *val)
668{
669 int voltage, ret;
670
671 ret = zx234502_get_field_val(bdi, ZX234502_REG_CVC,
672 ZX234502_REG_CVC_VBAT_MASK, ZX234502_REG_CVC_VBAT_SHIFT,
673 zx234502_cvc_vseta_values,
674 ARRAY_SIZE(zx234502_cvc_vseta_values), &voltage);
675 if (ret < 0)
676 return ret;
677
678 val->intval = voltage;
679 return 0;
680
681}
682#if 0
683static int zx234502_charger_set_current(struct zx234502_dev_info *bdi,union power_supply_propval *val)
684{
685 return zx234502_set_field_val(bdi, ZX234502_REG_ISC,
686 ZX234502_REG_ISC_ISET_DCIN_MASK, ZX234502_REG_ISC_ISET_DCIN_MASK,
687 zx234502_in_ilimit_values,
688 ARRAY_SIZE(zx234502_in_ilimit_values), val->intval);
689
690}
691#endif
692static int zx234502_charger_set_voltage(struct zx234502_dev_info *bdi,const union power_supply_propval *val)
693{
694 return zx234502_set_field_val(bdi, ZX234502_REG_CVC,
695 ZX234502_REG_CVC_VBAT_MASK, ZX234502_REG_CVC_VBAT_SHIFT,
696 zx234502_cvc_vseta_values,
697 ARRAY_SIZE(zx234502_cvc_vseta_values), val->intval);
698}
699
700static int zx234502_charger_set_charger_config(struct zx234502_dev_info *bdi,const union power_supply_propval *val)
701{
702 int ret;
703 union power_supply_propval enable_charge;
704
705 if (val->intval){
706 enable_charge.intval = 0 ;
707 stopchg_flag = 1;
708 ret = zx234502_write_mask(bdi, ZX234502_REG_OTGC,
709 ZX234502_REG_OTGC_OTGV_MASK,
710 ZX234502_REG_OTGC_OTGV_SHIFT,1);
711 printk("mmi start chg\n");
712 }
713 else{
714 stopchg_flag = 2;
715 enable_charge.intval = 1 ;
716 ret = zx234502_write_mask(bdi, ZX234502_REG_OTGC,
717 ZX234502_REG_OTGC_OTGV_MASK,
718 ZX234502_REG_OTGC_OTGV_SHIFT,2);
719 printk("mmi stop chg\n");
720 }
721
722 ret = zx234502_write_mask(bdi, ZX234502_REG_MS,
723 ZX234502_REG_MS_INSUS_MASK,
724 ZX234502_REG_MS_INSUS_SHIFT, enable_charge.intval ); /*0:disable 1:enable*/
725
726 return ret;
727}
728
729
730static int zx234502_charger_get_property(struct power_supply *psy,enum power_supply_property psp, union power_supply_propval *val)
731{
732 struct zx234502_dev_info *bdi = container_of(psy, struct zx234502_dev_info, charger);
733 int ret;
734
735 //dev_dbg(bdi->dev, "prop: %d\n", psp);
736
737 //pm_runtime_get_sync(bdi->dev);
738
739 switch (psp) {
740 case POWER_SUPPLY_PROP_PC1_AC2:
741 ret = zx234502_charger_get_charge_type(bdi, val);
742 break;
743
744 case POWER_SUPPLY_PROP_STATUS:
745 ret = zx234502_charger_get_status(bdi, val);
746 break;
747 case POWER_SUPPLY_PROP_HEALTH:
748 ret = zx234502_charger_get_health(bdi, val);
749 break;
750 case POWER_SUPPLY_PROP_ONLINE:
751 ret = zx234502_charger_get_online(bdi, val);
752 break;
753
754 /*
755 case POWER_SUPPLY_PROP_CURRENT_NOW:
756 ret = zx234502_charger_get_current(bdi, val);
757 break;
758
759 case POWER_SUPPLY_PROP_CURRENT_MAX:
760 ret = zx234502_charger_get_current_max(bdi, val);
761 break;
762
763 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
764 ret = zx234502_charger_get_voltage(bdi, val);
765 break;
766*/
767 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
768 ret = zx234502_charger_get_voltage_max(bdi, val);
769 break;
770
771 case POWER_SUPPLY_PROP_CHARGE_ENABLED:
772 ret = zx234502_charger_get_charger_enabled(bdi, val);
773 break;
774 default:
775 ret = -ENODATA;
776 }
777
778 //pm_runtime_put_sync(bdi->dev);
779 return ret;
780}
781
782static int zx234502_charger_set_property(struct power_supply *psy,enum power_supply_property psp,
783 const union power_supply_propval *val)
784{
785 struct zx234502_dev_info *bdi =
786 container_of(psy, struct zx234502_dev_info, charger);
787 int ret;
788
789 //dev_dbg(bdi->dev, "prop: %d\n", psp);
790
791 //pm_runtime_get_sync(bdi->dev);
792
793 switch (psp) {
794#if 0
795 case POWER_SUPPLY_PROP_CURRENT_NOW:
796 ret = zx234502_charger_set_current(bdi, val);
797 break;
798#endif
799 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
800 ret = zx234502_charger_set_voltage(bdi, val);
801 break;
802
803 case POWER_SUPPLY_PROP_CHARGE_ENABLED:
804 ret = zx234502_charger_set_charger_config(bdi, val);
805 power_supply_changed(&bdi->charger);
806 break;
807 default:
808 ret = -EINVAL;
809 }
810
811 //pm_runtime_put_sync(bdi->dev);
812 return ret;
813}
814
815static int zx234502_charger_property_is_writeable(struct power_supply *psy,enum power_supply_property psp)
816{
817 int ret;
818
819 switch (psp)
820 {
821 //case POWER_SUPPLY_PROP_CURRENT_NOW:
822 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
823 case POWER_SUPPLY_PROP_CHARGE_ENABLED:
824 ret = 1;
825 break;
826 default:
827 ret = 0;
828 break;
829 }
830
831 return ret;
832}
833
834static enum power_supply_property zx234502_charger_properties[] = {
835 POWER_SUPPLY_PROP_PC1_AC2,
836 POWER_SUPPLY_PROP_STATUS,
837 POWER_SUPPLY_PROP_HEALTH,
838 POWER_SUPPLY_PROP_ONLINE,
839 //POWER_SUPPLY_PROP_CURRENT_NOW,
840 //POWER_SUPPLY_PROP_CURRENT_MAX,
841 //POWER_SUPPLY_PROP_VOLTAGE_NOW,
842 POWER_SUPPLY_PROP_VOLTAGE_MAX,
843 POWER_SUPPLY_PROP_CHARGE_ENABLED,
844};
845
846static char *zx234502_charger_supplied_to[] = {
847 "main-battery",
848};
849
850static void zx234502_charger_init(struct power_supply *charger)
851{
852 charger->name = "charger";
853 charger->type = POWER_SUPPLY_PCAC_UNKNOWN;
854 charger->properties = zx234502_charger_properties;
855 charger->num_properties = ARRAY_SIZE(zx234502_charger_properties);
856 charger->supplied_to = zx234502_charger_supplied_to;
857 //charger->num_supplies = ARRAY_SIZE(zx234502_charger_supplied_to);
858 charger->get_property = zx234502_charger_get_property;
859 charger->set_property = zx234502_charger_set_property;
860 charger->property_is_writeable = zx234502_charger_property_is_writeable;
861}
862
863/* Battery power supply property routines */
864
865static int zx234502_battery_get_health(struct zx234502_dev_info *bdi,union power_supply_propval *val)
866{
867 u8 v;
868 int health, ret;
869
870 mutex_lock(&bdi->bs_reg_lock);
871
872 if(true!=bdi->pdata->ts_flag){
873 val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
874 mutex_unlock(&bdi->bs_reg_lock);
875 return 0;
876 }
877
878 if (bdi->battery_health_valid) {
879 v = bdi->ciis_curr_reg;
880 bdi->battery_health_valid = false;
881 } else {
882
883 ret = zx234502_read(bdi, ZX234502_REG_CIIS, &v);
884 if (ret < 0){
885
886 mutex_unlock(&bdi->bs_reg_lock);
887 return ret;
888 }
889 }
890
891 if (v & ZX234502_REG_CIIS_THERM_MASK) {
892 health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
893 } else {
894 v &= ZX234502_REG_CIIS_TS_METER_MASK;
895 v >>= ZX234502_REG_CIIS_TS_METER_SHIFT;
896
897 switch (v) {
898 case ZX234502_REG_CISS_TS_NORMAL: /* Normal */
899 health = POWER_SUPPLY_HEALTH_GOOD;
900 break;
901 case ZX234502_REG_CISS_TS_WARM: /*warm*/
902 health = POWER_SUPPLY_HEALTH_WARM;
903 break;
904 case ZX234502_REG_CISS_TS_HOT: /* TS1 Hot */
905 health = POWER_SUPPLY_HEALTH_OVERHEAT;
906 break;
907 case ZX234502_REG_CISS_TS_COOL:/*Cool*/
908 health = POWER_SUPPLY_HEALTH_COOL;
909 break;
910 case ZX234502_REG_CISS_TS_COLD: /* TS1 Cold */
911 health = POWER_SUPPLY_HEALTH_COLD;
912 break;
913 default:
914 health = POWER_SUPPLY_HEALTH_UNKNOWN;
915 }
916 }
917
918 val->intval = health;
919 mutex_unlock(&bdi->bs_reg_lock);
920 return 0;
921}
922
923static int zx234502_battery_get_online(struct zx234502_dev_info *bdi,union power_supply_propval *val)
924{
925 u8 batfet_disable;
926 int ret;
927
928 ret = zx234502_read_mask(bdi, ZX234502_REG_CBIS,
929 ZX234502_REG_CBIS_NOBAT_MASK,
930 ZX234502_REG_CBIS_NOBAT_SHIFT, &batfet_disable);
931 if (ret < 0)
932 return ret;
933
934 val->intval = !batfet_disable;
935 return 0;
936}
937#if 0
938static int zx234502_battery_get_capacity(struct zx234502_dev_info *bdi,union power_supply_propval *val)
939{
940 int ret;
941 uint volt;
942 int bat_levl = 0;
943 int i =0;
944 //union power_supply_propval * online;
945 struct zx234502_bat_calibration *calibration;
946
947 //zx234502_charger_get_online(bdi,online);
948
949 u8 v;
950 ret = zx234502_read_mask(bdi, ZX234502_REG_CBIS,ZX234502_REG_CBIS_DCIN_PG_MASK,
951 ZX234502_REG_CBIS_DCIN_PG_SHIFT, &v);
952 if(v)
953 calibration = bdi->pdata->charging;
954 else
955 calibration = bdi->pdata->discharging;
956//#ifdef CONFIG_ZX234290_ADC
957 volt = get_battery_voltage();
958//#endif
959 if (volt > calibration[0].voltage) {
960 bat_levl = calibration[0].level;
961 } else {
962 for (i = 0; calibration[i+1].voltage >= 0; i++) {
963 if (volt <= calibration[i].voltage &&
964 volt >= calibration[i+1].voltage) {
965 /* interval found - interpolate within range */
966 bat_levl = calibration[i].level -
967 ((calibration[i].voltage - volt) *
968 (calibration[i].level -
969 calibration[i+1].level)) /
970 (calibration[i].voltage -
971 calibration[i+1].voltage);
972 break;
973 }
974 }
975 }
976
977 val->intval = bat_levl;
978 //return 0;
979
980 return ret;
981}
982#endif
983
984static int zx234502_battery_set_online(struct zx234502_dev_info *bdi,const union power_supply_propval *val)
985{
986 return zx234502_write_mask(bdi, ZX234502_REG_MS,
987 ZX234502_REG_MS_ENSHIP_MASK,
988 ZX234502_REG_MS_ENSHIP_SHIFT, !val->intval); /*1:enable 0:disable*/
989}
990
991
992static int zx234502_battery_get_property(struct power_supply *psy,enum power_supply_property psp, union power_supply_propval *val)
993{
994 struct zx234502_dev_info *bdi =
995 container_of(psy, struct zx234502_dev_info, battery);
996 int ret;
997
998 //dev_dbg(bdi->dev, "prop: %d\n", psp);
999
1000 //pm_runtime_get_sync(bdi->dev);
1001
1002 switch (psp) {
1003
1004 case POWER_SUPPLY_PROP_HEALTH:
1005 ret = zx234502_battery_get_health(bdi, val);
1006 break;
1007 case POWER_SUPPLY_PROP_ONLINE:
1008 ret = zx234502_battery_get_online(bdi, val);
1009 break;
1010
1011 case POWER_SUPPLY_PROP_TEMP:
1012 val->intval = get_adc2_voltage();
1013 ret = 0;
1014 break;
1015
1016 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
1017 //#ifdef CONFIG_ZX234290_ADC
1018 val->intval = get_adc1_voltage() - 15;
1019 ret = 0;
1020 break;
1021#if 0
1022 case POWER_SUPPLY_PROP_CAPACITY:
1023 ret = zx234502_battery_get_capacity(bdi, val);
1024 break;
1025#endif
1026 default:
1027 ret = -ENODATA;
1028 }
1029
1030 //pm_runtime_put_sync(bdi->dev);
1031 return ret;
1032}
1033
1034static int zx234502_battery_set_property(struct power_supply *psy,enum power_supply_property psp,
1035 const union power_supply_propval *val)
1036{
1037 struct zx234502_dev_info *bdi =
1038 container_of(psy, struct zx234502_dev_info, battery);
1039 int ret;
1040
1041 //dev_dbg(bdi->dev, "prop: %d\n", psp);
1042
1043 //pm_runtime_put_sync(bdi->dev);
1044
1045 switch (psp) {
1046 case POWER_SUPPLY_PROP_ONLINE:
1047 ret = zx234502_battery_set_online(bdi, val);
1048 break;
1049 default:
1050 ret = -EINVAL;
1051 }
1052
1053 //pm_runtime_put_sync(bdi->dev);
1054 return ret;
1055}
1056
1057static int zx234502_battery_property_is_writeable(struct power_supply *psy,enum power_supply_property psp)
1058{
1059 int ret;
1060
1061 switch (psp) {
1062 case POWER_SUPPLY_PROP_ONLINE:
1063 ret = 1;
1064 break;
1065 default:
1066 ret = 0;
1067 }
1068
1069 return ret;
1070}
1071
1072static enum power_supply_property zx234502_battery_properties[] = {
1073 POWER_SUPPLY_PROP_HEALTH,
1074 POWER_SUPPLY_PROP_ONLINE,
1075 POWER_SUPPLY_PROP_TEMP,
1076 POWER_SUPPLY_PROP_VOLTAGE_NOW,
1077 //POWER_SUPPLY_PROP_CAPACITY,
1078};
1079
1080static void zx234502_battery_init(struct power_supply *battery)
1081{
1082 battery->name = "battery";
1083 battery->type = POWER_SUPPLY_PCAC_UNKNOWN;
1084 battery->properties = zx234502_battery_properties;
1085 battery->num_properties = ARRAY_SIZE(zx234502_battery_properties);
1086 battery->get_property = zx234502_battery_get_property;
1087 battery->set_property = zx234502_battery_set_property;
1088 battery->property_is_writeable = zx234502_battery_property_is_writeable;
1089}
1090
1091
1092static int zx234502_boost_get_online(struct zx234502_dev_info *bdi,union power_supply_propval *val)
1093{
1094
1095 val->intval = bdi->boost_online_flag;
1096 return 0;
1097}
1098
1099
1100static int zx234502_boost_get_current_now(struct zx234502_dev_info *bdi,union power_supply_propval *val)
1101{
1102 //gpio_set1 is GPIO39
1103 //gpio_set2 is GPIO40
1104 //gpio_set3 is GPIO41
1105 int gpio_set1,gpio_set2,gpio_set3;
1106
1107 gpio_set1 = gpio_get_value(bdi->pdata->boost_cur_gpio1);
1108 gpio_set2 = gpio_get_value(bdi->pdata->boost_cur_gpio2);
1109 gpio_set3 = gpio_get_value(bdi->pdata->boost_cur_gpio3);
1110
1111 if((GPIO_LOW==gpio_set1)&(GPIO_LOW==gpio_set2)&(GPIO_HIGH==gpio_set3)){
1112 val->intval = 600;
1113 }
1114 else if((GPIO_LOW==gpio_set1)&(GPIO_HIGH==gpio_set2)&(GPIO_LOW==gpio_set3)){
1115 val->intval = 1000;
1116 }
1117 else if((GPIO_LOW==gpio_set1)&(GPIO_HIGH==gpio_set2)&(GPIO_HIGH==gpio_set3)){
1118 val->intval = 1750;
1119 }
1120 else if((GPIO_HIGH==gpio_set1)&(GPIO_LOW==gpio_set2)&(GPIO_LOW==gpio_set3)){
1121 val->intval = 2000;
1122 }
1123 else if((GPIO_HIGH==gpio_set1)&(GPIO_LOW==gpio_set2)&(GPIO_HIGH==gpio_set3)){
1124 val->intval = 2850;
1125 }
1126 else{
1127
1128 dev_dbg(bdi->dev, "The boost current set with err\n");
1129 return -1;
1130 }
1131
1132 return 0;
1133}
1134
1135#if 0
1136static int zx234502_boost_get_current_max(struct zx234502_dev_info *bdi, union power_supply_propval *val)
1137{
1138 val->intval = 2850;
1139 return 0;
1140}
1141#endif
1142static int zx234502_boost_set_charge_enable(struct zx234502_dev_info *bdi,const union power_supply_propval *val)
1143{
1144 zx234502_write_mask(bdi,ZX234502_REG_MS,
1145 ZX234502_REG_MS_PWRBNK_MASK,ZX234502_REG_MS_PWRBNK_SHIFT,val->intval);
1146
1147 /*set the gpio34 open = HIGH*/
1148 gpio_set_value(bdi->pdata->boost_loadswitch_gpio,val->intval);
1149 //zx29_gpio_output_data(bdi->pdata->boost_loadswitch_gpio,GPIO_HIGH);
1150
1151 return 0;
1152}
1153
1154static int zx234502_boost_set_current_now(struct zx234502_dev_info *bdi,const union power_supply_propval *val)
1155{
1156 //gpio from 35/36/37 changed to 39/40/41
1157 //gpio_set1 is GPIO39
1158 //gpio_set2 is GPIO40
1159 //gpio_set3 is GPIO41
1160 int gpio_set1,gpio_set2,gpio_set3;
1161
1162 if(val->intval < 601){
1163 /*0.6A GPIO35:LOW GPIO36:LOW GPIO37:HIGH 40k */
1164 gpio_set1 = GPIO_LOW;
1165 gpio_set2 = GPIO_LOW;
1166 gpio_set3 = GPIO_HIGH;
1167 }
1168 else if( (600 < val->intval)&&(val->intval< 1001)){
1169 /*1A GPIO35:LOW GPIO36:HIGH GPIO37:LOW 20k */
1170 gpio_set1 = GPIO_LOW;
1171 gpio_set2 = GPIO_HIGH;
1172 gpio_set3 = GPIO_LOW;
1173 }
1174 else if( (1000 < val->intval)&&(val->intval < 1751)){
1175 /*1.75A GPIO35:LOW GPIO36:HIGH GPIO37:HIGH 13.3k*/
1176 gpio_set1 = GPIO_LOW;
1177 gpio_set2 = GPIO_HIGH;
1178 gpio_set3 = GPIO_HIGH;
1179 }
1180 else if(( 1750 < val->intval) &&( val->intval < 2001)){
1181 /*2A GPIO35:HIGH GPIO36:LOW GPIO37:LOW 10k */
1182 gpio_set1 = GPIO_HIGH;
1183 gpio_set2 = GPIO_LOW;
1184 gpio_set3 = GPIO_LOW;
1185 }
1186 else{
1187 /*2.85A GPIO35:HIGH GPIO36:LOW GPIO37:HIGH 8k*/
1188 gpio_set1 = GPIO_HIGH;
1189 gpio_set2 = GPIO_LOW;
1190 gpio_set3 = GPIO_HIGH;
1191 }
1192
1193 gpio_set_value(bdi->pdata->boost_cur_gpio1, gpio_set1);
1194 gpio_set_value(bdi->pdata->boost_cur_gpio2, gpio_set2);
1195 gpio_set_value(bdi->pdata->boost_cur_gpio3, gpio_set3);
1196 return 0;
1197}
1198
1199static int zx234502_boost_get_property(struct power_supply *psy,enum power_supply_property psp, union power_supply_propval *val)
1200{
1201 struct zx234502_dev_info *bdi =
1202 container_of(psy, struct zx234502_dev_info, boost);
1203 int ret;
1204
1205 //dev_dbg(bdi->dev, "prop: %d\n", psp);
1206
1207 //pm_runtime_get_sync(bdi->dev);
1208
1209 switch (psp) {
1210 case POWER_SUPPLY_PROP_ONLINE:
1211 ret = zx234502_boost_get_online(bdi, val);
1212 break;
1213 case POWER_SUPPLY_PROP_CURRENT_NOW:
1214 ret = zx234502_boost_get_current_now(bdi, val);
1215 break;
1216 #if 0
1217 case POWER_SUPPLY_PROP_CURRENT_MAX:
1218 ret = zx234502_boost_get_current_max(bdi, val);
1219 break;
1220 #endif
1221 default:
1222 ret = -ENODATA;
1223 }
1224
1225 //pm_runtime_put_sync(bdi->dev);
1226 return ret;
1227}
1228
1229static int zx234502_boost_set_property(struct power_supply *psy,enum power_supply_property psp,
1230 const union power_supply_propval *val)
1231{
1232 struct zx234502_dev_info *bdi =
1233 container_of(psy, struct zx234502_dev_info, boost);
1234 int ret;
1235
1236 //dev_dbg(bdi->dev, "prop: %d\n", psp);
1237
1238 //pm_runtime_put_sync(bdi->dev);
1239
1240 switch (psp) {
1241 case POWER_SUPPLY_PROP_BOOST_ENABLE:
1242 ret = zx234502_boost_set_charge_enable(bdi, val);
1243 break;
1244 case POWER_SUPPLY_PROP_CURRENT_NOW:
1245 ret = zx234502_boost_set_current_now(bdi, val);
1246 break;
1247
1248 default:
1249 ret = -EINVAL;
1250 }
1251
1252 //pm_runtime_put_sync(bdi->dev);
1253 return ret;
1254}
1255
1256static int zx234502_boost_property_is_writeable(struct power_supply *psy,enum power_supply_property psp)
1257{
1258 int ret;
1259
1260 switch (psp) {
1261 case POWER_SUPPLY_PROP_BOOST_ENABLE:
1262 case POWER_SUPPLY_PROP_CURRENT_NOW:
1263 ret = 1;
1264 break;
1265 default:
1266 ret = 0;
1267 }
1268
1269 return ret;
1270}
1271
1272static enum power_supply_property zx234502_boost_properties[] = {
1273 POWER_SUPPLY_PROP_ONLINE,
1274 POWER_SUPPLY_PROP_CURRENT_NOW,
1275 //WER_SUPPLY_PROP_CURRENT_MAX,
1276 POWER_SUPPLY_PROP_BOOST_ENABLE,
1277};
1278
1279static void zx234502_boost_init(struct power_supply *boost)
1280{
1281 #ifdef DBG_CHARGE
1282 //printk(KERN_INFO "zx234502_boost_init =%x.\n",boost);
1283 #endif
1284 boost->name = "boost";
1285 boost->type = POWER_SUPPLY_PCAC_UNKNOWN;
1286 boost->properties = zx234502_boost_properties;
1287 boost->num_properties = ARRAY_SIZE(zx234502_boost_properties);
1288 boost->get_property = zx234502_boost_get_property;
1289 boost->set_property = zx234502_boost_set_property;
1290 boost->property_is_writeable = zx234502_boost_property_is_writeable;
1291}
1292
1293
1294static int zx234502_charger_gpio_config(struct device *dev,int pin,gpio_func_id func_sel,char *name)
1295{
1296 int ret = -1;
1297
1298 if (gpio_is_valid(pin)){
1299 ret = gpio_request(pin, name);
1300 if (ret){
1301 dev_err(dev, "cannot get [%s] gpio\n",name);
1302 return -1;
1303 }
1304 ret = zx29_gpio_config(pin,func_sel);
1305 if(ret){
1306 dev_err(dev, "cannot config [%s] gpio\n",name);
1307 gpio_free(pin);
1308 return -1;
1309 }
1310 }
1311
1312 return 0;
1313}
1314
1315#if 0
1316//zx234500_charger_gpio_config_input
1317static void zx234502_charger_gpio_config_input(struct device *dev,int gpio,gpio_func_id func_sel,char *str)
1318{
1319 if(zx234502_charger_gpio_config(dev,gpio,func_sel,str)!=0)
1320 return;
1321 zx29_gpio_set_direction(gpio,GPIO_IN);
1322 zx29_gpio_input_data(gpio);
1323}
1324#endif
1325
1326//zx234500_charger_gpio_config_output
1327static int zx234502_charger_gpio_config_output(struct device *dev,int gpio,gpio_func_id func_sel,char *str,int value2)
1328{
1329 if(zx234502_charger_gpio_config(dev,gpio,func_sel,str)!=0)
1330 return -1;
1331 zx29_gpio_set_direction(gpio,GPIO_OUT);
1332 zx29_gpio_output_data(gpio,value2);
1333
1334 return 0;
1335}
1336
1337static int zx234502_boost_gpio_init(struct device *dev, struct zx234502_platform_data *pdata)
1338{
1339 int ret = -1;
1340
1341 ret = zx234502_charger_gpio_config_output(dev,pdata->boost_loadswitch_gpio,pdata->boost_loadswitch_fun_sel,"LoadSwitch",GPIO_LOW);
1342 /*set the out put current 1A*/
1343 ret += zx234502_charger_gpio_config_output(dev,pdata->boost_cur_gpio1,pdata->boost_gpio1_fun_sel,"Iset1",GPIO_LOW);
1344 ret += zx234502_charger_gpio_config_output(dev,pdata->boost_cur_gpio2,pdata->boost_gpio2_fun_sel,"Iset2",GPIO_HIGH);
1345 ret += zx234502_charger_gpio_config_output(dev,pdata->boost_cur_gpio3,pdata->boost_gpio3_fun_sel,"Iset3",GPIO_LOW);
1346
1347 return ret;
1348}
1349
1350static void zx234502_boost_gpio_uninit(struct zx234502_platform_data *pdata)
1351{
1352 gpio_free(pdata->boost_loadswitch_gpio);
1353 gpio_free(pdata->boost_cur_gpio1);
1354 gpio_free(pdata->boost_cur_gpio2);
1355 gpio_free(pdata->boost_cur_gpio3);
1356}
1357
1358/*
1359 when BAT goes under BAEdet(3.4V) or CHGRST set 1
1360 Group B(A1,A2,A3,A4,A5,A7) registers will reset
1361 call this function in init or dcin
1362*/
1363static int zx234502_charger_config_groupB_Regs(struct zx234502_dev_info *bdi)
1364{
1365 int ret;
1366
1367 /*set VINDPM to 4.52V*/
1368 ret = zx234502_write_mask(bdi,ZX234502_REG_ISC,
1369 ZX234502_REG_ISC_VINDPM_MASK,
1370 ZX234502_REG_ISC_VINDPM_SHIFT,
1371 0x8);
1372 /*set VSETA to 4.2V*/
1373 ret += zx234502_write_mask(bdi,ZX234502_REG_CVC,
1374 ZX234502_REG_CVC_VBAT_MASK,
1375 ZX234502_REG_CVC_VBAT_SHIFT,
1376 0x2);
1377
1378 /*disable the timer*/
1379 ret += zx234502_write_mask(bdi,ZX234502_REG_CTC,
1380 ZX234502_REG_CTC_EN_TIMER_MASK,
1381 ZX234502_REG_CTC_EN_TIMER_SHIFT,
1382 0x0);
1383 /*disable the 2*timer*/
1384 ret += zx234502_write_mask(bdi,ZX234502_REG_CTC,
1385 ZX234502_REG_CTC_EN_2XTIMER_MASK,
1386 ZX234502_REG_CTC_EN_2XTIMER_SHIFT,
1387 0x0);
1388 /*set CVCOMP to 20mV*/
1389 ret += zx234502_write_mask(bdi,ZX234502_REG_CTC,
1390 ZX234502_REG_CTC_CVCOMP_MASK,
1391 ZX234502_REG_CTC_CVCOMP_SHIFT,
1392 0x4);
1393
1394
1395 /*disable the JETTA*/
1396 ret += zx234502_write_mask(bdi,ZX234502_REG_THR,
1397 ZX234502_REG_THR_EN_JEITA_MASK,
1398 ZX234502_REG_THR_EN_JEITA_SHIFT,
1399 0x0);
1400
1401 /*set the temprator cool */
1402 /*00:0 01:5 10:10 11:15*/
1403 ret += zx234502_write_mask(bdi,ZX234502_REG_TS,
1404 ZX234502_REG_TS_COOL_MASK,
1405 ZX234502_REG_TS_COOL_SHIFT,
1406 0x0);
1407
1408 if (ret < 0){
1409 goto out;
1410 }
1411
1412 return 0;
1413
1414 out:
1415 //pm_runtime_put_sync(bdi->dev);
1416 dev_err(bdi->dev, "zx234502_charger_groupB_config ERROR: %d\n", ret);
1417 return ret;
1418
1419}
1420
1421static int zx234502_hw_init(struct zx234502_dev_info *bdi)
1422{
1423 u8 v;
1424 int ret;
1425
1426 union power_supply_propval voltage_val = {0};
1427
1428#ifdef DBG_CHARGE
1429 //set pshold1 1,just for test
1430 //gpio_request(ZX29_GPIO_51, "pshold1");
1431 //zx29_gpio_config(ZX29_GPIO_51, GPIO51_GPIO51);
1432 //zx29_gpio_set_direction(ZX29_GPIO_51, GPIO_OUT);
1433 //zx29_gpio_output_data(ZX29_GPIO_51, 1);
1434#endif
1435 //pm_runtime_get_sync(bdi->dev);
1436
1437 /* First check that the device really is what its supposed to be */
1438 ret = zx234502_read_mask(bdi, ZX234502_REG_VER,
1439 ZX234502_REG_VER_INFO_MASK,
1440 ZX234502_REG_VER_INFO_SHIFT,
1441 &v);
1442
1443 if (ret < 0){
1444 goto out;
1445 }
1446 //printk(KERN_INFO "zx234502_hw_init:zx234502-charger version reg: 0x%x\n", v);
1447 /*
1448 if (v != bdi->model) {
1449 ret = -ENODEV;
1450 goto out;
1451 }
1452 */
1453 voltage_val.intval = 4350;
1454 ret = zx234502_charger_set_voltage(bdi,&voltage_val);
1455 if (ret < 0){
1456 goto out;
1457 }
1458
1459 /*disable the timer*/
1460 ret = zx234502_write_mask(bdi,ZX234502_REG_CTC,
1461 ZX234502_REG_CTC_EN_TIMER_MASK,
1462 ZX234502_REG_CTC_EN_TIMER_SHIFT,
1463 0x0);
1464 if (ret < 0){
1465 goto out;
1466 }
1467 /*disable the 2*timer*/
1468 ret = zx234502_write_mask(bdi,ZX234502_REG_CTC,
1469 ZX234502_REG_CTC_EN_2XTIMER_MASK,
1470 ZX234502_REG_CTC_EN_2XTIMER_SHIFT,
1471 0x0);
1472
1473 if (ret < 0){
1474 goto out;
1475 }
1476
1477 //enable PMUON
1478 //ret = zx234502_write_mask(bdi,ZX234502_REG_MS,
1479 // ZX234502_REG_MS_PMUON_MASK,
1480 // ZX234502_REG_MS_PMUON_SHIFT,
1481 // 0x1);
1482 //config NTCDET
1483 // 0:enable auto ntc detection
1484 // 1:disable auto ntc detection
1485 ret += zx234502_write_mask(bdi,ZX234502_REG_PTS,
1486 ZX234502_REG_PTS_NTCDET_MASK,
1487 ZX234502_REG_PTS_NTCDET_SHIFT,
1488 0x1);
1489 //when NTCDET is 1 ,TSSEL is to select R
1490 // 0:10k
1491 // 1:100k
1492 //ret += zx234502_write_mask(bdi,ZX234502_REG_PTS,
1493 // ZX234502_REG_PTS_TSSEL_MASK,
1494 // ZX234502_REG_PTS_TSSEL_SHIFT,
1495 // 0x0);
1496
1497 /*disable the charger detect*/
1498 ret += zx234502_write_mask(bdi,ZX234502_REG_THR,
1499 ZX234502_REG_THR_EN_2DET_MASK,
1500 ZX234502_REG_THR_EN_2DET_SHIFT,
1501 0x0);
1502 ret += zx234502_write_mask(bdi,ZX234502_REG_THR,
1503 ZX234502_REG_THR_EN_1DET_MASK,
1504 ZX234502_REG_THR_EN_1DET_SHIFT,
1505 0x0);
1506 //enable charger
1507 ret += zx234502_write_mask(bdi,ZX234502_REG_MS,
1508 ZX234502_REG_MS_ENCHG_MASK,
1509 ZX234502_REG_MS_ENCHG_SHIFT,
1510 0x0);
1511 ret += zx234502_write_mask(bdi,ZX234502_REG_MS,
1512 ZX234502_REG_MS_INSUS_MASK,
1513 ZX234502_REG_MS_INSUS_SHIFT,
1514 0x0);
1515 //mask /SAFE it
1516 ret += zx234502_write_mask(bdi,ZX234502_REG_CBIM,ZX234502_REG_CBIM_MASK_SAFE_TIMER_MASK,
1517 ZX234502_REG_CBIM_MASK_SAFE_TIMER_SHIFT,0x1);
1518 //mask CHGRUN it
1519 ret += zx234502_write_mask(bdi,ZX234502_REG_CIIM,ZX234502_REG_CIIM_MASK_CHGRUN_MASK,
1520 ZX234502_REG_CIIM_MASK_CHGRUN_SHIFT,0x1);
1521 //mask INLIMIT it
1522 ret += zx234502_write_mask(bdi,ZX234502_REG_CIIM,ZX234502_REG_CIIM_MASK_INLIMIT_MASK,
1523 ZX234502_REG_CIIM_MASK_INLIMIT_SHIFT,0x1);
1524 //mask DCDET it
1525 ret += zx234502_write_mask(bdi,ZX234502_REG_CIIM,ZX234502_REG_CIIM_MASK_DCDET_MASK,
1526 ZX234502_REG_CIIM_MASK_DCDET_SHIFT,0x1);
1527 if (ret < 0){
1528 goto out;
1529 }
1530
1531 //set ts_meter interrupt mask
1532 if(true !=bdi->pdata->ts_flag){
1533 zx234502_write_mask(bdi,ZX234502_REG_CIIM,ZX234502_REG_CIIM_MASK_TS_MASK,
1534 ZX234502_REG_CIIM_MASK_TS_SHIFT,0x1);
1535 }
1536
1537 return 0;
1538
1539out:
1540 //pm_runtime_put_sync(bdi->dev);
1541 dev_err(bdi->dev, "zx234502_hw_init err: %d\n", ret);
1542 return ret;
1543}
1544
1545
1546static irqreturn_t zx234502_charger_irq_primary_handler(int irq, struct zx234502_dev_info *bdi)
1547{
1548 disable_irq_nosync(irq);
1549 //pcu_int_clear(irq);
1550 pcu_clr_irq_pending(irq);
1551
1552 up(&bdi->chgirq_sem);
1553 return IRQ_HANDLED;
1554}
1555
1556static irqreturn_t zx234502_irq_handler_thread(void *data)
1557{
1558 struct zx234502_dev_info *bdi = data;
1559 bool charger_changed_flag = false;
1560 bool battery_changed_flag = false;
1561 bool boost_changed_flag = false;
1562 int ret;
1563 u8 ms;
1564 struct sched_param param = { .sched_priority = 2 };
1565 param.sched_priority= 31;
1566 sched_setscheduler(current, SCHED_FIFO, &param);
1567
1568 while(1)
1569 {
1570 down(&bdi->chgirq_sem);
1571 //pm_runtime_get_sync(bdi->dev);
1572 mutex_lock(&bdi->bs_reg_lock);
1573 bdi->cbis_pre_reg=bdi->cbis_curr_reg;
1574 bdi->pis_pre_reg=bdi->pis_curr_reg;
1575 bdi->ciis_pre_reg=bdi->ciis_curr_reg;
1576 bdi->cfis_pre_reg = bdi->cfis_curr_reg;
1577
1578 //printk(KERN_INFO"zx234502_irq_handler_thread\n");
1579
1580
1581 ret = zx234502_read(bdi, ZX234502_REG_MS, &ms);
1582 if (ret < 0) {
1583 dev_err(bdi->dev, "Can't read MS reg: %d\n", ret);
1584 mutex_unlock(&bdi->bs_reg_lock);
1585 goto out;
1586 }
1587 //printk("zx234502 MS reg is %d",ms);
1588
1589 ret = zx234502_read(bdi, ZX234502_REG_CBIS, &bdi->cbis_curr_reg);
1590 if (ret < 0) {
1591 dev_err(bdi->dev, "Can't read CBIS reg: %d\n", ret);
1592 mutex_unlock(&bdi->bs_reg_lock);
1593 goto out;
1594 }
1595
1596
1597 ret = zx234502_read(bdi, ZX234502_REG_PIS, &bdi->pis_curr_reg);
1598 if (ret < 0) {
1599 dev_err(bdi->dev, "Can't read PIS reg: %d\n", ret);
1600 mutex_unlock(&bdi->bs_reg_lock);
1601 goto out;
1602 }
1603
1604 ret = zx234502_read(bdi, ZX234502_REG_CIIS, &bdi->ciis_curr_reg);
1605 if (ret < 0) {
1606 dev_err(bdi->dev, "Can't read CIIS reg: %d\n", ret);
1607 mutex_unlock(&bdi->bs_reg_lock);
1608 goto out;
1609 }
1610 printk("cbis_reg: 0x%02x, pis_reg: 0x%02x, ciis_reg: 0x%02x\n",
1611 bdi->cbis_curr_reg, bdi->pis_curr_reg, bdi->ciis_curr_reg);
1612 /*clear the A10 int*/
1613 ret = zx234502_write_mask(bdi, ZX234502_REG_CIIS,ZX234502_REG_CIIS_INT_MASK,ZX234502_REG_CIIS_INT_SHIFT,0);
1614
1615 if (ret < 0) {
1616 printk(KERN_INFO"chg clear int failed 1\n");
1617 ret = zx234502_write_mask(bdi, ZX234502_REG_CIIS,ZX234502_REG_CIIS_INT_MASK,ZX234502_REG_CIIS_INT_SHIFT,0);
1618 if (ret < 0) {
1619 printk(KERN_INFO"chg clear int failed 2\n");
1620 ret = zx234502_write_mask(bdi, ZX234502_REG_CIIS,ZX234502_REG_CIIS_INT_MASK,ZX234502_REG_CIIS_INT_SHIFT,0);
1621 if (ret < 0) {
1622 printk(KERN_INFO"chg clear int failed 3\n");
1623 }
1624 else{
1625 printk(KERN_INFO"chg clear int failed ok 3\n");
1626 //panic(0);
1627 }
1628 }
1629 else{
1630 printk(KERN_INFO"chg clear int failed ok 2\n");
1631 }
1632 }
1633
1634 if(bdi->cbis_curr_reg != bdi->cbis_pre_reg){
1635 if ((bdi->cbis_curr_reg & ZX234502_REG_CBIS_DCIN_PG_MASK) != (bdi->cbis_pre_reg & ZX234502_REG_CBIS_DCIN_PG_MASK)) {
1636 if(bdi->cbis_curr_reg & ZX234502_REG_CBIS_DCIN_PG_MASK){
1637 //zx234502_hw_init(bdi);
1638 printk(KERN_INFO"chg usb in\n");
1639 dwc_otg_chg_inform(0);/*usb in*/
1640
1641 ret = zx234502_charger_config_groupB_Regs(bdi);
1642 if(ret)
1643 {
1644 printk(KERN_INFO"chg config groupB Regs failed\n");
1645 }
1646 // ret = zx234502_write_mask(bdi,ZX234502_REG_MS,ZX234502_REG_MS_PMUON_MASK,ZX234502_REG_MS_PMUON_SHIFT,0x1);
1647 }
1648 else{
1649 printk(KERN_INFO"chg usb out\n");
1650 dwc_otg_chg_inform(1);/*usb out*/
1651 bdi->charger.type = POWER_SUPPLY_PCAC_UNKNOWN;
1652 // ret = zx234502_write_mask(bdi,ZX234502_REG_MS,ZX234502_REG_MS_PMUON_MASK,ZX234502_REG_MS_PMUON_SHIFT,0x0);
1653 }
1654 }
1655 charger_changed_flag = true;
1656 }
1657
1658 if(true == bdi->pdata->boost_flag){
1659 if (bdi->pis_curr_reg != bdi->pis_pre_reg) {
1660 if(bdi->pis_curr_reg & ZX234502_REG_PIS_POWERON_IT_MASK){
1661 queue_delayed_work(g_bdi->boostQueue,&bdi->boostWorkStruct,2000);
1662 }
1663 boost_changed_flag = true;
1664 bdi->boost_online_flag = 1;
1665 }
1666 }
1667
1668 if (bdi->ciis_curr_reg != bdi->ciis_pre_reg) {
1669 if(true == bdi->pdata->ts_flag){
1670 if((bdi->ciis_curr_reg & ZX234502_REG_CIIS_TS_METER_MASK) != (bdi->ciis_pre_reg & ZX234502_REG_CIIS_TS_METER_MASK)){
1671#ifdef DBG_CHARGE
1672 switch((bdi->ciis_curr_reg&ZX234502_REG_CIIS_TS_METER_MASK )>>ZX234502_REG_CIIS_TS_METER_SHIFT){
1673 case 0:
1674#ifdef DBG_CHARGE
1675 printk(KERN_INFO"chg bat temp nomrmal\n");
1676#endif
1677 break;
1678 case ZX234502_REG_CISS_TS_WARM:/*warm*/
1679 /*in warm state,stop boost*/
1680#ifdef DBG_CHARGE
1681 printk(KERN_INFO"chg bat temp warm \n");
1682#endif
1683 break;
1684 case ZX234502_REG_CISS_TS_COOL:/*cool*/
1685 /*in cool state,stop boost*/
1686#ifdef DBG_CHARGE
1687 printk(KERN_INFO"chg bat temp cool\n");
1688#endif
1689 //chg_disable.intval = 1;
1690 //pwrbnk_enable.intval = 0;
1691 //zx234502_charger_set_charger_config(bdi,&chg_disable);
1692 //zx234502_boost_set_charge_enable(bdi, &pwrbnk_enable);
1693 break;
1694 case 3:/*hot*/
1695 /*in hot state,charger chip auto off*/
1696 printk(KERN_INFO"chg bat temp hot \n");
1697 break;
1698 case 6:/*cold*/
1699 /*in cold state,charger chip auto off*/
1700 printk(KERN_INFO"chg bat temp cold\n");
1701 break;
1702 default:
1703 printk(KERN_INFO"chg bat temp unkonw\n");
1704 break;
1705 }
1706#endif
1707 }
1708 }
1709 battery_changed_flag = true;
1710 }
1711 bdi->charger_health_valid = true;/****?***/
1712 bdi->battery_health_valid = true;/****?***/
1713 bdi->battery_status_valid = true;/****?***/
1714
1715 mutex_unlock(&bdi->bs_reg_lock);
1716
1717 /*
1718 * Sometimes zx234502 gives a steady trickle of interrupts even
1719 * though the watchdog timer is turned off and neither the STATUS
1720 * nor FAULT registers have changed. Weed out these sprurious
1721 * interrupts so userspace isn't alerted for no reason.
1722 * In addition, the chip always generates an interrupt after
1723 * register reset so we should ignore that one (the very first
1724 * interrupt received).
1725 */
1726 //if (charger_changed_flag && !bdi->first_time)
1727 if (charger_changed_flag )
1728 power_supply_changed(&bdi->charger);
1729 //if (battery_changed_flag && !bdi->first_time)
1730 if (battery_changed_flag)
1731 power_supply_changed(&bdi->battery);
1732 if (true == bdi->pdata->boost_flag){
1733 //if (boost_changed_flag && !bdi->first_time)
1734 if (boost_changed_flag )
1735 power_supply_changed(&bdi->boost);
1736 }
1737
1738 bdi->first_time = false;
1739
1740 out:
1741 //pm_runtime_put_sync(bdi->dev);
1742
1743 dev_dbg(bdi->dev, "read reg:cbis_reg: 0x%02x, pis_reg: 0x%02x, ciis_reg: 0x%02x\n",
1744 bdi->cbis_curr_reg, bdi->pis_curr_reg, bdi->ciis_curr_reg);
1745
1746 enable_irq(bdi->irq);
1747 }
1748 return 0;
1749}
1750
1751
1752static int zx234502_setup_pdata(struct zx234502_dev_info *bdi,
1753 struct zx234502_platform_data *pdata)
1754{
1755 int ret;
1756
1757#if 0
1758 if (!gpio_is_valid(pdata->gpio_int))
1759 return -1;
1760
1761 ret = gpio_request(pdata->gpio_int, dev_name(bdi->dev));
1762 if (ret < 0)
1763 return -1;
1764
1765 ret = gpio_direction_input(pdata->gpio_int);
1766 if (ret < 0)
1767 goto out;
1768
1769 bdi->irq = gpio_to_irq(pdata->gpio_int);
1770 if (!bdi->irq)
1771 goto out;
1772#endif
1773
1774 bdi->irq = gpio_to_irq(pdata->gpio_int);
1775 #ifdef DBG_CHARGE
1776 printk(KERN_INFO"zx234502_setup_pdata irq= %d\n",bdi->irq);
1777 #endif
1778 /*Ñ¡Ôñ´Ë¸´Óù¦ÄÜΪÖжϹ¦ÄÜ*/
1779 ret = zx29_gpio_config(pdata->gpio_int,pdata->gpio_int_fun_sel);/********GPIO11:0 /EXT_INT:5*******/
1780 if (ret < 0){
1781 printk(KERN_INFO"zx234502 zx29_gpio_config error int= %d,fun= %d\n",pdata->gpio_int,pdata->gpio_int_fun_sel);
1782 return -1;
1783 }
1784
1785 zx29_gpio_set_inttype(pdata->gpio_int,IRQ_TYPE_EDGE_FALLING/*IRQ_TYPE_EDGE_RISING*/); //INT_POSEDGE
1786 zx29_gpio_pd_pu_set(pdata->gpio_int, IO_CFG_PULL_DISABLE);
1787
1788 bdi->gpio_int = pdata->gpio_int;
1789 //pcu_int_clear(bdi->irq);
1790 pcu_clr_irq_pending(bdi->irq);
1791 return 0;
1792#if 0
1793out:
1794 gpio_free(pdata->gpio_int);
1795 return -1;
1796#endif
1797
1798}
1799
1800
1801static int zx234502_init_state(struct zx234502_dev_info *bdi)
1802{
1803 u8 cfis_reg,pis_reg,cbis_reg,ciis_reg;
1804 int ret;
1805
1806 printk(KERN_INFO "zx234502_init_state start.\n");
1807
1808 ret = zx234502_read(bdi, ZX234502_REG_CBIS, &cbis_reg);
1809 if (ret < 0){
1810 printk(KERN_INFO "charger:init state:Can't read CBIS reg: 0x%x\n", cbis_reg);
1811 return ret;
1812 }
1813
1814 ret = zx234502_read(bdi, ZX234502_REG_PIS, &pis_reg);
1815 if (ret < 0) {
1816 printk(KERN_INFO "charger:init Power On /PMID state:Can't read PIS reg: %d\n", ret);
1817 return ret;
1818 }
1819
1820 ret = zx234502_read(bdi, ZX234502_REG_CFIS, &cfis_reg);
1821 if (ret < 0) {
1822 printk(KERN_INFO "charger:init Power On /PMID state:Can't read CFIS reg: %d\n", ret);
1823 return ret;
1824 }
1825
1826 ret = zx234502_read(bdi, ZX234502_REG_CIIS, &ciis_reg);
1827 if (ret < 0) {
1828 printk(KERN_INFO "charger:init Power On /PMID state:Can't read CISS reg: %d\n", ret);
1829 return ret;
1830 }
1831
1832 mutex_lock(&bdi->bs_reg_lock);
1833 #ifdef DBG_CHARGE
1834 printk(KERN_INFO "zx234502_init_state get lock ok.\n");
1835 #endif
1836 bdi->cbis_curr_reg= cbis_reg;
1837 bdi->pis_curr_reg= pis_reg;
1838 bdi->cfis_curr_reg= cfis_reg;
1839 bdi->ciis_curr_reg = ciis_reg;
1840 bdi->charger.type = POWER_SUPPLY_TYPE_UNKNOWN;
1841
1842 if(bdi->cbis_curr_reg & ZX234502_REG_CBIS_DCIN_PG_MASK){
1843 printk(KERN_INFO"send ap usb in message\n");
1844 dwc_otg_chg_inform(0);/*usb in*/
1845 }
1846 else{
1847 printk(KERN_INFO"send ap usb out message\n");
1848 dwc_otg_chg_inform(1);/*usb out*/
1849 }
1850 #ifdef DBG_CHARGE
1851 if(bdi->cbis_curr_reg & BIT(5))
1852 printk(KERN_INFO "no batterty.\n");
1853 else
1854 printk(KERN_INFO " baterry installed.\n");
1855 #endif
1856 mutex_unlock(&bdi->bs_reg_lock);
1857#ifdef DBG_CHARGE
1858 printk(KERN_INFO "zx234502_init_state:cfis_reg10=0x%x,pis_reg0E=0x%x,cbis_reg0C=0x%x,ciis_reg0A=0x%x.\n",cfis_reg,pis_reg,cbis_reg,ciis_reg);
1859#endif
1860
1861 return 0;
1862}
1863
1864
1865static void zx234502_boost_workstruct_callback(struct work_struct *work )
1866{
1867 uint vol_curr = 0;
1868 #ifdef DBG_CHARGE
1869 u8 mainset;
1870 #endif
1871 struct zx234502_dev_info *bdi =
1872 container_of(work, struct zx234502_dev_info, boostWorkStruct);
1873 vol_curr = get_adc2_voltage();/*get boost current*/
1874 #ifdef DBG_CHARGE
1875 printk(KERN_INFO"boost current is %d in\n",vol_curr);
1876 zx234502_read(bdi, 0, &mainset);
1877 printk(KERN_INFO"powerbank is %d in\n",mainset);
1878 printk(KERN_INFO"workqueue test\n");
1879 #endif
1880 if (vol_curr < ZX234502_BOOST_V_LIMIT)/*50mV*/{
1881 bdi->boostcount++;
1882 }
1883 if(bdi->boostcount > 3){
1884 bdi->boostcount = 0;
1885 bdi->boost_online_flag = 0;
1886 power_supply_changed(&bdi->boost);
1887 cancel_delayed_work_sync(&bdi->boostWorkStruct);
1888 }
1889 else{
1890 bdi->boost_online_flag = 1;
1891 queue_delayed_work(bdi->boostQueue,&bdi->boostWorkStruct,2000);
1892 }
1893
1894}
1895static void zx234502_charge_typedet(T_TYPE_USB_DETECT chg_type)
1896{
1897 int ret;
1898 #ifdef DBG_CHARGE
1899 printk(KERN_INFO"charge type is %d in\n",chg_type);
1900 #endif
1901 if(TYPE_ADAPTER == chg_type){
1902
1903 printk(KERN_INFO"chg type is TYPE_ADAPTER\n");
1904 /*set the DCIN Current = 1A*/
1905 ret = zx234502_write_mask(g_bdi,ZX234502_REG_ISC,
1906 ZX234502_REG_ISC_ISET_DCIN_MASK,
1907 ZX234502_REG_ISC_ISET_DCIN_SHIFT,
1908 0x3);
1909 if (ret < 0){
1910 printk(KERN_INFO"write REG_01 fault\n");
1911 }
1912 g_bdi->charger.type = POWER_SUPPLY_PCAC__AC;
1913 }
1914
1915 else{
1916 printk(KERN_INFO"chgage type is TYPE_PC\n");
1917
1918 /*set the DCIN Current = 450mA*/
1919 ret = zx234502_write_mask(g_bdi,ZX234502_REG_ISC,
1920 ZX234502_REG_ISC_ISET_DCIN_MASK,
1921 ZX234502_REG_ISC_ISET_DCIN_SHIFT,
1922 0x1);
1923 if (ret < 0){
1924 printk(KERN_INFO"write REG_01 fault\n");
1925 }
1926
1927 g_bdi->charger.type = POWER_SUPPLY_PCAC__PC;
1928 }
1929
1930
1931 #ifdef CONFIG_CHARGER_ZX234502_EVB
1932 /*set the DCIN Current = 2A*/
1933 ret = zx234502_write_mask(g_bdi,ZX234502_REG_ISC,
1934 ZX234502_REG_ISC_ISET_DCIN_MASK,
1935 ZX234502_REG_ISC_ISET_DCIN_SHIFT,
1936 0x5);
1937 if (ret < 0){
1938 printk(KERN_INFO"write REG_01 fault\n");
1939 }
1940 #endif
1941
1942}
1943
1944
1945#if defined(CONFIG_DEBUG_FS)
1946static ssize_t debugfs_regs_write(struct file *file, const char __user *buf,size_t nbytes, loff_t *ppos)
1947{
1948 unsigned int val1, val2;
1949 u8 reg, value;
1950 int ret;
1951 char *kern_buf;
1952 struct seq_file *s = file->private_data;
1953 struct zx234502_dev_info *zx234502 = s->private;
1954
1955 kern_buf = kzalloc(nbytes, GFP_KERNEL);
1956
1957 if (!kern_buf) {
1958 printk(KERN_INFO "zx234502_charger: Failed to allocate buffer\n");
1959 return -ENOMEM;
1960 }
1961
1962 if (copy_from_user(kern_buf, (void __user *)buf, nbytes)) {
1963 kfree(kern_buf);
1964 return -ENOMEM;
1965 }
1966 printk(KERN_INFO "%s input str=%s,nbytes=%d \n", __func__, kern_buf,nbytes);
1967
1968 ret = sscanf(kern_buf, "%x:%x", &val1, &val2);
1969 if (ret < 2 || val1 > ZX234502_REG_MAX ) {
1970 printk(KERN_INFO "zx234502_charger: failed to read user buf, ret=%d, input 0x%x:0x%x\n",
1971 ret, val1, val2);
1972 kfree(kern_buf);
1973 return -EINVAL;
1974 }
1975 kfree(kern_buf);
1976
1977 reg = val1 & 0xff;
1978 value = val2 & 0xff;
1979 printk(KERN_INFO "%s input %x,%x; reg=%x,value=%x\n", __func__, val1, val2, reg, value);
1980 ret = zx234502_write(zx234502,reg, value);
1981
1982 return ret ? ret : nbytes;
1983}
1984
1985static int debugfs_regs_show(struct seq_file *s, void *v)
1986{
1987 int i;
1988 u8 value[ZX234502_REG_MAX];
1989 int ret=0;
1990 int curr = 0;
1991 struct zx234502_dev_info *zx234502 = s->private;
1992
1993 for (i = 0; i < ZX234502_REG_MAX; i++){
1994 ret = zx234502_read(zx234502, i, &(value[i]));
1995
1996 if(ret){
1997 printk(KERN_INFO "%s err=%d, break\n", __func__, ret);
1998 seq_printf(s, "%s err=%d, break", __func__, ret);
1999 return ret;
2000 }
2001 }
2002
2003 for (i = 0; i < ZX234502_REG_MAX; i++) {
2004 if((i+1)%9 == 0)
2005 seq_printf(s, "\n");
2006
2007 seq_printf(s, "[0x%x]%02x ", i, value[i]);
2008 }
2009 /*charger type*/
2010 if(zx234502->charger.type ==POWER_SUPPLY_PCAC__PC){
2011 seq_printf(s, "charger type is PC\n");
2012 }
2013 else if(zx234502->charger.type ==POWER_SUPPLY_PCAC__AC){
2014 seq_printf(s, "charger type is AC\n");
2015 }
2016 else
2017 seq_printf(s, "charger type is unknow = %d\n",zx234502->charger.type);
2018
2019 /*stopchg_flag*/
2020 if(1==stopchg_flag){
2021 seq_printf(s, "mmi set charger enable,the charger state = %d\n",!(value[ZX234502_REG_MS]&ZX234502_REG_MS_INSUS_MASK));
2022 }
2023 else if(2==stopchg_flag){
2024 seq_printf(s, "mmi set charger disable,the charger state = %d\n",!(value[ZX234502_REG_MS]&ZX234502_REG_MS_INSUS_MASK));
2025 }
2026 else
2027 seq_printf(s, "mmi never set the charger ,the charger state = %d\n",!(value[ZX234502_REG_MS]&ZX234502_REG_MS_INSUS_MASK));
2028
2029 /*charge current*/
2030 ret = zx234502_get_field_val(zx234502, ZX234502_REG_ISC,
2031 ZX234502_REG_ISC_ISET_DCIN_MASK, ZX234502_REG_ISC_ISET_DCIN_SHIFT,
2032 zx234502_in_ilimit_values,
2033 ARRAY_SIZE(zx234502_in_ilimit_values), &curr);
2034
2035 if (ret < 0)
2036 return ret;
2037 seq_printf(s, "the charger current now = %dmA\n",curr);
2038
2039
2040 return ret;
2041}
2042
2043#define DEBUGFS_FILE_ENTRY(name) \
2044static int debugfs_##name##_open(struct inode *inode, struct file *file) \
2045{\
2046return single_open(file, debugfs_##name##_show, inode->i_private); \
2047}\
2048\
2049static const struct file_operations debugfs_##name##_fops = { \
2050.owner= THIS_MODULE, \
2051.open= debugfs_##name##_open, \
2052.write=debugfs_##name##_write, \
2053.read= seq_read, \
2054.llseek= seq_lseek, \
2055.release= single_release, \
2056}
2057
2058DEBUGFS_FILE_ENTRY(regs);
2059
2060static struct dentry *g_charger_root;
2061
2062static void debugfs_charger_init(struct zx234502_dev_info *zx234502)
2063{
2064 struct dentry *root;
2065 struct dentry *node;
2066 int i;
2067
2068 if(!zx234502)
2069 return;
2070
2071 //create root
2072 root = debugfs_create_dir("charger_zx29", NULL);
2073 if (!root) {
2074 dev_err(&zx234502->dev, "debugfs_create_dir err=%d\n", IS_ERR(root));
2075 goto err;
2076 }
2077
2078 //print regs;
2079 node = debugfs_create_file("regs", S_IRUGO | S_IWUGO, root, zx234502, &debugfs_regs_fops);
2080 if (!node){
2081 dev_err(&zx234502->dev, "debugfs_create_dir err=%d\n", IS_ERR(node));
2082 goto err;
2083 }
2084
2085 g_charger_root = (void *)root;
2086 return;
2087err:
2088 dev_err(&zx234502->dev, "debugfs_charger_init err\n");
2089}
2090
2091#endif
2092
2093
2094static int zx234502_probe(struct i2c_client *client, const struct i2c_device_id *id)
2095{
2096 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
2097 struct device *dev = &client->dev;
2098 struct zx234502_platform_data *pdata = client->dev.platform_data;
2099 struct zx234502_dev_info *bdi;
2100 int ret;
2101 int i; /*when err try 3 times*/
2102 //use for other
2103 //g_platform_data= client->dev.platform_data;
2104
2105 printk(KERN_INFO "charger probe.\n");
2106
2107 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
2108 dev_err(dev, "No support for SMBUS_BYTE_DATA\n");
2109 return -ENODEV;
2110 }
2111
2112 bdi = devm_kzalloc(dev, sizeof(*bdi), GFP_KERNEL);
2113 if (!bdi) {
2114 dev_err(dev, "Can't alloc bdi struct\n");
2115 return -ENOMEM;
2116 }
2117 bdi->pdata = pdata;
2118 bdi->client = client;
2119 bdi->dev = dev;
2120 bdi->model = id->driver_data;
2121 strncpy(bdi->model_name, id->name, sizeof(bdi->model_name)-1);
2122 mutex_init(&bdi->bs_reg_lock);
2123 bdi->first_time = true;
2124 bdi->charger_health_valid = false;
2125 bdi->battery_health_valid = false;
2126 bdi->battery_status_valid = false;
2127
2128 g_bdi = bdi;
2129
2130 i2c_set_clientdata(client, bdi);
2131
2132 if (dev->of_node)
2133 ret = 0;//zx234502_setup_dt(bdi);
2134 else
2135 ret = zx234502_setup_pdata(bdi, pdata);
2136
2137 if (ret) {
2138 dev_err(dev, "Can't get irq info\n");
2139 return -EINVAL;
2140 }
2141#ifdef DBG_CHARGE
2142 printk(KERN_INFO "hwinit.\n");
2143#endif
2144 //pm_runtime_enable(dev);
2145 //pm_runtime_resume(dev);
2146 i = 0;
2147 do{
2148 ret = zx234502_hw_init(bdi);
2149 if (ret < 0) {
2150 printk(KERN_INFO "zx234502_probe Hardware init failed times = %d\n",(i+1));
2151 i++;
2152 }
2153 else
2154 break;
2155
2156 }while(i<3);
2157
2158#ifdef DBG_CHARGE
2159 printk(KERN_INFO "zx234502_probe zx234502_hw_init ok.\n");
2160#endif
2161#ifdef CONFIG_CHARGER_ZX234502_EVB
2162 /*set the DCIN Current = 2A*/
2163 ret = zx234502_write_mask(g_bdi,ZX234502_REG_ISC,
2164 ZX234502_REG_ISC_ISET_DCIN_MASK,
2165 ZX234502_REG_ISC_ISET_DCIN_SHIFT,
2166 0x5);
2167 if (ret < 0){
2168 printk(KERN_INFO"write REG_01 fault\n");
2169 }
2170#endif
2171 ret = zx234502_charger_config_groupB_Regs(bdi);
2172 if (ret < 0) {
2173 printk(KERN_INFO "groupB config faild.\n");
2174 }
2175
2176 zx234502_charger_init(&bdi->charger);
2177
2178 ret = power_supply_register(dev, &bdi->charger);
2179 if (ret) {
2180 dev_err(dev, "Can't register charger\n");
2181 goto out2;
2182 }
2183 printk(KERN_INFO "zx234502_probe power_supply_register charger ok.\n");
2184
2185 zx234502_battery_init(&bdi->battery);
2186
2187 ret = power_supply_register(dev, &bdi->battery);
2188 if (ret) {
2189 dev_err(dev, "Can't register battery\n");
2190 goto out3;
2191 }
2192 printk(KERN_INFO "zx234502_probe power_supply_register battery ok.\n");
2193
2194 if(true == pdata->boost_flag){
2195 zx234502_boost_init(&bdi->boost);
2196 ret = power_supply_register(dev, &bdi->boost);
2197 if (ret) {
2198 dev_err(dev, "Can't register boost\n");
2199 goto out4;
2200 }
2201
2202 ret = zx234502_boost_gpio_init(dev,pdata);
2203 if (ret) {
2204 dev_err(dev, "Can't register boost\n");
2205 goto out4;
2206 }
2207 #ifdef DBG_CHARGE
2208 printk(KERN_INFO "zx234502_boost_gpio_init.\n");
2209 #endif
2210
2211 bdi->boostQueue = create_workqueue("zx234502boost");
2212 if (!bdi->boostQueue){
2213 if(bdi->pdata->boost_cur_gpio1)
2214 gpio_free(bdi->pdata->boost_cur_gpio1);
2215 if(bdi->pdata->boost_cur_gpio2)
2216 gpio_free(bdi->pdata->boost_cur_gpio2);
2217 if(bdi->pdata->boost_cur_gpio3)
2218 gpio_free(bdi->pdata->boost_cur_gpio3);
2219 if(bdi->pdata->boost_loadswitch_gpio)
2220 gpio_free(bdi->pdata->boost_loadswitch_gpio);
2221
2222 ret = -1;
2223 goto out4;
2224 }
2225
2226 INIT_DELAYED_WORK(&bdi->boostWorkStruct,zx234502_boost_workstruct_callback);
2227
2228 //queue_delayed_work(bdi->boostQueue,&bdi->boostWorkStruct,20000);
2229 #ifdef DBG_CHARGE
2230 printk(KERN_INFO "setup_workqueue.\n");
2231 #endif
2232 }
2233#if 0
2234//#ifdef CONFIG_SYSFS
2235 ret = zx234502_sysfs_create_group(bdi);
2236 if (ret) {
2237 dev_err(dev, "Can't create sysfs entries\n");
2238 goto out5;
2239 }
2240#endif
2241 dwc_chg_Regcallback(zx234502_charge_typedet);/*register for usb*/
2242
2243 sema_init(&bdi->chgirq_sem, 0);
2244
2245 ret = zx234502_init_state(bdi);
2246 if(ret)
2247 {
2248 dev_err(dev, "zx234502 init state error.\n");
2249 goto out1;
2250 }
2251
2252 bdi->chg_irq_thread = kthread_run(zx234502_irq_handler_thread, bdi, "zx234502-chgirq");
2253 BUG_ON(IS_ERR(bdi->chg_irq_thread));
2254
2255 ret = request_irq(bdi->irq, zx234502_charger_irq_primary_handler,IRQF_NO_THREAD, "zx234502-charger", bdi);
2256 if (ret < 0) {
2257 dev_err(dev, "Can't set up irq handler\n");
2258 goto out1;
2259 }
2260 irq_set_irq_wake(bdi->irq, 1);
2261
2262 /*clear all int*/
2263 ret = zx234502_write_mask(bdi,ZX234502_REG_CIIS,ZX234502_REG_CIIS_INT_MASK,ZX234502_REG_CIIS_INT_SHIFT,0x0);
2264 if (ret == 0) {
2265 printk(KERN_INFO "clear int ok \n");
2266 }
2267
2268
2269#if defined(CONFIG_DEBUG_FS)
2270 debugfs_charger_init(bdi);
2271#endif
2272
2273#ifdef DBG_CHARGE
2274 printk(KERN_INFO "zx234502_probe end.\n");
2275#endif
2276
2277 return 0;
2278#if 0
2279out5:
2280 zx234502_sysfs_remove_group(bdi);
2281#endif
2282out4:
2283 power_supply_unregister(&bdi->boost);
2284out3:
2285 power_supply_unregister(&bdi->battery);
2286out2:
2287 //pm_runtime_disable(dev);
2288 power_supply_unregister(&bdi->charger);
2289out1:
2290 if (bdi->gpio_int)
2291 gpio_free(bdi->gpio_int);
2292 dwc_chg_Regcallback(NULL);/*unregister for usb*/
2293
2294 return ret;
2295}
2296
2297static int zx234502_remove(struct i2c_client *client)
2298{
2299 struct zx234502_dev_info *bdi = i2c_get_clientdata(client);
2300 struct zx234502_platform_data *pdata = client->dev.platform_data;
2301
2302 if(!bdi)
2303 return -EINVAL;
2304
2305 //pm_runtime_get_sync(bdi->dev);
2306 zx234502_register_reset(bdi);
2307 //pm_runtime_put_sync(bdi->dev);
2308
2309 zx234502_sysfs_remove_group(bdi);
2310 power_supply_unregister(&bdi->battery);
2311 power_supply_unregister(&bdi->charger);
2312 if(true == pdata->boost_flag)
2313 power_supply_unregister(&bdi->boost);
2314 pm_runtime_disable(bdi->dev);
2315
2316 if (bdi->gpio_int)
2317 gpio_free(bdi->gpio_int);
2318 zx234502_boost_gpio_uninit(pdata);
2319
2320 if(bdi->boostQueue)
2321 destroy_workqueue(bdi->boostQueue);
2322
2323#if defined(CONFIG_DEBUG_FS)
2324 if(g_charger_root){
2325 printk(KERN_INFO "zx234502_device_exit:debugfs_remove_recursive \n");
2326 debugfs_remove_recursive(g_charger_root);
2327 }
2328#endif
2329
2330 return 0;
2331}
2332
2333static int zx234502_suspend(struct i2c_client *not_use, pm_message_t mesg)
2334{
2335
2336 disable_irq_nosync(g_bdi->irq);
2337 return 0;
2338
2339}
2340
2341static int zx234502_resume(struct i2c_client *not_use)
2342{
2343
2344 enable_irq(g_bdi->irq);
2345 return 0;
2346
2347}
2348/*
2349 * Only support the zx234502 right now. The bq24192, bq24192i, and bq24193
2350 * are similar but not identical so the driver needs to be extended to
2351 * support them.
2352 */
2353static const struct i2c_device_id zx234502_i2c_ids[] = {
2354 { "zx234502-charger", ZX234502_REG_VERS },
2355 { },
2356};
2357
2358static struct i2c_driver zx234502_driver = {
2359 .probe = zx234502_probe,
2360 .remove = zx234502_remove,
2361 .id_table = zx234502_i2c_ids,
2362 .driver = {
2363 .name = "zx234502-charger",
2364 .owner = THIS_MODULE,
2365 },
2366 .suspend = zx234502_suspend,
2367 .resume = zx234502_resume,
2368};
2369static int __init zx234502_i2c_init(void)
2370{
2371 int ret;
2372
2373 ret = i2c_add_driver(&zx234502_driver);
2374 if (ret != 0)
2375 pr_err("Failed to register visionox_i2c_driver : %d\n", ret);
2376
2377 return ret;
2378}
2379/* init early so consumer devices can complete system boot */
2380module_init(zx234502_i2c_init);
2381
2382static void __exit zx234502_i2c_exit(void)
2383{
2384 i2c_del_driver(&zx234502_driver);
2385}
2386module_exit(zx234502_i2c_exit);
2387
2388MODULE_LICENSE("GPL");
2389MODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
2390MODULE_ALIAS("i2c:zx234502-charger");
2391MODULE_DESCRIPTION("TI ZX234502 Charger Driver");