Chinaunix首页 | 论坛 | 博客
  • 博客访问: 90149
  • 博文数量: 17
  • 博客积分: 408
  • 博客等级: 一等列兵
  • 技术积分: 210
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-24 10:11
文章分类
文章存档

2012年(1)

2011年(16)

分类: 嵌入式

2011-10-11 14:59:15

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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);
阅读(2009) | 评论(0) | 转发(0) |
0

上一篇:input 键盘驱动及测试

下一篇:2440 uart

给主人留下些什么吧!~~