diff --git a/backend/plustek-usbhw.c b/backend/plustek-usbhw.c
index 1fa67f1f2..8c126e895 100644
--- a/backend/plustek-usbhw.c
+++ b/backend/plustek-usbhw.c
@@ -43,6 +43,9 @@
* - 0.49 - a_bRegs is now part of the device structure
* - fixed problem in backtracking, when speedup is enabled
* - added usb_UpdateButtonStatus()
+ * - 0.50 - added button support for Plustek/Genius devices
+ * - changed behaviour of usb_IsScannerReady
+ * - added special misc I/O setup for CIS devices (usb_ResetRegisters)
* .
*
* This file is part of the SANE package.
@@ -125,7 +128,7 @@ static void usb_Swap( u_short *pw, u_long dwBytes )
* according to the model, the function returns the address of
* the corresponding entry of the Motor table
*/
-static pClkMotorDef usb_GetMotorSet( eModelDef model )
+static ClkMotorDef *usb_GetMotorSet( eModelDef model )
{
int i;
@@ -151,7 +154,6 @@ static SANE_Bool usb_MotorOn( Plustek_Device *dev, SANE_Bool fOn )
dev->usbDev.a_bRegs[0x45] &= ~0x10;
usbio_WriteReg( dev->fd, 0x45, dev->usbDev.a_bRegs[0x45] );
-
return SANE_TRUE;
}
@@ -169,7 +171,8 @@ static SANE_Bool usb_IsScannerReady( Plustek_Device *dev )
u_char value;
double len;
long timeout;
- struct timeval t;
+ struct timeval t;
+ SANE_Status res;
/* time in s = 1000*scanner length in inches/max step speed/in */
len = (dev->usbDev.Caps.Normal.Size.y/(double)_MEASURE_BASE) + 5;
@@ -184,26 +187,29 @@ static SANE_Bool usb_IsScannerReady( Plustek_Device *dev )
timeout = t.tv_sec + len;
do {
- _UIO( usbio_ReadReg( dev->fd, 7, &value));
-
- if( value == 0 ) {
- _UIO( usbio_ResetLM983x( dev ));
- return SANE_TRUE;
- }
-
- if((value == 0) || (value >= 0x20) || (value == 0x03)) {
-
- if( !usbio_WriteReg( dev->fd, 0x07, 0 )) {
- DBG( _DBG_ERROR, "Scanner not ready!!!\n" );
- return SANE_FALSE;
+ res = usbio_ReadReg( dev->fd, 7, &value);
+ if( res != SANE_STATUS_GOOD ) {
+ sleep(1);
+ } else {
+ if( value == 0 ) {
+ _UIO( usbio_ResetLM983x( dev ));
+ return SANE_TRUE;
+ }
+
+ if((value == 0) || (value >= 0x20) || (value == 0x03)) {
+
+ if( !usbio_WriteReg( dev->fd, 0x07, 0 )) {
+ DBG( _DBG_ERROR, "Scanner not ready!!!\n" );
+ return SANE_FALSE;
+ }
+ else {
+ return SANE_TRUE;
+ }
}
- else
- return SANE_TRUE;
}
-
- gettimeofday( &t, NULL);
+ gettimeofday( &t, NULL);
- } while( t.tv_sec < timeout );
+ } while( t.tv_sec < timeout );
DBG( _DBG_ERROR, "Scanner not ready!!!\n" );
return SANE_FALSE;
@@ -284,7 +290,7 @@ static SANE_Bool usb_WaitPos( Plustek_Device *dev, u_long to, SANE_Bool stay )
}
gettimeofday( &start_time, NULL );
- dwTicks = start_time.tv_sec + to;
+ dwTicks = start_time.tv_sec + to;
step = 1;
retval = SANE_FALSE;
@@ -353,8 +359,8 @@ static SANE_Bool usb_ModuleMove( Plustek_Device *dev,
u_char bReg2, reg7, mclk_div;
u_short wFastFeedStepSize;
double dMaxMoveSpeed;
- pClkMotorDef clk;
- pHWDef hw = &dev->usbDev.HwSetting;
+ ClkMotorDef *clk;
+ HWDef *hw = &dev->usbDev.HwSetting;
u_char *regs = dev->usbDev.a_bRegs;
if( bAction != MOVE_ToPaperSensor &&
@@ -543,8 +549,8 @@ static SANE_Bool usb_ModuleToHome( Plustek_Device *dev, SANE_Bool fWait )
{
u_char mclk_div;
u_char value;
- pDCapsDef scaps = &dev->usbDev.Caps;
- pHWDef hw = &dev->usbDev.HwSetting;
+ DCapsDef *scaps = &dev->usbDev.Caps;
+ HWDef *hw = &dev->usbDev.HwSetting;
u_char *regs = dev->usbDev.a_bRegs;
/* Check if merlin is ready for setting command */
@@ -578,7 +584,7 @@ static SANE_Bool usb_ModuleToHome( Plustek_Device *dev, SANE_Bool fWait )
if(!_IS_PLUSTEKMOTOR(hw->motorModel)) {
- pClkMotorDef clk;
+ ClkMotorDef *clk;
clk = usb_GetMotorSet( hw->motorModel );
@@ -715,8 +721,8 @@ static SANE_Bool usb_ModuleToHome( Plustek_Device *dev, SANE_Bool fWait )
*/
static SANE_Bool usb_MotorSelect( Plustek_Device *dev, SANE_Bool fADF )
{
- pDCapsDef sCaps = &dev->usbDev.Caps;
- pHWDef hw = &dev->usbDev.HwSetting;
+ DCapsDef *sCaps = &dev->usbDev.Caps;
+ HWDef *hw = &dev->usbDev.HwSetting;
u_char *regs = dev->usbDev.a_bRegs;
if(!_IS_PLUSTEKMOTOR(hw->motorModel)) {
@@ -758,7 +764,7 @@ static SANE_Bool usb_MotorSelect( Plustek_Device *dev, SANE_Bool fADF )
*/
static SANE_Bool usb_AdjustLamps( Plustek_Device *dev )
{
- pHWDef hw = &dev->usbDev.HwSetting;
+ HWDef *hw = &dev->usbDev.HwSetting;
u_char *regs = dev->usbDev.a_bRegs;
regs[0x2c] = _HIBYTE(hw->red_lamp_on);
@@ -784,7 +790,7 @@ static SANE_Bool usb_AdjustLamps( Plustek_Device *dev )
*/
static void usb_AdjustCISLampSettings( Plustek_Device *dev, SANE_Bool on )
{
- pHWDef hw = &dev->usbDev.HwSetting;
+ HWDef *hw = &dev->usbDev.HwSetting;
if( !(hw->bReg_0x26 & _ONE_CH_COLOR))
return;
@@ -864,29 +870,29 @@ static void usb_GetLampRegAndMask( u_long flag, SANE_Byte *reg, SANE_Byte *msk )
*reg = 0x5b;
*msk = 0x80;
- } else if( _MIO5 == ( _MIO5 & flag )) {
+ } else if( _MIO5 == ( _MIO5 & flag )) {
*reg = 0x5b;
*msk = 0x08;
- } else if( _MIO4 == ( _MIO4 & flag )) {
+ } else if( _MIO4 == ( _MIO4 & flag )) {
*reg = 0x5a;
*msk = 0x80;
- } else if( _MIO3 == ( _MIO3 & flag )) {
+ } else if( _MIO3 == ( _MIO3 & flag )) {
*reg = 0x5a;
*msk = 0x08;
-
- } else if( _MIO2 == ( _MIO2 & flag )) {
+
+ } else if( _MIO2 == ( _MIO2 & flag )) {
*reg = 0x59;
*msk = 0x80;
- } else if( _MIO1 == ( _MIO1 & flag )) {
+ } else if( _MIO1 == ( _MIO1 & flag )) {
*reg = 0x59;
*msk = 0x08;
- } else {
- *reg = 0;
- *msk = 0;
+ } else {
+ *reg = 0;
+ *msk = 0;
}
}
@@ -901,10 +907,10 @@ static void usb_GetLampRegAndMask( u_long flag, SANE_Byte *reg, SANE_Byte *msk )
*/
static int usb_GetLampStatus( Plustek_Device *dev )
{
- int iLampStatus = 0;
- u_char *regs = dev->usbDev.a_bRegs;
- pHWDef hw = &dev->usbDev.HwSetting;
- pDCapsDef sc = &dev->usbDev.Caps;
+ int iLampStatus = 0;
+ u_char *regs = dev->usbDev.a_bRegs;
+ HWDef *hw = &dev->usbDev.HwSetting;
+ DCapsDef *sc = &dev->usbDev.Caps;
SANE_Byte reg, msk, val;
@@ -913,28 +919,14 @@ static int usb_GetLampStatus( Plustek_Device *dev )
return -1;
}
-#if 0
- /* on the CanoScan D660U switch always... */
- if((dev->usbDev.vendor == 0x04A9) && (dev->usbDev.product==0x2208)) {
- DBG( _DBG_INFO, "CanoScan D660U -> Lamp is off!!!\n" );
- return 0;
- }
-#endif
-
/* do we use the misc I/O pins for switching the lamp ? */
if( _WAF_MISC_IO_LAMPS & sc->workaroundFlag ) {
usb_GetLampRegAndMask( sc->lamp, ®, &msk );
if( 0 == reg ) {
-#if 0
- /* probably not correct, esp. when changing from color to gray...*/
- usbio_ReadReg( dev->fd, 0x29, ®s[0x29] );
- if( regs[0x29] & 3 )
-#else
usbio_ReadReg( dev->fd, 0x29, ® );
if( reg & 3 )
-#endif
iLampStatus |= DEV_LampReflection;
} else {
@@ -955,12 +947,11 @@ static int usb_GetLampStatus( Plustek_Device *dev )
if( val & msk )
iLampStatus |= DEV_LampTPA;
}
-
+
if((dev->usbDev.vendor == 0x04A9) && (dev->usbDev.product==0x2208)) {
-/* DBG( _DBG_INFO, "CanoScan D660U -> Lamp is off!!! (STATUS=%i)\n", iLampStatus );*/
sanei_lm983x_read( dev->fd, 0x29, ®s[0x29], 3, SANE_TRUE );
- DBG( _DBG_INFO, "[29]=0x%02x, [2A]=0x%02x, [2B]=0x%02x\n", regs[0x29], regs[0x2a], regs[0x2b] );
- /*return 0;*/
+ DBG( _DBG_INFO, "[29]=0x%02x, [2A]=0x%02x, [2B]=0x%02x\n",
+ regs[0x29], regs[0x2a], regs[0x2b] );
}
}
} else {
@@ -973,7 +964,7 @@ static int usb_GetLampStatus( Plustek_Device *dev )
if(!_IS_PLUSTEKMOTOR(hw->motorModel)) {
iLampStatus |= DEV_LampReflection;
- } else {
+ } else {
if((regs[0x2e] * 256 + regs[0x2f]) > hw->wLineEnd )
iLampStatus |= DEV_LampReflection;
@@ -995,7 +986,7 @@ static SANE_Bool usb_switchLampX( Plustek_Device *dev,
SANE_Bool on, SANE_Bool tpa )
{
SANE_Byte reg, msk;
- pDCapsDef sc = &dev->usbDev.Caps;
+ DCapsDef *sc = &dev->usbDev.Caps;
u_char *regs = dev->usbDev.a_bRegs;
if( tpa )
@@ -1060,7 +1051,7 @@ static void usb_LedOn( Plustek_Device *dev, SANE_Bool fOn )
*/
static void usb_FillLampRegs( Plustek_Device *dev )
{
- pHWDef hw = &dev->usbDev.HwSetting;
+ HWDef *hw = &dev->usbDev.HwSetting;
u_char *regs = dev->usbDev.a_bRegs;
regs[0x2a] = _HIBYTE( hw->wGreenPWMDutyCycleLow );
@@ -1087,9 +1078,9 @@ static void usb_FillLampRegs( Plustek_Device *dev )
static SANE_Bool usb_LampOn( Plustek_Device *dev,
SANE_Bool fOn, SANE_Bool fResetTimer )
{
- pDCapsDef sc = &dev->usbDev.Caps;
- pScanDef scanning = &dev->scanning;
- pHWDef hw = &dev->usbDev.HwSetting;
+ DCapsDef *sc = &dev->usbDev.Caps;
+ ScanDef *scanning = &dev->scanning;
+ HWDef *hw = &dev->usbDev.HwSetting;
u_char *regs = dev->usbDev.a_bRegs;
int iLampStatus = usb_GetLampStatus( dev );
int lampId = -1;
@@ -1179,7 +1170,7 @@ static SANE_Bool usb_LampOn( Plustek_Device *dev,
regs[0x2e] = 16383 / 256;
regs[0x2f] = 16383 % 256;
}
-
+
if( iStatusChange & DEV_LampTPA ) {
regs[0x36] = 16383 / 256;
regs[0x37] = 16383 % 256;
@@ -1223,7 +1214,7 @@ static void usb_ResetRegisters( Plustek_Device *dev )
{
int linend;
- pHWDef hw = &dev->usbDev.HwSetting;
+ HWDef *hw = &dev->usbDev.HwSetting;
u_char *regs = dev->usbDev.a_bRegs;
DBG( _DBG_INFO, "RESETTING REGISTERS(%i) - 0x%02x\n", dev->initialized,sizeof(dev->usbDev.a_bRegs));
@@ -1274,7 +1265,18 @@ static void usb_ResetRegisters( Plustek_Device *dev )
DBG( _DBG_INFO2, "SETTING THE MISC I/Os\n" );
memcpy( regs+0x54, &hw->bReg_0x54, 0x5e - 0x54 + 1 );
- sanei_lm983x_write( dev->fd, 0x59, ®s[0x59], 3, SANE_TRUE );
+
+ if( usb_IsCISDevice( dev )) {
+
+ /* this sequence seems to be needed at least for the
+ * CanoScan devices to work properly after power-up
+ */
+ sanei_lm983x_write_byte( dev->fd, 0x5b, regs[0x5b] );
+ sanei_lm983x_write_byte( dev->fd, 0x59, regs[0x59] );
+ sanei_lm983x_write_byte( dev->fd, 0x5a, regs[0x5a] );
+ } else {
+ sanei_lm983x_write( dev->fd, 0x59, ®s[0x59], 3, SANE_TRUE );
+ }
}
DBG( _DBG_INFO, "MISC I/O after RESET: 0x%02x, 0x%02x, 0x%02x\n",
regs[0x59], regs[0x5a], regs[0x5b] );
@@ -1285,7 +1287,7 @@ static void usb_ResetRegisters( Plustek_Device *dev )
static SANE_Bool usb_ModuleStatus( Plustek_Device *dev )
{
u_char value;
- pHWDef hw = &dev->usbDev.HwSetting;
+ HWDef *hw = &dev->usbDev.HwSetting;
/* HEINER: Maybe needed to avoid recalibration!!! */
#if 0
@@ -1462,7 +1464,7 @@ static SANE_Bool usb_Wait4Warmup( Plustek_Device *dev )
u_long dw;
struct timeval t;
- pHWDef hw = &dev->usbDev.HwSetting;
+ HWDef *hw = &dev->usbDev.HwSetting;
if( hw->bReg_0x26 & _ONE_CH_COLOR ) {
DBG(_DBG_INFO,"Warmup: skipped for CIS devices\n" );
@@ -1564,9 +1566,10 @@ static SANE_Bool usb_UpdateButtonStatus( Plustek_Scanner *s )
int i, j, bc;
int handle = -1;
SANE_Status status;
- Plustek_Device *dev = s->hw;
+ Plustek_Device *dev = s->hw;
+ DCapsDef *caps = &dev->usbDev.Caps;
- if (dev->usbDev.Caps.bButtons == 0)
+ if (caps->bButtons == 0)
return SANE_FALSE;
status = sanei_access_lock( dev->sane.name, 3 );
@@ -1593,25 +1596,57 @@ static SANE_Bool usb_UpdateButtonStatus( Plustek_Scanner *s )
/* first read clears the status... */
usbio_ReadReg( dev->fd, 0x02, &val );
- val >>= 2;
- bc = 0;
- for( i = 0; i < 3; i++ ) {
-
- DBG( _DBG_INFO2, "Checking MISC IO[%u]=0x%02x\n", i, mio[i] );
- mask = 0x01;
+ /* Plustek and KYE/Genius use altnernative button handling */
+ if((dev->usbDev.vendor == 0x07B3) || (dev->usbDev.vendor == 0x0458)) {
- for( j = 0; j < 2; j++ ) {
+ /* no button pressed so far */
+ for( i = 0; i < caps->bButtons; i++ )
+ s->val[OPT_BUTTON_0 + i].w = 0;
- if((mio[i] & mask) == 0) {
- DBG( _DBG_INFO2, "* port %u configured as input,"
- " status: %s (%u)\n", (i*2)+j+1,
- ((val & 1)?"PRESSED":"RELEASED"), (OPT_BUTTON_0 + bc));
- s->val[OPT_BUTTON_0 + bc].w = val & 1;
- bc++;
+ if (caps->bButtons == 2 || caps->bButtons == 5) {
+ val >>= 2;
+
+ switch( val ) {
+ case 1: s->val[OPT_BUTTON_1].w = 1; break;
+ case 2: s->val[OPT_BUTTON_0].w = 1; break;
+ case 3: s->val[OPT_BUTTON_2].w = 1; break;
+ case 4: s->val[OPT_BUTTON_3].w = 1; break;
+ case 6: s->val[OPT_BUTTON_4].w = 1; break;
+ }
+ } else if (caps->bButtons == 4 ) {
+ val >>= 5;
+ switch( val ) {
+ case 1: s->val[OPT_BUTTON_0].w = 1; break;
+ case 2: s->val[OPT_BUTTON_1].w = 1; break;
+ case 4: s->val[OPT_BUTTON_2].w = 1; break;
+ case 6: s->val[OPT_BUTTON_3].w = 1; break;
+ }
+ }
+
+ } else {
+
+ /* the generic section... */
+ val >>= 2;
+ bc = 0;
+
+ for( i = 0; i < 3; i++ ) {
+
+ DBG( _DBG_INFO2, "Checking MISC IO[%u]=0x%02x\n", i, mio[i] );
+ mask = 0x01;
+
+ for( j = 0; j < 2; j++ ) {
+
+ if((mio[i] & mask) == 0) {
+ DBG( _DBG_INFO2, "* port %u configured as input,"
+ " status: %s (%u)\n", (i*2)+j+1,
+ ((val & 1)?"PRESSED":"RELEASED"), (OPT_BUTTON_0 + bc));
+ s->val[OPT_BUTTON_0 + bc].w = val & 1;
+ bc++;
+ }
+ val >>= 1;
+ mask <<= 4;
}
- val >>= 1;
- mask <<= 4;
}
}
} else {