1 /* @file plustek-pp_p12.c
2 * @brief p12 and pt12 specific stuff
3 *
4 * based on sources acquired from Plustek Inc.
5 * Copyright (C) 2000 Plustek Inc.
6 * Copyright (C) 2001-2013 Gerhard Jaeger <gerhard@gjaeger.de>
7 *
8 * History:
9 * - 0.38 - initial version
10 * - 0.39 - added Genius Colorpage Vivid III V2 stuff
11 * - 0.40 - no changes
12 * - 0.41 - no changes
13 * - 0.42 - removed setting of ps->sCaps.dwFlag in p12InitiateComponentModel()
14 * - 0.43 - no changes
15 * - 0.44 - fix format string issues, as Long types default to int32_t
16 * now
17 * .
18 * <hr>
19 * This file is part of the SANE package.
20 *
21 * This program is free software; you can redistribute it and/or
22 * modify it under the terms of the GNU General Public License as
23 * published by the Free Software Foundation; either version 2 of the
24 * License, or (at your option) any later version.
25 *
26 * This program is distributed in the hope that it will be useful, but
27 * WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29 * General Public License for more details.
30 *
31 * You should have received a copy of the GNU General Public License
32 * along with this program. If not, see <https://www.gnu.org/licenses/>.
33 *
34 * As a special exception, the authors of SANE give permission for
35 * additional uses of the libraries contained in this release of SANE.
36 *
37 * The exception is that, if you link a SANE library with other files
38 * to produce an executable, this does not by itself cause the
39 * resulting executable to be covered by the GNU General Public
40 * License. Your use of that executable is in no way restricted on
41 * account of linking the SANE library code into it.
42 *
43 * This exception does not, however, invalidate any other reasons why
44 * the executable file might be covered by the GNU General Public
45 * License.
46 *
47 * If you submit changes to SANE to the maintainers to be included in
48 * a subsequent release, you agree by submitting the changes that
49 * those changes may be distributed with this exception intact.
50 *
51 * If you write modifications of your own for SANE, it is your choice
52 * whether to permit this exception to apply to your modifications.
53 * If you do not wish that, delete this exception notice.
54 * <hr>
55 */
56 #include "plustek-pp_scan.h"
57
58 /*************************** some local vars *********************************/
59
60 static RegDef p12CcdStop[] = {
61 {0x41, 0xff}, {0x42, 0xff}, {0x60, 0xff}, {0x61, 0xff},
62 {0x4b, 0xff}, {0x4c, 0xff}, {0x4d, 0xff}, {0x4e, 0xff},
63 {0x2a, 0x01}, {0x2b, 0x00}, {0x2d, 0x00}, {0x1b, 0x19}, {0x15, 0x00}
64 };
65
66 /*************************** local functions *********************************/
67
68 /** init the stuff according to the buttons
69 */
p12ButtonSetup(pScanData ps,Byte nrOfButtons)70 static void p12ButtonSetup( pScanData ps, Byte nrOfButtons )
71 {
72 ps->Device.buttons = nrOfButtons;
73
74 ps->Device.Model1Mono &= ~_BUTTON_MODE;
75 ps->Device.Model1Color &= ~_BUTTON_MODE;
76
77 ps->AsicReg.RD_MotorDriverType |= _BUTTON_DISABLE;
78 ps->Scan.motorPower |= _BUTTON_DISABLE;
79 }
80
81 /** According to what we have detected, set the other stuff
82 */
p12InitiateComponentModel(pScanData ps)83 static void p12InitiateComponentModel( pScanData ps )
84 {
85 /* preset some stuff and do the differences later */
86 ps->Device.buttons = 0;
87 ps->Device.Model1Mono = _BUTTON_MODE + _CCD_SHIFT_GATE + _SCAN_GRAYTYPE;
88 ps->Device.Model1Color = _BUTTON_MODE + _CCD_SHIFT_GATE;
89 ps->Device.dwModelOriginY = 64;
90 ps->Device.fTpa = _FALSE;
91 ps->Device.ModelCtrl = (_LED_ACTIVITY | _LED_CONTROL);
92
93 /* ps->sCaps.dwFlag should have been set correctly in models.c */
94
95 switch( ps->Device.bPCBID ) {
96
97 case _PLUSTEK_SCANNER:
98 DBG( DBG_LOW, "We have a Plustek Scanner\n" );
99 ps->sCaps.Model = MODEL_OP_P12;
100 break;
101
102 case _SCANNER_WITH_TPA:
103 DBG( DBG_LOW, "Scanner has TPA\n" );
104 ps->Device.fTpa = _TRUE;
105 ps->sCaps.dwFlag |= SFLAG_TPA;
106 break;
107
108 case _SCANNER4Button:
109 DBG( DBG_LOW, "Scanner has 4 Buttons\n" );
110 p12ButtonSetup( ps, 4 );
111 break;
112
113 case _SCANNER4ButtonTPA:
114 DBG( DBG_LOW, "Scanner has 4 Buttons & TPA\n" );
115 ps->Device.fTpa = _TRUE;
116 ps->sCaps.dwFlag |= SFLAG_TPA;
117 p12ButtonSetup( ps, 4 );
118 break;
119
120 case _SCANNER5Button:
121 DBG( DBG_LOW, "Scanner has 5 Buttons\n" );
122 ps->Device.dwModelOriginY = 64 + 20;
123 p12ButtonSetup( ps, 5 );
124 break;
125
126 case _SCANNER5ButtonTPA:
127 DBG( DBG_LOW, "Scanner has 5 Buttons & TPA\n" );
128 ps->Device.dwModelOriginY = 64 + 20;
129 ps->Device.fTpa = _TRUE;
130 ps->sCaps.dwFlag |= SFLAG_TPA;
131 p12ButtonSetup( ps, 5 );
132 break;
133
134 case _SCANNER1Button:
135 DBG( DBG_LOW, "Scanner has 1 Button\n" );
136 p12ButtonSetup( ps, 1 );
137 break;
138
139 case _SCANNER1ButtonTPA:
140 DBG( DBG_LOW, "Scanner has 1 Button & TPA\n" );
141 ps-> Device.fTpa = _TRUE;
142 ps->sCaps.dwFlag |= SFLAG_TPA;
143 p12ButtonSetup( ps, 1 );
144 break;
145
146 case _AGFA_SCANNER:
147 DBG( DBG_LOW, "Agfa Scanner\n" );
148 ps->Device.dwModelOriginY = 24; /* 1200 dpi */
149 break;
150
151 case _SCANNER2Button:
152 DBG( DBG_LOW, "Scanner has 2 Buttons\n" );
153 DBG( DBG_LOW, "Seems we have a Genius Colorpage Vivid III V2\n" );
154 ps->Device.dwModelOriginY = 64 - 33;
155 p12ButtonSetup( ps, 2 );
156 ps->sCaps.Model = MODEL_GEN_CPV2;
157 break;
158
159 default:
160 DBG( DBG_LOW, "Default Model: P12\n" );
161 ps->sCaps.Model = MODEL_OP_P12;
162 break;
163 }
164
165 if( _MOTOR0_2003 == ps->Device.bMotorID ) {
166 ps->Device.f2003 = _TRUE;
167 ps->Device.XStepMono = 10;
168 ps->Device.XStepColor = 6;
169 ps->Device.XStepBack = 5;
170 ps->AsicReg.RD_MotorDriverType |= _MOTORR_STRONG;
171 } else {
172 ps->Device.f2003 = _FALSE;
173 ps->Device.XStepMono = 8;
174 ps->Device.XStepColor = 4;
175 ps->Device.XStepBack = 5;
176 ps->AsicReg.RD_MotorDriverType |= _MOTORR_WEAK;
177 }
178 }
179
180 /*.............................................................................
181 * prepare all the necessary variables -
182 */
p12SetupScannerVariables(pScanData ps)183 static void p12SetupScannerVariables( pScanData ps )
184 {
185 DBG( DBG_LOW, "p12SetupScannerVariables()\n" );
186
187 /*
188 * these values were originally altered by registry entries (NT-driver)
189 * and used to adjust the picture position...
190 */
191 ps->Device.lUpNormal = 0;
192 ps->Device.lUpNegative = 20;
193 ps->Device.lUpPositive = -30;
194
195 ps->Device.lLeftNormal = 51;
196
197 ps->OpenScanPath( ps );
198 ps->ReInitAsic( ps, _FALSE );
199 ps->CloseScanPath( ps );
200 }
201
202 /*.............................................................................
203 *
204 */
p12SetupScanningCondition(pScanData ps)205 static void p12SetupScanningCondition( pScanData ps )
206 {
207 TimerDef timer;
208 ULong channel;
209 Byte bState;
210 pUChar pState = ps->Bufs.b1.pReadBuf;
211
212 DBG( DBG_LOW, "p12SetupScanningCondition()\n" );
213
214 P12SetGeneralRegister( ps );
215
216 IORegisterToScanner( ps, ps->RegResetMTSC );
217
218 /* ------- Setup MinRead/MaxRead Fifo size ------- */
219 if( ps->DataInf.wPhyDataType <= COLOR_TRUE24 ) {
220 ps->Scan.dwMaxReadFifo =
221 ps->Scan.dwMinReadFifo = ps->DataInf.dwAsicBytesPerPlane * 2;
222 } else {
223 ps->Scan.dwMaxReadFifo =
224 ps->Scan.dwMinReadFifo = ps->DataInf.dwAppPixelsPerLine << 1;
225 }
226
227 if( ps->Scan.dwMinReadFifo < 1024)
228 ps->Scan.dwMinReadFifo = ps->Scan.dwMaxReadFifo = 1024;
229
230 ps->Scan.dwMaxReadFifo += (ps->DataInf.dwAsicBytesPerPlane / 2);
231
232
233 DBG( DBG_LOW, "MinReadFifo=%u, MaxReadFifo=%u\n",
234 ps->Scan.dwMinReadFifo, ps->Scan.dwMaxReadFifo );
235
236 /* ------- Set the max. read fifo to asic ------- */
237 if( ps->DataInf.wPhyDataType > COLOR_256GRAY ) {
238
239 ps->Scan.bFifoSelect = ps->RegBFifoOffset;
240
241 if( !ps->Scan.p48BitBuf.pb ) {
242
243 Long lRed, lGreen;
244
245 lRed = (_SIZE_REDFIFO - _SIZE_BLUEFIFO) /
246 ps->DataInf.dwAsicBytesPerPlane - ps->Scan.bd_rk.wRedKeep;
247
248 lGreen = (_SIZE_GREENFIFO - _SIZE_BLUEFIFO) /
249 ps->DataInf.dwAsicBytesPerPlane - ps->Scan.gd_gk.wGreenKeep;
250
251 if((lRed < 0) || (lGreen < 0)) {
252
253 if( lRed < lGreen ) {
254 channel = _RED_FULLSIZE << 16;
255 ps->AsicReg.RD_BufFullSize = _SIZE_REDFIFO;
256 lGreen = lRed;
257 } else {
258 channel = _GREEN_FULLSIZE << 16;
259 ps->AsicReg.RD_BufFullSize = _SIZE_GREENFIFO;
260 }
261
262 lGreen = (ULong)(-lGreen * ps->DataInf.dwAsicBytesPerPlane);
263
264 if( ps->DataInf.wPhyDataType > COLOR_TRUE24 )
265 lGreen >>= 1;
266
267 ps->Scan.dwMinReadFifo += (ULong)lGreen;
268 ps->Scan.dwMaxReadFifo += (ULong)lGreen;
269
270 } else {
271 channel = _BLUE_FULLSIZE << 16;
272 ps->AsicReg.RD_BufFullSize = _SIZE_BLUEFIFO;
273 }
274 } else {
275 channel = _BLUE_FULLSIZE << 16;
276 ps->AsicReg.RD_BufFullSize = _SIZE_BLUEFIFO;
277 }
278 } else {
279 ps->Scan.bFifoSelect = ps->RegGFifoOffset;
280 channel = _GREEN_FULLSIZE << 16;
281 ps->AsicReg.RD_BufFullSize = _SIZE_GRAYFIFO;
282 }
283
284 ps->AsicReg.RD_BufFullSize -= (ps->DataInf.dwAsicBytesPerPlane << 1);
285
286 if( ps->DataInf.wPhyDataType > COLOR_TRUE24 )
287 ps->AsicReg.RD_BufFullSize >>= 1;
288
289 ps->AsicReg.RD_BufFullSize |= channel;
290
291 ps->Scan.bRefresh = (Byte)(ps->Scan.dwInterval << 1);
292 ps->AsicReg.RD_LineControl = (_LOBYTE (ps->Shade.wExposure));
293 ps->AsicReg.RD_ExtLineControl = (_HIBYTE (ps->Shade.wExposure));
294 ps->AsicReg.RD_XStepTime = (_LOBYTE (ps->Shade.wXStep));
295 ps->AsicReg.RD_ExtXStepTime = (_HIBYTE (ps->Shade.wXStep));
296 ps->AsicReg.RD_Motor0Control = _FORWARD_MOTOR;
297 ps->AsicReg.RD_StepControl = _MOTOR0_SCANSTATE;
298 ps->AsicReg.RD_ModeControl = (_ModeScan | _ModeFifoGSel);
299
300 DBG( DBG_LOW, "bRefresh = %i\n", ps->Scan.bRefresh );
301
302 if( ps->DataInf.wPhyDataType == COLOR_BW ) {
303 ps->AsicReg.RD_ScanControl = _SCAN_BITMODE;
304
305 if( !(ps->DataInf.dwScanFlag & SCANDEF_Inverse))
306 ps->AsicReg.RD_ScanControl |= _P98_SCANDATA_INVERT;
307
308 } else if( ps->DataInf.wPhyDataType <= COLOR_TRUE24 )
309 ps->AsicReg.RD_ScanControl = _SCAN_BYTEMODE;
310 else {
311 ps->AsicReg.RD_ScanControl = _SCAN_12BITMODE;
312
313 if(!(ps->DataInf.dwScanFlag & SCANDEF_RightAlign))
314 ps->AsicReg.RD_ScanControl |= _BITALIGN_LEFT;
315
316 if( ps->DataInf.dwScanFlag & SCANDEF_Inverse)
317 ps->AsicReg.RD_ScanControl |= _P98_SCANDATA_INVERT;
318 }
319
320 ps->AsicReg.RD_ScanControl |= _SCAN_1ST_AVERAGE;
321 IOSelectLampSource( ps );
322
323 DBG( DBG_LOW, "RD_ScanControl = 0x%02x\n", ps->AsicReg.RD_ScanControl );
324
325 ps->AsicReg.RD_MotorTotalSteps = (ULong)ps->DataInf.crImage.cy * 4 +
326 ((ps->Device.f0_8_16) ? 32 : 16) +
327 ((ps->Scan.bDiscardAll) ? 32 : 0);
328
329 ps->AsicReg.RD_ScanControl1 = (_MTSC_ENABLE | _SCANSTOPONBUFFULL |
330 _MFRC_RUNSCANSTATE | _MFRC_BY_XSTEP);
331
332 ps->AsicReg.RD_Dpi = ps->DataInf.xyPhyDpi.x;
333
334 if(!(ps->DataInf.dwScanFlag & SCANDEF_TPA )) {
335
336 ps->AsicReg.RD_Origin = (UShort)(ps->Device.lLeftNormal * 2 +
337 ps->Device.DataOriginX +
338 ps->DataInf.crImage.x );
339
340 } else if( ps->DataInf.dwScanFlag & SCANDEF_Transparency ) {
341 ps->AsicReg.RD_Origin =
342 (UShort)(ps->Scan.posBegin + ps->DataInf.crImage.x);
343 } else {
344 ps->AsicReg.RD_Origin =
345 (UShort)(ps->Scan.negBegin + ps->DataInf.crImage.x);
346 }
347
348 if( ps->Shade.bIntermediate & _ScanMode_AverageOut )
349 ps->AsicReg.RD_Origin >>= 1;
350
351 if( ps->DataInf.wPhyDataType == COLOR_BW )
352 ps->AsicReg.RD_Pixels = (UShort)ps->DataInf.dwAsicBytesPerPlane;
353 else
354 ps->AsicReg.RD_Pixels = (UShort)ps->DataInf.dwAppPixelsPerLine;
355
356 DBG( DBG_LOW, "RD_Origin = %u, RD_Pixels = %u\n",
357 ps->AsicReg.RD_Origin, ps->AsicReg.RD_Pixels );
358
359 /* ------- Prepare scan states ------- */
360 memset( ps->a_nbNewAdrPointer, 0, _SCANSTATE_BYTES );
361 memset( ps->Bufs.b1.pReadBuf, 0, _NUMBER_OF_SCANSTEPS );
362
363 if( ps->DataInf.wPhyDataType <= COLOR_256GRAY )
364 bState = (_SS_MONO | _SS_STEP);
365 else
366 bState = (_SS_COLOR | _SS_STEP);
367
368 for( channel = _NUMBER_OF_SCANSTEPS;
369 channel; channel -= ps->Scan.dwInterval ) {
370 *pState = bState;
371 if( ps->Scan.dwInterlace )
372 pState[ ps->Scan.dwInterlace] = _SS_STEP;
373 pState += ps->Scan.dwInterval;
374 }
375 for( channel = 0, pState = ps->Bufs.b1.pReadBuf;
376 channel < _SCANSTATE_BYTES; channel++) {
377 ps->a_nbNewAdrPointer[channel] = pState [0] | (pState [1] << 4);
378 pState += 2;
379 }
380
381 /* ------- Wait for scan state stop ------- */
382 MiscStartTimer( &timer, _SECOND * 2 );
383
384 while(!(IOGetScanState( ps, _FALSE ) & _SCANSTATE_STOP) &&
385 !MiscCheckTimer(&timer));
386
387 /* CHECK: Replace by IOPutAll.... */
388 IODownloadScanStates( ps );
389 IODataToRegister( ps, ps->RegLineControl, ps->AsicReg.RD_LineControl);
390 IODataToRegister( ps, ps->RegExtendedLineControl,
391 ps->AsicReg.RD_ExtLineControl);
392 IODataToRegister( ps, ps->RegXStepTime, ps->AsicReg.RD_XStepTime);
393 IODataToRegister( ps, ps->RegExtendedXStep, ps->AsicReg.RD_ExtXStepTime);
394 IODataToRegister( ps, ps->RegMotorDriverType,
395 ps->AsicReg.RD_MotorDriverType);
396 IODataToRegister( ps, ps->RegStepControl, ps->AsicReg.RD_StepControl);
397 IODataToRegister( ps, ps->RegMotor0Control, ps->AsicReg.RD_Motor0Control);
398 IODataToRegister( ps, ps->RegModelControl,ps->AsicReg.RD_ModelControl);
399 IODataToRegister( ps, ps->RegDpiLow, (_LOBYTE(ps->AsicReg.RD_Dpi)));
400 IODataToRegister( ps, ps->RegDpiHigh, (_HIBYTE(ps->AsicReg.RD_Dpi)));
401 IODataToRegister( ps, ps->RegScanPosLow, (_LOBYTE(ps->AsicReg.RD_Origin)));
402 IODataToRegister( ps, ps->RegScanPosHigh,(_HIBYTE(ps->AsicReg.RD_Origin)));
403 IODataToRegister( ps, ps->RegWidthPixelsLow,
404 (_LOBYTE(ps->AsicReg.RD_Pixels)));
405 IODataToRegister( ps, ps->RegWidthPixelsHigh,
406 (_HIBYTE(ps->AsicReg.RD_Pixels)));
407 IODataToRegister( ps, ps->RegThresholdLow,
408 (_LOBYTE(ps->AsicReg.RD_ThresholdControl)));
409 IODataToRegister( ps, ps->RegThresholdHigh,
410 (_HIBYTE(ps->AsicReg.RD_ThresholdControl)));
411 IODataToRegister( ps, ps->RegMotorTotalStep0,
412 (_LOBYTE(ps->AsicReg.RD_MotorTotalSteps)));
413 IODataToRegister( ps, ps->RegMotorTotalStep1,
414 (_HIBYTE(ps->AsicReg.RD_MotorTotalSteps)));
415 IODataToRegister( ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl);
416
417 IORegisterToScanner( ps, ps->RegInitDataFifo);
418 }
419
420 /*.............................................................................
421 * program the CCD relevant stuff
422 */
p12ProgramCCD(pScanData ps)423 static void p12ProgramCCD( pScanData ps)
424 {
425 UShort w;
426 pRegDef rp;
427
428 DBG( DBG_IO, "p12ProgramCCD: 0x%08lx[%lu]\n",
429 (unsigned long)ps->Device.pCCDRegisters,
430 ((unsigned long)ps->Device.wNumCCDRegs * ps->Shade.bIntermediate));
431
432 DBG( DBG_IO, " %u regs * %u (intermediate)\n",
433 ps->Device.wNumCCDRegs, ps->Shade.bIntermediate );
434
435 rp = ps->Device.pCCDRegisters +
436 (ULong)ps->Device.wNumCCDRegs * ps->Shade.bIntermediate;
437
438 for( w = ps->Device.wNumCCDRegs; w--; rp++ ) {
439
440 DBG( DBG_IO, "[0x%02x] = 0x%02x\n", rp->bReg, rp->bParam );
441 IODataToRegister( ps, rp->bReg, rp->bParam );
442 }
443 }
444
445 /*.............................................................................
446 * this initializes the ASIC and prepares the different functions for shading
447 * and scanning
448 */
p12Init98003(pScanData ps,Bool shading)449 static void p12Init98003( pScanData ps, Bool shading )
450 {
451 DBG( DBG_LOW, "p12InitP98003(%d)\n", shading );
452
453 /* get DAC and motor stuff */
454 ps->Device.bDACType = IODataFromRegister( ps, ps->RegResetConfig );
455 ps->Device.bMotorID = (Byte)(ps->Device.bDACType & _MOTOR0_MASK);
456
457 ps->AsicReg.RD_MotorDriverType =
458 (Byte)((ps->Device.bDACType & _MOTOR0_MASK) >> 3);
459 ps->AsicReg.RD_MotorDriverType |=
460 (Byte)((ps->Device.bDACType & _MOTOR1_MASK) >> 1);
461
462
463 ps->Scan.motorPower = ps->AsicReg.RD_MotorDriverType | _MOTORR_STRONG;
464
465 ps->Device.bDACType &= _ADC_MASK;
466
467 /*get CCD and PCB ID */
468 ps->Device.bPCBID = IODataFromRegister( ps, ps->RegConfiguration );
469 ps->Device.bCCDID = ps->Device.bPCBID & 0x07;
470 ps->Device.bPCBID &= 0xf0;
471
472 if( _AGFA_SCANNER == ps->Device.bPCBID )
473 ps->Device.bDACType = _DA_WOLFSON8141;
474
475 DBG( DBG_LOW, "PCB-ID=0x%02x, CCD-ID=0x%02x, DAC-TYPE=0x%02x\n",
476 ps->Device.bPCBID, ps->Device.bCCDID, ps->Device.bDACType );
477
478 p12InitiateComponentModel( ps );
479
480 /* encode the CCD-id into the flag parameter */
481 ps->sCaps.dwFlag |= ((ULong)(ps->Device.bCCDID | ps->Device.bPCBID) << 16);
482
483 P12InitCCDandDAC( ps, shading );
484
485 if( ps->Shade.bIntermediate & _ScanMode_Mono )
486 ps->AsicReg.RD_Model1Control = ps->Device.Model1Mono;
487 else
488 ps->AsicReg.RD_Model1Control = ps->Device.Model1Color;
489
490 IODataToRegister( ps, ps->RegPllPredivider, 1 );
491 IODataToRegister( ps, ps->RegPllMaindivider, 0x20 );
492 IODataToRegister( ps, ps->RegPllPostdivider, 2 );
493 IODataToRegister( ps, ps->RegClockSelector, 3 ); /* 2 */
494 IODataToRegister( ps, ps->RegMotorDriverType,
495 ps->AsicReg.RD_MotorDriverType );
496
497 /* this might be changed, def value is 11 */
498 IODataToRegister( ps, ps->RegWaitStateInsert, 11 );
499 IODataToRegister( ps, ps->RegModel1Control, ps->AsicReg.RD_Model1Control );
500
501 p12ProgramCCD( ps );
502 }
503
504 /*.............................................................................
505 * initialize the register values for the 98003 asic and preset other stuff
506 */
p12InitializeAsicRegister(pScanData ps)507 static void p12InitializeAsicRegister( pScanData ps )
508 {
509 memset( &ps->AsicReg, 0, sizeof(RegData));
510 }
511
512 /*.............................................................................
513 * as the function name says
514 */
p12PutToIdleMode(pScanData ps)515 static void p12PutToIdleMode( pScanData ps )
516 {
517 ULong i;
518
519 ps->OpenScanPath( ps );
520
521 DBG( DBG_IO, "CCD-Stop\n" );
522
523 for( i = 0; i < 13; i++ ) {
524
525 DBG( DBG_IO, "[0x%02x] = 0x%02x\n",
526 p12CcdStop[i].bReg, p12CcdStop[i].bParam );
527
528 IODataToRegister( ps, p12CcdStop[i].bReg, p12CcdStop[i].bParam );
529 }
530
531 ps->CloseScanPath( ps );
532 }
533
534 /*.............................................................................
535 * here we simply call the WaitForShading function which performs this topic
536 */
p12Calibration(pScanData ps)537 static int p12Calibration( pScanData ps )
538 {
539 Bool result;
540
541 DBG( DBG_LOW, "p12Calibration()\n" );
542
543 /*
544 * wait for shading to be done
545 */
546 ps->OpenScanPath( ps );
547
548 _ASSERT(ps->WaitForShading);
549 result = ps->WaitForShading( ps );
550 ps->CloseScanPath( ps );
551
552 if( !result )
553 return _E_TIMEOUT;
554
555 return _OK;
556 }
557
558 /************************ exported functions *********************************/
559
560 /*.............................................................................
561 * initialize the register values and function calls for the 98003 asic
562 */
P12InitAsic(pScanData ps)563 _LOC int P12InitAsic( pScanData ps )
564 {
565 int result;
566
567 DBG( DBG_LOW, "P12InitAsic()\n" );
568
569 /*
570 * preset the asic shadow registers
571 */
572 p12InitializeAsicRegister( ps );
573
574 ps->IO.bOpenCount = 0;
575
576 /*
577 * setup the register values
578 */
579 ps->RegSwitchBus = 0;
580 ps->RegEPPEnable = 1;
581 ps->RegECPEnable = 2;
582 ps->RegReadDataMode = 3;
583 ps->RegWriteDataMode = 4;
584 ps->RegInitDataFifo = 5;
585 ps->RegForceStep = 6;
586 ps->RegInitScanState = 7;
587 ps->RegRefreshScanState = 8;
588 ps->RegWaitStateInsert = 0x0a;
589 ps->RegRFifoOffset = 0x0a;
590 ps->RegGFifoOffset = 0x0b;
591 ps->RegBFifoOffset = 0x0c;
592 ps->RegBitDepth = 0x13;
593 ps->RegStepControl = 0x14;
594 ps->RegMotor0Control = 0x15;
595 ps->RegXStepTime = 0x16;
596 ps->RegGetScanState = 0x17;
597 ps->RegAsicID = 0x18;
598 ps->RegMemoryLow = 0x19;
599 ps->RegMemoryHigh = 0x1a;
600 ps->RegModeControl = 0x1b;
601 ps->RegLineControl = 0x1c;
602 ps->RegScanControl = 0x1d;
603 ps->RegConfiguration = 0x1e;
604 ps->RegModelControl = 0x1f;
605 ps->RegModel1Control = 0x20;
606 ps->RegDpiLow = 0x21;
607 ps->RegDpiHigh = 0x22;
608 ps->RegScanPosLow = 0x23;
609 ps->RegScanPosHigh = 0x24;
610 ps->RegWidthPixelsLow = 0x25;
611 ps->RegWidthPixelsHigh = 0x26;
612 ps->RegThresholdLow = 0x27;
613 ps->RegThresholdHigh = 0x28;
614 ps->RegThresholdGapControl = 0x29;
615 ps->RegADCAddress = 0x2a;
616 ps->RegADCData = 0x2b;
617 ps->RegADCPixelOffset = 0x2c;
618 ps->RegADCSerialOutStr = 0x2d;
619 ps->RegResetConfig = 0x2e;
620 ps->RegLensPosition = 0x2f;
621 ps->RegStatus = 0x30;
622 ps->RegScanStateControl = 0x31;
623 ps->RegRedChDarkOffsetLow = 0x33;
624 ps->RegRedChDarkOffsetHigh = 0x34;
625 ps->RegGreenChDarkOffsetLow = 0x35;
626 ps->RegGreenChDarkOffsetHigh= 0x36;
627 ps->RegBlueChDarkOffsetLow = 0x37;
628 ps->RegBlueChDarkOffsetHigh = 0x38;
629 ps->RegResetPulse0 = 0x39;
630 ps->RegResetPulse1 = 0x3a;
631 ps->RegCCDClampTiming0 = 0x3b;
632 ps->RegCCDClampTiming1 = 0x3c;
633 ps->RegVSMPTiming0 = 0x41;
634 ps->RegVSMPTiming1 = 0x42;
635 ps->RegCCDQ1Timing0 = 0x43;
636 ps->RegCCDQ1Timing1 = 0x44;
637 ps->RegCCDQ1Timing2 = 0x45;
638 ps->RegCCDQ1Timing3 = 0x46;
639 ps->RegCCDQ2Timing0 = 0x47;
640 ps->RegCCDQ2Timing1 = 0x48;
641 ps->RegCCDQ2Timing2 = 0x49;
642 ps->RegCCDQ2Timing3 = 0x4a;
643 ps->RegADCclockTiming0 = 0x4b;
644 ps->RegADCclockTiming1 = 0x4c;
645 ps->RegADCclockTiming2 = 0x4d;
646 ps->RegADCclockTiming3 = 0x4e;
647 ps->RegADCDVTiming0 = 0x50;
648 ps->RegADCDVTiming1 = 0x51;
649 ps->RegADCDVTiming2 = 0x52;
650 ps->RegADCDVTiming3 = 0x53;
651
652 ps->RegFifoFullLength0 = 0x54;
653 ps->RegFifoFullLength1 = 0x55;
654 ps->RegFifoFullLength2 = 0x56;
655
656 ps->RegMotorTotalStep0 = 0x57;
657 ps->RegMotorTotalStep1 = 0x58;
658 ps->RegMotorFreeRunCount0 = 0x59;
659 ps->RegMotorFreeRunCount1 = 0x5a;
660 ps->RegScanControl1 = 0x5b;
661 ps->RegMotorFreeRunTrigger = 0x5c;
662
663 ps->RegResetMTSC = 0x5d;
664
665 ps->RegMotor1Control = 0x62;
666 ps->RegMotor2Control = 0x63;
667 ps->RegMotorDriverType = 0x64;
668
669 ps->RegStatus2 = 0x66;
670
671 ps->RegExtendedLineControl = 0x6d;
672 ps->RegExtendedXStep = 0x6e;
673
674 ps->RegPllPredivider = 0x71;
675 ps->RegPllMaindivider = 0x72;
676 ps->RegPllPostdivider = 0x73;
677 ps->RegClockSelector = 0x74;
678 ps->RegTestMode = 0xf0;
679
680 /*
681 * setup function calls
682 */
683 ps->SetupScannerVariables = p12SetupScannerVariables;
684 ps->SetupScanningCondition = p12SetupScanningCondition;
685 ps->Calibration = p12Calibration;
686 ps->PutToIdleMode = p12PutToIdleMode;
687 ps->ReInitAsic = p12Init98003;
688
689 ps->CtrlReadHighNibble = _CTRL_GENSIGNAL + _CTRL_AUTOLF + _CTRL_STROBE;
690 ps->CtrlReadLowNibble = _CTRL_GENSIGNAL + _CTRL_AUTOLF;
691
692 ps->IO.useEPPCmdMode = _FALSE;
693
694 /*
695 * initialize the other modules and set some
696 * function pointer
697 */
698 result = DacInitialize( ps );
699 if( _OK != result )
700 return result;
701
702 result = ImageInitialize( ps );
703 if( _OK != result )
704 return result;
705
706 result = IOFuncInitialize( ps );
707 if( _OK != result )
708 return result;
709
710 result = IOInitialize( ps );
711 if( _OK != result )
712 return result;
713
714 result = MotorInitialize( ps );
715 if( _OK != result )
716 return result;
717
718 if( _FALSE == ps->OpenScanPath( ps )) {
719 DBG( DBG_LOW, "P12InitAsic() failed.\n" );
720 return _E_NO_DEV;
721 }
722
723 /*get CCD and PCB ID */
724 ps->Device.bPCBID = IODataFromRegister( ps, ps->RegConfiguration );
725 ps->Device.bCCDID = ps->Device.bPCBID & 0x07;
726 ps->Device.bPCBID &= 0xf0;
727
728 DBG( DBG_LOW, "PCB-ID=0x%02x, CCD-ID=0x%02x\n", ps->Device.bPCBID, ps->Device.bCCDID );
729
730 /* get a more closer model description...*/
731 p12InitiateComponentModel( ps );
732
733 ps->CloseScanPath( ps );
734
735 /* here we check for the OpticWorks 2000, which is not supported */
736 if( _OPTICWORKS2000 == ps->Device.bPCBID ) {
737 DBG( DBG_LOW, "OpticWorks 2000 not supported!\n" );
738 return _E_NOSUPP;
739 }
740
741 DBG( DBG_LOW, "P12InitAsic() done.\n" );
742 return _OK;
743 }
744
745 /*.............................................................................
746 * set all necessary register contents
747 */
P12SetGeneralRegister(pScanData ps)748 _LOC void P12SetGeneralRegister( pScanData ps )
749 {
750 DBG( DBG_LOW, "P12SetGeneralRegister()\n" );
751
752 ps->Scan.fMotorBackward = _FALSE;
753 ps->Scan.fRefreshState = _FALSE;
754
755 if( COLOR_BW == ps->DataInf.wPhyDataType )
756 ps->AsicReg.RD_ScanControl = _SCAN_BITMODE;
757 else {
758 if( ps->DataInf.wPhyDataType <= COLOR_TRUE24 )
759 ps->AsicReg.RD_ScanControl = _SCAN_BYTEMODE;
760 else
761 ps->AsicReg.RD_ScanControl = _SCAN_12BITMODE;
762 }
763
764 IOSelectLampSource( ps );
765
766 if( ps->Shade.bIntermediate & _ScanMode_AverageOut )
767 ps->AsicReg.RD_ModelControl = ps->Device.ModelCtrl | _ModelDpi300;
768 else
769 ps->AsicReg.RD_ModelControl = ps->Device.ModelCtrl | _ModelDpi600;
770
771 ps->AsicReg.RD_Motor0Control = _MotorOn | _MotorHQuarterStep | _MotorPowerEnable;
772 ps->AsicReg.RD_ScanControl1 = _SCANSTOPONBUFFULL | _MFRC_BY_XSTEP;
773 ps->AsicReg.RD_StepControl = _MOTOR0_SCANSTATE;
774 }
775
776 /* END PLUSTEK-PP_P12.C .....................................................*/
777