注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

deisp的博客

 
 
 

日志

 
 

Linux2.6内核TouchScreen驱动移植   

2008-02-14 12:08:23|  分类: 驱动移植 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

 /////////////////下面是编绎成功的重要文件全文,具体步骤参考下面引用文章说明,驱动文件路径不同////////////

drivers/char  s3c2410-ts.c

/*
 * s3c2410-ts.c
 */

#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/devfs_fs_kernel.h>

#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>

//--------------------------------------follow add by fla
#define WAIT4INT(x)  (((x)<<8) | \
       S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | \
       S3C2410_ADCTSC_XY_PST(3))
      
/* ADCTSC Register Bits */
#define S3C2410_ADCTSC_YM_SEN  (1<<7)
#define S3C2410_ADCTSC_YP_SEN  (1<<6)
#define S3C2410_ADCTSC_XM_SEN  (1<<5)
#define S3C2410_ADCTSC_XP_SEN  (1<<4)
#define S3C2410_ADCTSC_PULL_UP_DISABLE (1<<3)
#define S3C2410_ADCTSC_AUTO_PST  (1<<2)
#define S3C2410_ADCTSC_XY_PST(x) (((x)&0x3)<<0)

/* ADCCON Register Bits */
#define S3C2410_ADCCON_ECFLG  (1<<15)
#define S3C2410_ADCCON_PRSCEN  (1<<14)
#define S3C2410_ADCCON_PRSCVL(x) (((x)&0xFF)<<6)
#define S3C2410_ADCCON_PRSCVLMASK (0xFF<<6)
#define S3C2410_ADCCON_SELMUX(x) (((x)&0x7)<<3)
#define S3C2410_ADCCON_MUXMASK  (0x7<<3)
#define S3C2410_ADCCON_STDBM  (1<<2)
#define S3C2410_ADCCON_READ_START (1<<1)
#define S3C2410_ADCCON_ENABLE_START (1<<0)
#define S3C2410_ADCCON_STARTMASK (0x3<<0)

#ifdef S3C2410_ADCCON
#undef S3C2410_ADCCON
#endif

#ifdef S3C2410_ADCTSC
#undef S3C2410_ADCTSC
#endif

#ifdef S3C2410_ADCDLY
#undef S3C2410_ADCDLY
#endif

#ifdef S3C2410_ADCDAT0
#undef S3C2410_ADCDAT0
#endif

#ifdef S3C2410_ADCDAT1
#undef S3C2410_ADCDAT1
#endif

#ifdef S3C2410_PA_ADC
#undef S3C2410_PA_ADC
#endif


#define S3C2410_PA_ADC    (0x58000000)

 

static void __iomem *base_addr;
#define S3C2410_ADCCON (base_addr+(0x00))
#define S3C2410_ADCTSC (base_addr+(0x04))
#define S3C2410_ADCDLY (base_addr+(0x08))
#define S3C2410_ADCDAT0 (base_addr+(0x0c))
#define S3C2410_ADCDAT1 (base_addr+(0x10))

//-------------------------------------------------------------------fla


#ifdef CONFIG_PM
#include <linux/pm.h>
#endif

/* debug macros */
#define DEBUG
#undef DEBUG
#ifdef DEBUG
#define DPRINTK( x... ) printk("%s: ", __FUNCTION__,  ##x)
#else
#define DPRINTK( x... )
#endif

typedef struct {
  unsigned short pressure;
  unsigned short x;
  unsigned short y;
  unsigned short pad;
} TS_RET;

typedef struct {
  int xscale;
  int xtrans;
  int yscale;
  int ytrans;
  int xyswap;
} TS_CAL;

#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 
#define DEVICE_NAME "s3c2410-ts"
#define TSRAW_MINOR 1

typedef 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;
#ifdef USE_ASYNC
 struct fasync_struct *aq;
#endif
#ifdef CONFIG_PM
 struct pm_dev *pm_dev;
#endif
} TS_DEV;

static TS_DEV tsdev;

#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 */
static struct timer_list ts_timer;
#endif

 

 


//-------------------------fla  pick-up regs val from 2.4.18&2440
#define wait_down_int() __raw_writel(0x000000d3,S3C2410_ADCTSC)
#define wait_up_int() __raw_writel(0x000001d3, S3C2410_ADCTSC)
#define mode_x_axis() __raw_writel(0x00000069, S3C2410_ADCTSC)
#define mode_x_axis_n() __raw_writel(XP_EXTVLT | XM_GND | YP_AIN | YM_HIZ | \
    XP_PULL_UP_DIS | XP_PST(NOP_MODE), S3C2410_ADCTSC)
