中断函数接口

Chinese, Simplified

简介

中断接口函数有两种,一种是标准的Linux接口,一般用于系统irq。一种是mtk自定义的接口,一般用于外部中断。目前建议用第二种方法。

 

接口代码路径

kernel/drivers/irqchip/irq-mt-eic.c

kernel/include/linux/interrupt.h

kernel/kernel/irq/manage.c

接口函数使用方法。

Linux 标准接口

中断注册函数:

static inline int __must_check

request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,const char *name, void *dev)

 

举例:

request_irq(touch_irq, (irq_handler_t)tpd_eint_interrupt_handler, EINTF_TRIGGER_RISING, "TOUCH_PANEL-eint", NULL);

中断号,debounce时间,触发电平等参数一般是从dts解析而来。

Mtk 自定义中断接口

中断注册函数:

void mt_eint_registration(unsigned int eint_num, unsigned int flag, void (EINT_FUNC_PTR) (void), unsigned int is_auto_umask)

参数说明:

eint_num: 中断号

flag: 中断触发方式等,如下降沿触发。

EINT_FUNC_PTR: 中断处理函数

is_auto_umask:中断处理结束后是否自动un mask 中断。

举例,接近传感器cm36652中断注册:

mt_eint_registration(CUST_EINT_ALS_NUM,CUST_EINT_ALS_TYPE, cm36652_eint_func, 0);

 

中断硬件debounce时间设置函数:

void mt_eint_set_hw_debounce(unsigned int gpio_pin, unsigned int ms)

 

下面贴段完整的参考代码:

 

 
int cm36652_setup_eint(struct i2c_client *client)
{
#ifdef CUSTOM_KERNEL_SENSORHUB
    int err = 0;
 
    err = SCP_sensorHub_rsp_registration(ID_PROXIMITY, cm36652_irq_handler);
#else //#ifdef CUSTOM_KERNEL_SENSORHUB
 
#if defined(CONFIG_OF)
    u32 ints[2] = {0, 0};
#endif
 
    mt_set_gpio_dir(GPIO_ALS_EINT_PIN, GPIO_DIR_IN);
    mt_set_gpio_mode(GPIO_ALS_EINT_PIN, GPIO_ALS_EINT_PIN_M_EINT);
    mt_set_gpio_pull_enable(GPIO_ALS_EINT_PIN, TRUE);
    mt_set_gpio_pull_select(GPIO_ALS_EINT_PIN, GPIO_PULL_UP);
 
#if defined(CONFIG_OF)
    if (cm36652_obj->irq_node)
    {
        of_property_read_u32_array(cm36652_obj->irq_node, "debounce", ints, ARRAY_SIZE(ints));
        mt_gpio_set_debounce(ints[0], ints[1]);
        APS_LOG("ints[0] = %d, ints[1] = %d!!\n", ints[0], ints[1]);
 
        cm36652_obj->irq = irq_of_parse_and_map(cm36652_obj->irq_node, 0);
        APS_LOG("cm36652_obj->irq = %d\n", cm36652_obj->irq);
        if (!cm36652_obj->irq)
        {
            APS_ERR("irq_of_parse_and_map fail!!\n");
            return -EINVAL;
        }  
       
        if(request_irq(cm36652_obj->irq, cm36652_eint_handler, IRQF_TRIGGER_NONE, "ALS-eint", NULL)) {
            APS_ERR("IRQ LINE NOT AVAILABLE!!\n");
            return -EINVAL;
        }  
       
        enable_irq(cm36652_obj->irq);
    }  
    else
    {
        APS_ERR("null irq node!!\n");
        return -EINVAL;
    }
#elif defined(CUST_EINT_ALS_TYPE)
    mt_eint_set_hw_debounce(CUST_EINT_ALS_NUM, CUST_EINT_ALS_DEBOUNCE_CN);
    mt_eint_registration(CUST_EINT_ALS_NUM, CUST_EINT_ALS_TYPE, cm36652_eint_func, 0);
    mt_eint_unmask(CUST_EINT_ALS_NUM);
#else
    mt65xx_eint_set_sens(CUST_EINT_ALS_NUM,CUST_EINT_ALS_SENSITIVE);
mt65xx_eint_set_polarity(CUST_EINT_ALS_NUM,CUST_EINT_ALS_POLARITY);
mt65xx_eint_set_hw_debounce(CUST_EINT_ALS_NUM,CUST_EINT_ALS_DEBOUNCE_CN);
mt65xx_eint_registration(CUST_EINT_ALS_NUM,CUST_EINT_ALS_DEBOUNCE_EN, CUST_EINT_ALS_POLARITY, cm36652_eint_func, 0);
 
#endif
 
#endif //#ifdef CUSTOM_KERNEL_SENSORHUB
    return 0;
}


文档中心

以上内容是否对您有帮助?