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