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; }
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; }
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 }