(触摸屏)内核模块的定时器--来做中断源2

来源:互联网 发布:sharpdesk3.2扫描软件 编辑:程序博客网 时间:2024/06/05 06:21
//在触摸屏上可以划动的打印,x,y坐标
#include <linux/init.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/clk.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("bunter");


void function(unsigned long data);
irqreturn_t do_irq(int irq,void *data);
void wait_for_up();
void wait_for_down();
void auto_cvt();//==>更新dacdat
void get_lct();//打印
void time_on();
void time_off();


unsigned long ts_virt;
unsigned long *adctsc,*adcclrint,*adcclrintpndnu;
unsigned long *adccon,*adcupdn,*adcdat0,*adcdat1;
struct timer_list t;
struct clk *ts;


int test_init()
{
printk("hello test init\n");
  ts = clk_get(NULL,"adc");
        clk_enable(ts);//时钟


int ret = request_irq(IRQ_PENDN,do_irq,IRQF_SHARED,"mytouchtscreen",0x5555);
         if(ret<0)
         {
                 printk("request_irq IRQ_PENDN\n");
                 return ret;
         }
         ret = request_irq(IRQ_ADC,do_irq,IRQF_SHARED,"myadc",0x5555);
         if(ret<0)
         {
                 printk("request_irq IRQ_ADC\n");
                 return ret;
         }


ts_virt = ioremap(0x7e00b000,SZ_4K);
         adccon = ts_virt + 0x0;
         adctsc = ts_virt + 0x04;
         adcclrint = ts_virt + 0x18;
         adcclrintpndnu = ts_virt + 0x20;
         adcdat0 = ts_virt + 0x0c;
         adcdat1 = ts_virt + 0x10;
         adcupdn = ts_virt + 0x14;
 
         *adctsc = 0xd3;




return 0;
}


void test_exit()
{
printk("exit module\n");
}


module_init(test_init);
module_exit(test_exit);


void function(unsigned long data){
auto_cvt();
time_on();
// wait_for_up();
}


irqreturn_t do_irq(int irq,void *data)
{
if(irq == IRQ_PENDN)
{
*adcclrintpndnu = 1;


if(*adcupdn & 1)
{
printk("down touchscreen\n");
auto_cvt();
time_on();
wait_for_up();

}
if(*adcupdn &(1<<1))
{
printk("up touchscreen\n");
time_off();
wait_for_down();
}
*adcupdn = 0;
}
if(irq == IRQ_ADC)
{
*adcclrint = 1;
get_lct();
wait_for_up();
}
return IRQ_HANDLED;
}
void wait_for_up()
{
*adctsc = (1<<8)|0xd3;
}
void wait_for_down()
{
*adctsc = 0xd3;
}
void auto_cvt()
{


*adccon  = 1 | (30<<6)|(1<<14)|(1<<16);
        *adctsc |= 4;
}
void get_lct()
{
printk("x is :%x\n ",(*adcdat0) & 0xfff);
printk("y is :%x\n",(*adcdat1) & 0xfff);


}
void time_on()
{
init_timer(&t);
t.expires = jiffies +  (HZ>>1);//0.5秒
        t.function = function;
        t.data = 10;
add_timer(&t);
}
void time_off()
{
del_timer(&t);

}





default:
make -C /home/linux-2.6.28_smdk6410 M=`pwd`      //调用内核顶层目录中的makefile来编译当前目录下的makefile
clean:
make -C /home/linux-2.6.28_smdk6410 M=`pwd` clean
rm -rf modules.order
obj-m +=time.o



原创粉丝点击