* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
+#define RICOH619_BATTERY_VERSION "RICOH619_BATTERY_VERSION: 2014.05.06"
+
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/power/ricoh61x_battery_init.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
-#include <linux/delay.h>
-#include <mach/board.h>
-
+#include <linux/of.h>
+#include <linux/rtc.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/irqdomain.h>
/* define for function */
#define ENABLE_FUEL_GAUGE_FUNCTION
#define ENABLE_LOW_BATTERY_DETECTION
-#define ENABLE_FACTORY_MODE
+//#define ENABLE_FACTORY_MODE
#define DISABLE_CHARGER_TIMER
/* #define ENABLE_FG_KEEP_ON_MODE */
-
+/* #define ENABLE_OCV_TABLE_CALIB */
+//#define SUPPORT_USB_CONNECT_TO_ADP
/* FG setting */
#define RICOH619_CHARGE_RESUME_TIME 1
#define RICOH619_CHARGE_CALC_TIME 1
#define RICOH619_JEITA_UPDATE_TIME 60
+#define RICOH619_DELAY_TIME 60
/* define for FG parameter */
#define RICOH619_MAX_RESET_SOC_DIFF 5
#define RICOH619_GET_CHARGE_NUM 10
#define RICOH619_UPDATE_COUNT_DISP 4
#define RICOH619_UPDATE_COUNT_FULL 4
+#define RICOH619_UPDATE_COUNT_FULL_RESET 7
#define RICOH619_CHARGE_UPDATE_TIME 3
+#define RICOH619_FULL_WAIT_TIME 4
#define RE_CAP_GO_DOWN 10 /* 40 */
#define RICOH619_ENTER_LOW_VOL 70
-#define RICOH619_TAH_SEL2 5
-#define RICOH619_TAL_SEL2 6
+#define RICOH619_TAH_SEL2 5
+#define RICOH619_TAL_SEL2 6
+
+#define RICOH619_OCV_OFFSET_BOUND 3
+#define RICOH619_OCV_OFFSET_RATIO 2
+
+#define RICOH619_VADP_DROP_WORK
+#define RICOH619_TIME_CHG_STEP (1*HZ)// unit:secound
+#define RICOH619_TIME_CHG_COUNT 15*60//only for test //15*60
+
/* define for FG status */
enum {
RICOH619_SOCA_START,
struct ricoh619_soca_info {
int Rbat;
int n_cap;
+ int ocv_table_def[11];
int ocv_table[11];
+ int ocv_table_low[11];
int soc; /* Latest FG SOC value */
int displayed_soc;
int suspend_soc;
int chg_status; /* chg_status */
int soc_delta; /* soc delta for status3(DISP) */
int cc_delta;
+ int cc_cap_offset;
int last_soc;
+ int last_displayed_soc;
int ready_fg;
int reset_count;
int reset_soc[3];
- int reset_flg_90;
- int reset_flg_95;
- int f_chg_margin;
+ int chg_cmp_times;
int dischg_state;
int Vbat[RICOH619_GET_CHARGE_NUM];
int Vsys[RICOH619_GET_CHARGE_NUM];
int Ibat[RICOH619_GET_CHARGE_NUM];
int Vbat_ave;
+ int Vbat_old;
int Vsys_ave;
int Ibat_ave;
int chg_count;
- int update_count;
+ int full_reset_count;
+ int soc_full;
+ int fc_cap;
/* for LOW VOL state */
int target_use_cap;
int hurry_up_flg;
+ int zero_flg;
int re_cap_old;
int cutoff_ocv;
int Rsys;
int target_vsys;
int target_ibat;
int jt_limit;
+ int OCV100_min;
+ int OCV100_max;
+ int R_low;
+ int rsoc_ready_flag;
+ int init_pswr;
+ int last_cc_sum;
};
struct ricoh619_battery_info {
struct delayed_work charge_monitor_work;
struct delayed_work get_charge_work;
struct delayed_work jeita_work;
+ struct delayed_work charge_complete_ready;
struct work_struct irq_work; /* for Charging & VUSB/VADP */
struct work_struct usb_irq_work; /* for ADC_VUSB */
-
+ #ifdef RICOH619_VADP_DROP_WORK
+ struct delayed_work vadp_drop_work;
+ #endif
struct workqueue_struct *monitor_wqueue;
struct workqueue_struct *workqueue; /* for Charging & VUSB/VADP */
struct workqueue_struct *usb_workqueue; /* for ADC_VUSB */
int ch_icchg;
int fg_target_vsys;
int fg_target_ibat;
+ int fg_poff_vbat;
int jt_en;
int jt_hw_sw;
int jt_temp_h;
int jt_ichg_h;
int jt_ichg_l;
+ int chg_complete_rd_flag;
+ int chg_complete_rd_cnt;
+ int chg_complete_tm_ov_flag;
+ int chg_complete_sleep_flag;
+ int chg_old_dsoc;
+
int num;
};
+struct power_supply powerac;
+struct power_supply powerusb;
+
+int g_full_flag;
int charger_irq;
/* this value is for mfd fucntion */
int g_soc;
int g_fg_on_mode;
-extern int dwc_vbus_status(void);
+int type_n;
+extern int dwc_otg_check_dpdm(bool wait);
/*This is for full state*/
-int g_full_flag;
-static int BatteryTableFlageDef=0;
+static int BatteryTableFlagDef=0;
static int BatteryTypeDef=0;
static int Battery_Type(void)
{
static int Battery_Table(void)
{
- return BatteryTableFlageDef;
+ return BatteryTableFlagDef;
}
static void ricoh619_battery_work(struct work_struct *work)
static int measure_vbatt_FG(struct ricoh619_battery_info *info, int *data);
static int measure_Ibatt_FG(struct ricoh619_battery_info *info, int *data);
static int calc_capacity(struct ricoh619_battery_info *info);
+static int calc_capacity_2(struct ricoh619_battery_info *info);
static int get_OCV_init_Data(struct ricoh619_battery_info *info, int index);
static int get_OCV_voltage(struct ricoh619_battery_info *info, int index);
static int get_check_fuel_gauge_reg(struct ricoh619_battery_info *info,
int Reg_h, int Reg_l, int enable_bit);
static int calc_capacity_in_period(struct ricoh619_battery_info *info,
- int *cc_cap, bool *is_charging);
-static int get_charge_priority(struct ricoh619_battery_info *info, bool *data);
-static int set_charge_priority(struct ricoh619_battery_info *info, bool *data);
+ int *cc_cap, bool *is_charging, bool cc_rst);
+//static int get_charge_priority(struct ricoh619_battery_info *info, bool *data);
+//static int set_charge_priority(struct ricoh619_battery_info *info, bool *data);
static int get_power_supply_status(struct ricoh619_battery_info *info);
+static int get_power_supply_Android_status(struct ricoh619_battery_info *info);
static int measure_vsys_ADC(struct ricoh619_battery_info *info, int *data);
static int Calc_Linear_Interpolation(int x0, int y0, int x1, int y1, int y);
static int get_battery_temp(struct ricoh619_battery_info *info);
+static int get_battery_temp_2(struct ricoh619_battery_info *info);
static int check_jeita_status(struct ricoh619_battery_info *info, bool *is_jeita_updated);
+static void ricoh619_scaling_OCV_table(struct ricoh619_battery_info *info, int cutoff_vol, int full_vol, int *start_per, int *end_per);
+//static int ricoh619_Check_OCV_Offset(struct ricoh619_battery_info *info);
static int calc_ocv(struct ricoh619_battery_info *info)
{
return ocv;
}
+#if 0
+static int set_Rlow(struct ricoh619_battery_info *info)
+{
+ int err;
+ int Rbat_low_max;
+ uint8_t val;
+ int Vocv;
+ int temp;
+
+ if (info->soca->Rbat == 0)
+ info->soca->Rbat = get_OCV_init_Data(info, 12) * 1000 / 512
+ * 5000 / 4095;
+
+ Vocv = calc_ocv(info);
+ Rbat_low_max = info->soca->Rbat * 1.5;
+
+ if (Vocv < get_OCV_voltage(info,3))
+ {
+ info->soca->R_low = Calc_Linear_Interpolation(info->soca->Rbat,get_OCV_voltage(info,3),
+ Rbat_low_max, get_OCV_voltage(info,0), Vocv);
+ RICOH_FG_DBG("PMU: Modify RBAT from %d to %d ", info->soca->Rbat, info->soca->R_low);
+ temp = info->soca->R_low *4095/5000*512/1000;
+
+ val = info->soca->R_low>>8;
+ err = ricoh619_write_bank1(info->dev->parent, 0xD4, val);
+ if (err < 0) {
+ dev_err(info->dev, "batterry initialize error\n");
+ return err;
+ }
+
+ val = info->soca->R_low & 0xff;
+ err = ricoh619_write_bank1(info->dev->parent, 0xD5, val);
+ if (err < 0) {
+ dev_err(info->dev, "batterry initialize error\n");
+ return err;
+ }
+ }
+ else info->soca->R_low = 0;
+
+
+ return err;
+}
+
+static int Set_back_ocv_table(struct ricoh619_battery_info *info)
+{
+ int err;
+ uint8_t val;
+ int temp;
+ int i;
+ uint8_t debug_disp[22];
+
+ /* Modify back ocv table */
+
+ if (0 != info->soca->ocv_table_low[0])
+ {
+ for (i = 0 ; i < 11; i++){
+ battery_init_para[info->num][i*2 + 1] = info->soca->ocv_table_low[i];
+ battery_init_para[info->num][i*2] = info->soca->ocv_table_low[i] >> 8;
+ }
+ err = ricoh619_clr_bits(info->dev->parent, FG_CTRL_REG, 0x01);
+
+ err = ricoh619_bulk_writes_bank1(info->dev->parent,
+ BAT_INIT_TOP_REG, 22, battery_init_para[info->num]);
+
+ err = ricoh619_set_bits(info->dev->parent, FG_CTRL_REG, 0x01);
+
+ /* debug comment start*/
+ err = ricoh619_bulk_reads_bank1(info->dev->parent,
+ BAT_INIT_TOP_REG, 22, debug_disp);
+ for (i = 0; i < 11; i++){
+ RICOH_FG_DBG("PMU : %s : after OCV table %d 0x%x\n",__func__, i * 10, (debug_disp[i*2] << 8 | debug_disp[i*2+1]));
+ }
+ /* end */
+ /* clear table*/
+ for(i = 0; i < 11; i++)
+ {
+ info->soca->ocv_table_low[i] = 0;
+ }
+ }
+
+ /* Modify back Rbat */
+ if (0!=info->soca->R_low)
+ {
+ RICOH_FG_DBG("PMU: Modify back RBAT from %d to %d ", info->soca->R_low,info->soca->Rbat);
+ temp = info->soca->Rbat*4095/5000*512/1000;
+
+ val = info->soca->R_low>>8;
+ err = ricoh619_write_bank1(info->dev->parent, 0xD4, val);
+ if (err < 0) {
+ dev_err(info->dev, "batterry initialize error\n");
+ return err;
+ }
+
+ val = info->soca->R_low & 0xff;
+ err = ricoh619_write_bank1(info->dev->parent, 0xD5, val);
+ if (err < 0) {
+ dev_err(info->dev, "batterry initialize error\n");
+ return err;
+ }
+
+ info->soca->R_low = 0;
+ }
+ return 0;
+}
+
+/**
+**/
+
+static int ricoh619_Check_OCV_Offset(struct ricoh619_battery_info *info)
+{
+ int ocv_table[11]; // HEX value
+ int i;
+ int temp;
+ int ret;
+ uint8_t debug_disp[22];
+ uint8_t val = 0;
+
+ RICOH_FG_DBG("PMU : %s : calc ocv %d get OCV %d\n",__func__,calc_ocv(info),get_OCV_voltage(info, RICOH619_OCV_OFFSET_BOUND));
+
+ /* check adp/usb status */
+ ret = ricoh619_read(info->dev->parent, CHGSTATE_REG, &val);
+ if (ret < 0) {
+ dev_err(info->dev, "Error in reading the control register\n");
+ return ret;
+ }
+
+ val = (val & 0xC0) >> 6;
+
+ if (val != 0){ /* connect adp or usb */
+ if (calc_ocv(info) < get_OCV_voltage(info, RICOH619_OCV_OFFSET_BOUND) )
+ {
+ if(0 == info->soca->ocv_table_low[0]){
+ for (i = 0 ; i < 11; i++){
+ ocv_table[i] = (battery_init_para[info->num][i*2]<<8) | (battery_init_para[info->num][i*2+1]);
+ RICOH_FG_DBG("PMU : %s : OCV table %d 0x%x\n",__func__,i * 10, ocv_table[i]);
+ info->soca->ocv_table_low[i] = ocv_table[i];
+ }
+
+ for (i = 0 ; i < 11; i++){
+ temp = ocv_table[i] * (100 + RICOH619_OCV_OFFSET_RATIO) / 100;
+
+ battery_init_para[info->num][i*2 + 1] = temp;
+ battery_init_para[info->num][i*2] = temp >> 8;
+ }
+ ret = ricoh619_clr_bits(info->dev->parent, FG_CTRL_REG, 0x01);
+
+ ret = ricoh619_bulk_writes_bank1(info->dev->parent,
+ BAT_INIT_TOP_REG, 22, battery_init_para[info->num]);
+
+ ret = ricoh619_set_bits(info->dev->parent, FG_CTRL_REG, 0x01);
+
+ /* debug comment start*/
+ ret = ricoh619_bulk_reads_bank1(info->dev->parent,
+ BAT_INIT_TOP_REG, 22, debug_disp);
+ for (i = 0; i < 11; i++){
+ RICOH_FG_DBG("PMU : %s : after OCV table %d 0x%x\n",__func__, i * 10, (debug_disp[i*2] << 8 | debug_disp[i*2+1]));
+ }
+ /* end */
+ }
+ }
+ }
+
+ return 0;
+}
+#endif
+static int reset_FG_process(struct ricoh619_battery_info *info)
+{
+ int err;
+
+ //err = set_Rlow(info);
+ //err = ricoh619_Check_OCV_Offset(info);
+ err = ricoh619_write(info->dev->parent,
+ FG_CTRL_REG, 0x51);
+ info->soca->ready_fg = 0;
+ return err;
+}
+
+
static int check_charge_status_2(struct ricoh619_battery_info *info, int displayed_soc_temp)
{
if (displayed_soc_temp < 0)
displayed_soc_temp = 0;
get_power_supply_status(info);
- /* for issue 5 */
+ info->soca->soc = calc_capacity(info) * 100;
+
if (POWER_SUPPLY_STATUS_FULL == info->soca->chg_status) {
- g_full_flag = 1;
- info->soca->displayed_soc = 100*100;
+ if ((info->first_pwon == 1)
+ && (RICOH619_SOCA_START == info->soca->status)) {
+ g_full_flag = 1;
+ info->soca->soc_full = info->soca->soc;
+ info->soca->displayed_soc = 100*100;
+ info->soca->full_reset_count = 0;
+ } else {
+ if ( (displayed_soc_temp > 97*100)
+ && (calc_ocv(info) > (get_OCV_voltage(info, 9) + (get_OCV_voltage(info, 10) - get_OCV_voltage(info, 9))*7/10) )){
+ g_full_flag = 1;
+ info->soca->soc_full = info->soca->soc;
+ info->soca->displayed_soc = 100*100;
+ info->soca->full_reset_count = 0;
+ } else {
+ g_full_flag = 0;
+ info->soca->displayed_soc = displayed_soc_temp;
+ }
+
+ }
}
- if (info->soca->Ibat_ave >= 0) { /* for issue 3 */
+ if (info->soca->Ibat_ave >= 0) {
if (g_full_flag == 1) {
info->soca->displayed_soc = 100*100;
} else {
}
if (info->soca->Ibat_ave < 0) {
if (g_full_flag == 1) {
- if ((calc_ocv(info) < (get_OCV_voltage(info, 10) - info->soca->f_chg_margin) )
- && (info->soca->soc/100 <= 98) ) {
+ if (calc_ocv(info) < (get_OCV_voltage(info, 9) + (get_OCV_voltage(info, 10) - get_OCV_voltage(info, 9))*7/10) ) {
g_full_flag = 0;
- info->soca->displayed_soc = 100*100;
+ //info->soca->displayed_soc = 100*100;
+ info->soca->displayed_soc = displayed_soc_temp;
} else {
info->soca->displayed_soc = 100*100;
}
* @is_charging: Flag of charging current direction
* TRUE : charging (plus)
* FALSE: discharging (minus)
+* @cc_rst: reset CC_SUM or not
+* TRUE : reset
+* FALSE: not reset
**/
static int calc_capacity_in_period(struct ricoh619_battery_info *info,
- int *cc_cap, bool *is_charging)
+ int *cc_cap, bool *is_charging, bool cc_rst)
{
int err;
- uint8_t cc_sum_reg[4];
- uint8_t cc_clr[4] = {0, 0, 0, 0};
- uint8_t fa_cap_reg[2];
- uint16_t fa_cap;
- uint32_t cc_sum;
- int cc_stop_flag;
- uint8_t status;
- uint8_t charge_state;
- int Ocv;
+ uint8_t cc_sum_reg[4];
+ uint8_t cc_clr[4] = {0, 0, 0, 0};
+ uint8_t fa_cap_reg[2];
+ uint16_t fa_cap;
+ uint32_t cc_sum;
+ int cc_stop_flag;
+ uint8_t status;
+ uint8_t charge_state;
+ int Ocv;
+ uint32_t cc_cap_temp;
+ uint32_t cc_cap_min;
+ int cc_cap_res;
*is_charging = true; /* currrent state initialize -> charging */
if (err < 0)
goto out;
- /* CC_SUM <- 0 */
- err = ricoh619_bulk_writes(info->dev->parent,
- CC_SUMREG3_REG, 4, cc_clr);
- if (err < 0)
- goto out;
+ if (cc_rst == true) {
+ /* CC_SUM <- 0 */
+ err = ricoh619_bulk_writes(info->dev->parent,
+ CC_SUMREG3_REG, 4, cc_clr);
+ if (err < 0)
+ goto out;
+ }
/* CC_pause exist */
err = ricoh619_write(info->dev->parent, CC_CTRL_REG, 0);
cc_sum = (cc_sum^0xffffffff)+0x01;
*is_charging = false; /* discharge */
}
+ /* (CC_SUM x 10000)/3600/FA_CAP */
+ *cc_cap = cc_sum*25/9/fa_cap; /* unit is 0.01% */
- *cc_cap = cc_sum*25/9/fa_cap; /* CC_SUM/3600/FA_CAP */
-
+ //////////////////////////////////////////////////////////////////
+ cc_cap_min = fa_cap*3600/100/100/100; /* Unit is 0.0001% */
+ cc_cap_temp = cc_sum / cc_cap_min;
+
+ cc_cap_res = cc_cap_temp % 100;
+
+ RICOH_FG_DBG("PMU: cc_sum = %d: cc_cap_res= %d: \n", cc_sum, cc_cap_res);
+
+
+ if(*is_charging) {
+ info->soca->cc_cap_offset += cc_cap_res;
+ if (info->soca->cc_cap_offset >= 100) {
+ *cc_cap += 1;
+ info->soca->cc_cap_offset %= 100;
+ }
+ } else {
+ info->soca->cc_cap_offset -= cc_cap_res;
+ if (info->soca->cc_cap_offset <= -100) {
+ *cc_cap += 1;
+ info->soca->cc_cap_offset %= 100;
+ }
+ }
+ RICOH_FG_DBG("PMU: cc_cap_offset= %d: \n", info->soca->cc_cap_offset);
+
+ //////////////////////////////////////////////////////////////////
return 0;
out:
dev_err(info->dev, "Error !!-----\n");
**/
static int get_target_use_cap(struct ricoh619_battery_info *info)
{
- int i;
+ int i,j;
int ocv_table[11];
int temp;
- int Target_Cutoff_Vol;
+// int Target_Cutoff_Vol = 0;
int Ocv_ZeroPer_now;
int Ibat_now;
int fa_cap,use_cap;
int CC_OnePer_step;
int Ibat_min;
+// int Ocv_now;
+ int Ocv_now_table;
+// int soc_per;
+// int use_cap_now;
+ int Rsys_now;
+
/* get const value */
Ibat_min = -1 * info->soca->target_ibat;
if (info->soca->Ibat_ave > Ibat_min) /* I bat is minus */
fa_cap = get_check_fuel_gauge_reg(info, FA_CAP_H_REG, FA_CAP_L_REG,
0x7fff);
use_cap = fa_cap - info->soca->re_cap_old;
-
- Ocv_ZeroPer_now = info->soca->target_vsys * 1000 - Ibat_now * info->soca->Rsys;
-
- RICOH_FG_DBG("PMU: ------- Rsys= %d: cutoff_ocv= %d: Ocv_ZeroPer_now= %d =======\n",
- info->soca->Rsys, info->soca->cutoff_ocv, Ocv_ZeroPer_now);
- /* get FA_CAP_now */
- /* Check Start % */
+ /* get OCV table % */
for (i = 0; i <= 10; i = i+1) {
temp = (battery_init_para[info->num][i*2]<<8)
| (battery_init_para[info->num][i*2+1]);
/* conversion unit 1 Unit is 1.22mv (5000/4095 mv) */
temp = ((temp * 50000 * 10 / 4095) + 5) / 10;
ocv_table[i] = temp;
+ RICOH_FG_DBG("PMU : %s : ocv_table %d is %d v\n",__func__, i, ocv_table[i]);
+ }
+
+ /* Find out Current OCV */
+ i = info->soca->soc/1000;
+ j = info->soca->soc - info->soca->soc/1000*1000;
+ Ocv_now_table = ocv_table[i]*100+(ocv_table[i+1]-ocv_table[i])*j/10;
+
+ Rsys_now = (info->soca->Vsys_ave - Ocv_now_table) / info->soca->Ibat_ave;
+ if (((abs(info->soca->soc - info->soca->displayed_soc)) > 10)
+ && (info->soca->Ibat_ave > -250)) {
+ if (Rsys_now < 0)
+ Rsys_now = max(-info->soca->Rbat, Rsys_now);
+ else
+ Rsys_now = min(info->soca->Rbat, Rsys_now);
}
+
+ Ocv_ZeroPer_now = info->soca->target_vsys * 1000 - Ibat_now * Rsys_now;
+
+ RICOH_FG_DBG("PMU: ------- Ocv_now_table= %d: Rsys_now= %d =======\n",
+ Ocv_now_table, Rsys_now);
+
+ RICOH_FG_DBG("PMU: ------- Rsys= %d: cutoff_ocv= %d: Ocv_ZeroPer_now= %d =======\n",
+ info->soca->Rsys, info->soca->cutoff_ocv, Ocv_ZeroPer_now);
+
+ /* get FA_CAP_now */
+
+
for (i = 1; i < 11; i++) {
+ RICOH_FG_DBG("PMU : %s : ocv_table %d is %d v Ocv_ZerPernow is %d\n",__func__, i, ocv_table[i],(Ocv_ZeroPer_now / 100));
if (ocv_table[i] >= Ocv_ZeroPer_now / 100) {
/* unit is 0.001% */
start_per = Calc_Linear_Interpolation(
}
}
+ start_per = max(0, start_per);
+
FA_CAP_now = fa_cap * ((10000 - start_per) / 100 ) / 100;
- RICOH_FG_DBG("PMU: ------- Target_Cutoff_Vol= %d: Ocv_ZeroPer_now= %d: start_per= %d =======\n",
- Target_Cutoff_Vol, Ocv_ZeroPer_now, start_per);
+ RICOH_FG_DBG("PMU: -------Ocv_ZeroPer_now= %d: start_per= %d =======\n",
+ Ocv_ZeroPer_now, start_per);
/* get RE_CAP_now */
RE_CAP_now = FA_CAP_now - use_cap;
- if (RE_CAP_now < RE_CAP_GO_DOWN || info->soca->Vsys_ave < info->soca->target_vsys*1000) {
+ if (RE_CAP_now < RE_CAP_GO_DOWN) {
info->soca->hurry_up_flg = 1;
- } else {
- info->soca->hurry_up_flg = 0;
- /* get CC_OnePer_step */
- if (info->soca->displayed_soc > 0) { /* avoid divide-by-0 */
- CC_OnePer_step = RE_CAP_now / (info->soca->displayed_soc / 100);
+ } else if (info->soca->Vsys_ave < info->soca->target_vsys*1000) {
+ info->soca->hurry_up_flg = 1;
+ } else if (info->fg_poff_vbat != 0) {
+ if (info->soca->Vbat_ave < info->fg_poff_vbat*1000) {
+ info->soca->hurry_up_flg = 1;
} else {
- CC_OnePer_step = 0;
+ info->soca->hurry_up_flg = 0;
}
- /* get info->soca->target_use_cap */
- info->soca->target_use_cap = use_cap + CC_OnePer_step;
+ } else {
+ info->soca->hurry_up_flg = 0;
+ }
+
+ /* get CC_OnePer_step */
+ if (info->soca->displayed_soc > 0) { /* avoid divide-by-0 */
+ CC_OnePer_step = RE_CAP_now / (info->soca->displayed_soc / 100 + 1);
+ } else {
+ CC_OnePer_step = 0;
+ }
+ /* get info->soca->target_use_cap */
+ info->soca->target_use_cap = use_cap + CC_OnePer_step;
+
+ RICOH_FG_DBG("PMU: ------- FA_CAP_now= %d: RE_CAP_now= %d: CC_OnePer_step= %d: target_use_cap= %d: hurry_up_flg= %d -------\n",
+ FA_CAP_now, RE_CAP_now, CC_OnePer_step, info->soca->target_use_cap, info->soca->hurry_up_flg);
+
+ return 0;
+}
+#ifdef ENABLE_OCV_TABLE_CALIB
+/**
+* Calibration OCV Table
+* - Update the value of VBAT on 100% in OCV table
+* if battery is Full charged.
+* - int vbat_ocv <- unit is uV
+**/
+static int calib_ocvTable(struct ricoh619_battery_info *info, int vbat_ocv)
+{
+ int ret;
+ int cutoff_ocv;
+ int i;
+ int ocv100_new;
+ int start_per = 0;
+ int end_per = 0;
+
+ RICOH_FG_DBG("PMU: %s\n", __func__);
+
+ if (info->soca->Ibat_ave > RICOH619_REL1_SEL_VALUE) {
+ RICOH_FG_DBG("PMU: %s IBAT > 64mA -- Not Calibration --\n", __func__);
+ return 0;
}
- RICOH_FG_DBG("PMU: ------- FA_CAP_now= %d: RE_CAP_now= %d: target_use_cap= %d: hurry_up_flg= %d -------\n",
- FA_CAP_now, RE_CAP_now, info->soca->target_use_cap, info->soca->hurry_up_flg);
+ if (vbat_ocv < info->soca->OCV100_max) {
+ if (vbat_ocv < info->soca->OCV100_min)
+ ocv100_new = info->soca->OCV100_min;
+ else
+ ocv100_new = vbat_ocv;
+ } else {
+ ocv100_new = info->soca->OCV100_max;
+ }
+ RICOH_FG_DBG("PMU : %s :max %d min %d current %d\n",__func__,info->soca->OCV100_max,info->soca->OCV100_min,vbat_ocv);
+ RICOH_FG_DBG("PMU : %s : New OCV 100% = 0x%x\n",__func__,ocv100_new);
+ /* FG_En Off */
+ ret = ricoh619_clr_bits(info->dev->parent, FG_CTRL_REG, 0x01);
+ if (ret < 0) {
+ dev_err("PMU: %s Error in FG_En OFF\n", __func__);
+ goto err;
+ }
+
+
+ //cutoff_ocv = (battery_init_para[info->num][0]<<8) | (battery_init_para[info->num][1]);
+ cutoff_ocv = get_OCV_voltage(info, 0);
+
+ info->soca->ocv_table_def[10] = info->soca->OCV100_max;
+
+ ricoh619_scaling_OCV_table(info, cutoff_ocv/1000, ocv100_new/1000, &start_per, &end_per);
+
+ ret = ricoh619_bulk_writes_bank1(info->dev->parent,
+ BAT_INIT_TOP_REG, 22, battery_init_para[info->num]);
+ if (ret < 0) {
+ dev_err(info->dev, "batterry initialize error\n");
+ goto err;
+ }
+
+ for (i = 0; i <= 10; i = i+1) {
+ info->soca->ocv_table[i] = get_OCV_voltage(info, i);
+ RICOH_FG_DBG("PMU: %s : * %d0%% voltage = %d uV\n",
+ __func__, i, info->soca->ocv_table[i]);
+ }
+
+ /* FG_En on & Reset*/
+ ret = reset_FG_process(info);
+ if (ret < 0) {
+ dev_err("PMU: %s Error in FG_En On & Reset\n", __func__);
+ goto err;
+ }
+
+ RICOH_FG_DBG("PMU: %s Exit \n", __func__);
return 0;
+err:
+ return ret;
+
}
+#endif
static void ricoh619_displayed_work(struct work_struct *work)
{
int last_soc_round;
int last_disp_round;
int displayed_soc_temp;
+ int disp_dec;
int cc_cap = 0;
bool is_charging = true;
- int i;
int re_cap,fa_cap,use_cap;
bool is_jeita_updated;
+ uint8_t reg_val;
+ int delay_flag = 0;
+ int Vbat = 0;
+ int Ibat = 0;
+ int Vsys = 0;
+ int temp_ocv;
+ int fc_delta = 0;
struct ricoh619_battery_info *info = container_of(work,
struct ricoh619_battery_info, displayed_work.work);
is_jeita_updated = false;
if ((RICOH619_SOCA_START == info->soca->status)
- || (RICOH619_SOCA_STABLE == info->soca->status))
+ || (RICOH619_SOCA_STABLE == info->soca->status)
+ || (RICOH619_SOCA_FULL == info->soca->status))
info->soca->ready_fg = 1;
- /* judege Full state or Moni Vsys state */
+ /* judge Full state or Moni Vsys state */
if ((RICOH619_SOCA_DISP == info->soca->status)
|| (RICOH619_SOCA_STABLE == info->soca->status))
{
- /* for issue 1 solution start*/
- if(g_full_flag == 1){
+ /* caluc 95% ocv */
+ temp_ocv = get_OCV_voltage(info, 10) -
+ (get_OCV_voltage(info, 10) - get_OCV_voltage(info, 9))/2;
+
+ if(g_full_flag == 1){ /* for issue 1 solution start*/
info->soca->status = RICOH619_SOCA_FULL;
- info->soca->update_count = 0;
- }
- /* for issue1 solution end */
- /* check Full state or not*/
- if (info->soca->Ibat_ave >= 0) {
- if ((calc_ocv(info) > (get_OCV_voltage(info, 10) - info->soca->f_chg_margin))
- || (info->soca->displayed_soc/100 >= 99))
+ }else if ((POWER_SUPPLY_STATUS_FULL == info->soca->chg_status)
+ && (calc_ocv(info) > temp_ocv)) {
+ info->soca->status = RICOH619_SOCA_FULL;
+ g_full_flag = 0;
+ } else if (info->soca->Ibat_ave >= -20) {
+ /* for issue1 solution end */
+ /* check Full state or not*/
+ if ((calc_ocv(info) > (get_OCV_voltage(info, 9) + (get_OCV_voltage(info, 10) - get_OCV_voltage(info, 9))*7/10))
+ || (POWER_SUPPLY_STATUS_FULL == info->soca->chg_status)
+ || (info->soca->displayed_soc > 9850))
{
+ info->soca->status = RICOH619_SOCA_FULL;
g_full_flag = 0;
+ } else if ((calc_ocv(info) > (get_OCV_voltage(info, 9)))
+ && (info->soca->Ibat_ave < 300))
+ {
info->soca->status = RICOH619_SOCA_FULL;
- info->soca->update_count = 0;
+ g_full_flag = 0;
}
} else { /* dis-charging */
if (info->soca->displayed_soc/100 < RICOH619_ENTER_LOW_VOL) {
+ info->soca->target_use_cap = 0;
info->soca->status = RICOH619_SOCA_LOW_VOL;
}
}
}
if (RICOH619_SOCA_STABLE == info->soca->status) {
- info->soca->soc = calc_capacity(info) * 100;
- soc_round = info->soca->soc / 100;
- last_soc_round = info->soca->last_soc / 100;
-
- info->soca->soc_delta = soc_round - last_soc_round;
-
- //get charge status
- if (info->soca->chg_status == POWER_SUPPLY_STATUS_CHARGING) {
- if (soc_round >= 90) {
- if(soc_round < 95) {
- if (info->soca->reset_flg_90 == 0) {
- err = ricoh619_write(info->dev->parent,
- FG_CTRL_REG, 0x51);
- if (err< 0)
- dev_err(info->dev, "Error in writing the control register\n");
-
- info->soca->ready_fg = 0;
-
- for (i = 0; i < 3; i = i+1) {
- info->soca->reset_soc[i] = 0;
- }
- info->soca->stable_count = 0;
-
- info->soca->status = RICOH619_SOCA_FG_RESET;
- /* Delay for addition Reset Time (6s) */
- info->soca->stable_count = 1;
- queue_delayed_work(info->monitor_wqueue,
- &info->charge_stable_work,
- RICOH619_FG_RESET_TIME*HZ);
-
- info->soca->reset_flg_90 = 1;
- goto end_flow;
- }
- } else if (soc_round < 100) {
- if (info->soca->reset_flg_95 == 0) {
- err = ricoh619_write(info->dev->parent,
- FG_CTRL_REG, 0x51);
- if (err < 0)
- dev_err(info->dev, "Error in writing the control register\n");
-
- info->soca->ready_fg = 0;
-
- for (i = 0; i < 3; i = i+1) {
- info->soca->reset_soc[i] = 0;
- }
+ info->soca->soc = calc_capacity_2(info);
+ info->soca->soc_delta = info->soca->soc - info->soca->last_soc;
- info->soca->stable_count = 0;
- info->soca->status = RICOH619_SOCA_FG_RESET;
- info->soca->stable_count = 1;
- queue_delayed_work(info->monitor_wqueue,
- &info->charge_stable_work,
- RICOH619_FG_RESET_TIME*HZ);
-
- info->soca->reset_flg_95 = 1;
- goto end_flow;
- }
- }
- } else {
- info->soca->reset_flg_90 = 0;
- info->soca->reset_flg_95 = 0;
- }
- }
-
- if (info->soca->soc_delta >= -1 && info->soca->soc_delta <= 1) {
+ if (info->soca->soc_delta >= -100 && info->soca->soc_delta <= 100) {
info->soca->displayed_soc = info->soca->soc;
} else {
info->soca->status = RICOH619_SOCA_DISP;
}
info->soca->last_soc = info->soca->soc;
info->soca->soc_delta = 0;
- info->soca->update_count = 0;
} else if (RICOH619_SOCA_FULL == info->soca->status) {
err = check_jeita_status(info, &is_jeita_updated);
if (err < 0) {
goto end_flow;
}
info->soca->soc = calc_capacity(info) * 100;
- if (POWER_SUPPLY_STATUS_FULL == info->soca->chg_status) {
- if (0 == info->soca->jt_limit) {
- g_full_flag = 1;
- info->soca->displayed_soc = 100*100;
- info->soca->update_count = 0;
- } else {
- info->soca->update_count = 0;
- }
- }
- if (info->soca->Ibat_ave >= 0) { /* for issue 3 */
+ info->soca->last_soc = calc_capacity_2(info); /* for DISP */
+
+ if (info->soca->Ibat_ave >= -20) { /* charging */
if (0 == info->soca->jt_limit) {
if (g_full_flag == 1) {
- info->soca->displayed_soc = 100*100;
- info->soca->update_count = 0;
+
+ if (POWER_SUPPLY_STATUS_FULL == info->soca->chg_status) {
+ if(info->soca->full_reset_count < RICOH619_UPDATE_COUNT_FULL_RESET) {
+ info->soca->full_reset_count++;
+ } else if (info->soca->full_reset_count < (RICOH619_UPDATE_COUNT_FULL_RESET + 1)) {
+ err = reset_FG_process(info);
+ if (err < 0)
+ dev_err(info->dev, "Error in writing the control register\n");
+ info->soca->full_reset_count++;
+ goto end_flow;
+ } else if(info->soca->full_reset_count < (RICOH619_UPDATE_COUNT_FULL_RESET + 2)) {
+ info->soca->full_reset_count++;
+ info->soca->fc_cap = 0;
+ info->soca->soc_full = info->soca->soc;
+ }
+ } else {
+ if(info->soca->fc_cap < -1 * 200) {
+ g_full_flag = 0;
+ info->soca->displayed_soc = 99 * 100;
+ }
+ info->soca->full_reset_count = 0;
+ }
+
+
+ info->soca->chg_cmp_times = 0;
+ err = calc_capacity_in_period(info, &cc_cap, &is_charging, true);
+ if (err < 0)
+ dev_err(info->dev, "Read cc_sum Error !!-----\n");
+
+ fc_delta = (is_charging == true) ? cc_cap : -cc_cap;
+
+ info->soca->fc_cap = info->soca->fc_cap + fc_delta;
+
+ if (g_full_flag == 1){
+ info->soca->displayed_soc = 100*100;
+ }
} else {
- if (info->soca->displayed_soc/100 < 99) {
- info->soca->update_count++;
- if (info->soca->update_count
- >= RICOH619_UPDATE_COUNT_FULL) {
- info->soca->displayed_soc = info->soca->displayed_soc + 100;
- info->soca->update_count = 0;
+ if (calc_ocv(info) < (get_OCV_voltage(info, 8))) { /* fail safe*/
+ g_full_flag = 0;
+ info->soca->status = RICOH619_SOCA_DISP;
+ info->soca->soc_delta = 0;
+ } else if ((POWER_SUPPLY_STATUS_FULL == info->soca->chg_status)
+ && (info->soca->displayed_soc >= 9890)){
+ if(info->soca->chg_cmp_times > RICOH619_FULL_WAIT_TIME) {
+ info->soca->displayed_soc = 100*100;
+ g_full_flag = 1;
+ info->soca->full_reset_count = 0;
+ info->soca->soc_full = info->soca->soc;
+ info->soca->fc_cap = 0;
+#ifdef ENABLE_OCV_TABLE_CALIB
+ err = calib_ocvTable(info,calc_ocv(info));
+ if (err < 0)
+ dev_err(info->dev, "Calibration OCV Error !!\n");
+#endif
+ } else {
+ info->soca->chg_cmp_times++;
}
} else {
- info->soca->displayed_soc = 99 * 100;
- info->soca->update_count = 0;
+ fa_cap = get_check_fuel_gauge_reg(info, FA_CAP_H_REG, FA_CAP_L_REG,
+ 0x7fff);
+
+ if (info->soca->displayed_soc >= 9950) {
+ if((info->soca->soc_full - info->soca->soc) < 200) {
+ goto end_flow;
+ }
+ }
+ info->soca->chg_cmp_times = 0;
+
+ err = calc_capacity_in_period(info, &cc_cap, &is_charging, true);
+ if (err < 0)
+ dev_err(info->dev, "Read cc_sum Error !!-----\n");
+ info->soca->cc_delta
+ = (is_charging == true) ? cc_cap : -cc_cap;
+
+ if((POWER_SUPPLY_STATUS_FULL == info->soca->chg_status)
+ // || (info->soca->Ibat_ave > 200))
+ || (info->soca->Ibat_ave < info->ch_icchg*50 + 100) || (info->soca->displayed_soc<9700))
+ {
+ info->soca->displayed_soc += 13 * 3000 / fa_cap;
+ }
+ else {
+ info->soca->displayed_soc
+ = info->soca->displayed_soc + info->soca->cc_delta*8/10;
+ }
+
+ info->soca->displayed_soc
+ = min(10000, info->soca->displayed_soc);
+ info->soca->displayed_soc = max(0, info->soca->displayed_soc);
+
+ if (info->soca->displayed_soc >= 9890) {
+ info->soca->displayed_soc = 99 * 100;
+ }
}
}
} else {
- info->soca->update_count = 0;
+ info->soca->full_reset_count = 0;
}
- }
- if (info->soca->Ibat_ave < 0) { /* for issue 3 */
- info->soca->update_count = 0;
- if (g_full_flag == 1) {
- if ((calc_ocv(info) < (get_OCV_voltage(info, 10) - info->soca->f_chg_margin))
- && (info->soca->soc/100 <= 98)) { /* for issue 2 */
- g_full_flag = 0;
- info->soca->displayed_soc = 100*100;
- info->soca->status = RICOH619_SOCA_DISP;
- info->soca->last_soc = info->soca->soc;
- info->soca->soc_delta = 0;
- } else {
- info->soca->displayed_soc = 100*100;
+ } else { /* discharging */
+ if (info->soca->displayed_soc >= 9950) {
+ if (info->soca->Ibat_ave <= -1 * RICOH619_REL1_SEL_VALUE) {
+ if ((calc_ocv(info) < (get_OCV_voltage(info, 9) + (get_OCV_voltage(info, 10) - get_OCV_voltage(info, 9))*3/10))
+ || ((info->soca->soc_full - info->soca->soc) > 200)) {
+
+ g_full_flag = 0;
+ info->soca->full_reset_count = 0;
+ info->soca->displayed_soc = 100 * 100;
+ info->soca->status = RICOH619_SOCA_DISP;
+ info->soca->last_soc = info->soca->soc;
+ info->soca->soc_delta = 0;
+ } else {
+ info->soca->displayed_soc = 100 * 100;
+ }
+ } else { /* into relaxation state */
+ ricoh619_read(info->dev->parent, CHGSTATE_REG, ®_val);
+ if (reg_val & 0xc0) {
+ info->soca->displayed_soc = 100 * 100;
+ } else {
+ g_full_flag = 0;
+ info->soca->full_reset_count = 0;
+ info->soca->displayed_soc = 100 * 100;
+ info->soca->status = RICOH619_SOCA_DISP;
+ info->soca->last_soc = info->soca->soc;
+ info->soca->soc_delta = 0;
+ }
}
} else {
g_full_flag = 0;
info->soca->status = RICOH619_SOCA_DISP;
- info->soca->last_soc = info->soca->soc;
info->soca->soc_delta = 0;
+ info->soca->full_reset_count = 0;
+ info->soca->last_soc = info->soca->soc;
}
}
} else if (RICOH619_SOCA_LOW_VOL == info->soca->status) {
info->soca->status = RICOH619_SOCA_DISP;
info->soca->last_soc = info->soca->soc;
info->soca->soc_delta = 0;
- info->soca->update_count = 0;
} else {
re_cap = get_check_fuel_gauge_reg(info, RE_CAP_H_REG, RE_CAP_L_REG,
0x7fff);
0x7fff);
use_cap = fa_cap - re_cap;
- if ((info->soca->target_use_cap == 0)
- && (info->soca->hurry_up_flg == 0)) {
+ if (info->soca->target_use_cap == 0) {
info->soca->re_cap_old = re_cap;
get_target_use_cap(info);
}
-
- if((use_cap >= info->soca->target_use_cap)
- || (info->soca->hurry_up_flg == 1)) {
+
+ if(use_cap >= info->soca->target_use_cap) {
+ info->soca->displayed_soc = info->soca->displayed_soc - 100;
+ info->soca->displayed_soc = max(0, info->soca->displayed_soc);
+ info->soca->re_cap_old = re_cap;
+ } else if (info->soca->hurry_up_flg == 1) {
info->soca->displayed_soc = info->soca->displayed_soc - 100;
info->soca->displayed_soc = max(0, info->soca->displayed_soc);
info->soca->re_cap_old = re_cap;
info->soca->soc = calc_capacity(info) * 100;
}
}
- if (RICOH619_SOCA_DISP == info->soca->status) {
+ else if (RICOH619_SOCA_DISP == info->soca->status) {
- info->soca->soc = calc_capacity(info) * 100;
+ info->soca->soc = calc_capacity_2(info);
- soc_round = info->soca->soc / 100;
- last_soc_round = info->soca->last_soc / 100;
+ soc_round = (info->soca->soc + 50) / 100;
+ last_soc_round = (info->soca->last_soc + 50) / 100;
last_disp_round = (info->soca->displayed_soc + 50) / 100;
info->soca->soc_delta =
- info->soca->soc_delta + (soc_round - last_soc_round);
+ info->soca->soc_delta + (info->soca->soc - info->soca->last_soc);
info->soca->last_soc = info->soca->soc;
/* six case */
/* if SOC == DISPLAY move to stable */
info->soca->displayed_soc = info->soca->soc ;
info->soca->status = RICOH619_SOCA_STABLE;
+ delay_flag = 1;
} else if (info->soca->Ibat_ave > 0) {
if ((0 == info->soca->jt_limit) ||
- (POWER_SUPPLY_STATUS_FULL != info->soca->chg_status)) {
+ (POWER_SUPPLY_STATUS_FULL != info->soca->chg_status)) {
/* Charge */
if (last_disp_round < soc_round) {
/* Case 1 : Charge, Display < SOC */
- info->soca->update_count++;
- if ((info->soca->update_count
- >= RICOH619_UPDATE_COUNT_DISP)
- || (info->soca->soc_delta == 1)) {
+ if (info->soca->soc_delta >= 100) {
info->soca->displayed_soc
- = (last_disp_round + 1)*100;
- info->soca->update_count = 0;
- info->soca->soc_delta = 0;
+ = last_disp_round * 100 + 50;
+ info->soca->soc_delta -= 100;
+ if (info->soca->soc_delta >= 100)
+ delay_flag = 1;
+ } else {
+ info->soca->displayed_soc += 25;
+ disp_dec = info->soca->displayed_soc % 100;
+ if ((50 <= disp_dec) && (disp_dec <= 74))
+ info->soca->soc_delta = 0;
}
- if (info->soca->displayed_soc/100
+ if ((info->soca->displayed_soc + 50)/100
>= soc_round) {
info->soca->displayed_soc
= info->soca->soc ;
info->soca->status
= RICOH619_SOCA_STABLE;
+ delay_flag = 1;
}
} else if (last_disp_round > soc_round) {
/* Case 2 : Charge, Display > SOC */
- info->soca->update_count = 0;
- if (info->soca->soc_delta >= 3) {
- info->soca->displayed_soc =
- (last_disp_round + 1)*100;
- info->soca->soc_delta -= 3;
+ if (info->soca->soc_delta >= 300) {
+ info->soca->displayed_soc += 100;
+ info->soca->soc_delta -= 300;
}
- if (info->soca->displayed_soc/100
+ if ((info->soca->displayed_soc + 50)/100
<= soc_round) {
info->soca->displayed_soc
= info->soca->soc ;
info->soca->status
= RICOH619_SOCA_STABLE;
+ delay_flag = 1;
}
}
} else {
- info->soca->update_count = 0;
info->soca->soc_delta = 0;
}
} else {
/* Dis-Charge */
if (last_disp_round > soc_round) {
/* Case 3 : Dis-Charge, Display > SOC */
- info->soca->update_count++;
- if ((info->soca->update_count
- >= RICOH619_UPDATE_COUNT_DISP)
- || (info->soca->soc_delta == -1)) {
+ if (info->soca->soc_delta <= -100) {
info->soca->displayed_soc
- = (last_disp_round - 1)*100;
- info->soca->update_count = 0;
- info->soca->soc_delta = 0;
+ = last_disp_round * 100 - 75;
+ info->soca->soc_delta += 100;
+ if (info->soca->soc_delta <= -100)
+ delay_flag = 1;
+ } else {
+ info->soca->displayed_soc -= 25;
+ disp_dec = info->soca->displayed_soc % 100;
+ if ((25 <= disp_dec) && (disp_dec <= 49))
+ info->soca->soc_delta = 0;
}
- if (info->soca->displayed_soc/100
+ if ((info->soca->displayed_soc + 50)/100
<= soc_round) {
info->soca->displayed_soc
= info->soca->soc ;
info->soca->status
= RICOH619_SOCA_STABLE;
+ delay_flag = 1;
}
} else if (last_disp_round < soc_round) {
/* Case 4 : Dis-Charge, Display < SOC */
- info->soca->update_count = 0;
- if (info->soca->soc_delta <= -3) {
- info->soca->displayed_soc
- = (last_disp_round - 1)*100;
- info->soca->soc_delta += 3;
+ if (info->soca->soc_delta <= -300) {
+ info->soca->displayed_soc -= 100;
+ info->soca->soc_delta += 300;
}
- if (info->soca->displayed_soc/100
+ if ((info->soca->displayed_soc + 50)/100
>= soc_round) {
info->soca->displayed_soc
= info->soca->soc ;
info->soca->status
= RICOH619_SOCA_STABLE;
+ delay_flag = 1;
}
}
}
} else if (RICOH619_SOCA_UNSTABLE == info->soca->status) {
- if (0 == info->soca->jt_limit) {
- check_charge_status_2(info, info->soca->displayed_soc);
+ /* caluc 95% ocv */
+ temp_ocv = get_OCV_voltage(info, 10) -
+ (get_OCV_voltage(info, 10) - get_OCV_voltage(info, 9))/2;
+
+ if(g_full_flag == 1){ /* for issue 1 solution start*/
+ info->soca->status = RICOH619_SOCA_FULL;
+ err = reset_FG_process(info);
+ if (err < 0)
+ dev_err(info->dev, "Error in writing the control register\n");
+
+ goto end_flow;
+ }else if ((POWER_SUPPLY_STATUS_FULL == info->soca->chg_status)
+ && (calc_ocv(info) > temp_ocv)) {
+ info->soca->status = RICOH619_SOCA_FULL;
+ g_full_flag = 0;
+ err = reset_FG_process(info);
+ if (err < 0)
+ dev_err(info->dev, "Error in writing the control register\n");
+ goto end_flow;
+ } else if (info->soca->Ibat_ave >= -20) {
+ /* for issue1 solution end */
+ /* check Full state or not*/
+ if ((calc_ocv(info) > (get_OCV_voltage(info, 9) + (get_OCV_voltage(info, 10) - get_OCV_voltage(info, 9))*7/10))
+ || (POWER_SUPPLY_STATUS_FULL == info->soca->chg_status)
+ || (info->soca->displayed_soc > 9850))
+ {
+ info->soca->status = RICOH619_SOCA_FULL;
+ g_full_flag = 0;
+ err = reset_FG_process(info);
+ if (err < 0)
+ dev_err(info->dev, "Error in writing the control register\n");
+ goto end_flow;
+ } else if ((calc_ocv(info) > (get_OCV_voltage(info, 9)))
+ && (info->soca->Ibat_ave < 300))
+ {
+ info->soca->status = RICOH619_SOCA_FULL;
+ g_full_flag = 0;
+ err = reset_FG_process(info);
+ if (err < 0)
+ dev_err(info->dev, "Error in writing the control register\n");
+ goto end_flow;
+ }
}
+
+ err = ricoh619_read(info->dev->parent, PSWR_REG, &val);
+ val &= 0x7f;
+ info->soca->soc = val * 100;
+ if (err < 0) {
+ dev_err(info->dev,
+ "Error in reading PSWR_REG %d\n", err);
+ info->soca->soc
+ = calc_capacity(info) * 100;
+ }
+
+ err = calc_capacity_in_period(info, &cc_cap,
+ &is_charging, false);
+ if (err < 0)
+ dev_err(info->dev, "Read cc_sum Error !!-----\n");
+
+ info->soca->cc_delta
+ = (is_charging == true) ? cc_cap : -cc_cap;
+
+ displayed_soc_temp
+ = info->soca->soc + info->soca->cc_delta;
+ if (displayed_soc_temp < 0)
+ displayed_soc_temp = 0;
+ displayed_soc_temp
+ = min(9850, displayed_soc_temp);
+ displayed_soc_temp = max(0, displayed_soc_temp);
+
+ info->soca->displayed_soc = displayed_soc_temp;
+
} else if (RICOH619_SOCA_FG_RESET == info->soca->status) {
/* No update */
} else if (RICOH619_SOCA_START == info->soca->status) {
+
+ err = measure_Ibatt_FG(info, &Ibat);
+ err = measure_vbatt_FG(info, &Vbat);
+ err = measure_vsys_ADC(info, &Vsys);
+
+ info->soca->Ibat_ave = Ibat;
+ info->soca->Vbat_ave = Vbat;
+ info->soca->Vsys_ave = Vsys;
+
err = check_jeita_status(info, &is_jeita_updated);
is_jeita_updated = false;
if (err < 0) {
val &= 0x7f;
if (info->first_pwon) {
info->soca->soc = calc_capacity(info) * 100;
+ val = (info->soca->soc + 50)/100;
+ val &= 0x7f;
+ err = ricoh619_write(info->dev->parent, PSWR_REG, val);
+ if (err < 0)
+ dev_err(info->dev, "Error in writing PSWR_REG\n");
+ g_soc = val;
+
if ((info->soca->soc == 0) && (calc_ocv(info)
< get_OCV_voltage(info, 0))) {
info->soca->displayed_soc = 0;
} else {
info->soca->displayed_soc = info->soca->soc;
}
- info->soca->status = RICOH619_SOCA_UNSTABLE;
+ if (Ibat < 0) {
+ if (info->soca->displayed_soc < 300) {
+ info->soca->target_use_cap = 0;
+ info->soca->status = RICOH619_SOCA_LOW_VOL;
+ } else {
+ if ((info->fg_poff_vbat != 0)
+ && (Vbat < info->fg_poff_vbat * 1000) ){
+ info->soca->target_use_cap = 0;
+ info->soca->status = RICOH619_SOCA_LOW_VOL;
+ } else {
+ info->soca->status = RICOH619_SOCA_UNSTABLE;
+ }
+ }
+ } else {
+ info->soca->status = RICOH619_SOCA_UNSTABLE;
+ }
}
} else if (g_fg_on_mode && (val == 0x7f)) {
info->soca->soc = calc_capacity(info) * 100;
} else {
info->soca->displayed_soc = info->soca->soc;
}
+ info->soca->last_soc = info->soca->soc;
info->soca->status = RICOH619_SOCA_STABLE;
}
} else {
}
err = calc_capacity_in_period(info, &cc_cap,
- &is_charging);
+ &is_charging, false);
if (err < 0)
dev_err(info->dev, "Read cc_sum Error !!-----\n");
} else {
info->soca->displayed_soc = displayed_soc_temp;
}
- info->soca->status = RICOH619_SOCA_UNSTABLE;
+ info->soca->last_soc = calc_capacity(info) * 100;
+ if (Ibat < 0) {
+ if (info->soca->displayed_soc < 300) {
+ info->soca->target_use_cap = 0;
+ info->soca->status = RICOH619_SOCA_LOW_VOL;
+ } else {
+ if ((info->fg_poff_vbat != 0)
+ && (Vbat < info->fg_poff_vbat * 1000)){
+ info->soca->target_use_cap = 0;
+ info->soca->status = RICOH619_SOCA_LOW_VOL;
+ } else {
+ info->soca->status = RICOH619_SOCA_UNSTABLE;
+ }
+ }
+ } else {
+ if(info->soca->displayed_soc >= 9850)
+ {
+ info->soca->displayed_soc = 10000;
+ info->chg_complete_tm_ov_flag = 1;
+ }
+ info->soca->status = RICOH619_SOCA_UNSTABLE;
+ }
}
}
} else if (RICOH619_SOCA_ZERO == info->soca->status) {
if (calc_ocv(info) > get_OCV_voltage(info, 0)) {
- err = ricoh619_write(info->dev->parent,
- FG_CTRL_REG, 0x51);
+ err = reset_FG_process(info);
if (err < 0)
dev_err(info->dev, "Error in writing the control register\n");
+ info->soca->last_soc = calc_capacity_2(info);
info->soca->status = RICOH619_SOCA_STABLE;
- info->soca->ready_fg = 0;
}
- info->soca->displayed_soc = 0;
+ info->soca->displayed_soc = 0;
+ }
+end_flow:
+ /* keep DSOC = 1 when Vbat is over 3.4V*/
+ if( info->fg_poff_vbat != 0) {
+ if (info->soca->zero_flg == 1) {
+ if(info->soca->Ibat_ave >= 0) {
+ info->soca->zero_flg = 0;
+ }
+ info->soca->displayed_soc = 0;
+ } else if (info->soca->displayed_soc < 50) {
+ if (info->soca->Vbat_ave < 2000*1000) { /* error value */
+ info->soca->displayed_soc = 100;
+ } else if (info->soca->Vbat_ave < info->fg_poff_vbat*1000) {
+ info->soca->displayed_soc = 0;
+ info->soca->zero_flg = 1;
+ } else {
+ info->soca->displayed_soc = 100;
+ }
+ }
}
-end_flow:
+
if (g_fg_on_mode
&& (info->soca->status == RICOH619_SOCA_STABLE)) {
err = ricoh619_write(info->dev->parent, PSWR_REG, 0x7f);
if (err < 0)
dev_err(info->dev, "Error in writing PSWR_REG\n");
g_soc = 0x7F;
- } else {
- if (info->soca->displayed_soc < 0) {
- val = 0;
+ err = calc_capacity_in_period(info, &cc_cap,
+ &is_charging, true);
+ if (err < 0)
+ dev_err(info->dev, "Read cc_sum Error !!-----\n");
+
+ } else if (RICOH619_SOCA_UNSTABLE != info->soca->status) {
+ if ((info->soca->displayed_soc + 50) / 100 <= 1) {
+ val = 1;
} else {
val = (info->soca->displayed_soc + 50)/100;
val &= 0x7f;
g_soc = val;
- err = calc_capacity_in_period(info, &cc_cap, &is_charging);
+ err = calc_capacity_in_period(info, &cc_cap,
+ &is_charging, true);
if (err < 0)
dev_err(info->dev, "Read cc_sum Error !!-----\n");
}
if (0 == info->soca->ready_fg)
queue_delayed_work(info->monitor_wqueue, &info->displayed_work,
RICOH619_FG_RESET_TIME * HZ);
+ else if (delay_flag == 1)
+ queue_delayed_work(info->monitor_wqueue, &info->displayed_work,
+ RICOH619_DELAY_TIME * HZ);
else if (RICOH619_SOCA_DISP == info->soca->status)
queue_delayed_work(info->monitor_wqueue, &info->displayed_work,
RICOH619_DISPLAY_UPDATE_TIME * HZ);
RICOH619_DISPLAY_UPDATE_TIME * HZ);
mutex_unlock(&info->lock);
-
- if(true == is_jeita_updated)
+
+ if((true == is_jeita_updated)
+ || (info->soca->last_displayed_soc/100 != (info->soca->displayed_soc+50)/100))
power_supply_changed(&info->battery);
+ info->soca->last_displayed_soc = info->soca->displayed_soc+50;
+
+ if ((info->soca->displayed_soc >= 9850) && (info->soca->Ibat_ave > -20) && (info->capacity < 100)
+ && (info->soca->chg_status == POWER_SUPPLY_STATUS_CHARGING))
+ {
+ if(info->chg_complete_rd_flag == 0)
+ {
+ info->chg_complete_rd_flag = 1;
+ info->chg_complete_rd_cnt = 0;
+ queue_delayed_work(info->monitor_wqueue, &info->charge_complete_ready, 0);
+ }
+ }
+ else
+ {
+ info->chg_complete_rd_flag = 0;
+ }
+
+ if(info->chg_complete_tm_ov_flag == 1)
+ {
+ if(info->soca->displayed_soc < 9850 || info->soca->Ibat_ave < -20)
+ {
+ info->chg_complete_tm_ov_flag = 0;
+ power_supply_changed(&info->battery);
+ }
+ }
return;
}
if (2 <= info->soca->stable_count) {
if (3 == info->soca->stable_count
&& RICOH619_SOCA_FG_RESET == info->soca->status) {
- ret = ricoh619_write(info->dev->parent,
- FG_CTRL_REG, 0x51);
+ ret = reset_FG_process(info);
if (ret < 0)
dev_err(info->dev, "Error in writing the control register\n");
- info->soca->ready_fg = 0;
}
info->soca->stable_count = info->soca->stable_count - 1;
queue_delayed_work(info->monitor_wqueue,
return;
}
/* Do reset setting */
- ret = ricoh619_write(info->dev->parent,
- FG_CTRL_REG, 0x51);
+ ret = reset_FG_process(info);
if (ret < 0)
dev_err(info->dev, "Error in writing the control register\n");
- info->soca->ready_fg = 0;
info->soca->status = RICOH619_SOCA_FG_RESET;
/* Delay for addition Reset Time (6s) */
goto adjust;
} else {
/* Do reset setting */
- ret = ricoh619_write(info->dev->parent,
- FG_CTRL_REG, 0x51);
+ ret = reset_FG_process(info);
if (ret < 0)
dev_err(info->dev, "Error in writing the control register\n");
- info->soca->ready_fg = 0;
-
/* Delay for addition Reset Time (6s) */
queue_delayed_work(info->monitor_wqueue,
&info->charge_stable_work,
info->soca->last_soc = info->soca->soc;
info->soca->status = RICOH619_SOCA_DISP;
info->soca->soc_delta = 0;
- info->soca->update_count = 0;
}
mutex_unlock(&info->lock);
int i;
int err;
uint8_t val;
+ int cc_cap = 0;
+ bool is_charging = true;
for (i = 0; i <= 10; i = i+1) {
info->soca->ocv_table[i] = get_OCV_voltage(info, i);
dev_err(info->dev, "Error in writing the control register\n");
}
+ err = calc_capacity_in_period(info, &cc_cap, &is_charging, true);
+
msleep(6000);
err = ricoh619_write(info->dev->parent, CHGISET_REG, val);
* 5000 / 4095;
info->soca->n_cap = get_OCV_init_Data(info, 11);
- info->soca->f_chg_margin = (get_OCV_voltage(info, 10) -
- get_OCV_voltage(info, 9)) / 10 * 3;
info->soca->displayed_soc = 0;
+ info->soca->last_displayed_soc = 0;
info->soca->suspend_soc = 0;
info->soca->ready_fg = 0;
info->soca->soc_delta = 0;
- info->soca->update_count = 0;
+ info->soca->full_reset_count = 0;
+ info->soca->soc_full = 0;
+ info->soca->fc_cap = 0;
info->soca->status = RICOH619_SOCA_START;
/* stable count down 11->2, 1: reset; 0: Finished; */
info->soca->stable_count = 11;
+ info->soca->chg_cmp_times = 0;
info->soca->dischg_state = 0;
info->soca->Vbat_ave = 0;
+ info->soca->Vbat_old = 0;
info->soca->Vsys_ave = 0;
info->soca->Ibat_ave = 0;
info->soca->chg_count = 0;
info->soca->hurry_up_flg = 0;
info->soca->re_cap_old = 0;
info->soca->jt_limit = 0;
+ info->soca->zero_flg = 0;
+ info->soca->cc_cap_offset = 0;
+
+ for (i = 0; i < 11; i++) {
+ info->soca->ocv_table_low[i] = 0;
+ }
for (i = 0; i < RICOH619_GET_CHARGE_NUM; i++) {
info->soca->Vbat[i] = 0;
info->soca->Vsys[i] = 0;
info->soca->Ibat[i] = 0;
}
+
+ g_full_flag = 0;
#ifdef ENABLE_FG_KEEP_ON_MODE
g_fg_on_mode = 1;
}
#endif
+static void ricoh619_charging_complete_work(struct work_struct *work)
+{
+ struct ricoh619_battery_info *info = container_of(work,
+ struct ricoh619_battery_info, charge_complete_ready.work);
+
+ uint8_t time_ov_flag;
+ RICOH_FG_DBG("PMU: %s\n", __func__);
+ RICOH_FG_DBG("info->chg_complete_rd_cnt = %d\n", info->chg_complete_rd_cnt);
+ RICOH_FG_DBG("info->chg_complete_rd_flag = %d\n", info->chg_complete_rd_flag);
+ RICOH_FG_DBG("info->chg_complete_tm_ov_flag = %d\n", info->chg_complete_tm_ov_flag);
+
+ if(info->chg_complete_rd_flag == 1)
+ {
+ // start chg 99per to 100per timer
+ time_ov_flag = 0;
+ info->chg_complete_rd_flag = 2;
+ info->chg_complete_tm_ov_flag = 0;
+ }
+ else
+ {
+ if(info->capacity == 100)
+ {
+ // battery arriver to 100% earlier than time ov
+ time_ov_flag = 1;
+ info->chg_complete_rd_cnt = 0;
+ info->chg_complete_tm_ov_flag = 1;
+ }
+ else if(info->chg_complete_rd_cnt > RICOH619_TIME_CHG_COUNT)
+ {
+ // chg timer ov before cap arrive to 100%
+ time_ov_flag = 1;
+ info->chg_complete_tm_ov_flag = 1;
+ info->chg_complete_rd_cnt = 0;
+ info->soca->status = RICOH619_SOCA_FULL;
+ power_supply_changed(&info->battery);
+ }
+ else
+ {
+ time_ov_flag = 0;
+ info->chg_complete_tm_ov_flag = 0;
+ }
+ }
+
+ if ((time_ov_flag == 0) && (info->soca->chg_status == POWER_SUPPLY_STATUS_CHARGING))
+ {
+ info->chg_complete_rd_cnt++;
+ queue_delayed_work(info->monitor_wqueue, &info->charge_complete_ready,
+ RICOH619_TIME_CHG_STEP);
+ }
+ else
+ {
+ info->chg_complete_rd_flag = 0;
+ }
+
+ RICOH_FG_DBG("PMU2: %s return\n", __func__);
+ RICOH_FG_DBG("info->chg_complete_rd_cnt = %d\n", info->chg_complete_rd_cnt);
+ RICOH_FG_DBG("info->chg_complete_rd_flag = %d\n", info->chg_complete_rd_flag);
+ RICOH_FG_DBG("info->chg_complete_tm_ov_flag = %d\n", info->chg_complete_tm_ov_flag);
+ RICOH_FG_DBG("time_ov_flag = %d\n", time_ov_flag);
+
+}
static void ricoh619_changed_work(struct work_struct *work)
{
struct ricoh619_battery_info *info = container_of(work,
{
int temp;
int err = 0;
- uint8_t val;
int vfchg;
uint8_t chgiset_org;
uint8_t batset2_org;
/* Check FG Reset */
if (info->soca->ready_fg) {
- temp = get_battery_temp(info) / 10;
+ temp = get_battery_temp_2(info) / 10;
} else {
RICOH_FG_DBG(KERN_INFO "JEITA: %s *** cannot update by resetting FG ******\n", __func__);
goto out;
goto out;
}
info->soca->jt_limit = 0;
+ *is_jeita_updated = true;
} else
RICOH_FG_DBG(KERN_INFO "PMU: %s *** 12<Temp<50, already set vfchg==%d, so no need to update ******\n",
__func__, info->jt_vfchg_h);
return x;
}
-static int ricoh619_set_OCV_table(struct ricoh619_battery_info *info)
+static void ricoh619_scaling_OCV_table(struct ricoh619_battery_info *info, int cutoff_vol, int full_vol, int *start_per, int *end_per)
{
- int ret = 0;
- int ocv_table[11];
int i, j;
- int available_cap;
int temp;
- int start_par;
int percent_step;
int OCV_percent_new[11];
- int Rbat;
- int Ibat_min;
- info->soca->target_vsys = info->fg_target_vsys;
- info->soca->target_ibat = info->fg_target_ibat;
+ /* get ocv table. this table is calculated by Apprication */
+ //RICOH_FG_DBG("PMU : %s : original table\n",__func__);
+ for (i = 0; i <= 10; i = i+1) {
+ RICOH_FG_DBG(KERN_INFO "PMU: %s : %d0%% voltage = %d uV\n",
+ __func__, i, info->soca->ocv_table_def[i]);
+ }
+ //RICOH_FG_DBG("PMU: %s : cutoff_vol %d full_vol %d\n",
+ // __func__, cutoff_vol,full_vol);
- //for debug
- RICOH_FG_DBG("PMU : %s : target_vsys is %d target_ibat is %d",__func__,info->soca->target_vsys,info->soca->target_ibat);
-
- if ((info->soca->target_ibat == 0) || (info->soca->target_vsys == 0)) { /* normal version */
- } else { /*Slice cutoff voltage version. */
- /* get ocv table. this table is calculated by Apprication */
- for (i = 0; i <= 10; i = i+1) {
- temp = (battery_init_para[info->num][i*2]<<8)
- | (battery_init_para[info->num][i*2+1]);
- /* conversion unit 1 Unit is 1.22mv (5000/4095 mv) */
- temp = ((temp * 50000 * 10 / 4095) + 5) / 10;
- ocv_table[i] = temp;
-
+ /* Check Start % */
+ if (info->soca->ocv_table_def[0] > cutoff_vol * 1000) {
+ *start_per = 0;
+ RICOH_FG_DBG("PMU : %s : setting value of cuttoff_vol(%d) is out of range(%d) \n",__func__, cutoff_vol, info->soca->ocv_table_def[0]);
+ } else {
+ for (i = 1; i < 11; i++) {
+ if (info->soca->ocv_table_def[i] >= cutoff_vol * 1000) {
+ /* unit is 0.001% */
+ *start_per = Calc_Linear_Interpolation(
+ (i-1)*1000, info->soca->ocv_table_def[i-1], i*1000,
+ info->soca->ocv_table_def[i], (cutoff_vol * 1000));
+ break;
+ }
+ }
+ }
+
+ /* Check End % */
+ for (i = 1; i < 11; i++) {
+ if (info->soca->ocv_table_def[i] >= full_vol * 1000) {
+ /* unit is 0.001% */
+ *end_per = Calc_Linear_Interpolation(
+ (i-1)*1000, info->soca->ocv_table_def[i-1], i*1000,
+ info->soca->ocv_table_def[i], (full_vol * 1000));
+ break;
}
+ }
- /* get internal impedence */
- temp = (battery_init_para[info->num][24]<<8) | (battery_init_para[info->num][25]);
- Rbat = temp * 1000 / 512 * 5000 / 4095;
+ /* calc new ocv percent */
+ percent_step = ( *end_per - *start_per) / 10;
+ //RICOH_FG_DBG("PMU : %s : percent_step is %d end per is %d start per is %d\n",__func__, percent_step, *end_per, *start_per);
- Ibat_min = -1 * info->soca->target_ibat;
- info->soca->Rsys = Rbat + 55;
- info->soca->cutoff_ocv = info->soca->target_vsys - Ibat_min * info->soca->Rsys / 1000;
+ for (i = 0; i < 11; i++) {
+ OCV_percent_new[i]
+ = *start_per + percent_step*(i - 0);
+ }
+ /* calc new ocv voltage */
+ for (i = 0; i < 11; i++) {
+ for (j = 1; j < 11; j++) {
+ if (1000*j >= OCV_percent_new[i]) {
+ temp = Calc_Linear_Interpolation(
+ info->soca->ocv_table_def[j-1], (j-1)*1000,
+ info->soca->ocv_table_def[j] , j*1000,
+ OCV_percent_new[i]);
- RICOH_FG_DBG("PMU: ------- Rbat= %d: Rsys= %d: cutoff_ocv= %d: =======\n",
- Rbat, info->soca->Rsys, info->soca->cutoff_ocv);
+ temp = ( (temp/1000) * 4095 ) / 5000;
- /* Check Start % */
- for (i = 1; i < 11; i++) {
- if (ocv_table[i] >= info->soca->cutoff_ocv * 10) {
- /* unit is 0.001% */
- start_par = Calc_Linear_Interpolation(
- (i-1)*1000, ocv_table[i-1], i*1000,
- ocv_table[i], (info->soca->cutoff_ocv * 10));
- i = 11;
+ battery_init_para[info->num][i*2 + 1] = temp;
+ battery_init_para[info->num][i*2] = temp >> 8;
+
+ break;
}
}
- /* calc new ocv percent */
- percent_step = (10000 - start_par) / 10;
+ }
+ RICOH_FG_DBG("PMU : %s : new table\n",__func__);
+ for (i = 0; i <= 10; i = i+1) {
+ temp = (battery_init_para[info->num][i*2]<<8)
+ | (battery_init_para[info->num][i*2+1]);
+ /* conversion unit 1 Unit is 1.22mv (5000/4095 mv) */
+ temp = ((temp * 50000 * 10 / 4095) + 5) / 10;
+ RICOH_FG_DBG("PMU : %s : ocv_table %d is %d v\n",__func__, i, temp);
+ }
- for (i = 0; i < 11; i++) {
- OCV_percent_new[i]
- = start_par + percent_step*(i - 0);
- }
+}
- /* calc new ocv voltage */
- for (i = 0; i < 11; i++) {
- for (j = 1; j < 11; j++) {
- if (1000*j >= OCV_percent_new[i]) {
- temp = Calc_Linear_Interpolation(
- ocv_table[j-1], (j-1)*1000,
- ocv_table[j] , j*1000,
- OCV_percent_new[i]);
+static int ricoh619_set_OCV_table(struct ricoh619_battery_info *info)
+{
+ int ret = 0;
+ int i;
+ int full_ocv;
+ int available_cap;
+ int available_cap_ori;
+ int temp;
+ int temp1;
+ int start_per = 0;
+ int end_per = 0;
+ int Rbat;
+ int Ibat_min;
+ uint8_t val;
+ uint8_t val2;
+ uint8_t val_temp;
- temp = temp * 4095 / 50000;
- battery_init_para[info->num][i*2 + 1] = temp;
- battery_init_para[info->num][i*2] = temp >> 8;
+ //get ocv table
+ for (i = 0; i <= 10; i = i+1) {
+ info->soca->ocv_table_def[i] = get_OCV_voltage(info, i);
+ RICOH_FG_DBG(KERN_INFO "PMU: %s : %d0%% voltage = %d uV\n",
+ __func__, i, info->soca->ocv_table_def[i]);
+ }
- j = 11;
- }
- }
- }
+ temp = (battery_init_para[info->num][24]<<8) | (battery_init_para[info->num][25]);
+ Rbat = temp * 1000 / 512 * 5000 / 4095;
+ info->soca->Rsys = Rbat + 55;
+
+ if ((info->fg_target_ibat == 0) || (info->fg_target_vsys == 0)) { /* normal version */
+
+ temp = (battery_init_para[info->num][22]<<8) | (battery_init_para[info->num][23]);
+ //fa_cap = get_check_fuel_gauge_reg(info, FA_CAP_H_REG, FA_CAP_L_REG,
+ // 0x7fff);
+
+ info->soca->target_ibat = temp*2/10; /* calc 0.2C*/
+ temp1 = (battery_init_para[info->num][0]<<8) | (battery_init_para[info->num][1]);
+
+ info->soca->target_vsys = temp1 + ( info->soca->target_ibat * info->soca->Rsys ) / 1000;
+
- for (i = 0; i <= 10; i = i+1) {
- temp = (battery_init_para[info->num][i*2]<<8)
- | (battery_init_para[info->num][i*2+1]);
- /* conversion unit 1 Unit is 1.22mv (5000/4095 mv) */
- temp = ((temp * 50000 * 10 / 4095) + 5) / 10;
- RICOH_FG_DBG("PMU: ------- ocv_table[%d]= %d: =======\n",
- i, temp);
+ } else {
+ info->soca->target_ibat = info->fg_target_ibat;
+ /* calc min vsys value */
+ temp1 = (battery_init_para[info->num][0]<<8) | (battery_init_para[info->num][1]);
+ temp = temp1 + ( info->soca->target_ibat * info->soca->Rsys ) / 1000;
+ if( temp < info->fg_target_vsys) {
+ info->soca->target_vsys = info->fg_target_vsys;
+ } else {
+ info->soca->target_vsys = temp;
+ RICOH_FG_DBG("PMU : %s : setting value of target vsys(%d) is out of range(%d)\n",__func__, info->fg_target_vsys, temp);
}
+ }
+
+ //for debug
+ RICOH_FG_DBG("PMU : %s : target_vsys is %d target_ibat is %d\n",__func__,info->soca->target_vsys,info->soca->target_ibat);
+
+ if ((info->soca->target_ibat == 0) || (info->soca->target_vsys == 0)) { /* normal version */
+ } else { /*Slice cutoff voltage version. */
+
+ Ibat_min = -1 * info->soca->target_ibat;
+ info->soca->cutoff_ocv = info->soca->target_vsys - Ibat_min * info->soca->Rsys / 1000;
+
+ full_ocv = (battery_init_para[info->num][20]<<8) | (battery_init_para[info->num][21]);
+ full_ocv = full_ocv * 5000 / 4095;
+ ricoh619_scaling_OCV_table(info, info->soca->cutoff_ocv, full_ocv, &start_per, &end_per);
/* calc available capacity */
/* get avilable capacity */
| (battery_init_para[info->num][23]);
available_cap = available_cap
- * ((10000 - start_par) / 100) / 100 ;
+ * ((10000 - start_per) / 100) / 100 ;
battery_init_para[info->num][23] = available_cap;
battery_init_para[info->num][22] = available_cap >> 8;
}
- ret = ricoh619_bulk_writes_bank1(info->dev->parent,
- BAT_INIT_TOP_REG, 32, battery_init_para[info->num]);
+ ret = ricoh619_clr_bits(info->dev->parent, FG_CTRL_REG, 0x01);
+ if (ret < 0) {
+ dev_err(info->dev, "error in FG_En off\n");
+ goto err;
+ }
+ /////////////////////////////////
+ ret = ricoh619_read_bank1(info->dev->parent, 0xDC, &val);
if (ret < 0) {
dev_err(info->dev, "batterry initialize error\n");
- return ret;
+ goto err;
}
- return 1;
+ val_temp = val;
+ val &= 0x0F; //clear bit 4-7
+ val |= 0x10; //set bit 4
+
+ ret = ricoh619_write_bank1(info->dev->parent, 0xDC, val);
+ if (ret < 0) {
+ dev_err(info->dev, "batterry initialize error\n");
+ goto err;
+ }
+
+ ret = ricoh619_read_bank1(info->dev->parent, 0xDC, &val2);
+ if (ret < 0) {
+ dev_err(info->dev, "batterry initialize error\n");
+ goto err;
+ }
+
+ ret = ricoh619_write_bank1(info->dev->parent, 0xDC, val_temp);
+ if (ret < 0) {
+ dev_err(info->dev, "batterry initialize error\n");
+ goto err;
+ }
+
+ RICOH_FG_DBG("PMU : %s : original 0x%x, before 0x%x, after 0x%x\n",__func__, val_temp, val, val2);
+
+ if (val != val2) {
+ ret = ricoh619_bulk_writes_bank1(info->dev->parent,
+ BAT_INIT_TOP_REG, 30, battery_init_para[info->num]);
+ if (ret < 0) {
+ dev_err(info->dev, "batterry initialize error\n");
+ goto err;
+ }
+ } else {
+ ret = ricoh619_read_bank1(info->dev->parent, 0xD2, &val);
+ if (ret < 0) {
+ dev_err(info->dev, "batterry initialize error\n");
+ goto err;
+ }
+
+ ret = ricoh619_read_bank1(info->dev->parent, 0xD3, &val2);
+ if (ret < 0) {
+ dev_err(info->dev, "batterry initialize error\n");
+ goto err;
+ }
+
+ available_cap_ori = val2 + (val << 8);
+ available_cap = battery_init_para[info->num][23]
+ + (battery_init_para[info->num][22] << 8);
+
+ if (available_cap_ori == available_cap) {
+ ret = ricoh619_bulk_writes_bank1(info->dev->parent,
+ BAT_INIT_TOP_REG, 22, battery_init_para[info->num]);
+ if (ret < 0) {
+ dev_err(info->dev, "batterry initialize error\n");
+ return ret;
+ }
+
+ for (i = 0; i < 6; i++) {
+ ret = ricoh619_write_bank1(info->dev->parent, 0xD4+i, battery_init_para[info->num][24+i]);
+ if (ret < 0) {
+ dev_err(info->dev, "batterry initialize error\n");
+ return ret;
+ }
+ }
+ } else {
+ ret = ricoh619_bulk_writes_bank1(info->dev->parent,
+ BAT_INIT_TOP_REG, 30, battery_init_para[info->num]);
+ if (ret < 0) {
+ dev_err(info->dev, "batterry initialize error\n");
+ goto err;
+ }
+ }
+ }
+
+ ////////////////////////////////
+
+ return 0;
+err:
+ return ret;
}
/* Initial setting of battery */
/* -------------------------- */
#ifdef ENABLE_FUEL_GAUGE_FUNCTION
- /* set kanwa state */
+ /* set relaxation state */
if (RICOH619_REL1_SEL_VALUE > 240)
val = 0x0F;
else
val = RICOH619_REL1_SEL_VALUE / 16 ;
- /* set kanwa state */
+ /* set relaxation state */
if (RICOH619_REL2_SEL_VALUE > 120)
val2 = 0x0F;
else
return ret;
}
- ret = ricoh619_read(info->dev->parent, FG_CTRL_REG, &val);
+// ret = ricoh619_read(info->dev->parent, FG_CTRL_REG, &val);
+// if (ret < 0) {
+// dev_err(info->dev, "Error in reading the control register\n");
+// return ret;
+// }
+
+// val = (val & 0x10) >> 4;
+// info->first_pwon = (val == 0) ? 1 : 0;
+ ret = ricoh619_read(info->dev->parent, PSWR_REG, &val);
if (ret < 0) {
- dev_err(info->dev, "Error in reading the control register\n");
+ dev_err(info->dev,"Error in reading PSWR_REG %d\n", ret);
return ret;
}
-
- val = (val & 0x10) >> 4;
info->first_pwon = (val == 0) ? 1 : 0;
-
+ g_soc = val & 0x7f;
+
ret = ricoh619_set_OCV_table(info);
if (ret < 0) {
dev_err(info->dev, "Error in writing the OCV Tabler\n");
#endif
- ret = ricoh619_write(info->dev->parent, VINDAC_REG, 0x01);
+ ret = ricoh619_write(info->dev->parent, VINDAC_REG, 0x03);
if (ret < 0) {
dev_err(info->dev, "Error in writing the control register\n");
return ret;
uint8_t val2;
uint8_t val3;
int charge_status;
+ int vfchg_val;
+ int icchg_val;
+ int rbat;
+ int temp;
info->chg_ctr = 0;
info->chg_stat1 = 0;
if ((info->ch_icchg != 0xFF) || (info->ch_icchg <= 0x03)) {
val3 = info->ch_icchg << 6;
} else { /* Keep OTP value */
- val3 = (val & 0xC);
+ val3 = (val & 0xC0);
}
val = val2 + val3;
goto free_device;
}
}
+ /* get OCV100_min, OCV100_min*/
+ temp = (battery_init_para[info->num][24]<<8) | (battery_init_para[info->num][25]);
+ rbat = temp * 1000 / 512 * 5000 / 4095;
+
+ /* get vfchg value */
+ err = ricoh619_read(info->dev->parent, BATSET2_REG, &val);
+ if (err < 0) {
+ dev_err(info->dev, "Error in reading the batset2reg\n");
+ goto free_device;
+ }
+ val &= 0x70;
+ val2 = val >> 4;
+ if (val2 <= 3) {
+ vfchg_val = 4050 + val2 * 50;
+ } else {
+ vfchg_val = 4350;
+ }
+ RICOH_FG_DBG("PMU : %s : test test val %d, val2 %d vfchg %d\n", __func__, val, val2, vfchg_val);
+
+ /* get value */
+ err = ricoh619_read(info->dev->parent, CHGISET_REG, &val);
+ if (err < 0) {
+ dev_err(info->dev, "Error in reading the chgisetreg\n");
+ goto free_device;
+ }
+ val &= 0xC0;
+ val2 = val >> 6;
+ icchg_val = 50 + val2 * 50;
+ RICOH_FG_DBG("PMU : %s : test test val %d, val2 %d icchg %d\n", __func__, val, val2, icchg_val);
+
+ info->soca->OCV100_min = ( vfchg_val * 99 / 100 - (icchg_val * (rbat +20))/1000 - 20 ) * 1000;
+ info->soca->OCV100_max = ( vfchg_val * 101 / 100 - (icchg_val * (rbat +20))/1000 + 20 ) * 1000;
+
+ RICOH_FG_DBG("PMU : %s : 100 min %d, 100 max %d vfchg %d icchg %d rbat %d\n",__func__,
+ info->soca->OCV100_min,info->soca->OCV100_max,vfchg_val,icchg_val,rbat);
#ifdef ENABLE_LOW_BATTERY_DETECTION
/* Set ADRQ=00 to stop ADC */
/* Set ADC auto conversion interval 250ms */
ricoh619_write(info->dev->parent, RICOH619_ADC_CNT2, 0x0);
/* Enable VSYS pin conversion in auto-ADC */
- ricoh619_write(info->dev->parent, RICOH619_ADC_CNT1, 0x10);
- /* Set VSYS threshold low voltage = 3.50v */
- ricoh619_write(info->dev->parent, RICOH619_ADC_VSYS_THL, 0x77);
+// ricoh619_write(info->dev->parent, RICOH619_ADC_CNT1, 0x10);
+ ricoh619_write(info->dev->parent, RICOH619_ADC_CNT1, 0x16);
+ /* Set VSYS threshold low voltage value = (voltage(V)*255)/(3*2.5) */
+ val = info->alarm_vol_mv * 255 / 7500;
+ ricoh619_write(info->dev->parent, RICOH619_ADC_VSYS_THL, val);
/* Start auto-mode & average 4-time conversion mode for ADC */
ricoh619_write(info->dev->parent, RICOH619_ADC_CNT3, 0x28);
/* Enable master ADC INT */
return info->soca->chg_status;
}
+static int get_power_supply_Android_status(struct ricoh619_battery_info *info)
+{
+
+ get_power_supply_status(info);
+
+ /* get power supply status */
+ if (info->entry_factory_mode)
+ return POWER_SUPPLY_STATUS_NOT_CHARGING;
+
+ switch (info->soca->chg_status) {
+ case POWER_SUPPLY_STATUS_UNKNOWN:
+ return POWER_SUPPLY_STATUS_UNKNOWN;
+ break;
+
+ case POWER_SUPPLY_STATUS_NOT_CHARGING:
+ return POWER_SUPPLY_STATUS_NOT_CHARGING;
+ break;
+
+ case POWER_SUPPLY_STATUS_DISCHARGING:
+ return POWER_SUPPLY_STATUS_DISCHARGING;
+ break;
+
+ case POWER_SUPPLY_STATUS_CHARGING:
+ return POWER_SUPPLY_STATUS_CHARGING;
+ break;
+
+ case POWER_SUPPLY_STATUS_FULL:
+ if(info->soca->displayed_soc == 100 * 100) {
+ return POWER_SUPPLY_STATUS_FULL;
+ } else {
+ return POWER_SUPPLY_STATUS_CHARGING;
+ }
+ break;
+ default:
+ return POWER_SUPPLY_STATUS_UNKNOWN;
+ break;
+ }
+
+ return POWER_SUPPLY_STATUS_UNKNOWN;
+}
+extern struct ricoh619 *g_ricoh619;
static void charger_irq_work(struct work_struct *work)
{
struct ricoh619_battery_info *info
RICOH_FG_DBG("PMU:%s In\n", __func__);
power_supply_changed(&info->battery);
+ power_supply_changed(&powerac);
+ power_supply_changed(&powerusb);
- mutex_lock(&info->lock);
+// mutex_lock(&info->lock);
if (info->chg_stat1 & 0x01) {
ricoh619_read(info->dev->parent, CHGSTATE_REG, ®_val);
- if (reg_val & 0x40) { /* USE ADP */
- /* set adp limit current 2A */
- ricoh619_write(info->dev->parent, REGISET1_REG, 0x13);
- /* set charge current 2A */
- ricoh619_write(info->dev->parent, CHGISET_REG, 0xD3);
- }
- else if (reg_val & 0x80) { /* USE USB */
+ if (reg_val & 0x40) { /* USE ADP */
+ #ifdef SUPPORT_USB_CONNECT_TO_ADP
+ int i;
+ for(i =0;i<60;i++){
+ RICOH_FG_DBG("PMU:%s usb det dwc_otg_check_dpdm =%d\n", __func__,dwc_otg_check_dpdm(0));
+ if(2 == dwc_otg_check_dpdm(0)){
+ /* set adp limit current 2A */
+ ricoh619_write(info->dev->parent, REGISET1_REG, 0x16);
+ /* set charge current 2A */
+ ricoh619_write(info->dev->parent, CHGISET_REG, 0xD3);
+ }
+ else {
+ /* set adp limit current 500ma */
+ ricoh619_write(info->dev->parent, REGISET1_REG, 0x04);
+ /* set charge current 500ma */
+ ricoh619_write(info->dev->parent, CHGISET_REG, 0xc4);
+ }
+
+ power_supply_changed(&info->battery);
+ power_supply_changed(&powerac);
+ power_supply_changed(&powerusb);
+ msleep(100);
+ }
+ #else //support adp and usb chag
+ if (gpio_is_valid(g_ricoh619->dc_det)){
+ ret = gpio_request(g_ricoh619->dc_det, "ricoh619_dc_det");
+ if (ret < 0) {
+ RICOH_FG_DBG("Failed to request gpio %d with ret:""%d\n",g_ricoh619->dc_det, ret);
+ }
+ gpio_direction_input(g_ricoh619->dc_det);
+ ret = gpio_get_value(g_ricoh619->dc_det);
+
+ if (ret ==0){
+ /* set adp limit current 2A */
+ ricoh619_write(info->dev->parent, REGISET1_REG, 0x16);
+ /* set charge current 2A */
+ ricoh619_write(info->dev->parent, CHGISET_REG, 0xD3);
+ }
+ else {
+ /* set adp limit current 500ma */
+ ricoh619_write(info->dev->parent, REGISET1_REG, 0x04);
+ /* set charge current 500ma */
+ ricoh619_write(info->dev->parent, CHGISET_REG, 0xc4);
+ }
+ gpio_free(g_ricoh619->dc_det);
+ }
+ else{
+ /* set adp limit current 2A */
+ ricoh619_write(info->dev->parent, REGISET1_REG, 0x16);
+ /* set charge current 2A */
+ ricoh619_write(info->dev->parent, CHGISET_REG, 0xD3);
+ }
+ #endif
+ } else if (reg_val & 0x80) { /* USE ONLY USB */
queue_work(info->usb_workqueue, &info->usb_irq_work);
}
}
"%s(): Error in enable charger mask INT %d\n",
__func__, ret);
- mutex_unlock(&info->lock);
+// mutex_unlock(&info->lock);
RICOH_FG_DBG("PMU:%s Out\n", __func__);
}
{
struct ricoh619 *ricoh619 = g_ricoh619;
ricoh619_set_bits(ricoh619->dev,REGISET2_REG,(1 << 7)); //set usb limit current when SDP or other mode
- if(2 == dwc_vbus_status()){
- ricoh619_write(ricoh619->dev,REGISET2_REG,0x13); //set usb limit current 2A
+ RICOH_FG_DBG("PMU:%s usb det dwc_otg_check_dpdm =%d\n", __func__,dwc_otg_check_dpdm(0));
+ if(2 == dwc_otg_check_dpdm(0)){
+ ricoh619_write(ricoh619->dev,REGISET2_REG,0x16); //set usb limit current 2A
ricoh619_write(ricoh619->dev,CHGISET_REG,0xD3); //set charge current 2A
}
- else if(1 == dwc_vbus_status()){
+ else {
ricoh619_write(ricoh619->dev,REGISET2_REG,0x04); //set usb limit current 500ma
ricoh619_write(ricoh619->dev,CHGISET_REG,0xC4); //set charge current 500ma
}
+ power_supply_changed(&powerac);
+ power_supply_changed(&powerusb);
}
static void usb_det_irq_work(struct work_struct *work)
struct ricoh619_battery_info, usb_irq_work);
int ret = 0;
uint8_t sts;
- int time =0;
RICOH_FG_DBG("PMU:%s In\n", __func__);
power_supply_changed(&info->battery);
+ power_supply_changed(&powerac);
+ power_supply_changed(&powerusb);
mutex_lock(&info->lock);
dev_err(info->dev, "Error in reading the control register\n");
sts &= 0x02;
- if (sts) {
- //time = 60;
- //do {
- //ricoh619_usb_charge_det();
- //time --;
- //mdelay(1000);
- //}while(time >0);
-
- } else {
- /*********************/
- /* No process ?? */
- /*********************/
- }
+ if (sts)
+ ricoh619_usb_charge_det();
RICOH_FG_DBG("PMU:%s Out\n", __func__);
}
-extern void rk28_send_wakeup_key(void);
+extern void rk_send_wakeup_key(void);
static irqreturn_t charger_in_isr(int irq, void *battery_info)
{
struct ricoh619_battery_info *info = battery_info;
- struct ricoh619 *ricoh619 = g_ricoh619;
-
RICOH_FG_DBG("PMU:%s\n", __func__);
info->chg_stat1 |= 0x01;
queue_work(info->workqueue, &info->irq_work);
-// rk28_send_wakeup_key();
+// rk_send_wakeup_key();
return IRQ_HANDLED;
}
info->chg_stat1 |= 0x02;
queue_work(info->workqueue, &info->irq_work);
- rk28_send_wakeup_key();
+// rk_send_wakeup_key();
return IRQ_HANDLED;
}
info->soca->chg_count = 0;
// queue_work(info->usb_workqueue, &info->usb_irq_work);
-// rk28_send_wakeup_key();
+ rk_send_wakeup_key();
if (RICOH619_SOCA_UNSTABLE == info->soca->status
|| RICOH619_SOCA_FG_RESET == info->soca->status)
static irqreturn_t charger_adp_isr(int irq, void *battery_info)
{
struct ricoh619_battery_info *info = battery_info;
- struct ricoh619 *ricoh619 = g_ricoh619;
RICOH_FG_DBG("PMU:%s\n", __func__);
info->chg_ctr |= 0x01;
queue_work(info->workqueue, &info->irq_work);
- rk28_send_wakeup_key();
+ rk_send_wakeup_key();
info->soca->dischg_state = 0;
info->soca->chg_count = 0;
RICOH_FG_DBG("PMU:%s\n", __func__);
// ricoh619_write(info->dev->parent, RICOH619_INT_EN_ADC1, 0x10);
-// rk28_send_wakeup_key();
+ rk_send_wakeup_key();
+
+ return IRQ_HANDLED;
+}
+#endif
+#ifdef RICOH619_VADP_DROP_WORK
+static void vadp_drop_irq_work(struct work_struct *work)
+{
+ struct ricoh619_battery_info *info = container_of(work,
+ struct ricoh619_battery_info, vadp_drop_work.work);
+
+ int ret = 0;
+ uint8_t data[6];
+ u16 reg[2];
+
+ RICOH_FG_DBG("PMU vadp_drop_work:%s In\n", __func__);
+ mutex_lock(&info->lock);
+ ret = ricoh619_read(info->dev->parent, 0x6a, &data[0]);
+ ret = ricoh619_read(info->dev->parent, 0x6b, &data[1]);
+ ret = ricoh619_read(info->dev->parent, 0x6c, &data[2]);
+ ret = ricoh619_read(info->dev->parent, 0x6d, &data[3]);
+ ret = ricoh619_read(info->dev->parent, CHGSTATE_REG,&data[4]);
+ reg[0]= (data[0]<<4) |data[1];
+ reg[1]= (data[2]<<4) |data[3];
+
+// printk("PMU vadp_drop:%s In %08x %08x %08x %08x %08x %08x %d\n", __func__,data[0],data[1],data[2],data[3],reg[0],reg[1],ret);
+ if ((2*(reg[0] +82)) > 3*reg[1]){
+ ricoh619_write(info->dev->parent, 0xb3, 0x28);
+// printk("PMU vadp_drop charger disable:%s In %08x %08x\n", __func__,reg[0],reg[1]);
+ }
+ else if(data[4] & 0xc0){
+ ret = ricoh619_read(info->dev->parent, 0xb3, &data[5]);
+// printk("PMU charger is disabled:%s data[4]= %08x data[5]=%08x\n", __func__,data[4],data[5]);
+ if(((data[5] & 0x03) ==0)|| ((data[5] & 0x08)==0)){
+ ricoh619_write(info->dev->parent, 0xb3, 0x23);
+ ret = ricoh619_read(info->dev->parent, 0xb3, &data[5]);
+// printk("PMU charger enable:%s data[4]= %08x data[5]=%08x\n", __func__,data[4],data[5]);
+ }
+ }
+ power_supply_changed(&info->battery);
+ power_supply_changed(&powerac);
+ power_supply_changed(&powerusb);
+ mutex_unlock(&info->lock);
+ queue_delayed_work(info->monitor_wqueue, &info->vadp_drop_work,3*HZ);
- return IRQ_HANDLED;
}
#endif
-
/*
* Get Charger Priority
* - get higher-priority between VADP and VUSB
* true : VUSB
* false: VADP
*/
+ /*
static int get_charge_priority(struct ricoh619_battery_info *info, bool *data)
{
int ret = 0;
return ret;
}
+*/
/*
* Set Charger Priority
* true : VUSB
* false: VADP
*/
+ /*
static int set_charge_priority(struct ricoh619_battery_info *info, bool *data)
{
int ret = 0;
- uint8_t val = 0;
+ uint8_t val = 0x80;
- val = *data << 7;
- val &= 0x80;
+ if (*data == 1)
+ ret = ricoh619_set_bits(info->dev->parent, CHGCTL1_REG, val);
+ else
+ ret = ricoh619_clr_bits(info->dev->parent, CHGCTL1_REG, val);
- ret = ricoh619_set_bits(info->dev->parent, CHGCTL1_REG, val);
return ret;
}
-
+*/
#ifdef ENABLE_FUEL_GAUGE_FUNCTION
static int get_check_fuel_gauge_reg(struct ricoh619_battery_info *info,
int Reg_h, int Reg_l, int enable_bit)
int nt;
int temperature;
- temperature = get_battery_temp(info) / 10; /* unit 0.1 degree -> 1 degree */
+ temperature = get_battery_temp_2(info) / 10; /* unit 0.1 degree -> 1 degree */
if (temperature >= 25) {
nt = 0;
temp = capacity * 100 * 100 / (10000 - nt);
+ temp = min(100, temp);
+ temp = max(0, temp);
+
return temp; /* Unit is 1% */
}
+static int calc_capacity_2(struct ricoh619_battery_info *info)
+{
+ uint8_t val;
+ long capacity;
+ int re_cap, fa_cap;
+ int temp;
+ int ret = 0;
+ int nt;
+ int temperature;
+
+ temperature = get_battery_temp_2(info) / 10; /* unit 0.1 degree -> 1 degree */
+
+ if (temperature >= 25) {
+ nt = 0;
+ } else if (temperature >= 5) {
+ nt = (25 - temperature) * RICOH619_TAH_SEL2 * 625 / 100;
+ } else {
+ nt = (625 + (5 - temperature) * RICOH619_TAL_SEL2 * 625 / 100);
+ }
+
+ re_cap = get_check_fuel_gauge_reg(info, RE_CAP_H_REG, RE_CAP_L_REG,
+ 0x7fff);
+ fa_cap = get_check_fuel_gauge_reg(info, FA_CAP_H_REG, FA_CAP_L_REG,
+ 0x7fff);
+
+ if (fa_cap != 0) {
+ capacity = ((long)re_cap * 100 * 100 / fa_cap);
+ capacity = (long)(min(10000, (int)capacity));
+ capacity = (long)(max(0, (int)capacity));
+ } else {
+ ret = ricoh619_read(info->dev->parent, SOC_REG, &val);
+ if (ret < 0) {
+ dev_err(info->dev, "Error in reading the control register\n");
+ return ret;
+ }
+ capacity = (long)val * 100;
+ }
+
+
+ temp = (int)(capacity * 100 * 100 / (10000 - nt));
+
+ temp = min(10000, temp);
+ temp = max(0, temp);
+
+ return temp; /* Unit is 0.01% */
+}
+
static int get_battery_temp(struct ricoh619_battery_info *info)
{
int ret = 0;
return ret;
}
+static int get_battery_temp_2(struct ricoh619_battery_info *info)
+{
+ uint8_t reg_buff[2];
+ long temp, temp_off, temp_gain;
+ bool temp_sign, temp_off_sign, temp_gain_sign;
+ int Vsns = 0;
+ int Iout = 0;
+ int Vthm, Rthm;
+ int reg_val = 0;
+ int new_temp;
+ long R_ln1, R_ln2;
+ int ret = 0;
+
+ /* Calculate TEMP */
+ ret = get_check_fuel_gauge_reg(info, TEMP_1_REG, TEMP_2_REG, 0x0fff);
+ if (ret < 0) {
+ dev_err(info->dev, "Error in reading the fuel gauge register\n");
+ goto out;
+ }
+
+ reg_val = ret;
+ temp_sign = (reg_val & 0x0800) >> 11;
+ reg_val = (reg_val & 0x07ff);
+
+ if (temp_sign == 0) /* positive value part */
+ /* the unit is 0.0001 degree */
+ temp = (long)reg_val * 625;
+ else { /*negative value part */
+ reg_val = (~reg_val + 1) & 0x7ff;
+ temp = -1 * (long)reg_val * 625;
+ }
+
+ /* Calculate TEMP_OFF */
+ ret = ricoh619_bulk_reads_bank1(info->dev->parent,
+ TEMP_OFF_H_REG, 2, reg_buff);
+ if (ret < 0) {
+ dev_err(info->dev, "Error in reading the fuel gauge register\n");
+ goto out;
+ }
+
+ reg_val = reg_buff[0] << 8 | reg_buff[1];
+ temp_off_sign = (reg_val & 0x0800) >> 11;
+ reg_val = (reg_val & 0x07ff);
+
+ if (temp_off_sign == 0) /* positive value part */
+ /* the unit is 0.0001 degree */
+ temp_off = (long)reg_val * 625;
+ else { /*negative value part */
+ reg_val = (~reg_val + 1) & 0x7ff;
+ temp_off = -1 * (long)reg_val * 625;
+ }
+
+ /* Calculate TEMP_GAIN */
+ ret = ricoh619_bulk_reads_bank1(info->dev->parent,
+ TEMP_GAIN_H_REG, 2, reg_buff);
+ if (ret < 0) {
+ dev_err(info->dev, "Error in reading the fuel gauge register\n");
+ goto out;
+ }
+
+ reg_val = reg_buff[0] << 8 | reg_buff[1];
+ temp_gain_sign = (reg_val & 0x0800) >> 11;
+ reg_val = (reg_val & 0x07ff);
+
+ if (temp_gain_sign == 0) /* positive value part */
+ /* 1 unit is 0.000488281. the result is 0.01 */
+ temp_gain = (long)reg_val * 488281 / 100000;
+ else { /*negative value part */
+ reg_val = (~reg_val + 1) & 0x7ff;
+ temp_gain = -1 * (long)reg_val * 488281 / 100000;
+ }
+
+ /* Calculate VTHM */
+ if (0 != temp_gain)
+ Vthm = (int)((temp - temp_off) / 4095 * 2500 / temp_gain);
+ else {
+ RICOH_FG_DBG("PMU %s Skip to compensate temperature\n", __func__);
+ goto out;
+ }
+
+ ret = measure_Ibatt_FG(info, &Iout);
+ Vsns = Iout * 2 / 100;
+
+ if (temp < -120000) {
+ /* Low Temperature */
+ if (0 != (2500 - Vthm)) {
+ Rthm = 10 * 10 * (Vthm - Vsns) / (2500 - Vthm);
+ } else {
+ RICOH_FG_DBG("PMU %s Skip to compensate temperature\n", __func__);
+ goto out;
+ }
+
+ R_ln1 = Rthm / 10;
+ R_ln2 = (R_ln1 * R_ln1 * R_ln1 * R_ln1 * R_ln1 / 100000
+ - R_ln1 * R_ln1 * R_ln1 * R_ln1 * 2 / 100
+ + R_ln1 * R_ln1 * R_ln1 * 11
+ - R_ln1 * R_ln1 * 2980
+ + R_ln1 * 449800
+ - 784000) / 10000;
+
+ /* the unit of new_temp is 0.1 degree */
+ new_temp = (int)((100 * 1000 * B_VALUE / (R_ln2 + B_VALUE * 100 * 1000 / 29815) - 27315) / 10);
+ RICOH_FG_DBG("PMU %s low temperature %d\n", __func__, new_temp/10);
+ } else if (temp > 520000) {
+ /* High Temperature */
+ if (0 != (2500 - Vthm)) {
+ Rthm = 100 * 10 * (Vthm - Vsns) / (2500 - Vthm);
+ } else {
+ RICOH_FG_DBG("PMU %s Skip to compensate temperature\n", __func__);
+ goto out;
+ }
+ RICOH_FG_DBG("PMU %s [Rthm] Rthm %d[ohm]\n", __func__, Rthm);
+
+ R_ln1 = Rthm / 10;
+ R_ln2 = (R_ln1 * R_ln1 * R_ln1 * R_ln1 * R_ln1 / 100000 * 15652 / 100
+ - R_ln1 * R_ln1 * R_ln1 * R_ln1 / 1000 * 23103 / 100
+ + R_ln1 * R_ln1 * R_ln1 * 1298 / 100
+ - R_ln1 * R_ln1 * 35089 / 100
+ + R_ln1 * 50334 / 10
+ - 48569) / 100;
+ /* the unit of new_temp is 0.1 degree */
+ new_temp = (int)((100 * 100 * B_VALUE / (R_ln2 + B_VALUE * 100 * 100 / 29815) - 27315) / 10);
+ RICOH_FG_DBG("PMU %s high temperature %d\n", __func__, new_temp/10);
+ } else {
+ /* the unit of new_temp is 0.1 degree */
+ new_temp = temp / 1000;
+ }
+
+ return new_temp;
+
+out:
+ new_temp = get_battery_temp(info);
+ return new_temp;
+}
+#if 0
static int get_time_to_empty(struct ricoh619_battery_info *info)
{
int ret = 0;
return ret;
}
-
+#endif
/* battery voltage is get from Fuel gauge */
static int measure_vbatt_FG(struct ricoh619_battery_info *info, int *data)
{
int ret = 0;
- ret = get_check_fuel_gauge_reg(info, VOLTAGE_1_REG, VOLTAGE_2_REG,
- 0x0fff);
- if (ret < 0) {
- dev_err(info->dev, "Error in reading the fuel gauge control register\n");
- return ret;
- }
+ if(info->soca->ready_fg == 1) {
+ ret = get_check_fuel_gauge_reg(info, VOLTAGE_1_REG, VOLTAGE_2_REG,
+ 0x0fff);
+ if (ret < 0) {
+ dev_err(info->dev, "Error in reading the fuel gauge control register\n");
+ return ret;
+ }
- *data = ret;
- /* conversion unit 1 Unit is 1.22mv (5000/4095 mv) */
- *data = *data * 50000 / 4095;
- /* return unit should be 1uV */
- *data = *data * 100;
+ *data = ret;
+ /* conversion unit 1 Unit is 1.22mv (5000/4095 mv) */
+ *data = *data * 50000 / 4095;
+ /* return unit should be 1uV */
+ *data = *data * 100;
+ info->soca->Vbat_old = *data;
+ } else {
+ *data = info->soca->Vbat_old;
+ }
return ret;
}
mutex_lock(&info->lock);
switch (psp) {
+
case POWER_SUPPLY_PROP_ONLINE:
ret = ricoh619_read(info->dev->parent, CHGSTATE_REG, &status);
if (ret < 0) {
mutex_unlock(&info->lock);
return ret;
}
- if (psy->type == POWER_SUPPLY_TYPE_MAINS)
- val->intval = (status & 0x40 ? 1 : 0);
- else if (psy->type == POWER_SUPPLY_TYPE_USB)
- val->intval = (status & 0x80 ? 1 : 0);
+ #ifdef SUPPORT_USB_CONNECT_TO_ADP
+ if (psy->type == POWER_SUPPLY_TYPE_MAINS){
+ if((2 == dwc_otg_check_dpdm(0)) && (status & 0x40))
+ val->intval =1;
+ else
+ val->intval =0;
+ }
+ else if (psy->type == POWER_SUPPLY_TYPE_USB){
+ if((1 == dwc_otg_check_dpdm(0)) && (status & 0x40))
+ val->intval =1;
+ else
+ val->intval =0;
+ }
+ #else
+ if (psy->type == POWER_SUPPLY_TYPE_MAINS)
+ val->intval = (status & 0x40 ? 1 : 0);
+ else if (psy->type == POWER_SUPPLY_TYPE_USB)
+ val->intval = (status & 0x80 ? 1 : 0);
+ #endif
break;
/* this setting is same as battery driver of 584 */
case POWER_SUPPLY_PROP_STATUS:
- ret = get_power_supply_status(info);
- val->intval = ret;
- info->status = ret;
- /* RICOH_FG_DBG("Power Supply Status is %d\n",
+ if(info->chg_complete_tm_ov_flag == 0)
+ {
+ ret = get_power_supply_Android_status(info);
+ val->intval = ret;
+ info->status = ret;
+ /* RICOH_FG_DBG("Power Supply Status is %d\n",
info->status); */
+ }
+ else
+ {
+ val->intval = POWER_SUPPLY_STATUS_FULL;
+ }
break;
/* this setting is same as battery driver of 584 */
case POWER_SUPPLY_PROP_PRESENT:
- val->intval = info->present;
+ // val->intval = info->present;
+ val->intval = 1;
break;
/* current voltage is get from fuel gauge */
else {
//val->intval = -EINVAL;
data = info->cur_voltage * 1000;
- /* RICOH_FG_DBG( "battery voltage is not ready\n"); */
+ RICOH_FG_DBG( "battery voltage is not ready\n");
}
#else
ret = measure_vbatt_ADC(info, &data);
if (info->entry_factory_mode){
val->intval = 100;
info->capacity = 100;
- } else if (info->soca->displayed_soc <= 0) {
- val->intval = 0;
- info->capacity = 0;
+ } else if ((info->soca->displayed_soc < 0) || (info->cur_voltage == 0)) {
+ val->intval = 50;
+ info->capacity = 50;
} else {
- val->intval = (info->soca->displayed_soc + 50)/100;
- info->capacity = (info->soca->displayed_soc + 50)/100;
+ if(info->chg_complete_tm_ov_flag == 1)
+ {
+ info->capacity = 100;
+ val->intval = info->capacity;
+ }
+ else
+ {
+ info->capacity = (info->soca->displayed_soc + 50)/100;
+ val->intval = info->capacity;
+ }
}
- /* RICOH_FG_DBG("battery capacity is %d%%\n",
- info->capacity); */
+ RICOH_FG_DBG("battery capacity is %d%%\n", info->capacity);
break;
/* current temperature of battery */
case POWER_SUPPLY_PROP_TEMP:
if (info->soca->ready_fg) {
ret = 0;
- val->intval = get_battery_temp(info);
+ val->intval = get_battery_temp_2(info);
info->battery_temp = val->intval/10;
RICOH_FG_DBG( "battery temperature is %d degree\n", info->battery_temp);
} else {
}
break;
+ #if 0
case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
if (info->soca->ready_fg) {
ret = get_time_to_empty(info);
/* RICOH_FG_DBG("time of full battery is not ready\n"); */
}
break;
+
+ #endif
#endif
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
#ifdef ENABLE_FUEL_GAUGE_FUNCTION
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_TEMP,
- POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
- POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
+ //POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
+ //POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
#endif
POWER_SUPPLY_PROP_TECHNOLOGY,
POWER_SUPPLY_PROP_HEALTH,
.get_property = ricoh619_batt_get_prop,
};
-static __devinit int ricoh619_battery_probe(struct platform_device *pdev)
+#ifdef CONFIG_OF
+static struct ricoh619_battery_platform_data *
+ricoh619_battery_dt_init(struct platform_device *pdev)
+{
+ struct device_node *nproot = pdev->dev.parent->of_node;
+ struct device_node *np;
+ struct ricoh619_battery_platform_data *pdata;
+
+ if (!nproot)
+ return pdev->dev.platform_data;
+
+ np = of_find_node_by_name(nproot, "battery");
+ if (!np) {
+ dev_err(&pdev->dev, "failed to find battery node\n");
+ return NULL;
+ }
+
+ pdata = devm_kzalloc(&pdev->dev,
+ sizeof(struct ricoh619_battery_platform_data),
+ GFP_KERNEL);
+
+ of_property_read_u32(np, "ricoh,monitor-time", &pdata->monitor_time);
+ of_property_read_u32(np, "ricoh,alarm-vol-mv", &pdata->alarm_vol_mv);
+
+ /* check rage of b,.attery type */
+ type_n = Battery_Type();
+ RICOH_FG_DBG("%s type_n=%d\n", __func__, type_n);
+
+ switch (type_n) {
+ case (0):
+ of_property_read_u32(np, "ricoh,ch-vfchg", &pdata->type[0].ch_vfchg);
+ of_property_read_u32(np, "ricoh,ch-vrchg", &pdata->type[0].ch_vrchg);
+ of_property_read_u32(np, "ricoh,ch-vbatovset", &pdata->type[0].ch_vbatovset);
+ of_property_read_u32(np, "ricoh,ch-ichg", &pdata->type[0].ch_ichg);
+ of_property_read_u32(np, "ricoh,ch-ilim-adp", &pdata->type[0].ch_ilim_adp);
+ of_property_read_u32(np, "ricoh,ch-ilim-usb", &pdata->type[0].ch_ilim_usb);
+ of_property_read_u32(np, "ricoh,ch-icchg", &pdata->type[0].ch_icchg);
+ of_property_read_u32(np, "ricoh,fg-target-vsys", &pdata->type[0].fg_target_vsys);
+ of_property_read_u32(np, "ricoh,fg-target-ibat", &pdata->type[0].fg_target_ibat);
+ of_property_read_u32(np, "ricoh,fg-poff-vbat", &pdata->type[0].fg_poff_vbat);
+ of_property_read_u32(np, "ricoh,jt-en", &pdata->type[0].jt_en);
+ of_property_read_u32(np, "ricoh,jt-hw-sw", &pdata->type[0].jt_hw_sw);
+ of_property_read_u32(np, "ricoh,jt-temp-h", &pdata->type[0].jt_temp_h);
+ of_property_read_u32(np, "ricoh,jt-temp-l", &pdata->type[0].jt_temp_l);
+ of_property_read_u32(np, "ricoh,jt-vfchg-h", &pdata->type[0].jt_vfchg_h);
+ of_property_read_u32(np, "ricoh,jt-vfchg-l", &pdata->type[0].jt_vfchg_l);
+ of_property_read_u32(np, "ricoh,jt-ichg-h", &pdata->type[0].jt_ichg_h);
+ of_property_read_u32(np, "ricoh,jt-ichg-l", &pdata->type[0].jt_ichg_l);
+ break;
+#if 0
+ case (1):
+ of_property_read_u32(np, "ricoh,ch-vfchg-1", &pdata->type[1].ch_vfchg);
+ of_property_read_u32(np, "ricoh,ch-vrchg-1", &pdata->type[1].ch_vrchg);
+ of_property_read_u32(np, "ricoh,ch-vbatovset-1", &pdata->type[1].ch_vbatovset);
+ of_property_read_u32(np, "ricoh,ch-ichg-1", &pdata->type[1].ch_ichg);
+ of_property_read_u32(np, "ricoh,ch-ilim-adp-1", &pdata->type[1].ch_ilim_adp);
+ of_property_read_u32(np, "ricoh,ch-ilim-usb-1", &pdata->type[1].ch_ilim_usb);
+ of_property_read_u32(np, "ricoh,ch-icchg-1", &pdata->type[1].ch_icchg);
+ of_property_read_u32(np, "ricoh,fg-target-vsys-1", &pdata->type[1].fg_target_vsys);
+ of_property_read_u32(np, "ricoh,fg-target-ibat-1", &pdata->type[1].fg_target_ibat);
+ of_property_read_u32(np, "ricoh,fg-poff-vbat-1", &pdata->type[1].fg_poff_vbat);
+ of_property_read_u32(np, "ricoh,jt-en-1", &pdata->type[1].jt_en);
+ of_property_read_u32(np, "ricoh,jt-hw-sw-1", &pdata->type[1].jt_hw_sw);
+ of_property_read_u32(np, "ricoh,jt-temp-h-1", &pdata->type[1].jt_temp_h);
+ of_property_read_u32(np, "ricoh,jt-temp-l-1", &pdata->type[1].jt_temp_l);
+ of_property_read_u32(np, "ricoh,jt-vfchg-h-1", &pdata->type[1].jt_vfchg_h);
+ of_property_read_u32(np, "ricoh,jt-vfchg-l-1", &pdata->type[1].jt_vfchg_l);
+ of_property_read_u32(np, "ricoh,jt-ichg-h-1", &pdata->type[1].jt_ichg_h);
+ of_property_read_u32(np, "ricoh,jt-ichg-l-1", &pdata->type[1].jt_ichg_l);
+ break;
+#endif
+ default:
+ of_node_put(np);
+ return 0;
+ }
+
+ of_node_put(np);
+
+ return pdata;
+}
+#else
+static struct ricoh619_battery_platform_data *
+ricoh619_battery_dt_init(struct platform_device *pdev)
+{
+ return pdev->dev.platform_data;
+}
+#endif
+
+static int ricoh619_battery_probe(struct platform_device *pdev)
{
struct ricoh619_battery_info *info;
struct ricoh619_battery_platform_data *pdata;
- int type_n;
+ struct ricoh619 *ricoh619 = dev_get_drvdata(pdev->dev.parent);
int ret, temp;
- RICOH_FG_DBG("PMU: %s\n", __func__);
+ RICOH_FG_DBG(KERN_INFO "PMU: %s : version is %s\n", __func__,RICOH619_BATTERY_VERSION);
- info = kzalloc(sizeof(struct ricoh619_battery_info), GFP_KERNEL);
+ pdata = ricoh619_battery_dt_init(pdev);
+ if (!pdata) {
+ dev_err(&pdev->dev, "platform data isn't assigned to "
+ "power supply\n");
+ return -EINVAL;
+ }
+ info = devm_kzalloc(ricoh619->dev,sizeof(struct ricoh619_battery_info), GFP_KERNEL);
if (!info)
return -ENOMEM;
- info->soca = kzalloc(sizeof(struct ricoh619_soca_info), GFP_KERNEL);
+ info->soca = devm_kzalloc(ricoh619->dev,sizeof(struct ricoh619_soca_info), GFP_KERNEL);
if (!info->soca)
return -ENOMEM;
info->dev = &pdev->dev;
info->status = POWER_SUPPLY_STATUS_CHARGING;
- pdata = pdev->dev.platform_data;
info->monitor_time = pdata->monitor_time * HZ;
info->alarm_vol_mv = pdata->alarm_vol_mv;
- type_n = Battery_Type();
+ /* check rage of battery num */
info->num = Battery_Table();
temp = sizeof(battery_init_para)/(sizeof(uint8_t)*32);
- RICOH_FG_DBG("%s temp=%d\n", __func__, temp);
if(info->num >= (sizeof(battery_init_para)/(sizeof(uint8_t)*32)))
- info->num = 0;
- RICOH_FG_DBG("%s type_n=%d\n", __func__, type_n);
- RICOH_FG_DBG("%s info->num=%d\n", __func__, info->num);
- /* these valuse are set in platform */
- if (type_n == 0)
{
- info->ch_vfchg = pdata->ch_vfchg;
- info->ch_vrchg = pdata->ch_vrchg;
- info->ch_vbatovset = pdata->ch_vbatovset;
- info->ch_ichg = pdata->ch_ichg;
- info->ch_ilim_adp = pdata->ch_ilim_adp;
- info->ch_ilim_usb = pdata->ch_ilim_usb;
- info->ch_icchg = pdata->ch_icchg;
- info->fg_target_vsys = pdata->fg_target_vsys;
- info->fg_target_ibat = pdata->fg_target_ibat;
- info->jt_en = pdata->jt_en;
- info->jt_hw_sw = pdata->jt_hw_sw;
- info->jt_temp_h = pdata->jt_temp_h;
- info->jt_temp_l = pdata->jt_temp_l;
- info->jt_vfchg_h = pdata->jt_vfchg_h;
- info->jt_vfchg_l = pdata->jt_vfchg_l;
- info->jt_ichg_h = pdata->jt_ichg_h;
- info->jt_ichg_l = pdata->jt_ichg_l;
- } else {
+ RICOH_FG_DBG("%s : Battery num is out of range\n", __func__);
+ info->num = 0;
}
+ RICOH_FG_DBG("%s info->num=%d,temp is %d\n", __func__, info->num,temp);
+
+ /* these valuse are set in platform */
+ info->ch_vfchg = pdata->type[type_n].ch_vfchg;
+ info->ch_vrchg = pdata->type[type_n].ch_vrchg;
+ info->ch_vbatovset = pdata->type[type_n].ch_vbatovset;
+ info->ch_ichg = pdata->type[type_n].ch_ichg;
+ info->ch_ilim_adp = pdata->type[type_n].ch_ilim_adp;
+ info->ch_ilim_usb = pdata->type[type_n].ch_ilim_usb;
+ info->ch_icchg = pdata->type[type_n].ch_icchg;
+ info->fg_target_vsys = pdata->type[type_n].fg_target_vsys;
+ info->fg_target_ibat = pdata->type[type_n].fg_target_ibat;
+ info->fg_poff_vbat = pdata->type[type_n].fg_poff_vbat;
+ info->jt_en = pdata->type[type_n].jt_en;
+ info->jt_hw_sw = pdata->type[type_n].jt_hw_sw;
+ info->jt_temp_h = pdata->type[type_n].jt_temp_h;
+ info->jt_temp_l = pdata->type[type_n].jt_temp_l;
+ info->jt_vfchg_h = pdata->type[type_n].jt_vfchg_h;
+ info->jt_vfchg_l = pdata->type[type_n].jt_vfchg_l;
+ info->jt_ichg_h = pdata->type[type_n].jt_ichg_h;
+ info->jt_ichg_l = pdata->type[type_n].jt_ichg_l;
+
info->adc_vdd_mv = ADC_VDD_MV; /* 2800; */
info->min_voltage = MIN_VOLTAGE; /* 3100; */
info->max_voltage = MAX_VOLTAGE; /* 4200; */
info->delay = 500;
info->entry_factory_mode = false;
+ info->chg_complete_rd_flag = 0;
+ info->chg_complete_rd_cnt = 0;
+ info->chg_complete_tm_ov_flag = 0;
+ info->chg_complete_sleep_flag = 0;
+
mutex_init(&info->lock);
platform_set_drvdata(pdev, info);
/* Disable Charger/ADC interrupt */
ret = ricoh619_clr_bits(info->dev->parent, RICOH619_INTC_INTEN,
CHG_INT | ADC_INT);
- if (ret)
+ if (ret<0)
goto out;
ret = ricoh619_init_battery(info);
- if (ret)
+ if (ret<0)
goto out;
-
+/*
#ifdef ENABLE_FACTORY_MODE
info->factory_mode_wqueue
= create_singlethread_workqueue("ricoh619_factory_mode");
- INIT_DELAYED_WORK_DEFERRABLE(&info->factory_mode_work,
+ INIT_DEFERRABLE_WORK(&info->factory_mode_work,
check_charging_state_work);
ret = ricoh619_factory_mode(info);
- if (ret)
+ if (ret<0)
goto out;
#endif
-
+*/
ret = power_supply_register(&pdev->dev, &info->battery);
- if (ret)
+ if (ret<0)
info->battery.dev->parent = &pdev->dev;
ret = power_supply_register(&pdev->dev, &powerac);
= create_singlethread_workqueue("rc5t619_usb_det");
INIT_WORK(&info->usb_irq_work, usb_det_irq_work);
- INIT_DELAYED_WORK_DEFERRABLE(&info->monitor_work,
+ INIT_DEFERRABLE_WORK(&info->monitor_work,
ricoh619_battery_work);
- INIT_DELAYED_WORK_DEFERRABLE(&info->displayed_work,
+ INIT_DEFERRABLE_WORK(&info->displayed_work,
ricoh619_displayed_work);
- INIT_DELAYED_WORK_DEFERRABLE(&info->charge_stable_work,
+ INIT_DEFERRABLE_WORK(&info->charge_stable_work,
ricoh619_stable_charge_countdown_work);
- INIT_DELAYED_WORK_DEFERRABLE(&info->charge_monitor_work,
+ INIT_DEFERRABLE_WORK(&info->charge_monitor_work,
ricoh619_charge_monitor_work);
- INIT_DELAYED_WORK_DEFERRABLE(&info->get_charge_work,
+ INIT_DEFERRABLE_WORK(&info->get_charge_work,
ricoh619_get_charge_work);
- INIT_DELAYED_WORK_DEFERRABLE(&info->jeita_work, ricoh619_jeita_work);
+ INIT_DEFERRABLE_WORK(&info->jeita_work, ricoh619_jeita_work);
INIT_DELAYED_WORK(&info->changed_work, ricoh619_changed_work);
+ INIT_DELAYED_WORK(&info->charge_complete_ready, ricoh619_charging_complete_work);
+
/* Charger IRQ workqueue settings */
- charger_irq = pdata->irq;
- ret = request_threaded_irq(charger_irq + RICOH619_IRQ_FONCHGINT,
- NULL, charger_in_isr, IRQF_ONESHOT,
+ ret = request_threaded_irq( irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_FONCHGINT),NULL, charger_in_isr, IRQF_ONESHOT,
"rc5t619_charger_in", info);
if (ret < 0) {
- dev_err(&pdev->dev, "Can't get CHG_INT IRQ for chrager: %d\n",
- ret);
+ dev_err(&pdev->dev, "Can't get CHG_INT IRQ for chrager: %d\n",ret);
goto out;
}
- ret = request_threaded_irq(charger_irq + RICOH619_IRQ_FCHGCMPINT,
- NULL, charger_complete_isr,
- IRQF_ONESHOT, "rc5t619_charger_comp",
- info);
+ ret = request_threaded_irq(irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_FCHGCMPINT),NULL, charger_complete_isr,
+ IRQF_ONESHOT, "rc5t619_charger_comp",info);
if (ret < 0) {
- dev_err(&pdev->dev, "Can't get CHG_COMP IRQ for chrager: %d\n",
- ret);
+ dev_err(&pdev->dev, "Can't get CHG_COMP IRQ for chrager: %d\n",ret);
goto out;
}
- ret = request_threaded_irq(charger_irq + RICOH619_IRQ_FVUSBDETSINT,
- NULL, charger_usb_isr, IRQF_ONESHOT,
+ ret = request_threaded_irq(irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_FVUSBDETSINT) ,NULL, charger_usb_isr, IRQF_ONESHOT,
"rc5t619_usb_det", info);
if (ret < 0) {
- dev_err(&pdev->dev, "Can't get USB_DET IRQ for chrager: %d\n",
- ret);
+ dev_err(&pdev->dev, "Can't get USB_DET IRQ for chrager: %d\n",ret);
goto out;
}
- ret = request_threaded_irq(charger_irq + RICOH619_IRQ_FVADPDETSINT,
- NULL, charger_adp_isr, IRQF_ONESHOT,
+ ret = request_threaded_irq(irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_FVADPDETSINT),NULL, charger_adp_isr, IRQF_ONESHOT,
"rc5t619_adp_det", info);
if (ret < 0) {
dev_err(&pdev->dev,
}
#ifdef ENABLE_LOW_BATTERY_DETECTION
- ret = request_threaded_irq(charger_irq + RICOH619_IRQ_VSYSLIR,
- NULL, adc_vsysl_isr, IRQF_ONESHOT,
+ ret = request_threaded_irq(irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_VSYSLIR) ,NULL, adc_vsysl_isr, IRQF_ONESHOT,
"rc5t619_adc_vsysl", info);
if (ret < 0) {
dev_err(&pdev->dev,
"Can't get ADC_VSYSL IRQ for chrager: %d\n", ret);
goto out;
}
- INIT_DELAYED_WORK_DEFERRABLE(&info->low_battery_work,
+ INIT_DEFERRABLE_WORK(&info->low_battery_work,
low_battery_irq_work);
#endif
-
+#ifdef RICOH619_VADP_DROP_WORK
+ INIT_DEFERRABLE_WORK(&info->vadp_drop_work,vadp_drop_irq_work);
+ queue_delayed_work(info->monitor_wqueue, &info->vadp_drop_work,0);
+#endif
/* Charger init and IRQ setting */
ret = ricoh619_init_charger(info);
- if (ret)
+ if (ret<0)
goto out;
#ifdef ENABLE_FUEL_GAUGE_FUNCTION
queue_delayed_work(info->monitor_wqueue, &info->monitor_work,
RICOH619_MONITOR_START_TIME*HZ);
- /* Enable Charger interrupt */
- ricoh619_set_bits(info->dev->parent, RICOH619_INTC_INTEN, CHG_INT);
+ /* Enable Charger/ADC interrupt */
+ ricoh619_set_bits(info->dev->parent, RICOH619_INTC_INTEN, CHG_INT | ADC_INT);
return 0;
out:
- kfree(info);
return ret;
}
-static int __devexit ricoh619_battery_remove(struct platform_device *pdev)
+static int ricoh619_battery_remove(struct platform_device *pdev)
{
struct ricoh619_battery_info *info = platform_get_drvdata(pdev);
+ struct ricoh619 *ricoh619 = dev_get_drvdata(pdev->dev.parent);
uint8_t val;
int ret;
int err;
if (err < 0)
dev_err(info->dev, "Error in writing PSWR_REG\n");
g_soc = 0x7f;
- } else {
- if (info->soca->displayed_soc < 0) {
- val = 0;
+ } else if (info->soca->status != RICOH619_SOCA_START
+ && info->soca->status != RICOH619_SOCA_UNSTABLE) {
+ if (info->soca->displayed_soc <= 0) {
+ val = 1;
} else {
val = (info->soca->displayed_soc + 50)/100;
val &= 0x7f;
g_soc = val;
- ret = calc_capacity_in_period(info, &cc_cap, &is_charging);
+ ret = calc_capacity_in_period(info, &cc_cap,
+ &is_charging, true);
if (ret < 0)
dev_err(info->dev, "Read cc_sum Error !!-----\n");
}
if (err < 0) {
dev_err(info->dev, "Error in writing the control register\n");
}
+
+ if(info->capacity == 100)
+ {
+ ret = ricoh619_write(info->dev->parent, PSWR_REG, 100);
+ if (ret < 0)
+ dev_err(info->dev, "Error in writing PSWR_REG\n");
+ }
- free_irq(charger_irq + RICOH619_IRQ_FONCHGINT, &info);
- free_irq(charger_irq + RICOH619_IRQ_FCHGCMPINT, &info);
- free_irq(charger_irq + RICOH619_IRQ_FVUSBDETSINT, &info);
- free_irq(charger_irq + RICOH619_IRQ_FVADPDETSINT, &info);
+ free_irq(irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_FONCHGINT), &info);
+ free_irq(irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_FCHGCMPINT), &info);
+ free_irq(irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_FVUSBDETSINT), &info);
+ free_irq(irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_FVADPDETSINT) , &info);
#ifdef ENABLE_LOW_BATTERY_DETECTION
- free_irq(charger_irq + RICOH619_IRQ_VSYSLIR, &info);
+ free_irq(irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_VSYSLIR), &info);
#endif
cancel_delayed_work(&info->monitor_work);
#ifdef ENABLE_LOW_BATTERY_DETECTION
cancel_delayed_work(&info->low_battery_work);
#endif
+#ifdef RICOH619_VADP_DROP_WORK
+ cancel_delayed_work(&info->vadp_drop_work);
+#endif
+#ifdef ENABLE_FACTORY_MODE
cancel_delayed_work(&info->factory_mode_work);
+#endif
cancel_delayed_work(&info->jeita_work);
+ cancel_delayed_work(&info->charge_complete_ready);
cancel_work_sync(&info->irq_work);
cancel_work_sync(&info->usb_irq_work);
flush_workqueue(info->monitor_wqueue);
flush_workqueue(info->workqueue);
flush_workqueue(info->usb_workqueue);
+#ifdef ENABLE_FACTORY_MODE
flush_workqueue(info->factory_mode_wqueue);
-
+#endif
destroy_workqueue(info->monitor_wqueue);
destroy_workqueue(info->workqueue);
destroy_workqueue(info->usb_workqueue);
+#ifdef ENABLE_FACTORY_MODE
destroy_workqueue(info->factory_mode_wqueue);
+#endif
power_supply_unregister(&info->battery);
- kfree(info);
platform_set_drvdata(pdev, NULL);
return 0;
}
#ifdef CONFIG_PM
+struct timeval ts_suspend;
static int ricoh619_battery_suspend(struct device *dev)
{
struct ricoh619_battery_info *info = dev_get_drvdata(dev);
int err;
int cc_cap = 0;
bool is_charging = true;
+ int displayed_soc_temp;
+ do_gettimeofday(&ts_suspend);
if (g_fg_on_mode
&& (info->soca->status == RICOH619_SOCA_STABLE)) {
if (err < 0)
dev_err(info->dev, "Error in writing PSWR_REG\n");
g_soc = 0x7F;
- info->soca->suspend_soc = (info->soca->displayed_soc + 50)/100;
- } else {
- if (info->soca->displayed_soc < 0) {
- val = 0;
+ info->soca->suspend_soc = info->soca->displayed_soc;
+ ret = calc_capacity_in_period(info, &cc_cap,
+ &is_charging, true);
+ if (ret < 0)
+ dev_err(info->dev, "Read cc_sum Error !!-----\n");
+
+ } else if (info->soca->status != RICOH619_SOCA_START
+ && info->soca->status != RICOH619_SOCA_UNSTABLE) {
+ if (info->soca->displayed_soc <= 0) {
+ val = 1;
} else {
val = (info->soca->displayed_soc + 50)/100;
val &= 0x7f;
g_soc = val;
- info->soca->suspend_soc = (info->soca->displayed_soc + 50)/100;
-
- ret = calc_capacity_in_period(info, &cc_cap, &is_charging);
+ ret = calc_capacity_in_period(info, &cc_cap,
+ &is_charging, true);
if (ret < 0)
dev_err(info->dev, "Read cc_sum Error !!-----\n");
+
+ if (info->soca->status != RICOH619_SOCA_STABLE) {
+ info->soca->cc_delta
+ = (is_charging == true) ? cc_cap : -cc_cap;
+
+ displayed_soc_temp
+ = info->soca->displayed_soc + info->soca->cc_delta;
+ displayed_soc_temp = min(10000, displayed_soc_temp);
+ displayed_soc_temp = max(0, displayed_soc_temp);
+ info->soca->displayed_soc = displayed_soc_temp;
+ }
+ info->soca->suspend_soc = info->soca->displayed_soc;
+
+ } else if (info->soca->status == RICOH619_SOCA_START
+ || info->soca->status == RICOH619_SOCA_UNSTABLE) {
+
+ ret = ricoh619_read(info->dev->parent, PSWR_REG, &val);
+ if (ret < 0)
+ dev_err(info->dev, "Error in reading the pswr register\n");
+ val &= 0x7f;
+
+ info->soca->suspend_soc = val * 100;
+ }
+
+ if (info->soca->status == RICOH619_SOCA_DISP
+ || info->soca->status == RICOH619_SOCA_STABLE
+ || info->soca->status == RICOH619_SOCA_FULL) {
+ info->soca->soc = calc_capacity_2(info);
+ info->soca->soc_delta =
+ info->soca->soc_delta + (info->soca->soc - info->soca->last_soc);
+
+ } else {
+ info->soca->soc_delta = 0;
}
if (info->soca->status == RICOH619_SOCA_STABLE
|| info->soca->status == RICOH619_SOCA_FULL)
info->soca->status = RICOH619_SOCA_DISP;
-
/* set rapid timer 300 min */
err = ricoh619_set_bits(info->dev->parent, TIMSET_REG, 0x03);
if (err < 0) {
#ifdef ENABLE_LOW_BATTERY_DETECTION
// disable_irq(charger_irq + RICOH619_IRQ_VSYSLIR);
#endif
-
+#if 0
flush_delayed_work(&info->monitor_work);
flush_delayed_work(&info->displayed_work);
flush_delayed_work(&info->charge_stable_work);
#endif
flush_delayed_work(&info->factory_mode_work);
flush_delayed_work(&info->jeita_work);
+#ifdef RICOH619_VADP_DROP_WORK
+ flush_delayed_work(&info->vadp_drop_work);
+#endif
// flush_work(&info->irq_work);
// flush_work(&info->usb_irq_work);
-
+#else
+ cancel_delayed_work(&info->monitor_work);
+ cancel_delayed_work(&info->displayed_work);
+ cancel_delayed_work(&info->charge_stable_work);
+ cancel_delayed_work(&info->charge_monitor_work);
+ cancel_delayed_work(&info->get_charge_work);
+ cancel_delayed_work(&info->changed_work);
+#ifdef ENABLE_LOW_BATTERY_DETECTION
+ cancel_delayed_work(&info->low_battery_work);
+#endif
+/* cancel_delayed_work(&info->charge_complete_ready);*/
+#ifdef ENABLE_FACTORY_MODE
+ cancel_delayed_work(&info->factory_mode_work);
+#endif
+ cancel_delayed_work(&info->jeita_work);
+#ifdef RICOH619_VADP_DROP_WORK
+ cancel_delayed_work(&info->vadp_drop_work);
+#endif
+/* info->chg_complete_rd_cnt = 0;*/
+/* info->chg_complete_rd_flag = 0;*/
+
+ if(info->capacity == 100)
+ {
+ ret = ricoh619_write(info->dev->parent, PSWR_REG, 100);
+ if (ret < 0)
+ dev_err(info->dev, "Error in writing PSWR_REG\n");
+ if(info->chg_complete_tm_ov_flag != 1)
+ {
+ info->chg_complete_tm_ov_flag = 0;
+ info->chg_complete_sleep_flag = 1;
+ }
+ }
+// flush_work(&info->irq_work);
+// flush_work(&info->usb_irq_work);
+#endif
return 0;
}
bool is_charging = true;
bool is_jeita_updated;
int i;
+ int err;
+ struct rtc_time tm;
+ struct timespec tv = {
+ .tv_nsec = NSEC_PER_SEC >> 1,
+ };
+ struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
+
+ err = rtc_read_time(rtc, &tm);
+ if (err) {
+ dev_err(rtc->dev.parent,
+ "hctosys: unable to read the hardware clock\n");
+ }
+
+ err = rtc_valid_tm(&tm);
+ if (err) {
+ dev_err(rtc->dev.parent,
+ "hctosys: invalid date/time\n");
+ }
+
+ rtc_tm_to_time(&tm, &tv.tv_sec);
+
+ /*printk("suspend time: %d sec\n", ts_suspend.tv_sec);*/
+ /*printk("resume time: %d sec\n", tv.tv_sec);*/
+
+ if(info->chg_complete_rd_flag == 2){
+ printk("chg_complete_rd_cnt suspend: %d\n", info->chg_complete_rd_cnt);
+ info->chg_complete_rd_cnt += (tv.tv_sec - ts_suspend.tv_sec);
+ printk("chg_complete_rd_cnt resume: %d\n", info->chg_complete_rd_cnt);
+ flush_work(&info->charge_complete_ready.work);
+ }
RICOH_FG_DBG(KERN_INFO "PMU: %s: \n", __func__);
info->soca->displayed_soc = -EINVAL;
} else if (RICOH619_SOCA_ZERO == info->soca->status) {
if (calc_ocv(info) > get_OCV_voltage(info, 0)) {
+ RICOH_FG_DBG(KERN_INFO "PMU: %s: RICOH619_SOCA_ZERO if ()...\n", __func__);
ret = ricoh619_read(info->dev->parent, PSWR_REG, &val);
val &= 0x7f;
info->soca->soc = val * 100;
}
ret = calc_capacity_in_period(info, &cc_cap,
- &is_charging);
+ &is_charging, true);
if (ret < 0)
dev_err(info->dev, "Read cc_sum Error !!-----\n");
displayed_soc_temp = max(0, displayed_soc_temp);
info->soca->displayed_soc = displayed_soc_temp;
- ret = ricoh619_write(info->dev->parent,
- FG_CTRL_REG, 0x51);
+ ret = reset_FG_process(info);
+
if (ret < 0)
dev_err(info->dev, "Error in writing the control register\n");
- info->soca->ready_fg = 0;
info->soca->status = RICOH619_SOCA_FG_RESET;
- } else
- info->soca->displayed_soc = 0;
+ } else {
+ RICOH_FG_DBG(KERN_INFO "PMU: %s: RICOH619_SOCA_ZERO else()...\n", __func__);
+ /*info->soca->displayed_soc = 0;*/
+ info->soca->displayed_soc = info->soca->suspend_soc;
+ }
} else {
- info->soca->soc = info->soca->suspend_soc * 100;
+ info->soca->soc = info->soca->suspend_soc;
+
+ if (RICOH619_SOCA_START == info->soca->status
+ || RICOH619_SOCA_UNSTABLE == info->soca->status) {
+ ret = calc_capacity_in_period(info, &cc_cap,
+ &is_charging, false);
+ } else {
+ ret = calc_capacity_in_period(info, &cc_cap,
+ &is_charging, true);
+ }
- ret = calc_capacity_in_period(info, &cc_cap, &is_charging);
if (ret < 0)
dev_err(info->dev, "Read cc_sum Error !!-----\n");
info->soca->cc_delta = (is_charging == true) ? cc_cap : -cc_cap;
displayed_soc_temp = info->soca->soc + info->soca->cc_delta;
- if (displayed_soc_temp < 0)
+ if (info->soca->zero_flg == 1) {
+ if((info->soca->Ibat_ave >= 0)
+ || (displayed_soc_temp >= 100)){
+ info->soca->zero_flg = 0;
+ } else {
displayed_soc_temp = 0;
+ }
+ } else if (displayed_soc_temp < 100) {
+ /* keep DSOC = 1 when Vbat is over 3.4V*/
+ if( info->fg_poff_vbat != 0) {
+ if (info->soca->Vbat_ave < 2000*1000) { /* error value */
+ displayed_soc_temp = 100;
+ } else if (info->soca->Vbat_ave < info->fg_poff_vbat*1000) {
+ displayed_soc_temp = 0;
+ info->soca->zero_flg = 1;
+ } else {
+ displayed_soc_temp = 100;
+ }
+ }
+ }
displayed_soc_temp = min(10000, displayed_soc_temp);
displayed_soc_temp = max(0, displayed_soc_temp);
}
if (RICOH619_SOCA_DISP == info->soca->status) {
- info->soca->last_soc = calc_capacity(info) * 100;
- info->soca->soc_delta = 0;
+ info->soca->last_soc = calc_capacity_2(info);
}
}
- info->soca->update_count = 0;
ret = measure_vbatt_FG(info, &info->soca->Vbat_ave);
ret = measure_vsys_ADC(info, &info->soca->Vsys_ave);
ret = measure_Ibatt_FG(info, &info->soca->Ibat_ave);
+ if(info->chg_complete_sleep_flag == 1)
+ {
+ info->chg_complete_tm_ov_flag = 1;
+ info->chg_complete_sleep_flag = 0;
+ }
+
power_supply_changed(&info->battery);
queue_delayed_work(info->monitor_wqueue, &info->displayed_work, HZ);
info->soca->chg_count = 0;
queue_delayed_work(info->monitor_wqueue, &info->get_charge_work,
RICOH619_CHARGE_RESUME_TIME * HZ);
+ #ifdef RICOH619_VADP_DROP_WORK
+ queue_delayed_work(info->monitor_wqueue, &info->vadp_drop_work,1 * HZ);
+ #endif
if (info->jt_en) {
if (!info->jt_hw_sw) {
queue_delayed_work(info->monitor_wqueue, &info->jeita_work,
RICOH619_JEITA_UPDATE_TIME * HZ);
}
}
- ricoh619_write(info->dev->parent, 0x9d, 0x00);
+// ricoh619_write(info->dev->parent, 0x9d, 0x00);
// enable_irq(charger_irq + RICOH619_IRQ_FONCHGINT);
// enable_irq(charger_irq + RICOH619_IRQ_FCHGCMPINT);
// enable_irq(charger_irq + RICOH619_IRQ_FVUSBDETSINT);
return 0;
}
+#ifdef CONFIG_OF
+static const struct of_device_id ricoh619_battery_dt_match[] = {
+ { .compatible = "ricoh,ricoh619-battery", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ricoh619_battery_dt_match);
+#endif
+
+
static const struct dev_pm_ops ricoh619_battery_pm_ops = {
.suspend = ricoh619_battery_suspend,
.resume = ricoh619_battery_resume,
.driver = {
.name = "ricoh619-battery",
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(ricoh619_battery_dt_match),
#ifdef CONFIG_PM
.pm = &ricoh619_battery_pm_ops,
#endif
},
.probe = ricoh619_battery_probe,
- .remove = __devexit_p(ricoh619_battery_remove),
+ .remove = ricoh619_battery_remove,
};
static int __init ricoh619_battery_init(void)
RICOH_FG_DBG("PMU: %s\n", __func__);
return platform_driver_register(&ricoh619_battery_driver);
}
-subsys_initcall_sync(ricoh619_battery_init);
+fs_initcall_sync(ricoh619_battery_init);
static void __exit ricoh619_battery_exit(void)
{