RK3066 遥控器流程
1. 先看看配置的驱动程序
2. 查找在哪个配置文件中配置了上述选项,便可以知道驱动程序的源程序了。
3. 分析源程序
#vi kernel/drivers/input/remotectl/rkxx_remotectl.c
1. 先看看配置的驱动程序
#vi kernel/.config
CONFIG_RECKCHIP_REMOTECTL=y
CONFIG_RK_REMOTECTL=y
2. 查找在哪个配置文件中配置了上述选项,便可以知道驱动程序的源程序了。
#vi kernel/drivers/input/remotectl/Kconfig
menuconfig ROCKCHIP_REMOTECTL
bool "rkxx remotectl"
default y
help
...
if ROCKCHIP_REMOTECTL
config RK_REMOTECTL
bool "rkxx remotectl"
default y
...
endif
#vi kernel/drivers/input/remotectl/Makefile
obj-$(CONFIG_RK_REMOTECTL) += rkxx_remotectl.o
可以知道,如果配置了 RK_REMOTECTL为y,则把rkxx_remotectl.o放入内核,这个rkxx_remotectl.o会对应一个rkxx_remotectl.c文件
3. 分析源程序
#vi kernel/drivers/input/remotectl/rkxx_remotectl.c
static int __devinit remotectl_probe(struc platform_device *pdev)
{
struct RKxx_remotectl_platform_data *pdata; //存放遥控器平台数据的结构体
pdata = pdev->dev.platform_data;
struc rkxx_remotectl_drvdata *ddata; //存放驱动数据的结构体,比如当前按键状态,按键码,当前时间等等信息
...
ddata = kzalloc(sizeof(struct rkxx_remotectl_drvdata),GFP_KERNEL); //对任何结构体使用之前一定要分配内存
memset(ddata, 0, sizeof(struct rkxx_remotectl_drvdata)); //清空数据,以免有“脏”数据
ddata->state = RMC_PRELAOD; //设定此时的状态,总共有typedef enum _RMC_STATE{RMC_IDLE,RMC_PRELOAD,RMC_USERCODE,RMC_GETDATA,RMC_SEQUENCE}eRMC_STATE这么几个状态
input = input_allocate_device(); //分配一个输入设备。对应input_free_device,释放一个输入设备
platform_set_drvdata(pdev,ddata); //通过指针指向,让平台设备和这个驱动连接起来
//为输入设备设置一些信息
input->name = pdev->name;
input->phys = "gpio-keys/input0";
input->dev.parent = &pdev->dev;
input->id.bustype = BUS_HOST;
input->id.vendor = 0x0001;
input->id.product = 0x0001;
input->id.version = 0x0100;
if(pdata->rep) //假如驱动支持自动重复功能
__set_bit(EV_REP, input->evbit); //使用Linux子系统的自动重复功能(Enable auto repeat feature of Linux input subsystem)
ddata->input = input; //驱动的input指向这个input
wake_lock_init(&ddata->remotectl_wake_lock, WAKE_LOCK_SUSPEND,"rk29_remote"); //初始化这个锁