MT6737 平台TP driver分析(一)

1.makefie
\kernel-3.18\drivers\input\touchscreen\mediatek\makefile
这里写图片描述

2.
kernel-3.18\drivers\input\touchscreen\mediatek\tpd_common_probe.c
这里写图片描述

在驱动加载函数tpd_probe_init中直接调用了tpd_device_init函数

3
kernel-3.18\drivers\input\touchscreen\mediatek\mtk_tpd.c
这里写图片描述

在tpd_device_init函数中创建并初始化工作队列tpd_init_work,对应的callback函数为tpd_init_work_callback,之后通过queue_work调度运行该工作队列.那么再来看这个callback回调函数
这里写图片描述
在回调函数中直接调用了平台驱动注册函数,注册tpd_driver驱动

这里写图片描述

继续分析tpd_driver驱动的probe函数tpd_probe
kernel-3.18\drivers\input\touchscreen\mediatek\mtk_tpd.c

static int tpd_probe(struct platform_device *pdev)
{
    int touch_type = 1; /* 0:R-touch, 1: Cap-touch */
    int i = 0;
#ifndef CONFIG_CUSTOM_LCM_X
#ifdef CONFIG_LCM_WIDTH
        unsigned long tpd_res_x = 0, tpd_res_y = 0;
        int ret = 0;
#endif
#endif

    TPD_DMESG("enter %s, %d\n", __func__, __LINE__);

    if (misc_register(&tpd_misc_device))//注册混杂设备驱动
        pr_err("mtk_tpd: tpd_misc_device register failed\n");
    tpd_get_gpio_info(pdev);//gpio配置信息
    tpd = kmalloc(sizeof(struct tpd_device), GFP_KERNEL);
    if (tpd == NULL)
        return -ENOMEM;
    memset(tpd, 0, sizeof(struct tpd_device));

    /* allocate input device */
    tpd->dev = input_allocate_device();//分配一个输入设备结构体
    if (tpd->dev == NULL) {
        kfree(tpd);
        return -ENOMEM;
    }
    /* TPD_RES_X = simple_strtoul(LCM_WIDTH, NULL, 0); */
    /* TPD_RES_Y = simple_strtoul(LCM_HEIGHT, NULL, 0); */

    #ifdef CONFIG_MTK_LCM_PHYSICAL_ROTATION
    if (0 == strncmp(CONFIG_MTK_LCM_PHYSICAL_ROTATION, "90", 2)
        || 0 == strncmp(CONFIG_MTK_LCM_PHYSICAL_ROTATION, "270", 3)) {
#ifdef CONFIG_MTK_FB    /*Fix build errors,as some projects  cannot support these apis while bring up*/
        TPD_RES_Y = DISP_GetScreenWidth();
        TPD_RES_X = DISP_GetScreenHeight();
#endif
    } else
    #endif
    {
#ifdef CONFIG_CUSTOM_LCM_X
#ifndef CONFIG_MTK_FPGA
#ifdef CONFIG_MTK_FB    /*Fix build errors,as some projects  cannot support these apis while bring up*/
        TPD_RES_X = DISP_GetScreenWidth();
        TPD_RES_Y = DISP_GetScreenHeight();
#else/*for some projects, we do not use mtk framebuffer*/
        TPD_RES_X = tpd_dts_data.tpd_resolution[0];
        TPD_RES_Y = tpd_dts_data.tpd_resolution[1];
#endif
#endif
#else
#ifdef CONFIG_LCM_WIDTH
        ret = kstrtoul(CONFIG_LCM_WIDTH, 0, &tpd_res_x);
        if (ret < 0) {
            pr_err("Touch down get lcm_x failed");
            return ret;
        }
        TPD_RES_X = tpd_res_x;
        ret = kstrtoul(CONFIG_LCM_HEIGHT, 0, &tpd_res_y);
        if (ret < 0) {
            pr_err("Touch down get lcm_y failed");
            return ret;
        }
        TPD_RES_Y = tpd_res_y;
#endif
#endif
    }

    if (2560 == TPD_RES_X)
        TPD_RES_X = 2048;
    if (1600 == TPD_RES_Y)
        TPD_RES_Y = 1536;
    pr_debug("mtk_tpd: TPD_RES_X = %lu, TPD_RES_Y = %lu\n", TPD_RES_X, TPD_RES_Y);

    tpd_mode = TPD_MODE_NORMAL;
    tpd_mode_axis = 0;
    tpd_mode_min = TPD_RES_Y / 2;
    tpd_mode_max = TPD_RES_Y;
    tpd_mode_keypad_tolerance = TPD_RES_X * TPD_RES_X / 1600;
    /* struct input_dev dev initialization and registration */
    tpd->dev->name = TPD_DEVICE;//初始化输入设备input_dev
    set_bit(EV_ABS, tpd->dev->evbit);
    set_bit(EV_KEY, tpd->dev->evbit);
    set_bit(ABS_X, tpd->dev->absbit);
    set_bit(ABS_Y, tpd->dev->absbit);
    set_bit(ABS_PRESSURE, tpd->dev->absbit);
#if !defined(CONFIG_MTK_S3320) && !defined(CONFIG_MTK_S3320_47)\
    && !defined(CONFIG_MTK_S3320_50) && !defined(CONFIG_MTK_MIT200) \
    && !defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S3528) && !defined(CONFIG_MTK_S7020) \
    && !defined(CONFIG_TOUCHSCREEN_MTK_SYNAPTICS_3320_50)
    set_bit(BTN_TOUCH, tpd->dev->keybit);
#endif /* CONFIG_MTK_S3320 */
    set_bit(INPUT_PROP_DIRECT, tpd->dev->propbit);

    /* save dev for regulator_get() before tpd_local_init() */
    tpd->tpd_dev = &pdev->dev;
    for (i = 1; i < TP_DRV_MAX_COUNT; i++) {
        /* add tpd driver into list */
        if (tpd_driver_list[i].tpd_device_name != NULL) {
            tpd_driver_list[i].tpd_local_init();//调用具体TP驱动的tpd_local_init函数,具体的tp驱动在注册时肯定会有一个这样的tpd_local_init函数
            /* msleep(1); */
            if (tpd_load_status == 1) {
                TPD_DMESG("[mtk-tpd]tpd_probe, tpd_driver_name=%s\n",
                      tpd_driver_list[i].tpd_device_name);
                g_tpd_drv = &tpd_driver_list[i];
                break;
            }
        }
    }
    if (g_tpd_drv == NULL) {
        if (tpd_driver_list[0].tpd_device_name != NULL) {
            g_tpd_drv = &tpd_driver_list[0];
            /* touch_type:0: r-touch, 1: C-touch */
            touch_type = 0;
            g_tpd_drv->tpd_local_init();
            TPD_DMESG("[mtk-tpd]Generic touch panel driver\n");
        } else {
            TPD_DMESG("[mtk-tpd]cap touch and Generic touch both are not loaded!!\n");
            return 0;
        }
    }
    touch_resume_workqueue = create_singlethread_workqueue("touch_resume");
    INIT_WORK(&touch_resume_work, touch_resume_workqueue_callback);
    /* use fb_notifier */
    tpd_fb_notifier.notifier_call = tpd_fb_notifier_callback;
    if (fb_register_client(&tpd_fb_notifier))
        TPD_DMESG("register fb_notifier fail!\n");
    /* TPD_TYPE_CAPACITIVE handle */
    if (touch_type == 1) {
        set_bit(ABS_MT_TRACKING_ID, tpd->dev->absbit);
        set_bit(ABS_MT_TOUCH_MAJOR, tpd->dev->absbit);
        set_bit(ABS_MT_TOUCH_MINOR, tpd->dev->absbit);
        set_bit(ABS_MT_POSITION_X, tpd->dev->absbit);
        set_bit(ABS_MT_POSITION_Y, tpd->dev->absbit);
        input_set_abs_params(tpd->dev, ABS_MT_POSITION_X, 0, TPD_RES_X, 0, 0);
        input_set_abs_params(tpd->dev, ABS_MT_POSITION_Y, 0, TPD_RES_Y, 0, 0);
#if defined(CONFIG_MTK_S3320) || defined(CONFIG_MTK_S3320_47) \
    || defined(CONFIG_MTK_S3320_50) || defined(CONFIG_MTK_MIT200) \
    || defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S3528) || defined(CONFIG_MTK_S7020) \
    || defined(CONFIG_TOUCHSCREEN_MTK_SYNAPTICS_3320_50)
        input_set_abs_params(tpd->dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
        input_set_abs_params(tpd->dev, ABS_MT_WIDTH_MAJOR, 0, 15, 0, 0);
        input_set_abs_params(tpd->dev, ABS_MT_WIDTH_MINOR, 0, 15, 0, 0);
        input_mt_init_slots(tpd->dev, 10, 0);
#else
        input_set_abs_params(tpd->dev, ABS_MT_TOUCH_MAJOR, 0, 100, 0, 0);
        input_set_abs_params(tpd->dev, ABS_MT_TOUCH_MINOR, 0, 100, 0, 0);
#endif /* CONFIG_MTK_S3320 */
        TPD_DMESG("Cap touch panel driver\n");
    }
    input_set_abs_params(tpd->dev, ABS_X, 0, TPD_RES_X, 0, 0);
    input_set_abs_params(tpd->dev, ABS_Y, 0, TPD_RES_Y, 0, 0);
    input_abs_set_res(tpd->dev, ABS_X, TPD_RES_X);
    input_abs_set_res(tpd->dev, ABS_Y, TPD_RES_Y);
    input_set_abs_params(tpd->dev, ABS_PRESSURE, 0, 255, 0, 0);
    input_set_abs_params(tpd->dev, ABS_MT_TRACKING_ID, 0, 10, 0, 0);

    if (input_register_device(tpd->dev))//注册输入设备tpd->dev
        TPD_DMESG("input_register_device failed.(tpd)\n");
    else
        tpd_register_flag = 1;
    if (g_tpd_drv->tpd_have_button)
        tpd_button_init();

    if (g_tpd_drv->attrs.num)
        tpd_create_attributes(&pdev->dev, &g_tpd_drv->attrs);

    return 0;
}

以上主要是MTK平台tp驱动的通用框架,主要分析了两个文件.
kernel-3.18\drivers\input\touchscreen\mediatek\tpd_common_probe.c
kernel-3.18\drivers\input\touchscreen\mediatek\mtk_tpd.c

猜你喜欢

转载自blog.csdn.net/yuewen2008/article/details/79105133