kopia lustrzana https://gitlab.com/sane-project/backends
352 wiersze
8.8 KiB
C
352 wiersze
8.8 KiB
C
/*.............................................................................
|
|
* 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 "sane/sanei_usb.h"
|
|
#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 ......................................................*/
|