rk3188:pmu-ricoh619:updata the drivers,modify some rtc and fg bug
author张晴 <zhangqing@rock-chips.com>
Fri, 9 Aug 2013 03:46:18 +0000 (11:46 +0800)
committer张晴 <zhangqing@rock-chips.com>
Fri, 9 Aug 2013 03:46:18 +0000 (11:46 +0800)
drivers/mfd/ricoh619-irq.c
drivers/power/ricoh619-battery.c
drivers/regulator/ricoh619-regulator.c
drivers/rtc/rtc-ricoh619.c [changed mode: 0644->0755]
include/linux/power/ricoh619_battery.h [changed mode: 0755->0644]
include/linux/rtc/rtc-ricoh619.h

index 32c713873b559cb4cd97a5dd7965dfbab92732b9..5bf56f136ffd5f861fc74c539c7ef4f3f2dbe33a 100644 (file)
@@ -372,9 +372,9 @@ static irqreturn_t ricoh619_irq(int irq, void *data)
                }
                if (i != 2) {
                        ret = ricoh619_write(ricoh619->dev,
-                                       irq_clr_add[i], ~int_sts[i]);
+                               irq_clr_add[i], ~int_sts[i]);
                        if (ret < 0) {
-                               dev_err(ricoh619->dev, "Error in reading reg 0x%02x "
+                               dev_err(ricoh619->dev, "Error in writing reg 0x%02x "
                                        "error: %d\n", irq_clr_add[i], ret);
                        }
                }
