1141cc406Sopenharmony_ci/* @file plustek-pp_detect.c 2141cc406Sopenharmony_ci * @brief automatic scanner detection 3141cc406Sopenharmony_ci * 4141cc406Sopenharmony_ci * based on sources acquired from Plustek Inc. 5141cc406Sopenharmony_ci * Copyright (C) 1998 Plustek Inc. 6141cc406Sopenharmony_ci * Copyright (C) 2000-2013 Gerhard Jaeger <gerhard@gjaeger.de> 7141cc406Sopenharmony_ci * also based on the work done by Rick Bronson 8141cc406Sopenharmony_ci * 9141cc406Sopenharmony_ci * History: 10141cc406Sopenharmony_ci * - 0.30 - initial version 11141cc406Sopenharmony_ci * - 0.31 - no changes 12141cc406Sopenharmony_ci * - 0.32 - no changes 13141cc406Sopenharmony_ci * - 0.33 - added portmode check 14141cc406Sopenharmony_ci * - 0.34 - no changes 15141cc406Sopenharmony_ci * - 0.35 - no changes 16141cc406Sopenharmony_ci * - 0.36 - added some debug messages 17141cc406Sopenharmony_ci * - replace the old _OUTB/_INB macros 18141cc406Sopenharmony_ci * - 0.37 - cosmetic changes 19141cc406Sopenharmony_ci * - added speed-test for the parallel-port 20141cc406Sopenharmony_ci * - 0.38 - added P12 stuff - replaced detectP9636 by detectAsic9800x 21141cc406Sopenharmony_ci * - added detectResetPort() function 22141cc406Sopenharmony_ci * - 0.39 - fixed problem in ASIC9800x detection 23141cc406Sopenharmony_ci * - 0.40 - no changes 24141cc406Sopenharmony_ci * - 0.41 - no changes 25141cc406Sopenharmony_ci * - 0.42 - changed include names 26141cc406Sopenharmony_ci * - 0.43 - cleanup 27141cc406Sopenharmony_ci * - 0.44 - fix format string issues, as Long types default to int32_t 28141cc406Sopenharmony_ci * now 29141cc406Sopenharmony_ci * . 30141cc406Sopenharmony_ci * <hr> 31141cc406Sopenharmony_ci * This file is part of the SANE package. 32141cc406Sopenharmony_ci * 33141cc406Sopenharmony_ci * This program is free software; you can redistribute it and/or 34141cc406Sopenharmony_ci * modify it under the terms of the GNU General Public License as 35141cc406Sopenharmony_ci * published by the Free Software Foundation; either version 2 of the 36141cc406Sopenharmony_ci * License, or (at your option) any later version. 37141cc406Sopenharmony_ci * 38141cc406Sopenharmony_ci * This program is distributed in the hope that it will be useful, but 39141cc406Sopenharmony_ci * WITHOUT ANY WARRANTY; without even the implied warranty of 40141cc406Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 41141cc406Sopenharmony_ci * General Public License for more details. 42141cc406Sopenharmony_ci * 43141cc406Sopenharmony_ci * You should have received a copy of the GNU General Public License 44141cc406Sopenharmony_ci * along with this program. If not, see <https://www.gnu.org/licenses/>. 45141cc406Sopenharmony_ci * 46141cc406Sopenharmony_ci * As a special exception, the authors of SANE give permission for 47141cc406Sopenharmony_ci * additional uses of the libraries contained in this release of SANE. 48141cc406Sopenharmony_ci * 49141cc406Sopenharmony_ci * The exception is that, if you link a SANE library with other files 50141cc406Sopenharmony_ci * to produce an executable, this does not by itself cause the 51141cc406Sopenharmony_ci * resulting executable to be covered by the GNU General Public 52141cc406Sopenharmony_ci * License. Your use of that executable is in no way restricted on 53141cc406Sopenharmony_ci * account of linking the SANE library code into it. 54141cc406Sopenharmony_ci * 55141cc406Sopenharmony_ci * This exception does not, however, invalidate any other reasons why 56141cc406Sopenharmony_ci * the executable file might be covered by the GNU General Public 57141cc406Sopenharmony_ci * License. 58141cc406Sopenharmony_ci * 59141cc406Sopenharmony_ci * If you submit changes to SANE to the maintainers to be included in 60141cc406Sopenharmony_ci * a subsequent release, you agree by submitting the changes that 61141cc406Sopenharmony_ci * those changes may be distributed with this exception intact. 62141cc406Sopenharmony_ci * 63141cc406Sopenharmony_ci * If you write modifications of your own for SANE, it is your choice 64141cc406Sopenharmony_ci * whether to permit this exception to apply to your modifications. 65141cc406Sopenharmony_ci * If you do not wish that, delete this exception notice. 66141cc406Sopenharmony_ci * <hr> 67141cc406Sopenharmony_ci */ 68141cc406Sopenharmony_ci#include "plustek-pp_scan.h" 69141cc406Sopenharmony_ci 70141cc406Sopenharmony_ci/************************** local definitions ********************************/ 71141cc406Sopenharmony_ci 72141cc406Sopenharmony_ci/*************************** local functions *********************************/ 73141cc406Sopenharmony_ci 74141cc406Sopenharmony_ci/** as the name says... 75141cc406Sopenharmony_ci */ 76141cc406Sopenharmony_cistatic void detectResetPort( pScanData ps ) 77141cc406Sopenharmony_ci{ 78141cc406Sopenharmony_ci UChar control; 79141cc406Sopenharmony_ci 80141cc406Sopenharmony_ci DBG( DBG_HIGH, "ResetPort()\n" ); 81141cc406Sopenharmony_ci 82141cc406Sopenharmony_ci control = _INB_CTRL( ps ); 83141cc406Sopenharmony_ci _DO_UDELAY( 2 ); 84141cc406Sopenharmony_ci 85141cc406Sopenharmony_ci _OUTB_CTRL( ps, _CTRL_RESERVED ); /* reset, 0xc0 */ 86141cc406Sopenharmony_ci _DO_UDELAY( 2 ); 87141cc406Sopenharmony_ci 88141cc406Sopenharmony_ci _OUTB_CTRL( ps, control ); /* and restore... */ 89141cc406Sopenharmony_ci _DO_UDELAY( 2 ); 90141cc406Sopenharmony_ci} 91141cc406Sopenharmony_ci 92141cc406Sopenharmony_ci/** Check: will the status port changed between printer/scanner path changed? 93141cc406Sopenharmony_ci * Write out data and read in to compare 94141cc406Sopenharmony_ci */ 95141cc406Sopenharmony_cistatic int detectScannerConnection( pScanData ps ) 96141cc406Sopenharmony_ci{ 97141cc406Sopenharmony_ci UChar data, control, status; 98141cc406Sopenharmony_ci int retval = _E_NO_CONN; 99141cc406Sopenharmony_ci 100141cc406Sopenharmony_ci detectResetPort( ps ); 101141cc406Sopenharmony_ci 102141cc406Sopenharmony_ci /* 103141cc406Sopenharmony_ci * as we're called during InitPorts, we can be sure 104141cc406Sopenharmony_ci * to operate in EPP-mode (hopefully ;-) 105141cc406Sopenharmony_ci */ 106141cc406Sopenharmony_ci control = _INB_CTRL( ps ); 107141cc406Sopenharmony_ci 108141cc406Sopenharmony_ci /* 109141cc406Sopenharmony_ci * go ahead and do some checks 110141cc406Sopenharmony_ci */ 111141cc406Sopenharmony_ci _OUTB_CTRL( ps, _CTRL_GENSIGNAL ); 112141cc406Sopenharmony_ci _DO_UDELAY( 5 ); 113141cc406Sopenharmony_ci 114141cc406Sopenharmony_ci _OUTB_DATA( ps, 0x55 ); 115141cc406Sopenharmony_ci _DO_UDELAY( 5 ); 116141cc406Sopenharmony_ci 117141cc406Sopenharmony_ci data = _INB_DATA( ps ); 118141cc406Sopenharmony_ci 119141cc406Sopenharmony_ci if (0x55 == data) { 120141cc406Sopenharmony_ci 121141cc406Sopenharmony_ci DBG( DBG_HIGH, "Test 0x55\n" ); 122141cc406Sopenharmony_ci 123141cc406Sopenharmony_ci _OUTB_DATA( ps, 0xAA ); 124141cc406Sopenharmony_ci _DO_UDELAY( 5 ); 125141cc406Sopenharmony_ci 126141cc406Sopenharmony_ci data = _INB_DATA( ps ); 127141cc406Sopenharmony_ci 128141cc406Sopenharmony_ci if (0xAA == data) { 129141cc406Sopenharmony_ci 130141cc406Sopenharmony_ci DBG( DBG_HIGH, "Test 0xAA\n" ); 131141cc406Sopenharmony_ci 132141cc406Sopenharmony_ci _OUTB_DATA( ps, 0x0 ); 133141cc406Sopenharmony_ci _DO_UDELAY( 5 ); 134141cc406Sopenharmony_ci 135141cc406Sopenharmony_ci data = _INB_STATUS( ps ); 136141cc406Sopenharmony_ci 137141cc406Sopenharmony_ci ps->OpenScanPath( ps ); 138141cc406Sopenharmony_ci 139141cc406Sopenharmony_ci _OUTB_DATA( ps, 0x0 ); 140141cc406Sopenharmony_ci _DO_UDELAY( 5 ); 141141cc406Sopenharmony_ci 142141cc406Sopenharmony_ci status = _INB_STATUS( ps ); 143141cc406Sopenharmony_ci 144141cc406Sopenharmony_ci ps->CloseScanPath( ps ); 145141cc406Sopenharmony_ci 146141cc406Sopenharmony_ci /* 147141cc406Sopenharmony_ci * so we're done 'til now... 148141cc406Sopenharmony_ci */ 149141cc406Sopenharmony_ci DBG( DBG_HIGH, "Compare data=0x%x and status=0x%x, port=0x%x\n", 150141cc406Sopenharmony_ci data, status, ps->IO.portBase ); 151141cc406Sopenharmony_ci 152141cc406Sopenharmony_ci if( data != status ) { 153141cc406Sopenharmony_ci 154141cc406Sopenharmony_ci _ASSERT( ps->ReadWriteTest ); 155141cc406Sopenharmony_ci 156141cc406Sopenharmony_ci /* 157141cc406Sopenharmony_ci * here we try to detect the operation speed of our parallel 158141cc406Sopenharmony_ci * port if we have tested all the stuff and had no success, 159141cc406Sopenharmony_ci * retval will contain the error-code 160141cc406Sopenharmony_ci */ 161141cc406Sopenharmony_ci for( ps->IO.delay = 0; ps->IO.delay < 5; ps->IO.delay++ ) { 162141cc406Sopenharmony_ci 163141cc406Sopenharmony_ci retval = ps->ReadWriteTest( ps ); 164141cc406Sopenharmony_ci 165141cc406Sopenharmony_ci /* break on OK or when the ASIC detection fails */ 166141cc406Sopenharmony_ci if((_OK == retval) || (_E_NO_ASIC == retval)) 167141cc406Sopenharmony_ci break; 168141cc406Sopenharmony_ci } 169141cc406Sopenharmony_ci } 170141cc406Sopenharmony_ci } 171141cc406Sopenharmony_ci } 172141cc406Sopenharmony_ci 173141cc406Sopenharmony_ci /* work on the result */ 174141cc406Sopenharmony_ci if ( _OK == retval ) { 175141cc406Sopenharmony_ci ps->sCaps.wIOBase = ps->pardev; 176141cc406Sopenharmony_ci ps->PutToIdleMode( ps ); 177141cc406Sopenharmony_ci 178141cc406Sopenharmony_ci } else { 179141cc406Sopenharmony_ci ps->sCaps.wIOBase = _NO_BASE; 180141cc406Sopenharmony_ci } 181141cc406Sopenharmony_ci 182141cc406Sopenharmony_ci /* 183141cc406Sopenharmony_ci * restore control port value 184141cc406Sopenharmony_ci */ 185141cc406Sopenharmony_ci _OUTB_CTRL( ps, control ); 186141cc406Sopenharmony_ci _DO_UDELAY( 5 ); 187141cc406Sopenharmony_ci 188141cc406Sopenharmony_ci DBG( DBG_HIGH, "detectScannerConnection() returns %i.\n", retval ); 189141cc406Sopenharmony_ci 190141cc406Sopenharmony_ci return retval; 191141cc406Sopenharmony_ci} 192141cc406Sopenharmony_ci 193141cc406Sopenharmony_ci/** we need some memory... 194141cc406Sopenharmony_ci */ 195141cc406Sopenharmony_cistatic int detectSetupBuffers( pScanData ps ) 196141cc406Sopenharmony_ci{ 197141cc406Sopenharmony_ci DBG( DBG_LOW, "*** setupBuffers ***\n" ); 198141cc406Sopenharmony_ci 199141cc406Sopenharmony_ci /* bad news ? 200141cc406Sopenharmony_ci */ 201141cc406Sopenharmony_ci if ( 0 == ps->TotalBufferRequire ) { 202141cc406Sopenharmony_ci 203141cc406Sopenharmony_ci DBG( DBG_HIGH, 204141cc406Sopenharmony_ci "pt_drv: asic 0x%x probably not supported\n", ps->sCaps.AsicID); 205141cc406Sopenharmony_ci 206141cc406Sopenharmony_ci return _E_ALLOC; /* Out of memory */ 207141cc406Sopenharmony_ci 208141cc406Sopenharmony_ci } else { 209141cc406Sopenharmony_ci 210141cc406Sopenharmony_ci /* 211141cc406Sopenharmony_ci * allocate and clear 212141cc406Sopenharmony_ci */ 213141cc406Sopenharmony_ci DBG(DBG_LOW,"Driverbuf(%u bytes) needed !\n", ps->TotalBufferRequire); 214141cc406Sopenharmony_ci ps->driverbuf = (pUChar)_VMALLOC(ps->TotalBufferRequire); 215141cc406Sopenharmony_ci 216141cc406Sopenharmony_ci if ( NULL == ps->driverbuf ) { 217141cc406Sopenharmony_ci 218141cc406Sopenharmony_ci DBG( DBG_HIGH, 219141cc406Sopenharmony_ci "pt_drv: Not enough kernel memory %d\n", 220141cc406Sopenharmony_ci ps->TotalBufferRequire); 221141cc406Sopenharmony_ci return _E_ALLOC; /* Out of memory */ 222141cc406Sopenharmony_ci } 223141cc406Sopenharmony_ci 224141cc406Sopenharmony_ci memset( ps->driverbuf, 0, ps->TotalBufferRequire ); 225141cc406Sopenharmony_ci } 226141cc406Sopenharmony_ci 227141cc406Sopenharmony_ci ps->pPrescan16 = ps->driverbuf; 228141cc406Sopenharmony_ci ps->pPrescan8 = ps->pPrescan16 + ps->BufferFor1stColor; 229141cc406Sopenharmony_ci ps->pScanBuffer1 = ps->pPrescan8 + ps->BufferFor2ndColor; 230141cc406Sopenharmony_ci 231141cc406Sopenharmony_ci/* CHECK: Should we adjust that !!! 232141cc406Sopenharmony_ci*/ 233141cc406Sopenharmony_ci ps->pEndBufR = ps->pPrescan8; 234141cc406Sopenharmony_ci ps->pEndBufG = ps->pScanBuffer1; 235141cc406Sopenharmony_ci ps->pColorRunTable = ps->pScanBuffer1 + ps->BufferForDataRead1; 236141cc406Sopenharmony_ci 237141cc406Sopenharmony_ci DBG( DBG_LOW, "pColorRunTab = 0x%0lx - 0x%0lx\n", 238141cc406Sopenharmony_ci (unsigned long)ps->pColorRunTable, 239141cc406Sopenharmony_ci (unsigned long)((pUChar)ps->driverbuf + ps->TotalBufferRequire)); 240141cc406Sopenharmony_ci 241141cc406Sopenharmony_ci if ( _ASIC_IS_98001 == ps->sCaps.AsicID ) { 242141cc406Sopenharmony_ci 243141cc406Sopenharmony_ci DBG( DBG_LOW, "Adjust for 98001 ASIC\n" ); 244141cc406Sopenharmony_ci 245141cc406Sopenharmony_ci ps->pScanBuffer2 = ps->pPrescan16; 246141cc406Sopenharmony_ci ps->pScanBuffer1 = ps->pScanBuffer2 + _LINE_BUFSIZE1; 247141cc406Sopenharmony_ci ps->pColorRunTable = ps->pScanBuffer1 + _LINE_BUFSIZE * 2UL; 248141cc406Sopenharmony_ci ps->pProcessingBuf = ps->pColorRunTable + ps->BufferForColorRunTable; 249141cc406Sopenharmony_ci DBG( DBG_LOW, "sb2 = 0x%lx, sb1 = 0x%lx, Color = 0x%lx\n", 250141cc406Sopenharmony_ci (unsigned long)ps->pScanBuffer2, 251141cc406Sopenharmony_ci (unsigned long)ps->pScanBuffer1, 252141cc406Sopenharmony_ci (unsigned long)ps->pColorRunTable ); 253141cc406Sopenharmony_ci DBG( DBG_LOW, "Pro = 0x%lx, size = %d\n", 254141cc406Sopenharmony_ci (unsigned long)ps->pProcessingBuf, ps->TotalBufferRequire ); 255141cc406Sopenharmony_ci 256141cc406Sopenharmony_ci ps->dwShadow = (_DEF_BRIGHTEST_SKIP + _DEF_DARKEST_SKIP) * 5400UL * 2UL * 3UL; 257141cc406Sopenharmony_ci 258141cc406Sopenharmony_ci ps->Shade.pHilight = _VMALLOC( ps->dwShadow ); 259141cc406Sopenharmony_ci 260141cc406Sopenharmony_ci if ( NULL != ps->Shade.pHilight ) { 261141cc406Sopenharmony_ci 262141cc406Sopenharmony_ci memset( ps->Shade.pHilight, 0, ps->dwShadow ); 263141cc406Sopenharmony_ci 264141cc406Sopenharmony_ci ps->dwHilight = _DEF_BRIGHTEST_SKIP * 5400UL * 3UL; 265141cc406Sopenharmony_ci ps->dwShadow = _DEF_DARKEST_SKIP * 5400UL * 3UL; 266141cc406Sopenharmony_ci ps->pwShadow = (pUShort)ps->Shade.pHilight + ps->dwHilight; 267141cc406Sopenharmony_ci ps->Shade.dwDiv = 32UL - _DEF_BRIGHTEST_SKIP - _DEF_DARKEST_SKIP; 268141cc406Sopenharmony_ci 269141cc406Sopenharmony_ci ps->dwHilightCh = ps->dwHilight / 3UL; 270141cc406Sopenharmony_ci ps->dwShadowCh = ps->dwShadow / 3UL; 271141cc406Sopenharmony_ci } 272141cc406Sopenharmony_ci } else if ( _ASIC_IS_98003 == ps->sCaps.AsicID ) { 273141cc406Sopenharmony_ci 274141cc406Sopenharmony_ci DBG( DBG_LOW, "Adjust for 98003 ASIC\n" ); 275141cc406Sopenharmony_ci 276141cc406Sopenharmony_ci ps->Bufs.b1.pReadBuf = ps->driverbuf; 277141cc406Sopenharmony_ci ps->Bufs.b2.pSumBuf = ps->Bufs.b1.pReadBuf + _SizeDataBuf; 278141cc406Sopenharmony_ci ps->Bufs.TpaBuf.pb = &((pUChar)ps->Bufs.b2.pSumBuf)[_SizeShadingSumBuf]; 279141cc406Sopenharmony_ci 280141cc406Sopenharmony_ci/* CHECK: We might should play around with these values... */ 281141cc406Sopenharmony_ci ps->Shade.skipHilight = _DEF_BRIGHTEST_SKIP; 282141cc406Sopenharmony_ci ps->Shade.skipShadow = _DEF_DARKEST_SKIP; 283141cc406Sopenharmony_ci 284141cc406Sopenharmony_ci if( ps->Shade.skipHilight && ps->Shade.skipShadow ) { 285141cc406Sopenharmony_ci 286141cc406Sopenharmony_ci ULong skipSize; 287141cc406Sopenharmony_ci 288141cc406Sopenharmony_ci skipSize = (ULong)((ps->Shade.skipHilight + ps->Shade.skipShadow) 289141cc406Sopenharmony_ci * _SizeDataBuf * 3); 290141cc406Sopenharmony_ci 291141cc406Sopenharmony_ci ps->Shade.pHilight = _VMALLOC( skipSize ); 292141cc406Sopenharmony_ci 293141cc406Sopenharmony_ci if( NULL != ps->Shade.pHilight ) { 294141cc406Sopenharmony_ci ps->Shade.dwDiv = (ULong)(32UL - ps->Shade.skipHilight - 295141cc406Sopenharmony_ci ps->Shade.skipShadow); 296141cc406Sopenharmony_ci } 297141cc406Sopenharmony_ci } else 298141cc406Sopenharmony_ci ps->Shade.pHilight = NULL; 299141cc406Sopenharmony_ci } 300141cc406Sopenharmony_ci 301141cc406Sopenharmony_ci return _OK; 302141cc406Sopenharmony_ci} 303141cc406Sopenharmony_ci 304141cc406Sopenharmony_ci/** model 48xx detection or any other model using the 96001/3 ASIC 305141cc406Sopenharmony_ci */ 306141cc406Sopenharmony_cistatic int detectP48xx( pScanData ps ) 307141cc406Sopenharmony_ci{ 308141cc406Sopenharmony_ci int result; 309141cc406Sopenharmony_ci 310141cc406Sopenharmony_ci DBG( DBG_LOW, "************ DETECTP48xx ************\n" ); 311141cc406Sopenharmony_ci 312141cc406Sopenharmony_ci /* increase the delay-time */ 313141cc406Sopenharmony_ci ps->IO.delay = 4; 314141cc406Sopenharmony_ci 315141cc406Sopenharmony_ci ModelSet4800( ps ); 316141cc406Sopenharmony_ci 317141cc406Sopenharmony_ci result = P48xxInitAsic( ps ); 318141cc406Sopenharmony_ci if( _OK != result ) 319141cc406Sopenharmony_ci return result; 320141cc406Sopenharmony_ci 321141cc406Sopenharmony_ci return detectScannerConnection( ps ); 322141cc406Sopenharmony_ci} 323141cc406Sopenharmony_ci 324141cc406Sopenharmony_ci/** ASIC 98003 model detection 325141cc406Sopenharmony_ci */ 326141cc406Sopenharmony_cistatic int detectAsic98003( pScanData ps ) 327141cc406Sopenharmony_ci{ 328141cc406Sopenharmony_ci int result; 329141cc406Sopenharmony_ci 330141cc406Sopenharmony_ci DBG( DBG_LOW, "************* ASIC98003 *************\n" ); 331141cc406Sopenharmony_ci 332141cc406Sopenharmony_ci /* increase the delay-time */ 333141cc406Sopenharmony_ci ps->IO.delay = 4; 334141cc406Sopenharmony_ci 335141cc406Sopenharmony_ci ModelSetP12( ps ); 336141cc406Sopenharmony_ci 337141cc406Sopenharmony_ci result = P12InitAsic( ps ); 338141cc406Sopenharmony_ci if( _OK != result ) 339141cc406Sopenharmony_ci return result; 340141cc406Sopenharmony_ci 341141cc406Sopenharmony_ci IOSoftwareReset( ps ); 342141cc406Sopenharmony_ci 343141cc406Sopenharmony_ci return detectScannerConnection( ps ); 344141cc406Sopenharmony_ci} 345141cc406Sopenharmony_ci 346141cc406Sopenharmony_ci/** ASIC 98001 model detection 347141cc406Sopenharmony_ci */ 348141cc406Sopenharmony_cistatic int detectAsic98001( pScanData ps ) 349141cc406Sopenharmony_ci{ 350141cc406Sopenharmony_ci int result; 351141cc406Sopenharmony_ci 352141cc406Sopenharmony_ci DBG( DBG_LOW, "************* ASIC98001 *************\n" ); 353141cc406Sopenharmony_ci 354141cc406Sopenharmony_ci /* increase the delay-time */ 355141cc406Sopenharmony_ci ps->IO.delay = 4; 356141cc406Sopenharmony_ci 357141cc406Sopenharmony_ci ModelSet9636( ps ); 358141cc406Sopenharmony_ci 359141cc406Sopenharmony_ci result = P9636InitAsic( ps ); 360141cc406Sopenharmony_ci#ifndef _ASIC_98001_SIM 361141cc406Sopenharmony_ci if( _OK != result ) 362141cc406Sopenharmony_ci return result; 363141cc406Sopenharmony_ci 364141cc406Sopenharmony_ci return detectScannerConnection( ps ); 365141cc406Sopenharmony_ci#else 366141cc406Sopenharmony_ci DBG( DBG_HIGH, 367141cc406Sopenharmony_ci "!!!! WARNING, have a look at function detectAsic98001() !!!!\n" ); 368141cc406Sopenharmony_ci ps->sCaps.AsicID = _ASIC_IS_98001; 369141cc406Sopenharmony_ci ps->sCaps.wIOBase = ps->IO.pbSppDataPort; 370141cc406Sopenharmony_ci return _OK; 371141cc406Sopenharmony_ci#endif 372141cc406Sopenharmony_ci} 373141cc406Sopenharmony_ci 374141cc406Sopenharmony_ci/************************ exported functions *********************************/ 375141cc406Sopenharmony_ci 376141cc406Sopenharmony_ci/** here we try to find the scanner, depending on the mode 377141cc406Sopenharmony_ci */ 378141cc406Sopenharmony_ci_LOC int DetectScanner( pScanData ps, int mode ) 379141cc406Sopenharmony_ci{ 380141cc406Sopenharmony_ci Byte asic; 381141cc406Sopenharmony_ci int result = _E_INTERNAL; 382141cc406Sopenharmony_ci 383141cc406Sopenharmony_ci /* 384141cc406Sopenharmony_ci * before doing anything else, check the port-mode 385141cc406Sopenharmony_ci */ 386141cc406Sopenharmony_ci if((ps->IO.portMode != _PORT_EPP) && (ps->IO.portMode != _PORT_SPP) && 387141cc406Sopenharmony_ci (ps->IO.portMode != _PORT_BIDI)) { 388141cc406Sopenharmony_ci 389141cc406Sopenharmony_ci DBG( DBG_LOW, "!!! Portmode (%u)not supported !!!\n", ps->IO.portMode ); 390141cc406Sopenharmony_ci return _E_INTERNAL; 391141cc406Sopenharmony_ci } 392141cc406Sopenharmony_ci 393141cc406Sopenharmony_ci /* autodetection ? 394141cc406Sopenharmony_ci */ 395141cc406Sopenharmony_ci if( 0 == mode ) { 396141cc406Sopenharmony_ci 397141cc406Sopenharmony_ci DBG( DBG_HIGH, "Starting Scanner-Autodetection\n" ); 398141cc406Sopenharmony_ci 399141cc406Sopenharmony_ci /* try to find a 48xx Scanner 400141cc406Sopenharmony_ci * (or even a scanner based on the 96001/3) ASIC 401141cc406Sopenharmony_ci */ 402141cc406Sopenharmony_ci result = detectP48xx( ps ); 403141cc406Sopenharmony_ci 404141cc406Sopenharmony_ci if( _OK != result ) { 405141cc406Sopenharmony_ci 406141cc406Sopenharmony_ci DBG( DBG_LOW, "************* ASIC9800x *************\n" ); 407141cc406Sopenharmony_ci 408141cc406Sopenharmony_ci /* get the ASIC ID by using the OpenScanPath stuff from Asic9600x based 409141cc406Sopenharmony_ci * models - only difference: change the ReadHigh/ReadLow signals before 410141cc406Sopenharmony_ci */ 411141cc406Sopenharmony_ci ps->CtrlReadHighNibble = _CTRL_GENSIGNAL+_CTRL_AUTOLF+_CTRL_STROBE; 412141cc406Sopenharmony_ci ps->CtrlReadLowNibble = _CTRL_GENSIGNAL+_CTRL_AUTOLF; 413141cc406Sopenharmony_ci 414141cc406Sopenharmony_ci /* read Register 0x18 (AsicID Register) of Asic9800x based devices */ 415141cc406Sopenharmony_ci#ifdef _ASIC_98001_SIM 416141cc406Sopenharmony_ci DBG( DBG_HIGH, 417141cc406Sopenharmony_ci "!!!! WARNING, SW-Emulation active !!!!\n" ); 418141cc406Sopenharmony_ci asic = _ASIC_IS_98001; 419141cc406Sopenharmony_ci#else 420141cc406Sopenharmony_ci detectResetPort( ps ); 421141cc406Sopenharmony_ci 422141cc406Sopenharmony_ci /* do some presettings to make IODataRegisterFromScanner() work */ 423141cc406Sopenharmony_ci ps->RegAsicID = 0x18; 424141cc406Sopenharmony_ci ps->IO.useEPPCmdMode = _FALSE; 425141cc406Sopenharmony_ci ps->sCaps.AsicID = _ASIC_IS_98001; 426141cc406Sopenharmony_ci IOInitialize( ps ); 427141cc406Sopenharmony_ci 428141cc406Sopenharmony_ci asic = IODataRegisterFromScanner( ps, ps->RegAsicID ); 429141cc406Sopenharmony_ci 430141cc406Sopenharmony_ci DBG( DBG_HIGH, "ASIC = 0x%02X\n", asic ); 431141cc406Sopenharmony_ci#endif 432141cc406Sopenharmony_ci 433141cc406Sopenharmony_ci /* depending on what we have found, perform some extra tests */ 434141cc406Sopenharmony_ci switch( asic ) { 435141cc406Sopenharmony_ci 436141cc406Sopenharmony_ci case _ASIC_IS_98001: 437141cc406Sopenharmony_ci result = detectAsic98001( ps ); 438141cc406Sopenharmony_ci break; 439141cc406Sopenharmony_ci 440141cc406Sopenharmony_ci case _ASIC_IS_98003: 441141cc406Sopenharmony_ci 442141cc406Sopenharmony_ci /* as the reading of the ASIC ID causes trouble, 443141cc406Sopenharmony_ci * we reset the device 444141cc406Sopenharmony_ci */ 445141cc406Sopenharmony_ci ps->IO.useEPPCmdMode = _FALSE; 446141cc406Sopenharmony_ci ps->sCaps.AsicID = _ASIC_IS_98003; 447141cc406Sopenharmony_ci IOInitialize( ps ); 448141cc406Sopenharmony_ci IOSoftwareReset( ps ); 449141cc406Sopenharmony_ci 450141cc406Sopenharmony_ci result = detectAsic98003( ps ); 451141cc406Sopenharmony_ci break; 452141cc406Sopenharmony_ci 453141cc406Sopenharmony_ci default: 454141cc406Sopenharmony_ci DBG( DBG_HIGH, "Unknown ASIC-ID\n" ); 455141cc406Sopenharmony_ci result = _E_NO_DEV; 456141cc406Sopenharmony_ci break; 457141cc406Sopenharmony_ci } 458141cc406Sopenharmony_ci } 459141cc406Sopenharmony_ci 460141cc406Sopenharmony_ci } else { 461141cc406Sopenharmony_ci 462141cc406Sopenharmony_ci /* this will be called each time before operating on a previously 463141cc406Sopenharmony_ci * detected device, to make sure we are still operating on the same one 464141cc406Sopenharmony_ci */ 465141cc406Sopenharmony_ci if( _ASIC_IS_98001 == mode ) { 466141cc406Sopenharmony_ci 467141cc406Sopenharmony_ci DBG( DBG_HIGH, "Starting Scanner-detection (ASIC 98001)\n" ); 468141cc406Sopenharmony_ci result = detectAsic98001( ps ); 469141cc406Sopenharmony_ci 470141cc406Sopenharmony_ci } else if( _ASIC_IS_98003 == mode ) { 471141cc406Sopenharmony_ci 472141cc406Sopenharmony_ci DBG( DBG_HIGH, "Starting Scanner-detection (ASIC 98003)\n" ); 473141cc406Sopenharmony_ci result = detectAsic98003( ps ); 474141cc406Sopenharmony_ci 475141cc406Sopenharmony_ci } else { 476141cc406Sopenharmony_ci 477141cc406Sopenharmony_ci DBG( DBG_HIGH, "Starting Scanner-detection (ASIC 96001/3)\n" ); 478141cc406Sopenharmony_ci result = detectP48xx( ps ); 479141cc406Sopenharmony_ci } 480141cc406Sopenharmony_ci } 481141cc406Sopenharmony_ci 482141cc406Sopenharmony_ci if( _OK == result ) { 483141cc406Sopenharmony_ci 484141cc406Sopenharmony_ci _ASSERT( ps->SetupScannerVariables ); 485141cc406Sopenharmony_ci ps->SetupScannerVariables( ps ); 486141cc406Sopenharmony_ci 487141cc406Sopenharmony_ci detectSetupBuffers( ps ); 488141cc406Sopenharmony_ci 489141cc406Sopenharmony_ci } else { 490141cc406Sopenharmony_ci/* CHECK - we should not need that anymore - paranoia code ??!!!! 491141cc406Sopenharmony_ci*/ 492141cc406Sopenharmony_ci ps->sCaps.wIOBase = _NO_BASE; 493141cc406Sopenharmony_ci } 494141cc406Sopenharmony_ci 495141cc406Sopenharmony_ci DBG( DBG_LOW, "*** DETECTION DONE, result: %i ***\n", result ); 496141cc406Sopenharmony_ci return result; 497141cc406Sopenharmony_ci} 498141cc406Sopenharmony_ci 499141cc406Sopenharmony_ci/* END PLUSTEK-PP_DETECT.C ..................................................*/ 500