Fs2410上基于linux触摸屏的移植

来源:互联网 发布:淘宝复刻潮牌店铺排行 编辑:程序博客网 时间:2024/04/29 08:42

Fs2410上基于linux触摸屏的移植

device 设备的增加

增加如下的两个结构:

static struct platform_device s3c_ts = {

       .name               = "s3c2410ts",

       .id            = 4,

       .num_resources        = 0,

       .resource   = NULL,

};

 

static struct platform_device *smdk2410_devices[] __initdata = {

       &s3c_device_usb,

       &s3c_device_lcd,

       &s3c_device_wdt,

       &s3c_device_i2c,

       &s3c_device_iis,

       &s3c_device_ts,      //在平台设备中增加如下的结构;

};

 

Driver的增加

static struct device_drivers3c2410ts_driver = {

       .name             = DEVICE_NAME,

       .bus        = &platform_bus_type,

       .probe            = s3c2410ts_probe,

};

 

static int __init s3c2410ts_init(void)

{

       int ret;

       printk(KERN_EMERG "s3c2410ts init\n");

       ret = driver_register(&s3c2410ts_driver);

       return ret;

}

 

tatic void __exit s3c2410ts_exit(void)

{

       unregister_chrdev(tsMajor, DEVICE_NAME);

       free_irq(IRQ_ADC, s3c2410_isr_adc);

       free_irq(IRQ_TC, s3c2410_isr_tc);

       driver_unregister(&s3c2410ts_driver);

}

 

module_init(s3c2410ts_init);

module_exit(s3c2410ts_exit);

具体的驱动函数操作

1.probe注册函数

static int s3c2410ts_probe(struct device *dev)

{

 

       

 unsigned long SRCPND            ;

 unsigned long INTMOD            ;

 unsigned long INTMSK;

 unsigned long INTPND             ;

 unsigned long INTOFFSET     ;

 unsigned long SUBSRCPND      ;

 unsigned long INTSUBMSK     ;

 unsigned long EINTMASK      ;

 unsigned long EINTPEND       ;

 struct clk *adc_clock;

 

       int ret;

   printk(KERN_EMERG "s3c2410ts in probe\n");

       tsEvent = tsEvent_dummy;

 

       ret = register_chrdev(0, DEVICE_NAME, &s3c2410_fops);

       if (ret < 0) {

         printk(DEVICE_NAME " can't get major number\n");

         return ret;

       }

       tsMajor = ret;

       printk("%s device driver MAJOR:%d\n", DEVICE_NAME, tsMajor);

         adc_clock = clk_get(NULL, "adc");

    if (!adc_clock) {

        printk(KERN_EMERG "S3C2410 failed to get adc clock source ");

        return -ENOENT;

                                       }

          else

                     {

                   printk(KERN_EMERG "S3C2410 SUCCESS to get adc clock source ");

                     }

   // clk_use(adc_clock);//这个在高版本下已经不需要了

    clk_enable(adc_clock);

 

   

 

       __raw_writel(__raw_readl(S3C2410_GPGCON)|(0xff<<24), S3C2410_GPGCON);

 

       __raw_writel(30000, S3C2410_ADCDLY); //added by hzh

       /* Enable touch interrupt */

       ret = request_irq(IRQ_ADC, s3c2410_isr_adc,IRQF_DISABLED/* SA_INTERRUPT*/,

                       DEVICE_NAME, NULL);

       if (ret) goto adc_failed;

       ret = request_irq(IRQ_TC, s3c2410_isr_tc,IRQF_DISABLED/* SA_INTERRUPT*/,

                       DEVICE_NAME, NULL);

       if (ret) goto tc_failed;

 

       /* Wait for touch screen interrupts */

       wait_down_int();

       return 0;

 tc_failed:

       free_irq(IRQ_ADC, s3c2410_isr_adc);

 adc_failed:

       return ret;

}

 

2.两个中断函数

static irq_handler_t s3c2410_isr_adc(int irq, void *dev_id, struct pt_regs *reg)

{

   printk(KERN_EMERG "s3c2410_isr_adc\n");

       spin_lock_irq(&(tsdev.lock));

       if (tsdev.penStatus == PEN_UP)

         s3c2410_get_XY();

       spin_unlock_irq(&(tsdev.lock));

 

       return IRQ_HANDLED;

}

 

static irqreturn_t s3c2410_isr_tc(int irq, void *dev_id, struct pt_regs *reg)

{

   printk(KERN_EMERG "s3c2410_isr_tc\n");

       spin_lock_irq(&(tsdev.lock));

       if (tsdev.penStatus == PEN_UP) {

         ts_r_idx = 0;             //add by hzh

         ts_r_beg = 5;

         start_ts_adc();

       } else {

         tsdev.penStatus = PEN_UP;

         DPRINTK("PEN UP: x: %08d, y: %08d\n", x, y);

         wait_down_int();

         tsEvent();

       }

       spin_unlock_irq(&(tsdev.lock));

 

       return IRQ_HANDLED;

}

 

无法触发ADC中断的原因

由于linux使用了节电的处理,所以部分设备没有时钟,所以需要动态的启动。

adc_clock = clk_get(NULL, "adc");
  if (!adc_clock) {
  printk(KERN_ERR "failed to get adc clock source ");
  return -ENOENT;
  }
  clk_enable(adc_clock);

原创粉丝点击