一. data structure.
1. i2c_data 数据结构, 这是代表ilitek触摸屏在kernel里的工作状况的一个数据结构。
里面的各项数据在后面都有各自的用处。
// declare i2c data member
struct i2c_data {
// input device
struct input_dev *input_dev; //输入设备
// i2c client
struct i2c_client *client;
// polling thread
struct task_struct *thread;
// maximum x
int max_x;
// maximum y
int max_y;
// maximum touch point
int max_tp;
// maximum key button
int max_btn;
// the total number of x channel
int x_ch;
// the total number of y channel
int y_ch;
// check whether i2c driver is registered success
int valid_i2c_register;
// check whether input driver is registered success
int valid_input_register;
// check whether the i2c enter suspend or not
int stop_polling;
// read semaphore
struct semaphore wr_sem;
// protocol version
int protocol_ver;
// valid irq request
int valid_irq_request;
// work queue for interrupt use only
struct workqueue_struct *irq_work_queue;
// work struct for work queue
struct work_struct irq_work;
struct timer_list timer;
struct completion complete;
#ifdef CONFIG_HAS_EARLYSUSPEND
struct early_suspend early_suspend;
#endif
};
- 2. dev_data.
// device data struct dev_data { // device number dev_t devno; // character device struct cdev cdev; // class device struct class *class; };
- 3. global variables. 声明上述2数据结构的全局变量:
// global variables static struct i2c_data i2c; static struct dev_data dev; static char DBG_FLAG; static char Report_Flag;
- 二、设备驱动:
1. init/exit
/* set init and exit function for this module */ module_init(ilitek_init); module_exit(ilitek_exit); ilitek_init: /* description initiali function for driver to invoke. parameters nothing return status */ static int ilitek_init( void) { int ret = 0; printk(ILITEK_DEBUG_LEVEL "%s\n", __func__); // initialize global variable memset(&dev, 0, sizeof(struct dev_data)); //dev 变量 置为0 memset(&i2c, 0, sizeof(struct i2c_data)); //i2c 变量 置为0 // initialize mutex object #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37) //判断linux版本 init_MUTEX(&i2c.wr_sem); //初始化 信号量 #else sema_init(&i2c.wr_sem,1); //新版初始化信号量方式 #endif i2c.wr_sem.count = 1; //使用的信号量个数 // register i2c device ret = ilitek_i2c_register_device(); //注册I2C设备 if(ret < 0){ printk(ILITEK_ERROR_LEVEL "%s, register i2c device, error\n", __func__); return ret; } // allocate character device driver buffer ret = alloc_chrdev_region(&dev.devno, 0, 1, ILITEK_FILE_DRIVER_NAME); //分配字符设备驱动空间 if(ret){ printk(ILITEK_ERROR_LEVEL "%s, can't allocate chrdev\n", __func__); return ret; } printk(ILITEK_DEBUG_LEVEL "%s, register chrdev(%d, %d)\n", __func__, MAJOR(dev.devno), MINOR(dev.devno)); // initialize character device driver cdev_init(&dev.cdev, &ilitek_fops); //初始化字符设备驱动 dev.cdev.owner = THIS_MODULE; ret = cdev_add(&dev.cdev, dev.devno, 1); //添加字符设备 if(ret < 0){ printk(ILITEK_ERROR_LEVEL "%s, add character device error, ret %d\n", __func__, ret); return ret; } dev.class = class_create(THIS_MODULE, ILITEK_FILE_DRIVER_NAME); //建立class 类。 if(IS_ERR(dev.class)){ printk(ILITEK_ERROR_LEVEL "%s, create class, error\n", __func__); return ret; } device_create(dev.class, NULL, dev.devno, NULL, "ilitek_ctrl"); //建立设备 Report_Flag=0; return 0; }
- ilitek_exit
/* description driver exit function parameters none return nothing */ static void ilitek_exit( void) { #ifdef CONFIG_HAS_EARLYSUSPEND //判断系统是否支持early suspend 模式 unregister_early_suspend(&i2c.early_suspend); //如果支持,则注销early suspend. #endif // delete i2c driver if(i2c.client->irq != 0){ if(i2c.valid_irq_request != 0){ free_irq(i2c.client->irq, &i2c); //释放中断 printk(ILITEK_DEBUG_LEVEL "%s, free irq\n", __func__); if(i2c.irq_work_queue){ destroy_workqueue(i2c.irq_work_queue); //释放工作队列 printk(ILITEK_DEBUG_LEVEL "%s, destory work queue\n", __func__); } } } else{ if(i2c.thread != NULL){ kthread_stop(i2c.thread); //停止i2c thread。 printk(ILITEK_DEBUG_LEVEL "%s, stop i2c thread\n", __func__); } } if(i2c.valid_i2c_register != 0){ i2c_del_driver(&ilitek_i2c_driver); //删除i2c驱动。 printk(ILITEK_DEBUG_LEVEL "%s, delete i2c driver\n", __func__); } if(i2c.valid_input_register != 0){ input_unregister_device(i2c.input_dev); //注销设备。 printk(ILITEK_DEBUG_LEVEL "%s, unregister i2c input device\n", __func__); } // delete characte