Advertisement
Guest User

Untitled

a guest
Jun 23rd, 2010
292
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 67.08 KB | None | 0 0
  1. /*
  2.  * linux/drivers/power/s3c6410_battery.c
  3.  *
  4.  * Battery measurement code for S3C6410 platform.
  5.  *
  6.  * based on palmtx_battery.c
  7.  *
  8.  * Copyright (C) 2009 Samsung Electronics.
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License version 2 as
  12.  * published by the Free Software Foundation.
  13.  *
  14.  */
  15.  
  16. #include <linux/kernel.h>
  17. #include <linux/module.h>
  18. #include <linux/power_supply.h>
  19. #include <linux/delay.h>
  20. #include <linux/spinlock.h>
  21. #include <linux/interrupt.h>
  22. #include <linux/gpio.h>
  23. #include <linux/platform_device.h>
  24. #include <linux/timer.h>
  25. #include <linux/jiffies.h>
  26. #include <linux/irq.h>
  27. #include <linux/wakelock.h>
  28. #include <asm/mach-types.h>
  29. #include <mach/hardware.h>
  30. #include <plat/gpio-cfg.h>
  31.  
  32. #include "s3c6410_battery.h"
  33.  
  34. static struct wake_lock vbus_wake_lock;
  35. #if (defined __TEST_DEVICE_DRIVER__  || defined __ALWAYS_AWAKE_DEVICE__)
  36. static struct wake_lock wake_lock_for_dev;
  37. #endif /* __TEST_DEVICE_DRIVER__ || __ALWAYS_AWAKE_DEVICE__ */
  38.  
  39. #ifdef __USE_EGPIO__
  40. #include <plat/egpio.h>
  41. #endif /* __USE_EGPIO__ */
  42.  
  43. #ifdef __TEST_DEVICE_DRIVER__
  44. #include <linux/i2c/pmic.h>
  45. #endif /* __TEST_DEVICE_DRIVER__ */
  46.  
  47. #ifdef __FUEL_GAUGES_IC__
  48. #include <linux/i2c.h>
  49. #include "fuel_gauge.c"
  50. #endif /* __FUEL_GAUGES_IC__ */
  51.  
  52. /* Prototypes */
  53. extern int s3c_adc_get_adc_data(int channel);
  54. extern int get_usb_power_state(void);
  55.  
  56. static ssize_t s3c_bat_show_property(struct device *dev,
  57.                                       struct device_attribute *attr,
  58.                                       char *buf);
  59. static ssize_t s3c_bat_store(struct device *dev,
  60.                  struct device_attribute *attr,
  61.                  const char *buf, size_t count);
  62. static void s3c_set_chg_en(int enable);
  63.  
  64. #ifdef __TEST_DEVICE_DRIVER__
  65. extern int amp_enable(int);
  66. extern int audio_power(int);
  67.  
  68. static ssize_t s3c_test_show_property(struct device *dev,
  69.                                       struct device_attribute *attr,
  70.                                       char *buf);
  71. static ssize_t s3c_test_store(struct device *dev,
  72.                  struct device_attribute *attr,
  73.                  const char *buf, size_t count);
  74. static int bat_temper_state = 0; // for test 1: overheat, 2: freeze
  75. #endif /* __TEST_DEVICE_DRIVER__ */
  76.  
  77. #ifdef __TEST_MODE_INTERFACE__
  78. static struct power_supply *s3c_power_supplies_test = NULL;
  79. static void polling_timer_func(unsigned long unused);
  80. static void s3c_bat_status_update(struct power_supply *bat_ps);
  81. #endif /* __TEST_MODE_INTERFACE__ */
  82.  
  83. #define ADC_DATA_ARR_SIZE   6
  84. #define ADC_TOTAL_COUNT     10
  85. #define POLLING_INTERVAL    10000     // GuybrushT mod, old: 2000
  86. #ifdef __TEST_MODE_INTERFACE__
  87. #define POLLING_INTERVAL_TEST   5000      // GuybrushT mod, old: 1000
  88. #endif /* __TEST_MODE_INTERFACE__ */
  89.  
  90. #ifdef __BATTERY_COMPENSATION__
  91. /* Offset Bit Value */
  92. #define OFFSET_VIBRATOR_ON      (0x1 << 0)
  93. #define OFFSET_CAMERA_ON        (0x1 << 1)
  94. #define OFFSET_MP3_PLAY         (0x1 << 2)
  95. #define OFFSET_VIDEO_PLAY       (0x1 << 3)
  96. #define OFFSET_VOICE_CALL_2G        (0x1 << 4)
  97. #define OFFSET_VOICE_CALL_3G        (0x1 << 5)
  98. #define OFFSET_DATA_CALL        (0x1 << 6)
  99. #define OFFSET_LCD_ON           (0x1 << 7)
  100. #define OFFSET_TA_ATTACHED      (0x1 << 8)
  101. #define OFFSET_CAM_FLASH        (0x1 << 9)
  102. #define OFFSET_BOOTING          (0x1 << 10)
  103. #endif /* __BATTERY_COMPENSATION__ */
  104.  
  105. #ifdef __9BITS_RESOLUTION__
  106. #define INVALID_VOL_ADC     20
  107. #else /* __9BITS_RESOLUTION__ */
  108. #define INVALID_VOL_ADC     160
  109. #endif /* __9BITS_RESOLUTION__ */
  110.  
  111. #define ENABLE      1
  112. #define DISABLE     0
  113.  
  114. #ifndef convert_adc2voltage
  115.     #ifdef __9BITS_RESOLUTION__
  116.     #define convert_adc2voltage(x)      (x * 10000 / 848)
  117.     #else /* __9BITS_RESOLUTION__ */
  118.     #define convert_adc2voltage(x)      ((x - 2170 ) * 10 / 7 + 3200)
  119.     #endif /* __9BITS_RESOLUTION__ */
  120. #endif /* convert_adc2voltage */
  121.  
  122. static struct work_struct bat_work;
  123. static struct work_struct cable_work;
  124.  
  125. #ifdef COMPENSATE_BOOTING
  126. static struct workqueue_struct *batt_drv_wqueue;
  127. static struct work_struct compensate_boot_work;
  128. #endif /* COMPENSATE_BOOTING */
  129.  
  130. static struct device *dev;
  131. static struct timer_list polling_timer;
  132. static struct timer_list cable_timer;
  133. static int cable_intr_cnt = 0;
  134.  
  135. static int s3c_battery_initial;
  136. static int force_update;
  137. static int full_charge_flag;
  138.  
  139. static int batt_max;
  140. static int batt_full;
  141. static int batt_safe_rech;
  142. static int batt_almost;
  143. static int batt_high;
  144. static int batt_medium;
  145. static int batt_low;
  146. static int batt_critical;
  147. static int batt_min;
  148. static int batt_off;
  149. #ifdef __ADJUST_RECHARGE_ADC__
  150. static int batt_recharging;
  151. #endif /* __ADJUST_RECHARGE_ADC__ */
  152. #ifdef __BATTERY_COMPENSATION__
  153. static int batt_compensation;
  154. #endif /* __BATTERY_COMPENSATION__ */
  155.  
  156. static unsigned int start_time_msec;
  157. static unsigned int total_time_msec;
  158.  
  159. #ifdef __BOARD_REV_ADC__
  160. static int board_rev_adc;
  161. static int is_end_board_rev_adc;
  162. #endif /* __BOARD_REV_ADC__ */
  163.  
  164. static char *status_text[] = {
  165.     [POWER_SUPPLY_STATUS_UNKNOWN] =     "Unknown",
  166.     [POWER_SUPPLY_STATUS_CHARGING] =    "Charging",
  167.     [POWER_SUPPLY_STATUS_DISCHARGING] = "Discharging",
  168.     [POWER_SUPPLY_STATUS_NOT_CHARGING] =    "Not Charging",
  169.     [POWER_SUPPLY_STATUS_FULL] =        "Full",
  170. };
  171.  
  172. typedef enum {
  173.     CHARGER_BATTERY = 0,
  174.     CHARGER_USB,
  175.     CHARGER_AC,
  176.     CHARGER_DISCHARGE
  177. } charger_type_t;
  178.  
  179. struct battery_info {
  180.     u32 batt_id;        /* Battery ID from ADC */
  181.     s32 batt_vol;       /* Battery voltage from ADC */
  182.     s32 batt_vol_adc;   /* Battery ADC value */
  183.     s32 batt_vol_adc_cal;   /* Battery ADC value (calibrated)*/
  184.     s32 batt_temp;      /* Battery Temperature (C) from ADC */
  185.     s32 batt_temp_adc;  /* Battery Temperature ADC value */
  186.     s32 batt_temp_adc_cal;  /* Battery Temperature ADC value (calibrated) */
  187.     s32 batt_current;   /* Battery current from ADC */
  188.     u32 level;      /* formula */
  189.     u32 charging_source;    /* 0: no cable, 1:usb, 2:AC */
  190.     u32 charging_enabled;   /* 0: Disable, 1: Enable */
  191.     u32 batt_health;    /* Battery Health (Authority) */
  192.     u32 batt_is_full;       /* 0 : Not full 1: Full */
  193.     u32 batt_is_recharging; /* 0 : Not recharging 1: Recharging */
  194.     s32 batt_vol_adc_aver;  /* batt vol adc average */
  195. #ifdef __TEST_MODE_INTERFACE__
  196.     u32 batt_test_mode; /* test mode */
  197.     s32 batt_vol_aver;  /* batt vol average */
  198.     s32 batt_temp_aver; /* batt temp average */
  199.     s32 batt_temp_adc_aver; /* batt temp adc average */
  200.     s32 batt_v_f_adc;   /* batt V_F adc */
  201. #endif /* __TEST_MODE_INTERFACE__ */
  202. };
  203.  
  204. /* lock to protect the battery info */
  205. static DEFINE_MUTEX(work_lock);
  206.  
  207. struct s3c_battery_info {
  208.     int present;
  209.     int polling;
  210.     unsigned int polling_interval;
  211.     unsigned int device_state;
  212.  
  213.     struct battery_info bat_info;
  214. };
  215. static struct s3c_battery_info s3c_bat_info;
  216.  
  217. struct adc_sample_info {
  218.     unsigned int cnt;
  219.     int total_adc;
  220.     int average_adc;
  221.     int adc_arr[ADC_TOTAL_COUNT];
  222.     int index;
  223. };
  224. static struct adc_sample_info adc_sample[ENDOFADC];
  225.  
  226. static inline int s3c_adc_get_adc_data_ex(int channel) {
  227. #ifndef __9BITS_RESOLUTION__
  228.     return s3c_adc_get_adc_data(channel);
  229. #else
  230. #ifdef __REVERSE_TEMPER_ADC__
  231.     if (channel == S3C_ADC_TEMPERATURE)
  232.         return (4096 - s3c_adc_get_adc_data(channel)) / 8;
  233.     else
  234. #endif /* __REVERSE_TEMPER_ADC__ */
  235.         return s3c_adc_get_adc_data(channel) / 8;
  236. #endif /* __9BITS_RESOLUTION__ */
  237. }
  238.  
  239. #ifdef __CHECK_CHG_CURRENT__
  240. static inline void clear_adc_sample(adc_channel_type channel)
  241. {
  242.     adc_sample[channel].cnt = 0;
  243.     adc_sample[channel].total_adc = 0;
  244. }
  245. #endif /* __CHECK_CHG_CURRENT__ */
  246.  
  247. static unsigned long calculate_average_adc(adc_channel_type channel, int adc)
  248. {
  249.     unsigned int cnt = 0;
  250.     int total_adc = 0;
  251.     int average_adc = 0;
  252.     int index = 0;
  253.  
  254.     cnt = adc_sample[channel].cnt;
  255.     total_adc = adc_sample[channel].total_adc;
  256.  
  257.     if (adc < 0 || adc == 0) {
  258.         dev_err(dev, "%s: invalid adc : %d(ch:%d)\n", __func__,
  259.                 adc, channel);
  260.         adc = adc_sample[channel].average_adc;
  261.     }
  262.  
  263.     if( cnt < ADC_TOTAL_COUNT ) {
  264.         adc_sample[channel].adc_arr[cnt] = adc;
  265.         adc_sample[channel].index = cnt;
  266.         adc_sample[channel].cnt = ++cnt;
  267.  
  268.         total_adc += adc;
  269.         average_adc = total_adc / cnt;
  270.     } else {
  271. #if 0
  272.         if (channel == S3C_ADC_VOLTAGE &&
  273.                 !s3c_bat_info.bat_info.charging_enabled &&
  274.                 adc > adc_sample[channel].average_adc) {
  275.             dev_dbg(dev, "%s: adc over avg : %d\n", __func__, adc);
  276.             return adc_sample[channel].average_adc;
  277.         }
  278. #endif
  279.         index = adc_sample[channel].index;
  280.         if (++index >= ADC_TOTAL_COUNT)
  281.             index = 0;
  282.  
  283.         total_adc = (total_adc - adc_sample[channel].adc_arr[index]) + adc;
  284.         average_adc = total_adc / ADC_TOTAL_COUNT;
  285.  
  286.         adc_sample[channel].adc_arr[index] = adc;
  287.         adc_sample[channel].index = index;
  288.     }
  289.  
  290.     adc_sample[channel].total_adc = total_adc;
  291.     adc_sample[channel].average_adc = average_adc;
  292.  
  293.     dev_dbg(dev, "%s: ch:%d adc=%d, avg_adc=%d\n",
  294.             __func__, channel, adc, average_adc);
  295.     return average_adc;
  296. }
  297.  
  298. static int s3c_bat_get_adc_data(adc_channel_type adc_ch)
  299. {
  300.     int adc_arr[ADC_DATA_ARR_SIZE];
  301.     int adc_max = 0;
  302.     int adc_min = 0;
  303.     int adc_total = 0;
  304.     int i;
  305.  
  306.     for (i = 0; i < ADC_DATA_ARR_SIZE; i++) {
  307.         adc_arr[i] = s3c_adc_get_adc_data_ex(adc_ch);
  308.         dev_dbg(dev, "%s: adc_arr = %d\n", __func__, adc_arr[i]);
  309.         if (i != 0) {
  310.             if (adc_arr[i] > adc_max)
  311.                 adc_max = adc_arr[i];
  312.             else if (adc_arr[i] < adc_min)
  313.                 adc_min = adc_arr[i];
  314.         } else {
  315.             adc_max = adc_arr[0];
  316.             adc_min = adc_arr[0];
  317.         }
  318.         adc_total += adc_arr[i];
  319.     }
  320.  
  321.     dev_dbg(dev, "%s: adc_max = %d, adc_min = %d\n",
  322.             __func__, adc_max, adc_min);
  323.     return (adc_total - adc_max - adc_min) / (ADC_DATA_ARR_SIZE - 2);
  324. }
  325.  
  326. #ifndef __FUEL_GAUGES_IC__
  327. static unsigned long s3c_read_bat(struct power_supply *bat_ps)
  328. {
  329.     int adc = 0;
  330.     static int cnt = 0;
  331.  
  332.     dev_dbg(dev, "%s\n", __func__);
  333.  
  334.     adc = s3c_bat_get_adc_data(S3C_ADC_VOLTAGE);
  335.     dev_dbg(dev, "%s: adc = %d\n", __func__, adc);
  336.  
  337. #ifdef __BATTERY_COMPENSATION__
  338.     adc += batt_compensation;
  339. #endif /* __BATTERY_COMPENSATION__ */
  340.     if (adc < s3c_bat_info.bat_info.batt_vol_adc_aver - INVALID_VOL_ADC
  341.             && cnt < 10) {
  342.         dev_err(dev, "%s: invalid adc = %d\n", __func__, adc);
  343.         adc = s3c_bat_info.bat_info.batt_vol_adc_aver;
  344.         cnt++;
  345.     } else {
  346.         cnt = 0;
  347.     }
  348.     s3c_bat_info.bat_info.batt_vol_adc =  adc;
  349.  
  350.     return calculate_average_adc(S3C_ADC_VOLTAGE, adc);
  351. }
  352. #endif /* __FUEL_GAUGES_IC__ */
  353.  
  354. static unsigned long s3c_read_temp(struct power_supply *bat_ps)
  355. {
  356.     int adc = 0;
  357.  
  358.     dev_dbg(dev, "%s\n", __func__);
  359.  
  360.     adc = s3c_bat_get_adc_data(S3C_ADC_TEMPERATURE);
  361.     dev_dbg(dev, "%s: adc = %d\n", __func__, adc);
  362.  
  363. #ifdef __TEST_DEVICE_DRIVER__
  364.     switch (bat_temper_state) {
  365.     case 0:
  366.         break;
  367.     case 1:
  368.         adc = TEMP_HIGH_BLOCK;
  369.         break;
  370.     case 2:
  371.         adc = TEMP_LOW_BLOCK;
  372.         break;
  373.     default:
  374.         break;
  375.     }
  376. #endif /* __TEST_DEVICE_DRIVER__ */
  377.  
  378.     s3c_bat_info.bat_info.batt_temp_adc = adc;
  379.  
  380. #ifdef __AVG_TEMP_ADC__
  381.     return calculate_average_adc(S3C_ADC_TEMPERATURE, adc);
  382. #else /* __AVG_TEMP_ADC__ */
  383.     return adc;
  384. #endif /* __AVG_TEMP_ADC__ */
  385. }
  386.  
  387. static u32 s3c_get_bat_health(void)
  388. {
  389.     return s3c_bat_info.bat_info.batt_health;
  390. }
  391.  
  392. static void s3c_set_bat_health(u32 batt_health)
  393. {
  394.     s3c_bat_info.bat_info.batt_health = batt_health;
  395. }
  396.  
  397. static int is_over_abs_time(void)
  398. {
  399.     unsigned int total_time;
  400.  
  401.     if (!start_time_msec)
  402.         return 0;
  403.  
  404.     if (s3c_bat_info.bat_info.batt_is_recharging)
  405.         total_time = TOTAL_RECHARGING_TIME;
  406.     else
  407.         total_time = TOTAL_CHARGING_TIME;
  408.  
  409.     total_time_msec = jiffies_to_msecs(jiffies) - start_time_msec;
  410.     if (total_time_msec > total_time)
  411.         return 1;
  412.     else
  413.         return 0;
  414. }
  415.  
  416. #ifdef __BATTERY_COMPENSATION__
  417. static void s3c_bat_set_compesation(int mode,
  418.                     int offset,
  419.                     int compensate_value)
  420. {
  421.     if (mode) {
  422.         if (!(s3c_bat_info.device_state & offset)) {
  423.             s3c_bat_info.device_state |= offset;
  424.             batt_compensation += compensate_value;
  425.         }
  426.     } else {
  427.         if (s3c_bat_info.device_state & offset) {
  428.             s3c_bat_info.device_state &= ~offset;
  429.             batt_compensation -= compensate_value;
  430.         }
  431.     }
  432.     dev_dbg(dev, "%s: device_state=0x%x, compensation=%d\n", __func__,
  433.             s3c_bat_info.device_state, batt_compensation);
  434. }
  435. #endif /* __BATTERY_COMPENSATION__ */
  436.  
  437. #ifdef __CHECK_CHG_CURRENT__
  438. static int s3c_read_current(struct power_supply *bat_ps)
  439. {
  440.     int adc = 0;
  441.     adc = s3c_bat_get_adc_data(S3C_ADC_CHG_CURRENT);
  442.     dev_dbg(dev, "%s: adc = %d\n", __func__, adc);
  443.  
  444.     return calculate_average_adc(S3C_ADC_CHG_CURRENT, adc);
  445. }
  446.  
  447. static void check_chg_current(struct power_supply *bat_ps)
  448. {
  449.     static int cnt = 0;
  450.     int chg_current = 0;
  451.  
  452.     chg_current = s3c_read_current(bat_ps);
  453.     s3c_bat_info.bat_info.batt_current = chg_current;
  454.     if (chg_current <= CURRENT_OF_FULL_CHG) {
  455.         cnt++;
  456.         if (cnt >= 10) {
  457.             dev_info(dev, "%s: battery full(%d)\n",
  458.                     __func__, chg_current);
  459.             s3c_set_chg_en(DISABLE);
  460.             s3c_bat_info.bat_info.batt_is_full = 1;
  461.             force_update = 1;
  462.             full_charge_flag = 1;
  463.             cnt = 0;
  464.             clear_adc_sample(S3C_ADC_CHG_CURRENT);
  465.         }
  466.     } else {
  467.         cnt = 0;
  468.     }
  469.     dev_dbg(dev, "%s: chg_current=%d\n", __func__, chg_current);
  470. }
  471. #endif /* __CHECK_CHG_CURRENT__ */
  472.  
  473. #ifdef __ADJUST_RECHARGE_ADC__
  474. static void check_recharging_bat(int bat_vol)
  475. {
  476.     static int cnt = 0;
  477.  
  478.     if (s3c_get_bat_health() != POWER_SUPPLY_HEALTH_GOOD)
  479.         goto out;
  480.  
  481.     if (!s3c_bat_info.bat_info.batt_is_full ||
  482.         s3c_bat_info.bat_info.charging_enabled)
  483.         goto out;
  484.  
  485.     if (batt_recharging != -1 && bat_vol <= batt_recharging) {
  486.         if (++cnt >= 3) {
  487.             dev_info(dev, "%s: recharging(adj):%d\n", __func__,
  488.                     bat_vol);
  489.             s3c_bat_info.bat_info.batt_is_recharging = 1;
  490.             s3c_set_chg_en(ENABLE);
  491.             goto out;
  492.         }
  493.     } else {
  494.         cnt = 0;
  495.     }
  496.  
  497.     if (bat_vol <= batt_safe_rech ) {
  498.         dev_info(dev, "%s: recharging(safe):%d\n", __func__, bat_vol);
  499.         s3c_bat_info.bat_info.batt_is_recharging = 1;
  500.         s3c_set_chg_en(ENABLE);
  501.         goto out;
  502.     }
  503.    
  504.     return;
  505. out:
  506.     cnt = 0;
  507.     return;
  508. }
  509. #else /* __ADJUST_RECHARGE_ADC__ */
  510. #ifdef __FUEL_GAUGES_IC__
  511. static void check_recharging_bat(int fg_vcell)
  512. {
  513.     static int cnt = 0;
  514.  
  515.     if (s3c_get_bat_health() != POWER_SUPPLY_HEALTH_GOOD) {
  516.         cnt = 0;
  517.         return;
  518.     }
  519.  
  520.     if (s3c_bat_info.bat_info.batt_is_full &&
  521.         !s3c_bat_info.bat_info.charging_enabled &&
  522.         (fg_vcell <= RECHARGE_COND_VOLTAGE ||
  523.             fg_vcell <= FULL_CHARGE_COND_VOLTAGE)) {
  524.         if (++cnt >= 10) {
  525.             dev_info(dev, "%s: recharging(vcell:%d)\n", __func__,
  526.                     fg_vcell);
  527.             s3c_bat_info.bat_info.batt_is_recharging = 1;
  528.             s3c_set_chg_en(ENABLE);
  529.             cnt = 0;
  530.         }
  531.     } else {
  532.         cnt = 0;
  533.     }
  534. }
  535. #else /* __FUEL_GAUGES_IC__ */
  536. static void check_recharging_bat(int bat_vol)
  537. {
  538.     static int cnt = 0;
  539.  
  540.     if (s3c_get_bat_health() != POWER_SUPPLY_HEALTH_GOOD) {
  541.         cnt = 0;
  542.         return;
  543.     }
  544.  
  545.     if (bat_vol > batt_safe_rech ) {
  546.         cnt = 0;
  547.         return;
  548.     }
  549.  
  550.     if (s3c_bat_info.bat_info.batt_is_full &&
  551.         !s3c_bat_info.bat_info.charging_enabled) {
  552.         if (++cnt >= 10) {
  553.             dev_info(dev, "%s: recharging(safe), (adc:%d)\n",
  554.                     __func__, bat_vol);
  555.             s3c_bat_info.bat_info.batt_is_recharging = 1;
  556.             s3c_set_chg_en(ENABLE);
  557.             cnt = 0;
  558.         }
  559.     } else {
  560.         cnt = 0;
  561.     }
  562. }
  563. #endif /* __FUEL_GAUGES_IC__ */
  564. #endif /* __ADJUST_RECHARGE_ADC__ */
  565.  
  566. #ifndef __FUEL_GAUGES_IC__
  567. #ifdef __ANDROID_BAT_LEVEL_CONCEPT__
  568. static int s3c_get_bat_level(struct power_supply *bat_ps)
  569. {
  570.     int bat_level = 0;
  571.     int bat_vol = s3c_read_bat(bat_ps);
  572.  
  573.     s3c_bat_info.bat_info.batt_vol_adc_aver = bat_vol;
  574.  
  575.     if(is_over_abs_time()) {
  576.         bat_level = 100;
  577.         s3c_bat_info.bat_info.batt_is_full = 1;
  578.         dev_info(dev, "%s: charging time is over\n", __func__);
  579.         s3c_set_chg_en(DISABLE);
  580.         goto __end__;
  581.     }
  582.  
  583. #ifdef __BATTERY_COMPENSATION__
  584.     if (s3c_bat_info.bat_info.charging_enabled) {
  585.         if (bat_vol > batt_full - COMPENSATE_TA) {
  586.             s3c_bat_set_compesation(0, OFFSET_TA_ATTACHED,
  587.                     COMPENSATE_TA);
  588.         }
  589.     }
  590. #endif /* __BATTERY_COMPENSATION__ */
  591.  
  592.     check_recharging_bat(bat_vol);
  593.  
  594.     if (bat_vol > batt_full) {
  595.         int temp = 5;   /* 100% : 4.03V ADC : 341  Offset : 45 */
  596.         if (bat_vol > (batt_full + temp) ||
  597.                 s3c_bat_info.bat_info.batt_is_full)
  598.             bat_level = 100;
  599.         else
  600.             bat_level = 90;
  601.  
  602. #ifdef __CHECK_CHG_CURRENT__
  603.         if (s3c_bat_info.bat_info.charging_enabled) {
  604.             check_chg_current(bat_ps);
  605.             if (!s3c_bat_info.bat_info.batt_is_full)
  606.                 bat_level = 90;
  607.         }
  608. #endif /* __CHECK_CHG_CURRENT__ */
  609.         dev_dbg(dev, "%s: (full)level = %d\n", __func__, bat_level );
  610.     } else if (batt_full >= bat_vol && bat_vol > batt_almost) {
  611.         int temp = (batt_full - batt_almost) / 3;
  612.         if (bat_vol > (batt_almost + temp * 5 / 2))
  613.             bat_level = 95;
  614.         else if (bat_vol > (batt_almost + temp * 2))
  615.             bat_level = 90;
  616.         else if (bat_vol > (batt_almost + temp * 3 / 2))
  617.             bat_level = 85;
  618.         else if (bat_vol > (batt_almost + temp))
  619.             bat_level = 80;
  620.         else if (bat_vol > (batt_almost + temp / 2))
  621.             bat_level = 75;
  622.         else
  623.             bat_level = 70;
  624.  
  625.         if (s3c_bat_info.bat_info.batt_is_recharging)
  626.             bat_level = 100;
  627.  
  628.         dev_dbg(dev, "%s: (almost)level = %d\n", __func__, bat_level);
  629.     } else if (batt_almost >= bat_vol && bat_vol > batt_high) {
  630.         int temp = (batt_almost - batt_high) / 2;
  631.         if (bat_vol > (batt_high + temp * 3 / 2))
  632.             bat_level = 65;
  633.         else if (bat_vol > (batt_high + temp))
  634.             bat_level = 60;
  635.         else if (bat_vol > (batt_high + temp / 2))
  636.             bat_level = 55;
  637.         else
  638.             bat_level = 50;
  639.         dev_dbg(dev, "%s: (high)level = %d\n", __func__, bat_level );
  640.     } else if (batt_high >= bat_vol && bat_vol > batt_medium) {
  641.         int temp = (batt_high - batt_medium) / 2;
  642.         if (bat_vol > (batt_medium + temp * 3 / 2))
  643.             bat_level = 45;
  644.         else if (bat_vol > (batt_medium + temp))
  645.             bat_level = 40;
  646.         else if (bat_vol > (batt_medium + temp / 2))
  647.             bat_level = 35;
  648.         else
  649.             bat_level = 30;
  650.         dev_dbg(dev, "%s: (med)level = %d\n", __func__, bat_level);
  651.     } else if (batt_medium >= bat_vol && bat_vol > batt_low) {
  652.         int temp = (batt_medium - batt_low) / 3;
  653.         if (bat_vol > (batt_low + temp * 2))
  654.             bat_level = 25;
  655.         else if (bat_vol > (batt_low + temp))
  656.             bat_level = 20;
  657.         else
  658.             bat_level = 15;
  659.         dev_dbg(dev, "%s: (low)level = %d\n", __func__, bat_level);
  660.     } else if (batt_low >= bat_vol && bat_vol > batt_critical) {
  661.         int temp = (batt_low - batt_critical) / 2;
  662.         if (bat_vol > (batt_critical + temp))
  663.             bat_level = 10;
  664.         else
  665.             bat_level = 5;
  666.         dev_dbg(dev, "%s: (cri)level = %d, vol = %d\n", __func__,
  667.                 bat_level, bat_vol);
  668.     } else if (batt_critical >= bat_vol && bat_vol > batt_min) {
  669.         bat_level = 3;
  670.         dev_info(dev, "%s: (min)level = %d, vol = %d\n", __func__,
  671.                 bat_level, bat_vol);
  672.     } else if (batt_min >= bat_vol && bat_vol > batt_off) {
  673.         bat_level = 1;
  674.         dev_info(dev, "%s: (off)level = %d, vol = %d\n", __func__,
  675.                 bat_level, bat_vol);
  676.     } else if (batt_off >= bat_vol)  {
  677.         bat_level = 0;
  678.         dev_info(dev, "%s: (off)level = %d, vol = %d", __func__,
  679.                 bat_level, bat_vol);
  680.     }
  681.     dev_dbg(dev, "%s: level = %d\n", __func__, bat_level);
  682.  
  683. __end__:
  684.     dev_dbg(dev, "%s: bat_vol = %d, level = %d, is_full = %d\n",
  685.             __func__, bat_vol, bat_level,
  686.             s3c_bat_info.bat_info.batt_is_full);
  687. #ifdef __TEMP_ADC_VALUE__
  688.     return 80;
  689. #else
  690.     return bat_level;
  691. #endif /* __TEMP_ADC_VALUE__ */
  692. }
  693. #else /* __ANDROID_BAT_LEVEL_CONCEPT__ */
  694.  
  695. /*
  696.  *  Modded by GuybrushT
  697.  */
  698.  
  699.  
  700.  
  701. static int s3c_get_bat_level(struct power_supply *bat_ps)
  702. {
  703.     int bat_level = 0;
  704.     int bat_vol = s3c_read_bat(bat_ps);
  705.  
  706.     s3c_bat_info.bat_info.batt_vol_adc_aver = bat_vol;
  707.  
  708.     if(is_over_abs_time()) {
  709.         bat_level = 100;
  710.         s3c_bat_info.bat_info.batt_is_full = 1;
  711.         dev_info(dev, "%s: charging time is over\n", __func__);
  712.         s3c_set_chg_en(DISABLE);
  713.         goto __end__;
  714.     }
  715.  
  716. #ifdef __BATTERY_COMPENSATION__
  717.     if (s3c_bat_info.bat_info.charging_enabled) {
  718.         if (bat_vol > batt_almost - COMPENSATE_TA) {
  719.             s3c_bat_set_compesation(0, OFFSET_TA_ATTACHED,
  720.                     COMPENSATE_TA);
  721.         }
  722.     }
  723. #endif /* __BATTERY_COMPENSATION__ */
  724.  
  725.     if (bat_vol > batt_full) {
  726.         bat_level = 100;
  727. #ifdef __CHECK_CHG_CURRENT__
  728.         if (s3c_bat_info.bat_info.charging_enabled) {
  729.             check_chg_current(bat_ps);
  730.             if (!s3c_bat_info.bat_info.batt_is_full)
  731.                 bat_level = 90;
  732.         }
  733. #endif /* __CHECK_CHG_CURRENT__ */
  734. #ifdef __ADJUST_RECHARGE_ADC__
  735.         check_recharging_bat(bat_vol);
  736. #endif /* __ADJUST_RECHARGE_ADC__ */
  737.         dev_dbg(dev, "%s: (full)level = %d\n", __func__, bat_level );
  738.     } else if (batt_full >= bat_vol && bat_vol > batt_almost) {
  739.         int temp = (batt_full - batt_almost) / 3;
  740.         if (bat_vol > (batt_almost + temp * 5 / 2))
  741.             bat_level = 95;
  742.         else if (bat_vol > (batt_almost + temp * 2))
  743.             bat_level = 90;
  744.         else if (bat_vol > (batt_almost + temp * 3 / 2))
  745.             bat_level = 85;
  746.         else if (bat_vol > (batt_almost + temp))
  747.             bat_level = 80;
  748.         else if (bat_vol > (batt_almost + temp / 2))
  749.             bat_level = 75;
  750.         else
  751.             bat_level = 70;
  752.  
  753.         if (s3c_bat_info.bat_info.batt_is_recharging)
  754.             bat_level = 100;
  755.  
  756.         if (s3c_bat_info.bat_info.batt_is_full &&
  757.             !s3c_bat_info.bat_info.charging_enabled) {
  758.             dev_info(dev, "%s: recharging(under full)\n", __func__);
  759.             s3c_bat_info.bat_info.batt_is_recharging = 1;
  760.             s3c_set_chg_en(ENABLE);
  761.             bat_level = 100;
  762.         }
  763.         dev_dbg(dev, "%s: (almost)level = %d\n", __func__, bat_level);
  764.     } else if (batt_almost >= bat_vol && bat_vol > batt_high) {
  765.         int temp = (batt_almost - batt_high) / 2;
  766.         if (bat_vol > (batt_high + temp * 3 / 2))
  767.             bat_level = 65;
  768.         else if (bat_vol > (batt_high + temp))
  769.             bat_level = 60;
  770.         else if (bat_vol > (batt_high + temp / 2))
  771.             bat_level = 55;
  772.         else
  773.             bat_level = 50;
  774.  
  775.         dev_dbg(dev, "%s: (high)level = %d\n", __func__, bat_level );
  776.     } else if (batt_high >= bat_vol && bat_vol > batt_medium) {
  777.         int temp = (batt_high - batt_medium) / 2;
  778.         if (bat_vol > (batt_medium + temp * 3 / 2))
  779.             bat_level = 45;
  780.         else if (bat_vol > (batt_medium + temp))
  781.             bat_level = 40;
  782.         else if (bat_vol > (batt_medium + temp / 2))
  783.             bat_level = 35;
  784.         else
  785.             bat_level = 30;
  786.         dev_dbg(dev, "%s: (med)level = %d\n", __func__, bat_level);
  787.     } else if (batt_medium >= bat_vol && bat_vol > batt_low) {
  788.         int temp = (batt_medium - batt_low) / 3;
  789.         if (bat_vol > (batt_low + temp * 2))
  790.             bat_level = 25;
  791.         else if (bat_vol > (batt_low + temp))
  792.             bat_level = 20;
  793.         else
  794.             bat_level = 15;
  795.         dev_dbg(dev, "%s: (low)level = %d\n", __func__, bat_level);
  796.     } else if (batt_low >= bat_vol && bat_vol > batt_critical) {
  797.         int temp = (batt_low - batt_critical) / 2;
  798.         if (bat_vol > (batt_critical + temp))
  799.             bat_level = 10;
  800.         else
  801.             bat_level = 5;
  802.         dev_info(dev, "%s: (cri)level = %d, vol = %d\n", __func__,
  803.                 bat_level, bat_vol);
  804.     } else if (batt_critical >= bat_vol && bat_vol > batt_min) {
  805.         bat_level = 3;
  806.         dev_info(dev, "%s: (min)level = %d, vol = %d\n", __func__,
  807.                 bat_level, bat_vol);
  808.     } else if (batt_min >= bat_vol && bat_vol > batt_off) {
  809.         bat_level = 1;
  810.         dev_info(dev, "%s: (off)level = %d, vol = %d\n", __func__,
  811.                 bat_level, bat_vol);
  812.     } else if (batt_off >= bat_vol)  {
  813.         bat_level = 0;
  814.         dev_info(dev, "%s: (off)level = %d, vol = %d", __func__,
  815.                 bat_level, bat_vol);
  816.     }
  817.     dev_dbg(dev, "%s: level = %d\n", __func__, bat_level);
  818.  
  819. __end__:
  820.     dev_dbg(dev, "%s: bat_vol = %d, level = %d, is_full = %d\n",
  821.             __func__, bat_vol, bat_level,
  822.             s3c_bat_info.bat_info.batt_is_full);
  823. #ifdef __TEMP_ADC_VALUE__
  824.     return 80;
  825. #else
  826.     return bat_level;
  827. #endif /* __TEMP_ADC_VALUE__ */
  828. }
  829. #endif /* __ANDROID_BAT_LEVEL_CONCEPT__ */
  830.  
  831. static int s3c_get_bat_vol(struct power_supply *bat_ps)
  832. {
  833.     int bat_vol = 0;
  834.     int adc = s3c_bat_info.bat_info.batt_vol_adc;
  835. #ifdef __TEST_MODE_INTERFACE__
  836.     int batt_vol_adc_aver = s3c_bat_info.bat_info.batt_vol_adc_aver;
  837.     s3c_bat_info.bat_info.batt_vol_aver =
  838.         convert_adc2voltage(batt_vol_adc_aver);
  839. #endif /* __TEST_MODE_INTERFACE__ */
  840.  
  841.     bat_vol = convert_adc2voltage(adc);
  842.  
  843.     dev_dbg(dev, "%s: adc = %d, bat_vol = %d\n",
  844.             __func__, adc, bat_vol);
  845.  
  846.     return bat_vol;
  847. }
  848. #else /* __FUEL_GAUGES_IC__ */
  849. static int s3c_get_bat_level(struct power_supply *bat_ps)
  850. {
  851.     int fg_soc = -1;
  852.     int fg_vcell = -1;
  853.  
  854.     if ((fg_soc = fg_read_soc()) < 0) {
  855.         dev_err(dev, "%s: Can't read soc!!!\n", __func__);
  856.         fg_soc = s3c_bat_info.bat_info.level;
  857.     }
  858.    
  859.     if ((fg_vcell = fg_read_vcell()) < 0) {
  860.         dev_err(dev, "%s: Can't read vcell!!!\n", __func__);
  861.         fg_vcell = s3c_bat_info.bat_info.batt_vol;
  862.     } else
  863.         s3c_bat_info.bat_info.batt_vol = fg_vcell;
  864.  
  865.     if (is_over_abs_time()) {
  866.         fg_soc = 100;
  867.         s3c_bat_info.bat_info.batt_is_full = 1;
  868.         dev_info(dev, "%s: charging time is over\n", __func__);
  869.         s3c_set_chg_en(DISABLE);
  870.         goto __end__;
  871.     }
  872.  
  873.     if (fg_soc > 80) {
  874.         fg_soc += fg_soc - 80;
  875.  
  876.         if (fg_soc > 100)
  877.             fg_soc = 100;
  878.     }
  879. #ifdef __CHECK_CHG_CURRENT__
  880.     if (fg_vcell >= FULL_CHARGE_COND_VOLTAGE) {
  881.         if (s3c_bat_info.bat_info.charging_enabled) {
  882.             check_chg_current(bat_ps);
  883.             if (s3c_bat_info.bat_info.batt_is_full)
  884.                 fg_soc = 100;
  885.         }
  886.     }
  887. #endif /* __CHECK_CHG_CURRENT__ */
  888.  
  889.     check_recharging_bat(fg_vcell);
  890.  
  891. __end__:
  892.     dev_dbg(dev, "%s: fg_vcell = %d, fg_soc = %d, is_full = %d\n",
  893.             __func__, fg_vcell, fg_soc,
  894.             s3c_bat_info.bat_info.batt_is_full);
  895.     return fg_soc;
  896. }
  897.  
  898. static int s3c_get_bat_vol(struct power_supply *bat_ps)
  899. {
  900.     return s3c_bat_info.bat_info.batt_vol;
  901. }
  902. #endif /* __FUEL_GAUGES_IC__ */
  903.  
  904. #ifdef __BOARD_REV_ADC__
  905. static void s3c_get_board_rev_adc(struct power_supply *bat_ps)
  906. {
  907.     static unsigned int cnt = 0;
  908.     int adc = 0;
  909.  
  910.     adc = s3c_bat_get_adc_data(S3C_ADC_BOARD_REV);
  911.     board_rev_adc = calculate_average_adc(S3C_ADC_BOARD_REV, adc);
  912.     dev_dbg(dev, "%s: adc=%d, avg_adc=%d\n", __func__, adc, board_rev_adc);
  913.  
  914.     if (++cnt >= 10)
  915.         is_end_board_rev_adc = 1;
  916. }
  917. #endif /* __BOARD_REV_ADC__ */
  918.  
  919. #if (defined __TEST_MODE_INTERFACE__ && defined __BATTERY_V_F__)
  920. static void s3c_get_v_f_adc(void)
  921. {
  922.     s3c_bat_info.bat_info.batt_v_f_adc
  923.         = s3c_bat_get_adc_data(S3C_ADC_V_F);
  924.     dev_info(dev, "%s: vf=%d\n", __func__,
  925.             s3c_bat_info.bat_info.batt_v_f_adc);
  926. }
  927. #endif /* __TEST_MODE_INTERFACE__ && __BATTERY_V_F__ */
  928.  
  929. static inline int gpio_get_value_ex(unsigned int pin)
  930. {
  931. #ifndef __USE_EGPIO__
  932.     return gpio_get_value(pin);
  933. #else
  934.     return egpio_get_value(pin);
  935. #endif /* __USE_EGPIO__ */
  936. }
  937.  
  938. static inline void gpio_set_value_ex(unsigned int pin, unsigned int level)
  939. {
  940. #ifndef __USE_EGPIO__
  941.     gpio_set_value(pin, level);
  942. #else
  943.     egpio_set_value(pin, level);
  944. #endif /* __USE_EGPIO__ */
  945. }
  946.  
  947. static void s3c_set_time_for_charging(int mode) {
  948.     if (mode) {
  949.         /* record start time for abs timer */
  950.         start_time_msec = jiffies_to_msecs(jiffies);
  951.         dev_info(dev, "%s: start_time(%d)\n", __func__,
  952.                 start_time_msec);
  953.     } else {
  954.         /* initialize start time for abs timer */
  955.         start_time_msec = 0;
  956.         total_time_msec = 0;
  957.         dev_info(dev, "%s: reset abs timer\n", __func__);
  958.     }
  959. }
  960.  
  961. static void s3c_set_chg_en(int enable)
  962. {
  963.     int chg_en_val = gpio_get_value_ex(gpio_chg_en);
  964.  
  965.     if (enable) {
  966.         if (chg_en_val == GPIO_LEVEL_HIGH) {
  967.             gpio_set_value_ex(gpio_chg_en, GPIO_LEVEL_LOW);
  968. //.i [VinsQ] [Start] Charger IC Changed to MAX8922    Pineone hgwoo    2010.01.05
  969. #if defined(CONFIG_MACH_VINSQ)
  970.             udelay(2000);
  971.             gpio_set_value_ex(gpio_chg_en, GPIO_LEVEL_HIGH);
  972.             udelay(10);
  973.             gpio_set_value_ex(gpio_chg_en, GPIO_LEVEL_LOW);
  974.             udelay(2000);
  975. #endif
  976. //.i [VinsQ] [End] Charger IC Changed to MAX8922    Pineone hgwoo    2010.01.05
  977.             dev_info(dev, "%s: gpio_chg_en(0)\n", __func__);
  978.             s3c_set_time_for_charging(1);
  979. #ifdef __BATTERY_COMPENSATION__
  980.             s3c_bat_set_compesation(1, OFFSET_TA_ATTACHED,
  981.                     COMPENSATE_TA);
  982. #endif /* __BATTERY_COMPENSATION__ */
  983.         }
  984.     } else {
  985.         if (chg_en_val == GPIO_LEVEL_LOW) {
  986.             gpio_set_value_ex(gpio_chg_en, GPIO_LEVEL_HIGH);
  987. //.i [VinsQ] [Start] Charger IC Changed to MAX8922    Pineone hgwoo    2010.01.05
  988. #if defined(CONFIG_MACH_VINSQ)
  989.             udelay(2000);
  990. #endif
  991. //.i [VinsQ] [End] Charger IC Changed to MAX8922    Pineone hgwoo    2010.01.05
  992.             dev_info(dev, "%s: gpio_chg_en(1)\n", __func__);
  993.             s3c_set_time_for_charging(0);
  994.             s3c_bat_info.bat_info.batt_is_recharging = 0;
  995. #ifdef __BATTERY_COMPENSATION__
  996.             s3c_bat_set_compesation(0, OFFSET_TA_ATTACHED,
  997.                     COMPENSATE_TA);
  998. #endif /* __BATTERY_COMPENSATION__ */
  999.         }
  1000.     }
  1001.     s3c_bat_info.bat_info.charging_enabled = enable;
  1002. }
  1003.  
  1004. static void s3c_temp_control(int mode) {
  1005.     int adc = s3c_bat_info.bat_info.batt_temp_adc_aver;
  1006.     dev_info(dev, "%s: temp_adc=%d\n", __func__, adc);
  1007.  
  1008.     switch (mode) {
  1009.     case POWER_SUPPLY_HEALTH_GOOD:
  1010.         dev_info(dev, "%s: GOOD\n", __func__);
  1011.         s3c_set_bat_health(mode);
  1012.         break;
  1013.     case POWER_SUPPLY_HEALTH_OVERHEAT:
  1014.         dev_info(dev, "%s: OVERHEAT\n", __func__);
  1015.         s3c_set_bat_health(mode);
  1016.         break;
  1017.     case POWER_SUPPLY_HEALTH_COLD:
  1018.         dev_info(dev, "%s: COLD\n", __func__);
  1019.         s3c_set_bat_health(mode);
  1020.         break;
  1021.     default:
  1022.         break;
  1023.     }
  1024.     schedule_work(&cable_work);
  1025. }
  1026.  
  1027. static int s3c_get_bat_temp(struct power_supply *bat_ps)
  1028. {
  1029.     int temp = 0;
  1030.     int array_size = 0;
  1031.     int i = 0;
  1032.     int temp_adc = s3c_read_temp(bat_ps);
  1033.     int health = s3c_get_bat_health();
  1034. #ifdef __BATTERY_COMPENSATION__
  1035.     unsigned int ex_case = 0;
  1036. #endif /* __BATTERY_COMPENSATION__ */
  1037. #ifdef __TEST_MODE_INTERFACE__
  1038.     s3c_bat_info.bat_info.batt_temp_adc_aver = temp_adc;
  1039. #endif /* __TEST_MODE_INTERFACE__ */
  1040.  
  1041. #ifdef __BATTERY_COMPENSATION__
  1042.     ex_case = OFFSET_MP3_PLAY | OFFSET_VOICE_CALL_2G | OFFSET_VOICE_CALL_3G
  1043.         | OFFSET_DATA_CALL | OFFSET_VIDEO_PLAY;
  1044.     if (s3c_bat_info.device_state & ex_case)
  1045.         goto __map_temperature__;
  1046. #endif /* __BATTERY_COMPENSATION__ */
  1047.  
  1048.     if (s3c_bat_info.bat_info.charging_source == CHARGER_BATTERY)
  1049.         goto __map_temperature__;
  1050.  
  1051. #ifndef __REVERSE_TEMPER_ADC__
  1052.     if (temp_adc <= TEMP_HIGH_BLOCK) {
  1053.         if (health != POWER_SUPPLY_HEALTH_OVERHEAT &&
  1054.                 health != POWER_SUPPLY_HEALTH_UNSPEC_FAILURE)
  1055.             s3c_temp_control(POWER_SUPPLY_HEALTH_OVERHEAT);
  1056.     } else if (temp_adc >= TEMP_HIGH_RECOVER &&
  1057.             temp_adc <= TEMP_LOW_RECOVER) {
  1058.         if (health == POWER_SUPPLY_HEALTH_OVERHEAT ||
  1059.                 health == POWER_SUPPLY_HEALTH_COLD)
  1060.             s3c_temp_control(POWER_SUPPLY_HEALTH_GOOD);
  1061.     } else if (temp_adc >= TEMP_LOW_BLOCK) {
  1062.         if (health != POWER_SUPPLY_HEALTH_COLD &&
  1063.                 health != POWER_SUPPLY_HEALTH_UNSPEC_FAILURE)
  1064.             s3c_temp_control(POWER_SUPPLY_HEALTH_COLD);
  1065.     }
  1066.  
  1067. __map_temperature__:   
  1068.     array_size = ARRAY_SIZE(temper_table);
  1069.     for (i = 0; i < (array_size - 1); i++) {
  1070.         if (i == 0) {
  1071.             if (temp_adc >= temper_table[0][0]) {
  1072.                 temp = temper_table[0][1];
  1073.                 break;
  1074.             } else if (temp_adc <= temper_table[array_size-1][0]) {
  1075.                 temp = temper_table[array_size-1][1];
  1076.                 break;
  1077.             }
  1078.         }
  1079.  
  1080.         if (temper_table[i][0] > temp_adc &&
  1081.                 temper_table[i+1][0] <= temp_adc) {
  1082.             temp = temper_table[i+1][1];
  1083.         }
  1084.     }
  1085. #else /* __REVERSE_TEMPER_ADC__ */
  1086.     if (temp_adc >= TEMP_HIGH_BLOCK) {
  1087.         if (health != POWER_SUPPLY_HEALTH_OVERHEAT &&
  1088.                 health != POWER_SUPPLY_HEALTH_UNSPEC_FAILURE)
  1089.             s3c_temp_control(POWER_SUPPLY_HEALTH_OVERHEAT);
  1090.     } else if (temp_adc <= TEMP_HIGH_RECOVER &&
  1091.             temp_adc >= TEMP_LOW_RECOVER) {
  1092.         if (health == POWER_SUPPLY_HEALTH_OVERHEAT ||
  1093.                 health == POWER_SUPPLY_HEALTH_COLD)
  1094.             s3c_temp_control(POWER_SUPPLY_HEALTH_GOOD);
  1095.     } else if (temp_adc <= TEMP_LOW_BLOCK) {
  1096.         if (health != POWER_SUPPLY_HEALTH_COLD &&
  1097.                 health != POWER_SUPPLY_HEALTH_UNSPEC_FAILURE)
  1098.             s3c_temp_control(POWER_SUPPLY_HEALTH_COLD);
  1099.     }
  1100.  
  1101. __map_temperature__:   
  1102.     array_size = ARRAY_SIZE(temper_table);
  1103.     for (i = 0; i < (array_size - 1); i++) {
  1104.         if (i == 0) {
  1105.             if (temp_adc <= temper_table[0][0]) {
  1106.                 temp = temper_table[0][1];
  1107.                 break;
  1108.             } else if (temp_adc >= temper_table[array_size-1][0]) {
  1109.                 temp = temper_table[array_size-1][1];
  1110.                 break;
  1111.             }
  1112.         }
  1113.  
  1114.         if (temper_table[i][0] < temp_adc &&
  1115.                 temper_table[i+1][0] >= temp_adc) {
  1116.             temp = temper_table[i+1][1];
  1117.         }
  1118.     }
  1119. #endif /* __REVERSE_TEMPER_ADC__ */
  1120.     dev_dbg(dev, "%s: temp = %d, adc = %d\n",
  1121.             __func__, temp, temp_adc);
  1122.  
  1123. #ifdef __TEST_MODE_INTERFACE__
  1124.         s3c_bat_info.bat_info.batt_temp_aver = temp;
  1125. #endif /* __TEST_MODE_INTERFACE__ */
  1126.     return temp;
  1127. }
  1128.  
  1129. static int s3c_bat_get_charging_status(void)
  1130. {
  1131.         charger_type_t charger = CHARGER_BATTERY;
  1132.         int ret = 0;
  1133.        
  1134.         charger = s3c_bat_info.bat_info.charging_source;
  1135.        
  1136.         switch (charger) {
  1137.         case CHARGER_BATTERY:
  1138.                 ret = POWER_SUPPLY_STATUS_NOT_CHARGING;
  1139.                 break;
  1140.         case CHARGER_USB:
  1141.         case CHARGER_AC:
  1142.         if (s3c_get_bat_health() != POWER_SUPPLY_HEALTH_GOOD)
  1143.             ret = POWER_SUPPLY_STATUS_DISCHARGING;
  1144.         else {
  1145.             if (s3c_bat_info.bat_info.batt_is_full)
  1146.                 ret = POWER_SUPPLY_STATUS_FULL;
  1147.             else
  1148.                 ret = POWER_SUPPLY_STATUS_CHARGING;
  1149.         }
  1150.                 break;
  1151.     case CHARGER_DISCHARGE:
  1152.         ret = POWER_SUPPLY_STATUS_DISCHARGING;
  1153.         break;
  1154.         default:
  1155.                 ret = POWER_SUPPLY_STATUS_UNKNOWN;
  1156.         }
  1157.  
  1158.     dev_dbg(dev, "%s: %s\n", __func__, status_text[ret]);
  1159.         return ret;
  1160. }
  1161.  
  1162. static int s3c_bat_get_property(struct power_supply *bat_ps,
  1163.         enum power_supply_property psp,
  1164.         union power_supply_propval *val)
  1165. {
  1166.     dev_dbg(bat_ps->dev, "%s: psp = %d\n", __func__, psp);
  1167.  
  1168.     switch (psp) {
  1169.     case POWER_SUPPLY_PROP_STATUS:
  1170.         val->intval = s3c_bat_get_charging_status();
  1171.         break;
  1172.     case POWER_SUPPLY_PROP_HEALTH:
  1173.         val->intval = s3c_get_bat_health();
  1174.         break;
  1175.     case POWER_SUPPLY_PROP_PRESENT:
  1176.         val->intval = s3c_bat_info.present;
  1177.         break;
  1178.     case POWER_SUPPLY_PROP_TECHNOLOGY:
  1179.         val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
  1180.         break;
  1181.     case POWER_SUPPLY_PROP_CAPACITY:
  1182.         val->intval = s3c_bat_info.bat_info.level;
  1183.         dev_dbg(dev, "%s: level = %d\n", __func__,
  1184.                 val->intval);
  1185.         break;
  1186.     case POWER_SUPPLY_PROP_TEMP:
  1187.         val->intval = s3c_bat_info.bat_info.batt_temp;
  1188.         dev_dbg(bat_ps->dev, "%s: temp = %d\n", __func__,
  1189.                 val->intval);
  1190.         break;
  1191.     default:
  1192.         return -EINVAL;
  1193.     }
  1194.     return 0;
  1195. }
  1196.  
  1197. static int s3c_power_get_property(struct power_supply *bat_ps,
  1198.         enum power_supply_property psp,
  1199.         union power_supply_propval *val)
  1200. {
  1201.     charger_type_t charger;
  1202.    
  1203.     dev_dbg(bat_ps->dev, "%s: psp = %d\n", __func__, psp);
  1204.  
  1205.     charger = s3c_bat_info.bat_info.charging_source;
  1206.  
  1207.     switch (psp) {
  1208.     case POWER_SUPPLY_PROP_ONLINE:
  1209.         if (bat_ps->type == POWER_SUPPLY_TYPE_MAINS)
  1210.             val->intval = (charger == CHARGER_AC ? 1 : 0);
  1211.         else if (bat_ps->type == POWER_SUPPLY_TYPE_USB)
  1212.             val->intval = (charger == CHARGER_USB ? 1 : 0);
  1213.         else
  1214.             val->intval = 0;
  1215.         break;
  1216.     default:
  1217.         return -EINVAL;
  1218.     }
  1219.    
  1220.     return 0;
  1221. }
  1222.  
  1223. #define SEC_BATTERY_ATTR(_name)                             \
  1224. {                                           \
  1225.         .attr = { .name = #_name, .mode = S_IRUGO | S_IWUGO, .owner = THIS_MODULE },    \
  1226.         .show = s3c_bat_show_property,                          \
  1227.         .store = s3c_bat_store,                             \
  1228. }
  1229.  
  1230. static struct device_attribute s3c_battery_attrs[] = {
  1231.         SEC_BATTERY_ATTR(batt_vol),
  1232.         SEC_BATTERY_ATTR(batt_vol_adc),
  1233.         SEC_BATTERY_ATTR(batt_vol_adc_cal),
  1234.         SEC_BATTERY_ATTR(batt_temp),
  1235.         SEC_BATTERY_ATTR(batt_temp_adc),
  1236.         SEC_BATTERY_ATTR(batt_temp_adc_cal),
  1237.     SEC_BATTERY_ATTR(batt_vol_adc_aver),
  1238. #ifdef __BOARD_REV_ADC__
  1239.         SEC_BATTERY_ATTR(board_rev_adc),
  1240. #endif /* __BOARD_REV_ADC__ */
  1241. #ifdef __TEST_MODE_INTERFACE__
  1242.     /* test mode */
  1243.     SEC_BATTERY_ATTR(batt_test_mode),
  1244.     /* average */
  1245.     SEC_BATTERY_ATTR(batt_vol_aver),
  1246.     SEC_BATTERY_ATTR(batt_temp_aver),
  1247.     SEC_BATTERY_ATTR(batt_temp_adc_aver),
  1248.     SEC_BATTERY_ATTR(batt_v_f_adc),
  1249. #endif /* __TEST_MODE_INTERFACE__ */
  1250. #ifdef __CHECK_CHG_CURRENT__
  1251.     SEC_BATTERY_ATTR(batt_chg_current),
  1252.     SEC_BATTERY_ATTR(batt_chg_current_aver),
  1253. #endif /* __CHECK_CHG_CURRENT__ */
  1254.     SEC_BATTERY_ATTR(charging_source),
  1255. #ifdef __BATTERY_COMPENSATION__
  1256.     SEC_BATTERY_ATTR(vibrator),
  1257.     SEC_BATTERY_ATTR(camera),
  1258.     SEC_BATTERY_ATTR(mp3),
  1259.     SEC_BATTERY_ATTR(video),
  1260.     SEC_BATTERY_ATTR(talk_gsm),
  1261.     SEC_BATTERY_ATTR(talk_wcdma),
  1262.     SEC_BATTERY_ATTR(data_call),
  1263.     SEC_BATTERY_ATTR(device_state),
  1264.     SEC_BATTERY_ATTR(batt_compensation),
  1265.     SEC_BATTERY_ATTR(is_booting),
  1266. #endif /* __BATTERY_COMPENSATION__ */
  1267. #ifdef __FUEL_GAUGES_IC__
  1268.     SEC_BATTERY_ATTR(fg_soc),
  1269.     SEC_BATTERY_ATTR(reset_soc),
  1270. #endif /* __FUEL_GAUGES_IC__ */
  1271. };
  1272.  
  1273. enum {
  1274.         BATT_VOL = 0,
  1275.         BATT_VOL_ADC,
  1276.         BATT_VOL_ADC_CAL,
  1277.         BATT_TEMP,
  1278.         BATT_TEMP_ADC,
  1279.         BATT_TEMP_ADC_CAL,
  1280.     BATT_VOL_ADC_AVER,
  1281. #ifdef __BOARD_REV_ADC__
  1282.         BOARD_REV_ADC,
  1283. #endif /* __BOARD_REV_ADC__ */
  1284. #ifdef __TEST_MODE_INTERFACE__
  1285.     BATT_TEST_MODE,
  1286.     BATT_VOL_AVER,
  1287.     BATT_TEMP_AVER,
  1288.     BATT_TEMP_ADC_AVER,
  1289.     BATT_V_F_ADC,
  1290. #endif /* __TEST_MODE_INTERFACE__ */
  1291. #ifdef __CHECK_CHG_CURRENT__
  1292.     BATT_CHG_CURRENT,  
  1293.     BATT_CHG_CURRENT_AVER, 
  1294. #endif /* __CHECK_CHG_CURRENT__ */
  1295.     BATT_CHARGING_SOURCE,
  1296. #ifdef __BATTERY_COMPENSATION__
  1297.     BATT_VIBRATOR,
  1298.     BATT_CAMERA,
  1299.     BATT_MP3,
  1300.     BATT_VIDEO,
  1301.     BATT_VOICE_CALL_2G,
  1302.     BATT_VOICE_CALL_3G,
  1303.     BATT_DATA_CALL,
  1304.     BATT_DEV_STATE,
  1305.     BATT_COMPENSATION,
  1306.     BATT_BOOTING,
  1307. #endif /* __BATTERY_COMPENSATION__ */
  1308. #ifdef __FUEL_GAUGES_IC__
  1309.     BATT_FG_SOC,
  1310.     BATT_RESET_SOC,
  1311. #endif /* __FUEL_GAUGES_IC__ */
  1312. };
  1313.  
  1314. static int s3c_bat_create_attrs(struct device * dev)
  1315. {
  1316.         int i, rc;
  1317.        
  1318.         for (i = 0; i < ARRAY_SIZE(s3c_battery_attrs); i++) {
  1319.                 rc = device_create_file(dev, &s3c_battery_attrs[i]);
  1320.                 if (rc)
  1321.                         goto s3c_attrs_failed;
  1322.         }
  1323.         goto succeed;
  1324.        
  1325. s3c_attrs_failed:
  1326.         while (i--)
  1327.                 device_remove_file(dev, &s3c_battery_attrs[i]);
  1328. succeed:        
  1329.         return rc;
  1330. }
  1331.  
  1332. static ssize_t s3c_bat_show_property(struct device *dev,
  1333.                                       struct device_attribute *attr,
  1334.                                       char *buf)
  1335. {
  1336.         int i = 0;
  1337.         const ptrdiff_t off = attr - s3c_battery_attrs;
  1338.  
  1339.         switch (off) {
  1340.         case BATT_VOL:
  1341.                 i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
  1342.                                s3c_bat_info.bat_info.batt_vol);
  1343.                 break;
  1344.         case BATT_VOL_ADC:
  1345. #ifndef __FUEL_GAUGES_IC__
  1346.         s3c_bat_info.bat_info.batt_vol_adc =
  1347.             s3c_bat_get_adc_data(S3C_ADC_VOLTAGE);
  1348. #else
  1349.         s3c_bat_info.bat_info.batt_vol_adc = 0;
  1350. #endif /* __FUEL_GAUGES_IC__ */
  1351.                 i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
  1352.                                s3c_bat_info.bat_info.batt_vol_adc);
  1353.                 break;
  1354.         case BATT_VOL_ADC_CAL:
  1355.                 i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
  1356.                                s3c_bat_info.bat_info.batt_vol_adc_cal);
  1357.                 break;
  1358.         case BATT_TEMP:
  1359.                 i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
  1360.                                s3c_bat_info.bat_info.batt_temp);
  1361.                 break;
  1362.         case BATT_TEMP_ADC:
  1363.         s3c_bat_info.bat_info.batt_temp_adc =
  1364.             s3c_bat_get_adc_data(S3C_ADC_TEMPERATURE);
  1365.                 i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
  1366.                                s3c_bat_info.bat_info.batt_temp_adc);
  1367.                 break; 
  1368. #ifdef __TEST_MODE_INTERFACE__
  1369.     case BATT_TEST_MODE:
  1370.         i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
  1371.         s3c_bat_info.bat_info.batt_test_mode);
  1372.         break;
  1373. #endif /* __TEST_MODE_INTERFACE__ */
  1374.         case BATT_TEMP_ADC_CAL:
  1375.                 i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
  1376.                                s3c_bat_info.bat_info.batt_temp_adc_cal);
  1377.                 break;
  1378.         case BATT_VOL_ADC_AVER:
  1379.         i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
  1380.             s3c_bat_info.bat_info.batt_vol_adc_aver);
  1381.         break;
  1382. #ifdef __BOARD_REV_ADC__
  1383.         case BOARD_REV_ADC:
  1384.                 i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", board_rev_adc);
  1385.                 break;
  1386. #endif /* __BOARD_REV_ADC__ */
  1387. #ifdef __TEST_MODE_INTERFACE__
  1388.     case BATT_VOL_AVER:
  1389.         i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
  1390.             s3c_bat_info.bat_info.batt_vol_aver);
  1391.         break;
  1392.     case BATT_TEMP_AVER:
  1393.         i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
  1394.             s3c_bat_info.bat_info.batt_temp_aver);
  1395.         break;
  1396.     case BATT_TEMP_ADC_AVER:
  1397.         i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
  1398.             s3c_bat_info.bat_info.batt_temp_adc_aver);
  1399.         break;
  1400.     case BATT_V_F_ADC:
  1401.         i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
  1402.             s3c_bat_info.bat_info.batt_v_f_adc);
  1403.         break;
  1404. #endif /* __TEST_MODE_INTERFACE__ */
  1405. #ifdef __CHECK_CHG_CURRENT__
  1406.     case BATT_CHG_CURRENT:
  1407.         s3c_bat_info.bat_info.batt_current =
  1408.             s3c_bat_get_adc_data(S3C_ADC_CHG_CURRENT);
  1409.         i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
  1410.                 s3c_bat_info.bat_info.batt_current);
  1411.         break;
  1412.     case BATT_CHG_CURRENT_AVER:
  1413.         i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
  1414.                 adc_sample[S3C_ADC_CHG_CURRENT].average_adc);
  1415.         break;
  1416.  
  1417. #endif /* __CHECK_CHG_CURRENT__ */
  1418.     case BATT_CHARGING_SOURCE:
  1419.         i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
  1420.             s3c_bat_info.bat_info.charging_source);
  1421.         break;
  1422. #ifdef __BATTERY_COMPENSATION__
  1423.     case BATT_DEV_STATE:
  1424.         i += scnprintf(buf + i, PAGE_SIZE - i, "0x%08x\n",
  1425.             s3c_bat_info.device_state);
  1426.         break;
  1427.     case BATT_COMPENSATION:
  1428.         i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
  1429.             batt_compensation);
  1430.         break;
  1431. #endif /* __BATTERY_COMPENSATION__ */
  1432. #ifdef __FUEL_GAUGES_IC__
  1433.     case BATT_FG_SOC:
  1434.         i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n",
  1435.             fg_read_soc());
  1436.         break;
  1437. #endif /* __FUEL_GAUGES_IC__ */
  1438.         default:
  1439.                 i = -EINVAL;
  1440.         }      
  1441.        
  1442.         return i;
  1443. }
  1444.  
  1445. static void s3c_bat_set_vol_cal(int batt_cal)
  1446. {
  1447.     int max_cal = 4096;
  1448. #ifdef __9BITS_RESOLUTION__
  1449.     max_cal = 512;
  1450. #endif /* __9BITS_RESOLUTION__ */
  1451.  
  1452.     if (!batt_cal)
  1453.         return;
  1454.  
  1455.     if (batt_cal >= max_cal) {
  1456.         dev_err(dev, "%s: invalid battery_cal(%d)\n", __func__, batt_cal);
  1457.         return;
  1458.     }
  1459.  
  1460.     batt_max = batt_cal + BATT_MAXIMUM;
  1461.     batt_full = batt_cal + BATT_FULL;
  1462.     batt_safe_rech = batt_cal + BATT_SAFE_RECHARGE;
  1463.     batt_almost = batt_cal + BATT_ALMOST_FULL;
  1464.     batt_high = batt_cal + BATT_HIGH;
  1465.     batt_medium = batt_cal + BATT_MED;
  1466.     batt_low = batt_cal + BATT_LOW;
  1467.     batt_critical = batt_cal + BATT_CRITICAL;
  1468.     batt_min = batt_cal + BATT_MINIMUM;
  1469.     batt_off = batt_cal + BATT_OFF;
  1470. }
  1471.  
  1472. #ifdef COMPENSATE_BOOTING
  1473. static void s3c_bat_compensate_booting(int mode)
  1474. {
  1475.     if (mode)
  1476.         s3c_bat_set_compesation(1, OFFSET_BOOTING, COMPENSATE_BOOTING);
  1477.     else
  1478.         queue_work(batt_drv_wqueue, &compensate_boot_work);
  1479. }
  1480. #endif /* COMPENSATE_BOOTING */
  1481.  
  1482. static ssize_t s3c_bat_store(struct device *dev,
  1483.                  struct device_attribute *attr,
  1484.                  const char *buf, size_t count)
  1485. {
  1486.     int x = 0;
  1487.     int ret = 0;
  1488.     const ptrdiff_t off = attr - s3c_battery_attrs;
  1489.  
  1490.         switch (off) {
  1491.         case BATT_VOL_ADC_CAL:
  1492.         if (sscanf(buf, "%d\n", &x) == 1) {
  1493.             s3c_bat_info.bat_info.batt_vol_adc_cal = x;
  1494.             s3c_bat_set_vol_cal(x);
  1495.             ret = count;
  1496.         }
  1497.         dev_info(dev, "%s: batt_vol_adc_cal = %d\n", __func__, x);
  1498.                 break;
  1499.         case BATT_TEMP_ADC_CAL:
  1500.         if (sscanf(buf, "%d\n", &x) == 1) {
  1501.             s3c_bat_info.bat_info.batt_temp_adc_cal = x;
  1502.             ret = count;
  1503.         }
  1504.         dev_info(dev, "%s: batt_temp_adc_cal = %d\n", __func__, x);
  1505.                 break;
  1506. #ifdef __TEST_MODE_INTERFACE__
  1507.     case BATT_TEST_MODE:
  1508.         if (sscanf(buf, "%d\n", &x) == 1) {
  1509.             s3c_bat_info.bat_info.batt_test_mode = x;
  1510.             ret = count;
  1511.         }
  1512.         if (s3c_bat_info.bat_info.batt_test_mode) {
  1513.             s3c_bat_info.polling_interval = POLLING_INTERVAL_TEST;         
  1514.             if (s3c_bat_info.polling) {
  1515.                 del_timer_sync(&polling_timer);
  1516.                 mod_timer(&polling_timer, jiffies +
  1517.                     msecs_to_jiffies(s3c_bat_info.polling_interval));
  1518.             }
  1519.             s3c_bat_status_update(
  1520.                 &s3c_power_supplies_test[CHARGER_BATTERY]);
  1521.         } else {
  1522.             s3c_bat_info.polling_interval = POLLING_INTERVAL;      
  1523.             if (s3c_bat_info.polling) {
  1524.                 del_timer_sync(&polling_timer);
  1525.                 mod_timer(&polling_timer,jiffies +
  1526.                     msecs_to_jiffies(s3c_bat_info.polling_interval));
  1527.             }
  1528.             s3c_bat_status_update(
  1529.                 &s3c_power_supplies_test[CHARGER_BATTERY]);
  1530.         }
  1531.         dev_info(dev, "%s: batt_test_mode = %d\n", __func__, x);
  1532.         break;
  1533. #endif /* __TEST_MODE_INTERFACE__ */
  1534. #ifdef __BATTERY_COMPENSATION__
  1535.     case BATT_VIBRATOR:
  1536.         if (sscanf(buf, "%d\n", &x) == 1) {
  1537.             s3c_bat_set_compesation(x, OFFSET_VIBRATOR_ON,
  1538.                     COMPENSATE_VIBRATOR);
  1539.             ret = count;
  1540.         }
  1541.         dev_info(dev, "%s: vibrator = %d\n", __func__, x);
  1542.                 break;
  1543.     case BATT_CAMERA:
  1544.         if (sscanf(buf, "%d\n", &x) == 1) {
  1545.             s3c_bat_set_compesation(x, OFFSET_CAMERA_ON,
  1546.                     COMPENSATE_CAMERA);
  1547.             ret = count;
  1548.         }
  1549.         dev_info(dev, "%s: camera = %d\n", __func__, x);
  1550.                 break;
  1551.     case BATT_MP3:
  1552.         if (sscanf(buf, "%d\n", &x) == 1) {
  1553.             s3c_bat_set_compesation(x, OFFSET_MP3_PLAY,
  1554.                     COMPENSATE_MP3);
  1555.             ret = count;
  1556.         }
  1557.         dev_info(dev, "%s: mp3 = %d\n", __func__, x);
  1558.                 break;
  1559.     case BATT_VIDEO:
  1560.         if (sscanf(buf, "%d\n", &x) == 1) {
  1561.             s3c_bat_set_compesation(x, OFFSET_VIDEO_PLAY,
  1562.                     COMPENSATE_VIDEO);
  1563.             ret = count;
  1564.         }
  1565.         dev_info(dev, "%s: video = %d\n", __func__, x);
  1566.                 break;
  1567.     case BATT_VOICE_CALL_2G:
  1568.         if (sscanf(buf, "%d\n", &x) == 1) {
  1569.             s3c_bat_set_compesation(x, OFFSET_VOICE_CALL_2G,
  1570.                     COMPENSATE_VOICE_CALL_2G);
  1571.             ret = count;
  1572.         }
  1573.         dev_info(dev, "%s: voice call 2G = %d\n", __func__, x);
  1574.                 break;
  1575.     case BATT_VOICE_CALL_3G:
  1576.         if (sscanf(buf, "%d\n", &x) == 1) {
  1577.             s3c_bat_set_compesation(x, OFFSET_VOICE_CALL_3G,
  1578.                     COMPENSATE_VOICE_CALL_3G);
  1579.             ret = count;
  1580.         }
  1581.         dev_info(dev, "%s: voice call 3G = %d\n", __func__, x);
  1582.                 break;
  1583.     case BATT_DATA_CALL:
  1584.         if (sscanf(buf, "%d\n", &x) == 1) {
  1585.             s3c_bat_set_compesation(x, OFFSET_DATA_CALL,
  1586.                     COMPENSATE_DATA_CALL);
  1587.             ret = count;
  1588.         }
  1589.         dev_info(dev, "%s: data call = %d\n", __func__, x);
  1590.                 break;
  1591. #ifdef COMPENSATE_BOOTING
  1592.     case BATT_BOOTING:
  1593.         if (sscanf(buf, "%d\n", &x) == 1) {
  1594.             s3c_bat_compensate_booting(x);
  1595.             ret = count;
  1596.         }
  1597.         dev_info(dev, "%s: boot complete = %d\n", __func__, x);
  1598.                 break;
  1599. #endif /* COMPENSATE_BOOTING */
  1600. #endif /* __BATTERY_COMPENSATION__ */
  1601. #ifdef __FUEL_GAUGES_IC__
  1602.     case BATT_RESET_SOC:
  1603.         if (sscanf(buf, "%d\n", &x) == 1) {
  1604.             if (x == 1)
  1605.                 fg_reset_soc();
  1606.             ret = count;
  1607.         }
  1608.         dev_info(dev, "%s: Reset SOC:%d\n", __func__, x);
  1609.         break;
  1610. #endif /* __FUEL_GAUGES_IC__ */
  1611.         default:
  1612.                 ret = -EINVAL;
  1613.         }      
  1614.  
  1615.     return ret;
  1616. }
  1617.  
  1618. #ifdef __BATTERY_COMPENSATION__
  1619. void s3c_bat_set_compensation_for_drv(int mode, int offset)
  1620. {
  1621.     switch(offset) {
  1622.     case OFFSET_VIBRATOR_ON:
  1623.         dev_dbg(dev, "%s: vibrator = %d\n", __func__, mode);
  1624.         s3c_bat_set_compesation(mode, offset, COMPENSATE_VIBRATOR);
  1625.         break;
  1626.     case OFFSET_LCD_ON:
  1627.         dev_info(dev, "%s: LCD On = %d\n", __func__, mode);
  1628.         s3c_bat_set_compesation(mode, offset, COMPENSATE_LCD);
  1629.         break;
  1630.     case OFFSET_CAM_FLASH:
  1631.         dev_info(dev, "%s: flash = %d\n", __func__, mode);
  1632.         s3c_bat_set_compesation(mode, offset, COMPENSATE_CAM_FALSH);
  1633.         break;
  1634.     default:
  1635.         break;
  1636.     }
  1637.  
  1638. }
  1639. EXPORT_SYMBOL(s3c_bat_set_compensation_for_drv);
  1640. #endif /* __BATTERY_COMPENSATION__ */
  1641.  
  1642. #ifdef __TEST_DEVICE_DRIVER__
  1643. #define SEC_TEST_ATTR(_name)                                \
  1644. {                                           \
  1645.         .attr = { .name = #_name, .mode = S_IRUGO | S_IWUGO, .owner = THIS_MODULE },    \
  1646.         .show = s3c_test_show_property,                         \
  1647.         .store = s3c_test_store,                            \
  1648. }
  1649.  
  1650. static struct device_attribute s3c_test_attrs[] = {
  1651.         SEC_TEST_ATTR(pm),
  1652.         SEC_TEST_ATTR(usb),
  1653.         SEC_TEST_ATTR(bt_wl),
  1654.         SEC_TEST_ATTR(tflash),
  1655.         SEC_TEST_ATTR(audio),
  1656.         SEC_TEST_ATTR(lcd),
  1657.         SEC_TEST_ATTR(suspend_lock),
  1658.         SEC_TEST_ATTR(control_tmp),
  1659. };
  1660.  
  1661. enum {
  1662.         TEST_PM = 0,
  1663.     USB_OFF,
  1664.     BT_WL_OFF,
  1665.     TFLASH_OFF,
  1666.     AUDIO_OFF,
  1667.     LCD_CHECK,
  1668.     SUSPEND_LOCK,
  1669.     CTRL_TMP,
  1670. };
  1671.  
  1672. static int s3c_test_create_attrs(struct device * dev)
  1673. {
  1674.         int i, rc;
  1675.        
  1676.         for (i = 0; i < ARRAY_SIZE(s3c_test_attrs); i++) {
  1677.                 rc = device_create_file(dev, &s3c_test_attrs[i]);
  1678.                 if (rc)
  1679.                         goto s3c_attrs_failed;
  1680.         }
  1681.         goto succeed;
  1682.        
  1683. s3c_attrs_failed:
  1684.         while (i--)
  1685.                 device_remove_file(dev, &s3c_test_attrs[i]);
  1686. succeed:        
  1687.         return rc;
  1688. }
  1689.  
  1690. static void s3c_lcd_check(void)
  1691. {
  1692.     unsigned char reg_buff = 0;
  1693.     if (Get_MAX8698_PM_REG(ELDO6, &reg_buff)) {
  1694.         pr_info("%s: VLCD 1.8V (%d)\n", __func__, reg_buff);
  1695.     }
  1696.     if ((Get_MAX8698_PM_REG(ELDO7, &reg_buff))) {
  1697.         pr_info("%s: VLCD 2.8V (%d)\n", __func__, reg_buff);
  1698.     }
  1699. }
  1700.  
  1701. static void s3c_usb_off(void)
  1702. {
  1703.     unsigned char reg_buff = 0;
  1704.     if (Get_MAX8698_PM_REG(ELDO3, &reg_buff)) {
  1705.         pr_info("%s: OTGI 1.2V off(%d)\n", __func__, reg_buff);
  1706.         if (reg_buff)
  1707.             Set_MAX8698_PM_REG(ELDO3, 0);
  1708.     }
  1709.     if ((Get_MAX8698_PM_REG(ELDO8, &reg_buff))) {
  1710.         pr_info("%s: OTG 3.3V off(%d)\n", __func__, reg_buff);
  1711.         if (reg_buff)
  1712.             Set_MAX8698_PM_REG(ELDO8, 0);
  1713.     }
  1714. }
  1715.  
  1716. static void s3c_bt_wl_off(void)
  1717. {
  1718.     unsigned char reg_buff = 0;
  1719.     if (Get_MAX8698_PM_REG(ELDO4, &reg_buff)) {
  1720.         pr_info("%s: BT_WL 2.6V off(%d)\n", __func__, reg_buff);
  1721.         if (reg_buff)
  1722.             Set_MAX8698_PM_REG(ELDO4, 0);
  1723.     }
  1724. }
  1725.  
  1726. static void s3c_tflash_off(void)
  1727. {
  1728.     unsigned char reg_buff = 0;
  1729.     if (Get_MAX8698_PM_REG(ELDO5, &reg_buff)) {
  1730.         pr_info("%s: TF 3.0V off(%d)\n", __func__, reg_buff);
  1731.         if (reg_buff)
  1732.             Set_MAX8698_PM_REG(ELDO5, 0);
  1733.     }
  1734. }
  1735.  
  1736. static void s3c_audio_off(void)
  1737. {
  1738.     pr_info("%s: Turn off audio power, amp\n", __func__);
  1739.     amp_enable(0);
  1740.     audio_power(0);
  1741. }
  1742.  
  1743. static void s3c_test_pm(void)
  1744. {
  1745.     /* PMIC */
  1746.     s3c_usb_off();
  1747.     s3c_bt_wl_off();
  1748.     s3c_tflash_off();
  1749.     s3c_lcd_check();
  1750.  
  1751.     /* AUDIO */
  1752.     s3c_audio_off();
  1753.  
  1754.     /* GPIO */
  1755. }
  1756.  
  1757. static ssize_t s3c_test_show_property(struct device *dev,
  1758.                                       struct device_attribute *attr,
  1759.                                       char *buf)
  1760. {
  1761.         int i = 0;
  1762.         const ptrdiff_t off = attr - s3c_test_attrs;
  1763.  
  1764.         switch (off) {
  1765.         case TEST_PM:
  1766.                 i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", 0);
  1767.         s3c_test_pm();
  1768.                 break;
  1769.         case USB_OFF:
  1770.                 i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", 1);
  1771.         s3c_usb_off();
  1772.                 break;
  1773.         case BT_WL_OFF:
  1774.                 i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", 2);
  1775.         s3c_bt_wl_off();
  1776.                 break;
  1777.         case TFLASH_OFF:
  1778.                 i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", 3);
  1779.         s3c_tflash_off();
  1780.                 break;
  1781.         case AUDIO_OFF:
  1782.                 i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", 4);
  1783.         s3c_audio_off();
  1784.                 break;
  1785.         case LCD_CHECK:
  1786.                 i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", 5);
  1787.         s3c_lcd_check();
  1788.                 break;
  1789.         default:
  1790.                 i = -EINVAL;
  1791.         }      
  1792.        
  1793.         return i;
  1794. }
  1795.  
  1796. static ssize_t s3c_test_store(struct device *dev,
  1797.                  struct device_attribute *attr,
  1798.                  const char *buf, size_t count)
  1799. {
  1800.     int mode = 0;
  1801.     int ret = 0;
  1802.     const ptrdiff_t off = attr - s3c_test_attrs;
  1803.  
  1804.         switch (off) {
  1805.         case SUSPEND_LOCK:
  1806.         if (sscanf(buf, "%d\n", &mode) == 1) {
  1807.             dev_dbg(dev, "%s: suspend_lock(%d)\n", __func__, mode);
  1808.             if (mode)
  1809.                         wake_lock(&wake_lock_for_dev);
  1810.             else
  1811.                         wake_lock_timeout(
  1812.                         &wake_lock_for_dev, HZ / 2);
  1813.             ret = count;
  1814.         }
  1815.                 break;
  1816.     case CTRL_TMP:
  1817.         if (sscanf(buf, "%d\n", &mode) == 1) {
  1818.             dev_info(dev, "%s: control tmp(%d)\n", __func__, mode);
  1819.             bat_temper_state = mode;
  1820.             ret = count;
  1821.         }
  1822.         break;
  1823.         default:
  1824.                 ret = -EINVAL;
  1825.         }      
  1826.  
  1827.     return ret;
  1828. }
  1829. #endif /* __TEST_DEVICE_DRIVER__ */
  1830.  
  1831. static enum power_supply_property s3c_battery_properties[] = {
  1832.     POWER_SUPPLY_PROP_STATUS,
  1833.     POWER_SUPPLY_PROP_HEALTH,
  1834.     POWER_SUPPLY_PROP_PRESENT,
  1835.     POWER_SUPPLY_PROP_TECHNOLOGY,
  1836.     POWER_SUPPLY_PROP_CAPACITY,
  1837. };
  1838.  
  1839. static enum power_supply_property s3c_power_properties[] = {
  1840.     POWER_SUPPLY_PROP_ONLINE,
  1841. };
  1842.  
  1843. static char *supply_list[] = {
  1844.     "battery",
  1845. };
  1846.  
  1847. static struct power_supply s3c_power_supplies[] = {
  1848.     {
  1849.         .name = "battery",
  1850.         .type = POWER_SUPPLY_TYPE_BATTERY,
  1851.         .properties = s3c_battery_properties,
  1852.         .num_properties = ARRAY_SIZE(s3c_battery_properties),
  1853.         .get_property = s3c_bat_get_property,
  1854.     },
  1855.     {
  1856.         .name = "usb",
  1857.         .type = POWER_SUPPLY_TYPE_USB,
  1858.         .supplied_to = supply_list,
  1859.         .num_supplicants = ARRAY_SIZE(supply_list),
  1860.         .properties = s3c_power_properties,
  1861.         .num_properties = ARRAY_SIZE(s3c_power_properties),
  1862.         .get_property = s3c_power_get_property,
  1863.     },
  1864.     {
  1865.         .name = "ac",
  1866.         .type = POWER_SUPPLY_TYPE_MAINS,
  1867.         .supplied_to = supply_list,
  1868.         .num_supplicants = ARRAY_SIZE(supply_list),
  1869.         .properties = s3c_power_properties,
  1870.         .num_properties = ARRAY_SIZE(s3c_power_properties),
  1871.         .get_property = s3c_power_get_property,
  1872.     },
  1873. };
  1874.  
  1875. static int s3c_cable_status_update(int status)
  1876. {
  1877.     int ret = 0;
  1878.     charger_type_t source = CHARGER_BATTERY;
  1879.  
  1880.     dev_dbg(dev, "%s\n", __func__);
  1881.  
  1882.     if(!s3c_battery_initial)
  1883.         return -EPERM;
  1884.  
  1885.     switch(status) {
  1886.     case CHARGER_BATTERY:
  1887.         dev_dbg(dev, "%s: cable NOT PRESENT\n", __func__);
  1888.         s3c_bat_info.bat_info.charging_source = CHARGER_BATTERY;
  1889.         break;
  1890.     case CHARGER_USB:
  1891.         dev_dbg(dev, "%s: cable USB\n", __func__);
  1892.         s3c_bat_info.bat_info.charging_source = CHARGER_USB;
  1893.         break;
  1894.     case CHARGER_AC:
  1895.         dev_dbg(dev, "%s: cable AC\n", __func__);
  1896.         s3c_bat_info.bat_info.charging_source = CHARGER_AC;
  1897.         break;
  1898. #if 0
  1899.     case CHARGER_DISCHARGE:
  1900.         dev_dbg(dev, "%s: Discharge\n", __func__);
  1901.         s3c_bat_info.bat_info.charging_source = CHARGER_DISCHARGE;
  1902.         break;
  1903. #endif
  1904.     default:
  1905.         dev_err(dev, "%s: Nat supported status(%d)\n", __func__, status);
  1906.         ret = -EINVAL;
  1907.     }
  1908.     source = s3c_bat_info.bat_info.charging_source;
  1909.  
  1910.         if (source == CHARGER_USB || source == CHARGER_AC) {
  1911.                 wake_lock(&vbus_wake_lock);
  1912.         } else {
  1913.                 /* give userspace some time to see the uevent and update
  1914.                  * LED state or whatnot...
  1915.                  */
  1916.         if (gpio_get_value(gpio_ta_connected))
  1917.             wake_lock_timeout(&vbus_wake_lock, HZ / 2);
  1918.         }
  1919.         /* if the power source changes, all power supplies may change state */
  1920.         power_supply_changed(&s3c_power_supplies[CHARGER_BATTERY]);
  1921.     /*
  1922.         power_supply_changed(&s3c_power_supplies[CHARGER_USB]);
  1923.         power_supply_changed(&s3c_power_supplies[CHARGER_AC]);
  1924.     */
  1925.     dev_dbg(dev, "%s: call power_supply_changed\n", __func__);
  1926.     return ret;
  1927. }
  1928.  
  1929. #ifdef __CHECK_BATTERY_V_F__
  1930. static unsigned int s3c_bat_check_v_f(void)
  1931. {
  1932.     unsigned int rc = 0;
  1933.     int adc = 0;
  1934.    
  1935.     adc = s3c_bat_get_adc_data(S3C_ADC_V_F);
  1936.  
  1937.     dev_dbg(dev, "%s: V_F ADC = %d\n", __func__, adc);
  1938.  
  1939.     if (adc <= BATT_VF_MAX && adc >= BATT_VF_MIN) {
  1940.         /* s3c_set_bat_health(POWER_SUPPLY_HEALTH_GOOD); */
  1941.         rc = 1;
  1942.     } else {
  1943.         dev_info(dev, "%s: Unauthorized battery!\n", __func__);
  1944.         s3c_set_bat_health(POWER_SUPPLY_HEALTH_UNSPEC_FAILURE);
  1945.         s3c_set_chg_en(DISABLE);
  1946.         force_update = 1;
  1947.         rc = 0;
  1948.     }
  1949.     return rc;
  1950. }
  1951. #endif /* __CHECK_BATTERY_V_F__ */
  1952.  
  1953. static void s3c_bat_status_update(struct power_supply *bat_ps)
  1954. {
  1955.     int old_level, old_temp, old_is_full;
  1956.     dev_dbg(dev, "%s ++\n", __func__);
  1957.  
  1958.     if(!s3c_battery_initial)
  1959.         return;
  1960.  
  1961.     mutex_lock(&work_lock);
  1962.     old_temp = s3c_bat_info.bat_info.batt_temp;
  1963.     old_level = s3c_bat_info.bat_info.level;
  1964.     old_is_full = s3c_bat_info.bat_info.batt_is_full;
  1965.     s3c_bat_info.bat_info.batt_temp = s3c_get_bat_temp(bat_ps);
  1966.  
  1967.     s3c_bat_info.bat_info.level = s3c_get_bat_level(bat_ps);
  1968.     if (!s3c_bat_info.bat_info.charging_enabled &&
  1969.             !s3c_bat_info.bat_info.batt_is_full) {
  1970.         if (s3c_bat_info.bat_info.level > old_level)
  1971.             s3c_bat_info.bat_info.level = old_level;
  1972.     }
  1973.     s3c_bat_info.bat_info.batt_vol = s3c_get_bat_vol(bat_ps);
  1974.  
  1975. #ifdef __BOARD_REV_ADC__
  1976.     if (!is_end_board_rev_adc)
  1977.         s3c_get_board_rev_adc(bat_ps);
  1978. #endif /* __BOARD_REV_ADC__ */
  1979.  
  1980. #if (defined __TEST_MODE_INTERFACE__ && defined __BATTERY_V_F__)
  1981.     if (s3c_bat_info.bat_info.batt_test_mode == 1)
  1982.         s3c_get_v_f_adc();
  1983. #endif /* __TEST_MODE_INTERFACE__ && __BATTERY_V_F__ */
  1984.  
  1985. #ifdef __CHECK_BATTERY_V_F__
  1986.     if(s3c_bat_info.bat_info.charging_enabled &&
  1987.         s3c_get_bat_health() != POWER_SUPPLY_HEALTH_UNSPEC_FAILURE)
  1988.         s3c_bat_check_v_f();
  1989. #endif /* __CHECK_BATTERY_V_F__ */
  1990.  
  1991.     if (old_level != s3c_bat_info.bat_info.level
  1992.             || old_temp != s3c_bat_info.bat_info.batt_temp
  1993.             || old_is_full != s3c_bat_info.bat_info.batt_is_full
  1994.             || force_update) {
  1995.         force_update = 0;
  1996.         power_supply_changed(bat_ps);
  1997.         dev_dbg(dev, "%s: call power_supply_changed\n", __func__);
  1998.     }
  1999.  
  2000.     mutex_unlock(&work_lock);
  2001.     dev_dbg(dev, "%s --\n", __func__);
  2002. }
  2003.  
  2004. static void s3c_cable_check_status(void)
  2005. {
  2006.     charger_type_t status = 0;
  2007.  
  2008.     mutex_lock(&work_lock);
  2009.  
  2010.     if (!gpio_get_value(gpio_ta_connected)) {
  2011.         if (get_usb_power_state())
  2012.             status = CHARGER_USB;
  2013.         else
  2014.             status = CHARGER_AC;
  2015.  
  2016.         if (s3c_get_bat_health() != POWER_SUPPLY_HEALTH_GOOD) {
  2017.             dev_info(dev, "%s: Unhealth battery state!\n", __func__);
  2018.             s3c_set_chg_en(DISABLE);
  2019.         } else
  2020.             s3c_set_chg_en(ENABLE);
  2021.  
  2022.         dev_dbg(dev, "%s: status : %s\n", __func__,
  2023.                 (status == CHARGER_USB) ? "USB" : "AC");
  2024.     } else {
  2025.         u32 health = s3c_get_bat_health();
  2026.  
  2027.         status = CHARGER_BATTERY;
  2028.         s3c_set_chg_en(DISABLE);
  2029.  
  2030.         if (health == POWER_SUPPLY_HEALTH_OVERHEAT ||
  2031.                 health == POWER_SUPPLY_HEALTH_COLD) {
  2032.             s3c_set_bat_health(POWER_SUPPLY_HEALTH_GOOD);
  2033.         }
  2034.     }
  2035.     dev_dbg(dev, "%s: gpio_chg_en %s\n", __func__,
  2036.             gpio_get_value_ex(gpio_chg_en)?"disabled":"enabled");
  2037.  
  2038.     s3c_cable_status_update(status);
  2039.     mutex_unlock(&work_lock);
  2040. }
  2041.  
  2042. static void s3c_bat_work(struct work_struct *work)
  2043. {
  2044. #ifdef __ADJUST_RECHARGE_ADC__
  2045.     static int pre_rechar = 0;
  2046.     static int cnt = 0;
  2047.     if (s3c_bat_info.bat_info.batt_is_full == 1 && full_charge_flag == 1) {
  2048.         batt_recharging = -1;
  2049.         pre_rechar = 1;
  2050.         full_charge_flag = 0;
  2051.     }
  2052.  
  2053.     if (pre_rechar) {
  2054.         if (++cnt > 10) {
  2055.             int adc = s3c_bat_get_adc_data(S3C_ADC_VOLTAGE);
  2056.             batt_recharging = adc - BATT_RECHARGE_CODE;
  2057.             dev_info(dev, "%s: batt_recharging=%d\n", __func__,
  2058.                     batt_recharging);
  2059.             pre_rechar = 0;
  2060.             cnt = 0;
  2061.         }
  2062.     }
  2063. #endif /* __ADJUST_RECHARGE_ADC__ */
  2064.  
  2065.     dev_dbg(dev, "%s\n", __func__);
  2066.  
  2067.     s3c_bat_status_update(
  2068.             &s3c_power_supplies[CHARGER_BATTERY]);
  2069. }
  2070.  
  2071. static void s3c_cable_work(struct work_struct *work)
  2072. {
  2073.     dev_dbg(dev, "%s\n", __func__);
  2074.     s3c_cable_check_status();
  2075. }
  2076.  
  2077. #ifdef COMPENSATE_BOOTING
  2078. static void s3c_compensate_boot_work(struct work_struct *work)
  2079. {
  2080.     dev_info(dev, "%s ++\n", __func__);
  2081.     msleep(50000); /* 50sec */
  2082.     s3c_bat_set_compesation(0, OFFSET_BOOTING, COMPENSATE_BOOTING);
  2083.     dev_info(dev, "%s --\n", __func__);
  2084. }
  2085. #endif /* COMPENSATE_BOOTING */
  2086.  
  2087. #ifdef CONFIG_PM
  2088. static int s3c_bat_suspend(struct platform_device *pdev,
  2089.         pm_message_t state)
  2090. {
  2091.     dev_info(dev, "%s\n", __func__);
  2092.  
  2093.     if (s3c_bat_info.polling)
  2094.         del_timer_sync(&polling_timer);
  2095.  
  2096.     flush_scheduled_work();
  2097.     disable_irq(IRQ_TA_CONNECTED_N);
  2098.     disable_irq(IRQ_TA_CHG_N);
  2099.     return 0;
  2100. }
  2101.  
  2102. static int s3c_bat_resume(struct platform_device *pdev)
  2103. {
  2104.     dev_info(dev, "%s\n", __func__);
  2105.     wake_lock(&vbus_wake_lock);
  2106.     enable_irq(IRQ_TA_CONNECTED_N);
  2107.     enable_irq(IRQ_TA_CHG_N);
  2108.     schedule_work(&bat_work);
  2109.     schedule_work(&cable_work);
  2110.  
  2111.     if (s3c_bat_info.polling)
  2112.         mod_timer(&polling_timer,
  2113.               jiffies + msecs_to_jiffies(s3c_bat_info.polling_interval));
  2114.     return 0;
  2115. }
  2116. #else
  2117. #define s3c_bat_suspend NULL
  2118. #define s3c_bat_resume NULL
  2119. #endif /* CONFIG_PM */
  2120.  
  2121. static void polling_timer_func(unsigned long unused)
  2122. {
  2123.     dev_dbg(dev, "%s\n", __func__);
  2124.     schedule_work(&bat_work);
  2125.  
  2126.     mod_timer(&polling_timer,
  2127.           jiffies + msecs_to_jiffies(s3c_bat_info.polling_interval));
  2128. }
  2129.  
  2130. static void cable_timer_func(unsigned long unused)
  2131. {
  2132.     dev_info(dev, "%s : intr cnt = %d\n", __func__, cable_intr_cnt);
  2133.     cable_intr_cnt = 0;
  2134.     schedule_work(&cable_work);
  2135. }
  2136.  
  2137. static irqreturn_t s3c_cable_changed_isr(int irq, void *power_supply)
  2138. {
  2139.     dev_dbg(dev, "%s: irq=0x%x, gpio_ta_connected=%x\n", __func__, irq,
  2140.             gpio_get_value(gpio_ta_connected));
  2141.  
  2142.     if (!s3c_battery_initial)
  2143.         return IRQ_HANDLED;
  2144.  
  2145.     s3c_bat_info.bat_info.batt_is_full = 0;
  2146. #ifdef __ADJUST_RECHARGE_ADC__
  2147.     batt_recharging = -1;
  2148. #endif /* __ADJUST_RECHARGE_ADC__ */
  2149. #ifdef __CHECK_CHG_CURRENT__
  2150.     clear_adc_sample(S3C_ADC_CHG_CURRENT);
  2151. #endif /* __CHECK_CHG_CURRENT__ */
  2152.  
  2153.     cable_intr_cnt++;
  2154.     if (timer_pending(&cable_timer))
  2155.         del_timer(&cable_timer);
  2156.  
  2157.     cable_timer.expires = jiffies + msecs_to_jiffies(50);
  2158.     add_timer(&cable_timer);
  2159.  
  2160.     /*
  2161.      * Wait a bit before reading ac/usb line status and setting charger,
  2162.      * because ac/usb status readings may lag from irq.
  2163.      */
  2164.     if (s3c_bat_info.polling)
  2165.         mod_timer(&polling_timer,
  2166.               jiffies + msecs_to_jiffies(s3c_bat_info.polling_interval));
  2167.  
  2168.     return IRQ_HANDLED;
  2169. }
  2170.  
  2171. static irqreturn_t s3c_cable_charging_isr(int irq, void *power_supply)
  2172. {
  2173.     int chg_ing = gpio_get_value(gpio_chg_ing);
  2174.     dev_dbg(dev, "%s: irq=0x%x, gpio_chg_ing=%d\n", __func__, irq, chg_ing);
  2175.  
  2176.     if (!s3c_battery_initial)
  2177.         return IRQ_HANDLED;
  2178. #ifndef __DISABLE_CHG_ING_INTR__
  2179.     if (chg_ing && !gpio_get_value(gpio_ta_connected) &&
  2180.             s3c_bat_info.bat_info.charging_enabled &&
  2181.             s3c_get_bat_health() == POWER_SUPPLY_HEALTH_GOOD) {
  2182.         s3c_set_chg_en(DISABLE);
  2183.         s3c_bat_info.bat_info.batt_is_full = 1;
  2184.         force_update = 1;
  2185.         full_charge_flag = 1;
  2186.     }
  2187.  
  2188.     schedule_work(&bat_work);
  2189.     /*
  2190.      * Wait a bit before reading ac/usb line status and setting charger,
  2191.      * because ac/usb status readings may lag from irq.
  2192.      */
  2193.     if (s3c_bat_info.polling)
  2194.         mod_timer(&polling_timer,
  2195.               jiffies + msecs_to_jiffies(s3c_bat_info.polling_interval));
  2196. #endif /* __DISABLE_CHG_ING_INTR__ */
  2197.  
  2198.     return IRQ_HANDLED;
  2199. }
  2200.  
  2201. static int __devinit s3c_bat_probe(struct platform_device *pdev)
  2202. {
  2203.     int i;
  2204.     int ret = 0;
  2205.  
  2206.     dev = &pdev->dev;
  2207.     dev_info(dev, "%s\n", __func__);
  2208.  
  2209.     s3c_bat_info.present = 1;
  2210.     s3c_bat_info.polling = 1;
  2211.     s3c_bat_info.polling_interval = POLLING_INTERVAL;
  2212.     s3c_bat_info.device_state = 0;
  2213.  
  2214.     s3c_bat_info.bat_info.batt_vol_adc_aver = 0;
  2215. #ifdef __TEST_MODE_INTERFACE__
  2216.     s3c_bat_info.bat_info.batt_vol_aver = 0;
  2217.     s3c_bat_info.bat_info.batt_temp_aver = 0;
  2218.     s3c_bat_info.bat_info.batt_temp_adc_aver = 0;
  2219.     s3c_bat_info.bat_info.batt_v_f_adc = 0;
  2220.  
  2221.     s3c_bat_info.bat_info.batt_test_mode = 0;
  2222.     s3c_power_supplies_test = s3c_power_supplies;
  2223. #endif /* __TEST_MODE_INTERFACE__ */
  2224.     s3c_bat_info.bat_info.batt_id = 0;
  2225.     s3c_bat_info.bat_info.batt_vol = 0;
  2226.     s3c_bat_info.bat_info.batt_vol_adc = 0;
  2227.     s3c_bat_info.bat_info.batt_vol_adc_cal = 0;
  2228.     s3c_bat_info.bat_info.batt_temp = 0;
  2229.     s3c_bat_info.bat_info.batt_temp_adc = 0;
  2230.     s3c_bat_info.bat_info.batt_temp_adc_cal = 0;
  2231.     s3c_bat_info.bat_info.batt_current = 0;
  2232.     s3c_bat_info.bat_info.level = 100;
  2233.     s3c_bat_info.bat_info.charging_source = CHARGER_BATTERY;
  2234.     s3c_bat_info.bat_info.charging_enabled = 0;
  2235.     s3c_bat_info.bat_info.batt_health = POWER_SUPPLY_HEALTH_GOOD;
  2236.  
  2237.     memset(adc_sample, 0x00, sizeof adc_sample);
  2238.  
  2239.     batt_max = BATT_CAL + BATT_MAXIMUM;
  2240.     batt_full = BATT_CAL + BATT_FULL;
  2241.     batt_safe_rech = BATT_CAL + BATT_SAFE_RECHARGE;
  2242.     batt_almost = BATT_CAL + BATT_ALMOST_FULL;
  2243.     batt_high = BATT_CAL + BATT_HIGH;
  2244.     batt_medium = BATT_CAL + BATT_MED;
  2245.     batt_low = BATT_CAL + BATT_LOW;
  2246.     batt_critical = BATT_CAL + BATT_CRITICAL;
  2247.     batt_min = BATT_CAL + BATT_MINIMUM;
  2248.     batt_off = BATT_CAL + BATT_OFF;
  2249. #ifdef __ADJUST_RECHARGE_ADC__
  2250.     batt_recharging = -1;
  2251. #endif /* __ADJUST_RECHARGE_ADC__ */
  2252.  
  2253. #ifdef __BATTERY_COMPENSATION__
  2254.     batt_compensation = 0;
  2255. #ifdef COMPENSATE_BOOTING
  2256.     s3c_bat_set_compesation(1, OFFSET_BOOTING, COMPENSATE_BOOTING);
  2257.     s3c_bat_set_compesation(1, OFFSET_LCD_ON, COMPENSATE_LCD);
  2258. #endif /* COMPENSATE_BOOTING */
  2259. #endif /* __BATTERY_COMPENSATION__ */
  2260.  
  2261.     INIT_WORK(&bat_work, s3c_bat_work);
  2262.     INIT_WORK(&cable_work, s3c_cable_work);
  2263.  
  2264. #ifdef COMPENSATE_BOOTING
  2265.     INIT_WORK(&compensate_boot_work, s3c_compensate_boot_work);
  2266.     batt_drv_wqueue = create_singlethread_workqueue("batt_drv_workqueue");
  2267. #endif /* COMPENSATE_BOOTING */
  2268.  
  2269. #ifdef __ALWAYS_AWAKE_DEVICE__
  2270.     dev_info(dev, "%s: always awake(wake_lock)\n", __func__);
  2271.     wake_lock(&wake_lock_for_dev);
  2272. #endif /* __ALWAYS_AWAKE_DEVICE__ */
  2273.  
  2274.     /* init power supplier framework */
  2275.     for (i = 0; i < ARRAY_SIZE(s3c_power_supplies); i++) {
  2276.         ret = power_supply_register(&pdev->dev,
  2277.                 &s3c_power_supplies[i]);
  2278.         if (ret) {
  2279.             dev_err(dev, "Failed to register"
  2280.                     "power supply %d,%d\n", i, ret);
  2281.             goto __end__;
  2282.         }
  2283.     }
  2284.  
  2285.     /* create sec detail attributes */
  2286.     s3c_bat_create_attrs(s3c_power_supplies[CHARGER_BATTERY].dev);
  2287.  
  2288. #ifdef __TEST_DEVICE_DRIVER__
  2289.     s3c_test_create_attrs(s3c_power_supplies[CHARGER_AC].dev);
  2290. #endif /* __TEST_DEVICE_DRIVER__ */
  2291.  
  2292.     /* Request IRQ */
  2293.     set_irq_type(IRQ_TA_CONNECTED_N, IRQ_TYPE_EDGE_BOTH);
  2294.     ret = request_irq(IRQ_TA_CONNECTED_N, s3c_cable_changed_isr,
  2295.               IRQF_DISABLED,
  2296.               DRIVER_NAME,
  2297.               &s3c_power_supplies[CHARGER_BATTERY]);
  2298.     if(ret)
  2299.         goto __end__;
  2300.  
  2301.     set_irq_type(IRQ_TA_CHG_N, IRQ_TYPE_EDGE_BOTH);
  2302.     ret = request_irq(IRQ_TA_CHG_N, s3c_cable_charging_isr,
  2303.               IRQF_DISABLED,
  2304.               DRIVER_NAME,
  2305.               &s3c_power_supplies[CHARGER_BATTERY]);
  2306.  
  2307.     if (ret)
  2308.         goto __ta_connected_irq_failed__;
  2309.  
  2310.     if (s3c_bat_info.polling) {
  2311.         dev_dbg(dev, "%s: will poll for status\n",
  2312.                 __func__);
  2313.         setup_timer(&polling_timer, polling_timer_func, 0);
  2314.         mod_timer(&polling_timer,
  2315.               jiffies + msecs_to_jiffies(s3c_bat_info.polling_interval));
  2316.     }
  2317.  
  2318.     setup_timer(&cable_timer, cable_timer_func, 0);
  2319.  
  2320.     s3c_battery_initial = 1;
  2321.     force_update = 0;
  2322.     full_charge_flag = 0;
  2323.  
  2324.     s3c_bat_status_update(
  2325.             &s3c_power_supplies[CHARGER_BATTERY]);
  2326.  
  2327. #ifdef __CHECK_BATTERY_V_F__
  2328. #ifdef __CHECK_BOARD_REV__
  2329.     if (system_rev >= rev_to_check)
  2330. #endif /* __CHECK_BOARD_REV__ */
  2331.         s3c_bat_check_v_f();
  2332. #endif /* __CHECK_BATTERY_V_F__ */
  2333.     s3c_cable_check_status();
  2334. __end__:
  2335.     return ret;
  2336. __ta_connected_irq_failed__:
  2337.     free_irq(IRQ_TA_CONNECTED_N,
  2338.             &s3c_power_supplies[CHARGER_BATTERY]);
  2339.     return ret;
  2340. }
  2341.  
  2342. static int __devexit s3c_bat_remove(struct platform_device *pdev)
  2343. {
  2344.     int i;
  2345.     dev_info(dev, "%s\n", __func__);
  2346.  
  2347.     if (s3c_bat_info.polling)
  2348.         del_timer_sync(&polling_timer);
  2349.  
  2350.     free_irq(IRQ_TA_CONNECTED_N,
  2351.             &s3c_power_supplies[CHARGER_BATTERY]);
  2352.     free_irq(IRQ_TA_CHG_N, &s3c_power_supplies[CHARGER_BATTERY]);
  2353.  
  2354.     for (i = 0; i < ARRAY_SIZE(s3c_power_supplies); i++) {
  2355.         power_supply_unregister(&s3c_power_supplies[i]);
  2356.     }
  2357.  
  2358.     return 0;
  2359. }
  2360.  
  2361. static struct platform_driver s3c_bat_driver = {
  2362.     .driver.name    = DRIVER_NAME,
  2363.     .driver.owner   = THIS_MODULE,
  2364.     .probe      = s3c_bat_probe,
  2365.     .remove     = __devexit_p(s3c_bat_remove),
  2366.     .suspend    = s3c_bat_suspend,
  2367.     .resume     = s3c_bat_resume,
  2368. };
  2369.  
  2370. /* Initailize GPIO */
  2371. static void s3c_bat_init_hw(void)
  2372. {
  2373.     s3c_gpio_cfgpin(gpio_ta_connected,
  2374.             S3C_GPIO_SFN(gpio_ta_connected_af));
  2375.     s3c_gpio_setpull(gpio_ta_connected, S3C_GPIO_PULL_UP);
  2376.  
  2377.     s3c_gpio_cfgpin(gpio_chg_ing,
  2378.             S3C_GPIO_SFN(gpio_chg_ing_af));
  2379.     s3c_gpio_setpull(gpio_chg_ing, S3C_GPIO_PULL_UP);
  2380. #ifndef __USE_EGPIO__
  2381.     s3c_gpio_cfgpin(gpio_chg_en,
  2382.             S3C_GPIO_SFN(gpio_chg_en_af));
  2383.     s3c_gpio_setpull(gpio_chg_en, S3C_GPIO_PULL_NONE);
  2384. #endif /* __USE_EGPIO__ */
  2385.     gpio_set_value_ex(gpio_chg_en, GPIO_LEVEL_HIGH);
  2386. }
  2387.  
  2388. static int __init s3c_bat_init(void)
  2389. {
  2390.     pr_info("%s\n", __func__);
  2391.     s3c_bat_init_hw();
  2392.  
  2393.     wake_lock_init(&vbus_wake_lock, WAKE_LOCK_SUSPEND, "vbus_present");
  2394. #if (defined __TEST_DEVICE_DRIVER__  || defined __ALWAYS_AWAKE_DEVICE__)
  2395.     wake_lock_init(&wake_lock_for_dev, WAKE_LOCK_SUSPEND, "wake_lock_dev");
  2396. #endif /* __TEST_DEVICE_DRIVER__ || __ALWAYS_AWAKE_DEVICE__ */
  2397.  
  2398. #ifdef __FUEL_GAUGES_IC__
  2399.     if (i2c_add_driver(&fg_i2c_driver))
  2400.         pr_err("%s: Can't add fg i2c drv\n", __func__);
  2401. #endif /* __FUEL_GAUGES_IC__ */
  2402.     return platform_driver_register(&s3c_bat_driver);
  2403. }
  2404.  
  2405. static void __exit s3c_bat_exit(void)
  2406. {
  2407.     pr_info("%s\n", __func__);
  2408. #ifdef __FUEL_GAUGES_IC__
  2409.     i2c_del_driver(&fg_i2c_driver);
  2410. #endif /* __FUEL_GAUGES_IC__ */
  2411.     platform_driver_unregister(&s3c_bat_driver);
  2412. }
  2413.  
  2414. module_init(s3c_bat_init);
  2415. module_exit(s3c_bat_exit);
  2416.  
  2417. MODULE_AUTHOR("Minsung Kim <ms925.kim@samsung.com>");
  2418. MODULE_DESCRIPTION("S3C6410 battery driver");
  2419. MODULE_LICENSE("GPL");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement