免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1001 | 回复: 0
打印 上一主题 下一主题

6410platform触摸屏驱动 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-23 02:29 |只看该作者 |倒序浏览
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/wait.h>
#include <linux/poll.h>
#include <linux/mm.h>
#include <linux/dma-mapping.h>
#include <linux/device.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
#include <linux/sound.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/clk.h>
#include <asm/thread_info.h>
#include <asm/io.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("bzli");
struct touch_screen {
 struct input_dev *input; 
 char *name;
 struct timer_list tm;
 int interval;
 struct clk *ts_clk;
 unsigned long adccon, adctsc, adcdly,
  adcdat0, adcdat1, adcupdn,
  adcclrint, adcclrintpndnup; 
 void (*wait4down)(struct touch_screen *); 
 void (*wait4up)(struct touch_screen *);
 void (*auto_pst)(struct touch_screen *);
 irqreturn_t (*ts_handle)(int , struct touch_screen); 
 int (*get_x)(struct touch_screen *);
 int (*get_y)(struct touch_screen *);
 void (*timer_handle)(struct touch_screen *);
};
void s3c6410_ts_wait4down(struct touch_screen *t)
{
 iowrite32(3 | (1 << 4) | (1 << 6) | (1 << 7),
    t->adctsc); 
}
void s3c6410_ts_wait4up(struct touch_screen *t)
{
 iowrite32(3 | (1 << 4) | (1 << 6) | (1 << 7)
   | (1 << 8), t->adctsc);  
}
void s3c6410_ts_auto_pst(struct touch_screen *t)
{
 iowrite32( 1 << 2, t->adctsc); 
 iowrite32( 1 | (17 << 6) | ( 1 << 14) | ( 1 << 16),
   t->adccon);
}
irqreturn_t s3c6410_ts_handle(int irq, struct touch_screen *t)
{
 if (irq == IRQ_TC) {
  int temp;
  temp = ioread32(t->adcupdn);
  if (temp & 1) { //down
   t->auto_pst(t);
   iowrite32(temp & ~1, t->adcupdn);
   t->tm.expires = jiffies +
      t->interval;
   add_timer(&t->tm);
   //--------------------------
   input_event(t->input,
    EV_ABS, ABS_PRESSURE, 1);
  } else if (temp & (1 << 1)) { //up
   input_event(t->input,
    EV_ABS, ABS_PRESSURE, 0);
   input_event(t->input, EV_SYN, 0, 0);
   //--------------------------
   t->wait4down(t);
   iowrite32(temp & ~(1 << 1),
    t->adcupdn);
   del_timer(&t->tm);
  }
  iowrite32(0, t->adcclrintpndnup);
   
 } else if (irq == IRQ_ADC) {
  int x, y;
  x = t->get_x(t);
  y = t->get_y(t);
  input_event(t->input, EV_ABS, ABS_X, x);
  input_event(t->input, EV_ABS, ABS_Y, y);
  input_event(t->input, EV_SYN, 0, 0); 
  
  t->wait4up(t);
  iowrite32(0, t->adcclrint);
 }  
 return IRQ_HANDLED;
}
int s3c6410_ts_get_x(struct touch_screen *t)
{
 return (ioread32(t->adcdat0) & 0xfff);
}
int s3c6410_ts_get_y(struct touch_screen *t)
{
 return (ioread32(t->adcdat1) & 0xfff);
}
void s3c6410_ts_timer_handle(struct touch_screen *t)
{
 t->auto_pst(t); 
 t->tm.expires = jiffies + t->interval;
 add_timer(&t->tm);
}
struct touch_screen  s3c6410_ts;
int init_touch_screen(struct touch_screen *t)
{
 int ret = 0;
 
 t->name = "s3c6410 touch screen";
 t->adccon = ioremap(0x7E00B000, SZ_4K); 
 t->adctsc = t->adccon + 0x04;
 t->adcdly = t->adccon + 0x08;
 t->adcdat0 = t->adccon + 0x0c;
 t->adcdat1 = t->adccon + 0x10;
 t->adcupdn = t->adccon + 0x14;
 t->adcclrint = t->adccon + 0x18;
 t->adcclrintpndnup = t->adccon + 0x20;
 
 t->wait4down = s3c6410_ts_wait4down;
 t->wait4up   = s3c6410_ts_wait4up;
 t->auto_pst  = s3c6410_ts_auto_pst;
 t->ts_handle = s3c6410_ts_handle;
 t->get_x     = s3c6410_ts_get_x;
 t->get_y     = s3c6410_ts_get_y;
 t->timer_handle = s3c6410_ts_timer_handle;
 t->interval  = (HZ >> 2);
 init_timer(&t->tm);
 t->tm.function =  t->timer_handle;
 t->tm.data  = t;
 t->ts_clk = clk_get(NULL, "adc");
 clk_enable(t->ts_clk);  
//--------------------------------------------------------
 t->input = input_allocate_device();
 t->input->name = t->name; 
 t->input->evbit[0] = BIT(EV_ABS) | BIT(EV_SYN);
 input_set_abs_params(t->input, ABS_X, 0, 0xfff,
     0, 0);
 input_set_abs_params(t->input, ABS_Y, 0, 0xfff,
     0, 0);
 input_set_abs_params(t->input, ABS_PRESSURE, 0,
     1, 0, 0);
//-------------------------------------------------------
 
 request_irq(IRQ_TC, t->ts_handle, 0, t->name, t);
 request_irq(IRQ_ADC, t->ts_handle, 0, t->name, t);
  
 return ret;
}

void destroy_touch_screen(struct touch_screen *t)
{
 clk_disable(t->ts_clk);
 clk_put(t->ts_clk);
 
 free_irq(IRQ_ADC, t);
 free_irq(IRQ_TC, t);
 iounmap(t->adccon);
 
 input_free_device(t->input);
}
int ts_probe(struct platform_device *dev)
{
 int ret = 0;
 init_touch_screen(&s3c6410_ts);
 input_register_device(s3c6410_ts.input); 
 //----------------
 s3c6410_ts.wait4down(&s3c6410_ts); 
 return ret;
}
int ts_remove(struct platform_device *dev)
{
 int ret = 0;
 
 input_unregister_device(s3c6410_ts.input);
 destroy_touch_screen(&s3c6410_ts);
 return ret;
}
void ts_device_release(struct device *dev)
{
}
struct platform_device ts_device = {
 .name = "6410_ts",
 .dev = {
  .release = ts_device_release, 
 }, 
};
struct platform_driver ts_driver = {
 .probe = ts_probe,
 .remove = ts_remove,
 .driver = {
  .name = "6410_ts", 
 },
};
int test_init(void)
{
 int ret = 0;
 platform_device_register(&ts_device);
 platform_driver_register(&ts_driver);
 return 0;
}
void test_exit(void)
{
 platform_device_unregister(&ts_device);
 platform_driver_unregister(&ts_driver);
}
module_init(test_init);
module_exit(test_exit);
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP