简介
中断接口函数有两种,一种是标准的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; }