@@ -438,6 +438,7 @@ int ricoh619_irq_init(struct ricoh619 *ricoh619, int irq,
                                int irq_base)
 {
        int i, ret;
+       u8 reg_data = 0;
 
        if (!irq_base) {
                dev_warn(ricoh619->dev, "No interrupt support on IRQ base\n");
@@ -447,10 +448,21 @@ int ricoh619_irq_init(struct ricoh619 *ricoh619, int irq,
        mutex_init(&ricoh619->irq_lock);
 
        /* Initialize all locals to 0 */
-       for (i = 0; i < 8; i++) {
+       for (i = 0; i < 2; i++) {
                ricoh619->irq_en_cache[i] = 0;
                ricoh619->irq_en_reg[i] = 0;
        }
+
+       /* Initialize rtc */
+       ricoh619->irq_en_cache[2] = 0x20;
+       ricoh619->irq_en_reg[2] = 0x20;
+
+       /* Initialize all locals to 0 */
+       for (i = 3; i < 8; i++) {
+               ricoh619->irq_en_cache[i] = 0;
+               ricoh619->irq_en_reg[i] = 0;
+       }
+
        // Charger Mask register must be set to 1 for masking Int output.
        for (i = 8; i < MAX_INTERRUPT_MASKS; i++) {
                ricoh619->irq_en_cache[i] = 0xff;
@@ -490,11 +502,29 @@ int ricoh619_irq_init(struct ricoh619 *ricoh619, int irq,
 
        /* Clear all interrupts in case they woke up active. */
        for (i = 0; i < MAX_INTERRUPT_MASKS; i++)  {
-               ret = ricoh619_write(ricoh619->dev,
+               if(irq_clr_add[i] != RICOH619_INT_IR_RTC)
+               {
+                       ret = ricoh619_write(ricoh619->dev,
                                        irq_clr_add[i], 0);
-               if (ret < 0)
-                       dev_err(ricoh619->dev, "Error in writing reg 0x%02x "
-                               "error: %d\n", irq_clr_add[i], ret);
+                       if (ret < 0)
+                               dev_err(ricoh619->dev, "Error in writing reg 0x%02x "
+                                       "error: %d\n", irq_clr_add[i], ret);
+               }
+               else
+               {
+                       ret = ricoh619_read(ricoh619->dev,
+                                       RICOH619_INT_IR_RTC, &reg_data);
+                       if (ret < 0)
+                               dev_err(ricoh619->dev, "Error in reading reg 0x%02x "
+                                       "error: %d\n", RICOH619_INT_IR_RTC, ret);
+                       reg_data &= 0xf0;
+                       ret = ricoh619_write(ricoh619->dev,
+                                       RICOH619_INT_IR_RTC, reg_data);
+                       if (ret < 0)
+                               dev_err(ricoh619->dev, "Error in writing reg 0x%02x "
+                                       "error: %d\n", RICOH619_INT_IR_RTC, ret);
+                       
+               }
        }
 
        ricoh619->irq_base = irq_base;
@@ -512,7 +542,7 @@ int ricoh619_irq_init(struct ricoh619 *ricoh619, int irq,
        }
 
        ret = request_threaded_irq(irq, NULL, ricoh619_irq,
-                       IRQ_TYPE_EDGE_FALLING|IRQF_DISABLED|IRQF_ONESHOT,
+                       IRQ_TYPE_LEVEL_LOW|IRQF_DISABLED|IRQF_ONESHOT,
                                                   "ricoh619", ricoh619);
        if (ret < 0)
                dev_err(ricoh619->dev, "Error in registering interrupt "
index 2a01c4fd89e1a8809fcfbc8766d68113962fd4eb..ecab67ffe2387d8259a7822437e9f12b629a592a 100644 (file)
@@ -45,6 +45,7 @@
 #define ENABLE_FACTORY_MODE
 #define DISABLE_CHARGER_TIMER
 /* #define ENABLE_FG_KEEP_ON_MODE */
+#define ENABLE_OCV_TABLE_CALIB
 
 
 
@@ -71,12 +72,14 @@ enum int_type {
 #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_CHARGE_UPDATE_TIME            3
+#define RICOH619_FULL_WAIT_TIME                        2
 #define RE_CAP_GO_DOWN                         10      /* 40 */
 #define RICOH619_ENTER_LOW_VOL                 70
 #define RICOH619_TAH_SEL2                              5
@@ -101,6 +104,7 @@ enum {
 struct ricoh619_soca_info {
        int Rbat;
        int n_cap;
+       int ocv_table_def[11];
        int ocv_table[11];
        int soc;                /* Latest FG SOC value */
        int displayed_soc;
@@ -117,6 +121,7 @@ struct ricoh619_soca_info {
        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];
@@ -135,6 +140,8 @@ struct ricoh619_soca_info {
        int target_vsys;
        int target_ibat;
        int jt_limit;
+       int OCV100_min;
+       int OCV100_max;
 };
 
 struct ricoh619_battery_info {
@@ -211,8 +218,9 @@ int g_fg_on_mode;
 extern int dwc_vbus_status(void);
 /*This is for full state*/
 int g_full_flag;
-static int BatteryTableFlageDef=0;
+static int BatteryTableFlagDef=0;
 static int BatteryTypeDef=0;
+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 Battery_Type(void)
 {
        return BatteryTypeDef;
@@ -220,7 +228,7 @@ static int Battery_Type(void)
 
 static int Battery_Table(void)
 {
-       return BatteryTableFlageDef;
+       return BatteryTableFlagDef;
 }
 
 static void ricoh619_battery_work(struct work_struct *work)
@@ -238,18 +246,20 @@ 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);
+                                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 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 int calc_ocv(struct ricoh619_battery_info *info)
@@ -291,7 +301,7 @@ static int check_charge_status_2(struct ricoh619_battery_info *info, int display
        }
        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) )
+                       if ((calc_ocv(info) < (get_OCV_voltage(info, 9) + (get_OCV_voltage(info, 10) - get_OCV_voltage(info, 9))*3/10) )
                        && (info->soca->soc/100 <= 98) ) {
                                g_full_flag = 0;
                                info->soca->displayed_soc = 100*100;
@@ -315,9 +325,12 @@ static int check_charge_status_2(struct ricoh619_battery_info *info, int display
 * @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];
@@ -380,11 +393,13 @@ static int calc_capacity_in_period(struct ricoh619_battery_info *info,
        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);
@@ -522,6 +537,82 @@ static int get_target_use_cap(struct ricoh619_battery_info *info)
        
        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,end_per;
+       
+       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;
+       }
+       
+       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;
+       }
+
+       info->soca->ready_fg = 0;
+
+       //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 = ricoh619_write(info->dev->parent, FG_CTRL_REG, 0x51);
+       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)
 {
@@ -532,11 +623,19 @@ 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 ret;
+       int ocv;
+       int temp_ocv;
 
        struct ricoh619_battery_info *info = container_of(work,
        struct ricoh619_battery_info, displayed_work.work);
@@ -553,13 +652,23 @@ static void ricoh619_displayed_work(struct work_struct *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 */
        if ((RICOH619_SOCA_DISP == info->soca->status)
                 || (RICOH619_SOCA_STABLE == info->soca->status))
        {
+               /* caluc 95% ocv */
+               temp_ocv = get_OCV_voltage(info, 10) -
+                                       (get_OCV_voltage(info, 10) - get_OCV_voltage(info, 9))/2;
+               
+               if ((POWER_SUPPLY_STATUS_FULL == info->soca->chg_status)
+                       && (calc_ocv(info) > temp_ocv)) {
+                       info->soca->status = RICOH619_SOCA_FULL;
+                       info->soca->update_count = 0;
+               }
                /* for issue 1 solution start*/
                if(g_full_flag == 1){
                        info->soca->status = RICOH619_SOCA_FULL;
@@ -567,27 +676,34 @@ static void ricoh619_displayed_work(struct work_struct *work)
                }
                /* 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))
+               if (info->soca->Ibat_ave >= -20) {
+                       if ((calc_ocv(info) > (get_OCV_voltage(info, 9) + (get_OCV_voltage(info, 10) - get_OCV_voltage(info, 9))*7/10))
                                || (info->soca->displayed_soc/100 >= 99))
                        {
                                g_full_flag = 0;
                                info->soca->status = RICOH619_SOCA_FULL;
                                info->soca->update_count = 0;
+                       } else if ((calc_ocv(info) > (get_OCV_voltage(info, 9)))
+                               && (info->soca->Ibat_ave < 300))
+                       {
+                               g_full_flag = 0;
+                               info->soca->status = RICOH619_SOCA_FULL;
+                               info->soca->update_count = 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;
+               info->soca->soc = calc_capacity_2(info);
                soc_round = info->soca->soc / 100;
                last_soc_round = info->soca->last_soc / 100;
 
-               info->soca->soc_delta = soc_round - last_soc_round;
+               info->soca->soc_delta = info->soca->soc - info->soca->last_soc;
 
                //get charge status
                if (info->soca->chg_status == POWER_SUPPLY_STATUS_CHARGING) {
@@ -646,14 +762,13 @@ static void ricoh619_displayed_work(struct work_struct *work)
                        }
                }
 
-               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) {
@@ -661,54 +776,91 @@ static void ricoh619_displayed_work(struct work_struct *work)
                        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;
+                                       /* caluc 95% ocv */
+                                       //temp_ocv = get_OCV_voltage(info, 10) -
+                                       //                      (get_OCV_voltage(info, 10) - get_OCV_voltage(info, 9))/2;
+                                       temp_ocv = get_OCV_voltage(info, 9);
+                                       info->soca->update_count++;
+                                       info->soca->chg_cmp_times = 0;
+                                       if (info->soca->update_count >= RICOH619_UPDATE_COUNT_FULL) {
+                                               if (calc_ocv(info) < temp_ocv) {
+                                                       if(info->soca->displayed_soc > info->soca->soc) {
+                                                               info->soca->displayed_soc = info->soca->displayed_soc - 1;
+                                                       } else {
+                                                               info->soca->displayed_soc = info->soca->soc;
+                                                       }
+                                               } else {
+                                                       info->soca->displayed_soc = 100*100;
+                                               }
+                                               info->soca->update_count = 0;
+                                       }
                                } 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;
+                                       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) {
+                                               if(info->soca->chg_cmp_times >= RICOH619_FULL_WAIT_TIME) {
+                                                       info->soca->displayed_soc = 100*100;
                                                        info->soca->update_count = 0;
+                                                       g_full_flag = 1;
+#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;
+                                               info->soca->chg_cmp_times = 0;
+                                               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;
+                                                       }
+                                               } else {
+                                                       info->soca->displayed_soc = 99 * 100;
+                                                       info->soca->update_count = 0;
+                                               }
                                        }
                                }
                        } else {
                                info->soca->update_count = 0;
                        }
-               }
-               if (info->soca->Ibat_ave < 0) { /* for issue 3 */
-                       info->soca->update_count = 0;
+               } else { /* discharging */
                        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;
+                               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/100 <= 98)) {
+                                               g_full_flag = 0;
+                                               info->soca->displayed_soc = 100 * 100;
+                                               info->soca->status = RICOH619_SOCA_DISP;
+                                               info->soca->soc_delta = 0;
+                                       } else {
+                                               info->soca->displayed_soc = 100 * 100;
+                                       }
+                               } else { /* into relaxation state */
+                                       ricoh619_read(info->dev->parent, CHGSTATE_REG, &reg_val);
+                                       if (reg_val & 0xc0) {
+                                               info->soca->displayed_soc = 100 * 100;
+                                       } else {
+                                               g_full_flag = 0;
+                                               info->soca->displayed_soc = 100 * 100;
+                                               info->soca->status = RICOH619_SOCA_DISP;
+                                               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;
                        }
                }
@@ -718,7 +870,6 @@ static void ricoh619_displayed_work(struct work_struct *work)
                        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);
@@ -726,14 +877,16 @@ static void ricoh619_displayed_work(struct work_struct *work)
                                                                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;
@@ -744,14 +897,14 @@ static void ricoh619_displayed_work(struct work_struct *work)
        }
        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;
                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 */
@@ -759,20 +912,24 @@ static void ricoh619_displayed_work(struct work_struct *work)
                        /* 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
                                                                 >= soc_round) {
@@ -780,14 +937,13 @@ static void ricoh619_displayed_work(struct work_struct *work)
                                                        = 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
                                                                 <= soc_round) {
@@ -795,24 +951,27 @@ static void ricoh619_displayed_work(struct work_struct *work)
                                                        = 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
                                                         <= soc_round) {
@@ -820,14 +979,13 @@ static void ricoh619_displayed_work(struct work_struct *work)
                                                = 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
                                                         >= soc_round) {
@@ -835,12 +993,41 @@ static void ricoh619_displayed_work(struct work_struct *work)
                                                = info->soca->soc ;
                                        info->soca->status
                                                = RICOH619_SOCA_STABLE;
+                                       delay_flag = 1;
                                }
                        }
                }
        } else if (RICOH619_SOCA_UNSTABLE == info->soca->status) {
+               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(10000, displayed_soc_temp);
+               displayed_soc_temp = max(0, displayed_soc_temp);
+
                if (0 == info->soca->jt_limit) {
-                       check_charge_status_2(info, info->soca->displayed_soc);
+                       check_charge_status_2(info, displayed_soc_temp);
+               } else {
+                       info->soca->displayed_soc = displayed_soc_temp;
                }
        } else if (RICOH619_SOCA_FG_RESET == info->soca->status) {
                /* No update */
@@ -852,8 +1039,24 @@ static void ricoh619_displayed_work(struct work_struct *work)
                }
                err = ricoh619_read(info->dev->parent, PSWR_REG, &val);
                val &= 0x7f;
+               ////debug for Zero state///
+               ret = measure_vbatt_FG(info, &Vbat);
+               ret = measure_Ibatt_FG(info, &Ibat);
+               ocv = Vbat - Ibat * info->soca->Rbat;
+               RICOH_FG_DBG("Check ZERO state : Vbat %d, Ibat %d, ocv %d Rbat %d %d\n",Vbat,Ibat,ocv,info->soca->Rbat);
+               info->soca->soc = calc_capacity(info) * 100;
+               RICOH_FG_DBG("Check ZERO state : first_pwon %d, RSOC is %d OCV is %d\n",info->first_pwon,info->soca->soc/100,calc_ocv(info));
+               RICOH_FG_DBG("Check ZERO state : g_fg_on_mode %d, get ocv voltage %d\n",g_fg_on_mode,get_OCV_voltage(info, 0));
+               ///////////////////////////
                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;