#define mode_y_axis() __raw_writel(0x0000009a, S3C2410_ADCTSC)
#define start_adc_x() do {__raw_writel(0x00007ffa, S3C2410_ADCCON); \
    __raw_readl(S3C2410_ADCDAT0); } while(0)
#define start_adc_y() do {__raw_writel(0x00007ffa, S3C2410_ADCCON); \
    __raw_readl(S3C2410_ADCDAT1); } while(0)
#define disable_ts_adc() __raw_writel(__raw_readl(S3C2410_ADCCON)&0xfffffffd, S3C2410_ADCCON)
//---------------------------fla
static int adc_state = 0;
static int x, y; /* touch screen coorinates */

#define RT_BT_EMU_TM ((HZ>>1)+(HZ>>2)) //0.75S
static u16 ts_r_x[5];
static u16 ts_r_y[5];
static u16 ts_r_idx;
static u16 ts_r_beg;
static u32 dn_start;

static void tsEvent_raw(void)
{

 if (tsdev.penStatus == PEN_DOWN) {
  u16 i, j;
#ifdef HOOK_FOR_DRAG
  ts_timer.expires = jiffies + TS_TIMER_DELAY;
  add_timer(&ts_timer);
#endif
  ts_r_x[ts_r_idx] = x;
  ts_r_y[ts_r_idx] = y;
  ts_r_idx++;
  if(ts_r_idx>=5)
   ts_r_idx = 0;

  if(ts_r_beg) {
   ts_r_beg--;
   if(ts_r_beg)
    return;
   dn_start = jiffies;
  }

  for(i=4; i; i--)
   for(j=i; j; j--) {
    u16 swap_xy;
    if(ts_r_x[j-1]>ts_r_x[i]) {
     swap_xy = ts_r_x[j-1];
     ts_r_x[j-1] = ts_r_x[i];
     ts_r_x[i] = swap_xy;
    }
    if(ts_r_y[j-1]>ts_r_y[i]) {
     swap_xy = ts_r_y[j-1];
     ts_r_y[j-1] = ts_r_y[i];
     ts_r_y[i] = swap_xy;
    }
   }

  BUF_HEAD.x = x = ts_r_x[3];
  BUF_HEAD.y = y = ts_r_y[3];
  BUF_HEAD.pressure = ((jiffies - dn_start) >= RT_BT_EMU_TM) ? 2 : PEN_DOWN;
 } else {
#ifdef HOOK_FOR_DRAG
  del_timer(&ts_timer);
#endif
  if(ts_r_beg)
   return;
  BUF_HEAD.x = x;//0;
  BUF_HEAD.y = y;//0;
  BUF_HEAD.pressure = PEN_UP;
 }

 tsdev.head = INCBUF(tsdev.head, MAX_TS_BUF);
 wake_up_interruptible(&(tsdev.wq));

#ifdef USE_ASYNC
 if (tsdev.aq)
  kill_fasync(&(tsdev.aq), SIGIO, POLL_IN);
#endif

#ifdef CONFIG_PM
 pm_access(tsdev.pm_dev);
#endif
}

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);
}

#ifdef USE_ASYNC
static int s3c2410_ts_fasync(int fd, struct file *filp, int mode)
{
 return fasync_helper(fd, filp, mode, &(tsdev.aq));
}
#endif

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 start_ts_adc(void)
{
 adc_state = 0;
 mode_x_axis();
 start_adc_x();
}

static inline void s3c2410_get_XY(void)
{
 if (adc_state == 0) {
  adc_state = 1;
  disable_ts_adc();
  y = __raw_readl(S3C2410_ADCDAT1) & 0x3ff;
  mode_y_axis();
  start_adc_y();
 } else if (adc_state == 1) {
  adc_state = 0;
  disable_ts_adc();
  x = __raw_readl(S3C2410_ADCDAT0) & 0x3ff;
  DPRINTK("PEN DOWN: x: %08d, y: %08d\n", x, y);
  wait_up_int();
  tsdev.penStatus = PEN_DOWN;
  tsEvent();
 }
}

