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