kopia lustrzana https://gitlab.com/sane-project/backends
				
				
				
			
		
			
				
	
	
		
			777 wiersze
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			777 wiersze
		
	
	
		
			25 KiB
		
	
	
	
		
			C
		
	
	
/* @file plustek-pp_p12.c
 | 
						|
 * @brief p12 and pt12 specific stuff
 | 
						|
 *
 | 
						|
 * based on sources acquired from Plustek Inc.
 | 
						|
 * Copyright (C) 2000 Plustek Inc.
 | 
						|
 * Copyright (C) 2001-2013 Gerhard Jaeger <gerhard@gjaeger.de>
 | 
						|
 *
 | 
						|
 * History:
 | 
						|
 * - 0.38 - initial version
 | 
						|
 * - 0.39 - added Genius Colorpage Vivid III V2 stuff
 | 
						|
 * - 0.40 - no changes
 | 
						|
 * - 0.41 - no changes
 | 
						|
 * - 0.42 - removed setting of ps->sCaps.dwFlag in p12InitiateComponentModel()
 | 
						|
 * - 0.43 - no changes
 | 
						|
 * - 0.44 - fix format string issues, as Long types default to int32_t
 | 
						|
 *          now
 | 
						|
 * .
 | 
						|
 * <hr>
 | 
						|
 * This file is part of the SANE package.
 | 
						|
 *
 | 
						|
 * This program is free software; you can redistribute it and/or
 | 
						|
 * modify it under the terms of the GNU General Public License as
 | 
						|
 * published by the Free Software Foundation; either version 2 of the
 | 
						|
 * License, or (at your option) any later version.
 | 
						|
 *
 | 
						|
 * This program is distributed in the hope that it will be useful, but
 | 
						|
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
 * General Public License for more details.
 | 
						|
 *
 | 
						|
 * You should have received a copy of the GNU General Public License
 | 
						|
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
						|
 *
 | 
						|
 * As a special exception, the authors of SANE give permission for
 | 
						|
 * additional uses of the libraries contained in this release of SANE.
 | 
						|
 *
 | 
						|
 * The exception is that, if you link a SANE library with other files
 | 
						|
 * to produce an executable, this does not by itself cause the
 | 
						|
 * resulting executable to be covered by the GNU General Public
 | 
						|
 * License.  Your use of that executable is in no way restricted on
 | 
						|
 * account of linking the SANE library code into it.
 | 
						|
 *
 | 
						|
 * This exception does not, however, invalidate any other reasons why
 | 
						|
 * the executable file might be covered by the GNU General Public
 | 
						|
 * License.
 | 
						|
 *
 | 
						|
 * If you submit changes to SANE to the maintainers to be included in
 | 
						|
 * a subsequent release, you agree by submitting the changes that
 | 
						|
 * those changes may be distributed with this exception intact.
 | 
						|
 *
 | 
						|
 * If you write modifications of your own for SANE, it is your choice
 | 
						|
 * whether to permit this exception to apply to your modifications.
 | 
						|
 * If you do not wish that, delete this exception notice.
 | 
						|
 * <hr>
 | 
						|
 */
 | 
						|
#include "plustek-pp_scan.h"
 | 
						|
 | 
						|
/*************************** some local vars *********************************/
 | 
						|
 | 
						|
static RegDef p12CcdStop[] = {
 | 
						|
    {0x41, 0xff}, {0x42, 0xff}, {0x60, 0xff}, {0x61, 0xff},
 | 
						|
    {0x4b, 0xff}, {0x4c, 0xff}, {0x4d, 0xff}, {0x4e, 0xff},
 | 
						|
    {0x2a, 0x01}, {0x2b, 0x00}, {0x2d, 0x00}, {0x1b, 0x19}, {0x15, 0x00}
 | 
						|
};
 | 
						|
 | 
						|
/*************************** local functions *********************************/
 | 
						|
 | 
						|
/** init the stuff according to the buttons
 | 
						|
 */
 | 
						|
static void p12ButtonSetup( pScanData ps, Byte nrOfButtons )
 | 
						|
{
 | 
						|
    ps->Device.buttons = nrOfButtons;
 | 
						|
 | 
						|
    ps->Device.Model1Mono  &= ~_BUTTON_MODE;
 | 
						|
    ps->Device.Model1Color &= ~_BUTTON_MODE;
 | 
						|
 | 
						|
    ps->AsicReg.RD_MotorDriverType |= _BUTTON_DISABLE;
 | 
						|
    ps->Scan.motorPower            |= _BUTTON_DISABLE;
 | 
						|
}
 | 
						|
 | 
						|
/** According to what we have detected, set the other stuff
 | 
						|
 */
 | 
						|
