/*--------------------------------------------------------------------------- * * USB Biopod 3500 Driver - version 0.1.1 * * Micah Villmow, Michael A. Smith * Summer 2005 * Copyright 2005 - Michael A. Smith and Micah Villmow - All Rights Reserved * Purpose: declarations and definitions to be used by the biopod device driver * *--------------------------------------------------------------------------*/ #ifndef _BIOPOD_H_ #define _BIOPOD_H_ /*--------------------------------------------------------------------------- * * WW WW WW WW * WW WW WW * WWW WW WW WWW WW WWW WWW * WW W WW WW W WW W WW W W WW WW W * WW W WW WW W WW W WW W W WW WW WW W * WWW WW WW WWW WW WWW WW WW W * WW * WW * *--------------------------------------------------------------------------*/ #ifdef __KERNEL__ #include #include #include #include #include #include #include #include #include #include #include #define to_biopod_dev(d) container_of(d, struct usb_biopod, kref) #define send_register_and_value_to_device(regnum,value) \ { \ char buffer[4]; \ int tmp_int_num; \ sprintf(&buffer[0],"%c%c\n",(char)regnum,(char)value); \ retval = usb_bulk_msg(dev->udev, \ usb_sndbulkpipe(dev->udev,(dev->bulk_out).endpointAddr) \ ,buffer,2,&tmp_int_num,HZ); \ PDEBUG("%s - sent %d %s\n",current->comm,tmp_int_num,buffer); \ } #define size_of_buf(bufBegin, bufEnd) (size_t(bufEnd - bufBegin)) #define has_status(obj, some_status) \ (test_bit(some_status, (void*)&((obj)->status))) #define set_status(obj, some_status) \ set_bit(some_status, (void*)&(((obj)->status))) #define clear_status(obj, some_status) \ clear_bit(some_status, (void*)&(((obj)->status))) MODULE_LICENSE("GPL"); MODULE_AUTHOR("us"); /*MODULE_AUTHOR("Micah Villmow and Michael A. Smith"); */ /*MODULE_AUTHOR("Smith and Villmow Enterprises") */ MODULE_DESCRIPTION("Time to get your Biopod on!"); /*MODULE_DESCRIPTION("Fingerprint Scanner"); */ #define LARGE_NUMBER_OF_BYTES_FOR_BULK 30000 # ifdef BIOPOD_DEBUG # define BIOPOD_COUNT_REG_SETS 0 /* Register sets received. */ # define BIOPOD_COUNT_IMAGES 1 /* Images received. */ # define BIOPOD_COUNT_HISTOGRAMS 2 /* H/W histograms received. */ # define BIOPOD_COUNT_HEAD_SUB 3 /* Image subarray header count. */ # define BIOPOD_COUNT_HEAD_HIST 4 /* Histogram header count. */ # define BIOPOD_COUNT_HEAD_AUTH 5 /* Authentication header count. */ # define BIOPOD_COUNT_HEAD_REG 6 /* Register header count. */ # define BIOPOD_COUNT_ERR_HEAD_IN_DATA 7 /* Count of times a header byte */ /* .. (byte with MSB set) occur- */ /* .. red when the current byte */ /* .. should have been a data */ /* .. byte. */ # define BIOPOD_COUNT_ERR_UNREC_HEAD 8 /* Count of times an invalid */ /* .. header byte was received. */ /* .. Note that invalid bytes */ /* .. may or may not have their */ /* .. MSB set. We were expecting */ /* .. a header byte and got some-*/ /* .. thing strange. */ # define NUM_BIOPOD_DEBUGS 9 /* the # we just defined above */ # endif /* end if BIOPOD_DBUG */ #ifdef BIOPOD_DEBUG # ifdef __KERNEL__ /* This one if debugging is on, and kernel space */ # define PDEBUG(fmt, args...) printk( KERN_DEBUG "biopod: " fmt, ## args) # else /* This one for user space */ # define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args) # endif #else # define PDEBUG(fmt, args...) /* not debugging: nothing */ #endif #undef PDEBUGG #define PDEBUGG(fmt, args...) /* nothing: it's a placeholder */ #else /* in user space */ #include #include #include #endif /* end if __KERNEL__ else */ #define HAS_LTNG_RODS 0x01 #define IS_CARRIER_NULL_INVERTED 0x02 #define IS_PHASE_SHIFTED 0x04 #define IS_COL_SCAN_RATE_FIXED 0x08 #define IS_VALID_HISTROGRAM 0x01 #define IS_VALID_IMAGE 0x02 #define ARE_VALID_REGS 0x04 #define FRAME_HAS_ERROR 0x01 #define FRAME_IS_DONE 0x02 #define SENSOR_IS_ON 0x04 #define REGISTERS_ONLY 0x08 #define BIOPOD_ERROR_IBREAK 0 /* Break Interrupts */ #define BIOPOD_ERROR_FRAMING 1 /* Framing Errors */ #define BIOPOD_ERROR_PARITY 2 /* Parity Errors */ #define BIOPOD_ERROR_OVERRUN 3 /* Overrun Errors */ #define BIOPOD_ERROR_BUF_OVERFLOW 4 /* Input Buf Overflow Errors */ #define BIOPOD_ERROR_ARRAY_SIZE 5 #define BYTES_IN_AUTHORIZATION_DATA 8 #define BYTES_IN_REGISTER_DATA 1 #define BYTES_PER_COL_IN_IMG_SUBARRAY 8 #define BYTES_PER_HISTOGRAM_BIN 2 #define TEMPLATE_IS_VALID 0x01 #define TEMPLATE_IS_ENCRYPTED 0x02 #define TEMPLATE_IS_OK 0x04 #define BIOPOD_IOC_MAGIC 130 #define BIOPOD_IOCRESET _IO(BIOPOD_IOC_MAGIC,0) #define BIOPOD_IOCSTART _IO(BIOPOD_IOC_MAGIC,1) #define BIOPOD_IOCSTOP _IO(BIOPOD_IOC_MAGIC,2) #define BIOPOD_IOCDEFAULT _IO(BIOPOD_IOC_MAGIC,3) #define BIOPOD_IOCSINGLE _IO(BIOPOD_IOC_MAGIC,4) #define BIOPOD_IOCDEVRESET _IO(BIOPOD_IOC_MAGIC,5) #define BIOPOD_IOCASYNC _IO(BIOPOD_IOC_MAGIC,6) #define BIOPOD_IOCHIST _IO(BIOPOD_IOC_MAGIC,11) #define BIOPOD_IOCGAREG _IO(BIOPOD_IOC_MAGIC,7) #define BIOPOD_IOCGREGS _IOR(BIOPOD_IOC_MAGIC,8,struct biopod_sensor_registers) #define BIOPOD_IOCGIMAGE _IOR(BIOPOD_IOC_MAGIC,9,struct biopod_image) #define BIOPOD_IOCGHIST _IOR(BIOPOD_IOC_MAGIC,10,struct biopod_histogram) #define BIOPOD_IOCQREGS _IOR(BIOPOD_IOC_MAGIC,12,struct biopod_sensor_registers) #define BIOPOD_IOCQIMAGE _IOR(BIOPOD_IOC_MAGIC,13,struct biopod_image) #define BIOPOD_IOCQHIST _IOR(BIOPOD_IOC_MAGIC,14,struct biopod_histogram) #define BIOPOD_IOC_MAXNR 14 #define BIOPOD_NUM_SENSOR_FIELDS 61 /* Number of sensor fields */ #define BIOPOD_NUM_SENSOR_REGS 60 /* Number of sensor registers */ #define BIOPOD_NUM_SENSOR_ANALOG_CHANNELS 16 /* Number of analog chnls */ #define BIOPOD_NUM_SENSOR_SUBARRAYS 8 /* Number of sensor subarrays */ #define BIOPOD_HISTOGRAM_NUM_BINS 16 /* Number of sensor hist bins */ #define BIOPOD_HISTOGRAM_BYTES_PER_PIXEL 2 #define BIOPOD_NUM_HISTOGRAMS BIOPOD_NUM_SENSOR_SUBARRAYS #define BIOPOD_PHASE_TABLE_NUM_ROWS 2 #define BIOPOD_PHASE_TABLE_NUM_COLS 6 #define BIOPOD_GAIN_TABLE_NUM_ROWS 2 #define BIOPOD_GAIN_TABLE_NUM_COLS 8 #define BIOPOD_FOUR_TO_EIGHT_SIZE 16 #define BIOPOD_PIXEL_TABLE_SIZE 16 /* (not used ) */ #define BIOPOD_NUM_CAL_RESISTORS 2 #define BIOPOD_IMAGE_NUM_ROWS 128 #define BIOPOD_IMAGE_NUM_COLS 128 /* WHERE ARE THE IMAGE TYPES ? */ #define AT_PACKED_500DPI_IMAGE 0 typedef uint8_t reg_num_t; typedef uint8_t reg_val_t; typedef uint8_t header_t; typedef uint16_t template_t; typedef uint8_t matrix_data_t; typedef uint16_t hist_data_t; typedef unsigned char buf_data_t; typedef uint8_t bit_t; /*--------------------------------------------------------------------------*/ static const char *BIOPOD_FIELD_NAMES[] = { "(ILLEGAL)", "SENSOR_GAIN_1","SENSOR_GAIN_2","SENSOR_GAIN","CARRIER_NULL", "CARRIER_NULL_E","AD_REF_HI","AD_REF_LO","FINGER_DETECT", "MEASURE_FREQ","MEASURE_DRIVE","DETECT_FREQ","DETECT_DRIVE", "MAX_RES","COLUMN_SCAN_PER","FING_DETECT_CAP","FING_DETECT_RES", "Z_MATRIX_ENABLE","DEMOD_PHASE","REVISION_NUMBER","START_SCAN_ROW", "END_SCAN_ROW","DRIVE_BOOST","NORM_PHASE","IMAGE_DATA_DISABLE", "HISTOGRAM_EACH_ROW","MASTER_RESET","SET_ONE_SHOT","READ_REGISTERS", "CONTINUOUS_SCAN","ASYNC_REGISTER_UPD","EXCITATION_BIAS","DEBOUNCE_DELAY", "INTEGRATION_TIME","SENSE_AMP_BIAS","Z_MATRIX_VPATT","Z_MATRIX_HPATT", "DEMOD_PHASE_1","DEMOD_PHASE_2","Z_MATRIX_POWER","SAMPLE_HOLD_BIAS", "ANALOG_CHAN_BIAS","START_COL","END_COL","DATA_FORMAT", "THRESHOLD","TEST_REG_ENABLE","HISTOGRAM_FULL_ARY","HISTOGRAM_ENABLE", "GPO_0","GPO_1","GPO_2","GPO_3","Z_MATRIX_DOUBLER", "CHALLENGE_1","CHALLENGE_2","CHALLENGE_3","CHALLENGE_4", "CHALLENGE_5","_EXCITATION_SQUARE", "FORCE_FINGER_ON", "SSI_INT_ENABLE" }; /* [Right bit(start_bit)][left bit(end_bit)], (can be reversed) */ static const uint8_t BIOPOD_FIELD_MASK[8][8] = { {0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF}, {0x03, 0x02, 0x06, 0x0E, 0x1E, 0x3E, 0x7E, 0xFE}, {0x07, 0x06, 0x04, 0x0C, 0x1C, 0x3C, 0x7C, 0xFC}, {0x0F, 0x0E, 0x0C, 0x08, 0x18, 0x38, 0x78, 0xF8}, {0x1F, 0x1E, 0x1C, 0x18, 0x10, 0x30, 0x70, 0xF0}, {0x3F, 0x3E, 0x3C, 0x38, 0x30, 0x20, 0x60, 0xE0}, {0x7F, 0x7E, 0x7C, 0x78, 0x70, 0x60, 0x40, 0xC0}, {0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80} }; /* .. "index" used by AGC into */ /* .. composite gain 2/1 bits. */ /* Index meaning: */ /* 0 = 4x, 1=8x, 2=16x, 3=32x, 4=64x*/ /* 5=128x, 6=256x */ static const matrix_data_t gain_table_data_3500 [BIOPOD_GAIN_TABLE_NUM_ROWS][BIOPOD_GAIN_TABLE_NUM_COLS] = { { 0, 0, 0, 1, 2, 3, 3 }, { 0, 1, 2, 2, 2, 2, 3 } }; /* .. by measurement frequency. The entry from this phase table is */ /* .. added to the desired phase and anded with 0x7F before sending */ /* .. to the sensor. This table is specific to the AES3000 series */ static const matrix_data_t phase_table_data_3500 [BIOPOD_PHASE_TABLE_NUM_ROWS][BIOPOD_PHASE_TABLE_NUM_COLS] = { { 0x00, 0xB4, 0x38, 0x00, 0xB4, 0x38 }, { 0x00, 0xF9, 0x90, 0x00, 0xF9, 0x90 } }; /* see able_to_set_default_vals_for_regs for meaning */ static const uint8_t default_registers_3500[] = { 0x00, 0x00, 0x00, 0x10, 0x07, 0x7F, 0x03, 0x01, 0x02, 0x03, 0x05, 0x2F, 0x7A, 0x00, 0x20, 0x22, 0x00, 0x14, 0x03, 0x00, 0x0F, 0x00, 0x7F, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22 }; /* inverts as it converts to 8 bits */ static const uint8_t four_to_eight[BIOPOD_FOUR_TO_EIGHT_SIZE] = { 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00 }; /*--------------------------------------------------------------------------*/ #ifdef __KERNEL__ typedef enum { false, true } bool_t; #endif typedef enum { P_UNKNOWN, ENROLL, IDENTIFY, VERIFY } purpose_t; #define NUM_PURPOSES 4 typedef enum { I_UNKNOWN, RAW8I, I_2X8I, I_4X8I, SWIPE_PACKED, I_1500_SWIPED_PACKED, DISPLAY } biopod_image_t; /* 0 - Waiting for any header byte */ /* 1 - Processing register data */ /* 2 - Processing authorization bytes */ /* 3 - Processing "normal" image */ /* 4 - Processing histogram data */ typedef enum { WAITING_FOR_HEADER, PROCESSING_REG_DATA, PROCESSING_AUTHORIZATION, PROCESSING_IMAGE, PROCESSING_HISTOGRAM } read_state_t; struct matrix { uint8_t num_rows; uint8_t num_cols; matrix_data_t **data; }; typedef struct matrix matrix; struct chip_rev_range { uint8_t begin; /* Lowest Chip revision value for this snsr. */ uint8_t end; /* Highest Chip revision value for this snsr.*/ }; typedef struct chip_rev_range chip_rev_range; /* A struct for all the bulk_in stuff */ struct biopod_bulk_in { #ifdef __KERNEL__ struct semaphore bulk_in_mutex; #endif header_t hdr; /* the header byte of this bulk_in buffer */ buf_data_t *buffer; /* the bulk_in used by usb module */ size_t size; /* size of bulk_in buffer */ buf_data_t *data; /* a ptr to all data read during bulk read */ size_t data_size; /* amount of data read during bulk read */ buf_data_t *hdr_begin; /* pt in buf where the hdr info begins */ buf_data_t *hdr_end; /* pt in buf where the hdr info ends */ buf_data_t *data_begin; /* pt in buf where the actual data begins */ buf_data_t *data_end; /* pt in buf where the actual data ends */ buf_data_t *auth_data_off; /* authorization data offset */ #ifdef __KERNEL__ __u8 endpointAddr; /* the address of the bulk in endpoint */ #else uint8_t endpointAddr; #endif }; typedef struct biopod_bulk_in biopod_bulk_in; /* this isn't really necessary - it's here for symmetry */ struct biopod_bulk_out { #ifdef __KERNEL__ __u8 endpointAddr; #else uint8_t endpointAddr; #endif }; typedef struct biopod_bulk_out biopod_bulk_out; /* Structure to hold register information/range for bits to be modified */ struct biopod_sensor_register { size_t count; /* how many times has this reg come into parse */ #ifdef __KERNEL__ bool_t hasChanged; /* has this reg been changed across wutever */ #endif reg_val_t val; /* value of this register */ reg_val_t default_val; /* default value of this register */ }; typedef struct biopod_sensor_register biopod_sensor_register; struct biopod_sensor_registers { uint8_t num; uint8_t *runtime; #ifdef __KERNEL__ const uint8_t *defaults; #endif }; typedef struct biopod_sensor_registers biopod_sensor_registers; /* Structure to hold register information/range for bits to be modified */ struct biopod_sensor_field { reg_num_t reg_num; /* register number */ bit_t start_bit; /* start bit from l.o. (right) side (rightmost) */ bit_t end_bit; /* end bit from l.o. (right) side (leftmost) */ }; typedef struct biopod_sensor_field biopod_sensor_field; struct biopod_sensor_fields { uint8_t num; biopod_sensor_field *data; }; typedef struct biopod_sensor_fields biopod_sensor_fields; struct biopod_lightning_rod_info { uint8_t begin; /* Lightning Rod start (in raw image) */ uint8_t inc; /* Lightning Rod row increment */ }; typedef struct biopod_lightning_rod_info biopod_lightning_rod_info; struct biopod_lightning_rod_set { biopod_lightning_rod_info row; /* row info */ biopod_lightning_rod_info col; /* col info */ int8_t copy_row_offset; /* +1 to copy from row below */ /* -1 to copy from row above. */ }; typedef struct biopod_lightning_rod_set biopod_lightning_rod_set; struct biopod_sensor_calibrator_resistors { uint8_t num; uint8_t *res; }; typedef struct biopod_sensor_calibrator_resistors biopod_sensor_calibrator_resistors; struct biopod_sensor_calibrator { /* Calibration resistors, in order they are to be tried during calibration.*/ biopod_sensor_calibrator_resistors resistors; /* Amt to back off (increment) calibration capacitor value by, */ /* after finding free-run point. */ uint8_t cap_red; }; typedef struct biopod_sensor_calibrator biopod_sensor_calibrator; /* Structure for biopod histograms */ struct biopod_histogram { size_t count; /* num times came in during parsing */ uint16_t *bins; /* a bin is 16 bits... somehow */ uint8_t num_bins; /* num histogram bins */ uint8_t bytes_per_pixel; /* num bytes representing each pixel */ }; typedef struct biopod_histogram biopod_histogram; struct biopod_histograms { #ifdef __KERNEL__ struct semaphore histogram_mutex; #endif size_t count; uint8_t num; biopod_histogram *data; }; typedef struct biopod_histograms biopod_histograms; /* Structure for biopod images */ struct biopod_image { size_t id; /* Image (frame) number. */ matrix_data_t *data; /* pointer to image data. */ uint8_t num_cols; /* width of image, in pixels. */ uint8_t num_rows; /* height of image, in pixels. */ #ifdef __KERNEL__ /* driver specific variables, not for user space use */ uint8_t subarrays[8]; struct usb_biopod *dev; struct semaphore image_mutex; #endif }; typedef struct biopod_image biopod_image; struct biopod_register_vals { uint8_t num; reg_val_t *vals; }; typedef struct biopod_register_vals biopod_register_vals; struct biopod_register_vals_interface { #ifdef __KERNEL__ struct semaphore register_intf_mutex; #endif biopod_register_vals in; /* regs read from sensor */ biopod_register_vals out; /* regs written to sensor */ }; typedef struct biopod_register_vals_interface biopod_register_vals_interface; /* Structure for information from one frame from the sensor. */ struct biopod_frame { #ifdef __KERNEL__ struct semaphore frame_mutex; #endif biopod_histograms histos; /* subarray histos */ biopod_image image; /* Pointer to image data */ biopod_register_vals_interface regs; /* regs read and written to sns */ #ifdef __KERNEL__ atomic_t status; /* bits for checking validity */ /* bit 1 - IS_VALID_HISTOGRAM true if histogram is valid in frame. */ /* bit 2 - IS_VALID_IMAGE true if image is valid in frame. */ /* bit 3 - ARE_VALID_REGS true if registers are valid in frame */ /* bit 4 - IMAGE_FREE true if the current image is writable */ /* bit 5 - REGS_FREE true if the current registers are writeable */ /* bit 6 - HIST_FREE true if the histogram is writeable */ #endif }; typedef struct biopod_frame biopod_frame; /* Structure to hold sensor-specific attributes/information */ struct biopod_sensor { #ifdef __KERNEL__ struct semaphore sensor_mutex; #endif biopod_sensor_registers regs; biopod_sensor_fields fields; biopod_sensor_calibrator calibrator; biopod_lightning_rod_set lr; uint32_t input_length; /* Suggested input buffer size, in bytes. */ uint32_t output_length; /* Suggested output buffer size, in bytes. */ uint16_t dpi; /* Resolution of sensor, in dots-per-inch. */ uint8_t num_cols; /* Number of sensor columns. */ uint8_t num_rows; /* Number opaf sensor rows. */ uint8_t bits_per_pixel; /* Number of bits per pixel. */ uint8_t num_regs_to_send; /* Number of registers to send when sending */ /* .. a complete register set to sensor. */ uint8_t num_channels; /* Number of analog channels. */ chip_rev_range chip_rev; reg_val_t reg80_mask; /* Mask to be anded with reg 80 to clear */ /* .. self-resetting and reserved bits. */ reg_val_t reg81_mask; /* Mask to be anded with reg 81 to clear */ /* .. self-resetting and reserved bits. */ uint16_t errors[BIOPOD_ERROR_ARRAY_SIZE]; #ifdef __KERNEL__ atomic_t status; /* bits containing status (below) */ /* bit 1 - HAS_LTNG_RODS true if sensor array has ltng rods. */ /* bit 2 - IS_CARRIER_NULL_INVERTED true if carrier null is inverted. */ /* bit 3 - IS_PHASE_SHIFTED true if phase needs to be shifted before storing in Demod Phase 1 and 2 */ /* bit 4 - IS_COL_SCAN_RATE_FIXED true if col scan rate should be 1 */ #endif }; typedef struct biopod_sensor biopod_sensor; #ifdef __KERNEL__ /* Structure to hold all of our device specific stuff */ struct usb_biopod { struct usb_device *udev; /* the usb device for this dev */ struct usb_interface *interface; /* the interface for this dev */ struct kref kref; struct semaphore biopod_mutex;/* use this to lock out the whole struct */ biopod_bulk_in bulk_in; /* a struct for bulk_in needs */ biopod_bulk_out bulk_out; /* a struct for bulk_out needs */ /*biopod_generic_template biopod_template;*/ /* not sure if needed */ biopod_sensor sensor; biopod_frame frame; matrix phase_table; const uint8_t *four_to_eight; const uint8_t *pixel_table; matrix gain_table; read_state_t read_state; /* bit 1 is for biopod_read * bit 2 is for biopod_write */ uint8_t usage; atomic_t status; /* bits for status (see below) */ /* bit 1 - FRAME_HAS_ERROR true if current frame has errors. */ /* bit 2 - FRAME_IS_DONE true if if the current frame completed */ /* bit 3 - SENSOR_IS_ON true if sensor power is currently on */ /* bit 4 - REGISTERS_ONLY true if expecting only registers. */ #ifdef BIOPOD_DEBUG uint32_t debug_counts[NUM_BIOPOD_DEBUGS]; #endif /* end if BIOPOD_DEBUG */ }; typedef struct usb_biopod usb_biopod; #endif /*--------------------------------------------------------------------------*/ #endif /* end if _BIOPOD_H_ */