⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test.c

📁 ARM 嵌入式 系统 设计与实例开发 实验教材 二源码
💻 C
字号:
/* * s3c2410-ts.c * * touchScreen driver for SAMSUNG S3C2410 * * Author: Janghoon Lyu <nandy@mizi.com> * Date  : $Date: 2002/06/04 07:11:00 $  * * $Revision: 1.1.2.6 $ * * Based on pt036001b-ts.c * * This file is subject to the terms and conditions of the GNU General Public * License.  See the file COPYING in the main directory of this archive * for more details. * * History: * * 2002-05-27: Janghoon Lyu <nandy@mizi.com> *    - Add HOOK_FOR_DRAG *    - PM 内靛啊 甸绢啊 乐变 窍瘤父 抛胶飘 登瘤 臼疽澜. *  */#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/miscdevice.h>#include <linux/sched.h>#include <linux/delay.h>#include <linux/poll.h>#include <linux/spinlock.h>#include <linux/irq.h>#include <linux/delay.h>#include <asm/hardware.h>//#include <asm/arch/spi.h>/* debug macros */#undef DEBUG#define DEBUG#ifdef DEBUG#define DPRINTK( x... )	printk("s3c2410-ts: " ##x)#else#define DPRINTK( x... )#endif#define PEN_UP	        0		#define PEN_DOWN	1#define PEN_FLEETING	2#define MAX_TS_BUF	16	/* how many do we want to buffer */#undef USE_ASYNC	1#define DEVICE_NAME	"s3c2410-ts"#define TSRAW_MINOR	1typedef struct {  unsigned int penStatus;		/* PEN_UP, PEN_DOWN, PEN_SAMPLE */  TS_RET buf[MAX_TS_BUF];		/* protect against overrun */  unsigned int head, tail;	/* head and tail for queued events */  wait_queue_head_t wq;  spinlock_t lock;} TS_DEV;static TS_DEV tsdev;#undef	IRQ_TC#define IRQ_TC          IRQ_EINT5	//IRQ_EINT5#define ADS7843_PIN_CS          (1<<12)  //GPG12#define ADS7843_PIN_PEN 	(1<<5)  //GPF5#define	TS_OPEN_INT()	enable_irq(IRQ_TC)#define	TS_CLOSE_INT()	disable_irq(IRQ_TC)#define GPIO_TC_SPIMISO        (GPIO_MODE_ALT0 | GPIO_PULLUP_DIS | GPIO_E11)#define GPIO_TC_SPIMOSI        (GPIO_MODE_ALT0 | GPIO_PULLUP_DIS | GPIO_E12)#define GPIO_TC_SPICLK         (GPIO_MODE_ALT0 | GPIO_PULLUP_DIS | GPIO_E13)#define	GPIO_TC_INTR		(GPIO_MODE_ALT0 | GPIO_PULLUP_EN | GPIO_F5)#define	GPIO_TC_OUT		(GPIO_MODE_OUT | GPIO_PULLUP_EN | GPIO_F5)#ifdef	GPIO_XMON#undef	GPIO_XMON#endif#define GPIO_XMON       	(GPIO_MODE_OUT | GPIO_PULLUP_EN | GPIO_G12)#define ADS7843_CTRL_START              0x80#define ADS7843_GET_X                   0x50#define ADS7843_GET_Y                   0x10#define ADS7843_CTRL_12MODE    		0x0#define ADS7843_CTRL_8MODE      	0x8#define ADS7843_CTRL_SER                0x4#define ADS7843_CTRL_DFR                0x0#define ADS7843_CTRL_DISPWD     	0x3     // Disable power down#define ADS7843_CTRL_ENPWD      	0x0     // enable power down#define ADS7843_CMD_X   (ADS7843_CTRL_START|ADS7843_GET_X|ADS7843_CTRL_12MODE|ADS7843_CTRL_DFR|ADS7843_CTRL_ENPWD)#define ADS7843_CMD_Y   (ADS7843_CTRL_START|ADS7843_GET_Y|ADS7843_CTRL_12MODE|ADS7843_CTRL_DFR|ADS7843_CTRL_ENPWD)#define ADS7843_CMD_START ADS7843_CMD_X#define BUF_HEAD	(tsdev.buf[tsdev.head])#define BUF_TAIL	(tsdev.buf[tsdev.tail])#define INCBUF(x,mod) 	((++(x)) & ((mod) - 1))static int tsMajor = 0;static void (*tsEvent)(void);#define HOOK_FOR_DRAG#ifdef HOOK_FOR_DRAG#define TS_TIMER_DELAY  (HZ/100) /* 10 ms */#define	TS_TIMER_DELAY1	(HZ/200) /* 5 ms*/static struct timer_list ts_timer;#endifstatic int adc_state = 0;static int x, y;	/* touch screen coorinates */static void printRegisters(void){  printk ("GPFCON:%x\tGPFUP:%x\tGPFDAT:%x\n",	  GPFCON, GPFUP, GPFDAT );  printk ("GPGCON:%x\tGPGUP:%x\tGPGDAT:%x\n",	  GPGCON, GPGUP, GPGDAT );  printk ("INTMOD:%x\tINTMSK:%x\tINTPND:%x\tSRCPND:%x\n",	  INTMOD, INTMSK, INTPND, SRCPND);  printk ("EXTINT0:%x\tEINTMASK:%x\tEINTPEND:%x\n",	  EXTINT0, EINTMASK, EINTPEND );}static void printGPE (void){  printk ("GPECON:%x\tGPEUP:%x\tGPEDAT:%x\n",	  GPECON, GPEUP, GPEDAT );}static void printSPI (void){  printk ("SPPRE0:%d\tSPCON0:%x\tSPSTA0:%x\n", SPPRE0, SPCON0, SPSTA0 );  printk ("SPTDAT0:%x\tSPRDAT0:%x\n", SPTDAT0, SPRDAT0 );  printk ("SPPIN0:%x\n", SPPIN0);}inline static void enable_7843(void){  GPGDAT &= ~ADS7843_PIN_CS;}inline static void disable_7843(void){  GPGDAT |= ADS7843_PIN_CS;}inline static void SPISend ( unsigned char val, int channel ){  if ( channel == 0 ){    while (!(SPSTA0 & 1));    SPTDAT0 = val;  }else if ( channel == 1 ){    while (!(SPSTA1 & 1));    SPTDAT1 = val;  }else    return;}inline static char SPIRecv ( int channel ){  char retv;  if (channel == 0){    //    SPISend (0xff, 0);    while (!(SPSTA0 & 1));    return SPRDAT0;  }else if (channel == 1) {    //    SPISend (0xff, 0);    while (!(SPSTA1 & 1));    return SPRDAT1;  }else    return -1;}inline static void set7843toIRQmode(void){  enable_7843 ();  printk ("aaaaaaaaaaa\n");  SPISend (ADS7843_CMD_X, 0);  printk ("bbbbbbbbbbbb\n");  SPIRecv (0);  printk ("cccccccccccc\n");  SPIRecv (0);  printk ("ddddddddddd\n" );  disable_7843 ();  printk ("eeeeeeeeeee\n");}static void setSPImode (){  printSPI();  SPPIN0 = 2;  SPPRE0 = 33;  SPCON0 = SPCON_SMOD_POLL | SPCON_ENSCK | SPCON_MSTR |    SPCON_CPOL_HIGH | SPCON_CPHA_FMTA;  printSPI();}static void tsEvent_raw(void){  if (tsdev.penStatus == PEN_DOWN) {    BUF_HEAD.x = x;    BUF_HEAD.y = y;    BUF_HEAD.pressure = PEN_DOWN;  } else {    BUF_HEAD.x = 0;    BUF_HEAD.y = 0;    BUF_HEAD.pressure = PEN_UP;  }  tsdev.head = INCBUF(tsdev.head, MAX_TS_BUF);  wake_up_interruptible(&(tsdev.wq));}static int tsRead(TS_RET * ts_ret){  spin_lock_irq(&(tsdev.lock));  ts_ret->x = BUF_TAIL.x;  ts_ret->y = BUF_TAIL.y;  ts_ret->pressure = BUF_TAIL.pressure;  tsdev.tail = INCBUF(tsdev.tail, MAX_TS_BUF);  spin_unlock_irq(&(tsdev.lock));  return sizeof(TS_RET);}static ssize_t s3c2410_ts_read(struct file *filp, char *buffer, size_t count, loff_t *ppos){  TS_RET ts_ret; retry:   if (tsdev.head != tsdev.tail) {    int count;    count = tsRead(&ts_ret);    if (count) copy_to_user(buffer, (char *)&ts_ret, count);    return count;  } else {    if (filp->f_flags & O_NONBLOCK)      return -EAGAIN;    interruptible_sleep_on(&(tsdev.wq));    if (signal_pending(current))      return -ERESTARTSYS;    goto retry;  }  return sizeof(TS_RET);}static unsigned int s3c2410_ts_poll(struct file *filp, struct poll_table_struct *wait){  poll_wait(filp, &(tsdev.wq), wait);  return (tsdev.head == tsdev.tail) ? 0 : (POLLIN | POLLRDNORM); }static inline void s3c2410_get_XY(void){  unsigned int temp;  int flags;  local_irq_save(flags);                                                                                  enable_7843();  SPISend(ADS7843_CMD_X, 0);  SPISend(0, 0);  temp=SPIRecv(0);  SPISend(ADS7843_CMD_X, 0);  temp<<=8;  temp|=SPIRecv(0);  x=(temp>>4);                                                                                  SPISend(0, 0);  temp=SPIRecv(0);  SPISend(ADS7843_CMD_Y, 0);  temp<<=8;  temp|=SPIRecv(0);  x+=(temp>>4);  x>>=1;          //x=x/2;                                                                                  SPISend(0, 0);  temp=SPIRecv(0);  SPISend(ADS7843_CMD_Y, 0);  temp<<=8;  temp|=SPIRecv(0);  y=(temp>>4);                                                                                  SPISend(0, 0);  temp=SPIRecv(0);  SPISend(0, 0);  temp<<=8;  temp|=SPIRecv(0);  y+=(temp>>4);  y>>=1;          //y=y/2;                                                                                  disable_7843 ();  local_irq_restore(flags);                                                                                  //tsdev.penStatus = PEN_DOWN;  if(tsdev.penStatus == PEN_DOWN)    DPRINTK("PEN DOWN: x: %d, y: %d\n", x, y);  else    DPRINTK("PEN FLEETING: x: %d, y: %d\n", x, y);  tsEvent();#if 0  if (adc_state == 0) {     adc_state = 1;    disable_ts_adc();    y = (ADCDAT0 & 0x3ff);     mode_y_axis();    start_adc_y();  } else if (adc_state == 1) {     adc_state = 0;    disable_ts_adc();    x = (ADCDAT1 & 0x3ff);     tsdev.penStatus = PEN_DOWN;    DPRINTK("PEN DOWN: x: %08d, y: %08d\n", x, y);    wait_up_int();    tsEvent();  }#endif}static void s3c2410_isr_tc(int irq, void *dev_id, struct pt_regs *reg){  printk ("Touch Screen Interrupt occured\n");  spin_lock_irq(&(tsdev.lock));  printk ("ISR 1\n");  if (tsdev.penStatus == PEN_UP) {    int i;    TS_CLOSE_INT();    udelay(1);    if (( GPFDAT & ADS7843_PIN_PEN) == 0 ) {      printk ("low\n");      tsdev.penStatus = PEN_DOWN;#ifdef	HOOK_FOR_DRAG      ts_timer.expires = jiffies + TS_TIMER_DELAY1;      add_timer (&ts_timer);#endif    }else{      printk ("High\n");      TS_OPEN_INT();    }	  }  spin_unlock_irq(&(tsdev.lock));  printk ("ISR 2\n");}#ifdef HOOK_FOR_DRAGstatic void ts_timer_handler(unsigned long data){  spin_lock_irq(&(tsdev.lock));  if((GPFDAT & ADS7843_PIN_PEN) == 0 ){    s3c2410_get_XY ();    tsdev.penStatus = PEN_FLEETING;#ifdef HOOK_FOR_DRAG    ts_timer.expires = jiffies + TS_TIMER_DELAY;    add_timer(&ts_timer);#endif  }else{    tsdev.penStatus = PEN_UP;    del_timer (&ts_timer);    DPRINTK ("PEN UP:x:%d,y:%d\n", x, y);    tsEvent ();    TS_OPEN_INT ();  }  spin_unlock_irq(&(tsdev.lock));}#endifstatic int s3c2410_ts_open(struct inode *inode, struct file *filp){  tsdev.head = tsdev.tail = 0;  tsdev.penStatus = PEN_UP;#ifdef HOOK_FOR_DRAG   init_timer(&ts_timer);  ts_timer.function = ts_timer_handler;#endif  tsEvent = tsEvent_raw;  init_waitqueue_head(&(tsdev.wq));  TS_OPEN_INT ();  MOD_INC_USE_COUNT;  printk ( "ts opened\n");  return 0;}static int s3c2410_ts_release(struct inode *inode, struct file *filp){#ifdef HOOK_FOR_DRAG  del_timer(&ts_timer);#endif  TS_CLOSE_INT ();  MOD_DEC_USE_COUNT;  printk ( "ts closed\n");  return 0;}static struct file_operations s3c2410_fops = {  owner:	THIS_MODULE,  open:	s3c2410_ts_open,  read:	s3c2410_ts_read,	  release:	s3c2410_ts_release,#ifdef USE_ASYNC  fasync:	s3c2410_ts_fasync,#endif  poll:	s3c2410_ts_poll,};void tsEvent_dummy(void) {}#ifdef CONFIG_DEVFS_FSstatic devfs_handle_t devfs_ts_dir, devfs_tsraw;#endifstatic int __init s3c2410_ts_init(void){  int ret;  int flags;  int delay;  unsigned short tmp;  local_irq_save (flags);  printGPE();  set_gpio_ctrl (GPIO_TC_SPIMISO);  set_gpio_ctrl (GPIO_TC_SPIMOSI);  set_gpio_ctrl (GPIO_TC_SPICLK);  printGPE();  printk( "11111111111111\n");  setSPImode();  printk( "22222222222222\n");  set7843toIRQmode();  printk( "3333333333333\n" );  ret =set_external_irq( IRQ_TC, EXT_LOWLEVEL, /*low level request*/			 GPIO_PULLUP_DIS/*poll up*/ );  if (ret)    return ret;  local_irq_restore (flags);  tsEvent = tsEvent_dummy;  ret = register_chrdev(0, DEVICE_NAME, &s3c2410_fops);  if (ret < 0) {    printk(DEVICE_NAME " can't get major number\n");    return ret;  }  tsMajor = ret;  /* Enable touch interrupt */  ret = request_irq(IRQ_TC, s3c2410_isr_tc,SA_INTERRUPT,		    DEVICE_NAME, s3c2410_isr_tc);  if (ret) {    return ret;  }  TS_CLOSE_INT();#ifdef CONFIG_DEVFS_FS  devfs_ts_dir = devfs_mk_dir(NULL, "touchscreen", NULL);  devfs_tsraw = devfs_register(devfs_ts_dir, "0raw", DEVFS_FL_DEFAULT,			       tsMajor, TSRAW_MINOR, S_IFCHR | S_IRUSR | S_IWUSR,			       &s3c2410_fops, NULL);#endif  printk (DEVICE_NAME"\tinitialized\n");  return 0;}static void __exit s3c2410_ts_exit(void){#ifdef CONFIG_DEVFS_FS	  devfs_unregister(devfs_tsraw);  devfs_unregister(devfs_ts_dir);#endif  unregister_chrdev(tsMajor, DEVICE_NAME);  free_irq(IRQ_TC, s3c2410_isr_tc);}module_init(s3c2410_ts_init);module_exit(s3c2410_ts_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -