Beispiel #1
0
void battery_set_charging_allowed(int allowed)
{
	charging_allowed = allowed;

	if (!allowed)
		disable_charging();
}
Beispiel #2
0
static void bat_removal_detection_work_handler(struct work_struct *work)
{
	sec_bci->battery.battery_vf_ok = check_battery_vf();
	if (!sec_bci->battery.battery_vf_ok) {
		disable_charging();
	}
	disable_irq(BAT_REMOVAL_IRQ);

	return;
}
Beispiel #3
0
void battery_callback()
{
	if (!charging_allowed)
		return;

	adc_configure(&batt_adc_config);
    BATTERY_VOLTAGE_TRIS = 1;
	BATTERY_VOLTAGE_DIGITAL = 0;

    adc_set_channel(1);
    last_battery_voltage = adc_convert_one();

    //Disable charging if battery voltage is greater than max charge level
    if (last_battery_voltage >= kBatteryChargedLevel)
    	disable_charging();
    else if (last_battery_voltage < kBatteryHysteresisLevel) //Reenable charging once battery level falls below hysteresis
    	enable_charging();
}
Beispiel #4
0
static void change_charge_status(int status)
{

	switch (status) {
	case POWER_SUPPLY_STATUS_UNKNOWN:
	case POWER_SUPPLY_STATUS_NOT_CHARGING:
	case POWER_SUPPLY_STATUS_DISCHARGING:
		if (sec_bci->battery.battery_health != POWER_SUPPLY_HEALTH_DEAD)
			disable_charging();

#ifdef HIGH_TEMP_GAURD_FOR_CAMCORDER
		sec_bci->charger.camera_recording_inout = 0;
#endif
		break;

	case POWER_SUPPLY_STATUS_FULL:
		break;

	case POWER_SUPPLY_STATUS_FULL_END:
		sec_bci->charger.rechg_count = 4;
		/*Cancel timer */
		clear_charge_start_time();

		disable_charging();
		break;
		
	case POWER_SUPPLY_STATUS_CHARGING:

		if (sec_bci->battery.battery_vf_ok) {
			sec_bci->battery.battery_health = POWER_SUPPLY_HEALTH_GOOD;

			/*Start monitoring charging time */
			set_charge_start_time();

			enable_charging();
			break;

		} else {
			sec_bci->battery.battery_health = POWER_SUPPLY_HEALTH_DEAD;

			status = POWER_SUPPLY_STATUS_DISCHARGING;

			printk( KERN_INFO "[TA] INVALID BATTERY, %d !! \n", status);

			disable_charging();
			break;

		}

	case POWER_SUPPLY_STATUS_RECHARGING_FOR_FULL:
		/*Start monitoring charging time */
		sec_bci->charger.charging_timeout = DEFAULT_RECHARGING_TIMEOUT;
		set_charge_start_time();

		enable_charging();

		break;

	case POWER_SUPPLY_STATUS_RECHARGING_FOR_TEMP:
		enable_charging();
		break;

	default:
		;
	}

	sec_bci->charger.prev_charge_status = sec_bci->charger.charge_status;
	sec_bci->charger.charge_status = status;

	_charger_state_change_(STATUS_CATEGORY_CHARGING, status);

}
Beispiel #5
0
static int __devinit charger_probe( struct platform_device *pdev )
// ----------------------------------------------------------------------------
// Description    : probe function for charger driver.
// Input Argument : 
// Return Value   : 
{

	int ret = 0;
	int irq = 0;
	struct charger_driver_info *di;
	
	printk( "[TA] Charger probe...\n" );

	sec_bci = get_sec_bci();

	di = kzalloc( sizeof(*di), GFP_KERNEL );
	if (!di)
		return -ENOMEM;

	platform_set_drvdata( pdev, di );
	di->dev = &pdev->dev;
	device_config = pdev->dev.platform_data;

	/* printk( "%d, %d, %d\n ",
			device_config->VF_CHECK_USING_ADC,
			device_config->VF_ADC_PORT,
			device_config->SUPPORT_CHG_ING_IRQ);*/

	this_dev = &pdev->dev; 

	/*Init Work*/
	INIT_DELAYED_WORK( &di->cable_detection_work, cable_detection_work_handler );
	INIT_DELAYED_WORK( &di->full_charge_work, full_charge_work_handler );

// [ USE_REGULATOR
	di->usb3v1 = regulator_get( &pdev->dev, "usb3v1" );
	if( IS_ERR( di->usb3v1 ) )
		goto fail_regulator1;

	di->usb1v8 = regulator_get( &pdev->dev, "usb1v8" );
	if( IS_ERR( di->usb1v8 ) )
		goto fail_regulator2;

	di->usb1v5 = regulator_get( &pdev->dev, "usb1v5" );
	if( IS_ERR( di->usb1v5 ) )
		goto fail_regulator3;
// ]

	/*Request charger interface interruption*/

#ifndef CONFIG_USB_SWITCH_FSA9480
#ifdef USE_DISABLE_CONN_IRQ
#ifdef MANAGE_CONN_IRQ
	is_enabling_conn_irq = false;
#endif
#endif

	KUSB_CONN_IRQ = platform_get_irq( pdev, 0 );
	if ( KUSB_CONN_IRQ ) // if this irq was null, we use ta_nconnected gpio to detect cable.
	{
		set_irq_type( KUSB_CONN_IRQ, IRQ_TYPE_EDGE_BOTH );
		ret = request_irq( KUSB_CONN_IRQ, cable_detection_isr, 
				IRQF_DISABLED | IRQF_SHARED, pdev->name, di );
		if ( ret )
		{
			printk( "[TA] 1. could not request irq %d, status %d\n", KUSB_CONN_IRQ, ret );
			goto usb_irq_fail;
		}
#ifdef USE_DISABLE_CONN_IRQ
		disable_irq( KUSB_CONN_IRQ );
#endif
	}
	else
#endif
	{
		sec_bci->charger.use_ta_nconnected_irq = true;
	}

	KTA_NCONN_IRQ = platform_get_irq( pdev, 1 );

	if ( sec_bci->charger.use_ta_nconnected_irq )
		KTA_NCONN_GPIO = irq_to_gpio( KTA_NCONN_IRQ );

#ifndef CONFIG_USB_SWITCH_FSA9480
#ifdef USE_IRQ_LEVEL_TRIGGER
	if(KTA_NCONN_GPIO) {
		if ( gpio_get_value( KTA_NCONN_GPIO ) )
			set_irq_type( KTA_NCONN_IRQ, IRQ_TYPE_LEVEL_LOW );
		else
			set_irq_type( KTA_NCONN_IRQ, IRQ_TYPE_LEVEL_HIGH );
	}
#else
	set_irq_type( KTA_NCONN_IRQ, IRQ_TYPE_EDGE_BOTH );
#endif

	ret = request_irq( KTA_NCONN_IRQ, cable_detection_isr, IRQF_DISABLED, pdev->name, di );
	if ( ret )
	{
		printk( "[TA] 2. could not request irq %d, status %d\n", KTA_NCONN_IRQ, ret );
		goto ta_irq_fail;
	}

#ifdef USE_DISABLE_CONN_IRQ
	disable_irq( KTA_NCONN_IRQ );
#endif
#endif

	KCHG_ING_IRQ = platform_get_irq( pdev, 2 );
	KCHG_ING_GPIO = irq_to_gpio( KCHG_ING_IRQ );
	printk( "[TA] CHG_ING IRQ : %d \n", KCHG_ING_IRQ );
	printk( "[TA] CHG_ING GPIO : %d \n", KCHG_ING_GPIO );

	if ( device_config->SUPPORT_CHG_ING_IRQ )
	{
		ret = request_irq( KCHG_ING_IRQ, full_charge_isr, IRQF_DISABLED, pdev->name, di ); 
		set_irq_type( KCHG_ING_IRQ, IRQ_TYPE_EDGE_RISING );
		if ( ret )
		{
			printk( "[TA] 3. could not request irq2 %d, status %d\n",
				IH_USBIC_BASE, ret );
			goto chg_full_irq_fail;
		}
		disable_irq( KCHG_ING_IRQ );
	}

	KCHG_EN_GPIO = irq_to_gpio( platform_get_irq( pdev, 3 ) );
	printk( "[TA] CHG_EN GPIO : %d \n", KCHG_EN_GPIO );

	/*disable CHE_EN*/
	disable_charging( CHARGE_DUR_ACTIVE );

#ifdef CONFIG_USB_SWITCH_FSA9480
	di->callbacks.set_cable = charger_set_cable;
	if (device_config->register_callbacks)
		device_config->register_callbacks(&di->callbacks);
#endif

	//schedule_delayed_work( &di->cable_detection_work, 5*HZ );
	queue_delayed_work( sec_bci->sec_battery_workq, &di->cable_detection_work, HZ );

	return 0;


chg_full_irq_fail:
	irq = platform_get_irq( pdev, 1 );
	free_irq( irq, di );

ta_irq_fail:
	irq = platform_get_irq( pdev, 0 );
	free_irq( irq, di );

usb_irq_fail:
// [ USE_REGULATOR
	regulator_put( di->usb1v5 );
	di->usb1v5 = NULL;

fail_regulator3:
	regulator_put( di->usb1v8 );
	di->usb1v8 = NULL;

fail_regulator2:
	regulator_put( di->usb3v1 );
	di->usb3v1 = NULL;

fail_regulator1:
// ]
	kfree(di);

	return ret;
}
Beispiel #6
0
static bool check_battery_vf( void )
{
	int count = 0;
	int val;
	bool ret = false;

#if 0
	count = 0;
	disable_charging( CHARGE_DUR_ACTIVE );
	msleep( 100 );
	enable_charging( CHARGE_DUR_ACTIVE );
	val = gpio_get_value( KCHG_ING_GPIO );
	if ( !val )
		return true;
	
	while ( count < 10 )
	{
		if ( !gpio_get_value( KCHG_ING_GPIO ) )
			return true;

		count++;
		msleep( 1 );
	}

	if ( !ret && device_config->VF_CHECK_USING_ADC )
	{
#if 0
		int i;
		int val[5];
		for ( i = 0; i < 5 ; i++ )
		{
			val[i] = _get_t2adc_data_( device_config->VF_ADC_PORT );
		}

		count = _get_average_value_( val, 5 );
#else
		count = _get_t2adc_data_( device_config->VF_ADC_PORT );
#endif
		
		printk("vf: %d\n", count);
		if ( count < 100 )
			return true;
	}
	
	disable_charging( CHARGE_DUR_ACTIVE );
#elif 0
	if ( device_config->VF_CHECK_USING_ADC )
	{
		int i;
		int val[5];
		
		for ( i = 0; i < 5 ; i++ )
		{
			val[i] = _get_t2adc_data_( device_config->VF_ADC_PORT );
			if ( val[i] >= 100 )
			{
				printk( "vf: %d\n", val[i] );
				return false;
			}
			msleep( 100 );
		}

		count = _get_average_value_( val, 5 );
		printk("vf: %d\n", count);
		if ( count < 100 )
			return true;
		
/*		count = _get_t2adc_data_( device_config->VF_ADC_PORT );		
		printk("vf: %d\n", count);
		if ( count < 100 )
			return true;*/
	}
	else
	{
		count = 0;
		disable_charging( CHARGE_DUR_ACTIVE );
		msleep( 100 );
		enable_charging( CHARGE_DUR_ACTIVE );
		val = gpio_get_value( KCHG_ING_GPIO );
		if ( !val )
			return true;
		
		while ( count < 10 )
		{
			if ( !gpio_get_value( KCHG_ING_GPIO ) )
				return true;

			count++;
			msleep( 1 );
		}

		disable_charging( CHARGE_DUR_ACTIVE );

	}
#else
	count = 0;
	disable_charging( CHARGE_DUR_ACTIVE );
	msleep( 100 );
	enable_charging( CHARGE_DUR_ACTIVE );
	val = gpio_get_value( KCHG_ING_GPIO );
	if ( !val )
	{
		ret = true;
	}
	
	while ( count < 10 )
	{
		if ( !gpio_get_value( KCHG_ING_GPIO ) )
		{
			ret = true;
			break;
		}

		count++;
		msleep( 1 );
	}

	disable_charging( CHARGE_DUR_ACTIVE );

	if ( !ret &&  device_config->VF_CHECK_USING_ADC )
	{
		int i;
		int val[5];
		
		for ( i = 0; i < 5 ; i++ )
		{
			val[i] = _get_t2adc_data_( device_config->VF_ADC_PORT );
			msleep( 100 );
		}

		count = _get_average_value_( val, 5 );
		printk("vf: %d\n", count);
		if ( count < 200)
			return true;
	}

#endif
	return ret;
}
Beispiel #7
0
static void change_charge_status( int status, bool is_sleep )
// ----------------------------------------------------------------------------
// Description    : 
// Input Argument :  
// Return Value   : 
{

	switch ( status )
	{
	case POWER_SUPPLY_STATUS_UNKNOWN :
	case POWER_SUPPLY_STATUS_DISCHARGING :
	case POWER_SUPPLY_STATUS_NOT_CHARGING :
		disable_charging( is_sleep );
		break;

	case POWER_SUPPLY_STATUS_FULL :
		disable_charging( is_sleep );
		/*Cancel timer*/
		clear_charge_start_time();

		break;

	case POWER_SUPPLY_STATUS_CHARGING :

		if ( sec_bci->battery.battery_vf_ok )
		{
			sec_bci->battery.battery_health = POWER_SUPPLY_HEALTH_GOOD;

			/*Start monitoring charging time*/
			set_charge_start_time();

			enable_charging( is_sleep );
		}
		else
		{
			sec_bci->battery.battery_health = POWER_SUPPLY_HEALTH_DEAD;

			status = POWER_SUPPLY_STATUS_NOT_CHARGING;

			disable_charging( is_sleep );

			printk( "[TA] INVALID BATTERY, %d !! \n", status );
		}

		break;

	case POWER_SUPPLY_STATUS_RECHARGING_FOR_FULL :
		/*Start monitoring charging time*/
		sec_bci->charger.charging_timeout = DEFAULT_RECHARGING_TIMEOUT;
		set_charge_start_time();

		enable_charging( is_sleep );

		break;
		
	case POWER_SUPPLY_STATUS_RECHARGING_FOR_TEMP :
		enable_charging( is_sleep );
		break;

	default :
		;
	}

	sec_bci->charger.prev_charge_status = sec_bci->charger.charge_status;
	sec_bci->charger.charge_status = status;

	_charger_state_change_( STATUS_CATEGORY_CHARGING, status, is_sleep );

}
int main(int argc, char *argv[])
{
    char *file_name = "/dev/battery";
    int fd;
    enum
    {
        e_get,
        e_clr,
        e_set
    } option;

    if (argc == 1)
    {
        option = e_get;
    }
    else if (argc == 2)
    {
        if (strcmp(argv[1], "-g") == 0)
        {
            option = e_get;
        }
        else if (strcmp(argv[1], "-c") == 0)
        {
            option = e_clr;
        }
        else if (strcmp(argv[1], "-s") == 0)
        {
            option = e_set;
        }
        else
        {
            fprintf(stderr, "Usage: %s [-g | -c | -s]\n", argv[0]);
            return 1;
        }
    }
    else
    {
        fprintf(stderr, "Usage: %s [-g | -c | -s]\n", argv[0]);
        return 1;
    }
    fd = open(file_name, O_RDWR);
    if (fd == -1)
    {
        perror("query_apps open");
        return 2;
    }

    switch (option)
    {
    case e_get:
        get_vars(fd);
        break;
    case e_clr:
        disable_charging(fd);
        break;
    case e_set:
        enable_charge(fd);
        break;
    default:
        break;
    }

    close (fd);

    return 0;
}
static void update_charge_state(void)
{
	int module_type = 0;
	int usb_type;

	if( _usb && !_dcin ) {
		// usb without DC-in
		usb_type = atmega_io_getUsbType();
DBG 		printk("usb_type=%d\n", usb_type);

		if (usb_type & USB_LOCAL) {
			if ( usb_charge_level() ) {
				enable_high_charging();
			} else {
				enable_low_charging();
			}
		} else if (usb_type == USB_EXT) {
			module_type = atmega_io_getModuleType();
DBG 			printk("module_type=%d\n", module_type);

			if ( module_type == MODULE_ID_SERIAL_ADAPTER ) {
				enable_low_charging();
			} else {
				disable_charging();
			}
		} else {
			// no charge with only ext usb & can't happen when plugging the PC cable
			disable_charging();
		}
		goto out;
	}

	if( _dcin && !_usb ){
		// ! warning ! this case should appears with pc_cable during plug or with
		// not complete connection, don't enable high charge in this case
		// enable high charge only if an allowed module is identified
		module_type = atmega_io_getModuleType();
DBG 		printk("module_type=%d\n", module_type);

		if ( is_module_capable_high_charging(module_type) ) {
			enable_high_charging();
		}
		goto out;
	}

	if( _usb && _dcin ){
		// Means normally that both the USB cable and DC-in are plugged.
		// But be careful that both flags are also enabled when plugging the PC cable
		module_type = atmega_io_getModuleType();
DBG 		printk("module_type=%d\n", module_type);

		if ( is_module_capable_high_charging(module_type) ) {
			enable_high_charging();
		} else {	// pc cable only or pc cable and micro usb
			usb_type = atmega_io_getUsbType();
DBG 			printk("usb_type=%d\n", usb_type);

			if (usb_type == USB_EXT) {		// pc cable only
				if ( usb_charge_level() ) {
					enable_high_charging();
				} else {
					enable_low_charging();
				}
			} else	// in this case, usb source to check is not the power source
				enable_low_charging();

		}	
		goto out;
	}

	if( charge_state && ( !_usb && !_dcin )){
		disable_charging();	
		goto out;
	}
	
 out:
#ifdef CONFIG_POWER_SUPPLY
	 power_supply_changed(&main_battery);
#endif
	 /* make compiler happy if CONFIG_POWER_SUPPLY is not defined */
	 return;
}