Button input interrupt under linux kernel 2.6.35.7 send message to touch screen

来源:互联网 发布:思迪软件科技 编辑:程序博客网 时间:2024/05/16 06:29

/**************************************************************** * OFN/ts.c * * Copyright (c) 2011-11-24 * * light*****************************************************************/#include <linux/module.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/interrupt.h>#include <linux/irq.h>#include <linux/sched.h>#include <linux/pm.h>#include <linux/sysctl.h>#include <linux/proc_fs.h>#include <linux/delay.h>#include <linux/platform_device.h>#include <linux/input.h>#include <linux/gpio_keys.h>#include <mach/gpio.h>#include <plat/gpio-cfg.h>#include <mach/regs-gpio.h>#include <linux/i2c.h>#include <linux/kernel.h>#include <linux/slab.h>#include <linux/poll.h>#include <linux/delay.h>#include <linux/device.h>#include <mach/hardware.h>#include <asm/irq.h>#include <asm/io.h>//--------------------------------------------------------------------------------------------------#define IIC_DEVICE_ADDRESS 0x33#define SCL_H  { gpio_set_value (S5PV210_GPG3(5), 1) ; }#define SCL_L  { gpio_set_value (S5PV210_GPG3(5), 0) ; }#define SDA_H  { gpio_set_value (S5PV210_GPG3(6), 1) ; }#define SDA_L  { gpio_set_value (S5PV210_GPG3(6), 0) ; }#define SDA_IN  { gpio_direction_input (S5PV210_GPG3(6)); }#define SDA_OUT { gpio_direction_output (S5PV210_GPG3(6),1); }#define WHILE_SDA_HIGH (gpio_get_value (S5PV210_GPG3(6)))unsigned int ByteDelayTimeout = 0x0700;unsigned int BitDelayTimeout  = 0x200;static void ByteDelay( void );static void BitDelay ( void );static int dvcIIC_read ( char *, size_t );static int dvcIIC_write ( char *, size_t );static void InterfaceInit ( void );static void I2C_Start ( void );static void I2C_Stop ( void );static void I2C_Ack ( void );static void I2C_Nack ( void );//--------------------------------------------------------------------------------------------------static void I2C_Start(void){SDA_OUT ;SDA_H ;BitDelay () ;SCL_H ;BitDelay () ;SDA_L ;BitDelay () ;}static void I2C_Stop(void){SDA_OUT ;SDA_L ;BitDelay () ;SCL_H ;BitDelay () ;SDA_H ;BitDelay () ;}static void I2C_Ack(void){SDA_OUT ;SDA_L ;BitDelay () ;SCL_H ;BitDelay () ;SCL_L ;BitDelay () ;SDA_IN ;BitDelay () ;}static void I2C_Ack1(void){int i=0;SCL_H ;BitDelay () ;SDA_IN ;while((WHILE_SDA_HIGH)&&(i<255)) i++;//无应答延时一段时间后默认已经收到SCL_L ;BitDelay () ;SDA_OUT; BitDelay () ; }static void I2C_Nack(void){SDA_OUT ;SDA_H ;BitDelay () ;SCL_H ;BitDelay () ;SCL_L ;BitDelay () ;SCL_H ;}//--------------------------------------------------------------------------------------------------static char Write_I2C_Byte ( char byte ){char i;SCL_L;BitDelay ();for(i = 0 ; i < 8 ; i++){if((byte & 0x80) == 0x80) {SDA_H;}else {SDA_L;}BitDelay () ;SCL_H ;BitDelay () ;SCL_L ;BitDelay () ;byte <<= 1 ; } return 1 ;}//--------------------------------------------------------------------------------------------------static char Read_I2C_Byte ( void ){char i, buff = 0 ;SCL_L ;BitDelay () ;for(i = 0 ; i < 8 ; i++){SDA_OUT;SDA_H ;BitDelay () ;SCL_H ;SDA_IN ;BitDelay () ;if(WHILE_SDA_HIGH)buff |= 0x01 ;else buff &=~0x01;if(i<7) buff <<= 1 ;SCL_L ;BitDelay () ;}return buff ;}//--------------------------------------------------------------------------------------------------static void ByteDelay ( void ){volatile unsigned int dwTimeout ;dwTimeout = ByteDelayTimeout ;while ( --dwTimeout ){asm ( "nop" ) ;}}static void BitDelay ( void ){volatile unsigned int dwTimeout ;dwTimeout = BitDelayTimeout ;while ( --dwTimeout ){asm ( "nop" ) ;}}//--------------------------------------------------------------------------------------------------static void InterfaceInit ( void ){gpio_direction_output (S5PV210_GPG3(5), 1);// SCL OUTgpio_direction_output (S5PV210_GPG3(6), 1); // SDA OUTgpio_set_value (S5PV210_GPG3(5), 1); gpio_set_value (S5PV210_GPG3(6), 1);  ByteDelay () ;ByteDelay () ;ByteDelay () ;}//--------------------------------------------------------------------------------------------------static int dvcIIC_read ( char *data, size_t count){int i;I2C_Start () ;Write_I2C_Byte((IIC_DEVICE_ADDRESS<<1)+1);I2C_Ack1() ;for ( i = 0; i < count; i++ ){data[i] = Read_I2C_Byte ();I2C_Ack () ;//printk( "0x%x ", data[i] );}Read_I2C_Byte () ;I2C_Nack () ;I2C_Stop () ;return 0;}//--------------------------------------------------------------------------------------------------static int dvcIIC_write ( char *data, size_t size){int i;I2C_Start () ;Write_I2C_Byte ((IIC_DEVICE_ADDRESS<<1));I2C_Ack1 () ;for( i = 0; i < size; i++ ){//printk( "0x%x ", data[i] );Write_I2C_Byte ( data[i] );I2C_Ack1 ();}I2C_Stop ();I2C_Nack ();I2C_Stop ();return 0;}//-------------------------------------------------------------------------------------------------void delay(){unsigned int i,j;for(i=5000;i>0;i--){for(j=5000;j>0;j--);}}//-------------------------------------------------------------------------------------------------//=================================================================================================static struct input_dev *OFN_dev;#define MiniX10#define MaxX750#define MiniY10#define MaxY450#define CenterX380#define CenterY230int absX = CenterX;int absY = CenterY;//--------------------------------------------------------------------------------------------------static irqreturn_t KeyOFN_isr(int irq, void *dev_id)//中断0 处理函数{printk("Enter EIENT0 ! \n");input_report_abs(OFN_dev, ABS_X, absX);//X轴坐标input_report_abs(OFN_dev, ABS_Y, absY);//Y轴坐标input_report_key(OFN_dev, BTN_TOUCH, 1);//按下 按键input_report_abs(OFN_dev, ABS_PRESSURE, 1);//按下 压力input_sync(OFN_dev);//事件同步input_report_key(OFN_dev, BTN_TOUCH, 0);//抬起 按键值此两条抬起信息必须添加input_report_abs(OFN_dev, ABS_PRESSURE, 0);//抬起 压力值input_sync(OFN_dev);//事件同步delay();return IRQ_RETVAL(IRQ_HANDLED);  }//--------------------------------------------------------------------------------------------------static irqreturn_t MotionOFN_isr(int irq, void *dev_id)//中断1处理函数{char buf[3];buf[0] = 2;printk("Enter IRQ_EINT1,MOtionOFN_isr~!--hello1--\n");dvcIIC_write( buf, 1);//发送地址dvcIIC_read ( buf, 3);//从地址2,3,4 读取三位数据printk("OFN return 0x%x--0x%x--0x%x\n", buf[0],buf[1],buf[2]);if((buf[0]&1)&&(buf[0]!=0xff))// OFN{if(buf[1] > 0xF0 )//判断X轴向{absX = (CenterX+(buf[1])/2);if( absX > MaxX ){absX = MaxX;}}else{absX = (CenterX-(0xF0 - buf[1])/2);if( absX < MiniX ){absX = MiniX;}}if(buf[2] > 0xF0 )//判断Y轴向{absY = (CenterY+(buf[2])/2);if( absY > MaxY ){absY = MaxY;}}else{absY = (CenterY-(0xF0 - buf[2])/2);if( absY < MiniY ){absY = MiniY;}}input_report_abs(OFN_dev, ABS_X, absX);input_report_abs(OFN_dev, ABS_Y, absY);input_sync(OFN_dev);//坐标信息同步delay();}return IRQ_RETVAL(IRQ_HANDLED);}//--------------------------------------------------------------------------------------------------static int __init OFN_init(void)// {char buf1[10];int ret = 0;char buffer[2];InterfaceInit ();// IIC 接口初始化printk("--1\n");gpio_direction_input(S5PV210_GPH0(0));gpio_direction_input(S5PV210_GPH0(1));s3c_gpio_cfgpin(S5PV210_GPH0(0), S3C_GPIO_SFN(0x0000000f));//设置为外部中断 eint0 ,参考GP0CON【】s3c_gpio_cfgpin(S5PV210_GPH0(1), S3C_GPIO_SFN(0x000000f0));//设置为外部中断 eint1 ,参考GP0CON【】set_irq_type(IRQ_EINT0, IRQ_TYPE_EDGE_FALLING);set_irq_type(IRQ_EINT1, IRQ_TYPE_EDGE_FALLING);//-------------------------------------------------------------------------OFN_dev = input_allocate_device();// 申请一个输入设备if (!OFN_dev) return -ENOMEM;OFN_dev->name = "TouchScreen Pipe";// 触摸屏设备属性信息OFN_dev->phys = "input(ts)";OFN_dev->id.bustype = BUS_RS232;OFN_dev->id.vendor  = 0xDEAD;OFN_dev->id.product = 0xBEEF;OFN_dev->id.version = 0x0101;input_set_abs_params(OFN_dev, ABS_X, 0, 0x320, 0, 0);// 800input_set_abs_params(OFN_dev, ABS_Y, 0, 0x1E0, 0, 0);// 480input_set_abs_params(OFN_dev, ABS_PRESSURE, 0, 1, 0, 0);// 压力OFN_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);OFN_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);//---------------------------------------------------------------------------printk("--2\n");ret = request_irq(IRQ_EINT0, KeyOFN_isr, IRQ_TYPE_EDGE_FALLING, "OFN0", NULL);//EINT0 注册if(ret){printk(KERN_ERR "OFN0: unable to allocate VSYNC interrupt\n");input_free_device(OFN_dev);return -EBUSY;}ret = request_irq(IRQ_EINT1, MotionOFN_isr, IRQF_SHARED, "OFN1", OFN_dev);//EINT1 注册if(ret){printk(KERN_ERR "OFN1: unable to allocate VSYNC interrupt\n");input_free_device(OFN_dev);return -EBUSY;}//--------------------------------------------------------------------------------ret = input_register_device(OFN_dev);if(ret){free_irq(IRQ_EINT0, OFN_dev);free_irq(IRQ_EINT1, OFN_dev);input_free_device(OFN_dev);return -1;}//--------------------------------------------------------------------------------buffer[0]=0x13;buffer[1] = 2;// dvcIIC_write( buffer, 2);delay();buffer[0]=0x15;buffer[1] = 3;// 初始化dvcIIC_write( buffer, 2);delay();buf1[0] = 0;dvcIIC_write( buf1, 1);delay();dvcIIC_read( buf1, 1);printk("OFN return 0x%x--0x%x--0x%x\n", buf1[0],buf1[1],buf1[2]);delay();buf1[0] = 2;dvcIIC_write( buf1, 1);delay();dvcIIC_read( buf1, 3);printk("OFN return 0x%x--0x%x--0x%x\n", buf1[0],buf1[1],buf1[2]);delay();return 0;}//--------------------------------------------------------------------------------------------------static void __exit OFN_exit(void){free_irq(IRQ_EINT0, NULL);free_irq(IRQ_EINT1, OFN_dev);input_unregister_device(OFN_dev);}//--------------------------------------------------------------------------------------------------MODULE_LICENSE("GPL");MODULE_AUTHOR("Light");module_init(OFN_init);module_exit(OFN_exit);//--------------------------------------------------------------------------------------------------

按键中断输入 按键事件 传送信息给触摸屏 驱动实现。input输入设备注册。

原创粉丝点击