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