幻想小说网 酷文学 深夜书屋 叮当小说网 找小说网 无限小说网 红尘小说网

DA9034驱动程序阅读笔记(3)

转载时请注明出处和作者联系方式
文章出处:http://www.limodev.cn/blog
作者联系方式:李先静 <xianjimli at hotmail dot com>

DA9034是一个集成了电源管理、音频设备、触摸屏控制器和能用A/D|D/A转换的多功能芯片。最近读了一下相关驱动程序,这里记些笔记,不成体系,作为备忘而已。有兴趣的朋友可以一起讨论。

DA9034有两个输入设备,一个开关机键和触摸屏。

开关机键设备是一个platform device,在littleton.c中定义:

static struct platform_device micco_keys_device =
{
    .name = "micco-keys",
    .id = -1,
};

开关机键的驱动程序在drivers/input/keyboard/micco_keys.c里:

static struct platform_driver micco_keys_driver =
{
    .probe      = micco_keys_probe,
    .remove     = __devexit_p (micco_keys_remove),
    .suspend    = micco_keys_suspend,
    .resume     = micco_keys_resume,
    .driver     =
    {
        .name   = "micco-keys",
    },
};

在micco_keys_probe里会创建一个输入设备。

static int __devinit micco_keys_probe (struct platform_device *pdev)
{
    input_dev = input_allocate_device ();
    ...
    input_dev->name = pdev->name;
    input_dev->id.bustype = BUS_HOST;
    input_dev->open = micco_keys_open;
    input_dev->close = micco_keys_close;
    input_dev->dev.parent = &pdev->dev;
    if (input_register_device (input_dev))
    {
        dev_err (&pdev->dev, "failed to register input device/n");
 
        input_free_device (input_dev);
 
        return -ENOMEM;
    }
 
    g_input_dev = input_dev;
 
    return 0;
}

在micco_keys_open里会注册DA9034的中断处理函数:

static int micco_keys_open (struct input_dev *dev)
{
    unsigned long flags;
 
    spin_lock_irqsave (&g_use_count, flags);
    if (g_use_count == 0)
    {
        if (pmic_callback_register (EVENT_KEYS, micco_keys_interrup) < 0)
        {
            spin_unlock_irqrestore (&g_use_count, flags);
 
            return -1;
        }
        g_use_count ++;
    }
    spin_unlock_irqrestore (&g_use_count, flags);
 
    return 0;
}

在第一篇笔记中,我们已经知道:在micco的中断处理函数中,会调用pmic_event_handle去分发中断事件,我们说过DA9034是一个多功能设备,每个设备都有自己的驱动程序,pmic_event_handle。所以只是一个总入口它只是调用各个实际驱动程序注册的回调函数:

对于开关机键的驱动程序,它注册了函数micco_keys_interrup给pmic_event_handle调用。在micco_keys_interrup函数里,会根据按键的状态上报输入事件。

    if (event & PMIC_EVENT_ONKEY)
    {
        micco_read (MICCO_STATUS_A, &val);
        input_report_key (g_input_dev, KEY_POWER, (val & MICCO_STATUS_A_ONKEY) ? 0 : 1);
    }

触摸屏设备是一个platform device,在littleton.c中定义:

static struct platform_device micco_ts_device = {
    .name       = "micco-ts",
    .id         = -1,
};

触摸屏设备的驱动程序在drivers/input/touchscreen/micco_touch.c里:

static struct platform_driver micco_ts_driver = {
    .driver = {
        .name   = "micco-ts",
    },
    .probe      = micco_ts_probe,
    .remove     = micco_ts_remove,
    .resume     = micco_ts_resume,
    .suspend    = micco_ts_suspend,
};

和开关机键的probe函数一样,micco_ts_probe先注册了一个输入设备,不过还同时做了其它事件:
1. 注册了micco_ts_interrupt给pmic_event_handle调用。
2. 初始化触摸屏相关的寄存器。
3. 创建proc文件。
4. 注册笔点事件的处理函数。

static int micco_ts_probe(struct platform_device *pdev)
{
...
    ret = input_register_device(micco_ts_input_dev);
...
    ret = pmic_callback_register(PMIC_EVENT_TOUCH, micco_ts_interrupt);
...
    micco_enable_pen_down_irq(1);
    micco_tsi_poweron();
    micco_ts_proc_entry = create_proc_entry("driver/micco_ts", 0, NULL);
...
    ts_filter_create_chain (pdev, micco_ts_filter_apis, micco_ts_filter_configs, &micco_ts_filter, 2);
    micco_ts_filter->api->clear (micco_ts_filter);
 
    return 0;
}

在函数micco_ts_open中,创建了一个线程(micco_ts_thread)循环查询触摸屏的状态,对事件进行滤波处理后,上报给用户空间。

在中断处理函数micco_ts_interrupt里,只是唤醒事件处理线程。

posted on 2009-10-30 11:02  张云临  阅读(92)  评论(0编辑  收藏  举报

导航