blob: 055539934e4ea247b56bec7b70c28fa04d37ff57 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14/*
15 * this needs to be before <linux/kernel.h> is loaded,
16 * and <linux/sched.h> loads <linux/kernel.h>
17 */
Taniya Dasd06ac742011-07-19 12:55:28 +053018#define DEBUG 0
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070019
20#include <linux/slab.h>
21#include <linux/earlysuspend.h>
22#include <linux/err.h>
23#include <linux/module.h>
24#include <linux/platform_device.h>
25#include <linux/power_supply.h>
26#include <linux/sched.h>
27#include <linux/signal.h>
28#include <linux/uaccess.h>
29#include <linux/wait.h>
30#include <linux/workqueue.h>
31
32#include <asm/atomic.h>
33
34#include <mach/msm_rpcrouter.h>
35#include <mach/msm_battery.h>
36
37#define BATTERY_RPC_PROG 0x30000089
38#define BATTERY_RPC_VER_1_1 0x00010001
39#define BATTERY_RPC_VER_2_1 0x00020001
40#define BATTERY_RPC_VER_4_1 0x00040001
41#define BATTERY_RPC_VER_5_1 0x00050001
42
43#define BATTERY_RPC_CB_PROG (BATTERY_RPC_PROG | 0x01000000)
44
45#define CHG_RPC_PROG 0x3000001a
46#define CHG_RPC_VER_1_1 0x00010001
47#define CHG_RPC_VER_1_3 0x00010003
48#define CHG_RPC_VER_2_2 0x00020002
49#define CHG_RPC_VER_3_1 0x00030001
50#define CHG_RPC_VER_4_1 0x00040001
51
52#define BATTERY_REGISTER_PROC 2
53#define BATTERY_MODIFY_CLIENT_PROC 4
54#define BATTERY_DEREGISTER_CLIENT_PROC 5
55#define BATTERY_READ_MV_PROC 12
56#define BATTERY_ENABLE_DISABLE_FILTER_PROC 14
57
58#define VBATT_FILTER 2
59
60#define BATTERY_CB_TYPE_PROC 1
61#define BATTERY_CB_ID_ALL_ACTIV 1
62#define BATTERY_CB_ID_LOW_VOL 2
63
64#define BATTERY_LOW 3200
65#define BATTERY_HIGH 4300
66
67#define ONCRPC_CHG_GET_GENERAL_STATUS_PROC 12
68#define ONCRPC_CHARGER_API_VERSIONS_PROC 0xffffffff
69
70#define BATT_RPC_TIMEOUT 5000 /* 5 sec */
71
72#define INVALID_BATT_HANDLE -1
73
74#define RPC_TYPE_REQ 0
75#define RPC_TYPE_REPLY 1
76#define RPC_REQ_REPLY_COMMON_HEADER_SIZE (3 * sizeof(uint32_t))
77
78
79#if DEBUG
80#define DBG_LIMIT(x...) do {if (printk_ratelimit()) pr_debug(x); } while (0)
81#else
82#define DBG_LIMIT(x...) do {} while (0)
83#endif
84
85enum {
86 BATTERY_REGISTRATION_SUCCESSFUL = 0,
87 BATTERY_DEREGISTRATION_SUCCESSFUL = BATTERY_REGISTRATION_SUCCESSFUL,
88 BATTERY_MODIFICATION_SUCCESSFUL = BATTERY_REGISTRATION_SUCCESSFUL,
89 BATTERY_INTERROGATION_SUCCESSFUL = BATTERY_REGISTRATION_SUCCESSFUL,
90 BATTERY_CLIENT_TABLE_FULL = 1,
91 BATTERY_REG_PARAMS_WRONG = 2,
92 BATTERY_DEREGISTRATION_FAILED = 4,
93 BATTERY_MODIFICATION_FAILED = 8,
94 BATTERY_INTERROGATION_FAILED = 16,
95 /* Client's filter could not be set because perhaps it does not exist */
96 BATTERY_SET_FILTER_FAILED = 32,
97 /* Client's could not be found for enabling or disabling the individual
98 * client */
99 BATTERY_ENABLE_DISABLE_INDIVIDUAL_CLIENT_FAILED = 64,
100 BATTERY_LAST_ERROR = 128,
101};
102
103enum {
104 BATTERY_VOLTAGE_UP = 0,
105 BATTERY_VOLTAGE_DOWN,
106 BATTERY_VOLTAGE_ABOVE_THIS_LEVEL,
107 BATTERY_VOLTAGE_BELOW_THIS_LEVEL,
108 BATTERY_VOLTAGE_LEVEL,
109 BATTERY_ALL_ACTIVITY,
110 VBATT_CHG_EVENTS,
111 BATTERY_VOLTAGE_UNKNOWN,
112};
113
114/*
115 * This enum contains defintions of the charger hardware status
116 */
117enum chg_charger_status_type {
118 /* The charger is good */
119 CHARGER_STATUS_GOOD,
120 /* The charger is bad */
121 CHARGER_STATUS_BAD,
122 /* The charger is weak */
123 CHARGER_STATUS_WEAK,
124 /* Invalid charger status. */
125 CHARGER_STATUS_INVALID
126};
127
128/*
129 *This enum contains defintions of the charger hardware type
130 */
131enum chg_charger_hardware_type {
132 /* The charger is removed */
133 CHARGER_TYPE_NONE,
134 /* The charger is a regular wall charger */
135 CHARGER_TYPE_WALL,
136 /* The charger is a PC USB */
137 CHARGER_TYPE_USB_PC,
138 /* The charger is a wall USB charger */
139 CHARGER_TYPE_USB_WALL,
140 /* The charger is a USB carkit */
141 CHARGER_TYPE_USB_CARKIT,
142 /* Invalid charger hardware status. */
143 CHARGER_TYPE_INVALID
144};
145
146/*
147 * This enum contains defintions of the battery status
148 */
149enum chg_battery_status_type {
150 /* The battery is good */
151 BATTERY_STATUS_GOOD,
152 /* The battery is cold/hot */
153 BATTERY_STATUS_BAD_TEMP,
154 /* The battery is bad */
155 BATTERY_STATUS_BAD,
156 /* The battery is removed */
157 BATTERY_STATUS_REMOVED, /* on v2.2 only */
158 BATTERY_STATUS_INVALID_v1 = BATTERY_STATUS_REMOVED,
159 /* Invalid battery status. */
160 BATTERY_STATUS_INVALID
161};
162
163/*
164 *This enum contains defintions of the battery voltage level
165 */
166enum chg_battery_level_type {
167 /* The battery voltage is dead/very low (less than 3.2V) */
168 BATTERY_LEVEL_DEAD,
169 /* The battery voltage is weak/low (between 3.2V and 3.4V) */
170 BATTERY_LEVEL_WEAK,
171 /* The battery voltage is good/normal(between 3.4V and 4.2V) */
172 BATTERY_LEVEL_GOOD,
173 /* The battery voltage is up to full (close to 4.2V) */
174 BATTERY_LEVEL_FULL,
175 /* Invalid battery voltage level. */
176 BATTERY_LEVEL_INVALID
177};
178
179#ifndef CONFIG_BATTERY_MSM_FAKE
180struct rpc_reply_batt_chg_v1 {
181 struct rpc_reply_hdr hdr;
182 u32 more_data;
183
184 u32 charger_status;
185 u32 charger_type;
186 u32 battery_status;
187 u32 battery_level;
188 u32 battery_voltage;
189 u32 battery_temp;
190};
191
192struct rpc_reply_batt_chg_v2 {
193 struct rpc_reply_batt_chg_v1 v1;
194
195 u32 is_charger_valid;
196 u32 is_charging;
197 u32 is_battery_valid;
198 u32 ui_event;
199};
200
201union rpc_reply_batt_chg {
202 struct rpc_reply_batt_chg_v1 v1;
203 struct rpc_reply_batt_chg_v2 v2;
204};
205
206static union rpc_reply_batt_chg rep_batt_chg;
207#endif
208
209struct msm_battery_info {
210 u32 voltage_max_design;
211 u32 voltage_min_design;
212 u32 chg_api_version;
213 u32 batt_technology;
214 u32 batt_api_version;
215
216 u32 avail_chg_sources;
217 u32 current_chg_source;
218
219 u32 batt_status;
220 u32 batt_health;
221 u32 charger_valid;
222 u32 batt_valid;
223 u32 batt_capacity; /* in percentage */
224
225 u32 charger_status;
226 u32 charger_type;
227 u32 battery_status;
228 u32 battery_level;
229 u32 battery_voltage; /* in millie volts */
230 u32 battery_temp; /* in celsius */
231
232 u32(*calculate_capacity) (u32 voltage);
233
234 s32 batt_handle;
235
236 struct power_supply *msm_psy_ac;
237 struct power_supply *msm_psy_usb;
238 struct power_supply *msm_psy_batt;
239 struct power_supply *current_ps;
240
241 struct msm_rpc_client *batt_client;
242 struct msm_rpc_endpoint *chg_ep;
243
244 wait_queue_head_t wait_q;
245
246 u32 vbatt_modify_reply_avail;
247
248 struct early_suspend early_suspend;
249};
250
251static struct msm_battery_info msm_batt_info = {
252 .batt_handle = INVALID_BATT_HANDLE,
253 .charger_status = CHARGER_STATUS_BAD,
254 .charger_type = CHARGER_TYPE_INVALID,
255 .battery_status = BATTERY_STATUS_GOOD,
256 .battery_level = BATTERY_LEVEL_FULL,
257 .battery_voltage = BATTERY_HIGH,
258 .batt_capacity = 100,
259 .batt_status = POWER_SUPPLY_STATUS_DISCHARGING,
260 .batt_health = POWER_SUPPLY_HEALTH_GOOD,
261 .batt_valid = 1,
262 .battery_temp = 23,
263 .vbatt_modify_reply_avail = 0,
264};
265
266static enum power_supply_property msm_power_props[] = {
267 POWER_SUPPLY_PROP_ONLINE,
268};
269
270static char *msm_power_supplied_to[] = {
271 "battery",
272};
273
274static int msm_power_get_property(struct power_supply *psy,
275 enum power_supply_property psp,
276 union power_supply_propval *val)
277{
278 switch (psp) {
279 case POWER_SUPPLY_PROP_ONLINE:
280 if (psy->type == POWER_SUPPLY_TYPE_MAINS) {
281 val->intval = msm_batt_info.current_chg_source & AC_CHG
282 ? 1 : 0;
283 }
284 if (psy->type == POWER_SUPPLY_TYPE_USB) {
285 val->intval = msm_batt_info.current_chg_source & USB_CHG
286 ? 1 : 0;
287 }
288 break;
289 default:
290 return -EINVAL;
291 }
292 return 0;
293}
294
295static struct power_supply msm_psy_ac = {
296 .name = "ac",
297 .type = POWER_SUPPLY_TYPE_MAINS,
298 .supplied_to = msm_power_supplied_to,
299 .num_supplicants = ARRAY_SIZE(msm_power_supplied_to),
300 .properties = msm_power_props,
301 .num_properties = ARRAY_SIZE(msm_power_props),
302 .get_property = msm_power_get_property,
303};
304
305static struct power_supply msm_psy_usb = {
306 .name = "usb",
307 .type = POWER_SUPPLY_TYPE_USB,
308 .supplied_to = msm_power_supplied_to,
309 .num_supplicants = ARRAY_SIZE(msm_power_supplied_to),
310 .properties = msm_power_props,
311 .num_properties = ARRAY_SIZE(msm_power_props),
312 .get_property = msm_power_get_property,
313};
314
315static enum power_supply_property msm_batt_power_props[] = {
316 POWER_SUPPLY_PROP_STATUS,
317 POWER_SUPPLY_PROP_HEALTH,
318 POWER_SUPPLY_PROP_PRESENT,
319 POWER_SUPPLY_PROP_TECHNOLOGY,
320 POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
321 POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
322 POWER_SUPPLY_PROP_VOLTAGE_NOW,
323 POWER_SUPPLY_PROP_CAPACITY,
324};
325
326static int msm_batt_power_get_property(struct power_supply *psy,
327 enum power_supply_property psp,
328 union power_supply_propval *val)
329{
330 switch (psp) {
331 case POWER_SUPPLY_PROP_STATUS:
332 val->intval = msm_batt_info.batt_status;
333 break;
334 case POWER_SUPPLY_PROP_HEALTH:
335 val->intval = msm_batt_info.batt_health;
336 break;
337 case POWER_SUPPLY_PROP_PRESENT:
338 val->intval = msm_batt_info.batt_valid;
339 break;
340 case POWER_SUPPLY_PROP_TECHNOLOGY:
341 val->intval = msm_batt_info.batt_technology;
342 break;
343 case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
344 val->intval = msm_batt_info.voltage_max_design;
345 break;
346 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
347 val->intval = msm_batt_info.voltage_min_design;
348 break;
349 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
350 val->intval = msm_batt_info.battery_voltage;
351 break;
352 case POWER_SUPPLY_PROP_CAPACITY:
353 val->intval = msm_batt_info.batt_capacity;
354 break;
355 default:
356 return -EINVAL;
357 }
358 return 0;
359}
360
361static struct power_supply msm_psy_batt = {
362 .name = "battery",
363 .type = POWER_SUPPLY_TYPE_BATTERY,
364 .properties = msm_batt_power_props,
365 .num_properties = ARRAY_SIZE(msm_batt_power_props),
366 .get_property = msm_batt_power_get_property,
367};
368
369#ifndef CONFIG_BATTERY_MSM_FAKE
370struct msm_batt_get_volt_ret_data {
371 u32 battery_voltage;
372};
373
374static int msm_batt_get_volt_ret_func(struct msm_rpc_client *batt_client,
375 void *buf, void *data)
376{
377 struct msm_batt_get_volt_ret_data *data_ptr, *buf_ptr;
378
379 data_ptr = (struct msm_batt_get_volt_ret_data *)data;
380 buf_ptr = (struct msm_batt_get_volt_ret_data *)buf;
381
382 data_ptr->battery_voltage = be32_to_cpu(buf_ptr->battery_voltage);
383
384 return 0;
385}
386
387static u32 msm_batt_get_vbatt_voltage(void)
388{
389 int rc;
390
391 struct msm_batt_get_volt_ret_data rep;
392
393 rc = msm_rpc_client_req(msm_batt_info.batt_client,
394 BATTERY_READ_MV_PROC,
395 NULL, NULL,
396 msm_batt_get_volt_ret_func, &rep,
397 msecs_to_jiffies(BATT_RPC_TIMEOUT));
398
399 if (rc < 0) {
400 pr_err("%s: FAIL: vbatt get volt. rc=%d\n", __func__, rc);
401 return 0;
402 }
403
404 return rep.battery_voltage;
405}
406
407#define be32_to_cpu_self(v) (v = be32_to_cpu(v))
408
409static int msm_batt_get_batt_chg_status(void)
410{
411 int rc;
412
413 struct rpc_req_batt_chg {
414 struct rpc_request_hdr hdr;
415 u32 more_data;
416 } req_batt_chg;
417 struct rpc_reply_batt_chg_v1 *v1p;
418
419 req_batt_chg.more_data = cpu_to_be32(1);
420
421 memset(&rep_batt_chg, 0, sizeof(rep_batt_chg));
422
423 v1p = &rep_batt_chg.v1;
424 rc = msm_rpc_call_reply(msm_batt_info.chg_ep,
425 ONCRPC_CHG_GET_GENERAL_STATUS_PROC,
426 &req_batt_chg, sizeof(req_batt_chg),
427 &rep_batt_chg, sizeof(rep_batt_chg),
428 msecs_to_jiffies(BATT_RPC_TIMEOUT));
429 if (rc < 0) {
430 pr_err("%s: ERROR. msm_rpc_call_reply failed! proc=%d rc=%d\n",
431 __func__, ONCRPC_CHG_GET_GENERAL_STATUS_PROC, rc);
432 return rc;
433 } else if (be32_to_cpu(v1p->more_data)) {
434 be32_to_cpu_self(v1p->charger_status);
435 be32_to_cpu_self(v1p->charger_type);
436 be32_to_cpu_self(v1p->battery_status);
437 be32_to_cpu_self(v1p->battery_level);
438 be32_to_cpu_self(v1p->battery_voltage);
439 be32_to_cpu_self(v1p->battery_temp);
440 } else {
441 pr_err("%s: No battery/charger data in RPC reply\n", __func__);
442 return -EIO;
443 }
444
445 return 0;
446}
447
448static void msm_batt_update_psy_status(void)
449{
450 static u32 unnecessary_event_count;
451 u32 charger_status;
452 u32 charger_type;
453 u32 battery_status;
454 u32 battery_level;
455 u32 battery_voltage;
456 u32 battery_temp;
457 struct power_supply *supp;
458
459 if (msm_batt_get_batt_chg_status())
460 return;
461
462 charger_status = rep_batt_chg.v1.charger_status;
463 charger_type = rep_batt_chg.v1.charger_type;
464 battery_status = rep_batt_chg.v1.battery_status;
465 battery_level = rep_batt_chg.v1.battery_level;
466 battery_voltage = rep_batt_chg.v1.battery_voltage;
467 battery_temp = rep_batt_chg.v1.battery_temp;
468
469 /* Make correction for battery status */
470 if (battery_status == BATTERY_STATUS_INVALID_v1) {
471 if (msm_batt_info.chg_api_version < CHG_RPC_VER_3_1)
472 battery_status = BATTERY_STATUS_INVALID;
473 }
474
475 if (charger_status == msm_batt_info.charger_status &&
476 charger_type == msm_batt_info.charger_type &&
477 battery_status == msm_batt_info.battery_status &&
478 battery_level == msm_batt_info.battery_level &&
479 battery_voltage == msm_batt_info.battery_voltage &&
480 battery_temp == msm_batt_info.battery_temp) {
481 /* Got unnecessary event from Modem PMIC VBATT driver.
482 * Nothing changed in Battery or charger status.
483 */
484 unnecessary_event_count++;
485 if ((unnecessary_event_count % 20) == 1)
486 DBG_LIMIT("BATT: same event count = %u\n",
487 unnecessary_event_count);
488 return;
489 }
490
491 unnecessary_event_count = 0;
492
493 DBG_LIMIT("BATT: rcvd: %d, %d, %d, %d; %d, %d\n",
494 charger_status, charger_type, battery_status,
495 battery_level, battery_voltage, battery_temp);
496
497 if (battery_status == BATTERY_STATUS_INVALID &&
498 battery_level != BATTERY_LEVEL_INVALID) {
499 DBG_LIMIT("BATT: change status(%d) to (%d) for level=%d\n",
500 battery_status, BATTERY_STATUS_GOOD, battery_level);
501 battery_status = BATTERY_STATUS_GOOD;
502 }
503
504 if (msm_batt_info.charger_type != charger_type) {
505 if (charger_type == CHARGER_TYPE_USB_WALL ||
506 charger_type == CHARGER_TYPE_USB_PC ||
507 charger_type == CHARGER_TYPE_USB_CARKIT) {
508 DBG_LIMIT("BATT: USB charger plugged in\n");
509 msm_batt_info.current_chg_source = USB_CHG;
510 supp = &msm_psy_usb;
511 } else if (charger_type == CHARGER_TYPE_WALL) {
512 DBG_LIMIT("BATT: AC Wall changer plugged in\n");
513 msm_batt_info.current_chg_source = AC_CHG;
514 supp = &msm_psy_ac;
515 } else {
516 if (msm_batt_info.current_chg_source & AC_CHG)
517 DBG_LIMIT("BATT: AC Wall charger removed\n");
518 else if (msm_batt_info.current_chg_source & USB_CHG)
519 DBG_LIMIT("BATT: USB charger removed\n");
520 else
521 DBG_LIMIT("BATT: No charger present\n");
522 msm_batt_info.current_chg_source = 0;
523 supp = &msm_psy_batt;
524
525 /* Correct charger status */
526 if (charger_status != CHARGER_STATUS_INVALID) {
527 DBG_LIMIT("BATT: No charging!\n");
528 charger_status = CHARGER_STATUS_INVALID;
529 msm_batt_info.batt_status =
530 POWER_SUPPLY_STATUS_NOT_CHARGING;
531 }
532 }
533 } else
534 supp = NULL;
535
536 if (msm_batt_info.charger_status != charger_status) {
537 if (charger_status == CHARGER_STATUS_GOOD ||
538 charger_status == CHARGER_STATUS_WEAK) {
539 if (msm_batt_info.current_chg_source) {
540 DBG_LIMIT("BATT: Charging.\n");
541 msm_batt_info.batt_status =
542 POWER_SUPPLY_STATUS_CHARGING;
543
544 /* Correct when supp==NULL */
545 if (msm_batt_info.current_chg_source & AC_CHG)
546 supp = &msm_psy_ac;
547 else
548 supp = &msm_psy_usb;
549 }
550 } else {
551 DBG_LIMIT("BATT: No charging.\n");
552 msm_batt_info.batt_status =
553 POWER_SUPPLY_STATUS_NOT_CHARGING;
554 supp = &msm_psy_batt;
555 }
556 } else {
557 /* Correct charger status */
558 if (charger_type != CHARGER_TYPE_INVALID &&
559 charger_status == CHARGER_STATUS_GOOD) {
560 DBG_LIMIT("BATT: In charging\n");
561 msm_batt_info.batt_status =
562 POWER_SUPPLY_STATUS_CHARGING;
563 }
564 }
565
566 /* Correct battery voltage and status */
567 if (!battery_voltage) {
568 if (charger_status == CHARGER_STATUS_INVALID) {
569 DBG_LIMIT("BATT: Read VBATT\n");
570 battery_voltage = msm_batt_get_vbatt_voltage();
571 } else
572 /* Use previous */
573 battery_voltage = msm_batt_info.battery_voltage;
574 }
575 if (battery_status == BATTERY_STATUS_INVALID) {
576 if (battery_voltage >= msm_batt_info.voltage_min_design &&
577 battery_voltage <= msm_batt_info.voltage_max_design) {
578 DBG_LIMIT("BATT: Battery valid\n");
579 msm_batt_info.batt_valid = 1;
580 battery_status = BATTERY_STATUS_GOOD;
581 }
582 }
583
584 if (msm_batt_info.battery_status != battery_status) {
585 if (battery_status != BATTERY_STATUS_INVALID) {
586 msm_batt_info.batt_valid = 1;
587
588 if (battery_status == BATTERY_STATUS_BAD) {
589 DBG_LIMIT("BATT: Battery bad.\n");
590 msm_batt_info.batt_health =
591 POWER_SUPPLY_HEALTH_DEAD;
592 } else if (battery_status == BATTERY_STATUS_BAD_TEMP) {
593 DBG_LIMIT("BATT: Battery overheat.\n");
594 msm_batt_info.batt_health =
595 POWER_SUPPLY_HEALTH_OVERHEAT;
596 } else {
597 DBG_LIMIT("BATT: Battery good.\n");
598 msm_batt_info.batt_health =
599 POWER_SUPPLY_HEALTH_GOOD;
600 }
601 } else {
602 msm_batt_info.batt_valid = 0;
603 DBG_LIMIT("BATT: Battery invalid.\n");
604 msm_batt_info.batt_health = POWER_SUPPLY_HEALTH_UNKNOWN;
605 }
606
607 if (msm_batt_info.batt_status != POWER_SUPPLY_STATUS_CHARGING) {
608 if (battery_status == BATTERY_STATUS_INVALID) {
609 DBG_LIMIT("BATT: Battery -> unknown\n");
610 msm_batt_info.batt_status =
611 POWER_SUPPLY_STATUS_UNKNOWN;
612 } else {
613 DBG_LIMIT("BATT: Battery -> discharging\n");
614 msm_batt_info.batt_status =
615 POWER_SUPPLY_STATUS_DISCHARGING;
616 }
617 }
618
619 if (!supp) {
620 if (msm_batt_info.current_chg_source) {
621 if (msm_batt_info.current_chg_source & AC_CHG)
622 supp = &msm_psy_ac;
623 else
624 supp = &msm_psy_usb;
625 } else
626 supp = &msm_psy_batt;
627 }
628 }
629
630 msm_batt_info.charger_status = charger_status;
631 msm_batt_info.charger_type = charger_type;
632 msm_batt_info.battery_status = battery_status;
633 msm_batt_info.battery_level = battery_level;
634 msm_batt_info.battery_temp = battery_temp;
635
636 if (msm_batt_info.battery_voltage != battery_voltage) {
637 msm_batt_info.battery_voltage = battery_voltage;
638 msm_batt_info.batt_capacity =
639 msm_batt_info.calculate_capacity(battery_voltage);
640 DBG_LIMIT("BATT: voltage = %u mV [capacity = %d%%]\n",
641 battery_voltage, msm_batt_info.batt_capacity);
642
643 if (!supp)
644 supp = msm_batt_info.current_ps;
645 }
646
647 if (supp) {
648 msm_batt_info.current_ps = supp;
649 DBG_LIMIT("BATT: Supply = %s\n", supp->name);
650 power_supply_changed(supp);
651 }
652}
653
654#ifdef CONFIG_HAS_EARLYSUSPEND
655struct batt_modify_client_req {
656
657 u32 client_handle;
658
659 /* The voltage at which callback (CB) should be called. */
660 u32 desired_batt_voltage;
661
662 /* The direction when the CB should be called. */
663 u32 voltage_direction;
664
665 /* The registered callback to be called when voltage and
666 * direction specs are met. */
667 u32 batt_cb_id;
668
669 /* The call back data */
670 u32 cb_data;
671};
672
673struct batt_modify_client_rep {
674 u32 result;
675};
676
677static int msm_batt_modify_client_arg_func(struct msm_rpc_client *batt_client,
678 void *buf, void *data)
679{
680 struct batt_modify_client_req *batt_modify_client_req =
681 (struct batt_modify_client_req *)data;
682 u32 *req = (u32 *)buf;
683 int size = 0;
684
685 *req = cpu_to_be32(batt_modify_client_req->client_handle);
686 size += sizeof(u32);
687 req++;
688
689 *req = cpu_to_be32(batt_modify_client_req->desired_batt_voltage);
690 size += sizeof(u32);
691 req++;
692
693 *req = cpu_to_be32(batt_modify_client_req->voltage_direction);
694 size += sizeof(u32);
695 req++;
696
697 *req = cpu_to_be32(batt_modify_client_req->batt_cb_id);
698 size += sizeof(u32);
699 req++;
700
701 *req = cpu_to_be32(batt_modify_client_req->cb_data);
702 size += sizeof(u32);
703
704 return size;
705}
706
707static int msm_batt_modify_client_ret_func(struct msm_rpc_client *batt_client,
708 void *buf, void *data)
709{
710 struct batt_modify_client_rep *data_ptr, *buf_ptr;
711
712 data_ptr = (struct batt_modify_client_rep *)data;
713 buf_ptr = (struct batt_modify_client_rep *)buf;
714
715 data_ptr->result = be32_to_cpu(buf_ptr->result);
716
717 return 0;
718}
719
720static int msm_batt_modify_client(u32 client_handle, u32 desired_batt_voltage,
721 u32 voltage_direction, u32 batt_cb_id, u32 cb_data)
722{
723 int rc;
724
725 struct batt_modify_client_req req;
726 struct batt_modify_client_rep rep;
727
728 req.client_handle = client_handle;
729 req.desired_batt_voltage = desired_batt_voltage;
730 req.voltage_direction = voltage_direction;
731 req.batt_cb_id = batt_cb_id;
732 req.cb_data = cb_data;
733
734 rc = msm_rpc_client_req(msm_batt_info.batt_client,
735 BATTERY_MODIFY_CLIENT_PROC,
736 msm_batt_modify_client_arg_func, &req,
737 msm_batt_modify_client_ret_func, &rep,
738 msecs_to_jiffies(BATT_RPC_TIMEOUT));
739
740 if (rc < 0) {
741 pr_err("%s: ERROR. failed to modify Vbatt client\n",
742 __func__);
743 return rc;
744 }
745
746 if (rep.result != BATTERY_MODIFICATION_SUCCESSFUL) {
747 pr_err("%s: ERROR. modify client failed. result = %u\n",
748 __func__, rep.result);
749 return -EIO;
750 }
751
752 return 0;
753}
754
755void msm_batt_early_suspend(struct early_suspend *h)
756{
757 int rc;
758
759 pr_debug("%s: enter\n", __func__);
760
761 if (msm_batt_info.batt_handle != INVALID_BATT_HANDLE) {
762 rc = msm_batt_modify_client(msm_batt_info.batt_handle,
763 BATTERY_LOW, BATTERY_VOLTAGE_BELOW_THIS_LEVEL,
764 BATTERY_CB_ID_LOW_VOL, BATTERY_LOW);
765
766 if (rc < 0) {
767 pr_err("%s: msm_batt_modify_client. rc=%d\n",
768 __func__, rc);
769 return;
770 }
771 } else {
772 pr_err("%s: ERROR. invalid batt_handle\n", __func__);
773 return;
774 }
775
776 pr_debug("%s: exit\n", __func__);
777}
778
779void msm_batt_late_resume(struct early_suspend *h)
780{
781 int rc;
782
783 pr_debug("%s: enter\n", __func__);
784
785 if (msm_batt_info.batt_handle != INVALID_BATT_HANDLE) {
786 rc = msm_batt_modify_client(msm_batt_info.batt_handle,
787 BATTERY_LOW, BATTERY_ALL_ACTIVITY,
788 BATTERY_CB_ID_ALL_ACTIV, BATTERY_ALL_ACTIVITY);
789 if (rc < 0) {
790 pr_err("%s: msm_batt_modify_client FAIL rc=%d\n",
791 __func__, rc);
792 return;
793 }
794 } else {
795 pr_err("%s: ERROR. invalid batt_handle\n", __func__);
796 return;
797 }
798
799 msm_batt_update_psy_status();
800 pr_debug("%s: exit\n", __func__);
801}
802#endif
803
804struct msm_batt_vbatt_filter_req {
805 u32 batt_handle;
806 u32 enable_filter;
807 u32 vbatt_filter;
808};
809
810struct msm_batt_vbatt_filter_rep {
811 u32 result;
812};
813
814static int msm_batt_filter_arg_func(struct msm_rpc_client *batt_client,
815
816 void *buf, void *data)
817{
818 struct msm_batt_vbatt_filter_req *vbatt_filter_req =
819 (struct msm_batt_vbatt_filter_req *)data;
820 u32 *req = (u32 *)buf;
821 int size = 0;
822
823 *req = cpu_to_be32(vbatt_filter_req->batt_handle);
824 size += sizeof(u32);
825 req++;
826
827 *req = cpu_to_be32(vbatt_filter_req->enable_filter);
828 size += sizeof(u32);
829 req++;
830
831 *req = cpu_to_be32(vbatt_filter_req->vbatt_filter);
832 size += sizeof(u32);
833 return size;
834}
835
836static int msm_batt_filter_ret_func(struct msm_rpc_client *batt_client,
837 void *buf, void *data)
838{
839
840 struct msm_batt_vbatt_filter_rep *data_ptr, *buf_ptr;
841
842 data_ptr = (struct msm_batt_vbatt_filter_rep *)data;
843 buf_ptr = (struct msm_batt_vbatt_filter_rep *)buf;
844
845 data_ptr->result = be32_to_cpu(buf_ptr->result);
846 return 0;
847}
848
849static int msm_batt_enable_filter(u32 vbatt_filter)
850{
851 int rc;
852 struct msm_batt_vbatt_filter_req vbatt_filter_req;
853 struct msm_batt_vbatt_filter_rep vbatt_filter_rep;
854
855 vbatt_filter_req.batt_handle = msm_batt_info.batt_handle;
856 vbatt_filter_req.enable_filter = 1;
857 vbatt_filter_req.vbatt_filter = vbatt_filter;
858
859 rc = msm_rpc_client_req(msm_batt_info.batt_client,
860 BATTERY_ENABLE_DISABLE_FILTER_PROC,
861 msm_batt_filter_arg_func, &vbatt_filter_req,
862 msm_batt_filter_ret_func, &vbatt_filter_rep,
863 msecs_to_jiffies(BATT_RPC_TIMEOUT));
864
865 if (rc < 0) {
866 pr_err("%s: FAIL: enable vbatt filter. rc=%d\n",
867 __func__, rc);
868 return rc;
869 }
870
871 if (vbatt_filter_rep.result != BATTERY_DEREGISTRATION_SUCCESSFUL) {
872 pr_err("%s: FAIL: enable vbatt filter: result=%d\n",
873 __func__, vbatt_filter_rep.result);
874 return -EIO;
875 }
876
877 pr_debug("%s: enable vbatt filter: OK\n", __func__);
878 return rc;
879}
880
881struct batt_client_registration_req {
882 /* The voltage at which callback (CB) should be called. */
883 u32 desired_batt_voltage;
884
885 /* The direction when the CB should be called. */
886 u32 voltage_direction;
887
888 /* The registered callback to be called when voltage and
889 * direction specs are met. */
890 u32 batt_cb_id;
891
892 /* The call back data */
893 u32 cb_data;
894 u32 more_data;
895 u32 batt_error;
896};
897
898struct batt_client_registration_req_4_1 {
899 /* The voltage at which callback (CB) should be called. */
900 u32 desired_batt_voltage;
901
902 /* The direction when the CB should be called. */
903 u32 voltage_direction;
904
905 /* The registered callback to be called when voltage and
906 * direction specs are met. */
907 u32 batt_cb_id;
908
909 /* The call back data */
910 u32 cb_data;
911 u32 batt_error;
912};
913
914struct batt_client_registration_rep {
915 u32 batt_handle;
916};
917
918struct batt_client_registration_rep_4_1 {
919 u32 batt_handle;
920 u32 more_data;
921 u32 err;
922};
923
924static int msm_batt_register_arg_func(struct msm_rpc_client *batt_client,
925 void *buf, void *data)
926{
927 struct batt_client_registration_req *batt_reg_req =
928 (struct batt_client_registration_req *)data;
929
930 u32 *req = (u32 *)buf;
931 int size = 0;
932
933
934 if (msm_batt_info.batt_api_version == BATTERY_RPC_VER_4_1) {
935 *req = cpu_to_be32(batt_reg_req->desired_batt_voltage);
936 size += sizeof(u32);
937 req++;
938
939 *req = cpu_to_be32(batt_reg_req->voltage_direction);
940 size += sizeof(u32);
941 req++;
942
943 *req = cpu_to_be32(batt_reg_req->batt_cb_id);
944 size += sizeof(u32);
945 req++;
946
947 *req = cpu_to_be32(batt_reg_req->cb_data);
948 size += sizeof(u32);
949 req++;
950
951 *req = cpu_to_be32(batt_reg_req->batt_error);
952 size += sizeof(u32);
953
954 return size;
955 } else {
956 *req = cpu_to_be32(batt_reg_req->desired_batt_voltage);
957 size += sizeof(u32);
958 req++;
959
960 *req = cpu_to_be32(batt_reg_req->voltage_direction);
961 size += sizeof(u32);
962 req++;
963
964 *req = cpu_to_be32(batt_reg_req->batt_cb_id);
965 size += sizeof(u32);
966 req++;
967
968 *req = cpu_to_be32(batt_reg_req->cb_data);
969 size += sizeof(u32);
970 req++;
971
972 *req = cpu_to_be32(batt_reg_req->more_data);
973 size += sizeof(u32);
974 req++;
975
976 *req = cpu_to_be32(batt_reg_req->batt_error);
977 size += sizeof(u32);
978
979 return size;
980 }
981
982}
983
984static int msm_batt_register_ret_func(struct msm_rpc_client *batt_client,
985 void *buf, void *data)
986{
987 struct batt_client_registration_rep *data_ptr, *buf_ptr;
988 struct batt_client_registration_rep_4_1 *data_ptr_4_1, *buf_ptr_4_1;
989
990 if (msm_batt_info.batt_api_version == BATTERY_RPC_VER_4_1) {
991 data_ptr_4_1 = (struct batt_client_registration_rep_4_1 *)data;
992 buf_ptr_4_1 = (struct batt_client_registration_rep_4_1 *)buf;
993
994 data_ptr_4_1->batt_handle
995 = be32_to_cpu(buf_ptr_4_1->batt_handle);
996 data_ptr_4_1->more_data
997 = be32_to_cpu(buf_ptr_4_1->more_data);
998 data_ptr_4_1->err = be32_to_cpu(buf_ptr_4_1->err);
999 return 0;
1000 } else {
1001 data_ptr = (struct batt_client_registration_rep *)data;
1002 buf_ptr = (struct batt_client_registration_rep *)buf;
1003
1004 data_ptr->batt_handle = be32_to_cpu(buf_ptr->batt_handle);
1005 return 0;
1006 }
1007}
1008
1009static int msm_batt_register(u32 desired_batt_voltage,
1010 u32 voltage_direction, u32 batt_cb_id, u32 cb_data)
1011{
1012 struct batt_client_registration_req batt_reg_req;
1013 struct batt_client_registration_req_4_1 batt_reg_req_4_1;
1014 struct batt_client_registration_rep batt_reg_rep;
1015 struct batt_client_registration_rep_4_1 batt_reg_rep_4_1;
1016 void *request;
1017 void *reply;
1018 int rc;
1019
1020 if (msm_batt_info.batt_api_version == BATTERY_RPC_VER_4_1) {
1021 batt_reg_req_4_1.desired_batt_voltage = desired_batt_voltage;
1022 batt_reg_req_4_1.voltage_direction = voltage_direction;
1023 batt_reg_req_4_1.batt_cb_id = batt_cb_id;
1024 batt_reg_req_4_1.cb_data = cb_data;
1025 batt_reg_req_4_1.batt_error = 1;
1026 request = &batt_reg_req_4_1;
1027 } else {
1028 batt_reg_req.desired_batt_voltage = desired_batt_voltage;
1029 batt_reg_req.voltage_direction = voltage_direction;
1030 batt_reg_req.batt_cb_id = batt_cb_id;
1031 batt_reg_req.cb_data = cb_data;
1032 batt_reg_req.more_data = 1;
1033 batt_reg_req.batt_error = 0;
1034 request = &batt_reg_req;
1035 }
1036
1037 if (msm_batt_info.batt_api_version == BATTERY_RPC_VER_4_1)
1038 reply = &batt_reg_rep_4_1;
1039 else
1040 reply = &batt_reg_rep;
1041
1042 rc = msm_rpc_client_req(msm_batt_info.batt_client,
1043 BATTERY_REGISTER_PROC,
1044 msm_batt_register_arg_func, request,
1045 msm_batt_register_ret_func, reply,
1046 msecs_to_jiffies(BATT_RPC_TIMEOUT));
1047
1048 if (rc < 0) {
1049 pr_err("%s: FAIL: vbatt register. rc=%d\n", __func__, rc);
1050 return rc;
1051 }
1052
1053 if (msm_batt_info.batt_api_version == BATTERY_RPC_VER_4_1) {
1054 if (batt_reg_rep_4_1.more_data != 0
1055 && batt_reg_rep_4_1.err
1056 != BATTERY_REGISTRATION_SUCCESSFUL) {
1057 pr_err("%s: vBatt Registration Failed proc_num=%d\n"
1058 , __func__, BATTERY_REGISTER_PROC);
1059 return -EIO;
1060 }
1061 msm_batt_info.batt_handle = batt_reg_rep_4_1.batt_handle;
1062 } else
1063 msm_batt_info.batt_handle = batt_reg_rep.batt_handle;
1064
1065 return 0;
1066}
1067
1068struct batt_client_deregister_req {
1069 u32 batt_handle;
1070};
1071
1072struct batt_client_deregister_rep {
1073 u32 batt_error;
1074};
1075
1076static int msm_batt_deregister_arg_func(struct msm_rpc_client *batt_client,
1077 void *buf, void *data)
1078{
1079 struct batt_client_deregister_req *deregister_req =
1080 (struct batt_client_deregister_req *)data;
1081 u32 *req = (u32 *)buf;
1082 int size = 0;
1083
1084 *req = cpu_to_be32(deregister_req->batt_handle);
1085 size += sizeof(u32);
1086
1087 return size;
1088}
1089
1090static int msm_batt_deregister_ret_func(struct msm_rpc_client *batt_client,
1091 void *buf, void *data)
1092{
1093 struct batt_client_deregister_rep *data_ptr, *buf_ptr;
1094
1095 data_ptr = (struct batt_client_deregister_rep *)data;
1096 buf_ptr = (struct batt_client_deregister_rep *)buf;
1097
1098 data_ptr->batt_error = be32_to_cpu(buf_ptr->batt_error);
1099
1100 return 0;
1101}
1102
1103static int msm_batt_deregister(u32 batt_handle)
1104{
1105 int rc;
1106 struct batt_client_deregister_req req;
1107 struct batt_client_deregister_rep rep;
1108
1109 req.batt_handle = batt_handle;
1110
1111 rc = msm_rpc_client_req(msm_batt_info.batt_client,
1112 BATTERY_DEREGISTER_CLIENT_PROC,
1113 msm_batt_deregister_arg_func, &req,
1114 msm_batt_deregister_ret_func, &rep,
1115 msecs_to_jiffies(BATT_RPC_TIMEOUT));
1116
1117 if (rc < 0) {
1118 pr_err("%s: FAIL: vbatt deregister. rc=%d\n", __func__, rc);
1119 return rc;
1120 }
1121
1122 if (rep.batt_error != BATTERY_DEREGISTRATION_SUCCESSFUL) {
1123 pr_err("%s: vbatt deregistration FAIL. error=%d, handle=%d\n",
1124 __func__, rep.batt_error, batt_handle);
1125 return -EIO;
1126 }
1127
1128 return 0;
1129}
1130#endif /* CONFIG_BATTERY_MSM_FAKE */
1131
1132static int msm_batt_cleanup(void)
1133{
1134 int rc = 0;
1135
1136#ifndef CONFIG_BATTERY_MSM_FAKE
1137 if (msm_batt_info.batt_handle != INVALID_BATT_HANDLE) {
1138
1139 rc = msm_batt_deregister(msm_batt_info.batt_handle);
1140 if (rc < 0)
1141 pr_err("%s: FAIL: msm_batt_deregister. rc=%d\n",
1142 __func__, rc);
1143 }
1144
1145 msm_batt_info.batt_handle = INVALID_BATT_HANDLE;
1146
1147 if (msm_batt_info.batt_client)
1148 msm_rpc_unregister_client(msm_batt_info.batt_client);
1149#endif /* CONFIG_BATTERY_MSM_FAKE */
1150
1151 if (msm_batt_info.msm_psy_ac)
1152 power_supply_unregister(msm_batt_info.msm_psy_ac);
1153
1154 if (msm_batt_info.msm_psy_usb)
1155 power_supply_unregister(msm_batt_info.msm_psy_usb);
1156 if (msm_batt_info.msm_psy_batt)
1157 power_supply_unregister(msm_batt_info.msm_psy_batt);
1158
1159#ifndef CONFIG_BATTERY_MSM_FAKE
1160 if (msm_batt_info.chg_ep) {
1161 rc = msm_rpc_close(msm_batt_info.chg_ep);
1162 if (rc < 0) {
1163 pr_err("%s: FAIL. msm_rpc_close(chg_ep). rc=%d\n",
1164 __func__, rc);
1165 }
1166 }
1167
1168#ifdef CONFIG_HAS_EARLYSUSPEND
1169 if (msm_batt_info.early_suspend.suspend == msm_batt_early_suspend)
1170 unregister_early_suspend(&msm_batt_info.early_suspend);
1171#endif
1172#endif
1173 return rc;
1174}
1175
1176static u32 msm_batt_capacity(u32 current_voltage)
1177{
1178 u32 low_voltage = msm_batt_info.voltage_min_design;
1179 u32 high_voltage = msm_batt_info.voltage_max_design;
1180
1181 if (current_voltage <= low_voltage)
1182 return 0;
1183 else if (current_voltage >= high_voltage)
1184 return 100;
1185 else
1186 return (current_voltage - low_voltage) * 100
1187 / (high_voltage - low_voltage);
1188}
1189
1190#ifndef CONFIG_BATTERY_MSM_FAKE
1191int msm_batt_get_charger_api_version(void)
1192{
1193 int rc ;
1194 struct rpc_reply_hdr *reply;
1195
1196 struct rpc_req_chg_api_ver {
1197 struct rpc_request_hdr hdr;
1198 u32 more_data;
1199 } req_chg_api_ver;
1200
1201 struct rpc_rep_chg_api_ver {
1202 struct rpc_reply_hdr hdr;
1203 u32 num_of_chg_api_versions;
1204 u32 *chg_api_versions;
1205 };
1206
1207 u32 num_of_versions;
1208
1209 struct rpc_rep_chg_api_ver *rep_chg_api_ver;
1210
1211
1212 req_chg_api_ver.more_data = cpu_to_be32(1);
1213
1214 msm_rpc_setup_req(&req_chg_api_ver.hdr, CHG_RPC_PROG, CHG_RPC_VER_1_1,
1215 ONCRPC_CHARGER_API_VERSIONS_PROC);
1216
1217 rc = msm_rpc_write(msm_batt_info.chg_ep, &req_chg_api_ver,
1218 sizeof(req_chg_api_ver));
1219 if (rc < 0) {
1220 pr_err("%s: FAIL: msm_rpc_write. proc=0x%08x, rc=%d\n",
1221 __func__, ONCRPC_CHARGER_API_VERSIONS_PROC, rc);
1222 return rc;
1223 }
1224
1225 for (;;) {
1226 rc = msm_rpc_read(msm_batt_info.chg_ep, (void *) &reply, -1,
1227 BATT_RPC_TIMEOUT);
1228 if (rc < 0)
1229 return rc;
1230 if (rc < RPC_REQ_REPLY_COMMON_HEADER_SIZE) {
1231 pr_err("%s: LENGTH ERR: msm_rpc_read. rc=%d (<%d)\n",
1232 __func__, rc, RPC_REQ_REPLY_COMMON_HEADER_SIZE);
1233
1234 rc = -EIO;
1235 break;
1236 }
1237 /* we should not get RPC REQ or call packets -- ignore them */
1238 if (reply->type == RPC_TYPE_REQ) {
1239 pr_err("%s: TYPE ERR: type=%d (!=%d)\n",
1240 __func__, reply->type, RPC_TYPE_REQ);
1241 kfree(reply);
1242 continue;
1243 }
1244
1245 /* If an earlier call timed out, we could get the (no
1246 * longer wanted) reply for it. Ignore replies that
1247 * we don't expect
1248 */
1249 if (reply->xid != req_chg_api_ver.hdr.xid) {
1250 pr_err("%s: XID ERR: xid=%d (!=%d)\n", __func__,
1251 reply->xid, req_chg_api_ver.hdr.xid);
1252 kfree(reply);
1253 continue;
1254 }
1255 if (reply->reply_stat != RPCMSG_REPLYSTAT_ACCEPTED) {
1256 rc = -EPERM;
1257 break;
1258 }
1259 if (reply->data.acc_hdr.accept_stat !=
1260 RPC_ACCEPTSTAT_SUCCESS) {
1261 rc = -EINVAL;
1262 break;
1263 }
1264
1265 rep_chg_api_ver = (struct rpc_rep_chg_api_ver *)reply;
1266
1267 num_of_versions =
1268 be32_to_cpu(rep_chg_api_ver->num_of_chg_api_versions);
1269
1270 rep_chg_api_ver->chg_api_versions = (u32 *)
1271 ((u8 *) reply + sizeof(struct rpc_reply_hdr) +
1272 sizeof(rep_chg_api_ver->num_of_chg_api_versions));
1273
1274 rc = be32_to_cpu(
1275 rep_chg_api_ver->chg_api_versions[num_of_versions - 1]);
1276
1277 pr_debug("%s: num_of_chg_api_versions = %u. "
1278 "The chg api version = 0x%08x\n", __func__,
1279 num_of_versions, rc);
1280 break;
1281 }
1282 kfree(reply);
1283 return rc;
1284}
1285
1286static int msm_batt_cb_func(struct msm_rpc_client *client,
1287 void *buffer, int in_size)
1288{
1289 int rc = 0;
1290 struct rpc_request_hdr *req;
1291 u32 procedure;
1292 u32 accept_status;
1293
1294 req = (struct rpc_request_hdr *)buffer;
1295 procedure = be32_to_cpu(req->procedure);
1296
1297 switch (procedure) {
1298 case BATTERY_CB_TYPE_PROC:
1299 accept_status = RPC_ACCEPTSTAT_SUCCESS;
1300 break;
1301
1302 default:
1303 accept_status = RPC_ACCEPTSTAT_PROC_UNAVAIL;
1304 pr_err("%s: ERROR. procedure (%d) not supported\n",
1305 __func__, procedure);
1306 break;
1307 }
1308
1309 msm_rpc_start_accepted_reply(msm_batt_info.batt_client,
1310 be32_to_cpu(req->xid), accept_status);
1311
1312 rc = msm_rpc_send_accepted_reply(msm_batt_info.batt_client, 0);
1313 if (rc)
1314 pr_err("%s: FAIL: sending reply. rc=%d\n", __func__, rc);
1315
1316 if (accept_status == RPC_ACCEPTSTAT_SUCCESS)
1317 msm_batt_update_psy_status();
1318
1319 return rc;
1320}
1321#endif /* CONFIG_BATTERY_MSM_FAKE */
1322
1323static int __devinit msm_batt_probe(struct platform_device *pdev)
1324{
1325 int rc;
1326 struct msm_psy_batt_pdata *pdata = pdev->dev.platform_data;
1327
1328 if (pdev->id != -1) {
1329 dev_err(&pdev->dev,
1330 "%s: MSM chipsets Can only support one"
1331 " battery ", __func__);
1332 return -EINVAL;
1333 }
1334
1335#ifndef CONFIG_BATTERY_MSM_FAKE
1336 if (pdata->avail_chg_sources & AC_CHG) {
1337#else
1338 {
1339#endif
1340 rc = power_supply_register(&pdev->dev, &msm_psy_ac);
1341 if (rc < 0) {
1342 dev_err(&pdev->dev,
1343 "%s: power_supply_register failed"
1344 " rc = %d\n", __func__, rc);
1345 msm_batt_cleanup();
1346 return rc;
1347 }
1348 msm_batt_info.msm_psy_ac = &msm_psy_ac;
1349 msm_batt_info.avail_chg_sources |= AC_CHG;
1350 }
1351
1352 if (pdata->avail_chg_sources & USB_CHG) {
1353 rc = power_supply_register(&pdev->dev, &msm_psy_usb);
1354 if (rc < 0) {
1355 dev_err(&pdev->dev,
1356 "%s: power_supply_register failed"
1357 " rc = %d\n", __func__, rc);
1358 msm_batt_cleanup();
1359 return rc;
1360 }
1361 msm_batt_info.msm_psy_usb = &msm_psy_usb;
1362 msm_batt_info.avail_chg_sources |= USB_CHG;
1363 }
1364
1365 if (!msm_batt_info.msm_psy_ac && !msm_batt_info.msm_psy_usb) {
1366
1367 dev_err(&pdev->dev,
1368 "%s: No external Power supply(AC or USB)"
1369 "is avilable\n", __func__);
1370 msm_batt_cleanup();
1371 return -ENODEV;
1372 }
1373
1374 msm_batt_info.voltage_max_design = pdata->voltage_max_design;
1375 msm_batt_info.voltage_min_design = pdata->voltage_min_design;
1376 msm_batt_info.batt_technology = pdata->batt_technology;
1377 msm_batt_info.calculate_capacity = pdata->calculate_capacity;
1378
1379 if (!msm_batt_info.voltage_min_design)
1380 msm_batt_info.voltage_min_design = BATTERY_LOW;
1381 if (!msm_batt_info.voltage_max_design)
1382 msm_batt_info.voltage_max_design = BATTERY_HIGH;
1383
1384 if (msm_batt_info.batt_technology == POWER_SUPPLY_TECHNOLOGY_UNKNOWN)
1385 msm_batt_info.batt_technology = POWER_SUPPLY_TECHNOLOGY_LION;
1386
1387 if (!msm_batt_info.calculate_capacity)
1388 msm_batt_info.calculate_capacity = msm_batt_capacity;
1389
1390 rc = power_supply_register(&pdev->dev, &msm_psy_batt);
1391 if (rc < 0) {
1392 dev_err(&pdev->dev, "%s: power_supply_register failed"
1393 " rc=%d\n", __func__, rc);
1394 msm_batt_cleanup();
1395 return rc;
1396 }
1397 msm_batt_info.msm_psy_batt = &msm_psy_batt;
1398
1399#ifndef CONFIG_BATTERY_MSM_FAKE
1400 rc = msm_batt_register(BATTERY_LOW, BATTERY_ALL_ACTIVITY,
1401 BATTERY_CB_ID_ALL_ACTIV, BATTERY_ALL_ACTIVITY);
1402 if (rc < 0) {
1403 dev_err(&pdev->dev,
1404 "%s: msm_batt_register failed rc = %d\n", __func__, rc);
1405 msm_batt_cleanup();
1406 return rc;
1407 }
1408
1409 rc = msm_batt_enable_filter(VBATT_FILTER);
1410
1411 if (rc < 0) {
1412 dev_err(&pdev->dev,
1413 "%s: msm_batt_enable_filter failed rc = %d\n",
1414 __func__, rc);
1415 msm_batt_cleanup();
1416 return rc;
1417 }
1418
1419#ifdef CONFIG_HAS_EARLYSUSPEND
1420 msm_batt_info.early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
1421 msm_batt_info.early_suspend.suspend = msm_batt_early_suspend;
1422 msm_batt_info.early_suspend.resume = msm_batt_late_resume;
1423 register_early_suspend(&msm_batt_info.early_suspend);
1424#endif
1425 msm_batt_update_psy_status();
1426
1427#else
1428 power_supply_changed(&msm_psy_ac);
1429#endif /* CONFIG_BATTERY_MSM_FAKE */
1430
1431 return 0;
1432}
1433
1434static int __devexit msm_batt_remove(struct platform_device *pdev)
1435{
1436 int rc;
1437 rc = msm_batt_cleanup();
1438
1439 if (rc < 0) {
1440 dev_err(&pdev->dev,
1441 "%s: msm_batt_cleanup failed rc=%d\n", __func__, rc);
1442 return rc;
1443 }
1444 return 0;
1445}
1446
1447static struct platform_driver msm_batt_driver = {
1448 .probe = msm_batt_probe,
1449 .remove = __devexit_p(msm_batt_remove),
1450 .driver = {
1451 .name = "msm-battery",
1452 .owner = THIS_MODULE,
1453 },
1454};
1455
1456static int __devinit msm_batt_init_rpc(void)
1457{
1458 int rc;
1459
1460#ifdef CONFIG_BATTERY_MSM_FAKE
1461 pr_info("Faking MSM battery\n");
1462#else
1463
1464 msm_batt_info.chg_ep =
1465 msm_rpc_connect_compatible(CHG_RPC_PROG, CHG_RPC_VER_4_1, 0);
1466 msm_batt_info.chg_api_version = CHG_RPC_VER_4_1;
1467 if (msm_batt_info.chg_ep == NULL) {
1468 pr_err("%s: rpc connect CHG_RPC_PROG = NULL\n", __func__);
1469 return -ENODEV;
1470 }
1471
1472 if (IS_ERR(msm_batt_info.chg_ep)) {
1473 msm_batt_info.chg_ep = msm_rpc_connect_compatible(
1474 CHG_RPC_PROG, CHG_RPC_VER_3_1, 0);
1475 msm_batt_info.chg_api_version = CHG_RPC_VER_3_1;
1476 }
1477 if (IS_ERR(msm_batt_info.chg_ep)) {
1478 msm_batt_info.chg_ep = msm_rpc_connect_compatible(
1479 CHG_RPC_PROG, CHG_RPC_VER_1_1, 0);
1480 msm_batt_info.chg_api_version = CHG_RPC_VER_1_1;
1481 }
1482 if (IS_ERR(msm_batt_info.chg_ep)) {
1483 msm_batt_info.chg_ep = msm_rpc_connect_compatible(
1484 CHG_RPC_PROG, CHG_RPC_VER_1_3, 0);
1485 msm_batt_info.chg_api_version = CHG_RPC_VER_1_3;
1486 }
1487 if (IS_ERR(msm_batt_info.chg_ep)) {
1488 msm_batt_info.chg_ep = msm_rpc_connect_compatible(
1489 CHG_RPC_PROG, CHG_RPC_VER_2_2, 0);
1490 msm_batt_info.chg_api_version = CHG_RPC_VER_2_2;
1491 }
1492 if (IS_ERR(msm_batt_info.chg_ep)) {
1493 rc = PTR_ERR(msm_batt_info.chg_ep);
1494 pr_err("%s: FAIL: rpc connect for CHG_RPC_PROG. rc=%d\n",
1495 __func__, rc);
1496 msm_batt_info.chg_ep = NULL;
1497 return rc;
1498 }
1499
1500 /* Get the real 1.x version */
1501 if (msm_batt_info.chg_api_version == CHG_RPC_VER_1_1)
1502 msm_batt_info.chg_api_version =
1503 msm_batt_get_charger_api_version();
1504
1505 /* Fall back to 1.1 for default */
1506 if (msm_batt_info.chg_api_version < 0)
1507 msm_batt_info.chg_api_version = CHG_RPC_VER_1_1;
1508 msm_batt_info.batt_api_version = BATTERY_RPC_VER_4_1;
1509
1510 msm_batt_info.batt_client =
1511 msm_rpc_register_client("battery", BATTERY_RPC_PROG,
1512 BATTERY_RPC_VER_4_1,
1513 1, msm_batt_cb_func);
1514
1515 if (msm_batt_info.batt_client == NULL) {
1516 pr_err("%s: FAIL: rpc_register_client. batt_client=NULL\n",
1517 __func__);
1518 return -ENODEV;
1519 }
1520 if (IS_ERR(msm_batt_info.batt_client)) {
1521 msm_batt_info.batt_client =
1522 msm_rpc_register_client("battery", BATTERY_RPC_PROG,
1523 BATTERY_RPC_VER_1_1,
1524 1, msm_batt_cb_func);
1525 msm_batt_info.batt_api_version = BATTERY_RPC_VER_1_1;
1526 }
1527 if (IS_ERR(msm_batt_info.batt_client)) {
1528 msm_batt_info.batt_client =
1529 msm_rpc_register_client("battery", BATTERY_RPC_PROG,
1530 BATTERY_RPC_VER_2_1,
1531 1, msm_batt_cb_func);
1532 msm_batt_info.batt_api_version = BATTERY_RPC_VER_2_1;
1533 }
1534 if (IS_ERR(msm_batt_info.batt_client)) {
1535 msm_batt_info.batt_client =
1536 msm_rpc_register_client("battery", BATTERY_RPC_PROG,
1537 BATTERY_RPC_VER_5_1,
1538 1, msm_batt_cb_func);
1539 msm_batt_info.batt_api_version = BATTERY_RPC_VER_5_1;
1540 }
1541 if (IS_ERR(msm_batt_info.batt_client)) {
1542 rc = PTR_ERR(msm_batt_info.batt_client);
1543 pr_err("%s: ERROR: rpc_register_client: rc = %d\n ",
1544 __func__, rc);
1545 msm_batt_info.batt_client = NULL;
1546 return rc;
1547 }
1548#endif /* CONFIG_BATTERY_MSM_FAKE */
1549
1550 rc = platform_driver_register(&msm_batt_driver);
1551
1552 if (rc < 0)
1553 pr_err("%s: FAIL: platform_driver_register. rc = %d\n",
1554 __func__, rc);
1555
1556 return rc;
1557}
1558
1559static int __init msm_batt_init(void)
1560{
1561 int rc;
1562
1563 pr_debug("%s: enter\n", __func__);
1564
1565 rc = msm_batt_init_rpc();
1566
1567 if (rc < 0) {
1568 pr_err("%s: FAIL: msm_batt_init_rpc. rc=%d\n", __func__, rc);
1569 msm_batt_cleanup();
1570 return rc;
1571 }
1572
1573 pr_info("%s: Charger/Battery = 0x%08x/0x%08x (RPC version)\n",
1574 __func__, msm_batt_info.chg_api_version,
1575 msm_batt_info.batt_api_version);
1576
1577 return 0;
1578}
1579
1580static void __exit msm_batt_exit(void)
1581{
1582 platform_driver_unregister(&msm_batt_driver);
1583}
1584
1585module_init(msm_batt_init);
1586module_exit(msm_batt_exit);
1587
1588MODULE_LICENSE("GPL v2");
1589MODULE_AUTHOR("Kiran Kandi, Qualcomm Innovation Center, Inc.");
1590MODULE_DESCRIPTION("Battery driver for Qualcomm MSM chipsets.");
1591MODULE_VERSION("1.0");
1592MODULE_ALIAS("platform:msm_battery");