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产生中断后要通过读出事件寄存器的值,才能清除中断,否则中断线不响应后面的中断。

 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值