sec_board-msm8610.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. /*
  2. * sec_board-msm8610.c
  3. * Samsung Mobile Battery Driver
  4. *
  5. * Copyright (C) 2012 Samsung Electronics
  6. *
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. */
  12. #include <linux/battery/sec_battery.h>
  13. #include <linux/battery/sec_fuelgauge.h>
  14. #include <linux/battery/sec_charging_common.h>
  15. #include <linux/qpnp/pin.h>
  16. #include <linux/qpnp/qpnp-adc.h>
  17. #if defined(CONFIG_EXTCON)
  18. int current_cable_type = POWER_SUPPLY_TYPE_BATTERY;
  19. #else
  20. extern int current_cable_type;
  21. #endif
  22. extern unsigned int system_rev;
  23. #if defined(CONFIG_FUELGAUGE_MAX17048)
  24. static struct battery_data_t samsung_battery_data[] = {
  25. /* SDI battery data (High voltage 4.35V) */
  26. {
  27. #if defined(CONFIG_MACH_HEAT_DYN)
  28. .RCOMP0 = 0x5C,
  29. .RCOMP_charging = 0x5C,
  30. .temp_cohot = -1000,
  31. .temp_cocold = -4350,
  32. .is_using_model_data = true,
  33. .type_str = "SDI",
  34. #else
  35. .RCOMP0 = 0x73,
  36. .RCOMP_charging = 0x8D,
  37. .temp_cohot = -1000,
  38. .temp_cocold = -4350,
  39. .is_using_model_data = true,
  40. .type_str = "SDI",
  41. #endif
  42. }
  43. };
  44. #elif defined(CONFIG_FUELGAUGE_MAX17050)
  45. static struct battery_data_t samsung_battery_data[] = {
  46. /* SDI battery data (High voltage 4.35V) */
  47. {
  48. #if defined(CONFIG_MACH_PICASSO)
  49. .Capacity = 0x3F76, /* N1/N2: 8123mAh */
  50. #elif defined(CONFIG_MACH_MONDRIAN)
  51. .Capacity = 0x2456, /* Mondrian : 4651mAh */
  52. #else
  53. .Capacity = 0x4A38, /* V1/V2: 9500mAh */
  54. #endif
  55. .low_battery_comp_voltage = 3500,
  56. .low_battery_table = {
  57. /* range, slope, offset */
  58. {-5000, 0, 0}, /* dummy for top limit */
  59. {-1250, 0, 3320},
  60. {-750, 97, 3451},
  61. {-100, 96, 3461},
  62. {0, 0, 3456},
  63. },
  64. .temp_adjust_table = {
  65. /* range, slope, offset */
  66. {47000, 122, 8950},
  67. {60000, 200, 51000},
  68. {100000, 0, 0}, /* dummy for top limit */
  69. },
  70. .type_str = "SDI",
  71. }
  72. };
  73. #else
  74. static void * samsung_battery_data;
  75. #endif
  76. #define CAPACITY_MAX 1000
  77. #define CAPACITY_MAX_MARGIN 50
  78. #define CAPACITY_MIN 0
  79. //static struct qpnp_vadc_chip *adc_client;
  80. static enum qpnp_vadc_channels temp_channel;
  81. static struct sec_fuelgauge_info *sec_fuelgauge = NULL;
  82. #if defined(CONFIG_MACH_HEAT_DYN)
  83. static sec_bat_adc_table_data_t temp_table[] = {
  84. {25898, 900},
  85. {26106, 850},
  86. {26351, 800},
  87. {26641, 750},
  88. {26982, 700},
  89. {27382, 650},
  90. {27839, 600},
  91. {28376, 550},
  92. {28999, 500},
  93. {29709, 450},
  94. {30849, 400},
  95. {31813, 350},
  96. {32821, 300},
  97. {33881, 250},
  98. {35007, 200},
  99. {36117, 150},
  100. {37207, 100},
  101. {38228, 50},
  102. {39170, 0},
  103. {39670, -50},
  104. {40436, -100},
  105. {41105, -150},
  106. {41653, -200},
  107. };
  108. #elif defined(CONFIG_SEC_KANAS_PROJECT)
  109. static sec_bat_adc_table_data_t temp_table[] = {
  110. {29153, 600},
  111. {29859, 550},
  112. {30576, 500},
  113. {31518, 450},
  114. {32491, 400},
  115. {33484, 350},
  116. {34508, 300},
  117. {35532, 250},
  118. {36556, 200},
  119. {37509, 150},
  120. {38481, 100},
  121. {39249, 50},
  122. {40017, 0},
  123. {40591, -50},
  124. {41154, -100},
  125. {41543, -150},
  126. {41902, -200},
  127. };
  128. #else
  129. static sec_bat_adc_table_data_t temp_table[] = {
  130. {27281, 700},
  131. {27669, 650},
  132. {28178, 600},
  133. {28724, 550},
  134. {29342, 500},
  135. {30101, 450},
  136. {30912, 400},
  137. {31807, 350},
  138. {32823, 300},
  139. {33858, 250},
  140. {34950, 200},
  141. {36049, 150},
  142. {37054, 100},
  143. {38025, 50},
  144. {38219, 40},
  145. {38448, 30},
  146. {38626, 20},
  147. {38795, 10},
  148. {38989, 0},
  149. {39229, -10},
  150. {39540, -30},
  151. {39687, -40},
  152. {39822, -50},
  153. {40523, -100},
  154. {41123, -150},
  155. {41619, -200},
  156. };
  157. #endif
  158. #if defined(CONFIG_MACH_HEAT_DYN)
  159. #define TEMP_HIGH_THRESHOLD_EVENT 500
  160. #define TEMP_HIGH_RECOVERY_EVENT 450
  161. #define TEMP_LOW_THRESHOLD_EVENT -50
  162. #define TEMP_LOW_RECOVERY_EVENT 0
  163. #define TEMP_HIGH_THRESHOLD_NORMAL 500
  164. #define TEMP_HIGH_RECOVERY_NORMAL 450
  165. #define TEMP_LOW_THRESHOLD_NORMAL -50
  166. #define TEMP_LOW_RECOVERY_NORMAL 0
  167. #define TEMP_HIGH_THRESHOLD_LPM 500
  168. #define TEMP_HIGH_RECOVERY_LPM 450
  169. #define TEMP_LOW_THRESHOLD_LPM -50
  170. #define TEMP_LOW_RECOVERY_LPM 0
  171. #elif defined(CONFIG_SEC_KANAS_PROJECT)
  172. #define TEMP_HIGH_THRESHOLD_EVENT 600
  173. #define TEMP_HIGH_RECOVERY_EVENT 460
  174. #define TEMP_LOW_THRESHOLD_EVENT -50
  175. #define TEMP_LOW_RECOVERY_EVENT 0
  176. #define TEMP_HIGH_THRESHOLD_NORMAL 600
  177. #define TEMP_HIGH_RECOVERY_NORMAL 460
  178. #define TEMP_LOW_THRESHOLD_NORMAL -50
  179. #define TEMP_LOW_RECOVERY_NORMAL 0
  180. #define TEMP_HIGH_THRESHOLD_LPM 600
  181. #define TEMP_HIGH_RECOVERY_LPM 460
  182. #define TEMP_LOW_THRESHOLD_LPM -50
  183. #define TEMP_LOW_RECOVERY_LPM 0
  184. #else
  185. #define TEMP_HIGH_THRESHOLD_EVENT 600
  186. #define TEMP_HIGH_RECOVERY_EVENT 460
  187. #define TEMP_LOW_THRESHOLD_EVENT -50
  188. #define TEMP_LOW_RECOVERY_EVENT 0
  189. #define TEMP_HIGH_THRESHOLD_NORMAL 600
  190. #define TEMP_HIGH_RECOVERY_NORMAL 460
  191. #define TEMP_LOW_THRESHOLD_NORMAL -50
  192. #define TEMP_LOW_RECOVERY_NORMAL 0
  193. #define TEMP_HIGH_THRESHOLD_LPM 600
  194. #define TEMP_HIGH_RECOVERY_LPM 460
  195. #define TEMP_LOW_THRESHOLD_LPM -50
  196. #define TEMP_LOW_RECOVERY_LPM 0
  197. #endif
  198. void sec_bat_check_batt_id(struct sec_battery_info *battery)
  199. {
  200. #if defined(CONFIG_SENSORS_QPNP_ADC_VOLTAGE)
  201. int rc, data = -1;
  202. struct qpnp_vadc_result results;
  203. rc = qpnp_vadc_read(NULL, LR_MUX2_BAT_ID, &results);
  204. if (rc) {
  205. pr_err("%s: Unable to read batt id rc=%d\n",
  206. __func__, rc);
  207. return;
  208. }
  209. data = results.adc_code;
  210. pr_info("%s: batt_id_adc = (%d)\n", __func__, data);
  211. #endif
  212. }
  213. static void sec_bat_adc_ap_init(struct platform_device *pdev,
  214. struct sec_battery_info *battery)
  215. {
  216. #if defined(CONFIG_SEC_KANAS_PROJECT)
  217. temp_channel = P_MUX3_1_1;
  218. #else
  219. temp_channel = LR_MUX1_BATT_THERM;
  220. #endif
  221. pr_info("%s : temp_channel = %d\n", __func__,temp_channel);
  222. }
  223. static int sec_bat_adc_ap_read(struct sec_battery_info *battery, int channel)
  224. {
  225. struct qpnp_vadc_result results;
  226. int rc = -1;
  227. int data = -1;
  228. switch (channel)
  229. {
  230. case SEC_BAT_ADC_CHANNEL_TEMP :
  231. rc = qpnp_vadc_read(NULL, temp_channel, &results);
  232. if (rc) {
  233. pr_err("%s: Unable to read batt temperature rc=%d\n",
  234. __func__, rc);
  235. return 0;
  236. }
  237. data = results.adc_code;
  238. break;
  239. case SEC_BAT_ADC_CHANNEL_TEMP_AMBIENT:
  240. data = 33000;
  241. break;
  242. case SEC_BAT_ADC_CHANNEL_BAT_CHECK :
  243. rc = qpnp_vadc_read(NULL, LR_MUX2_BAT_ID, &results);
  244. if (rc) {
  245. pr_err("%s: Unable to read BATT_ID ADC rc=%d\n",
  246. __func__, rc);
  247. return 0;
  248. }
  249. data = ((int)results.physical) / 1000;
  250. break;
  251. default :
  252. break;
  253. }
  254. pr_debug("%s: data(%d)\n", __func__, data);
  255. return data;
  256. }
  257. static void sec_bat_adc_ap_exit(void)
  258. {
  259. }
  260. static void sec_bat_adc_none_init(struct platform_device *pdev,
  261. struct sec_battery_info *battery)
  262. {
  263. }
  264. static int sec_bat_adc_none_read(struct sec_battery_info *battery, int channel)
  265. {
  266. return 0;
  267. }
  268. static void sec_bat_adc_none_exit(void)
  269. {
  270. }
  271. static void sec_bat_adc_ic_init(struct platform_device *pdev,
  272. struct sec_battery_info *battery)
  273. {
  274. }
  275. static int sec_bat_adc_ic_read(struct sec_battery_info *battery, int channel)
  276. {
  277. return 0;
  278. }
  279. static void sec_bat_adc_ic_exit(void)
  280. {
  281. }
  282. static int adc_read_type(struct sec_battery_info *battery, int channel)
  283. {
  284. int adc = 0;
  285. switch (battery->pdata->temp_adc_type)
  286. {
  287. case SEC_BATTERY_ADC_TYPE_NONE :
  288. adc = sec_bat_adc_none_read(battery, channel);
  289. break;
  290. case SEC_BATTERY_ADC_TYPE_AP :
  291. adc = sec_bat_adc_ap_read(battery, channel);
  292. break;
  293. case SEC_BATTERY_ADC_TYPE_IC :
  294. adc = sec_bat_adc_ic_read(battery, channel);
  295. break;
  296. case SEC_BATTERY_ADC_TYPE_NUM :
  297. break;
  298. default :
  299. break;
  300. }
  301. pr_debug("[%s] ADC = %d\n", __func__, adc);
  302. return adc;
  303. }
  304. static void adc_init_type(struct platform_device *pdev,
  305. struct sec_battery_info *battery)
  306. {
  307. switch (battery->pdata->temp_adc_type)
  308. {
  309. case SEC_BATTERY_ADC_TYPE_NONE :
  310. sec_bat_adc_none_init(pdev, battery);
  311. break;
  312. case SEC_BATTERY_ADC_TYPE_AP :
  313. sec_bat_adc_ap_init(pdev, battery);
  314. break;
  315. case SEC_BATTERY_ADC_TYPE_IC :
  316. sec_bat_adc_ic_init(pdev, battery);
  317. break;
  318. case SEC_BATTERY_ADC_TYPE_NUM :
  319. break;
  320. default :
  321. break;
  322. }
  323. }
  324. static void adc_exit_type(struct sec_battery_info *battery)
  325. {
  326. switch (battery->pdata->temp_adc_type)
  327. {
  328. case SEC_BATTERY_ADC_TYPE_NONE :
  329. sec_bat_adc_none_exit();
  330. break;
  331. case SEC_BATTERY_ADC_TYPE_AP :
  332. sec_bat_adc_ap_exit();
  333. break;
  334. case SEC_BATTERY_ADC_TYPE_IC :
  335. sec_bat_adc_ic_exit();
  336. break;
  337. case SEC_BATTERY_ADC_TYPE_NUM :
  338. break;
  339. default :
  340. break;
  341. }
  342. }
  343. int adc_read(struct sec_battery_info *battery, int channel)
  344. {
  345. int adc = 0;
  346. adc = adc_read_type(battery, channel);
  347. pr_info("[%s]adc = %d\n", __func__, adc);
  348. return adc;
  349. }
  350. void adc_exit(struct sec_battery_info *battery)
  351. {
  352. adc_exit_type(battery);
  353. }
  354. bool sec_bat_check_jig_status(void)
  355. {
  356. return (current_cable_type == POWER_SUPPLY_TYPE_UARTOFF);
  357. }
  358. /* callback for battery check
  359. * return : bool
  360. * true - battery detected, false battery NOT detected
  361. */
  362. bool sec_bat_check_callback(struct sec_battery_info *battery)
  363. {
  364. return true;
  365. }
  366. bool sec_bat_check_cable_result_callback(
  367. int cable_type)
  368. {
  369. return true;
  370. }
  371. int sec_bat_check_cable_callback(struct sec_battery_info *battery)
  372. {
  373. union power_supply_propval value;
  374. if (battery->pdata->ta_irq_gpio == 0) {
  375. pr_err("%s: ta_int_gpio is 0 or not assigned yet(cable_type(%d))\n",
  376. __func__, current_cable_type);
  377. } else {
  378. if (current_cable_type == POWER_SUPPLY_TYPE_BATTERY &&
  379. !gpio_get_value_cansleep(battery->pdata->ta_irq_gpio)) {
  380. pr_info("%s : VBUS IN\n", __func__);
  381. psy_do_property("battery", set, POWER_SUPPLY_PROP_ONLINE, value);
  382. return POWER_SUPPLY_TYPE_UARTOFF;
  383. }
  384. if ((current_cable_type == POWER_SUPPLY_TYPE_UARTOFF ||
  385. current_cable_type == POWER_SUPPLY_TYPE_CARDOCK) &&
  386. gpio_get_value_cansleep(battery->pdata->ta_irq_gpio)) {
  387. pr_info("%s : VBUS OUT\n", __func__);
  388. psy_do_property("battery", set, POWER_SUPPLY_PROP_ONLINE, value);
  389. return POWER_SUPPLY_TYPE_BATTERY;
  390. }
  391. }
  392. return current_cable_type;
  393. }
  394. void board_battery_init(struct platform_device *pdev, struct sec_battery_info *battery)
  395. {
  396. if ((!battery->pdata->temp_adc_table) &&
  397. (battery->pdata->thermal_source == SEC_BATTERY_THERMAL_SOURCE_ADC)) {
  398. pr_info("%s : assign temp adc table\n", __func__);
  399. battery->pdata->temp_adc_table = temp_table;
  400. battery->pdata->temp_amb_adc_table = temp_table;
  401. battery->pdata->temp_adc_table_size = sizeof(temp_table)/sizeof(sec_bat_adc_table_data_t);
  402. battery->pdata->temp_amb_adc_table_size = sizeof(temp_table)/sizeof(sec_bat_adc_table_data_t);
  403. }
  404. battery->pdata->temp_high_threshold_event = TEMP_HIGH_THRESHOLD_EVENT;
  405. battery->pdata->temp_high_recovery_event = TEMP_HIGH_RECOVERY_EVENT;
  406. battery->pdata->temp_low_threshold_event = TEMP_LOW_THRESHOLD_EVENT;
  407. battery->pdata->temp_low_recovery_event = TEMP_LOW_RECOVERY_EVENT;
  408. battery->pdata->temp_high_threshold_normal = TEMP_HIGH_THRESHOLD_NORMAL;
  409. battery->pdata->temp_high_recovery_normal = TEMP_HIGH_RECOVERY_NORMAL;
  410. battery->pdata->temp_low_threshold_normal = TEMP_LOW_THRESHOLD_NORMAL;
  411. battery->pdata->temp_low_recovery_normal = TEMP_LOW_RECOVERY_NORMAL;
  412. battery->pdata->temp_high_threshold_lpm = TEMP_HIGH_THRESHOLD_LPM;
  413. battery->pdata->temp_high_recovery_lpm = TEMP_HIGH_RECOVERY_LPM;
  414. battery->pdata->temp_low_threshold_lpm = TEMP_LOW_THRESHOLD_LPM;
  415. battery->pdata->temp_low_recovery_lpm = TEMP_LOW_RECOVERY_LPM;
  416. adc_init_type(pdev, battery);
  417. }
  418. void board_fuelgauge_init(struct sec_fuelgauge_info *fuelgauge)
  419. {
  420. sec_fuelgauge = fuelgauge;
  421. if (!fuelgauge->pdata->battery_data) {
  422. pr_info("%s : assign battery data\n", __func__);
  423. fuelgauge->pdata->battery_data = (void *)samsung_battery_data;
  424. }
  425. fuelgauge->pdata->capacity_max = CAPACITY_MAX;
  426. fuelgauge->pdata->capacity_max_margin = CAPACITY_MAX_MARGIN;
  427. fuelgauge->pdata->capacity_min = CAPACITY_MIN;
  428. #if defined(CONFIG_FUELGAUGE_MAX17048)
  429. pr_info("%s: RCOMP0: 0x%x, RCOMP_charging: 0x%x, "
  430. "temp_cohot: %d, temp_cocold: %d, "
  431. "is_using_model_data: %d, type_str: %s, "
  432. "capacity_max: %d, capacity_max_margin: %d, "
  433. "capacity_min: %d, \n", __func__ ,
  434. get_battery_data(fuelgauge).RCOMP0,
  435. get_battery_data(fuelgauge).RCOMP_charging,
  436. get_battery_data(fuelgauge).temp_cohot,
  437. get_battery_data(fuelgauge).temp_cocold,
  438. get_battery_data(fuelgauge).is_using_model_data,
  439. get_battery_data(fuelgauge).type_str,
  440. fuelgauge->pdata->capacity_max,
  441. fuelgauge->pdata->capacity_max_margin,
  442. fuelgauge->pdata->capacity_min
  443. );
  444. #endif
  445. }
  446. void cable_initial_check(struct sec_battery_info *battery)
  447. {
  448. union power_supply_propval value;
  449. pr_info("%s : current_cable_type : (%d)\n", __func__, current_cable_type);
  450. if (POWER_SUPPLY_TYPE_BATTERY != current_cable_type) {
  451. value.intval = current_cable_type;
  452. psy_do_property("battery", set,
  453. POWER_SUPPLY_PROP_ONLINE, value);
  454. } else {
  455. psy_do_property(battery->pdata->charger_name, get,
  456. POWER_SUPPLY_PROP_ONLINE, value);
  457. if (value.intval == POWER_SUPPLY_TYPE_WIRELESS) {
  458. value.intval =
  459. POWER_SUPPLY_TYPE_WIRELESS;
  460. psy_do_property("battery", set,
  461. POWER_SUPPLY_PROP_ONLINE, value);
  462. }
  463. }
  464. }