linux rs232触摸屏驱动程序,AR1020 触摸屏驱动 spi模式linux实现

/* linux/drivers/input/touchscreen/sep0718_ts.c

*

*

*  Copyright (C) 2010 SEU ASIC.

*

* This program is free software; you can redistribute it and/or modify

* it under the terms of the GNU General Public License as published by

* the Free Software Foundation; either version 2 of the License, or

* (at your option) any later version.

*

* This program is distributed in the hope that it will be useful,

* but WITHOUT ANY WARRANTY; without even the implied warranty of

* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

* GNU General Public License for more details.

*

* You should have received a copy of the GNU General Public License

* along with this program; if not, write to the Free Software

* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*

*/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

/* For ts->dev.id.version */

#define SEP_TSVERSION0x0101

void __iomem  *base;

#define PEN_TIMER_DELAY_JUDGE           2// judge whether the pendown message is a true pendown     jiffes

#define PEN_TIMER_DELAY_LONGTOUCH       1// judge whether the pendown message is a long-time touch  jiffes

struct sep_ts

{

struct input_dev *dev;

unsigned short zp;

unsigned short xp;

unsigned short yp;

struct timer_list ts_timer;

};

struct sep_ts *ts;//触摸屏结构体

unsigned short  SendCommand  (unsigned short ADCommand)

{

int data = 0;

*(volatile unsigned long*)(base + SEP0718_DR)=ADCommand;

while (!(*(volatile unsigned long*)(base + SEP0718_SR)& 0x4));

while (*(volatile unsigned long*)(base + SEP0718_SR) & 0x1);

data = *(volatile unsigned long*)(base + SEP0718_DR);

while ((*(volatile unsigned long*)(base + SEP0718_SR) & 0x8));

while (*(volatile unsigned long*)(base + SEP0718_SR) & 0x1);

return data;

}

void write_reg(unsigned short addr, unsigned short data)

{

//printk("we write the AR1020 register address :0x%x,data:0x%x\n",addr,data);

SendCommand(0x55);

SendCommand(0x05);

SendCommand(0x21);

SendCommand(0x00);

SendCommand(addr);

SendCommand(0x01);

SendCommand(data);

//printk(" write register end \n");

}

void read_reg(unsigned short addr)

{

SendCommand(0x55);

SendCommand(0x04);

SendCommand(0x20);

SendCommand(0x00);

SendCommand(addr);

SendCommand(0x01);

}

static void sep0718_ts_setup(void )

{

// printk("we are in sep0718 touch screen setup\n");

SEP0718_INT_DISABLE(INTSRC_EXT11);

*(volatile unsigned long*)GPIO_PORTI_DIR_V &=~(1<<11);

*(volatile unsigned long*)GPIO_PORTI_SEL_V |=(1<<11);

*(volatile unsigned long*)GPIO_PORTI_INTRSEL_V |=(1<<11);

*(volatile unsigned long*)GPIO_PORTI_INTRLEL_V |= (1<<11);

*(volatile unsigned long*)GPIO_PORTI_INTRPOL_V &= ~(1<<11);

writeb(0x0,  base + SEP0718_SSIENR);

writeb(0x47, base + SEP0718_CONTROL0);

writeb(0x00, base + SEP0718_CONTROL1);

writel(0x300, base + SEP0718_BAUDR);

writeb(0x1, base + SEP0718_TXFTLR);

writeb(0x0, base + SEP0718_RXFTLR);

writeb(0x0, base + SEP0718_DMACR);

writeb(0x0, base + SEP0718_IMR);

writeb(0x1, base + SEP0718_SER);

writeb(0x1, base + SEP0718_SSIENR);

mdelay(2);

*(volatile unsigned long*)GPIO_PORTI_INTRCLR_V |=(1<<11);

*(volatile unsigned long*)GPIO_PORTI_INTRCLR_V &= 0x000;                 //清除中断

SEP0718_INT_ENABLE(INTSRC_EXT11);

write_reg(0x2C,0x51);

write_reg(0x31,0x10);

printk("have  setup the touch screen \n");

}

static void tsevent(void)