static irqreturn_t s3c2410_isr_adc(int irq, void *dev_id, struct pt_regs *reg)
{
#if 0
 DPRINTK("Occured Touch Screen Interrupt\n");
 DPRINTK("SUBSRCPND = 0x%08lx\n", SUBSRCPND);
#endif
  //printk(KERN_ERR "Occured Touch Screen Interrupt in s3c2410_isr_adc!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
 spin_lock_irq(&(tsdev.lock));
 if (tsdev.penStatus == PEN_UP)
  {//printk(KERN_ERR "hi,i'm s3c2410_isr_adc!");
 s3c2410_get_XY();}
#ifdef HOOK_FOR_DRAG
 else
   s3c2410_get_XY();
#endif
 spin_unlock_irq(&(tsdev.lock));

 return IRQ_HANDLED;
}

static irqreturn_t s3c2410_isr_tc(int irq, void *dev_id, struct pt_regs *reg)
{
#if 0
 DPRINTK("Occured Touch Screen Interrupt\n");
 DPRINTK("SUBSRCPND = 0x%08lx\n", SUBSRCPND);
#endif
//printk(KERN_ERR "Occured Touch Screen Interrupt in s3c2410_isr_tc!!!!!!!!!!!!!!!!!!!!!\n");
 spin_lock_irq(&(tsdev.lock));
 if (tsdev.penStatus == PEN_UP) {
   //printk(KERN_ERR "hi,i'm s3c2410_isr_tc_p1!\n");
   ts_r_idx = 0;  //add by hzh
   ts_r_beg = 5;
   start_ts_adc();
 } else {
   tsdev.penStatus = PEN_UP;
   //printk(KERN_ERR "hi,i'm s3c2410_isr_tc_p2!\n");
   DPRINTK("PEN UP: x: %08d, y: %08d\n", x, y);
   //printk(KERN_ERR "PEN UP: x: %08d, y: %08d\n", x, y);
   wait_down_int();
   tsEvent();
 }
 spin_unlock_irq(&(tsdev.lock));

 return IRQ_HANDLED;
}

#ifdef HOOK_FOR_DRAG
static void ts_timer_handler(unsigned long data)
{
 spin_lock_irq(&(tsdev.lock));
 if (tsdev.penStatus == PEN_DOWN) {
  start_ts_adc();
 }
 spin_unlock_irq(&(tsdev.lock));
}
#endif

static 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));

 //MOD_INC_USE_COUNT;
 return 0;
}

static int s3c2410_ts_release(struct inode *inode, struct file *filp)
{
#ifdef HOOK_FOR_DRAG
 del_timer(&ts_timer);
#endif
 //MOD_DEC_USE_COUNT;
 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_PM
static int s3c2410_ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req,
           void *data)
{
    switch (req) {
  case PM_SUSPEND:
   tsEvent = tsEvent_dummy;
   break;
  case PM_RESUME:
   tsEvent = tsEvent_raw;
   wait_down_int();
   break;
    }
    return 0;
}
#endif

 

static struct clk *adc_clock;
static int __init s3c2410ts_probe(struct device *dev)
{
 int ret;
 
 tsEvent = tsEvent_dummy;
        //printk(KERN_ERR "hello,just junp in s3c2410ts_probe!!!!!!!!!!!!!!\n");
 ret = register_chrdev(0, DEVICE_NAME, &s3c2410_fops);
 if (ret < 0) {
   printk(DEVICE_NAME " can't get major number\n");
   return ret;
 }
 printk(KERN_ERR "success get major number!!!!!!\n");
 tsMajor = ret;
 printk("%s device driver MAJOR:%d\n", DEVICE_NAME, tsMajor);
 //fla input ts clk!
 adc_clock = clk_get(NULL, "adc");
 if (!adc_clock) {
  //printk(KERN_ERR "failed to get adc clock source\n");
  return -ENOENT;
 }
 clk_use(adc_clock);
 clk_enable(adc_clock);
 printk(KERN_ERR "success to get adc clock source!\n");
 
 
 base_addr = ioremap(S3C2410_PA_ADC,0x20);
 printk(KERN_ERR "base_addr = %#p\n",base_addr);
 //printk(KERN_ERR "hi,new adctsc = 0x%08x!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",__raw_readl(S3C2410_ADCTSC));
 //writel((readl(S3C2410_ADCTSC)&0x00000000)|0x00000053,S3C2410_ADCTSC);
 //writel(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(info->presc&0xFF),\
    //    S3C2410_ADCCON);
 __raw_writel(WAIT4INT(0), S3C2410_ADCTSC);
 //printk(KERN_ERR "hi,the newer0 adctsc = 0x%08x!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",__raw_readl(S3C2410_ADCTSC));
 /* set gpio to XP, YM, YP and  YM */
// set_gpio_ctrl(GPIO_YPON);
// set_gpio_ctrl(GPIO_YMON);
// set_gpio_ctrl(GPIO_XPON);
 //set_gpio_ctrl(GPIO_XMON);
 //__raw_writel(__raw_readl(S3C2410_GPGCON)|(0xff<<24), S3C2410_GPGCON); FLA MASK

 __raw_writel(30000, S3C2410_ADCDLY); //added by hzh 30000--20000
 /* Enable touch interrupt */
 ret = request_irq(IRQ_ADC, s3c2410_isr_adc, SA_INTERRUPT,
     DEVICE_NAME, s3c2410_isr_adc);
 if (ret) goto adc_failed;
 ret = request_irq(IRQ_TC, s3c2410_isr_tc, SA_INTERRUPT,    //IRQ_TC--->IRQ_TIMER0
     DEVICE_NAME, s3c2410_isr_tc);
 if (ret) goto tc_failed;

 /* Wait for touch screen interrupts */
 printk(KERN_ERR "line %d passed!\n",__LINE__);
 wait_down_int();  //fla mask!
 //printk(KERN_ERR "hi,the newer1 adctsc = 0x%08x!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",__raw_readl(S3C2410_ADCTSC));
__raw_writel(0x12345678,S3C2410_ADCCON);
//printk(KERN_ERR "hi,the new adccon = 0x%08x!!!!!!!\n",__raw_readl(S3C2410_ADCCON));
#ifdef CONFIG_DEVFS_FS
 devfs_mk_dir("touchscreen");
 devfs_mk_cdev(MKDEV(tsMajor, TSRAW_MINOR), S_IFCHR|S_IRUGO|S_IWUSR, "touchscreen/%d", 0);
#endif

#ifdef CONFIG_PM
#if 0
 tsdev.pm_dev = pm_register(PM_GP_DEV, PM_USER_INPUT,
       s3c2410_ts_pm_callback);
#endif
 tsdev.pm_dev = pm_register(PM_DEBUG_DEV, PM_USER_INPUT,
       s3c2410_ts_pm_callback);
#endif
 //printk(DEVICE_NAME " hello,success initialized!!!!!!!!!!!!!!!!!!\n");

 return 0;
 tc_failed:
        {printk(KERN_ERR "tc failed!!!!!!!!!!!!!\n");
 free_irq(IRQ_ADC, s3c2410_isr_adc);}
 adc_failed:
         {printk(KERN_ERR "adc failed!!!!!!!!!!!!!\n");
  return ret;}
}

static struct device_driver s3c2410ts_driver = {
 .name  = DEVICE_NAME,
 .bus  = &platform_bus_type,
 .probe  = s3c2410ts_probe,
#ifdef CONFIG_PM
 .suspend = s3c2410ts_suspend,
 .resume  = s3c2410ts_resume,
#endif
};

static int __init s3c2410ts_init(void)
{
 
 int ret;
 

 printk("in s3c2410ts init()\n");
 ret = driver_register(&s3c2410ts_driver);
 if(ret)
  printk("register %s driver failed, return code is %d\n", DEVICE_NAME, ret);
 else printk(KERN_ERR "register %s driver success, return code is %d\n", DEVICE_NAME, ret);
 return ret;
}


static void __exit s3c2410ts_exit(void)
{
#ifdef CONFIG_DEVFS_FS 
 devfs_remove("touchscreen/%d", 0);
 devfs_remove("touchscreen");
#endif 
 unregister_chrdev(tsMajor, DEVICE_NAME);
#ifdef CONFIG_PM
 pm_unregister(tsdev.pm_dev);
#endif
 free_irq(IRQ_ADC, s3c2410_isr_adc);
 free_irq(IRQ_TC, s3c2410_isr_tc);
 driver_unregister(&s3c2410ts_driver);
}

module_init(s3c2410ts_init);
module_exit(s3c2410ts_exit);

////////////////////////////////////////////////regs-adc.h
#ifndef __ASM_ARCH_REGS_ADC_H
#define __ASM_ARCH_REGS_ADC_H "regs-adc.h"

#define S3C2410_VA_ADC    (0xF0000000+0x01000000)
#define S3C2410_ADCREG(x) ((x) + S3C2410_VA_ADC)

#define S3C2410_ADCCON       S3C2410_ADCREG(0x00)
#define S3C2410_ADCTSC       S3C2410_ADCREG(0x04)
#define S3C2410_ADCDLY       S3C2410_ADCREG(0x08)
#define S3C2410_ADCDAT0       S3C2410_ADCREG(0x0c)
#define S3C2410_ADCDAT1       S3C2410_ADCREG(0x10)

#define ADC_IN0                 0
#define ADC_IN1                 1
#define ADC_IN2                 2
#define ADC_IN3                 3
#define ADC_IN4                 4
#define ADC_IN5                 5
#define ADC_IN6                 6
#define ADC_IN7                 7
#define ADC_BUSY  1
#define ADC_READY  0
#define NOP_MODE  0
#define X_AXIS_MODE  1
#define Y_AXIS_MODE  2
#define WAIT_INT_MODE  3
/* ... */
#define ADCCON_ECFLG  (1 << 15)
#define PRESCALE_ENDIS  (1 << 14)
#define PRESCALE_DIS  (PRESCALE_ENDIS*0)
#define PRESCALE_EN  (PRESCALE_ENDIS*1)

#define PRSCVL(x)  (x << 6)
#define ADC_INPUT(x)  (x << 3)
#define ADCCON_STDBM  (1 << 2)        /* 1: standby mode, 0: normal mode */
#define ADC_NORMAL_MODE  (ADCCON_STDBM*0)
#define ADC_STANDBY_MODE (ADCCON_STDBM*1)
#define ADCCON_READ_START (1 << 1)
#define ADC_START_BY_RD_DIS (ADCCON_READ_START*0)
#define ADC_START_BY_RD_EN (ADCCON_READ_START*1)
#define ADC_START  (1 << 0)

#define UD_SEN   (1 << 8)
#define DOWN_INT  (UD_SEN*0)
#define UP_INT   (UD_SEN*1)
#define YM_SEN   (1 << 7)
#define YM_HIZ   (YM_SEN*0)
#define YM_GND   (YM_SEN*1)
#define YP_SEN   (1 << 6)
#define YP_EXTVLT  (YP_SEN*0)
#define YP_AIN   (YP_SEN*1)
#define XM_SEN   (1 << 5)
#define XM_HIZ   (XM_SEN*0)
#define XM_GND   (XM_SEN*1)
#define XP_SEN   (1 << 4)
#define XP_EXTVLT  (XP_SEN*0)
#define XP_AIN   (XP_SEN*1)
#define XP_PULL_UP  (1 << 3)
#define XP_PULL_UP_EN  (XP_PULL_UP*0)
#define XP_PULL_UP_DIS  (XP_PULL_UP*1)
#define AUTO_PST  (1 << 2)
#define CONVERT_MAN  (AUTO_PST*0)
#define CONVERT_AUTO  (AUTO_PST*1)
#define XP_PST(x)  (x << 0)

#endif /* __ASM_ARCH_REGS_ADC_H */

////下面是引用他人文章

在 linux2.6.14.1 中没有提供 s3c2410 的驱动,所以我们要新建驱动文件,从网上下载s3c2410_ts.c与s3c2410_ts.h两个文件,将s3c2410_ts.c 文件拷到 linux2.6.14.1/drivers/input/touchscreen 目录下,头文件则拷到源码包的include/asm/arch下,

   首先:我们需要修改 linux2.6.14/drivers/input/touchscreen 目录下的 makefile 文件,在文件的最后添加 :

obj-$(CONFIG_TOUCHSCREEN_S3C2410) += s3c2410_ts.o

第二:我们需要修改 linux2.6.14/ drivers/input/touchscreen/Kconfig 中添加:

     config TOUCHSCREEN_S3C2410

     tristate "Samsung S3C2410 touchscreen input driver"

     depends on ARCH_SMDK2410 && INPUT && INPUT_TOUCHSCREEN

     select SERIO

     help

     Say Y here if you have the s3c2410 touchscreen.

     If unsure, say N.

     To compile this driver as a module, choose M here: the

     module will be called s3c2410_ts.

    

config TOUCHSCREEN_S3C2410_DEBUG

     boolean "Samsung S3C2410 touchscreen debug messages"

     depends on TOUCHSCREEN_S3C2410

     help

     Select this if you want debug messages

修改完成以后,在我们配置内核的时候,就会增加关系s3c2410的触摸屏配置,我们选择上这些配置就可以把驱动增加进去了

