diff options
Diffstat (limited to 'backend/plustek-usbio.c')
-rw-r--r-- | backend/plustek-usbio.c | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/backend/plustek-usbio.c b/backend/plustek-usbio.c new file mode 100644 index 0000000..cae0e0d --- /dev/null +++ b/backend/plustek-usbio.c @@ -0,0 +1,351 @@ +/*............................................................................. + * Project : SANE library for Plustek flatbed scanners. + *............................................................................. + */ + +/** @file plustek-usbio.c + * @brief Some I/O stuff. + * + * Based on sources acquired from Plustek Inc.<br> + * Copyright (C) 2001-2007 Gerhard Jaeger <gerhard@gjaeger.de> + * + * History: + * History: + * - 0.40 - starting version of the USB support + * - 0.41 - moved some functions to a sane library (sanei_lm983x.c) + * - 0.42 - no changes + * - 0.43 - no changes + * - 0.44 - added dump registers and dumpPic functions + * - beautyfied output of ASIC detection + * - 0.45 - fixed dumpRegs + * - added dimension stuff to dumpPic + * - 0.46 - disabled reset prior to the detection of Merlin + * - 0.47 - no changes + * - 0.48 - cleanup + * - 0.49 - no changes + * - 0.50 - usbio_DetectLM983x() now returns error if register + * could not be red + * - usbio_ResetLM983x() checks for reg7 value before writing + * - 0.51 - allow dumpRegs to be called without valid fd + * - 0.52 - no changes + * . + * <hr> + * This file is part of the SANE package. + * + * 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., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + * + * As a special exception, the authors of SANE give permission for + * additional uses of the libraries contained in this release of SANE. + * + * The exception is that, if you link a SANE library with other files + * to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public + * License. Your use of that executable is in no way restricted on + * account of linking the SANE library code into it. + * + * This exception does not, however, invalidate any other reasons why + * the executable file might be covered by the GNU General Public + * License. + * + * If you submit changes to SANE to the maintainers to be included in + * a subsequent release, you agree by submitting the changes that + * those changes may be distributed with this exception intact. + * + * If you write modifications of your own for SANE, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * <hr> + */ + +#include "../include/sane/sanei_usb.h" +#include "../include/sane/sanei_lm983x.h" + +#define _UIO(func) \ + { \ + SANE_Status status; \ + status = func; \ + if (status != SANE_STATUS_GOOD) { \ + DBG( _DBG_ERROR, "UIO error\n" ); \ + return SANE_FALSE; \ + } \ + } + +#define usbio_ReadReg(fd, reg, value) \ + sanei_lm983x_read (fd, reg, value, 1, 0) + +typedef struct { + + u_char depth; + u_long x; + u_long y; +} PicDef, *pPicDef; + +static PicDef dPix; + +/** + */ +static void dumpPic( char* name, SANE_Byte *buffer, u_long len, int is_gray ) +{ + u_short type; + FILE *fp; + + if( DBG_LEVEL < _DBG_DPIC ) + return; + + if( NULL == buffer ) { + + DBG( _DBG_DPIC, "Creating file '%s'\n", name ); + + fp = fopen( name, "w+b" ); + + if( NULL != fp ) { + + if( 0 != dPix.x ) { + + if (is_gray) + type = 5; + else + type = 6; + + DBG( _DBG_DPIC, "> X=%lu, Y=%lu, depth=%u\n", + dPix.x, dPix.y, dPix.depth ); + if( dPix.depth > 8 ) + fprintf( fp, "P%u\n%lu %lu\n65535\n", type, dPix.x, dPix.y); + else + fprintf( fp, "P%u\n%lu %lu\n255\n", type, dPix.x, dPix.y); + } + } + } else { + fp = fopen( name, "a+b" ); + } + + if( NULL == fp ) { + DBG( _DBG_DPIC, "Can not open file '%s'\n", name ); + return; + } + + fwrite( buffer, 1, len, fp ); + fclose( fp ); +} + +/** + */ +static void dumpPicInit( ScanParam *sd, char* name ) +{ + dPix.x = sd->Size.dwPhyBytes; + + if( sd->bDataType == SCANDATATYPE_Color ) + dPix.x /= 3; + + if( sd->bBitDepth > 8 ) + dPix.x /= 2; + + dPix.y = sd->Size.dwLines; + dPix.depth = sd->bBitDepth; + + if( sd->bDataType == SCANDATATYPE_Color ) + dumpPic(name, NULL, 0, 0); + else + dumpPic(name, NULL, 0, 1); +} + +/** + * dump the LM983x registers + */ +static void dumpregs( int fd, SANE_Byte *cmp ) +{ + char buf[256], b2[10]; + SANE_Byte regs[0x80]; + int i; + + if( DBG_LEVEL < _DBG_DREGS ) + return; + + buf[0] = '\0'; + + if( fd >= 0 ) { + usbio_ReadReg(fd, 0x01, ®s[0x01]); + usbio_ReadReg(fd, 0x02, ®s[0x02]); + usbio_ReadReg(fd, 0x03, ®s[0x03]); + usbio_ReadReg(fd, 0x04, ®s[0x04]); + usbio_ReadReg(fd, 0x07, ®s[0x07]); + + sanei_lm983x_read( fd, 0x08, ®s[0x8], 0x80-0x8, SANE_TRUE ); + + for( i = 0x0; i < 0x80; i++ ) { + + if((i%16) ==0 ) { + + if( buf[0] ) + DBG( _DBG_DREGS, "%s\n", buf ); + sprintf( buf, "0x%02x:", i ); + } + + if((i%8)==0) + strcat( buf, " "); + + /* the dataport read returns with "0 Bytes read", of course. */ + if((i == 0) || (i == 5) || (i == 6)) + strcat( buf, "XX "); + else { + + sprintf( b2, "%02x ", regs[i]); + strcat( buf, b2 ); + } + } + DBG( _DBG_DREGS, "%s\n", buf ); + } + + if( cmp ) { + + buf[0] = '\0'; + + DBG( _DBG_DREGS, "Internal setting:\n" ); + for( i = 0x0; i < 0x80; i++ ) { + + if((i%16) ==0 ) { + + if( buf[0] ) + DBG( _DBG_DREGS, "%s\n", buf ); + sprintf( buf, "0x%02x:", i ); + } + + if((i%8)==0) + strcat( buf, " "); + + if((i == 0) || (i == 5) || (i == 6)) + strcat( buf, "XX "); + else { + sprintf( b2, "%02x ", cmp[i]); + strcat( buf, b2 ); + } + } + DBG( _DBG_DREGS, "%s\n", buf ); + } +} + +/** + * function to read the contents of a LM983x register and regarding some + * extra stuff, like flushing register 2 when writing register 0x58, etc + * + * @param handle - + * @param reg - + * @param value - + * @return + */ +static SANE_Bool usbio_WriteReg( SANE_Int handle, + SANE_Byte reg, SANE_Byte value ) +{ + int i; + SANE_Byte data; + + /* retry loop... */ + for( i = 0; i < 100; i++ ) { + + sanei_lm983x_write_byte( handle, reg, value ); + + /* Flush register 0x02 when register 0x58 is written */ + if( 0x58 == reg ) { + _UIO( usbio_ReadReg( handle, 2, &data )); + _UIO( usbio_ReadReg( handle, 2, &data )); + } + + if( reg != 7 ) + return SANE_TRUE; + + /* verify register 7 */ + _UIO( usbio_ReadReg( handle, 7, &data )); + if( data == value ) { + return SANE_TRUE; + } + } + + return SANE_FALSE; +} + +/** try and read register 0x69 from a LM983x to find out which version we have. + */ +static SANE_Status usbio_DetectLM983x( SANE_Int fd, SANE_Byte *version ) +{ + char buf[256]; + SANE_Byte value; + SANE_Status res; + + DBG( _DBG_INFO, "usbio_DetectLM983x\n"); + + res = usbio_ReadReg(fd, 0x69, &value); + if( res != SANE_STATUS_GOOD ) { + DBG( _DBG_ERROR, " * could not read version register!\n"); + return res; + } + + value &= 7; + if (version) + *version = value; + + res = SANE_STATUS_GOOD; + + sprintf( buf, "usbio_DetectLM983x: found " ); + + switch((SANE_Int)value ) { + + case 4: strcat( buf, "LM9832/3" ); break; + case 3: strcat( buf, "LM9831" ); break; + case 2: strcat( buf, "LM9830 --> unsupported!!!" ); + res = SANE_STATUS_INVAL; + break; + default: DBG( _DBG_INFO, "Unknown chip v%d", value ); + res = SANE_STATUS_INVAL; + break; + } + + DBG( _DBG_INFO, "%s\n", buf ); + return res; +} + +/** well, this is more or less a reset function, for LM9831 based devices + * we issue a real reset command, while for LM9832/3 based devices, checking + * and resetting register 7 will be enough... + */ +static SANE_Status usbio_ResetLM983x( Plustek_Device *dev ) +{ + SANE_Byte value; + HWDef *hw = &dev->usbDev.HwSetting; + + if( _LM9831 == hw->chip ) { + + DBG( _DBG_INFO," * resetting LM9831 device!\n"); + _UIO( sanei_lm983x_write_byte( dev->fd, 0x07, 0)); + _UIO( sanei_lm983x_write_byte( dev->fd, 0x07,0x20)); + _UIO( sanei_lm983x_write_byte( dev->fd, 0x07, 0)); + _UIO( usbio_ReadReg( dev->fd, 0x07, &value)); + if (value != 0) { + DBG( _DBG_ERROR, "usbio_ResetLM983x: reset was not " + "successful, status=%d\n", value ); + return SANE_STATUS_INVAL; + } + + } else { + _UIO( usbio_ReadReg( dev->fd, 0x07, &value)); + if (value != 0 ) { + DBG( _DBG_INFO," * setting device to idle state!\n"); + _UIO( sanei_lm983x_write_byte( dev->fd, 0x07, 0)); + } + } + return SANE_STATUS_GOOD; +} + +/* END PLUSTEK-USBIO.C ......................................................*/ |