kopia lustrzana https://gitlab.com/sane-project/backends
				
				
				
			Major Update. Esp. improved support for multiple
devices and autodetection.merge-requests/1/head
							rodzic
							
								
									78e3e2975a
								
							
						
					
					
						commit
						7107aee632
					
				| 
						 | 
				
			
			@ -38,6 +38,7 @@
 | 
			
		|||
 *        - change usbDev_stopScan and usbDev_open prototype
 | 
			
		||||
 *        - cleanup
 | 
			
		||||
 * - 0.48 - added function usb_CheckAndCopyAdjs()
 | 
			
		||||
 * - 0.49 - changed autodetection
 | 
			
		||||
 * .
 | 
			
		||||
 * <hr>
 | 
			
		||||
 * This file is part of the SANE package.
 | 
			
		||||
| 
						 | 
				
			
			@ -103,9 +104,6 @@ static TabDef usbVendors[] = {
 | 
			
		|||
	{ 0xFFFF, NULL              }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** for autodetection */
 | 
			
		||||
static SANE_Char USB_devname[1024];
 | 
			
		||||
 | 
			
		||||
/** we use at least 8 megs for scanning... */
 | 
			
		||||
#define _SCANBUF_SIZE (8 * 1024 * 1024)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -433,104 +431,158 @@ static SANE_Bool usb_IsDeviceInList( char *usbIdStr )
 | 
			
		|||
	return SANE_FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
/** get last valid entry of a list
 | 
			
		||||
 */
 | 
			
		||||
static DevList*
 | 
			
		||||
getLast( DevList *l )
 | 
			
		||||
{
 | 
			
		||||
	if( l == NULL )
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	while( l->next != NULL )
 | 
			
		||||
		l = l->next;
 | 
			
		||||
	return l; 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** add a new entry to our internal device list, when a device is detected
 | 
			
		||||
 */
 | 
			
		||||
static SANE_Status usb_attach( SANE_String_Const dev_name )
 | 
			
		||||
{
 | 
			
		||||
	if( USB_devname[0] == '\0' ) {
 | 
			
		||||
		DBG( _DBG_INFO, "Found device at >%s<\n", dev_name );
 | 
			
		||||
		strncpy( USB_devname, dev_name, 1023 );
 | 
			
		||||
		USB_devname[1023] = '\0';
 | 
			
		||||
	} else {
 | 
			
		||||
		DBG( _DBG_INFO, "Device >%s< ignoring\n", dev_name );
 | 
			
		||||
	}
 | 
			
		||||
	int      len;
 | 
			
		||||
	DevList *tmp, *last;
 | 
			
		||||
 | 
			
		||||
	/* get some memory for the entry... */
 | 
			
		||||
	len = sizeof(DevList) + strlen(dev_name) + 1;
 | 
			
		||||
	tmp = (DevList*)malloc(len);
 | 
			
		||||
 | 
			
		||||
	/* initialize and set the values */
 | 
			
		||||
	memset(tmp, 0, len );
 | 
			
		||||
 | 
			
		||||
	/* the device name is part of our structure space */
 | 
			
		||||
	tmp->dev_name = &((char*)tmp)[sizeof(DevList)];
 | 
			
		||||
	strcpy( tmp->dev_name, dev_name );
 | 
			
		||||
	tmp->attached = SANE_FALSE;
 | 
			
		||||
 | 
			
		||||
	/* root set ? */
 | 
			
		||||
	if( usbDevs == NULL ) {
 | 
			
		||||
		usbDevs = tmp;
 | 
			
		||||
	} else {
 | 
			
		||||
		last = getLast(usbDevs); /* append... */
 | 
			
		||||
		last->next = tmp;
 | 
			
		||||
	}
 | 
			
		||||
	return SANE_STATUS_GOOD;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** here we roam through our list of supported devices and
 | 
			
		||||
 * cross check with the ones the system reports...
 | 
			
		||||
 * @param vendor  - pointer to receive vendor ID
 | 
			
		||||
 * @param product - pointer to receive product ID
 | 
			
		||||
 * @return SANE_TRUE if a matching device has been found or
 | 
			
		||||
 *         SANE_FALSE if nothing supported found...
 | 
			
		||||
/**
 | 
			
		||||
 */
 | 
			
		||||
static SANE_Bool usbDev_autodetect( SANE_Word *vendor, SANE_Word *product )
 | 
			
		||||
static void
 | 
			
		||||
usbGetList( DevList **devs )
 | 
			
		||||
{
 | 
			
		||||
	int       i;
 | 
			
		||||
	SANE_Word v, p;
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO, "Autodetection...\n" );
 | 
			
		||||
	int        i;
 | 
			
		||||
	SANE_Word  v, p;
 | 
			
		||||
	DevList   *tmp;
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO, "Retrieving all supported and conntected devices\n" );
 | 
			
		||||
	for( i = 0; NULL != Settings[i].pIDString; i++ ) {
 | 
			
		||||
 | 
			
		||||
		v = strtol( &(Settings[i].pIDString)[0], 0, 0 );
 | 
			
		||||
		p = strtol( &(Settings[i].pIDString)[7], 0, 0 );
 | 
			
		||||
 | 
			
		||||
		/* get the last entry... */
 | 
			
		||||
		tmp = getLast(*devs);
 | 
			
		||||
		DBG( _DBG_INFO2, "Checking for 0x%04x-0x%04x\n", v, p );
 | 
			
		||||
 | 
			
		||||
		sanei_usb_find_devices( v, p, usb_attach );
 | 
			
		||||
 | 
			
		||||
		if( USB_devname[0] != '\0' ) {
 | 
			
		||||
		if( getLast(*devs) != tmp ) {
 | 
			
		||||
			
 | 
			
		||||
			if( tmp == NULL )
 | 
			
		||||
				tmp = *devs;
 | 
			
		||||
			else
 | 
			
		||||
				tmp = tmp->next;
 | 
			
		||||
 | 
			
		||||
			*vendor  = v;
 | 
			
		||||
			*product = p;
 | 
			
		||||
			return SANE_TRUE;
 | 
			
		||||
			while( tmp != NULL ) {
 | 
			
		||||
				tmp->vendor_id = v;
 | 
			
		||||
				tmp->device_id = p;
 | 
			
		||||
				tmp = tmp->next;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return SANE_FALSE;
 | 
			
		||||
	DBG( _DBG_INFO, "Available and supported devices:\n" );
 | 
			
		||||
	if( *devs == NULL )
 | 
			
		||||
		DBG( _DBG_INFO, "NONE.\n" );
 | 
			
		||||
 | 
			
		||||
	for( tmp = *devs; tmp; tmp = tmp->next ) {
 | 
			
		||||
		DBG( _DBG_INFO, "Device: >%s< - 0x%04xx0x%04x\n", 
 | 
			
		||||
			tmp->dev_name, tmp->vendor_id, tmp->device_id );
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 */
 | 
			
		||||
static int usbDev_open( Plustek_Device *dev )
 | 
			
		||||
static int usbDev_open( Plustek_Device *dev, DevList *devs )
 | 
			
		||||
{
 | 
			
		||||
	char      devStr[50];
 | 
			
		||||
	int       result;
 | 
			
		||||
	int       i;
 | 
			
		||||
	int       lc;
 | 
			
		||||
	SANE_Int  handle;
 | 
			
		||||
	SANE_Byte version;
 | 
			
		||||
	SANE_Word vendor, product;
 | 
			
		||||
	SANE_Bool was_empty;
 | 
			
		||||
	char       dn[512];
 | 
			
		||||
	char       devStr[50];
 | 
			
		||||
	int        result;
 | 
			
		||||
	int        i;
 | 
			
		||||
	int        lc;
 | 
			
		||||
	SANE_Int   handle;
 | 
			
		||||
	SANE_Byte  version;
 | 
			
		||||
	SANE_Word  vendor, product;
 | 
			
		||||
	SANE_Bool  was_empty;
 | 
			
		||||
	DevList   *tmp;
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO, "usbDev_open(%s,%s)\n", dev->name, dev->usbId );
 | 
			
		||||
	DBG( _DBG_INFO, "usbDev_open(%s,%s) - %p\n", 
 | 
			
		||||
	    dev->name, dev->usbId, (void*)devs );
 | 
			
		||||
 | 
			
		||||
	/* preset our internal usb device structure */
 | 
			
		||||
	memset( &dev->usbDev, 0, sizeof(DeviceDef));
 | 
			
		||||
	USB_devname[0] = '\0';
 | 
			
		||||
 | 
			
		||||
	if( !strcmp( dev->name, "auto" )) {
 | 
			
		||||
	/* devs is NULL, when called from sane_start */
 | 
			
		||||
	if( devs ) {
 | 
			
		||||
	
 | 
			
		||||
		dn[0] = '\0';
 | 
			
		||||
		if( !strcmp( dev->name, "auto" )) {
 | 
			
		||||
 | 
			
		||||
		if( dev->usbId[0] == '\0' ) {
 | 
			
		||||
 | 
			
		||||
			if( !usbDev_autodetect( &vendor, &product )) {
 | 
			
		||||
				DBG( _DBG_ERROR, "No supported device found!\n" );
 | 
			
		||||
				return -1;
 | 
			
		||||
			/* use the first "unattached"... */
 | 
			
		||||
			for( tmp = devs; tmp; tmp = tmp->next ) {
 | 
			
		||||
				if( !tmp->attached ) {
 | 
			
		||||
					tmp->attached = SANE_TRUE;
 | 
			
		||||
					strcpy( dn, tmp->dev_name );
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
			vendor  = strtol( &dev->usbId[0], 0, 0 );
 | 
			
		||||
			product = strtol( &dev->usbId[7], 0, 0 );
 | 
			
		||||
 | 
			
		||||
			sanei_usb_find_devices( vendor, product, usb_attach );
 | 
			
		||||
 | 
			
		||||
			if( USB_devname[0] == '\0' ) {
 | 
			
		||||
				DBG( _DBG_ERROR, "No matching device found!\n" );
 | 
			
		||||
        		return -1;
 | 
			
		||||
			/* check the first match... */
 | 
			
		||||
			for( tmp = devs; tmp; tmp = tmp->next ) {
 | 
			
		||||
				if( tmp->vendor_id == vendor && tmp->device_id == product ) {
 | 
			
		||||
					if( !tmp->attached ) {
 | 
			
		||||
						tmp->attached = SANE_TRUE;
 | 
			
		||||
						strcpy( dn, tmp->dev_name );
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if( SANE_STATUS_GOOD != sanei_usb_open( USB_devname, &handle ))
 | 
			
		||||
    		return -1;
 | 
			
		||||
		if( !dn[0] ) {
 | 
			
		||||
			DBG( _DBG_ERROR, "No supported device found!\n" );
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if( SANE_STATUS_GOOD != sanei_usb_open( dn, &handle ))
 | 
			
		||||
			return -1;
 | 
			
		||||
 | 
			
		||||
		/* replace the old devname, so we are able to have multiple
 | 
			
		||||
         * auto-detected devices
 | 
			
		||||
         */
 | 
			
		||||
		 * auto-detected devices
 | 
			
		||||
		 */
 | 
			
		||||
		free( dev->name );
 | 
			
		||||
	    dev->name      = strdup( USB_devname );
 | 
			
		||||
		dev->name      = strdup(dn);
 | 
			
		||||
		dev->sane.name = dev->name; 
 | 
			
		||||
 | 
			
		||||
	} else {
 | 
			
		||||
| 
						 | 
				
			
			@ -900,9 +952,9 @@ static int usbDev_setScanEnv( Plustek_Device *dev, pScanInfo si )
 | 
			
		|||
	if( dev->scanning.sParam.bSource == SOURCE_ADF ) {
 | 
			
		||||
 | 
			
		||||
		if( dev->scanning.dwFlag & SCANDEF_ContinuousScan )
 | 
			
		||||
			fLastScanIsAdf = SANE_TRUE;
 | 
			
		||||
			dev->usbDev.fLastScanIsAdf = SANE_TRUE;
 | 
			
		||||
		else
 | 
			
		||||
			fLastScanIsAdf = SANE_FALSE;
 | 
			
		||||
			dev->usbDev.fLastScanIsAdf = SANE_FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -940,11 +992,11 @@ static int usbDev_startScan( Plustek_Device *dev )
 | 
			
		|||
/* HEINER: Preview currently not working correctly */
 | 
			
		||||
#if 0
 | 
			
		||||
	if( scanning->dwFlag & SCANDEF_QualityScan )
 | 
			
		||||
		a_bRegs[0x0a] = 0;
 | 
			
		||||
		dev->usbDev.a_bRegs[0x0a] = 0;
 | 
			
		||||
	else
 | 
			
		||||
		a_bRegs[0x0a] = 1;
 | 
			
		||||
		dev->usbDev.a_bRegs[0x0a] = 1;
 | 
			
		||||
#endif
 | 
			
		||||
	a_bRegs[0x0a] = 0;
 | 
			
		||||
	dev->usbDev.a_bRegs[0x0a] = 0;
 | 
			
		||||
 | 
			
		||||
	/* Allocate shading buffer */
 | 
			
		||||
	if((dev->scanning.dwFlag & SCANDEF_Adf) &&
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,6 +33,8 @@
 | 
			
		|||
 * - 0.48 - added DEVCAPSFLAG_LargeTPA
 | 
			
		||||
 *        - added _WAF_BIN_FROM_COLOR and _WAF_GRAY_FROM_COLOR
 | 
			
		||||
 *        - added dHighSpeed to struct HwDefault
 | 
			
		||||
 * - 0.49 - added a_bRegs, fModFirstHome and fLastScanIsAdf
 | 
			
		||||
 *          to struct DeviceDef
 | 
			
		||||
 * .
 | 
			
		||||
 * <hr>
 | 
			
		||||
 * This file is part of the SANE package.
 | 
			
		||||
| 
						 | 
				
			
			@ -477,6 +479,9 @@ typedef struct DeviceDef
 | 
			
		|||
	u_long      dwLampOnPeriod;/**< How many seconds to keep lamp on         */
 | 
			
		||||
	SANE_Bool   bLampOffOnEnd; /**< switch lamp off on end or keep cur. state*/
 | 
			
		||||
	int         currentLamp;   /**< The lamp ID of the currently used lamp   */
 | 
			
		||||
	SANE_Bool   fModFirstHome; /**<                                          */
 | 
			
		||||
	SANE_Bool   fLastScanIsAdf;/**<                                          */
 | 
			
		||||
	u_char      a_bRegs[0x80]; /**< our global register file                 */
 | 
			
		||||
 | 
			
		||||
} DeviceDef, *pDeviceDef;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,6 +38,7 @@
 | 
			
		|||
 *         - fixed problem in cano_AdjustLightsource(), so that it won't
 | 
			
		||||
 *           stop too early.
 | 
			
		||||
 * - 0.48  - cleanup
 | 
			
		||||
 * - 0.49 - a_bRegs is now part of the device structure
 | 
			
		||||
 * 
 | 
			
		||||
 * This file is part of the SANE package.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -85,7 +86,7 @@ static int strip_state=0;
 | 
			
		|||
/** depending on the strip state, the sensor is moved to the shading position
 | 
			
		||||
 *  and the lamp ist switched on
 | 
			
		||||
 */
 | 
			
		||||
static int cano_PrepareToReadWhiteCal( pPlustek_Device dev )
 | 
			
		||||
static int cano_PrepareToReadWhiteCal( Plustek_Device *dev )
 | 
			
		||||
{
 | 
			
		||||
	pHWDef hw = &dev->usbDev.HwSetting;
 | 
			
		||||
	
 | 
			
		||||
| 
						 | 
				
			
			@ -102,9 +103,9 @@ static int cano_PrepareToReadWhiteCal( pPlustek_Device dev )
 | 
			
		|||
			}
 | 
			
		||||
	    	break;
 | 
			
		||||
		case 2:
 | 
			
		||||
			a_bRegs[0x29] = hw->bReg_0x29;
 | 
			
		||||
			dev->usbDev.a_bRegs[0x29] = hw->bReg_0x29;
 | 
			
		||||
			usb_switchLamp( dev, SANE_TRUE );
 | 
			
		||||
			if( !usbio_WriteReg( dev->fd, 0x29, a_bRegs[0x29])) {
 | 
			
		||||
			if( !usbio_WriteReg( dev->fd, 0x29, dev->usbDev.a_bRegs[0x29])) {
 | 
			
		||||
				DBG( _DBG_ERROR, "cano_PrepareToReadWhiteCal() failed\n" );
 | 
			
		||||
				return _E_LAMP_NOT_IN_POS;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -117,7 +118,7 @@ static int cano_PrepareToReadWhiteCal( pPlustek_Device dev )
 | 
			
		|||
 | 
			
		||||
/**
 | 
			
		||||
 */
 | 
			
		||||
static int cano_PrepareToReadBlackCal( pPlustek_Device dev )
 | 
			
		||||
static int cano_PrepareToReadBlackCal( Plustek_Device *dev )
 | 
			
		||||
{
 | 
			
		||||
	if( strip_state == 0 )
 | 
			
		||||
		if(cano_PrepareToReadWhiteCal(dev))
 | 
			
		||||
| 
						 | 
				
			
			@ -133,13 +134,13 @@ static int cano_PrepareToReadBlackCal( pPlustek_Device dev )
 | 
			
		|||
			usb_ModuleToHome( dev, SANE_TRUE );
 | 
			
		||||
			usb_ModuleMove  ( dev, MOVE_Forward,
 | 
			
		||||
								(u_long)dev->usbDev.pSource->DarkShadOrgY );
 | 
			
		||||
			a_bRegs[0x45] &= ~0x10;
 | 
			
		||||
			dev->usbDev.a_bRegs[0x45] &= ~0x10;
 | 
			
		||||
			strip_state = 0;
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
		 	/* switch lamp off to read dark data... */
 | 
			
		||||
			a_bRegs[0x29] = 0;
 | 
			
		||||
			dev->usbDev.a_bRegs[0x29] = 0;
 | 
			
		||||
			usb_switchLamp( dev, SANE_FALSE );
 | 
			
		||||
			strip_state = 2;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -149,15 +150,15 @@ static int cano_PrepareToReadBlackCal( pPlustek_Device dev )
 | 
			
		|||
 | 
			
		||||
/**
 | 
			
		||||
 */
 | 
			
		||||
static int cano_LampOnAfterCalibration( pPlustek_Device dev )
 | 
			
		||||
static int cano_LampOnAfterCalibration( Plustek_Device *dev )
 | 
			
		||||
{
 | 
			
		||||
	pHWDef hw = &dev->usbDev.HwSetting;
 | 
			
		||||
 | 
			
		||||
	switch (strip_state) {
 | 
			
		||||
		case 2:
 | 
			
		||||
			a_bRegs[0x29] = hw->bReg_0x29;
 | 
			
		||||
			dev->usbDev.a_bRegs[0x29] = hw->bReg_0x29;
 | 
			
		||||
			usb_switchLamp( dev, SANE_TRUE );
 | 
			
		||||
			if( !usbio_WriteReg( dev->fd, 0x29, a_bRegs[0x29])) {
 | 
			
		||||
			if( !usbio_WriteReg( dev->fd, 0x29, dev->usbDev.a_bRegs[0x29])) {
 | 
			
		||||
				DBG( _DBG_ERROR, "cano_LampOnAfterCalibration() failed\n" );
 | 
			
		||||
				return _E_LAMP_NOT_IN_POS;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -224,7 +225,7 @@ static int cano_adjLampSetting( u_short *min,
 | 
			
		|||
 * where the lamp_off parameter is adjustable; I'd make it more general, 
 | 
			
		||||
 * but I only have the CIS hardware to test.
 | 
			
		||||
 */
 | 
			
		||||
static int cano_AdjustLightsource( pPlustek_Device dev )
 | 
			
		||||
static int cano_AdjustLightsource( Plustek_Device *dev )
 | 
			
		||||
{
 | 
			
		||||
	char         tmp[40];
 | 
			
		||||
	int          i;
 | 
			
		||||
| 
						 | 
				
			
			@ -450,7 +451,7 @@ cano_adjGainSetting( u_char *min, u_char *max, u_char *gain,u_long val )
 | 
			
		|||
 *
 | 
			
		||||
 * adjLightsource, above, steals most of this function's thunder.
 | 
			
		||||
 */
 | 
			
		||||
static SANE_Bool cano_AdjustGain( pPlustek_Device dev )
 | 
			
		||||
static SANE_Bool cano_AdjustGain( Plustek_Device *dev )
 | 
			
		||||
{
 | 
			
		||||
	char      tmp[40];
 | 
			
		||||
	int       i = 0, adj = 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -471,9 +472,9 @@ static SANE_Bool cano_AdjustGain( pPlustek_Device dev )
 | 
			
		|||
	DBG( _DBG_INFO, "cano_AdjustGain()\n" );
 | 
			
		||||
	if((dev->adj.rgain != -1) && 
 | 
			
		||||
	   (dev->adj.ggain != -1) && (dev->adj.bgain != -1)) {
 | 
			
		||||
		setAdjGain( dev->adj.rgain, &a_bRegs[0x3b] );
 | 
			
		||||
		setAdjGain( dev->adj.ggain, &a_bRegs[0x3c] );
 | 
			
		||||
		setAdjGain( dev->adj.bgain, &a_bRegs[0x3d] );
 | 
			
		||||
		setAdjGain( dev->adj.rgain, &dev->usbDev.a_bRegs[0x3b] );
 | 
			
		||||
		setAdjGain( dev->adj.ggain, &dev->usbDev.a_bRegs[0x3c] );
 | 
			
		||||
		setAdjGain( dev->adj.bgain, &dev->usbDev.a_bRegs[0x3d] );
 | 
			
		||||
		DBG( _DBG_INFO, "- function skipped, using frontend values!\n" );
 | 
			
		||||
		return SANE_TRUE;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -571,9 +572,9 @@ static SANE_Bool cano_AdjustGain( pPlustek_Device dev )
 | 
			
		|||
									max_rgb.Red, max_rgb.Red, max_rgb.Green,
 | 
			
		||||
									max_rgb.Green, max_rgb.Blue, max_rgb.Blue );
 | 
			
		||||
      
 | 
			
		||||
			adj  = cano_adjGainSetting(min  , max  ,a_bRegs+0x3b,max_rgb.Red  );
 | 
			
		||||
			adj += cano_adjGainSetting(min+1, max+1,a_bRegs+0x3c,max_rgb.Green);
 | 
			
		||||
			adj += cano_adjGainSetting(min+2, max+2,a_bRegs+0x3d,max_rgb.Blue );
 | 
			
		||||
			adj  = cano_adjGainSetting(min  , max  ,dev->usbDev.a_bRegs+0x3b,max_rgb.Red  );
 | 
			
		||||
			adj += cano_adjGainSetting(min+1, max+1,dev->usbDev.a_bRegs+0x3c,max_rgb.Green);
 | 
			
		||||
			adj += cano_adjGainSetting(min+2, max+2,dev->usbDev.a_bRegs+0x3d,max_rgb.Blue );
 | 
			
		||||
      
 | 
			
		||||
	    } else {
 | 
			
		||||
      
 | 
			
		||||
| 
						 | 
				
			
			@ -584,15 +585,15 @@ static SANE_Bool cano_AdjustGain( pPlustek_Device dev )
 | 
			
		|||
					w_max = ((u_short*)pScanBuffer)[dw];
 | 
			
		||||
			}
 | 
			
		||||
      
 | 
			
		||||
			adj = cano_adjGainSetting(min,max,a_bRegs+0x3c,w_max);
 | 
			
		||||
			a_bRegs[0x3b] = (a_bRegs[0x3d] = a_bRegs[0x3c]);
 | 
			
		||||
			adj = cano_adjGainSetting(min,max,dev->usbDev.a_bRegs+0x3c,w_max);
 | 
			
		||||
			dev->usbDev.a_bRegs[0x3b] = (dev->usbDev.a_bRegs[0x3d] = dev->usbDev.a_bRegs[0x3c]);
 | 
			
		||||
      
 | 
			
		||||
			DBG(_DBG_INFO2, "MAX(G)= 0x%04x(%u)\n", w_max, w_max );
 | 
			
		||||
      
 | 
			
		||||
		}
 | 
			
		||||
		DBG( _DBG_INFO2, "REG[0x3b] = %u\n", a_bRegs[0x3b] );
 | 
			
		||||
		DBG( _DBG_INFO2, "REG[0x3c] = %u\n", a_bRegs[0x3c] );
 | 
			
		||||
		DBG( _DBG_INFO2, "REG[0x3d] = %u\n", a_bRegs[0x3d] );
 | 
			
		||||
		DBG( _DBG_INFO2, "REG[0x3b] = %u\n", dev->usbDev.a_bRegs[0x3b] );
 | 
			
		||||
		DBG( _DBG_INFO2, "REG[0x3c] = %u\n", dev->usbDev.a_bRegs[0x3c] );
 | 
			
		||||
		DBG( _DBG_INFO2, "REG[0x3d] = %u\n", dev->usbDev.a_bRegs[0x3d] );
 | 
			
		||||
  
 | 
			
		||||
	}
 | 
			
		||||
  
 | 
			
		||||
| 
						 | 
				
			
			@ -603,15 +604,15 @@ static SANE_Bool cano_AdjustGain( pPlustek_Device dev )
 | 
			
		|||
 | 
			
		||||
/**
 | 
			
		||||
 */
 | 
			
		||||
static int cano_GetNewOffset( u_long *val, int channel, signed char *low, 
 | 
			
		||||
							  signed char *now, signed char *high )
 | 
			
		||||
static int cano_GetNewOffset( Plustek_Device *dev, u_long *val, int channel, 
 | 
			
		||||
                              signed char *low, signed char *now, signed char *high )
 | 
			
		||||
{
 | 
			
		||||
	/* if we're too black, we're likely off the low end */
 | 
			
		||||
	if( val[channel] <= 16 ) {
 | 
			
		||||
		low[channel] =  now[channel];
 | 
			
		||||
		now[channel] = (now[channel]+high[channel])/2;
 | 
			
		||||
 | 
			
		||||
		a_bRegs[0x38+channel]= (now[channel]&0x3f);
 | 
			
		||||
		dev->usbDev.a_bRegs[0x38+channel]= (now[channel]&0x3f);
 | 
			
		||||
 | 
			
		||||
		if( low[channel]+1 >= high[channel] )
 | 
			
		||||
			return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -621,7 +622,7 @@ static int cano_GetNewOffset( u_long *val, int channel, signed char *low,
 | 
			
		|||
		high[channel]=now[channel];
 | 
			
		||||
		now[channel]=(now[channel]+low[channel])/2;
 | 
			
		||||
 | 
			
		||||
		a_bRegs[0x38+channel]= (now[channel]&0x3f);
 | 
			
		||||
		dev->usbDev.a_bRegs[0x38+channel]= (now[channel]&0x3f);
 | 
			
		||||
 | 
			
		||||
		if(low[channel]+1>=high[channel])
 | 
			
		||||
			return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -644,7 +645,7 @@ static int cano_GetNewOffset( u_long *val, int channel, signed char *low,
 | 
			
		|||
   Plustek's example code disagrees with NatSemi's docs; going by the
 | 
			
		||||
   docs works better, I will assume the docs are correct. --Monty */
 | 
			
		||||
 | 
			
		||||
static int cano_AdjustOffset( pPlustek_Device dev )
 | 
			
		||||
static int cano_AdjustOffset( Plustek_Device *dev )
 | 
			
		||||
{
 | 
			
		||||
	char   tmp[40];
 | 
			
		||||
	int    i, adj;
 | 
			
		||||
| 
						 | 
				
			
			@ -664,9 +665,9 @@ static int cano_AdjustOffset( pPlustek_Device dev )
 | 
			
		|||
	DBG( _DBG_INFO, "cano_AdjustOffset()\n" );
 | 
			
		||||
	if((dev->adj.rofs != -1) && 
 | 
			
		||||
	   (dev->adj.gofs != -1) && (dev->adj.bofs != -1)) {
 | 
			
		||||
		a_bRegs[0x38] = (dev->adj.rofs & 0x3f);
 | 
			
		||||
		a_bRegs[0x39] = (dev->adj.gofs & 0x3f);
 | 
			
		||||
		a_bRegs[0x3a] = (dev->adj.bofs & 0x3f);
 | 
			
		||||
		dev->usbDev.a_bRegs[0x38] = (dev->adj.rofs & 0x3f);
 | 
			
		||||
		dev->usbDev.a_bRegs[0x39] = (dev->adj.gofs & 0x3f);
 | 
			
		||||
		dev->usbDev.a_bRegs[0x3a] = (dev->adj.bofs & 0x3f);
 | 
			
		||||
		DBG( _DBG_INFO, "- function skipped, using frontend values!\n" );
 | 
			
		||||
		return SANE_TRUE;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -751,9 +752,9 @@ static int cano_AdjustOffset( pPlustek_Device dev )
 | 
			
		|||
			dwSum[1] /= dwPixels;
 | 
			
		||||
			dwSum[2] /= dwPixels;
 | 
			
		||||
      
 | 
			
		||||
			adj  = cano_GetNewOffset( dwSum, 0, low, now, high );
 | 
			
		||||
			adj |= cano_GetNewOffset( dwSum, 1, low, now, high );
 | 
			
		||||
			adj |= cano_GetNewOffset( dwSum, 2, low, now, high );
 | 
			
		||||
			adj  = cano_GetNewOffset( dev, dwSum, 0, low, now, high );
 | 
			
		||||
			adj |= cano_GetNewOffset( dev, dwSum, 1, low, now, high );
 | 
			
		||||
			adj |= cano_GetNewOffset( dev, dwSum, 2, low, now, high );
 | 
			
		||||
      
 | 
			
		||||
			DBG( _DBG_INFO2, "RedOff   = %d/%d/%d\n",
 | 
			
		||||
										(int)low[0],(int)now[0],(int)high[0]);
 | 
			
		||||
| 
						 | 
				
			
			@ -772,28 +773,30 @@ static int cano_AdjustOffset( pPlustek_Device dev )
 | 
			
		|||
			DBG( _DBG_INFO2, "Sum = %lu, ave = %lu\n",
 | 
			
		||||
												dwSum[0], dwSum[0] /dwPixels );
 | 
			
		||||
      
 | 
			
		||||
			adj = cano_GetNewOffset( dwSum, 0, low, now, high );
 | 
			
		||||
			adj = cano_GetNewOffset( dev, dwSum, 0, low, now, high );
 | 
			
		||||
 | 
			
		||||
			a_bRegs[0x3a] = a_bRegs[0x39] = a_bRegs[0x38];
 | 
			
		||||
			dev->usbDev.a_bRegs[0x3a] = dev->usbDev.a_bRegs[0x39] = dev->usbDev.a_bRegs[0x38];
 | 
			
		||||
      
 | 
			
		||||
			DBG( _DBG_INFO2, "GrayOff = %d/%d/%d\n",
 | 
			
		||||
										(int)low[0],(int)now[0],(int)high[0]);
 | 
			
		||||
		}
 | 
			
		||||
    
 | 
			
		||||
		DBG( _DBG_INFO2, "REG[0x38] = %u\n", a_bRegs[0x38] );
 | 
			
		||||
		DBG( _DBG_INFO2, "REG[0x39] = %u\n", a_bRegs[0x39] );
 | 
			
		||||
		DBG( _DBG_INFO2, "REG[0x3a] = %u\n", a_bRegs[0x3a] );
 | 
			
		||||
		DBG( _DBG_INFO2, "REG[0x38] = %u\n", dev->usbDev.a_bRegs[0x38] );
 | 
			
		||||
		DBG( _DBG_INFO2, "REG[0x39] = %u\n", dev->usbDev.a_bRegs[0x39] );
 | 
			
		||||
		DBG( _DBG_INFO2, "REG[0x3a] = %u\n", dev->usbDev.a_bRegs[0x3a] );
 | 
			
		||||
 | 
			
		||||
		_UIO(sanei_lm983x_write(dev->fd, 0x38, &a_bRegs[0x38], 3, SANE_TRUE));
 | 
			
		||||
		_UIO(sanei_lm983x_write(dev->fd, 0x38, &dev->usbDev.a_bRegs[0x38], 3, SANE_TRUE));
 | 
			
		||||
	}
 | 
			
		||||
  
 | 
			
		||||
	if( m_ScanParam.bDataType == SCANDATATYPE_Color ) {
 | 
			
		||||
    	a_bRegs[0x38] = now[0];	
 | 
			
		||||
	    a_bRegs[0x39] = now[1];	
 | 
			
		||||
		a_bRegs[0x3a] = now[2];
 | 
			
		||||
    	dev->usbDev.a_bRegs[0x38] = now[0];	
 | 
			
		||||
	    dev->usbDev.a_bRegs[0x39] = now[1];	
 | 
			
		||||
		dev->usbDev.a_bRegs[0x3a] = now[2];
 | 
			
		||||
	} else {
 | 
			
		||||
    
 | 
			
		||||
		a_bRegs[0x38] = a_bRegs[0x39] = a_bRegs[0x3a] = now[0];	
 | 
			
		||||
		dev->usbDev.a_bRegs[0x38] = 
 | 
			
		||||
		dev->usbDev.a_bRegs[0x39] = 
 | 
			
		||||
		dev->usbDev.a_bRegs[0x3a] = now[0];
 | 
			
		||||
	}
 | 
			
		||||
  
 | 
			
		||||
	DBG( _DBG_INFO, "cano_AdjustOffset() done.\n" );
 | 
			
		||||
| 
						 | 
				
			
			@ -804,7 +807,7 @@ static int cano_AdjustOffset( pPlustek_Device dev )
 | 
			
		|||
 * fine calibration part 1
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
static SANE_Bool cano_AdjustDarkShading( pPlustek_Device dev )
 | 
			
		||||
static SANE_Bool cano_AdjustDarkShading( Plustek_Device *dev )
 | 
			
		||||
{
 | 
			
		||||
	char         tmp[40];
 | 
			
		||||
	pScanParam   pParam   = &dev->scanning.sParam;
 | 
			
		||||
| 
						 | 
				
			
			@ -944,7 +947,7 @@ static SANE_Bool cano_AdjustDarkShading( pPlustek_Device dev )
 | 
			
		|||
 * fine calibration part 2 - read the white calibration area and calculate
 | 
			
		||||
 * the gain coefficient for each pixel
 | 
			
		||||
 */
 | 
			
		||||
static SANE_Bool cano_AdjustWhiteShading( pPlustek_Device dev )
 | 
			
		||||
static SANE_Bool cano_AdjustWhiteShading( Plustek_Device *dev )
 | 
			
		||||
{
 | 
			
		||||
	char         tmp[40];
 | 
			
		||||
	pScanParam   pParam   = &dev->scanning.sParam;
 | 
			
		||||
| 
						 | 
				
			
			@ -1074,7 +1077,7 @@ static SANE_Bool cano_AdjustWhiteShading( pPlustek_Device dev )
 | 
			
		|||
 | 
			
		||||
/**
 | 
			
		||||
 */
 | 
			
		||||
static int cano_DoCalibration( pPlustek_Device dev )
 | 
			
		||||
static int cano_DoCalibration( Plustek_Device *dev )
 | 
			
		||||
{
 | 
			
		||||
	pScanDef  scanning = &dev->scanning;
 | 
			
		||||
	pHWDef    hw       = &dev->usbDev.HwSetting;
 | 
			
		||||
| 
						 | 
				
			
			@ -1107,7 +1110,7 @@ static int cano_DoCalibration( pPlustek_Device dev )
 | 
			
		|||
		if( cano_PrepareToReadWhiteCal(dev))
 | 
			
		||||
			return SANE_FALSE;
 | 
			
		||||
     
 | 
			
		||||
		a_bRegs[0x45] &= ~0x10;
 | 
			
		||||
		dev->usbDev.a_bRegs[0x45] &= ~0x10;
 | 
			
		||||
		if( !cano_AdjustLightsource(dev)) {
 | 
			
		||||
			DBG( _DBG_ERROR, "Coarse Calibration failed!!!\n" );
 | 
			
		||||
			return _E_INTERNAL;
 | 
			
		||||
| 
						 | 
				
			
			@ -1139,7 +1142,7 @@ static int cano_DoCalibration( pPlustek_Device dev )
 | 
			
		|||
	if(cano_PrepareToReadBlackCal(dev))
 | 
			
		||||
		return SANE_FALSE;
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x45] |= 0x10;
 | 
			
		||||
	dev->usbDev.a_bRegs[0x45] |= 0x10;
 | 
			
		||||
	if( !cano_AdjustDarkShading(dev)) {
 | 
			
		||||
		DBG( _DBG_ERROR, "Fine Calibration failed!!!\n" );
 | 
			
		||||
		return _E_INTERNAL;
 | 
			
		||||
| 
						 | 
				
			
			@ -1174,13 +1177,13 @@ static int cano_DoCalibration( pPlustek_Device dev )
 | 
			
		|||
	DBG( _DBG_INFO, "cano_DoCalibration() done\n" );
 | 
			
		||||
	DBG( _DBG_INFO, "-------------------------\n" );
 | 
			
		||||
	DBG( _DBG_INFO, "Static Gain:\n" );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x3b] = %u\n", a_bRegs[0x3b] );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x3c] = %u\n", a_bRegs[0x3c] );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x3d] = %u\n", a_bRegs[0x3d] );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x3b] = %u\n", dev->usbDev.a_bRegs[0x3b] );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x3c] = %u\n", dev->usbDev.a_bRegs[0x3c] );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x3d] = %u\n", dev->usbDev.a_bRegs[0x3d] );
 | 
			
		||||
	DBG( _DBG_INFO, "Static Offset:\n" );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x38] = %u\n", a_bRegs[0x38] );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x39] = %u\n", a_bRegs[0x39] );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x3a] = %u\n", a_bRegs[0x3a] );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x38] = %u\n", dev->usbDev.a_bRegs[0x38] );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x39] = %u\n", dev->usbDev.a_bRegs[0x39] );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x3a] = %u\n", dev->usbDev.a_bRegs[0x3a] );
 | 
			
		||||
	DBG( _DBG_INFO, "-------------------------\n" );
 | 
			
		||||
 | 
			
		||||
	return SANE_TRUE;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,6 +12,7 @@
 | 
			
		|||
 * - 0.46 - first version
 | 
			
		||||
 * - 0.47 - no changes
 | 
			
		||||
 * - 0.48 - no changes
 | 
			
		||||
 * - 0.49 - a_bRegs is now part of the device structure
 | 
			
		||||
 * .
 | 
			
		||||
 * <hr>
 | 
			
		||||
 * This file is part of the SANE package.
 | 
			
		||||
| 
						 | 
				
			
			@ -172,32 +173,34 @@ static char *usb_ReadOtherLines( FILE *fp, char *except )
 | 
			
		|||
 | 
			
		||||
/**
 | 
			
		||||
 */
 | 
			
		||||
static void usb_RestoreCalData( pCalData cal )
 | 
			
		||||
static void usb_RestoreCalData( Plustek_Device *dev, CalData *cal )
 | 
			
		||||
{
 | 
			
		||||
	a_bRegs[0x3b] = (u_char)cal->red_gain;
 | 
			
		||||
	a_bRegs[0x3c] = (u_char)cal->green_gain;
 | 
			
		||||
	a_bRegs[0x3d] = (u_char)cal->blue_gain;
 | 
			
		||||
	a_bRegs[0x38] = (u_char)cal->red_offs;
 | 
			
		||||
	a_bRegs[0x39] = (u_char)cal->green_offs;
 | 
			
		||||
	a_bRegs[0x3a] = (u_char)cal->blue_offs;
 | 
			
		||||
	u_char *regs = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x2a] = _HIBYTE((u_short)cal->light.green_pwm_duty);
 | 
			
		||||
	a_bRegs[0x2b] = _LOBYTE((u_short)cal->light.green_pwm_duty);
 | 
			
		||||
	regs[0x3b] = (u_char)cal->red_gain;
 | 
			
		||||
	regs[0x3c] = (u_char)cal->green_gain;
 | 
			
		||||
	regs[0x3d] = (u_char)cal->blue_gain;
 | 
			
		||||
	regs[0x38] = (u_char)cal->red_offs;
 | 
			
		||||
	regs[0x39] = (u_char)cal->green_offs;
 | 
			
		||||
	regs[0x3a] = (u_char)cal->blue_offs;
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x2c] = _HIBYTE((u_short)cal->light.red_light_on);
 | 
			
		||||
	a_bRegs[0x2d] = _LOBYTE((u_short)cal->light.red_light_on);
 | 
			
		||||
	a_bRegs[0x2e] = _HIBYTE((u_short)cal->light.red_light_off);
 | 
			
		||||
	a_bRegs[0x2f] = _LOBYTE((u_short)cal->light.red_light_off);
 | 
			
		||||
	regs[0x2a] = _HIBYTE((u_short)cal->light.green_pwm_duty);
 | 
			
		||||
	regs[0x2b] = _LOBYTE((u_short)cal->light.green_pwm_duty);
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x30] = _HIBYTE((u_short)cal->light.green_light_on);
 | 
			
		||||
	a_bRegs[0x31] = _LOBYTE((u_short)cal->light.green_light_on);
 | 
			
		||||
	a_bRegs[0x32] = _HIBYTE((u_short)cal->light.green_light_off);
 | 
			
		||||
	a_bRegs[0x33] = _LOBYTE((u_short)cal->light.green_light_off);
 | 
			
		||||
	regs[0x2c] = _HIBYTE((u_short)cal->light.red_light_on);
 | 
			
		||||
	regs[0x2d] = _LOBYTE((u_short)cal->light.red_light_on);
 | 
			
		||||
	regs[0x2e] = _HIBYTE((u_short)cal->light.red_light_off);
 | 
			
		||||
	regs[0x2f] = _LOBYTE((u_short)cal->light.red_light_off);
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x34] = _HIBYTE((u_short)cal->light.blue_light_on);
 | 
			
		||||
	a_bRegs[0x35] = _LOBYTE((u_short)cal->light.blue_light_on);
 | 
			
		||||
	a_bRegs[0x36] = _HIBYTE((u_short)cal->light.blue_light_off);
 | 
			
		||||
	a_bRegs[0x37] = _LOBYTE((u_short)cal->light.blue_light_off);
 | 
			
		||||
	regs[0x30] = _HIBYTE((u_short)cal->light.green_light_on);
 | 
			
		||||
	regs[0x31] = _LOBYTE((u_short)cal->light.green_light_on);
 | 
			
		||||
	regs[0x32] = _HIBYTE((u_short)cal->light.green_light_off);
 | 
			
		||||
	regs[0x33] = _LOBYTE((u_short)cal->light.green_light_off);
 | 
			
		||||
 | 
			
		||||
	regs[0x34] = _HIBYTE((u_short)cal->light.blue_light_on);
 | 
			
		||||
	regs[0x35] = _LOBYTE((u_short)cal->light.blue_light_on);
 | 
			
		||||
	regs[0x36] = _HIBYTE((u_short)cal->light.blue_light_off);
 | 
			
		||||
	regs[0x37] = _LOBYTE((u_short)cal->light.blue_light_off);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -227,7 +230,7 @@ static void usb_CreatePrefix( pPlustek_Device dev, char *pfx )
 | 
			
		|||
 | 
			
		||||
/** function to read and set the calibration data from external file
 | 
			
		||||
 */
 | 
			
		||||
static SANE_Bool usb_ReadAndSetCalData( pPlustek_Device dev )
 | 
			
		||||
static SANE_Bool usb_ReadAndSetCalData( Plustek_Device *dev )
 | 
			
		||||
{
 | 
			
		||||
	char       pfx[20];
 | 
			
		||||
	char       tmp[1024];
 | 
			
		||||
| 
						 | 
				
			
			@ -290,7 +293,7 @@ static SANE_Bool usb_ReadAndSetCalData( pPlustek_Device dev )
 | 
			
		|||
						&cal.light.green_pwm_duty );
 | 
			
		||||
 | 
			
		||||
		if( 13 == res ) {
 | 
			
		||||
			usb_RestoreCalData( &cal );
 | 
			
		||||
			usb_RestoreCalData( dev, &cal );
 | 
			
		||||
			ret = SANE_TRUE;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -303,26 +306,28 @@ static SANE_Bool usb_ReadAndSetCalData( pPlustek_Device dev )
 | 
			
		|||
 | 
			
		||||
/**
 | 
			
		||||
 */
 | 
			
		||||
static void usb_PrepCalData( pCalData cal )
 | 
			
		||||
static void usb_PrepCalData( Plustek_Device *dev, CalData *cal )
 | 
			
		||||
{
 | 
			
		||||
	u_char *regs = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	memset( cal, 0, sizeof(CalData));
 | 
			
		||||
    cal->version = _PT_CF_VERSION;
 | 
			
		||||
 | 
			
		||||
	cal->red_gain   = (u_short)a_bRegs[0x3b];
 | 
			
		||||
	cal->green_gain = (u_short)a_bRegs[0x3c];
 | 
			
		||||
	cal->blue_gain  = (u_short)a_bRegs[0x3d];
 | 
			
		||||
	cal->red_offs   = (u_short)a_bRegs[0x38];
 | 
			
		||||
	cal->green_offs = (u_short)a_bRegs[0x39];
 | 
			
		||||
	cal->blue_offs  = (u_short)a_bRegs[0x3a];
 | 
			
		||||
	cal->red_gain   = (u_short)regs[0x3b];
 | 
			
		||||
	cal->green_gain = (u_short)regs[0x3c];
 | 
			
		||||
	cal->blue_gain  = (u_short)regs[0x3d];
 | 
			
		||||
	cal->red_offs   = (u_short)regs[0x38];
 | 
			
		||||
	cal->green_offs = (u_short)regs[0x39];
 | 
			
		||||
	cal->blue_offs  = (u_short)regs[0x3a];
 | 
			
		||||
 | 
			
		||||
	cal->light.green_pwm_duty  = a_bRegs[0x2a] * 256 + a_bRegs[0x2b];
 | 
			
		||||
	cal->light.green_pwm_duty  = regs[0x2a] * 256 + regs[0x2b];
 | 
			
		||||
 | 
			
		||||
	cal->light.red_light_on    = a_bRegs[0x2c] * 256 + a_bRegs[0x2d];
 | 
			
		||||
	cal->light.red_light_off   = a_bRegs[0x2e] * 256 + a_bRegs[0x2f];
 | 
			
		||||
	cal->light.green_light_on  = a_bRegs[0x30] * 256 + a_bRegs[0x31];
 | 
			
		||||
	cal->light.green_light_off = a_bRegs[0x32] * 256 + a_bRegs[0x33];
 | 
			
		||||
	cal->light.blue_light_on   = a_bRegs[0x34] * 256 + a_bRegs[0x35];
 | 
			
		||||
	cal->light.blue_light_off  = a_bRegs[0x36] * 256 + a_bRegs[0x37];
 | 
			
		||||
	cal->light.red_light_on    = regs[0x2c] * 256 + regs[0x2d];
 | 
			
		||||
	cal->light.red_light_off   = regs[0x2e] * 256 + regs[0x2f];
 | 
			
		||||
	cal->light.green_light_on  = regs[0x30] * 256 + regs[0x31];
 | 
			
		||||
	cal->light.green_light_off = regs[0x32] * 256 + regs[0x33];
 | 
			
		||||
	cal->light.blue_light_on   = regs[0x34] * 256 + regs[0x35];
 | 
			
		||||
	cal->light.blue_light_off  = regs[0x36] * 256 + regs[0x37];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** function to save/update the calibration data
 | 
			
		||||
| 
						 | 
				
			
			@ -353,7 +358,7 @@ static void usb_SaveCalData( pPlustek_Device dev )
 | 
			
		|||
	DBG( _DBG_INFO, "- Saving calibration data to file\n" );
 | 
			
		||||
	DBG( _DBG_INFO, "  %s\n", dev->calFile );
 | 
			
		||||
 | 
			
		||||
	usb_PrepCalData ( &cal );
 | 
			
		||||
	usb_PrepCalData ( dev, &cal );
 | 
			
		||||
	usb_CreatePrefix( dev, pfx );
 | 
			
		||||
 | 
			
		||||
	sprintf( set_tmp, "%s%u,%u,%u,%u,%u,%u,"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,6 +49,7 @@
 | 
			
		|||
 *        - added parameters for UMAX 3450 TPA
 | 
			
		||||
 *        - parameter tuning for CanoScan D660U
 | 
			
		||||
 *        - cleanup
 | 
			
		||||
 * - 0.49 - no changes
 | 
			
		||||
 * .
 | 
			
		||||
 * <hr>
 | 
			
		||||
 * This file is part of the SANE package.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,7 +40,8 @@
 | 
			
		|||
 *        - added usb_WaitPos()
 | 
			
		||||
 *        - added usb_FillLampRegs() - sets also PWMDutyCylce now
 | 
			
		||||
 *        - added UMAX3450 TPA autodetection
 | 
			
		||||
 * .
 | 
			
		||||
 * - 0.49 - a_bRegs is now part of the device structure
 | 
			
		||||
 * .                                        
 | 
			
		||||
 * <hr>
 | 
			
		||||
 * This file is part of the SANE package.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -95,10 +96,6 @@
 | 
			
		|||
 | 
			
		||||
static u_long dwCrystalFrequency = 48000000UL;
 | 
			
		||||
 | 
			
		||||
static SANE_Bool fModuleFirstHome;  /* HEINER: this has to be initialized */
 | 
			
		||||
static SANE_Bool fLastScanIsAdf;
 | 
			
		||||
static u_char    a_bRegs[0x80];     /**< our global register file */
 | 
			
		||||
 | 
			
		||||
/** the NatSemi 983x is a big endian chip, and the line protocol data all
 | 
			
		||||
 *  arrives big-endian.  This determines if we need to swap to host-order
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -146,14 +143,14 @@ static pClkMotorDef usb_GetMotorSet( eModelDef model )
 | 
			
		|||
 * @param fOn    - SANE_TRUE means motor on, SANE_FALSE means motor off
 | 
			
		||||
 * @return always SANE_TRUE
 | 
			
		||||
 */
 | 
			
		||||
static SANE_Bool usb_MotorOn( int handle, SANE_Bool fOn )
 | 
			
		||||
static SANE_Bool usb_MotorOn( Plustek_Device *dev, SANE_Bool fOn )
 | 
			
		||||
{
 | 
			
		||||
	if( fOn )
 | 
			
		||||
		a_bRegs[0x45] |= 0x10;
 | 
			
		||||
		dev->usbDev.a_bRegs[0x45] |= 0x10;
 | 
			
		||||
	else
 | 
			
		||||
		a_bRegs[0x45] &= ~0x10;
 | 
			
		||||
		dev->usbDev.a_bRegs[0x45] &= ~0x10;
 | 
			
		||||
 | 
			
		||||
	usbio_WriteReg( handle, 0x45, a_bRegs[0x45] );
 | 
			
		||||
	usbio_WriteReg( dev->fd, 0x45, dev->usbDev.a_bRegs[0x45] );
 | 
			
		||||
 | 
			
		||||
	return SANE_TRUE;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -246,7 +243,8 @@ static SANE_Bool usb_WaitPos( Plustek_Device *dev, u_long to, SANE_Bool stay )
 | 
			
		|||
	double         maxf, fac, speed;
 | 
			
		||||
	struct timeval start_time, t2;
 | 
			
		||||
 | 
			
		||||
	HWDef         *hw = &dev->usbDev.HwSetting;
 | 
			
		||||
	HWDef         *hw   = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char        *regs = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	/* get current master clock divider */
 | 
			
		||||
	usbio_ReadReg( dev->fd, 0x08, &value );
 | 
			
		||||
| 
						 | 
				
			
			@ -257,7 +255,7 @@ static SANE_Bool usb_WaitPos( Plustek_Device *dev, u_long to, SANE_Bool stay )
 | 
			
		|||
	mch = ((value & 0x07) > 1) ? 1:3;
 | 
			
		||||
 | 
			
		||||
	/* calculate the current speed */
 | 
			
		||||
	ffs   = a_bRegs[0x48] * 256 + a_bRegs[0x49];
 | 
			
		||||
	ffs   = regs[0x48] * 256 + regs[0x49];
 | 
			
		||||
	speed = ((double)dwCrystalFrequency) /(double)((u_long)mclk_div * 32UL * 
 | 
			
		||||
	                                (u_long)mch * (u_long)ffs * hw->wMotorDpi);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -323,9 +321,9 @@ static SANE_Bool usb_WaitPos( Plustek_Device *dev, u_long to, SANE_Bool stay )
 | 
			
		|||
				if((int)fac > 25 )
 | 
			
		||||
					usleep( 150 * 1000 );
 | 
			
		||||
 | 
			
		||||
				a_bRegs[0x48] = (u_char)(ffs >> 8);
 | 
			
		||||
				a_bRegs[0x49] = (u_char)(ffs & 0xFF);
 | 
			
		||||
				sanei_lm983x_write(dev->fd, 0x48, &a_bRegs[0x48], 2, SANE_TRUE);
 | 
			
		||||
				regs[0x48] = (u_char)(ffs >> 8);
 | 
			
		||||
				regs[0x49] = (u_char)(ffs & 0xFF);
 | 
			
		||||
				sanei_lm983x_write(dev->fd, 0x48, ®s[0x48], 2, SANE_TRUE);
 | 
			
		||||
				if(ffs == min_ffs )
 | 
			
		||||
					ffs = 0;
 | 
			
		||||
			} else {
 | 
			
		||||
| 
						 | 
				
			
			@ -357,7 +355,8 @@ static SANE_Bool usb_ModuleMove( Plustek_Device *dev,
 | 
			
		|||
	u_short      wFastFeedStepSize;
 | 
			
		||||
	double       dMaxMoveSpeed;
 | 
			
		||||
	pClkMotorDef clk;
 | 
			
		||||
	pHWDef       hw = &dev->usbDev.HwSetting;
 | 
			
		||||
	pHWDef       hw   = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char      *regs = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	if( bAction != MOVE_ToPaperSensor   &&
 | 
			
		||||
		bAction != MOVE_EjectAllPapers  &&
 | 
			
		||||
| 
						 | 
				
			
			@ -395,7 +394,7 @@ static SANE_Bool usb_ModuleMove( Plustek_Device *dev,
 | 
			
		|||
			return SANE_FALSE;
 | 
			
		||||
 | 
			
		||||
		usbio_WriteReg( dev->fd, 0x07, 0);
 | 
			
		||||
		usbio_WriteReg( dev->fd, 0x58, a_bRegs[0x58]);
 | 
			
		||||
		usbio_WriteReg( dev->fd, 0x58, regs[0x58]);
 | 
			
		||||
 | 
			
		||||
		usbio_ReadReg( dev->fd, 0x02, &bReg2 );
 | 
			
		||||
		hw->dMaxMoveSpeed = d;
 | 
			
		||||
| 
						 | 
				
			
			@ -421,14 +420,14 @@ static SANE_Bool usb_ModuleMove( Plustek_Device *dev,
 | 
			
		|||
	                    ((u_long)mclk_div * 8UL * 1 *
 | 
			
		||||
	                    dMaxMoveSpeed * 4 * hw->wMotorDpi));
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x48] = (u_char)(wFastFeedStepSize >> 8);
 | 
			
		||||
	a_bRegs[0x49] = (u_char)(wFastFeedStepSize & 0xFF);
 | 
			
		||||
	regs[0x48] = (u_char)(wFastFeedStepSize >> 8);
 | 
			
		||||
	regs[0x49] = (u_char)(wFastFeedStepSize & 0xFF);
 | 
			
		||||
 | 
			
		||||
	dwStep = dwStep * hw->wMotorDpi / 300UL;
 | 
			
		||||
	a_bRegs[0x4a] = _HIBYTE(_LOWORD(dwStep));
 | 
			
		||||
	a_bRegs[0x4b] = _LOBYTE(_LOWORD(dwStep));
 | 
			
		||||
	regs[0x4a] = _HIBYTE(_LOWORD(dwStep));
 | 
			
		||||
	regs[0x4b] = _LOBYTE(_LOWORD(dwStep));
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x45] |= 0x10;
 | 
			
		||||
	regs[0x45] |= 0x10;
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO2,"MotorDPI=%u, MaxMoveSpeed=%.3f, "
 | 
			
		||||
					"FFStepSize=%u, Steps=%lu\n", hw->wMotorDpi,
 | 
			
		||||
| 
						 | 
				
			
			@ -436,8 +435,8 @@ static SANE_Bool usb_ModuleMove( Plustek_Device *dev,
 | 
			
		|||
	DBG( _DBG_INFO2, "MOTOR: "
 | 
			
		||||
					"PWM=0x%02x, PWM_DUTY=0x%02x 0x45=0x%02x "
 | 
			
		||||
                    "0x48=0x%02x, 0x49=0x%02x \n",
 | 
			
		||||
					a_bRegs[0x56], a_bRegs[0x57], a_bRegs[0x45],
 | 
			
		||||
					a_bRegs[0x48], a_bRegs[0x49] );
 | 
			
		||||
					regs[0x56], regs[0x57], regs[0x45],
 | 
			
		||||
					regs[0x48], regs[0x49] );
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO2,"MCLK_FFW = %u --> 0x%02x\n", mclk_div, (mclk_div-1)*2 );
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -462,14 +461,14 @@ static SANE_Bool usb_ModuleMove( Plustek_Device *dev,
 | 
			
		|||
	if( !usbio_WriteReg(dev->fd, 0x26, 0x0C))
 | 
			
		||||
		return SANE_FALSE;
 | 
			
		||||
 | 
			
		||||
	_UIO(sanei_lm983x_write(dev->fd, 0x48, &a_bRegs[0x48], 2, SANE_TRUE));
 | 
			
		||||
	_UIO(sanei_lm983x_write(dev->fd, 0x4A, &a_bRegs[0x4A], 2, SANE_TRUE));
 | 
			
		||||
	_UIO(sanei_lm983x_write(dev->fd, 0x48, ®s[0x48], 2, SANE_TRUE));
 | 
			
		||||
	_UIO(sanei_lm983x_write(dev->fd, 0x4A, ®s[0x4A], 2, SANE_TRUE));
 | 
			
		||||
 | 
			
		||||
	/* disable home */
 | 
			
		||||
	if( !usbio_WriteReg(dev->fd, 0x58, a_bRegs[0x58] & ~7))
 | 
			
		||||
	if( !usbio_WriteReg(dev->fd, 0x58, regs[0x58] & ~7))
 | 
			
		||||
		return SANE_FALSE;
 | 
			
		||||
 | 
			
		||||
	if( !usbio_WriteReg(dev->fd, 0x45, a_bRegs[0x45] ))
 | 
			
		||||
	if( !usbio_WriteReg(dev->fd, 0x45, regs[0x45] ))
 | 
			
		||||
		return SANE_FALSE;
 | 
			
		||||
 | 
			
		||||
	if( bAction == MOVE_Forward || bAction == MOVE_ToShading )
 | 
			
		||||
| 
						 | 
				
			
			@ -501,7 +500,7 @@ static SANE_Bool usb_ModuleMove( Plustek_Device *dev,
 | 
			
		|||
 | 
			
		||||
				if( usb_SensorPaper( dev->fd )) {
 | 
			
		||||
					usbio_WriteReg( dev->fd, 0x07, 0 );
 | 
			
		||||
					usbio_WriteReg( dev->fd, 0x58, a_bRegs[0x58] );
 | 
			
		||||
					usbio_WriteReg( dev->fd, 0x58, regs[0x58] );
 | 
			
		||||
					usbio_ReadReg ( dev->fd, 0x02, &bReg2 );
 | 
			
		||||
					return SANE_TRUE;
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -516,7 +515,7 @@ static SANE_Bool usb_ModuleMove( Plustek_Device *dev,
 | 
			
		|||
 | 
			
		||||
				if( usb_SensorPaper( dev->fd )) {
 | 
			
		||||
					usbio_WriteReg( dev->fd, 0x07, 0 );
 | 
			
		||||
					usbio_WriteReg( dev->fd, 0x58, a_bRegs[0x58] );
 | 
			
		||||
					usbio_WriteReg( dev->fd, 0x58, regs[0x58] );
 | 
			
		||||
					usbio_ReadReg ( dev->fd, 0x02, &bReg2 );
 | 
			
		||||
					return SANE_TRUE;
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -530,7 +529,7 @@ static SANE_Bool usb_ModuleMove( Plustek_Device *dev,
 | 
			
		|||
			retval = usb_WaitPos( dev, 200, SANE_TRUE );
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		usbio_WriteReg( dev->fd, 0x58, a_bRegs[0x58] );
 | 
			
		||||
		usbio_WriteReg( dev->fd, 0x58, regs[0x58] );
 | 
			
		||||
		usbio_ReadReg ( dev->fd, 0x02, &bReg2 );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -547,20 +546,21 @@ static SANE_Bool usb_ModuleToHome( Plustek_Device *dev, SANE_Bool fWait )
 | 
			
		|||
	u_char    value;
 | 
			
		||||
	pDCapsDef scaps = &dev->usbDev.Caps;
 | 
			
		||||
	pHWDef    hw    = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char   *regs  = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	/* Check if merlin is ready for setting command */
 | 
			
		||||
	usbio_WriteReg( dev->fd, 0x58, hw->bReg_0x58 );
 | 
			
		||||
	usbio_ReadReg ( dev->fd, 2, &value );
 | 
			
		||||
 | 
			
		||||
	if( value & 1 ) {
 | 
			
		||||
		fModuleFirstHome = SANE_FALSE;
 | 
			
		||||
		dev->usbDev.fModFirstHome = SANE_FALSE;
 | 
			
		||||
		return SANE_TRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_UIO( usbio_ReadReg( dev->fd, 0x07, &value ));
 | 
			
		||||
 | 
			
		||||
	if( fModuleFirstHome ) {
 | 
			
		||||
		fModuleFirstHome = SANE_FALSE;
 | 
			
		||||
	if( dev->usbDev.fModFirstHome ) {
 | 
			
		||||
		dev->usbDev.fModFirstHome = SANE_FALSE;
 | 
			
		||||
		if( hw->motorModel != MODEL_Tokyo600 )
 | 
			
		||||
			usb_ModuleMove( dev, MOVE_Forward, hw->wMotorDpi / 2);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -583,8 +583,8 @@ static SANE_Bool usb_ModuleToHome( Plustek_Device *dev, SANE_Bool fWait )
 | 
			
		|||
 | 
			
		||||
			clk = usb_GetMotorSet( hw->motorModel );
 | 
			
		||||
 | 
			
		||||
			a_bRegs[0x56] = clk->pwm_fast;
 | 
			
		||||
			a_bRegs[0x57] = clk->pwm_duty_fast;
 | 
			
		||||
			regs[0x56] = clk->pwm_fast;
 | 
			
		||||
			regs[0x57] = clk->pwm_duty_fast;
 | 
			
		||||
			mclk_div      = clk->mclk_fast;
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
| 
						 | 
				
			
			@ -597,8 +597,8 @@ static SANE_Bool usb_ModuleToHome( Plustek_Device *dev, SANE_Bool fWait )
 | 
			
		|||
				case MODEL_KaoHsiung:
 | 
			
		||||
				case MODEL_HuaLien:
 | 
			
		||||
				default:
 | 
			
		||||
					a_bRegs[0x56] = 1;
 | 
			
		||||
					a_bRegs[0x57] = 63;
 | 
			
		||||
					regs[0x56] = 1;
 | 
			
		||||
					regs[0x57] = 63;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			} else { /* if(Device.Caps.OpticDpi.x == 600) */
 | 
			
		||||
| 
						 | 
				
			
			@ -606,23 +606,23 @@ static SANE_Bool usb_ModuleToHome( Plustek_Device *dev, SANE_Bool fWait )
 | 
			
		|||
				switch( hw->motorModel ) {
 | 
			
		||||
 | 
			
		||||
				case MODEL_Tokyo600:
 | 
			
		||||
					a_bRegs[0x56] = 4;
 | 
			
		||||
					a_bRegs[0x57] = 4;	/* 2; */
 | 
			
		||||
					regs[0x56] = 4;
 | 
			
		||||
					regs[0x57] = 4;	/* 2; */
 | 
			
		||||
					break;
 | 
			
		||||
				case MODEL_HuaLien:
 | 
			
		||||
					if( dev->caps.dwFlag & SFLAG_ADF ) {
 | 
			
		||||
						a_bRegs[0x56] = 64;	/* 32; */
 | 
			
		||||
						a_bRegs[0x57] = 4;	/* 16; */
 | 
			
		||||
						regs[0x56] = 64;	/* 32; */
 | 
			
		||||
						regs[0x57] = 4;	/* 16; */
 | 
			
		||||
					} else {
 | 
			
		||||
						a_bRegs[0x56] = 32;
 | 
			
		||||
						a_bRegs[0x57] = 16;
 | 
			
		||||
						regs[0x56] = 32;
 | 
			
		||||
						regs[0x57] = 16;
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				
 | 
			
		||||
				case MODEL_KaoHsiung:
 | 
			
		||||
				default:
 | 
			
		||||
					a_bRegs[0x56] = 64;
 | 
			
		||||
					a_bRegs[0x57] = 20;
 | 
			
		||||
					regs[0x56] = 64;
 | 
			
		||||
					regs[0x57] = 20;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -633,20 +633,20 @@ static SANE_Bool usb_ModuleToHome( Plustek_Device *dev, SANE_Bool fWait )
 | 
			
		|||
		 */
 | 
			
		||||
		wFastFeedStepSize = (u_short)(dwCrystalFrequency / (mclk_div * 8 * 1 *
 | 
			
		||||
		                              hw->dMaxMotorSpeed * 4 * hw->wMotorDpi));
 | 
			
		||||
		a_bRegs[0x48] = (u_char)(wFastFeedStepSize >> 8);
 | 
			
		||||
		a_bRegs[0x49] = (u_char)(wFastFeedStepSize & 0xFF);
 | 
			
		||||
		a_bRegs[0x4a] = 0;
 | 
			
		||||
		a_bRegs[0x4b] = 0;
 | 
			
		||||
		regs[0x48] = (u_char)(wFastFeedStepSize >> 8);
 | 
			
		||||
		regs[0x49] = (u_char)(wFastFeedStepSize & 0xFF);
 | 
			
		||||
		regs[0x4a] = 0;
 | 
			
		||||
		regs[0x4b] = 0;
 | 
			
		||||
 | 
			
		||||
		a_bRegs[0x45] |= 0x10;
 | 
			
		||||
		regs[0x45] |= 0x10;
 | 
			
		||||
 | 
			
		||||
		DBG( _DBG_INFO2,"MotorDPI=%u, MaxMotorSpeed=%.3f, FFStepSize=%u\n",
 | 
			
		||||
						hw->wMotorDpi, hw->dMaxMotorSpeed, wFastFeedStepSize );
 | 
			
		||||
		DBG( _DBG_INFO, "MOTOR: "
 | 
			
		||||
						"PWM=0x%02x, PWM_DUTY=0x%02x 0x45=0x%02x "
 | 
			
		||||
                        "0x48=0x%02x, 0x49=0x%02x\n",
 | 
			
		||||
						a_bRegs[0x56], a_bRegs[0x57],
 | 
			
		||||
						a_bRegs[0x45], a_bRegs[0x48], a_bRegs[0x49] );
 | 
			
		||||
						regs[0x56], regs[0x57],
 | 
			
		||||
						regs[0x45], regs[0x48], regs[0x49] );
 | 
			
		||||
 | 
			
		||||
		/* The setting for chassis moving is:
 | 
			
		||||
		 * MCLK divider = 6, 8 bits/pixel, HDPI divider = 12,
 | 
			
		||||
| 
						 | 
				
			
			@ -672,10 +672,10 @@ static SANE_Bool usb_ModuleToHome( Plustek_Device *dev, SANE_Bool fWait )
 | 
			
		|||
		if( !usbio_WriteReg(dev->fd, 0x26, 0x8C))
 | 
			
		||||
			return SANE_FALSE;
 | 
			
		||||
 | 
			
		||||
		_UIO(sanei_lm983x_write(dev->fd, 0x48, &a_bRegs[0x48], 4, SANE_TRUE));
 | 
			
		||||
		_UIO(sanei_lm983x_write(dev->fd, 0x56, &a_bRegs[0x56], 3, SANE_TRUE));
 | 
			
		||||
		_UIO(sanei_lm983x_write(dev->fd, 0x48, ®s[0x48], 4, SANE_TRUE));
 | 
			
		||||
		_UIO(sanei_lm983x_write(dev->fd, 0x56, ®s[0x56], 3, SANE_TRUE));
 | 
			
		||||
 | 
			
		||||
		if( !usbio_WriteReg(dev->fd, 0x45, a_bRegs[0x45]))
 | 
			
		||||
		if( !usbio_WriteReg(dev->fd, 0x45, regs[0x45]))
 | 
			
		||||
			return SANE_FALSE;
 | 
			
		||||
 | 
			
		||||
		usbio_WriteReg(dev->fd, 0x0a, 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -702,9 +702,9 @@ static SANE_Bool usb_ModuleToHome( Plustek_Device *dev, SANE_Bool fWait )
 | 
			
		|||
			}
 | 
			
		||||
			wFastFeedStepSize = (WORD)(dwCrystalFrequency / (6UL * 8UL * 1 * Device.HwSetting.dMaxMotorSpeed * 4 *
 | 
			
		||||
				Device.HwSetting.wMotorDpi) * 60 / 78);	
 | 
			
		||||
			a_bRegs[0x48] = (u_char)(wFastFeedStepSize >> 8);
 | 
			
		||||
			a_bRegs[0x49] = (u_char)(wFastFeedStepSize & 0xFF);
 | 
			
		||||
			WriteRegisters(0x48, &a_bRegs[0x48], 2);
 | 
			
		||||
			regs[0x48] = (u_char)(wFastFeedStepSize >> 8);
 | 
			
		||||
			regs[0x49] = (u_char)(wFastFeedStepSize & 0xFF);
 | 
			
		||||
			WriteRegisters(0x48, ®s[0x48], 2);
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -717,6 +717,7 @@ static SANE_Bool usb_MotorSelect( Plustek_Device *dev, SANE_Bool fADF )
 | 
			
		|||
{
 | 
			
		||||
	pDCapsDef sCaps = &dev->usbDev.Caps;
 | 
			
		||||
	pHWDef    hw    = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char   *regs  = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	if(!_IS_PLUSTEKMOTOR(hw->motorModel)) {
 | 
			
		||||
		return SANE_TRUE;
 | 
			
		||||
| 
						 | 
				
			
			@ -731,7 +732,7 @@ static SANE_Bool usb_MotorSelect( Plustek_Device *dev, SANE_Bool fADF )
 | 
			
		|||
			hw->dMaxMoveSpeed  = 1.5;
 | 
			
		||||
			sCaps->OpticDpi.y  = 600;
 | 
			
		||||
		}
 | 
			
		||||
		a_bRegs[0x5b] |= 0x80;
 | 
			
		||||
		regs[0x5b] |= 0x80;
 | 
			
		||||
		
 | 
			
		||||
	} else {
 | 
			
		||||
	
 | 
			
		||||
| 
						 | 
				
			
			@ -742,14 +743,14 @@ static SANE_Bool usb_MotorSelect( Plustek_Device *dev, SANE_Bool fADF )
 | 
			
		|||
			hw->dMaxMoveSpeed  = 0.9;
 | 
			
		||||
			sCaps->OpticDpi.y  = 1200;
 | 
			
		||||
		}
 | 
			
		||||
		a_bRegs[0x5b] &= ~0x80;
 | 
			
		||||
		regs[0x5b] &= ~0x80;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* To stop the motor moving */
 | 
			
		||||
	usbio_WriteReg( dev->fd, 0x07, 0 );
 | 
			
		||||
	usleep(10 * 1000);
 | 
			
		||||
 | 
			
		||||
	usbio_WriteReg( dev->fd, 0x5b, a_bRegs[0x5b] );
 | 
			
		||||
	usbio_WriteReg( dev->fd, 0x5b, regs[0x5b] );
 | 
			
		||||
	return SANE_TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -757,25 +758,26 @@ static SANE_Bool usb_MotorSelect( Plustek_Device *dev, SANE_Bool fADF )
 | 
			
		|||
 */
 | 
			
		||||
static SANE_Bool usb_AdjustLamps( Plustek_Device *dev )
 | 
			
		||||
{
 | 
			
		||||
	pHWDef hw = &dev->usbDev.HwSetting;
 | 
			
		||||
	pHWDef  hw   = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char *regs = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x2c] = _HIBYTE(hw->red_lamp_on);
 | 
			
		||||
	a_bRegs[0x2d] = _LOBYTE(hw->red_lamp_on);
 | 
			
		||||
	a_bRegs[0x2e] = _HIBYTE(hw->red_lamp_off);
 | 
			
		||||
	a_bRegs[0x2f] = _LOBYTE(hw->red_lamp_off);
 | 
			
		||||
	regs[0x2c] = _HIBYTE(hw->red_lamp_on);
 | 
			
		||||
	regs[0x2d] = _LOBYTE(hw->red_lamp_on);
 | 
			
		||||
	regs[0x2e] = _HIBYTE(hw->red_lamp_off);
 | 
			
		||||
	regs[0x2f] = _LOBYTE(hw->red_lamp_off);
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x30] = _HIBYTE(hw->green_lamp_on);
 | 
			
		||||
	a_bRegs[0x31] = _LOBYTE(hw->green_lamp_on);
 | 
			
		||||
	a_bRegs[0x32] = _HIBYTE(hw->green_lamp_off);
 | 
			
		||||
	a_bRegs[0x33] = _LOBYTE(hw->green_lamp_off);
 | 
			
		||||
	regs[0x30] = _HIBYTE(hw->green_lamp_on);
 | 
			
		||||
	regs[0x31] = _LOBYTE(hw->green_lamp_on);
 | 
			
		||||
	regs[0x32] = _HIBYTE(hw->green_lamp_off);
 | 
			
		||||
	regs[0x33] = _LOBYTE(hw->green_lamp_off);
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x34] = _HIBYTE(hw->blue_lamp_on);
 | 
			
		||||
	a_bRegs[0x35] = _LOBYTE(hw->blue_lamp_on);
 | 
			
		||||
	a_bRegs[0x36] = _HIBYTE(hw->blue_lamp_off);
 | 
			
		||||
	a_bRegs[0x37] = _LOBYTE(hw->blue_lamp_off);
 | 
			
		||||
	regs[0x34] = _HIBYTE(hw->blue_lamp_on);
 | 
			
		||||
	regs[0x35] = _LOBYTE(hw->blue_lamp_on);
 | 
			
		||||
	regs[0x36] = _HIBYTE(hw->blue_lamp_off);
 | 
			
		||||
	regs[0x37] = _LOBYTE(hw->blue_lamp_off);
 | 
			
		||||
 | 
			
		||||
	return sanei_lm983x_write( dev->fd, 0x2c,
 | 
			
		||||
	                           &a_bRegs[0x2c], 0x37-0x2c+1, SANE_TRUE );
 | 
			
		||||
	return sanei_lm983x_write( dev->fd, 0x2c, 
 | 
			
		||||
	                           ®s[0x2c], 0x37-0x2c+1, SANE_TRUE );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -845,7 +847,7 @@ static void usb_AdjustCISLampSettings( Plustek_Device *dev, SANE_Bool on )
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x29] = hw->bReg_0x29;
 | 
			
		||||
	dev->usbDev.a_bRegs[0x29] = hw->bReg_0x29;
 | 
			
		||||
	usb_AdjustLamps( dev );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -900,6 +902,7 @@ 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;
 | 
			
		||||
	SANE_Byte reg, msk, val;
 | 
			
		||||
| 
						 | 
				
			
			@ -926,8 +929,8 @@ static int usb_GetLampStatus( Plustek_Device *dev )
 | 
			
		|||
		if( 0 == reg ) {
 | 
			
		||||
#if 0
 | 
			
		||||
			/* probably not correct, esp. when changing from color to gray...*/
 | 
			
		||||
			usbio_ReadReg( dev->fd, 0x29, &a_bRegs[0x29] );
 | 
			
		||||
			if( a_bRegs[0x29] & 3 )
 | 
			
		||||
			usbio_ReadReg( dev->fd, 0x29, ®s[0x29] );
 | 
			
		||||
			if( regs[0x29] & 3 )
 | 
			
		||||
#else
 | 
			
		||||
			usbio_ReadReg( dev->fd, 0x29, ® );
 | 
			
		||||
			if( reg & 3 )
 | 
			
		||||
| 
						 | 
				
			
			@ -955,15 +958,15 @@ static int usb_GetLampStatus( Plustek_Device *dev )
 | 
			
		|||
	
 | 
			
		||||
			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, &a_bRegs[0x29], 3, SANE_TRUE );
 | 
			
		||||
				DBG( _DBG_INFO, "[29]=0x%02x, [2A]=0x%02x, [2B]=0x%02x\n", a_bRegs[0x29], a_bRegs[0x2a], a_bRegs[0x2b] );
 | 
			
		||||
				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;*/
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		sanei_lm983x_read(dev->fd, 0x29,&a_bRegs[0x29],0x37-0x29+1,SANE_TRUE);
 | 
			
		||||
		sanei_lm983x_read(dev->fd, 0x29,®s[0x29],0x37-0x29+1,SANE_TRUE);
 | 
			
		||||
 | 
			
		||||
		if((a_bRegs[0x29] & 3) == 1) {
 | 
			
		||||
		if((regs[0x29] & 3) == 1) {
 | 
			
		||||
 | 
			
		||||
/* HEINER: BETTER define register to check ! */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -972,10 +975,10 @@ static int usb_GetLampStatus( Plustek_Device *dev )
 | 
			
		|||
 | 
			
		||||
            } else {
 | 
			
		||||
 | 
			
		||||
				if((a_bRegs[0x2e] * 256 + a_bRegs[0x2f]) > hw->wLineEnd )
 | 
			
		||||
				if((regs[0x2e] * 256 + regs[0x2f]) > hw->wLineEnd )
 | 
			
		||||
					iLampStatus |= DEV_LampReflection;
 | 
			
		||||
 | 
			
		||||
				if((a_bRegs[0x36] * 256 + a_bRegs[0x37]) > hw->wLineEnd )
 | 
			
		||||
				if((regs[0x36] * 256 + regs[0x37]) > hw->wLineEnd )
 | 
			
		||||
					iLampStatus |= DEV_LampTPA;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -992,7 +995,8 @@ static SANE_Bool usb_switchLampX( Plustek_Device *dev,
 | 
			
		|||
                                  SANE_Bool on, SANE_Bool tpa )
 | 
			
		||||
{
 | 
			
		||||
	SANE_Byte reg, msk;
 | 
			
		||||
	pDCapsDef sc = &dev->usbDev.Caps;
 | 
			
		||||
	pDCapsDef sc   = &dev->usbDev.Caps;
 | 
			
		||||
	u_char   *regs = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	if( tpa )
 | 
			
		||||
		usb_GetLampRegAndMask( _GET_TPALAMP(sc->lamp), ®, &msk );
 | 
			
		||||
| 
						 | 
				
			
			@ -1005,13 +1009,13 @@ static SANE_Bool usb_switchLampX( Plustek_Device *dev,
 | 
			
		|||
	DBG( _DBG_INFO, "usb_switchLampX(ON=%u,TPA=%u)\n", on, tpa );
 | 
			
		||||
 | 
			
		||||
	if( on )
 | 
			
		||||
		a_bRegs[reg] |= msk;
 | 
			
		||||
		regs[reg] |= msk;
 | 
			
		||||
	else
 | 
			
		||||
		a_bRegs[reg] &= ~msk;
 | 
			
		||||
		regs[reg] &= ~msk;
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO, "Switch Lamp: %u, regs[0x%02x] = 0x%02x\n",
 | 
			
		||||
	                on, reg, a_bRegs[reg] );
 | 
			
		||||
	usbio_WriteReg( dev->fd, reg, a_bRegs[reg] );
 | 
			
		||||
	                on, reg, regs[reg] );
 | 
			
		||||
	usbio_WriteReg( dev->fd, reg, regs[reg] );
 | 
			
		||||
	return SANE_TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1040,14 +1044,14 @@ static void usb_LedOn( Plustek_Device *dev, SANE_Bool fOn )
 | 
			
		|||
	if( dev->usbDev.HwSetting.motorModel != MODEL_HuaLien )
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	value = a_bRegs[0x0d];
 | 
			
		||||
	value = dev->usbDev.a_bRegs[0x0d];
 | 
			
		||||
 | 
			
		||||
	if( fOn )
 | 
			
		||||
		value |= 0x10;
 | 
			
		||||
	else
 | 
			
		||||
		value &= ~0x10;
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x0d] = value;
 | 
			
		||||
	dev->usbDev.a_bRegs[0x0d] = value;
 | 
			
		||||
	usbio_WriteReg( dev->fd, 0x0d, value );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1056,25 +1060,26 @@ static void usb_LedOn( Plustek_Device *dev, SANE_Bool fOn )
 | 
			
		|||
 */
 | 
			
		||||
static void usb_FillLampRegs( Plustek_Device *dev )
 | 
			
		||||
{
 | 
			
		||||
	pHWDef hw = &dev->usbDev.HwSetting;
 | 
			
		||||
	pHWDef  hw   = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char *regs = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x2a] = _HIBYTE( hw->wGreenPWMDutyCycleLow );
 | 
			
		||||
	a_bRegs[0x2b] = _LOBYTE( hw->wGreenPWMDutyCycleLow );
 | 
			
		||||
	regs[0x2a] = _HIBYTE( hw->wGreenPWMDutyCycleLow );
 | 
			
		||||
	regs[0x2b] = _LOBYTE( hw->wGreenPWMDutyCycleLow );
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x2c] = _HIBYTE( hw->red_lamp_on );
 | 
			
		||||
	a_bRegs[0x2d] = _LOBYTE( hw->red_lamp_on );
 | 
			
		||||
	a_bRegs[0x2e] = _HIBYTE( hw->red_lamp_off);
 | 
			
		||||
	a_bRegs[0x2f] = _LOBYTE( hw->red_lamp_off);
 | 
			
		||||
	regs[0x2c] = _HIBYTE( hw->red_lamp_on );
 | 
			
		||||
	regs[0x2d] = _LOBYTE( hw->red_lamp_on );
 | 
			
		||||
	regs[0x2e] = _HIBYTE( hw->red_lamp_off);
 | 
			
		||||
	regs[0x2f] = _LOBYTE( hw->red_lamp_off);
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x30] = _HIBYTE( hw->green_lamp_on );
 | 
			
		||||
	a_bRegs[0x31] = _LOBYTE( hw->green_lamp_on );
 | 
			
		||||
	a_bRegs[0x32] = _HIBYTE( hw->green_lamp_off);
 | 
			
		||||
	a_bRegs[0x33] = _LOBYTE( hw->green_lamp_off);
 | 
			
		||||
	regs[0x30] = _HIBYTE( hw->green_lamp_on );
 | 
			
		||||
	regs[0x31] = _LOBYTE( hw->green_lamp_on );
 | 
			
		||||
	regs[0x32] = _HIBYTE( hw->green_lamp_off);
 | 
			
		||||
	regs[0x33] = _LOBYTE( hw->green_lamp_off);
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x34] = _HIBYTE( hw->blue_lamp_on );
 | 
			
		||||
	a_bRegs[0x35] = _LOBYTE( hw->blue_lamp_on );
 | 
			
		||||
	a_bRegs[0x36] = _HIBYTE( hw->blue_lamp_off);
 | 
			
		||||
	a_bRegs[0x37] = _LOBYTE( hw->blue_lamp_off);
 | 
			
		||||
	regs[0x34] = _HIBYTE( hw->blue_lamp_on );
 | 
			
		||||
	regs[0x35] = _LOBYTE( hw->blue_lamp_on );
 | 
			
		||||
	regs[0x36] = _HIBYTE( hw->blue_lamp_off);
 | 
			
		||||
	regs[0x37] = _LOBYTE( hw->blue_lamp_off);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** usb_LampOn
 | 
			
		||||
| 
						 | 
				
			
			@ -1085,6 +1090,7 @@ static SANE_Bool usb_LampOn( Plustek_Device *dev,
 | 
			
		|||
	pDCapsDef      sc          = &dev->usbDev.Caps;
 | 
			
		||||
	pScanDef       scanning    = &dev->scanning;
 | 
			
		||||
	pHWDef         hw          = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char        *regs        = dev->usbDev.a_bRegs;
 | 
			
		||||
	int            iLampStatus = usb_GetLampStatus( dev );
 | 
			
		||||
	int            lampId      = -1;
 | 
			
		||||
	struct timeval t;
 | 
			
		||||
| 
						 | 
				
			
			@ -1123,20 +1129,20 @@ static SANE_Bool usb_LampOn( Plustek_Device *dev,
 | 
			
		|||
					usb_switchLampX( dev, SANE_FALSE, SANE_TRUE );
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			memset( &a_bRegs[0x29], 0, (0x37-0x29+1));
 | 
			
		||||
			memset( ®s[0x29], 0, (0x37-0x29+1));
 | 
			
		||||
			
 | 
			
		||||
			a_bRegs[0x29] = hw->bReg_0x29;
 | 
			
		||||
			regs[0x29] = hw->bReg_0x29;
 | 
			
		||||
 | 
			
		||||
			if( !usb_switchLamp(dev, SANE_TRUE )) {
 | 
			
		||||
 | 
			
		||||
				if( lampId == DEV_LampReflection ) {
 | 
			
		||||
					a_bRegs[0x2e] = 16383 / 256;
 | 
			
		||||
					a_bRegs[0x2f] = 16383 % 256;
 | 
			
		||||
					regs[0x2e] = 16383 / 256;
 | 
			
		||||
					regs[0x2f] = 16383 % 256;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if( lampId == DEV_LampTPA ) {
 | 
			
		||||
					a_bRegs[0x36] = 16383 / 256;
 | 
			
		||||
					a_bRegs[0x37] = 16383 % 256;
 | 
			
		||||
					regs[0x36] = 16383 / 256;
 | 
			
		||||
					regs[0x37] = 16383 % 256;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1144,7 +1150,7 @@ static SANE_Bool usb_LampOn( Plustek_Device *dev,
 | 
			
		|||
				usb_FillLampRegs( dev );
 | 
			
		||||
 | 
			
		||||
			sanei_lm983x_write( dev->fd, 0x29,
 | 
			
		||||
			                    &a_bRegs[0x29], 0x37-0x29+1, SANE_TRUE );
 | 
			
		||||
			                    ®s[0x29], 0x37-0x29+1, SANE_TRUE );
 | 
			
		||||
			if( lampId != dev->usbDev.currentLamp ) {
 | 
			
		||||
			
 | 
			
		||||
				dev->usbDev.currentLamp = lampId;
 | 
			
		||||
| 
						 | 
				
			
			@ -1166,17 +1172,17 @@ static SANE_Bool usb_LampOn( Plustek_Device *dev,
 | 
			
		|||
 | 
			
		||||
			DBG( _DBG_INFO, "Switching Lamp off\n" );
 | 
			
		||||
		
 | 
			
		||||
			memset( &a_bRegs[0x29], 0, 0x37-0x29+1 );
 | 
			
		||||
			memset( ®s[0x29], 0, 0x37-0x29+1 );
 | 
			
		||||
			if( !usb_switchLamp(dev, SANE_FALSE )) {
 | 
			
		||||
			
 | 
			
		||||
				if( iStatusChange & DEV_LampReflection ) {
 | 
			
		||||
					a_bRegs[0x2e] = 16383 / 256;
 | 
			
		||||
					a_bRegs[0x2f] = 16383 % 256;
 | 
			
		||||
					regs[0x2e] = 16383 / 256;
 | 
			
		||||
					regs[0x2f] = 16383 % 256;
 | 
			
		||||
				}
 | 
			
		||||
    	
 | 
			
		||||
				if( iStatusChange & DEV_LampTPA ) {
 | 
			
		||||
					a_bRegs[0x36] = 16383 / 256;
 | 
			
		||||
					a_bRegs[0x37] = 16383 % 256;
 | 
			
		||||
					regs[0x36] = 16383 / 256;
 | 
			
		||||
					regs[0x37] = 16383 % 256;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1184,7 +1190,7 @@ static SANE_Bool usb_LampOn( Plustek_Device *dev,
 | 
			
		|||
				usb_FillLampRegs( dev );
 | 
			
		||||
 | 
			
		||||
			sanei_lm983x_write( dev->fd, 0x29,
 | 
			
		||||
			                    &a_bRegs[0x29], 0x37-0x29+1, SANE_TRUE );
 | 
			
		||||
			                    ®s[0x29], 0x37-0x29+1, SANE_TRUE );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if( usb_GetLampStatus(dev))
 | 
			
		||||
| 
						 | 
				
			
			@ -1217,40 +1223,41 @@ static void usb_ResetRegisters( Plustek_Device *dev )
 | 
			
		|||
{
 | 
			
		||||
	int linend;
 | 
			
		||||
 | 
			
		||||
	pHWDef hw = &dev->usbDev.HwSetting;
 | 
			
		||||
	pHWDef  hw   = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char *regs = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO, "RESETTING REGISTERS(%i)\n", dev->initialized );
 | 
			
		||||
	memset( a_bRegs, 0, sizeof(a_bRegs));
 | 
			
		||||
	DBG( _DBG_INFO, "RESETTING REGISTERS(%i) - 0x%02x\n", dev->initialized,sizeof(dev->usbDev.a_bRegs));
 | 
			
		||||
	memset( regs, 0, sizeof(dev->usbDev.a_bRegs));
 | 
			
		||||
 | 
			
		||||
	memcpy( a_bRegs+0x0b, &hw->bSensorConfiguration, 4 );
 | 
			
		||||
	memcpy( a_bRegs+0x0f, &hw->bReg_0x0f_Color, 10 );
 | 
			
		||||
	a_bRegs[0x1a] = _HIBYTE( hw->StepperPhaseCorrection );
 | 
			
		||||
	a_bRegs[0x1b] = _LOBYTE( hw->StepperPhaseCorrection );
 | 
			
		||||
	memcpy( regs+0x0b, &hw->bSensorConfiguration, 4 );
 | 
			
		||||
	memcpy( regs+0x0f, &hw->bReg_0x0f_Color, 10 );
 | 
			
		||||
	regs[0x1a] = _HIBYTE( hw->StepperPhaseCorrection );
 | 
			
		||||
	regs[0x1b] = _LOBYTE( hw->StepperPhaseCorrection );
 | 
			
		||||
#if 0
 | 
			
		||||
	a_bRegs[0x1e] = _HIBYTE( hw->wActivePixelsStart );
 | 
			
		||||
	a_bRegs[0x1f] = _LOBYTE( hw->wActivePixelsStart );
 | 
			
		||||
	regs[0x1e] = _HIBYTE( hw->wActivePixelsStart );
 | 
			
		||||
	regs[0x1f] = _LOBYTE( hw->wActivePixelsStart );
 | 
			
		||||
#endif
 | 
			
		||||
	a_bRegs[0x20] = _HIBYTE( hw->wLineEnd );
 | 
			
		||||
	a_bRegs[0x21] = _LOBYTE( hw->wLineEnd );
 | 
			
		||||
	regs[0x20] = _HIBYTE( hw->wLineEnd );
 | 
			
		||||
	regs[0x21] = _LOBYTE( hw->wLineEnd );
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x22] = _HIBYTE( hw->bOpticBlackStart );
 | 
			
		||||
	a_bRegs[0x22] = _LOBYTE( hw->bOpticBlackStart );
 | 
			
		||||
	regs[0x22] = _HIBYTE( hw->bOpticBlackStart );
 | 
			
		||||
	regs[0x22] = _LOBYTE( hw->bOpticBlackStart );
 | 
			
		||||
 | 
			
		||||
	linend = hw->bOpticBlackStart + hw->wLineEnd;
 | 
			
		||||
	if( linend < (hw->wLineEnd-20))
 | 
			
		||||
		linend = hw->wLineEnd-20;
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x24] = _HIBYTE( linend );
 | 
			
		||||
	a_bRegs[0x25] = _LOBYTE( linend );
 | 
			
		||||
	regs[0x24] = _HIBYTE( linend );
 | 
			
		||||
	regs[0x25] = _LOBYTE( linend );
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x2a] = _HIBYTE( hw->wGreenPWMDutyCycleHigh );
 | 
			
		||||
	a_bRegs[0x2b] = _LOBYTE( hw->wGreenPWMDutyCycleHigh );
 | 
			
		||||
	regs[0x2a] = _HIBYTE( hw->wGreenPWMDutyCycleHigh );
 | 
			
		||||
	regs[0x2b] = _LOBYTE( hw->wGreenPWMDutyCycleHigh );
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x45] = hw->bReg_0x45;
 | 
			
		||||
	a_bRegs[0x4c] = _HIBYTE( hw->wStepsAfterPaperSensor2 );
 | 
			
		||||
	a_bRegs[0x4d] = _LOBYTE( hw->wStepsAfterPaperSensor2 );
 | 
			
		||||
	a_bRegs[0x50] = hw->bStepsToReverse;
 | 
			
		||||
	a_bRegs[0x51] = hw->bReg_0x51;
 | 
			
		||||
	regs[0x45] = hw->bReg_0x45;
 | 
			
		||||
	regs[0x4c] = _HIBYTE( hw->wStepsAfterPaperSensor2 );
 | 
			
		||||
	regs[0x4d] = _LOBYTE( hw->wStepsAfterPaperSensor2 );
 | 
			
		||||
	regs[0x50] = hw->bStepsToReverse;
 | 
			
		||||
	regs[0x51] = hw->bReg_0x51;
 | 
			
		||||
 | 
			
		||||
	/* if already initialized, we ignore the MISC I/O settings as
 | 
			
		||||
	 * they are used to determine the current lamp settings...
 | 
			
		||||
| 
						 | 
				
			
			@ -1258,19 +1265,19 @@ static void usb_ResetRegisters( Plustek_Device *dev )
 | 
			
		|||
	if( dev->initialized >= 0 ) {
 | 
			
		||||
 | 
			
		||||
		DBG( _DBG_INFO2, "USING MISC I/O settings\n" );
 | 
			
		||||
		memcpy( a_bRegs+0x54, &hw->bReg_0x54, 0x58 - 0x54 + 1 );
 | 
			
		||||
		a_bRegs[0x5c] = hw->bReg_0x5c;
 | 
			
		||||
		a_bRegs[0x5d] = hw->bReg_0x5d;
 | 
			
		||||
		a_bRegs[0x5e] = hw->bReg_0x5e;
 | 
			
		||||
		sanei_lm983x_read( dev->fd, 0x59, &a_bRegs[0x59], 3, SANE_TRUE );
 | 
			
		||||
		memcpy( regs+0x54, &hw->bReg_0x54, 0x58 - 0x54 + 1 );
 | 
			
		||||
		regs[0x5c] = hw->bReg_0x5c;
 | 
			
		||||
		regs[0x5d] = hw->bReg_0x5d;
 | 
			
		||||
		regs[0x5e] = hw->bReg_0x5e;
 | 
			
		||||
		sanei_lm983x_read( dev->fd, 0x59, ®s[0x59], 3, SANE_TRUE );
 | 
			
		||||
	} else {
 | 
			
		||||
 | 
			
		||||
		DBG( _DBG_INFO2, "SETTING THE MISC I/Os\n" );
 | 
			
		||||
		memcpy( a_bRegs+0x54, &hw->bReg_0x54, 0x5e - 0x54 + 1 );
 | 
			
		||||
		sanei_lm983x_write( dev->fd, 0x59, &a_bRegs[0x59], 3, SANE_TRUE );
 | 
			
		||||
		memcpy( regs+0x54, &hw->bReg_0x54, 0x5e - 0x54 + 1 );
 | 
			
		||||
		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",
 | 
			
		||||
	                        a_bRegs[0x59], a_bRegs[0x5a], a_bRegs[0x5b] );
 | 
			
		||||
	                        regs[0x59], regs[0x5a], regs[0x5b] );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** usb_ModuleStatus
 | 
			
		||||
| 
						 | 
				
			
			@ -1304,7 +1311,7 @@ static SANE_Bool usb_ModuleStatus( Plustek_Device *dev )
 | 
			
		|||
			usbio_ReadReg( dev->fd, 2, &value );
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		usb_MotorOn( dev->fd, SANE_FALSE );
 | 
			
		||||
		usb_MotorOn( dev, SANE_FALSE );
 | 
			
		||||
		return SANE_TRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,6 +28,7 @@
 | 
			
		|||
 *          usb_ColorScaleGray16()
 | 
			
		||||
 *        - added usb_BWScaleFromColor() and usb_BWDuplicateFromColor
 | 
			
		||||
 *        - cleanup
 | 
			
		||||
 * - 0.49 - a_bRegs is now part of the device structure
 | 
			
		||||
 * .
 | 
			
		||||
 * <hr>
 | 
			
		||||
 * This file is part of the SANE package.
 | 
			
		||||
| 
						 | 
				
			
			@ -1633,7 +1634,7 @@ static SANE_Int usb_ReadData( Plustek_Device *dev )
 | 
			
		|||
 | 
			
		||||
	DBG( _DBG_READ, "usb_ReadData()\n" );
 | 
			
		||||
 | 
			
		||||
	pl = a_bRegs[0x4e] * hw->wDRAMSize/128;
 | 
			
		||||
	pl = dev->usbDev.a_bRegs[0x4e] * hw->wDRAMSize/128;
 | 
			
		||||
 | 
			
		||||
	while( scan->sParam.Size.dwTotalBytes ) {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1651,13 +1652,13 @@ static SANE_Int usb_ReadData( Plustek_Device *dev )
 | 
			
		|||
 | 
			
		||||
		if(!scan->sParam.Size.dwTotalBytes && dw < (pl * 1024))
 | 
			
		||||
		{
 | 
			
		||||
			if(!(a_bRegs[0x4e] = (u_char)ceil((double)dw /
 | 
			
		||||
			if(!(dev->usbDev.a_bRegs[0x4e] = (u_char)ceil((double)dw /
 | 
			
		||||
			                                         (4.0 * hw->wDRAMSize)))) {
 | 
			
		||||
				a_bRegs[0x4e] = 1;
 | 
			
		||||
				dev->usbDev.a_bRegs[0x4e] = 1;
 | 
			
		||||
			}
 | 
			
		||||
			a_bRegs[0x4f] = 0;
 | 
			
		||||
			dev->usbDev.a_bRegs[0x4f] = 0;
 | 
			
		||||
 | 
			
		||||
			sanei_lm983x_write( dev->fd, 0x4e, &a_bRegs[0x4e], 2, SANE_TRUE );
 | 
			
		||||
			sanei_lm983x_write( dev->fd, 0x4e, &dev->usbDev.a_bRegs[0x4e], 2, SANE_TRUE );
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		while( scan->bLinesToSkip ) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,6 +22,7 @@
 | 
			
		|||
 * - 0.46 - disabled reset prior to the detection of Merlin
 | 
			
		||||
 * - 0.47 - no changes
 | 
			
		||||
 * - 0.48 - cleanup
 | 
			
		||||
 * - 0.49 - no changes
 | 
			
		||||
 * .
 | 
			
		||||
 * <hr>
 | 
			
		||||
 * This file is part of the SANE package.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,7 @@
 | 
			
		|||
 * - 0.46 - no changes
 | 
			
		||||
 * - 0.47 - cleanup work
 | 
			
		||||
 * - 0.48 - added support for binary from color scans
 | 
			
		||||
 * - 0.49 - no changes
 | 
			
		||||
 * .
 | 
			
		||||
 * <hr>
 | 
			
		||||
 * This file is part of the SANE package.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,6 +24,7 @@
 | 
			
		|||
 * - 0.46 - fixed problem in usb_SetScanParameters()
 | 
			
		||||
 * - 0.47 - no changes
 | 
			
		||||
 * - 0.48 - minor fixes
 | 
			
		||||
 * - 0.49 - a_bRegs is now part of the device structure
 | 
			
		||||
 * .
 | 
			
		||||
 * <hr>
 | 
			
		||||
 * This file is part of the SANE package.
 | 
			
		||||
| 
						 | 
				
			
			@ -131,6 +132,7 @@ static u_short usb_SetAsicDpiX( Plustek_Device *dev, u_short xdpi )
 | 
			
		|||
	u_short   res;
 | 
			
		||||
    pScanDef  scanning = &dev->scanning;
 | 
			
		||||
	pDCapsDef scaps    = &dev->usbDev.Caps;
 | 
			
		||||
	u_char   *regs     = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
     * limit xdpi to lower value for certain devices...
 | 
			
		||||
| 
						 | 
				
			
			@ -148,47 +150,47 @@ static u_short usb_SetAsicDpiX( Plustek_Device *dev, u_short xdpi )
 | 
			
		|||
	if (m_dHDPIDivider < 1.5)
 | 
			
		||||
	{
 | 
			
		||||
		m_dHDPIDivider = 1.0;
 | 
			
		||||
		a_bRegs[0x09]  = 0;
 | 
			
		||||
		regs[0x09]  = 0;
 | 
			
		||||
	}
 | 
			
		||||
	else if (m_dHDPIDivider < 2.0)
 | 
			
		||||
	{
 | 
			
		||||
		m_dHDPIDivider = 1.5;
 | 
			
		||||
		a_bRegs[0x09]  = 1;
 | 
			
		||||
		regs[0x09]  = 1;
 | 
			
		||||
	}
 | 
			
		||||
	else if (m_dHDPIDivider < 3.0)
 | 
			
		||||
	{
 | 
			
		||||
		m_dHDPIDivider = 2.0;
 | 
			
		||||
		a_bRegs[0x09]  = 2;
 | 
			
		||||
		regs[0x09]  = 2;
 | 
			
		||||
	}
 | 
			
		||||
	else if (m_dHDPIDivider < 4.0)
 | 
			
		||||
	{
 | 
			
		||||
		m_dHDPIDivider = 3.0;
 | 
			
		||||
		a_bRegs[0x09]  = 3;
 | 
			
		||||
		regs[0x09]  = 3;
 | 
			
		||||
	}
 | 
			
		||||
	else if (m_dHDPIDivider < 6.0)
 | 
			
		||||
	{
 | 
			
		||||
		m_dHDPIDivider = 4.0;
 | 
			
		||||
		a_bRegs[0x09]  = 4;
 | 
			
		||||
		regs[0x09]  = 4;
 | 
			
		||||
	}
 | 
			
		||||
	else if (m_dHDPIDivider < 8.0)
 | 
			
		||||
	{
 | 
			
		||||
		m_dHDPIDivider = 6.0;
 | 
			
		||||
		a_bRegs[0x09]  = 5;
 | 
			
		||||
		regs[0x09]  = 5;
 | 
			
		||||
	}
 | 
			
		||||
	else if (m_dHDPIDivider < 12.0)
 | 
			
		||||
	{
 | 
			
		||||
		m_dHDPIDivider = 8.0;
 | 
			
		||||
		a_bRegs[0x09]  = 6;
 | 
			
		||||
		regs[0x09]  = 6;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		m_dHDPIDivider = 12.0;
 | 
			
		||||
		a_bRegs[0x09]  = 7;
 | 
			
		||||
		regs[0x09]  = 7;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* adjust, if any turbo/preview mode is set, should be 0 here... */
 | 
			
		||||
	if( a_bRegs[0x0a] )
 | 
			
		||||
		a_bRegs[0x09] -= ((a_bRegs[0x0a] >> 2) + 2);
 | 
			
		||||
	if( regs[0x0a] )
 | 
			
		||||
		regs[0x09] -= ((regs[0x0a] >> 2) + 2);
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO2, "* HDPI: %.3f\n", m_dHDPIDivider );
 | 
			
		||||
	res = (u_short)((double)scaps->OpticDpi.x / m_dHDPIDivider);
 | 
			
		||||
| 
						 | 
				
			
			@ -258,7 +260,8 @@ static u_short usb_SetAsicDpiY( Plustek_Device *dev, u_short ydpi )
 | 
			
		|||
 */
 | 
			
		||||
static void usb_SetColorAndBits( Plustek_Device *dev, pScanParam pParam )
 | 
			
		||||
{
 | 
			
		||||
	pHWDef hw = &dev->usbDev.HwSetting;
 | 
			
		||||
	pHWDef    hw   = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char   *regs = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
     * Set pixel packing, data mode and AFE operation
 | 
			
		||||
| 
						 | 
				
			
			@ -266,38 +269,38 @@ static void usb_SetColorAndBits( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
	switch( pParam->bDataType ) {
 | 
			
		||||
		case SCANDATATYPE_Color:
 | 
			
		||||
			m_bCM = 3;
 | 
			
		||||
			a_bRegs[0x26] = hw->bReg_0x26 & 0x7;
 | 
			
		||||
			regs[0x26] = hw->bReg_0x26 & 0x7;
 | 
			
		||||
 | 
			
		||||
			/* if set to one channel color, we select the blue channel
 | 
			
		||||
             * as input source, this is the default, but I don't know
 | 
			
		||||
             * what happens, if we deselect this
 | 
			
		||||
             */
 | 
			
		||||
			if( a_bRegs[0x26] & _ONE_CH_COLOR )
 | 
			
		||||
				a_bRegs[0x26] |= (_BLUE_CH | 0x01);
 | 
			
		||||
			if( regs[0x26] & _ONE_CH_COLOR )
 | 
			
		||||
				regs[0x26] |= (_BLUE_CH | 0x01);
 | 
			
		||||
 | 
			
		||||
			memcpy( &a_bRegs[0x0f], hw->bReg_0x0f_Color, 10 );
 | 
			
		||||
			memcpy( ®s[0x0f], hw->bReg_0x0f_Color, 10 );
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case SCANDATATYPE_Gray:
 | 
			
		||||
			m_bCM = 1;
 | 
			
		||||
			a_bRegs[0x26] = (hw->bReg_0x26 & 0x18) | 0x04;
 | 
			
		||||
			memcpy( &a_bRegs[0x0f], hw->bReg_0x0f_Mono, 10 );
 | 
			
		||||
			regs[0x26] = (hw->bReg_0x26 & 0x18) | 0x04;
 | 
			
		||||
			memcpy( ®s[0x0f], hw->bReg_0x0f_Mono, 10 );
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case SCANDATATYPE_BW:
 | 
			
		||||
			m_bCM = 1;
 | 
			
		||||
			a_bRegs[0x26] = (hw->bReg_0x26 & 0x18) | 0x04;
 | 
			
		||||
			memcpy( &a_bRegs[0x0f], hw->bReg_0x0f_Mono, 10 );
 | 
			
		||||
			regs[0x26] = (hw->bReg_0x26 & 0x18) | 0x04;
 | 
			
		||||
			memcpy( ®s[0x0f], hw->bReg_0x0f_Mono, 10 );
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
			
 | 
			
		||||
	a_bRegs[0x27] = hw->bReg_0x27;
 | 
			
		||||
	regs[0x27] = hw->bReg_0x27;
 | 
			
		||||
 | 
			
		||||
	if( pParam->bBitDepth > 8 ) {
 | 
			
		||||
		a_bRegs[0x09] |= 0x20;         /* 14/16bit image data */
 | 
			
		||||
		regs[0x09] |= 0x20;         /* 14/16bit image data */
 | 
			
		||||
 | 
			
		||||
	} else if( pParam->bBitDepth == 8 ) {
 | 
			
		||||
		a_bRegs[0x09] |= 0x18;        /* 8bits/per pixel */
 | 
			
		||||
		regs[0x09] |= 0x18;        /* 8bits/per pixel */
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -319,6 +322,7 @@ static void usb_GetScanRect( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
 | 
			
		||||
	pDCapsDef sCaps = &dev->usbDev.Caps;
 | 
			
		||||
	pHWDef    hw    = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char   *regs  = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	/* Convert pixels to physical dpi based */
 | 
			
		||||
	pParam->Size.dwValidPixels = pParam->Size.dwPixels *
 | 
			
		||||
| 
						 | 
				
			
			@ -402,12 +406,12 @@ static void usb_GetScanRect( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
		                                           wDataPixelStart, wLineEnd );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x22] = _HIBYTE( wDataPixelStart );
 | 
			
		||||
	a_bRegs[0x23] = _LOBYTE( wDataPixelStart );
 | 
			
		||||
	regs[0x22] = _HIBYTE( wDataPixelStart );
 | 
			
		||||
	regs[0x23] = _LOBYTE( wDataPixelStart );
 | 
			
		||||
 | 
			
		||||
	/* should match: wLineEnd-wDataPixelStart%(m_dHDPIDivider*2) = 0!! */
 | 
			
		||||
	a_bRegs[0x24] = _HIBYTE( wLineEnd );
 | 
			
		||||
	a_bRegs[0x25] = _LOBYTE( wLineEnd );
 | 
			
		||||
	regs[0x24] = _HIBYTE( wLineEnd );
 | 
			
		||||
	regs[0x25] = _LOBYTE( wLineEnd );
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO2, ">> End-Start=%u, HDPI=%.2f\n",
 | 
			
		||||
	                                 wLineEnd-wDataPixelStart, m_dHDPIDivider);
 | 
			
		||||
| 
						 | 
				
			
			@ -475,8 +479,8 @@ static void usb_GetScanRect( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
 | 
			
		||||
	DBG(_DBG_INFO2,"* Full Steps to Skip at Start = 0x%04x\n",pParam->Origin.y);
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x4a] = _HIBYTE( pParam->Origin.y );
 | 
			
		||||
	a_bRegs[0x4b] = _LOBYTE( pParam->Origin.y );
 | 
			
		||||
	regs[0x4a] = _HIBYTE( pParam->Origin.y );
 | 
			
		||||
	regs[0x4b] = _LOBYTE( pParam->Origin.y );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** preset scan stepsize and fastfeed stepsize
 | 
			
		||||
| 
						 | 
				
			
			@ -486,14 +490,15 @@ static void usb_PresetStepSize( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
	u_short ssize;
 | 
			
		||||
	double  mclkdiv = pParam->dMCLK;
 | 
			
		||||
	pHWDef  hw      = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char *regs    = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	ssize = (u_short)((double)dwCrystalFrequency / ( mclkdiv * 8.0 *
 | 
			
		||||
            (double)m_bCM * hw->dMaxMotorSpeed * 4.0 * (double)hw->wMotorDpi));
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x46] = _HIBYTE( ssize );
 | 
			
		||||
	a_bRegs[0x47] = _LOBYTE( ssize );
 | 
			
		||||
	a_bRegs[0x48] = _HIBYTE( ssize );
 | 
			
		||||
	a_bRegs[0x49] = _LOBYTE( ssize );
 | 
			
		||||
	regs[0x46] = _HIBYTE( ssize );
 | 
			
		||||
	regs[0x47] = _LOBYTE( ssize );
 | 
			
		||||
	regs[0x48] = _HIBYTE( ssize );
 | 
			
		||||
	regs[0x49] = _LOBYTE( ssize );
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO2, "* StepSize(Preset) = %u (0x%04x)\n", ssize, ssize );
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -508,23 +513,24 @@ static void usb_GetDPD( Plustek_Device *dev  )
 | 
			
		|||
	int    dpd;	    /* calculated dpd reg 52:53               */
 | 
			
		||||
	int    st;		/* step size reg 46:47                    */
 | 
			
		||||
 | 
			
		||||
	pHWDef hw = &dev->usbDev.HwSetting;
 | 
			
		||||
	pHWDef  hw    = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char *regs  = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	qtcnt = (a_bRegs [0x51] & 0x30) >> 4;	/* quarter speed count */
 | 
			
		||||
	hfcnt = (a_bRegs [0x51] & 0xc0) >> 6;	/* half speed count    */
 | 
			
		||||
	qtcnt = (regs[0x51] & 0x30) >> 4;	/* quarter speed count */
 | 
			
		||||
	hfcnt = (regs[0x51] & 0xc0) >> 6;	/* half speed count    */
 | 
			
		||||
 | 
			
		||||
	if( _LM9831 == hw->chip )
 | 
			
		||||
		strev = a_bRegs [0x50] & 0x3f;		/* steps to reverse */
 | 
			
		||||
		strev = regs[0x50] & 0x3f;		/* steps to reverse */
 | 
			
		||||
	else /* LM9832/3 */
 | 
			
		||||
	{
 | 
			
		||||
		if (qtcnt == 3)
 | 
			
		||||
			qtcnt = 8;
 | 
			
		||||
		if (hfcnt == 3)
 | 
			
		||||
			hfcnt = 8;
 | 
			
		||||
		strev = a_bRegs[0x50]; /* steps to reverse */
 | 
			
		||||
		strev = regs[0x50]; /* steps to reverse */
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	st = a_bRegs[0x46] * 256 + a_bRegs[0x47]; /* scan step size */
 | 
			
		||||
	st = regs[0x46] * 256 + regs[0x47]; /* scan step size */
 | 
			
		||||
 | 
			
		||||
	if (m_wLineLength == 0)
 | 
			
		||||
		dpd = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -541,9 +547,9 @@ static void usb_GetDPD( Plustek_Device *dev  )
 | 
			
		|||
	DBG( _DBG_INFO2, "* llen=%u, lineRateColor=%u, qtcnt=%u, hfcnt=%u\n",
 | 
			
		||||
						  m_wLineLength, m_bLineRateColor, qtcnt, hfcnt );
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x51] |= (u_char)((dpd >> 16) & 0x03);
 | 
			
		||||
	a_bRegs[0x52] = (u_char)(dpd >> 8);
 | 
			
		||||
	a_bRegs[0x53] = (u_char)(dpd & 0xFF);
 | 
			
		||||
	regs[0x51] |= (u_char)((dpd >> 16) & 0x03);
 | 
			
		||||
	regs[0x52] = (u_char)(dpd >> 8);
 | 
			
		||||
	regs[0x53] = (u_char)(dpd & 0xFF);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Plusteks' poor-man MCLK calculation...
 | 
			
		||||
| 
						 | 
				
			
			@ -557,6 +563,7 @@ static double usb_GetMCLKDivider( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
 | 
			
		||||
	pDCapsDef sCaps = &dev->usbDev.Caps;
 | 
			
		||||
	pHWDef    hw    = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char   *regs  = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO, "usb_GetMCLKDivider()\n" );
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -584,7 +591,7 @@ static double usb_GetMCLKDivider( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
			}
 | 
			
		||||
 | 
			
		||||
			if(((hw->motorModel == MODEL_HP) && (sCaps->bCCD == kNECSLIM))/* ||
 | 
			
		||||
			 	( a_bRegs[0x26] & _ONE_CH_COLOR )*/) {
 | 
			
		||||
			 	( regs[0x26] & _ONE_CH_COLOR )*/) {
 | 
			
		||||
 | 
			
		||||
       			bMaxITA = (u_char)floor((m_dMCLKDivider + 1) / 2.0);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -599,8 +606,8 @@ static double usb_GetMCLKDivider( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
	DBG( _DBG_INFO2, "* Integration Time Adjust = %u (HDPI=%.3f,MCLKD=%.3f)\n",
 | 
			
		||||
							m_bIntTimeAdjust, m_dHDPIDivider, m_dMCLKDivider );
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x08] = (u_char)((m_dMCLKDivider - 1) * 2);
 | 
			
		||||
	a_bRegs[0x19] = m_bIntTimeAdjust;
 | 
			
		||||
	regs[0x08] = (u_char)((m_dMCLKDivider - 1) * 2);
 | 
			
		||||
	regs[0x19] = m_bIntTimeAdjust;
 | 
			
		||||
 | 
			
		||||
	if( m_bIntTimeAdjust != 0 ) {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -609,11 +616,11 @@ static double usb_GetMCLKDivider( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
		if( m_wStepSize < 2 )
 | 
			
		||||
			m_wStepSize = 2;
 | 
			
		||||
 | 
			
		||||
		a_bRegs[0x46] = _HIBYTE(m_wStepSize);
 | 
			
		||||
		a_bRegs[0x47] = _LOBYTE(m_wStepSize);
 | 
			
		||||
		regs[0x46] = _HIBYTE(m_wStepSize);
 | 
			
		||||
		regs[0x47] = _LOBYTE(m_wStepSize);
 | 
			
		||||
 | 
			
		||||
		DBG( _DBG_INFO2, "* Stepsize = %u, 0x46=0x%02x 0x47=0x%02x\n",
 | 
			
		||||
		                   m_wStepSize, a_bRegs[0x46], a_bRegs[0x47] );
 | 
			
		||||
		                   m_wStepSize, regs[0x46], regs[0x47] );
 | 
			
		||||
	    usb_GetDPD( dev );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
| 
						 | 
				
			
			@ -628,14 +635,14 @@ static double usb_GetMCLKDivider( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
	if( m_dMCLKDivider > dMaxMCLKDivider ) {
 | 
			
		||||
 | 
			
		||||
		DBG( _DBG_INFO2, "* Setting GreenPWMDutyCycleLow\n" );
 | 
			
		||||
		a_bRegs[0x2a] = _HIBYTE( hw->wGreenPWMDutyCycleLow );
 | 
			
		||||
		a_bRegs[0x2b] = _LOBYTE( hw->wGreenPWMDutyCycleLow );
 | 
			
		||||
		regs[0x2a] = _HIBYTE( hw->wGreenPWMDutyCycleLow );
 | 
			
		||||
		regs[0x2b] = _LOBYTE( hw->wGreenPWMDutyCycleLow );
 | 
			
		||||
 | 
			
		||||
	} else {
 | 
			
		||||
 | 
			
		||||
		DBG( _DBG_INFO2, "* Setting GreenPWMDutyCycleHigh\n" );
 | 
			
		||||
		a_bRegs[0x2a] = _HIBYTE( hw->wGreenPWMDutyCycleHigh );
 | 
			
		||||
		a_bRegs[0x2b] = _LOBYTE( hw->wGreenPWMDutyCycleHigh );
 | 
			
		||||
		regs[0x2a] = _HIBYTE( hw->wGreenPWMDutyCycleHigh );
 | 
			
		||||
		regs[0x2b] = _LOBYTE( hw->wGreenPWMDutyCycleHigh );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO2, "* Current MCLK Divider = %f\n", m_dMCLKDivider );
 | 
			
		||||
| 
						 | 
				
			
			@ -646,7 +653,8 @@ static double usb_GetMCLKDivider( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
 */
 | 
			
		||||
static void usb_GetStepSize( Plustek_Device *dev, pScanParam pParam )
 | 
			
		||||
{
 | 
			
		||||
	pHWDef hw = &dev->usbDev.HwSetting;
 | 
			
		||||
	pHWDef  hw   = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char *regs = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	/* Compute step size using equation 1 */
 | 
			
		||||
	if (m_bIntTimeAdjust != 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -663,11 +671,11 @@ static void usb_GetStepSize( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
 | 
			
		||||
	m_wStepSize = m_wStepSize * 298 / 297;
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x46] = _HIBYTE( m_wStepSize );
 | 
			
		||||
	a_bRegs[0x47] = _LOBYTE( m_wStepSize );
 | 
			
		||||
	regs[0x46] = _HIBYTE( m_wStepSize );
 | 
			
		||||
	regs[0x47] = _LOBYTE( m_wStepSize );
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO2, "* Stepsize = %u, 0x46=0x%02x 0x47=0x%02x\n",
 | 
			
		||||
	                  m_wStepSize, a_bRegs[0x46], a_bRegs[0x47] );
 | 
			
		||||
	                  m_wStepSize, regs[0x46], regs[0x47] );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -694,22 +702,23 @@ static void usb_GetLineLength( Plustek_Device *dev )
 | 
			
		|||
	int tradj;	/* ITA                                                   */
 | 
			
		||||
	int en_tradj;
 | 
			
		||||
 | 
			
		||||
	pHWDef hw = &dev->usbDev.HwSetting;
 | 
			
		||||
	pHWDef  hw   = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char *regs = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	tpspd = (a_bRegs[0x0a] & 0x0c) >> 2; /* turbo/preview mode speed  */
 | 
			
		||||
	tpsel = a_bRegs[0x0a] & 3; 			 /* turbo/preview mode select */
 | 
			
		||||
	tpspd = (regs[0x0a] & 0x0c) >> 2; /* turbo/preview mode speed  */
 | 
			
		||||
	tpsel = regs[0x0a] & 3; 			 /* turbo/preview mode select */
 | 
			
		||||
 | 
			
		||||
	gbnd = (a_bRegs[0x0e] & 0xf0) >> 4;	 /* TR fi1 guardband duration */
 | 
			
		||||
	dur = (a_bRegs[0x0e] & 0xf);		 /* TR pulse duration         */
 | 
			
		||||
	gbnd = (regs[0x0e] & 0xf0) >> 4;	 /* TR fi1 guardband duration */
 | 
			
		||||
	dur = (regs[0x0e] & 0xf);		 /* TR pulse duration         */
 | 
			
		||||
 | 
			
		||||
	ntr = a_bRegs[0x0d] / 128;			 /* number of tr pulses       */
 | 
			
		||||
	ntr = regs[0x0d] / 128;			 /* number of tr pulses       */
 | 
			
		||||
 | 
			
		||||
	afeop = a_bRegs[0x26] & 7;			 /* afe op - 3 channel or 1 channel */
 | 
			
		||||
	afeop = regs[0x26] & 7;			 /* afe op - 3 channel or 1 channel */
 | 
			
		||||
 | 
			
		||||
	tradj = a_bRegs[0x19] & 0x7f;		 /* integration time adjust */
 | 
			
		||||
	tradj = regs[0x19] & 0x7f;		 /* integration time adjust */
 | 
			
		||||
	en_tradj = (tradj) ? 1 : 0;
 | 
			
		||||
 | 
			
		||||
	ctmode = (a_bRegs[0x0b] >> 3) & 3;	 /* cis tr timing mode */
 | 
			
		||||
	ctmode = (regs[0x0b] >> 3) & 3;	 /* cis tr timing mode */
 | 
			
		||||
 | 
			
		||||
	m_bLineRateColor = 1;	
 | 
			
		||||
	if (afeop == 1 || afeop == 5) /* if 3 channel line or 1 channel mode b */
 | 
			
		||||
| 
						 | 
				
			
			@ -778,11 +787,12 @@ static void usb_GetLineLength( Plustek_Device *dev )
 | 
			
		|||
 */
 | 
			
		||||
static void usb_GetMotorParam( Plustek_Device *dev, pScanParam pParam )
 | 
			
		||||
{
 | 
			
		||||
	int       	 idx, i;
 | 
			
		||||
	int          idx, i;
 | 
			
		||||
	pClkMotorDef clk;
 | 
			
		||||
	pMDef     	 md;
 | 
			
		||||
	pDCapsDef 	 sCaps = &dev->usbDev.Caps;
 | 
			
		||||
	pHWDef    	 hw    = &dev->usbDev.HwSetting;
 | 
			
		||||
	pMDef        md;
 | 
			
		||||
	pDCapsDef    sCaps = &dev->usbDev.Caps;
 | 
			
		||||
	pHWDef       hw    = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char      *regs  = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	if( !_IS_PLUSTEKMOTOR(hw->motorModel)) {
 | 
			
		||||
	
 | 
			
		||||
| 
						 | 
				
			
			@ -797,22 +807,22 @@ static void usb_GetMotorParam( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
		if( idx >= _MAX_CLK )
 | 
			
		||||
			idx = _MAX_CLK - 1;
 | 
			
		||||
 | 
			
		||||
		a_bRegs[0x56] = md[idx].pwm;
 | 
			
		||||
		a_bRegs[0x57] = md[idx].pwm_duty;
 | 
			
		||||
		regs[0x56] = md[idx].pwm;
 | 
			
		||||
		regs[0x57] = md[idx].pwm_duty;
 | 
			
		||||
 | 
			
		||||
		a_bRegs[0x43] = 0;
 | 
			
		||||
		a_bRegs[0x44] = 0;
 | 
			
		||||
		regs[0x43] = 0;
 | 
			
		||||
		regs[0x44] = 0;
 | 
			
		||||
 | 
			
		||||
		if( md[idx].scan_lines_per_line > 1 ) {
 | 
			
		||||
 | 
			
		||||
			if((pParam->bBitDepth > 8) &&
 | 
			
		||||
				(pParam->bDataType == SCANDATATYPE_Color)) {
 | 
			
		||||
 | 
			
		||||
				a_bRegs[0x43] = 0xff;
 | 
			
		||||
				a_bRegs[0x44] = md[idx].scan_lines_per_line;
 | 
			
		||||
				regs[0x43] = 0xff;
 | 
			
		||||
				regs[0x44] = md[idx].scan_lines_per_line;
 | 
			
		||||
 | 
			
		||||
				DBG( _DBG_INFO2, "* Line Skipping : 0x43=0x%02x, 0x44=0x%02x\n",
 | 
			
		||||
	  											a_bRegs[0x43], a_bRegs[0x44] );
 | 
			
		||||
	  											regs[0x43], regs[0x44] );
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -826,28 +836,28 @@ static void usb_GetMotorParam( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
        	default:
 | 
			
		||||
        		if(pParam->PhyDpi.x <= 200)
 | 
			
		||||
        		{
 | 
			
		||||
        			a_bRegs[0x56] = 1;
 | 
			
		||||
        			a_bRegs[0x57] = 48;	/* 63; */
 | 
			
		||||
        			regs[0x56] = 1;
 | 
			
		||||
        			regs[0x57] = 48;	/* 63; */
 | 
			
		||||
        		}
 | 
			
		||||
        		else if(pParam->PhyDpi.x <= 300)
 | 
			
		||||
        		{
 | 
			
		||||
        			a_bRegs[0x56] = 2;	/* 8;  */
 | 
			
		||||
        			a_bRegs[0x57] = 48;	/* 56; */
 | 
			
		||||
        			regs[0x56] = 2;	/* 8;  */
 | 
			
		||||
        			regs[0x57] = 48;	/* 56; */
 | 
			
		||||
        		}
 | 
			
		||||
        		else if(pParam->PhyDpi.x <= 400)
 | 
			
		||||
        		{
 | 
			
		||||
        			a_bRegs[0x56] = 8;	
 | 
			
		||||
        			a_bRegs[0x57] = 48;	
 | 
			
		||||
        			regs[0x56] = 8;	
 | 
			
		||||
        			regs[0x57] = 48;	
 | 
			
		||||
        		}
 | 
			
		||||
        		else if(pParam->PhyDpi.x <= 600)
 | 
			
		||||
        		{
 | 
			
		||||
        			a_bRegs[0x56] = 2;	/* 10; */
 | 
			
		||||
        			a_bRegs[0x57] = 48;	/* 56; */
 | 
			
		||||
        			regs[0x56] = 2;	/* 10; */
 | 
			
		||||
        			regs[0x57] = 48;	/* 56; */
 | 
			
		||||
        		}
 | 
			
		||||
        		else /* pParam->PhyDpi.x == 1200) */
 | 
			
		||||
        		{
 | 
			
		||||
        			a_bRegs[0x56] = 1;	/* 8;  */
 | 
			
		||||
        			a_bRegs[0x57] = 48;	/* 56; */
 | 
			
		||||
        			regs[0x56] = 1;	/* 8;  */
 | 
			
		||||
        			regs[0x57] = 48;	/* 56; */
 | 
			
		||||
        		}
 | 
			
		||||
        		break;
 | 
			
		||||
        	}
 | 
			
		||||
| 
						 | 
				
			
			@ -855,25 +865,25 @@ static void usb_GetMotorParam( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
        	switch ( hw->motorModel ) {
 | 
			
		||||
 | 
			
		||||
        	case MODEL_Tokyo600:
 | 
			
		||||
        		a_bRegs[0x56] = 16;
 | 
			
		||||
        		a_bRegs[0x57] = 4;	/* 2; */
 | 
			
		||||
        		regs[0x56] = 16;
 | 
			
		||||
        		regs[0x57] = 4;	/* 2; */
 | 
			
		||||
        		break;
 | 
			
		||||
        	case MODEL_HuaLien:
 | 
			
		||||
        		{
 | 
			
		||||
        			if(pParam->PhyDpi.x <= 200)
 | 
			
		||||
        			{
 | 
			
		||||
        				a_bRegs[0x56] = 64;	/* 24; */
 | 
			
		||||
        				a_bRegs[0x57] = 4;	/* 16; */
 | 
			
		||||
        				regs[0x56] = 64;	/* 24; */
 | 
			
		||||
        				regs[0x57] = 4;	/* 16; */
 | 
			
		||||
        			}
 | 
			
		||||
        			else if(pParam->PhyDpi.x <= 300)
 | 
			
		||||
        			{
 | 
			
		||||
        				a_bRegs[0x56] = 64;	/* 16; */
 | 
			
		||||
        				a_bRegs[0x57] = 4;	/* 16; */
 | 
			
		||||
        				regs[0x56] = 64;	/* 16; */
 | 
			
		||||
        				regs[0x57] = 4;	/* 16; */
 | 
			
		||||
        			}
 | 
			
		||||
        			else if(pParam->PhyDpi.x <= 400)
 | 
			
		||||
        			{
 | 
			
		||||
        				a_bRegs[0x56] = 64;	/* 16; */
 | 
			
		||||
        				a_bRegs[0x57] = 4;	/* 16; */
 | 
			
		||||
        				regs[0x56] = 64;	/* 16; */
 | 
			
		||||
        				regs[0x57] = 4;	/* 16; */
 | 
			
		||||
        			}
 | 
			
		||||
        			else /* if(pParam->PhyDpi.x <= 600) */
 | 
			
		||||
        			{
 | 
			
		||||
| 
						 | 
				
			
			@ -881,14 +891,14 @@ static void usb_GetMotorParam( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
     #if 0
 | 
			
		||||
        				if(ScanInf.m_fADF)
 | 
			
		||||
        				{
 | 
			
		||||
        					a_bRegs[0x56] = 8;
 | 
			
		||||
        					a_bRegs[0x57] = 48;
 | 
			
		||||
        					regs[0x56] = 8;
 | 
			
		||||
        					regs[0x57] = 48;
 | 
			
		||||
        				}
 | 
			
		||||
        				else
 | 
			
		||||
     #endif
 | 
			
		||||
        				{
 | 
			
		||||
        					a_bRegs[0x56] = 64;	/* 2;  */
 | 
			
		||||
        					a_bRegs[0x57] = 4;	/* 48; */
 | 
			
		||||
        					regs[0x56] = 64;	/* 2;  */
 | 
			
		||||
        					regs[0x57] = 4;	/* 48; */
 | 
			
		||||
        				}
 | 
			
		||||
        			}
 | 
			
		||||
        		}
 | 
			
		||||
| 
						 | 
				
			
			@ -897,23 +907,23 @@ static void usb_GetMotorParam( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
        	default:
 | 
			
		||||
        		if(pParam->PhyDpi.x <= 200)
 | 
			
		||||
        		{
 | 
			
		||||
        			a_bRegs[0x56] = 24;
 | 
			
		||||
        			a_bRegs[0x57] = 16;
 | 
			
		||||
        			regs[0x56] = 24;
 | 
			
		||||
        			regs[0x57] = 16;
 | 
			
		||||
        		}
 | 
			
		||||
        		else if(pParam->PhyDpi.x <= 300)
 | 
			
		||||
        		{
 | 
			
		||||
        			a_bRegs[0x56] = 16;
 | 
			
		||||
        			a_bRegs[0x57] = 16;
 | 
			
		||||
        			regs[0x56] = 16;
 | 
			
		||||
        			regs[0x57] = 16;
 | 
			
		||||
        		}
 | 
			
		||||
        		else if(pParam->PhyDpi.x <= 400)
 | 
			
		||||
        		{
 | 
			
		||||
        			a_bRegs[0x56] = 16;
 | 
			
		||||
        			a_bRegs[0x57] = 16;
 | 
			
		||||
        			regs[0x56] = 16;
 | 
			
		||||
        			regs[0x57] = 16;
 | 
			
		||||
        		}
 | 
			
		||||
        		else /* if(pParam->PhyDpi.x <= 600) */
 | 
			
		||||
        		{
 | 
			
		||||
        			a_bRegs[0x56] = 2;
 | 
			
		||||
        			a_bRegs[0x57] = 48;
 | 
			
		||||
        			regs[0x56] = 2;
 | 
			
		||||
        			regs[0x57] = 48;
 | 
			
		||||
        		}
 | 
			
		||||
        		break;
 | 
			
		||||
        	}
 | 
			
		||||
| 
						 | 
				
			
			@ -921,15 +931,16 @@ static void usb_GetMotorParam( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
	}
 | 
			
		||||
	
 | 
			
		||||
	DBG( _DBG_INFO2, "* MOTOR-Settings: PWM=0x%02x, PWM_DUTY=0x%02x\n",
 | 
			
		||||
	                 a_bRegs[0x56], a_bRegs[0x57] );
 | 
			
		||||
	                 regs[0x56], regs[0x57] );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 */
 | 
			
		||||
static void usb_GetPauseLimit( Plustek_Device *dev, pScanParam pParam )
 | 
			
		||||
{
 | 
			
		||||
	int    coeffsize, scaler;
 | 
			
		||||
	pHWDef hw = &dev->usbDev.HwSetting;
 | 
			
		||||
	int     coeffsize, scaler;
 | 
			
		||||
	pHWDef  hw   = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char *regs = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	scaler = 1;
 | 
			
		||||
	if( hw->bReg_0x26 & _ONE_CH_COLOR ) {
 | 
			
		||||
| 
						 | 
				
			
			@ -942,7 +953,7 @@ static void usb_GetPauseLimit( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
	coeffsize = 4 + 16 + 16;	/* gamma and shading and offset */
 | 
			
		||||
 | 
			
		||||
	/* if 16 bit, then not all is used */
 | 
			
		||||
	if( a_bRegs[0x09] & 0x20 ) {
 | 
			
		||||
	if( regs[0x09] & 0x20 ) {
 | 
			
		||||
		coeffsize = 16 + 16;	/* no gamma */
 | 
			
		||||
	}
 | 
			
		||||
	coeffsize *= (2*3); /* 3 colors and 2 bytes/word */
 | 
			
		||||
| 
						 | 
				
			
			@ -956,8 +967,8 @@ static void usb_GetPauseLimit( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
	m_dwPauseLimit -= ((pParam->Size.dwPhyBytes*scaler) / 1024 + 1);
 | 
			
		||||
 | 
			
		||||
	/* If not reversing, take into account the steps to reverse */
 | 
			
		||||
	if( a_bRegs[0x50] == 0 )
 | 
			
		||||
		m_dwPauseLimit -= ((a_bRegs[0x54] & 7) *
 | 
			
		||||
	if( regs[0x50] == 0 )
 | 
			
		||||
		m_dwPauseLimit -= ((regs[0x54] & 7) *
 | 
			
		||||
							(pParam->Size.dwPhyBytes * scaler) + 1023) / 1024;
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO2, "* PL=%lu, coeffsize=%u, scaler=%u\n",
 | 
			
		||||
| 
						 | 
				
			
			@ -966,22 +977,22 @@ static void usb_GetPauseLimit( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
	m_dwPauseLimit = usb_max( usb_min(m_dwPauseLimit,
 | 
			
		||||
						(u_long)ceil(pParam->Size.dwTotalBytes / 1024.0)), 2);
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x4e] = (u_char)floor((m_dwPauseLimit*512.0)/(2.0*hw->wDRAMSize));
 | 
			
		||||
	regs[0x4e] = (u_char)floor((m_dwPauseLimit*512.0)/(2.0*hw->wDRAMSize));
 | 
			
		||||
 | 
			
		||||
	if( a_bRegs[0x4e] > 1 )	{
 | 
			
		||||
		a_bRegs[0x4e]--;
 | 
			
		||||
		if(a_bRegs[0x4e] > 1)
 | 
			
		||||
			a_bRegs[0x4e]--;
 | 
			
		||||
	if( regs[0x4e] > 1 )	{
 | 
			
		||||
		regs[0x4e]--;
 | 
			
		||||
		if(regs[0x4e] > 1)
 | 
			
		||||
			regs[0x4e]--;
 | 
			
		||||
	} else
 | 
			
		||||
		a_bRegs[0x4e] = 1;
 | 
			
		||||
		regs[0x4e] = 1;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * resume, when buffer is 2/8 kbytes full (512k/2M memory)
 | 
			
		||||
	 */
 | 
			
		||||
	a_bRegs[0x4f] = 1;
 | 
			
		||||
	regs[0x4f] = 1;
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO2, "* PauseLimit = %lu, [0x4e] = 0x%02x, [0x4f] = 0x%02x\n",
 | 
			
		||||
	                  m_dwPauseLimit, a_bRegs[0x4e], a_bRegs[0x4f] );
 | 
			
		||||
	                  m_dwPauseLimit, regs[0x4e], regs[0x4f] );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** usb_GetScanLinesAndSize
 | 
			
		||||
| 
						 | 
				
			
			@ -1018,6 +1029,7 @@ static SANE_Bool usb_SetScanParameters( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
 | 
			
		||||
	pScanParam pdParam = &dev->scanning.sParam;
 | 
			
		||||
	pHWDef     hw      = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char    *regs    = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	m_pParam = pParam;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1032,7 +1044,7 @@ static SANE_Bool usb_SetScanParameters( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
*/
 | 
			
		||||
		hw->dMaxMoveSpeed = 1.0;
 | 
			
		||||
		usb_MotorSelect( dev, SANE_TRUE );
 | 
			
		||||
		usb_MotorOn( dev->fd, SANE_TRUE );
 | 
			
		||||
		usb_MotorOn( dev, SANE_TRUE );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
| 
						 | 
				
			
			@ -1051,32 +1063,32 @@ static SANE_Bool usb_SetScanParameters( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
		if( pParam->bCalibration == PARAM_Scan ) {
 | 
			
		||||
 | 
			
		||||
			if( pdParam->bSource == SOURCE_ADF ) {
 | 
			
		||||
				a_bRegs[0x50] = 0;
 | 
			
		||||
				a_bRegs[0x51] = 0x40;
 | 
			
		||||
				regs[0x50] = 0;
 | 
			
		||||
				regs[0x51] = 0x40;
 | 
			
		||||
				if( pParam->PhyDpi.x <= 300)
 | 
			
		||||
					a_bRegs[0x54] = (a_bRegs[0x54] & ~7) | 4;	/* 3; */
 | 
			
		||||
					regs[0x54] = (regs[0x54] & ~7) | 4;	/* 3; */
 | 
			
		||||
				else
 | 
			
		||||
					a_bRegs[0x54] = (a_bRegs[0x54] & ~7) | 5;	/* 4; */
 | 
			
		||||
					regs[0x54] = (regs[0x54] & ~7) | 5;	/* 4; */
 | 
			
		||||
			} else {
 | 
			
		||||
				a_bRegs[0x50] = hw->bStepsToReverse;
 | 
			
		||||
				a_bRegs[0x51] = hw->bReg_0x51;
 | 
			
		||||
				a_bRegs[0x54] &= ~7;
 | 
			
		||||
				regs[0x50] = hw->bStepsToReverse;
 | 
			
		||||
				regs[0x51] = hw->bReg_0x51;
 | 
			
		||||
				regs[0x54] &= ~7;
 | 
			
		||||
			}
 | 
			
		||||
		} else
 | 
			
		||||
			a_bRegs[0x50] = 0;
 | 
			
		||||
			regs[0x50] = 0;
 | 
			
		||||
	} else {
 | 
			
		||||
		if( pParam->bCalibration == PARAM_Scan )
 | 
			
		||||
			a_bRegs[0x50] = hw->bStepsToReverse;
 | 
			
		||||
			regs[0x50] = hw->bStepsToReverse;
 | 
			
		||||
		else
 | 
			
		||||
			a_bRegs[0x50] = 0;
 | 
			
		||||
			regs[0x50] = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Assume we will not use ITA */
 | 
			
		||||
	a_bRegs[0x19] = m_bIntTimeAdjust = 0;
 | 
			
		||||
	regs[0x19] = m_bIntTimeAdjust = 0;
 | 
			
		||||
 | 
			
		||||
	/* Get variables from calculation algorithms */
 | 
			
		||||
	if(!(pParam->bCalibration == PARAM_Scan &&
 | 
			
		||||
         pParam->bSource == SOURCE_ADF && fLastScanIsAdf )) {
 | 
			
		||||
          pParam->bSource == SOURCE_ADF && dev->usbDev.fLastScanIsAdf )) {
 | 
			
		||||
 | 
			
		||||
		DBG( _DBG_INFO2, "* Scan calculations...\n" );
 | 
			
		||||
		usb_GetLineLength ( dev );
 | 
			
		||||
| 
						 | 
				
			
			@ -1102,13 +1114,13 @@ static SANE_Bool usb_SetScanParameters( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
	if( m_bIntTimeAdjust != 0 )
 | 
			
		||||
		m_wFastFeedStepSize /= m_bIntTimeAdjust;
 | 
			
		||||
 | 
			
		||||
	if(a_bRegs[0x0a])
 | 
			
		||||
		m_wFastFeedStepSize *= ((a_bRegs[0x0a] >> 2) + 2);
 | 
			
		||||
	a_bRegs[0x48] = _HIBYTE( m_wFastFeedStepSize );
 | 
			
		||||
	a_bRegs[0x49] = _LOBYTE( m_wFastFeedStepSize );
 | 
			
		||||
	if(regs[0x0a])
 | 
			
		||||
		m_wFastFeedStepSize *= ((regs[0x0a] >> 2) + 2);
 | 
			
		||||
	regs[0x48] = _HIBYTE( m_wFastFeedStepSize );
 | 
			
		||||
	regs[0x49] = _LOBYTE( m_wFastFeedStepSize );
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO2, "* FFStepSize = %u, [0x48] = 0x%02x, [0x49] = 0x%02x\n",
 | 
			
		||||
	                       m_wFastFeedStepSize, a_bRegs[0x48], a_bRegs[0x49] );
 | 
			
		||||
	                       m_wFastFeedStepSize, regs[0x48], regs[0x49] );
 | 
			
		||||
 | 
			
		||||
	/* Compute the number of lines to scan using actual Y resolution */
 | 
			
		||||
	usb_GetScanLinesAndSize( dev, pParam );
 | 
			
		||||
| 
						 | 
				
			
			@ -1121,17 +1133,17 @@ static SANE_Bool usb_SetScanParameters( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
	/* For ADF .... */
 | 
			
		||||
	if(pParam->bCalibration == PARAM_Scan && pParam->bSource == SOURCE_ADF)	{
 | 
			
		||||
 | 
			
		||||
		if( fLastScanIsAdf ) {
 | 
			
		||||
		if( dev->usbDev.fLastScanIsAdf ) {
 | 
			
		||||
 | 
			
		||||
			a_bRegs[0x08] = reg8;
 | 
			
		||||
			memcpy( &a_bRegs[0x38], reg38, sizeof(reg38));
 | 
			
		||||
			memcpy( &a_bRegs[0x48], reg48, sizeof(reg48));
 | 
			
		||||
			regs[0x08] = reg8;
 | 
			
		||||
			memcpy( ®s[0x38], reg38, sizeof(reg38));
 | 
			
		||||
			memcpy( ®s[0x48], reg48, sizeof(reg48));
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
			reg8 = a_bRegs[0x08];
 | 
			
		||||
			memcpy( reg38, &a_bRegs[0x38], sizeof(reg38));
 | 
			
		||||
			memcpy( reg48, &a_bRegs[0x48], sizeof(reg48));
 | 
			
		||||
			reg8 = regs[0x08];
 | 
			
		||||
			memcpy( reg38, ®s[0x38], sizeof(reg38));
 | 
			
		||||
			memcpy( reg48, ®s[0x48], sizeof(reg48));
 | 
			
		||||
		}
 | 
			
		||||
		usb_MotorSelect( dev, SANE_TRUE );
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -1148,16 +1160,16 @@ static SANE_Bool usb_SetScanParameters( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
	if( !usbio_WriteReg( dev->fd, 0x19, 6 ))
 | 
			
		||||
		return SANE_FALSE;
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x07] = 0;
 | 
			
		||||
	a_bRegs[0x28] = 0;
 | 
			
		||||
	regs[0x07] = 0;
 | 
			
		||||
	regs[0x28] = 0;
 | 
			
		||||
 | 
			
		||||
	/* set unused registers to 0 */
 | 
			
		||||
	memset( &a_bRegs[0x03], 0, 3 );
 | 
			
		||||
	memset( &a_bRegs[0x5f], 0, 0x7f-0x5f+1 );
 | 
			
		||||
	memset( ®s[0x03], 0, 3 );
 | 
			
		||||
	memset( ®s[0x5f], 0, 0x7f-0x5f+1 );
 | 
			
		||||
 | 
			
		||||
	/* set the merlin registers */
 | 
			
		||||
	_UIO(sanei_lm983x_write( dev->fd, 0x03, &a_bRegs[0x03], 3, SANE_TRUE));
 | 
			
		||||
	_UIO(sanei_lm983x_write( dev->fd, 0x08, &a_bRegs[0x08], 0x7f - 0x08+1, SANE_TRUE));
 | 
			
		||||
	_UIO(sanei_lm983x_write( dev->fd, 0x03, ®s[0x03], 3, SANE_TRUE));
 | 
			
		||||
	_UIO(sanei_lm983x_write( dev->fd, 0x08, ®s[0x08], 0x7f - 0x08+1, SANE_TRUE));
 | 
			
		||||
 | 
			
		||||
    usleep( 100 );
 | 
			
		||||
	
 | 
			
		||||
| 
						 | 
				
			
			@ -1174,8 +1186,9 @@ static SANE_Bool usb_ScanBegin( Plustek_Device *dev, SANE_Bool auto_park )
 | 
			
		|||
{
 | 
			
		||||
	u_char  value;
 | 
			
		||||
	u_short inches;
 | 
			
		||||
	pHWDef       hw = &dev->usbDev.HwSetting;
 | 
			
		||||
	pDCapsDef    sc = &dev->usbDev.Caps;
 | 
			
		||||
	pHWDef       hw   = &dev->usbDev.HwSetting;
 | 
			
		||||
	pDCapsDef    sc   = &dev->usbDev.Caps;
 | 
			
		||||
	u_char      *regs = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO, "usb_ScanBegin()\n" );
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1184,7 +1197,7 @@ static SANE_Bool usb_ScanBegin( Plustek_Device *dev, SANE_Bool auto_park )
 | 
			
		|||
 | 
			
		||||
	/* Disable home sensor during scan, or the chassis cannot move */
 | 
			
		||||
	value = ((m_pParam->bCalibration == PARAM_Scan &&
 | 
			
		||||
			  m_pParam->bSource == SOURCE_ADF)? (a_bRegs[0x58] & ~7): 0);
 | 
			
		||||
			  m_pParam->bSource == SOURCE_ADF)? (regs[0x58] & ~7): 0);
 | 
			
		||||
 | 
			
		||||
	if(!usbio_WriteReg( dev->fd, 0x58, value ))
 | 
			
		||||
		return SANE_FALSE;
 | 
			
		||||
| 
						 | 
				
			
			@ -1286,6 +1299,8 @@ static SANE_Bool usb_IsDataAvailableInDRAM( Plustek_Device *dev )
 | 
			
		|||
	u_char         a_bBand[3];
 | 
			
		||||
	long           dwTicks;
 | 
			
		||||
    struct timeval t;
 | 
			
		||||
	u_char         *regs  = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO, "usb_IsDataAvailableInDRAM()\n" );
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1313,9 +1328,9 @@ static SANE_Bool usb_IsDataAvailableInDRAM( Plustek_Device *dev )
 | 
			
		|||
 | 
			
		||||
			if( m_pParam->bSource != SOURCE_Reflection )
 | 
			
		||||
 | 
			
		||||
				usleep(1000*(30 * a_bRegs[0x08] * dev->usbDev.Caps.OpticDpi.x / 600));
 | 
			
		||||
				usleep(1000*(30 * regs[0x08] * dev->usbDev.Caps.OpticDpi.x / 600));
 | 
			
		||||
			else
 | 
			
		||||
				usleep(1000*(20 * a_bRegs[0x08] * dev->usbDev.Caps.OpticDpi.x / 600));
 | 
			
		||||
				usleep(1000*(20 * regs[0x08] * dev->usbDev.Caps.OpticDpi.x / 600));
 | 
			
		||||
 | 
			
		||||
			DBG( _DBG_INFO, "Data is available\n" );
 | 
			
		||||
			return SANE_TRUE;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,7 @@
 | 
			
		|||
 * - 0.47 - made calibration work on big-endian machines
 | 
			
		||||
 * - 0.48 - added more debug output
 | 
			
		||||
 *        - added usb_AutoWarmup()
 | 
			
		||||
 * - 0.49 - a_bRegs is now part of the device structure
 | 
			
		||||
 * .
 | 
			
		||||
 * <hr>
 | 
			
		||||
 * This file is part of the SANE package.
 | 
			
		||||
| 
						 | 
				
			
			@ -225,30 +226,31 @@ static void	usb_SetMCLK( Plustek_Device *dev, pScanParam pParam )
 | 
			
		|||
/** usb_SetDarkShading
 | 
			
		||||
 * download the dark shading data to Merlins' DRAM
 | 
			
		||||
 */
 | 
			
		||||
static SANE_Bool usb_SetDarkShading( int fd, u_char channel,
 | 
			
		||||
static SANE_Bool usb_SetDarkShading( Plustek_Device *dev, u_char channel,
 | 
			
		||||
                                     void *coeff_buffer, u_short wCount )
 | 
			
		||||
{
 | 
			
		||||
	int res;
 | 
			
		||||
	int     res;
 | 
			
		||||
	u_char *regs = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x03] = 0;
 | 
			
		||||
	regs[0x03] = 0;
 | 
			
		||||
	if( channel == CHANNEL_green )
 | 
			
		||||
		a_bRegs[0x03] |= 4;
 | 
			
		||||
		regs[0x03] |= 4;
 | 
			
		||||
	else
 | 
			
		||||
		if( channel == CHANNEL_blue )
 | 
			
		||||
			a_bRegs[0x03] |= 8;
 | 
			
		||||
			regs[0x03] |= 8;
 | 
			
		||||
 | 
			
		||||
	if( usbio_WriteReg( fd, 0x03, a_bRegs[0x03] )) {
 | 
			
		||||
	if( usbio_WriteReg( dev->fd, 0x03, regs[0x03] )) {
 | 
			
		||||
 | 
			
		||||
		/* Dataport address is always 0 for setting offset coefficient */
 | 
			
		||||
		a_bRegs[0x04] = 0;
 | 
			
		||||
		a_bRegs[0x05] = 0;
 | 
			
		||||
		regs[0x04] = 0;
 | 
			
		||||
		regs[0x05] = 0;
 | 
			
		||||
 | 
			
		||||
		res = sanei_lm983x_write( fd, 0x04, &a_bRegs[0x04], 2, SANE_TRUE );
 | 
			
		||||
		res = sanei_lm983x_write( dev->fd, 0x04, ®s[0x04], 2, SANE_TRUE );
 | 
			
		||||
 | 
			
		||||
		/* Download offset coefficients */
 | 
			
		||||
		if( SANE_STATUS_GOOD == res ) {
 | 
			
		||||
			
 | 
			
		||||
			res = sanei_lm983x_write( fd, 0x06,
 | 
			
		||||
			res = sanei_lm983x_write( dev->fd, 0x06,
 | 
			
		||||
			                          (u_char*)coeff_buffer, wCount, SANE_FALSE );
 | 
			
		||||
			if( SANE_STATUS_GOOD == res )
 | 
			
		||||
				return SANE_TRUE;
 | 
			
		||||
| 
						 | 
				
			
			@ -259,32 +261,33 @@ static SANE_Bool usb_SetDarkShading( int fd, u_char channel,
 | 
			
		|||
	return SANE_FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** usb_SetWhiteShading
 | 
			
		||||
	/** usb_SetWhiteShading
 | 
			
		||||
 * download the white shading data to Merlins' DRAM
 | 
			
		||||
 */
 | 
			
		||||
static SANE_Bool usb_SetWhiteShading( int fd, u_char channel,
 | 
			
		||||
static SANE_Bool usb_SetWhiteShading( Plustek_Device *dev, u_char channel,
 | 
			
		||||
                                      void *data_buffer, u_short wCount )
 | 
			
		||||
{
 | 
			
		||||
	int res;
 | 
			
		||||
	int     res;
 | 
			
		||||
	u_char *regs = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	a_bRegs [0x03] = 1;
 | 
			
		||||
	regs[0x03] = 1;
 | 
			
		||||
	if (channel == CHANNEL_green)
 | 
			
		||||
		a_bRegs [0x03] |= 4;
 | 
			
		||||
		regs [0x03] |= 4;
 | 
			
		||||
	else
 | 
			
		||||
		if (channel == CHANNEL_blue)
 | 
			
		||||
			a_bRegs [0x03] |= 8;
 | 
			
		||||
			regs[0x03] |= 8;
 | 
			
		||||
 | 
			
		||||
	if( usbio_WriteReg( fd, 0x03, a_bRegs[0x03] )) {
 | 
			
		||||
	if( usbio_WriteReg( dev->fd, 0x03, regs[0x03] )) {
 | 
			
		||||
 | 
			
		||||
		/* Dataport address is always 0 for setting offset coefficient */
 | 
			
		||||
		a_bRegs[0x04] = 0;
 | 
			
		||||
		a_bRegs[0x05] = 0;
 | 
			
		||||
		regs[0x04] = 0;
 | 
			
		||||
		regs[0x05] = 0;
 | 
			
		||||
 | 
			
		||||
		res = sanei_lm983x_write( fd, 0x04, &a_bRegs[0x04], 2, SANE_TRUE );
 | 
			
		||||
		res = sanei_lm983x_write( dev->fd, 0x04, ®s[0x04], 2, SANE_TRUE );
 | 
			
		||||
 | 
			
		||||
		/* Download offset coefficients */
 | 
			
		||||
		if( SANE_STATUS_GOOD == res ) {
 | 
			
		||||
			res = sanei_lm983x_write(fd, 0x06,
 | 
			
		||||
			res = sanei_lm983x_write(dev->fd, 0x06,
 | 
			
		||||
			                        (u_char*)data_buffer, wCount, SANE_FALSE );
 | 
			
		||||
			if( SANE_STATUS_GOOD == res )
 | 
			
		||||
				return SANE_TRUE;
 | 
			
		||||
| 
						 | 
				
			
			@ -586,7 +589,7 @@ static void usb_GetSWOffsetGain( Plustek_Device *dev )
 | 
			
		|||
 | 
			
		||||
/** according to the pixel values,
 | 
			
		||||
 */
 | 
			
		||||
static u_char usb_GetNewGain( u_short wMax, int channel )
 | 
			
		||||
static u_char usb_GetNewGain( Plustek_Device *dev, u_short wMax, int channel )
 | 
			
		||||
{
 | 
			
		||||
	double dRatio, dAmp;
 | 
			
		||||
	u_long dwInc, dwDec;
 | 
			
		||||
| 
						 | 
				
			
			@ -595,7 +598,7 @@ static u_char usb_GetNewGain( u_short wMax, int channel )
 | 
			
		|||
	if( !wMax )
 | 
			
		||||
		wMax = 1;
 | 
			
		||||
 | 
			
		||||
	dAmp = 0.93 + 0.067 * a_bRegs[0x3b+channel];
 | 
			
		||||
	dAmp = 0.93 + 0.067 * dev->usbDev.a_bRegs[0x3b+channel];
 | 
			
		||||
 | 
			
		||||
	if((m_dwIdealGain / (wMax / dAmp)) < 3) {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -653,8 +656,8 @@ static void setAdjGain( int gain, u_char *reg )
 | 
			
		|||
 * @param l_off   -
 | 
			
		||||
 * @return
 | 
			
		||||
 */
 | 
			
		||||
static SANE_Bool adjLampSetting( int channel, u_long  max,  u_long   ideal,
 | 
			
		||||
                                                 u_short l_on, u_short *l_off )
 | 
			
		||||
static SANE_Bool adjLampSetting( Plustek_Device *dev, int channel, u_long max,  
 | 
			
		||||
                                 u_long ideal, u_short l_on, u_short *l_off )
 | 
			
		||||
{
 | 
			
		||||
	SANE_Bool adj = SANE_FALSE;
 | 
			
		||||
	u_long    lamp_on;
 | 
			
		||||
| 
						 | 
				
			
			@ -671,7 +674,7 @@ static SANE_Bool adjLampSetting( int channel, u_long  max,  u_long   ideal,
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
    /* if the image was too dull, increase lamp by 1% */
 | 
			
		||||
	if( a_bRegs[0x3b + channel] == 63 ) {
 | 
			
		||||
	if( dev->usbDev.a_bRegs[0x3b + channel] == 63 ) {
 | 
			
		||||
 | 
			
		||||
		lamp_on  = (*l_off) - l_on;
 | 
			
		||||
	    lamp_on += (lamp_on/100);
 | 
			
		||||
| 
						 | 
				
			
			@ -702,6 +705,7 @@ static SANE_Bool usb_AdjustGain( Plustek_Device *dev, int fNegative )
 | 
			
		|||
	pScanDef  scanning = &dev->scanning;
 | 
			
		||||
	pDCapsDef scaps    = &dev->usbDev.Caps;
 | 
			
		||||
	pHWDef    hw       = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char   *regs     = dev->usbDev.a_bRegs;
 | 
			
		||||
	u_long    dw, start, end, len;
 | 
			
		||||
	SANE_Bool fRepeatITA = SANE_TRUE;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -714,9 +718,9 @@ static SANE_Bool usb_AdjustGain( Plustek_Device *dev, int fNegative )
 | 
			
		|||
	DBG( _DBG_INFO, "usb_AdjustGain()\n" );
 | 
			
		||||
	if((dev->adj.rgain != -1) && 
 | 
			
		||||
	   (dev->adj.ggain != -1) && (dev->adj.bgain != -1)) {
 | 
			
		||||
		setAdjGain( dev->adj.rgain, &a_bRegs[0x3b] );
 | 
			
		||||
		setAdjGain( dev->adj.ggain, &a_bRegs[0x3c] );
 | 
			
		||||
		setAdjGain( dev->adj.bgain, &a_bRegs[0x3d] );
 | 
			
		||||
		setAdjGain( dev->adj.rgain, ®s[0x3b] );
 | 
			
		||||
		setAdjGain( dev->adj.ggain, ®s[0x3c] );
 | 
			
		||||
		setAdjGain( dev->adj.bgain, ®s[0x3d] );
 | 
			
		||||
		DBG( _DBG_INFO, "- function skipped, using frontend values!\n" );
 | 
			
		||||
		return SANE_TRUE;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -831,9 +835,9 @@ TOGAIN:
 | 
			
		|||
			    Gain_Hilight.Red, Gain_Hilight.Red, Gain_Hilight.Green, 
 | 
			
		||||
			    Gain_Hilight.Green, Gain_Hilight.Blue, Gain_Hilight.Blue );
 | 
			
		||||
 | 
			
		||||
			a_bRegs[0x3b] = usb_GetNewGain(Gain_Hilight.Red,   0 );
 | 
			
		||||
			a_bRegs[0x3c] = usb_GetNewGain(Gain_Hilight.Green, 1 );
 | 
			
		||||
			a_bRegs[0x3d] = usb_GetNewGain(Gain_Hilight.Blue,  2 );
 | 
			
		||||
			regs[0x3b] = usb_GetNewGain(dev,Gain_Hilight.Red,   0 );
 | 
			
		||||
			regs[0x3c] = usb_GetNewGain(dev,Gain_Hilight.Green, 1 );
 | 
			
		||||
			regs[0x3d] = usb_GetNewGain(dev,Gain_Hilight.Blue,  2 );
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -856,8 +860,8 @@ TOGAIN:
 | 
			
		|||
			Gain_Hilight.Blue = (u_short)(dwMax / 20UL);
 | 
			
		||||
 | 
			
		||||
			Gain_Reg.Red  = Gain_Reg.Green =
 | 
			
		||||
			Gain_Reg.Blue = a_bRegs[0x3b] =
 | 
			
		||||
			a_bRegs[0x3c] = a_bRegs[0x3d] = usb_GetNewGain(Gain_Hilight.Green,1);
 | 
			
		||||
			Gain_Reg.Blue = regs[0x3b] =
 | 
			
		||||
			regs[0x3c] = regs[0x3d] = usb_GetNewGain(dev,Gain_Hilight.Green,1);
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
	
 | 
			
		||||
| 
						 | 
				
			
			@ -927,9 +931,9 @@ TOGAIN:
 | 
			
		|||
/*			m_dwIdealGain = IDEAL_GainNormal;
 | 
			
		||||
*/						 /* min(min(rgb.wRed, rgb.wGreen), rgb.wBlue) */
 | 
			
		||||
 | 
			
		||||
			a_bRegs[0x3b] = usb_GetNewGain( tmp_rgb.Red,   0 );
 | 
			
		||||
			a_bRegs[0x3c] = usb_GetNewGain( tmp_rgb.Green, 1 );
 | 
			
		||||
			a_bRegs[0x3d] = usb_GetNewGain( tmp_rgb.Blue,  2 );
 | 
			
		||||
			regs[0x3b] = usb_GetNewGain( dev, tmp_rgb.Red,   0 );
 | 
			
		||||
			regs[0x3c] = usb_GetNewGain( dev, tmp_rgb.Green, 1 );
 | 
			
		||||
			regs[0x3d] = usb_GetNewGain( dev, tmp_rgb.Blue,  2 );
 | 
			
		||||
 | 
			
		||||
			if( !_IS_PLUSTEKMOTOR(hw->motorModel)) {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -940,17 +944,17 @@ TOGAIN:
 | 
			
		|||
 | 
			
		||||
/*					m_dwIdealGain = IDEAL_GainNormal;
 | 
			
		||||
 */
 | 
			
		||||
					if( adjLampSetting( CHANNEL_red, tmp_rgb.Red, m_dwIdealGain,
 | 
			
		||||
					if( adjLampSetting( dev, CHANNEL_red, tmp_rgb.Red, m_dwIdealGain,
 | 
			
		||||
					                    hw->red_lamp_on, &hw->red_lamp_off )) {
 | 
			
		||||
						adj = SANE_TRUE;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if( adjLampSetting( CHANNEL_green, tmp_rgb.Green, m_dwIdealGain,
 | 
			
		||||
					if( adjLampSetting( dev, CHANNEL_green, tmp_rgb.Green, m_dwIdealGain,
 | 
			
		||||
								    hw->green_lamp_on, &hw->green_lamp_off )) {
 | 
			
		||||
						adj = SANE_TRUE;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if( adjLampSetting( CHANNEL_blue, tmp_rgb.Blue, m_dwIdealGain,
 | 
			
		||||
					if( adjLampSetting( dev, CHANNEL_blue, tmp_rgb.Blue, m_dwIdealGain,
 | 
			
		||||
									    hw->blue_lamp_on, &hw->blue_lamp_off)){
 | 
			
		||||
						adj = SANE_TRUE;
 | 
			
		||||
					}
 | 
			
		||||
| 
						 | 
				
			
			@ -965,19 +969,19 @@ TOGAIN:
 | 
			
		|||
	             
 | 
			
		||||
				} else {
 | 
			
		||||
 | 
			
		||||
					if((!a_bRegs[0x3b] ||
 | 
			
		||||
					    !a_bRegs[0x3c] || !a_bRegs[0x3d]) && dMCLK > 3.0) {
 | 
			
		||||
					if((!regs[0x3b] ||
 | 
			
		||||
					    !regs[0x3c] || !regs[0x3d]) && dMCLK > 3.0) {
 | 
			
		||||
 | 
			
		||||
						scanning->sParam.dMCLK = dMCLK = dMCLK - 0.5;
 | 
			
		||||
						a_bRegs[0x3b] = a_bRegs[0x3c] = a_bRegs[0x3d] = 1;
 | 
			
		||||
						regs[0x3b] = regs[0x3c] = regs[0x3d] = 1;
 | 
			
		||||
						
 | 
			
		||||
						adj = SANE_TRUE;
 | 
			
		||||
 | 
			
		||||
					} else if(((a_bRegs[0x3b] == 63) || (a_bRegs[0x3c] == 63) ||
 | 
			
		||||
									  (a_bRegs[0x3d] == 63)) && (dMCLK < 10)) {
 | 
			
		||||
					} else if(((regs[0x3b] == 63) || (regs[0x3c] == 63) ||
 | 
			
		||||
									  (regs[0x3d] == 63)) && (dMCLK < 10)) {
 | 
			
		||||
 | 
			
		||||
						scanning->sParam.dMCLK = dMCLK = dMCLK + 0.5;
 | 
			
		||||
						a_bRegs[0x3b] = a_bRegs[0x3c] = a_bRegs[0x3d] = 1;
 | 
			
		||||
						regs[0x3b] = regs[0x3c] = regs[0x3d] = 1;
 | 
			
		||||
 | 
			
		||||
						adj = SANE_TRUE;
 | 
			
		||||
					}
 | 
			
		||||
| 
						 | 
				
			
			@ -994,27 +998,27 @@ TOGAIN:
 | 
			
		|||
				 * 1200 dpi color mode
 | 
			
		||||
				 */
 | 
			
		||||
				if( hw->motorModel == MODEL_KaoHsiung &&
 | 
			
		||||
				    scaps->bCCD == kNEC3778 && dMCLK>= 5.5 && !a_bRegs[0x3c]){
 | 
			
		||||
				    scaps->bCCD == kNEC3778 && dMCLK>= 5.5 && !regs[0x3c]){
 | 
			
		||||
 | 
			
		||||
					a_bRegs[0x3b] = a_bRegs[0x3c] = a_bRegs[0x3d] = 1;
 | 
			
		||||
					regs[0x3b] = regs[0x3c] = regs[0x3d] = 1;
 | 
			
		||||
					scanning->sParam.dMCLK = dMCLK = dMCLK - 1.5;
 | 
			
		||||
					goto TOGAIN;
 | 
			
		||||
 | 
			
		||||
				} else if( hw->motorModel == MODEL_HuaLien &&
 | 
			
		||||
					       scaps->bCCD == kNEC3799 && fRepeatITA ) {
 | 
			
		||||
 | 
			
		||||
					if((!a_bRegs[0x3b] ||
 | 
			
		||||
					    !a_bRegs[0x3c] || !a_bRegs[0x3d]) && dMCLK > 3.0) {
 | 
			
		||||
					if((!regs[0x3b] ||
 | 
			
		||||
					    !regs[0x3c] || !regs[0x3d]) && dMCLK > 3.0) {
 | 
			
		||||
 | 
			
		||||
						scanning->sParam.dMCLK = dMCLK = dMCLK - 0.5;
 | 
			
		||||
						a_bRegs[0x3b] = a_bRegs[0x3c] = a_bRegs[0x3d] = 1;
 | 
			
		||||
						regs[0x3b] = regs[0x3c] = regs[0x3d] = 1;
 | 
			
		||||
						goto TOGAIN;
 | 
			
		||||
 | 
			
		||||
					} else if(((a_bRegs[0x3b] == 63) || (a_bRegs[0x3c] == 63) ||
 | 
			
		||||
										  (a_bRegs[0x3d] == 63)) && (dMCLK < 10)) {
 | 
			
		||||
					} else if(((regs[0x3b] == 63) || (regs[0x3c] == 63) ||
 | 
			
		||||
										  (regs[0x3d] == 63)) && (dMCLK < 10)) {
 | 
			
		||||
 | 
			
		||||
						scanning->sParam.dMCLK = dMCLK = dMCLK + 0.5;
 | 
			
		||||
						a_bRegs[0x3b] = a_bRegs[0x3c] = a_bRegs[0x3d] = 1;
 | 
			
		||||
						regs[0x3b] = regs[0x3c] = regs[0x3d] = 1;
 | 
			
		||||
						goto TOGAIN;
 | 
			
		||||
					}
 | 
			
		||||
					bMaxITA = (u_char)floor((dMCLK + 1) / 2);
 | 
			
		||||
| 
						 | 
				
			
			@ -1037,9 +1041,9 @@ TOGAIN:
 | 
			
		|||
			if( hw->bReg_0x26 & _ONE_CH_COLOR )
 | 
			
		||||
				w_tmp = w_min;
 | 
			
		||||
 | 
			
		||||
			a_bRegs[0x3b] =
 | 
			
		||||
			a_bRegs[0x3c] =
 | 
			
		||||
			a_bRegs[0x3d] = usb_GetNewGain(w_tmp, 0);
 | 
			
		||||
			regs[0x3b] =
 | 
			
		||||
			regs[0x3c] =
 | 
			
		||||
			regs[0x3d] = usb_GetNewGain(dev, w_tmp, 0);
 | 
			
		||||
 | 
			
		||||
			DBG(_DBG_INFO2, "MAX(G)= 0x%04x(%u)\n", w_max, w_max );
 | 
			
		||||
			DBG(_DBG_INFO2, "MIN(G)= 0x%04x(%u)\n", w_min, w_min );
 | 
			
		||||
| 
						 | 
				
			
			@ -1054,7 +1058,7 @@ TOGAIN:
 | 
			
		|||
				/* on CIS devices, we can control the lamp off settings */
 | 
			
		||||
				if( hw->bReg_0x26 & _ONE_CH_COLOR ) {
 | 
			
		||||
 | 
			
		||||
					if( adjLampSetting( CHANNEL_green, w_tmp, m_dwIdealGain,
 | 
			
		||||
					if( adjLampSetting( dev, CHANNEL_green, w_tmp, m_dwIdealGain,
 | 
			
		||||
					                    hw->green_lamp_on, &hw->green_lamp_off )) {
 | 
			
		||||
						adj = SANE_TRUE;
 | 
			
		||||
					}
 | 
			
		||||
| 
						 | 
				
			
			@ -1069,17 +1073,17 @@ TOGAIN:
 | 
			
		|||
 | 
			
		||||
				} else {
 | 
			
		||||
 | 
			
		||||
					if( !a_bRegs[0x3b] && (dMCLK > 6.0)) {
 | 
			
		||||
					if( !regs[0x3b] && (dMCLK > 6.0)) {
 | 
			
		||||
 | 
			
		||||
						scanning->sParam.dMCLK = dMCLK = dMCLK - 0.5;
 | 
			
		||||
						a_bRegs[0x3b] = a_bRegs[0x3c] = a_bRegs[0x3d] = 1;
 | 
			
		||||
						regs[0x3b] = regs[0x3c] = regs[0x3d] = 1;
 | 
			
		||||
 | 
			
		||||
						adj = SANE_TRUE;
 | 
			
		||||
 | 
			
		||||
					} else if((a_bRegs[0x3b] == 63) && (dMCLK < 20)) {
 | 
			
		||||
					} else if((regs[0x3b] == 63) && (dMCLK < 20)) {
 | 
			
		||||
 | 
			
		||||
						scanning->sParam.dMCLK = dMCLK = dMCLK + 0.5;
 | 
			
		||||
						a_bRegs[0x3b] = a_bRegs[0x3c] = a_bRegs[0x3d] = 1;
 | 
			
		||||
						regs[0x3b] = regs[0x3c] = regs[0x3d] = 1;
 | 
			
		||||
 | 
			
		||||
						adj = SANE_TRUE;
 | 
			
		||||
					}
 | 
			
		||||
| 
						 | 
				
			
			@ -1093,9 +1097,9 @@ TOGAIN:
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO2, "REG[0x3b] = %u\n", a_bRegs[0x3b] );
 | 
			
		||||
	DBG( _DBG_INFO2, "REG[0x3c] = %u\n", a_bRegs[0x3c] );
 | 
			
		||||
	DBG( _DBG_INFO2, "REG[0x3d] = %u\n", a_bRegs[0x3d] );
 | 
			
		||||
	DBG( _DBG_INFO2, "REG[0x3b] = %u\n", regs[0x3b] );
 | 
			
		||||
	DBG( _DBG_INFO2, "REG[0x3c] = %u\n", regs[0x3c] );
 | 
			
		||||
	DBG( _DBG_INFO2, "REG[0x3d] = %u\n", regs[0x3d] );
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO2, "red_lamp_on    = %u\n", hw->red_lamp_on  );
 | 
			
		||||
	DBG( _DBG_INFO2, "red_lamp_off   = %u\n", hw->red_lamp_off );
 | 
			
		||||
| 
						 | 
				
			
			@ -1118,9 +1122,9 @@ TOGAIN:
 | 
			
		|||
 * @param channel  -
 | 
			
		||||
 * @param cAdjust  -
 | 
			
		||||
 */
 | 
			
		||||
static void usb_GetNewOffset( u_long *pdwSum, u_long *pdwDiff,
 | 
			
		||||
								signed char *pcOffset, u_char *pIdeal,
 | 
			
		||||
										u_long channel, signed char cAdjust )
 | 
			
		||||
static void usb_GetNewOffset( Plustek_Device *dev, u_long *pdwSum, u_long *pdwDiff,
 | 
			
		||||
                              signed char *pcOffset, u_char *pIdeal,
 | 
			
		||||
                              u_long channel, signed char cAdjust )
 | 
			
		||||
{
 | 
			
		||||
	/* IDEAL_Offset is currently set to 0x1000 = 4096 */
 | 
			
		||||
	u_long dwIdealOffset = IDEAL_Offset;
 | 
			
		||||
| 
						 | 
				
			
			@ -1132,7 +1136,7 @@ static void usb_GetNewOffset( u_long *pdwSum, u_long *pdwDiff,
 | 
			
		|||
		if( pdwSum[channel] < pdwDiff[channel] ) {
 | 
			
		||||
			/* New offset is better than old one */
 | 
			
		||||
			pdwDiff[channel] = pdwSum[channel];
 | 
			
		||||
			pIdeal[channel]  = a_bRegs[0x38 + channel];
 | 
			
		||||
			pIdeal[channel]  = dev->usbDev.a_bRegs[0x38 + channel];
 | 
			
		||||
		}
 | 
			
		||||
		pcOffset[channel] -= cAdjust;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1143,15 +1147,15 @@ static void usb_GetNewOffset( u_long *pdwSum, u_long *pdwDiff,
 | 
			
		|||
		if( pdwSum[channel] < pdwDiff[channel] ) {
 | 
			
		||||
			/* New offset is better than old one */
 | 
			
		||||
			pdwDiff[channel] = pdwSum[channel];
 | 
			
		||||
			pIdeal[channel]  = a_bRegs[0x38 + channel];
 | 
			
		||||
			pIdeal[channel]  = dev->usbDev.a_bRegs[0x38 + channel];
 | 
			
		||||
		}
 | 
			
		||||
		pcOffset[channel] += cAdjust;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( pcOffset[channel] >= 0 )
 | 
			
		||||
		a_bRegs[0x38 + channel] = pcOffset[channel];
 | 
			
		||||
		dev->usbDev.a_bRegs[0x38 + channel] = pcOffset[channel];
 | 
			
		||||
	else
 | 
			
		||||
		a_bRegs[0x38 + channel] = (u_char)(32 - pcOffset[channel]);
 | 
			
		||||
		dev->usbDev.a_bRegs[0x38 + channel] = (u_char)(32 - pcOffset[channel]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** usb_AdjustOffset
 | 
			
		||||
| 
						 | 
				
			
			@ -1173,7 +1177,8 @@ static SANE_Bool usb_AdjustOffset( Plustek_Device *dev )
 | 
			
		|||
	u_long        dw, dwPixels;
 | 
			
		||||
    u_long        dwDiff[3], dwSum[3];
 | 
			
		||||
 | 
			
		||||
	pHWDef hw = &dev->usbDev.HwSetting;
 | 
			
		||||
	pHWDef  hw   = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char *regs = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	if( usb_IsEscPressed())
 | 
			
		||||
		return SANE_FALSE;
 | 
			
		||||
| 
						 | 
				
			
			@ -1182,9 +1187,9 @@ static SANE_Bool usb_AdjustOffset( Plustek_Device *dev )
 | 
			
		|||
	DBG( _DBG_INFO, "usb_AdjustOffset()\n" );
 | 
			
		||||
	if((dev->adj.rofs != -1) && 
 | 
			
		||||
	   (dev->adj.gofs != -1) && (dev->adj.bofs != -1)) {
 | 
			
		||||
		a_bRegs[0x38] = (dev->adj.rofs & 0x3f);
 | 
			
		||||
		a_bRegs[0x39] = (dev->adj.gofs & 0x3f);
 | 
			
		||||
		a_bRegs[0x3a] = (dev->adj.bofs & 0x3f);
 | 
			
		||||
		regs[0x38] = (dev->adj.rofs & 0x3f);
 | 
			
		||||
		regs[0x39] = (dev->adj.gofs & 0x3f);
 | 
			
		||||
		regs[0x3a] = (dev->adj.bofs & 0x3f);
 | 
			
		||||
		DBG( _DBG_INFO, "- function skipped, using frontend values!\n" );
 | 
			
		||||
		return SANE_TRUE;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -1214,7 +1219,7 @@ static SANE_Bool usb_AdjustOffset( Plustek_Device *dev )
 | 
			
		|||
	cOffset[0] = cOffset[1] = cOffset[2] = 0;
 | 
			
		||||
	bExpect[0] = bExpect[1] = bExpect[2] = 0;
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x38] = a_bRegs [0x39] = a_bRegs [0x3a] = 0;
 | 
			
		||||
	regs[0x38] = regs[0x39] = regs[0x3a] = 0;
 | 
			
		||||
 | 
			
		||||
	if( hw->bReg_0x26 & _ONE_CH_COLOR ) {
 | 
			
		||||
	    /*
 | 
			
		||||
| 
						 | 
				
			
			@ -1227,12 +1232,12 @@ static SANE_Bool usb_AdjustOffset( Plustek_Device *dev )
 | 
			
		|||
			usb_ModuleMove  ( dev, MOVE_Forward,
 | 
			
		||||
								(u_long)dev->usbDev.pSource->DarkShadOrgY );
 | 
			
		||||
 | 
			
		||||
			a_bRegs[0x45] &= ~0x10;
 | 
			
		||||
			regs[0x45] &= ~0x10;
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
 | 
			
		||||
		 	/* switch lamp off to read dark data... */
 | 
			
		||||
			a_bRegs[0x29] = 0;
 | 
			
		||||
			regs[0x29] = 0;
 | 
			
		||||
			usb_switchLamp( dev, SANE_FALSE );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -1303,9 +1308,9 @@ static SANE_Bool usb_AdjustOffset( Plustek_Device *dev )
 | 
			
		|||
			dwSum[1] /= dwPixels;
 | 
			
		||||
			dwSum[2] /= dwPixels;
 | 
			
		||||
 | 
			
		||||
			usb_GetNewOffset( dwSum, dwDiff, cOffset, bExpect, 0, cAdjust );
 | 
			
		||||
			usb_GetNewOffset( dwSum, dwDiff, cOffset, bExpect, 1, cAdjust );
 | 
			
		||||
			usb_GetNewOffset( dwSum, dwDiff, cOffset, bExpect, 2, cAdjust );
 | 
			
		||||
			usb_GetNewOffset( dev, dwSum, dwDiff, cOffset, bExpect, 0, cAdjust );
 | 
			
		||||
			usb_GetNewOffset( dev, dwSum, dwDiff, cOffset, bExpect, 1, cAdjust );
 | 
			
		||||
			usb_GetNewOffset( dev, dwSum, dwDiff, cOffset, bExpect, 2, cAdjust );
 | 
			
		||||
 | 
			
		||||
            DBG( _DBG_INFO2, "RedExpect   = %u\n", bExpect[0] );
 | 
			
		||||
            DBG( _DBG_INFO2, "GreenExpect = %u\n", bExpect[1] );
 | 
			
		||||
| 
						 | 
				
			
			@ -1322,38 +1327,38 @@ static SANE_Bool usb_AdjustOffset( Plustek_Device *dev )
 | 
			
		|||
#endif
 | 
			
		||||
			}
 | 
			
		||||
			dwSum [0] /= dwPixels;
 | 
			
		||||
			usb_GetNewOffset( dwSum, dwDiff, cOffset, bExpect, 0, cAdjust );
 | 
			
		||||
			a_bRegs[0x3a] = a_bRegs[0x39] = a_bRegs[0x38];
 | 
			
		||||
			usb_GetNewOffset( dev, dwSum, dwDiff, cOffset, bExpect, 0, cAdjust );
 | 
			
		||||
			regs[0x3a] = regs[0x39] = regs[0x38];
 | 
			
		||||
 | 
			
		||||
			DBG(_DBG_INFO2,"Sum = %lu, ave = %lu\n",dwSum[0],dwSum[0]/dwPixels);
 | 
			
		||||
			DBG(_DBG_INFO2,"Expect = %u\n", bExpect[0]);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		_UIO(sanei_lm983x_write(dev->fd, 0x38, &a_bRegs[0x38], 3, SANE_TRUE));
 | 
			
		||||
		_UIO(sanei_lm983x_write(dev->fd, 0x38, ®s[0x38], 3, SANE_TRUE));
 | 
			
		||||
		cAdjust >>= 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( m_ScanParam.bDataType == SCANDATATYPE_Color ) {
 | 
			
		||||
		a_bRegs[0x38] = bExpect[0];
 | 
			
		||||
		a_bRegs[0x39] = bExpect[1];
 | 
			
		||||
		a_bRegs[0x3a] = bExpect[2];
 | 
			
		||||
		regs[0x38] = bExpect[0];
 | 
			
		||||
		regs[0x39] = bExpect[1];
 | 
			
		||||
		regs[0x3a] = bExpect[2];
 | 
			
		||||
	} else {
 | 
			
		||||
 | 
			
		||||
		a_bRegs[0x38] = a_bRegs[0x39] = a_bRegs[0x3a] = bExpect[0];	
 | 
			
		||||
		regs[0x38] = regs[0x39] = regs[0x3a] = bExpect[0];	
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO2, "REG[0x38] = %u\n", a_bRegs[0x38] );
 | 
			
		||||
	DBG( _DBG_INFO2, "REG[0x39] = %u\n", a_bRegs[0x39] );
 | 
			
		||||
	DBG( _DBG_INFO2, "REG[0x3a] = %u\n", a_bRegs[0x3a] );
 | 
			
		||||
	DBG( _DBG_INFO2, "REG[0x38] = %u\n", regs[0x38] );
 | 
			
		||||
	DBG( _DBG_INFO2, "REG[0x39] = %u\n", regs[0x39] );
 | 
			
		||||
	DBG( _DBG_INFO2, "REG[0x3a] = %u\n", regs[0x3a] );
 | 
			
		||||
	DBG( _DBG_INFO, "usb_AdjustOffset() done.\n" );
 | 
			
		||||
 | 
			
		||||
	/* switch it on again on CIS based scanners */
 | 
			
		||||
	if( hw->bReg_0x26 & _ONE_CH_COLOR ) {
 | 
			
		||||
 | 
			
		||||
		if( dev->usbDev.pSource->DarkShadOrgY < 0 ) {
 | 
			
		||||
			a_bRegs[0x29] = hw->bReg_0x29;
 | 
			
		||||
			regs[0x29] = hw->bReg_0x29;
 | 
			
		||||
			usb_switchLamp( dev, SANE_TRUE );
 | 
			
		||||
			usbio_WriteReg( dev->fd, 0x29, a_bRegs[0x29]);
 | 
			
		||||
			usbio_WriteReg( dev->fd, 0x29, regs[0x29]);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1493,6 +1498,7 @@ static SANE_Bool usb_AdjustDarkShading( Plustek_Device *dev )
 | 
			
		|||
    pScanDef  scanning = &dev->scanning;
 | 
			
		||||
	pDCapsDef scaps    = &dev->usbDev.Caps;
 | 
			
		||||
	pHWDef    hw       = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char   *regs     = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	if( usb_IsEscPressed())
 | 
			
		||||
		return SANE_FALSE;
 | 
			
		||||
| 
						 | 
				
			
			@ -1550,7 +1556,7 @@ static SANE_Bool usb_AdjustDarkShading( Plustek_Device *dev )
 | 
			
		|||
	} else {
 | 
			
		||||
 | 
			
		||||
	 	/* switch lamp off to read dark data... */
 | 
			
		||||
		a_bRegs[0x29] = 0;
 | 
			
		||||
		regs[0x29] = 0;
 | 
			
		||||
		usb_switchLamp( dev, SANE_FALSE );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1562,9 +1568,9 @@ static SANE_Bool usb_AdjustDarkShading( Plustek_Device *dev )
 | 
			
		|||
 | 
			
		||||
      	/* on error, reset the lamp settings*/
 | 
			
		||||
		
 | 
			
		||||
		a_bRegs[0x29] = hw->bReg_0x29;
 | 
			
		||||
		regs[0x29] = hw->bReg_0x29;
 | 
			
		||||
  		usb_switchLamp( dev, SANE_TRUE );
 | 
			
		||||
		usbio_WriteReg( dev->fd, 0x29, a_bRegs[0x29] );
 | 
			
		||||
		usbio_WriteReg( dev->fd, 0x29, regs[0x29] );
 | 
			
		||||
		
 | 
			
		||||
		DBG( _DBG_ERROR, "usb_AdjustDarkShading() failed\n" );
 | 
			
		||||
		return SANE_FALSE;
 | 
			
		||||
| 
						 | 
				
			
			@ -1573,10 +1579,10 @@ static SANE_Bool usb_AdjustDarkShading( Plustek_Device *dev )
 | 
			
		|||
	/*
 | 
			
		||||
	 * set illumination mode and switch lamp on again
 | 
			
		||||
	 */
 | 
			
		||||
	a_bRegs[0x29] = hw->bReg_0x29;
 | 
			
		||||
	regs[0x29] = hw->bReg_0x29;
 | 
			
		||||
	usb_switchLamp( dev, SANE_TRUE );
 | 
			
		||||
 | 
			
		||||
	if( !usbio_WriteReg( dev->fd, 0x29, a_bRegs[0x29])) {
 | 
			
		||||
	if( !usbio_WriteReg( dev->fd, 0x29, regs[0x29])) {
 | 
			
		||||
		DBG( _DBG_ERROR, "usb_AdjustDarkShading() failed\n" );
 | 
			
		||||
		return SANE_FALSE;
 | 
			
		||||
	}	
 | 
			
		||||
| 
						 | 
				
			
			@ -1634,7 +1640,7 @@ static SANE_Bool usb_AdjustDarkShading( Plustek_Device *dev )
 | 
			
		|||
				a_wDarkShading, m_ScanParam.Size.dwPhyPixels * 2 );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	a_bRegs[0x45] |= 0x10;
 | 
			
		||||
	regs[0x45] |= 0x10;
 | 
			
		||||
 | 
			
		||||
	usb_line_statistics( "Dark", a_wDarkShading, m_ScanParam.Size.dwPhyPixels,
 | 
			
		||||
                          scanning->sParam.bDataType == SCANDATATYPE_Color?1:0);
 | 
			
		||||
| 
						 | 
				
			
			@ -2136,6 +2142,7 @@ static void usb_PrepareCalibration( Plustek_Device *dev )
 | 
			
		|||
{
 | 
			
		||||
    pScanDef  scanning = &dev->scanning;
 | 
			
		||||
	pDCapsDef scaps    = &dev->usbDev.Caps;
 | 
			
		||||
	u_char   *regs     = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	usb_GetSWOffsetGain( dev );
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2159,9 +2166,9 @@ static void usb_PrepareCalibration( Plustek_Device *dev )
 | 
			
		|||
	usb_SetMCLK( dev, &m_ScanParam );
 | 
			
		||||
 
 | 
			
		||||
	/* preset these registers offset/gain */
 | 
			
		||||
	a_bRegs[0x38] = a_bRegs[0x39] = a_bRegs[0x3a] = 0;
 | 
			
		||||
	a_bRegs[0x3b] = a_bRegs[0x3c] = a_bRegs[0x3d] = 1;
 | 
			
		||||
	a_bRegs[0x45] &= ~0x10;
 | 
			
		||||
	regs[0x38] = regs[0x39] = regs[0x3a] = 0;
 | 
			
		||||
	regs[0x3b] = regs[0x3c] = regs[0x3d] = 1;
 | 
			
		||||
	regs[0x45] &= ~0x10;
 | 
			
		||||
 | 
			
		||||
	memset( a_wWhiteShading, 0, _SHADING_BUF );
 | 
			
		||||
	memset( a_wDarkShading,  0, _SHADING_BUF );
 | 
			
		||||
| 
						 | 
				
			
			@ -2182,6 +2189,7 @@ static SANE_Bool usb_AutoWarmup( Plustek_Device *dev )
 | 
			
		|||
	pScanDef  scanning = &dev->scanning;
 | 
			
		||||
	pDCapsDef scaps    = &dev->usbDev.Caps;
 | 
			
		||||
	pHWDef    hw       = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char   *regs     = dev->usbDev.a_bRegs;
 | 
			
		||||
	u_long    dw, start, end, len;
 | 
			
		||||
	u_long    curR,   curG,  curB;
 | 
			
		||||
	u_long    lastR, lastG, lastB;
 | 
			
		||||
| 
						 | 
				
			
			@ -2207,8 +2215,8 @@ static SANE_Bool usb_AutoWarmup( Plustek_Device *dev )
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	usb_PrepareCalibration( dev );
 | 
			
		||||
	a_bRegs[0x38] = a_bRegs[0x39] = a_bRegs[0x3a] = 0;
 | 
			
		||||
	a_bRegs[0x3b] = a_bRegs[0x3c] = a_bRegs[0x3d] = 1;
 | 
			
		||||
	regs[0x38] = regs[0x39] = regs[0x3a] = 0;
 | 
			
		||||
	regs[0x3b] = regs[0x3c] = regs[0x3d] = 1;
 | 
			
		||||
 | 
			
		||||
	/* define the strip to scan for warming up the lamp, in the end
 | 
			
		||||
	 * we always scan the full line, even for TPA
 | 
			
		||||
| 
						 | 
				
			
			@ -2355,6 +2363,7 @@ static int usb_DoCalibration( Plustek_Device *dev )
 | 
			
		|||
	pScanDef  scanning = &dev->scanning;
 | 
			
		||||
	pDCapsDef scaps    = &dev->usbDev.Caps;
 | 
			
		||||
	pHWDef    hw       = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char   *regs     = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO, "usb_DoCalibration()\n" );
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2415,17 +2424,17 @@ static int usb_DoCalibration( Plustek_Device *dev )
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
		DBG( _DBG_INFO, "--> BYPASS\n" );
 | 
			
		||||
		a_bRegs[0x38] = a_bRegs[0x39] = a_bRegs[0x3a] = 0;
 | 
			
		||||
		a_bRegs[0x3b] = a_bRegs[0x3c] = a_bRegs[0x3d] = 1;
 | 
			
		||||
		regs[0x38] = regs[0x39] = regs[0x3a] = 0;
 | 
			
		||||
		regs[0x3b] = regs[0x3c] = regs[0x3d] = 1;
 | 
			
		||||
 | 
			
		||||
		setAdjGain( dev->adj.rgain, &a_bRegs[0x3b] );
 | 
			
		||||
		setAdjGain( dev->adj.ggain, &a_bRegs[0x3c] );
 | 
			
		||||
		setAdjGain( dev->adj.bgain, &a_bRegs[0x3d] );
 | 
			
		||||
		setAdjGain( dev->adj.rgain, ®s[0x3b] );
 | 
			
		||||
		setAdjGain( dev->adj.ggain, ®s[0x3c] );
 | 
			
		||||
		setAdjGain( dev->adj.bgain, ®s[0x3d] );
 | 
			
		||||
 | 
			
		||||
		a_bRegs[0x45] |= 0x10;
 | 
			
		||||
		regs[0x45] |= 0x10;
 | 
			
		||||
		usb_SetMCLK( dev, &scanning->sParam );
 | 
			
		||||
 | 
			
		||||
	    dumpregs( dev->fd, a_bRegs );
 | 
			
		||||
	    dumpregs( dev->fd, regs );
 | 
			
		||||
		DBG( _DBG_INFO, "<-- BYPASS\n" );
 | 
			
		||||
 | 
			
		||||
	} else {
 | 
			
		||||
| 
						 | 
				
			
			@ -2450,10 +2459,10 @@ static int usb_DoCalibration( Plustek_Device *dev )
 | 
			
		|||
 | 
			
		||||
				for(;;) {
 | 
			
		||||
					if( usb_AdjustGain( dev, 2)) {
 | 
			
		||||
						if( a_bRegs[0x3b] && a_bRegs[0x3c] && a_bRegs[0x3d]) {
 | 
			
		||||
						if( regs[0x3b] && regs[0x3c] && regs[0x3d]) {
 | 
			
		||||
							break;
 | 
			
		||||
						} else {
 | 
			
		||||
							a_bRegs[0x3b] = a_bRegs[0x3c] = a_bRegs[0x3d] = 1;
 | 
			
		||||
							regs[0x3b] = regs[0x3c] = regs[0x3d] = 1;
 | 
			
		||||
							dMCLK--;
 | 
			
		||||
						}
 | 
			
		||||
					} else {
 | 
			
		||||
| 
						 | 
				
			
			@ -2461,15 +2470,15 @@ static int usb_DoCalibration( Plustek_Device *dev )
 | 
			
		|||
					}
 | 
			
		||||
				}
 | 
			
		||||
				scanning->sParam.dMCLK = dMCLK;
 | 
			
		||||
				Gain_Reg.Red    = a_bRegs[0x3b];
 | 
			
		||||
				Gain_Reg.Green  = a_bRegs[0x3c];
 | 
			
		||||
				Gain_Reg.Blue   = a_bRegs[0x3d];
 | 
			
		||||
				Gain_Reg.Red    = regs[0x3b];
 | 
			
		||||
				Gain_Reg.Green  = regs[0x3c];
 | 
			
		||||
				Gain_Reg.Blue   = regs[0x3d];
 | 
			
		||||
				Gain_NegHilight = Gain_Hilight;
 | 
			
		||||
			
 | 
			
		||||
				DBG( _DBG_INFO, "MCLK      = %.3f\n", dMCLK );
 | 
			
		||||
				DBG( _DBG_INFO, "GainRed   = %u\n", a_bRegs[0x3b] );
 | 
			
		||||
				DBG( _DBG_INFO, "GainGreen = %u\n", a_bRegs[0x3c] );
 | 
			
		||||
				DBG( _DBG_INFO, "GainBlue  = %u\n", a_bRegs[0x3d] );
 | 
			
		||||
				DBG( _DBG_INFO, "GainRed   = %u\n", regs[0x3b] );
 | 
			
		||||
				DBG( _DBG_INFO, "GainGreen = %u\n", regs[0x3c] );
 | 
			
		||||
				DBG( _DBG_INFO, "GainBlue  = %u\n", regs[0x3d] );
 | 
			
		||||
 | 
			
		||||
    #if 0
 | 
			
		||||
    			if( !usb_ModuleMove( dev, MOVE_Backward,
 | 
			
		||||
| 
						 | 
				
			
			@ -2479,14 +2488,14 @@ static int usb_DoCalibration( Plustek_Device *dev )
 | 
			
		|||
    				return _E_LAMP_NOT_IN_POS;
 | 
			
		||||
    			}
 | 
			
		||||
    #endif
 | 
			
		||||
				a_bRegs[0x45] &= ~0x10;
 | 
			
		||||
				regs[0x45] &= ~0x10;
 | 
			
		||||
 | 
			
		||||
				a_bRegs[0x3b] = a_bRegs[0x3c] = a_bRegs[0x3d] = 1;
 | 
			
		||||
				regs[0x3b] = regs[0x3c] = regs[0x3d] = 1;
 | 
			
		||||
 | 
			
		||||
				if(!usb_AdjustGain( dev, 1 ))
 | 
			
		||||
					return _E_INTERNAL;
 | 
			
		||||
				
 | 
			
		||||
				a_bRegs[0x3b] = a_bRegs[0x3c] = a_bRegs[0x3d] = 1;
 | 
			
		||||
				regs[0x3b] = regs[0x3c] = regs[0x3d] = 1;
 | 
			
		||||
 | 
			
		||||
				DBG( _DBG_INFO, "Settings done, so start...\n" );
 | 
			
		||||
				if( !usb_AdjustOffset(dev) || !usb_AdjustDarkShading(dev) ||
 | 
			
		||||
| 
						 | 
				
			
			@ -2663,8 +2672,8 @@ static int usb_DoCalibration( Plustek_Device *dev )
 | 
			
		|||
    							((scanning->sParam.bBitDepth == 8 && 
 | 
			
		||||
								 (scanning->sParam.PhyDpi.x == 200 ||scanning->sParam.PhyDpi.x == 300))))
 | 
			
		||||
    							hw->wLineEnd = 7000;
 | 
			
		||||
    						a_bRegs[0x20] = _HIBYTE(hw->wLineEnd);
 | 
			
		||||
    						a_bRegs[0x21] = _LOBYTE(hw->wLineEnd);
 | 
			
		||||
    						regs[0x20] = _HIBYTE(hw->wLineEnd);
 | 
			
		||||
    						regs[0x21] = _LOBYTE(hw->wLineEnd);
 | 
			
		||||
 | 
			
		||||
    						if( scanning->sParam.PhyDpi.x > 300 ) {
 | 
			
		||||
    							if (scanning->sParam.bBitDepth > 8)
 | 
			
		||||
| 
						 | 
				
			
			@ -2693,7 +2702,7 @@ static int usb_DoCalibration( Plustek_Device *dev )
 | 
			
		|||
    						scanning->sParam.dMCLK = dMCLK = 6.0;
 | 
			
		||||
    					else {
 | 
			
		||||
    						scanning->sParam.dMCLK = dMCLK = 5.0;
 | 
			
		||||
    						a_bRegs[0x0a] = 1;
 | 
			
		||||
    						regs[0x0a] = 1;
 | 
			
		||||
    					}
 | 
			
		||||
    				} else {
 | 
			
		||||
    					if( scanning->sParam.PhyDpi.x <= 300)
 | 
			
		||||
| 
						 | 
				
			
			@ -2741,20 +2750,20 @@ static int usb_DoCalibration( Plustek_Device *dev )
 | 
			
		|||
		else /* if( scaps->bCCD == kNEC3799) */
 | 
			
		||||
			usb_ModuleMove( dev, MOVE_Forward, 3 * 300 + 38 );
 | 
			
		||||
 | 
			
		||||
		usb_MotorOn( dev->fd, SANE_FALSE );
 | 
			
		||||
		usb_MotorOn( dev, SANE_FALSE );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	scanning->fCalibrated = SANE_TRUE;
 | 
			
		||||
	DBG( _DBG_INFO, "Calibration done\n" );
 | 
			
		||||
	DBG( _DBG_INFO, "-----------------------\n" );
 | 
			
		||||
	DBG( _DBG_INFO, "Static Gain:\n" );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x3b] = %u\n", a_bRegs[0x3b] );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x3c] = %u\n", a_bRegs[0x3c] );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x3d] = %u\n", a_bRegs[0x3d] );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x3b] = %u\n", regs[0x3b] );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x3c] = %u\n", regs[0x3c] );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x3d] = %u\n", regs[0x3d] );
 | 
			
		||||
	DBG( _DBG_INFO, "Static Offset:\n" );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x38] = %u\n", a_bRegs[0x38] );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x39] = %u\n", a_bRegs[0x39] );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x3a] = %u\n", a_bRegs[0x3a] );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x38] = %u\n", regs[0x38] );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x39] = %u\n", regs[0x39] );
 | 
			
		||||
	DBG( _DBG_INFO, "REG[0x3a] = %u\n", regs[0x3a] );
 | 
			
		||||
	DBG( _DBG_INFO, "-----------------------\n" );
 | 
			
		||||
 | 
			
		||||
	return SANE_TRUE;
 | 
			
		||||
| 
						 | 
				
			
			@ -2769,6 +2778,7 @@ static SANE_Bool usb_DownloadShadingData( Plustek_Device *dev, u_char what )
 | 
			
		|||
	u_char    channel;
 | 
			
		||||
	pDCapsDef scaps = &dev->usbDev.Caps;
 | 
			
		||||
	pHWDef    hw    = &dev->usbDev.HwSetting;
 | 
			
		||||
	u_char   *regs  = dev->usbDev.a_bRegs;
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_INFO, "usb_DownloadShadingData(%u)\n", what );
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2781,31 +2791,31 @@ static SANE_Bool usb_DownloadShadingData( Plustek_Device *dev, u_char what )
 | 
			
		|||
		case PARAM_WhiteShading:
 | 
			
		||||
			if( m_ScanParam.bDataType == SCANDATATYPE_Color ) {
 | 
			
		||||
 | 
			
		||||
				usb_SetDarkShading( dev->fd, CHANNEL_red, a_wDarkShading,
 | 
			
		||||
				usb_SetDarkShading( dev, CHANNEL_red, a_wDarkShading,
 | 
			
		||||
									(u_short)m_ScanParam.Size.dwPhyPixels * 2);
 | 
			
		||||
				usb_SetDarkShading( dev->fd, CHANNEL_green, a_wDarkShading +
 | 
			
		||||
				usb_SetDarkShading( dev, CHANNEL_green, a_wDarkShading +
 | 
			
		||||
									m_ScanParam.Size.dwPhyPixels,
 | 
			
		||||
							 	    (u_short)m_ScanParam.Size.dwPhyPixels * 2);
 | 
			
		||||
				usb_SetDarkShading( dev->fd, CHANNEL_blue, a_wDarkShading +
 | 
			
		||||
				usb_SetDarkShading( dev, CHANNEL_blue, a_wDarkShading +
 | 
			
		||||
									m_ScanParam.Size.dwPhyPixels * 2,
 | 
			
		||||
								    (u_short)m_ScanParam.Size.dwPhyPixels * 2);
 | 
			
		||||
			} else {
 | 
			
		||||
				usb_SetDarkShading( dev->fd, channel, a_wDarkShading +
 | 
			
		||||
				usb_SetDarkShading( dev, channel, a_wDarkShading +
 | 
			
		||||
									m_ScanParam.Size.dwPhyPixels,
 | 
			
		||||
								    (u_short)m_ScanParam.Size.dwPhyPixels * 2);
 | 
			
		||||
			}
 | 
			
		||||
			a_bRegs[0x40] = 0x40;
 | 
			
		||||
			a_bRegs[0x41] = 0x00;
 | 
			
		||||
			regs[0x40] = 0x40;
 | 
			
		||||
			regs[0x41] = 0x00;
 | 
			
		||||
 | 
			
		||||
			/* set RAM configuration AND
 | 
			
		||||
             * Gain = Multiplier Coefficient/16384
 | 
			
		||||
             * CFG Register 0x40/0x41 for Multiplier Coefficient Source
 | 
			
		||||
             * External DRAM for Offset Coefficient Source
 | 
			
		||||
             */
 | 
			
		||||
			a_bRegs[0x42] = (u_char)(( hw->wDRAMSize > 512)? 0x64: 0x24);
 | 
			
		||||
			regs[0x42] = (u_char)(( hw->wDRAMSize > 512)? 0x64: 0x24);
 | 
			
		||||
 | 
			
		||||
			_UIO(sanei_lm983x_write( dev->fd, 0x40,
 | 
			
		||||
									 &a_bRegs[0x40], 0x42-0x40+1, SANE_TRUE ));
 | 
			
		||||
									 ®s[0x40], 0x42-0x40+1, SANE_TRUE ));
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case PARAM_Scan:
 | 
			
		||||
| 
						 | 
				
			
			@ -2823,15 +2833,15 @@ static SANE_Bool usb_DownloadShadingData( Plustek_Device *dev, u_char what )
 | 
			
		|||
		             * CFG Register 0x40/0x41 for Multiplier Coefficient Source
 | 
			
		||||
        		     * CFG Register 0x3e/0x3f for Offset Coefficient Source
 | 
			
		||||
		             */
 | 
			
		||||
					a_bRegs[0x03] = 0;
 | 
			
		||||
					a_bRegs[0x40] = 0x40;
 | 
			
		||||
					a_bRegs[0x41] = 0x00;
 | 
			
		||||
					a_bRegs[0x42] = (u_char)((hw->wDRAMSize > 512)? 0x61:0x21);
 | 
			
		||||
					if( !usbio_WriteReg( dev->fd, 0x03, a_bRegs[0x03]))
 | 
			
		||||
					regs[0x03] = 0;
 | 
			
		||||
					regs[0x40] = 0x40;
 | 
			
		||||
					regs[0x41] = 0x00;
 | 
			
		||||
					regs[0x42] = (u_char)((hw->wDRAMSize > 512)? 0x61:0x21);
 | 
			
		||||
					if( !usbio_WriteReg( dev->fd, 0x03, regs[0x03]))
 | 
			
		||||
						return SANE_FALSE;
 | 
			
		||||
 | 
			
		||||
					_UIO(sanei_lm983x_write( dev->fd, 0x40,
 | 
			
		||||
											 &a_bRegs[0x40], 3, SANE_TRUE));
 | 
			
		||||
											 ®s[0x40], 3, SANE_TRUE));
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2840,9 +2850,9 @@ static SANE_Bool usb_DownloadShadingData( Plustek_Device *dev, u_char what )
 | 
			
		|||
 | 
			
		||||
				if( scaps->workaroundFlag & _WAF_SKIP_FINE ) {
 | 
			
		||||
					DBG( _DBG_INFO, "Skipping fine calibration\n" );
 | 
			
		||||
    				a_bRegs[0x42] = (u_char)(( hw->wDRAMSize > 512)? 0x60: 0x20);
 | 
			
		||||
    				regs[0x42] = (u_char)(( hw->wDRAMSize > 512)? 0x60: 0x20);
 | 
			
		||||
        
 | 
			
		||||
					if( !usbio_WriteReg( dev->fd, 0x42, a_bRegs[0x42]))
 | 
			
		||||
					if( !usbio_WriteReg( dev->fd, 0x42, regs[0x42]))
 | 
			
		||||
						return SANE_FALSE;
 | 
			
		||||
 | 
			
		||||
					break;						
 | 
			
		||||
| 
						 | 
				
			
			@ -2852,33 +2862,33 @@ static SANE_Bool usb_DownloadShadingData( Plustek_Device *dev, u_char what )
 | 
			
		|||
 | 
			
		||||
				/* Download the dark & white shadings to LM983x */
 | 
			
		||||
				if( pParam->bDataType == SCANDATATYPE_Color ) {
 | 
			
		||||
					usb_SetDarkShading( dev->fd, CHANNEL_red, a_wDarkShading,
 | 
			
		||||
					usb_SetDarkShading( dev, CHANNEL_red, a_wDarkShading,
 | 
			
		||||
									(u_short)m_ScanParam.Size.dwPhyPixels * 2);
 | 
			
		||||
					usb_SetDarkShading( dev->fd, CHANNEL_green,
 | 
			
		||||
					usb_SetDarkShading( dev, CHANNEL_green,
 | 
			
		||||
									a_wDarkShading + m_dwPixels,
 | 
			
		||||
									(u_short)m_ScanParam.Size.dwPhyPixels * 2);
 | 
			
		||||
					usb_SetDarkShading( dev->fd, CHANNEL_blue,
 | 
			
		||||
					usb_SetDarkShading( dev, CHANNEL_blue,
 | 
			
		||||
										a_wDarkShading + m_dwPixels * 2,
 | 
			
		||||
									(u_short)m_ScanParam.Size.dwPhyPixels * 2);
 | 
			
		||||
				} else {
 | 
			
		||||
					usb_SetDarkShading( dev->fd, channel,
 | 
			
		||||
					usb_SetDarkShading( dev, channel,
 | 
			
		||||
										a_wDarkShading + m_dwPixels,
 | 
			
		||||
									(u_short)m_ScanParam.Size.dwPhyPixels * 2);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if( pParam->bDataType == SCANDATATYPE_Color ) {
 | 
			
		||||
					usb_SetWhiteShading( dev->fd, CHANNEL_red, a_wWhiteShading,
 | 
			
		||||
					usb_SetWhiteShading( dev, CHANNEL_red, a_wWhiteShading,
 | 
			
		||||
									(u_short)m_ScanParam.Size.dwPhyPixels * 2);
 | 
			
		||||
					usb_SetWhiteShading( dev->fd, CHANNEL_green,
 | 
			
		||||
					usb_SetWhiteShading( dev, CHANNEL_green,
 | 
			
		||||
										 a_wWhiteShading +
 | 
			
		||||
										 m_ScanParam.Size.dwPhyPixels,
 | 
			
		||||
									(u_short)m_ScanParam.Size.dwPhyPixels * 2);
 | 
			
		||||
					usb_SetWhiteShading( dev->fd, CHANNEL_blue,
 | 
			
		||||
					usb_SetWhiteShading( dev, CHANNEL_blue,
 | 
			
		||||
									     a_wWhiteShading +
 | 
			
		||||
										 m_ScanParam.Size.dwPhyPixels * 2,
 | 
			
		||||
									(u_short)m_ScanParam.Size.dwPhyPixels * 2);
 | 
			
		||||
				} else {
 | 
			
		||||
					usb_SetWhiteShading( dev->fd, channel, a_wWhiteShading,
 | 
			
		||||
					usb_SetWhiteShading( dev, channel, a_wWhiteShading,
 | 
			
		||||
									(u_short)m_ScanParam.Size.dwPhyPixels * 2);
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
| 
						 | 
				
			
			@ -2887,33 +2897,33 @@ static SANE_Bool usb_DownloadShadingData( Plustek_Device *dev, u_char what )
 | 
			
		|||
				 * External DRAM for Multiplier Coefficient Source
 | 
			
		||||
				 * External DRAM for Offset Coefficient Source
 | 
			
		||||
				 */
 | 
			
		||||
				a_bRegs[0x42] = (u_char)((hw->wDRAMSize > 512)? 0x66: 0x26);
 | 
			
		||||
				regs[0x42] = (u_char)((hw->wDRAMSize > 512)? 0x66: 0x26);
 | 
			
		||||
 | 
			
		||||
				if( scaps->workaroundFlag & _WAF_SKIP_WHITEFINE ) {
 | 
			
		||||
					DBG( _DBG_INFO,"Skipping fine white calibration result\n");
 | 
			
		||||
					a_bRegs[0x42] = (u_char)(( hw->wDRAMSize > 512)? 0x64: 0x24);
 | 
			
		||||
					regs[0x42] = (u_char)(( hw->wDRAMSize > 512)? 0x64: 0x24);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if( !usbio_WriteReg( dev->fd, 0x42, a_bRegs[0x42]))
 | 
			
		||||
				if( !usbio_WriteReg( dev->fd, 0x42, regs[0x42]))
 | 
			
		||||
					return SANE_FALSE;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		default:
 | 
			
		||||
			/* for coarse calibration and "black fine" */
 | 
			
		||||
			a_bRegs[0x3e] = 0;
 | 
			
		||||
			a_bRegs[0x3f] = 0;
 | 
			
		||||
			a_bRegs[0x40] = 0x40;
 | 
			
		||||
			a_bRegs[0x41] = 0x00;
 | 
			
		||||
			regs[0x3e] = 0;
 | 
			
		||||
			regs[0x3f] = 0;
 | 
			
		||||
			regs[0x40] = 0x40;
 | 
			
		||||
			regs[0x41] = 0x00;
 | 
			
		||||
 | 
			
		||||
			/* set RAM configuration AND
 | 
			
		||||
			 * GAIN = Multiplier Coefficient/16384
 | 
			
		||||
			 * CFG Register 0x40/0x41 for Multiplier Coefficient Source
 | 
			
		||||
			 * CFG Register 0x3e/0x3f for Offset Coefficient Source
 | 
			
		||||
			 */
 | 
			
		||||
			a_bRegs[0x42] = (u_char)((hw->wDRAMSize > 512)? 0x60: 0x20);
 | 
			
		||||
			regs[0x42] = (u_char)((hw->wDRAMSize > 512)? 0x60: 0x20);
 | 
			
		||||
 | 
			
		||||
			_UIO(sanei_lm983x_write( dev->fd, 0x3e, &a_bRegs[0x3e],
 | 
			
		||||
			_UIO(sanei_lm983x_write( dev->fd, 0x3e, ®s[0x3e],
 | 
			
		||||
									  0x42 - 0x3e + 1, SANE_TRUE ));
 | 
			
		||||
			break;									
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -71,6 +71,7 @@
 | 
			
		|||
 *        - closing now writer pipe, when reader_process is done
 | 
			
		||||
 * - 0.48 - added additional options
 | 
			
		||||
 *          split scanmode and bit-depth
 | 
			
		||||
 * - 0.49 - improved multi-device capability
 | 
			
		||||
 *.
 | 
			
		||||
 * <hr>
 | 
			
		||||
 * This file is part of the SANE package.
 | 
			
		||||
| 
						 | 
				
			
			@ -146,7 +147,7 @@
 | 
			
		|||
#include "../include/sane/sanei.h"
 | 
			
		||||
#include "../include/sane/saneopts.h"
 | 
			
		||||
 | 
			
		||||
#define BACKEND_VERSION "0.48-10"
 | 
			
		||||
#define BACKEND_VERSION "0.49-1"
 | 
			
		||||
#define BACKEND_NAME    plustek
 | 
			
		||||
#include "../include/sane/sanei_backend.h"
 | 
			
		||||
#include "../include/sane/sanei_config.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -177,7 +178,8 @@
 | 
			
		|||
#define _PLUSTEK_USB
 | 
			
		||||
 | 
			
		||||
/* declare it here, as it's used in plustek-usbscan.c too :-( */
 | 
			
		||||
static SANE_Bool cancelRead;
 | 
			
		||||
static SANE_Bool  cancelRead;
 | 
			
		||||
static DevList   *usbDevs;
 | 
			
		||||
 | 
			
		||||
/* the USB-stuff... I know this is in general no good idea, but it works */
 | 
			
		||||
#ifdef _PLUSTEK_USB
 | 
			
		||||
| 
						 | 
				
			
			@ -1173,7 +1175,7 @@ static SANE_Status attach( const char *dev_name,
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
	/* go ahead and open the scanner device */
 | 
			
		||||
	handle = usbDev_open( dev );
 | 
			
		||||
	handle = usbDev_open( dev, usbDevs );
 | 
			
		||||
	if( handle < 0 ) {
 | 
			
		||||
		DBG( _DBG_ERROR,"open failed: %d\n", handle );
 | 
			
		||||
		return SANE_STATUS_IO_ERROR;
 | 
			
		||||
| 
						 | 
				
			
			@ -1306,10 +1308,14 @@ sane_init( SANE_Int *version_code, SANE_Auth_Callback authorize )
 | 
			
		|||
	first_dev    = NULL;
 | 
			
		||||
	first_handle = NULL;
 | 
			
		||||
	num_devices  = 0;
 | 
			
		||||
	usbDevs      = NULL;
 | 
			
		||||
 | 
			
		||||
	/* initialize the configuration structure */                
 | 
			
		||||
	init_config_struct( &config );
 | 
			
		||||
 | 
			
		||||
	/* try and get a list of all connected AND supported devices */
 | 
			
		||||
	usbGetList( &usbDevs );
 | 
			
		||||
 | 
			
		||||
	if( version_code != NULL )
 | 
			
		||||
		*version_code = SANE_VERSION_CODE(V_MAJOR, V_MINOR, 0);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1433,6 +1439,7 @@ sane_init( SANE_Int *version_code, SANE_Auth_Callback authorize )
 | 
			
		|||
void
 | 
			
		||||
sane_exit( void )
 | 
			
		||||
{
 | 
			
		||||
	DevList        *tmp;
 | 
			
		||||
	Plustek_Device *dev, *next;
 | 
			
		||||
 | 
			
		||||
	DBG( _DBG_SANE_INIT, "sane_exit\n" );
 | 
			
		||||
| 
						 | 
				
			
			@ -1463,6 +1470,12 @@ sane_exit( void )
 | 
			
		|||
	if( devlist )
 | 
			
		||||
		free( devlist );
 | 
			
		||||
 | 
			
		||||
	for( tmp = usbDevs;  tmp; tmp = usbDevs->next ) {
 | 
			
		||||
		free( usbDevs );
 | 
			
		||||
		usbDevs = tmp;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	usbDevs      = NULL;
 | 
			
		||||
	devlist      = NULL;
 | 
			
		||||
	auth         = NULL;
 | 
			
		||||
	first_dev    = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -2114,7 +2127,7 @@ sane_start( SANE_Handle handle )
 | 
			
		|||
 | 
			
		||||
	/* open the driver and get some information about the scanner
 | 
			
		||||
	 */
 | 
			
		||||
	dev->fd = usbDev_open( dev );
 | 
			
		||||
	dev->fd = usbDev_open( dev, NULL );
 | 
			
		||||
	if( dev->fd < 0 ) {
 | 
			
		||||
		DBG( _DBG_ERROR,"sane_start: open failed: %d\n", errno );
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,6 +52,7 @@
 | 
			
		|||
 *        - moved SCANDEF definitions to plustek-usb.h
 | 
			
		||||
 *        - removed function pointer
 | 
			
		||||
 *        - added OPT_BIT_DEPTH
 | 
			
		||||
 * - 0.49 - added typedef struct DevList
 | 
			
		||||
 * .
 | 
			
		||||
 * <hr>
 | 
			
		||||
 * This file is part of the SANE package.
 | 
			
		||||
| 
						 | 
				
			
			@ -391,6 +392,15 @@ typedef struct {
 | 
			
		|||
 | 
			
		||||
} CnfDef, *pCnfDef;
 | 
			
		||||
 | 
			
		||||
/** for supported device list
 | 
			
		||||
 */
 | 
			
		||||
typedef struct DevList {
 | 
			
		||||
	SANE_Word       vendor_id;
 | 
			
		||||
	SANE_Word       device_id;
 | 
			
		||||
	SANE_Bool       attached;
 | 
			
		||||
	SANE_Char      *dev_name;
 | 
			
		||||
	struct DevList *next;
 | 
			
		||||
} DevList;
 | 
			
		||||
#endif	/* guard __PLUSTEK_H__ */
 | 
			
		||||
 | 
			
		||||
/* END PLUSTEK.H.............................................................*/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue