电容屏驱动,输入设备注册,I2C设备注册,中断注册,虽然没有完全调试成功

SSL_TSC.C

/* multi_touch_xx.c - Part of lm_sensors, Linux kernel modules for hardware monitoring Copyright (C) 1998, 1999 Frodo Looijaard <[email protected]> and Philip Edelbrock <[email protected]> Copyright (C) 2003 Greg Kroah-Hartman <[email protected]> Copyright (C) 2003 IBM Corp. 2004-01-16 Jean Delvare <[email protected]> Divide the multi_touch_xx in 32-byte (arbitrary) slices. This significantly speeds sensors up, as well as various scripts using the multi_touch_xx module. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * What this driver doesn't yet support: * * - SPI * - INT2 handling * - Pulse detection (and the sysctls to control it) */ #include <linux/cdev.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/jiffies.h> #include <linux/interrupt.h> #include <linux/i2c.h> #include <linux/mutex.h> #include <linux/input.h> #include <asm/gpio.h> #include <linux/delay.h> #include <asm/irq.h> #include <linux/irq.h> /* Size of multi_touch_xx in bytes */ int NASTECH_TS_MAJOR = 60; #define SLAVE_ADD 0x60 #define TOUCH_INT_PIN GPIO_NUM(0,29) /* Use our own dbg macro */ #define dbg(format, arg...) printk("----[%s: %d]: " format , __FUNCTION__ , __LINE__, ## arg) #define mmadbg(format, arg...) printk("----[%s: %d]: " format , __FUNCTION__ , __LINE__, ## arg) /* Addresses to scan */ static unsigned short normal_i2c[] = { 0x60, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD; //I2C_CLIENT_INSMOD_1(multi_touch_xx); static int irq_no=-1; /* Each client has this additional data */ static int nastech_i2c_continue_read(struct i2c_client *clinet, u8* buffer, u8 len); typedef struct { u32 u32X; /* X coordinate, 0~2047 */ u32 u32Y; /* Y coordinate, 0~2047 */ u8 u8Finger; /* Number of fingers in the touch event */ u32 u32Dis_X; /* X distance between two fingers */ u32 u32Dis_Y; /* Y distance between two fingers. This value could be negative */ } TOUCH_DATA_st; static struct work_struct nas_works; static struct i2c_client *myI2C_client=NULL; struct nas_cdev { struct cdev *cdev; }; /* Structure for Input Type*/ struct nas_ts_priv { uint32_t local_irq; struct nas_cdev cdev; TOUCH_DATA_st *touchData; //struct i2c_client *client; struct i2c_client *client; struct input_dev *input; //int reported_finger_count; u16 keybuff[20]; // number of key K1 K2 ...K5 #ifdef REPORTALL u16 prekeybuff[20]; // number of key K1 K2 ...K5 #endif char phys[32]; }; static struct nas_ts_priv *nas_priv = NULL; #define ST_PEN_UP 0 #define ST_PEN_DOWN 1 u8 Calculate_8BitsChecksum( u8 *msg, s32 s32Length ) { s32 s32Checksum = 0; s32 i; for ( i = 0 ; i < s32Length; i++ ) { s32Checksum += msg[i]; } return (u8)( ( -s32Checksum ) & 0xFF ); } #define REPORT_PACKET_LENGTH 8 void nas_ts_irq_callback(void) { // read coordinate thought I2C u8 val[REPORT_PACKET_LENGTH] = {0}; u8 Checksum = 0; nas_priv->touchData->u32X = 0; nas_priv->touchData->u32Y = 0; nas_priv->touchData->u32Dis_X = 0; nas_priv->touchData->u32Dis_Y = 0; nas_priv->touchData->u8Finger = 0; printk("**************************/n"); printk("***nas_ts_irq_callback***/n"); printk("**************************/n"); static bool pen_updown = false; //1(true) for down, 0(false) for up static bool pre_pen_updown = ST_PEN_UP; myI2C_client = nas_priv->client; if(nastech_i2c_continue_read(myI2C_client,&val[0], REPORT_PACKET_LENGTH ) >= 0) { Checksum = Calculate_8BitsChecksum( val, (REPORT_PACKET_LENGTH-1) ); if ( ( Checksum == val[7] && val[0] == 0x52 ) ) // Check the packet ID(0x52)and checksum { /* parsing the coordinate report packet */ /* MSG20XX EVK report format */ /* * +---------------------------------+ * byte[0] | Packet ID ( 0x52 ) | * +----------------+----------------+ * byte[1] | u32X[11:8] | u32Y[11:8] | * +---------------------------------+ * byte[2] | u32X[7:0] | * +---------------------------------+ * byte[3] | u32Y[7:0] | * +----------------+----------------+ * byte[4] | u32Dis_X[11:8] | u32Dis_Y[11:8] | * +----------------+----------------+ * byte[5] | u32Dis_X[7:0] | * +---------------------------------+ * byte[6] | u32Dis_Y[7:0] | * +---------------------------------+ * byte[7] | Checksum | * +---------------------------------+ */ nas_priv->touchData->u32X = ( val[1] & 0xF0 ) << 4 | val[2]; nas_priv->touchData->u32Y = ( val[1] & 0x0F )<< 8 | val[3]; nas_priv->touchData->u32Dis_X = ( val[4] & 0xF0 ) << 4 | val[5]; nas_priv->touchData->u32Dis_Y = ( val[4] & 0x0F ) << 8 | val[6]; printk("<<<<<<<<<data<<<<<<<<<<<<</n"); printk("<x=%d,y=%d,dx=%d,dy=%d,</n",nas_priv->touchData->u32X,nas_priv->touchData->u32Y,nas_priv->touchData->u32Dis_X,nas_priv->touchData->u32Dis_Y); printk("<<<<<<<<<data<<<<<<<<<<<<</n"); if ( nas_priv->touchData->u32X == 0xFFF && nas_priv->touchData->u32Y == 0xFFF && nas_priv->touchData->u32X == 0xFFF && nas_priv->touchData->u32Y == 0xFFF ) { /* The coordinate report stands for a Touch-End event */ /* Inform the OS or system mailbox that the Touch-End event happened */ } else { /* The coordinate report stands for Touch-On-Panel event */ if ( nas_priv->touchData->u32Dis_X == 0 && nas_priv->touchData->u32Dis_Y == 0 ) { /* If the distance values are zero, the TP detects one-finger-touch event */ nas_priv->touchData->u8Finger = 1; } else if ( nas_priv->touchData->u32Dis_X <= 2047 && nas_priv->touchData->u32Dis_Y <= 2047 ) { /* If the distance values are valid, the TP detects two-finger-touch event */ nas_priv->touchData->u8Finger = 2; } else { #ifdef DEBUG printk(" /* Fetal error */n/* Discard the invalid coordinate reports due to fetal error. *//n"); #endif } } } else { /* Packet error happened. */ /* Check I2C signal quality and I2C master codes */ } input_report_abs(nas_priv->input, ABS_X, nas_priv->touchData->u32X); input_report_abs(nas_priv->input, ABS_Y, nas_priv->touchData->u32Y); input_report_abs(nas_priv->input, ABS_HAT0X, nas_priv->touchData->u32Dis_X); input_report_abs(nas_priv->input, ABS_HAT0Y, nas_priv->touchData->u32Dis_Y); input_sync(nas_priv->input); } } static void nastech_ts_work(struct work_struct *work) { nas_ts_irq_callback(); } static int multi_touch_xx_probe(struct i2c_client *client,const struct i2c_device_id *id); static int __devexit multi_touch_xx_remove(struct i2c_client *client); static const struct i2c_device_id multi_touch_xx_id[]={ {"multi_touch_xx",0}, {} }; /* This is the driver that will be inserted */ static struct i2c_driver multi_touch_xx_driver = { .driver = { .name = "multi_touch_xx", .owner = THIS_MODULE, }, //.id = I2C_DRIVERID_multi_touch_xx, .probe = multi_touch_xx_probe, .remove = __devexit_p(multi_touch_xx_remove), .id_table = multi_touch_xx_id, }; static irqreturn_t nastech_ts_isr(int irq, void *dev_id) { //disable_irq(ON_TOUCH_INT); disable_irq(&nas_priv->local_irq); schedule_work(&nas_works); enable_irq( &nas_priv->local_irq); return IRQ_HANDLED; } static int nastech_i2c_continue_read(struct i2c_client *clinet, u8* buffer, u8 len) { //unsigned char buffer[8]; int rc; //buffer[0] = addr; if (1 != (rc = i2c_master_send(clinet, 0x60, 1))) { //printk("i2c i/o error: rc == %d (should be 1)/n", rc); mmadbg("i2c i/o error: rc == %d (should be 1)/n", rc); } //msleep(10); if (1 != (rc = i2c_master_recv(clinet, &buffer[0], len))) { //dbg("i2c i/o error: rc == %d (should be 1)/n", rc); mmadbg("i2c i/o error: rc == %d (should be 1)/n", rc); } printk(">>> nastech_i2c_continue_read>>>>>>>>>>>%x,>>>>>>>>>>>>/n",buffer[0]); dbg("read : addr:value = 0x%x:0x%x/n", 0x60, buffer[0] ); return (buffer[0]); } static int multi_touch_xx_probe(struct i2c_client *client,const struct i2c_device_id *id) { u8 value[8]; int err = 0; uint32_t irq; struct i2c_client *new_client; //struct nas_ts_data *nastech_data; struct input_dev *pInput_dev; static struct nas_ts_priv *nas_priv = NULL; INIT_WORK(&nas_works, nastech_ts_work); /*----------------------i2c init---------------------*/ printk("/***************************/n"); printk("/*******multi_touch_xx_probe********************/n"); printk("/***************************/n"); //================================// // Register as I2C Client // //================================// if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { goto exit; } printk(">>>>>>after check_functionality/n"); if(!(nas_priv=kzalloc(sizeof(struct nas_ts_priv), GFP_KERNEL))) { err = -ENOMEM; goto exit; } printk(">>>>>>after zalloc/n"); nas_priv->client=kzalloc(sizeof(struct i2c_client),GFP_KERNEL); new_client=nas_priv->client; //=====================================================================================================================// //nas_priv->nas_ts_datap = nastech_data; printk(">1oc/n"); //nas_priv->client = &nastech_data->client; printk("2loc/n"); i2c_set_clientdata(new_client,nas_priv); //printk(">>>>>>after i2c_set_clientdata/n"); nas_priv->client->addr = 0x60; printk(">>>3oc/n"); nas_priv->client->adapter = client->adapter; printk(">>4alloc/n"); nas_priv->client->driver = &multi_touch_xx_driver; printk(">5c/n"); nas_priv->client->flags = 0; printk(">>>6alloc/n"); //=====================================================================================================================// // Touch Panel Setting & Calibrate // //=====================================================================================================================// //=====================================================================================================================// //================================// // Register as Input Device // //================================// printk(">>>>>>before input allocate/n"); pInput_dev = input_allocate_device(); printk(">>>>>>after input allocate/n"); if(!pInput_dev) { printk(KERN_ERR"[%s - %d] malloc memory for pInput_dev ERR!/n", __FUNCTION__, __LINE__); goto exit_kfree; } printk("input/n"); nas_priv->input=pInput_dev; nas_priv->input->evbit[0] = BIT_MASK (EV_SYN)| BIT_MASK (EV_ABS) | BIT_MASK (EV_KEY) ;//mult touch nas_priv->input->keybit [BIT_WORD (BTN_TOUCH)] = BIT_MASK (BTN_TOUCH); // printk("input_set_abs_params/n"); input_set_abs_params(nas_priv->input, ABS_X, 0, 1791, 0, 0);//³]©wµŽ¹ï®yŒÐªº³Ì€j­È»P³Ì€p­È input_set_abs_params(nas_priv->input, ABS_Y, 0, 1023, 0, 0);//³]©wµŽ¹ï®yŒÐªº³Ì€j­È»P³Ì€p­È input_set_abs_params(nas_priv->input, ABS_HAT0X, 0, 1791, 0, 0);//³]©wµŽ¹ï®yŒÐªº³Ì€j­È»P³Ì€p­È input_set_abs_params(nas_priv->input, ABS_HAT0Y, 0, 1023, 0, 0);//³]©wµŽ¹ï®yŒÐªº³Ì€j­È»P³Ì€p­È printk(" after input_set_abs_params/n"); //sprintf(nas_priv->phys, "ts0"); //nas_priv->input->private = nas_priv; //???? nas_priv->input->name = "nastech_ts"; nas_priv->input->phys = nas_priv->phys; nas_priv->input->id.bustype = BUS_I2C; nas_priv->input->id.vendor = 0x2011; nas_priv->input->id.product = 0x0800; //nas_priv->input->id.version = NASTECH_TS_VERSION; //=====================================================================================================================// if(input_register_device(nas_priv->input)) { printk(KERN_ERR"[%s - %d] input_register_device for auo-tp2 err!/n", __FUNCTION__, __LINE__); goto exit_kfree; } printk(" after input_register_device/n"); nastech_i2c_continue_read(nas_priv->client,&value[0],8); printk(" after icontinue_read_device%x,/n",value[0]); // register the GPIO inerrupt gpio_direction_input(TOUCH_INT_PIN); irq = gpio_to_irq(TOUCH_INT_PIN); nas_priv->local_irq = irq; set_irq_type(irq, IRQ_TYPE_EDGE_FALLING); if( request_irq(irq, nastech_ts_isr,IRQF_DISABLED|IRQF_TRIGGER_FALLING, "nastech_ts", (void *)nas_priv->input)) { input_free_device(pInput_dev); goto exit_kfree; } enable_irq(&nas_priv->local_irq); return 0; exit_kfree: kfree(nas_priv->client); exit: destroy_workqueue (&nas_works); unregister_chrdev_region(MKDEV(NASTECH_TS_MAJOR, 0), 1); cdev_del(&nas_priv->cdev); kfree(nas_priv); return err; return err; } //static int multi_touch_xx_detach_client(struct i2c_client *client) static int __devexit multi_touch_xx_remove(struct i2c_client *client) { struct multi_touch_xx_info *data = i2c_get_clientdata(client); kfree(data); dbg("no err, return /n"); return 0; } uint32_t ssltsc_vbat(void) { return 0; } static int __init multi_touch_xx_init(void) { dbg("register the driver/n"); dbg("init multi_touch_xx/n"); printk("***********************/n"); printk("**********multi_touch_xx_init*************/n"); printk("***********************/n"); return i2c_add_driver(&multi_touch_xx_driver); } static void __exit multi_touch_xx_exit(void) { dbg("exit multi_touch_xx/n"); i2c_del_driver(&multi_touch_xx_driver); } MODULE_AUTHOR("Maggie Qiu <[email protected]>"); MODULE_DESCRIPTION("I2C multi_touch_xx driver 

 

 

 

 

static const struct s35390a_platform_data multi_touch_xx = { .irq1 = 1, .irq2 = gpio_to_irq(GPIO_NUM(0,29)), }; static struct i2c_board_info __initdata _i2c[] = { { I2C_BOARD_INFO("mma7455l", 0x1D), .platform_data = &mma7455l, }, { I2C_BOARD_INFO("multi_touch_xx", 0x60), .platform_data = &multi_touch_xx, }, }; 

 

电容屏驱动,输入设备注册,I2C设备注册,中断注册,虽然没有完全调试成功_第1张图片

 

i2c_register_board_info(0, _i2c, ARRAY_SIZE(_i2c));

你可能感兴趣的:(c,struct,report,buffer,input,distance)