board-vienna-battery.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  1. /*
  2. * Copyright (C) 2012 Samsung Electronics, Inc.
  3. *
  4. * This software is licensed under the terms of the GNU General Public
  5. * License version 2, as published by the Free Software Foundation, and
  6. * may be copied, distributed, and modified under those terms.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. */
  14. #include <linux/kernel.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/gpio.h>
  17. #include <linux/io.h>
  18. #include <linux/irq.h>
  19. #include <linux/irqdomain.h>
  20. #include <linux/of.h>
  21. #include <linux/of_address.h>
  22. #include <linux/of_platform.h>
  23. #include <linux/memory.h>
  24. #include <linux/regulator/machine.h>
  25. #include <linux/regulator/krait-regulator.h>
  26. #include <linux/msm_thermal.h>
  27. #include <asm/mach/map.h>
  28. #include <asm/hardware/gic.h>
  29. #include <asm/mach/map.h>
  30. #include <asm/mach/arch.h>
  31. #include <mach/board.h>
  32. #include <mach/gpiomux.h>
  33. #include <mach/msm_iomap.h>
  34. #include <mach/irqs.h>
  35. #ifdef CONFIG_ION_MSM
  36. #include <mach/ion.h>
  37. #endif
  38. #include <mach/msm_memtypes.h>
  39. #include <mach/msm_smd.h>
  40. #include <mach/restart.h>
  41. #include <mach/rpm-smd.h>
  42. #include <mach/rpm-regulator-smd.h>
  43. #include <mach/socinfo.h>
  44. #include <mach/msm_bus_board.h>
  45. #include <linux/i2c-gpio.h>
  46. #include <linux/i2c.h>
  47. #if defined(CONFIG_SENSORS_QPNP_ADC_VOLTAGE)
  48. #include <linux/qpnp/qpnp-adc.h>
  49. #endif
  50. #if defined(CONFIG_BATTERY_SAMSUNG)
  51. #include <linux/battery/sec_battery.h>
  52. #include <linux/battery/sec_fuelgauge.h>
  53. #include <linux/battery/sec_charger.h>
  54. #include <linux/battery/sec_charging_common.h>
  55. #define SEC_BATTERY_PMIC_NAME ""
  56. #define GPIO_FUELGAUGE_I2C_SDA 87
  57. #define GPIO_FUELGAUGE_I2C_SCL 88
  58. #define GPIO_FUEL_INT 26
  59. #define GPIO_TA_nCHG 85
  60. #define GPIO_IF_CON_SENSE_18 76
  61. /*#define GPIO_TA_INT 29*/
  62. #define MSM_FUELGAUGE_I2C_BUS_ID 19
  63. static unsigned int sec_bat_recovery_mode;
  64. static sec_charging_current_t charging_current_table[] = {
  65. {2000, 2000, 300, 40*60},
  66. {0, 0, 0, 0},
  67. {500, 500, 300, 40*60},
  68. {2000, 2000, 300, 40*60},
  69. {500, 500, 300, 40*60},
  70. {500, 500, 300, 40*60},
  71. {1000, 1000, 300, 40*60},
  72. {500, 500, 300, 40*60},
  73. {2000, 2000, 300, 40*60},
  74. {2000, 2000, 300, 40*60},/*car dock*/
  75. {0, 0, 0, 0},
  76. {2000, 2000, 300, 40*60},
  77. {0, -1, 0, 0},/*OTG: - value for chg current*/
  78. {0, 0, 0, 0},
  79. };
  80. extern int msm8974_get_cable_type(void);
  81. int ta_int_gpio;
  82. static bool sec_bat_adc_none_init(
  83. struct platform_device *pdev) {return true; }
  84. static bool sec_bat_adc_none_exit(void) {return true; }
  85. static int sec_bat_adc_none_read(unsigned int channel) {return 0; }
  86. static bool sec_bat_adc_ap_init(
  87. struct platform_device *pdev) {return true; }
  88. static bool sec_bat_adc_ap_exit(void) {return true; }
  89. static int sec_bat_adc_ap_read(unsigned int channel)
  90. {
  91. #if defined(CONFIG_SENSORS_QPNP_ADC_VOLTAGE)
  92. int rc = -1, data = -1;
  93. struct qpnp_vadc_result results;
  94. switch (channel) {
  95. case SEC_BAT_ADC_CHANNEL_TEMP:
  96. rc = qpnp_vadc_read(NULL, LR_MUX5_PU2_AMUX_THM2, &results);
  97. if (rc) {
  98. pr_err("%s: Unable to read batt temperature rc=%d\n",
  99. __func__, rc);
  100. return 0;
  101. }
  102. data = results.adc_code;
  103. break;
  104. case SEC_BAT_ADC_CHANNEL_TEMP_AMBIENT:
  105. data = 33000;
  106. break;
  107. case SEC_BAT_ADC_CHANNEL_BAT_CHECK:
  108. break;
  109. default:
  110. break;
  111. }
  112. return data;
  113. #else
  114. return 33000;
  115. #endif
  116. }
  117. static bool sec_bat_adc_ic_init(
  118. struct platform_device *pdev) {return true; }
  119. static bool sec_bat_adc_ic_exit(void) {return true; }
  120. static int sec_bat_adc_ic_read(unsigned int channel) {return 0; }
  121. static bool sec_bat_gpio_init(void)
  122. {
  123. return true;
  124. }
  125. static struct i2c_gpio_platform_data gpio_i2c_data_fgchg = {
  126. .sda_pin = GPIO_FUELGAUGE_I2C_SDA,
  127. .scl_pin = GPIO_FUELGAUGE_I2C_SCL,
  128. };
  129. static bool sec_fg_gpio_init(void)
  130. {
  131. gpio_tlmm_config(GPIO_CFG(GPIO_FUEL_INT, 0, GPIO_CFG_INPUT,
  132. GPIO_CFG_NO_PULL, GPIO_CFG_2MA), 1);
  133. gpio_tlmm_config(GPIO_CFG(gpio_i2c_data_fgchg.scl_pin, 0,
  134. GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), 1);
  135. gpio_tlmm_config(GPIO_CFG(gpio_i2c_data_fgchg.sda_pin, 0,
  136. GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), 1);
  137. gpio_set_value(gpio_i2c_data_fgchg.scl_pin, 1);
  138. gpio_set_value(gpio_i2c_data_fgchg.sda_pin, 1);
  139. return true;
  140. }
  141. static bool sec_chg_gpio_init(void)
  142. {
  143. return true;
  144. }
  145. extern int poweroff_charging;
  146. static bool sec_bat_is_lpm(void) {return (bool)poweroff_charging; }
  147. int extended_cable_type;
  148. extern int current_cable_type;
  149. extern int mhl_connection_state(void);
  150. static void sec_bat_initial_check(void)
  151. {
  152. union power_supply_propval value;
  153. int cable_type = 0;
  154. cable_type = msm8974_get_cable_type();
  155. value.intval = cable_type;
  156. if (POWER_SUPPLY_TYPE_BATTERY <= cable_type) {
  157. value.intval = cable_type<<ONLINE_TYPE_MAIN_SHIFT;
  158. psy_do_property("battery", set,
  159. POWER_SUPPLY_PROP_ONLINE, value);
  160. }
  161. if (ta_int_gpio == 0) {
  162. pr_err("%s: ta_int_gpio is 0 or not assigned yet\n", __func__);
  163. } else {
  164. if (cable_type == POWER_SUPPLY_TYPE_BATTERY &&
  165. !gpio_get_value_cansleep(ta_int_gpio)) {
  166. #if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2)
  167. if (!mhl_connection_state()) {
  168. value.intval = POWER_SUPPLY_TYPE_UARTOFF<<ONLINE_TYPE_MAIN_SHIFT;
  169. pr_info("%s : VBUS IN\n", __func__);
  170. }
  171. #else
  172. value.intval = POWER_SUPPLY_TYPE_UARTOFF<<ONLINE_TYPE_MAIN_SHIFT;
  173. pr_info("%s : VBUS IN\n", __func__);
  174. #endif
  175. }
  176. if (value.intval)
  177. psy_do_property("battery", set,
  178. POWER_SUPPLY_PROP_ONLINE, value);
  179. }
  180. }
  181. bool sec_bat_check_jig_status(void)
  182. {
  183. if (gpio_get_value_cansleep(GPIO_IF_CON_SENSE_18))/*IF_CON_SENSE*/
  184. return true;
  185. else
  186. return false;
  187. #if 0
  188. return (current_cable_type == POWER_SUPPLY_TYPE_UARTOFF);
  189. #endif
  190. }
  191. static bool sec_bat_switch_to_check(void) {return true; }
  192. static bool sec_bat_switch_to_normal(void) {return true; }
  193. static bool sec_bat_is_interrupt_cable_check_possible(int extended_cable_type)
  194. {
  195. return true;
  196. }
  197. int sec_bat_check_cable_callback(void)
  198. {
  199. union power_supply_propval value;
  200. msleep(750);
  201. if (ta_int_gpio == 0) {
  202. pr_err("%s: ta_int_gpio is 0 or not assigned yet(cable_type(%d))\n",
  203. __func__, current_cable_type);
  204. }
  205. #if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2)
  206. else if (!mhl_connection_state()) {
  207. #else
  208. else {
  209. #endif
  210. if (current_cable_type == POWER_SUPPLY_TYPE_BATTERY &&
  211. !gpio_get_value_cansleep(ta_int_gpio)) {
  212. pr_info("%s : VBUS IN\n", __func__);
  213. value.intval = POWER_SUPPLY_TYPE_UARTOFF<<ONLINE_TYPE_MAIN_SHIFT;
  214. psy_do_property("battery", set, POWER_SUPPLY_PROP_ONLINE, value);
  215. return POWER_SUPPLY_TYPE_UARTOFF;
  216. }
  217. if ((current_cable_type == POWER_SUPPLY_TYPE_UARTOFF ||
  218. current_cable_type == POWER_SUPPLY_TYPE_CARDOCK) &&
  219. gpio_get_value_cansleep(ta_int_gpio)) {
  220. pr_info("%s : VBUS OUT\n", __func__);
  221. value.intval = POWER_SUPPLY_TYPE_BATTERY<<ONLINE_TYPE_MAIN_SHIFT;
  222. psy_do_property("battery", set, POWER_SUPPLY_PROP_ONLINE, value);
  223. return POWER_SUPPLY_TYPE_BATTERY;
  224. }
  225. }
  226. return current_cable_type;
  227. }
  228. static int sec_bat_get_cable_from_extended_cable_type(
  229. int input_extended_cable_type)
  230. {
  231. int cable_main, cable_sub, cable_power;
  232. int cable_type = POWER_SUPPLY_TYPE_UNKNOWN;
  233. union power_supply_propval value;
  234. int charge_current_max = 0, charge_current = 0;
  235. cable_main = GET_MAIN_CABLE_TYPE(input_extended_cable_type);
  236. if (cable_main != POWER_SUPPLY_TYPE_UNKNOWN)
  237. extended_cable_type = (extended_cable_type &
  238. ~(int)ONLINE_TYPE_MAIN_MASK) |
  239. (cable_main << ONLINE_TYPE_MAIN_SHIFT);
  240. cable_sub = GET_SUB_CABLE_TYPE(input_extended_cable_type);
  241. if (cable_sub != ONLINE_SUB_TYPE_UNKNOWN)
  242. extended_cable_type = (extended_cable_type &
  243. ~(int)ONLINE_TYPE_SUB_MASK) |
  244. (cable_sub << ONLINE_TYPE_SUB_SHIFT);
  245. cable_power = GET_POWER_CABLE_TYPE(input_extended_cable_type);
  246. if (cable_power != ONLINE_POWER_TYPE_UNKNOWN)
  247. extended_cable_type = (extended_cable_type &
  248. ~(int)ONLINE_TYPE_PWR_MASK) |
  249. (cable_power << ONLINE_TYPE_PWR_SHIFT);
  250. switch (cable_main) {
  251. case POWER_SUPPLY_TYPE_CARDOCK:
  252. switch (cable_power) {
  253. case ONLINE_POWER_TYPE_BATTERY:
  254. cable_type = POWER_SUPPLY_TYPE_BATTERY;
  255. break;
  256. case ONLINE_POWER_TYPE_TA:
  257. switch (cable_sub) {
  258. case ONLINE_SUB_TYPE_MHL:
  259. cable_type = POWER_SUPPLY_TYPE_USB;
  260. break;
  261. case ONLINE_SUB_TYPE_AUDIO:
  262. case ONLINE_SUB_TYPE_DESK:
  263. case ONLINE_SUB_TYPE_SMART_NOTG:
  264. case ONLINE_SUB_TYPE_KBD:
  265. cable_type = POWER_SUPPLY_TYPE_MAINS;
  266. break;
  267. case ONLINE_SUB_TYPE_SMART_OTG:
  268. cable_type = POWER_SUPPLY_TYPE_CARDOCK;
  269. break;
  270. }
  271. break;
  272. case ONLINE_POWER_TYPE_USB:
  273. cable_type = POWER_SUPPLY_TYPE_USB;
  274. break;
  275. default:
  276. cable_type = current_cable_type;
  277. break;
  278. }
  279. break;
  280. case POWER_SUPPLY_TYPE_MISC:
  281. switch (cable_sub) {
  282. case ONLINE_SUB_TYPE_MHL:
  283. switch (cable_power) {
  284. case ONLINE_POWER_TYPE_BATTERY:
  285. cable_type = POWER_SUPPLY_TYPE_BATTERY;
  286. break;
  287. case ONLINE_POWER_TYPE_MHL_500:
  288. cable_type = POWER_SUPPLY_TYPE_MISC;
  289. charge_current_max = 400;
  290. charge_current = 400;
  291. break;
  292. case ONLINE_POWER_TYPE_MHL_900:
  293. cable_type = POWER_SUPPLY_TYPE_MISC;
  294. charge_current_max = 500;
  295. charge_current = 500;
  296. break;
  297. case ONLINE_POWER_TYPE_MHL_1500:
  298. cable_type = POWER_SUPPLY_TYPE_MISC;
  299. charge_current_max = 1300;
  300. charge_current = 1300;
  301. break;
  302. case ONLINE_POWER_TYPE_USB:
  303. cable_type = POWER_SUPPLY_TYPE_USB;
  304. charge_current_max = 150;
  305. charge_current = 500;
  306. break;
  307. default:
  308. cable_type = cable_main;
  309. }
  310. break;
  311. default:
  312. cable_type = cable_main;
  313. break;
  314. }
  315. break;
  316. default:
  317. cable_type = cable_main;
  318. break;
  319. }
  320. if (charge_current_max == 0) {
  321. charge_current_max =
  322. charging_current_table[cable_type].input_current_limit;
  323. charge_current =
  324. charging_current_table[cable_type].
  325. fast_charging_current;
  326. }
  327. value.intval = charge_current_max;
  328. psy_do_property(sec_battery_pdata.charger_name, set,
  329. POWER_SUPPLY_PROP_CURRENT_MAX, value);
  330. value.intval = charge_current;
  331. psy_do_property(sec_battery_pdata.charger_name, set,
  332. POWER_SUPPLY_PROP_CURRENT_AVG, value);
  333. return cable_type;
  334. }
  335. static bool sec_bat_check_cable_result_callback(
  336. int cable_type)
  337. {
  338. current_cable_type = cable_type;
  339. switch (cable_type) {
  340. case POWER_SUPPLY_TYPE_USB:
  341. pr_info("%s set vbus applied\n",
  342. __func__);
  343. break;
  344. case POWER_SUPPLY_TYPE_BATTERY:
  345. pr_info("%s set vbus cut\n",
  346. __func__);
  347. break;
  348. case POWER_SUPPLY_TYPE_MAINS:
  349. break;
  350. default:
  351. pr_err("%s cable type (%d)\n",
  352. __func__, cable_type);
  353. return false;
  354. }
  355. return true;
  356. }
  357. /* callback for battery check
  358. * return : bool
  359. * true - battery detected, false battery NOT detected
  360. */
  361. static bool sec_bat_check_callback(void)
  362. {
  363. #if 0/*No need for Tablet*/
  364. struct power_supply *psy;
  365. union power_supply_propval value;
  366. psy = get_power_supply_by_name(("sec-charger"));
  367. if (!psy) {
  368. pr_err("%s: Fail to get psy (%s)\n",
  369. __func__, "sec-charger");
  370. value.intval = 1;
  371. } else {
  372. int ret;
  373. ret = psy->get_property(psy, POWER_SUPPLY_PROP_PRESENT, &(value));
  374. if (ret < 0) {
  375. pr_err("%s: Fail to sec-charger get_property (%d=>%d)\n",
  376. __func__, POWER_SUPPLY_PROP_PRESENT, ret);
  377. value.intval = 1;
  378. }
  379. }
  380. return value.intval;
  381. #endif
  382. return true;
  383. }
  384. static bool sec_bat_check_result_callback(void) {return true; }
  385. /* callback for OVP/UVLO check
  386. * return : int
  387. * battery health
  388. */
  389. static int sec_bat_ovp_uvlo_callback(void)
  390. {
  391. int health;
  392. health = POWER_SUPPLY_HEALTH_GOOD;
  393. return health;
  394. }
  395. static bool sec_bat_ovp_uvlo_result_callback(int health) {return true; }
  396. /*
  397. * val.intval : temperature
  398. */
  399. static bool sec_bat_get_temperature_callback(
  400. enum power_supply_property psp,
  401. union power_supply_propval *val) {return true; }
  402. static bool sec_fg_fuelalert_process(bool is_fuel_alerted) {return true; }
  403. /* ADC region should be exclusive */
  404. static sec_bat_adc_region_t cable_adc_value_table[] = {
  405. {0, 0},
  406. {0, 0},
  407. {0, 0},
  408. {0, 0},
  409. {0, 0},
  410. {0, 0},
  411. {0, 0},
  412. {0, 0},
  413. {0, 0},
  414. {0, 0},
  415. {0, 0},
  416. };
  417. static int polling_time_table[] = {
  418. 10, /* BASIC */
  419. 30, /* CHARGING */
  420. 30, /* DISCHARGING */
  421. 30, /* NOT_CHARGING */
  422. 60 * 60, /* SLEEP */
  423. };
  424. /* for MAX17050 */
  425. static struct battery_data_t samsung_battery_data[] = {
  426. /* SDI battery data */
  427. {
  428. .Capacity = 0x4A8E,
  429. .low_battery_comp_voltage = 3500,
  430. .low_battery_table = {
  431. /* range, slope, offset */
  432. {-5000, 0, 0}, /* dummy for top limit */
  433. {-1250, 0, 3320},
  434. {-750, 97, 3451},
  435. {-100, 96, 3461},
  436. {0, 0, 3456},
  437. },
  438. .temp_adjust_table = {
  439. /* range, slope, offset */
  440. {47000, 122, 8950},
  441. {60000, 200, 51000},
  442. {100000, 0, 0}, /* dummy for top limit */
  443. },
  444. .type_str = "SDI",
  445. }
  446. };
  447. /* temp, same with board-8974-sec.c */
  448. #define IF_PMIC_IRQ_BASE 353 /* temp val */
  449. sec_battery_platform_data_t sec_battery_pdata = {
  450. /* NO NEED TO BE CHANGED */
  451. .initial_check = sec_bat_initial_check,
  452. .bat_gpio_init = sec_bat_gpio_init,
  453. .fg_gpio_init = sec_fg_gpio_init,
  454. .chg_gpio_init = sec_chg_gpio_init,
  455. .is_lpm = sec_bat_is_lpm,
  456. .jig_irq = 0,
  457. .jig_irq_attr =
  458. IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
  459. .check_jig_status = sec_bat_check_jig_status,
  460. .is_interrupt_cable_check_possible =
  461. sec_bat_is_interrupt_cable_check_possible,
  462. .check_cable_callback =
  463. sec_bat_check_cable_callback,
  464. .get_cable_from_extended_cable_type =
  465. sec_bat_get_cable_from_extended_cable_type,
  466. .cable_switch_check = sec_bat_switch_to_check,
  467. .cable_switch_normal = sec_bat_switch_to_normal,
  468. .check_cable_result_callback =
  469. sec_bat_check_cable_result_callback,
  470. .check_battery_callback =
  471. sec_bat_check_callback,
  472. .check_battery_result_callback =
  473. sec_bat_check_result_callback,
  474. .ovp_uvlo_callback = sec_bat_ovp_uvlo_callback,
  475. .ovp_uvlo_result_callback =
  476. sec_bat_ovp_uvlo_result_callback,
  477. .fuelalert_process = sec_fg_fuelalert_process,
  478. .get_temperature_callback =
  479. sec_bat_get_temperature_callback,
  480. .adc_api[SEC_BATTERY_ADC_TYPE_NONE] = {
  481. .init = sec_bat_adc_none_init,
  482. .exit = sec_bat_adc_none_exit,
  483. .read = sec_bat_adc_none_read
  484. },
  485. .adc_api[SEC_BATTERY_ADC_TYPE_AP] = {
  486. .init = sec_bat_adc_ap_init,
  487. .exit = sec_bat_adc_ap_exit,
  488. .read = sec_bat_adc_ap_read
  489. },
  490. .adc_api[SEC_BATTERY_ADC_TYPE_IC] = {
  491. .init = sec_bat_adc_ic_init,
  492. .exit = sec_bat_adc_ic_exit,
  493. .read = sec_bat_adc_ic_read
  494. },
  495. .cable_adc_value = cable_adc_value_table,
  496. .charging_current = charging_current_table,
  497. .polling_time = polling_time_table,
  498. /* NO NEED TO BE CHANGED */
  499. .pmic_name = SEC_BATTERY_PMIC_NAME,
  500. .adc_check_count = 6,
  501. .adc_type = {
  502. SEC_BATTERY_ADC_TYPE_NONE, /* CABLE_CHECK */
  503. SEC_BATTERY_ADC_TYPE_NONE, /* BAT_CHECK */
  504. SEC_BATTERY_ADC_TYPE_NONE, /* TEMP */
  505. SEC_BATTERY_ADC_TYPE_NONE, /* TEMP_AMB */
  506. SEC_BATTERY_ADC_TYPE_AP, /* FULL_CHECK */
  507. },
  508. /* Battery */
  509. .vendor = "SDI SDI",
  510. .technology = POWER_SUPPLY_TECHNOLOGY_LION,
  511. .battery_data = (void *)samsung_battery_data,
  512. .bat_gpio_ta_nconnected = 0,
  513. .bat_polarity_ta_nconnected = 0,
  514. .bat_irq = 0,
  515. .bat_irq_attr = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
  516. .cable_check_type =
  517. SEC_BATTERY_CABLE_CHECK_INT |
  518. SEC_BATTERY_CABLE_CHECK_NOUSBCHARGE |
  519. SEC_BATTERY_CABLE_CHECK_PSY,
  520. .cable_source_type =
  521. SEC_BATTERY_CABLE_SOURCE_EXTERNAL |
  522. SEC_BATTERY_CABLE_SOURCE_EXTENDED |
  523. SEC_BATTERY_CABLE_SOURCE_CALLBACK,
  524. .event_check = false,
  525. .event_waiting_time = 600,
  526. /* Monitor setting */
  527. .polling_type = SEC_BATTERY_MONITOR_ALARM,
  528. .monitor_initial_count = 3,
  529. /* Battery check */
  530. .battery_check_type = SEC_BATTERY_CHECK_NONE,
  531. .check_count = 0,
  532. /* Battery check by ADC */
  533. .check_adc_max = 0,
  534. .check_adc_min = 0,
  535. /* OVP/UVLO check */
  536. .ovp_uvlo_check_type = SEC_BATTERY_OVP_UVLO_CHGPOLLING,
  537. /* Temperature check */
  538. .thermal_source = SEC_BATTERY_THERMAL_SOURCE_FG,
  539. .temp_check_type = SEC_BATTERY_TEMP_CHECK_TEMP,
  540. .temp_check_count = 1,
  541. .temp_high_threshold_event = 700,
  542. .temp_high_recovery_event = 420,
  543. .temp_low_threshold_event = -50,
  544. .temp_low_recovery_event = 0,
  545. .temp_high_threshold_normal = 700,
  546. .temp_high_recovery_normal = 420,
  547. .temp_low_threshold_normal = -50,
  548. .temp_low_recovery_normal = 0,
  549. .temp_high_threshold_lpm = 700,
  550. .temp_high_recovery_lpm = 420,
  551. .temp_low_threshold_lpm = -50,
  552. .temp_low_recovery_lpm = 0,
  553. .full_check_type = SEC_BATTERY_FULLCHARGED_FG_CURRENT,
  554. .full_check_type_2nd = SEC_BATTERY_FULLCHARGED_TIME,
  555. .full_check_count = 1,
  556. .chg_gpio_full_check = GPIO_TA_nCHG,
  557. .chg_polarity_full_check = 0,
  558. .full_condition_type = SEC_BATTERY_FULL_CONDITION_SOC |
  559. SEC_BATTERY_FULL_CONDITION_NOTIMEFULL |
  560. SEC_BATTERY_FULL_CONDITION_VCELL,
  561. .full_condition_soc = 97,
  562. .full_condition_vcell = 4300,
  563. .recharge_check_count = 2,
  564. .recharge_condition_type =
  565. SEC_BATTERY_RECHARGE_CONDITION_VCELL |
  566. SEC_BATTERY_RECHARGE_CONDITION_AVGVCELL,
  567. .recharge_condition_soc = 98,
  568. .recharge_condition_avgvcell = 4150,
  569. .recharge_condition_vcell = 4250,
  570. .charging_total_time = 10 * 60 * 60,
  571. .recharging_total_time = 90 * 60,
  572. .charging_reset_time = 0,
  573. /* Fuel Gauge */
  574. .fg_irq = 0,
  575. .fg_irq_attr =
  576. IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
  577. .fuel_alert_soc = 1,
  578. .repeated_fuelalert = false,
  579. .capacity_calculation_type =
  580. SEC_FUELGAUGE_CAPACITY_TYPE_RAW |
  581. SEC_FUELGAUGE_CAPACITY_TYPE_SCALE |
  582. SEC_FUELGAUGE_CAPACITY_TYPE_DYNAMIC_SCALE,
  583. /* SEC_FUELGAUGE_CAPACITY_TYPE_ATOMIC, */
  584. .capacity_max = 1000,
  585. .capacity_max_margin = 50,
  586. .capacity_min = 0,
  587. /* Charger */
  588. .charger_name = "sec-charger",
  589. .chg_gpio_en = 0,
  590. .chg_polarity_en = 0,
  591. .chg_gpio_status = 0,
  592. .chg_polarity_status = 0,
  593. .chg_irq = 0,
  594. .chg_irq_attr = 0,
  595. .chg_float_voltage = 4360,
  596. };
  597. static struct platform_device sec_device_battery = {
  598. .name = "sec-battery",
  599. .id = -1,
  600. .dev.platform_data = &sec_battery_pdata,
  601. };
  602. struct platform_device sec_device_fgchg = {
  603. .name = "i2c-gpio",
  604. .id = MSM_FUELGAUGE_I2C_BUS_ID,
  605. .dev.platform_data = &gpio_i2c_data_fgchg,
  606. };
  607. static struct i2c_board_info sec_brdinfo_fgchg[] __initdata = {
  608. {
  609. I2C_BOARD_INFO("sec-charger",
  610. SEC_CHARGER_I2C_SLAVEADDR),
  611. .platform_data = &sec_battery_pdata,
  612. },
  613. {
  614. I2C_BOARD_INFO("sec-fuelgauge",
  615. SEC_FUELGAUGE_I2C_SLAVEADDR),
  616. .platform_data = &sec_battery_pdata,
  617. },
  618. };
  619. static struct platform_device *samsung_battery_devices[] __initdata = {
  620. &sec_device_fgchg,
  621. &sec_device_battery,
  622. };
  623. static int __init sec_bat_current_boot_mode(char *mode)
  624. {
  625. /*
  626. * 1 is recovery booting
  627. * 0 is normal booting
  628. */
  629. if (strncmp(mode, "1", 1) == 0)
  630. sec_bat_recovery_mode = 1;
  631. else
  632. sec_bat_recovery_mode = 0;
  633. pr_info("%s : %s", __func__, sec_bat_recovery_mode == 1 ?
  634. "recovery" : "normal");
  635. return 1;
  636. }
  637. __setup("androidboot.boot_recovery=", sec_bat_current_boot_mode);
  638. static void charger_gpio_init(void)
  639. {
  640. /*gpio_tlmm_config(GPIO_CFG(GPIO_TA_INT, 0, GPIO_CFG_INPUT,
  641. GPIO_CFG_NO_PULL, GPIO_CFG_2MA), 1);*/
  642. gpio_tlmm_config(GPIO_CFG(GPIO_TA_nCHG, 0, GPIO_CFG_INPUT,
  643. GPIO_CFG_NO_PULL, GPIO_CFG_2MA), 1);
  644. gpio_tlmm_config(GPIO_CFG(GPIO_IF_CON_SENSE_18, 0, GPIO_CFG_INPUT,
  645. GPIO_CFG_NO_PULL, GPIO_CFG_2MA), 1);
  646. }
  647. void __init samsung_init_battery(void)
  648. {
  649. pr_err("%s\n", __func__);
  650. charger_gpio_init();
  651. /* FUEL_SDA/SCL setting */
  652. platform_add_devices(
  653. samsung_battery_devices,
  654. ARRAY_SIZE(samsung_battery_devices));
  655. i2c_register_board_info(
  656. MSM_FUELGAUGE_I2C_BUS_ID,
  657. sec_brdinfo_fgchg,
  658. ARRAY_SIZE(sec_brdinfo_fgchg));
  659. }
  660. #endif