DA9034中断处理

/*
* Micco interrupt service routine.
* In the ISR we need to check the Status bits in Micco and according
* to those bits to check which kind of IRQ had happened.
*/
static irqreturn_t micco_irq_handler(int irq, void *dev_id)
{
struct i2c_client *client = dev_id;
struct micco_platform_data *pdata = client->dev.platform_data;

/* clear the irq */
pdata->ack_irq();

schedule_work(&pdata->work);

return IRQ_HANDLED;
}

static void micco_worker(struct work_struct *work)
{
unsigned int event;
u8 val;

event = micco_event_change();
pmic_event_handle(event);

/* We don't put these codes to USB specific code because
* we need handle it even when no USB callback registered.
*/
if (event & PMIC_EVENT_OTGCP_IOVER) {
/* According to Micco spec, when OTGCP_IOVER happen,
* Need clean the USBPCP_EN in MISC. and then set
* it again.
*/
micco_read(MICCO_MISC, &val);
val &= ~MICCO_MISC_USBCP_EN;
micco_write(MICCO_MISC, val);
val |= MICCO_MISC_USBCP_EN;
micco_write(MICCO_MISC, val);
}
}

static unsigned int micco_event_change(void)
{
unsigned int ret = 0;
u8 val, mask;

micco_read(MICCO_EVENT_A, &val);
if (val & MICCO_EA_ONKEY)
ret |= MICCO_EA_ONKEY;

if (val & MICCO_EA_CHDET)
ret |= PMIC_EVENT_CHDET;

if (val & MICCO_EA_REV_IOVER)
ret |= PMIC_EVENT_REV_IOVER;

if (val & MICCO_EA_IOVER)
ret |= PMIC_EVENT_IOVER;

if (val & MICCO_EA_TBAT)
ret |= PMIC_EVENT_TBAT;

if (val & MICCO_EA_VBATMON)
ret |= PMIC_EVENT_VBATMON;

micco_read(MICCO_EVENT_B, &val);
if (val & MICCO_EB_USB_DEV)
ret |= PMIC_EVENT_VBUS;

if (val & (MICCO_EB_VBUS_4P55|MICCO_EB_VBUS_3P8))
ret |= PMIC_EVENT_VBUS;

if (val & MICCO_EB_SESSION_1P8) {
micco_read(MICCO_IRQ_MASK_B, &mask);
if (!(mask & IRQ_MASK_B_SESSION_VALID_1_8))
ret |= PMIC_EVENT_VBUS;
}

if (val & MICCO_EB_OTGCP_IOVER)
ret |= PMIC_EVENT_OTGCP_IOVER;

micco_read(MICCO_EVENT_C, &val);
if (val & MICCO_EC_PEN_DOWN)
ret |= PMIC_EVENT_TOUCH;

micco_read(MICCO_EVENT_D, &val);
if (val & MICCO_ED_HEADSET)
{
ret |= PMIC_EVENT_HSDETECT;
}

if (val & MICCO_ED_HOOKSWITCH)
{
ret |= PMIC_EVENT_HOOKSWITCH;
}
return ret;
}

int pmic_event_handle(unsigned long event)
{
int ret;
unsigned long flags;
struct pmic_callback *pmic_cb;

ret = check_pmic_ops();
if (ret < 0)
return ret;

spin_lock_irqsave(&pxa3xx_pmic_ops->cb_lock, flags);
list_for_each_entry(pmic_cb, &pxa3xx_pmic_ops->list, list) {
spin_unlock_irqrestore(&pxa3xx_pmic_ops->cb_lock, flags);
/* event is bit-wise parameter, need bit AND here as filter */
if ((pmic_cb->event & event) && (pmic_cb->func))
pmic_cb->func(event);
spin_lock_irqsave(&pxa3xx_pmic_ops->cb_lock, flags);
}
spin_unlock_irqrestore(&pxa3xx_pmic_ops->cb_lock, flags);
return 0;
}
EXPORT_SYMBOL(pmic_event_handle);

比如触摸屏的处理,

DA9034注册的时候调用micco_probe函数将DA9034的中断处理函数注册

ret = request_irq(client->irq, micco_irq_handler, IRQF_TRIGGER_FALLING,
"Micco", client);

触摸屏在注册时将触摸屏的事件和触摸屏中断处理程序注册,通过下面语句注册

ret = pmic_callback_register(PMIC_EVENT_TOUCH, micco_ts_interrupt);

当发生触摸屏中断时调用 micco_irq_handler,接着调用micco_worker,event = micco_event_change();

读出产生中断的事件,调用pmic_event_handle(event);对相应的事件进行处理。

DA9034产生中断后要通过读出事件寄存器的值,才能清除中断,否则中断线不响应后面的中断。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值