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 */
79 typedef void (*pFnSpeed_Set)(pScanData);
80 
81 static 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 
108 static 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 
123 static 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 
138 static 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 
156 static 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 
338 static pModeTypeVar	pModeType;
339 static pDiffModeVar	pModeDiff;
340 
341 /*
342  * prototypes for the speed procs (ASIC 98001), EPP, SPP and BIDI
343  */
344 static void fnLineArtSpeed( pScanData ps );
345 static void fnGraySpeed   ( pScanData ps );
346 static void fnColorSpeed  ( pScanData ps );
347 
348 static void fnSppLineArtSpeed( pScanData ps );
349 static void fnSppGraySpeed   ( pScanData ps );
350 static void fnSppColorSpeed  ( pScanData ps );
351 
352 static void fnBppLineArtSpeed( pScanData ps );
353 static void fnBppGraySpeed   ( pScanData ps );
354 static void fnBppColorSpeed  ( pScanData ps );
355 
356 /*
357  * some procedures for the different modes
358  */
359 static pFnSpeed_Set a_fnSpeedProcs[5] = {
360 	fnLineArtSpeed,
361 	fnGraySpeed,
362 	fnGraySpeed,
363 	fnColorSpeed,
364 	fnColorSpeed
365 };
366 
367 static pFnSpeed_Set a_fnSppSpeedProcs[5] = {
368 	fnSppLineArtSpeed,
369 	fnSppGraySpeed,
370 	fnSppGraySpeed,
371 	fnSppColorSpeed,
372 	fnSppColorSpeed
373 };
374 
375 static 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  */
ioP96InitialSetCurrentSpeed( pScanData ps )389 static 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  */
fnLineArtSpeed( pScanData ps )503 static 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  */
fnGraySpeed( pScanData ps )527 static 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  */
fnColorSpeed( pScanData ps )553 static 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  */
fnSppLineArtSpeed( pScanData ps )614 static 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  */
fnSppGraySpeed( pScanData ps )639 static 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  */
fnSppColorSpeed( pScanData ps )674 static 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  */
fnBppLineArtSpeed( pScanData ps )727 static 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  */
fnBppGraySpeed( pScanData ps )754 static 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  */
fnBppColorSpeed( pScanData ps )784 static 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  */
ioP98SppNegativeProcs( pScanData ps )821 static 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  */
ioP98EppNegativeProcs( pScanData ps )852 static 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  */
ioP98BppNegativeProcs( pScanData ps )884 static 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  */
ioControlLampOnOff( pScanData ps )917 static 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  */
ioP98InitialSetCurrentSpeed( pScanData ps )960 static 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  */
IOFuncInitialize( pScanData ps )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  */
IOSetToMotorRegister( pScanData ps )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  */
IOGetScanState( pScanData ps, Bool fOpenned )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  */
IOGetExtendedStatus( pScanData ps )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  */
IOGetCurrentStateCount( pScanData ps, pScanState pScanStep )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  */
IOIsReadyForScan( pScanData ps )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  */
IOSetXStepLineScanTime( pScanData ps, Byte b )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  */
IOSetToMotorStepCount( pScanData ps )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  */
IOSelectLampSource( pScanData ps )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  */
IOReadOneShadingLine( pScanData ps, pUChar pBuf, ULong len )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  */
IOReadFifoLength( pScanData ps )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  */
IOPutOnAllRegisters( pScanData ps )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  */
IOReadColorData( pScanData ps, pUChar pBuf, ULong len )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