#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/serio.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <asm/io.h>
#include <asm/irq.h>
struct tiny_ts_regs {
unsigned long tsadccon1;
unsigned long tscon1;
unsigned long tsdly1;
unsigned long tsdatx1;
unsigned long tsdaty1;
unsigned long tspenstat1;
unsigned long clrintadc1;
unsigned long reserved;
unsigned long clrintpen1;
};
static struct input_dev *tiny_ts_dev;
static volatile struct tiny_ts_regs *tiny_ts_regs;
static unsigned long *tsadccon0;
static void enter_wait_pen_down_mode(void)
{
tiny_ts_regs->tscon1 = 0xd3;
}
static void enter_wait_pen_up_mode(void)
{
tiny_ts_regs->tscon1 = 0x1d3;
}
static irqreturn_t pen_down_up_irq(int irq, void *dev_id)
{
if (tiny_ts_regs->tsdatx1 & (1<<15))
{
printk("pen up\n");
enter_wait_pen_down_mode();
}
else
{
printk("pen down\n");
enter_wait_pen_up_mode();
}
return IRQ_HANDLED;
}
static int s3c_ts_init(void)
{
struct clk* clk;
/* 1. 分配一个input_dev结构体 */
tiny_ts_dev = input_allocate_device();
/* 2. 设置 */
/* 2.1 能产生哪类事件 */
set_bit(EV_KEY, tiny_ts_dev->evbit);
set_bit(EV_ABS, tiny_ts_dev->evbit);
/* 2.2 能产生这类事件里的哪些事件 */
set_bit(BTN_TOUCH, tiny_ts_dev->keybit);
input_set_abs_params(tiny_ts_dev, ABS_X, 0, 0x3FF, 0, 0);
input_set_abs_params(tiny_ts_dev, ABS_Y, 0, 0x3FF, 0, 0);
input_set_abs_params(tiny_ts_dev, ABS_PRESSURE, 0, 1, 0, 0);
/* 3. 注册 */
input_register_device(tiny_ts_dev);
/* 4. 硬件相关的操作 */
/* 4.1 使能时钟(CLKCON[15]) */
clk = clk_get(NULL, "adc");
clk_enable(clk);
/* 4.2 设置S3C2440的ADC/TS寄存器 */
tsadccon0 = ioremap(0xE1700000, 4);
tiny_ts_regs = ioremap(0xE1701000, sizeof(struct tiny_ts_regs));
/* s5pv210有触摸屏接口0,1
* Tiny210开发板向外提供接口1
* 所以这里选择接口1
*/
tsadccon0 |= 1<<17;
/* bit[14] : 1-A/D converter prescaler enable
* bit[13:6]: A/D converter prescaler value,
* 65, ADCCLK=PCLKP/(65+1)=66.7MHz/(65+1)=1MHz
* bit[2]: 默认为1,即Standby mode,我们要设置为0,正常模式
* bit[0]: A/D conversion starts by enable. 先设为0
*/
tiny_ts_regs->tsadccon1 &= ~(1<<2);
tiny_ts_regs->tsadccon1 |= (1<<14)|(65<<6);
request_irq(IRQ_TC, pen_down_up_irq, IRQF_SAMPLE_RANDOM, "ts_pen", NULL);
enter_wait_pen_down_mode();
return 0;
}
static void s3c_ts_exit(void)
{
free_irq(IRQ_TC, NULL);
iounmap(tiny_ts_regs);
iounmap(tsadccon0);
input_unregister_device(tiny_ts_dev);
input_free_device(tiny_ts_dev);
}
module_init(s3c_ts_init);
module_exit(s3c_ts_exit);
MODULE_LICENSE("GPL");
这是一个最简单的四线电阻屏驱动程序,它只是用于检测触摸笔有无按下,但是好像不响应IRQ_TC中断,不知道为什么?
用cat /proc/interrupts可以看到ts_pen已经注册成功。
量xp,yp引脚都为3.3v
量xm,ym引脚都为0V
当用触摸笔按下时,xp,yp变为0v,说明电阻屏是工作的,但就是不响应中断处理函数pen_down_up_irq,请问这是为什么呢?求各位大虾指导?