说明:本分析基于AM6C平台Linux3.0.8内核,其他内核版本仅供参考。
一、platform设备注册的按键映射
common/customer/boards/board-m6tv-h32.c
static struct adc_key adc_kp_key[] = {
{KEY_UP, "vol+", CHAN_0, 821, 60},//k3 //change by tank@tcl.com
{KEY_LEFT, "vol-", CHAN_0, 648, 60},//k4
{KEY_UP, "ch+", CHAN_0, 464, 60},//k5
{KEY_DOWN, "ch-", CHAN_0, 247, 60},//k6
{KEY_ENTER, "power", CHAN_0, 28, 60},//k7
}
/*
struct adc_key{
int code; /* input key code */
unsigned char *name;
int chan;
int value; /* voltage/3.3v * 1023 */
int tolerance;
int gpio_code;
};
*/
static struct adc_kp_platform_data adc_kp_pdata = {
.key = &adc_kp_key[0],
.key_num = ARRAY_SIZE(adc_kp_key),
};
static struct platform_device adc_kp_device = {
.name = "m1-adckp",
.id = 0,
.num_resources = 0,
.resource = NULL,
.dev = {
.platform_data = &adc_kp_pdata,
}
};
platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
static struct platform_device *platform_devs[] = {
......
&adc_kp_device,
......
}
二、驱动
static struct platform_driver kp_driver = {
.probe = kp_probe,
.remove = kp_remove,
.suspend = NULL,
.resume = NULL,
.driver = {
.name = "m1-adckp",
},
};
static int __devinit kp_init(void)
{
printk(KERN_INFO "ADC Keypad Driver init.\n");
return platform_driver_register(&kp_driver);
}
module_init(kp_init);
//
static int __devinit kp_probe(struct platform_device *pdev)
{
struct adc_kp_platform_data *pdata = pdev->dev.platform_data;
kp = kzalloc(sizeof(struct kp), GFP_KERNEL);
platform_set_drvdata(pdev, kp);
kp->input = input_dev;
kp->cur_keycode = 0;
kp->tmp_code = 0;
kp->count = 0;
//注册工作队列update_work_func
INIT_WORK(&(kp->work_update), update_work_func);
//注册时钟中断kp_timer_sr;该时钟中断处理程序的底半部为上处工作队列。
//该底半部由工作队列调度,因此、运行与进程上下文
setup_timer(&kp->timer, kp_timer_sr, (unsigned int)kp);
/*
void kp_timer_sr(unsigned long data)
{
struct kp *kp_data=(struct kp *)data;
schedule_work(&(kp_data->work_update));
mod_timer(&kp_data->timer,jiffies+msecs_to_jiffies(10));
}
*/
mod_timer(&kp->timer, jiffies+msecs_to_jiffies(100));
kp->key = pdata->key;
kp->key_num = pdata->key_num;
adckp_set_keypad(kp);
}