主题 : 编写的驱动不能进入触摸中断中--哪位大大能帮忙看看 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 8921
精华: 0
发帖: 3
金钱: 30 两
威望: 15 点
综合积分: 6 分
注册时间: 2009-09-11
最后登录: 2009-10-19
楼主  发表于: 2009-10-16 15:27

 编写的驱动不能进入触摸中断中--哪位大大能帮忙看看

自己在QQ2440上编写的驱动不能进入触摸中断中:
代码如下:/*

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/interrupt.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 <asm/io.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <asm/hardware.h>
#include <asm/arch/regs-gpio.h>
#include <asm/arch/regs-adc.h>
#include <linux/serio.h>
/* debug macros */
#undef 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
#define DEVICE_NAME "s3c2410-ts"
#define TSRAW_MINOR 1

static void __iomem *base_addr;

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

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;
//struct cdev cdev;
} 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 = 230;

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
  
#define wait_down_int(x) (iowrite32((((x)<<8) | S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | S3C2410_ADCTSC_XY_PST(3)),base_addr+S3C2410_ADCTSC))

#define AUTOPST     (iowrite32((S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN |   S3C2410_ADCTSC_AUTO_PST|S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0)),base_addr+S3C2410_ADCTSC))

/*待机模式*/
#define TSC_SLEEP  (iowrite32((S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0)),base_addr+S3C2410_ADCTSC))

/*启动AD转换*/
#define start_adc_x() (iowrite32((S3C2410_ADCCON_PRSCEN|S3C2410_ADCCON_PRSCVL(49)|S3C2410_ADCCON_STARTMASK),base_addr+S3C2410_ADCCON))

/*关闭TC中断*/
#define disable_ts_adc()(iowrite32(~(S3C2410_ADCCON_READ_START)&(ioread32(base_addr+S3C2410_ADCCON)),base_addr+S3C2410_ADCCON ))
static int adc_state = 0;
static int x, y; /* touch screen coorinates */

static void tsEvent_raw(void)
{
if (tsdev.penStatus == PEN_DOWN) {
  BUF_HEAD.x = x;
  BUF_HEAD.y = y;
  BUF_HEAD.pressure = PEN_DOWN;

#ifdef HOOK_FOR_DRAG
  ts_timer.expires = jiffies + TS_TIMER_DELAY;
  add_timer(&ts_timer);
#endif
} else {
#ifdef HOOK_FOR_DRAG
  del_timer(&ts_timer);
#endif
  
  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));

#ifdef USE_ASYNC
if (tsdev.aq)
  kill_fasync(&(tsdev.aq), SIGIO, POLL_IN);
#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;
   printk(DEVICE_NAME " ts_read\n");
retry:
if (tsdev.head != tsdev.tail) {
  int count;
  count = tsRead(&ts_ret);
  if (count)
   copy_to_user(buffer, (char *)&ts_ret, count);
   printk(DEVICE_NAME " ts_read11111111111\n");
  return count;
} else {
  if (filp->f_flags & O_NONBLOCK)
   return -EAGAIN;
  interruptible_sleep_on(&(tsdev.wq));
  if (signal_pending(current))
   return -ERESTARTSYS;
   printk(DEVICE_NAME " ts_read22222222222222\n");
  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;
AUTOPST;
start_adc_x();
}

static inline void s3c2410_get_XY(void)
{

  disable_ts_adc();
  y = (ioread32(base_addr+S3C2410_ADCDAT0)& 0x3ff);
  x = (ioread32(base_addr+S3C2410_ADCDAT1)& 0x3ff);
  tsdev.penStatus = PEN_DOWN;
  DPRINTK("PEN DOWN: x: %08d, y: %08d\n", x, y);
  wait_down_int(1);
  tsEvent();

}

static void s3c2410_isr_adc(int irq, void *dev_id, struct pt_regs *reg)
{
  printk(DEVICE_NAME "adc_isr\n");
spin_lock_irq(&(tsdev.lock));
if (tsdev.penStatus == PEN_UP)
   s3c2410_get_XY();
#ifdef HOOK_FOR_DRAG
else
   s3c2410_get_XY();
#endif
spin_unlock_irq(&(tsdev.lock));
}

static void s3c2410_isr_tc(int irq, void *dev_id, struct pt_regs *reg)
{
printk(DEVICE_NAME "tc_isr\n");
spin_lock_irq(&(tsdev.lock));
if (tsdev.penStatus == PEN_UP) {
   start_ts_adc();
} else {
   tsdev.penStatus = PEN_UP;
   DPRINTK("PEN UP: x: %08d, y: %08d\n", x, y);
   wait_down_int(0);
   tsEvent();
}
spin_unlock_irq(&(tsdev.lock));
}

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

   printk(DEVICE_NAME "ts-open\n");
// 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) {}

static int __init s3c2410_ts_init(void)
{
int ret;

tsEvent = tsEvent_dummy;

ret = register_chrdev(tsMajor, DEVICE_NAME, &s3c2410_fops);
if (ret < 0) {
   printk(DEVICE_NAME " can't get major number\n");
   return ret;
}


/* Enable touch interrupt */
ret = request_irq(IRQ_ADC, s3c2410_isr_adc, IRQF_SAMPLE_RANDOM,
     DEVICE_NAME, s3c2410_isr_adc);
if (ret) goto adc_failed;
ret = request_irq(IRQ_TC, s3c2410_isr_tc, IRQF_SAMPLE_RANDOM,
     DEVICE_NAME, s3c2410_isr_tc);
if (ret) goto tc_failed;

/*虚拟地址*/
  base_addr = ioremap(S3C2410_PA_ADC,0x20);    
  if (base_addr == NULL)
  {  
   printk(KERN_ERR "Failed to remap register block\n");      
   return -ENOMEM;  
}
/* Wait for touch screen interrupts */
wait_down_int(0);
printk(DEVICE_NAME " initialized\n");
return 0;
tc_failed:
free_irq(IRQ_ADC, s3c2410_isr_adc);
adc_failed:
return ret;
}

static void __exit s3c2410_ts_exit(void)
{
unregister_chrdev(tsMajor, DEVICE_NAME);
free_irq(IRQ_ADC, s3c2410_isr_adc);
free_irq(IRQ_TC, s3c2410_isr_tc);
}

module_init(s3c2410_ts_init);
module_exit(s3c2410_ts_exit);





我调试时:module能装载,open函数能进去,read函数也能进去,停止在read中,等待触摸,

但是每次触摸,就没反应了

就是不能进入触摸中断:

static void s3c2410_isr_tc(int irq, void *dev_id, struct pt_regs *reg)
{
printk(DEVICE_NAME "tc_isr\n");
spin_lock_irq(&(tsdev.lock));
if (tsdev.penStatus == PEN_UP) {
   start_ts_adc();
} else {
   tsdev.penStatus = PEN_UP;
   DPRINTK("PEN UP: x: %08d, y: %08d\n", x, y);
   wait_down_int(0);
   tsEvent();
}
spin_unlock_irq(&(tsdev.lock));
}

中。

请问大大们:

是不是我的注册中断有问题,或者是adc寄存器映射有问题,或者是管脚没设置,2410的adc管脚都要设置下,2440需要吗,??????



哪位大大能帮忙啊

*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
1楼  发表于: 2009-10-17 07:39
CLKCON寄存器中bit15: ADC(&Touch screen)置1了没有?
2.6.29内核里已经自带了S3C2410的触摸屏控制器驱动(drivers/input/touchscreen/s3c2410_ts.c),和你自己写的对比一下看看还漏了什么
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."