Esempio n. 1
0
static void max17040_schedule(void)
{
	switch(max17040_data.online)
		{
		case 0 : //usb not connected
			if(max17040_data.slow_poll) //usb not connected and suspend
			{
			sleep_dbg("CONFIG SLOW_POLL [The alarm is set for [%d] seconds ]\n",SLOW_POLL);
			max17040_program_alarm_set(&max17040_data, SLOW_POLL);		
			}
			else
			{
			sleep_dbg("CONFIG FAST_POLL [The alarm is set for [%d] seconds]\n",FAST_POLL);	
			max17040_program_alarm_set(&max17040_data, FAST_POLL);
			}			
			break;
		case 1 : //usb connection
			sleep_dbg("CONFIG FAST_POLL [The alarm is set for [%d] seconds]\n",FAST_POLL);	
			max17040_program_alarm_set(&max17040_data, FAST_POLL);			
			break;
		default:	
			sleep_dbg("CONFIG [Time setting is not]\n");				
			break;			
		}
}
Esempio n. 2
0
static void max17040_quick_get_vcell(void)
{
	u8 msb=0;
	u8 lsb=0;
	unsigned long quick_avalue;
	//unsigned long temp;	
	unsigned long voltage=0;
	int i=0;
	bool completed = false;

	while (!completed) {

	msb = max17040_read_reg(MAX17040_VCELL_MSB);
	lsb = max17040_read_reg(MAX17040_VCELL_LSB);
	if(msb < 0 || lsb < 0)
	{
		for(i=0;i<MAX_READ;i++)
		{
		msb = max17040_read_reg(MAX17040_VCELL_MSB);
		lsb = max17040_read_reg(MAX17040_VCELL_LSB);
		if(msb < 0 || lsb <0)
		{
		continue;
		}
		else
		break;
		}
	}
	voltage=(msb<<4)|((lsb&0xf0)>>4);
	quick_avalue=(voltage*1250)/100;
	sleep_dbg("MAX17040_QUICK  LOW MSB [%d] : LSB [%d] : LOW VOLTAGE [%d]\n",msb,lsb,voltage);
	sleep_dbg("MAX17040_QUICK  Adjusted [%d] : I2C Error Count [%d]\n",quick_avalue,i);	
	
	if(i==MAX_READ) {
		printk("Re-running to check V-Cell!!!\n");
		i = 0;
		continue;
	} else {
		mutex_lock(&max17040_data.data_mutex); 	
		max17040_data.quick_data.vcell_msb = msb;	
		max17040_data.quick_data.vcell_lsb = lsb;	
		max17040_data.quick_data.quick_vcell = quick_avalue;
		mutex_unlock(&max17040_data.data_mutex);
		completed = true;
		break;
	}

	}

}
Esempio n. 3
0
static ssize_t max17040_get_low_soc(struct device *dev, struct device_attribute *attr, char *buf)
{
	int enable;
	sleep_dbg("max17040_get_low_soc START\n");
	enable=max17040_data.soc;
	return sprintf(buf, "%d\n", enable);
}
Esempio n. 4
0
static int max17040_write_reg(u8 reg, u8 ahigh, u8 alow)
{
	int ret;
	u8 buf[20];
	buf[0]=reg;
	buf[1]=ahigh;
	buf[2]=alow;
	if ( max17040_data.client == NULL ) {
		sleep_dbg("%s : max17040.client is NULL\n", __func__);
		return -ENODEV;
	}
	mutex_lock(&max17040_data.i2c_mutex); 
	ret = i2c_master_send(max17040_data.client, buf, 3);		
	mutex_unlock(&max17040_data.i2c_mutex);
	if (ret<0)
        {   
                dev_err(&max17040_data.client->dev,
                "%s couldn't write reg %d\n", __func__, ret);
	return -1;	
        }
	else if (ret!=3)
        {   
                dev_err(&max17040_data.client->dev,
                "%s couldn't write reg %d\n", __func__, ret);
	return -1;
        }
	else
	return ret;
}
Esempio n. 5
0
static ssize_t max17040_start_quickstart(struct device *dev, struct device_attribute *attr, char *buf)
{
	int enable;
	sleep_dbg("QUICK START\n");
	max17040_restart();
	msleep(300); //quick start update time
	enable=max17040_data.quick_data.quick_state;
	return sprintf(buf, "%d\n", enable);
}
Esempio n. 6
0
static ssize_t max17040_get_low_voltage(struct device *dev, struct device_attribute *attr, char *buf)
{
	int enable;
	sleep_dbg("max17040_get_low_voltage START\n");
	max17040_restart();
	msleep(300); //quick start update time
	enable=max17040_data.vcell;
	return sprintf(buf, "%d\n", enable);
}
Esempio n. 7
0
static int max17040_resume(struct i2c_client *client)
{
	dbg_func_in();
	if (max17040_data.slow_poll) {
		schedule_delayed_work(&max17040_data.work, 0);		
		sleep_dbg("[RESUME] CONFIG FAST_POLL [The alarm is set for [%d] seconds]\n",FAST_POLL);	
	}
	dbg_func_out();
	return 0;
}
Esempio n. 8
0
static void max17040_quick_get_soc(void)
{
	u8 msb=0;
	u8 lsb=0;
	int avalue=0;
	//unsigned long quick_soc;
	int i=0;
	bool completed = false;
	dbg_func_in();

	while (!completed) {

	msb = max17040_read_reg(MAX17040_SOC_MSB);
	lsb = max17040_read_reg(MAX17040_SOC_LSB);
	if(msb < 0 || lsb < 0)
	{
		for(i=0;i<MAX_READ;i++)
		{
			msb = max17040_read_reg(MAX17040_SOC_MSB);
			lsb = max17040_read_reg(MAX17040_SOC_LSB);
			if(msb < 0 || lsb <0)
			{
				continue;
			}
			else
			break;
		}
	}
	/*//description
	read i2c data [msb=20,lsb=10]
	avalue=20*1000+(10*1000)/256
	*/
	avalue=SKY_MULT_1000(msb)+(SKY_MULT_1000(lsb)/SKY_SOC_LSB);	
	//Ajdusted soc%=(SOC%-EMPTY)/(FULL-EMPTY)*100
	//logic code	
	sleep_dbg("MAX17040_QUICK Adjusted SOC MSB [%d] : LSB [%d] : Adjusted SOC [%d] :Try Count [%d]\n",msb,lsb,avalue,i);
	
	if(i>=MAX_READ-1 || msb < 0 || lsb <0 ) { //Battery Bug Fixing Coded by Illustrious by Proto
		printk("Re-running to check Battery SoC!!!\n");
		i = 0;
		continue;			
	} else {
		mutex_lock(&max17040_data.data_mutex); 	
		max17040_data.quick_data.soc_msb=msb;	
		max17040_data.quick_data.soc_lsb=lsb;
		max17040_data.quick_data.quick_soc=avalue;
		mutex_unlock(&max17040_data.data_mutex);
		completed = true;
		break;
	}

	}	

	dbg_func_out();	
}
Esempio n. 9
0
static void max_battery_alarm_callback(struct alarm *alarm)
{

	struct max17040_chip *di =
		container_of(alarm, struct max17040_chip, alarm);
	dbg_func_in();
	sleep_dbg("MAX17040_ALARM_CALLBACK CALL.\n");					
	/*enable wake_lock*/
	max17040_prevent_suspend();
	/*schdule workqueue*/
	queue_work(di->monitor_wqueue, &di->monitor_work);
	dbg_func_out();	
}
Esempio n. 10
0
static void max17040_quick_get_vcell(void)
{
    u8 msb=0;
    u8 lsb=0;
    unsigned long quick_avalue;
    //unsigned long temp;
    unsigned long voltage=0;
    int i=0;
    msb = max17040_read_reg(MAX17040_VCELL_MSB);
    lsb = max17040_read_reg(MAX17040_VCELL_LSB);
    if(msb < 0 || lsb < 0)
    {
        for(i=0; i<MAX_READ; i++)
        {
            msb = max17040_read_reg(MAX17040_VCELL_MSB);
            lsb = max17040_read_reg(MAX17040_VCELL_LSB);
            if(msb < 0 || lsb <0)
            {
                continue;
            }
            else
                break;
        }
    }
    voltage=(msb<<4)|((lsb&0xf0)>>4);
    quick_avalue=(voltage*1250)/100;
    sleep_dbg("MAX17040_QUICK  LOW MSB [%d] : LSB [%d] : LOW VOLTAGE [%d]\n",msb,lsb,(unsigned int)voltage);
    sleep_dbg("MAX17040_QUICK  Adjusted [%d] : I2C Error Count [%d]\n",(unsigned int)quick_avalue,i);
    mutex_lock(&max17040_data.data_mutex);
    max17040_data.quick_data.vcell_msb = msb;
    max17040_data.quick_data.vcell_lsb = lsb;
    if(i==MAX_READ)
        max17040_data.quick_data.quick_vcell = 33975;
    else
        max17040_data.quick_data.quick_vcell = quick_avalue;
    mutex_unlock(&max17040_data.data_mutex);

}
Esempio n. 11
0
static u8 max17040_read_reg(u8 reg)
{
	u8 ret_s,ret_r ,ret;
	u8 buf[20];

	buf[0]=reg;
	mutex_lock(&max17040_data.i2c_mutex); 
	ret_s = i2c_master_send(max17040_data.client,  buf, 1);
	ret_r = i2c_master_recv(max17040_data.client, buf, 1);
	mutex_unlock(&max17040_data.i2c_mutex);	
	if(ret_s<0 || ret_r<0)
	{
	sleep_dbg("max17040 I2C FILED ret [%d] [%d]\n",ret_s,ret_r);		
	return -1;
	}
	else if(ret_s !=1 || ret_r !=1)
	{
	sleep_dbg("max17040 I2C FILED [%d] [%d] bytes transferred (expected 1)\n",ret_s,ret_r);				
	return -1;
	}
	else
	ret=buf[0];
	return ret;
}
Esempio n. 12
0
void max17040_batt_early_suspend(struct early_suspend *h)
{
	dbg_func_in();
	/* If we are on battery, reduce our update rate until
	 * we next resume.
	 */
	/*ps2 team shs : Runs only when the cable is not connected.*/
	max17040_data.online=sky_get_plug_state();
	max17040_data.slow_poll = Early_suspend;	
	if(!max17040_data.online)
	{
	sleep_dbg("[IMPORT]USB CABLE is not connected\n");				
	max17040_program_alarm_set(&max17040_data, SLOW_POLL);
	sleep_dbg("CONFIG SLOW_POLL [The alarm is set for [%d] seconds ]\n",SLOW_POLL);	
	}
	else
	{
	sleep_dbg("[IMPORT]USB CABLE is connected\n");			
	max17040_program_alarm_set(&max17040_data, FAST_POLL);
	sleep_dbg("CONFIG SLOW_POLL [The alarm is set for [%d] seconds ]\n",FAST_POLL);	
	}
	dbg_func_out();

}
Esempio n. 13
0
static int max17040_check_restart( unsigned long avoltage, int soc )
{
	int i=0;
	//ps2 team shs : dont check charging mode
	unsigned long sky_low_soc=0;
	unsigned long sky_fuelgauge_ref_soc=0;
	unsigned long sky_high_soc=0;
	int high_soc=0;
	int low_soc=0;
	  for( i = 0; i < COMPENSATION_MAX; i++ )
	  {
	    if( avoltage >= sky_fuelgauge_linearlize_table[0][i].volt )
	    {
		  mutex_lock(&max17040_data.quick_mutex); 			
	      sky_high_soc = (avoltage - sky_fuelgauge_linearlize_table[0][i].offset)/sky_fuelgauge_linearlize_table[0][i].slop;
		  sky_low_soc=(avoltage - sky_fuelgauge_linearlize_table[0][i].offset)%sky_fuelgauge_linearlize_table[0][i].slop;	  
		  sky_fuelgauge_ref_soc = SKY_MULT_1000(sky_high_soc)+(SKY_MULT_1000(sky_low_soc)/sky_fuelgauge_linearlize_table[0][i].slop);	  
		  high_soc=sky_fuelgauge_ref_soc + 30000;
		  low_soc=sky_fuelgauge_ref_soc  - 30000;
		  mutex_unlock(&max17040_data.quick_mutex);		  
		  //ps1 team shs :  soc+20 > soc and soc < soc-20 and soc <=1 && ref_soc > 4
	      if( (soc > high_soc) || (soc < low_soc)|| ( (soc <= 1000) && (sky_fuelgauge_ref_soc > 4000) ) )
	      {
			max17040_data.quick_data.quick_state=i;	      
			sleep_dbg("[QUICK START] voltage : [%u]mv, soc : [%d], index [%d], sky_high_soc [%u] ,sky_low_soc [%u]\n",avoltage,soc,i,sky_high_soc,sky_low_soc);	      
			sleep_dbg("[QUICK START] ref_soc : [%u], high_soc : [%u], low_soc : [%d]\n",sky_fuelgauge_ref_soc,high_soc,low_soc);	      			
	        return 1;
	      }
	      break;
	    }
	  }
	max17040_data.quick_data.quick_state=-1;	      	  
	sleep_dbg("[QUICK DISABLE] voltage : [%u]mv, soc : [%d], index [%d], sky_high_soc [%u], sky_low_soc [%u] \n",avoltage,soc,i,sky_high_soc,sky_low_soc);	      
	sleep_dbg("[QUICK DISABLE] ref_soc : [%u], high_soc : [%u], low_soc : [%d]\n",sky_fuelgauge_ref_soc,high_soc,low_soc);	      			
return 0;
}
Esempio n. 14
0
void max17040_batt_late_resume(struct early_suspend *h)
{
	dbg_func_in();
	/* We might be on a slow sample cycle.  If we're
	 * resuming we should resample the battery state
	 * if it's been over a minute since we last did
	 * so, and move back to sampling every minute until
	 * we suspend again.
	 */
	if (max17040_data.slow_poll) {
		max17040_program_alarm_set(&max17040_data, FAST_POLL);
		max17040_data.slow_poll = Early_resume;
		sleep_dbg("CONFIG FAST_POLL [The alarm is set for [%d] seconds]\n",FAST_POLL);	
	}
	dbg_func_out();	
}
Esempio n. 15
0
static void max17040_set_rcomp(void)
{
	int ret=0,i=0;	
	ret=max17040_write_reg(MAX17040_RCOMP_MSB, 0xc0,0x00);
	if(ret<0)
	{
		for(i=0;i<MAX_READ;i++)
		{
			ret=max17040_write_reg(MAX17040_RCOMP_MSB, 0xc0,0x00);			
			if(ret<0)
			continue;
			else
			break;
		}
	}
	sleep_dbg("MAX17040 SET_RCOMP TRY : [%d]\n",i);			
}
Esempio n. 16
0
static void max17040_restart(void)
{
	int ret=0,i=0;
	ret=max17040_write_reg(MAX17040_MODE_MSB, 0x40,0x00);
	if(ret<0)
	{
		for(i=0;i<MAX_READ;i++)
		{
			ret=max17040_write_reg(MAX17040_MODE_MSB, 0x40,0x00);	
			if(ret<0)
			continue;
			else
			break;
		}
	}
	sleep_dbg("MAX17040 QUICK START TRY : [%d]\n",i);
}
Esempio n. 17
0
static void max17040_quick_get_soc(void)
{
    u8 msb=0;
    u8 lsb=0;
    int avalue=0;
    //unsigned long quick_soc;
    int i=0;
    dbg_func_in();
    msb = max17040_read_reg(MAX17040_SOC_MSB);
    lsb = max17040_read_reg(MAX17040_SOC_LSB);
    if(msb < 0 || lsb < 0)
    {
        for(i=0; i<MAX_READ; i++)
        {
            msb = max17040_read_reg(MAX17040_SOC_MSB);
            lsb = max17040_read_reg(MAX17040_SOC_LSB);
            if(msb < 0 || lsb <0)
            {
                continue;
            }
            else
                break;
        }
    }
    /*//description
    read i2c data [msb=20,lsb=10]
    avalue=20*1000+(10*1000)/256
    */
    avalue=SKY_MULT_1000(msb)+(SKY_MULT_1000(lsb)/SKY_SOC_LSB);
    //Ajdusted soc%=(SOC%-EMPTY)/(FULL-EMPTY)*100
    //logic code
    sleep_dbg("MAX17040_QUICK Adjusted SOC MSB [%d] : LSB [%d] : Adjusted SOC [%d] :Try Count [%d]\n",msb,lsb,avalue,i);
    mutex_lock(&max17040_data.data_mutex);
    max17040_data.quick_data.soc_msb=msb;
    max17040_data.quick_data.soc_lsb=lsb;
    if(i==MAX_READ)
        max17040_data.quick_data.quick_soc=0;
    else
        max17040_data.quick_data.quick_soc=avalue;
    mutex_unlock(&max17040_data.data_mutex);
    dbg_func_out();
}
Esempio n. 18
0
static void max17040_set_rcomp(void)
{
	int ret=0,i=0;	
	int chg_type;

	chg_type = atomic_read(&smb_charger_state);
	
	if((high_current_rcomp_mode == 1) && (chg_type == 0)){
		ret = max17040_write_reg(MAX17040_RCOMP_MSB, 0x25,0x00);
		ret=max17040_write_reg(MAX17040_RCOMP_LSB, 0x1F,0x00);
		max17040_data.set_rcomp_mode = 1;
	}
	else {
		ret=max17040_write_reg(MAX17040_RCOMP_MSB, 0xC0,0x00);
		ret=max17040_write_reg(MAX17040_RCOMP_LSB, 0x1F,0x00);
		max17040_data.set_rcomp_mode = 0;
	}
	
	if(ret<0)
	{
		for(i=0;i<MAX_READ;i++)
		{
			if((high_current_rcomp_mode == 1) && (chg_type == 0)) {
                        	ret=max17040_write_reg(MAX17040_RCOMP_MSB, 0x65,0x00);
				ret=max17040_write_reg(MAX17040_RCOMP_LSB, 0x1F,0x00);
			}
			else {
				ret=max17040_write_reg(MAX17040_RCOMP_MSB, 0xC0,0x00);	
				ret=max17040_write_reg(MAX17040_RCOMP_LSB, 0x1F,0x00);
			}
			if(ret<0)
			continue;
			else
			break;
		}
	}

	sleep_dbg("MAX17040 SET_RCOMP TRY : [%d]\n",i);			
}
Esempio n. 19
0
static int max17040_suspend(struct i2c_client *client,
		pm_message_t state)
{
	int time =0;
	int soc=max17040_data.soc;
	dbg_func_in();

	/* If we are on battery, reduce our update rate until
	 * we next resume.
	 */
	/*ps2 team shs : Runs only when the cable is not connected.*/
	max17040_data.online=sky_get_plug_state();
	max17040_data.slow_poll = Early_suspend;	
	//ps1 team shs : cancel schedule_delayer_work
	cancel_delayed_work(&max17040_data.work);	
	//ps1 team shs : set time
	time=max17040_sleep_time(soc);
	msm_pm_set_max_sleep_time((int64_t)((int64_t) time * NSEC_PER_SEC)); 	
	sleep_dbg("[SUSPEND] set time [%d] seconds : soc [%d] ]\n",time,soc);		
	dbg_func_out();
	return 0;
}
Esempio n. 20
0
static void max17040_work(struct work_struct *work)
{
#ifdef MAX17040_ALARM_RTC_ENABLE
	struct max17040_chip *di =
		container_of(work, struct max17040_chip, monitor_work);
#else
	struct max17040_chip *di = container_of(work, struct max17040_chip, work.work);
#endif //MAX17040_ALARM_RTC_ENABLE
#ifdef MAX17040_ALARM_RTC_ENABLE
	unsigned long flags;	
#endif //MAX17040_ALARM_RTC_ENABLE
	int enable;	
	static int first_enable = 1;
	dbg_func_in();
	max17040_data.event=NoEvents;
	max17040_data.suspend_event=NoEvents;
	
#ifndef MAX17040_ALARM_RTC_ENABLE	
//	sleep_dbg("MAX17040_WORK CALL.\n");				
	//prevent suspend
	max17040_prevent_suspend();
#else
//	sleep_dbg("MAX17040_WORK RTC CALL.\n");				
#endif //MAX17040_ALARM_RTC_ENABLE

	//read voltage now
	max17040_get_vcell();

	//read soc 
	max17040_get_soc();
#ifdef MAX17040_DEBUG_QUICK	
	max17040_quick_get_value();	
#endif
	enable = atomic_read(&max17040_data.set_test);
	//save volate now and soc [TEST APPLICATION]
	if(enable)
	{	
		if((max17040_data.event)||first_enable) // ps2 team shs : soc is changed 
			{	
			sleep_dbg("MAX17040 SET TEST.\n");						
			sleep_dbg("MAX17040_WORK SOC [%d] prev[%d] : voltage [%d] : charger_state [%d] : i2c state [%d]\n",max17040_data.soc,max17040_data.prev_soc, max17040_data.vcell,charge_state,max17040_data.i2c_state);							
			input_report_rel(max17040_data.max17040_input_data, REL_RX, max17040_data.vcell);
			input_report_rel(max17040_data.max17040_input_data, REL_RY, max17040_data.soc);
		    input_report_rel(max17040_data.max17040_input_data, REL_RZ, enable);		
			input_sync(max17040_data.max17040_input_data);	
			if(first_enable)
				first_enable = 0;
			}

	}	
	else
		first_enable = 1;
	//ps2 team shs : After you determine the value of voltage and soc If there are changes to the event generates.
	if(max17040_data.slow_poll) //do not call early resume state.
	{
		if(max17040_data.suspend_event)// 15 percent below where they were soc.
			{
				dbg("low battery [%d] percent!!!!!!!\n",max17040_data.soc);				
				power_supply_changed(&di->battery);	
				sleep_dbg("[SLEEP_EVENT] 15 percent below Send Event [%d].\n",max17040_data.soc );				
			}
		else	//15 percent up where were soc.
			{	
				power_supply_changed(&di->battery);					
				sleep_dbg("[SLEEP_EVENT] 15 percent up Send Event [%d].\n",max17040_data.soc );				
			}

	}
	else //call early resume state.
	{
		if(max17040_data.event) //Different values soc.
			{
			sleep_dbg("MAX17040_WORK SOC [%d] prev[%d] : voltage [%d] : charger_state [%d] : i2c state [%d]\n",max17040_data.soc,max17040_data.prev_soc, max17040_data.vcell,charge_state,max17040_data.i2c_state);							
			power_supply_changed(&di->battery);
			}
		else	//same values soc.
			{
			dbg("[EVENT] Stop Event.\n");			
			}
	}
#ifdef MAX17040_ALARM_RTC_ENABLE
	di->last_poll=alarm_get_elapsed_realtime();		
	/* prevent suspend before starting the alarm */
	local_irq_save(flags);	
	max17040_schedule();
	max17040_allow_suspend();			
	local_irq_restore(flags);	
	dbg_func_out();	
#else
	max17040_data.slow_poll = Early_resume;
	max17040_allow_suspend();			
	schedule_delayed_work(&max17040_data.work, MAX17040_DELAY);	
#endif // MAX17040_ALARM_RTC_ENABLE
}
Esempio n. 21
0
static void max17040_work(struct work_struct *work)
{
#ifdef MAX17040_ALARM_RTC_ENABLE
	struct max17040_chip *di =
		container_of(work, struct max17040_chip, monitor_work);
#else
	struct max17040_chip *di = container_of(work, struct max17040_chip, work.work);
#endif //MAX17040_ALARM_RTC_ENABLE

#ifdef CONFIG_SKY_SMB136S_CHARGER
	int thermal_time_check_count = 0;
	unsigned long pm_temp = 0;
	unsigned long pm_temp_sum = 0;
	unsigned long current_batt_delta = 0;
	unsigned long pre_batt_delta = 0;
	int batt_delta_sum = 0;
	int batt_delta = 0;
	int chg_type;
#endif

//	unsigned long flags;	
	int enable;	
	dbg_func_in();
	max17040_data.event=NoEvents;
	max17040_data.suspend_event=NoEvents;
	
#ifndef MAX17040_ALARM_RTC_ENABLE	
//	sleep_dbg("MAX17040_WORK CALL.\n");				
	//prevent suspend
	max17040_prevent_suspend();
#else
//	sleep_dbg("MAX17040_WORK RTC CALL.\n");				
#endif //MAX17040_ALARM_RTC_ENABLE

	//read voltage now
	max17040_get_vcell();

	//read soc 
	max17040_get_soc();
#ifdef MAX17040_DEBUG_QUICK	
	max17040_quick_get_value();	
#endif
	enable = atomic_read(&max17040_data.set_test);
	//save volate now and soc [TEST APPLICATION]
	if(enable)
	{	
		if(max17040_data.event) // soc is changed 
		{	
			pr_err("MAX17040 SET TEST.\n");						
			sleep_dbg("MAX17040_WORK SOC [%d] prev[%d] : voltage [%d] : charger_state [%d] : i2c state [%d]\n", 
				max17040_data.soc,max17040_data.prev_soc, max17040_data.vcell,charge_state,max17040_data.i2c_state);							
			input_report_abs(max17040_data.max17040_input_data, ABS_X, max17040_data.vcell);
			input_report_abs(max17040_data.max17040_input_data, ABS_Y, max17040_data.soc);
		    	input_report_abs(max17040_data.max17040_input_data, ABS_WAKE, enable);		
			input_sync(max17040_data.max17040_input_data);	
		}

	}
	
	//After you determine the value of voltage and soc If there are changes to the event generates.
	if(max17040_data.slow_poll) //do not call early resume state.
	{
		if(max17040_data.suspend_event)// 15 percent below where they were soc.
			{
				pr_err("low battery [%d] percent!!!!!!!\n",max17040_data.soc);				
				power_supply_changed(&di->battery);	
				pr_err("[SLEEP_EVENT] 15 percent below Send Event [%d].\n",max17040_data.soc );				
			}
		else	//15 percent up where were soc.
			{	
				power_supply_changed(&di->battery);					
				pr_err("[SLEEP_EVENT] 15 percent up Send Event [%d].\n",max17040_data.soc );				
			}

	}
	else //call early resume state.
	{
		if(max17040_data.event) {	//Different values soc.
			pr_err("MAX17040_WORK SOC [%d] prev[%d] : voltage [%d] : charger_state [%d] : i2c state [%d]\n", 
				max17040_data.soc,max17040_data.prev_soc, max17040_data.vcell,charge_state,max17040_data.i2c_state);	
			power_supply_changed(&di->battery);
		}
		else	 {	//same values soc.
			//pr_err("[EVENT] Stop Event.\n");			
		}
	}

	if(max17040_raw_soc != max17040_raw_pre_soc) {
		pr_err("[SOC:%d->%d]\n", max17040_raw_pre_soc, max17040_raw_soc);
		/* if battery is fully charged, charging done*/
		if(sky_get_plug_state() == 1 && 
			(max17040_raw_pre_soc >= (CHARGING_DONE_THRESHOLD-5) 
			&& max17040_raw_soc >= CHARGING_DONE_THRESHOLD)) {
			notify_event_charging_done();
		}

		/* if gauge falls below a threshold, recharging */
		if(sky_get_plug_state() == 0 && 
			(max17040_raw_pre_soc >= (RECHARGING_THRESHOLD-5) 
			&& max17040_raw_soc <= RECHARGING_THRESHOLD)) {
			notify_event_recharging();
		}
	}
	
#ifdef MAX17040_ALARM_RTC_ENABLE
	di->last_poll=alarm_get_elapsed_realtime();		
	/* prevent suspend before starting the alarm */
	local_irq_save(flags);	
	max17040_schedule();
	max17040_allow_suspend();			
	local_irq_restore(flags);	
	dbg_func_out();	
#else
#ifdef CONFIG_SKY_SMB136S_CHARGER
	chg_type = atomic_read(&smb_charger_state);
        pmic8058_tz_get_temp_charging(&pm_temp);
	if(thermal_time_check_count != 3) { 
		pm_temp_sum = pm_temp_sum + pm_temp;
		current_batt_delta = pm_temp;
		if (pm_temp > pre_batt_delta) {
			batt_delta = pm_temp - pre_batt_delta;
			batt_delta_sum = batt_delta_sum + batt_delta;
		}
		else {
			batt_delta = 0;
			batt_delta_sum = batt_delta_sum + batt_delta;
		}
		pre_batt_delta = current_batt_delta;
		thermal_time_check_count ++;
	}
	else {
		if(chg_type == 0) {
			if(((pm_temp_sum > 114000) || (batt_delta_sum > 600 && pm_temp_sum > 84000)) && max17040_data.set_rcomp_mode == 0) {
				high_current_rcomp_mode = 1;
				max17040_set_rcomp(); 
			}
			else {
			    if(max17040_data.set_rcomp_mode == 1) {
				high_current_rcomp_mode = 0;
				max17040_set_rcomp();
			    }
			}
		}	
		else {
				high_current_rcomp_mode = 0;
				max17040_set_rcomp();
		}
		thermal_time_check_count = 0;
		pm_temp_sum = 0;
		batt_delta_sum = 0;
			
	}
#endif
	max17040_data.slow_poll = Early_resume;
	max17040_allow_suspend();			
	schedule_delayed_work(&max17040_data.work, MAX17040_DELAY);	
#endif // MAX17040_ALARM_RTC_ENABLE
}
Esempio n. 22
0
static void max17040_work(struct work_struct *work)
{
#ifdef MAX17040_ALARM_RTC_ENABLE
    unsigned long flags;
#endif //MAX17040_ALARM_RTC_ENABLE
    int enable;
    static int first_enable = 1;
    dbg_func_in();
    max17040_data.event=NoEvents;
    max17040_data.suspend_event=NoEvents;

#ifndef MAX17040_ALARM_RTC_ENABLE
//	sleep_dbg("MAX17040_WORK CALL.\n");
    //prevent suspend
    max17040_prevent_suspend();
#else
//	sleep_dbg("MAX17040_WORK RTC CALL.\n");
#endif //MAX17040_ALARM_RTC_ENABLE

    //read voltage now
    max17040_get_vcell();

    //read soc
    max17040_get_soc();
#ifdef MAX17040_DEBUG_QUICK
    max17040_quick_get_value();
#endif
    enable = atomic_read(&max17040_data.set_test);
    //save volate now and soc [TEST APPLICATION]
    if(enable)
    {
        if((max17040_data.event)||first_enable) // ps2 team shs : soc is changed
        {
            sleep_dbg("MAX17040 SET TEST.\n");
            sleep_dbg("MAX17040_WORK SOC [%d] prev[%d] : voltage [%d] : charger_state [%d] : i2c state [%d]\n",max17040_data.soc,max17040_data.prev_soc, max17040_data.vcell,charge_state,max17040_data.i2c_state);
            input_report_rel(max17040_data.max17040_input_data, REL_RX, max17040_data.vcell);
            input_report_rel(max17040_data.max17040_input_data, REL_RY, max17040_data.soc);
            input_report_rel(max17040_data.max17040_input_data, REL_RZ, enable);
            input_sync(max17040_data.max17040_input_data);
            if(first_enable)
                first_enable = 0;
        }

    }
    else
        first_enable = 1;
    //ps2 team shs : After you determine the value of voltage and soc If there are changes to the event generates.
    if(max17040_data.slow_poll) //do not call early resume state.
    {
        if(max17040_data.suspend_event)// 15 percent below where they were soc.
        {
            dbg("low battery [%d] percent!!!!!!!\n",max17040_data.soc);
            max17040_power_supply_changed();
            sleep_dbg("[SLEEP_EVENT] 15 percent below Send Event [%d].\n",max17040_data.soc );
        }
        else	//15 percent up where were soc.
        {
            max17040_power_supply_changed();
            sleep_dbg("[SLEEP_EVENT] 15 percent up Send Event [%d].\n",max17040_data.soc );
        }

    }
    else //call early resume state.
    {
        if(max17040_data.event) //Different values soc.
        {
            sleep_dbg("MAX17040_WORK SOC [%d] prev[%d] : voltage [%d] : charger_state [%d] : i2c state [%d]\n",max17040_data.soc,max17040_data.prev_soc, max17040_data.vcell,charge_state,max17040_data.i2c_state);
            max17040_power_supply_changed();
        }
        else	//same values soc.
        {
            dbg("[EVENT] Stop Event.\n");
        }
    }

#if defined(CONFIG_SKY_SMB136S_CHARGER)
    if(max17040_raw_soc != max17040_raw_pre_soc) {
        pr_err("[SOC:%d->%d]\n", max17040_raw_pre_soc, max17040_raw_soc);
        /* if battery is fully charged, charging done*/
        if(sky_get_plug_state() == 1 &&
                (max17040_raw_pre_soc >= (CHARGING_DONE_THRESHOLD-5)
                 && max17040_raw_soc >= CHARGING_DONE_THRESHOLD)) {
            notify_event_charging_done();
        }

        /* if gauge falls below a threshold, recharging */
        if(sky_get_plug_state() == 0 &&
                (max17040_raw_pre_soc >= (RECHARGING_THRESHOLD-5)
                 && max17040_raw_soc <= RECHARGING_THRESHOLD)) {
            notify_event_recharging();
        }
    }
#endif

#ifdef MAX17040_ALARM_RTC_ENABLE
    di->last_poll=alarm_get_elapsed_realtime();
    /* prevent suspend before starting the alarm */
    local_irq_save(flags);
    max17040_schedule();
    max17040_allow_suspend();
    local_irq_restore(flags);
    dbg_func_out();
#else
    max17040_data.slow_poll = Early_resume;
    max17040_allow_suspend();
    schedule_delayed_work(&max17040_data.work, MAX17040_DELAY);
#endif // MAX17040_ALARM_RTC_ENABLE
}
Esempio n. 23
0
static void max17040_get_soc(void)
{
	u8 msb;
	u8 lsb;
	int avalue=0;
	int soc=0;
#ifdef MAX17040_SLEEP_DEBUG
	int sky_state=0;
#endif
	dbg_func_in();
	msb = max17040_read_reg(MAX17040_SOC_MSB);
	lsb = max17040_read_reg(MAX17040_SOC_LSB);

	//check i2c error
	if(msb<0 ||lsb <0)
	{
	max17040_data.i2c_state =1;
	}
	else
	{
	max17040_data.i2c_state =0;
	max17040_data.prev_soc=max17040_data.soc;
	}

#ifdef MAX17040_DEBUG_QUICK		
	//quick start code
	soc=SKY_MULT_1000(msb)+(SKY_MULT_1000(lsb)/SKY_SOC_LSB);	
	soc=soc/1000;
#else
	/*//description
	read i2c data [msb=20,lsb=10]
	avalue=20*1000+(10*1000)/256
	*/
	avalue=SKY_MULT_1000(msb)+(SKY_MULT_1000(lsb)/SKY_SOC_LSB);	
	//Ajdusted soc%=(SOC%-EMPTY)/(FULL-EMPTY)*100
	if(avalue>1200)
		soc=(((avalue-SKY_MULT_100(SKY_SOC_EMPTY))*100)/(SKY_MULT_100(SKY_SOC_FULL)-SKY_MULT_100(SKY_SOC_EMPTY)));
	else 
		soc=0;
	if(avalue >1000 && avalue <1200)
		soc=1;	
#endif	
	//logic code
	if(soc>100) //soc>100
		soc=100;
	if(soc==100)
	charge_state=1;
	else
	charge_state=0;		
#ifdef CONFIG_SKY_CHARGING
	if(pm8058_chg_nobattery_factory_cable())
		soc = 10;
#endif
	if(max17040_data.event) // ps2 team shs : soc is changed 
	{
	sleep_dbg("CONFIG CAPACITY [%d] : BATTERY STATS  : [%d]\n",soc,sky_state);
	sleep_dbg("SOC MSB [%d] : LSB [%d] : Lower SOC [%d] : Adjusted SOC [%d] : charge_state [%d] \n",msb,lsb,avalue,soc,charge_state);
	}
	if(soc!=max17040_data.soc)
	max17040_data.event=Events;
	if(soc==0)//ps1 team shs : 0% persent is occured events
	max17040_data.event=Events;
	max17040_check_power(soc);
	mutex_lock(&max17040_data.data_mutex); 	
	max17040_data.soc = soc;	
	mutex_unlock(&max17040_data.data_mutex);
	dbg_func_out();		
}
Esempio n. 24
0
static void max17040_quick_get_value(void)
{
	u8 rcomp=0, rcomp_low;
	sleep_dbg("\n=======================================================================\n");	
	sleep_dbg("[INFORMATION] QUICK START STATE [%d]\n",max17040_data.quick_data.quick_state);	      
	sleep_dbg("[INFORMATION] QUICK START SOC_MSB [%d]\n",max17040_data.quick_data.soc_msb);	
	sleep_dbg("[INFORMATION] QUICK START SOC_LSB [%d]\n",max17040_data.quick_data.soc_lsb);		
	sleep_dbg("[INFORMATION] QUICK START SOC [%d]\n",max17040_data.quick_data.quick_soc);	
	sleep_dbg("[INFORMATION] QUICK START REFERENSE SOC [%d]\n",sky_fuelgauge_ref_soc);				
	sleep_dbg("[INFORMATION] QUICK START VCELL_MSB [%d]\n",max17040_data.quick_data.vcell_msb);		
	sleep_dbg("[INFORMATION] QUICK START VCELL_LSB [%d]\n",max17040_data.quick_data.vcell_lsb);	
	sleep_dbg("[INFORMATION] QUICK START VOLTAGE [%d]\n",max17040_data.quick_data.quick_vcell);	
	rcomp=max17040_read_reg(MAX17040_RCOMP_MSB);
	rcomp_low=max17040_read_reg(MAX17040_RCOMP_LSB);	
	sleep_dbg("[INFORMATION] RCOMP 0x[%x][%x]\n",rcomp,rcomp_low);			
	sleep_dbg("\n=======================================================================\n");		
}
Esempio n. 25
0
static int __devinit max17040_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
    struct input_dev *input_data = NULL;	
	int ret;