Device drivers -->

          Input device support -->

                     Touchscreens -->

                      <*>Samsung S3C2410 touchscreen input driver

                      []Samsung s3c2410 touchscreen debug message

第三:在 /linux-2.6.14/arch/arm/mach-s3c2410/mach-smdk2410.c, 中增加如下内容:

#include <asm/arch/s3c2410_ts.h>

     static struct s3c2410_ts_mach_info s3c2410_ts_cfg __initdata = {

     .delay = 10000,

     .presc = 49,

     .oversampling_shift = 2,

     };

     在smdk2410_devices结构中,添加:

     &s3c_device_ts,

     在smdk2410_map_io函数中添加:

     set_s3c2410ts_info(&s3c2410_ts_cfg);

第四:在 /linux-2.6.14/ arch/arm/mach-s3c2410/devs.h 文件中添加:

     extern struct platform_device s3c_device_ts;

第五:在arch/arm/mach-s3c2410/devs.c文件中添加如下几行:

    /* Touchscreen */

#include <asm/arch/s3c2410_ts.h>

    static struct s3c2410_ts_mach_info s3c2410ts_info;

    void __init set_s3c2410ts_info(struct s3c2410_ts_mach_info *hard_s3c2410ts_info)

{

memcpy(&s3c2410ts_info,hard_s3c2410ts_info,sizeof(struct s3c2410_ts_mach_info));

}

EXPORT_SYMBOL(set_s3c2410ts_info);

struct platform_device s3c_device_ts = {

.name = "s3c2410-ts",

.id = -1,

.dev = {

.platform_data = &s3c2410ts_info,

}

};

EXPORT_SYMBOL(s3c_device_ts);

以上是参考网上的文章的,但仅此还不够,编译内核会出错,出错信息如下:

[arm@localhost linux-2.6.14.1]$ make zImage

  CHK     include/linux/version.h

make[1]: `include/asm-arm/mach-types.h' is up to date.

  CHK     include/linux/compile.h

  CHK     usr/initramfs_list

  CC      drivers/input/touchscreen/s3c2410_ts.o

drivers/input/touchscreen/s3c2410_ts.c: In function `touch_timer_fire':

drivers/input/touchscreen/s3c2410_ts.c:137: error: called object is not a function

drivers/input/touchscreen/s3c2410_ts.c:146: error: called object is not a function

drivers/input/touchscreen/s3c2410_ts.c: In function `stylus_action':

drivers/input/touchscreen/s3c2410_ts.c:189: error: called object is not a function

drivers/input/touchscreen/s3c2410_ts.c:193: error: called object is not a function

drivers/input/touchscreen/s3c2410_ts.c: In function `s3c2410ts_probe':

drivers/input/touchscreen/s3c2410_ts.c:254: error: called object is not a function

drivers/input/touchscreen/s3c2410_ts.c: In function `touch_timer_fire':

drivers/input/touchscreen/s3c2410_ts.c:137: warning: statement with no effect

drivers/input/touchscreen/s3c2410_ts.c:146: warning: statement with no effect

drivers/input/touchscreen/s3c2410_ts.c: In function `stylus_action':

drivers/input/touchscreen/s3c2410_ts.c:189: warning: statement with no effect

drivers/input/touchscreen/s3c2410_ts.c:193: warning: statement with no effect

drivers/input/touchscreen/s3c2410_ts.c: In function `s3c2410ts_probe':

drivers/input/touchscreen/s3c2410_ts.c:254: warning: statement with no effect

make[3]: *** [drivers/input/touchscreen/s3c2410_ts.o] Error 1

make[2]: *** [drivers/input/touchscreen] Error 2

make[1]: *** [drivers/input] Error 2

make: *** [drivers] Error 2

在网上搜也找不到解决方法,后来又搜到了一篇触摸屏驱动移植的文章,里面有说要新建regs-adc.h这个头文件的(言下之意他的linux2.6里没有这个),但我的里面有这个文件,经过对比,发现这个头文件里的一句:#define S3C2410_ADCTSC_XY_PST(x) (((x)&0x3)<<0),而我的2.6里自带的是#define S3C2410_ADCTSC_XY_PST (0x3<<0),改过之后,终于通过了,进入控制台后可以触摸了,并且可以看到这个触摸屏驱动在内核注册为 /dev/input/mouse0

  评论这张
 
阅读(632)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018