기존 이솝 임베디드 포럼의 지식인 서비스가 게시판 형태로 변경되었습니다.

/*
 * 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 생겨야 하는데요...안생기네요..아니면 직접 만들어줘야 하나요? 답변 부탁드립니다.


관리자

2009.02.24 06:09:30
*.32.117.22

아무래도 input device 다른 예제를 보셔야 할 듯 합니다.

소스가 보기힘들어서 대충만 봤습니다만, 2.6서부터는 시키는대로 해야 잘 올라가더군요......^^

정성욱

2009.02.24 06:14:22
*.247.184.164

혹시 그럼..ads784x 된 2.6에서 만들어진 input device 예제 있으신가요? 2주가 다 되어 가는데..휴~~~

관리자

2009.02.24 06:22:29
*.32.117.22

input device driver는 그다지 어려운게 아닙니다....쩝

커널 버전을 보시고, drivers/input/touchscreen/s3c2410_ts.c 를 참조하셔서
초기화 하는 부분만 보시기 바랍니다.

지금 메세지의 경우를 보면 동적으로 input device를 생성하라는 메세지 인 듯 싶네요.
다른 소스를 참조해서 보시면 동적으로 생성해서 해당 포인터를 붙이는 형태로 되어 있을겁니다.

그 부분을 참조하시면 어렵지 않을겁니다.
List of Articles
번호 제목 글쓴이 날짜 조회 수

CPU 어드레스 인식에 관한여 간단한 질문하나 드립니다. [4]

GStreamer Plug-In 타입의 코덱개발하시는 분 계신가요 ? [2]

native 개발환경 구축 방법 [2]

제가 ads7843 터치스크린 디바이스 드라이버를 만들었는데요..insmod ... [3]

스캐터 파일 질문 [2]

Filezilla 오픈소스... 리눅스에서 컴파일은 어떻게 하나요 ? [1]

외주 개발 업체를 찾습니다. [2]

su 유저 변경.. [3]

pxa255 MMU 설정 질문 - 2번째(그림 첨부) [8]

동영상 재생 솔루션 [5]

pxa255 MMU 설정 질문 [6]

kernel boot 관련 질문 [7]

flashlite로 UI개발에 대해서.. [3]

nfs mount에 대한 질문입니다. [3]

flashlite질문 [8]

buffers, cache 관련 질문 [2]

linux pci, pcie 포팅 관련 문의 [2]

linux base에서 동영상 녹화 [4]

Audio Driver에 관한.... [5]

리눅스 개발환경 [3]

사용자 로그인