在我们平常的TV,商显,等电子类产品很多是需要遥控器操作的。首先遥控器也是一款标准的设备驱动,一起分享一下M平台遥控器驱动。
设备树
在配置文件m7221_an.dts,中定义了遥控器设备
ir {
compatible = "mstar-ir";
};
这里只配置遥控器设备驱动的名称。
注册驱动
通过设备驱动的名称,可以找到平台驱动code。
static struct platform_driver Mstar_ir_driver = {
.probe = mstar_ir_drv_probe,
.remove = mstar_ir_drv_remove,
.suspend = mstar_ir_drv_suspend,
.resume = mstar_ir_drv_resume,
.driver = {
#if defined(CONFIG_OF)
.of_match_table = mstarir_of_device_ids,
#endif
.name = "Mstar-ir",
.owner = THIS_MODULE,
.bus = &platform_bus_type,
}
};
static int __init mstar_ir_drv_init_module(void)
{
int ret = 0;
// 注册平台驱动
ret = platform_driver_register(&Mstar_ir_driver);
if (ret)
{
IRDBG_ERR("Register Mstar IR Platform Driver Failed!");
}
#ifdef CONFIG_MIRC_INPUT_DEVICE
#if(CONFIG_IR_KEYMAP_MSTAR_NEC)
init_key_map_mstar_tv();
init_key_map_cultraview_tv();
#endif
#if(CONFIG_IR_KEYMAP_TCL_RCA)
init_key_map_tcl_tv();
#endif
#if(CONFIG_IR_KEYMAP_TCL)
init_key_map_tcl_tv();
#endif
#if(CONFIG_IR_KEYMAP_CHANGHONG)
init_key_map_changhong_tv();
#endif
#if(CONFIG_IR_KEYMAP_HISENSE)
init_key_map_hisense_tv();
#endif
#if (CONFIG_IR_KEYMAP_HAIER)
init_key_map_haier_tv();
#endif
#if(CONFIG_IR_KEYMAP_KONKA)
init_key_map_konka_tv();
#endif
#if(CONFIG_IR_KEYMAP_SKYWORTH)
init_key_map_skyworth_tv();
#endif
#if(CONFIG_IR_KEYMAP_PANASONIC_7051)
init_key_map_p7051_stb();
#endif
#if(CONFIG_IR_KEYMAP_KATHREIN)
init_key_map_rc6_kathrein();
#endif
#if(CONFIG_IR_KEYMAP_RC5)
init_key_map_rc5_tv();
#endif
#if(CONFIG_IR_KEYMAP_METZ)
init_key_map_metz_rm18();
init_key_map_metz_rm19();
#endif
#endif
return ret;
}
注册完设备驱动之后,紧接着有注册了多款遥控器,最终通过MIRC_Map_Register将按键映射表添加到链表keymap_list中,
方便后面通过scancode 寻找keycode。
设备探测
/**===============end IR ATTR Functions ==================**/
static int mstar_ir_drv_probe(struct platform_device *pdev)
{
int ret=0;
if (!(pdev->name) || strcmp(pdev->name,"Mstar-ir")|| pdev->id!=0)
{
ret = -ENXIO;
}
IRDev.u32IRFlag = 0;
ret = mstar_ir_cdev_init();
if (ret < 0)
{
IRDBG_ERR("mstar_ir_cdev_init Failed! \n");
}
ret = mstar_ir_creat_sysfs_attr(pdev);
if (ret < 0)
{
IRDBG_ERR("mstar_ir_creat_sysfs_attr Failed! \n");
}
ret = mstar_ir_register_device(pdev);
if (ret < 0)
{
IRDBG_ERR("mstar_ir_register_device Failed! \n");
}
pdev->dev.platform_data=&IRDev;
mstar_ir_customer_config();
#ifdef CONFIG_MIRC_INPUT_DEVICE
mstar_ir_init(0);
IRDev.u32IRFlag |= (IRFLAG_IRENABLE|IRFLAG_HWINITED);
#endif
return ret;
}
mstar_ir_cdev_init 创建字符设备,mstar_ir_creat_sysfs_attr创建硬件设备驱动信息,mstar_ir_register_device 注册遥控器设备,mstar_ir_customer_config设置客户配置,mstar_ir_init 设置遥控器解码方式,注册中断。
注册设备
int mstar_ir_register_device(struct platform_device *pdev)
{
struct mstar_ir_dev *dev = NULL;
int ret;
#ifdef CONFIG_MIRC_INPUT_DEVICE
int i = 0;
#endif
//1. alloc struct ir_dev
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
//2. init locks
spin_lock_init(&dev->keylock);
spin_lock_init(&irq_read_lock);
mutex_init(&dev->lock);
mutex_lock(&dev->lock);
//3. init other args
dev->priv = &IRDev;
//4. init readfifo & sem & waitqueue
ret= kfifo_alloc(&dev->read_fifo,MAX_IR_DATA_SIZE,GFP_KERNEL);
if (ret<0)
{
IRDBG_ERR("ERROR kfifo_alloc!\n");
goto out_dev;
}
sema_init(&dev->sem, 1);
init_waitqueue_head(&dev->read_wait);
#ifdef CONFIG_MIRC_INPUT_DEVICE
//5. alloc struct input_dev
dev->input_dev = input_allocate_device();
if (!dev->input_dev)
{
ret = -ENOMEM;
goto out_kfifo;
}
input_set_drvdata(dev->input_dev, dev);
dev->input_name = MSTAR_IR_DEVICE_NAME;
dev->input_phys = "/dev/ir";
dev->driver_name = MSTAR_IR_DRIVER_NAME;
dev->map_num = NUM_KEYMAP_MSTAR_TV; //default :mstar keymap
//6. init®ister input device
dev->input_dev->id.bustype = BUS_I2C;
dev->input_dev->id.vendor = INPUTID_VENDOR;
dev->input_dev->id.product = INPUTID_PROD