@@ -878,6 +1081,7 @@ static void ricoh619_displayed_work(struct work_struct *work)
                                } else {
                                        info->soca->displayed_soc = info->soca->soc;
                                }
+                               info->soca->last_soc = info->soca->soc;
                                info->soca->status = RICOH619_SOCA_STABLE;
                        }
                } else {
@@ -890,7 +1094,7 @@ static void ricoh619_displayed_work(struct work_struct *work)
                        }
 
                        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");
 
@@ -912,6 +1116,7 @@ static void ricoh619_displayed_work(struct work_struct *work)
                                } else {
                                        info->soca->displayed_soc = displayed_soc_temp;
                                }
+                               info->soca->last_soc = calc_capacity(info) * 100;
                                info->soca->status = RICOH619_SOCA_UNSTABLE;
                        }
                }
@@ -921,6 +1126,7 @@ static void ricoh619_displayed_work(struct work_struct *work)
                                                         FG_CTRL_REG, 0x51);
                        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;
                }
@@ -933,9 +1139,9 @@ end_flow:
                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 (RICOH619_SOCA_UNSTABLE != info->soca->status) {
+               if (info->soca->displayed_soc <= 0) {
+                       val = 1;
                } else {
                        val = (info->soca->displayed_soc + 50)/100;
                        val &= 0x7f;
@@ -946,7 +1152,8 @@ end_flow:
 
                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");
        }
@@ -985,6 +1192,9 @@ end_flow:
        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);
@@ -1112,7 +1322,6 @@ adjust:
                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);
@@ -1299,7 +1508,7 @@ static int ricoh619_init_fgsoca(struct ricoh619_battery_info *info)
        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;
+                                                               get_OCV_voltage(info, 9)) / 10;
 
        info->soca->displayed_soc = 0;
        info->soca->suspend_soc = 0;
@@ -1309,6 +1518,7 @@ static int ricoh619_init_fgsoca(struct ricoh619_battery_info *info)
        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->Vsys_ave = 0;
@@ -1325,6 +1535,8 @@ static int ricoh619_init_fgsoca(struct ricoh619_battery_info *info)
                info->soca->Ibat[i] = 0;
        }
        
+       g_full_flag = 0;
+       
 #ifdef ENABLE_FG_KEEP_ON_MODE
        g_fg_on_mode = 1;
 #else
@@ -1420,7 +1632,7 @@ static int check_jeita_status(struct ricoh619_battery_info *info, bool *is_jeita
 
        /* 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;
@@ -1700,95 +1912,133 @@ static int Calc_Linear_Interpolation(int x0, int y0, int x1, int y1, int y)
        return x;
 }
 
+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             i, j;
+       int             temp;
+       int             percent_step;
+       int             OCV_percent_new[11];
+
+       /* 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);
+
+       /* Check Start % */
+       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));
+                       i = 11;
+               }
+       }
+
+       /* 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));
+                       i = 11;
+               }
+       }
+
+       /* 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);
+
+       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]);
+
+                               temp = ( (temp/1000) * 4095 ) / 5000;
+
+                               battery_init_para[info->num][i*2 + 1] = temp;
+                               battery_init_para[info->num][i*2] = temp >> 8;
+
+                               j = 11;
+                       }
+               }
+       }
+       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);
+       }
+
+}
+
 static int ricoh619_set_OCV_table(struct ricoh619_battery_info *info)
 {
        int             ret = 0;
-       int             ocv_table[11];
+       int             OCV_set_table[11];
        int             i, j;
+       int             full_ocv;
        int             available_cap;
+       int             available_cap_ori;
+       int             OCV_100_def;
+       int             OCV_0_def;
+       int             OCV_100_diff;
+       int             OCV_0_diff;
        int             temp;
-       int             start_par;
+       int             start_per;
+       int             end_per;
        int             percent_step;
        int             OCV_percent_new[11];
        int             Rbat;
        int             Ibat_min;
+       uint8_t val;
+       uint8_t val2;
+       uint8_t val_temp;
+
+
+       //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]);
+       }
 
        info->soca->target_vsys = info->fg_target_vsys;
        info->soca->target_ibat = info->fg_target_ibat;
 
        //for debug
-       RICOH_FG_DBG("PMU : %s : target_vsys is %d target_ibat is %d",__func__,info->soca->target_vsys,info->soca->target_ibat);
+       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. */
-               /* 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;
-                       
-               }
-
-               /* get internal impedence */
                temp =  (battery_init_para[info->num][24]<<8) | (battery_init_para[info->num][25]);
                Rbat = temp * 1000 / 512 * 5000 / 4095;
 
                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;
+               
+               full_ocv = (battery_init_para[info->num][20]<<8) | (battery_init_para[info->num][21]);
+               full_ocv = full_ocv * 5000 / 4095;
 
-
-               RICOH_FG_DBG("PMU: -------  Rbat= %d: Rsys= %d: cutoff_ocv= %d: =======\n",
-                       Rbat, info->soca->Rsys, info->soca->cutoff_ocv);
-
-               /* 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;
-                       }
-               }
-               /* calc new ocv percent */
-               percent_step = (10000 - start_par) / 10;
-
-               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]);
-
-                                       temp = temp * 4095 / 50000;
-
-                                       battery_init_para[info->num][i*2 + 1] = temp;
-                                       battery_init_para[info->num][i*2] = temp >> 8;
-
-                                       j = 11;
-                               }
-                       }
-               }
-
-               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);
-               }
-
+               ricoh619_scaling_OCV_table(info, info->soca->cutoff_ocv, full_ocv, &start_per, &end_per);
 
                /* calc available capacity */
                /* get avilable capacity */
@@ -1797,21 +2047,155 @@ static int ricoh619_set_OCV_table(struct ricoh619_battery_info *info)
                                         | (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;
+       }
+       ////////////////////////////////
+       ////////////////////////////////
+       //check OCV calibration or not
+       /* get ocv table from setting */
+       for (i = 0; i < 11; i++){
+               ret = ricoh619_read_bank1(info->dev->parent, (0xBC + i*2), &val);
+               if (ret < 0) {
                dev_err(info->dev, "batterry initialize error\n");
                return ret;
+               }
+               ret = ricoh619_read_bank1(info->dev->parent, (0xBD + i*2), &val2);
+               if (ret < 0) {
+                       dev_err(info->dev, "batterry initialize error\n");
+                       return ret;
+               }
+               val &= 0x0F;
+               OCV_set_table[i] = val2 + (val << 8);
+               RICOH_FG_DBG("PMU : %s : no %d OCV_set_table %x\n", __func__, i, OCV_set_table[i]);
+
        }
 
