1/* @file plustek-pp_genericio.c
2 * @brief all i/o functions
3 *
4 * based on sources acquired from Plustek Inc.
5 * Copyright (C) 1998 Plustek Inc.
6 * Copyright (C) 2000-2004 Gerhard Jaeger <gerhard@gjaeger.de>
7 * also based on the work done by Rick Bronson
8 *
9 * History:
10 * - 0.30 - initial version
11 * - 0.31 - moved ioP96ReadScannerImageData and ioP98ReadScannerImageData
12 *          into this file
13 *        - added SPP-read functions
14 * - 0.32 - changes in function ioControlLampOnOff()
15 *        - made IOReadingImage a local function -> ioP98ReadingImage()
16 *        - rewritten function ioP96ReadScannerImageData()
17 *        - moved function IOSetStartStopRegister to p9636.c
18 * - 0.33 - added debug messages to IOPutOnAllRegisters
19 *        - fixed a bug in ioP96InitialSetCurrentSpeed
20 * - 0.34 - no changes
21 * - 0.35 - no changes
22 * - 0.36 - removed some warning conditions
23 * - 0.37 - moved functions IOSPPWrite(), IODataToScanner(), IODataToRegister(),
24 *          IODataFromRegister() to io.c
25 *        - moved the data read functions to io.c
26 *        - renamed IOInitialize to IOFuncInitialize
27 * - 0.38 - moved some functions to io.c
28 *        - added P12 stuff
29 * - 0.39 - no changes
30 * - 0.40 - no changes
31 * - 0.41 - no changes
32 * - 0.42 - changed include names
33 * - 0.43 - fixed a problem in ioP96InitialSetCurrentSpeed(), for COLOR_BW
34 *          at least, used the setting for A3I
35 * .
36 * <hr>
37 * This file is part of the SANE package.
38 *
39 * This program is free software; you can redistribute it and/or
40 * modify it under the terms of the GNU General Public License as
41 * published by the Free Software Foundation; either version 2 of the
42 * License, or (at your option) any later version.
43 *
44 * This program is distributed in the hope that it will be useful, but
45 * WITHOUT ANY WARRANTY; without even the implied warranty of
46 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
47 * General Public License for more details.
48 *
49 * You should have received a copy of the GNU General Public License
50 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
51 *
52 * As a special exception, the authors of SANE give permission for
53 * additional uses of the libraries contained in this release of SANE.
54 *
55 * The exception is that, if you link a SANE library with other files
56 * to produce an executable, this does not by itself cause the
57 * resulting executable to be covered by the GNU General Public
58 * License.  Your use of that executable is in no way restricted on
59 * account of linking the SANE library code into it.
60 *
61 * This exception does not, however, invalidate any other reasons why
62 * the executable file might be covered by the GNU General Public
63 * License.
64 *
65 * If you submit changes to SANE to the maintainers to be included in
66 * a subsequent release, you agree by submitting the changes that
67 * those changes may be distributed with this exception intact.
68 *
69 * If you write modifications of your own for SANE, it is your choice
70 * whether to permit this exception to apply to your modifications.
71 * If you do not wish that, delete this exception notice.
72 * <hr>
73 */
74#include "plustek-pp_scan.h"
75
76/*************************** local vars **************************************/
77
78/* WORK COMMENT THIS */
79typedef void (*pFnSpeed_Set)(pScanData);
80
81static ModeTypeVar a_FilmSettings[18] = {
82	/* SppNegFilmPos */
83	{0xa0, 1782, 96, _QuarterStep, 0, 0},
84	{0xb7, 1782, 96, _QuarterStep, 0, 0},
85	{0xb7, 1782, 96, _QuarterStep, 0, 0},
86	/* BppNegFilmPos */
87	{0xa9, 1782, 96, _QuarterStep, 0, 0},
88	{0xbf, 1782, 96, _QuarterStep, 0, 0},
89	{0xbf, 1782, 96, _QuarterStep, 0, 0},
90	/* EppNegFilmPos */
91	{0x95, 1782, 96, _QuarterStep, 0, 0},
92	{0xa6, 1782, 96, _QuarterStep, 0, 0},
93	{0xa6, 1782, 96, _QuarterStep, 0, 0},
94	/* SppPosFilmPos */
95	{0x50, 1782, 96, _QuarterStep, 0, 0},
96	{0x67, 1782, 96, _QuarterStep, 0, 0},
97	{0x67, 1782, 96, _QuarterStep, 0, 0},
98	/* BppPosFilmPos */
99	{0x59, 1782, 96, _QuarterStep, 0, 0},
100	{0x6f, 1782, 96, _QuarterStep, 0, 0},
101	{0x6f, 1782, 96, _QuarterStep, 0, 0},
102	/* EppPosFilmPos */
103	{0x45, 1782, 96, _QuarterStep, 0, 0},
104	{0x56, 1782, 96, _QuarterStep, 0, 0},
105	{0x56, 1782, 96, _QuarterStep, 0, 0}
106};
107
108static ModeTypeVar a_BwSettings[12] = {
109	{_Home_BE75,   890, 96, _HalfStep,    2, 1},
110	{_Home_BE150, 1780, 88, _QuarterStep, 2, 0},
111	{_Home_BE300, 3542, 96, _QuarterStep, 2, 0},
112	{_Home_BE600, 7070, 96, _QuarterStep, 2, 0},
113	{_Home_BB75,   890, 96, _HalfStep,    2, 1},
114	{_Home_BB150, 1780, 88, _QuarterStep, 2, 0},
115	{_Home_BB300, 3542, 96, _QuarterStep, 2, 0},
116	{_Home_BB600, 7070, 96, _QuarterStep, 2, 0},
117	{_Home_BS75,   890, 96, _HalfStep,    2, 1},
118	{_Home_BS150, 1780, 88, _QuarterStep, 2, 0},
119	{_Home_BS300, 3542, 96, _QuarterStep, 2, 0},
120	{_Home_BS600, 7070, 96, _QuarterStep, 2, 0}
121};
122
123static ModeTypeVar a_GraySettings[12] = {
124	{_Home_GE75,   890, 96, _HalfStep,    2, 0},
125	{_Home_GE150, 1780, 88, _QuarterStep, 2, 0},
126	{_Home_GE300, 3542, 88, _QuarterStep, 2, 0},
127	{_Home_GE600, 7070, 88, _QuarterStep, 2, 0},
128	{_Home_GB75,   890, 96, _HalfStep,    2, 0},
129	{_Home_GB150, 1780, 88, _QuarterStep, 2, 0},
130	{_Home_GB300, 3542, 88, _QuarterStep, 2, 0},
131	{_Home_GB600, 7070, 88, _QuarterStep, 2, 0},
132	{_Home_GS75,   890, 96, _HalfStep,    2, 0},
133	{_Home_GS150, 1782, 96, _QuarterStep, 2, 0},
134	{_Home_GS300, 3549, 88, _QuarterStep, 2, 0},
135	{_Home_GS600, 7070, 88, _QuarterStep, 2, 0}
136};
137
138static ModeTypeVar a_ColorSettings[15] = {
139	{_Home_CE50,   720,  60, _HalfStep,	   1, 1},
140	{_Home_CE100, 1782,  48, _QuarterStep, 1, 0},
141	{_Home_CE150, 1782,  88, _QuarterStep, 0, 0},
142	{_Home_CE300, 3549,  96, _QuarterStep, 0, 0},
143	{_Home_CE600, 7082,  96, _QuarterStep, 0, 0},
144	{_Home_CB50,   720, 120, _QuarterStep, 0, 1},
145	{_Home_CB100, 1782,  96, _QuarterStep, 0, 0},
146	{_Home_CB150, 1782,  96, _QuarterStep, 0, 0},
147	{_Home_CB300, 3549,  96, _QuarterStep, 0, 0},
148	{_Home_CB600, 7082,  96, _QuarterStep, 0, 0},
149	{_Home_CS50,   720, 120, _QuarterStep, 0, 1},
150	{_Home_CS100, 1782,  96, _QuarterStep, 0, 0},
151	{_Home_CS150, 1782,  96, _QuarterStep, 0, 0},
152	{_Home_CS300, 3549,  96, _QuarterStep, 0, 0},
153	{_Home_CS600, 7082,  96, _QuarterStep, 0, 0}
154};
155
156static DiffModeVar a_tabDiffParam[] ={
157	/* BPP/EPP B/W */
158	{0, 1, 11}, /* Bpp/Epp B/W, Dpi <= 150		 ;(0) */
159	{0, 1, 24}, /* Bpp/Epp B/W, Dpi <= 300		 ;(1) */
160	{0, 1, 48}, /* Bpp/Epp B/W, Dpi > 300		 ;(2) */
161   	/* SPP B/W */
162	{0, 1, 11}, /* Spp B/W, Dpi <= 150		 ;(3) */
163	{0, 1, 24}, /* Spp B/W, Dpi <= 300		 ;(4) */
164    {0, 1, 48}, /* Spp B/W, Dpi > 300		 ;(5) */
165	/* EPP Gray */
166	/* The difference for this DPI:
167     * if pixels <=        | 3000 | Others
168     * --------------------+------+-------------
169     *  VarFullStateSpeed  |   0  |   1
170     *  VarCurrentSpeed    |   1  |   2
171     *  VarStepSpeed       |  44  |  88
172     */
173		{0, 1, 12}, /* Epp Gray, Dpi <= 150		 ;(6)         */
174		{1, 2, 80}, /* Epp Gray, Dpi <= 300		 ;(7)         */
175		{0, 1, 80}, /* Epp Gray, Dpi > 300, Px <= 3000	 ;(8) */
176		{0, 1, 80}, /* Epp Gray, Dpi > 300, Px > 3000	 ;(9) */
177
178   /* BPP Gray */
179		{0, 1, 11}, /* Bpp Gray, Dpi <= 150		 ; 10 */
180	/* The difference for this DPI:
181	 *     if pixels <=    | 1600 | Others
182	 * --------------------+------+-------------
183	 *   VarFullStateSpeed |   0  |   1
184	 *   VarCurrentSpeed   |   1  |   2
185	 *   VarStepSpeed      |  24  |  48
186     */
187		{0, 1, 24}, /* Bpp Gray, Dpi <= 300, Px <= 1600  ; 11 */
188		{1, 2, 48}, /* Bpp Gray, Dpi <= 300, Px > 1600	 ; 12 */
189	/* The difference for this DPI:
190	 *     if pixels <=    | 1600 | 3200 | Others
191	 * --------------------+-----+-------+----------------------
192	 *   VarFullStateSpeed |  0  |	 1   |	 2
193	 *   VarCurrentSpeed   |  1  |	 2   |	 4
194	 *	 VarStepSpeed      | 44  |	88   |	88
195	 */
196		{0, 1, 44}, /* Bpp Gray, Dpi > 300, Px <= 1600	 ; 13 */
197		{1, 2, 88}, /* Bpp Gray, Dpi > 300, Px <= 3200	 ; 14 */
198		{2, 4, 88}, /* Bpp Gray, Dpi > 300, Px > 3200	 ; 15 */
199    /* SPP Gray */
200	/* The difference for this DPI:
201	 *     if pixels <=    | 800 | Others
202	 * --------------------+-----+-------------
203	 *   VarFullStateSpeed |  0  |	 1
204	 *   VarCurrentSpeed   |  1  |	 2
205	 *	 VarStepSpeed      | 12  |	24
206	 */
207		{0, 1, 12}, /* Spp Gray, Dpi <= 150, Px <= 800	 ; 16 */
208		{1, 2, 24}, /* Spp Gray, Dpi <= 150, Px > 800	 ; 17 */
209	/* The difference for this DPI:
210	 *     if pixels <=    |  800 | 1600 | Others
211	 * --------------------+-----+-------+----------------------
212     *   VarFullStateSpeed |  0  |	 1   |	 1
213	 *   VarCurrentSpeed   |  1  |	 2   |	 4
214	 *   VarStepSpeed      | 22  |	88   |	88
215	 */
216		{0, 1, 22}, /* Spp Gray, Dpi <= 300, Px <= 800	 ; 18 */
217		{1, 2, 88}, /* Spp Gray, Dpi <= 300, Px <= 1600  ; 19 */
218		{1, 4, 88}, /* Spp Gray, Dpi <= 300, Px > 1600	 ; 20 */
219	/* The difference for this DPI:
220	 *     if pixels <=    | 800 | 1600 | 3200 | Others
221	 * --------------------+-----+------+------+---------------
222	 *   VarFullStateSpeed |  0  |	 1  |	2  |   3
223	 *   VarCurrentSpeed   |  1  |	 2  |	4  |   6
224	 *   VarStepSpeed      | 44  |	88  |  88  |  88
225	 */
226		{0, 1, 44}, /* Spp Gray, Dpi > 300, Px <= 800	 ; 21 */
227		{1, 2, 88}, /* Spp Gray, Dpi > 300, Px <= 1600	 ; 22 */
228		{2, 4, 88}, /* Spp Gray, Dpi > 300, Px <= 3200	 ; 23 */
229		{3, 6, 88}, /* Spp Gray, Dpi > 300, Px > 3200	 ; 24 */
230	/* EPP Color */
231		{0, 1, 6},  /* Epp Color, Dpi <= 60/100 	 ; 25 */
232		{0, 1, 11}, /* Epp Color, Dpi <= 150		 ; 26 */
233	/* The difference for this DPI:
234	 *     if pixels <=    | 1200 | Others
235	 * --------------------+------+-------------
236	 *   VarFullStateSpeed |   0  |   1
237	 *   VarCurrentSpeed   |   1  |   2
238	 *	 VarStepSpeed      |  24  |  48
239	 */
240		{0, 1, 24}, /* Epp Color, Dpi <= 300, Px <= 1400 ; 27 */
241		{1, 2, 48}, /* Epp Color, Dpi <= 300, Px > 1400  ; 28 */
242	/* The difference for this DPI:
243	 *     if pixels <=    | 1400 | 2800 | 4000 | Others
244	 * --------------------+------+------+------+---------------
245	 *   VarFullStateSpeed |   0  |   1  |	 2  |	3
246	 *   VarCurrentSpeed   |   1  |   2  |	 4  |	6
247	 *  VarStepSpeed       |  48  |  96  |	88  |  88
248	 *     VarExposureTime |  96  |  96  |	88  |  88
249	 */
250		{0, 1, 48}, /* Epp Color, Dpi > 300, Px <= 1400  ; 29 */
251		{1, 2, 96}, /* Epp Color, Dpi > 300, Px <= 2800  ; 30 */
252		{2, 4, 88}, /* Epp Color, Dpi > 300, Px <= 4000  ; 31 */
253		{4, 8, 88}, /* Epp Color, Dpi > 300, Px >  4000  ; 32 */
254    /* BPP Color */
255		{0, 1, 6},  /* Bpp/Spp Color, Dpi <= 60 	 ; 33 */
256		{0, 1, 12}, /* Bpp/Spp Color, Dpi <= 100	 ; 34 */
257	/*     if pixels <=    | 800 | Others
258	 * --------------------+-----+-------------
259	 *   VarFullStateSpeed |  0  |	 1
260     *     VarCurrentSpeed |  1  |	 2
261	 *	 VarStepSpeed      | 12  |	24
262	 */
263		{0, 1, 12}, /* Bpp/Spp Color, Dpi <= 150, Px <= 800  ; 35 */
264		{1, 2, 24}, /* Bpp/Spp Color, Dpi <= 150, Px > 800   ; 36 */
265	/* The difference for this DPI:
266	 *     if pixels <=    |  800 | 1600 | Others
267	 * --------------------+-----+-------+----------------------
268	 *   VarFullStateSpeed |  0  |	 1   |	 1
269	 *   VarCurrentSpeed   |  1  |	 2   |	 4
270	 *	 VarStepSpeed      | 24  |	48   |	96
271	 */
272		{0, 1, 24}, /* Bpp Color, Dpi <= 300, Px <= 800  ; 37 */
273		{1, 2, 48}, /* Bpp Color, Dpi <= 300, Px <= 1600 ; 38 */
274		{1, 4, 96}, /* Bpp Color, Dpi <= 300, Px > 1600  ; 39 */
275	/* The difference for this DPI:
276	 *     if pixels <=    | 800 | 1600 | 3200 | Others
277	 * --------------------+-----+------+------+---------------
278	 *   VarFullStateSpeed |  0  |	 1  |	2  |   4
279	 *   VarCurrentSpeed   |  1  |	 2  |	4  |   8
280	 *   VarStepSpeed      | 48  |	96  |  96  |  96
281     */
282		{0, 1, 48}, /* Bpp Color, Dpi > 300, Px <= 800	 ; 40 */
283		{1, 2, 48}, /* Bpp Color, Dpi > 300, Px <= 1600  ; 41 */
284		{2, 4, 96}, /* Bpp Color, Dpi > 300, Px <= 3200  ; 42 */
285		{4, 8, 96}, /* Bpp Color, Dpi > 300, Px > 3200	 ; 43 */
286    /* SPP Color */
287	/* The difference for this DPI:
288	 *     if pixels <=    | 500 | 1000 | 2000 | Others
289	 * --------------------+-----+------+------+---------------
290	 *   VarFullStateSpeed |  0  |	 1  |	1  |   2
291	 *   VarCurrentSpeed   |  1  |	 2  |	4  |   8
292	 *	 VarStepSpeed      | 24  |	48  |  96  |  96
293	 */
294		{0, 1, 24}, /* Spp Color, Dpi <= 300, Px <= 500  ; 44 */
295		{1, 2, 48}, /* Spp Color, Dpi <= 300, Px <= 1000 ; 45 */
296		{1, 4, 96}, /* Spp Color, Dpi <= 300, Px <= 2000 ; 46 */
297		{2, 8, 96}, /* Spp Color, Dpi <= 300, Px > 2000  ; 47 */
298	/* The difference for this DPI:
299	 *     if pixels <=    | 500 | 1000 | 2000 | 4000 | Others
300	 * --------------------+-----+------+------+------+--------
301	 *   VarFullStateSpeed |  0  |	 1  |	2  |   4  |   5
302	 *   VarCurrentSpeed   |  1  |	 2  |	4  |   8  |  10
303	 *	 VarStepSpeed      | 48  |	96  |  96  |  96  |  96
304     */
305		{0, 1, 48},  /* Spp Color, Dpi > 300, Px <= 500   ; 48 */
306		{1, 2, 96},  /* Spp Color, Dpi > 300, Px <= 1000  ; 49 */
307		{2, 4, 96},  /* Spp Color, Dpi > 300, Px <= 2000  ; 50 */
308		{4, 8, 96},  /* Spp Color, Dpi > 300, Px <= 4000  ; 51 */
309		{5, 10, 96}, /* Spp Color, Dpi > 300, Px > 4000   ; 52 */
310
311    /* Negative & Transparency   */
312    /* EPP/SPP/BPP               */
313/* for exposure time = 96 */
314		{0, 1, 12},  /* Spp/EPP Color, Dpi <= 150	  ; 60 */
315		{0, 1, 24},  /* Spp Color, Dpi <= 300		  ; 61 */
316		{0, 1, 48},  /* Spp Color, Dpi > 300		  ; 62 */
317		{0, 1, 12},  /* Bpp/Epp B/W, Dpi <= 75		  ; 56 */
318
319/* for exposure time = 144 */
320		{0, 1, 18},  /* Spp/EPP Color, Dpi <= 150	  ; 57 */
321		{0, 1, 36},  /* Spp Color, Dpi <= 300		  ; 58 */
322		{0, 1, 72},  /* Spp Color, Dpi > 300		  ; 59 */
323
324/* for exposure time = 192 */
325		{0, 1, 24},  /* Spp/EPP Color, Dpi <= 150	  ; 53 */
326		{0, 1, 48},  /* Spp Color, Dpi <= 300		  ; 54 */
327		{0, 1, 96},  /* Spp Color, Dpi > 300		  ; 55 */
328
329/* for 48 bits color */
330		{1, 2, 12}, /* Epp Color, Dpi <= 100, Px > 1400   ; 63 */
331		{1, 2, 22}, /* Epp Color, Dpi <= 150, Px > 1900   ; 64 */
332		{2, 4, 48}, /* Epp Color, Dpi <= 300, Px > 4000   ; 65 */
333		{5, 10, 88},/* Epp Color, Dpi >  300, Px > 9600   ; 66 */
334		{3, 12, 96} /* Spp Color, Dpi <= 300, Px > 3000   ; 67 */
335};
336
337
338static pModeTypeVar	pModeType;
339static pDiffModeVar	pModeDiff;
340
341/*
342 * prototypes for the speed procs (ASIC 98001), EPP, SPP and BIDI
343 */
344static void fnLineArtSpeed( pScanData ps );
345static void fnGraySpeed   ( pScanData ps );
346static void fnColorSpeed  ( pScanData ps );
347
348static void fnSppLineArtSpeed( pScanData ps );
349static void fnSppGraySpeed   ( pScanData ps );
350static void fnSppColorSpeed  ( pScanData ps );
351
352static void fnBppLineArtSpeed( pScanData ps );
353static void fnBppGraySpeed   ( pScanData ps );
354static void fnBppColorSpeed  ( pScanData ps );
355
356/*
357 * some procedures for the different modes
358 */
359static pFnSpeed_Set a_fnSpeedProcs[5] = {
360	fnLineArtSpeed,
361	fnGraySpeed,
362	fnGraySpeed,
363	fnColorSpeed,
364	fnColorSpeed
365};
366
367static pFnSpeed_Set a_fnSppSpeedProcs[5] = {
368	fnSppLineArtSpeed,
369	fnSppGraySpeed,
370	fnSppGraySpeed,
371	fnSppColorSpeed,
372	fnSppColorSpeed
373};
374
375static pFnSpeed_Set a_fnBppSpeedProcs[5] = {
376	fnBppLineArtSpeed,
377	fnBppGraySpeed,
378	fnBppGraySpeed,
379	fnBppColorSpeed,
380	fnBppColorSpeed
381};
382
383
384/*************************** local functions *********************************/
385
386/*.............................................................................
387 *
388 */
389static void ioP96InitialSetCurrentSpeed( pScanData ps )
390{
391	DBG( DBG_LOW, "ioP96InitialSetCurrentSpeed()\n" );
392
393	switch ( ps->DataInf.wPhyDataType ) {
394
395	case COLOR_BW:
396		ps->bCurrentSpeed = (ps->DataInf.dwAsicPixelsPerPlane >
397			                      _BUF_SIZE_BASE_CONST * 2) ? 2 : 1;
398		break;
399
400	case COLOR_256GRAY:
401		if ( COLOR_256GRAY == ps->DataInf.wAppDataType ) {
402
403			ps->bCurrentSpeed = (Byte)(ps->a_wGrayInitTime[ps->IO.portMode] /
404			                           ps->wLinesPer64kTime);
405			if (!ps->bCurrentSpeed)
406			    ps->bCurrentSpeed = 1;
407
408			if ((ps->DataInf.dwAsicPixelsPerPlane>=1500) && (ps->bCurrentSpeed==1))
409			    ps->bCurrentSpeed = 2;
410
411			if ( ps->DataInf.xyAppDpi.x > 1200) {
412			    ps->bCurrentSpeed += 2; 			/* 1201-2400 */
413
414			    if ( ps->DataInf.xyAppDpi.x > 2400 )
415					ps->bCurrentSpeed += 2;			/* >= 2401   */
416			}
417
418			MotorP96AdjustCurrentSpeed( ps, ps->bCurrentSpeed );
419
420	    } else {
421
422			if ( _PORT_SPP != ps->IO.portMode ) {
423			    if( ps->DataInf.dwAsicPixelsPerPlane <= 1280 )
424					ps->bCurrentSpeed = 1;	/* <= 1280 pixels */
425
426			    else if( ps->DataInf.dwAsicPixelsPerPlane <= 1720 )
427				    ps->bCurrentSpeed = 2;	/* 1281-1720 */
428
429				else if( ps->DataInf.dwAsicPixelsPerPlane <= 3780 )
430					ps->bCurrentSpeed = 4;	/* 1721-3780 */
431
432			    else
433					ps->bCurrentSpeed = 6;	/* >= 3780 */
434
435			} else {
436
437			    if( ps->DataInf.dwAsicPixelsPerPlane <= 400 )
438					ps->bCurrentSpeed = 1;			/* <= 400 pixels */
439
440			    else if( ps->DataInf.dwAsicPixelsPerPlane <= 853 )
441				    ps->bCurrentSpeed = 2;		/* 401-853 */
442
443				else if( ps->DataInf.dwAsicPixelsPerPlane <= 1280 )
444					ps->bCurrentSpeed = 4;	/* 854-1280 */
445
446			    else if( ps->DataInf.dwAsicPixelsPerPlane <= 1728 )
447				    ps->bCurrentSpeed = 6;	/* 1281-1728 */
448
449				else if( ps->DataInf.dwAsicPixelsPerPlane <= 3780 )
450					ps->bCurrentSpeed = 8;	/* 1729-3780 */
451
452			    else
453					ps->bCurrentSpeed = 10;	/* > 3780 */
454			}
455	    }
456	    break;
457
458	case COLOR_TRUE24:
459	    ps->bCurrentSpeed = (Byte)(ps->a_wColorInitTime[ps->IO.portMode] /
460								   ps->wLinesPer64kTime);
461
462	    if( 0 == ps->bCurrentSpeed ) {
463			DBG( DBG_LOW, "Initially set to 1\n" );
464			ps->bCurrentSpeed = 1;
465		}
466
467	    if (ps->DataInf.xyAppDpi.x > 150)  {
468			if (ps->bCurrentSpeed < 4)
469			    ps->bCurrentSpeed = 4;
470	    } else {
471/*
472// HEINER:A3I
473//			if (ps->DataInf.xyAppDpi.x > 100)
474*/
475			if (ps->DataInf.xyAppDpi.x > 75)
476			    if (ps->bCurrentSpeed < 2)
477					ps->bCurrentSpeed = 2;
478		}
479
480	    if( 1 != ps->bCurrentSpeed )
481			ps->bCurrentSpeed += ps->bExtraAdd;
482
483    	if (ps->DataInf.xyAppDpi.x > ps->PhysicalDpi) {
484			if (ps->DataInf.xyAppDpi.x <= 600)
485			    ps->bCurrentSpeed += 2;
486			else if (ps->DataInf.xyAppDpi.x <= 1200)
487				ps->bCurrentSpeed += 2;
488    		else if (ps->DataInf.xyAppDpi.x <= 2400)
489			    ps->bCurrentSpeed += 2;
490			else
491			    ps->bCurrentSpeed += 2;
492	    }
493
494		MotorP96AdjustCurrentSpeed( ps, ps->bCurrentSpeed );
495    }
496
497	DBG( DBG_LOW, "Current Speed = %u\n", ps->bCurrentSpeed );
498}
499
500/*.............................................................................
501 *
502 */
503static void fnLineArtSpeed( pScanData ps )
504{
505    pModeType = a_BwSettings + _FixParamEppBw;
506    pModeDiff = a_tabDiffParam + _BwEpp75;
507
508    if (ps->DataInf.xyAppDpi.y > 75) {
509		pModeType++;
510		pModeDiff = a_tabDiffParam + _BwEpp150;
511    }
512
513    if (ps->DataInf.xyAppDpi.y > 150) {
514		if (ps->DataInf.xyAppDpi.y <= 300) {
515		    pModeType++;
516		    pModeDiff = a_tabDiffParam + _BwEpp300;
517		} else {
518		    pModeType += 2;
519		    pModeDiff = a_tabDiffParam + _BwEpp600;
520		}
521	}
522}
523
524/*.............................................................................
525 *
526 */
527static void fnGraySpeed( pScanData ps )
528{
529    pModeType = a_GraySettings + _FixParamEppGray;
530    pModeDiff = a_tabDiffParam + _GrayEpp75;
531
532    if (ps->DataInf.xyAppDpi.y > 75) {
533		pModeType++;
534		pModeDiff = a_tabDiffParam + _GrayEpp150;
535    }
536
537    if ( ps->DataInf.xyAppDpi.y > 150) {
538		if (ps->DataInf.xyAppDpi.y <= 300) {
539		    pModeType++;
540		    pModeDiff = a_tabDiffParam + _GrayEpp300;
541		} else {
542		    pModeType += 2;
543		    pModeDiff = a_tabDiffParam + _GrayEpp600;
544	    	if (ps->DataInf.dwAsicPixelsPerPlane > 3000)
545				pModeDiff++;
546		}
547	}
548}
549
550/*.............................................................................
551 *
552 */
553static void fnColorSpeed( pScanData ps )
554{
555	DBG( DBG_LOW, "fnColorSpeed();\n" );
556
557    pModeType = a_ColorSettings + _FixParamEppColor;
558
559    if ( ps->DataInf.xyAppDpi.y <= ps->wMinCmpDpi ) {
560		/* DPI <= 60 */
561		pModeDiff = a_tabDiffParam + _ColorEpp60;
562
563	} else {
564
565		if (ps->DataInf.xyAppDpi.y <= 100) {
566		    pModeType++;
567		    pModeDiff = a_tabDiffParam + _ColorEpp100;
568
569	    	if (ps->DataInf.dwAsicBytesPerPlane > 1400)
570				pModeDiff = a_tabDiffParam + _ColorEpp100_1400;
571		} else {
572		    if (ps->DataInf.xyAppDpi.y <= 150) {
573				pModeType += 2;
574				pModeDiff = a_tabDiffParam + _ColorEpp150;
575
576				if (ps->DataInf.dwAsicBytesPerPlane > 1900)
577				    pModeDiff = a_tabDiffParam + _ColorEpp150_1900;
578		    } else {
579				if (ps->DataInf.xyAppDpi.y <= 300) {
580				    pModeType += 3;
581				    pModeDiff = a_tabDiffParam + _ColorEpp300_1200;
582				    if (ps->DataInf.dwAsicBytesPerPlane <= 1200)
583						pModeDiff --;
584				    else {
585						if (ps->DataInf.dwAsicBytesPerPlane > 4000)
586						    pModeDiff = a_tabDiffParam + _ColorEpp300_4000;
587					}
588				} else {
589				    pModeType += 4;
590				    pModeDiff = a_tabDiffParam + _ColorEpp600_4000;
591				    pModeType->bExposureTime = 88;
592
593				    if (ps->DataInf.dwAsicBytesPerPlane <= 4000) {
594						pModeDiff--;
595						if (ps->DataInf.dwAsicBytesPerPlane <= 2800) {
596						    pModeType->bExposureTime = 96;
597						    pModeDiff--;
598						    if (ps->DataInf.dwAsicBytesPerPlane <= 1200)
599								pModeDiff--;
600						}
601		    		} else {
602						if (ps->DataInf.dwAsicBytesPerPlane >= 9600)
603						    pModeDiff = a_tabDiffParam + _ColorEpp600_9600;
604					}
605				}
606			}
607     	}
608	}
609}
610
611/*.............................................................................
612 *
613 */
614static void fnSppLineArtSpeed( pScanData ps )
615{
616    pModeType = a_BwSettings + _FixParamSppBw;
617    pModeDiff = a_tabDiffParam + _BwSpp75;
618
619    if (ps->DataInf.xyAppDpi.y > 75) {
620
621		pModeType++;
622		pModeDiff = a_tabDiffParam + _BwSpp150;
623    }
624
625    if (ps->DataInf.xyAppDpi.y > 150) {
626		if (ps->DataInf.xyAppDpi.y <= 300) {
627		    pModeType++;
628		    pModeDiff = a_tabDiffParam + _BwSpp300;
629		} else {
630		    pModeType += 2;
631		    pModeDiff = a_tabDiffParam + _BwSpp600;
632		}
633	}
634}
635
636/*.............................................................................
637 *
638 */
639static void fnSppGraySpeed( pScanData ps )
640{
641    pModeType = a_GraySettings + _FixParamSppGray;
642    pModeDiff = a_tabDiffParam + _GraySpp75;
643
644    if (ps->DataInf.xyAppDpi.y > 75) {
645		pModeType++;
646		pModeDiff = a_tabDiffParam + _GraySpp150_800;
647
648	    if (ps->DataInf.xyAppDpi.y > 150) {
649
650			if (ps->DataInf.xyAppDpi.y <= 300) {
651			    pModeType ++;
652	    		pModeDiff = a_tabDiffParam + _GraySpp300_1600;
653			} else {
654
655			    pModeType += 2;
656	    		pModeDiff = a_tabDiffParam + _GraySpp600_3200;
657
658			    if (ps->DataInf.dwAsicPixelsPerPlane <= 3200)
659					pModeDiff--;
660			}
661
662			if (ps->DataInf.dwAsicPixelsPerPlane <= 1600)
663			    pModeDiff--;
664	    }
665
666		if (ps->DataInf.dwAsicPixelsPerPlane <= 800)
667			pModeDiff--;
668    }
669}
670
671/*.............................................................................
672 *
673 */
674static void fnSppColorSpeed( pScanData ps )
675{
676    pModeType = a_ColorSettings + _FixParamSppColor;
677    pModeDiff = a_tabDiffParam + _ColorSpp60;
678
679    if (ps->DataInf.xyAppDpi.y > ps->wMinCmpDpi) {
680		pModeType ++;
681		pModeDiff = a_tabDiffParam + _ColorSpp100;
682
683		if (ps->DataInf.xyAppDpi.y > 100) {
684		    pModeType ++;
685		    pModeDiff = a_tabDiffParam + _ColorSpp150_800;
686
687	    	if (ps->DataInf.xyAppDpi.y > 150) {
688				pModeType ++;
689				pModeDiff = a_tabDiffParam + _ColorSpp300_2000;
690
691				if (ps->DataInf.xyAppDpi.y > 300) {
692
693				    pModeType ++;
694				    pModeDiff = a_tabDiffParam + _ColorSpp600_4000;
695
696				    if (ps->DataInf.dwAsicBytesPerPlane > 4000)
697						return;
698		    		else
699						pModeDiff--;
700				} else {
701				    if (ps->DataInf.dwAsicBytesPerPlane > 3000)
702						pModeDiff = a_tabDiffParam + _ColorSpp300_3000;
703		    		return;
704				}
705
706				if (ps->DataInf.dwAsicBytesPerPlane <= 2000) {
707				    pModeDiff--;
708				    if (ps->DataInf.dwAsicBytesPerPlane <= 1000) {
709						pModeDiff--;
710
711						if (ps->DataInf.dwAsicBytesPerPlane <= 500)
712						    pModeDiff--;
713		    		}
714				}
715	    	} else {
716
717				if (ps->DataInf.dwAsicBytesPerPlane <= 800)
718				    pModeDiff--;
719	    	}
720		}
721    }
722}
723
724/*.............................................................................
725 *
726 */
727static void fnBppLineArtSpeed( pScanData ps )
728{
729    pModeType = a_BwSettings + _FixParamBppBw;
730/* (+) Micky, 7-14-1998
731 *   pModeDiff = a_tabDiffParam + _BwBpp150;
732 */
733    pModeDiff = a_tabDiffParam + _BwBpp75;
734
735    if( ps->DataInf.xyAppDpi.y > 75 ) {
736		pModeType++;
737		pModeDiff = a_tabDiffParam + _BwBpp150;
738    }
739/* (-) Micky, 7-14-1998 */
740    if( ps->DataInf.xyAppDpi.y > 150 ) {
741		if( ps->DataInf.xyAppDpi.y <= 300 ) {
742		    pModeType++;
743		    pModeDiff = a_tabDiffParam + _BwBpp300;
744		} else {
745		    pModeType += 2;
746		    pModeDiff = a_tabDiffParam + _BwBpp600;
747		}
748	}
749}
750
751/*.............................................................................
752 *
753 */
754static void fnBppGraySpeed( pScanData ps )
755{
756    pModeType = a_GraySettings + _FixParamBppGray;
757/* (+) Micky, 7-14-1998
758 *   pModeDiff = a_tabDiffParam + _GrayBpp150;
759 */
760    pModeDiff = a_tabDiffParam + _GrayBpp75;
761
762    if( ps->DataInf.xyAppDpi.y > 75 ) {
763		pModeType++;
764		pModeDiff = a_tabDiffParam + _GrayBpp150;
765    }
766/* (-) Micky, 7-14-1998 */
767    if( ps->DataInf.xyAppDpi.y > 150 ) {
768		pModeType ++;
769		pModeDiff = a_tabDiffParam + _GrayBpp300_1600;
770		if( ps->DataInf.xyAppDpi.y > 300 ) {
771		    pModeType ++;
772		    pModeDiff = a_tabDiffParam + _GrayBpp600_3200;
773	    	if( ps->DataInf.dwAsicPixelsPerPlane <= 3200 )
774				pModeDiff --;
775		}
776		if( ps->DataInf.dwAsicPixelsPerPlane <= 1600 )
777		    pModeDiff --;
778    }
779}
780
781/*.............................................................................
782 *
783 */
784static void fnBppColorSpeed( pScanData ps )
785{
786    pModeType = a_ColorSettings + _FixParamBppColor;
787    pModeDiff = a_tabDiffParam + _ColorBpp60;
788
789    if (ps->DataInf.xyAppDpi.y > ps->wMinCmpDpi ) {
790		pModeType ++;
791		pModeDiff = a_tabDiffParam + _ColorBpp100;
792
793		if( ps->DataInf.xyAppDpi.y > 100 ) {
794		    pModeType ++;
795		    pModeDiff = a_tabDiffParam + _ColorBpp150_800;
796	    	if( ps->DataInf.xyAppDpi.y > 150 ) {
797				pModeType ++;
798				pModeDiff = a_tabDiffParam + _ColorBpp300_1600;
799				if( ps->DataInf.xyAppDpi.y > 300 ) {
800				    pModeType ++;
801				    pModeDiff = a_tabDiffParam + _ColorBpp600_3200;
802				    if( ps->DataInf.dwAsicBytesPerPlane <= 3200 )
803						return;
804		    		else
805						pModeDiff--;
806				}
807
808				if( ps->DataInf.dwAsicBytesPerPlane <= 1600 )
809				    pModeDiff--;
810	    	}
811
812		    if( ps->DataInf.dwAsicBytesPerPlane <= 800 )
813				pModeDiff--;
814		}
815    }
816}
817
818/*.............................................................................
819 *
820 */
821static void ioP98SppNegativeProcs( pScanData ps )
822{
823	if ( ps->DataInf.dwScanFlag & SCANDEF_Negative )
824		pModeType = a_FilmSettings + _FixParamSppNegative;
825    else
826		pModeType = a_FilmSettings + _FixParamSppPositive;
827
828    pModeDiff = a_tabDiffParam + _NegativeSpp150;
829
830    if (ps->DataInf.xyAppDpi.y > 150) {
831		if (ps->DataInf.xyAppDpi.y < 300) {
832		    pModeType ++;
833		    pModeDiff ++;
834		} else {
835		    pModeType += 2;
836		    pModeDiff += 2;
837		}
838	}
839
840    if (ps->DataInf.dwScanFlag & SCANDEF_Negative) {
841		if (ps->AsicReg.RD_LineControl == 144)
842		    pModeDiff += 4;
843		else
844	    	if (ps->AsicReg.RD_LineControl == 192)
845			pModeDiff += 7;
846    }
847}
848
849/*.............................................................................
850 *
851 */
852static void ioP98EppNegativeProcs( pScanData ps )
853{
854    if (ps->DataInf.dwScanFlag & SCANDEF_Negative)
855		pModeType = a_FilmSettings + _FixParamEppNegative;
856    else
857		pModeType = a_FilmSettings + _FixParamEppPositive;
858
859	pModeDiff = a_tabDiffParam + _NegativeEpp150;
860
861    if (ps->DataInf.xyAppDpi.y > 150) {
862		if (ps->DataInf.xyAppDpi.y < 300)
863		{
864	    	pModeType ++;
865		    pModeDiff ++;
866		} else {
867		    pModeType += 2;
868		    pModeDiff += 2;
869		}
870	}
871
872    if (ps->DataInf.dwScanFlag & SCANDEF_Negative) {
873		if (ps->AsicReg.RD_LineControl == 144)
874		    pModeDiff += 4;
875		else
876		    if (ps->AsicReg.RD_LineControl == 192)
877				pModeDiff += 7;
878    }
879}
880
881/*.............................................................................
882 *
883 */
884static void ioP98BppNegativeProcs( pScanData ps )
885{
886    if( ps->DataInf.dwScanFlag & SCANDEF_Negative) {
887		pModeType = a_FilmSettings + _FixParamBppNegative;
888	} else {
889		pModeType = a_FilmSettings + _FixParamBppPositive;
890	}
891
892    pModeDiff = a_tabDiffParam + _NegativeBpp150;
893
894    if( ps->DataInf.xyAppDpi.y > 150 ) {
895		if( ps->DataInf.xyAppDpi.y < 300 ) {
896		    pModeType ++;
897		    pModeDiff ++;
898		} else {
899		    pModeType += 2;
900		    pModeDiff += 2;
901		}
902	}
903
904    if ( ps->DataInf.dwScanFlag & SCANDEF_Negative ) {
905		if( ps->AsicReg.RD_LineControl == 144 ) {
906		    pModeDiff += 4;
907		} else {
908		    if( ps->AsicReg.RD_LineControl == 192 )
909				pModeDiff += 7;
910	    }
911	}
912}
913
914/*.............................................................................
915 *
916 */
917static void ioControlLampOnOff( pScanData ps )
918{
919	Byte lampStatus;
920
921	ps->fWarmupNeeded = _TRUE;
922
923	if( _IS_ASIC98(ps->sCaps.AsicID)) {
924
925	    lampStatus = ps->AsicReg.RD_ScanControl & _SCAN_LAMPS_ON;
926
927    	if (ps->bLastLampStatus != lampStatus) {
928
929			DBG( DBG_LOW, "Using OTHER Lamp !\n" );
930			ps->bLastLampStatus = lampStatus;
931
932			IOCmdRegisterToScanner( ps, ps->RegScanControl,
933									ps->AsicReg.RD_ScanControl);
934			return;
935	    }
936	} else {
937
938	    lampStatus = ps->AsicReg.RD_ScanControl & _SCAN_LAMP_ON;
939
940		if (ps->DataInf.dwScanFlag&(SCANDEF_Transparency + SCANDEF_Negative)) {
941	    	ps->bLampOn = 0;
942		} else {
943	    	ps->bLampOn = _SCAN_LAMP_ON;
944		}
945
946    	if (ps->bLastLampStatus != lampStatus) {
947			DBG( DBG_LOW, "Using OTHER Lamp !\n" );
948			ps->bLastLampStatus = lampStatus;
949			return;
950		}
951	}
952
953	ps->fWarmupNeeded = _FALSE;
954	DBG( DBG_LOW, "Using SAME Lamp !\n" );
955}
956
957/*.............................................................................
958 *
959 */
960static void ioP98InitialSetCurrentSpeed( pScanData ps )
961{
962	DBG( DBG_LOW, "ioP98InitialSetCurrentSpeed()\n" );
963
964    if( ps->DataInf.dwScanFlag & SCANDEF_TPA) {
965
966		switch (ps->IO.portMode)
967		{
968	    	case _PORT_SPP:  ioP98SppNegativeProcs( ps ); break;
969		    case _PORT_BIDI: ioP98BppNegativeProcs( ps ); break;
970
971		    default: ioP98EppNegativeProcs( ps ); break;
972		}
973    } else {
974
975		switch (ps->IO.portMode) {
976		    case _PORT_SPP:
977				a_fnSppSpeedProcs[ps->DataInf.wAppDataType](ps);
978				break;
979
980		    case _PORT_BIDI:
981				a_fnBppSpeedProcs[ps->DataInf.wAppDataType](ps);
982				break;
983
984		    default:
985				a_fnSpeedProcs[ps->DataInf.wAppDataType](ps);
986				break;
987		}
988    }
989
990    ps->wInitialStep = pModeType->wHomePos;
991    ps->wMaxMoveStep = pModeType->wMaxSteps;
992
993	ps->AsicReg.RD_LineControl = pModeType->bExposureTime;
994
995    if (ps->DataInf.dwScanFlag & SCANDEF_Negative)
996		ps->AsicReg.RD_LineControl = 144;
997
998#ifdef DEBUG
999    if( pModeType->bFlagScanMode != ps->Shade.bIntermediate )
1000        DBG( DBG_HIGH, "bSetScanModeFlag != bIntermediate\n" );
1001#endif
1002
1003    ps->bHpMotor 		 = pModeType->bMotorStep;
1004    ps->bSetScanModeFlag = pModeType->bFlagScanMode;
1005    ps->bShadingTimeFlag = pModeType->bTimesShading;
1006
1007    ps->dwFullStateSpeed = pModeDiff->dwFullSpeed;
1008    ps->bCurrentSpeed    = pModeDiff->bCurrentSpeed;
1009    ps->bStepSpeed       = pModeDiff->bStepSpeed;
1010
1011    if( ps->DataInf.xyAppDpi.y > 600 ) {
1012		if( ps->dwFullStateSpeed )
1013		    ps->dwFullStateSpeed = 0;
1014		else
1015		    ps->bStepSpeed <<= 1;
1016		ps->wMaxMoveStep <<= 1;
1017    }
1018}
1019
1020/************************ exported functions *********************************/
1021
1022/*.............................................................................
1023 * here we do some init work
1024 */
1025_LOC int IOFuncInitialize( pScanData ps )
1026{
1027	DBG( DBG_HIGH, "IOFuncInitialize()\n" );
1028
1029	if( NULL == ps )
1030		return _E_NULLPTR;
1031
1032	ps->lpEppColorHomePos  = &a_ColorSettings[0];
1033	ps->lpEppColorExposure = &a_ColorSettings[4];
1034	ps->lpBppColorHomePos  = &a_ColorSettings[5];
1035	ps->lpSppColorHomePos  = &a_ColorSettings[10];
1036	ps->a_tabDiffParam	   = a_tabDiffParam;
1037	ps->a_ColorSettings	   = a_ColorSettings;
1038
1039	/*
1040	 * depending on the asic, we set some functions
1041	 */
1042	if( _IS_ASIC98(ps->sCaps.AsicID)) {
1043
1044		ps->InitialSetCurrentSpeed = ioP98InitialSetCurrentSpeed;
1045
1046  	} else 	if( _IS_ASIC96(ps->sCaps.AsicID)) {
1047
1048		ps->InitialSetCurrentSpeed = ioP96InitialSetCurrentSpeed;
1049
1050 	} else {
1051
1052		DBG( DBG_HIGH , "NOT SUPPORTED ASIC !!!\n" );
1053		return _E_NOSUPP;
1054	}
1055
1056	return _OK;
1057}
1058
1059/*.............................................................................
1060 * 1) Fill scan states to asic.
1061 * 2) Refresh the scan states if necessary
1062 * 3) Wait for motor running within half-second period.
1063 */
1064_LOC Byte IOSetToMotorRegister( pScanData ps )
1065{
1066    ps->OpenScanPath( ps );
1067
1068    IORegisterToScanner( ps, ps->RegInitScanState );
1069
1070    IODownloadScanStates( ps );
1071
1072    ps->CloseScanPath( ps );
1073
1074	if( _ASIC_IS_98001 != ps->sCaps.AsicID ) {
1075		return 0;
1076	}
1077
1078	ps->Scan.bOldScanState = IOGetScanState( ps, _FALSE );
1079
1080    return ps->Scan.bOldScanState;
1081}
1082
1083/*.............................................................................
1084 * 1) If scanner path is not established, connect it
1085 * 2) Read the recent state count
1086 * 3) Disconnect the path if necessary
1087 */
1088_LOC Byte IOGetScanState( pScanData ps, Bool fOpenned )
1089{
1090    Byte bScanState, bScanStateNow;
1091
1092    if( !fOpenned && (_ASIC_IS_98003 != ps->sCaps.AsicID))
1093		ps->OpenScanPath( ps );
1094
1095    bScanState    = IODataFromRegister( ps, ps->RegGetScanState );
1096    bScanStateNow = IODataFromRegister( ps, ps->RegGetScanState );
1097
1098    if((bScanState != bScanStateNow)
1099		|| ((ps->sCaps.AsicID == _ASIC_IS_98001 && bScanState & 0x40))) {
1100		bScanState = IODataFromRegister( ps, ps->RegGetScanState);
1101	}
1102
1103    if( !fOpenned && (_ASIC_IS_98003 != ps->sCaps.AsicID))
1104		ps->CloseScanPath( ps );
1105
1106    return bScanState;
1107}
1108
1109/*.............................................................................
1110 * ASIC 98003 specific function to read status 2 register
1111 */
1112_LOC Byte IOGetExtendedStatus( pScanData ps )
1113{
1114    Byte b;
1115
1116    b = IODataFromRegister( ps, ps->RegStatus2 );
1117
1118    if( b == 0xff )
1119    	return 0;
1120    return b;
1121}
1122
1123/*.............................................................................
1124 * Read the scan state. Return the count with status bit, and count.
1125 */
1126_LOC void IOGetCurrentStateCount( pScanData ps, pScanState pScanStep )
1127{
1128    pScanStep->bStatus = IOGetScanState( ps, _FALSE );
1129    pScanStep->bStep   = pScanStep->bStatus & _SCANSTATE_MASK;
1130}
1131
1132/*.............................................................................
1133 * 1) If scanner connection is not established, return error
1134 * 2) If paper not ready, return error
1135 * 3) If scanning environment is not prepared, return error
1136 * 4) Setup the buffers for reassembler the CCD incoming lines.
1137 * 5) Initiate the registers of asic.
1138 * [NOTE]
1139 *	This routine combines from SetupAsicDependentVariables & IsReadyForScan
1140 *	routines in assembly source.
1141 */
1142_LOC int IOIsReadyForScan( pScanData ps )
1143{
1144	ULong  dw;
1145	pULong pdwTable;
1146
1147    if((_NO_BASE != ps->sCaps.wIOBase) &&
1148							   (ps->DataInf.dwVxdFlag & _VF_ENVIRONMENT_READY)) {
1149
1150		if( _ASIC_IS_98001 == ps->sCaps.AsicID ) {
1151
1152			IOSelectLampSource( ps );
1153			ioControlLampOnOff( ps );
1154			ps->AsicReg.RD_Motor0Control = 0;	    /* motor off */
1155			ps->AsicReg.RD_Motor1Control = 0;	    /* motor off */
1156			ps->AsicReg.RD_ModelControl = (_ModelDpi600 +
1157										   _LED_ACTIVITY + _LED_CONTROL);
1158			ps->AsicReg.RD_Origin = 0;
1159			ps->AsicReg.RD_Pixels = 5110;
1160
1161        } else if( _ASIC_IS_98003 == ps->sCaps.AsicID ) {
1162
1163            ps->OpenScanPath( ps );
1164            P12SetGeneralRegister( ps );
1165            ps->CloseScanPath( ps );
1166
1167			ioControlLampOnOff( ps );
1168
1169		} else {
1170
1171			ioControlLampOnOff( ps );
1172
1173			/* SetupAsicDependentVariables */
1174			ps->pPutBufR = ps->pGetBufR = ps->pPrescan16; /* 1st color plane */
1175			ps->pPutBufG = ps->pGetBufG = ps->pPrescan8;  /* 2nd color plane */
1176
1177			ps->AsicReg.RD_ScanControl    = ps->bLampOn;
1178			ps->Asic96Reg.RD_MotorControl = 0;
1179			ps->AsicReg.RD_Origin         = 0;
1180			ps->AsicReg.RD_ModelControl   = ps->Device.ModelCtrl | _ModelWhiteIs0;
1181			ps->AsicReg.RD_Pixels         = 5110; /* ps->RdPix; */
1182			IOPutOnAllRegisters( ps );
1183		}
1184
1185		/*
1186		 * MotorInitiate
1187		 */
1188        if( _ASIC_IS_98003 != ps->sCaps.AsicID ) {
1189    		for (dw = _SCANSTATE_BYTES,
1190	    	     pdwTable = (pULong)ps->a_wMoveStepTable; dw; dw--, pdwTable++) {
1191	        	*pdwTable = 0x10001;
1192    		}
1193
1194	    	memset( ps->a_bColorByteTable, 0, _NUMBER_OF_SCANSTEPS );
1195        }
1196
1197		return _OK;
1198    }
1199
1200	return _E_SEQUENCE;
1201}
1202
1203/*.............................................................................
1204 *
1205 */
1206_LOC void IOSetXStepLineScanTime( pScanData ps, Byte b )
1207{
1208    ps->AsicReg.RD_LineControl = b;
1209    ps->bSpeed1  = b;
1210    ps->bSpeed2  = b >> 1;
1211    ps->bSpeed4  = b >> 2;
1212	ps->bSpeed8  = b >> 3;
1213    ps->bSpeed16 = b >> 4;
1214    ps->bSpeed32 = b >> 5;
1215    ps->bSpeed24 = b / 24;
1216    ps->bSpeed12 = b / 12;
1217    ps->bSpeed6  = b / 6;
1218    ps->bSpeed3  = b / 3;
1219}
1220
1221/*.............................................................................
1222 * 1) Reset and fill all new scan states (Mode = Scan)
1223 * 2) Refresh scan state
1224 * 3) Wait for motor running within half second.
1225 */
1226_LOC void IOSetToMotorStepCount( pScanData ps )
1227{
1228	ULong	 dw;
1229    pUChar	 pb;
1230	TimerDef timer;
1231
1232  	ps->OpenScanPath( ps );
1233
1234	if( _ASIC_IS_98001 == ps->sCaps.AsicID ) {
1235	    IORegisterToScanner( ps, ps->RegInitScanState );
1236	} else {
1237	    ps->AsicReg.RD_ModeControl = _ModeScan;
1238	    IODataToRegister( ps, ps->RegModeControl, _ModeScan );
1239	}
1240    IORegisterToScanner( ps, ps->RegScanStateControl );
1241
1242    for (dw =  _SCANSTATE_BYTES, pb = ps->a_nbNewAdrPointer; dw; dw--, pb++)
1243		IODataToScanner( ps, *pb );
1244
1245    IORegisterToScanner( ps, ps->RegRefreshScanState );
1246
1247	MiscStartTimer( &timer, (_SECOND/2));
1248    do {
1249
1250		if (!( IOGetScanState( ps, _TRUE) & _SCANSTATE_STOP))
1251		    break;
1252    }
1253    while( !MiscCheckTimer(&timer));
1254
1255/* CHECK - this line has been added by Rick ? Why ?
1256 *   return (pScanData->bOldTempScanState = GetScanState (pScanData, FALSE));
1257 */
1258	ps->Scan.bOldScanState = IOGetScanState( ps, _TRUE );
1259
1260    ps->CloseScanPath( ps );
1261}
1262
1263/*.............................................................................
1264 *
1265 */
1266_LOC void IOSelectLampSource( pScanData ps )
1267{
1268 	ps->AsicReg.RD_ScanControl &= (~_SCAN_LAMPS_ON);
1269
1270    if (ps->DataInf.dwScanFlag & (SCANDEF_TPA)) {
1271		ps->AsicReg.RD_ScanControl |= _SCAN_TPALAMP_ON;
1272	} else {
1273		ps->AsicReg.RD_ScanControl |= _SCAN_NORMALLAMP_ON;
1274	}
1275}
1276
1277/*.............................................................................
1278 *
1279 */
1280_LOC Bool IOReadOneShadingLine( pScanData ps, pUChar pBuf, ULong len )
1281{
1282	TimerDef timer;
1283
1284	MiscStartTimer( &timer, _SECOND );
1285
1286    if( _ASIC_IS_98003 == ps->sCaps.AsicID )
1287        ps->Scan.bFifoSelect = ps->RegGFifoOffset;
1288
1289    do {
1290    	if( IOReadFifoLength( ps ) >= ps->AsicReg.RD_Pixels ) {
1291
1292            IOReadColorData( ps, pBuf, len );
1293	        return _TRUE;
1294    	}
1295    } while( _OK == MiscCheckTimer( &timer ));
1296
1297    return _FALSE;
1298}
1299
1300/*.............................................................................
1301 *
1302 */
1303_LOC ULong IOReadFifoLength( pScanData ps )
1304{
1305	DataType Data;
1306
1307    Data.dwValue  = 0;
1308
1309    if( _ASIC_IS_98003 != ps->sCaps.AsicID )
1310    	ps->OpenScanPath( ps );
1311
1312    IODataToRegister( ps, ps->RegBitDepth, _BIT0_7 );
1313    Data.dwOverlap.w1st.b1st = IODataFromRegister( ps, ps->Scan.bFifoSelect );
1314
1315    IODataToRegister( ps, ps->RegBitDepth, _BIT8_15 );
1316    Data.dwOverlap.w1st.b2nd = IODataFromRegister( ps, ps->Scan.bFifoSelect );
1317
1318    IODataToRegister( ps, ps->RegBitDepth, _BIT16_20 );
1319    Data.dwOverlap.w2nd.b1st = (IODataFromRegister( ps, ps->Scan.bFifoSelect) & 0x0f);
1320
1321    if( _ASIC_IS_98003 != ps->sCaps.AsicID )
1322        ps->CloseScanPath( ps );
1323
1324    return Data.dwValue;
1325}
1326
1327/*.............................................................................
1328 * 1) Initiates the scan states
1329 * 2) Write the contents to corresponding registers (from ps->RegModeControl to
1330 *    ps->RegGreenGainOutDirect (P9363) or from ps->RegModeControl to
1331 *	  ps->RegModeControl2 (48xx)
1332 */
1333_LOC void IOPutOnAllRegisters( pScanData ps )
1334{
1335	pUChar	pValue;
1336    Byte	bReg;
1337
1338	/* setup scan states */
1339    if( _ASIC_IS_98003 == ps->sCaps.AsicID )
1340        IODownloadScanStates( ps );
1341    else {
1342    	IOSetToMotorRegister( ps );
1343    	ps->OpenScanPath( ps );
1344    }
1345
1346	if( _IS_ASIC98(ps->sCaps.AsicID)) {
1347
1348		IODataToRegister(ps, ps->RegStepControl, ps->AsicReg.RD_StepControl);
1349    	IODataToRegister(ps, ps->RegMotor0Control,
1350						 ps->AsicReg.RD_Motor0Control);
1351
1352	    if( _ASIC_IS_98003 == ps->sCaps.AsicID )
1353            IODataToRegister(ps,ps->RegLineControl,ps->AsicReg.RD_LineControl);
1354
1355	    IODataToRegister(ps, ps->RegXStepTime, 	  ps->AsicReg.RD_XStepTime);
1356    	IODataToRegister(ps, ps->RegModelControl, ps->AsicReg.RD_ModelControl);
1357
1358		/* the 1st register to write */
1359    	pValue = (pUChar)&ps->AsicReg.RD_Dpi;
1360
1361		/* 0x21 - 0x28 */
1362    	for (bReg = ps->RegDpiLow;
1363			 bReg <= ps->RegThresholdHigh; bReg++, pValue++) {
1364
1365			IODataToRegister( ps, bReg, *pValue);
1366		}
1367
1368    	IORegisterToScanner( ps, ps->RegInitDataFifo );
1369	    IORegisterToScanner( ps, ps->RegRefreshScanState );
1370
1371	    if( _ASIC_IS_98003 == ps->sCaps.AsicID )
1372            IODataToRegister( ps, ps->RegModeControl, _ModeScan );
1373        else
1374            IODataToRegister( ps, ps->RegModeControl, (_ModeScan + _ModeFifoRSel));
1375
1376	} else {
1377
1378		/*
1379		 * the original driver uses a loop, starting at RegModeControl
1380		 * 0x18 - 0x26
1381		 * as we use the Asic96Reg structure only  for the differences
1382		 * to the AsicReg struct, we have to write to each register by hand
1383		 */
1384		IODataToRegister( ps, ps->RegModeControl, ps->AsicReg.RD_ModeControl );
1385		IODataToRegister( ps, ps->RegLineControl, ps->AsicReg.RD_LineControl );
1386		IODataToRegister( ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl );
1387		IODataToRegister( ps, ps->RegMotorControl,
1388											   ps->Asic96Reg.RD_MotorControl );
1389		IODataToRegister( ps, ps->RegModelControl,
1390												 ps->AsicReg.RD_ModelControl );
1391		IODataToRegister( ps, ps->RegMemAccessControl,
1392		 				  	  		       ps->Asic96Reg.RD_MemAccessControl );
1393
1394#if 0
1395		DBG( DBG_LOW, "[0x%02x] = 0x%02x\n",
1396							  ps->RegModeControl, ps->AsicReg.RD_ModeControl );
1397		DBG( DBG_LOW, "[0x%02x] = 0x%02x\n",
1398							  ps->RegLineControl, ps->AsicReg.RD_LineControl );
1399		DBG( DBG_LOW, "[0x%02x] = 0x%02x\n",
1400							  ps->RegScanControl, ps->AsicReg.RD_ScanControl );
1401		DBG( DBG_LOW, "[0x%02x] = 0x%02x\n",
1402						  ps->RegMotorControl, ps->Asic96Reg.RD_MotorControl );
1403		DBG( DBG_LOW, "[0x%02x] = 0x%02x\n",
1404					   		ps->RegModelControl, ps->AsicReg.RD_ModelControl );
1405		DBG( DBG_LOW, "[0x%02x] = 0x%02x\n",
1406				  ps->RegMemAccessControl, ps->Asic96Reg.RD_MemAccessControl );
1407#endif
1408
1409    	pValue = (pUChar)&ps->AsicReg.RD_Dpi;
1410
1411		/* 0x21 - 0x26 */
1412    	for (bReg = ps->RegDpiLow;
1413			 bReg <= ps->RegWidthPixelsHigh; bReg++, pValue++) {
1414
1415			IODataToRegister( ps, bReg, *pValue );
1416#if 0
1417			DBG( DBG_LOW, "[0x%02x] = 0x%02x\n", bReg, *pValue );
1418#endif
1419		}
1420
1421		/* the rest */
1422		IODataToRegister( ps, ps->RegThresholdControl,
1423									 (Byte)ps->AsicReg.RD_ThresholdControl );
1424
1425		IODataToRegister( ps, ps->RegWatchDogControl,
1426									 (Byte)ps->Asic96Reg.RD_WatchDogControl );
1427
1428		IODataToRegister( ps, ps->RegModelControl2,
1429										  ps->Asic96Reg.u26.RD_ModelControl2 );
1430
1431#if 0
1432		DBG( DBG_LOW, "[0x%02x] = 0x%02x\n",
1433					ps->RegThresholdControl, ps->AsicReg.RD_ThresholdControl );
1434		DBG( DBG_LOW, "[0x%02x] = 0x%02x\n",
1435					ps->RegWatchDogControl, ps->Asic96Reg.RD_WatchDogControl );
1436		DBG( DBG_LOW, "[0x%02x] = 0x%02x\n",
1437					ps->RegModelControl2, ps->Asic96Reg.u26.RD_ModelControl2 );
1438#endif
1439		IORegisterToScanner( ps, ps->RegInitDataFifo );
1440	}
1441
1442    if( _ASIC_IS_98003 != ps->sCaps.AsicID )
1443        ps->CloseScanPath( ps );
1444}
1445
1446/*.............................................................................
1447 *
1448 */
1449_LOC void IOReadColorData( pScanData ps, pUChar pBuf, ULong len )
1450{
1451   	ps->AsicReg.RD_ModeControl = _ModeFifoRSel;
1452    IOReadScannerImageData( ps, pBuf, len );
1453
1454    ps->AsicReg.RD_ModeControl = _ModeFifoGSel;
1455    IOReadScannerImageData( ps, pBuf + len, len );
1456
1457  	ps->AsicReg.RD_ModeControl = _ModeFifoBSel;
1458    IOReadScannerImageData( ps, pBuf + len * 2,  len );
1459}
1460
1461/* END PLUSTEK-PP_GENERICIO.C ...............................................*/
1462