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;

#ifdef CONFIG_SKY_CHARGER_BATTERY
	max17040_data.status = BATT_STATE_NONE;
#endif

	dbgme_rel("[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);

	max17040_data.vcell = 0;
	max17040_data.soc = 0;

#ifdef CONFIG_SKY_CHARGER_BATTERY
	//registor
	sky_battery_register(&battery_ops);
#endif

	//mutex is init
	mutex_init(&max17040_data.i2c_mutex);	

	//rcomp is set
	max17040_set_rcomp();

	//Version of reading
	max17040_get_version();

#ifdef CONFIG_SKY_CHARGER_BATTERY
	if (max17040_get_battery_id() != BATT_ID_NONE)
		max17040_data.status = BATT_STATE_PRESENT;
#endif

	return 0;
}
Example #2
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;
}
Example #3
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
}