.bitfield = {
.CHGBC_EN = 1,
.TE = 1,
- .CCCHG_TIMEOUT = RT5025_CCCHG_TO_6H,
- .PRECHG_TIMEOUT = RT5025_PRECHG_TO_30M,
+ .CCCHG_TIMEOUT = RT5025_CCCHG_TO_10H,
+ .PRECHG_TIMEOUT = RT5025_PRECHG_TO_60M,
},
},
.CHGControl3 = {
.CHGControl4 = {
.bitfield = {
.AICR_CON = 1,
- .AICR = RT5025_AICR_500MA,
- .ICC = RT5025_ICC_0P5A,
+ .AICR = RT5025_AICR_1A,
+ .ICC = RT5025_ICC_1A,
},
},
.CHGControl5 = {
},
.CHGControl6 = {
.bitfield = {
- .IPREC = RT5025_IPREC_10P,
+ .IPREC = RT5025_IPREC_20P,
.IEOC = RT5025_IEOC_10P,
.VPREC = RT5025_VPREC_3V,
},
},
.VSYSCtrl = {
.bitfield = {
- .VOFF = RT5025_VOFF_3P4V,
+ .VOFF = RT5025_VOFF_3P0V,
},
},
.PwrOnCfg = {
.DCDC3LV_ENSHDN = 0,
.DCDC2LV_ENSHDN = 0,
.DCDC1LV_ENSHDN = 0,
- .SYSLV_ENSHDN = 0,
+ .SYSLV_ENSHDN = 1,
},
},
};
static struct rt5025_irq_data rt5025_irq_data = {
.irq_enable1 = {
.bitfield = {
- .BATABS = 1,
+ .BATABS = 0,
.INUSB_PLUGIN = 1,
.INUSBOVP = 1,
.INAC_PLUGIN = 1,
.CHTERMI = 1,
.CHBATOVI = 1,
.CHGOODI_INUSB = 0,
- .CHBADI_INUSB = 1,
+ .CHBADI_INUSB = 0,
.CHSLPI_INUSB = 1,
.CHGOODI_INAC = 0,
- .CHBADI_INAC = 1,
+ .CHBADI_INAC = 0,
.CHSLPI_INAC = 1,
},
},
.irq_enable3 = {
.bitfield = {
- .TIMEOUT_CC = 1,
- .TIMEOUT_PC = 1,
+ .TIMEOUT_CC = 0,
+ .TIMEOUT_PC = 0,
.CHVSREGI = 0,
.CHTREGI = 0,
.CHRCHGI = 1,
},
.irq_enable4 = {
.bitfield = {
- .SYSLV = 1,
- .DCDC4LVHV = 1,
+ .SYSLV = 0,
+ .DCDC4LVHV = 0,
.PWRONLP = 0,
.PWRONSP = 0,
- .DCDC3LV = 1,
- .DCDC2LV = 1,
- .DCDC1LV = 1,
+ .DCDC3LV = 0,
+ .DCDC2LV = 0,
+ .DCDC1LV = 0,
.OT = 1,
},
},
//temp unit: 'c*10 degree
static int jeita_temp[4] = { 0, 150, 500, 600};
-static u8 jeita_scalar[4] = { 0x2d, 0x25, 0x12, 0x0e};
+ //-5', 5', 15', 20', 45' 55' 55', 65'
+static u8 jeita_scalar[8] = { 0x30, 0x2B, 0x25, 0x20, 0x15, 0x10, 0x10, 0x0D };
//cc unit: xxx mA
static int jeita_temp_cc[][5] = {{ 500, 500, 500, 500, 500}, // not plugin
- { 0 , 250, 500, 250, 0}, // normal USB
+ { 0 , 500, 500, 500, 0}, // normal USB
{ 0, 500, 1000, 500, 0}, // USB charger
{ 0, 500, 1000, 500, 0}}; // AC Adapter
//cv unit: xxx mV
static void rt5025_charger_event_callback(uint32_t detected)
{
- RTINFO("event detected = 0x%08x\n", detected);
+ RTINFO("charger event detected = 0x%08x\n", detected);
if (detected & CHG_EVENT_CHTERMI)
{
pr_info("charger termination OK\n");
static void rt5025_power_event_callback(uint32_t detected)
{
- RTINFO("event detected = 0x%08x\n", detected);
- if (detected & PWR_EVENT_SYSLV)
- {
- pr_info("sys voltage low\n");
- }
+ RTINFO("power event detected = 0x%08x\n", detected);
}
static struct rt5025_event_callback rt5025_event_callback = {
.max_uv = 3300000,
},
+ {
+ .name = "rt5025-dcdc4", //vccio
+ .min_uv = 5000000,
+ .max_uv = 5000000,
+ },
+
};
static struct pmu_info rt5025_ldo_info[] = {
{
MODULE_AUTHOR("CY Huang <cy_huang@richtek.com");
MODULE_DESCRIPTION("GPIO driver for RT5025");
MODULE_ALIAS("platform:" RT5025_DEVICE_NAME "-gpio");
+MODULE_VERSION(RT5025_DRV_VER);
static struct dentry *debugfs_peek;
static struct dentry *debugfs_poke;
static struct dentry *debugfs_regs;
+static struct dentry *debugfs_reset_b;
static unsigned char read_data[10];
}
else
rc = -EINVAL;
+ } else if (!strcmp(access_str, "reset_b")) {
+ /* read */
+ rc = get_parameters(lbuf, param, 1);
+ if (param[0] == 1 && rc == 0)
+ {
+ memset(lbuf, 0, 15);
+ rt5025_reg_block_write(client, 0x21, 15, lbuf);
+ }
}
if (rc == 0)
debugfs_regs = debugfs_create_file("regs",
S_IFREG | S_IRUGO, debugfs_rt_dent,
(void *) "regs", ®_debug_ops);
+
+ debugfs_reset_b = debugfs_create_file("reset_b",
+ S_IFREG | S_IRUGO, debugfs_rt_dent,
+ (void *) "reset_b", ®_debug_ops);
}
platform_set_drvdata(pdev, di);
MODULE_AUTHOR("CY Huang <cy_huang@richtek.com");
MODULE_DESCRIPTION("Debug driver for RT5025");
MODULE_ALIAS("platform:" RT5025_DEVICE_NAME "-debug");
+MODULE_VERSION(RT5025_DRV_VER);
{
struct rt5025_chip *chip = i2c_get_clientdata(client);
chip->suspend = 1;
+ RTINFO("\n");
return 0;
}
{
struct rt5025_chip *chip = i2c_get_clientdata(client);
chip->suspend = 0;
+ RTINFO("\n");
return 0;
}
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("I2C Driver for Richtek RT5025");
MODULE_AUTHOR("CY Huang <cy_huang@richtek.com>");
+MODULE_VERSION(RT5025_DRV_VER);
{
return platform_driver_register(&rt5025_irq_driver);
}
-subsys_initcall_sync(rt5025_irq_init);
+module_init(rt5025_irq_init);
static void __exit rt5025_irq_exit(void)
{
MODULE_AUTHOR("CY Huang <cy_huang@richtek.com");
MODULE_DESCRIPTION("IRQ driver for RT5025");
MODULE_ALIAS("platform:" RT5025_DEVICE_NAME "-irq");
+MODULE_VERSION(RT5025_DRV_VER);
static struct i2c_client *g_shdn;
void rt5025_power_off(void)
{
+ rt5025_reg_write(g_shdn, RT5025_CHENH_REG, 0x00);
+ rt5025_reg_write(g_shdn, RT5025_CHENL_REG, 0x80);
rt5025_set_bits(g_shdn, RT5025_SHDNCTRL_REG, RT5025_SHDNCTRL_MASK);
}
EXPORT_SYMBOL(rt5025_power_off);
{
return platform_driver_register(&rt5025_misc_driver);
}
-subsys_initcall_sync(rt5025_misc_init);
+module_init(rt5025_misc_init);
static void __exit rt5025_misc_exit(void)
{
MODULE_AUTHOR("CY Huang <cy_huang@richtek.com");
MODULE_DESCRIPTION("Misc driver for RT5025");
MODULE_ALIAS("platform:" RT5025_DEVICE_NAME "-misc");
+MODULE_VERSION(RT5025_DRV_VER);
#include <linux/mfd/rt5025.h>
#include <linux/power/rt5025-battery.h>
-#define VOLTAGE_ALERT 1
+#define VOLTAGE_ALERT 0
#define TEMPERATURE_ALERT 0
#define RT5025_CSV 0
#define RT5025_B 1
-#define RT5025_TEST_WAKE_LOCK 1
+#define RT5025_TEST_WAKE_LOCK 0
u8 irq_thres[LAST_TYPE];
+static int rt5025_battery_parameter_backup(struct rt5025_battery_info *);
+
void rt5025_gauge_set_status(struct rt5025_battery_info *bi, int status)
{
bi->status = status;
if (status == POWER_SUPPLY_STATUS_FULL)
+ {
bi->tp_flag = true;
+ bi->last_tp_flag = true;
+ }
+ else
+ power_supply_changed(&bi->battery);
+ wake_lock_timeout(&bi->status_wake_lock, 1.5*HZ);
+ schedule_delayed_work(&bi->monitor_work, 0);
}
EXPORT_SYMBOL(rt5025_gauge_set_status);
{
struct rt5025_battery_info *bi = (struct rt5025_battery_info *)container_of(alarm, struct rt5025_battery_info, wakeup_alarm);
- wake_lock(&bi->monitor_wake_lock);
+ //wake_lock(&bi->monitor_wake_lock);
schedule_delayed_work(&bi->monitor_work, 0);
}
static void rt5025_program_alarm(struct rt5025_battery_info *bi)
{
ktime_t low_interval = ktime_set(bi->update_time, 0);
- ktime_t slack = ktime_set(20, 0);
+ //ktime_t slack = ktime_set(20, 0);
ktime_t next;
next = ktime_add(bi->last_poll, low_interval);
- alarm_start_range(&bi->wakeup_alarm, next, ktime_add(next, slack));
+ //alarm_start_range(&bi->wakeup_alarm, next, ktime_add(next, slack));
}
#if 0
{
u8 data[2];
+ if (bi->init_once)
+ {
+ rt5025_clr_bits(bi->client, 0x07, 0x10);
+ RTINFO("set_current switch off\n");
+ mdelay(1000);
+ }
+
if (rt5025_read_reg(bi->client, RT5025_REG_VCELL_MSB, data, 2) < 0){
printk(KERN_ERR "%s: Failed to read Voltage\n", __func__);
}
+ if (bi->init_once)
+ {
+ rt5025_set_bits(bi->client, 0x07, 0x10);
+ RTINFO("set_current switch on\n");
+ }
+
if (bi->avg_flag)
bi->vcell = ((data[0] << 8) + data[1]) * 61 / 100;
else
u8 data[2];
s32 temp;
int sign = 0;
+ u8 curr_region;
if (rt5025_read_reg(bi->client, RT5025_REG_CURRENT_MSB, data, 2) < 0) {
printk(KERN_ERR "%s: Failed to read CURRENT\n", __func__);
else
bi->curr = (bi->curr + temp) / 2;
+ if (bi->curr > -500)
+ curr_region = 0;
+ else if (bi->curr <= -500 && bi->curr > -1500)
+ curr_region = 1;
+ else
+ curr_region = 2;
+
+ if (curr_region != bi->edv_region)
+ {
+ switch (curr_region)
+ {
+ case 0:
+ bi->empty_edv = rt5025_battery_param2[4].x;
+ break;
+ case 1:
+ bi->empty_edv = rt5025_battery_param2[4].x - 75;
+ break;
+ case 2:
+ bi->empty_edv = rt5025_battery_param2[4].x - 100 ;
+ break;
+ }
+ bi->edv_region = curr_region;
+ }
+ RTINFO("empty_voltage=%d\n", bi->empty_edv);
+
if(bi->curr > 0)
+ {
bi->internal_status = POWER_SUPPLY_STATUS_CHARGING;
+ bi->last_tp_flag = false;
+ }
else
bi->internal_status = POWER_SUPPLY_STATUS_DISCHARGING;
RTINFO("current=%d, internal_status=%d\n", bi->curr, bi->internal_status);
#endif
}
+static void rt5025_get_internal_temp(struct rt5025_battery_info *bi)
+{
+ u8 data[2];
+ s32 temp;
+ if (rt5025_read_reg(bi->client, RT5025_REG_INT_TEMPERATUE_MSB, data, 2) < 0){
+ printk(KERN_ERR "%s: Failed to read internal TEMPERATURE\n", __func__);
+ }
+
+ temp = ((data[0]&0x1F)<<8) + data[1];
+ temp *= 15625;
+ temp /= 100000;
+
+ temp = (data[0]&0x20)?-temp:temp;
+ bi->int_temp = temp;
+ RTINFO("internal temperature: %d\n", bi->int_temp);
+}
+
static void rt5025_get_external_temp(struct rt5025_battery_info *bi)
{
u8 data[2];
bi->health = POWER_SUPPLY_HEALTH_GOOD;
bi->temp_recover_cnt = 0;
}
- //RTINFO("external temperature: %d\n", bi->ext_temp);
+ RTINFO("external temperature: %d\n", bi->ext_temp);
}
static void rt5025_clear_cc(struct rt5025_battery_info *bi, operation_mode mode)
{
u8 data[4];
u32 qh_old,ql_old,qh_new,ql_new;
- u32 cc_masec,offset;
+ u32 cc_masec,offset=0;
if (rt5025_read_reg(bi->client, RT5025_REG_QCHGH_MSB, data, 4) < 0){
pr_err("%s: Failed to read QCHG\n", __func__);
}
qh_old = (data[0]<<8) + data[1];
ql_old = (data[2]<<8) + data[3];
+ RTINFO("qh_old=%d, ql_old=%d\n", qh_old, ql_old);
if (rt5025_read_reg(bi->client, RT5025_REG_QCHGH_MSB, data, 4) < 0){
pr_err("%s: Failed to read QCHG\n", __func__);
}
qh_new = (data[0]<<8) + data[1];
ql_new = (data[2]<<8) + data[3];
+ RTINFO("qh_new=%d, ql_new=%d\n", qh_new, ql_new);
#if RT5025_B
if (qh_new > qh_old){
- cc_masec = (((qh_new<<16) + ql_new) * 50134) / 10;
+ //cc_masec = (((qh_new<<16) + ql_new) * 50134) / 10;
+ cc_masec = qh_new*328558+(qh_new*1824+ql_new*50134)/10000;
}else if (qh_new == qh_old){
if (ql_new >= ql_old){
- cc_masec = (((qh_new<<16) + ql_new) * 50134) / 10;
+ //cc_masec = (((qh_new<<16) + ql_new) * 50134) / 10;
+ cc_masec = qh_new*328558+(qh_new*1824+ql_new*50134)/10000;
}else {
- cc_masec = (((qh_old<<16) + ql_old) * 50134) / 10;
+ //cc_masec = (((qh_old<<16) + ql_old) * 50134) / 10;
+ cc_masec = qh_old*328558+(qh_old*1824+ql_old*50134)/10000;
}
}
+ if (!bi->init_once)
offset = bi->curr_offset * bi->time_interval;
if (cc_masec > offset){
- cc_masec = (cc_masec - offset) / 1000;
+ cc_masec = cc_masec - (offset / 1000);
}
#else
if (qh_new > qh_old){
RTINFO("chg_cc_mAsec: %d\n", cc_masec);
#endif
- bi->chg_cc = cc_masec;
+ //if (!bi->init_once)
+ bi->chg_cc = cc_masec;
//bi->chg_cc = (cc_masec + bi->chg_cc_unuse) / 3600;
//bi->chg_cc_unuse = (cc_masec + bi->chg_cc_unuse) % 3600;
rt5025_clear_cc(bi, CHG);
#if RT5025_B
if (qh_new > qh_old){
- cc_masec = (((qh_new<<16) + ql_new) * 50134) / 10;
+ //cc_masec = (((qh_new<<16) + ql_new) * 50134) / 10;
+ cc_masec = qh_new*328558+(qh_new*1824+ql_new*50134)/10000;
}else if (qh_new == qh_old){
if (ql_new >= ql_old){
- cc_masec = (((qh_new<<16) + ql_new) * 50134) / 10;
+ //cc_masec = (((qh_new<<16) + ql_new) * 50134) / 10;
+ cc_masec = qh_new*328558+(qh_new*1824+ql_new*50134)/10000;
}else {
- cc_masec = (((qh_old<<16) + ql_old) * 50134) / 10;
+ //cc_masec = (((qh_old<<16) + ql_old) * 50134) / 10;
+ cc_masec = qh_old*328558+(qh_old*1824+ql_old*50134)/10000;
}
}
+ if (!bi->init_once)
offset = bi->curr_offset * bi->time_interval;
if (cc_masec != 0){
- cc_masec = (cc_masec + offset) / 1000;
+ cc_masec = cc_masec + (offset / 1000);
}
#else
if (qh_new > qh_old){
RTINFO("dchg_cc_mAsec: %d\n", cc_masec);
#endif
bi->dchg_cc = cc_masec;
+ if (bi->last_tp_flag)
+ bi->cal_fcc += cc_masec;
+ else
+ bi->cal_fcc = 0;
+ RTINFO("bi->cal_fcc=%d, bi->last_tp_flag=%d\n", bi->cal_fcc, bi->last_tp_flag);
//bi->dchg_cc = (cc_masec + bi->dchg_cc_unuse) / 3600;
//bi->dchg_cc_unuse = (cc_masec + bi->dchg_cc_unuse) % 3600;
rt5025_clear_cc(bi, DCHG);
/* Set RT5025 gauge alert configuration */
rt5025_alert_threshold_init(bi->client);
/* Enable gauge alert function */
- rt5025_alert_setting(bi, MINVOLT2,VOLTAGE_ALERT);
+ //rt5025_alert_setting(bi, MINVOLT2,VOLTAGE_ALERT);
}
void rt5025_gauge_irq_handler(struct rt5025_battery_info *bi, u8 irq_flag)
wake_lock_timeout(&bi->low_battery_wake_lock, msecs_to_jiffies(LOW_BAT_WAKE_LOK_TIME*MSEC_PER_SEC));
}
- wake_lock(&bi->monitor_wake_lock);
+ //wake_lock(&bi->monitor_wake_lock);
+ wake_lock_timeout(&bi->status_wake_lock, 1.5*HZ);
schedule_delayed_work(&bi->monitor_work, 0);
}
EXPORT_SYMBOL(rt5025_gauge_irq_handler);
bi->soc = bi->rm /36/bi->fcc_aging;
bi->init_cap = false;
+ rt5025_battery_parameter_backup(bi);
+
//pr_err("[rt5025] i=%d, delta_x=%d, delta_y=%d, slope=%d, const_term=%d\n", i, delta_x, delta_y, slope, const_term);
RTINFO("voltage=%d, permille=%d, soc=%d, rm=%d\n", bi->vcell, bi->permille, bi->soc, bi->rm);
return;
static void rt5025_smooth_soc(struct rt5025_battery_info *bi)
{
- if ((bi->internal_status == POWER_SUPPLY_STATUS_CHARGING) &&
+ if ((bi->internal_status == POWER_SUPPLY_STATUS_CHARGING || bi->tp_flag == 1) &&
(bi->soc < 100))
{
bi->soc++;
else
bi->init_once = false;
+ if (bi->pre_soc != bi->soc)
+ rt5025_battery_parameter_backup(bi);
+
bi->pre_soc = bi->soc;
-// RTINFO("pre_soc=%d, soc=%d, internal status=%d\n", bi->pre_soc,bi->soc,bi->internal_status);
+ RTINFO("pre_soc=%d, soc=%d, internal status=%d\n", bi->pre_soc,bi->soc,bi->internal_status);
}
static void rt5025_soc_lock(struct rt5025_battery_info *bi)
}
else if ((bi->soc < 99) && (bi->tp_flag))
{
- bi->update_time = SMOOTH_POLL;
- bi->smooth_flag = true;
- rt5025_smooth_soc(bi);
+ if (!bi->last_suspend)
+ {
+ bi->update_time = SMOOTH_POLL;
+ bi->smooth_flag = true;
+ rt5025_smooth_soc(bi);
+ }
+ else
+ bi->last_suspend=false;
}
else
{
}else if ((bi->soc > 1) &&
(bi->internal_status == POWER_SUPPLY_STATUS_DISCHARGING) &&
(bi->edv_flag)){
- bi->update_time = SMOOTH_POLL;
- bi->smooth_flag = true;
- rt5025_smooth_soc(bi);
+ if (!bi->last_suspend)
+ {
+ bi->update_time = SMOOTH_POLL;
+ bi->smooth_flag = true;
+ rt5025_smooth_soc(bi);
+ }
+ else
+ bi->last_suspend=false;
}else{
bi->edv_flag = false;
}
rt5025_convert_masec_to_permille(bi);
bi->update_time = NORMAL_POLL;
}
+
+ if (bi->vcell <= bi->empty_edv)
+ {
+ if (bi->edv_cnt < 2)
+ bi->edv_cnt++;
+ }
+ else
+ bi->edv_cnt=0;
- if(rt5025_battery_param2[4].x < bi->vcell && bi->vcell <= rt5025_battery_param2[4].x+300)
+ if(bi->empty_edv < bi->vcell && bi->vcell <= bi->empty_edv+300)
{
bi->update_time = EDV_POLL;
bi->edv_detection = true;
}
- else if((bi->vcell >= rt5025_battery_param2[4].x + 300 +EDV_HYS) && (bi->edv_detection == true))
+ else if((bi->vcell >= bi->empty_edv + 300 +EDV_HYS) && (bi->edv_detection == true))
{
bi->update_time = NORMAL_POLL;
bi->edv_detection = false;
}
- else if((bi->vcell <= rt5025_battery_param2[4].x) && (bi->min_volt2_alert == true))
+ else if((bi->vcell <= bi->empty_edv && bi->edv_cnt == 2)) //&& (bi->min_volt2_alert == true))
{
bi->edv_flag = true;
bi->rm = 0;
bi->edv_detection = false;
bi->update_time = NORMAL_POLL;
}
- else if((bi->vcell > rt5025_battery_param2[4].x + EDV_HYS) && (bi->min_volt2_alert == true))
+ else if((bi->vcell > bi->empty_edv + EDV_HYS)) //&& (bi->min_volt2_alert == true))
{
bi->min_volt2_alert = false;
bi->edv_flag = false;
}*/
if (bi->internal_status == POWER_SUPPLY_STATUS_CHARGING)
bi->edv_flag = false;
- else if (bi->status != POWER_SUPPLY_STATUS_FULL)
+ if (bi->status != POWER_SUPPLY_STATUS_FULL)
bi->tp_flag = false;
#if RT5025_CSV
return;
}
+#if 0
static void rt5025_channel_cc(struct rt5025_battery_info *bi, bool enable)
{
u8 data[1];
printk(KERN_INFO "%s: failed to write channel\n", __func__);
}
}
+#endif
#if 0
static void rt5025_pretrim(struct rt5025_battery_info *bi)
//cycle_count
data[0] = (bi->cycle_cnt)&0xff;
rt5025_write_reg(bi->client, 0x2B, data, 1);
+ //soc
+ data[0] = (bi->soc)&0xff;
+ rt5025_write_reg(bi->client, 0x2C, data, 1);
+ //gauge_timer
+ data[0] = (bi->pre_gauge_timer>>8)&0xff;
+ data[1] = bi->pre_gauge_timer&0xff;
+ rt5025_write_reg(bi->client, 0x2D, data, 2);
return 0;
}
rt5025_read_reg(bi->client, 0x21, data, 2);
bi->fcc = bi->fcc_aging = data[0]<<8 | data[1];
//rm
- rt5025_read_reg(bi->client, 0x23, data, 4);
- bi->rm = data[0]<<24 | data[1]<<16 | data[2]<<8 | data[3];
+ //rt5025_read_reg(bi->client, 0x23, data, 4);
+ //bi->rm = data[0]<<24 | data[1]<<16 | data[2]<<8 | data[3];
//acc_dchg_cap
rt5025_read_reg(bi->client, 0x27, data, 4);
bi->acc_dchg_cap = data[0]<<24 | data[1]<<16 | data[2]<<8 | data[3];
//cycle_count
rt5025_read_reg(bi->client, 0x2B, data, 1);
bi->cycle_cnt = data[0];
+ //soc
+ rt5025_read_reg(bi->client, 0x2C, data, 1);
+ bi->soc = bi->pre_soc = data[0];
+ //pre_gauge_timer
+ rt5025_read_reg(bi->client, 0x2D, data, 2);
+ bi->pre_gauge_timer = bi->gauge_timer = (data[0]<<8) + data[1];
return 0;
}
static void rt5025_register_init(struct rt5025_battery_info *bi)
{
u8 data[1];
-
+
/* enable the channel of current,qc,ain,vbat and vadc */
if (rt5025_read_reg(bi->client, RT5025_REG_CHANNEL_LSB, data, 1) < 0){
pr_err("%s: failed to read channel\n", __func__);
}
+ RTINFO("initial change enable=%02x\n", data[0]);
data[0] = data[0] | CHANNEL_L_BIT_CADC_EN | CHANNEL_L_BIT_AINCH | \
- CHANNEL_L_BIT_VBATSCH | CHANNEL_L_BIT_VADC_EN;
+ CHANNEL_L_BIT_VBATSCH | CHANNEL_L_BIT_VADC_EN | CHANNEL_L_BIT_INTEMPCH;
if (rt5025_write_reg(bi->client, RT5025_REG_CHANNEL_LSB, data, 1) < 0){
pr_err("%s: failed to write channel\n", __func__);
}
bi->acc_dchg_cap = 0;
bi->cycle_cnt = 0;
+ bi->empty_edv = rt5025_battery_param2[4].x;
+ bi->edv_region = 0;
// if has initial data, rewrite to the stored data
if (rt5025_battery_parameter_initcheck(bi))
{
bi->init_cap = false;
rt5025_battery_parameter_restore(bi);
- bi->soc = bi->rm/36/bi->fcc_aging;
+ //bi->soc = bi->rm/36/bi->fcc_aging;
+ bi->rm = bi->soc*bi->fcc_aging*36;
}
-
+
bi->update_time = NORMAL_POLL;
bi->device_suspend = false;
RTINFO("register initialized\n");
rt5025_get_vcell(bi);
/* Update current */
rt5025_get_current(bi);
-
+ /* Update internal temperature */
+ rt5025_get_internal_temp(bi);
/* Update external temperature */
rt5025_get_external_temp(bi);
/* Read timer */
#if VOLTAGE_ALERT
if ((bi->min_volt2_irq == false) &&
- (bi->vcell > (rt5025_battery_param2[4].x + EDV_HYS))){
+ (bi->vcell > (bi->empty_edv + EDV_HYS))){
rt5025_alert_setting(bi,MINVOLT2,true);
}
#endif
bi->dchg_cc,bi->tp_cnt,bi->tp_flag,bi->edv_detection,bi->edv_cnt,bi->edv_flag,bi->soc,
bi->permille,bi->rm,bi->fcc,bi->smooth_flag,bi->acc_dchg_cap,bi->cycle_cnt,bi->update_time);
#else
- pr_info("[RT5025] update_time=%d\n",bi->update_time);
- pr_info("\n");
+ RTINFO("[RT5025] update_time=%d\n",bi->update_time);
+ RTINFO("\n");
#endif
}
struct delayed_work *delayed_work = (struct delayed_work *)container_of(work, struct delayed_work, work);
struct rt5025_battery_info *bi = (struct rt5025_battery_info *)container_of(delayed_work, struct rt5025_battery_info, monitor_work);
unsigned long flags;
-
- rt5025_update(bi);
+
+ wake_lock(&bi->monitor_wake_lock);
+ rt5025_update(bi);
+ power_supply_changed(&bi->battery);
/* prevent suspend before starting the alarm */
local_irq_save(flags);
local_irq_restore(flags);
wake_unlock(&bi->monitor_wake_lock);
+ schedule_delayed_work(&bi->monitor_work, bi->update_time*HZ);
}
static enum power_supply_property rt5025_battery_props[] = {
#endif
};
+static int rt5025_battery_sleepvth_setting(struct rt5025_battery_info* bi)
+{
+ u32 temp;
+ u8 vmax_th, vmin_th;
+ u8 vbat[2];
+ RTINFO("\n");
+ rt5025_read_reg(bi->client, RT5025_REG_VCELL_MSB, vbat, 2);
+ temp = ((vbat[0]<<8) + vbat[1])*61;
+ vmax_th = (temp+5000)/1953;
+ vmin_th = (temp-5000)/1953;
+
+ rt5025_write_reg(bi->client, RT5025_REG_VALRT_MAXTH, &vmax_th, 1);
+ rt5025_write_reg(bi->client, RT5025_REG_VALRT_MIN1TH, &vmin_th, 1);
+
+ RTINFO("vmax_th=0x%02x, vmin_th=0x%02x\n", vmax_th, vmin_th);
+ return 0;
+}
+
static int rt5025_battery_suspend(struct platform_device *pdev, pm_message_t state)
{
struct rt5025_battery_info *bi = platform_get_drvdata(pdev);
+ RTINFO("\n");
+ //rt5025_get_timer(bi);
//bi->last_event = ktime_get();
bi->last_event = current_kernel_time();
//cy add for battery parameter backup
- rt5025_battery_parameter_backup(bi);
+ //rt5025_battery_parameter_backup(bi);
- rt5025_channel_cc(bi, false);
- cancel_delayed_work(&bi->monitor_work);
- rt5025_get_timer(bi);
+ //rt5025_channel_cc(bi, false);
+ cancel_delayed_work_sync(&bi->monitor_work);
+ //rt5025_update(bi);
bi->device_suspend = true;
+ /* prevent suspend before starting the alarm */
//bi->update_time = SUSPEND_POLL;
+ rt5025_alert_setting(bi,MAXVOLT, false);
+ rt5025_alert_setting(bi,MINVOLT1,false);
+ rt5025_battery_sleepvth_setting(bi);
+ rt5025_alert_setting(bi,MAXVOLT, true);
+ rt5025_alert_setting(bi,MINVOLT1,true);
RTINFO("RM=%d\n",bi->rm);
return 0;
}
//bi->rm = bi->rm - (time_interval * SLEEP_CURRENT);
//RTINFO("Sleep time=%d, RM=%d",(int)time_interval,bi->rm);
- rt5025_channel_cc(bi, true);
- wake_lock(&bi->monitor_wake_lock);
- schedule_delayed_work(&bi->monitor_work, 0);
+ //rt5025_channel_cc(bi, true);
+ bi->last_suspend = true;
bi->device_suspend = false;
- //RTINFO("\n");
+ schedule_delayed_work(&bi->monitor_work, 0);
+ RTINFO("\n");
return 0;
}
wake_lock_init(&bi->monitor_wake_lock, WAKE_LOCK_SUSPEND, "rt-battery-monitor");
wake_lock_init(&bi->low_battery_wake_lock, WAKE_LOCK_SUSPEND, "low_battery_wake_lock");
+ wake_lock_init(&bi->status_wake_lock, WAKE_LOCK_SUSPEND, "battery-status-changed");
#if RT5025_TEST_WAKE_LOCK
wake_lock_init(&bi->test_wake_lock, WAKE_LOCK_SUSPEND, "rt-test");
#endif
}
- wake_lock(&bi->monitor_wake_lock);
+ //wake_lock(&bi->monitor_wake_lock);
#if RT5025_TEST_WAKE_LOCK
wake_lock(&bi->test_wake_lock);
#endif
static void rt5025_battery_shutdown(struct platform_device *pdev)
{
struct rt5025_battery_info *bi = platform_get_drvdata(pdev);
-
RTINFO("\n");
+ if (bi->soc == 0 && bi->cal_fcc != 0 )
+ {
+ bi->fcc_aging = bi->cal_fcc/3600 - (bi->fcc -bi->fcc_aging);
+ RTINFO("bi->cal_fcc=%d\n", bi->cal_fcc);
+ }
rt5025_battery_parameter_backup(bi);
}
MODULE_AUTHOR("Nick Hung <nick_hung@richtek.com");
MODULE_DESCRIPTION("battery gauge driver for RT5025");
MODULE_ALIAS("platform:" RT5025_DEVICE_NAME "-battery");
+MODULE_VERSION(RT5025_DRV_VER);
if (info->chip->battery_info)
{
if (info->chg_term == 0)
- rt5025_gauge_set_status(info->chip->battery_info, POWER_SUPPLY_STATUS_DISCHARGING);
+ rt5025_gauge_set_status(info->chip->battery_info, POWER_SUPPLY_STATUS_CHARGING);
else if (info->chg_term > 0)
{
rt5025_gauge_set_status(info->chip->battery_info, POWER_SUPPLY_STATUS_FULL);
old_acval = info->ac_online;
old_usbval = info->usb_online;
old_chgval = info->chg_stat;
+
+ mdelay(10);
ret = rt5025_reg_read(info->i2c, RT5025_REG_CHGSTAT);
if (ret<0)
if (new_acval || new_usbval)
{
- if (old_chgval != new_chgval)
- {
+ //if (old_chgval != new_chgval)
+ //{
ret = rt5025_chgstat_changed(info, new_chgval);
- }
+ //}
}
else
{
rt5025_notify_charging_cable(info->chip->jeita_info, JEITA_NO_CHARGE);
#if 1
if (info->chip->battery_info)
- rt5025_gauge_set_status(info->chip->battery_info, POWER_SUPPLY_STATUS_NOT_CHARGING);
+ rt5025_gauge_set_status(info->chip->battery_info, POWER_SUPPLY_STATUS_DISCHARGING);
#else
if (info->event_callback)
info->event_callback->rt5025_gauge_set_status(POWER_SUPPLY_STATUS_NOT_CHARGING);
struct delayed_work *delayed_work = (struct delayed_work *)container_of(work, struct delayed_work, work);
struct rt5025_power_info *pi = (struct rt5025_power_info *)container_of(delayed_work, struct rt5025_power_info, usb_detect_work);
- pr_info("rt5025: %s ++", __func__);
+ RTINFO("rt5025: %s ++", __func__);
mutex_lock(&pi->var_lock);
if (pi->ac_online)
}
else if (pi->usb_online)
{
- pr_info("%s: usb_cnt %d\n", __func__, pi->usb_cnt);
+ RTINFO("%s: usb_cnt %d\n", __func__, pi->usb_cnt);
switch(dwc_vbus_status())
{
case 2: // USB Wall charger
rt5025_set_charging_current(pi->i2c, 1000);
rt5025_notify_charging_cable(pi->chip->jeita_info, JEITA_USB_TA);
- pr_info("rt5025: detect usb wall charger\n");
+ RTINFO("rt5025: detect usb wall charger\n");
break;
case 1: //normal USB
default:
rt5025_set_charging_current(pi->i2c, 500);
rt5025_notify_charging_cable(pi->chip->jeita_info, JEITA_NORMAL_USB);
- pr_info("rt5025: detect normal usb\n");
+ RTINFO("rt5025: detect normal usb\n");
break;
}
if (pi->usb_cnt++ < 60)
}
mutex_unlock(&pi->var_lock);
- pr_info("rt5025: %s --", __func__);
+ RTINFO("rt5025: %s --", __func__);
}
static int __devinit rt5025_init_charger(struct rt5025_power_info *info, struct rt5025_power_data* pd)
{
+ //unsigned char data;
info->ac_online = 0;
info->usb_online =0;
//init charger buckck & charger current en to disable stat
if (info->event_callback)
info->event_callback->rt5025_gauge_set_status(POWER_SUPPLY_STATUS_DISCHARGING);
#endif
- rt5025_set_bits(info->i2c, RT5025_REG_CHGCTL4, RT5025_CHGRST_MASK);
- udelay(200);
+ //rt5025_set_bits(info->i2c, RT5025_REG_CHGCTL4, RT5025_CHGRST_MASK);
+ //udelay(200);
//init register setting
rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL2, pd->CHGControl2.val);
rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL3, pd->CHGControl3.val);
rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL4, pd->CHGControl4.val);
rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL5, pd->CHGControl5.val);
rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL6, pd->CHGControl6.val);
- rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL7, pd->CHGControl7.val);
+ //rt5025_reg_write(info->i2c, RT5025_REG_CHGCTL7, pd->CHGControl7.val);
+ rt5025_assign_bits(info->i2c, RT5025_REG_CHGCTL7, 0xEF, pd->CHGControl7.val);
+ rt5025_reg_write(info->i2c, 0xA9, 0x60 );
+ //Special buck setting
+ #if 0
+ //Buck 1
+ data = rt5025_reg_read(info->i2c, 0x47);
+ data ^=0xc2;
+ rt5025_reg_write(info->i2c, 0x47, data);
+ //Buck 2
+ data = rt5025_reg_read(info->i2c, 0x48);
+ data ^=0xc2;
+ rt5025_reg_write(info->i2c, 0x48, data);
+ //Buck 3
+ data = rt5025_reg_read(info->i2c, 0x49);
+ data ^=0xc2;
+ rt5025_reg_write(info->i2c, 0x49, data);
+ #endif //#if 0
rt5025_power_charge_detect(info);
if (pi->event_callback)
pi->event_callback->rt5025_gauge_suspend();
#endif
+ RTINFO("\n");
return 0;
}
if (pi->event_callback)
pi->event_callback->rt5025_gauge_resume();
#endif
+ RTINFO("\n");
return 0;
}
{
return platform_driver_register(&rt5025_power_driver);
}
-device_initcall_sync(rt5025_power_init);
+late_initcall_sync(rt5025_power_init);
static void __exit rt5025_power_exit(void)
{
MODULE_AUTHOR("CY Huang <cy_huang@richtek.com");
MODULE_DESCRIPTION("Power/Gauge driver for RT5025");
MODULE_ALIAS("platform:" RT5025_DEVICE_NAME "-power");
+MODULE_VERSION(RT5025_DRV_VER);
#include <linux/mfd/rt5025.h>
#include <linux/power/rt5025-swjeita.h>
-#define TEMP_TOLERANCE 10 // 'c*10 gap for tolerance
+#define TEMP_TOLERANCE 0 // 'c*10 gap for tolerance
static int rt5025_set_charging_cc_switch (struct i2c_client *i2c, int onoff)
{
ret = rt5025_assign_bits(i2c, RT5025_REG_CHGCTL4, RT5025_CHGICC_MASK, data);
- if (cur_value == 0)
+ if (cur_value < 500)
rt5025_set_charging_cc_switch(i2c, 0);
else
rt5025_set_charging_cc_switch(i2c, 1);
return ret;
}
+static inline int rt5025_set_intadc_onoff(struct rt5025_swjeita_info *swji, int enable)
+{
+ int ret;
+
+ RTINFO("enable = %d\n", enable);
+ if (enable)
+ ret = rt5025_set_bits(swji->i2c, RT5025_REG_CHANNELL, RT5025_INTEN_MASK);
+ else
+ ret = rt5025_clr_bits(swji->i2c, RT5025_REG_CHANNELL, RT5025_INTEN_MASK);
+
+ return ret;
+}
+
static int rt5025_set_exttemp_alert(struct rt5025_swjeita_info *swji, int index)
{
int ret = 0;
switch (index)
{
case 0:
- rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMIN, swji->temp_scalar[0]);
+ rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMIN, swji->temp_scalar[1]);
break;
case 1:
rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMAX, swji->temp_scalar[0]);
- rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMIN, swji->temp_scalar[1]);
+ rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMIN, swji->temp_scalar[3]);
break;
case 2:
- rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMAX, swji->temp_scalar[1]);
- rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMIN, swji->temp_scalar[2]);
+ rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMAX, swji->temp_scalar[2]);
+ rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMIN, swji->temp_scalar[5]);
break;
case 3:
- rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMAX, swji->temp_scalar[2]);
- rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMIN, swji->temp_scalar[3]);
+ rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMAX, swji->temp_scalar[4]);
+ rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMIN, swji->temp_scalar[7]);
break;
case 4:
- rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMAX, swji->temp_scalar[3]);
+ rt5025_reg_write(swji->i2c, RT5025_REG_TALRTMAX, swji->temp_scalar[6]);
break;
}
switch (cable_type)
{
case JEITA_NORMAL_USB:
- rt5025_set_charging_cc(swji->i2c, swji->temp_cc[cable_type][swji->cur_section]);
+ rt5025_set_charging_cc(swji->i2c, swji->temp_cc[cable_type][swji->cur_section]\
+ - swji->dec_current);
rt5025_set_charging_cv(swji->i2c, swji->temp_cv[cable_type][swji->cur_section]);
break;
case JEITA_USB_TA:
- rt5025_set_charging_cc(swji->i2c, swji->temp_cc[cable_type][swji->cur_section]);
+ rt5025_set_charging_cc(swji->i2c, swji->temp_cc[cable_type][swji->cur_section]\
+ - swji->dec_current);
rt5025_set_charging_cv(swji->i2c, swji->temp_cv[cable_type][swji->cur_section]);
break;
case JEITA_AC_ADAPTER:
- rt5025_set_charging_cc(swji->i2c, swji->temp_cc[cable_type][swji->cur_section]);
+ rt5025_set_charging_cc(swji->i2c, swji->temp_cc[cable_type][swji->cur_section]\
+ - swji->dec_current);
rt5025_set_charging_cv(swji->i2c, swji->temp_cv[cable_type][swji->cur_section]);
break;
case JEITA_NO_CHARGE:
}
EXPORT_SYMBOL(rt5025_swjeita_irq_handler);
+static void rt5025_get_internal_temp(struct rt5025_swjeita_info *swji)
+{
+ u8 data[2];
+ s32 temp;
+ if (rt5025_reg_block_read(swji->i2c, RT5025_REG_INTTEMP_MSB, 2, data) < 0){
+ pr_err("%s: Failed to read internal TEMPERATURE\n", __func__);
+ }
+
+ temp = ((data[0]&0x1F)<<8) + data[1];
+ temp *= 15625;
+ temp /= 100000;
+
+ temp = (data[0]&0x20)?-temp:temp;
+ swji->cur_inttemp = temp;
+
+ RTINFO("internal temperature: %d\n", temp);
+}
+
+static void thermal_reg_work_func(struct work_struct *work)
+{
+ struct delayed_work *delayed_work = (struct delayed_work *)container_of(work, struct delayed_work, work);
+ struct rt5025_swjeita_info *swji = (struct rt5025_swjeita_info *)container_of(delayed_work, struct rt5025_swjeita_info, thermal_reg_work);
+ int therm_region;
+
+ RTINFO("%s ++", __func__);
+ rt5025_get_internal_temp(swji);
+ if (swji->cur_inttemp < 800)
+ therm_region = 0;
+ else if (swji->cur_inttemp >= 800 && swji->cur_inttemp < 1000)
+ therm_region = 1;
+ else
+ therm_region = 2;
+
+ if (therm_region != swji->cur_therm_region)
+ {
+ switch (therm_region)
+ {
+ case 0:
+ swji->dec_current = 0;
+ break;
+ case 1:
+ swji->dec_current = 300;
+ break;
+ case 2:
+ swji->dec_current = 1000;
+ break;
+ }
+ swji->cur_therm_region = therm_region;
+ rt5025_notify_charging_cable(swji, swji->cur_cable);
+ }
+
+ schedule_delayed_work(&swji->thermal_reg_work, 5*HZ);
+
+ RTINFO("%s --", __func__);
+}
+
static int __devinit rt5025_swjeita_probe(struct platform_device *pdev)
{
struct rt5025_chip *chip = dev_get_drvdata(pdev->dev.parent);
pdata->jeita_data->temp_cv[ret][1], pdata->jeita_data->temp_cv[ret][2], \
pdata->jeita_data->temp_cv[ret][3], pdata->jeita_data->temp_cv[ret][4]);
}
- for (ret=0; ret<4; ret++)
+ for (ret=0; ret<8; ret++)
{
RTINFO("temp_scalar[%d] = 0x%02x\n", ret, pdata->jeita_data->temp_scalar[ret]);
}
swji->temp_scalar = pdata->jeita_data->temp_scalar;
swji->temp_cc = pdata->jeita_data->temp_cc;
swji->temp_cv = pdata->jeita_data->temp_cv;
+ INIT_DELAYED_WORK(&swji->thermal_reg_work, thermal_reg_work_func);
platform_set_drvdata(pdev, swji);
rt5025_set_ainadc_onoff(swji, 1);
+ rt5025_set_intadc_onoff(swji, 1);
mdelay(100);
rt5025_notify_charging_cable(swji, swji->cur_cable);
+ schedule_delayed_work(&swji->thermal_reg_work, 1*HZ);
chip->jeita_info = swji;
RTINFO("rt5025-swjeita driver is successfully loaded\n");
static int rt5025_swjeita_suspend(struct platform_device *pdev, pm_message_t state)
{
struct rt5025_swjeita_info *swji = platform_get_drvdata(pdev);
-
+ cancel_delayed_work_sync(&swji->thermal_reg_work);
+ swji->cur_therm_region = swji->dec_current = 0;
+ rt5025_notify_charging_cable(swji, swji->cur_cable);
swji->suspend = 1;
+ RTINFO("\n");
return 0;
}
struct rt5025_swjeita_info *swji = platform_get_drvdata(pdev);
swji->suspend = 0;
+ schedule_delayed_work(&swji->thermal_reg_work, 0);
+ RTINFO("\n");
return 0;
}
MODULE_AUTHOR("CY Huang <cy_huang@richtek.com");
MODULE_DESCRIPTION("Swjeita driver for RT5025");
MODULE_ALIAS("platform:" RT5025_DEVICE_NAME "-swjeita");
+MODULE_VERSION(RT5025_DRV_VER);
MODULE_AUTHOR("CY Huang <cy_huang@richtek.com");
MODULE_DESCRIPTION("Regulator driver for RT5025");
MODULE_ALIAS("platform:" RT5025_DEVICE_NAME "-regulator");
+MODULE_VERSION(RT5025_DRV_VER);
#define RT5025_PWRONCTRL_REG 0x19
#define RT5025_SHDNCTRL_REG 0x1A
#define RT5025_PWROFFEN_REG 0x1B
+#define RT5025_CHENH_REG 0x62
+#define RT5025_CHENL_REG 0x63
#define RT5025_SHDNCTRL_MASK 0x80
#define RT5025_VSYSOFF_MASK 0xE0
#include <linux/android_alarm.h>
#define RT5025_DEVICE_NAME "RT5025"
+#define RT5025_DRV_VER "1.0.2_R"
enum {
RT5025_RSTDELAY1_100MS,
#endif
};
-struct rt5025_platform_data {
- struct regulator_init_data* regulator[RT5025_MAX_REGULATOR];
- struct rt5025_power_data* power_data;
- struct rt5025_gpio_data* gpio_data;
- struct rt5025_misc_data* misc_data;
- struct rt5025_irq_data* irq_data;
- struct rt5025_jeita_data* jeita_data;
- struct rt5025_event_callback *cb;
- int (*pre_init)(struct rt5025_chip *rt5025_chip);
- /** Called after subdevices are set up */
- int (*post_init)(void);
- int intr_pin;
-};
-
struct rt5025_power_info {
struct i2c_client *i2c;
struct device *dev;
struct rt5025_swjeita_info {
struct i2c_client *i2c;
struct rt5025_chip *chip;
+ struct delayed_work thermal_reg_work;
int *temp;
u8 *temp_scalar;
int (*temp_cc)[5];
int (*temp_cv)[5];
+ int dec_current;
int cur_section;
+ int cur_therm_region;
int cur_cable;
int cur_temp;
+ int cur_inttemp;
int init_once;
int suspend;
};
struct delayed_work monitor_work;
struct wake_lock monitor_wake_lock;
struct wake_lock low_battery_wake_lock;
+ struct wake_lock status_wake_lock;
//#if RT5025_TEST_WAKE_LOCK
struct wake_lock test_wake_lock;
//#endif
u16 curr_offset;
/* AIN voltage */
u16 ain_volt;
+ /* battery internal temperature */
+ s16 int_temp;
/* battery external temperature */
s16 ext_temp;
/* charge coulomb counter */
u16 gauge_timer;
s16 curr_raw;
+ u32 empty_edv;
+ u8 edv_region;
bool init_once;
bool device_suspend;
+ bool last_suspend;
+ bool last_tp_flag;
+ u32 cal_fcc;
u8 test_temp;
};
struct mutex io_lock;
};
+struct rt5025_platform_data {
+ struct regulator_init_data* regulator[RT5025_MAX_REGULATOR];
+ struct rt5025_power_data* power_data;
+ struct rt5025_gpio_data* gpio_data;
+ struct rt5025_misc_data* misc_data;
+ struct rt5025_irq_data* irq_data;
+ struct rt5025_jeita_data* jeita_data;
+ struct rt5025_event_callback *cb;
+ int (*pre_init)(struct rt5025_chip *rt5025_chip);
+ /** Called after subdevices are set up */
+ int (*post_init)(void);
+ int intr_pin;
+};
+
#ifdef CONFIG_MFD_RT5025_MISC
extern void rt5025_power_off(void);
#endif /* CONFIG_MFD_RT5025_MISC */
--- /dev/null
+battery_graph_prop rt5025_battery_param1[] =
+{
+ {4190, 1000},
+ {4120, 980},
+ {4037, 890},
+ {3970, 800},
+ {3914, 710},
+ {3835, 580},
+ {3796, 490},
+ {3773, 400},
+ {3736, 240},
+ {3697, 140},
+ {3665, 70},
+ {3651, 50},
+ {3545, 20},
+ {3400, 0},
+};
+
+battery_graph_prop rt5025_battery_param2[] =
+{
+ {450,14},
+ {250, 0},
+ {50,-78},
+ {50, 10},
+ {3400, 3671},
+};
#ifndef __LINUX_RT5025_BATTERY_H
#define __LINUX_RT5025_BATTERY_H
-#define ROCKCHIP_BATTERY_6200MAH
-#undef ROCKCHIP_BATTERY_2100MAH
+#undef ROCKCHIP_BATTERY_6900MAH
+#undef ROCKCHIP_BATTERY_4000MAH
#define RT5025_REG_IRQ_CTL 0x50
#define RT5025_REG_IRQ_FLAG 0x51
#define RT5025_REG_TALRT_MINTH 0x57
#define RT5025_REG_VCELL_MSB 0x58
#define RT5025_REG_VCELL_LSB 0x59
-#define RT5025_REG_INT_TEMPERATUE_MSB 0x5B
-#define RT5025_REG_INT_TEMPERATUE_LSB 0x5C
+#define RT5025_REG_INT_TEMPERATUE_MSB 0x5A
+#define RT5025_REG_INT_TEMPERATUE_LSB 0x5B
#define RT5025_REG_EXT_TEMPERATUE_MSB 0x5E
#define RT5025_REG_EXT_TEMPERATUE_LSB 0x5F
#define RT5025_REG_TIMER 0x60
#define NORMAL_POLL 30 /* 30 sec */
#define TP_POLL 5 /* 5 sec */
-#define EDV_POLL 1 /* 1 sec */
-#define SMOOTH_POLL 5 /* 5 sec */
+#define EDV_POLL 5 /* 1 sec */
+#define SMOOTH_POLL 20 /* 5 sec */
#define SUSPEND_POLL (30*60) /* 30 min */
#define INIT_POLL 1
#define LOW_BAT_WAKE_LOK_TIME 120
LAST_TYPE,
}alert_type;
-#if defined(ROCKCHIP_BATTERY_6200MAH)
-#include <linux/power/rockchip-6200ma-bat.h>
-#elif defined(ROCKCHIP_BATTERY_2100MAH)
-#include <linux/power/rockchip-2100ma-bat.h>
+#if defined(ROCKCHIP_BATTERY_6900MAH)
+#include <linux/power/rockchip-6900ma-bat.h>
+#elif defined(ROCKCHIP_BATTERY_4000MAH)
+#include <linux/power/rockchip-4000ma-bat.h>
#else
#include <linux/power/rockchip-general-bat.h>
#endif
#define RT5025_CHGSTAT_SHIFT 4
#define RT5025_CHGSTAT_UNKNOWN 0x04
-#define RT5025_CHG_ACONLINE 0x02
-#define RT5025_CHG_ACSHIFT 1
-#define RT5025_CHG_USBONLINE 0x01
-#define RT5025_CHG_USBSHIFT 0
+#define RT5025_CHG_ACONLINE 0x01
+#define RT5025_CHG_ACSHIFT 0
+#define RT5025_CHG_USBONLINE 0x02
+#define RT5025_CHG_USBSHIFT 1
#endif /* #ifndef __LINUX_RT5025_POWER_H */
#define RT5025_REG_IRQCTL 0x50
#define RT5025_REG_TALRTMAX 0x56
#define RT5025_REG_TALRTMIN 0x57
+#define RT5025_REG_INTTEMP_MSB 0x5A
#define RT5025_CHGCCEN_MASK 0x10
#define RT5025_CHGICC_SHIFT 3
#define RT5025_CHGCV_SHIFT 2
#define RT5025_CHGCV_MASK 0xFC
#define RT5025_AINEN_MASK 0x04
+#define RT5025_INTEN_MASK 0x40
#define RT5025_TMXEN_MASK 0x20
#define RT5025_TMNEN_MASK 0x10