{

int data[5] = {0};

int i;

int x,y;

*(volatile unsigned long*)(base + SEP0718_SSIENR)=0x0;

udelay(1);

*(volatile unsigned long*)(base + SEP0718_SSIENR)=0x1;

data[0]=SendCommand(0x00)&0x81;

data[1]=SendCommand(0x00)&0x3F;

data[2]=SendCommand(0x00)&0x1F;

data[3]=SendCommand(0x00)&0x3F;

data[4]=SendCommand(0x00)&0x1F;

ts->zp=data[0];

ts->xp=(((data[2]<<7)+data[1])-140)*800/(3850-140);

ts->yp=(((data[4]<<7)+data[3])-290)*480/(3850-290);

if((ts->xp)>800 && (ts->xp)<900 )

ts->xp=799;

else if((ts->xp) >=65000)

ts->xp=1;

if((ts->yp)>480 && (ts->yp) <520 )

ts->yp=479;

else if((ts->yp) >=65000)

ts->yp=1;

printk("x:%d,y:%d,p:%x\n",ts->xp,ts->yp,ts->zp);

if (ts->zp==0x81)

{

input_report_abs(ts->dev, ABS_X, ts->xp);

input_report_abs(ts->dev, ABS_Y, ts->yp);

input_report_key(ts->dev, BTN_TOUCH, 1);

input_report_abs(ts->dev, ABS_PRESSURE, 1);

input_sync(ts->dev);

ts->zp=0;

ts->xp=0;

ts->yp=0;

}

else if(ts->zp==0x80)

{

input_report_abs(ts->dev, ABS_X, ts->xp);

input_report_abs(ts->dev, ABS_Y, ts->yp);

input_report_key(ts->dev, BTN_TOUCH, 0);

input_report_abs(ts->dev, ABS_PRESSURE, 0);

input_sync(ts->dev);

}

return;

}

static void ts_timer_handler(unsigned long arg)

{

SEP0718_INT_ENABLE(INTSRC_EXT11);

return;

}

static int sep0718_ts_irqhandler(int irq, void *dev_id, struct pt_regs *regs)

{

//printk("we are in sep0718_ts_irqhandler\n");

SEP0718_INT_DISABLE(INTSRC_EXT11);

tsevent();

SEP0718_INT_ENABLE(INTSRC_EXT11);

*(volatile unsigned long*)GPIO_PORTI_INTRCLR_V |=(1<<11);

*(volatile unsigned long*)GPIO_PORTI_INTRCLR_V &= 0x000;                 //清除中断

return IRQ_HANDLED;

}

static int __init sep0718_ts_probe(struct platform_device *pdev)

{

struct input_dev *input_dev;

int err;

printk("sep0718_ts_probe!\n");

ts = kzalloc(sizeof(struct sep_ts), GFP_KERNEL);

base = ioremap(SSI2_BASE, SZ_4K);

if (base == NULL) {

printk("base is null\n");

}

input_dev = input_allocate_device();

if (!input_dev) {

err = -ENOMEM;

goto fail;

}

ts->dev = input_dev;

ts->dev->evbit[0] = ts->dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);

ts->dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);

input_set_abs_params(ts->dev, ABS_X, 0, 800, 0, 0);

input_set_abs_params(ts->dev, ABS_Y, 0, 480, 0, 0);

input_set_abs_params(ts->dev, ABS_PRESSURE, 0, 1, 0, 0);

//sprintf(ts->phys, "input(ts)");

//ts->dev->private = ts;

ts->dev->name = "SEP0718 Touchscreen";

//ts->dev->phys = ts->phys;

ts->dev->id.bustype = BUS_RS232;

ts->dev->id.vendor = 0xDEAD;

ts->dev->id.product = 0xBEEF;

ts->dev->id.version = SEP_TSVERSION;

if(request_irq(INTSRC_EXT11,sep0718_ts_irqhandler,0,"sep0718_ts",ts->dev))

{

printk("request ts irq11 failed!\n");

kfree(ts);

return -1;

}

/* All went ok, so register to the input system */

err = input_register_device(ts->dev);

if(err) {

free_irq(INTSRC_EXT11, ts->dev);

return -EIO;

}

sep0718_ts_setup();

setup_timer(&ts->ts_timer,ts_timer_handler,0);

return 0;

fail:input_free_device(input_dev);

kfree(ts);

return err;

}

static int sep0718_ts_remove(struct platform_device *dev)

{

printk(KERN_INFO "sep0718_ts_remove() of TS called !\n");

SEP0718_INT_DISABLE(INTSRC_EXT11);

free_irq(INTSRC_EXT11, ts->dev);

input_unregister_device(ts->dev);

return 0;

}

static int sep0718_ts_suspend(struct platform_device *dev, pm_message_t state)

{

SEP0718_INT_DISABLE(INTSRC_EXT11);

return 0;

}

static int sep0718_ts_resume(struct platform_device *pdev)

{

SEP0718_INT_ENABLE(INTSRC_EXT11);

return 0;

}

static struct platform_driver sep0718_ts_driver = {

.probe          = sep0718_ts_probe,

.remove         = sep0718_ts_remove,

.suspend        = sep0718_ts_suspend,

.resume         = sep0718_ts_resume,

.driver= {

.owner= THIS_MODULE,

.name= "sep0718_ts",

},

};

