/* * vt1603_bat_work - vt1603 battery workqueue routine, switch * vt1603 working mode to battery detecting * @work: battery work struct */ static void vt1603_bat_work(struct work_struct *work) { int tmp = 0; int timeout, i = 0; int bat_arrary[DFLT_BAT_VAL_AVG]={0}; struct vt1603_bat_drvdata *bat_drv; dbg("Enter\n"); bat_drv = container_of(work, struct vt1603_bat_drvdata, work); if (unlikely(vt1603_get_pen_state(bat_drv) == TS_PENDOWN_STATE)) { dbg("vt1603 pendown when battery detect\n"); goto out; } /* enable sar-adc power and clock */ vt1603_bat_power_up(bat_drv); /* enable pen down/up to avoid miss irq */ vt1603_bat_pen_manual(bat_drv); /* switch vt1603 to battery detect mode */ vt1603_switch_to_bat_mode(bat_drv); /* do conversion use battery manual mode */ vt1603_setbits(bat_drv, VT1603_INTS_REG, BIT0); vt1603_set_reg8(bat_drv, VT1603_CR_REG, BIT4); for(i=0; i<DFLT_BAT_VAL_AVG; i++){ timeout = 2000; while(--timeout && (vt1603_get_reg8(bat_drv, VT1603_INTS_REG) & BIT0)==0) ; if(timeout){ if(vt1603_get_bat_data(bat_drv,&bat_arrary[i]) < 0) dbg_err("vt1603 get bat adc data Failed!\n"); }else { dbg_err("wait adc end timeout ?!\n"); goto out; } vt1603_setbits(bat_drv, VT1603_INTS_REG, BIT0); vt1603_set_reg8(bat_drv, VT1603_CR_REG, BIT4);//start manual ADC mode } tmp = vt1603_bat_avg(bat_arrary,DFLT_BAT_VAL_AVG); bat_drv->bat_new = tmp; vt1603_fifo_push(&Bat_buf, tmp); vt1603_fifo_avg(Bat_buf, &tmp); bat_drv->bat_val = tmp; //printk(KERN_ERR"reported battery val:%d, new val:%d\n",tmp, bat_drv->bat_new); out: vt1603_clrbits(bat_drv, VT1603_INTCR_REG, BIT7); vt1603_setbits(bat_drv, VT1603_INTS_REG, BIT0 | BIT3); vt1603_set_reg8(bat_drv, VT1603_CR_REG, BIT1); mod_timer(&bat_drv->bat_tmr, jiffies + msecs_to_jiffies(DFLT_POLLING_BAT_INTERVAL* 1000)); dbg("Exit\n\n\n"); return ; }
static void vt1603_gpio1_low_active_setup(struct vt1603_bat_drvdata *bat_drv) { /* mask other module interrupts */ vt1603_set_reg8(bat_drv, VT1603_IMASK_REG27, 0xFF); vt1603_set_reg8(bat_drv, VT1603_IMASK_REG28, 0xFF); vt1603_set_reg8(bat_drv, VT1603_IMASK_REG29, 0xFF); /* gpio1 low active */ vt1603_set_reg8(bat_drv, VT1603_IPOL_REG33, 0xFF); /* vt1603 gpio1 as IRQ output */ vt1603_set_reg8(bat_drv, VT1603_ISEL_REG36, 0x04); /* clear vt1603 irq */ vt1603_setbits(bat_drv, VT1603_INTS_REG, BIT0 | BIT1 | BIT2 | BIT3); }
static int vt1603_bat_alarm_setup(struct vt1603_bat_drvdata *bat_drv, u8 threshold, int wk_src) { dbg("Enter\n"); /* register setting */ vt1603_set_reg8(bat_drv, VT1603_PWC_REG, 0x08); vt1603_set_reg8(bat_drv, VT1603_CR_REG, 0x00); vt1603_set_reg8(bat_drv, VT1603_AMCR_REG, 0x01); vt1603_set_reg8(bat_drv, VT1603_BTHD_REG, threshold & 0xFF); vt1603_clrbits(bat_drv, VT1603_BAEN_REG, BIT2); vt1603_setbits(bat_drv, VT1603_BAEN_REG, BIT1 | BIT0); vt1603_set_reg8(bat_drv, VT1603_BCLK_REG, 0x28); /* vt1603 gpio1 setup */ vt1603_gpio1_low_active_setup(bat_drv); /* wakeup setup */ wm8650_wakeup_init(wk_src); dbg("Exit\n"); return 0; }
static inline void vt1603_bat_pen_manual(struct vt1603_bat_drvdata *bat_drv) { vt1603_setbits(bat_drv, VT1603_INTCR_REG, BIT7); }
/* * vt1603_bat_work - vt1603 battery workqueue routine, switch * vt1603 working mode to battery detecting * @work: battery work struct */ static void vt1603_bat_work(struct work_struct *work) { u8 tmp = 0; u16 val = 0; int tout = 0; unsigned long now = 0; struct vt1603_bat_drvdata *bat_drv; bat_dbg("Enter\n"); bat_drv = container_of(work, struct vt1603_bat_drvdata, work); if (unlikely(vt1603_get_pen_state(bat_drv) == TS_PENDOWN_STATE)) { bat_dbg("vt1603 pendown when battery detect\n"); tout = 1000; goto out; } /* enable sar-adc power and clock */ vt1603_bat_power_up(bat_drv); /* enable pen down/up to avoid miss irq */ vt1603_bat_pen_manual(bat_drv); /* switch vt1603 to battery detect mode */ vt1603_switch_to_bat_mode(bat_drv); /* do conversion use battery manual mode */ vt1603_setbits(bat_drv, VT1603_INTS_REG, BIT0); if (vt1603_get_reg8(bat_drv, VT1603_AMCR_REG) != 0x01) { tout = 1000; bat_dbg("vt1603 battery channel changed already?\n"); goto out; } vt1603_set_reg8(bat_drv, VT1603_CR_REG, BIT4); now = jiffies; while (time_before(jiffies, now + msecs_to_jiffies(POLL_TOUT))) { tmp = vt1603_get_reg8(bat_drv, VT1603_INTS_REG); if (tmp & BIT0) { val = vt1603_get_bat_convert_data(bat_drv); bat_dbg("vt1603 battery value is %d\n", val); if (vt1603_get_reg8(bat_drv, VT1603_AMCR_REG) != 0x01) { tout = 1000; bat_dbg("vt1603 battery channel changed already?\n"); goto out; } if (val < 2048) { tout = 1000; printk(KERN_ERR "vt1603 battery conversion failed?!\n"); goto out; } bat_drv->bat_val = val; bat_drv->detect_time++; bat_drv->time_stamp = jiffies; tout = bat_drv->interval; goto out; } } bat_dbg("vt1603 battery detect failed, conversion timeout!\n"); tout = 1000; goto out; out: vt1603_clrbits(bat_drv, VT1603_INTCR_REG, BIT7); vt1603_setbits(bat_drv, VT1603_INTS_REG, BIT0 | BIT3); vt1603_set_reg8(bat_drv, VT1603_CR_REG, BIT1); mod_timer(&bat_drv->bat_tmr, jiffies + msecs_to_jiffies(tout)); bat_dbg("Exit\n\n\n"); return ; }