#if 0	
	int aflag=0;
#endif
	sleep_dbg("[MAX17040] max17040_probe [IN]\n");	
	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
		return -EIO;

	max17040_data.client = client;
	i2c_set_clientdata(client, &max17040_data);
	//sys file system are registered
	max17040_data.battery.name		= "batterys";
	max17040_data.battery.type		= POWER_SUPPLY_TYPE_BATTERY;
	max17040_data.battery.get_property	= max17040_get_property;
	max17040_data.battery.properties	= max17040_battery_props;
	max17040_data.battery.external_power_changed = max17040_bat_external_power_changed;
	max17040_data.battery.num_properties	= ARRAY_SIZE(max17040_battery_props);
	ret = power_supply_register(&client->dev, &max17040_data.battery);
	if (ret) {
		sleep_dbg("[MAX17040] failed: power supply register [ERROR]\n");			
		i2c_set_clientdata(client, NULL);
		return ret;
	}
	//The code used in the test mode [TEST MODE]	
	ret = sysfs_create_group(&client->dev.kobj, &max17040_attr_group);	
	if (ret) {
		sleep_dbg("[MAX17040] failed: sysfs_create_group  [ERROR]\n");					
	}	
	//mutex is init
	mutex_init(&max17040_data.data_mutex);
	mutex_init(&max17040_data.i2c_mutex);	
	mutex_init(&max17040_data.quick_mutex);		
	//rcomp is set
	max17040_set_rcomp();
	//Version of reading
	max17040_get_version();
	//read vell and soc 
	max17040_quick_get_vcell();
	max17040_quick_get_soc();

#if 0	
	//check quick start
	aflag=max17040_check_restart(max17040_data.quick_data.quick_vcell,max17040_data.quick_data.quick_soc);
	if(aflag)
	{
	max17040_restart();	
	msleep(300); //quick start update time
	}
#endif

	//The code used in the test mode [TEST MODE]
	atomic_set(&max17040_data.set_test, 0);		
    input_data = input_allocate_device();
  if (!input_data) {
        sleep_dbg("MAX17040: Unable to input_allocate_device \n");  	
		return -1;
    }
	
    set_bit(EV_REL,input_data->evbit);
    input_set_capability(input_data, EV_REL, REL_RX);	
    input_set_capability(input_data, EV_REL, REL_RY); /* wake */	
    input_set_capability(input_data, EV_REL, REL_RZ); /* wake */
	input_data->name="max17040";
    ret =input_register_device(input_data);
    if (ret) {
        sleep_dbg("MAX17040: Unable to register input_data device\n");
		return -1;
    }
    input_set_drvdata(input_data, &max17040_data);	
	max17040_data.max17040_input_data=input_data;
	//initialize workqueue and alarm setting
	wake_lock_init(&max17040_data.work_wake_lock, WAKE_LOCK_SUSPEND,
			"max17040-battery");


#ifdef MAX17040_ALARM_RTC_ENABLE
	max17040_data.last_poll=alarm_get_elapsed_realtime();	
	INIT_WORK(&max17040_data.monitor_work, max17040_work);
	max17040_data.monitor_wqueue = create_freezeable_workqueue("max17040");
	/* init to something sane */
	if (!max17040_data.monitor_wqueue) {
		sleep_dbg("fail_workqueue Error [PROBE FUNCTION]");
		return -1;
	}
	alarm_init(&max17040_data.alarm, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
			max_battery_alarm_callback);
	//prevent suspend
	max17040_prevent_suspend();
#ifdef CONFIG_HAS_EARLYSUSPEND
	max17040_data.early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
	max17040_data.early_suspend.suspend = max17040_batt_early_suspend;
	max17040_data.early_suspend.resume = max17040_batt_late_resume;
	dbg("set max17040 EARLY_SUSPEND\n");	
	register_early_suspend(&max17040_data.early_suspend);
#endif	//CONFIG_HAS_EARLYSUSPEND
	queue_work(max17040_data.monitor_wqueue, &max17040_data.monitor_work);
	
#else
	INIT_DELAYED_WORK_DEFERRABLE(&max17040_data.work, max17040_work);
	schedule_delayed_work(&max17040_data.work, 0);
#endif //MAX17040_ALARM_RTC_ENABLE
	sleep_dbg("[MAX17040] max17040_probe [OUT]\n");	
	return 0;
}