static char banner[] __initdata = KERN_INFO "sep0718 Touchscreen driver, (c) 2010 SEU ASIC\n";

static int __init sep0718_ts_init(void)

{

printk(banner);

return platform_driver_register(&sep0718_ts_driver);

}

static void __exit sep0718_ts_exit(void)

{

platform_driver_unregister(&sep0718_ts_driver);

}

module_init(sep0718_ts_init);

module_exit(sep0718_ts_exit);

MODULE_AUTHOR("liyu allenseu@gmail.com ");

MODULE_DESCRIPTION("sep0718 touchscreen driver");

MODULE_LICENSE("GPL");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的Linux内核RS232触摸屏驱动代码的示例,用于演示输入子系统的实现方法: ``` #include <linux/module.h> #include <linux/init.h> #include <linux/serial.h> #include <linux/input.h> #define TOUCHSCREEN_NAME "rs232_touchscreen" #define TOUCHSCREEN_MIN_X 0 #define TOUCHSCREEN_MAX_X 1023 #define TOUCHSCREEN_MIN_Y 0 #define TOUCHSCREEN_MAX_Y 767 static struct input_dev *ts_input_dev; static struct serio *ts_serio; static irqreturn_t ts_interrupt(int irq, void *dev_id) { u8 buf[3]; int x, y; serio_read(ts_serio, buf, sizeof(buf)); /* 解析串口数据,获取坐标信息 */ x = buf[0] | ((buf[1] & 0x0F) << 8); y = buf[2] | ((buf[1] & 0xF0) << 4); /* 转换坐标系 */ x = TOUCHSCREEN_MIN_X + x * (TOUCHSCREEN_MAX_X - TOUCHSCREEN_MIN_X) / 0xFFF; y = TOUCHSCREEN_MIN_Y + y * (TOUCHSCREEN_MAX_Y - TOUCHSCREEN_MIN_Y) / 0xFFF; /* 向输入子系统报告事件 */ input_report_abs(ts_input_dev, ABS_X, x); input_report_abs(ts_input_dev, ABS_Y, y); input_report_key(ts_input_dev, BTN_TOUCH, 1); input_sync(ts_input_dev); return IRQ_HANDLED; } static int ts_probe(struct serio *serio, struct serio_driver *drv) { int err; /* 分配输入设备结构体 */ ts_input_dev = input_allocate_device(); if (!ts_input_dev) return -ENOMEM; /* 设置输入设备参数 */ ts_input_dev->name = TOUCHSCREEN_NAME; ts_input_dev->id.bustype = BUS_RS232; ts_input_dev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); ts_input_dev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y); ts_input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); /* 注册输入设备 */ err = input_register_device(ts_input_dev); if (err) { input_free_device(ts_input_dev); return err; } /* 记录串口设备 */ ts_serio = serio; /* 注册中断 */ err = serio_open(ts_serio, drv); if (err) { input_unregister_device(ts_input_dev); return err; } err = request_irq(ts_serio->irq, ts_interrupt, IRQF_SHARED, TOUCHSCREEN_NAME, ts_serio); if (err) { serio_close(ts_serio); input_unregister_device(ts_input_dev); return err; } return 0; } static void ts_disconnect(struct serio *serio) { /* 释放中断和串口 */ free_irq(serio->irq, serio); serio_close(serio); /* 注销输入设备 */ input_unregister_device(ts_input_dev); input_free_device(ts_input_dev); } static const struct serio_device_id ts_serio_ids[] = { { .type = SERIO_RS232, .proto = SERIO_RS232, .id = SERIO_ANY_ID, .description = "RS232 Touchscreen", }, { } }; MODULE_DEVICE_TABLE(serio, ts_serio_ids); static struct serio_driver ts_drv = { .driver = { .name = "rs232_touchscreen", .owner = THIS_MODULE, }, .id_table = ts_serio_ids, .probe = ts_probe, .disconnect = ts_disconnect, }; static int __init ts_init(void) { return serio_register_driver(&ts_drv); } static void __exit ts_exit(void) { serio_unregister_driver(&ts_drv); } module_init(ts_init); module_exit(ts_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name <youremail@example.com>"); MODULE_DESCRIPTION("RS232 Touchscreen Driver"); ``` 以上代码中,驱动程序使用了输入子系统的API来报告触摸事件,并且通过解析串口数据来获取坐标信息。需要注意的是,不同的触摸屏硬件设备可能存在一些细节上的差异,因此需要仔细查阅硬件文档来进行相应的调整和修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值