-       return 1;
+       OCV_100_def = (battery_init_para[info->num][20]<<8)
+                                | (battery_init_para[info->num][21]);
+
+       OCV_0_def = (battery_init_para[info->num][0]<<8)
+                                | (battery_init_para[info->num][1]);
+       
+       if(OCV_100_def < OCV_set_table[10]) {
+               OCV_100_diff = OCV_set_table[10] - OCV_100_def;
+       } else {
+               OCV_100_diff = OCV_100_def - OCV_set_table[10];
+       }
+
+       if(OCV_0_def < OCV_set_table[0]) {
+               OCV_0_diff = OCV_set_table[0] - OCV_0_def;
+       } else {
+               OCV_0_diff = OCV_0_def - OCV_set_table[0];
+       }
+       RICOH_FG_DBG("PMU : %s : def OCV 100 %x OCV 0 %x \n", __func__, OCV_100_def, OCV_0_def);
+       RICOH_FG_DBG("PMU : %s : OCV 100 %x OCV 0 %x \n", __func__, OCV_set_table[10], OCV_set_table[0]);
+       RICOH_FG_DBG("PMU : %s : diff OCV 100 %x OCV 0 %x \n", __func__, OCV_100_diff, OCV_0_diff);
+
+       if ( (OCV_100_diff > 5)
+               &&(OCV_0_diff < 5))
+       {/* keep setting OCV table */
+               for (i = 0; i < 11; i++) {
+                       RICOH_FG_DBG("PMU : 1\n");
+                       battery_init_para[info->num][i*2+1] = OCV_set_table[i];
+                       battery_init_para[info->num][i*2] = OCV_set_table[i] >> 8;
+               }
+       }
+
+       /////////////////////////////////
+       ret = ricoh619_read_bank1(info->dev->parent, 0xDC, &val);
+       if (ret < 0) {
+               dev_err(info->dev, "batterry initialize error\n");
+               goto err;
+       }
+
+       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][23+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 */
@@ -1854,15 +2238,22 @@ static int ricoh619_init_battery(struct ricoh619_battery_info *info)
                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");
@@ -1895,10 +2286,15 @@ static int ricoh619_init_battery(struct ricoh619_battery_info *info)
 static int ricoh619_init_charger(struct ricoh619_battery_info *info)
 {
        int err;
+       int i;
        uint8_t val;
        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;
@@ -2151,6 +2547,41 @@ static int ricoh619_init_charger(struct ricoh619_battery_info *info)
                        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 */
@@ -2161,8 +2592,9 @@ static int ricoh619_init_charger(struct ricoh619_battery_info *info)
        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);
+       /* 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 */
@@ -2572,7 +3004,7 @@ static int calc_capacity(struct ricoh619_battery_info *info)
        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;
@@ -2594,6 +3026,50 @@ static int calc_capacity(struct ricoh619_battery_info *info)
        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) + 50;
+               capacity = min(10000, capacity);
+               capacity = max(0, 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));
+
+       return temp;            /* Unit is 0.01% */
+}
+
 static int get_battery_temp(struct ricoh619_battery_info *info)
 {
        int ret = 0;
@@ -2624,6 +3100,141 @@ static int get_battery_temp(struct ricoh619_battery_info *info)
        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;
+}
+
 static int get_time_to_empty(struct ricoh619_battery_info *info)
 {
        int ret = 0;
@@ -2830,6 +3441,7 @@ static int ricoh619_batt_get_prop(struct power_supply *psy,
        mutex_lock(&info->lock);
 
        switch (psp) {
+#if 0
        case POWER_SUPPLY_PROP_ONLINE:
                ret = ricoh619_read(info->dev->parent, CHGSTATE_REG, &status);
                if (ret < 0) {
@@ -2842,6 +3454,7 @@ static int ricoh619_batt_get_prop(struct power_supply *psy,
                else if (psy->type == POWER_SUPPLY_TYPE_USB)
                        val->intval = (status & 0x80 ? 1 : 0);
                break;
+#endif
        /* this setting is same as battery driver of 584 */
        case POWER_SUPPLY_PROP_STATUS:
                ret = get_power_supply_status(info);
@@ -2899,7 +3512,7 @@ static int ricoh619_batt_get_prop(struct power_supply *psy,
        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 {
@@ -3002,8 +3615,8 @@ static __devinit int ricoh619_battery_probe(struct platform_device *pdev)
        int type_n;
        int ret, temp;
 
-       RICOH_FG_DBG("PMU: %s\n", __func__);
-
+       RICOH_FG_DBG("PMU:2013.8.3 %s\n", __func__);
+       
        info = kzalloc(sizeof(struct ricoh619_battery_info), GFP_KERNEL);
        if (!info)
                return -ENOMEM;
@@ -3207,9 +3820,10 @@ static int __devexit ricoh619_battery_remove(struct platform_device *pdev)
                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;
@@ -3220,7 +3834,8 @@ static int __devexit ricoh619_battery_remove(struct platform_device *pdev)
 
                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");
        }
@@ -3294,10 +3909,11 @@ static int ricoh619_battery_suspend(struct device *dev)
                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;
+       } 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;
@@ -3308,17 +3924,37 @@ static int ricoh619_battery_suspend(struct device *dev)
 
                g_soc = val;
 
-               info->soca->suspend_soc = (info->soca->displayed_soc + 50)/100;
+               info->soca->suspend_soc = info->soca->displayed_soc;
 
-               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");
+       } 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) {
@@ -3385,7 +4021,7 @@ static int ricoh619_battery_resume(struct device *dev)
                        }
 
                        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");
 
@@ -3410,9 +4046,17 @@ static int ricoh619_battery_resume(struct device *dev)
                } else
                        info->soca->displayed_soc = 0;
        } 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");
 
@@ -3431,8 +4075,7 @@ static int ricoh619_battery_resume(struct device *dev)
                }
 
                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;
@@ -3476,7 +4119,7 @@ static int ricoh619_battery_resume(struct device *dev)
                                         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);
index 5502d87f1042a3d64648fc915ea276ba5116143a..900f25ef9eee012a892b421b36dc4e621728856e 100644 (file)
@@ -285,7 +285,7 @@ static unsigned int ricoh619_dcdc_get_mode(struct regulator_dev *rdev)
                return REGULATOR_MODE_NORMAL;
        case 2:
                return REGULATOR_MODE_STANDBY;
-       case 4:
+       case 3:
                return REGULATOR_MODE_NORMAL;
        default:
                return -1;
old mode 100644 (file)
new mode 100755 (executable)
index d26d218..1db0367
@@ -6,7 +6,7 @@
  * Copyright (C) 2012-2013 RICOH COMPANY,LTD
  *
  * Based on code
- *  Copyright (C) 2011 NVIDIA Corporation  
+ *  Copyright (C) 2011 NVIDIA Corporation
  *
  * this program is free software; you can redistribute it and/or modify
  * it under the terms of the gnu general public license as published by
