기존 이솝 임베디드 포럼의 지식인 서비스가 게시판 형태로 변경되었습니다.
/*
* FileName main.c
* Author wangzhenhui
* Date 09/18/06
* Board SESI_AT91RM9200EDUKIT
* Desc touchscreen driver ads7843
*/
//#include <linux/config.h>
#include <linux/module.h>
//#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/kernel.h> /* printk() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/fcntl.h> /* O_ACCMODE */
#include <linux/delay.h>
#include <asm/system.h> /* cli(), *_flags */
#include <asm/uaccess.h> /* copy_*_user */
#include <asm/arch/board.h>
#include <asm/arch/gpio.h>
//#include <asm/hardware.h>
#include <linux/interrupt.h>
#include <asm/irq.h>
#include "ads7843.h"
//#undef DEBUG_ADS7843
#define DEBUG_ADS7843 1
#ifdef DEBUG_ADS7843
#define DBG_ADS7843(fmt, args...) printk(fmt,## args)
#else
#define DBG_ADS7843(fmt, args...)
#endif
struct ads7843_dev {
struct input_dev dev;
long xp;
long yp;
char phys[32];
u8 evt_head;
u8 evt_tail;
struct ts_event events[NR_EVENTS];
};
static void ads7843_ts_read_pos(struct ads7843_dev *);
static void ads7843_timer(unsigned long);
static struct ads7843_dev ads7843_device;
unsigned short data[2];
char touch_data[4];
static inline void ads7843_ts_evt_add(struct ads7843_dev *ts, unsigned short pressure, unsigned short x, unsigned short y)
{
int next_head;
next_head = (ts->evt_head + 1) & (NR_EVENTS - 1);
if (next_head != ts->evt_tail) {
ts->events[ts->evt_head].pressure = pressure;
ts->events[ts->evt_head].x = x;
ts->events[ts->evt_head].y = y;
do_gettimeofday(&ts->events[ts->evt_head].stamp);
ts->evt_head = next_head;
}
}
static inline void ads7843_ts_event_release(struct ads7843_dev *ts)
{
ads7843_ts_evt_add(ts, 0, 0, 0);
}
static irqreturn_t ads7843_pen_irq(int irq, void *dev_id, struct pt_regs *regs)
{
// struct ts_evnet event;
printk("ads7843_pen_irqn");
disable_irq(AT91_PIN_PD0);
ads7843_ts_read_pos(&ads7843_device/*, &event*/);
return IRQ_HANDLED;
}
static int ads7843_startup(struct ads7843_dev *ts)
{
/*int ret;
unsigned long j=jiffies;
if(down_interruptible(&ts->sem))
return -EINTR;*/
/* check if open first time */
// if(ts->use_count!=0)
// return -EBUSY;
/* init PIO */
// DBG_ADS7843("ADS7843 init PIO.n");
/* at91_set_gpio_output(TS_CS,0);
at91_set_gpio_output(TS_CLK,0);
at91_set_gpio_output(TS_DIN,0);
at91_set_gpio_input(TS_DOUT,0);
at91_set_gpio_input(AT91_PIN_PD0,0);
at91_set_gpio_input(AT91_PIN_PD4,0);*/
/* reg irq */
/* module counter add */
// ts->use_count++;
//up(&ts->sem);
return 0;
}
static unsigned short ads7843_transfer(unsigned char cmd)
{
int i;
unsigned char bit;
unsigned short read_data = 0;
/* CS# Low */
at91_sys_write(AT91_PIOA + PIO_CODR,TS_CS);
// at91_set_gpio_value(TS_CS, 0);
udelay(40);
/* Transform CMD */
for(i=1; i<=8; i++){
/* CMD Output */
bit = ( cmd >> (8-i) ) & 0x01 ;
// at91_set_gpio_value(TS_DIN, bit);
if(bit)
at91_sys_write(AT91_PIOA + PIO_SODR, TS_DIN);
else
at91_sys_write(AT91_PIOA + PIO_CODR, TS_DIN);
udelay(20);
/* CLK High */
//at91_set_gpio_value(TS_CLK, 1);
at91_sys_write(AT91_PIOA + PIO_SODR, TS_CLK);
udelay(40);
/* CLK Low */
//at91_set_gpio_value(TS_CLK, 0);
at91_sys_write(AT91_PIOA + PIO_CODR, TS_CLK);
udelay(20);
}
/* Waiting for busy */
udelay(50);
/* Read DATA */
for(i=7; i>=0; i--){
/* CLK High */
//at91_set_gpio_value(TS_CLK, 1);
at91_sys_write(AT91_PIOA + PIO_SODR, TS_CLK);
udelay(40);
/* CLK Low */
//at91_set_gpio_value(TS_CLK, 0);
at91_sys_write(AT91_PIOA + PIO_CODR, TS_CLK);
/* Data in */
if( (at91_sys_read(AT91_PIOA + PIO_PDSR) & TS_DOUT ) != 0)
//if( at91_get_gpio_value(TS_DOUT) != 0 )
read_data |= 1 << i;
udelay(40);
}
//printk("read data 0x%Xn",read_data);
/* CS# High */
//at91_set_gpio_value(TS_CS, 1);
at91_sys_write(AT91_PIOA + PIO_SODR, TS_CS);
udelay(50);
return read_data;
}
static void ads7843_ts_read_pos(struct ads7843_dev *ts/*, struct ts_event *event*/)
{
int i;
unsigned char cmd[2];
cmd[0] = MEASURE_8BIT_X;
cmd[1] = MEASURE_8BIT_Y;
for(i=0; i<2; i++){
data[i] = ads7843_transfer(cmd[i]);
}
//event->x = data[0];
//event->y = data[1];
//event->pressure = 100;
input_report_abs(&ads7843_device.dev, ABS_X, data[0]);
input_report_abs(&ads7843_device.dev, ABS_Y, data[1]);
input_report_abs(&ads7843_device.dev, BTN_TOUCH, 1);
input_sync(&ads7843_device.dev);
printk("ts read pos: x = %d, y = %dn", data[0], data[1]);
}
ssize_t ads7843_read(struct file *filp, char *buffer, size_t count,loff_t *f_pos)
{
memcpy(touch_data+0, &data[0], 2);
memcpy(touch_data+2, &data[1], 2);
copy_to_user(buffer, touch_data, 4);
}
return 0;
}
int ads7843_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
return 0;
}
int ads7843_release(struct inode *inode, struct file *filp)
{
struct ads7843_dev *ts = filp->private_data;
free_irq(AT91_PIN_PD0,ts);
return 0;
}
int ads7843_open(struct inode *inode, struct file *filp)
{
int ret = 0;
return ret;
}
ssize_t ads7843_write(struct file *filp, const char __user *buf, size_t count,
loff_t *f_pos)
{
return 0;
}
struct file_operations ads7843_fops = {
.owner = THIS_MODULE,
.read = ads7843_read,
.write = ads7843_write,
.ioctl = ads7843_ioctl,
.open = ads7843_open,
.release = ads7843_release,
};
void ads7843_cleanup_module(void)
{
printk("ads7843 module cleanup.n");
// kfree(ads7843_device);
free_irq(AT91_PIN_PD0,0);
input_unregister_device(&ads7843_device.dev);
}
int ads7843_init_module(void)
{
at91_sys_write(AT91_PIOA + PIO_PER, TS_CS | TS_CLK | TS_DIN | TS_DOUT);
at91_sys_write(AT91_PIOA + PIO_OER, TS_CS | TS_CLK | TS_DIN);
at91_sys_write(AT91_PIOD + PIO_ODR, TS_DOUT);
at91_sys_write(AT91_PIOA + PIO_SODR, TS_CS);
at91_sys_write(AT91_PIOA + PIO_CODR, TS_CLK | TS_DIN);
at91_sys_write(AT91_PIOD + PIO_PER, AT91_PIN_PD0 | AT91_PIN_PD4);
at91_sys_write(AT91_PIOD + PIO_ODR, AT91_PIN_PD0 | AT91_PIN_PD4);
int ret;
//ads7843_device = input_allocate_device();
/* mem alloc for device */
memset(&ads7843_device, 0, sizeof(struct ads7843_dev));
printk("initdjoejfn");
/* reg device */
init_input_dev(&ads7843_device.dev);
ads7843_device.dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
ads7843_device.dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
input_set_abs_params(&ads7843_device.dev, ABS_X, 0, 0x3FF, 0, 0);
input_set_abs_params(&ads7843_device.dev, ABS_Y, 0, 0x3FF, 0, 0);
sprintf(ads7843_device.phys, "ts/input0");
ads7843_device.dev.private = &ads7843_device;
ads7843_device.dev.name = ts_name;
ads7843_device.dev.phys = ads7843_device.phys;
ads7843_device.dev.id.bustype = BUS_RS232;
ads7843_device.dev.id.vendor = 0xDEAD;
ads7843_device.dev.id.product = 0xBEEf;
ads7843_device.dev.id.version = 0x0100;
ret=request_irq(AT91_PIN_PD0, ads7843_pen_irq,SA_SAMPLE_RANDOM | SA_TRIGGER_FALLING,
"ts", &ads7843_device.dev);
enable_irq(AT91_PIN_PD0);
if(ret)
{
DBG_ADS7843("request irq failed.n");
return ret;
}
ads7843_ts_evt_clear(&ads7843_device);
input_register_device(&ads7843_device.dev);
printk("input_register successn");
return 0;
fail:
ads7843_cleanup_module();
return ret;
}
module_init(ads7843_init_module);
module_exit(ads7843_cleanup_module);
MODULE_AUTHOR("Zhenhui wang, [email protected]");
MODULE_LICENSE("GPL");
input_register_device하니 등록에러가 납니다.
input : device ADS7843 TuchScreen is statically allocated, will not register Please convert to input_allocate_device() or ..이렇게 에러가 납니다..
왜 에러가 나는걸까요?
이렇게 하면 램디스크에 /dev/input/ts 생겨야 하는데요...안생기네요..아니면 직접 만들어줘야 하나요? 답변 부탁드립니다.
소스가 보기힘들어서 대충만 봤습니다만, 2.6서부터는 시키는대로 해야 잘 올라가더군요......^^