ar1020 spi设备驱动的实现(有一个小bug)
时间:2010-07-23 来源:flysunni
最近在做一个设备驱动,验证spi总线的可用性,就为spi总线写 了一个设备驱动,驱动里面有个bug,原子操作调度什么的,不知道怎么回事。。。以后研读下任务调度在来解决,是任务调度那里出问题了。附上自己写的源码,仅供交流学习,希望牛人指点bug的具体解决方法,谢啦
/* linux/drivers/input/touchscreen/ar1020.c
#include <linux/kernel.h>
#include <linux/slab.h> #include <linux/input.h> #include <linux/init.h> #include <linux/serio.h>
#include <linux/platform_device.h>
#include <linux/module.h> #include <linux/types.h> #include <linux/fs.h> #include <linux/errno.h> #include <linux/mm.h> #include <linux/sched.h> #include <linux/init.h> #include <linux/cdev.h>
#include <linux/interrupt.h> #include <linux/time.h> #include <linux/spinlock_types.h> #include <linux/delay.h>
#include <asm/types.h> #include <asm/system.h> #include <asm/uaccess.h> #include <asm/io.h> #include <mach/hardware.h>
#include <linux/input.h> #include <mach/regs-spi.h> #include <linux/spi/spi.h> /* For ts->dev.id.version */ #define SEP_TSVERSION 0x0101
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 #define TS_POLL_DELAY (1 * 1000000) /* ns delay before the first sample */
/* this driver doesn't aim at the peak continuous sample rate */ #define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */)
struct sep_ts { struct input_dev *dev; unsigned short zp; unsigned short xp; unsigned short yp;
struct spi_message msg; struct spi_transfer xfer[10]; struct timer_list ts_timer; struct hrtimer timer; struct spi_device *spi; char data[5]; unsigned char read_x, read_y; spinlock_t lock; };
struct sep_ts *ts;//触摸屏结构体
struct write_reg { u8 data0; u8 data1; u8 data2; u8 data3; u8 data4; u8 data5; u8 data6; struct spi_message msg; struct spi_transfer xfer[6]; };
static int ar1020_write_reg(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct sep_ts *ts = dev_get_drvdata(dev); struct write_reg *req = kzalloc(sizeof *req, GFP_KERNEL); int status;
if (!req) return -ENOMEM; spi_message_init(&req->msg);
req->data0 = 0x55; req->xfer[0].tx_buf = &req->data0; req->xfer[0].len = 1; spi_message_add_tail(&req->xfer[0], &req->msg);
req->data1 = 0x05; req->xfer[1].tx_buf = &req->data1; req->xfer[1].len = 1; spi_message_add_tail(&req->xfer[1], &req->msg);
req->data2 = 0x21; req->xfer[2].tx_buf = &req->data2; req->xfer[2].len = 1; spi_message_add_tail(&req->xfer[2], &req->msg);
req->data3 = 0x00; req->xfer[3].tx_buf = &req->data3; req->xfer[3].len = 1; spi_message_add_tail(&req->xfer[3], &req->msg);
req->data4 = 0x31; req->xfer[4].tx_buf = &req->data4; req->xfer[4].len = 1; spi_message_add_tail(&req->xfer[4], &req->msg);
req->data5 = 0x01; req->xfer[5].tx_buf = &req->data5; req->xfer[5].len = 1; spi_message_add_tail(&req->xfer[5], &req->msg);
req->data6 = 0x10; req->xfer[6].tx_buf = &req->data6; req->xfer[6].len = 1; spi_message_add_tail(&req->xfer[6], &req->msg);
status = spi_sync(spi, &req->msg);
kfree(req); return status; }
static int ts_receive_data (struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct sep_ts *ts = dev_get_drvdata(dev); int status=0;
spi_message_init(&ts->msg);
ts->xfer[1].rx_buf = &ts->data[0]; ts->xfer[1].len = 5; spi_message_add_tail(&ts->xfer[1], &ts->msg);
return status; }
static void ar1020_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);
mdelay(2); *(volatile unsigned long*)GPIO_PORTI_INTRCLR_V |=(1<<11); *(volatile unsigned long*)GPIO_PORTI_INTRCLR_V &= 0x000; //清除中断 SEP0718_INT_ENABLE(INTSRC_EXT11);
printk("have setup the touch screen \n"); }
void tsevent(void) {
ts->zp=ts->data[0];
ts->xp=(((ts->data[2]<<7)+ts->data[1])-140)*800/(3850-140); ts->yp=(((ts->data[4]<<7)+ts->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);
/* linux/drivers/input/touchscreen/ar1020.c
#include <linux/kernel.h>
#include <linux/slab.h> #include <linux/input.h> #include <linux/init.h> #include <linux/serio.h>
#include <linux/platform_device.h>
#include <linux/module.h> #include <linux/types.h> #include <linux/fs.h> #include <linux/errno.h> #include <linux/mm.h> #include <linux/sched.h> #include <linux/init.h> #include <linux/cdev.h>
#include <linux/interrupt.h> #include <linux/time.h> #include <linux/spinlock_types.h> #include <linux/delay.h>
#include <asm/types.h> #include <asm/system.h> #include <asm/uaccess.h> #include <asm/io.h> #include <mach/hardware.h>
#include <linux/input.h> #include <mach/regs-spi.h> #include <linux/spi/spi.h> /* For ts->dev.id.version */ #define SEP_TSVERSION 0x0101
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 #define TS_POLL_DELAY (1 * 1000000) /* ns delay before the first sample */
/* this driver doesn't aim at the peak continuous sample rate */ #define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */)
struct sep_ts { struct input_dev *dev; unsigned short zp; unsigned short xp; unsigned short yp;
struct spi_message msg; struct spi_transfer xfer[10]; struct timer_list ts_timer; struct hrtimer timer; struct spi_device *spi; char data[5]; unsigned char read_x, read_y; spinlock_t lock; };
struct sep_ts *ts;//触摸屏结构体
struct write_reg { u8 data0; u8 data1; u8 data2; u8 data3; u8 data4; u8 data5; u8 data6; struct spi_message msg; struct spi_transfer xfer[6]; };
static int ar1020_write_reg(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct sep_ts *ts = dev_get_drvdata(dev); struct write_reg *req = kzalloc(sizeof *req, GFP_KERNEL); int status;
if (!req) return -ENOMEM; spi_message_init(&req->msg);
req->data0 = 0x55; req->xfer[0].tx_buf = &req->data0; req->xfer[0].len = 1; spi_message_add_tail(&req->xfer[0], &req->msg);
req->data1 = 0x05; req->xfer[1].tx_buf = &req->data1; req->xfer[1].len = 1; spi_message_add_tail(&req->xfer[1], &req->msg);
req->data2 = 0x21; req->xfer[2].tx_buf = &req->data2; req->xfer[2].len = 1; spi_message_add_tail(&req->xfer[2], &req->msg);
req->data3 = 0x00; req->xfer[3].tx_buf = &req->data3; req->xfer[3].len = 1; spi_message_add_tail(&req->xfer[3], &req->msg);
req->data4 = 0x31; req->xfer[4].tx_buf = &req->data4; req->xfer[4].len = 1; spi_message_add_tail(&req->xfer[4], &req->msg);
req->data5 = 0x01; req->xfer[5].tx_buf = &req->data5; req->xfer[5].len = 1; spi_message_add_tail(&req->xfer[5], &req->msg);
req->data6 = 0x10; req->xfer[6].tx_buf = &req->data6; req->xfer[6].len = 1; spi_message_add_tail(&req->xfer[6], &req->msg);
status = spi_sync(spi, &req->msg);
kfree(req); return status; }
static int ts_receive_data (struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct sep_ts *ts = dev_get_drvdata(dev); int status=0;
spi_message_init(&ts->msg);
ts->xfer[1].rx_buf = &ts->data[0]; ts->xfer[1].len = 5; spi_message_add_tail(&ts->xfer[1], &ts->msg);
return status; }
static void ar1020_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);
mdelay(2); *(volatile unsigned long*)GPIO_PORTI_INTRCLR_V |=(1<<11); *(volatile unsigned long*)GPIO_PORTI_INTRCLR_V &= 0x000; //清除中断 SEP0718_INT_ENABLE(INTSRC_EXT11);
printk("have setup the touch screen \n"); }
void tsevent(void) {
ts->zp=ts->data[0];
ts->xp=(((ts->data[2]<<7)+ts->data[1])-140)*800/(3850-140); ts->yp=(((ts->data[4]<<7)+ts->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);
相关阅读 更多 +