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

📄 fps200usb.c

📁 小程序,但是有点用出处的.进攻参考.请多多提意见.
💻 C
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************//* *      fps200usb.c  --  Veridicom FPS200 usb driver. * *      Copyright (C) 2002, 2003  Cristiano Rodrigues de Carvalho  *                                (crc@cefala.org) *      Developed at the Federal University of Minas Gerais (www.ufm.br) *      Laboratory of the Center for Research in Speech, Acoustics,  *      Language and Music (www.cefala.org) * *      The Author thanks CNPq - Brazil for the financial support * *      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. * * * History: *  01/08/2003: first release.  * * Todo: *  * finish the Finger Detect Circuit implementation. * *//*****************************************************************************/#include <linux/module.h>#include <linux/socket.h>#include <linux/miscdevice.h>#include <linux/list.h>#include <linux/vmalloc.h>#include <linux/slab.h>#include <linux/init.h>#include <asm/uaccess.h>#include <asm/atomic.h>#include <linux/delay.h>#include <linux/smp_lock.h>#include <linux/types.h>#include <linux/usb.h>#include "fps200usb.h"#include "fps200.h"#include "fps200ctl.h"#include "bmp.h"/* * Version Information */#define VERSION_NUMBER 0x0001#define DRIVER_VERSION "v0.02"#define DRIVER_AUTHOR "Cristiano Rodrigues de Carvalho, crc@cefala.org"#define DRIVER_DESC "FINGERSENSOR Veridicom's Sensor Interface Driver for Linux (c)2002, 2003"/* some compatible stuff */#ifndef MODULE_LICENSE#define MODULE_LICENSE(l)#endif/* let's get rid of the gcc 3x complaints about the __FUNCTION__ thing */#ifdef DEBUG#define fdbg(format, arg...) printk(KERN_DEBUG __FILE__ ": "  format "\n" , ## arg)#else#define fdbg(format, arg...) do {} while (0)#endif#define ferr(format, arg...) printk(KERN_ERR __FILE__ ": " /*__FUNCTION__ ": "*/ format "\n" , ## arg)/* I dont't know exactly when they changed the usb support (for better) but * I know that in 2.4.18 the support is good. I can change this latter  * for a older version if I figure out that the support for the new features * is older than that I touhght. */#define USB_SUPPORT_KERNEL KERNEL_VERSION(2,4,18)#ifndef min#define min(a,b) (a <= b ? a : b)#endif#ifndef max#define max(a, b) (a >= b ? a: b)#endif/* the bitmap file format header size */#define BMP_HEADER_SIZE (sizeof(WINBMPFILEHEADER) + sizeof(WIN2XBITMAPHEADER) + (256*sizeof(WIN2XPALETTEELEMENT)))/* the size of the header for pgm format */#define PGM_HEADER_SIZE 128 /* I think this should be more thant enough */#define RAW_HEADER_SIZE 0  /* it doesn't contain any header at all *//* we will fit the header of the file in only one size so we don't need   to manipulate memory every time the file format changes. It's easy   to control memory this way.*/#define BIGGEST_HEADER_SIZE (((unsigned int)max((unsigned int)BMP_HEADER_SIZE, (unsigned int)max((unsigned int)PGM_HEADER_SIZE, (unsigned int)RAW_HEADER_SIZE))+128 /* just to avoi problems due to different cpu data alignment */))#ifdef ENABLEDIRECTACCESS#warning "----------> You are compiling the driver with the option ENABLEDIRECTACCESS active. Be aware that this can be dangerous depending of your system configuration. See comments at readme file."#endif/* --------------------------------------------------------------------- *//** number of sensors supported for one machine */#define NRSENSORS 4/*-------------------------------------------------------------------*/static fps200usb_t fsusb[NRSENSORS];/* parameters for the module control */static int minor = FPS200USB_MINOR;/* parameters for the acquisition */static int dtr = 10;static int dcr = 6;static int pgc = 8;static int thr = 0;/* a copy for the parameters */static struct {  int dtr, dcr, pgc, thr;} parcopy;/*-------------------------------------------------------------------*//* some function prototypes */static void fps200_read_bulk_callback(struct urb *urb);static int fps200usb_configureImage(pfps200usb_t s, int file_format, int x, 				    int y, int width, int height);#ifdef INTERRUPT_HANDLINGstatic void fps200_interrupt_callback(struct urb *urb);static int fps200usb_configInterrupt(pfps200usb_t s);#endif/* ---------------------------------------------------------------- *//**\brief This function reads the especified register from the FPS200 sensor  * \param usbdev the device for the usb control * \param reg the register index * \param data the pointer to where data must be returned * \return >= 0 in case of sucess or < 0 in case of error */static int fps200_usb_readRegister(struct usb_device *usbdev, 				   int reg, unsigned char *data){  return usb_control_msg(usbdev, /* the device */			 usb_rcvctrlpipe(usbdev, 0),  /* pipe */			 FPS200_USB_READ_REQUEST, /* request */  			 USB_TYPE_VENDOR | USB_DIR_IN | 			 USB_RECIP_DEVICE,/* bmRequestType */			 reg, /* value */			 0, /* index */			 data, 			 1, 			 FPS200_USB_TIMEOUT);}/* ---------------------------------------------------------------- *//**\brief This function writes to the especified register  *        from the FPS200 sensor  * \param usbdev the device for the usb control * \param reg the register index * \param data to be written * \return 0 in case of sucess or < 0 in case of error */static int fps200_usb_writeRegister(struct usb_device *usbdev, 				   int reg, unsigned char data){  return usb_control_msg(usbdev, /* the device */			 usb_sndctrlpipe(usbdev, 0),  /* pipe */			 FPS200_USB_WRITE_REQUEST, /* request */  			 USB_TYPE_VENDOR | USB_DIR_OUT | 			 USB_RECIP_DEVICE,/* bmRequestType */			 (data << 8) | reg, /* value */			 0, /* index */			 NULL, 			 0, 			 FPS200_USB_TIMEOUT);}/* ---------------------------------------------------------------- *//**\brief Send Initialization commands to the sensor * \param usbdev the device for the usb control * \return 0 in case of sucess or < 0 in case of error */static int fps200_usb_sensorInitialization(pfps200usb_t s){  int ret;  /* Enable ADC */  fdbg("initializing the sensor");  /* Write CTRLB with bits 2 and 0 set - if using external clock, then     set bit 1 also */  if ((ret=fps200_usb_writeRegister(s->usbdev, FPS200_CTRLB, 				    FPS200_CTRLB_ENABLE |#ifdef INTERRUPT_HANDLING				    FPS200_CTRLB_AFDEN |#endif				    FPS200_CTRLB_AUTOINCEN				    )) < 0){    ferr("error trying to configure the device");     return ret;  }  /* wait 30us */  udelay(30);  /* Sensor Enabled */#ifdef INTERRUPT_HANDLING  /* configure interrupts - enable the Finger Detect Sensor to trigger finger   down. */  s->icr_state = FPS200_ICR_IE0 | FPS200_ICR_IP0 | FPS200_ICR_IM0;  if ((ret=fps200_usb_writeRegister(s->usbdev, FPS200_ICR, s->icr_state)) < 0){    ferr("error trying to configure interrupts for the device");    return ret;  }#endif  return 0;}				      /* ---------------------------------------------------------------- *//* \brief Disables the sensor saving power * \param usbdev the device for the usb control * \return 0 in case of sucess or < 0 in case of error */static int fps200_usb_sensorDisable(struct usb_device *usbdev) {  int ret;  fdbg("disabling the sensor");  if ((ret=fps200_usb_writeRegister(usbdev, FPS200_CTRLB, 0)) < 0)    return ret;  return 0;}/* ---------------------------------------------------------------- *//**\brief Starts the acquisition of the image * \param x initial line * \param y initial column * \param cx number of rows * \param cy number of columns * \return 0 if sucess or < 0 in case of error */static int fps200_usb_StartImageAcquisition(struct usb_device *usbdev, 					int x, int y, int cx, int cy){  int _cx, endrow, endcolumn;  unsigned char ctrla_com;  int ret;  if ((x < 0) || (y < 0) || (cx <= 0) || (cy <= 0))    return -1;  if (cx > FPS200_WIDTH)    cx = FPS200_WIDTH;  if (cy > FPS200_HEIGHT)    cy = FPS200_HEIGHT;  /* fits the best acquisition process */  if ((x == 0) && (y == 0) && (cx == FPS200_WIDTH) && (cy == FPS200_HEIGHT)) {    ctrla_com = FPS200_CTRLA_GETIMG;  }  else {        /* sanity check */    _cx = (cx / 64)*64;    endcolumn = x + _cx - 1;    if (endcolumn >= FPS200_WIDTH)      endcolumn = FPS200_WIDTH-1;    endrow = y + cy - 1;    if (endrow >= FPS200_HEIGHT)      endrow = FPS200_HEIGHT-1;    if ((ret=fps200_usb_writeRegister(usbdev, FPS200_RAH, 				      (y >> 8) & 0x01)) < 0)      return ret;      if ((ret=fps200_usb_writeRegister(usbdev, FPS200_RAL, y & 0xff)) < 0)      return ret;      if (cy == 1) {            /* single row acquisition */      ctrla_com = FPS200_CTRLA_GETROW;        }    else {      if ((ret=fps200_usb_writeRegister(usbdev, FPS200_CAL, x & 0xff)) < 0)	return ret;        if ((ret=fps200_usb_writeRegister(usbdev, FPS200_REH, 					(endrow >> 8) & 0x01)) < 0)	return ret;        if ((ret=fps200_usb_writeRegister(usbdev, FPS200_REL, 					endrow & 0xff)) < 0)	return ret;            if ((ret=fps200_usb_writeRegister(usbdev, FPS200_CEL, 					endcolumn & 0xff)) < 0)	return ret;            /* reads a subimage */      ctrla_com = FPS200_CTRLA_GETSUB;    }  }  /* starts the acquisition */  if ((ret=fps200_usb_writeRegister(usbdev, FPS200_CTRLA, ctrla_com)) < 0)    return ret;    return 0;}/* ---------------------------------------------------------------- *//* \brief called on the completion of a urb (read) function * \param s pointer to the control struct of the device */static void fps200_read_bulk_callback(struct urb *urb) {  pfps200usb_t s = (pfps200usb_t)urb->context;  if ((urb->status != -ENOENT) &&       (urb->status != -ECONNRESET)) {    if (urb->status != 0)      fdbg("status = %d\n", urb->status);    s->statusDataReceived = 1; /* ok */  }  else {    s->statusDataReceived = 0; /* error */  }  /* wake up pending processes */  wake_up_interruptible(&s->waitReadCompletion);    }#ifdef INTERRUPT_HANDLING/* ---------------------------------------------------------------- *//* \brief called on the reception of an interrupt * \param s pointer to the control struct of the device */static void fps200_interrupt_callback(struct urb *urb) {  pfps200usb_t s = (pfps200usb_t)urb->context;  fdbg("interrupt with value %02X status=%d",       s->irq_status & 0xff,       urb->status);  if (urb->status == -ENOENT){    dbg("urb status = ENOENT");    return;  }  return;#if 0  /* Interrupt handling is not operational yet. It seems that we can't     use usb commands inside the interrupt handling routines. The kernel     crashed when I tryed it */  if ((urb->status != -ENOENT) &&       (urb->status != -ECONNRESET)) {    if (urb->status != 0)      fdbg("status = %d\n", urb->status);    if (s->icr_state & FPS200_ICR_IP0)      fdbg("detected finger down");    else      fdbg("detected finger up");    /* change the detection direction */    s->icr_state ^= FPS200_ICR_IP0;    fps200_usb_writeRegister(s->usbdev, FPS200_ICR, s->icr_state);  }  else {    /* error */  }  /* acknowledges the interrupts */  fps200_usb_writeRegister(s->usbdev, FPS200_ISR, 			   s->irq_status & 			   (FPS200_ISR_IR0 | FPS200_ISR_IR1));#endif}#endif /* INTERRUPT_HANDLING *//* ---------------------------------------------------------------- *//* \brief implements the read operation on the driver * \param file the pointer to the file struct * \param buf the pointer to the user space buffer * \param count the number of bytes to be copied * \param ppos the pointer to the position of the file * \return return values conforming to the read function. */static ssize_t fps200usb_read (struct file *file, 			   char *buf, 			   size_t count, 			   loff_t * ppos){  pfps200usb_t s = (pfps200usb_t) file->private_data;  unsigned ret = 0;  int codret;  int rem;  int cnt;  if (s->fatal_error)    return -EIO;    if (*ppos)    return -ESPIPE;  if (s->remove_pending)    return -EIO;    if (!s->usbdev)    return -EIO;  down (&s->mutex);  while (count > 0) {    if (s->remove_pending) {      ret = -EIO;

⌨️ 快捷键说明

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