@@ -19,7 +19,7 @@
  * more details.
  *
  * you should have received a copy of the gnu general public license
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.  
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
 #include <linux/slab.h>
 
 struct ricoh619_rtc {
-       unsigned long           epoch_start;
        int                     irq;
        struct rtc_device       *rtc;
-       bool                    irq_en;
+       bool            irq_en;
 };
 
 static int ricoh619_read_regs(struct device *dev, int reg, int len,
@@ -70,21 +69,24 @@ static int ricoh619_write_regs(struct device *dev, int reg, int len,
        return ret;
 }
 
+// 0=OK, -EINVAL= FAIL
 static int ricoh619_rtc_valid_tm(struct device *dev, struct rtc_time *tm)
 {
-       if (tm->tm_year >= (rtc_year_offset + 99)
-               || tm->tm_mon > 12
+       if (tm->tm_year > 199 || tm->tm_year < 70
+               || tm->tm_mon > 11 || tm->tm_mon < 0
                || tm->tm_mday < 1
-               || tm->tm_mday > rtc_month_days(tm->tm_mon,
-                       tm->tm_year + os_ref_year)
-               || tm->tm_hour >= 24
-               || tm->tm_min >= 60
-               || tm->tm_sec >= 60) {
-               dev_err(dev->parent, "\n returning error due to time"
-               "%d/%d/%d %d:%d:%d", tm->tm_mon, tm->tm_mday,
-               tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec);
+               || tm->tm_mday > rtc_month_days(tm->tm_mon, tm->tm_year + os_ref_year)
+               || tm->tm_hour >= 24 || tm->tm_hour <0
+               || tm->tm_min < 0 || tm->tm_min >= 60
+               || tm->tm_sec < 0 || tm->tm_sec >= 60   
+               ) 
+       {
+               dev_err(dev->parent, "PMU: %s *** Returning error due to time, %d/%d/%d %d:%d:%d *****\n",
+                       __func__, tm->tm_mon, tm->tm_mday, tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec);
+
                return -EINVAL;
        }
+       
        return 0;
 }
 
@@ -114,47 +116,199 @@ static void convert_decimal_to_bcd(u8 *buf, u8 len)
 
 static void print_time(struct device *dev, struct rtc_time *tm)
 {
-       dev_info(dev, "rtc-time : %d/%d/%d %d:%d\n",
-               (tm->tm_mon + 1), tm->tm_mday, (tm->tm_year + os_ref_year),
-               tm->tm_hour, tm->tm_min);
+       dev_info(dev, "PMU: %s *** rtc-time : %d/%d/%d %d:%d:%d *****\n",
+               __func__, (tm->tm_mon), tm->tm_mday, (tm->tm_year + os_ref_year), tm->tm_hour, tm->tm_min,tm->tm_sec);
+}
+
+static int ricoh619_rtc_periodic_disable(struct device *dev)
+{
+       int err;
+       uint8_t reg_data;
+
+       // disable function
+       err = ricoh619_read_regs(dev, rtc_ctrl1, 1, &reg_data);
+       if(err < 0)
+       {
+               dev_err(dev->parent, "read rtc_ctrl1 error=0x%x\n", err);
+               return err;
+       }
+       reg_data &= 0xf8;
+       err = ricoh619_write_regs(dev, rtc_ctrl1, 1, &reg_data);
+       if(err < 0)
+       {
+               dev_err(dev->parent, "read rtc_ctrl1 error=0x%x\n", err);
+               return err;
+       }
+
+       // clear alarm flag and CTFG
+       err = ricoh619_read_regs(dev, rtc_ctrl2, 1, &reg_data);
+       if(err < 0)
+       {
+               dev_err(dev->parent, "read rtc_ctrl1 error=0x%x\n", err);
+               return err;
+       }
+       reg_data &= ~0x85;// 1000-0101
+       err = ricoh619_write_regs(dev, rtc_ctrl2, 1, &reg_data);
+       if(err < 0)
+       {
+               dev_err(dev->parent, "read rtc_ctrl1 error=0x%x\n", err);
+               return err;
+       }
+
+       return 0;
+}
+
+static int ricoh619_rtc_clk_adjust(struct device *dev, uint8_t clk)
+{
+       return ricoh619_write_regs(dev, rtc_adjust, 1, &clk);
+}
+
+static int ricoh619_rtc_Pon_get_clr(struct device *dev, uint8_t *Pon_f)
+{
+       int err;
+       uint8_t reg_data;
+       
+       err = ricoh619_read_regs(dev, rtc_ctrl2, 1, &reg_data);
+       if(err < 0)
+       {
+               dev_err(dev->parent, "rtc_ctrl1 read err=0x%x\n", err);
+               return err;
+       }
+//     printk("%s,PON=1 -- CTRL2=0x%x\n", __func__, reg_data);
+       
+       if(reg_data & 0x10)
+       {
+               *Pon_f = 1;
+               //clear VDET PON
+               reg_data &= ~0x5b;// 0101-1011
+               reg_data |= 0x20; // 0010-0000
+               err = ricoh619_write_regs(dev, rtc_ctrl2, 1, &reg_data);
+               if(err < 0)
+               {
+                       dev_err(dev->parent, "rtc_ctrl1 write err=0x%x\n", err);
+               }
+       }
+       else
+       {
+               *Pon_f = 0;
+       }
+       
+
+       return err;
+}
+
+// 0-12hour, 1-24hour
+static int ricoh619_rtc_hour_mode_get(struct device *dev, int *mode)
+{
+       int err;
+
+       err = ricoh619_read_regs(dev, rtc_ctrl1, 1, mode);
+       if(err < 0)
+               dev_err(dev->parent, "read rtc ctrl1 error\n");
+
+       if(*mode & 0x20)
+               *mode = 1;
+       else
+               *mode = 0;
+       
+       return err;
+}
+
+// 0-12hour, 1-24hour
+static int ricoh619_rtc_hour_mode_set(struct device *dev, int mode)
+{
+       uint8_t reg_data;
+       int err;
+
+       err = ricoh619_read_regs(dev, rtc_ctrl1, 1, &reg_data);
+       if(err < 0)
+       {
+               dev_err(dev->parent, "read rtc_ctrl1 error\n");
+               return err;
+       }
+       if(mode == 0)
+               reg_data &= 0xDF;
+       else
+               reg_data |= 0x20;
+       err = ricoh619_write_regs(dev, rtc_ctrl1, 1, &reg_data);
+       if(err < 0)
+       {
+               dev_err(dev->parent, "write rtc_ctrl1 error\n");
+       }
+
+       return err;
 }
 
+
 static int ricoh619_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
        u8 buff[7];
        int err;
+       int cent_flag;
+       int i;
+
+//     printk(KERN_INFO "PMU: %s\n", __func__);
        err = ricoh619_read_regs(dev, rtc_seconds_reg, sizeof(buff), buff);
+               
        if (err < 0) {
-               dev_err(dev, "\n %s :: failed to read time\n", __FILE__);
+               dev_err(dev->parent, "PMU: %s *** failed to read time *****\n", __func__);
                return err;
        }
-       convert_bcd_to_decimal(buff, sizeof(buff));
+       
+       if (buff[5] & 0x80)
+               cent_flag = 1;
+       else
+               cent_flag = 0;
+
+       buff[5] = buff[5]&0x1f; //bit5 19_20
+       convert_bcd_to_decimal(buff, sizeof(buff));     
+               
        tm->tm_sec  = buff[0];
        tm->tm_min  = buff[1];
-       tm->tm_hour = buff[2];
+       tm->tm_hour = buff[2];  //bit5 PA_H20
        tm->tm_wday = buff[3];
        tm->tm_mday = buff[4];
-       tm->tm_mon  = buff[5] - 1;
-       tm->tm_year = buff[6] + rtc_year_offset;
-//     print_time(dev, tm);
-       return ricoh619_rtc_valid_tm(dev, tm);
+       tm->tm_mon  = buff[5];  //for print
+       tm->tm_year = buff[6] + 100 * cent_flag;
+       print_time(dev, tm);    //for print
+       tm->tm_mon  = buff[5] - 1;  //back to system 0-11 
+               
+       return 0;
 }
 
 static int ricoh619_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
        u8 buff[7];
        int err;
+       int cent_flag;
+
+//     printk(KERN_INFO "PMU: %s\n", __func__);        
+
+       if(ricoh619_rtc_valid_tm(dev, tm) != 0)
+       {
+               return -EINVAL;
+       }
+
+       if (tm->tm_year >= 100)
+               cent_flag = 1;
+       else
+               cent_flag = 0;
 
-//     print_time(dev, tm);
+       tm->tm_mon = tm->tm_mon + 1;
        buff[0] = tm->tm_sec;
        buff[1] = tm->tm_min;
        buff[2] = tm->tm_hour;
        buff[3] = tm->tm_wday;
        buff[4] = tm->tm_mday;
-       buff[5] = tm->tm_mon + 1;
-       buff[6] = tm->tm_year - rtc_year_offset;
+       buff[5] = tm->tm_mon; //system set 0-11
+       buff[6] = tm->tm_year - 100 * cent_flag;
+       print_time(dev, tm);    // RTC_TEST
 
        convert_decimal_to_bcd(buff, sizeof(buff));
+       
+       if (1 == cent_flag)
+               buff[5] |= 0x80;
+
        err = ricoh619_write_regs(dev, rtc_seconds_reg, sizeof(buff), buff);
        if (err < 0) {
                dev_err(dev->parent, "\n failed to program new time\n");
@@ -163,118 +317,221 @@ static int ricoh619_rtc_set_time(struct device *dev, struct rtc_time *tm)
 
        return 0;
 }
-static int ricoh619_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm);
 
-static int ricoh619_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+static int ricoh619_rtc_alarm_is_enabled(struct device *dev,  uint8_t *enabled)
 {
        struct ricoh619_rtc *rtc = dev_get_drvdata(dev);
-       unsigned long seconds;
-       u8 buff[6];
        int err;
-       struct rtc_time tm;
-
-       if (rtc->irq == -1)
-               return -EIO;
-
-       rtc_tm_to_time(&alrm->time, &seconds);
-       err = ricoh619_rtc_read_time(dev, &tm);
-       if (err) {
-               dev_err(dev, "\n failed to read time\n");
-               return err;
+       uint8_t reg_data;
+
+       err = 0;
+       err = ricoh619_read_regs(dev, rtc_ctrl1, 1,&reg_data);
+       if(err)
+       {
+               dev_err(dev->parent, "read rtc_ctrl1 error 0x%lx\n", err);
+               *enabled = 0;
        }
-       rtc_tm_to_time(&tm, &rtc->epoch_start);
-
-       dev_info(dev->parent, "\n setting alarm to requested time::\n");
-//     print_time(dev->parent, &alrm->time);
-
-       if (WARN_ON(alrm->enabled && (seconds < rtc->epoch_start))) {
-               dev_err(dev->parent, "\n can't set alarm to requested time\n");
-               return -EINVAL;
+       else
+       {
+               if(reg_data & 0x40)
+                       *enabled = 1;
+               else
+                       *enabled = 0;
        }
+       return err;
+}
 
-       if (alrm->enabled && !rtc->irq_en)
-               rtc->irq_en = true;
-       else if (!alrm->enabled && rtc->irq_en)
-               rtc->irq_en = false;
-
-       buff[0] = alrm->time.tm_sec;
-       buff[1] = alrm->time.tm_min;
-       buff[2] = alrm->time.tm_hour;
-       buff[3] = alrm->time.tm_mday;
-       buff[4] = alrm->time.tm_mon + 1;
-       buff[5] = alrm->time.tm_year - rtc_year_offset;
-       convert_decimal_to_bcd(buff, sizeof(buff));
-       buff[3] |= 0x80;        /* set DAL_EXT */
-       err = ricoh619_write_regs(dev, rtc_alarm_y_sec, sizeof(buff), buff);
-       if (err) {
-               dev_err(dev->parent, "\n unable to set alarm\n");
-               return -EBUSY;
+// 0-disable, 1-enable
+static int ricoh619_rtc_alarm_enable(struct device *dev, unsigned int enabled)
+{
+       struct ricoh619_rtc *rtc = dev_get_drvdata(dev);
+       int err;
+       uint8_t reg_data;
+
+//     printk(KERN_INFO "PMU: %s :%d\n", __func__,enabled);    
+       
+       err = 0;
+       if(enabled)
+       {
+               rtc->irq_en = 1;
+               err = ricoh619_read_regs(dev, rtc_ctrl1, 1,&reg_data);
+               if(err < 0)
+               {
+                       dev_err(dev->parent, "read rtc_ctrl1 error 0x%lx\n", err);
+                       goto ERR;
+               }
+               reg_data |= 0x40;// set DALE
+               err = ricoh619_write_regs(dev, rtc_ctrl1, 1,&reg_data);
+               if(dev < 0)
+                       dev_err(dev->parent, "write rtc_ctrl1 error 0x%lx\n", err);
        }
-
-       err = ricoh619_read_regs(dev, rtc_ctrl2, 1, buff);
-       if (err) {
-               dev_err(dev->parent, "unable to read rtc_ctrl2 reg\n");
-               return -EBUSY;
+       else
+       {
+               rtc->irq_en = 0;
+               err = ricoh619_read_regs(dev, rtc_ctrl1, 1,&reg_data);
+               if(err < 0)
+               {
+                       dev_err(dev->parent, "read rtc_ctrl1 error 0x%lx\n", err);
+                       goto ERR;
+               }
+               reg_data &= 0xbf;// clear DALE
+               err = ricoh619_write_regs(dev, rtc_ctrl1, 1,&reg_data);
+               if(dev < 0)
+                       dev_err(dev->parent, "write rtc_ctrl1 error 0x%lx\n", err);
        }
 
-       buff[1] = buff[0] & ~0x81; /* to clear alarm-D flag, and set adjustment parameter */
-       buff[0] = 0x60; /* to enable alarm_d and 24-hour format */
-       err = ricoh619_write_regs(dev, rtc_ctrl1, 2, buff);
-       if (err) {
-               dev_err(dev, "failed programming rtc ctrl regs\n");
-               return -EBUSY;
-       }
-return err;
+ERR:
+       return err;
 }
 
 static int ricoh619_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
        u8 buff[6];
+       u8 buff_cent;
        int err;
+       int cent_flag;
+       unsigned char enabled_flag;
+
+//     printk(KERN_INFO "PMU: %s\n", __func__);
+
+       err = 0;
+
+       alrm->time.tm_sec  = 0;
+       alrm->time.tm_min  = 0;
+       alrm->time.tm_hour = 0;
+       alrm->time.tm_mday = 0;
+       alrm->time.tm_mon  = 0;
+       alrm->time.tm_year = 0;
+       alrm->enabled = 0;
+
+       err = ricoh619_read_regs(dev, rtc_month_reg, 1, &buff_cent);
+       if (err < 0) {
+               dev_err(dev->parent, "PMU: %s *** failed to read time *****\n", __func__);
+               return err;
+       }
+       if (buff_cent & 0x80)
+               cent_flag = 1;
+       else
+               cent_flag = 0;
 
        err = ricoh619_read_regs(dev, rtc_alarm_y_sec, sizeof(buff), buff);
-       if (err)
+       if(err)
+       {
+               dev_err(dev->parent, "RTC: %s *** read rtc_alarm timer error 0x%lx\n", __func__, err);
+               return err;
+       }
+       
+       err = ricoh619_read_regs(dev, rtc_ctrl1, 1,&enabled_flag);
+       if(err)
+       {
+               dev_err(dev->parent, "RTC: %s *** read rtc_enable flag error 0x%lx\n", __func__, err);
                return err;
+       }
+       if(enabled_flag & 0x40)
+               enabled_flag = 1;
+       else
+               enabled_flag = 0;
+       
        buff[3] &= ~0x80;       /* clear DAL_EXT */
-       convert_bcd_to_decimal(buff, sizeof(buff));
 
+       buff[3] = buff[3]&0x3f;
+       convert_bcd_to_decimal(buff, sizeof(buff));
+       
        alrm->time.tm_sec  = buff[0];
        alrm->time.tm_min  = buff[1];
        alrm->time.tm_hour = buff[2];
        alrm->time.tm_mday = buff[3];
+       alrm->time.tm_mon = buff[4];// for print
+       alrm->time.tm_year = buff[5] + 100 * cent_flag;
+       dev_info(dev, "PMU: read alarm: %d/%d/%d %d:%d:%d *****\n",
+               (alrm->time.tm_mon), alrm->time.tm_mday, (alrm->time.tm_year + os_ref_year), alrm->time.tm_hour, alrm->time.tm_min,alrm->time.tm_sec);
        alrm->time.tm_mon  = buff[4] - 1;
-       alrm->time.tm_year = buff[5] + rtc_year_offset;
-
-//     dev_info(dev->parent, "\n getting alarm time::\n");
-//     print_time(dev, &alrm->time);
+       alrm->enabled = enabled_flag;
 
        return 0;
 }
 
+static int ricoh619_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+       struct ricoh619_rtc *rtc = dev_get_drvdata(dev);
+       u8 buff[6];
+       int err;
+       int cent_flag;
+
+//     printk(KERN_INFO "PMU: %s\n", __func__);
+       err = 0;
+       ricoh619_rtc_alarm_enable(dev, 0);
+       if (rtc->irq == -1)
+       {
+               err = -EIO;
+               goto ERR;
+       }
+       
+       if(alrm->enabled== 0)
+               return 0;
+       
+       if (alrm->time.tm_year >= 100)
+               cent_flag = 1;
+       else
+               cent_flag = 0;
+
+       alrm->time.tm_mon += 1;
+       print_time(dev->parent, &alrm->time);
+       buff[0] = alrm->time.tm_sec;
+       buff[1] = alrm->time.tm_min;
+       buff[2] = alrm->time.tm_hour;
+       buff[3] = alrm->time.tm_mday;
+       buff[4] = alrm->time.tm_mon;
+//     buff[5] = alrm->time.tm_year - rtc_year_offset;
+       buff[5] = alrm->time.tm_year - 100 * cent_flag;
+       convert_decimal_to_bcd(buff, sizeof(buff));
+       buff[3] |= 0x80;        /* set DAL_EXT */
+       err = ricoh619_write_regs(dev, rtc_alarm_y_sec, sizeof(buff), buff);
+       if (err) {
+               dev_err(dev->parent, "\n unable to set alarm\n");
+               err = -EBUSY;
+               goto ERR;
+       }
+
+       ricoh619_rtc_alarm_enable(dev, alrm->enabled);
+       
+ERR:
+       return err;
+}
+
 static const struct rtc_class_ops ricoh619_rtc_ops = {
        .read_time      = ricoh619_rtc_read_time,
        .set_time       = ricoh619_rtc_set_time,
        .set_alarm      = ricoh619_rtc_set_alarm,
        .read_alarm     = ricoh619_rtc_read_alarm,
+       .alarm_irq_enable = ricoh619_rtc_alarm_enable,
 };
 
-static irqreturn_t ricoh619_rtc_irq(int irq, void *data)
+static int ricoh619_rtc_alarm_flag_clr(struct device *dev)
 {
-       struct device *dev = data;
-       struct ricoh619_rtc *rtc = dev_get_drvdata(dev);
-       u8 reg;
        int err;
+       uint8_t reg_data;
 
        /* clear alarm-D status bits.*/
-       err = ricoh619_read_regs(dev, rtc_ctrl2, 1, &reg);
+       err = ricoh619_read_regs(dev, rtc_ctrl2, 1, &reg_data);
        if (err)
                dev_err(dev->parent, "unable to read rtc_ctrl2 reg\n");
 
        /* to clear alarm-D flag, and set adjustment parameter */
-       reg &= ~0x81;
-       err = ricoh619_write_regs(dev, rtc_ctrl2, 1, &reg);
+       reg_data &= ~0x81;
+       err = ricoh619_write_regs(dev, rtc_ctrl2, 1, &reg_data);
        if (err)
                dev_err(dev->parent, "unable to program rtc_status reg\n");
+       return err;
+}
+static irqreturn_t ricoh619_rtc_irq(int irq, void *data)
+{
+       struct device *dev = data;
+       struct ricoh619_rtc *rtc = dev_get_drvdata(dev);
+
+//     printk(KERN_INFO "PMU: %s\n", __func__);
+
+       ricoh619_rtc_alarm_flag_clr(dev);
 
        rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF);
        return IRQ_HANDLED;
@@ -285,103 +542,224 @@ static int __devinit ricoh619_rtc_probe(struct platform_device *pdev)
        struct ricoh619_rtc_platform_data *pdata = pdev->dev.platform_data;
        struct ricoh619_rtc *rtc;
        struct rtc_time tm;
+       uint8_t Pon_flag,Alarm_flag;
        int err;
-       u8 reg;
-       rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
-//     printk("%s,line=%d\n", __func__,__LINE__);      
-
-       if (!rtc)
-               return -ENOMEM;
+       uint8_t buff[6];
 
-       rtc->irq = -1;
+//     printk(KERN_INFO "******PMU RTC: Version 2013-08-01 REDS!******\n");
+//     printk(KERN_INFO "PMU RTC: %s, ricoh619 driver run at 24H-mode\n", __func__);
+//     printk(KERN_INFO "PMU RTC: we never using periodic function and interrupt\n");
 
-       if (!pdata) {
+       if(!pdata) 
+       {
                dev_err(&pdev->dev, "no platform_data specified\n");
                return -EINVAL;
        }
 
-       if (pdata->irq < 0)
+       rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
+       if(IS_ERR(rtc))
+       {
+               err = PTR_ERR(rtc);
+               dev_err(&pdev->dev, "no enough memory for ricoh619_rtc using\n");
+               return err;
+       }
+       
+       dev_set_drvdata(&pdev->dev, rtc);
+       if(IS_ERR(rtc->rtc)) 
+       {
+               err = PTR_ERR(rtc->rtc);
+               goto fail;
+       }
+
+       if(pdata->irq < 0)
+       {
                dev_err(&pdev->dev, "\n no irq specified, wakeup is disabled\n");
+               rtc->irq = -1;
+               rtc->irq_en = 0;
+       }
+       else
+       {
+               rtc->irq = pdata->irq;
+               rtc->irq_en = 1;
+       }
 
-       dev_set_drvdata(&pdev->dev, rtc);
-       device_init_wakeup(&pdev->dev, 1);
-       rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
-                                      &ricoh619_rtc_ops, THIS_MODULE);
+       //get interrupt flag
+       err = ricoh619_rtc_alarm_is_enabled(&pdev->dev, &Alarm_flag);
+       if(err)
+       {
+               dev_err(&pdev->dev, "5T619 RTC: Disable alarm interrupt error\n");
+               goto fail;
 
-       if (IS_ERR(rtc->rtc)) {
-               err = PTR_ERR(rtc->rtc);
+       }
+
+       // get PON flag
+       err = ricoh619_rtc_Pon_get_clr(&pdev->dev, &Pon_flag);
+       if(err)
+       {
+               dev_err(&pdev->dev, "5T619 RTC: get PON flag error\n");
                goto fail;
        }
 
-       reg = 0x60; /* to enable alarm_d and 24-hour format */
-       err = ricoh619_write_regs(&pdev->dev, rtc_ctrl1, 1, &reg);
-       if (err) {
-               dev_err(&pdev->dev, "failed rtc setup\n");
-               return -EBUSY;
+       // disable rtc periodic function
+       err = ricoh619_rtc_periodic_disable(&pdev->dev);
+       if(err)
+       {
+               dev_err(&pdev->dev, "5T619 RTC: disable rtc periodic int error\n");
+               goto fail;
        }
 
-       reg =  0; /* clearing RTC Adjust register */
-       err = ricoh619_write_regs(&pdev->dev, rtc_adjust, 1, &reg);
-       if (err) {
+       // clearing RTC Adjust register
+       err = ricoh619_rtc_clk_adjust(&pdev->dev, 0);
+       if(err) 
+       {
                dev_err(&pdev->dev, "unable to program rtc_adjust reg\n");
-               return -EBUSY;
+               err = -EBUSY;
+               goto fail;
+       }
+
+       //disable interrupt
+       err = ricoh619_rtc_alarm_enable(&pdev->dev, 0);
+       if(err)
+       {
+               dev_err(&pdev->dev, "5T619 RTC: Disable alarm interrupt error\n");
+               goto fail;
        }
-       /* Set default time-1970.1.1-0h:0m:0s if PON is on */
-       err = ricoh619_read_regs(&pdev->dev, rtc_ctrl2, 1, &reg);
-       if (err) {
-               dev_err(&pdev->dev, "\n failed to read rtc ctl2 reg\n");
-               return -EBUSY;
-       }
-       if (reg&0x10) {
-               printk("%s,PON=1 -- CTRL2=%x\n", __func__, reg);
-               tm.tm_sec  = 0;
-               tm.tm_min  = 0;
-               tm.tm_hour = 0;
-               tm.tm_wday = 4;
-               tm.tm_mday = 1;
-               tm.tm_mon  = 0;
-               tm.tm_year = 0x70;
-               /* VDET & PON = 0, others are not changed */
-               reg &= ~0x50;
-               err = ricoh619_write_regs(&pdev->dev, rtc_ctrl2, 1, &reg);
-               if (err) {
-                       dev_err(&pdev->dev, "\n failed to write rtc ctl2 reg\n");
-                       return -EBUSY;
-               }
                
-       } else {
-               err = ricoh619_rtc_read_time(&pdev->dev, &tm);
-               if (err) {
-                       dev_err(&pdev->dev, "\n failed to read time\n");
-                       return err;
+       // PON=1
+       if(Pon_flag) 
+       {
+               Alarm_flag = 0;
+               // clear int flag
+               err = ricoh619_rtc_alarm_flag_clr(&pdev->dev);
+               if(err)
+               {
+                       dev_err(&pdev->dev, "5T619 RTC: Pon=1 clear alarm flag error\n");
+                       goto fail;
                }
-       }
-       if (ricoh619_rtc_valid_tm(&pdev->dev, &tm)) {
-               if (pdata->time.tm_year < 2000 || pdata->time.tm_year > 2100) {
-                       memset(&pdata->time, 0, sizeof(pdata->time));
-                       pdata->time.tm_year = rtc_year_offset;
-                       pdata->time.tm_mday = 1;
-               } else
+
+               // using 24h-mode
+               err = ricoh619_rtc_hour_mode_set(&pdev->dev,1);
+               if(err)
+               {
+                       dev_err(&pdev->dev, "5T619 RTC: Pon=1 set 24h-mode error\n");
+                       goto fail;
+               }
+               
+               // setting the default year
+//             printk(KERN_INFO "PMU: %s Set default time\n", __func__);
+               
+               pdata->time.tm_sec=0;
+               pdata->time.tm_min=0;
+               pdata->time.tm_hour=0;
+               pdata->time.tm_wday=6;
+               pdata->time.tm_mday=1;
+               pdata->time.tm_mon=1;
+               pdata->time.tm_year=2012;
                pdata->time.tm_year -= os_ref_year;
-               err = ricoh619_rtc_set_time(&pdev->dev, &pdata->time);
-               if (err) {
-                       dev_err(&pdev->dev, "\n failed to set time\n");
-                       return err;
+               if(ricoh619_rtc_valid_tm(&pdev->dev, &(pdata->time)) == 0)
+               {
+                       tm.tm_sec   = pdata->time.tm_sec;
+                       tm.tm_min  = pdata->time.tm_min;
+                       tm.tm_hour = pdata->time.tm_hour;
+                       tm.tm_wday= pdata->time.tm_wday;
+                       tm.tm_mday= pdata->time.tm_mday;
+                       tm.tm_mon  = pdata->time.tm_mon-1;
+                       tm.tm_year = pdata->time.tm_year;
+               }
+               else
+               {
+                       // using the ricoh default time instead of board default time
+                       dev_err(&pdev->dev, "board rtc default is erro\n");
+                       tm.tm_sec  = 0;
+                       tm.tm_min  = 0;
+                       tm.tm_hour = 0;
+                       tm.tm_wday = 4;
+                       tm.tm_mday = 1;
+                       tm.tm_mon  = 0;
+                       tm.tm_year = 70;
+               }
+
+               // set default alarm time 
+               if (tm.tm_year >= 100)
+                       buff[5] = tm.tm_year-100-1;
+               else
+                       buff[5] = tm.tm_year-1;
+               buff[0] = tm.tm_sec;
+               buff[1] = tm.tm_min;
+               buff[2] = tm.tm_hour;
+               buff[3] = tm.tm_mday;
+               buff[4] = tm.tm_mon +1;
+               
+               err = ricoh619_rtc_set_time(&pdev->dev, &tm);
+               if(err) 
+               {
+                       dev_err(&pdev->dev, "5t619 RTC:\n failed to set time\n");
+                       goto fail;
                }
+
+               convert_decimal_to_bcd(buff, sizeof(buff));
+               buff[3] |= 0x80;        /* set DAL_EXT */
+
+               err = ricoh619_write_regs(&pdev->dev, rtc_alarm_y_sec, sizeof(buff), buff);
+               if (err) 
+                       printk( "\n unable to set alarm\n");
+
        }
-       if (pdata && (pdata->irq >= 0)) {
-               rtc->irq = pdata->irq + RICOH619_IRQ_DALE;
+
+       device_init_wakeup(&pdev->dev, 1);
+       
+//     printk(KERN_INFO "PMU: %s register rtc device \n", __func__);
+       rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
+                                      &ricoh619_rtc_ops, THIS_MODULE);
+
+       // set interrupt and enable it
+       if(rtc->irq != -1) 
+       {
+               rtc->irq = rtc->irq + RICOH619_IRQ_DALE;
                err = request_threaded_irq(rtc->irq, NULL, ricoh619_rtc_irq,
-                                       IRQF_ONESHOT, "rtc_ricoh619",
-                                       &pdev->dev);
-               if (err) {
+                                       IRQF_ONESHOT, "rtc_ricoh619", &pdev->dev);
+               if(err) 
+               {
                        dev_err(&pdev->dev, "request IRQ:%d fail\n", rtc->irq);
                        rtc->irq = -1;
-               } else {
-                       device_init_wakeup(&pdev->dev, 1);
+                       err = ricoh619_rtc_alarm_enable(&pdev->dev, 0);
+                       if(err)
+                       {
+                               dev_err(&pdev->dev, "5T619 RTC: enable rtc alarm error\n");
+                               goto fail;
+                       }
+               }
+               else
+               {
+                       // enable wake  
                        enable_irq_wake(rtc->irq);
+                       // enable alarm_d
+                       err = ricoh619_rtc_alarm_enable(&pdev->dev, Alarm_flag);
+                       if(err) 
+                       {
+                               dev_err(&pdev->dev, "failed rtc setup\n");
+                               err = -EBUSY;
+                               goto fail;
+                       }
                }
        }
+       else
+       {
+               // system don't want to using alarm interrupt, so close it
+               err = ricoh619_rtc_alarm_enable(&pdev->dev, 0);
+               if(err)
+               {
+                       dev_err(&pdev->dev, "5T619 RTC: Disable rtc alarm error\n");
+                       goto fail;
+               }
+               dev_err(&pdev->dev, "ricoh619 interrupt is disabled\n");
+       }
+
+       printk(KERN_INFO "RICOH619 RTC Register Success\n");
+       
+       ricoh619_read_regs(&pdev->dev, rtc_ctrl1, 1,&buff[0]);
+       ricoh619_read_regs(&pdev->dev, rtc_ctrl2, 1,&buff[1]);
+//     printk(KERN_INFO "0xAE:%x 0xAF:%x\n",buff[0],buff[1]);
        return 0;
 
 fail:
old mode 100755 (executable)
new mode 100644 (file)
index d052edd..32738df
@@ -35,6 +35,8 @@
 #define        ADC_VDD_MV      2800
 #define        MIN_VOLTAGE     3100
 #define        MAX_VOLTAGE     4200
+#define        B_VALUE         3435
+
 
 /* 619 Register information */
 /* bank 0 */
@@ -54,6 +56,7 @@
 #define        REGISET1_REG    0xB6
 #define        REGISET2_REG    0xB7
 #define        CHGISET_REG             0xB8
+#define        TIMSET_REG              0xB9
 #define        BATSET1_REG             0xBA
 #define        BATSET2_REG             0xBB
 
@@ -85,6 +88,8 @@
 /* bank 1 */
 /* Top address for battery initial setting */
 #define        BAT_INIT_TOP_REG        0xBC
+#define        TEMP_GAIN_H_REG 0xD6
+#define        TEMP_OFF_H_REG  0xB8
 #define        BAT_REL_SEL_REG         0xDA
 #define        BAT_TA_SEL_REG          0xDB
 /**************************/
index 317e7ef9364b67cda774985a239e439f579d3bb6..36c20f48d81844811406a7a93fa29974708394b9 100755 (executable)
@@ -1,12 +1,12 @@
 /*
  * include/linux/rtc/rtc-ricoh619.h
  *
- * Real time clock driver for RICOH RC5T619 power management chip.
+ * Real time clock driver for RICOH R5T619 power management chip.
  *
  * Copyright (C) 2012-2013 RICOH COMPANY,LTD
  *
  * Based on code
- *  Copyright (C) 2011 NVIDIA Corporation  
+ *  Copyright (C) 2011 NVIDIA Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
  * more details.
  *
  * you should have received a copy of the gnu general public license
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.  
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
 #ifndef __LINUX_RTC_RICOH619_H_
@@ -32,6 +32,9 @@
 #define rtc_seconds_reg                0xA0
 #define rtc_alarm_y_sec                0xA8
 #define rtc_adjust             0xA7
+#define rtc_month_reg          0xA5
+#define rtc_mday_reg           0xA4
+#define rtc_dal_month_reg      0xAC
 
 
 /*
@@ -44,7 +47,6 @@ linux rtc driver refers 1900 as base year in many calculations.
        pmu rtc have only 2 nibbles to store year information, so using an
        offset of 100 to set the base year as 2000 for our driver.
 */
-#define rtc_year_offset 100