示例#1
0
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");
	}

}
示例#2
0
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
}
示例#3
0
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;
}
示例#4
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;

}