• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* @file plustek-pp_p9636.c
2  * @brief here we have all functionality according to the p9636t
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 - Added some comments
12  * - 0.32 - minor bug-fixes
13  *        - change p9636ReconnectScannerPath
14  *        - moved function IOSetStartStopRegister into this file
15  * - 0.33 - went back to original three calls to p9636ReconnectScannerPath
16  *          to make sure that HP-printers will not start to print during
17  *          scan-process
18  *        - removed function p9636PositionLamp()
19  * - 0.34 - no changes
20  * - 0.35 - no changes
21  * - 0.36 - changes, due to define renaming
22  * - 0.37 - move p9636OpenScanPath, p9636CloseScanPath
23  *          and p9636RegisterToScanner to io.c
24  *        - removed skipping of the memory test for OP9636P
25  *        - removed // comments
26  * - 0.38 - added function p9636PutToIdleMode()
27  *        - moved p9636ReadWriteTest to io.c
28  *        - added function p9636Calibration
29  *        - renamed function p9636SetP98001Init() to p9636InitP98001()
30  * - 0.39 - no changes
31  * - 0.40 - no changes
32  * - 0.41 - no changes
33  * - 0.42 - changed include names
34  * - 0.43 - no changes
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 /*************************** some definitions ********************************/
77 
78 #define _NUM_OF_DACREGS_W8144    11
79 
80 /*************************** some local vars *********************************/
81 
82 static UShort P97ColorModeRegister[] = {
83 	0x022C, 0x2A39, 0x0A3A, 0x373B, 0x163C, 0x0E41, 0x9042, 0x0143,
84 	0x2744, 0x2745, 0x0146, 0x0347, 0x2748, 0x2F49, 0x094A, 0x034B,
85 	0x074C, 0x054D, 0x064E, 0x0850, 0x0D51, 0x0C52, 0x0B53, 0x00F0,
86 
87 	0x022C, 0x3D39, 0x043A, 0x463B, 0x063C, 0x1F41, 0x8C42, 0x0143,
88 	0x1344, 0x1345, 0xF246, 0x0247, 0x1348, 0x1349, 0xFA4A, 0x004B,
89 	0x074C, 0x054D, 0x0E4E, 0x0150, 0x0651, 0x1252, 0x0B53, 0x00F0,
90 
91 	0x002C, 0x1639, 0x033A, 0x1F3B, 0x073C, 0x0441, 0x1E42, 0x0143,
92 	0x1344, 0x1345, 0xF146, 0x0247, 0x1348, 0x1349, 0xF94A, 0x044B,
93 	0x074C, 0x054D, 0x034E, 0x0650, 0x0351, 0x0952, 0x0B53, 0x00F0,
94 
95 	0x022C, 0x1839, 0x043A, 0x1D3B, 0x033C, 0x0C41, 0x8442, 0x0343,
96 	0x0A44, 0x0845, 0xFA46, 0x0447, 0x0A48, 0x0849, 0xF24A, 0x024B,
97 	0x034C, 0x024D, 0x0E4E, 0x0050, 0x0951, 0x0352, 0x0353, 0x00F0
98 };
99 
100 static UShort P17ColorModeRegister[] = {
101 	0x022C, 0x2C39, 0x053A, 0x3c3B, 0x0e3C, 0x0E41, 0x9042, 0x0143,
102 	0x2744, 0x2745, 0x0146, 0x0247, 0x2748, 0x2F49, 0x094A, 0x054B,
103 	0x074C, 0x054D, 0x064E, 0x0850, 0x0D51, 0x0C52, 0x0B53, 0x00F0,
104 
105 	0x022C, 0x3D39, 0x043A, 0x463B, 0x063C, 0x1F41, 0x8C42, 0x0143,
106 	0x1344, 0x1345, 0xF246, 0x0147, 0x1348, 0x1349, 0xFA4A, 0x004B,
107 	0x074C, 0x054D, 0x0E4E, 0x0150, 0x0651, 0x1252, 0x0B53, 0x00F0,
108 
109 	0x002C, 0x1639, 0x023A, 0x1a3B, 0x053C, 0x0441, 0x1E42, 0x0143,
110 	0x1344, 0x1345, 0xF146, 0x0147, 0x1348, 0x1349, 0xF94A, 0x044B,
111 	0x074C, 0x054D, 0x034E, 0x0650, 0x0351, 0x0952, 0x0B53, 0x00F0,
112 
113 	0x022C, 0x1839, 0x043A, 0x1D3B, 0x033C, 0x0C41, 0x8442, 0x0343,
114 	0x0A44, 0x0845, 0xFA46, 0x0347, 0x0A48, 0x0849, 0xF24A, 0x024B,
115 	0x034C, 0x024D, 0x0E4E, 0x0050, 0x0951, 0x0352, 0x0353, 0x00F0
116 };
117 
118 static UShort P535ColorModeRegister[] = {
119 	0x022C, 0x2F39, 0x883A, 0x403B, 0x0F3C, 0x0E41, 0x9042, 0x0143,
120 	0x2744, 0x2745, 0x0146, 0x0147, 0x2748, 0x2F49, 0x094A, 0x034B,
121 	0x074C, 0x054D, 0x064E, 0x0850, 0x0D51, 0x0C52, 0x0B53, 0x00F0,
122 
123 	0x022C, 0x3D39, 0x843A, 0x463B, 0x063C, 0x1F41, 0x8C42, 0x0143,
124 	0x1344, 0x1345, 0xF246, 0x0147, 0x1348, 0x1349, 0xFA4A, 0x014B,
125 	0x074C, 0x054D, 0x0E4E, 0x0150, 0x0651, 0x1252, 0x0B53, 0x00F0,
126 
127 	0x002C, 0x1639, 0x833A, 0x1F3B, 0x073C, 0x0441, 0x1E42, 0x0143,
128 	0x1344, 0x1345, 0xF146, 0x0147, 0x1348, 0x1349, 0xF94A, 0x044B,
129 	0x074C, 0x054D, 0x034E, 0x0650, 0x0351, 0x0952, 0x0B53, 0x00F0,
130 
131 	0x022C, 0x1639, 0x833A, 0x1D3B, 0x033C, 0x0C41, 0x8442, 0x0343,
132 	0x0A44, 0x0845, 0xFA46, 0x0347, 0x0A48, 0x0849, 0xF24A, 0x024B,
133 	0x034C, 0x024D, 0x0E4E, 0x0050, 0x0951, 0x0352, 0x0353, 0x00F0
134 };
135 
136 static UShort P518ColorModeRegister[] = {
137 	0x022C, 0x2F39, 0x883A, 0x403B, 0x0F3C, 0x0E41, 0x9042, 0x0143,
138 	0x2744, 0x2745, 0x0146, 0x0147, 0x2748, 0x2F49, 0x094A, 0x034B,
139 	0x074C, 0x054D, 0x064E, 0x0850, 0x0D51, 0x0C52, 0x0B53, 0x00F0,
140 
141 	0x022C, 0x3D39, 0x843A, 0x463B, 0x063C, 0x1F41, 0x8C42, 0x0143,
142 	0x1344, 0x1345, 0xF246, 0x0147, 0x1348, 0x1349, 0xFA4A, 0x014B,
143 	0x074C, 0x054D, 0x0E4E, 0x0150, 0x0651, 0x1252, 0x0B53, 0x00F0,
144 
145 	0x002C, 0x1639, 0x853A, 0x1F3B, 0x073C, 0x0441, 0x1E42, 0x0143,
146 	0x1344, 0x1345, 0xF146, 0x0147, 0x1348, 0x1349, 0xF94A, 0x044B,
147 	0x074C, 0x054D, 0x034E, 0x0650, 0x0351, 0x0952, 0x0B53, 0x00F0,
148 
149 	0x022C, 0x1639, 0x833A, 0x1D3B, 0x033C, 0x0C41, 0x8442, 0x0343,
150 	0x0A44, 0x0845, 0xFA46, 0x0347, 0x0A48, 0x0849, 0xF24A, 0x024B,
151 	0x034C, 0x024D, 0x0E4E, 0x0050, 0x0951, 0x0352, 0x0353, 0x00F0
152 };
153 
154 static UShort P56ColorModeRegister[] = {
155 	0x022C, 0x2F39, 0x043A, 0x363B, 0x033C, 0x0E41, 0x9042, 0x0143,
156 	0x2744, 0x2745, 0x0146, 0x0247, 0x2748, 0x2F49, 0x094A, 0x034B,
157 	0x074C, 0x054D, 0x064E, 0x0850, 0x0D51, 0x0C52, 0x0B53, 0x00F0,
158 
159 	0x022C, 0x3D39, 0x033A, 0x443B, 0x033C, 0x1F41, 0x8C42, 0x0143,
160 	0x1344, 0x1345, 0xF246, 0x0247, 0x1348, 0x1349, 0xFA4A, 0x004B,
161 	0x074C, 0x054D, 0x0E4E, 0x0150, 0x0651, 0x1252, 0x0B53, 0x00F0,
162 
163 	0x002C, 0x1439, 0x033A, 0x1D3B, 0x033C, 0x0441, 0x1E42, 0x0143,
164 	0x1344, 0x1345, 0xF146, 0x0247, 0x1348, 0x1349, 0xF94A, 0x044B,
165 	0x074C, 0x054D, 0x034E, 0x0650, 0x0351, 0x0952, 0x0B53, 0x00F0,
166 
167 	0x022C, 0x1639, 0x033A, 0x1B3B, 0x023C, 0x0C41, 0x8442, 0x0343,
168 	0x0A44, 0x0845, 0xFA46, 0x0447, 0x0A48, 0x0849, 0xF24A, 0x024B,
169 	0x034C, 0x024D, 0x0E4E, 0x0050, 0x0951, 0x0352, 0x0353, 0x00F0
170 };
171 
172 static UShort P539ColorModeRegister[] = {
173 	0x022C, 0x2F39, 0x883A, 0x403B, 0x0F3C, 0x0E41, 0x9042, 0x0143,
174 	0x2744, 0x2745, 0x0146, 0x0147, 0x2748, 0x2F49, 0x094A, 0x034B,
175 	0x074C, 0x054D, 0x064E, 0x0850, 0x0D51, 0x0C52, 0x0B53, 0x00F0,
176 
177 	0x022C, 0x3D39, 0x843A, 0x463B, 0x063C, 0x1F41, 0x8C42, 0x0143,
178 	0x1344, 0x1345, 0xF246, 0x0147, 0x1348, 0x1349, 0xFA4A, 0x014B,
179 	0x074C, 0x054D, 0x0E4E, 0x0150, 0x0651, 0x1252, 0x0B53, 0x00F0,
180 
181 	0x002C, 0x1639, 0x833A, 0x1F3B, 0x073C, 0x0441, 0x1E42, 0x0143,
182 	0x1344, 0x1345, 0xF146, 0x0147, 0x1348, 0x1349, 0xF94A, 0x044B,
183 	0x074C, 0x054D, 0x034E, 0x0650, 0x0351, 0x0952, 0x0B53, 0x00F0,
184 
185 	0x022C, 0x1639, 0x833A, 0x1D3B, 0x033C, 0x0C41, 0x8442, 0x0343,
186 	0x0A44, 0x0845, 0xFA46, 0x0347, 0x0A48, 0x0849, 0xF24A, 0x024B,
187 	0x034C, 0x024D, 0x0E4E, 0x0050, 0x0951, 0x0352, 0x0353, 0x00F0
188 };
189 
190 static RegDef WolfsonDAC8144[_NUM_OF_DACREGS_W8144] = {
191     {0x01, 0x01}, {0x02, 0x04}, {0x03, 0x42}, {0x05, 0x10}, {0x20, 0xd0},
192     {0x21, 0xd0}, {0x22, 0xd0}, {0x24, 0x00}, {0x25, 0x00},	{0x26, 0x00},
193     {0x02, 0x04}
194 };
195 
196 static RegDef ccdStop[] = {
197     {0x41, 0xff}, {0x42, 0xff}, {0x4b, 0xff}, {0x4c, 0xff},
198     {0x4d, 0xff}, {0x4e, 0xff}, {0x2a, 0x01}, {0x2b, 0x00},
199     {0x2d, 0x00}, {0x1b, 0x19}, {0x14, 0xff}, {0x15, 0x00}
200 };
201 
202 static DACTblDef shadingVar = {
203     {{100, 100, 94}}, {{0x20, 0x20, 0x20}},
204     {{0x10, 0x10, 0x10}}, {{0x00, 0x00, 0x00}}, {{0xd0, 0xd0, 0xd0}}, 0
205 };
206 
207 /*************************** local functions *********************************/
208 
209 /*.............................................................................
210  * initialize the register values for the 98001 asic
211  */
p9636InitializeAsicRegister(pScanData ps)212 static void p9636InitializeAsicRegister( pScanData ps )
213 {
214     memset( &ps->AsicReg, 0, sizeof(RegData));
215     ps->AsicReg.RD_ScanControl = _SCAN_1ST_AVERAGE + _SCAN_BYTEMODE;
216     ps->Scan.bFifoSelect       = ps->RegGFifoOffset;
217 }
218 
219 /*.............................................................................
220  * 1) Setup the registers of asic.
221  * 2) Determine which type of CCD we are using
222  * 3) According to the CCD, prepare the CCD dependent veriables
223  *    SONY CCD:
224  *		The color exposure sequence: Red, Green (after 11 red lines),
225  *		Blue (after 8 green lines)
226  *	TOSHIBA CCD:
227  *		The color exposure sequence: Red, Blue (after 11 red lines),
228  *		Green (after 8 blue lines)
229  */
p9636Init98001(pScanData ps,Bool shading)230 static void p9636Init98001( pScanData ps, Bool shading )
231 {
232     Byte   	 bData;
233     UShort   w;
234 	ULong    dwID;
235     DataType Data;
236     pUShort  pw;
237 
238 	DBG( DBG_LOW, "p9636InitP98001(%d)\n", shading );
239 
240     bData = IODataRegisterFromScanner( ps, ps->RegConfiguration );
241 
242     ps->Device.bCCDID = bData;
243     ps->Device.bCCDID &= _P98_CCD_TYPE_ID;
244 	DBG( DBG_HIGH, "bData = 0x%04X, PCB-ID = 0x%02X\n", bData, (bData >> 4));
245 
246 	/* encode the CCD-id into the flag parameter */
247     dwID = (ULong)ps->Device.bCCDID;
248     dwID = dwID << 16;
249     ps->sCaps.dwFlag |= dwID;
250 
251     /* do the defaults here and the differences below */
252     ps->Device.f0_8_16 = _FALSE;
253 
254     ps->Shade.pCcdDac->DarkCmpHi.Colors.Red   = 0x30;
255     ps->Shade.pCcdDac->DarkCmpLo.Colors.Red   = 0x20;
256     ps->Shade.pCcdDac->DarkCmpHi.Colors.Green = 0x30;
257     ps->Shade.pCcdDac->DarkCmpLo.Colors.Green = 0x20;
258     ps->Shade.pCcdDac->DarkCmpHi.Colors.Blue  = 0x30;
259     ps->Shade.pCcdDac->DarkCmpLo.Colors.Blue  = 0x20;
260 
261     ps->Shade.pCcdDac->DarkOffSub.Colors.Red   = 0x10;
262     ps->Shade.pCcdDac->DarkOffSub.Colors.Green = 0x10;
263     ps->Shade.pCcdDac->DarkOffSub.Colors.Blue  = 0x10;
264 
265     ps->Shade.pCcdDac->DarkDAC.Colors.Red   = 0xd0;
266     ps->Shade.pCcdDac->DarkDAC.Colors.Green = 0xd0;
267     ps->Shade.pCcdDac->DarkDAC.Colors.Blue  = 0xd0;
268 
269 	/*
270 	 * yes, I know this function is rather ugly to read, but depending
271 	 * on the scan-settings and the detected CCD-chip it prepares the
272 	 * settings for the DAC
273 	 */
274     ps->Device.dwModelOriginY = 0x50;
275     ps->Device.wNumDACRegs    = _NUM_OF_DACREGS_W8144;
276 
277     switch( ps->Device.bCCDID ) {
278 
279 	case _CCD_3797:
280 		DBG( DBG_HIGH, "CCD-ID = 0x%02X = _CCD_3797\n", ps->Device.bCCDID );
281         ps->Shade.pCcdDac->GainResize.Colors.Red   = 100;
282         ps->Shade.pCcdDac->GainResize.Colors.Green = 100;
283         ps->Shade.pCcdDac->GainResize.Colors.Blue  =  96;
284 
285 	    if( ps->DataInf.dwScanFlag & SCANDEF_TPA ) {
286 			if (ps->DataInf.dwScanFlag & SCANDEF_Transparency) {
287 
288                 ps->Shade.pCcdDac->GainResize.Colors.Red   = 130;
289                 ps->Shade.pCcdDac->GainResize.Colors.Green = 110;
290                 ps->Shade.pCcdDac->GainResize.Colors.Blue  = 112;
291 
292                 ps->Shade.pCcdDac->DarkDAC.Colors.Red   = 0xcc;
293                 ps->Shade.pCcdDac->DarkDAC.Colors.Green = 0xcc;
294                 ps->Shade.pCcdDac->DarkDAC.Colors.Blue  = 0xcc;
295 
296 			    ps->bsPreRedDAC = ps->bsPreGreenDAC = ps->bsPreBlueDAC = 0xcc;
297 
298 			    ps->wsDACCompareHighRed   = 0x0B0;
299 			    ps->wsDACCompareLowRed 	  = 0x0A0;
300 			    ps->wsDACCompareHighGreen = 0x90;
301 			    ps->wsDACCompareLowGreen  = 0x80;
302 		    	ps->wsDACCompareHighBlue  = 0x90;
303 			    ps->wsDACCompareLowBlue   = 0x80;
304 		    	ps->wsDACOffsetRed =
305 				ps->wsDACOffsetGreen = ps->wsDACOffsetBlue = 0x30;
306 			} else {
307                 ps->Shade.pCcdDac->GainResize.Colors.Red   =  97;
308                 ps->Shade.pCcdDac->GainResize.Colors.Green =  82;
309                 ps->Shade.pCcdDac->GainResize.Colors.Blue  = 100;
310 
311                 ps->Shade.pCcdDac->DarkDAC.Colors.Red   = 0x80;
312                 ps->Shade.pCcdDac->DarkDAC.Colors.Green = 0x80;
313                 ps->Shade.pCcdDac->DarkDAC.Colors.Blue  = 0x80;
314 
315 		    	ps->bsPreRedDAC = ps->bsPreGreenDAC = ps->bsPreBlueDAC = 0x80;
316 
317 			    ps->wsDACCompareHighRed   = 0x90;
318 			    ps->wsDACCompareLowRed    = 0x80;
319 		    	ps->wsDACCompareHighGreen = 0x1a0;
320 			    ps->wsDACCompareLowGreen  = 0x190;
321 			    ps->wsDACCompareHighBlue  = 0x260;
322 			    ps->wsDACCompareLowBlue   = 0x250;
323 		    	ps->wsDACOffsetRed =
324 				ps->wsDACOffsetGreen = ps->wsDACOffsetBlue = 0x20;
325 			}
326 		} else {
327             ps->Shade.pCcdDac->DarkCmpHi.Colors.Red   = 0x50;
328             ps->Shade.pCcdDac->DarkCmpLo.Colors.Red   = 0x40;
329             ps->Shade.pCcdDac->DarkCmpHi.Colors.Green = 0x38;
330             ps->Shade.pCcdDac->DarkCmpLo.Colors.Green = 0x28;
331             ps->Shade.pCcdDac->DarkCmpHi.Colors.Blue  = 0x28;
332             ps->Shade.pCcdDac->DarkCmpLo.Colors.Blue  = 0x18;
333 
334             ps->Shade.pCcdDac->DarkOffSub.Colors.Red   = 0x30;
335             ps->Shade.pCcdDac->DarkOffSub.Colors.Green = 0x18;
336             ps->Shade.pCcdDac->DarkOffSub.Colors.Blue  = 0x08;
337 
338             ps->Shade.pCcdDac->DarkDAC.Colors.Red   = 0xf0;
339             ps->Shade.pCcdDac->DarkDAC.Colors.Blue  = 0xcc;
340 			if (ps->bSetScanModeFlag & _ScanMode_Mono) {
341                 ps->Shade.pCcdDac->DarkDAC.Colors.Green =
342 					((ps->bSetScanModeFlag & _ScanMode_AverageOut)? 0xa0:0x68);
343 			} else {
344                 ps->Shade.pCcdDac->DarkDAC.Colors.Green = 0xcc;
345 			}
346 	    }
347 
348 	    if ((ps->bSetScanModeFlag & _ScanMode_Mono) ||
349 			(ps->DataInf.dwScanFlag & SCANDEF_Negative)) {
350        		WolfsonDAC8144[3].bParam = 0x12;
351 		} else {
352        		WolfsonDAC8144[3].bParam = 0x10;
353 		}
354 
355 	    pw = P97ColorModeRegister;
356 	    break;
357 
358 	case _CCD_3717:
359 		DBG( DBG_HIGH, "CCD-ID = 0x%02X = _CCD_3717\n", ps->Device.bCCDID );
360 
361         ps->Shade.pCcdDac->GainResize.Colors.Red   =  96;
362         ps->Shade.pCcdDac->GainResize.Colors.Green =  97;
363         ps->Shade.pCcdDac->GainResize.Colors.Blue  = 100;
364 
365         ps->Shade.pCcdDac->DarkCmpHi.Colors.Red   = 0x15;
366         ps->Shade.pCcdDac->DarkCmpLo.Colors.Red   = 0x05;
367         ps->Shade.pCcdDac->DarkCmpHi.Colors.Green = 0x10;
368         ps->Shade.pCcdDac->DarkCmpLo.Colors.Green = 0x01;
369         ps->Shade.pCcdDac->DarkCmpHi.Colors.Blue  = 0x10;
370         ps->Shade.pCcdDac->DarkCmpLo.Colors.Blue  = 0x01;
371 
372         ps->Shade.pCcdDac->DarkOffSub.Colors.Red   = 0x28;
373         ps->Shade.pCcdDac->DarkOffSub.Colors.Green = 0x14;
374         ps->Shade.pCcdDac->DarkOffSub.Colors.Blue  = 0x10;
375 
376         ps->Shade.pCcdDac->DarkDAC.Colors.Green =
377                              ((ps->bSetScanModeFlag&_ScanMode_Mono)?0xd0:0xd6);
378         ps->Shade.pCcdDac->DarkDAC.Colors.Red   = 0xdd;
379         ps->Shade.pCcdDac->DarkDAC.Colors.Blue  = 0xd9;
380 	    ps->Device.f0_8_16 	= _TRUE;
381 	    pw = P17ColorModeRegister;
382 	    break;
383 
384 	case _CCD_535:
385 		DBG( DBG_HIGH, "CCD-ID = 0x%02X = _CCD_535\n", ps->Device.bCCDID );
386         ps->Shade.pCcdDac->GainResize.Colors.Red   = 100;
387         ps->Shade.pCcdDac->GainResize.Colors.Green = 100;
388         ps->Shade.pCcdDac->GainResize.Colors.Blue  =  95;
389 
390         ps->Shade.pCcdDac->DarkOffSub.Colors.Red   = 0x2e;
391         ps->Shade.pCcdDac->DarkOffSub.Colors.Green = 0x20;
392         ps->Shade.pCcdDac->DarkOffSub.Colors.Blue  = 0x28;
393 
394 		ps->wMinCmpDpi = 75;
395 	    ps->lpEppColorHomePos->wMaxSteps = 890;
396 	    ps->lpBppColorHomePos->wMaxSteps = 890;
397 	    ps->lpSppColorHomePos->wMaxSteps = 890;
398 /*
399  * for less 75 Dpi Motor can't moveable in Some machine
400  *	    ps->lpEppColorHomePos->bExposureTime = 48;
401  */
402 	    ps->lpEppColorHomePos->bExposureTime 	   = 64;
403 	    ps->a_tabDiffParam[_ColorEpp60].bStepSpeed = 8;
404 		ps->a_ColorSettings [1].bExposureTime      = 64;
405 	    ps->a_tabDiffParam[_ColorEpp100_1400].bStepSpeed = 16;
406 		ps->lpBppColorHomePos->bExposureTime = 96;
407 	    ps->lpSppColorHomePos->bExposureTime = 96;
408 
409         ps->Shade.pCcdDac->DarkDAC.Colors.Red  = 0xf0;
410         ps->Shade.pCcdDac->DarkDAC.Colors.Blue = 0xdf;
411 
412 	    if (ps->bSetScanModeFlag & _ScanMode_Mono) {
413             ps->Shade.pCcdDac->GainResize.Colors.Green = 110;
414 
415             ps->Shade.pCcdDac->DarkCmpHi.Colors.Green  = 0x30;
416             ps->Shade.pCcdDac->DarkCmpLo.Colors.Green  = 0x20;
417             ps->Shade.pCcdDac->DarkOffSub.Colors.Green = 0x20;
418             ps->Shade.pCcdDac->DarkDAC.Colors.Green    = 0xf0;
419 	    } else {
420 			if (ps->bSetScanModeFlag & _ScanMode_AverageOut) {
421 
422                 ps->Shade.pCcdDac->DarkDAC.Colors.Red   = 0xf6;
423                 ps->Shade.pCcdDac->DarkDAC.Colors.Green = 0xe5;
424                 ps->Shade.pCcdDac->DarkDAC.Colors.Blue  = 0xe4;
425                 ps->Shade.pCcdDac->DarkOffSub.Colors.Red   = 0x18;
426                 ps->Shade.pCcdDac->DarkOffSub.Colors.Green = 0;
427                 ps->Shade.pCcdDac->DarkOffSub.Colors.Blue  = 0;
428 			} else {
429                 ps->Shade.pCcdDac->DarkDAC.Colors.Red   = 0xf0;
430                 ps->Shade.pCcdDac->DarkDAC.Colors.Green = 0xe1;
431                 ps->Shade.pCcdDac->DarkDAC.Colors.Blue  = 0xdf;
432 			}
433 	    }
434 	    pw = P535ColorModeRegister;
435 	    break;
436 
437 	case _CCD_2556:
438 		DBG( DBG_HIGH, "CCD-ID = 0x%02X = _CCD_2556\n", ps->Device.bCCDID );
439         ps->Shade.pCcdDac->GainResize.Colors.Red   = 100;
440         ps->Shade.pCcdDac->GainResize.Colors.Green = 100;
441         ps->Shade.pCcdDac->GainResize.Colors.Blue  = 100;
442 
443         ps->Shade.pCcdDac->DarkCmpHi.Colors.Red   = 0x20;
444         ps->Shade.pCcdDac->DarkCmpLo.Colors.Red   = 0x10;
445         ps->Shade.pCcdDac->DarkCmpHi.Colors.Green = 0x20;
446         ps->Shade.pCcdDac->DarkCmpLo.Colors.Green = 0x10;
447         ps->Shade.pCcdDac->DarkCmpHi.Colors.Blue  = 0x20;
448         ps->Shade.pCcdDac->DarkCmpLo.Colors.Blue  = 0x10;
449 
450         ps->Shade.pCcdDac->DarkOffSub.Colors.Red   = 0;
451         ps->Shade.pCcdDac->DarkOffSub.Colors.Green = 0;
452         ps->Shade.pCcdDac->DarkOffSub.Colors.Blue  = 0;
453 
454 	    pw = P56ColorModeRegister;
455 	    break;
456 
457 	case _CCD_518:
458 		DBG( DBG_HIGH, "CCD-ID = 0x%02X = _CCD_518\n", ps->Device.bCCDID );
459         ps->Device.dwModelOriginY = 0x50-3;                 /* 0x50-13 */
460         ps->Shade.pCcdDac->GainResize.Colors.Red   = 98;
461         ps->Shade.pCcdDac->GainResize.Colors.Green = 98;
462         ps->Shade.pCcdDac->GainResize.Colors.Blue  = 98;
463 
464         ps->Shade.pCcdDac->DarkDAC.Colors.Red   = 0xcc;
465         ps->Shade.pCcdDac->DarkDAC.Colors.Green = 0xcc;
466         ps->Shade.pCcdDac->DarkDAC.Colors.Blue  = 0xcc;
467 
468 	    if (ps->bSetScanModeFlag & _ScanMode_Mono) {
469 
470             ps->Shade.pCcdDac->DarkCmpHi.Colors.Green = 0x30;
471             ps->Shade.pCcdDac->DarkCmpLo.Colors.Green = 0x20;
472 	    }
473 
474 	    if( ps->DataInf.dwScanFlag & SCANDEF_TPA ) {
475 			if( ps->DataInf.dwScanFlag & SCANDEF_Transparency ) {
476                 ps->Shade.pCcdDac->GainResize.Colors.Red   = 104;
477                 ps->Shade.pCcdDac->GainResize.Colors.Green =  92;
478                 ps->Shade.pCcdDac->GainResize.Colors.Blue  =  96;
479 			    ps->bsPreRedDAC = ps->bsPreGreenDAC = ps->bsPreBlueDAC = 0xcc;
480 
481                 ps->Shade.pCcdDac->DarkCmpHi.Colors.Red   = 0x20;
482                 ps->Shade.pCcdDac->DarkCmpLo.Colors.Red   = 0x10;
483                 ps->Shade.pCcdDac->DarkCmpHi.Colors.Green = 0x20;
484                 ps->Shade.pCcdDac->DarkCmpLo.Colors.Green = 0x10;
485                 ps->Shade.pCcdDac->DarkCmpHi.Colors.Blue  = 0x20;
486                 ps->Shade.pCcdDac->DarkCmpLo.Colors.Blue  = 0x10;
487 
488                 ps->Shade.pCcdDac->DarkOffSub.Colors.Red   = 0;
489                 ps->Shade.pCcdDac->DarkOffSub.Colors.Green = 0;
490                 ps->Shade.pCcdDac->DarkOffSub.Colors.Blue  = 0;
491 
492 			    ps->wsDACCompareHighRed   = 0x80;     	/* 0x35 */
493 			    ps->wsDACCompareLowRed 	  = 0x70;	    /* 0x25 */
494 			    ps->wsDACCompareHighGreen = 0x80;   	/* 0x46 */
495 		    	ps->wsDACCompareLowGreen  = 0x70;    	/* 0x36 */
496 			    ps->wsDACCompareHighBlue  = 0x80;    	/* 0x54 */
497 			    ps->wsDACCompareLowBlue   = 0x70;     	/* 0x44 */
498 			    ps->wsDACOffsetRed =
499 				ps->wsDACOffsetGreen = ps->wsDACOffsetBlue = 0; /* 0x70 */
500 			} else {
501                 ps->Shade.pCcdDac->GainResize.Colors.Red   = 94;
502                 ps->Shade.pCcdDac->GainResize.Colors.Green = 80;
503                 ps->Shade.pCcdDac->GainResize.Colors.Blue  = 78;
504 
505                 ps->Shade.pCcdDac->DarkDAC.Colors.Red   = 0x80;
506                 ps->Shade.pCcdDac->DarkDAC.Colors.Green = 0x80;
507                 ps->Shade.pCcdDac->DarkDAC.Colors.Blue  = 0x80;
508 
509 			    ps->bsPreRedDAC = ps->bsPreGreenDAC = ps->bsPreBlueDAC = 0x80;
510 
511 			    ps->wsDACCompareHighRed   = 0x90;
512 		    	ps->wsDACCompareLowRed    = 0x80;
513 			    ps->wsDACCompareHighGreen = 0x1a0;
514 			    ps->wsDACCompareLowGreen  = 0x190;
515 			    ps->wsDACCompareHighBlue  = 0x160;
516 			    ps->wsDACCompareLowBlue   = 0x150;
517 			    ps->wsDACOffsetRed 	 = 0xb0;	       /* 0x180 */
518 			    ps->wsDACOffsetGreen = 0xcc;	       /* 0x180 */
519 		    	ps->wsDACOffsetBlue  = 0xe2;	       /* 0x240 */
520 			}
521 		}
522 
523 	    if ((ps->bSetScanModeFlag & _ScanMode_Mono) ||
524 								(ps->DataInf.dwScanFlag & SCANDEF_Negative)) {
525        		WolfsonDAC8144[3].bParam = 0x12;
526 	    } else {
527        		WolfsonDAC8144[3].bParam = 0x10;
528 		}
529 	    ps->Device.f0_8_16    = _TRUE;
530 	    pw = P518ColorModeRegister;
531 	    break;
532 
533 	/*
534 	 * CCD_539
535 	 */
536 	default:
537 		DBG( DBG_HIGH, "CCD-ID = 0x%02X = _CCD_539\n", ps->Device.bCCDID );
538         ps->Shade.pCcdDac->GainResize.Colors.Red   = 100;
539         ps->Shade.pCcdDac->GainResize.Colors.Green = 100;
540         ps->Shade.pCcdDac->GainResize.Colors.Blue  =  98;
541 
542         ps->Shade.pCcdDac->DarkDAC.Colors.Red   = 0xcc;
543         ps->Shade.pCcdDac->DarkDAC.Colors.Green = 0xcc;
544         ps->Shade.pCcdDac->DarkDAC.Colors.Blue  = 0xcc;
545 
546 	    if( ps->DataInf.dwScanFlag & SCANDEF_TPA ) {
547 			if( ps->DataInf.dwScanFlag & SCANDEF_Transparency ) {
548 
549                 ps->Shade.pCcdDac->GainResize.Colors.Red   = 80;
550                 ps->Shade.pCcdDac->GainResize.Colors.Green = 80;
551                 ps->Shade.pCcdDac->GainResize.Colors.Blue  = 80;
552 			    ps->bsPreRedDAC   = 0xcc;
553                 ps->bsPreGreenDAC = 0xcc;
554                 ps->bsPreBlueDAC  = 0xcc;
555 			    ps->wsDACCompareHighRed = 0x90;
556 			    ps->wsDACCompareLowRed  = 0x80;
557 			    ps->wsDACCompareHighGreen = 0x90;
558 			    ps->wsDACCompareLowGreen  = 0x80;
559 		    	ps->wsDACCompareHighBlue  = 0x90;
560 			    ps->wsDACCompareLowBlue   = 0x80;
561 			    ps->wsDACOffsetRed =
562 				ps->wsDACOffsetGreen = ps->wsDACOffsetBlue = 0x70;
563 			} else {
564                 ps->Shade.pCcdDac->GainResize.Colors.Red   = 80;
565                 ps->Shade.pCcdDac->GainResize.Colors.Green = 96;
566                 ps->Shade.pCcdDac->GainResize.Colors.Blue  = 95;
567 
568                 ps->Shade.pCcdDac->DarkDAC.Colors.Red   = 0x90;
569                 ps->Shade.pCcdDac->DarkDAC.Colors.Green = 0x90;
570                 ps->Shade.pCcdDac->DarkDAC.Colors.Blue  = 0x90;
571 
572 			    ps->bsPreRedDAC = ps->bsPreGreenDAC = ps->bsPreBlueDAC = 0x90;
573 			    ps->wsDACCompareHighRed   = 0xd0;	 	/* 0x90  */
574 			    ps->wsDACCompareLowRed 	  = 0xc0;		/* 0x80  */
575 			    ps->wsDACCompareHighGreen = 0x110;		/* 0x1a0 */
576 		    	ps->wsDACCompareLowGreen  = 0x100;		/* 0x190 */
577 			    ps->wsDACCompareHighBlue  = 0x130;		/* 0x260 */
578 			    ps->wsDACCompareLowBlue   = 0x120;		/* 0x250 */
579 			    ps->wsDACOffsetRed 		  = 0x70;		/* 0x70  */
580 		    	ps->wsDACOffsetGreen 	  = 0x70;		/* 0x180 */
581 			    ps->wsDACOffsetBlue 	  = 0x70;		/* 0x240 */
582 			}
583 		}
584 
585 	    if (ps->bSetScanModeFlag & _ScanMode_Mono ||
586 								(ps->DataInf.dwScanFlag & SCANDEF_Negative)) {
587        		WolfsonDAC8144[3].bParam = 0x12;
588 		} else {
589        		WolfsonDAC8144[3].bParam = 0x10;
590 		}
591 	    ps->Device.f0_8_16 = _TRUE;
592 	    pw = P539ColorModeRegister;
593         break;
594     }
595 
596     if( ps->bSetScanModeFlag == _ScanMode_Color )
597    		WolfsonDAC8144[2].bParam = 0x52;
598     else
599    		WolfsonDAC8144[2].bParam = 0x42;
600 
601     if( ps->bSetScanModeFlag == _ScanMode_Mono )
602    		WolfsonDAC8144[0].bParam = 7;
603     else
604 	    WolfsonDAC8144[0].bParam = 3;
605 
606     ps->OpenScanPath( ps );
607 
608 	/*
609 	 * base init of the DAC
610  	 */
611     DBG( DBG_IO, "Programming DAC (%u regs)\n", ps->Device.wNumDACRegs );
612 
613     for( w = 0; w < ps->Device.wNumDACRegs; w++) {
614 
615         DBG( DBG_IO, "*[0x%02x] = 0x%02x\n",
616                             WolfsonDAC8144[w].bReg, WolfsonDAC8144[w].bParam );
617 		IODataRegisterToDAC( ps,
618                              WolfsonDAC8144[w].bReg, WolfsonDAC8144[w].bParam );
619     }
620 
621     if( ps->bSetScanModeFlag & _ScanMode_Mono ) {
622 		ps->AsicReg.RD_Model1Control = _MOTOR_2916 + _BUTTON_MODE +
623 									   _CCD_SHIFT_GATE + _SCAN_GRAYTYPE;
624 	} else {
625 		ps->AsicReg.RD_Model1Control = _MOTOR_2916 +
626                                        _BUTTON_MODE + _CCD_SHIFT_GATE;
627 	}
628     IODataToRegister( ps, ps->RegModel1Control, ps->AsicReg.RD_Model1Control );
629 
630     /* Check: THIS IS 11 on the 98003 */
631 	IODataToRegister( ps, ps->RegWaitStateInsert, 6 );
632 
633 	/*
634 	 * according to the scan mode, program the CCD
635 	 */
636     pw = pw + (ULong)ps->bSetScanModeFlag * 24;
637 	DBG( DBG_LOW, "bSetScanModeFlag = %u\n", ps->bSetScanModeFlag );
638 
639     for( w = 24; w--; pw++) {
640 		Data.wValue = *pw;
641 		IODataToRegister( ps, Data.wOverlap.b1st, Data.wOverlap.b2nd );
642     }
643 
644     ps->CloseScanPath( ps );
645 }
646 
647 /*.............................................................................
648  * call the InitAsic function
649  * set LineControl and stop motor
650  */
p9636SetupScannerVariables(pScanData ps)651 static void p9636SetupScannerVariables( pScanData ps )
652 {
653 	ps->ReInitAsic( ps, _FALSE );
654 
655     IOCmdRegisterToScanner(ps, ps->RegLineControl, ps-> AsicReg.RD_LineControl);
656 
657     memset( ps->a_nbNewAdrPointer, 0, _SCANSTATE_BYTES);
658     IOSetToMotorRegister( ps );
659 }
660 
661 /*.............................................................................
662  * set all necessary register contents
663  */
p9636SetGeneralRegister(pScanData ps)664 static void p9636SetGeneralRegister( pScanData ps )
665 {
666 	DBG( DBG_LOW, "p9636SetGeneralRegister()\n" );
667 
668 	ps->AsicReg.RD_StepControl   = _MOTOR0_SCANSTATE + _MOTOR0_ONESTEP;
669 	ps->AsicReg.RD_ModeControl   = _ModeScan + _ModeFifoRSel;
670 	ps->AsicReg.RD_Motor1Control = _MotorOn  + _MotorDirForward;
671 	ps->AsicReg.RD_Motor0Control = ps->bHpMotor | (_MotorOn+_MotorDirForward);
672 	ps->AsicReg.RD_XStepTime 	 = ps->bStepSpeed;
673 
674     if( COLOR_BW == ps->DataInf.wPhyDataType ) {
675 
676 		ps->AsicReg.RD_ScanControl = _SCAN_BITMODE;
677 
678 		if( !(ps->DataInf.dwScanFlag & SCANDEF_Inverse))
679 			ps->AsicReg.RD_ScanControl |= _P98_SCANDATA_INVERT;
680 
681     } else {
682 
683 		if (COLOR_TRUE48 == ps->DataInf.wPhyDataType) {
684 			ps->AsicReg.RD_ScanControl = _SCAN_12BITMODE;
685 
686 		    if (!(ps->DataInf.dwScanFlag & SCANDEF_RightAlign))
687 				ps->AsicReg.RD_ScanControl |= _BITALIGN_LEFT;
688 		} else
689 			ps->AsicReg.RD_ScanControl = _SCAN_BYTEMODE;
690 
691 		if( ps->DataInf.dwScanFlag & SCANDEF_Inverse )
692 			ps->AsicReg.RD_ScanControl |= _P98_SCANDATA_INVERT;
693     }
694 
695     ps->AsicReg.RD_ScanControl |= _SCAN_1ST_AVERAGE;
696     IOSelectLampSource( ps );
697 }
698 
699 /*.............................................................................
700  * tell the scanner/ASIC where to start scanning and how many pixels
701  */
p9636SetStartStopRegister(pScanData ps)702 static void p9636SetStartStopRegister( pScanData ps )
703 {
704 	ps->AsicReg.RD_Origin = (UShort)(ps->dwOffset70 + ps->Device.DataOriginX +
705 									 ps->DataInf.crImage.x);
706 
707 	DBG( DBG_LOW, "p9636SetStartStopRegister()\n" );
708 
709     if (ps->bSetScanModeFlag & _ScanMode_AverageOut )
710 
711 		ps->AsicReg.RD_Origin = ps->AsicReg.RD_Origin >> 1;
712 
713     if (ps->DataInf.wPhyDataType < COLOR_256GRAY) {
714 		ps->AsicReg.RD_Pixels = (UShort)ps->DataInf.dwAsicBytesPerLine;
715 	} else {
716 		ps->AsicReg.RD_Pixels = (UShort)ps->DataInf.dwAsicPixelsPerPlane;
717 	}
718 
719 	DBG( DBG_LOW, "RD_Origin = %u, RD_Pixels = %u\n",
720 					ps->AsicReg.RD_Origin, ps->AsicReg.RD_Pixels );
721 }
722 
723 /*.............................................................................
724  *
725  */
p9636SetupScanningCondition(pScanData ps)726 static void p9636SetupScanningCondition( pScanData ps )
727 {
728 	ULong dw;
729 
730 	IORegisterDirectToScanner( ps, ps->RegInitDataFifo );
731 
732 	ps->InitialSetCurrentSpeed( ps );
733 
734     if (ps->DataInf.wPhyDataType > COLOR_TRUE24) {
735 		if (ps->DataInf.dwAsicBytesPerPlane < 1024)
736 		    ps->Scan.dwMinReadFifo = 1024;
737 		else
738 		    ps->Scan.dwMinReadFifo = ps->DataInf.dwAsicBytesPerPlane;
739 	} else {
740 		if (ps->DataInf.dwAsicBytesPerPlane * 2 < 1024)
741 		    ps->Scan.dwMinReadFifo = 1024;
742 		else
743 		    ps->Scan.dwMinReadFifo = ps->DataInf.dwAsicBytesPerPlane * 2;
744 	}
745 
746     p9636SetGeneralRegister( ps );
747 
748 	IORegisterDirectToScanner( ps, ps->RegInitDataFifo );
749 
750 	ps->SetupMotorRunTable( ps );
751 
752     ps->AsicReg.RD_Dpi = ps->DataInf.xyPhyDpi.x;
753 
754 	p9636SetStartStopRegister( ps );
755 	IOSetToMotorRegister  ( ps );
756 
757 	ps->bCurrentLineCount = 0;
758     IOCmdRegisterToScanner(ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl);
759 
760 	IOPutOnAllRegisters( ps );
761 
762 	ps->OpenScanPath( ps );
763 
764 	ps->AsicReg.RD_ModeControl &= ~_ModeIdle;
765     IODataToRegister( ps, ps->RegModeControl, ps->AsicReg.RD_ModeControl);
766 
767 	ps->AsicReg.RD_ModeControl = _ModeScan + _ModeFifoRSel;
768     IODataToRegister( ps, ps->RegModeControl, ps->AsicReg.RD_ModeControl);
769 
770 	IORegisterToScanner( ps, ps->RegInitDataFifo );
771 
772 	ps->CloseScanPath( ps );
773 
774     if (ps->DataInf.wPhyDataType >= COLOR_TRUE24) {
775 
776 		dw = ps->DataInf.dwAsicPixelsPerPlane;
777 		ps->dwMaxReadFifoData = _SIZE_COLORFIFO -
778 							    ps->DataInf.dwAsicBytesPerPlane * 64UL /
779 			    				(ULong)ps->bCurrentSpeed - dw;
780     } else {
781 		dw = ps->DataInf.dwAsicBytesPerPlane;
782 		ps->dwMaxReadFifoData = _SIZE_GRAYFIFO -
783 			   					ps->DataInf.dwAsicBytesPerPlane * 64UL /
784 							    (ULong)ps->bCurrentSpeed - dw;
785     }
786 
787     if ((dw = dw * 4UL) > ps->dwMaxReadFifoData) {
788 		ps->dwSizeMustProcess = ps->dwMaxReadFifoData;
789     } else {
790 		ps->dwSizeMustProcess = dw;
791 	}
792 
793     if (ps->DataInf.wPhyDataType >= COLOR_TRUE24) {
794 
795 		if (ps->DataInf.xyPhyDpi.y <= 150) {
796 		    dw = ps->DataInf.dwAsicPixelsPerPlane;
797 		} else {
798 		    if (ps->DataInf.xyPhyDpi.y <= 300) {
799 				dw = ps->DataInf.dwAsicPixelsPerPlane * 2;
800 		    } else {
801 				if (ps->DataInf.xyPhyDpi.y <= 600) {
802 		    		dw = ps->DataInf.dwAsicPixelsPerPlane * 4;
803 				} else {
804 				    dw = ps->DataInf.dwAsicPixelsPerPlane * 8;
805 				}
806 			}
807 		}
808 
809 		if (ps->Device.f0_8_16 && (ps->DataInf.xyPhyDpi.y >= 150))
810 		    dw <<= 1;
811 
812 		ps->dwSizeMustProcess  += dw;
813 		ps->Scan.dwMinReadFifo += dw;
814 		ps->dwMaxReadFifoData  += dw;
815     }
816 }
817 
818 /*.............................................................................
819  * switch the scanner into idle mode
820  */
p9636PutToIdleMode(pScanData ps)821 static void p9636PutToIdleMode( pScanData ps )
822 {
823     int i;
824 
825 	DBG( DBG_LOW, "Putting Scanner (ASIC 98001) into Idle-Mode\n" );
826 
827     /*
828      * turn off motor
829    	 */
830     IOCmdRegisterToScanner( ps, ps->RegMotor0Control, 0x00 );
831     IOCmdRegisterToScanner( ps, ps->RegLineControl,ps->AsicReg.RD_LineControl);
832 
833     IOCmdRegisterToScanner( ps, ps->RegModeControl,
834                 	                            (_ModeIdle + _ModeFifoClose));
835 
836     ps->OpenScanPath(ps);
837 
838     DBG( DBG_IO, "CCD-Stop\n" );
839 
840     for( i = 0; i < 12; i++ ) {
841 
842         DBG(DBG_IO, "*[0x%02x] = 0x%02x\n",ccdStop[i].bReg, ccdStop[i].bParam);
843 		IODataToRegister( ps, ccdStop[i].bReg, ccdStop[i].bParam );
844 	}
845 
846     IODataRegisterToDAC( ps, 0x01, 0x00 );	/* Close ADC */
847 
848 	ps->CloseScanPath(ps);
849 }
850 
851 /*.............................................................................
852  * do all the preliminary stuff here (calibrate the scanner and move the
853  * sensor to it´s start position, also setup the driver for the
854  * current run)
855  */
p9636Calibration(pScanData ps)856 static int p9636Calibration( pScanData ps )
857 {
858 	DBG( DBG_LOW, "p9636Calibration()\n" );
859 
860     ps->Scan.bFifoSelect = ps->RegGFifoOffset;
861 
862 	/*
863 	 * wait for shading to be done
864 	 */
865 	_ASSERT(ps->WaitForShading);
866 	if( !ps->WaitForShading( ps ))
867 		return _E_TIMEOUT;
868 
869 	IOCmdRegisterToScanner( ps, ps->RegLineControl, _DEFAULT_LINESCANTIME );
870 
871 	/*
872 	 * move sensor and setup scanner for grabbing the picture
873 	 */
874 	_ASSERT(ps->WaitForPositionY);
875 	ps->WaitForPositionY( ps );
876 
877 	IOCmdRegisterToScanner( ps, ps->RegLineControl,
878 								ps->AsicReg.RD_LineControl );
879 
880 	ps->fDoFilter     = ps->fFilterFirstLine = _FALSE;
881 	ps->dwDivFilter   = ps->dwMul = 53;
882 	ps->bOffsetFilter = 12;
883 
884 	if (COLOR_256GRAY == ps->DataInf.wPhyDataType) {
885 		ps->fDoFilter  = _TRUE;
886 		ps->pFilterBuf = ps->pGet1 = ps->pProcessingBuf;
887 		ps->pGet2      = ps->pGet1 + 5120;
888 		ps->pGet3      = ps->pGet2 + 5120;
889 		ps->pEndBuf    = ps->pGet3 + 5120;
890 
891 		ps->fFilterFirstLine = _TRUE;
892 		ps->dwLinesFilter 	 = ps->DataInf.dwAppLinesPerArea;
893 	}
894 
895     ps->bCurrentLineCount = 0x3f;
896 	_DODELAY(1);
897 
898 	return _OK;
899 }
900 
901 /************************ exported functions *********************************/
902 
903 /*.............................................................................
904  * initialize the register values and function calls for the 98001 asic
905  */
P9636InitAsic(pScanData ps)906 _LOC int P9636InitAsic( pScanData ps )
907 {
908 	int result;
909 
910 	DBG( DBG_LOW, "P9636InitAsic()\n" );
911 
912     /*
913      * preset the asic shadow registers
914      */
915     p9636InitializeAsicRegister( ps );
916 
917 	ps->IO.bOpenCount = 0;
918 
919 	/*
920 	 * setup the register values
921 	 */
922 	ps->RegSwitchBus 			= 0;
923   	ps->RegEPPEnable 			= 1;
924 	ps->RegECPEnable 			= 2;
925 	ps->RegReadDataMode 		= 3;
926 	ps->RegWriteDataMode 		= 4;
927 	ps->RegInitDataFifo 		= 5;
928 	ps->RegForceStep 			= 6;
929 	ps->RegInitScanState 		= 7;
930 	ps->RegRefreshScanState 	= 8;
931 	ps->RegWaitStateInsert 		= 0x0a;
932 	ps->RegRFifoOffset 			= 0x0a;
933 	ps->RegGFifoOffset 			= 0x0b;
934 	ps->RegBFifoOffset 			= 0x0c;
935 	ps->RegBitDepth 			= 0x13;
936 	ps->RegStepControl 			= 0x14;
937 	ps->RegMotor0Control 		= 0x15;
938 	ps->RegXStepTime 			= 0x16;
939 	ps->RegGetScanState 		= 0x17;
940 	ps->RegAsicID 				= 0x18;
941 	ps->RegMemoryLow 			= 0x19;
942 	ps->RegMemoryHigh 			= 0x1a;
943 	ps->RegModeControl 			= 0x1b;
944 	ps->RegLineControl 			= 0x1c;
945 	ps->RegScanControl 			= 0x1d;
946 	ps->RegConfiguration 		= 0x1e;
947 	ps->RegModelControl 		= 0x1f;
948 	ps->RegModel1Control 		= 0x20;
949 	ps->RegDpiLow 				= 0x21;
950 	ps->RegDpiHigh 				= 0x22;
951 	ps->RegScanPosLow 			= 0x23;
952 	ps->RegScanPosHigh 			= 0x24;
953 	ps->RegWidthPixelsLow 		= 0x25;
954 	ps->RegWidthPixelsHigh 		= 0x26;
955 	ps->RegThresholdLow 		= 0x27;
956 	ps->RegThresholdHigh 		= 0x28;
957 	ps->RegThresholdGapControl 	= 0x29;
958 	ps->RegADCAddress 			= 0x2a;
959 	ps->RegADCData 				= 0x2b;
960 	ps->RegADCPixelOffset 		= 0x2c;
961 	ps->RegADCSerialOutStr 		= 0x2d;
962 	ps->RegResetConfig 			= 0x2e;
963 	ps->RegLensPosition			= 0x2f;
964 	ps->RegStatus 				= 0x30;
965 	ps->RegScanStateControl 	= 0x31;
966 	ps->RegRedChDarkOffsetLow 	= 0x33;
967 	ps->RegRedChDarkOffsetHigh 	= 0x34;
968 	ps->RegGreenChDarkOffsetLow = 0x35;
969 	ps->RegGreenChDarkOffsetHigh= 0x36;
970 	ps->RegBlueChDarkOffsetLow 	= 0x37;
971 	ps->RegBlueChDarkOffsetHigh = 0x38;
972 	ps->RegResetPulse0 			= 0x39;
973 	ps->RegResetPulse1 			= 0x3a;
974 	ps->RegCCDClampTiming0 		= 0x3b;
975 	ps->RegCCDClampTiming1 		= 0x3c;
976 	ps->RegVSMPTiming0 			= 0x41;
977 	ps->RegVSMPTiming1 			= 0x42;
978 	ps->RegCCDQ1Timing0 		= 0x43;
979 	ps->RegCCDQ1Timing1 		= 0x44;
980 	ps->RegCCDQ1Timing2 		= 0x45;
981 	ps->RegCCDQ1Timing3 		= 0x46;
982 	ps->RegCCDQ2Timing0 		= 0x47;
983 	ps->RegCCDQ2Timing1 		= 0x48;
984 	ps->RegCCDQ2Timing2 		= 0x49;
985 	ps->RegCCDQ2Timing3 		= 0x4a;
986 	ps->RegADCclockTiming0 		= 0x4b;
987 	ps->RegADCclockTiming1		= 0x4c;
988 	ps->RegADCclockTiming2 		= 0x4d;
989 	ps->RegADCclockTiming3 		= 0x4e;
990 	ps->RegADCDVTiming0 		= 0x50;
991 	ps->RegADCDVTiming1 		= 0x51;
992 	ps->RegADCDVTiming2 		= 0x52;
993 	ps->RegADCDVTiming3 		= 0x53;
994 
995 	/*
996 	 * setup function calls
997 	 */
998 	ps->SetupScannerVariables  = p9636SetupScannerVariables;
999 	ps->SetupScanningCondition = p9636SetupScanningCondition;
1000 	ps->ReInitAsic			   = p9636Init98001;
1001     ps->PutToIdleMode          = p9636PutToIdleMode;
1002     ps->Calibration            = p9636Calibration;
1003 
1004 	/*
1005 	 * setup misc
1006 	 */
1007 	ps->CtrlReadHighNibble  = _CTRL_GENSIGNAL + _CTRL_AUTOLF + _CTRL_STROBE;
1008 	ps->CtrlReadLowNibble   = _CTRL_GENSIGNAL + _CTRL_AUTOLF;
1009 
1010 	ps->f97003 				= _FALSE;
1011     ps->IO.useEPPCmdMode    = _FALSE;
1012     ps->Scan.fRefreshState  = _TRUE;
1013 	ps->wMinCmpDpi   		= 60;
1014 	ps->Scan.fMotorBackward = _FALSE;
1015 
1016 	IOSetXStepLineScanTime( ps, _DEFAULT_LINESCANTIME );
1017 
1018     ps->Shade.pCcdDac = &shadingVar;
1019 	ps->bFastMoveFlag = _FastMove_Low_C75_G150;
1020 	ps->dwOffset70 	  = _P98_OFFSET70;
1021 
1022 	/*
1023 	 * initialize the other modules and set some
1024 	 * function pointer
1025 	 */
1026 	result = DacInitialize( ps );
1027 	if( _OK != result )
1028 		return result;
1029 
1030 	result = ImageInitialize( ps );
1031 	if( _OK != result )
1032 		return result;
1033 
1034 	result = IOFuncInitialize( ps );
1035 	if( _OK != result )
1036 		return result;
1037 
1038 	result = IOInitialize( ps );
1039 	if( _OK != result )
1040 		return result;
1041 
1042 	result = MotorInitialize( ps );
1043 	if( _OK != result )
1044 		return result;
1045 
1046 	/*
1047 	 * in debug version, check all function pointers
1048 	 */
1049 #ifdef DEBUG
1050 	if(	_FALSE == MiscAllPointersSet( ps ))
1051 		return _E_INTERNAL;
1052 #endif
1053 
1054 	DBG( DBG_LOW, "0x%02x\n", ps->sCaps.AsicID );
1055 
1056     if( _FALSE == ps->OpenScanPath( ps )) {
1057     	DBG( DBG_LOW, "P9636InitAsic() failed.\n" );
1058         return _E_NO_DEV;
1059     }
1060 
1061     /*get CCD ID */
1062     ps->Device.bCCDID = IODataFromRegister( ps, ps->RegConfiguration );
1063     ps->Device.bCCDID &= _P98_CCD_TYPE_ID;
1064 	DBG( DBG_HIGH, "CCID = 0x%02X\n", ps->Device.bCCDID);
1065 
1066     ps->CloseScanPath( ps );
1067 
1068     /* as the program parts concerning some CCDs don't handle TPA stuff,
1069      * I assume that these devices won't have TPA functionality
1070      */
1071     switch( ps->Device.bCCDID ) {
1072 
1073 	case _CCD_3717:
1074 	case _CCD_535:
1075 	case _CCD_2556:
1076 		DBG( DBG_HIGH, "Seems we have a 9636P\n" );
1077 		ps->sCaps.Model = MODEL_OP_9636PP;
1078         ps->sCaps.dwFlag &= ~SFLAG_TPA;
1079         break;
1080 	}
1081 
1082 	DBG( DBG_LOW, "P9636InitAsic() done.\n" );
1083 	return _OK;
1084 }
1085 
1086 /* END PLUSTEK-PP_P9636.C ...................................................*/
1087