⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 touchscreen.c

📁 gpm-1.20.0.tar.gz
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -*- linux-c -*- *//*  * Driver for USB Touchscreen (Microtech - IBM SurePos 4820) * * Copyright (C) 2000 Wojciech Woziwodzki * Written by Radoslaw Garbacz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Originally based upon scanner.c (David E. Nelson). * * History * *  0.1  06/05/2000 (RGA) *    Development work was begun. * *  0.2  09/05/2000 (RGA) *    Documentation about MicroTouch controller was arrived. * */#include <linux/version.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/errno.h>#include <asm/uaccess.h>#include <linux/init.h>#include <linux/malloc.h>#include <linux/delay.h>#include <linux/ioctl.h>#include <linux/config.h>#include <linux/interrupt.h>#include <linux/ptrace.h>#include <linux/poll.h>#include <linux/in.h>#include <linux/malloc.h>#include <linux/tty.h>#include <linux/errno.h>#include <linux/string.h>	/* used in new tty drivers */#include <linux/signal.h>	/* used in new tty drivers */#include <asm/system.h>#include <asm/bitops.h>#include <asm/termios.h>#include <linux/if.h>#ifdef CONFIG_KERNELD#include <linux/kerneld.h>#endif//#define DEBUG#define TSCRN_IOCTL//#define __TEST_NO_DEVICE__#define TSCRN_MAX_MNR 16		/* We're allocated 16 minors */#define TSCRN_BASE_MNR 48		/* USB Scanners start at minor 48 */#define IS_EP_BULK(ep)  ((ep).bmAttributes == USB_ENDPOINT_XFER_BULK ? 1 : 0)#define IS_EP_BULK_IN(ep) (IS_EP_BULK(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)#define IS_EP_BULK_OUT(ep) (IS_EP_BULK(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)#define IS_EP_INTR(ep) ((ep).bmAttributes == USB_ENDPOINT_XFER_INT ? 1 : 0)#define IS_EP_INTR_IN(ep) (IS_EP_INTR(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)#define IS_EP_INTR_OUT(ep) (IS_EP_INTR(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)#define USB_TSCRN_MINOR(X) MINOR((X)->i_rdev) - TSCRN_BASE_MNR#ifdef DEBUG#define TSCRN_DEBUG(X) X#else#define TSCRN_DEBUG(X)#endif#include <linux/usb.h>#include <linux/input.h>#include "touchscreen.h"struct tscrn_usb_data{  struct usb_device *dev;  wait_queue_head_t wait;  struct urb irq;  struct urb ctrlin;  struct urb ctrlout;  devrequest *setup_packet;     // for control transfers   unsigned int ifnum;	        // Interface number of the USB device   kdev_t minor;	                // TouchScreen minor - used in disconnect()   unsigned char data[TSCRN_USB_RAPORT_SIZE_DATA];       // Data buffer X-Y, and button   int nLoopCounter;             // number of data packet last received +1  char isopen;		        // Not zero if the device is open   char present;		        // Not zero if device is present   unsigned char *obuf, *ibuf;	// transfer buffers   unsigned char *pToRead,*pToWrite;// pointers to toRead cell of buffer and to toWrite one   char intr_ep;                 // Endpoint assignments   struct input_dev input_dev;   // to work as an input device driver};static struct tscrn_usb_data *p_tscrn_table[TSCRN_MAX_MNR] = { NULL, /* ... */};MODULE_AUTHOR("Radoslaw Garbacz, garbacz@posexperts.com.pl");MODULE_DESCRIPTION("USB touchscreen driver");static __s32 vendor=-1, product=-1;MODULE_PARM(vendor, "i");MODULE_PARM_DESC(vendor, "User specified USB idVendor");MODULE_PARM(product, "i");MODULE_PARM_DESC(product, "User specified USB idProduct");/* Forward declarations */static struct usb_driver touchscreen_driver;/* Procedures *//** * Runs after ctrl requests. */static void ctrl_touchscreen(struct urb *urb){  struct tscrn_usb_data *tscrn = urb->context;  dbg("ctrl_touchscreen(%d): status=%d", tscrn->minor, urb->status);  if (waitqueue_active(&tscrn->wait))    wake_up_interruptible(&tscrn->wait);  return;};/** * Runs on new data received from device * The buffer should keep the last state of device, thus the buffer overflow * can occurre * The client can't read data when pToRead == pToWrite */static void irq_touchscreen(struct urb *urb){  /*   * data raports...   */  struct tscrn_usb_data *tscrn = urb->context;  struct tscrn_usb_data_report *data = (struct tscrn_usb_data_report *)tscrn->data;  if (urb->status) return;  //return when driver was clesed   if(!tscrn->isopen) return;  // increase loop counter  // !!! Unfortunately the data was lost to seldom !!!  //if((int)GET_LOOP(data) != tscrn->nLoopCounter)  //  warn("warn:Lost data new loop %d previous loop %d",(int)GET_LOOP(data),(int)tscrn->nLoopCounter);  input_report_key(&tscrn->input_dev, BTN_LEFT, IS_TOUCHED(data));  input_report_abs(&tscrn->input_dev, ABS_X, GET_XC(data));  input_report_abs(&tscrn->input_dev, ABS_Y, GET_YC(data));  tscrn->nLoopCounter = (GET_LOOP(data))+1;   // store data to buffer  memcpy(tscrn->pToWrite,data,TSCRN_USB_RAPORT_SIZE_DATA);  // next data to next cell  if(tscrn->pToRead == NULL)    tscrn->pToRead = tscrn->pToWrite;  tscrn->pToWrite += TSCRN_USB_RAPORT_SIZE_DATA;  if(tscrn->pToWrite >= tscrn->obuf+OBUF_SIZE)    tscrn->pToWrite = tscrn->obuf;  if (waitqueue_active(&tscrn->wait))    wake_up_interruptible(&tscrn->wait);  //dbg("irq_touchscreen(): GET_Data 0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x status=%d", (int)data[0],(int)data[1],(int)data[2],(int)data[3],(int)data[4],(int)data[5],(int)data[6],(int)data[7],(int)data[8],(int)data[9],(int)data[10], tscrn->ctrlout.status);  return;}static int open_touchscreen(struct inode * inode, struct file * file){  struct tscrn_usb_data *tscrn;  struct usb_device *dev;  kdev_t minor;#ifdef __TEST_NO_DEVICE__  return -ENODEV;#endif   minor = USB_TSCRN_MINOR(inode);  dbg("open_touchscreen: tscrn_minor:%d", minor);  if (!p_tscrn_table[minor])  {    err("open_touchscreen(%d): invalid tscrn_minor", minor);    return -ENODEV;  }  tscrn = p_tscrn_table[minor];  dev = tscrn->dev;  if (!dev)  {    return -ENODEV;  }  if (!tscrn->present) {    return -ENODEV;  }  if (tscrn->isopen) {    return -EBUSY;  }  //clear up the data buffer  memset(tscrn->obuf, 0x0, OBUF_SIZE);  tscrn->pToRead = NULL;  tscrn->pToWrite = tscrn->obuf;  tscrn->isopen = 1;  file->private_data = tscrn; /* Used by the read and write metheds */  MOD_INC_USE_COUNT;  return 0;}static int close_touchscreen(struct inode * inode, struct file * file){  struct tscrn_usb_data *tscrn;  kdev_t minor;#ifdef __TEST_NO_DEVICE__  return -ENODEV;#endif   minor = USB_TSCRN_MINOR (inode);  dbg("close_touchscreen: tscrn_minor:%d", minor);  if (!p_tscrn_table[minor]) {    err("close_touchscreen(%d): invalid tscrn_minor", minor);    return -ENODEV;  }  tscrn = p_tscrn_table[minor];  tscrn->isopen = 0;  file->private_data = NULL;  MOD_DEC_USE_COUNT;  return 0;}static ssize_t read_touchscreen(struct file * file, char * buffer,    size_t count, loff_t *ppos){  struct tscrn_usb_data *tscrn;  struct usb_device *dev;  ssize_t bytes_read;	/* Overall count of bytes_read */  ssize_t ret;  kdev_t minor;  int partial;		/* Number of bytes successfully read */  int this_read;		/* Max number of bytes to read */  //int result;  unsigned char *buf, *pToRead;#ifdef __TEST_NO_DEVICE__  return -ENODEV;#endif   tscrn = file->private_data;  minor = tscrn->minor;  buf = tscrn->obuf;  pToRead = tscrn->pToRead;  dev = tscrn->dev;  bytes_read = 0;  ret = 0;  if((tscrn->pToWrite == tscrn->pToRead) || (tscrn->pToRead == NULL))    return 0;   // no new data  if (signal_pending(current))  {    ret = -EINTR;    return ret;  }  this_read = (count >= TSCRN_USB_RAPORT_SIZE_DATA) ? TSCRN_USB_RAPORT_SIZE_DATA: count;  partial = this_read;  //dbg("read stats(%d): result:%d this_read:%d partial:%d", minor, result, this_read, partial);  dbg("read count=%d", count);  if (partial)  { /* Data returned */    if (copy_to_user(buffer, tscrn->pToRead, this_read))    {      ret = -EFAULT;      return ret;//break;    }    count -= partial;    bytes_read += partial;    buffer += partial;    tscrn->pToRead += partial;    if(tscrn->pToRead >= tscrn->obuf+OBUF_SIZE)      tscrn->pToRead = tscrn->obuf;  }  dbg("read ended bytes_read(%d)", bytes_read);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -