1. 程式人生 > >MT6735平臺GPIO中斷除錯記錄

MT6735平臺GPIO中斷除錯記錄

dws檔案配置:kernel-3.10/tools/dct/drvgen.exe 

bootable/bootloader/lk/target/mt6735_66t_a19/dct/dct/codegen.dws

bootable/bootloader/preloader/custom/mt6735_66t_a19/dct/dct/codegen.dws

kernel-3.10/drivers/misc/mediatek/mach/mt6735/mt6735_66t_a19/dct/dct/codegen.dws

vendor/mediatek/proprietary/custom/mt6735_66t_a19/kernel/dct/dct/codegen.dws

MTK中斷IC驅動:kernel-3.10/drivers/irqchip/irq-mt-eic.c

 函式:mt_eint_irq_set_type 即設定中斷到暫存器。

struct irq_chip mt_irq_eint = {
   .name       = "mt-eint",
   .irq_mask   = mt_eint_irq_mask,
   .irq_unmask = mt_eint_irq_unmask,
   .irq_ack    = mt_eint_irq_ack,
   .irq_set_type   = mt_eint_irq_set_type,
};

linux 驅動設定介面:kernel-3.10/kernel/irq/manage.c

主要流程:request_irq --> request_threaded_irq  --> __irq_set_trigger

MTK平臺似乎不支援同時上升沿及下降沿觸發。

switch_data->irq = gpio_to_irq(switch_data->gpio);
if (switch_data->irq < 0) {
ret = switch_data->irq;
goto err_detect_irq_num_failed;
}
flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | 0;
irq_set_irq_type(switch_data->irq, IRQ_TYPE_EDGE_BOTH);
    DBLOG("request_irq: irq=%d, flag=%lu\n", switch_data->irq, flags);
    ret = request_irq(switch_data->irq, gpio_irq_handler, flags, pdata->name, switch_data);
    if (ret < 0) {
        DBLOG("%s: request_irq fail ret=%d\n", __func__, ret);
        goto err_request_irq;
    }
    enable_irq_wake(switch_data->irq);
/* Perform initial detection */
//gpio_switch_work(&switch_data->work);


移除驅動時注意input devices 裝置 input_unregister_device後再/input_free_device會有問題。


static int dbatt_switch_remove(struct platform_device *pdev) {
    struct gpio_switch_data *switch_data = platform_get_drvdata(pdev);


DBLOG("%s: entry\n", __func__);
    disable_irq_wake(switch_data->irq);
    free_irq(switch_data->irq, switch_data);
    gpio_free(switch_data->gpio);
    gpio_free(DBATT_MBATID_DET_PIN);
    gpio_free(DBATT_SWITCH_EN_PIN);
    input_unregister_device(switch_data->input_dev);
    //input_free_device(switch_data->input_dev);
    kfree(switch_data);
    
#ifdef DBATT_HALL_STATUS_NOTIFY
    device_remove_file(&pdev->dev, &hall_dev_attr);
#endif


return 0;
}