Beispiel #1
0
/*
 * Interrupt service routine
 * 
 * Attends to BCI interruptions events, 
 * specifically BATSTS (battery connection and removal)
 * VBATOV (main battery voltage threshold) events
 * 
 */
static irqreturn_t twl4030battery_interrupt(int irq, void *dev_id)
{
	int ret;
	u8 isr1a_val, isr2a_val, clear_2a, clear_1a;

	if ((ret = twl4030_i2c_read_u8(TWL4030_MODULE_INTERRUPTS, &isr1a_val, 
				REG_BCIISR1A)))	
		return IRQ_NONE;
	
	if ((ret = twl4030_i2c_read_u8(TWL4030_MODULE_INTERRUPTS, &isr2a_val, 
				REG_BCIISR2A)))
		return IRQ_NONE;
	
	clear_2a = (isr2a_val & VBATLVL_ISR1)? (VBATLVL_ISR1): 0;
	clear_1a = (isr1a_val & BATSTS_ISR1)? (BATSTS_ISR1): 0;
	
	/* cleaning BCI interrupt status flags */
	if ((ret = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 
			clear_1a , REG_BCIISR1A)))
	return IRQ_NONE;
	
	if ((ret = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 
			clear_2a , REG_BCIISR2A)))
	return IRQ_NONE;
		
			
	/* battery connetion or removal event */
	if (isr1a_val & BATSTS_ISR1)
	{
		ret = twl4030battery_presence_evt();
		if (ret == -ENXIO)
		{
			twl4030battery_hw_presence_en(EVT_DISABLE);
			return IRQ_HANDLED;
		}
		if (ret)
			return IRQ_NONE;		
	}
		
	/* battery voltage threshold event*/
	else if (isr2a_val & VBATLVL_ISR1)
	{
		ret = twl4030battery_level_evt();
		if (ret == -ENXIO)
		{
			twl4030battery_hw_level_en(EVT_DISABLE);
			return IRQ_HANDLED;
		}	
		if (ret)
			return IRQ_NONE;
	}
	/* Only for debuging purpouses this branch never be taken */
	else
		return IRQ_NONE;
			
	return IRQ_HANDLED;		
}
Beispiel #2
0
/*
 * API function
 * 
 * Registers the event handler structure
 * 
 * Return 	0	on success
 *     		<0	on failure
 */
int twl4030battery_event_register(struct twl4030battery_events events)
{
	twl4030battery_event.battery_level = events.battery_level;
	twl4030battery_event.battery_presence = events.battery_presence;
	twl4030battery_event.charger_presence = events.charger_presence;
	twl4030battery_event.bci_status = events.bci_status;
	
	twl4030battery_event.battery_sw_level_event_cfg = (
		events.battery_sw_level_event_cfg & (EVT_LVL_4_EN |
		EVT_LVL_3_EN | EVT_LVL_2_EN | EVT_LVL_1_EN)) ;
	
	if(events.battery_level == NULL)
	{
		twl4030battery_hw_level_en(EVT_DISABLE);
	}
	else
	{
		twl4030battery_hw_level_en(EVT_ENABLE);
		twl4030battery_level_evt();	
	}
	
	if(events.battery_presence == NULL)
	{
		twl4030battery_hw_presence_en(EVT_DISABLE);
	}
	else
	{
		twl4030battery_hw_presence_en(EVT_ENABLE);
		twl4030battery_presence_evt();
	}
	
	if(events.charger_presence == NULL)
	{
		twl4030charger_hw_presence_en(EVT_DISABLE);
	}
	else
	{
		twl4030charger_hw_presence_en(EVT_ENABLE);
		twl4030charger_presence_evt();
	}
	
	if(events.bci_status == NULL)
	{
		twl4030bci_sw_status_en(EVT_DISABLE);
		flush_scheduled_work();
	}
	else
	{
		twl4030bci_status_tmr.expires = jiffies + CHG_STS_DLY;
		add_timer(&twl4030bci_status_tmr);
		twl4030battery_event.temp_std = -1;
		twl4030bci_status_evt();
	}
	
	return 0;
}
Beispiel #3
0
/*
 * Interrupt service routine
 *
 * Attends to BCI interruptions events,
 * specifically BATSTS (battery connection and removal)
 * VBATOV (main battery voltage threshold) events
 *
 */
static irqreturn_t twl4030battery_interrupt(int irq, void *_di)
{
	u8 uninitialized_var(isr1a_val), uninitialized_var(isr2a_val);
	u8 clear_2a, clear_1a;
	int ret;

#ifdef CONFIG_LOCKDEP
	/* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
	 * we don't want and can't tolerate.  Although it might be
	 * friendlier not to borrow this thread context...
	 */
	local_irq_enable();
#endif

	ret = twl4030_i2c_read_u8(TWL4030_MODULE_INTERRUPTS, &isr1a_val,
				REG_BCIISR1A);
	if (ret)
		return IRQ_NONE;

	ret = twl4030_i2c_read_u8(TWL4030_MODULE_INTERRUPTS, &isr2a_val,
				REG_BCIISR2A);
	if (ret)
		return IRQ_NONE;

	clear_2a = (isr2a_val & VBATLVL_ISR1) ? (VBATLVL_ISR1) : 0;
	clear_1a = (isr1a_val & BATSTS_ISR1) ? (BATSTS_ISR1) : 0;

	/* cleaning BCI interrupt status flags */
	ret = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS,
			clear_1a , REG_BCIISR1A);
	if (ret)
		return IRQ_NONE;

	ret = twl4030_i2c_write_u8(TWL4030_MODULE_INTERRUPTS,
			clear_2a , REG_BCIISR2A);
	if (ret)
		return IRQ_NONE;

	/* battery connetion or removal event */
	if (isr1a_val & BATSTS_ISR1)
		twl4030battery_presence_evt();
	/* battery voltage threshold event*/
	else if (isr2a_val & VBATLVL_ISR1)
		twl4030battery_level_evt();
	else
		return IRQ_NONE;

	return IRQ_HANDLED;
}