static void twl6030charger_ctrl_work_handler(struct work_struct *work) { struct charger_device_info *di = container_of(work, struct charger_device_info, twl6030charger_ctrl_work.work); int ret; int n_usbic_state; int charger_fault = 0; long int events; u8 stat_toggle, stat_reset, stat_set = 0; u8 charge_state = 0; u8 present_charge_state = 0; u8 ac_or_vbus, no_ac_and_vbus = 0; u8 hw_state = 0, temp = 0; dev_dbg(di->dev, "[TA] %s start\n",__func__); clear_charge_start_time(); /* read charger controller_stat1 */ ret = twl_i2c_read_u8(TWL6030_MODULE_CHARGER, &present_charge_state, CONTROLLER_STAT1); if (ret) return 0; twl_i2c_read_u8(TWL6030_MODULE_ID0, &hw_state, STS_HW_CONDITIONS); charge_state = di->stat1; stat_toggle = charge_state ^ present_charge_state; stat_set = stat_toggle & present_charge_state; stat_reset = stat_toggle & charge_state; no_ac_and_vbus = !((present_charge_state) & (VBUS_DET | VAC_DET)); ac_or_vbus = charge_state & (VBUS_DET | VAC_DET); if (no_ac_and_vbus && ac_or_vbus) { dev_dbg(di->dev, "[TA] No Charging source\n"); /* disable charging when no source present */ } charge_state = present_charge_state; di->stat1 = present_charge_state; if (stat_reset & VBUS_DET) { /* On a USB detach, UNMASK VBUS OVP if masked*/ twl_i2c_read_u8(TWL6030_MODULE_CHARGER, &temp, CHARGERUSB_INT_MASK); if (temp & MASK_MCHARGERUSB_FAULT) twl_i2c_write_u8(TWL6030_MODULE_CHARGER, (temp & ~MASK_MCHARGERUSB_FAULT), CHARGERUSB_INT_MASK); dev_dbg(di->dev, "[TA] Charging source removed\n"); change_cable_status(POWER_SUPPLY_TYPE_BATTERY, di); #ifdef CONFIG_DYNAMIC_TSP_SETTINGS_FOR_CHARGER_STATE set_tsp_for_ta_detect(0); #endif } if (stat_set & VBUS_DET) { /* In HOST mode (ID GROUND) when a device is connected, Mask * VBUS OVP interrupt and do no enable usb charging */ if (hw_state & STS_USB_ID) { twl_i2c_read_u8(TWL6030_MODULE_CHARGER, &temp, CHARGERUSB_INT_MASK); if (!(temp & MASK_MCHARGERUSB_FAULT)) twl_i2c_write_u8(TWL6030_MODULE_CHARGER, (temp | MASK_MCHARGERUSB_FAULT), CHARGERUSB_INT_MASK); } else { n_usbic_state = get_real_usbic_state(); dev_dbg(di->dev, "[TA] cable_detection_isr handler. usbic_state: %d\n", n_usbic_state); switch (n_usbic_state) { case MICROUSBIC_5W_CHARGER: case MICROUSBIC_TA_CHARGER: case MICROUSBIC_USB_CHARGER: case MICROUSBIC_PHONE_USB: case MICROUSBIC_USB_CABLE: case MICROUSBIC_MHL_CHARGER: case MICROUSBIC_JIG_USB_ON: if (sec_bci->charger.cable_status == POWER_SUPPLY_TYPE_USB || sec_bci->charger.cable_status == POWER_SUPPLY_TYPE_MAINS ){ dev_dbg(di->dev, "[TA] Already Plugged\n"); break; } /*Check VF */ sec_bci->battery.battery_vf_ok = check_battery_vf(); /*TA or USB or MHL is inserted */ if (n_usbic_state == MICROUSBIC_USB_CABLE) { //current : 395mA dev_dbg(di->dev,"[TA] USB CABLE PLUGGED\n"); change_cable_status(POWER_SUPPLY_TYPE_USB, di); #ifdef CONFIG_DYNAMIC_TSP_SETTINGS_FOR_CHARGER_STATE set_tsp_for_ta_detect(1); #endif } else if (n_usbic_state == MICROUSBIC_MHL_CHARGER) { //current : 395mA dev_dbg(di->dev,"[TA] MHL CABLE PLUGGED\n"); change_cable_status(POWER_SUPPLY_TYPE_USB, di); #ifdef CONFIG_DYNAMIC_TSP_SETTINGS_FOR_CHARGER_STATE set_tsp_for_ta_detect(1); #endif } else if (n_usbic_state == MICROUSBIC_JIG_USB_ON) { //current : 1000mA dev_dbg(di->dev,"[TA] JIG_USB_ON CABLE PLUGGED\n"); change_cable_status(POWER_SUPPLY_TYPE_MAINS, di); #ifdef CONFIG_DYNAMIC_TSP_SETTINGS_FOR_CHARGER_STATE set_tsp_for_ta_detect(1); #endif } else { //current : 1000mA dev_dbg(di->dev,"[TA] CHARGER CABLE PLUGGED\n"); change_cable_status(POWER_SUPPLY_TYPE_MAINS, di); #ifdef CONFIG_DYNAMIC_TSP_SETTINGS_FOR_CHARGER_STATE set_tsp_for_ta_detect(1); #endif } break; default: ; } } } if (sec_bci->charger.prev_cable_status == -1 && sec_bci->charger.cable_status == -1) { dev_dbg(di->dev,"[TA] Fisrt time after bootig.\n"); change_cable_status(POWER_SUPPLY_TYPE_BATTERY, di); #ifdef CONFIG_DYNAMIC_TSP_SETTINGS_FOR_CHARGER_STATE set_tsp_for_ta_detect(0); #endif } if (stat_set & CONTROLLER_STAT1_FAULT_WDG) { // charger_fault = 1; dev_dbg(di->dev, "Fault watchdog fired\n"); } if (stat_reset & CONTROLLER_STAT1_FAULT_WDG) dev_dbg(di->dev, "Fault watchdog recovered\n"); if (stat_set & CONTROLLER_STAT1_BAT_REMOVED) dev_dbg(di->dev, "Battery removed\n"); if (stat_reset & CONTROLLER_STAT1_BAT_REMOVED) dev_dbg(di->dev, "Battery inserted\n"); if (stat_set & CONTROLLER_STAT1_BAT_TEMP_OVRANGE) dev_dbg(di->dev, "Battery temperature overrange\n"); if (stat_reset & CONTROLLER_STAT1_BAT_TEMP_OVRANGE) dev_dbg(di->dev, "Battery temperature within range\n"); if (charger_fault) { change_charge_status(POWER_SUPPLY_STATUS_NOT_CHARGING); dev_err(di->dev, "Charger Fault stop charging\n"); } }
static void cable_detection_work_handler( struct work_struct * work ) // ---------------------------------------------------------------------------- // Description : // Input Argument : // Return Value : None { printk( "cable_detection_work_handler :----------------------------- \n"); struct charger_driver_info *di = container_of( work, struct charger_driver_info, cable_detection_work.work ); int n_usbic_state; int count; int ret; if ( !sec_bci->ready ) { queue_delayed_work( sec_bci->sec_battery_workq, &di->cable_detection_work, HZ ); return; } clear_charge_start_time(); #ifdef CONFIG_USB_SWITCH_FSA9480 n_usbic_state = di->cable_status; #else n_usbic_state = get_real_usbic_state(); #endif printk( "[TA] cable_detection_isr handler. usbic_state: %d\n", n_usbic_state ); if ( sec_bci->charger.use_ta_nconnected_irq ) { if ( gpio_get_value( KTA_NCONN_GPIO ) ) { count = 0; while ( count < 10 ) { if ( gpio_get_value( KTA_NCONN_GPIO ) ) { count++; msleep( 1 ); if ( count == 10 ) { n_usbic_state = -10; printk( "[TA] CABLE UNPLUGGED.\n" ); } } else break; } } } // Workaround for Archer [ if ( !n_usbic_state && sec_bci->charger.use_ta_nconnected_irq ) { if ( !gpio_get_value( KTA_NCONN_GPIO ) ) n_usbic_state = MICROUSBIC_5W_CHARGER; } // ] switch ( n_usbic_state ) { #ifdef CONFIG_USB_SWITCH_FSA9480 case CABLE_TYPE_USB : case CABLE_TYPE_AC : #else case MICROUSBIC_5W_CHARGER : case MICROUSBIC_TA_CHARGER : case MICROUSBIC_USB_CHARGER : case MICROUSBIC_PHONE_USB : case MICROUSBIC_USB_CABLE : #endif if ( sec_bci->charger.cable_status == POWER_SUPPLY_TYPE_USB || sec_bci->charger.cable_status == POWER_SUPPLY_TYPE_MAINS ) { printk( "[TA] already Plugged.\n" ); goto Out_IRQ_Cable_Det; } #ifdef WR_ADC /* Workaround to get proper adc value */ #ifdef CONFIG_USB_SWITCH_FSA9480 if(n_usbic_state != CABLE_TYPE_USB) #else if(n_usbic_state != MICROUSBIC_USB_CABLE) #endif { if ( !di->usb3v1_is_enabled ) { ret = regulator_enable( di->usb3v1 ); if ( ret ) printk("Regulator 3v1 error!!\n"); else di->usb3v1_is_enabled = true; } } twl_i2c_write_u8( TWL4030_MODULE_PM_RECEIVER, REMAP_ACTIVE, TWL4030_VUSB3V1_REMAP ); twl_i2c_write_u8( TWL4030_MODULE_PM_RECEIVER, REMAP_ACTIVE, TWL4030_VINTANA2_REMAP ); msleep( 100 ); #endif /*Check VF*/ sec_bci->battery.battery_vf_ok = check_battery_vf(); /*TA or USB is inserted*/ #ifdef CONFIG_USB_SWITCH_FSA9480 if ( n_usbic_state == CABLE_TYPE_USB ) #else if ( n_usbic_state == MICROUSBIC_USB_CABLE ) #endif { //current : 482mA printk( "[TA] USB CABLE PLUGGED\n" ); change_cable_status( POWER_SUPPLY_TYPE_USB, di, CHARGE_DUR_ACTIVE ); } else { //current : 636mA printk( "[TA] CHARGER CABLE PLUGGED\n" ); change_cable_status( POWER_SUPPLY_TYPE_MAINS, di, CHARGE_DUR_ACTIVE ); } if ( device_config->SUPPORT_CHG_ING_IRQ ) enable_irq( KCHG_ING_IRQ ); break; default: if ( sec_bci->charger.prev_cable_status != POWER_SUPPLY_TYPE_BATTERY && sec_bci->charger.cable_status == POWER_SUPPLY_TYPE_BATTERY ) { printk( "[TA] already Unplugged.\n" ); goto Out_IRQ_Cable_Det; } else if ( sec_bci->charger.prev_cable_status == -1 && sec_bci->charger.cable_status == -1 ) { // first time after booting. printk( "[TA] Fisrt time after bootig.\n" ); goto FirstTime_Boot; } disable_irq( KCHG_ING_IRQ ); #ifdef WR_ADC /* Workaround to get proper adc value */ if ( di->usb3v1_is_enabled ) regulator_disable( di->usb3v1 ); di->usb3v1_is_enabled = false; twl_i2c_write_u8( TWL4030_MODULE_PM_RECEIVER, REMAP_OFF, TWL4030_VUSB3V1_REMAP ); twl_i2c_write_u8( TWL4030_MODULE_PM_RECEIVER, REMAP_OFF, TWL4030_VINTANA2_REMAP ); #endif FirstTime_Boot: /*TA or USB is ejected*/ printk( "[TA] CABLE UNPLUGGED\n" ); change_cable_status( POWER_SUPPLY_TYPE_BATTERY, di, CHARGE_DUR_ACTIVE ); break; } Out_IRQ_Cable_Det: ; #ifdef USE_DISABLE_CONN_IRQ #ifdef MANAGE_CONN_IRQ enable_irq_conn( true ); #else if ( !sec_bci->charger.use_ta_nconnected_irq ) enable_irq( KUSB_CONN_IRQ ); enable_irq( KTA_NCONN_IRQ ); #endif #endif }
int _battery_state_change_(int category, int value) { struct charger_device_info *di; struct platform_device *pdev; int state; pdev = to_platform_device(this_dev); di = platform_get_drvdata(pdev); printk( KERN_INFO "[TA] cate: %d, value: %d, %s\n", category, value, di->dev->kobj.name ); switch (category) { case STATUS_CATEGORY_TEMP: switch (value) { case BATTERY_TEMPERATURE_NORMAL: printk( KERN_INFO "[TA] Charging re start normal TEMP!!\n"); change_charge_status(POWER_SUPPLY_STATUS_RECHARGING_FOR_TEMP); break; case BATTERY_TEMPERATURE_LOW: printk( KERN_INFO "[TA] Charging stop LOW TEMP!!\n"); change_charge_status(POWER_SUPPLY_STATUS_NOT_CHARGING); break; case BATTERY_TEMPERATURE_HIGH: printk( KERN_INFO "[TA] Charging stop HI TEMP!!\n"); change_charge_status(POWER_SUPPLY_STATUS_NOT_CHARGING); break; #ifdef HIGH_TEMP_GAURD_FOR_CAMCORDER case BATTERY_TEMPERATURE_ETC: if(sec_bci->charger.camera_recording && sec_bci->charger.camera_recording_inout){ printk( KERN_INFO "[TA] Charger is set to the USB mode\n"); state = sec_bci->charger.cable_status; sec_bci->charger.cable_status = POWER_SUPPLY_TYPE_USB; enable_charging(); sec_bci->charger.cable_status = state; break; } else { printk( KERN_INFO "[TA] Charger is set to the original mode\n"); enable_charging(); break; } #endif default: break; } break; case STATUS_CATEGORY_CHARGING: switch (value) { case POWER_SUPPLY_STATUS_FULL: printk( KERN_INFO "[TA] Charge FULL(#1)! (monitoring charge current)\n"); change_charge_status(POWER_SUPPLY_STATUS_FULL); break; case POWER_SUPPLY_STATUS_FULL_END: printk( KERN_INFO "[TA] Charge FULL(#2)! (monitoring charge current)\n"); change_charge_status(POWER_SUPPLY_STATUS_FULL_END); break; case POWER_SUPPLY_STATUS_CHARGING_OVERTIME: printk( KERN_INFO "[TA] CHARGING TAKE OVER 6 hours !!\n"); change_charge_status(POWER_SUPPLY_STATUS_FULL_END); break; case POWER_SUPPLY_STATUS_FULL_DUR_SLEEP: printk( KERN_INFO "[TA] Charge FULL!\n"); change_charge_status(POWER_SUPPLY_STATUS_FULL); break; case POWER_SUPPLY_STATUS_RECHARGING_FOR_FULL: printk( KERN_INFO "[TA] Re-Charging Start!!\n"); change_charge_status(POWER_SUPPLY_STATUS_RECHARGING_FOR_FULL); break; default: break; } break; case STATUS_CATEGORY_ETC: switch (value) { case ETC_CABLE_IS_DISCONNECTED: printk( KERN_INFO "[TA] CABLE IS NOT CONNECTED.... Charge Stop!!\n"); change_cable_status(POWER_SUPPLY_TYPE_BATTERY, di); break; default: break; } break; default: printk( KERN_INFO "[TA] Invalid category!!!!!\n"); break; } return 0; }
int _battery_state_change_( int category, int value, bool is_sleep ) // ---------------------------------------------------------------------------- // Description : // Input Argument : // Return Value : { struct charger_driver_info *di; struct platform_device *pdev; pdev = to_platform_device( this_dev ); di = platform_get_drvdata( pdev ); //printk( "[TA] cate: %d, value: %d, %s\n", category, value, di->dev->kobj.name ); if ( category == STATUS_CATEGORY_TEMP ) { switch ( value ) { case BATTERY_TEMPERATURE_NORMAL : printk( "[TA] Charging re start normal TEMP!!\n" ); change_charge_status( POWER_SUPPLY_STATUS_RECHARGING_FOR_TEMP, is_sleep ); break; case BATTERY_TEMPERATURE_LOW : printk( "[TA] Charging stop LOW TEMP!!\n" ); change_charge_status( POWER_SUPPLY_STATUS_NOT_CHARGING, is_sleep ); break; case BATTERY_TEMPERATURE_HIGH : printk( "[TA] Charging stop HI TEMP!!\n" ); change_charge_status( POWER_SUPPLY_STATUS_NOT_CHARGING, is_sleep ); break; default : ; } } else if ( category == STATUS_CATEGORY_CHARGING ) { switch ( value ) { case POWER_SUPPLY_STATUS_FULL : printk( "[TA] Charge FULL! (monitoring charge current)\n" ); change_charge_status( POWER_SUPPLY_STATUS_FULL, is_sleep ); break; case POWER_SUPPLY_STATUS_CHARGING_OVERTIME : printk( "[TA] CHARGING TAKE OVER 5 hours !!\n" ); change_charge_status( POWER_SUPPLY_STATUS_FULL, is_sleep ); break; case POWER_SUPPLY_STATUS_FULL_DUR_SLEEP : printk( "<ta> Charge FULL!\n" ); change_charge_status( POWER_SUPPLY_STATUS_FULL, is_sleep ); break; case POWER_SUPPLY_STATUS_RECHARGING_FOR_FULL : printk( "[TA] Re-Charging Start!!\n" ); change_charge_status( POWER_SUPPLY_STATUS_RECHARGING_FOR_FULL, is_sleep ); break; default : break; } } else if ( category == STATUS_CATEGORY_ETC ) { switch ( value ) { case ETC_CABLE_IS_DISCONNECTED : printk( "[TA] CABLE IS NOT CONNECTED.... Charge Stop!!\n" ); change_cable_status( POWER_SUPPLY_TYPE_BATTERY, di, is_sleep ); break; default : ; } } else { ; } return 0; }