static void p12InitiateComponentModel( pScanData ps )
 | 
						|
{
 | 
						|
    /* preset some stuff and do the differences later */
 | 
						|
    ps->Device.buttons        = 0;
 | 
						|
    ps->Device.Model1Mono     = _BUTTON_MODE + _CCD_SHIFT_GATE + _SCAN_GRAYTYPE;
 | 
						|
    ps->Device.Model1Color    = _BUTTON_MODE + _CCD_SHIFT_GATE;
 | 
						|
    ps->Device.dwModelOriginY = 64;
 | 
						|
    ps->Device.fTpa           = _FALSE;
 | 
						|
    ps->Device.ModelCtrl      = (_LED_ACTIVITY | _LED_CONTROL);
 | 
						|
 | 
						|
	/* ps->sCaps.dwFlag should have been set correctly in models.c */
 | 
						|
 | 
						|
    switch( ps->Device.bPCBID ) {
 | 
						|
 | 
						|
	case _PLUSTEK_SCANNER:
 | 
						|
    	DBG( DBG_LOW, "We have a Plustek Scanner\n" );
 | 
						|
        ps->sCaps.Model = MODEL_OP_P12;
 | 
						|
	    break;
 | 
						|
 | 
						|
	case _SCANNER_WITH_TPA:
 | 
						|
    	DBG( DBG_LOW, "Scanner has TPA\n" );
 | 
						|
	    ps->Device.fTpa   = _TRUE;
 | 
						|
	    ps->sCaps.dwFlag |= SFLAG_TPA;
 | 
						|
	    break;
 | 
						|
 | 
						|
	case _SCANNER4Button:
 | 
						|
    	DBG( DBG_LOW, "Scanner has 4 Buttons\n" );
 | 
						|
	    p12ButtonSetup( ps, 4 );
 | 
						|
	    break;
 | 
						|
 | 
						|
	case _SCANNER4ButtonTPA:
 | 
						|
    	DBG( DBG_LOW, "Scanner has 4 Buttons & TPA\n" );
 | 
						|
	    ps->Device.fTpa   = _TRUE;
 | 
						|
	    ps->sCaps.dwFlag |= SFLAG_TPA;
 | 
						|
	    p12ButtonSetup( ps, 4 );
 | 
						|
	    break;
 | 
						|
 | 
						|
	case _SCANNER5Button:
 | 
						|
    	DBG( DBG_LOW, "Scanner has 5 Buttons\n" );
 | 
						|
	    ps->Device.dwModelOriginY = 64 + 20;
 | 
						|
	    p12ButtonSetup( ps, 5 );
 | 
						|
	    break;
 | 
						|
 | 
						|
	case _SCANNER5ButtonTPA:
 | 
						|
    	DBG( DBG_LOW, "Scanner has 5 Buttons & TPA\n" );
 | 
						|
	    ps->Device.dwModelOriginY = 64 + 20;
 | 
						|
	    ps->Device.fTpa           = _TRUE;
 | 
						|
	    ps->sCaps.dwFlag         |= SFLAG_TPA;
 | 
						|
	    p12ButtonSetup( ps, 5 );
 | 
						|
	    break;
 | 
						|
 | 
						|
	case _SCANNER1Button:
 | 
						|
    	DBG( DBG_LOW, "Scanner has 1 Button\n" );
 | 
						|
	    p12ButtonSetup( ps, 1 );
 | 
						|
	    break;
 | 
						|
 | 
						|
	case _SCANNER1ButtonTPA:
 | 
						|
    	DBG( DBG_LOW, "Scanner has 1 Button & TPA\n" );
 | 
						|
        ps-> Device.fTpa  = _TRUE;
 | 
						|
	    ps->sCaps.dwFlag |= SFLAG_TPA;
 | 
						|
	    p12ButtonSetup( ps, 1 );
 | 
						|
	    break;
 | 
						|
 | 
						|
	case _AGFA_SCANNER:
 | 
						|
    	DBG( DBG_LOW, "Agfa Scanner\n" );
 | 
						|
	    ps->Device.dwModelOriginY = 24; 	/* 1200 dpi */
 | 
						|
	    break;
 | 
						|
 | 
						|
	case _SCANNER2Button:
 | 
						|
    	DBG( DBG_LOW, "Scanner has 2 Buttons\n" );
 | 
						|
    	DBG( DBG_LOW, "Seems we have a Genius Colorpage Vivid III V2\n" );
 | 
						|
	    ps->Device.dwModelOriginY = 64 - 33;
 | 
						|
	    p12ButtonSetup( ps, 2 );
 | 
						|
        ps->sCaps.Model = MODEL_GEN_CPV2;
 | 
						|
	    break;
 | 
						|
 | 
						|
    default:
 | 
						|
    	DBG( DBG_LOW, "Default Model: P12\n" );
 | 
						|
        ps->sCaps.Model = MODEL_OP_P12;
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    if( _MOTOR0_2003 == ps->Device.bMotorID ) {
 | 
						|
    	ps->Device.f2003      = _TRUE;
 | 
						|
    	ps->Device.XStepMono  = 10;
 | 
						|
	    ps->Device.XStepColor = 6;
 | 
						|
    	ps->Device.XStepBack  = 5;
 | 
						|
	    ps->AsicReg.RD_MotorDriverType |= _MOTORR_STRONG;
 | 
						|
    } else {
 | 
						|
    	ps->Device.f2003      = _FALSE;
 | 
						|
    	ps->Device.XStepMono  = 8;
 | 
						|
	    ps->Device.XStepColor = 4;
 | 
						|
    	ps->Device.XStepBack  = 5;
 | 
						|
	    ps->AsicReg.RD_MotorDriverType |= _MOTORR_WEAK;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/*.............................................................................
 | 
						|
 * prepare all the necessary variables -
 | 
						|
 */
 | 
						|
static void p12SetupScannerVariables( pScanData ps )
 | 
						|
{
 | 
						|
	DBG( DBG_LOW, "p12SetupScannerVariables()\n" );
 | 
						|
 | 
						|
    /*
 | 
						|
     * these values were originally altered by registry entries (NT-driver)
 | 
						|
     * and used to adjust the picture position...
 | 
						|
     */
 | 
						|
    ps->Device.lUpNormal   = 0;
 | 
						|
    ps->Device.lUpNegative = 20;
 | 
						|
    ps->Device.lUpPositive = -30;
 | 
						|
 | 
						|
    ps->Device.lLeftNormal = 51;
 | 
						|
 | 
						|
    ps->OpenScanPath( ps );
 | 
						|
	ps->ReInitAsic( ps, _FALSE );
 | 
						|
    ps->CloseScanPath( ps );
 | 
						|
}
 | 
						|
 | 
						|
/*.............................................................................
 | 
						|
 *
 | 
						|
 */
 | 
						|
static void p12SetupScanningCondition( pScanData ps )
 | 
						|
{
 | 
						|
    TimerDef timer;
 | 
						|
    ULong    channel;
 | 
						|
    Byte	 bState;
 | 
						|
    pUChar	 pState = ps->Bufs.b1.pReadBuf;
 | 
						|
 | 
						|
	DBG( DBG_LOW, "p12SetupScanningCondition()\n" );
 | 
						|
 | 
						|
    P12SetGeneralRegister( ps );
 | 
						|
 | 
						|
    IORegisterToScanner( ps, ps->RegResetMTSC );
 | 
						|
 | 
						|
    /* ------- Setup MinRead/MaxRead Fifo size ------- */
 | 
						|
    if( ps->DataInf.wPhyDataType <= COLOR_TRUE24 ) {
 | 
						|
    	ps->Scan.dwMaxReadFifo =
 | 
						|
	    ps->Scan.dwMinReadFifo = ps->DataInf.dwAsicBytesPerPlane * 2;
 | 
						|
    } else {
 | 
						|
    	ps->Scan.dwMaxReadFifo =
 | 
						|
	    ps->Scan.dwMinReadFifo = ps->DataInf.dwAppPixelsPerLine << 1;
 | 
						|
    }
 | 
						|
 | 
						|
    if( ps->Scan.dwMinReadFifo < 1024)
 | 
						|
    	ps->Scan.dwMinReadFifo = ps->Scan.dwMaxReadFifo = 1024;
 | 
						|
 | 
						|
    ps->Scan.dwMaxReadFifo += (ps->DataInf.dwAsicBytesPerPlane / 2);
 | 
						|
 | 
						|
 | 
						|
	DBG( DBG_LOW, "MinReadFifo=%u, MaxReadFifo=%u\n",
 | 
						|
         ps->Scan.dwMinReadFifo, ps->Scan.dwMaxReadFifo );
 | 
						|
 | 
						|
    /* ------- Set the max. read fifo to asic ------- */
 | 
						|
    if( ps->DataInf.wPhyDataType > COLOR_256GRAY ) {
 | 
						|
 | 
						|
    	ps->Scan.bFifoSelect = ps->RegBFifoOffset;
 | 
						|
 | 
						|
    	if( !ps->Scan.p48BitBuf.pb ) {
 | 
						|
 | 
						|
    	    Long lRed, lGreen;
 | 
						|
 | 
						|
    	    lRed = (_SIZE_REDFIFO - _SIZE_BLUEFIFO) /
 | 
						|
                    ps->DataInf.dwAsicBytesPerPlane - ps->Scan.bd_rk.wRedKeep;
 | 
						|
 | 
						|
    	    lGreen = (_SIZE_GREENFIFO - _SIZE_BLUEFIFO) /
 | 
						|
                    ps->DataInf.dwAsicBytesPerPlane - ps->Scan.gd_gk.wGreenKeep;
 | 
						|
 | 
						|
	        if((lRed < 0) || (lGreen < 0)) {
 | 
						|
 | 
						|
        		if( lRed < lGreen ) {
 | 
						|
        		    channel = _RED_FULLSIZE << 16;
 | 
						|
		            ps->AsicReg.RD_BufFullSize = _SIZE_REDFIFO;
 | 
						|
        		    lGreen = lRed;
 | 
						|
		        } else {
 | 
						|
        		    channel = _GREEN_FULLSIZE << 16;
 | 
						|
		            ps->AsicReg.RD_BufFullSize = _SIZE_GREENFIFO;
 | 
						|
        		}
 | 
						|
 | 
						|
                lGreen = (ULong)(-lGreen * ps->DataInf.dwAsicBytesPerPlane);
 | 
						|
 | 
						|
        		if(  ps->DataInf.wPhyDataType > COLOR_TRUE24 )
 | 
						|
		            lGreen >>= 1;
 | 
						|
 | 
						|
                ps->Scan.dwMinReadFifo += (ULong)lGreen;
 | 
						|
		        ps->Scan.dwMaxReadFifo += (ULong)lGreen;
 | 
						|
 | 
						|
    	    } else {
 | 
						|
       		    channel = _BLUE_FULLSIZE << 16;
 | 
						|
	            ps->AsicReg.RD_BufFullSize = _SIZE_BLUEFIFO;
 | 
						|
            }
 | 
						|
    	} else {
 | 
						|
   		    channel = _BLUE_FULLSIZE << 16;
 | 
						|
            ps->AsicReg.RD_BufFullSize = _SIZE_BLUEFIFO;
 | 
						|
       	}
 | 
						|
    } else {
 | 
						|
    	ps->Scan.bFifoSelect = ps->RegGFifoOffset;
 | 
						|
	    channel = _GREEN_FULLSIZE << 16;
 | 
						|
        ps->AsicReg.RD_BufFullSize = _SIZE_GRAYFIFO;
 | 
						|
    }
 | 
						|
 | 
						|
    ps->AsicReg.RD_BufFullSize -= (ps->DataInf.dwAsicBytesPerPlane << 1);
 | 
						|
 | 
						|
    if( ps->DataInf.wPhyDataType > COLOR_TRUE24 )
 | 
						|
    	ps->AsicReg.RD_BufFullSize >>= 1;
 | 
						|
 | 
						|
    ps->AsicReg.RD_BufFullSize |= channel;
 | 
						|
 | 
						|
    ps->Scan.bRefresh = (Byte)(ps->Scan.dwInterval << 1);
 | 
						|
    ps->AsicReg.RD_LineControl    = (_LOBYTE (ps->Shade.wExposure));
 | 
						|
    ps->AsicReg.RD_ExtLineControl = (_HIBYTE (ps->Shade.wExposure));
 | 
						|
    ps->AsicReg.RD_XStepTime      = (_LOBYTE (ps->Shade.wXStep));
 | 
						|
    ps->AsicReg.RD_ExtXStepTime   = (_HIBYTE (ps->Shade.wXStep));
 | 
						|
    ps->AsicReg.RD_Motor0Control  = _FORWARD_MOTOR;
 | 
						|
    ps->AsicReg.RD_StepControl    = _MOTOR0_SCANSTATE;
 | 
						|
    ps->AsicReg.RD_ModeControl    = (_ModeScan | _ModeFifoGSel);
 | 
						|
 | 
						|
    DBG( DBG_LOW, "bRefresh = %i\n", ps->Scan.bRefresh );
 | 
						|
 | 
						|
    if( ps->DataInf.wPhyDataType == COLOR_BW ) {
 | 
						|
    	ps->AsicReg.RD_ScanControl = _SCAN_BITMODE;
 | 
						|
 | 
						|
		if( !(ps->DataInf.dwScanFlag & SCANDEF_Inverse))
 | 
						|
			ps->AsicReg.RD_ScanControl |= _P98_SCANDATA_INVERT;
 | 
						|
 | 
						|
    } else if( ps->DataInf.wPhyDataType <= COLOR_TRUE24 )
 | 
						|
	    ps->AsicReg.RD_ScanControl = _SCAN_BYTEMODE;
 | 
						|
	else {
 | 
						|
	    ps->AsicReg.RD_ScanControl = _SCAN_12BITMODE;
 | 
						|
 | 
						|
        if(!(ps->DataInf.dwScanFlag & SCANDEF_RightAlign))
 | 
						|
	    	ps->AsicReg.RD_ScanControl |= _BITALIGN_LEFT;
 | 
						|
 | 
						|
    	if( ps->DataInf.dwScanFlag & SCANDEF_Inverse)
 | 
						|
    		ps->AsicReg.RD_ScanControl |= _P98_SCANDATA_INVERT;
 | 
						|
    }
 | 
						|
 | 
						|
    ps->AsicReg.RD_ScanControl |= _SCAN_1ST_AVERAGE;
 | 
						|
    IOSelectLampSource( ps );
 | 
						|
 | 
						|
	DBG( DBG_LOW, "RD_ScanControl = 0x%02x\n", ps->AsicReg.RD_ScanControl );
 | 
						|
 | 
						|
    ps->AsicReg.RD_MotorTotalSteps = (ULong)ps->DataInf.crImage.cy * 4 +
 | 
						|
                                 	 ((ps->Device.f0_8_16) ? 32 : 16) +
 | 
						|
                                     ((ps->Scan.bDiscardAll) ? 32 : 0);
 | 
						|
 | 
						|
    ps->AsicReg.RD_ScanControl1 = (_MTSC_ENABLE | _SCANSTOPONBUFFULL |
 | 
						|
                               	   _MFRC_RUNSCANSTATE | _MFRC_BY_XSTEP);
 | 
						|
 | 
						|
    ps->AsicReg.RD_Dpi = ps->DataInf.xyPhyDpi.x;
 | 
						|
 | 
						|
    if(!(ps->DataInf.dwScanFlag & SCANDEF_TPA )) {
 | 
						|
 | 
						|
    	ps->AsicReg.RD_Origin = (UShort)(ps->Device.lLeftNormal * 2 +
 | 
						|
    	                        		 ps->Device.DataOriginX +
 | 
						|
                    				     ps->DataInf.crImage.x );
 | 
						|
 | 
						|
    } else if( ps->DataInf.dwScanFlag & SCANDEF_Transparency ) {
 | 
						|
	    ps->AsicReg.RD_Origin =
 | 
						|
                            (UShort)(ps->Scan.posBegin + ps->DataInf.crImage.x);
 | 
						|
	} else {
 | 
						|
	    ps->AsicReg.RD_Origin =
 | 
						|
                            (UShort)(ps->Scan.negBegin + ps->DataInf.crImage.x);
 | 
						|
    }
 | 
						|
 | 
						|
    if( ps->Shade.bIntermediate & _ScanMode_AverageOut )
 | 
						|
    	ps->AsicReg.RD_Origin >>= 1;
 | 
						|
 | 
						|
    if( ps->DataInf.wPhyDataType == COLOR_BW )
 | 
						|
    	ps->AsicReg.RD_Pixels = (UShort)ps->DataInf.dwAsicBytesPerPlane;
 | 
						|
    else
 | 
						|
	    ps->AsicReg.RD_Pixels = (UShort)ps->DataInf.dwAppPixelsPerLine;
 | 
						|
 | 
						|
	DBG( DBG_LOW, "RD_Origin = %u, RD_Pixels = %u\n",
 | 
						|
					ps->AsicReg.RD_Origin, ps->AsicReg.RD_Pixels );
 | 
						|
 | 
						|
    /* ------- Prepare scan states ------- */
 | 
						|
    memset( ps->a_nbNewAdrPointer, 0, _SCANSTATE_BYTES );
 | 
						|
    memset( ps->Bufs.b1.pReadBuf,  0, _NUMBER_OF_SCANSTEPS );
 | 
						|
 | 
						|
    if( ps->DataInf.wPhyDataType <= COLOR_256GRAY )
 | 
						|
    	bState = (_SS_MONO | _SS_STEP);
 | 
						|
    else
 | 
						|
	    bState = (_SS_COLOR | _SS_STEP);
 | 
						|
 | 
						|
    for( channel = _NUMBER_OF_SCANSTEPS;
 | 
						|
                                    channel; channel -= ps->Scan.dwInterval ) {
 | 
						|
    	*pState = bState;
 | 
						|
	    if( ps->Scan.dwInterlace )
 | 
						|
	        pState[ ps->Scan.dwInterlace] = _SS_STEP;
 | 
						|
    	pState += ps->Scan.dwInterval;
 | 
						|
    }
 | 
						|
    for( channel = 0, pState = ps->Bufs.b1.pReadBuf;
 | 
						|
                                      channel < _SCANSTATE_BYTES; channel++)  {
 | 
						|
    	ps->a_nbNewAdrPointer[channel] = pState [0] | (pState [1] << 4);
 | 
						|
	    pState += 2;
 | 
						|
    }
 | 
						|
 | 
						|
    /* ------- Wait for scan state stop ------- */
 | 
						|
    MiscStartTimer( &timer, _SECOND * 2 );
 | 
						|
 | 
						|
    while(!(IOGetScanState( ps, _FALSE ) & _SCANSTATE_STOP) &&
 | 
						|
                                                    !MiscCheckTimer(&timer));
 | 
						|
 | 
						|
/* CHECK: Replace by IOPutAll.... */
 | 
						|
    IODownloadScanStates( ps );
 | 
						|
    IODataToRegister( ps, ps->RegLineControl, ps->AsicReg.RD_LineControl);
 | 
						|
    IODataToRegister( ps, ps->RegExtendedLineControl,
 | 
						|
                          ps->AsicReg.RD_ExtLineControl);
 | 
						|
    IODataToRegister( ps, ps->RegXStepTime, ps->AsicReg.RD_XStepTime);
 | 
						|
    IODataToRegister( ps, ps->RegExtendedXStep, ps->AsicReg.RD_ExtXStepTime);
 | 
						|
    IODataToRegister( ps, ps->RegMotorDriverType,
 | 
						|
                          ps->AsicReg.RD_MotorDriverType);
 | 
						|
    IODataToRegister( ps, ps->RegStepControl, ps->AsicReg.RD_StepControl);
 | 
						|
    IODataToRegister( ps, ps->RegMotor0Control, ps->AsicReg.RD_Motor0Control);
 | 
						|
    IODataToRegister( ps, ps->RegModelControl,ps->AsicReg.RD_ModelControl);
 | 
						|
    IODataToRegister( ps, ps->RegDpiLow,  (_LOBYTE(ps->AsicReg.RD_Dpi)));
 | 
						|
    IODataToRegister( ps, ps->RegDpiHigh, (_HIBYTE(ps->AsicReg.RD_Dpi)));
 | 
						|
    IODataToRegister( ps, ps->RegScanPosLow, (_LOBYTE(ps->AsicReg.RD_Origin)));
 | 
						|
    IODataToRegister( ps, ps->RegScanPosHigh,(_HIBYTE(ps->AsicReg.RD_Origin)));
 | 
						|
    IODataToRegister( ps, ps->RegWidthPixelsLow,
 | 
						|
                                             (_LOBYTE(ps->AsicReg.RD_Pixels)));
 | 
						|
    IODataToRegister( ps, ps->RegWidthPixelsHigh,
 | 
						|
                                             (_HIBYTE(ps->AsicReg.RD_Pixels)));
 | 
						|
    IODataToRegister( ps, ps->RegThresholdLow,
 | 
						|
                                   (_LOBYTE(ps->AsicReg.RD_ThresholdControl)));
 | 
						|
    IODataToRegister( ps, ps->RegThresholdHigh,
 | 
						|
                                   (_HIBYTE(ps->AsicReg.RD_ThresholdControl)));
 | 
						|
    IODataToRegister( ps, ps->RegMotorTotalStep0,
 | 
						|
                                    (_LOBYTE(ps->AsicReg.RD_MotorTotalSteps)));
 | 
						|
    IODataToRegister( ps, ps->RegMotorTotalStep1,
 | 
						|
                                    (_HIBYTE(ps->AsicReg.RD_MotorTotalSteps)));
 | 
						|
    IODataToRegister( ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl);
 | 
						|
 | 
						|
    IORegisterToScanner( ps, ps->RegInitDataFifo);
 | 
						|
}
 | 
						|
 | 
						|
/*.............................................................................
 | 
						|
 * program the CCD relevant stuff
 | 
						|
 */
 | 
						|
static void p12ProgramCCD( pScanData ps)
 | 
						|
{
 | 
						|
    UShort  w;
 | 
						|
    pRegDef rp;
 | 
						|
 | 
						|
    DBG( DBG_IO, "p12ProgramCCD: 0x%08lx[%lu]\n",
 | 
						|
            (unsigned long)ps->Device.pCCDRegisters,
 | 
						|
            ((unsigned long)ps->Device.wNumCCDRegs * ps->Shade.bIntermediate));
 | 
						|
 | 
						|
    DBG( DBG_IO, " %u regs * %u (intermediate)\n",
 | 
						|
                    ps->Device.wNumCCDRegs, ps->Shade.bIntermediate );
 | 
						|
 | 
						|
    rp = ps->Device.pCCDRegisters +
 | 
						|
         (ULong)ps->Device.wNumCCDRegs * ps->Shade.bIntermediate;
 | 
						|
 | 
						|
    for( w = ps->Device.wNumCCDRegs; w--; rp++ ) {
 | 
						|
 | 
						|
        DBG( DBG_IO, "[0x%02x] = 0x%02x\n", rp->bReg, rp->bParam );
 | 
						|
        IODataToRegister( ps, rp->bReg, rp->bParam );
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/*.............................................................................
 | 
						|
 * this initializes the ASIC and prepares the different functions for shading
 | 
						|
 * and scanning
 | 
						|
 */
 | 
						|
static void p12Init98003( pScanData ps, Bool shading )
 | 
						|
{
 | 
						|
	DBG( DBG_LOW, "p12InitP98003(%d)\n", shading );
 | 
						|
 | 
						|
    /* get DAC and motor stuff */
 | 
						|
    ps->Device.bDACType = IODataFromRegister( ps, ps->RegResetConfig );
 | 
						|
    ps->Device.bMotorID = (Byte)(ps->Device.bDACType & _MOTOR0_MASK);
 | 
						|
 | 
						|
    ps->AsicReg.RD_MotorDriverType  =
 | 
						|
                            (Byte)((ps->Device.bDACType & _MOTOR0_MASK) >> 3);
 | 
						|
    ps->AsicReg.RD_MotorDriverType |=
 | 
						|
                            (Byte)((ps->Device.bDACType & _MOTOR1_MASK) >> 1);
 | 
						|
 | 
						|
 | 
						|
    ps->Scan.motorPower = ps->AsicReg.RD_MotorDriverType | _MOTORR_STRONG;
 | 
						|
 | 
						|
    ps->Device.bDACType &= _ADC_MASK;
 | 
						|
 | 
						|
    /*get CCD and PCB ID */
 | 
						|
    ps->Device.bPCBID = IODataFromRegister( ps, ps->RegConfiguration );
 | 
						|
    ps->Device.bCCDID = ps->Device.bPCBID & 0x07;
 | 
						|
    ps->Device.bPCBID &= 0xf0;
 | 
						|
 | 
						|
    if( _AGFA_SCANNER == ps->Device.bPCBID )
 | 
						|
        ps->Device.bDACType = _DA_WOLFSON8141;
 | 
						|
 | 
						|
    DBG( DBG_LOW, "PCB-ID=0x%02x, CCD-ID=0x%02x, DAC-TYPE=0x%02x\n",
 | 
						|
                   ps->Device.bPCBID, ps->Device.bCCDID, ps->Device.bDACType );
 | 
						|
 | 
						|
    p12InitiateComponentModel( ps );
 | 
						|
 | 
						|
	/* encode the CCD-id into the flag parameter */
 | 
						|
    ps->sCaps.dwFlag |= ((ULong)(ps->Device.bCCDID | ps->Device.bPCBID) << 16);
 | 
						|
 | 
						|
    P12InitCCDandDAC( ps, shading );
 | 
						|
 | 
						|
    if( ps->Shade.bIntermediate & _ScanMode_Mono )
 | 
						|
    	ps->AsicReg.RD_Model1Control = ps->Device.Model1Mono;
 | 
						|
    else
 | 
						|
	    ps->AsicReg.RD_Model1Control = ps->Device.Model1Color;
 | 
						|
 | 
						|
    IODataToRegister( ps, ps->RegPllPredivider,  1 );
 | 
						|
    IODataToRegister( ps, ps->RegPllMaindivider, 0x20 );
 | 
						|
    IODataToRegister( ps, ps->RegPllPostdivider, 2 );
 | 
						|
    IODataToRegister( ps, ps->RegClockSelector,	 3 );		/* 2 */
 | 
						|
    IODataToRegister( ps, ps->RegMotorDriverType,
 | 
						|
                          ps->AsicReg.RD_MotorDriverType );
 | 
						|
 | 
						|
    /* this might be changed, def value is 11 */
 | 
						|
    IODataToRegister( ps, ps->RegWaitStateInsert, 11 );
 | 
						|
    IODataToRegister( ps, ps->RegModel1Control, ps->AsicReg.RD_Model1Control );
 | 
						|
 | 
						|
    p12ProgramCCD( ps );
 | 
						|
}
 | 
						|
 | 
						|
/*.............................................................................
 | 
						|
 * initialize the register values for the 98003 asic and preset other stuff
 | 
						|
 */
 | 
						|
static void p12InitializeAsicRegister( pScanData ps )
 | 
						|
{
 | 
						|
    memset( &ps->AsicReg, 0, sizeof(RegData));
 | 
						|
}
 | 
						|
 | 
						|
/*.............................................................................
 | 
						|
 * as the function name says
 | 
						|
 */
 | 
						|
static void p12PutToIdleMode( pScanData ps )
 | 
						|
{
 | 
						|
    ULong i;
 | 
						|
 | 
						|
    ps->OpenScanPath( ps );
 | 
						|
 | 
						|
    DBG( DBG_IO, "CCD-Stop\n" );
 | 
						|
 | 
						|
   for( i = 0; i < 13; i++ ) {
 | 
						|
 | 
						|
        DBG( DBG_IO, "[0x%02x] = 0x%02x\n",
 | 
						|
                        p12CcdStop[i].bReg, p12CcdStop[i].bParam );
 | 
						|
 | 
						|
        IODataToRegister( ps, p12CcdStop[i].bReg, p12CcdStop[i].bParam );
 | 
						|
    }
 | 
						|
 | 
						|
    ps->CloseScanPath( ps );
 | 
						|
}
 | 
						|
 | 
						|
/*.............................................................................
 | 
						|
 * here we simply call the WaitForShading function which performs this topic
 | 
						|
 */
 | 
						|
static int p12Calibration( pScanData ps )
 | 
						|
{
 | 
						|
    Bool result;
 | 
						|
 | 
						|
	DBG( DBG_LOW, "p12Calibration()\n" );
 | 
						|
 | 
						|
	/*
 | 
						|
	 * wait for shading to be done
 | 
						|
	 */
 | 
						|
    ps->OpenScanPath( ps );
 | 
						|
 | 
						|
	_ASSERT(ps->WaitForShading);
 | 
						|
	result = ps->WaitForShading( ps );
 | 
						|
    ps->CloseScanPath( ps );
 | 
						|
 | 
						|
	if( !result )
 | 
						|
		return _E_TIMEOUT;
 | 
						|
 | 
						|
    return _OK;
 | 
						|
}
 | 
						|
 | 
						|
/************************ exported functions *********************************/
 | 
						|
 | 
						|
/*.............................................................................
 | 
						|
 * initialize the register values and function calls for the 98003 asic
 | 
						|
 */
 | 
						|
_LOC int P12InitAsic( pScanData ps )
 | 
						|
{
 | 
						|
	int result;
 | 
						|
 | 
						|
	DBG( DBG_LOW, "P12InitAsic()\n" );
 | 
						|
 | 
						|
    /*
 | 
						|
     * preset the asic shadow registers
 | 
						|
     */
 | 
						|
    p12InitializeAsicRegister( ps );
 | 
						|
 | 
						|
	ps->IO.bOpenCount = 0;
 | 
						|
 | 
						|
	/*
 | 
						|
	 * setup the register values
 | 
						|
	 */
 | 
						|
	ps->RegSwitchBus 			= 0;
 | 
						|
  	ps->RegEPPEnable 			= 1;
 | 
						|
	ps->RegECPEnable 			= 2;
 | 
						|
	ps->RegReadDataMode 		= 3;
 | 
						|
	ps->RegWriteDataMode 		= 4;
 | 
						|
	ps->RegInitDataFifo 		= 5;
 | 
						|
	ps->RegForceStep 			= 6;
 | 
						|
	ps->RegInitScanState 		= 7;
 | 
						|
	ps->RegRefreshScanState 	= 8;
 | 
						|
	ps->RegWaitStateInsert 		= 0x0a;
 | 
						|
	ps->RegRFifoOffset 			= 0x0a;
 | 
						|
	ps->RegGFifoOffset 			= 0x0b;
 | 
						|
	ps->RegBFifoOffset 			= 0x0c;
 | 
						|
	ps->RegBitDepth 			= 0x13;
 | 
						|
	ps->RegStepControl 			= 0x14;
 | 
						|
	ps->RegMotor0Control 		= 0x15;
 | 
						|
	ps->RegXStepTime 			= 0x16;
 | 
						|
	ps->RegGetScanState 		= 0x17;
 | 
						|
	ps->RegAsicID 				= 0x18;
 | 
						|
	ps->RegMemoryLow 			= 0x19;
 | 
						|
	ps->RegMemoryHigh 			= 0x1a;
 | 
						|
	ps->RegModeControl 			= 0x1b;
 | 
						|
	ps->RegLineControl 			= 0x1c;
 | 
						|
	ps->RegScanControl 			= 0x1d;
 | 
						|
	ps->RegConfiguration 		= 0x1e;
 | 
						|
	ps->RegModelControl 		= 0x1f;
 | 
						|
	ps->RegModel1Control 		= 0x20;
 | 
						|
	ps->RegDpiLow 				= 0x21;
 | 
						|
	ps->RegDpiHigh 				= 0x22;
 | 
						|
	ps->RegScanPosLow 			= 0x23;
 | 
						|
	ps->RegScanPosHigh 			= 0x24;
 | 
						|
	ps->RegWidthPixelsLow 		= 0x25;
 | 
						|
	ps->RegWidthPixelsHigh 		= 0x26;
 | 
						|
	ps->RegThresholdLow 		= 0x27;
 | 
						|
	ps->RegThresholdHigh 		= 0x28;
 | 
						|
	ps->RegThresholdGapControl 	= 0x29;
 | 
						|
	ps->RegADCAddress 			= 0x2a;
 | 
						|
	ps->RegADCData 				= 0x2b;
 | 
						|
	ps->RegADCPixelOffset 		= 0x2c;
 | 
						|
	ps->RegADCSerialOutStr 		= 0x2d;
 | 
						|
	ps->RegResetConfig 			= 0x2e;
 | 
						|
	ps->RegLensPosition			= 0x2f;
 | 
						|
	ps->RegStatus 				= 0x30;
 | 
						|
	ps->RegScanStateControl 	= 0x31;
 | 
						|
	ps->RegRedChDarkOffsetLow 	= 0x33;
 | 
						|
	ps->RegRedChDarkOffsetHigh 	= 0x34;
 | 
						|
	ps->RegGreenChDarkOffsetLow = 0x35;
 | 
						|
	ps->RegGreenChDarkOffsetHigh= 0x36;
 | 
						|
	ps->RegBlueChDarkOffsetLow 	= 0x37;
 | 
						|
	ps->RegBlueChDarkOffsetHigh = 0x38;
 | 
						|
	ps->RegResetPulse0 			= 0x39;
 | 
						|
	ps->RegResetPulse1 			= 0x3a;
 | 
						|
	ps->RegCCDClampTiming0 		= 0x3b;
 | 
						|
	ps->RegCCDClampTiming1 		= 0x3c;
 | 
						|
	ps->RegVSMPTiming0 			= 0x41;
 | 
						|
	ps->RegVSMPTiming1 			= 0x42;
 | 
						|
	ps->RegCCDQ1Timing0 		= 0x43;
 | 
						|
	ps->RegCCDQ1Timing1 		= 0x44;
 | 
						|
	ps->RegCCDQ1Timing2 		= 0x45;
 | 
						|
	ps->RegCCDQ1Timing3 		= 0x46;
 | 
						|
	ps->RegCCDQ2Timing0 		= 0x47;
 | 
						|
	ps->RegCCDQ2Timing1 		= 0x48;
 | 
						|
	ps->RegCCDQ2Timing2 		= 0x49;
 | 
						|
	ps->RegCCDQ2Timing3 		= 0x4a;
 | 
						|
	ps->RegADCclockTiming0 		= 0x4b;
 | 
						|
	ps->RegADCclockTiming1		= 0x4c;
 | 
						|
	ps->RegADCclockTiming2 		= 0x4d;
 | 
						|
	ps->RegADCclockTiming3 		= 0x4e;
 | 
						|
	ps->RegADCDVTiming0 		= 0x50;
 | 
						|
	ps->RegADCDVTiming1 		= 0x51;
 | 
						|
	ps->RegADCDVTiming2 		= 0x52;
 | 
						|
	ps->RegADCDVTiming3 		= 0x53;
 | 
						|
 | 
						|
    ps->RegFifoFullLength0	    = 0x54;
 | 
						|
    ps->RegFifoFullLength1	    = 0x55;
 | 
						|
    ps->RegFifoFullLength2	    = 0x56;
 | 
						|
 | 
						|
    ps->RegMotorTotalStep0	    = 0x57;
 | 
						|
    ps->RegMotorTotalStep1	    = 0x58;
 | 
						|
    ps->RegMotorFreeRunCount0	= 0x59;
 | 
						|
    ps->RegMotorFreeRunCount1	= 0x5a;
 | 
						|
    ps->RegScanControl1	        = 0x5b;
 | 
						|
    ps->RegMotorFreeRunTrigger  = 0x5c;
 | 
						|
 | 
						|
    ps->RegResetMTSC		    = 0x5d;
 | 
						|
 | 
						|
    ps->RegMotor1Control	    = 0x62;
 | 
						|
    ps->RegMotor2Control	    = 0x63;
 | 
						|
    ps->RegMotorDriverType	    = 0x64;
 | 
						|
 | 
						|
    ps->RegStatus2		        = 0x66;
 | 
						|
 | 
						|
    ps->RegExtendedLineControl  = 0x6d;
 | 
						|
    ps->RegExtendedXStep	    = 0x6e;
 | 
						|
 | 
						|
    ps->RegPllPredivider	    = 0x71;
 | 
						|
    ps->RegPllMaindivider	    = 0x72;
 | 
						|
    ps->RegPllPostdivider	    = 0x73;
 | 
						|
    ps->RegClockSelector	    = 0x74;
 | 
						|
    ps->RegTestMode		        = 0xf0;
 | 
						|
 | 
						|
	/*
 | 
						|
	 * setup function calls
 | 
						|
	 */
 | 
						|
	ps->SetupScannerVariables  = p12SetupScannerVariables;
 | 
						|
	ps->SetupScanningCondition = p12SetupScanningCondition;
 | 
						|
    ps->Calibration            = p12Calibration;
 | 
						|
    ps->PutToIdleMode          = p12PutToIdleMode;
 | 
						|
	ps->ReInitAsic			   = p12Init98003;
 | 
						|
 | 
						|
	ps->CtrlReadHighNibble  = _CTRL_GENSIGNAL + _CTRL_AUTOLF + _CTRL_STROBE;
 | 
						|
	ps->CtrlReadLowNibble   = _CTRL_GENSIGNAL + _CTRL_AUTOLF;
 | 
						|
 | 
						|
	ps->IO.useEPPCmdMode = _FALSE;
 | 
						|
 | 
						|
	/*
 | 
						|
	 * initialize the other modules and set some
 | 
						|
	 * function pointer
 | 
						|
	 */
 | 
						|
	result = DacInitialize( ps );
 | 
						|
	if( _OK != result )
 | 
						|
		return result;
 | 
						|
 | 
						|
	result = ImageInitialize( ps );
 | 
						|
	if( _OK != result )
 | 
						|
		return result;
 | 
						|
 | 
						|
	result = IOFuncInitialize( ps );
 | 
						|
	if( _OK != result )
 | 
						|
		return result;
 | 
						|
 | 
						|
	result = IOInitialize( ps );
 | 
						|
	if( _OK != result )
 | 
						|
		return result;
 | 
						|
 | 
						|
	result = MotorInitialize( ps );
 | 
						|
	if( _OK != result )
 | 
						|
		return result;
 | 
						|
 | 
						|
    if( _FALSE == ps->OpenScanPath( ps )) {
 | 
						|
    	DBG( DBG_LOW, "P12InitAsic() failed.\n" );
 | 
						|
        return _E_NO_DEV;
 | 
						|
    }
 | 
						|
 | 
						|
    /*get CCD and PCB ID */
 | 
						|
    ps->Device.bPCBID = IODataFromRegister( ps, ps->RegConfiguration );
 | 
						|
    ps->Device.bCCDID = ps->Device.bPCBID & 0x07;
 | 
						|
    ps->Device.bPCBID &= 0xf0;
 | 
						|
 | 
						|
	DBG( DBG_LOW, "PCB-ID=0x%02x, CCD-ID=0x%02x\n", ps->Device.bPCBID, ps->Device.bCCDID );
 | 
						|
 | 
						|
    /* get a more closer model description...*/
 | 
						|
    p12InitiateComponentModel( ps );
 | 
						|
 | 
						|
    ps->CloseScanPath( ps );
 | 
						|
 | 
						|
    /* here we check for the OpticWorks 2000, which is not supported */
 | 
						|
    if( _OPTICWORKS2000 == ps->Device.bPCBID ) {
 | 
						|
    	DBG( DBG_LOW, "OpticWorks 2000 not supported!\n" );
 | 
						|
        return _E_NOSUPP;
 | 
						|
    }
 | 
						|
 | 
						|
	DBG( DBG_LOW, "P12InitAsic() done.\n" );
 | 
						|
	return _OK;
 | 
						|
}
 | 
						|
 | 
						|
/*.............................................................................
 | 
						|
 * set all necessary register contents
 | 
						|
 */
 | 
						|
_LOC void P12SetGeneralRegister( pScanData ps )
 | 
						|
{
 | 
						|
	DBG( DBG_LOW, "P12SetGeneralRegister()\n" );
 | 
						|
 | 
						|
    ps->Scan.fMotorBackward = _FALSE;
 | 
						|
    ps->Scan.fRefreshState  = _FALSE;
 | 
						|
 | 
						|
    if( COLOR_BW == ps->DataInf.wPhyDataType )
 | 
						|
    	ps->AsicReg.RD_ScanControl = _SCAN_BITMODE;
 | 
						|
    else {
 | 
						|
        if( ps->DataInf.wPhyDataType <= COLOR_TRUE24 )
 | 
						|
	        ps->AsicReg.RD_ScanControl = _SCAN_BYTEMODE;
 | 
						|
    	else
 | 
						|
	        ps->AsicReg.RD_ScanControl = _SCAN_12BITMODE;
 | 
						|
    }
 | 
						|
 | 
						|
	IOSelectLampSource( ps );
 | 
						|
 | 
						|
   	if( ps->Shade.bIntermediate & _ScanMode_AverageOut )
 | 
						|
    	ps->AsicReg.RD_ModelControl = ps->Device.ModelCtrl | _ModelDpi300;
 | 
						|
    else
 | 
						|
	    ps->AsicReg.RD_ModelControl = ps->Device.ModelCtrl | _ModelDpi600;
 | 
						|
 | 
						|
    ps->AsicReg.RD_Motor0Control = _MotorOn | _MotorHQuarterStep | _MotorPowerEnable;
 | 
						|
    ps->AsicReg.RD_ScanControl1  = _SCANSTOPONBUFFULL | _MFRC_BY_XSTEP;
 | 
						|
    ps->AsicReg.RD_StepControl   = _MOTOR0_SCANSTATE;
 | 
						|
}
 | 
						|
 | 
						|
/* END PLUSTEK-PP_P12.C .....................................................*/
 |