bq2415x_charger: Add support for offline and 100mA mode
[kernel-power] / kernel-power-2.6.28 / debian / patches / bq2415x_charger.patch
1 --- /dev/null
2 +++ kernel-power/drivers/power/bq2415x_charger.c
3 @@ -0,0 +1,1655 @@
4 +/*
5 +    bq2415x_charger.c - bq2415x charger driver
6 +    Copyright (C) 2011-2012  Pali Rohár <pali.rohar@gmail.com>
7 +
8 +    This program is free software; you can redistribute it and/or modify
9 +    it under the terms of the GNU General Public License as published by
10 +    the Free Software Foundation; either version 2 of the License, or
11 +    (at your option) any later version.
12 +
13 +    This program is distributed in the hope that it will be useful,
14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 +    GNU General Public License for more details.
17 +
18 +    You should have received a copy of the GNU General Public License along
19 +    with this program; if not, write to the Free Software Foundation, Inc.,
20 +    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 +*/
22 +
23 +/*
24 +  Datasheets:
25 +  http://www.ti.com/product/bq24150
26 +  http://www.ti.com/product/bq24150a
27 +  http://www.ti.com/product/bq24152
28 +  http://www.ti.com/product/bq24153
29 +  http://www.ti.com/product/bq24153a
30 +  http://www.ti.com/product/bq24155
31 +*/
32 +
33 +#include <linux/version.h>
34 +#include <linux/kernel.h>
35 +#include <linux/module.h>
36 +#include <linux/param.h>
37 +#include <linux/err.h>
38 +#include <linux/workqueue.h>
39 +#include <linux/sysfs.h>
40 +#include <linux/platform_device.h>
41 +#include <linux/power_supply.h>
42 +#include <linux/idr.h>
43 +#include <linux/i2c.h>
44 +#include <linux/slab.h>
45 +
46 +#include <linux/power/bq2415x_charger.h>
47 +
48 +/* timeout for resetting chip timer */
49 +#define BQ2415X_TIMER_TIMEOUT          10
50 +
51 +#define BQ2415X_REG_STATUS             0x00
52 +#define BQ2415X_REG_CONTROL            0x01
53 +#define BQ2415X_REG_VOLTAGE            0x02
54 +#define BQ2415X_REG_VENDER             0x03
55 +#define BQ2415X_REG_CURRENT            0x04
56 +
57 +/* reset state for all registers */
58 +#define BQ2415X_RESET_STATUS           BIT(6)
59 +#define BQ2415X_RESET_CONTROL          (BIT(4)|BIT(5))
60 +#define BQ2415X_RESET_VOLTAGE          (BIT(1)|BIT(3))
61 +#define BQ2415X_RESET_CURRENT          (BIT(0)|BIT(3)|BIT(7))
62 +
63 +/* status register */
64 +#define BQ2415X_BIT_TMR_RST            7
65 +#define BQ2415X_BIT_OTG                        7
66 +#define BQ2415X_BIT_EN_STAT            6
67 +#define BQ2415X_MASK_STAT              (BIT(4)|BIT(5))
68 +#define BQ2415X_SHIFT_STAT             4
69 +#define BQ2415X_BIT_BOOST              3
70 +#define BQ2415X_MASK_FAULT             (BIT(0)|BIT(1)|BIT(2))
71 +#define BQ2415X_SHIFT_FAULT            0
72 +
73 +/* control register */
74 +#define BQ2415X_MASK_LIMIT             (BIT(6)|BIT(7))
75 +#define BQ2415X_SHIFT_LIMIT            6
76 +#define BQ2415X_MASK_VLOWV             (BIT(4)|BIT(5))
77 +#define BQ2415X_SHIFT_VLOWV            4
78 +#define BQ2415X_BIT_TE                 3
79 +#define BQ2415X_BIT_CE                 2
80 +#define BQ2415X_BIT_HZ_MODE            1
81 +#define BQ2415X_BIT_OPA_MODE           0
82 +
83 +/* voltage register */
84 +#define BQ2415X_MASK_VO                (BIT(2)|BIT(3)|BIT(4)|BIT(5)|BIT(6)|BIT(7))
85 +#define BQ2415X_SHIFT_VO               2
86 +#define BQ2415X_BIT_OTG_PL             1
87 +#define BQ2415X_BIT_OTG_EN             0
88 +
89 +/* vender register */
90 +#define BQ2415X_MASK_VENDER            (BIT(5)|BIT(6)|BIT(7))
91 +#define BQ2415X_SHIFT_VENDER           5
92 +#define BQ2415X_MASK_PN                        (BIT(3)|BIT(4))
93 +#define BQ2415X_SHIFT_PN               3
94 +#define BQ2415X_MASK_REVISION          (BIT(0)|BIT(1)|BIT(2))
95 +#define BQ2415X_SHIFT_REVISION         0
96 +
97 +/* current register */
98 +#define BQ2415X_MASK_RESET             BIT(7)
99 +#define BQ2415X_MASK_VI_CHRG           (BIT(4)|BIT(5)|BIT(6))
100 +#define BQ2415X_SHIFT_VI_CHRG          4
101 +/* N/A                                 BIT(3) */
102 +#define BQ2415X_MASK_VI_TERM           (BIT(0)|BIT(1)|BIT(2))
103 +#define BQ2415X_SHIFT_VI_TERM          0
104 +
105 +
106 +enum bq2415x_command {
107 +       BQ2415X_TIMER_RESET,
108 +       BQ2415X_OTG_STATUS,
109 +       BQ2415X_STAT_PIN_STATUS,
110 +       BQ2415X_STAT_PIN_ENABLE,
111 +       BQ2415X_STAT_PIN_DISABLE,
112 +       BQ2415X_CHARGE_STATUS,
113 +       BQ2415X_BOOST_STATUS,
114 +       BQ2415X_FAULT_STATUS,
115 +
116 +       BQ2415X_CHARGE_TERMINATION_STATUS,
117 +       BQ2415X_CHARGE_TERMINATION_ENABLE,
118 +       BQ2415X_CHARGE_TERMINATION_DISABLE,
119 +       BQ2415X_CHARGER_STATUS,
120 +       BQ2415X_CHARGER_ENABLE,
121 +       BQ2415X_CHARGER_DISABLE,
122 +       BQ2415X_HIGH_IMPEDANCE_STATUS,
123 +       BQ2415X_HIGH_IMPEDANCE_ENABLE,
124 +       BQ2415X_HIGH_IMPEDANCE_DISABLE,
125 +       BQ2415X_BOOST_MODE_STATUS,
126 +       BQ2415X_BOOST_MODE_ENABLE,
127 +       BQ2415X_BOOST_MODE_DISABLE,
128 +
129 +       BQ2415X_OTG_LEVEL,
130 +       BQ2415X_OTG_ACTIVATE_HIGH,
131 +       BQ2415X_OTG_ACTIVATE_LOW,
132 +       BQ2415X_OTG_PIN_STATUS,
133 +       BQ2415X_OTG_PIN_ENABLE,
134 +       BQ2415X_OTG_PIN_DISABLE,
135 +
136 +       BQ2415X_VENDER_CODE,
137 +       BQ2415X_PART_NUMBER,
138 +       BQ2415X_REVISION,
139 +};
140 +
141 +enum bq2415x_chip {
142 +       BQUNKNOWN,
143 +       BQ24150,
144 +       BQ24150A,
145 +       BQ24151,
146 +       BQ24151A,
147 +       BQ24152,
148 +       BQ24153,
149 +       BQ24153A,
150 +       BQ24155,
151 +       BQ24156,
152 +       BQ24156A,
153 +       BQ24158,
154 +};
155 +
156 +static char *bq2415x_chip_name[] = {
157 +       "unknown",
158 +       "bq24150",
159 +       "bq24150a",
160 +       "bq24151",
161 +       "bq24151a",
162 +       "bq24152",
163 +       "bq24153",
164 +       "bq24153a",
165 +       "bq24155",
166 +       "bq24156",
167 +       "bq24156a",
168 +       "bq24158",
169 +};
170 +
171 +struct bq2415x_device {
172 +       struct device *dev;
173 +       struct bq2415x_platform_data init_data;
174 +       struct power_supply charger;
175 +       struct delayed_work work;
176 +       enum bq2415x_mode reported_mode;/* mode reported by hook function */
177 +       enum bq2415x_mode mode;         /* current configured mode */
178 +       enum bq2415x_chip chip;
179 +       const char *timer_error;
180 +       char *model;
181 +       char *name;
182 +       int autotimer;  /* 1 - if driver automatically reset timer, 0 - not */
183 +       int automode;   /* 1 - enabled, 0 - disabled; -1 - not supported */
184 +       int id;
185 +};
186 +
187 +/* each registered chip must have unique id */
188 +static DEFINE_IDR(bq2415x_id);
189 +
190 +static DEFINE_MUTEX(bq2415x_id_mutex);
191 +static DEFINE_MUTEX(bq2415x_timer_mutex);
192 +static DEFINE_MUTEX(bq2415x_i2c_mutex);
193 +
194 +/**** i2c read functions ****/
195 +
196 +/* read value from register */
197 +static int bq2415x_i2c_read(struct bq2415x_device *bq, u8 reg)
198 +{
199 +       struct i2c_client *client = to_i2c_client(bq->dev);
200 +       struct i2c_msg msg[2];
201 +       u8 val;
202 +       int ret;
203 +
204 +       if (!client->adapter)
205 +               return -ENODEV;
206 +
207 +       msg[0].addr = client->addr;
208 +       msg[0].flags = 0;
209 +       msg[0].buf = &reg;
210 +       msg[0].len = sizeof(reg);
211 +       msg[1].addr = client->addr;
212 +       msg[1].flags = I2C_M_RD;
213 +       msg[1].buf = &val;
214 +       msg[1].len = sizeof(val);
215 +
216 +       mutex_lock(&bq2415x_i2c_mutex);
217 +       ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
218 +       mutex_unlock(&bq2415x_i2c_mutex);
219 +
220 +       if (ret < 0)
221 +               return ret;
222 +
223 +       return val;
224 +}
225 +
226 +/* read value from register, apply mask and right shift it */
227 +static int bq2415x_i2c_read_mask(struct bq2415x_device *bq, u8 reg,
228 +                               u8 mask, u8 shift)
229 +{
230 +       int ret;
231 +
232 +       if (shift > 8)
233 +               return -EINVAL;
234 +
235 +       ret = bq2415x_i2c_read(bq, reg);
236 +       if (ret < 0)
237 +               return ret;
238 +       else
239 +               return (ret & mask) >> shift;
240 +}
241 +
242 +/* read value from register and return one specified bit */
243 +static int bq2415x_i2c_read_bit(struct bq2415x_device *bq, u8 reg, u8 bit)
244 +{
245 +       if (bit > 8)
246 +               return -EINVAL;
247 +       else
248 +               return bq2415x_i2c_read_mask(bq, reg, BIT(bit), bit);
249 +}
250 +
251 +/**** i2c write functions ****/
252 +
253 +/* write value to register */
254 +static int bq2415x_i2c_write(struct bq2415x_device *bq, u8 reg, u8 val)
255 +{
256 +       struct i2c_client *client = to_i2c_client(bq->dev);
257 +       struct i2c_msg msg[1];
258 +       u8 data[2];
259 +       int ret;
260 +
261 +       data[0] = reg;
262 +       data[1] = val;
263 +
264 +       msg[0].addr = client->addr;
265 +       msg[0].flags = 0;
266 +       msg[0].buf = data;
267 +       msg[0].len = ARRAY_SIZE(data);
268 +
269 +       mutex_lock(&bq2415x_i2c_mutex);
270 +       ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
271 +       mutex_unlock(&bq2415x_i2c_mutex);
272 +
273 +       /* i2c_transfer returns number of messages transferred */
274 +       if (ret < 0)
275 +               return ret;
276 +       else if (ret != 1)
277 +               return -EIO;
278 +
279 +       return 0;
280 +}
281 +
282 +/* read value from register, change it with mask left shifted and write back */
283 +static int bq2415x_i2c_write_mask(struct bq2415x_device *bq, u8 reg, u8 val,
284 +                               u8 mask, u8 shift)
285 +{
286 +       int ret;
287 +
288 +       if (shift > 8)
289 +               return -EINVAL;
290 +
291 +       ret = bq2415x_i2c_read(bq, reg);
292 +       if (ret < 0)
293 +               return ret;
294 +
295 +       ret &= ~mask;
296 +       ret |= val << shift;
297 +
298 +       return bq2415x_i2c_write(bq, reg, ret);
299 +}
300 +
301 +/* change only one bit in register */
302 +static int bq2415x_i2c_write_bit(struct bq2415x_device *bq, u8 reg,
303 +                               bool val, u8 bit)
304 +{
305 +       if (bit > 8)
306 +               return -EINVAL;
307 +       else
308 +               return bq2415x_i2c_write_mask(bq, reg, val, BIT(bit), bit);
309 +}
310 +
311 +/**** global functions ****/
312 +
313 +/* exec command function */
314 +static int bq2415x_exec_command(struct bq2415x_device *bq,
315 +                               enum bq2415x_command command)
316 +{
317 +       int ret;
318 +       switch (command) {
319 +       case BQ2415X_TIMER_RESET:
320 +               return bq2415x_i2c_write_bit(bq, BQ2415X_REG_STATUS,
321 +                               1, BQ2415X_BIT_TMR_RST);
322 +       case BQ2415X_OTG_STATUS:
323 +               return bq2415x_i2c_read_bit(bq, BQ2415X_REG_STATUS,
324 +                               BQ2415X_BIT_OTG);
325 +       case BQ2415X_STAT_PIN_STATUS:
326 +               return bq2415x_i2c_read_bit(bq, BQ2415X_REG_STATUS,
327 +                               BQ2415X_BIT_EN_STAT);
328 +       case BQ2415X_STAT_PIN_ENABLE:
329 +               return bq2415x_i2c_write_bit(bq, BQ2415X_REG_STATUS, 1,
330 +                               BQ2415X_BIT_EN_STAT);
331 +       case BQ2415X_STAT_PIN_DISABLE:
332 +               return bq2415x_i2c_write_bit(bq, BQ2415X_REG_STATUS, 0,
333 +                               BQ2415X_BIT_EN_STAT);
334 +       case BQ2415X_CHARGE_STATUS:
335 +               return bq2415x_i2c_read_mask(bq, BQ2415X_REG_STATUS,
336 +                               BQ2415X_MASK_STAT, BQ2415X_SHIFT_STAT);
337 +       case BQ2415X_BOOST_STATUS:
338 +               return bq2415x_i2c_read_bit(bq, BQ2415X_REG_STATUS,
339 +                               BQ2415X_BIT_BOOST);
340 +       case BQ2415X_FAULT_STATUS:
341 +               return bq2415x_i2c_read_mask(bq, BQ2415X_REG_STATUS,
342 +                       BQ2415X_MASK_FAULT, BQ2415X_SHIFT_FAULT);
343 +
344 +       case BQ2415X_CHARGE_TERMINATION_STATUS:
345 +               return bq2415x_i2c_read_bit(bq, BQ2415X_REG_CONTROL,
346 +                               BQ2415X_BIT_TE);
347 +       case BQ2415X_CHARGE_TERMINATION_ENABLE:
348 +               return bq2415x_i2c_write_bit(bq, BQ2415X_REG_CONTROL,
349 +                               1, BQ2415X_BIT_TE);
350 +       case BQ2415X_CHARGE_TERMINATION_DISABLE:
351 +               return bq2415x_i2c_write_bit(bq, BQ2415X_REG_CONTROL,
352 +                               0, BQ2415X_BIT_TE);
353 +       case BQ2415X_CHARGER_STATUS:
354 +               ret = bq2415x_i2c_read_bit(bq, BQ2415X_REG_CONTROL,
355 +                       BQ2415X_BIT_CE);
356 +               if (ret < 0)
357 +                       return ret;
358 +               else
359 +                       return ret > 0 ? 0 : 1;
360 +       case BQ2415X_CHARGER_ENABLE:
361 +               return bq2415x_i2c_write_bit(bq, BQ2415X_REG_CONTROL,
362 +                               0, BQ2415X_BIT_CE);
363 +       case BQ2415X_CHARGER_DISABLE:
364 +               return bq2415x_i2c_write_bit(bq, BQ2415X_REG_CONTROL,
365 +                               1, BQ2415X_BIT_CE);
366 +       case BQ2415X_HIGH_IMPEDANCE_STATUS:
367 +               return bq2415x_i2c_read_bit(bq, BQ2415X_REG_CONTROL,
368 +                               BQ2415X_BIT_HZ_MODE);
369 +       case BQ2415X_HIGH_IMPEDANCE_ENABLE:
370 +               return bq2415x_i2c_write_bit(bq, BQ2415X_REG_CONTROL,
371 +                               1, BQ2415X_BIT_HZ_MODE);
372 +       case BQ2415X_HIGH_IMPEDANCE_DISABLE:
373 +               return bq2415x_i2c_write_bit(bq, BQ2415X_REG_CONTROL,
374 +                               0, BQ2415X_BIT_HZ_MODE);
375 +       case BQ2415X_BOOST_MODE_STATUS:
376 +               return bq2415x_i2c_read_bit(bq, BQ2415X_REG_CONTROL,
377 +                               BQ2415X_BIT_OPA_MODE);
378 +       case BQ2415X_BOOST_MODE_ENABLE:
379 +               return bq2415x_i2c_write_bit(bq, BQ2415X_REG_CONTROL,
380 +                               1, BQ2415X_BIT_OPA_MODE);
381 +       case BQ2415X_BOOST_MODE_DISABLE:
382 +               return bq2415x_i2c_write_bit(bq, BQ2415X_REG_CONTROL,
383 +                               0, BQ2415X_BIT_OPA_MODE);
384 +
385 +       case BQ2415X_OTG_LEVEL:
386 +               return bq2415x_i2c_read_bit(bq, BQ2415X_REG_VOLTAGE,
387 +                               BQ2415X_BIT_OTG_PL);
388 +       case BQ2415X_OTG_ACTIVATE_HIGH:
389 +               return bq2415x_i2c_write_bit(bq, BQ2415X_REG_VOLTAGE,
390 +                               1, BQ2415X_BIT_OTG_PL);
391 +       case BQ2415X_OTG_ACTIVATE_LOW:
392 +               return bq2415x_i2c_write_bit(bq, BQ2415X_REG_VOLTAGE,
393 +                               0, BQ2415X_BIT_OTG_PL);
394 +       case BQ2415X_OTG_PIN_STATUS:
395 +               return bq2415x_i2c_read_bit(bq, BQ2415X_REG_VOLTAGE,
396 +                               BQ2415X_BIT_OTG_EN);
397 +       case BQ2415X_OTG_PIN_ENABLE:
398 +               return bq2415x_i2c_write_bit(bq, BQ2415X_REG_VOLTAGE,
399 +                               1, BQ2415X_BIT_OTG_EN);
400 +       case BQ2415X_OTG_PIN_DISABLE:
401 +               return bq2415x_i2c_write_bit(bq, BQ2415X_REG_VOLTAGE,
402 +                               0, BQ2415X_BIT_OTG_EN);
403 +
404 +       case BQ2415X_VENDER_CODE:
405 +               return bq2415x_i2c_read_mask(bq, BQ2415X_REG_VENDER,
406 +                       BQ2415X_MASK_VENDER, BQ2415X_SHIFT_VENDER);
407 +       case BQ2415X_PART_NUMBER:
408 +               return bq2415x_i2c_read_mask(bq, BQ2415X_REG_VENDER,
409 +                               BQ2415X_MASK_PN, BQ2415X_SHIFT_PN);
410 +       case BQ2415X_REVISION:
411 +               return bq2415x_i2c_read_mask(bq, BQ2415X_REG_VENDER,
412 +                       BQ2415X_MASK_REVISION, BQ2415X_SHIFT_REVISION);
413 +
414 +       default:
415 +               return -EINVAL;
416 +       }
417 +}
418 +
419 +/* detect chip type */
420 +static enum bq2415x_chip bq2415x_detect_chip(struct bq2415x_device *bq)
421 +{
422 +       struct i2c_client *client = to_i2c_client(bq->dev);
423 +       int ret = bq2415x_exec_command(bq, BQ2415X_PART_NUMBER);
424 +
425 +       if (ret < 0)
426 +               return ret;
427 +
428 +       switch (client->addr) {
429 +       case 0x6b:
430 +               switch (ret) {
431 +               case 0:
432 +                       if (bq->chip == BQ24151A)
433 +                               return bq->chip;
434 +                       else
435 +                               return BQ24151;
436 +               case 1:
437 +                       if (bq->chip == BQ24150A ||
438 +                               bq->chip == BQ24152 ||
439 +                               bq->chip == BQ24155)
440 +                               return bq->chip;
441 +                       else
442 +                               return BQ24150;
443 +               case 2:
444 +                       if (bq->chip == BQ24153A)
445 +                               return bq->chip;
446 +                       else
447 +                               return BQ24153;
448 +               default:
449 +                       return BQUNKNOWN;
450 +               }
451 +               break;
452 +
453 +       case 0x6a:
454 +               switch (ret) {
455 +               case 0:
456 +                       if (bq->chip == BQ24156A)
457 +                               return bq->chip;
458 +                       else
459 +                               return BQ24156;
460 +               case 2:
461 +                       return BQ24158;
462 +               default:
463 +                       return BQUNKNOWN;
464 +               }
465 +               break;
466 +       }
467 +
468 +       return BQUNKNOWN;
469 +}
470 +
471 +/* detect chip revision */
472 +static int bq2415x_detect_revision(struct bq2415x_device *bq)
473 +{
474 +       int ret = bq2415x_exec_command(bq, BQ2415X_REVISION);
475 +       int chip = bq2415x_detect_chip(bq);
476 +       if (ret < 0 || chip < 0)
477 +               return -1;
478 +
479 +       switch (chip) {
480 +       case BQ24150:
481 +       case BQ24150A:
482 +       case BQ24151:
483 +       case BQ24151A:
484 +       case BQ24152:
485 +               if (ret >= 0 && ret <= 3)
486 +                       return ret;
487 +               else
488 +                       return -1;
489 +
490 +       case BQ24153:
491 +       case BQ24153A:
492 +       case BQ24156:
493 +       case BQ24156A:
494 +       case BQ24158:
495 +               if (ret == 3)
496 +                       return 0;
497 +               else if (ret == 1)
498 +                       return 1;
499 +               else
500 +                       return -1;
501 +
502 +       case BQ24155:
503 +               if (ret == 3)
504 +                       return 3;
505 +               else
506 +                       return -1;
507 +
508 +       case BQUNKNOWN:
509 +               return -1;
510 +       }
511 +
512 +       return -1;
513 +}
514 +
515 +/* return chip vender code */
516 +static int bq2415x_get_vender_code(struct bq2415x_device *bq)
517 +{
518 +       int ret = bq2415x_exec_command(bq, BQ2415X_VENDER_CODE);
519 +       if (ret < 0)
520 +               return 0;
521 +       else /* convert to binary */
522 +               return (ret & 0x1) +
523 +                       ((ret >> 1) & 0x1) * 10 +
524 +                       ((ret >> 2) & 0x1) * 100;
525 +}
526 +
527 +/* reset all chip registers to default state */
528 +static void bq2415x_reset_chip(struct bq2415x_device *bq)
529 +{
530 +       bq2415x_i2c_write(bq, BQ2415X_REG_CURRENT, BQ2415X_RESET_CURRENT);
531 +       bq2415x_i2c_write(bq, BQ2415X_REG_VOLTAGE, BQ2415X_RESET_VOLTAGE);
532 +       bq2415x_i2c_write(bq, BQ2415X_REG_CONTROL, BQ2415X_RESET_CONTROL);
533 +       bq2415x_i2c_write(bq, BQ2415X_REG_STATUS, BQ2415X_RESET_STATUS);
534 +       bq->timer_error = NULL;
535 +}
536 +
537 +/**** properties functions ****/
538 +
539 +/* set current limit in mA */
540 +static int bq2415x_set_current_limit(struct bq2415x_device *bq, int mA)
541 +{
542 +       int val;
543 +       if (mA <= 100)
544 +               val = 0;
545 +       else if (mA <= 500)
546 +               val = 1;
547 +       else if (mA <= 800)
548 +               val = 2;
549 +       else
550 +               val = 3;
551 +       return bq2415x_i2c_write_mask(bq, BQ2415X_REG_CONTROL, val,
552 +                       BQ2415X_MASK_LIMIT, BQ2415X_SHIFT_LIMIT);
553 +}
554 +
555 +/* get current limit in mA */
556 +static int bq2415x_get_current_limit(struct bq2415x_device *bq)
557 +{
558 +       int ret = bq2415x_i2c_read_mask(bq, BQ2415X_REG_CONTROL,
559 +                       BQ2415X_MASK_LIMIT, BQ2415X_SHIFT_LIMIT);
560 +       if (ret < 0)
561 +               return ret;
562 +       else if (ret == 0)
563 +               return 100;
564 +       else if (ret == 1)
565 +               return 500;
566 +       else if (ret == 2)
567 +               return 800;
568 +       else if (ret == 3)
569 +               return 1800;
570 +       else
571 +               return -EINVAL;
572 +}
573 +
574 +/* set weak battery voltage in mV */
575 +static int bq2415x_set_weak_battery_voltage(struct bq2415x_device *bq, int mV)
576 +{
577 +       /* round to 100mV */
578 +       int val;
579 +       if (mV <= 3400 + 50)
580 +               val = 0;
581 +       else if (mV <= 3500 + 50)
582 +               val = 1;
583 +       else if (mV <= 3600 + 50)
584 +               val = 2;
585 +       else
586 +               val = 3;
587 +       return bq2415x_i2c_write_mask(bq, BQ2415X_REG_CONTROL, val,
588 +                       BQ2415X_MASK_VLOWV, BQ2415X_SHIFT_VLOWV);
589 +}
590 +
591 +/* get weak battery voltage in mV */
592 +static int bq2415x_get_weak_battery_voltage(struct bq2415x_device *bq)
593 +{
594 +       int ret = bq2415x_i2c_read_mask(bq, BQ2415X_REG_CONTROL,
595 +                       BQ2415X_MASK_VLOWV, BQ2415X_SHIFT_VLOWV);
596 +       if (ret < 0)
597 +               return ret;
598 +       else
599 +               return 100 * (34 + ret);
600 +}
601 +
602 +/* set battery regulation voltage in mV */
603 +static int bq2415x_set_battery_regulation_voltage(struct bq2415x_device *bq,
604 +                                               int mV)
605 +{
606 +       int val = (mV/10 - 350) / 2;
607 +
608 +       if (val < 0)
609 +               val = 0;
610 +       else if (val > 94) /* FIXME: Max is 94 or 122 ? Set max value ? */
611 +               return -EINVAL;
612 +
613 +       return bq2415x_i2c_write_mask(bq, BQ2415X_REG_VOLTAGE, val,
614 +                       BQ2415X_MASK_VO, BQ2415X_SHIFT_VO);
615 +}
616 +
617 +/* get battery regulation voltage in mV */
618 +static int bq2415x_get_battery_regulation_voltage(struct bq2415x_device *bq)
619 +{
620 +       int ret = bq2415x_i2c_read_mask(bq, BQ2415X_REG_VOLTAGE,
621 +                       BQ2415X_MASK_VO, BQ2415X_SHIFT_VO);
622 +       if (ret < 0)
623 +               return ret;
624 +       else
625 +               return 10 * (350 + 2*ret);
626 +}
627 +
628 +/* set charge current in mA (platform data must provide resistor sense) */
629 +static int bq2415x_set_charge_current(struct bq2415x_device *bq, int mA)
630 +{
631 +       int val;
632 +       if (bq->init_data.resistor_sense <= 0)
633 +               return -ENOSYS;
634 +
635 +       val = (mA * bq->init_data.resistor_sense - 37400) / 6800;
636 +
637 +       if (val < 0)
638 +               val = 0;
639 +       else if (val > 7)
640 +               val = 7;
641 +
642 +       return bq2415x_i2c_write_mask(bq, BQ2415X_REG_CURRENT, val,
643 +                       BQ2415X_MASK_VI_CHRG | BQ2415X_MASK_RESET,
644 +                       BQ2415X_SHIFT_VI_CHRG);
645 +}
646 +
647 +/* get charge current in mA (platform data must provide resistor sense) */
648 +static int bq2415x_get_charge_current(struct bq2415x_device *bq)
649 +{
650 +       int ret;
651 +       if (bq->init_data.resistor_sense <= 0)
652 +               return -ENOSYS;
653 +
654 +       ret = bq2415x_i2c_read_mask(bq, BQ2415X_REG_CURRENT,
655 +                       BQ2415X_MASK_VI_CHRG, BQ2415X_SHIFT_VI_CHRG);
656 +       if (ret < 0)
657 +               return ret;
658 +       else
659 +               return (37400 + 6800*ret) / bq->init_data.resistor_sense;
660 +}
661 +
662 +/* set termination current in mA (platform data must provide resistor sense) */
663 +static int bq2415x_set_termination_current(struct bq2415x_device *bq, int mA)
664 +{
665 +       int val;
666 +       if (bq->init_data.resistor_sense <= 0)
667 +               return -ENOSYS;
668 +
669 +       val = (mA * bq->init_data.resistor_sense - 3400) / 3400;
670 +
671 +       if (val < 0)
672 +               val = 0;
673 +       else if (val > 7)
674 +               val = 7;
675 +
676 +       return bq2415x_i2c_write_mask(bq, BQ2415X_REG_CURRENT, val,
677 +                       BQ2415X_MASK_VI_TERM | BQ2415X_MASK_RESET,
678 +                       BQ2415X_SHIFT_VI_TERM);
679 +}
680 +
681 +/* get termination current in mA (platform data must provide resistor sense) */
682 +static int bq2415x_get_termination_current(struct bq2415x_device *bq)
683 +{
684 +       int ret;
685 +       if (bq->init_data.resistor_sense <= 0)
686 +               return -ENOSYS;
687 +
688 +       ret = bq2415x_i2c_read_mask(bq, BQ2415X_REG_CURRENT,
689 +                       BQ2415X_MASK_VI_TERM, BQ2415X_SHIFT_VI_TERM);
690 +       if (ret < 0)
691 +               return ret;
692 +       else
693 +               return (3400 + 3400*ret) / bq->init_data.resistor_sense;
694 +}
695 +
696 +/* set default value of property */
697 +#define bq2415x_set_default_value(bq, prop) \
698 +       do { \
699 +               int ret = 0; \
700 +               if (bq->init_data.prop != -1) \
701 +                       ret = bq2415x_set_##prop(bq, bq->init_data.prop); \
702 +               if (ret < 0) \
703 +                       return ret; \
704 +       } while (0)
705 +
706 +/* set default values of all properties */
707 +static int bq2415x_set_defaults(struct bq2415x_device *bq)
708 +{
709 +       bq2415x_exec_command(bq, BQ2415X_BOOST_MODE_DISABLE);
710 +       bq2415x_exec_command(bq, BQ2415X_CHARGER_DISABLE);
711 +       bq2415x_exec_command(bq, BQ2415X_CHARGE_TERMINATION_DISABLE);
712 +       bq2415x_set_default_value(bq, current_limit);
713 +       bq2415x_set_default_value(bq, weak_battery_voltage);
714 +       bq2415x_set_default_value(bq, battery_regulation_voltage);
715 +       if (bq->init_data.resistor_sense > 0) {
716 +               bq2415x_set_default_value(bq, charge_current);
717 +               bq2415x_set_default_value(bq, termination_current);
718 +               bq2415x_exec_command(bq, BQ2415X_CHARGE_TERMINATION_ENABLE);
719 +       }
720 +       bq2415x_exec_command(bq, BQ2415X_CHARGER_ENABLE);
721 +       return 0;
722 +}
723 +
724 +/**** charger mode functions ****/
725 +
726 +/* set charger mode */
727 +static int bq2415x_set_mode(struct bq2415x_device *bq, enum bq2415x_mode mode)
728 +{
729 +       int ret = 0;
730 +       int charger = 0;
731 +       int boost = 0;
732 +
733 +       if (mode == BQ2415X_MODE_BOOST)
734 +               boost = 1;
735 +       else if (mode != BQ2415X_MODE_OFF)
736 +               charger = 1;
737 +
738 +       if (!charger)
739 +               ret = bq2415x_exec_command(bq, BQ2415X_CHARGER_DISABLE);
740 +
741 +       if (!boost)
742 +               ret = bq2415x_exec_command(bq, BQ2415X_BOOST_MODE_DISABLE);
743 +
744 +       if (ret < 0)
745 +               return ret;
746 +
747 +       switch (mode) {
748 +       case BQ2415X_MODE_OFF:
749 +               dev_dbg(bq->dev, "changing mode to: Offline\n");
750 +               ret = bq2415x_set_current_limit(bq, 100);
751 +               break;
752 +       case BQ2415X_MODE_NONE:
753 +               dev_dbg(bq->dev, "changing mode to: N/A\n");
754 +               ret = bq2415x_set_current_limit(bq, 100);
755 +               break;
756 +       case BQ2415X_MODE_HOST_CHARGER:
757 +               dev_dbg(bq->dev, "changing mode to: Host/HUB charger\n");
758 +               ret = bq2415x_set_current_limit(bq, 500);
759 +               break;
760 +       case BQ2415X_MODE_DEDICATED_CHARGER:
761 +               dev_dbg(bq->dev, "changing mode to: Dedicated charger\n");
762 +               ret = bq2415x_set_current_limit(bq, 1800);
763 +               break;
764 +       case BQ2415X_MODE_BOOST: /* Boost mode */
765 +               dev_dbg(bq->dev, "changing mode to: Boost\n");
766 +               ret = bq2415x_set_current_limit(bq, 100);
767 +               break;
768 +       }
769 +
770 +       if (ret < 0)
771 +               return ret;
772 +
773 +       if (charger)
774 +               ret = bq2415x_exec_command(bq, BQ2415X_CHARGER_ENABLE);
775 +       else if (boost)
776 +               ret = bq2415x_exec_command(bq, BQ2415X_BOOST_MODE_ENABLE);
777 +
778 +       if (ret < 0)
779 +               return ret;
780 +
781 +       bq2415x_set_default_value(bq, weak_battery_voltage);
782 +       bq2415x_set_default_value(bq, battery_regulation_voltage);
783 +
784 +       bq->mode = mode;
785 +       sysfs_notify(&bq->charger.dev->kobj, NULL, "mode");
786 +
787 +       return 0;
788 +
789 +}
790 +
791 +/* hook function called by other driver which set reported mode */
792 +static void bq2415x_hook_function(enum bq2415x_mode mode, void *data)
793 +{
794 +       struct bq2415x_device *bq = data;
795 +
796 +       if (!bq)
797 +               return;
798 +
799 +       dev_dbg(bq->dev, "hook function was called\n");
800 +       bq->reported_mode = mode;
801 +
802 +       /* if automode is not enabled do not tell about reported_mode */
803 +       if (bq->automode < 1)
804 +               return;
805 +
806 +       sysfs_notify(&bq->charger.dev->kobj, NULL, "reported_mode");
807 +       bq2415x_set_mode(bq, bq->reported_mode);
808 +
809 +}
810 +
811 +/**** timer functions ****/
812 +
813 +/* enable/disable auto resetting chip timer */
814 +static void bq2415x_set_autotimer(struct bq2415x_device *bq, int state)
815 +{
816 +       mutex_lock(&bq2415x_timer_mutex);
817 +
818 +       if (bq->autotimer == state) {
819 +               mutex_unlock(&bq2415x_timer_mutex);
820 +               return;
821 +       }
822 +
823 +       bq->autotimer = state;
824 +
825 +       if (state) {
826 +               schedule_delayed_work(&bq->work, BQ2415X_TIMER_TIMEOUT * HZ);
827 +               bq2415x_exec_command(bq, BQ2415X_TIMER_RESET);
828 +               bq->timer_error = NULL;
829 +       } else {
830 +               cancel_delayed_work_sync(&bq->work);
831 +       }
832 +
833 +       mutex_unlock(&bq2415x_timer_mutex);
834 +}
835 +
836 +/* called by bq2415x_timer_work on timer error */
837 +static void bq2415x_timer_error(struct bq2415x_device *bq, const char *msg)
838 +{
839 +       bq->timer_error = msg;
840 +       sysfs_notify(&bq->charger.dev->kobj, NULL, "timer");
841 +       dev_err(bq->dev, "%s\n", msg);
842 +       if (bq->automode > 0)
843 +               bq->automode = 0;
844 +       bq2415x_set_mode(bq, BQ2415X_MODE_OFF);
845 +       bq2415x_set_autotimer(bq, 0);
846 +}
847 +
848 +/* delayed work function for auto resetting chip timer */
849 +static void bq2415x_timer_work(struct work_struct *work)
850 +{
851 +       struct bq2415x_device *bq = container_of(work, struct bq2415x_device,
852 +                                               work.work);
853 +       int ret, error, boost;
854 +
855 +       if (!bq->autotimer)
856 +               return;
857 +
858 +       ret = bq2415x_exec_command(bq, BQ2415X_TIMER_RESET);
859 +       if (ret < 0) {
860 +               bq2415x_timer_error(bq, "Resetting timer failed");
861 +               return;
862 +       }
863 +
864 +       boost = bq2415x_exec_command(bq, BQ2415X_BOOST_MODE_STATUS);
865 +       if (boost < 0) {
866 +               bq2415x_timer_error(bq, "Unknown error");
867 +               return;
868 +       }
869 +
870 +       error = bq2415x_exec_command(bq, BQ2415X_FAULT_STATUS);
871 +       if (error < 0) {
872 +               bq2415x_timer_error(bq, "Unknown error");
873 +               return;
874 +       }
875 +
876 +       if (boost) {
877 +               switch (error) {
878 +               /* Non fatal errors, chip is OK */
879 +               case 0: /* No error */
880 +                       break;
881 +               case 6: /* Timer expired */
882 +                       dev_err(bq->dev, "Timer expired\n");
883 +                       break;
884 +               case 3: /* Battery voltage too low */
885 +                       dev_err(bq->dev, "Battery voltage to low\n");
886 +                       break;
887 +
888 +               /* Fatal errors, disable and reset chip */
889 +               case 1: /* Overvoltage protection (chip fried) */
890 +                       bq2415x_timer_error(bq,
891 +                               "Overvoltage protection (chip fried)");
892 +                       return;
893 +               case 2: /* Overload */
894 +                       bq2415x_timer_error(bq, "Overload");
895 +                       return;
896 +               case 4: /* Battery overvoltage protection */
897 +                       bq2415x_timer_error(bq,
898 +                               "Battery overvoltage protection");
899 +                       return;
900 +               case 5: /* Thermal shutdown (too hot) */
901 +                       bq2415x_timer_error(bq,
902 +                                       "Thermal shutdown (too hot)");
903 +                       return;
904 +               case 7: /* N/A */
905 +                       bq2415x_timer_error(bq, "Unknown error");
906 +                       return;
907 +               }
908 +       } else {
909 +               switch (error) {
910 +               /* Non fatal errors, chip is OK */
911 +               case 0: /* No error */
912 +                       break;
913 +               case 2: /* Sleep mode */
914 +                       dev_err(bq->dev, "Sleep mode\n");
915 +                       break;
916 +               case 3: /* Poor input source */
917 +                       dev_err(bq->dev, "Poor input source\n");
918 +                       break;
919 +               case 6: /* Timer expired */
920 +                       dev_err(bq->dev, "Timer expired\n");
921 +                       break;
922 +               case 7: /* No battery */
923 +                       dev_err(bq->dev, "No battery\n");
924 +                       break;
925 +
926 +               /* Fatal errors, disable and reset chip */
927 +               case 1: /* Overvoltage protection (chip fried) */
928 +                       bq2415x_timer_error(bq,
929 +                               "Overvoltage protection (chip fried)");
930 +                       return;
931 +               case 4: /* Battery overvoltage protection */
932 +                       bq2415x_timer_error(bq,
933 +                               "Battery overvoltage protection");
934 +                       return;
935 +               case 5: /* Thermal shutdown (too hot) */
936 +                       bq2415x_timer_error(bq,
937 +                               "Thermal shutdown (too hot)");
938 +                       return;
939 +               }
940 +       }
941 +
942 +       schedule_delayed_work(&bq->work, BQ2415X_TIMER_TIMEOUT * HZ);
943 +}
944 +
945 +/**** power supply interface code ****/
946 +
947 +static enum power_supply_property bq2415x_power_supply_props[] = {
948 +       /* TODO: maybe add more power supply properties */
949 +       POWER_SUPPLY_PROP_STATUS,
950 +       POWER_SUPPLY_PROP_MODEL_NAME,
951 +};
952 +
953 +static int bq2415x_power_supply_get_property(struct power_supply *psy,
954 +       enum power_supply_property psp, union power_supply_propval *val)
955 +{
956 +       struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
957 +                                               charger);
958 +       int ret;
959 +
960 +       switch (psp) {
961 +       case POWER_SUPPLY_PROP_STATUS:
962 +               ret = bq2415x_exec_command(bq, BQ2415X_CHARGE_STATUS);
963 +               if (ret < 0)
964 +                       return ret;
965 +               else if (ret == 0) /* Ready */
966 +                       val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
967 +               else if (ret == 1) /* Charge in progress */
968 +                       val->intval = POWER_SUPPLY_STATUS_CHARGING;
969 +               else if (ret == 2) /* Charge done */
970 +                       val->intval = POWER_SUPPLY_STATUS_FULL;
971 +               else
972 +                       val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
973 +               break;
974 +       case POWER_SUPPLY_PROP_MODEL_NAME:
975 +               val->strval = bq->model;
976 +               break;
977 +       default:
978 +               return -EINVAL;
979 +       }
980 +       return 0;
981 +}
982 +
983 +static int bq2415x_power_supply_init(struct bq2415x_device *bq)
984 +{
985 +       int ret;
986 +       int chip;
987 +       char revstr[8];
988 +
989 +       bq->charger.name = bq->name;
990 +       bq->charger.type = POWER_SUPPLY_TYPE_USB;
991 +       bq->charger.properties = bq2415x_power_supply_props;
992 +       bq->charger.num_properties = ARRAY_SIZE(bq2415x_power_supply_props);
993 +       bq->charger.get_property = bq2415x_power_supply_get_property;
994 +
995 +       ret = bq2415x_detect_chip(bq);
996 +       if (ret < 0)
997 +               chip = BQUNKNOWN;
998 +       else
999 +               chip = ret;
1000 +
1001 +       ret = bq2415x_detect_revision(bq);
1002 +       if (ret < 0)
1003 +               strcpy(revstr, "unknown");
1004 +       else
1005 +               sprintf(revstr, "1.%d", ret);
1006 +
1007 +       bq->model = kasprintf(GFP_KERNEL,
1008 +                               "chip %s, revision %s, vender code %.3d",
1009 +                               bq2415x_chip_name[chip], revstr,
1010 +                               bq2415x_get_vender_code(bq));
1011 +       if (!bq->model) {
1012 +               dev_err(bq->dev, "failed to allocate model name\n");
1013 +               return -ENOMEM;
1014 +       }
1015 +
1016 +       ret = power_supply_register(bq->dev, &bq->charger);
1017 +       if (ret) {
1018 +               kfree(bq->model);
1019 +               return ret;
1020 +       }
1021 +
1022 +       return 0;
1023 +}
1024 +
1025 +static void bq2415x_power_supply_exit(struct bq2415x_device *bq)
1026 +{
1027 +       bq->autotimer = 0;
1028 +       if (bq->automode > 0)
1029 +               bq->automode = 0;
1030 +       cancel_delayed_work_sync(&bq->work);
1031 +       power_supply_unregister(&bq->charger);
1032 +       kfree(bq->model);
1033 +}
1034 +
1035 +/**** additional sysfs entries for power supply interface ****/
1036 +
1037 +/* show *_status entries */
1038 +static ssize_t bq2415x_sysfs_show_status(struct device *dev,
1039 +               struct device_attribute *attr, char *buf)
1040 +{
1041 +       struct power_supply *psy = dev_get_drvdata(dev);
1042 +       struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
1043 +                                               charger);
1044 +       enum bq2415x_command command;
1045 +       int ret;
1046 +
1047 +       if (strcmp(attr->attr.name, "otg_status") == 0)
1048 +               command = BQ2415X_OTG_STATUS;
1049 +       else if (strcmp(attr->attr.name, "charge_status") == 0)
1050 +               command = BQ2415X_CHARGE_STATUS;
1051 +       else if (strcmp(attr->attr.name, "boost_status") == 0)
1052 +               command = BQ2415X_BOOST_STATUS;
1053 +       else if (strcmp(attr->attr.name, "fault_status") == 0)
1054 +               command = BQ2415X_FAULT_STATUS;
1055 +       else
1056 +               return -EINVAL;
1057 +
1058 +       ret = bq2415x_exec_command(bq, command);
1059 +       if (ret < 0)
1060 +               return ret;
1061 +       else
1062 +               return sprintf(buf, "%d\n", ret);
1063 +}
1064 +
1065 +/* set timer entry:
1066 +     auto - enable auto mode
1067 +     off - disable auto mode
1068 +     (other values) - reset chip timer
1069 +*/
1070 +static ssize_t bq2415x_sysfs_set_timer(struct device *dev,
1071 +               struct device_attribute *attr, const char *buf, size_t count)
1072 +{
1073 +       struct power_supply *psy = dev_get_drvdata(dev);
1074 +       struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
1075 +                                               charger);
1076 +       int ret = 0;
1077 +
1078 +       if (strncmp(buf, "auto", 4) == 0)
1079 +               bq2415x_set_autotimer(bq, 1);
1080 +       else if (strncmp(buf, "off", 3) == 0)
1081 +               bq2415x_set_autotimer(bq, 0);
1082 +       else
1083 +               ret = bq2415x_exec_command(bq, BQ2415X_TIMER_RESET);
1084 +
1085 +       if (ret < 0)
1086 +               return ret;
1087 +       else
1088 +               return count;
1089 +}
1090 +
1091 +/* show timer entry (auto or off) */
1092 +static ssize_t bq2415x_sysfs_show_timer(struct device *dev,
1093 +               struct device_attribute *attr, char *buf)
1094 +{
1095 +       struct power_supply *psy = dev_get_drvdata(dev);
1096 +       struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
1097 +                                               charger);
1098 +
1099 +       if (bq->timer_error)
1100 +               return sprintf(buf, "%s\n", bq->timer_error);
1101 +
1102 +       if (bq->autotimer)
1103 +               return sprintf(buf, "auto\n");
1104 +       else
1105 +               return sprintf(buf, "off\n");
1106 +}
1107 +
1108 +/* set mode entry:
1109 +     auto - if automode is supported, enable it and set mode to reported
1110 +     none - disable charger and boost mode
1111 +     host - charging mode for host/hub chargers (current limit 500mA)
1112 +     dedicated - charging mode for dedicated chargers (unlimited current limit)
1113 +     boost - disable charger and enable boost mode
1114 +*/
1115 +static ssize_t bq2415x_sysfs_set_mode(struct device *dev,
1116 +               struct device_attribute *attr, const char *buf, size_t count)
1117 +{
1118 +       struct power_supply *psy = dev_get_drvdata(dev);
1119 +       struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
1120 +                                               charger);
1121 +       enum bq2415x_mode mode;
1122 +       int ret = 0;
1123 +
1124 +       if (strncmp(buf, "auto", 4) == 0) {
1125 +               if (bq->automode < 0)
1126 +                       return -ENOSYS;
1127 +               bq->automode = 1;
1128 +               mode = bq->reported_mode;
1129 +       } else if (strncmp(buf, "off", 3) == 0) {
1130 +               if (bq->automode > 0)
1131 +                       bq->automode = 0;
1132 +               mode = BQ2415X_MODE_OFF;
1133 +       } else if (strncmp(buf, "none", 4) == 0) {
1134 +               if (bq->automode > 0)
1135 +                       bq->automode = 0;
1136 +               mode = BQ2415X_MODE_NONE;
1137 +       } else if (strncmp(buf, "host", 4) == 0) {
1138 +               if (bq->automode > 0)
1139 +                       bq->automode = 0;
1140 +               mode = BQ2415X_MODE_HOST_CHARGER;
1141 +       } else if (strncmp(buf, "dedicated", 9) == 0) {
1142 +               if (bq->automode > 0)
1143 +                       bq->automode = 0;
1144 +               mode = BQ2415X_MODE_DEDICATED_CHARGER;
1145 +       } else if (strncmp(buf, "boost", 5) == 0) {
1146 +               if (bq->automode > 0)
1147 +                       bq->automode = 0;
1148 +               mode = BQ2415X_MODE_BOOST;
1149 +       } else if (strncmp(buf, "reset", 5) == 0) {
1150 +               bq2415x_reset_chip(bq);
1151 +               bq2415x_set_defaults(bq);
1152 +               if (bq->automode <= 0)
1153 +                       return count;
1154 +               bq->automode = 1;
1155 +               mode = bq->reported_mode;
1156 +       } else
1157 +               return -EINVAL;
1158 +
1159 +       ret = bq2415x_set_mode(bq, mode);
1160 +       if (ret < 0)
1161 +               return ret;
1162 +       else
1163 +               return count;
1164 +}
1165 +
1166 +/* show mode entry (auto, none, host, dedicated or boost) */
1167 +static ssize_t bq2415x_sysfs_show_mode(struct device *dev,
1168 +               struct device_attribute *attr, char *buf)
1169 +{
1170 +       struct power_supply *psy = dev_get_drvdata(dev);
1171 +       struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
1172 +                                               charger);
1173 +       ssize_t ret = 0;
1174 +
1175 +       if (bq->automode > 0)
1176 +               ret += sprintf(buf+ret, "auto (");
1177 +
1178 +       switch (bq->mode) {
1179 +       case BQ2415X_MODE_OFF:
1180 +               ret += sprintf(buf+ret, "off");
1181 +               break;
1182 +       case BQ2415X_MODE_NONE:
1183 +               ret += sprintf(buf+ret, "none");
1184 +               break;
1185 +       case BQ2415X_MODE_HOST_CHARGER:
1186 +               ret += sprintf(buf+ret, "host");
1187 +               break;
1188 +       case BQ2415X_MODE_DEDICATED_CHARGER:
1189 +               ret += sprintf(buf+ret, "dedicated");
1190 +               break;
1191 +       case BQ2415X_MODE_BOOST:
1192 +               ret += sprintf(buf+ret, "boost");
1193 +               break;
1194 +       }
1195 +
1196 +       if (bq->automode > 0)
1197 +               ret += sprintf(buf+ret, ")");
1198 +
1199 +       ret += sprintf(buf+ret, "\n");
1200 +       return ret;
1201 +}
1202 +
1203 +/* show reported_mode entry (none, host, dedicated or boost) */
1204 +static ssize_t bq2415x_sysfs_show_reported_mode(struct device *dev,
1205 +               struct device_attribute *attr, char *buf)
1206 +{
1207 +       struct power_supply *psy = dev_get_drvdata(dev);
1208 +       struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
1209 +                                               charger);
1210 +
1211 +       if (bq->automode < 0)
1212 +               return -EINVAL;
1213 +
1214 +       switch (bq->reported_mode) {
1215 +       case BQ2415X_MODE_OFF:
1216 +               return sprintf(buf, "off\n");
1217 +       case BQ2415X_MODE_NONE:
1218 +               return sprintf(buf, "none\n");
1219 +       case BQ2415X_MODE_HOST_CHARGER:
1220 +               return sprintf(buf, "host\n");
1221 +       case BQ2415X_MODE_DEDICATED_CHARGER:
1222 +               return sprintf(buf, "dedicated\n");
1223 +       case BQ2415X_MODE_BOOST:
1224 +               return sprintf(buf, "boost\n");
1225 +       }
1226 +
1227 +       return -EINVAL;
1228 +}
1229 +
1230 +/* directly set raw value to chip register, format: 'register value' */
1231 +static ssize_t bq2415x_sysfs_set_registers(struct device *dev,
1232 +               struct device_attribute *attr, const char *buf, size_t count)
1233 +{
1234 +       struct power_supply *psy = dev_get_drvdata(dev);
1235 +       struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
1236 +                                               charger);
1237 +       ssize_t ret = 0;
1238 +       unsigned int reg;
1239 +       unsigned int val;
1240 +
1241 +       if (sscanf(buf, "%x %x", &reg, &val) != 2)
1242 +               return -EINVAL;
1243 +
1244 +       if (reg > 4 || val > 255)
1245 +               return -EINVAL;
1246 +
1247 +       ret = bq2415x_i2c_write(bq, reg, val);
1248 +       if (ret < 0)
1249 +               return ret;
1250 +       else
1251 +               return count;
1252 +}
1253 +
1254 +/* print value of chip register, format: 'register=value' */
1255 +static ssize_t bq2415x_sysfs_print_reg(struct bq2415x_device *bq,
1256 +                                       u8 reg, char *buf)
1257 +{
1258 +       int ret = bq2415x_i2c_read(bq, reg);
1259 +       if (ret < 0)
1260 +               return sprintf(buf, "%#.2x=error %d\n", reg, ret);
1261 +       else
1262 +               return sprintf(buf, "%#.2x=%#.2x\n", reg, ret);
1263 +}
1264 +
1265 +/* show all raw values of chip register, format per line: 'register=value' */
1266 +static ssize_t bq2415x_sysfs_show_registers(struct device *dev,
1267 +               struct device_attribute *attr, char *buf)
1268 +{
1269 +       struct power_supply *psy = dev_get_drvdata(dev);
1270 +       struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
1271 +                                               charger);
1272 +       ssize_t ret = 0;
1273 +
1274 +       ret += bq2415x_sysfs_print_reg(bq, BQ2415X_REG_STATUS, buf+ret);
1275 +       ret += bq2415x_sysfs_print_reg(bq, BQ2415X_REG_CONTROL, buf+ret);
1276 +       ret += bq2415x_sysfs_print_reg(bq, BQ2415X_REG_VOLTAGE, buf+ret);
1277 +       ret += bq2415x_sysfs_print_reg(bq, BQ2415X_REG_VENDER, buf+ret);
1278 +       ret += bq2415x_sysfs_print_reg(bq, BQ2415X_REG_CURRENT, buf+ret);
1279 +       return ret;
1280 +}
1281 +
1282 +/* set current and voltage limit entries (in mA or mV) */
1283 +static ssize_t bq2415x_sysfs_set_limit(struct device *dev,
1284 +               struct device_attribute *attr, const char *buf, size_t count)
1285 +{
1286 +       struct power_supply *psy = dev_get_drvdata(dev);
1287 +       struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
1288 +                                               charger);
1289 +       long val;
1290 +       int ret;
1291 +
1292 +       if (kstrtol(buf, 10, &val) < 0)
1293 +               return -EINVAL;
1294 +
1295 +       if (strcmp(attr->attr.name, "current_limit") == 0)
1296 +               ret = bq2415x_set_current_limit(bq, val);
1297 +       else if (strcmp(attr->attr.name, "weak_battery_voltage") == 0)
1298 +               ret = bq2415x_set_weak_battery_voltage(bq, val);
1299 +       else if (strcmp(attr->attr.name, "battery_regulation_voltage") == 0)
1300 +               ret = bq2415x_set_battery_regulation_voltage(bq, val);
1301 +       else if (strcmp(attr->attr.name, "charge_current") == 0)
1302 +               ret = bq2415x_set_charge_current(bq, val);
1303 +       else if (strcmp(attr->attr.name, "termination_current") == 0)
1304 +               ret = bq2415x_set_termination_current(bq, val);
1305 +       else
1306 +               return -EINVAL;
1307 +
1308 +       if (ret < 0)
1309 +               return ret;
1310 +       else
1311 +               return count;
1312 +}
1313 +
1314 +/* show current and voltage limit entries (in mA or mV) */
1315 +static ssize_t bq2415x_sysfs_show_limit(struct device *dev,
1316 +               struct device_attribute *attr, char *buf)
1317 +{
1318 +       struct power_supply *psy = dev_get_drvdata(dev);
1319 +       struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
1320 +                                               charger);
1321 +       int ret;
1322 +
1323 +       if (strcmp(attr->attr.name, "current_limit") == 0)
1324 +               ret = bq2415x_get_current_limit(bq);
1325 +       else if (strcmp(attr->attr.name, "weak_battery_voltage") == 0)
1326 +               ret = bq2415x_get_weak_battery_voltage(bq);
1327 +       else if (strcmp(attr->attr.name, "battery_regulation_voltage") == 0)
1328 +               ret = bq2415x_get_battery_regulation_voltage(bq);
1329 +       else if (strcmp(attr->attr.name, "charge_current") == 0)
1330 +               ret = bq2415x_get_charge_current(bq);
1331 +       else if (strcmp(attr->attr.name, "termination_current") == 0)
1332 +               ret = bq2415x_get_termination_current(bq);
1333 +       else
1334 +               return -EINVAL;
1335 +
1336 +       if (ret < 0)
1337 +               return ret;
1338 +       else
1339 +               return sprintf(buf, "%d\n", ret);
1340 +}
1341 +
1342 +/* set *_enable entries */
1343 +static ssize_t bq2415x_sysfs_set_enable(struct device *dev,
1344 +               struct device_attribute *attr, const char *buf, size_t count)
1345 +{
1346 +       struct power_supply *psy = dev_get_drvdata(dev);
1347 +       struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
1348 +                                               charger);
1349 +       enum bq2415x_command command;
1350 +       long val;
1351 +       int ret;
1352 +
1353 +       if (kstrtol(buf, 10, &val) < 0)
1354 +               return -EINVAL;
1355 +
1356 +       if (strcmp(attr->attr.name, "charge_termination_enable") == 0)
1357 +               command = val ? BQ2415X_CHARGE_TERMINATION_ENABLE :
1358 +                       BQ2415X_CHARGE_TERMINATION_DISABLE;
1359 +       else if (strcmp(attr->attr.name, "high_impedance_enable") == 0)
1360 +               command = val ? BQ2415X_HIGH_IMPEDANCE_ENABLE :
1361 +                       BQ2415X_HIGH_IMPEDANCE_DISABLE;
1362 +       else if (strcmp(attr->attr.name, "otg_pin_enable") == 0)
1363 +               command = val ? BQ2415X_OTG_PIN_ENABLE :
1364 +                       BQ2415X_OTG_PIN_DISABLE;
1365 +       else if (strcmp(attr->attr.name, "stat_pin_enable") == 0)
1366 +               command = val ? BQ2415X_STAT_PIN_ENABLE :
1367 +                       BQ2415X_STAT_PIN_DISABLE;
1368 +       else
1369 +               return -EINVAL;
1370 +
1371 +       ret = bq2415x_exec_command(bq, command);
1372 +       if (ret < 0)
1373 +               return ret;
1374 +       else
1375 +               return count;
1376 +}
1377 +
1378 +/* show *_enable entries */
1379 +static ssize_t bq2415x_sysfs_show_enable(struct device *dev,
1380 +               struct device_attribute *attr, char *buf)
1381 +{
1382 +       struct power_supply *psy = dev_get_drvdata(dev);
1383 +       struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
1384 +                                               charger);
1385 +       enum bq2415x_command command;
1386 +       int ret;
1387 +
1388 +       if (strcmp(attr->attr.name, "charge_termination_enable") == 0)
1389 +               command = BQ2415X_CHARGE_TERMINATION_STATUS;
1390 +       else if (strcmp(attr->attr.name, "high_impedance_enable") == 0)
1391 +               command = BQ2415X_HIGH_IMPEDANCE_STATUS;
1392 +       else if (strcmp(attr->attr.name, "otg_pin_enable") == 0)
1393 +               command = BQ2415X_OTG_PIN_STATUS;
1394 +       else if (strcmp(attr->attr.name, "stat_pin_enable") == 0)
1395 +               command = BQ2415X_STAT_PIN_STATUS;
1396 +       else
1397 +               return -EINVAL;
1398 +
1399 +       ret = bq2415x_exec_command(bq, command);
1400 +       if (ret < 0)
1401 +               return ret;
1402 +       else
1403 +               return sprintf(buf, "%d\n", ret);
1404 +}
1405 +
1406 +static DEVICE_ATTR(current_limit, S_IWUSR | S_IRUGO,
1407 +               bq2415x_sysfs_show_limit, bq2415x_sysfs_set_limit);
1408 +static DEVICE_ATTR(weak_battery_voltage, S_IWUSR | S_IRUGO,
1409 +               bq2415x_sysfs_show_limit, bq2415x_sysfs_set_limit);
1410 +static DEVICE_ATTR(battery_regulation_voltage, S_IWUSR | S_IRUGO,
1411 +               bq2415x_sysfs_show_limit, bq2415x_sysfs_set_limit);
1412 +static DEVICE_ATTR(charge_current, S_IWUSR | S_IRUGO,
1413 +               bq2415x_sysfs_show_limit, bq2415x_sysfs_set_limit);
1414 +static DEVICE_ATTR(termination_current, S_IWUSR | S_IRUGO,
1415 +               bq2415x_sysfs_show_limit, bq2415x_sysfs_set_limit);
1416 +
1417 +static DEVICE_ATTR(charge_termination_enable, S_IWUSR | S_IRUGO,
1418 +               bq2415x_sysfs_show_enable, bq2415x_sysfs_set_enable);
1419 +static DEVICE_ATTR(high_impedance_enable, S_IWUSR | S_IRUGO,
1420 +               bq2415x_sysfs_show_enable, bq2415x_sysfs_set_enable);
1421 +static DEVICE_ATTR(otg_pin_enable, S_IWUSR | S_IRUGO,
1422 +               bq2415x_sysfs_show_enable, bq2415x_sysfs_set_enable);
1423 +static DEVICE_ATTR(stat_pin_enable, S_IWUSR | S_IRUGO,
1424 +               bq2415x_sysfs_show_enable, bq2415x_sysfs_set_enable);
1425 +
1426 +static DEVICE_ATTR(reported_mode, S_IRUGO,
1427 +               bq2415x_sysfs_show_reported_mode, NULL);
1428 +static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO,
1429 +               bq2415x_sysfs_show_mode, bq2415x_sysfs_set_mode);
1430 +static DEVICE_ATTR(timer, S_IWUSR | S_IRUGO,
1431 +               bq2415x_sysfs_show_timer, bq2415x_sysfs_set_timer);
1432 +
1433 +static DEVICE_ATTR(registers, S_IWUSR | S_IRUGO,
1434 +               bq2415x_sysfs_show_registers, bq2415x_sysfs_set_registers);
1435 +
1436 +static DEVICE_ATTR(otg_status, S_IRUGO, bq2415x_sysfs_show_status, NULL);
1437 +static DEVICE_ATTR(charge_status, S_IRUGO, bq2415x_sysfs_show_status, NULL);
1438 +static DEVICE_ATTR(boost_status, S_IRUGO, bq2415x_sysfs_show_status, NULL);
1439 +static DEVICE_ATTR(fault_status, S_IRUGO, bq2415x_sysfs_show_status, NULL);
1440 +
1441 +static struct attribute *bq2415x_sysfs_attributes[] = {
1442 +       &dev_attr_current_limit.attr,
1443 +       &dev_attr_weak_battery_voltage.attr,
1444 +       &dev_attr_battery_regulation_voltage.attr,
1445 +       &dev_attr_charge_current.attr,
1446 +       &dev_attr_termination_current.attr,
1447 +
1448 +       &dev_attr_charge_termination_enable.attr,
1449 +       &dev_attr_high_impedance_enable.attr,
1450 +       &dev_attr_otg_pin_enable.attr,
1451 +       &dev_attr_stat_pin_enable.attr,
1452 +
1453 +       &dev_attr_reported_mode.attr,
1454 +       &dev_attr_mode.attr,
1455 +       &dev_attr_timer.attr,
1456 +
1457 +       &dev_attr_registers.attr,
1458 +
1459 +       &dev_attr_otg_status.attr,
1460 +       &dev_attr_charge_status.attr,
1461 +       &dev_attr_boost_status.attr,
1462 +       &dev_attr_fault_status.attr,
1463 +       NULL,
1464 +};
1465 +
1466 +static const struct attribute_group bq2415x_sysfs_attr_group = {
1467 +       .attrs = bq2415x_sysfs_attributes,
1468 +};
1469 +
1470 +static int bq2415x_sysfs_init(struct bq2415x_device *bq)
1471 +{
1472 +       return sysfs_create_group(&bq->charger.dev->kobj,
1473 +                       &bq2415x_sysfs_attr_group);
1474 +}
1475 +
1476 +static void bq2415x_sysfs_exit(struct bq2415x_device *bq)
1477 +{
1478 +       sysfs_remove_group(&bq->charger.dev->kobj, &bq2415x_sysfs_attr_group);
1479 +}
1480 +
1481 +/* main bq2415x probe function */
1482 +static int bq2415x_probe(struct i2c_client *client,
1483 +               const struct i2c_device_id *id)
1484 +{
1485 +       int ret;
1486 +       int num;
1487 +       char *name;
1488 +       struct bq2415x_device *bq;
1489 +
1490 +       if (!client->dev.platform_data) {
1491 +               dev_err(&client->dev, "platform data not set\n");
1492 +               return -ENODEV;
1493 +       }
1494 +
1495 +       /* Get new ID for the new device */
1496 +       ret = idr_pre_get(&bq2415x_id, GFP_KERNEL);
1497 +       if (ret == 0)
1498 +               return -ENOMEM;
1499 +
1500 +       mutex_lock(&bq2415x_id_mutex);
1501 +       ret = idr_get_new(&bq2415x_id, client, &num);
1502 +       mutex_unlock(&bq2415x_id_mutex);
1503 +
1504 +       if (ret < 0)
1505 +               return ret;
1506 +
1507 +       name = kasprintf(GFP_KERNEL, "%s-%d", id->name, num);
1508 +       if (!name) {
1509 +               dev_err(&client->dev, "failed to allocate device name\n");
1510 +               ret = -ENOMEM;
1511 +               goto error_1;
1512 +       }
1513 +
1514 +       bq = kzalloc(sizeof(*bq), GFP_KERNEL);
1515 +       if (!bq) {
1516 +               dev_err(&client->dev, "failed to allocate device data\n");
1517 +               ret = -ENOMEM;
1518 +               goto error_2;
1519 +       }
1520 +
1521 +       i2c_set_clientdata(client, bq);
1522 +
1523 +       bq->id = num;
1524 +       bq->dev = &client->dev;
1525 +       bq->chip = id->driver_data;
1526 +       bq->name = name;
1527 +       bq->mode = BQ2415X_MODE_OFF;
1528 +       bq->reported_mode = BQ2415X_MODE_OFF;
1529 +       bq->autotimer = 0;
1530 +       bq->automode = 0;
1531 +
1532 +       memcpy(&bq->init_data, client->dev.platform_data,
1533 +                       sizeof(bq->init_data));
1534 +
1535 +       bq2415x_reset_chip(bq);
1536 +
1537 +       ret = bq2415x_power_supply_init(bq);
1538 +       if (ret) {
1539 +               dev_err(bq->dev, "failed to register power supply: %d\n", ret);
1540 +               goto error_3;
1541 +       }
1542 +
1543 +       ret = bq2415x_sysfs_init(bq);
1544 +       if (ret) {
1545 +               dev_err(bq->dev, "failed to create sysfs entries: %d\n", ret);
1546 +               goto error_4;
1547 +       }
1548 +
1549 +       ret = bq2415x_set_defaults(bq);
1550 +       if (ret) {
1551 +               dev_err(bq->dev, "failed to set default values: %d\n", ret);
1552 +               goto error_5;
1553 +       }
1554 +
1555 +       if (bq->init_data.set_mode_hook) {
1556 +               if (bq->init_data.set_mode_hook(
1557 +                               bq2415x_hook_function, bq)) {
1558 +                       bq->automode = 1;
1559 +                       bq2415x_set_mode(bq, bq->reported_mode);
1560 +                       dev_info(bq->dev, "automode enabled\n");
1561 +               } else {
1562 +                       bq->automode = -1;
1563 +                       dev_info(bq->dev, "automode failed\n");
1564 +               }
1565 +       } else {
1566 +               bq->automode = -1;
1567 +               dev_info(bq->dev, "automode not supported\n");
1568 +       }
1569 +
1570 +       INIT_DELAYED_WORK(&bq->work, bq2415x_timer_work);
1571 +       bq2415x_set_autotimer(bq, 1);
1572 +
1573 +       dev_info(bq->dev, "driver registered\n");
1574 +       return 0;
1575 +
1576 +error_5:
1577 +       bq2415x_sysfs_exit(bq);
1578 +error_4:
1579 +       bq2415x_power_supply_exit(bq);
1580 +error_3:
1581 +       kfree(bq);
1582 +error_2:
1583 +       kfree(name);
1584 +error_1:
1585 +       mutex_lock(&bq2415x_id_mutex);
1586 +       idr_remove(&bq2415x_id, num);
1587 +       mutex_unlock(&bq2415x_id_mutex);
1588 +
1589 +       return ret;
1590 +}
1591 +
1592 +/* main bq2415x remove function */
1593 +
1594 +static int bq2415x_remove(struct i2c_client *client)
1595 +{
1596 +       struct bq2415x_device *bq = i2c_get_clientdata(client);
1597 +
1598 +       if (bq->init_data.set_mode_hook)
1599 +               bq->init_data.set_mode_hook(NULL, NULL);
1600 +
1601 +       bq2415x_sysfs_exit(bq);
1602 +       bq2415x_power_supply_exit(bq);
1603 +
1604 +       bq2415x_reset_chip(bq);
1605 +
1606 +       mutex_lock(&bq2415x_id_mutex);
1607 +       idr_remove(&bq2415x_id, bq->id);
1608 +       mutex_unlock(&bq2415x_id_mutex);
1609 +
1610 +       dev_info(bq->dev, "driver unregistered\n");
1611 +
1612 +       kfree(bq->name);
1613 +       kfree(bq);
1614 +
1615 +       return 0;
1616 +}
1617 +
1618 +static const struct i2c_device_id bq2415x_i2c_id_table[] = {
1619 +       { "bq2415x", BQUNKNOWN },
1620 +       { "bq24150", BQ24150 },
1621 +       { "bq24150a", BQ24150A },
1622 +       { "bq24151", BQ24151 },
1623 +       { "bq24151a", BQ24151A },
1624 +       { "bq24152", BQ24152 },
1625 +       { "bq24153", BQ24153 },
1626 +       { "bq24153a", BQ24153A },
1627 +       { "bq24155", BQ24155 },
1628 +       { "bq24156", BQ24156 },
1629 +       { "bq24156a", BQ24156A },
1630 +       { "bq24158", BQ24158 },
1631 +       {},
1632 +};
1633 +MODULE_DEVICE_TABLE(i2c, bq2415x_i2c_id_table);
1634 +
1635 +static struct i2c_driver bq2415x_driver = {
1636 +       .driver = {
1637 +               .name = "bq2415x-charger",
1638 +       },
1639 +       .probe = bq2415x_probe,
1640 +       .remove = bq2415x_remove,
1641 +       .id_table = bq2415x_i2c_id_table,
1642 +};
1643 +
1644 +static int __init bq2415x_init(void)
1645 +{
1646 +       return i2c_add_driver(&bq2415x_driver);
1647 +}
1648 +module_init(bq2415x_init);
1649 +
1650 +static void __exit bq2415x_exit(void)
1651 +{
1652 +       i2c_del_driver(&bq2415x_driver);
1653 +}
1654 +module_exit(bq2415x_exit);
1655 +
1656 +MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>");
1657 +MODULE_DESCRIPTION("bq2415x charger driver");
1658 +MODULE_LICENSE("GPL");
1659 --- /dev/null
1660 +++ kernel-power/include/linux/power/bq2415x_charger.h
1661 @@ -0,0 +1,91 @@
1662 +/*
1663 +    bq2415x_charger.h - bq2415x charger driver
1664 +    Copyright (C) 2011-2012  Pali Rohár <pali.rohar@gmail.com>
1665 +
1666 +    This program is free software; you can redistribute it and/or modify
1667 +    it under the terms of the GNU General Public License as published by
1668 +    the Free Software Foundation; either version 2 of the License, or
1669 +    (at your option) any later version.
1670 +
1671 +    This program is distributed in the hope that it will be useful,
1672 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
1673 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1674 +    GNU General Public License for more details.
1675 +
1676 +    You should have received a copy of the GNU General Public License along
1677 +    with this program; if not, write to the Free Software Foundation, Inc.,
1678 +    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1679 +*/
1680 +
1681 +#ifndef BQ2415X_CHARGER_H
1682 +#define BQ2415X_CHARGER_H
1683 +
1684 +/*
1685 +  This is platform data for bq2415x chip. It contains default board voltages
1686 +  and currents which can be also later configured via sysfs. If value is -1
1687 +  then default chip value (specified in datasheet) will be used.
1688 +
1689 +  Value resistor_sense is needed for for configuring charge and termination
1690 +  current. It it is less or equal to zero, configuring charge and termination
1691 +  current will not be possible.
1692 +
1693 +  Function set_mode_hook is needed for automode (setting correct current limit
1694 +  when charger is connected/disconnected or setting boost mode). When is NULL,
1695 +  automode function is disabled. When is not NULL, it must have this prototype:
1696 +
1697 +    int (*set_mode_hook)(
1698 +      void (*hook)(enum bq2415x_mode mode, void *data),
1699 +      void *data)
1700 +
1701 +  hook is hook function (see below) and data is pointer to driver private data
1702 +
1703 +  bq2415x driver will call it as:
1704 +
1705 +    platform_data->set_mode_hook(bq2415x_hook_function, bq2415x_device);
1706 +
1707 +  Board/platform function set_mode_hook return non zero value when hook
1708 +  function was successful registered. Platform code should call that hook
1709 +  function (which get from pointer, with data) every time when charger was
1710 +  connected/disconnected or require to enable boost mode. bq2415x driver then
1711 +  will set correct current limit, enable/disable charger or boost mode.
1712 +
1713 +  Hook function has this prototype:
1714 +
1715 +    void hook(enum bq2415x_mode mode, void *data);
1716 +
1717 +  mode is bq2415x mode (charger or boost)
1718 +  data is pointer to driver private data (which get from set_charger_type_hook)
1719 +
1720 +  When bq driver is being unloaded, it call function:
1721 +
1722 +    platform_data->set_mode_hook(NULL, NULL);
1723 +
1724 +  (hook function and driver private data are NULL)
1725 +
1726 +  After that board/platform code must not call driver hook function! It is
1727 +  possible that pointer to hook function will not be valid and calling will
1728 +  cause undefined result.
1729 +
1730 +*/
1731 +
1732 +/* Supported modes with maximal current limit */
1733 +enum bq2415x_mode {
1734 +       BQ2415X_MODE_OFF,               /* offline mode (charger disabled) */
1735 +       BQ2415X_MODE_NONE,              /* unknown charger (100mA) */
1736 +       BQ2415X_MODE_HOST_CHARGER,      /* usb host/hub charger (500mA) */
1737 +       BQ2415X_MODE_DEDICATED_CHARGER, /* dedicated charger (unlimited) */
1738 +       BQ2415X_MODE_BOOST,             /* boost mode (charging disabled) */
1739 +};
1740 +
1741 +struct bq2415x_platform_data {
1742 +       int current_limit;              /* mA */
1743 +       int weak_battery_voltage;       /* mV */
1744 +       int battery_regulation_voltage; /* mV */
1745 +       int charge_current;             /* mA */
1746 +       int termination_current;        /* mA */
1747 +       int resistor_sense;             /* m ohm */
1748 +       int (*set_mode_hook)(void (*hook)(enum bq2415x_mode mode, void *data),
1749 +                            void *data);
1750 +};
1751 +
1752 +#endif