Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 247605 | Differences between
and this patch

Collapse All | Expand All

(-)sane-backends-1.0.19/backend/Makefile.in (-3 / +6 lines)
Lines 69-75 Link Here
69
69
70
@SET_MAKE@
70
@SET_MAKE@
71
71
72
PRELOADABLE_BACKENDS = @BACKENDS@
72
PRELOADABLE_BACKENDS = hp_rts88xx  @BACKENDS@
73
73
74
ALL_BACKENDS = $(PRELOADABLE_BACKENDS) dll
74
ALL_BACKENDS = $(PRELOADABLE_BACKENDS) dll
75
75
Lines 87-93 Link Here
87
87
88
LIBOBJS = $(addprefix ../lib/,$(addsuffix .lo,$(LIBLIB_FUNCS)))
88
LIBOBJS = $(addprefix ../lib/,$(addsuffix .lo,$(LIBLIB_FUNCS)))
89
89
90
DISTFILES = Makefile.in saned.conf.in sane_strstatus.c stubs.c \
90
DISTFILES =  hp_rts88xx.c hp_rts88xx.h Makefile.in saned.conf.in sane_strstatus.c stubs.c \
91
  abaton.c abaton.conf.in abaton.h \
91
  abaton.c abaton.conf.in abaton.h \
92
  agfafocus.c agfafocus.conf.in agfafocus.h \
92
  agfafocus.c agfafocus.conf.in agfafocus.h \
93
  apple.c apple.conf.in apple.h \
93
  apple.c apple.conf.in apple.h \
Lines 359-365 Link Here
359
359
360
libsane-abaton.la: ../sanei/sanei_config2.lo
360
libsane-abaton.la: ../sanei/sanei_config2.lo
361
libsane-abaton.la: ../sanei/sanei_constrain_value.lo
361
libsane-abaton.la: ../sanei/sanei_constrain_value.lo
362
libsane-abaton.la: ../sanei/sanei_scsi.lo
362
libsane-abaton.la: ../sanei/sanei_scsi.lo 
363
libsane-hp_rts88xx.la: ../sanei/sanei_config2.lo 
364
libsane-hp_rts88xx.la: ../sanei/sanei_constrain_value.lo 
365
libsane-hp_rts88xx.la: ../sanei/sanei_usb.lo
363
libsane-agfafocus.la: ../sanei/sanei_config2.lo
366
libsane-agfafocus.la: ../sanei/sanei_config2.lo
364
libsane-agfafocus.la: ../sanei/sanei_constrain_value.lo
367
libsane-agfafocus.la: ../sanei/sanei_constrain_value.lo
365
libsane-agfafocus.la: ../sanei/sanei_scsi.lo
368
libsane-agfafocus.la: ../sanei/sanei_scsi.lo
(-)sane-backends-1.0.19/backend/dll.conf (+1 lines)
Line 0 Link Here
1
hp_rts88xx
(-)sane-backends-1.0.19/backend/hp_rts88xx.c (+1594 lines)
Line 0 Link Here
1
   /* sane - Scanner Access Now Easy.
2
   Copyright (C) 2003 Johannes Hub (JohannesHub@t-online.de)
3
4
   This file was initially copied from the hp3300 backend.
5
6
   This file is part of the SANE package.
7
8
   This program is free software; you can redistribute it and/or
9
   modify it under the terms of the GNU General Public License
10
   as published by the Free Software Foundation; either version 2
11
   of the License, or (at your option) any later version.
12
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
18
   You should have received a copy of the GNU General Public License
19
   along with this program; if not, write to the Free Software
20
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21
22
   As a special exception, the authors of SANE give permission for
23
   additional uses of the libraries contained in this release of SANE.
24
25
   The exception is that, if you link a SANE library with other files
26
   to produce an exutable, this does not by itself cause the
27
   resulting executable to be covered by the GNU General Public
28
   License.  Your use of that executable is in no way restricted on
29
   account of linking the SANE library code into it.
30
31
   This exception does not, however, invalidate any other reasons why
32
   the executable file might be covered by the GNU General Public
33
   License.
34
35
   If you submit changes to SANE to the maintainers to be included in
36
   a subsequent release, you agree by submitting the changes that
37
   those changes may be distributed with this exception intact.
38
39
   If you write modifications of your own for SANE, it is your choice
40
   whether to permit this exception to apply to your modifications.
41
   If you do not wish that, delete this exception notice.
42
*/
43
44
/*
45
    Concept for a backend for scanners based on the RTS88xx chipset,
46
    such as HP4400C, HP4470C, HP3500C, 3530C, and HP ScanJet 3570C.
47
    Parts of this source were inspired by other backends.
48
49
		History:
50
51
		Version 0.18  21.11.04 13.alpha,
52
				- source sorted,
53
				- now only SANEI_USB_SUPPORT for a better overview(xfermodules removed)
54
				- read and verify the MainBoardID 
55
		Version 0.17p 02.11.04 12.alpha, source sorted, little fixes, SANEI_USB_SUPPORT implemented
56
		Version 0.17p 02.11.04 12.alpha, source sourted, little fixes, SANEI_USB_SUPPORT implemented
57
		Version 0.17b 30.03.04 10.alpha, little fixes and libusb implemented
58
		Version 0.17  09.03.04 9. alpha, HP3500 included
59
		Version 0.16  06.02.04 8. alpha, wait counting on LCD
60
		Version 0.15a 29.01.04 7. alpha, CCD switch moved to config file
61
		Version 0.15  11.01.04 6. alpha, a second CCD implemented
62
		Version 0.13a 21.11.04 4. alpha, an little fix included
63
		Version 0.12  22.10.03 third alpha, Backend name changed to HP_RTS88xx
64
		Version 0.11  30.08.03 second alpha
65
		Version 0.10  19.07.03 first alpha
66
*/
67
68
/*
69
		enable DEDUG output:
70
		use a nomal shell (konsole) and type
71
		export SANE_DEBUG_HP_RTS88XX=32
72
		xsane
73
*/
74
75
#ifndef BACKEND_NAME
76
#define BACKEND_NAME hp_rts88xx
77
#endif
78
#ifndef BUILD
79
#define BUILD 18
80
#endif
81
82
/*#define STANDALONE*/
83
/*#define ENABLE_VI8920*/
84
85
/* definitions for debug */
86
#define DEBUG								/* debug output */
87
/*#define DEBUG_HP3500			* debug switch to test the 3500 code under hp4470c */
88
/*#define STOP_HP3500_1*/
89
90
/*#define DEBUG_SCAN					* debug output about getting the immage datas */
91
/*#define DEBUG_L							* don't wait for lamp warm up */
92
/*#define USBDEBUG					* debug output about the USB in/out */
93
/*#define DEBUG_FILE				* additional write into a pnm file (not allowed as driver)*/
94
95
#include <stdlib.h>					/* malloc, free */
96
#include <string.h>					/* memcpy */
97
#include <stdio.h>
98
#include "../include/sane/sane.h"
99
#include "../include/sane/config.h"
100
#include "../include/sane/sanei.h"
101
#include "../include/sane/sanei_config.h"
102
#include "../include/sane/saneopts.h"
103
104
#ifdef STANDALONE
105
	#define V_MAJOR 1
106
	#define V_MINOR 15
107
	#define PATH_MAX 128
108
	#define DBG          fprintf
109
	#define DBG_MSG      stdout
110
	#define DBG_USB      stdout
111
	#define DBG_OPT      stdout
112
	#define DBG_SCAN     stdout
113
	#define DBG_ASSERT   stdout
114
	#define DBG_ERR      stdout
115
#else
116
#include "../include/sane/sanei_backend.h"
117
	#define DBG_ASSERT  1
118
	#define DBG_ERR     2
119
	#define DBG_MSG     16
120
	#define DBG_SCAN    32
121
	#define DBG_OPT     64
122
	#define DBG_USB     128
123
#endif
124
125
#define HP_RTS_CONFIG_FILE "hp_rts88xx.conf"
126
127
#include "hp_rts88xx.h"
128
#include "hp_rts_44x0c.h"
129
#include "hp_rts_35x0c.h"
130
131
/* (source) includes for data transfer methods */
132
#include "hp_rts_xfer.c"
133
/* (source) includes for special scanner code */
134
#include "hp_rts_44x0c.c"
135
#include "hp_rts_35x0c.c"
136
137
138
/****************************************************************************/
139
SANE_Bool _InitScan(TScanParams *pParams, THWParams *pHWParams, TDataPipe *pDataPipe)
140
/****************************************************************************/
141
{
142
	SANE_Int	iHandle;
143
	SANE_Bool result;
144
	iHandle = pHWParams->iXferHandle;
145
146
	result = SANE_FALSE;
147
	/* check validity of scanparameters */
148
	switch (pParams->iDpi) {
149
		case 150:
150
		case 200:
151
		case 300:
152
		case 600:
153
		break;
154
	default:
155
		DBG(DBG_ERR, "InitScan: Invalid dpi (%d)\n", pParams->iDpi);
156
		return SANE_FALSE;
157
	}
158
	switch (pParams->iLpi) {
159
		case 150:
160
		case 200:
161
		case 300:
162
		case 600:
163
		break;
164
	default:
165
		DBG(DBG_ERR, "InitScan: Invalid lpi (%d)\n", pParams->iLpi);
166
		return SANE_FALSE;
167
	}
168
	/*   *** Done checking scan parameters validity ***  */
169
	switch (pHWParams->ScannerModel) {
170
		case eHp3500c: case eHp3530c:
171
#ifdef ENABLE_VI8920
172
	  case eVi8920:
173
#endif
174
			result = Hp35x0c_init_scan(pHWParams,pParams,pDataPipe);
175
				if (result)
176
					DBG(DBG_ERR, "InitScan: OK\n");
177
				else
178
					DBG(DBG_ERR, "InitScan: ERROR from Hp35x0_init_scan\n");
179
			break;
180
		case eHp4400c: case eHp4470c:
181
			if (Hp44x0_cal_scanner(pHWParams,pParams) == SANE_TRUE){
182
				result = Hp44x0_init_scan(pHWParams,pParams,pDataPipe);
183
				if (result)
184
					DBG(DBG_ERR, "InitScan: OK\n");
185
				else
186
					DBG(DBG_ERR, "InitScan: ERROR from Hp44x0_init_scan\n");
187
			}
188
			break;
189
		case eUnknownModel:
190
		default:
191
			DBG(DBG_ERR, "InitScan: ERROR: unknown model! (%d)\n",
192
					(SANE_Int)pHWParams->ScannerModel);
193
			result = SANE_FALSE;
194
			break;
195
  }
196
	return result;
197
}
198
199
/****************************************************************************
200
	_FinishScan
201
	=================
202
	Finishes the scan. Makes the scanner head move back to the home position.
203
****************************************************************************/
204
SANE_Bool _FinishScan( SANE_Handle h )
205
{
206
	TScanner *s;
207
	THWParams *pHWParams;
208
	TScanParams *pParams;
209
	SANE_Int iHandle;
210
	SANE_Word size;
211
212
	s = (TScanner *)h;
213
214
	iHandle		= s->HWParams.iXferHandle;
215
	pHWParams	= &s->HWParams;
216
	pParams		= &s->ScanParams;
217
218
	DBG(DBG_MSG,"Finish scan:\n");
219
  /* check, if the scanner moving */
220
	if (Hp_rts_is_moving(iHandle)){
221
		DBG(DBG_MSG,"Finish scan, scanner is moving, stop it!!!\n");
222
		Hp_rts_stop_moving(iHandle);
223
	};
224
	usleep(100);
225
	
226
	/* clean the Scanner Buffer */
227
	do{
228
		/*if ( !*/(Hp_rts_data_ready(iHandle,&size));/*) return SANE_FALSE;*/
229
		if ( size > 0)
230
			if ( !(Hp_rts_read_data(iHandle,size,s->DataPipe.pabXferBuf))) return SANE_FALSE;
231
	} while (size != 0);
232
233
	DBG(DBG_MSG,"Finish scan, park to home\n");
234
	switch (pHWParams->ScannerModel) {
235
		case eHp3500c: case eHp3530c: case eHp3570c:
236
#ifdef ENABLE_VI8920
237
	  case eVi8920:
238
#endif
239
			Hp35x0c_rewind(pHWParams);
240
			break;
241
		case eHp4400c: case eHp4470c:
242
			Hp44x0_park_to_home(pHWParams,pParams);
243
			break;
244
		default:
245
			DBG(DBG_ERR, "FinishScan: ERROR: unknown model! (%d) %s\n",
246
					(SANE_Int)pHWParams->ScannerModel, ScannerModels[(SANE_Int)pHWParams->ScannerModel].pszName);
247
		return SANE_FALSE;
248
  }
249
	return SANE_TRUE;
250
}
251
252
253
/****************************************************************************/
254
static SANE_Int
255
_max_string_size (const SANE_String_Const strings[])
256
/****************************************************************************/
257
{
258
	SANE_Int size, max_size = 0;
259
	SANE_Int i;
260
261
	for (i = 0; strings[i]; ++i) {
262
		size = strlen (strings[i]) + 1;
263
		if (size > max_size)
264
			max_size = size;
265
	}
266
	return max_size;
267
}
268
269
270
/****************************************************************************/
271
SANE_Status _Init_Interface(THWParams *pHWParams, TScanParams *pParams)
272
/****************************************************************************/
273
{
274
275
	DBG(DBG_SCAN, "Init_Interface....\n");
276
	/* autodetect some hardware properties */
277
	if (Hp_rts_ProbeRegisters(pHWParams) != SANE_STATUS_GOOD) {
278
		DBG(DBG_ERR, "Init_Interface: Hp_rts_ProbeRegisters failed!\n");
279
		return SANE_STATUS_IO_ERROR;
280
	}
281
	/* default HW params */
282
	pHWParams->iTopLeftX      = 0;
283
	pHWParams->iTopLeftY      = 3;
284
	pHWParams->iReversedHead  = SANE_FALSE;
285
	DBG(DBG_MSG, "Init_Interface: Use scanner (%d) %s\n",
286
 		(SANE_Int)pHWParams->ScannerModel,ScannerModels[pHWParams->ScannerModel].pszName);
287
	switch (pHWParams->ScannerModel) {
288
289
		case eHp3500c: case eHp3530c:
290
#ifdef ENABLE_VI8920
291
		case eVi8920:
292
#endif
293
			pHWParams->iTopLeftX    = 7;
294
#ifndef DEBUG_HP3500
295
			Hp35x0c_init_power_on(pHWParams);
296
#else
297
			if ( !(Hp44x0_Wakeup(pHWParams, pParams))) return SANE_STATUS_IO_ERROR;
298
			if ( !(Hp44x0_cal_scanner(pHWParams, pParams))) return SANE_STATUS_IO_ERROR;
299
#endif
300
			break;
301
		case eHp4400c: case eHp4470c:
302
			pHWParams->iTopLeftX    = 7;
303
			if ( !(Hp44x0_Wakeup(pHWParams, pParams))) return SANE_STATUS_IO_ERROR;
304
			if ( !(Hp44x0_cal_scanner(pHWParams, pParams))) return SANE_STATUS_IO_ERROR;
305
			if ( !(Hp44x0_park_to_home(pHWParams, pParams))) return SANE_STATUS_IO_ERROR;
306
			break;
307
		case eUnknownModel:
308
		default:
309
			DBG(DBG_ERR, "Init_Interface: ERROR: internal error! (%d)\n",
310
		 		(SANE_Int)pHWParams->ScannerModel);
311
			return SANE_STATUS_UNSUPPORTED;
312
	}
313
	return SANE_STATUS_GOOD;
314
}
315
316
317
/****************************************************************************/
318
void _Close_Interface(THWParams *pHWParams)
319
/****************************************************************************/
320
{
321
	DBG(DBG_MSG, "Close_Interface: ..\n");
322
	switch (pHWParams->ScannerModel) {
323
		case eHp3500c: case eHp3530c:
324
#ifdef ENABLE_VI8920
325
	  case eVi8920:
326
#endif
327
			Hp35x0c_turn_off_lamp(pHWParams->iXferHandle);
328
			Hp35x0c_set_powersave_mode(pHWParams->iXferHandle,1);
329
			break;
330
		case eHp4400c: case eHp4470c:
331
			/* turn of scanner lamp */
332
			Hp44x0_SetLamp(pHWParams->iXferHandle, SANE_FALSE);
333
			Hp44x0_Down(pHWParams->iXferHandle);
334
			break;
335
		case eUnknownModel:
336
		default:
337
			DBG(DBG_ERR, "Close_Interface: ERROR: internal error! (%d)\n", (SANE_Int)pHWParams->ScannerModel);
338
			return;
339
	}
340
	Hp_rts_XferExit(pHWParams->iXferHandle);
341
	pHWParams->iXferHandle = 0;
342
}
343
344
/****************************************************************************/
345
static void SANE_InitOptions(TScanner *s)
346
/****************************************************************************/
347
{
348
	SANE_Int i, Model;
349
	SANE_Option_Descriptor *pDesc;
350
	TOptionValue *pVal;
351
352
	Model = s->HWParams.ScannerModel;
353
	DBG(DBG_SCAN, "SANE_InitOptions: Use model # %d\n", Model);
354
	/* set a neutral gamma */
355
	if( s->aGammaTableR == NULL )   /* Not yet allocated */
356
	{
357
		s->aGammaTableR = malloc( NUM_GAMMA_ENTRIES * sizeof( SANE_Int ) );
358
		s->aGammaTableG = malloc( NUM_GAMMA_ENTRIES * sizeof( SANE_Int ) );
359
		s->aGammaTableB = malloc( NUM_GAMMA_ENTRIES * sizeof( SANE_Int ) );
360
361
		for (i = 0; i < NUM_GAMMA_ENTRIES; i++) {
362
			s->aGammaTableR[i] = i;
363
			s->aGammaTableG[i] = i;
364
			s->aGammaTableB[i] = i;
365
		}
366
	}
367
368
	if ( (Model==eHp4400c) || (Model==eHp4470c) ){
369
		DBG(DBG_MSG,"SANE_InitOptions: use HP4x00 mode\n");
370
/*		mode_list[0]="B/W";*/
371
		mode_list[0]="Gray";
372
		mode_list[1]=NULL;
373
		if (OPT_COLOR){
374
			mode_list[1]="Color";
375
			mode_list[2]=NULL;
376
		}
377
	}else
378
	{ /* hp35x0 */
379
		DBG(DBG_MSG,"SANE_InitOptions: use HP35x0 mode\n");
380
		/*	mode_list[0]="B/W";*/
381
		mode_list[0]="Gray"; /**/
382
		mode_list[1]=NULL;
383
		if (OPT_COLOR){
384
			mode_list[1]="Color";
385
			mode_list[2]=NULL;
386
		}
387
	}
388
389
	ccd_list[0]="CCDType 0";
390
	ccd_list[1]="CCDType 1";
391
	ccd_list[2]=NULL;
392
393
	scan_option_list[0]="bed light";
394
	scan_option_list[1]="XPA";
395
	scan_option_list[2]=NULL;
396
397
	for (i = optCount; i < optLast; i++) {
398
399
		pDesc = &s->aOptions[i];
400
		pVal = &s->aValues[i];
401
402
		/* defaults */
403
		pDesc->name   = "";
404
		pDesc->title  = "";
405
		pDesc->desc   = "";
406
		pDesc->type   = SANE_TYPE_INT;
407
		pDesc->unit   = SANE_UNIT_NONE;
408
		pDesc->size   = sizeof(SANE_Word);
409
		pDesc->constraint_type = SANE_CONSTRAINT_NONE;
410
		pDesc->cap    = 0;
411
412
		switch (i) {
413
414
			case optCount:
415
				pDesc->title  = SANE_TITLE_NUM_OPTIONS;
416
				pDesc->desc   = SANE_DESC_NUM_OPTIONS;
417
				pDesc->cap    = SANE_CAP_SOFT_DETECT;
418
				pVal->w       = (SANE_Word)optLast;
419
			break;
420
421
			case optGroupGeometry:
422
				pDesc->title  = "Geometry";
423
				pDesc->type   = SANE_TYPE_GROUP;
424
				pDesc->size   = 0;
425
			break;
426
427
			case optTLX:
428
				pDesc->name   = SANE_NAME_SCAN_TL_X;
429
				pDesc->title  = SANE_TITLE_SCAN_TL_X;
430
				pDesc->desc   = SANE_DESC_SCAN_TL_X;
431
				pDesc->unit   = SANE_UNIT_MM;
432
				pDesc->constraint_type  = SANE_CONSTRAINT_RANGE;
433
				pDesc->cap    = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
434
				pDesc->constraint.range = &rangeXmm;
435
				pVal->w       = rangeXmm.min;
436
			break;
437
438
			case optTLY:
439
				pDesc->name   = SANE_NAME_SCAN_TL_Y;
440
				pDesc->title  = SANE_TITLE_SCAN_TL_Y;
441
				pDesc->desc   = SANE_DESC_SCAN_TL_Y;
442
				pDesc->unit   = SANE_UNIT_MM;
443
				pDesc->constraint_type  = SANE_CONSTRAINT_RANGE;
444
				pDesc->constraint.range = &rangeYmm;
445
				pDesc->cap    = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
446
				pVal->w       = rangeYmm.min;
447
			break;
448
449
			case optBRX:
450
				pDesc->name   = SANE_NAME_SCAN_BR_X;
451
				pDesc->title  = SANE_TITLE_SCAN_BR_X;
452
				pDesc->desc   = SANE_DESC_SCAN_BR_X;
453
				pDesc->unit   = SANE_UNIT_MM;
454
				pDesc->constraint_type  = SANE_CONSTRAINT_RANGE;
455
				pDesc->constraint.range = &rangeXmm;
456
				pDesc->cap    = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
457
				pVal->w       = rangeXmm.max;
458
			break;
459
460
			case optBRY:
461
				pDesc->name   = SANE_NAME_SCAN_BR_Y;
462
				pDesc->title  = SANE_TITLE_SCAN_BR_Y;
463
				pDesc->desc   = SANE_DESC_SCAN_BR_Y;
464
				pDesc->unit   = SANE_UNIT_MM;
465
				pDesc->constraint_type  = SANE_CONSTRAINT_RANGE;
466
				pDesc->constraint.range = &rangeYmm;
467
				pDesc->cap    = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
468
				pVal->w       = rangeYmm.max;
469
			break;
470
471
			case optDPI:
472
				pDesc->name   = SANE_NAME_SCAN_RESOLUTION;
473
				pDesc->title  = SANE_TITLE_SCAN_RESOLUTION;
474
				pDesc->desc   = SANE_DESC_SCAN_RESOLUTION;
475
				pDesc->unit   = SANE_UNIT_DPI;
476
				pDesc->constraint_type  = SANE_CONSTRAINT_WORD_LIST;
477
				pDesc->cap    = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
478
				if ((Model==eHp4400c) || (Model==eHp4470c) ){
479
					if (OPT_T_RES) {
480
						DBG(DBG_MSG,"SANE_InitOptions: use HP4x00 TEST mode \n");
481
						pDesc->constraint.word_list = Hp44x0c_setResolutions_t;
482
						pVal->w       = Hp44x0c_setResolutions_t[1];
483
					} else {
484
						DBG(DBG_MSG,"SANE_InitOptions: use HP4x00 normal mode \n");
485
						pDesc->constraint.word_list = Hp44x0c_setResolutions;
486
						pVal->w       = Hp44x0c_setResolutions[1];
487
					}
488
				}else{ /* it's a HP35xx */
489
					if (OPT_T_RES) {
490
						DBG(DBG_MSG,"SANE_InitOptions: use HP35x0 TEST mode \n");
491
						pDesc->constraint.word_list = Hp35x0c_setResolutions_t;
492
						pVal->w       = Hp35x0c_setResolutions_t[1];
493
					} else {
494
						DBG(DBG_MSG,"SANE_InitOptions: use HP35x0 normal mode \n");
495
						pDesc->constraint.word_list = Hp35x0c_setResolutions;
496
						pVal->w       = Hp35x0c_setResolutions[1];
497
				}
498
				}
499
			break;
500
501
			case optGroupImage:
502
				pDesc->title  = SANE_I18N("Image");
503
				pDesc->type   = SANE_TYPE_GROUP;
504
				pDesc->size   = 0;
505
			break;
506
507
			case optGammaTableRed:
508
				pDesc->name   = SANE_NAME_GAMMA_VECTOR_R;
509
				pDesc->title  = SANE_TITLE_GAMMA_VECTOR_R;
510
				pDesc->desc   = SANE_DESC_GAMMA_VECTOR_R;
511
				pDesc->size   = NUM_GAMMA_ENTRIES * sizeof( SANE_Int );
512
				pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
513
				pDesc->constraint.range = &rangeGammaTable;
514
				pDesc->cap    = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
515
				pVal->wa      = s->aGammaTableR;
516
			break;
517
518
			case optGammaTableGreen:
519
				pDesc->name   = SANE_NAME_GAMMA_VECTOR_G;
520
				pDesc->title  = SANE_TITLE_GAMMA_VECTOR_G;
521
				pDesc->desc   = SANE_DESC_GAMMA_VECTOR_G;
522
				pDesc->size   = NUM_GAMMA_ENTRIES * sizeof( SANE_Int );
523
				pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
524
				pDesc->constraint.range = &rangeGammaTable;
525
				pDesc->cap    = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
526
				pVal->wa      = s->aGammaTableG;
527
			break;
528
529
			case optGammaTableBlue:
530
				pDesc->name   = SANE_NAME_GAMMA_VECTOR_B;
531
				pDesc->title  = SANE_TITLE_GAMMA_VECTOR_B;
532
				pDesc->desc   = SANE_DESC_GAMMA_VECTOR_B;
533
				pDesc->size   = NUM_GAMMA_ENTRIES * sizeof( SANE_Int );
534
				pDesc->constraint_type = SANE_CONSTRAINT_RANGE;
535
				pDesc->constraint.range = &rangeGammaTable;
536
				pDesc->cap    = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
537
				pVal->wa      = s->aGammaTableB;
538
			break;
539
540
			case optGroupMisc:
541
				pDesc->title = SANE_I18N ("Miscellaneous");
542
				pDesc->type  = SANE_TYPE_GROUP;
543
				pDesc->size  = 0;
544
			break;
545
546
			case optBrightness:
547
				pDesc->name   = SANE_NAME_BRIGHTNESS;
548
				pDesc->title  = SANE_TITLE_BRIGHTNESS;
549
				pDesc->desc   = SANE_DESC_BRIGHTNESS;
550
				pDesc->type   = SANE_TYPE_INT;
551
				pDesc->size   = sizeof(SANE_Int);
552
				pDesc->unit   = SANE_UNIT_NONE;
553
				pDesc->constraint_type  = SANE_CONSTRAINT_RANGE;
554
				pDesc->constraint.range = &rangeBrightness;
555
				pDesc->cap    = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
556
				pVal->w       = 10;
557
			break;
558
559
			case OPT_MODE:
560
				pDesc->name   = SANE_NAME_SCAN_MODE;
561
				pDesc->title  = SANE_TITLE_SCAN_MODE;
562
				pDesc->desc   = SANE_DESC_SCAN_MODE;
563
				pDesc->type   = SANE_TYPE_STRING;
564
				pDesc->constraint_type  = SANE_CONSTRAINT_STRING_LIST;
565
				pDesc->size   = _max_string_size (mode_list);
566
				pDesc->constraint.string_list = mode_list;
567
				pVal->s       = strdup (mode_list[0]);
568
				pDesc->cap    = ~SANE_CAP_INACTIVE;
569
			break;
570
571
			case optXPDA:
572
				pDesc->name   = SANE_NAME_SCAN_SOURCE;
573
				pDesc->title  = SANE_TITLE_SCAN_SOURCE;
574
				pDesc->desc   = SANE_I18N("Switches the scaner source mode (normal/xPDA).");
575
				pDesc->type   = SANE_TYPE_STRING;
576
				pDesc->constraint_type  = SANE_CONSTRAINT_STRING_LIST;
577
				pDesc->size   = _max_string_size (scan_option_list);
578
				pDesc->constraint.string_list = scan_option_list;
579
				pVal->s       = strdup (scan_option_list[0]);
580
				if (Model == eHp4470c)
581
					pDesc->cap    = ~SANE_CAP_INACTIVE;
582
				else
583
					pDesc->cap    = SANE_CAP_INACTIVE;
584
				s->ScanParams.optXPA = SANE_FALSE;
585
			break;
586
587
			case optCCD:
588
				pDesc->name   = SANE_NAME_SCAN_SOURCE;
589
				pDesc->title  = "CCD_Type";
590
				pDesc->desc   = SANE_I18N("Switches the scaner CCD mode (0/1).");
591
				pDesc->type   = SANE_TYPE_STRING;
592
				pDesc->constraint_type  = SANE_CONSTRAINT_STRING_LIST;
593
				pDesc->size   = _max_string_size (ccd_list);
594
				pDesc->constraint.string_list = ccd_list;
595
				pVal->s       = strdup (ccd_list[0]);
596
				if ((Model==eHp4400c) || (Model==eHp4470c) ){
597
					if (OPT_CCD){
598
						pDesc->cap    = ~SANE_CAP_INACTIVE;
599
						s->ScanParams.oCCD_Type = 0;
600
					} else
601
						pDesc->cap    = SANE_CAP_INACTIVE;
602
				}else
603
					pDesc->cap    = SANE_CAP_INACTIVE;
604
			break;
605
606
			case optGainR:
607
				pDesc->name   = "optGainR";
608
				pDesc->title  = "optGainR";
609
				pDesc->desc   = SANE_I18N("optGainR");
610
				pDesc->type   = SANE_TYPE_INT;
611
				pDesc->size   = sizeof(SANE_Int);
612
				pDesc->unit   = SANE_UNIT_NONE;
613
				pDesc->constraint_type  = SANE_CONSTRAINT_RANGE;
614
				pDesc->constraint.range = &rangeBrightness;
615
				pDesc->cap    = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
616
				pVal->w       = 0x0a;
617
			break;
618
			case optGainG:
619
				pDesc->name   = "optGainG";
620
				pDesc->title  = "optGainG";
621
				pDesc->desc   = SANE_I18N("optGainG");
622
				pDesc->type   = SANE_TYPE_INT;
623
				pDesc->size   = sizeof(SANE_Int);
624
				pDesc->unit   = SANE_UNIT_NONE;
625
				pDesc->constraint_type  = SANE_CONSTRAINT_RANGE;
626
				pDesc->constraint.range = &rangeBrightness;
627
				pDesc->cap    = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
628
				pVal->w       = 0x0a;
629
			break;
630
			case optGainB:
631
				pDesc->name   = "optGainB";
632
				pDesc->title  = "optGainB";
633
				pDesc->desc   = SANE_I18N("optGainB");
634
				pDesc->type   = SANE_TYPE_INT;
635
				pDesc->size   = sizeof(SANE_Int);
636
				pDesc->unit   = SANE_UNIT_NONE;
637
				pDesc->constraint_type  = SANE_CONSTRAINT_RANGE;
638
				pDesc->constraint.range = &rangeBrightness;
639
				pDesc->cap    = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
640
				pVal->w       = 0x0a;
641
			break;
642
643
			default:
644
				DBG(DBG_ERR, "InitOptions: Uninitialised option %d\n", i);
645
			break;
646
		}
647
	}
648
}
649
650
/****************************************************************************/
651
SANE_Status
652
sane_init(SANE_Int *piVersion, SANE_Auth_Callback pfnAuth)
653
/****************************************************************************/
654
{
655
	SANE_Char line[PATH_MAX];
656
	SANE_Char *word;
657
	SANE_String_Const cp;
658
	SANE_Int linenumber;
659
	FILE *conf_fp;
660
	TScanner *s;
661
662
/* prevent compiler from complaing about unused parameters */
663
	pfnAuth = pfnAuth;
664
	s = malloc (sizeof (TScanner));
665
	if (!s)
666
	{
667
		DBG (DBG_MSG,"sane_init : malloc failed\n");
668
		return SANE_STATUS_NO_MEM;
669
	}
670
671
#ifndef STANDALONE
672
	DBG_INIT();
673
	DBG (DBG_MSG, "SANE HP_RTS88XX USB backend version %d.%d build %d from %s\n", V_MAJOR,
674
		V_MINOR, BUILD, PACKAGE_STRING);
675
#else
676
	DBG (DBG_MSG, "SANE HP_RTS88XX USB backend version %d.%d build %d from \n", V_MAJOR,
677
		V_MINOR, BUILD);
678
#endif
679
680
	iNumSaneDev = 0;
681
	_pFirstSaneDev = 0;
682
683
	/* initialise scanner object */
684
	DBG(DBG_OPT, "Init_Interface: call Hp_rts_XferInit\n");
685
	if ( Hp_rts_XferInit() != SANE_TRUE) {
686
		DBG(DBG_ERR, "Init_Interface: Hp_rts_XferInit failed\n");
687
		/* free scanner object memory */
688
		free ((void *) s);
689
		return SANE_STATUS_IO_ERROR;
690
	}
691
	/* free scanner object memory */
692
	free ((void *) s);
693
	DBG(DBG_OPT, "sane_init: call sanei_config_open\n");
694
	conf_fp = sanei_config_open (HP_RTS_CONFIG_FILE);
695
	if (conf_fp) {
696
		linenumber = 0;
697
		DBG (DBG_OPT, "sane_init: reading config file '%s'\n",HP_RTS_CONFIG_FILE);
698
		while (sanei_config_read (line, sizeof (line), conf_fp)) {
699
			word = 0;
700
			linenumber++;
701
			cp = sanei_config_get_string (line, &word);
702
			/* Discards white lines and comments*/
703
			if (!word || cp == line) {
704
				if (word)
705
					free (word);
706
				continue;
707
			}
708
709
			if (word[0] == '#') {
710
					free (word);
711
					continue;
712
			}
713
			if (strcmp (word, "option") == 0) {
714
				free (word);
715
				word = 0;
716
				cp = sanei_config_get_string (cp, &word);
717
				if (!word) {
718
					DBG (DBG_ERR,
719
						"sane_init: config file line %d: missing quotation mark?\n",
720
						linenumber);
721
					continue;
722
				}
723
				if (strcmp (word, "CCD0") == 0) {
724
					DBG(DBG_OPT,"sane_init: Find option '%s'\n",line);
725
					free (word);
726
					word = 0;
727
					OPT_CCD = SANE_FALSE;
728
					s->ScanParams.oCCD_Type = 0;
729
					continue;
730
				}
731
				if (strcmp (word, "CCD1") == 0) {
732
					DBG(DBG_OPT,"sane_init: Find option '%s'\n",line);
733
					free (word);
734
					word = 0;
735
					OPT_CCD = SANE_FALSE;
736
					s->ScanParams.oCCD_Type = 1;
737
					continue;
738
				}
739
				if (strcmp (word, "ENABLE_COLOR") == 0) {
740
					DBG(DBG_OPT,"sane_init: Find option '%s'\n",line);
741
					free (word);
742
					word = 0;
743
					OPT_COLOR = SANE_TRUE;
744
					continue;
745
				}
746
				if (strcmp (word, "ENABLE_T_RES") == 0) {
747
					DBG(DBG_OPT,"sane_init: Find option '%s'\n",line);
748
					free (word);
749
					word = 0;
750
					OPT_T_RES = SANE_TRUE;
751
					continue;
752
				}
753
			}
754
		}  /*while*/
755
		fclose(conf_fp);
756
	}
757
	else {
758
		DBG (DBG_ERR, "sane_init: Unable to read config file \"%s\": %s\n",
759
		HP_RTS_CONFIG_FILE,strerror(errno));
760
		DBG (DBG_OPT, "sane_init: Using default built-in values\n");
761
	}
762
	if (piVersion != NULL) {
763
		*piVersion = SANE_VERSION_CODE (V_MAJOR, V_MINOR, BUILD);
764
	}
765
	return SANE_STATUS_GOOD;
766
}
767
768
769
/****************************************************************************/
770
void
771
sane_exit(void)
772
/****************************************************************************/
773
{
774
	TDevListEntry *pDev, *pNext;
775
776
	DBG(DBG_MSG, "sane_exit\n");
777
778
	/* free device list memory */
779
	if (_pSaneDevList)
780
	{
781
		for (pDev = _pFirstSaneDev; pDev; pDev = pNext)
782
		{
783
			pNext = pDev->pNext;
784
			free ((void *) pDev->dev.name);
785
			free (pDev);
786
		}
787
		_pFirstSaneDev = 0;
788
		free (_pSaneDevList);
789
		_pSaneDevList = 0;
790
	}
791
}
792
793
/****************************************************************************/
794
SANE_Status
795
sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
796
/****************************************************************************/
797
{
798
	TDevListEntry *pDev;
799
	SANE_Int i;
800
#if 0
801
	DBG (DBG_MSG, "sane_get_devices\n");
802
#endif
803
	local_only = local_only;
804
805
	if (_pSaneDevList)
806
	{
807
		free (_pSaneDevList);
808
	}
809
810
	_pSaneDevList = malloc (sizeof (*_pSaneDevList) * (iNumSaneDev + 1));
811
	if (!_pSaneDevList)
812
	{
813
		DBG (DBG_MSG, "sane_get_devices : no mem\n");
814
		return SANE_STATUS_NO_MEM;
815
	}
816
	i = 0;
817
	for (pDev = _pFirstSaneDev; pDev; pDev = pDev->pNext)
818
	{
819
		_pSaneDevList[i++] = &pDev->dev;
820
		DBG (DBG_MSG, "sane_get_devices: name %s\n",pDev->dev.name);
821
	}
822
	_pSaneDevList[i++] = 0;	/* last entry is 0 */
823
824
	 *device_list = _pSaneDevList;
825
826
	return SANE_STATUS_GOOD;
827
}
828
829
/****************************************************************************/
830
SANE_Status
831
sane_open(SANE_String_Const name, SANE_Handle *h)
832
/****************************************************************************/
833
{
834
	TScanner *s;
835
836
	DBG(DBG_MSG, "sane_open: %s\n", name);
837
838
	s = malloc (sizeof (TScanner));
839
	if (!s)
840
	{
841
		DBG (DBG_MSG,"sane_open : malloc failed\n");
842
		return SANE_STATUS_NO_MEM;
843
	}
844
	*h = s;
845
846
	s->HWParams.iXferHandle = Hp_rts_XferOpen (name,(EScannerModel *) &s->HWParams.ScannerModel);
847
#if 0
848
	DBG (DBG_MSG, "sane_open: s->HWParams.ScannerModel = %d\n",s->HWParams.ScannerModel);
849
#endif
850
	if (s->HWParams.iXferHandle < 0)
851
	{
852
		DBG (DBG_ERR, "sane_open: Hp_rts_XferOpen failed for '%s'\n", name);
853
		return SANE_STATUS_DEVICE_BUSY;
854
	}
855
856
	/* initialise scanner object */
857
#if 1 /* only for test, normaly 1 */
858
	s->HWParams.lamp_warm = SANE_FALSE;
859
#else
860
	s->HWParams.lamp_warm = SANE_TRUE; /*only for test */
861
#endif
862
	s->fScanning = SANE_FALSE;
863
  s->fCanceled = SANE_FALSE;
864
865
	s->aGammaTableR = NULL;
866
	s->aGammaTableG = NULL;
867
	s->aGammaTableB = NULL;
868
869
	if (_Init_Interface(&s->HWParams,&s->ScanParams) == SANE_STATUS_GOOD) {
870
		SANE_InitOptions((TScanner *)s);
871
	}
872
	else{
873
		DBG (DBG_ERR, "sane_open: _Init_Interface failed\n");
874
		s->HWParams.iXferHandle = -1;
875
		return SANE_STATUS_IO_ERROR;
876
	}
877
	return SANE_STATUS_GOOD;
878
}
879
880
881
/****************************************************************************/
882
void
883
sane_close(SANE_Handle h)
884
/****************************************************************************/
885
{
886
	TScanner *s;
887
888
	DBG(DBG_MSG, "sane_close\n");
889
	s = (TScanner *)h;
890
	/* close scanner */
891
	_Close_Interface(&s->HWParams);
892
	#ifdef DEBUG_FILE
893
	if ( s->ScanParams.DebugOpen ){
894
		fclose(s->ScanParams.FD_r);
895
		s->ScanParams.DebugOpen = SANE_FALSE;
896
	}
897
	#endif
898
	if ( s->aGammaTableR != NULL ){
899
		free(s->aGammaTableR);
900
		s->aGammaTableR = NULL;}
901
	if ( s->aGammaTableG != NULL ){
902
		free(s->aGammaTableG);
903
		s->aGammaTableG = NULL;}
904
	if ( s->aGammaTableB != NULL ){
905
		free(s->aGammaTableB);
906
		s->aGammaTableB = NULL;}
907
908
	/* free scanner object memory */
909
	free ((void *) s);
910
}
911
912
913
/****************************************************************************/
914
const SANE_Option_Descriptor *
915
sane_get_option_descriptor(SANE_Handle h, SANE_Int n)
916
/****************************************************************************/
917
{
918
	TScanner *s;
919
920
	DBG(DBG_OPT, "sane_get_option_descriptor %d\n", n);
921
	if ((n < optCount) || (n >= optLast)) {
922
		return NULL;
923
	}
924
	s = (TScanner *)h;
925
	return &s->aOptions[n];
926
}
927
928
929
/****************************************************************************/
930
SANE_Status
931
sane_control_option(SANE_Handle h, SANE_Int option, SANE_Action Action, void *pVal,
932
										SANE_Int *pInfo)
933
/****************************************************************************/
934
{
935
	TScanner    *s;
936
	SANE_Int    info;
937
	SANE_Status status;
938
939
	DBG(DBG_OPT,"sane_control_option: option %d, action %d\n", option, Action);
940
	s = (TScanner *)h;
941
	info = 0;
942
943
	if (option < 0 || option >= optLast)
944
		return SANE_STATUS_INVAL;
945
946
	if (pInfo != NULL)
947
		*pInfo = 0;
948
949
	/*************************************************/
950
	switch (Action) {
951
	/*************************************************/
952
		case SANE_ACTION_GET_VALUE:
953
			switch (option) {
954
955
				/* Get options of type SANE_Word */
956
				case optCount: case optDPI:
957
				case optTLX: case optTLY: case optBRX: case optBRY:
958
				case optBrightness: case optGainR: case optGainG: case optGainB:
959
					DBG(DBG_OPT,"sane_control_option: SANE_ACTION_GET_VALUE %d = %d\n", option,
960
							(SANE_Int)s->aValues[option].w);
961
					*(SANE_Word*)pVal = s->aValues[option].w;
962
				break;
963
964
				/* Get options of type SANE_Word array */
965
				case optGammaTableRed: case optGammaTableGreen: case optGammaTableBlue:
966
					DBG(DBG_OPT, "Reading gamma table\n");
967
					memcpy (pVal, s->aValues[option].wa, s->aOptions[option].size);
968
				break;
969
970
				/* Get options of type SANE_TYPE STRING */
971
				case OPT_MODE: case optXPDA: case optCCD:
972
					DBG(DBG_OPT,"sane_control_option: SANE_ACTION_GET_VALUE %s\n",s->aValues[option].s);
973
					status = sanei_constrain_value (s->aOptions + option, s->aValues[option].s,
974
										(SANE_Int *)info);
975
					strcpy ((char *)pVal, s->aValues[option].s);
976
					return SANE_STATUS_GOOD;
977
				break;
978
979
				default: ;
980
					DBG(DBG_ERR,"SANE_ACTION_GET_VALUE: Invalid option (%d)\n", option);
981
				break;
982
			}
983
		break;
984
		case SANE_ACTION_SET_VALUE:
985
			/* no changes while in mid-pass! */
986
			if (s->fScanning){
987
				DBG(DBG_ERR,"sane_control_option: SANE_ACTION_SET_VALUE not allowed during scan\n");
988
				return SANE_STATUS_DEVICE_BUSY;
989
			}
990
			status = sanei_constrain_value (s->aOptions + option, pVal, pInfo);
991
			if (status != SANE_STATUS_GOOD)
992
				return status;
993
			switch (option) {
994
995
				/* Set options of type SANE_Word */
996
				case optCount:
997
					return SANE_STATUS_INVAL;
998
				break;
999
1000
				case optDPI: case optTLX: case optTLY: case optBRX: case optBRY:
1001
				case optBrightness: case optGainR: case optGainG: case optGainB:
1002
					DBG(DBG_OPT,"sane_control_option: SANE_ACTION_SET_VALUE %d to %d\n",
1003
						option,*(SANE_Word *) pVal);
1004
					info |= SANE_INFO_RELOAD_PARAMS;
1005
					s->aValues[option].w = *(SANE_Word *) pVal;
1006
				break;
1007
1008
				/* Get options of type SANE_Word array */
1009
				case optGammaTableRed: case optGammaTableGreen: case optGammaTableBlue:
1010
					DBG(DBG_OPT, "Writing gamma table\n");
1011
					memcpy (s->aValues[option].wa, pVal, s->aOptions[option].size);
1012
				break;
1013
1014
				/* Set options of type SANE_TYPE_STRING */
1015
				case OPT_MODE: case optXPDA: case optCCD:
1016
					DBG(DBG_OPT,"sane_control_option: SANE_ACTION_SET_String %d to %s\n",
1017
							option,(char *)pVal);
1018
					if (s->aValues[option].s)
1019
						free (s->aValues[option].s);
1020
					s->aValues[option].s = strdup (pVal);
1021
					if (info)
1022
						info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
1023
				break;
1024
1025
				default: ;
1026
					DBG(DBG_ERR,"SANE_ACTION_SET_VALUE: Invalid option (%d)\n", option);
1027
					return SANE_STATUS_INVAL;
1028
			} /* switch option */
1029
			if (pInfo != NULL) {
1030
				*pInfo = info;
1031
			}
1032
			break; /*case SANE_ACTION_SET_VALUE*/
1033
		case SANE_ACTION_SET_AUTO:
1034
			return SANE_STATUS_UNSUPPORTED;
1035
		default: ;
1036
			DBG(DBG_ERR,"sane_control_option: Invalid action (%d)\n", Action);
1037
			return SANE_STATUS_INVAL;
1038
	}
1039
	return SANE_STATUS_GOOD;
1040
}
1041
1042
1043
/****************************************************************************/
1044
SANE_Status
1045
sane_get_parameters(SANE_Handle h, SANE_Parameters *p)
1046
/****************************************************************************/
1047
{
1048
	TScanner *s;
1049
	SANE_String val;
1050
1051
	s = (TScanner *)h;
1052
	val = s->aValues[OPT_MODE].s;
1053
1054
	/* first do some checks */
1055
	if (s->aValues[optTLX].w >= s->aValues[optBRX].w) {
1056
		DBG(DBG_ERR,"sane_get_parameters: TLX should be smaller than BRX\n");
1057
		s->aValues[optTLX].w = s->aValues[optBRX].w; /* new 17.06.03 JoHu */
1058
		/* return SANE_STATUS_INVAL; / proper error code? */
1059
	}
1060
	if (s->aValues[optTLY].w >= s->aValues[optBRY].w) {
1061
		DBG(DBG_ERR,"sane_get_parameters: TLY should be smaller than BRY\n");
1062
		s->aValues[optTLY].w = s->aValues[optBRY].w; /* new 17.06.03 JoHu */
1063
		/* return SANE_STATUS_INVAL; / proper error code? */
1064
	}
1065
1066
	/* return the data */
1067
	p->last_frame = SANE_TRUE;
1068
	s->ScanParams.brightness = s->aValues[optBrightness].w;
1069
	s->ScanParams.GainR = s->aValues[optGainR].w;
1070
	s->ScanParams.GainG = s->aValues[optGainG].w;
1071
	s->ScanParams.GainB = s->aValues[optGainB].w;
1072
	p->depth = 8;
1073
1074
	if (!strcmp (s->aValues[optXPDA].s, "XPA")){
1075
		s->ScanParams.optXPA = SANE_TRUE;
1076
		DBG(DBG_MSG,"sane_get_parameters: set XPA to TRUE\n");
1077
	}else{
1078
		s->ScanParams.optXPA = SANE_FALSE;
1079
		DBG(DBG_MSG,"sane_get_parameters: set XPA to FALSE\n");
1080
	}
1081
1082
	if (s->aOptions[optCCD].cap != SANE_CAP_INACTIVE){
1083
		if (!strcmp (s->aValues[optCCD].s, "CCDType 0")){
1084
			s->ScanParams.oCCD_Type = 0;
1085
			DBG(DBG_MSG,"sane_get_parameters: set CCD to 0\n");
1086
		}
1087
		if (!strcmp (s->aValues[optCCD].s, "CCDType 1")){
1088
			s->ScanParams.oCCD_Type = 1;
1089
			DBG(DBG_MSG,"sane_get_parameters: set CCD to 1\n");
1090
		}
1091
	}
1092
1093
	if (!strcmp (val, "Color")){
1094
		s->ScanParams.mode = COLOR;
1095
		DBG(DBG_MSG,"sane_get_parameters: switch to color 24 bit!\n");
1096
		p->format = SANE_FRAME_RGB;
1097
	}else{
1098
		if (!strcmp (val, "B/W")){
1099
			DBG(DBG_MSG,"sane_get_parameters:  switch to B/W 8 bit\n");
1100
			s->ScanParams.mode = BLACK_WHITE;
1101
			p->format = SANE_FRAME_GRAY;
1102
			p->depth = 1;
1103
		} else {
1104
			DBG(DBG_MSG,"sane_get_parameters:  switch to gray 8 bit\n");
1105
			s->ScanParams.mode = GRAY;
1106
			p->format = SANE_FRAME_GRAY;
1107
		}
1108
	}
1109
	p->lines = MM_TO_PIXEL(s->aValues[optBRY].w - s->aValues[optTLY].w,
1110
													s->aValues[optDPI].w);
1111
	p->pixels_per_line = MM_TO_PIXEL(s->aValues[optBRX].w - s->aValues[optTLX].w,
1112
													s->aValues[optDPI].w);
1113
	p->bytes_per_line = p->pixels_per_line;
1114
	/* fill in the scanparams using the option values */
1115
	s->ScanParams.iLinesLeft = p->lines;
1116
	s->ScanParams.iDpi = s->aValues[optDPI].w;
1117
	s->ScanParams.iLpi = s->aValues[optDPI].w;
1118
	s->ScanParams.iWidth = p->pixels_per_line;
1119
	s->ScanParams.iLenght = p->lines;
1120
	s->ScanParams.fCalib = SANE_FALSE;
1121
1122
	switch (s->ScanParams.iDpi) {
1123
		case 150:
1124
			s->ScanParams.iY =
1125
				MM_TO_PIXEL(s->aValues[optTLY].w + s->HWParams.iTopLeftY, 150);
1126
			s->ScanParams.iX =
1127
				MM_TO_PIXEL(s->aValues[optTLX].w + s->HWParams.iTopLeftX, 150);
1128
		break;
1129
		case 300:
1130
			s->ScanParams.iY =
1131
				MM_TO_PIXEL(s->aValues[optTLY].w + s->HWParams.iTopLeftY, 300);
1132
			s->ScanParams.iX =
1133
				MM_TO_PIXEL(s->aValues[optTLX].w + s->HWParams.iTopLeftX, 300);
1134
		break;
1135
		case 600:
1136
			s->ScanParams.iY =
1137
				MM_TO_PIXEL(s->aValues[optTLY].w + s->HWParams.iTopLeftY, 600);
1138
			s->ScanParams.iX =
1139
				MM_TO_PIXEL(s->aValues[optTLX].w + (s->HWParams.iTopLeftX / 2), 600);
1140
		break;
1141
		default:
1142
		DBG(DBG_MSG,"sane_get_parameters: invalid resolution !");
1143
		return SANE_STATUS_INVAL;
1144
	}
1145
	if (s->ScanParams.mode == COLOR)
1146
		p->bytes_per_line = p->bytes_per_line * 3;
1147
1148
	/* init data pipe */
1149
	s->DataPipe.iBytesLeft = 0;
1150
	s->DataPipe.iScanned   = 0;
1151
	s->DataPipe.iLinesLeft = p->lines;
1152
	s->DataPipe.iLinesInCircBuf = 1;
1153
	DBG(DBG_MSG,
1154
		"sane_get_parameters: lpi %3d; dpi %3d; p->lines %3d; p->pixels_per_line %3d; p->bytes_per_line %3d; Mode %x\n",
1155
		s->ScanParams.iLpi,s->ScanParams.iDpi,p->lines,
1156
		p->pixels_per_line,p->bytes_per_line,
1157
		s->ScanParams.mode);
1158
	return SANE_STATUS_GOOD;
1159
}
1160
1161
1162
/****************************************************************************/
1163
SANE_Status
1164
sane_start(SANE_Handle h)
1165
/****************************************************************************/
1166
{
1167
	TScanner             *s;
1168
	SANE_Parameters      par;
1169
	SANE_Int             pabLineBufSize;
1170
	SANE_Status          State;
1171
1172
	DBG(DBG_MSG,"sane_start\n");
1173
	s = (TScanner *)h;
1174
1175
	if (sane_get_parameters(h, &par) != SANE_STATUS_GOOD) {
1176
		DBG(DBG_MSG," sane_get_parameters,invalid scan parameters\n");
1177
		return SANE_STATUS_INVAL;
1178
	}
1179
	#ifdef DEBUG_FILE
1180
		s->ScanParams.DebugOpen = SANE_FALSE;
1181
		s->ScanParams.DebugSeek0 = SANE_FALSE;
1182
	#endif
1183
1184
	DBG(DBG_MSG,"sane_start: optDPI=%d optTLY=%dmm, optTLX=%dmm, optBRX=%dmm, optBRY=%dmm.\n",
1185
		s->aValues[optDPI].w,
1186
		s->aValues[optTLY].w,
1187
		s->aValues[optTLX].w,
1188
		s->aValues[optBRX].w,
1189
		s->aValues[optBRY].w);
1190
1191
	DBG(DBG_MSG,"sane_start: iDpi=%d iLpi=%d iY=%dpix. iX=%dpix. iWidth=%dpix iLenght=%dpix. mode=0x%x brightness=0x%x\n",
1192
		s->ScanParams.iDpi,      /* horizontal resolution */
1193
		s->ScanParams.iLpi,       /* vertical resolution */
1194
		s->ScanParams.iY,         /* in HW coordsane_readinates */
1195
		s->ScanParams.iX,         /* in HW coordinates */
1196
		s->ScanParams.iWidth,     /* pixels per line*/
1197
		s->ScanParams.iLenght,    /* Pixel lines */
1198
		s->ScanParams.mode,
1199
		s->ScanParams.brightness);
1200
1201
	/* hack */
1202
	pabLineBufSize = par.bytes_per_line * 3;
1203
	DBG(DBG_MSG,"sane_start: pabLineBufSize=%d\n",pabLineBufSize);
1204
	s->DataPipe.pabLineBuf = (SANE_Byte *)malloc(pabLineBufSize);
1205
1206
	s->DataPipe.iZeroLines = 0;
1207
1208
	/* copy gamma table */
1209
	Hp_rts_WriteGammaCalibTable (s->HWParams.iXferHandle, s->aGammaTableR,
1210
			s->aGammaTableG, s->aGammaTableB);
1211
1212
	/* prepare and start the actual scan */
1213
	State = Hp_rts_CircBufferInit( h, &s->DataPipe, par.bytes_per_line,
1214
						s->ScanParams.iWidth, s->ScanParams.mode);
1215
	if ( State == SANE_STATUS_GOOD ){
1216
		State = _InitScan(&s->ScanParams, &s->HWParams, &s->DataPipe);
1217
		if ( !State ) {
1218
/*		if ( State != SANE_STATUS_GOOD ) {*/
1219
			DBG(DBG_MSG,"sane_start: InitScan, invalid scan parameters\n");
1220
			return SANE_STATUS_IO_ERROR;
1221
		}
1222
		s->fScanning = SANE_TRUE;
1223
		return SANE_STATUS_GOOD;
1224
	}
1225
	s->fScanning = SANE_FALSE;
1226
	return State;
1227
}
1228
1229
1230
/****************************************************************************/
1231
SANE_Status
1232
sane_read(SANE_Handle h, SANE_Byte *buf, SANE_Int maxlen, SANE_Int *len)
1233
/* buf have the lenght maxlen; len returns the lenght of the retuned bytes  */
1234
/****************************************************************************/
1235
{
1236
	TScanner  *s;
1237
	TDataPipe *p;
1238
1239
	s = (TScanner *)h;
1240
1241
	DBG(DBG_SCAN,"sane_read: starts here\n");
1242
	/* sane_read only allowed after sane_start */
1243
	if (!s->fScanning) {
1244
		DBG(DBG_ERR," sane_read: sane_read only allowed after sane_start\n");
1245
		return SANE_STATUS_EOF;
1246
	}
1247
1248
	p = &s->DataPipe;
1249
1250
	/* anything left to read? */
1251
	if ((s->ScanParams.iLinesLeft == 0) && (p->iBytesLeft == 0)) {
1252
		DBG(DBG_SCAN," sane_read: end of scan\n");
1253
		_FinishScan(s);
1254
		*len = 0;
1255
		s->fScanning = SANE_FALSE;
1256
		Hp_rts_CircBufferExit( h );
1257
		if (p->pabLineBuf != NULL){
1258
			free(p->pabLineBuf);
1259
			p->pabLineBuf = NULL;
1260
		}
1261
		#ifdef DEBUG_FILE
1262
		if ( s->ScanParams.DebugOpen ){
1263
			fclose(s->ScanParams.FD_r);
1264
			s->ScanParams.DebugOpen = SANE_FALSE;
1265
		}
1266
		#endif
1267
		return SANE_STATUS_EOF;
1268
	}
1269
1270
	/* time to read the next line? */
1271
	*len = 0;
1272
	if (p->iBytesLeft == 0) {
1273
		if (Hp_rts_CircBufferGetLine(h, p, p->pabLineBuf,s->ScanParams.mode)){
1274
			p->iBytesLeft = p->iBytesPerLine;
1275
			s->ScanParams.iLinesLeft--;
1276
			DBG(DBG_SCAN," sane_read: p->iBytesLeft=%3d s->ScanParams.iLinesLeft=%3d\n",
1277
				p->iBytesLeft,s->ScanParams.iLinesLeft);
1278
		}else
1279
		{ /* no data read from the pipe ! */
1280
			s->DataPipe.iZeroLines = s->DataPipe.iZeroLines +1;
1281
			DBG(DBG_SCAN," sane_read: no bytes read from CircBuffer\n");
1282
			if (s->DataPipe.iZeroLines <10){
1283
				*len = 0;
1284
				return SANE_STATUS_GOOD;
1285
			}else /* time over */
1286
			{
1287
				*len = 0;
1288
				return SANE_STATUS_IO_ERROR;
1289
			}
1290
		}
1291
		/* copy (part of) a line */
1292
		*len = MIN(maxlen, p->iBytesLeft);
1293
		memcpy(buf, &p->pabLineBuf[p->iBytesPerLine - p->iBytesLeft], *len);
1294
		p->iBytesLeft -= *len;
1295
	}
1296
1297
	DBG(DBG_SCAN," sane_read: read %d bytes; maxlen = %d\n", *len,maxlen);
1298
	return SANE_STATUS_GOOD;
1299
}
1300
1301
1302
/****************************************************************************/
1303
void
1304
sane_cancel(SANE_Handle h)
1305
/****************************************************************************/
1306
{
1307
	TScanner *s;
1308
1309
	DBG(DBG_MSG,"sane_cancel\n");
1310
	s = (TScanner *)h;
1311
1312
	/* Make sure the scanner head returns home */
1313
	_FinishScan(s);
1314
	Hp_rts_CircBufferExit( h );
1315
	if (s->DataPipe.pabLineBuf != NULL){
1316
		free(s->DataPipe.pabLineBuf);
1317
		s->DataPipe.pabLineBuf = NULL;
1318
	}
1319
	#ifdef DEBUG_FILE
1320
	if ( s->ScanParams.DebugOpen ){
1321
		fclose(s->ScanParams.FD_r);
1322
		s->ScanParams.DebugOpen = SANE_FALSE;
1323
	}
1324
	#endif
1325
	s->fCanceled = SANE_TRUE;
1326
	s->fScanning = SANE_FALSE;
1327
}
1328
1329
1330
/****************************************************************************/
1331
SANE_Status
1332
sane_set_io_mode(SANE_Handle h, SANE_Bool m)
1333
/****************************************************************************/
1334
{
1335
	DBG(DBG_MSG, "sane_set_io_mode: %s\n", m ? "non-blocking" : "blocking");
1336
	/* prevent compiler from complaining about unused parameters */
1337
	h = h;
1338
1339
	if (m) {
1340
		return SANE_STATUS_UNSUPPORTED;
1341
	}
1342
	return SANE_STATUS_GOOD;
1343
}
1344
1345
1346
/****************************************************************************/
1347
SANE_Status
1348
sane_get_select_fd(SANE_Handle h, SANE_Int *fd)
1349
/****************************************************************************/
1350
{
1351
	DBG(DBG_MSG, "sane_select_fd\n");
1352
	/* prevent compiler from complaining about unused parameters */
1353
	h = h;
1354
	fd = fd;
1355
	return SANE_STATUS_UNSUPPORTED;
1356
}
1357
1358
1359
#ifdef STANDALONE
1360
/****************************************************************************/
1361
/****************************************************************************/
1362
/****************************************************************************/
1363
/****************************************************************************/
1364
/****************************************************************************/
1365
1366
typedef void (*rts8801_callback)(	void	*param,
1367
					unsigned bytes,
1368
					void	*data);
1369
1370
/****************************************************************************/
1371
void
1372
main_UsageError()
1373
/****************************************************************************/
1374
{
1375
	fprintf(stderr,	"SANE HP_RTS88XX  x y width height resolution filename\n"
1376
			"	x, y, width, height: in pixels\n"
1377
			"	resolution: 1200/600/300/200/150/75\n");
1378
	exit(1);
1379
}
1380
1381
1382
/****************************************************************************/
1383
int
1384
main (int argc, char *argv[])
1385
/****************************************************************************/
1386
{
1387
	TScanner *s;
1388
	/*SANE_String_Const name;*/
1389
	SANE_Int piVersion;
1390
	unsigned	x, y, w, h;
1391
	SANE_Word	resolution;
1392
	char const *	filename;
1393
	FILE		*fp;
1394
	int		result = 1;
1395
	int		multiplier;
1396
	/*int	depth;
1397
	SANE_Int i;*/
1398
	SANE_Auth_Callback pfnAuth;
1399
	const SANE_Device **device_list;
1400
	SANE_Bool local;
1401
	SANE_Handle device;
1402
	SANE_Status status;
1403
	SANE_Int num_dev_options;
1404
	SANE_Int info;
1405
	SANE_Byte *buf;
1406
	/*SANE_Int maxlen;*/
1407
	SANE_Int len;
1408
1409
	DBG (DBG_MSG, "SANE HP_RTS88XX USB test version\n");
1410
1411
	if (argc != 7)
1412
		main_UsageError();
1413
1414
	x = atoi(argv[1]);
1415
	y = atoi(argv[2]);
1416
	w = atoi(argv[3]);
1417
	h = atoi(argv[4]);
1418
	resolution = atoi(argv[5]);
1419
	filename = argv[6];
1420
1421
	switch (resolution)
1422
	{
1423
	case 1200:
1424
	case 600:
1425
	case 400:
1426
	case 300:
1427
	case 200:
1428
	case 150:
1429
	case 100:
1430
	case 75:
1431
	case 50:
1432
	case 25:
1433
		break;
1434
1435
	default:
1436
		fprintf(stderr, "Invalid resolution: %s\n", argv[5]);
1437
		return 1;
1438
	}
1439
1440
	multiplier = 1200 / resolution;
1441
	if ((y + h) * multiplier > 16800)
1442
	{
1443
		fprintf(stderr, "Scan parameters take the image past the bottom of the scanner\n");
1444
		return 1;
1445
	}
1446
	if ((x + w) * multiplier > 10451)
1447
	{
1448
		fprintf(stderr, "Scan parameters take the image past the right hand side of the scanner\n");
1449
		return 1;
1450
	}
1451
	if (!x || !y || !w || !h)
1452
	{
1453
		fprintf(stderr, "None of the co-ordinates may be zero\n");
1454
		return 1;
1455
	}
1456
	if (y * multiplier < 600)
1457
	{
1458
		fprintf(stderr, "Warning: at this resolution 'y' values under %d are in the pre-scan area\n",
1459
				599 / multiplier + 1);
1460
	}
1461
	if (x * multiplier < 251)
1462
	{
1463
		fprintf(stderr, "Warning: at this resolution, 'x' values under %d are left of the scan area\n",
1464
			250 / multiplier + 1);
1465
	}
1466
1467
  s = malloc (sizeof (TScanner));
1468
  if (!s)
1469
    {
1470
      DBG (DBG_MSG,"main : malloc for s failed\n");
1471
      return SANE_STATUS_NO_MEM;
1472
    }
1473
  buf = malloc (5000);
1474
  if (!buf)
1475
    {
1476
      DBG (DBG_MSG,"main : malloc buf failed\n");
1477
      return SANE_STATUS_NO_MEM;
1478
    }
1479
1480
	if (sane_init(&piVersion,pfnAuth) != SANE_STATUS_GOOD)
1481
	{
1482
		fprintf(stderr, "Could not initialise scanner\n");
1483
		/* free scanner object memory */
1484
		free ((void *) s);
1485
		exit(1);
1486
	}
1487
	local = SANE_TRUE;
1488
	if (sane_get_devices (&device_list, local) != SANE_STATUS_GOOD)
1489
	{
1490
		fprintf(stderr, "Could not sane_get_devices\n");
1491
		/* free scanner object memory */
1492
		free ((void *) s);
1493
		exit(1);
1494
	}
1495
1496
	status = sane_open ("libusb:001:002", &device);
1497
	if (status != SANE_STATUS_GOOD)
1498
	{
1499
		fprintf(stderr, "Could not sane_open\n");
1500
		/* free scanner object memory */
1501
		free ((void *) s);
1502
		exit(1);
1503
	}
1504
1505
	/* Get the number of options. */
1506
	status = sane_control_option (device, 0, SANE_ACTION_GET_VALUE, &num_dev_options, 0);
1507
	if (status != SANE_STATUS_GOOD)
1508
	{
1509
		fprintf(stderr, "Could not read sane_control_option\n");
1510
		/* free scanner object memory */
1511
		free ((void *) s);
1512
		exit(1);
1513
	}
1514
1515
/*SANE_Word:
1516
	case optDPI: case optTLX: case optTLY: case optBRX: case optBRY:
1517
	case optBrightness: case optGainR: case optGainG: case optGainB:
1518
SANE_TYPE_STRING
1519
	case OPT_MODE: case optXPDA: case optCCD:
1520
*/
1521
	status = sane_control_option (device,optDPI, SANE_ACTION_SET_VALUE,
1522
								  &resolution, &info);
1523
	status = sane_control_option (device,optTLX, SANE_ACTION_SET_VALUE,
1524
								  &x, &info);
1525
	status = sane_control_option (device,optBRX, SANE_ACTION_SET_VALUE,
1526
								  &w, &info);
1527
	status = sane_control_option (device,optTLY, SANE_ACTION_SET_VALUE,
1528
								  &y, &info);
1529
	status = sane_control_option (device,optBRY, SANE_ACTION_SET_VALUE,
1530
								  &h, &info);
1531
#if 0
1532
	free ((void *) s);
1533
	exit(1);
1534
#endif
1535
	s = (TScanner *)device;
1536
1537
	/* TScanParams */
1538
	s->ScanParams.brightness = 10;
1539
	s->ScanParams.mode = 1;         /* B/W = 0; grayscale = 1 color = 2 */
1540
	s->ScanParams.optXPA = 0;       /* 0=normal; 1 = XPA */
1541
	s->ScanParams.oCCD_Type = 0;    /* 0/1 */
1542
1543
	fprintf(stdout, "Will open file %s\n",filename);
1544
	fp = fopen(filename, "w");
1545
1546
	if (fp)
1547
	{
1548
		fprintf(fp, "P6\n%d %d\n255\n", w, h);
1549
1550
		switch (s->HWParams.ScannerModel)
1551
		{
1552
			case eHp3500c: case eHp3530c: case eHp3570c:
1553
				if (Hp35x0c_init_scan(&s->HWParams, &s->ScanParams, &s->DataPipe))
1554
					;
1555
				else result = 1;
1556
				break;
1557
1558
			case eHp4400c: case eHp4470c:
1559
				if (Hp44x0_init_scan(&s->HWParams, &s->ScanParams, &s->DataPipe))
1560
				{
1561
					if (Hp44x0_start_scan(&s->HWParams, &s->ScanParams, &s->DataPipe))
1562
					{
1563
						s->fScanning = SANE_TRUE;
1564
					}
1565
				} /* if */
1566
1567
				break;
1568
			default:
1569
				fprintf(stderr, "Wrong scanner model\n");
1570
				result = 1;
1571
		}
1572
	}
1573
	else
1574
	{
1575
		perror(filename);
1576
	}
1577
1578
	if (s->fScanning == SANE_TRUE)
1579
	{
1580
		while ( s->fScanning == SANE_FALSE )
1581
		{
1582
			status = sane_read(device, (SANE_Byte *)buf, 5000, &len);
1583
/*			status = sane_read(device, &buf, 5000, &len);*/
1584
			/* buf have the lenght maxlen; len returns the lenght of the retuned bytes  */
1585
		}
1586
	}
1587
	/* free scanner object memory */
1588
	free ((void *) s);
1589
	return result;
1590
}
1591
1592
#endif
1593
1594
(-)sane-backends-1.0.19/backend/hp_rts88xx.conf (+20 lines)
Line 0 Link Here
1
# hp_rts88xx.conf: Configuration file for HP35x00C and HP44x0 USB scanners
2
# Read man sane-hp_rts88xx.man for documentation
3
4
# ALL:
5
# If autodetection doesn't work uncomment or add your device file
6
#/dev/usbscanner
7
8
# HP44x0C option_CCD
9
# CCD0 or CCD1 allowed
10
# if you receive a black image, change it to CCD1
11
#option CCD0
12
13
# HP44x0C option_color
14
# none or ENABLE_COLOR allowed
15
# allow the color mode
16
#option ENABLE_COLOR
17
18
# HP35x00C/HP44x0C enable all resolutions
19
# !!!!! only for test and development !!!!! 
20
#option ENABLE_T_RES
(-)sane-backends-1.0.19/backend/hp_rts88xx.h (+242 lines)
Line 0 Link Here
1
 /* sane - Scanner Access Now Easy.
2
   Copyright (C) 2003 Johannes Hub (JohannesHub@t-online.de)
3
4
   This file was initially copied from the hp3300 backend.
5
   This file is part of the SANE package.
6
7
   This program is free software; you can redistribute it and/or
8
   modify it under the terms of the GNU General Public License
9
   as published by the Free Software Foundation; either version 2
10
   of the License, or (at your option) any later version.
11
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21
   As a special exception, the authors of SANE give permission for
22
   additional uses of the libraries contained in this release of SANE.
23
24
   The exception is that, if you link a SANE library with other files
25
   to produce an exutable, this does not by itself cause the
26
   resulting executable to be covered by the GNU General Public
27
   License.  Your use of that executable is in no way restricted on
28
   account of linking the SANE library code into it.
29
30
   This exception does not, however, invalidate any other reasons why
31
   the executable file might be covered by the GNU General Public
32
   License.
33
34
   If you submit changes to SANE to the maintainers to be included in
35
   a subsequent release, you agree by submitting the changes that
36
   those changes may be distributed with this exception intact.
37
38
   If you write modifications of your own for SANE, it is your choice
39
   whether to permit this exception to apply to your modifications.
40
   If you do not wish that, delete this exception notice.
41
*/
42
43
/*
44
    Concept for a backend for scanners based on the RTS88xx chipset,
45
    such as HP4400C, HP4470C, HP3500C, 3530C, and HP ScanJet 3570C.
46
    Parts of this source were inspired by other backends.
47
48
		History:
49
50
		Version 0.18  21.11.04 13.alpha,
51
				- source sorted,
52
				- now only SANEI_USB_SUPPORT for a better overview(xfermodules removed)
53
				- read and verify the MainBoardID 
54
		Version 0.17p 02.11.04 12.alpha, source sorted, little fixes, SANEI_USB_SUPPORT implemented
55
		Version 0.17p 02.11.04 12.alpha, source sourted, little fixes, SANEI_USB_SUPPORT implemented
56
		Version 0.17b 30.03.04 10.alpha, little fixes and libusb implemented
57
		Version 0.17  09.03.04 9. alpha, HP3500 included
58
		Version 0.16  06.02.04 8. alpha, wait counting on LCD
59
		Version 0.15a 29.01.04 7. alpha, CCD switch moved to config file
60
		Version 0.15  11.01.04 6. alpha, a second CCD implemented
61
		Version 0.13a 21.11.04 4. alpha, an little fix included
62
		Version 0.12  22.10.03 third alpha, Backend name changed to HP_RTS88xx
63
		Version 0.11  30.08.03 second alpha
64
		Version 0.10  19.07.03 first alpha
65
*/
66
67
/*
68
		Provides a simple interface to read and write data from the scanner,
69
		without any knowledge whether it's a parallel or USB scanner
70
71
		enable DEDUG output:
72
		use a nomal shell (konsole) and type
73
		export SANE_DEBUG_HP_RTS88XX=32
74
		export XSANE_DEBUG=100
75
		xsane
76
*/
77
78
#ifndef _HP_RTS88xx_H_
79
#define _HP_RTS88xx_H_
80
81
82
#define MM_TO_PIXEL(_mm_, _dpi_)    ((_mm_) * (_dpi_) / 25.4)
83
#define PIXEL_TO_MM(_pixel_, _dpi_) ((_pixel_) * 25.4 / (_dpi_))
84
#define ENABLE(OPTION)  s->opt[OPTION].cap &= ~SANE_CAP_INACTIVE
85
#define DISABLE(OPTION) s->opt[OPTION].cap |=  SANE_CAP_INACTIVE
86
#define IS_ACTIVE(OPTION) (((s->opt[OPTION].cap) & SANE_CAP_INACTIVE) == 0)
87
#define NUM_GAMMA_ENTRIES  65536
88
89
#define	RTS8801_GREYSCALE	1
90
#define	RTS8801_COLOUR		2
91
#define	RTS8801_BW		0
92
93
typedef enum
94
	{
95
		BLACK_WHITE = 0,
96
		GRAY,       /*1*/
97
		COLOR       /*2*/
98
	}
99
BACKEND_MODE;
100
101
/* options enumerator */
102
typedef enum {
103
	optCount = 0,
104
105
	optGroupGeometry,
106
		optTLX, optTLY, optBRX, optBRY,
107
		optDPI,
108
		optGroupImage,
109
		optGammaTableRed,		/* Gamma Tables */
110
		optGammaTableGreen,
111
		optGammaTableBlue,
112
	optGroupMisc,
113
		OPT_MODE,
114
		optXPDA,
115
		optCCD,
116
		optBrightness,
117
		optGainR,
118
		optGainG,
119
		optGainB,
120
	optLast
121
} EOptionIndex;
122
123
124
typedef union {
125
	SANE_Word w;
126
	SANE_Word *wa;     /* word array */
127
	SANE_String s;
128
} TOptionValue;
129
130
131
typedef struct {
132
	SANE_Int		iDpi;         /* horizontal resolution */
133
	SANE_Int		iLpi;         /* vertical resolution */
134
	SANE_Int		iY;           /* iTop in HW coordinates */
135
	SANE_Int		iX;           /* iLeft in HW coordinates */
136
	SANE_Int		iWidth;       /* pixels per line */
137
	SANE_Int		iLenght;      /* iHeight pixel lines */
138
	SANE_Int		iSkipLines;   /* Steps to pos. for scann */
139
	SANE_Int		iLinesLeft;   /* Lines witch left over to scan */
140
	SANE_Int		fCalib;       /* if TRUE, disable backtracking? */
141
	SANE_Int		brightness;
142
	SANE_Int		mode;         /* B/W = 0; grayscale = 1 color = 2 */
143
	SANE_Int		optXPA;       /* 0=normal; 1 = XPA */
144
	SANE_Int		oCCD_Type;    /* 0/1 */
145
	SANE_Int		GainR;
146
	SANE_Int		GainG;
147
	SANE_Int		GainB;
148
	#ifdef		DEBUG_FILE
149
	FILE			*FD_r;            /* rgb  test pnm file*/
150
	SANE_Int		DebugOpen;
151
	SANE_Int		DebugSeek0;
152
	#endif
153
} TScanParams;
154
155
156
typedef struct {
157
	/* transfer buffer */
158
	SANE_Byte		*pabXferBuf;
159
	SANE_Int		iCurLine, iBytesPerLine, iLinesPerXferBuf;
160
	SANE_Int		iLastLine;
161
	SANE_Int		iScanned;     /* Lines witch have scanned */
162
	SANE_Int		iLinesLeft;   /* Lines witch left over to scan */
163
	/* circular buffer */
164
	SANE_Byte		*pabCircBuf;
165
	SANE_Int		iLinesPerCircBuf;
166
	SANE_Int		iLinesInCircBuf;
167
	SANE_Int		iMisAlignment;
168
	SANE_Int		iRedLine, iGrnLine, iBluLine;
169
	/* current line buffer */
170
	SANE_Byte		*pabLineBuf;
171
	SANE_Int		iBytesLeft;
172
173
	SANE_Int		iZeroLines;
174
} TDataPipe;
175
176
177
typedef struct {
178
/*	EScannerModel		ScannerModel;*/
179
	SANE_Int		ScannerModel;
180
	SANE_Int		iXferHandle;    /* handle used for data transfer to HW */
181
	SANE_Int		iTopLeftX;      /* in mm */
182
	SANE_Int		iTopLeftY;      /* in mm */
183
	SANE_Int		iMainBoardID;   /*  */
184
	SANE_Bool		iReversedHead;  /* Head is reversed */
185
	SANE_Bool		lamp_warm;      /* TRUE = the lamp is warm */
186
	SANE_Byte		regs[0xff];
187
} THWParams;
188
189
190
typedef struct {
191
	SANE_Option_Descriptor	aOptions[optLast];
192
	TOptionValue						aValues[optLast];
193
194
	TScanParams						ScanParams;
195
	THWParams						HWParams;
196
	TDataPipe						DataPipe;
197
198
	SANE_Int						*aGammaTableR;	/* a 16-to-16 bit color lookup table */
199
	SANE_Int						*aGammaTableG;	/* a 16-to-16 bit color lookup table */
200
	SANE_Int						*aGammaTableB;	/* a 16-to-16 bit color lookup table */
201
202
	SANE_Bool						fScanning;    /* TRUE if actively scanning */
203
	SANE_Bool						fCanceled;
204
} TScanner;
205
206
207
/* option constraints */
208
static SANE_Bool OPT_CCD				=	SANE_TRUE;
209
static SANE_Bool OPT_COLOR				=	SANE_FALSE;
210
static SANE_Bool OPT_T_RES				=	SANE_FALSE;
211
static const SANE_Range	rangeGammaTable			=	{0,65535,1};
212
static const SANE_Int	Hp44x0c_setResolutions[]	=	{1,300};
213
static const SANE_Int	Hp44x0c_setResolutions_t[]	=	{2,300,600};
214
static const SANE_Int	Hp35x0c_setResolutions[]	=	{1,150};
215
static const SANE_Int	Hp35x0c_setResolutions_t[]	=	{3,150,300,600};
216
217
#ifndef WITH_TSTBACKEND
218
static const SANE_Range rangeXmm       = {0, 220, 1}; /* max. mm */
219
static const SANE_Range rangeYmm       = {0, 295, 1}; /* max. mm */
220
#endif
221
#ifdef WITH_TSTBACKEND
222
static const SANE_Range rangeXmm       = {0, 70, 1}; /* max. mm */
223
static const SANE_Range rangeYmm       = {0, 70, 1}; /* max. mm */
224
#endif
225
static const SANE_Range rangeBrightness     = {0, 20, 1};
226
/*static const SANE_Range rangeBrightness     = {0, 0x40, 1};*/
227
#if 0
228
static const SANE_Range rangeLampBrightness = {0xa1, 0xaf, 1};
229
#endif
230
231
static SANE_String_Const mode_list[5];
232
static SANE_String_Const scan_option_list[3];
233
static SANE_String_Const ccd_list[3];
234
235
/* Device filename for USB access */
236
SANE_Char * usb_devfile = "/dev/usb/scanner0";
237
238
SANE_Status _Init_Interface(THWParams *pHWParams, TScanParams *pParams);
239
void _Close_Interface(THWParams *pHWParams);
240
SANE_Bool _InitScan  (TScanParams *pParams,THWParams *pHWParams, TDataPipe *pDataPipe);
241
SANE_Bool _FinishScan     (SANE_Handle h);
242
#endif
(-)sane-backends-1.0.19/backend/hp_rts_35x0c.c (+1421 lines)
Line 0 Link Here
1
 /* sane - Scanner Access Now Easy.
2
   Copyright (C) 2003 Johannes Hub (JohannesHub@t-online.de)
3
4
   This file was initially copied from the hp3300 backend.
5
   This file is part of the SANE package.
6
7
   This program is free software; you can redistribute it and/or
8
   modify it under the terms of the GNU General Public License
9
   as published by the Free Software Foundation; either version 2
10
   of the License, or (at your option) any later version.
11
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21
   As a special exception, the authors of SANE give permission for
22
   additional uses of the libraries contained in this release of SANE.
23
24
   The exception is that, if you link a SANE library with other files
25
   to produce an exutable, this does not by itself cause the
26
   resulting executable to be covered by the GNU General Public
27
   License.  Your use of that executable is in no way restricted on
28
   account of linking the SANE library code into it.
29
30
   This exception does not, however, invalidate any other reasons why
31
   the executable file might be covered by the GNU General Public
32
   License.
33
34
   If you submit changes to SANE to the maintainers to be included in
35
   a subsequent release, you agree by submitting the changes that
36
   those changes may be distributed with this exception intact.
37
38
   If you write modifications of your own for SANE, it is your choice
39
   whether to permit this exception to apply to your modifications.
40
   If you do not wish that, delete this exception notice.
41
*/
42
43
/*
44
    Concept for a backend for scanners based on the RTS88xx chipset,
45
    such as HP3500C, 3530C, and HP ScanJet 3570C.
46
    Parts of this source were inspired by other backends.
47
48
		History:
49
50
		Version 0.18  21.11.04 13.alpha,
51
				- source sorted,
52
				- now only SANEI_USB_SUPPORT for a better overview(xfermodules removed)
53
				- read and verify the MainBoardID 
54
		Version 0.17p 02.11.04 12.alpha, source sorted, little fixes, SANEI_USB_SUPPORT implemented
55
		Version 0.17p 02.11.04 12.alpha, source sourted, little fixes, SANEI_USB_SUPPORT implemented
56
		Version 0.17b 30.03.04 10.alpha, little fixes and libusb implemented
57
		Version 0.17  09.03.04 9. alpha, HP3500 included
58
		Version 0.16  06.02.04 8. alpha, wait counting on LCD
59
		Version 0.15a 29.01.04 7. alpha, CCD switch moved to config file
60
		Version 0.15  11.01.04 6. alpha, a second CCD implemented
61
		Version 0.13a 21.11.04 4. alpha, an little fix included
62
		Version 0.12  22.10.03 third alpha, Backend name changed to HP_RTS88xx
63
		Version 0.11  30.08.03 second alpha
64
		Version 0.10  19.07.03 first alpha
65
*/
66
67
/*
68
    Core HP35x0c functions.
69
*/
70
71
#include <stdio.h>  /* fopen, fread, fwrite, fclose etc */
72
#include <stdarg.h> /* va_list for vfprintf */
73
#include <string.h> /* memcpy, memset */
74
#include <unistd.h> /* unlink */
75
#include <stdlib.h> /* malloc, free */
76
#include <math.h>   /* exp, pow */
77
#include <ctype.h>
78
79
#include "hp_rts_xfer.h"
80
#include "hp_rts_44x0c.h"
81
#include "hp_rts_35x0c.h"
82
83
static SANE_Byte sram_access_method = 0;
84
static SANE_Word sram_size = 0;
85
86
/****************************************************************************/
87
SANE_Int
88
Hp35x0c_queue_read_register( SANE_Int iHandle, SANE_Byte reg, SANE_Int bytes, SANE_Byte *data)
89
/****************************************************************************/
90
{
91
	if (bytes == 1)
92
		return ( Hp_rts_RegRead(iHandle,reg, data));
93
	else
94
		return ( Hp_rts_BulkRead( iHandle, reg, data, bytes, SANE_TRUE) );
95
  }
96
97
/****************************************************************************/
98
SANE_Int
99
Hp35x0c_read_register_immediate( SANE_Int iHandle, SANE_Int reg, SANE_Int bytes, SANE_Byte *data)
100
/****************************************************************************/
101
{
102
	if (bytes == 1)
103
		return ( Hp_rts_RegRead(iHandle,reg, data) );
104
	else
105
		return ( Hp_rts_BulkRead( iHandle, reg, data, bytes, SANE_TRUE) );
106
}
107
108
/****************************************************************************
109
SANE_Int
110
Hp35x0c_queue_set_register( SANE_Int iHandle, SANE_Int reg, SANE_Int bytes, void *data)
111
****************************************************************************
112
{
113
	if (bytes == 1)
114
		return( Hp_rts_RegWrite (iHandle, reg, data));
115
	else
116
		return( Hp_rts_BulkWrite(iHandle, reg, data, bytes, SANE_TRUE));
117
}*/
118
119
/****************************************************************************/
120
SANE_Int
121
Hp35x0c_set_register_immediate( SANE_Int iHandle, SANE_Int reg, SANE_Int bytes, SANE_Byte *data)
122
/****************************************************************************/
123
{
124
	if (reg < 0xb3 && reg + bytes > 0xb3)
125
	{
126
		SANE_Int	bytes_in_first_block = 0xb3 - reg;
127
128
		if (Hp35x0c_set_register_immediate(iHandle, reg, bytes_in_first_block, data) < 0 ||
129
		    Hp35x0c_set_register_immediate(iHandle, 0xb4, bytes - bytes_in_first_block - 1,
130
							data + bytes_in_first_block + 1) < 0)
131
			return -1;
132
		return 0;
133
	}
134
	if (bytes == 1){
135
		return( Hp_rts_RegWrite (iHandle, reg, *data));
136
	}else
137
		return( Hp_rts_BulkWrite(iHandle, reg, (SANE_Byte *)data, bytes, SANE_TRUE));
138
}
139
140
141
/****************************************************************************/
142
SANE_Int
143
Hp35x0c_send_command_immediate( SANE_Int iHandle, SANE_Int command,
144
/****************************************************************************/
145
				SANE_Byte	reg,
146
				SANE_Int	count,
147
				SANE_Int	bytes,
148
				SANE_Byte	*data,
149
				SANE_Int	readbytes,
150
				SANE_Byte	*readdata)
151
{
152
	callibration_buffer[0] = command;
153
	callibration_buffer[1] = reg;
154
	callibration_buffer[2] = count >> 8;
155
	callibration_buffer[3] = count;
156
	memcpy(callibration_buffer + 4, data, bytes);
157
	Hp_rts_BulkWrite(iHandle, 0,callibration_buffer, bytes+4, SANE_FALSE);
158
	if (readbytes)
159
	{
160
		return(Hp_rts_BulkRead(iHandle, 0,readdata,readbytes,SANE_FALSE));
161
	}
162
	return( 0 );
163
}
164
165
166
/****************************************************************************/
167
SANE_Int
168
Hp35x0c_write_sram( SANE_Int iHandle, SANE_Word	bytes, SANE_Byte	*data)
169
/****************************************************************************/
170
{
171
	callibration_buffer[0] = RTCMD_WRITESRAM;
172
	callibration_buffer[1] = 0x00;
173
	callibration_buffer[2] = bytes >> 8;
174
	callibration_buffer[3] = bytes;
175
	memcpy(callibration_buffer + 4, data, bytes);
176
	return( Hp_rts_BulkWrite(iHandle, 0,
177
		callibration_buffer, bytes+4, SANE_FALSE));
178
}
179
180
/****************************************************************************/
181
SANE_Int
182
Hp35x0c_read_sram( SANE_Int iHandle, SANE_Int	bytes, SANE_Byte *data)
183
/****************************************************************************/
184
{
185
	return Hp35x0c_send_command_immediate(iHandle,RTCMD_READSRAM, 0, bytes, 0, 0, bytes, data);
186
}
187
188
/****************************************************************************/
189
SANE_Int
190
Hp35x0c_set_sram_page( SANE_Int iHandle, SANE_Byte	page)
191
/****************************************************************************/
192
{
193
	return(Hp_rts_Set_double_reg(iHandle,0x91,  page, page >> 8));
194
}
195
196
/****************************************************************************/
197
SANE_Int
198
Hp35x0c_detect_sram( SANE_Int iHandle, SANE_Word *totalbytes, SANE_Byte *r93setting)
199
/****************************************************************************/
200
{
201
	SANE_Byte	data[0x818];
202
	SANE_Byte	testbuf[0x818];
203
	SANE_Int	i;
204
	SANE_Int	test_values[] = { 6, 2, 1, -1 };
205
206
	for (i = 0; i < (SANE_Int)sizeof(data); ++i)
207
		data[i] = i % 0x61;
208
209
210
	for (i = 0; test_values[i] != -1; ++i)
211
	{
212
		if (Hp_rts_RegWrite(iHandle,0x93, test_values[i]) ||
213
			Hp35x0c_set_sram_page(iHandle,0x81) ||
214
			Hp35x0c_write_sram(iHandle,0x818, data) ||
215
			Hp35x0c_set_sram_page(iHandle,0x81) ||
216
			Hp_rts_Read_Sram (iHandle, testbuf,0x818) )
217
			return -1;
218
		if (!memcmp(testbuf, data, 0x818))
219
		{
220
			sram_access_method = test_values[i];
221
			if (r93setting)
222
				*r93setting = sram_access_method;
223
			break;
224
		}
225
	}
226
	if (!sram_access_method)
227
		return -1;
228
229
	for (i = 0; i < 16; ++i)
230
	{
231
		SANE_Int	j;
232
		SANE_Byte	write_data[32];
233
		SANE_Byte	read_data[32];
234
		SANE_Int	pagesetting;
235
236
		for (j = 0; j < 16; j++)
237
		{
238
			write_data[j * 2] = j * 2;
239
			write_data[j * 2 + 1] = i;
240
		}
241
242
		pagesetting = i * 4096;
243
244
		if (Hp35x0c_set_sram_page(iHandle,pagesetting) < 0||
245
		    Hp35x0c_write_sram(iHandle,32, write_data) < 0)
246
			return -1;
247
		if (i)
248
		{
249
			if (Hp35x0c_set_sram_page(iHandle,0) < 0 ||
250
			    Hp35x0c_read_sram(iHandle,32, read_data) < 0)
251
				return -1;
252
			if (!memcmp(read_data, write_data, 32))
253
			{
254
				sram_size = i * 0x20000;
255
				if (totalbytes)
256
					*totalbytes = sram_size;
257
				return 0;
258
			}
259
		}
260
		return -1;
261
	}
262
	return -1;
263
}
264
265
/****************************************************************************/
266
SANE_Int
267
Hp35x0c_is_rewound( SANE_Int iHandle )
268
/****************************************************************************/
269
{
270
	SANE_Byte	r;
271
272
	if (Hp35x0c_read_register_immediate( iHandle, 0x1d, 1, &r) < 0)
273
		return -1;
274
	if (r & 0x02)
275
		return 1;
276
	return 0;
277
}
278
279
/****************************************************************************/
280
SANE_Int
281
Hp35x0c_set_direction_forwards(SANE_Byte *regs)
282
/****************************************************************************/
283
{
284
	regs[0xc6] |= 0x08;
285
	return 0;
286
}
287
288
/****************************************************************************/
289
SANE_Int
290
Hp35x0c_set_direction_rewind(SANE_Byte *regs)
291
/****************************************************************************/
292
{
293
	regs[0xc6] &= 0xf7;
294
	return 0;
295
}
296
297
/****************************************************************************/
298
SANE_Int
299
Hp35x0c_set_stop_when_rewound( SANE_Byte *regs, SANE_Int	stop)
300
/****************************************************************************/
301
{
302
	if (stop)
303
		regs[0xb2] |= 0x10;
304
	else
305
		regs[0xb2] &= 0xef;
306
	return 0;
307
}
308
309
/****************************************************************************/
310
SANE_Int
311
Hp35x0c_set_distances( SANE_Int iHandle,SANE_Int location1,
312
		   SANE_Int location2)
313
/****************************************************************************/
314
{
315
	SANE_Byte	regbuffer[4];
316
317
	regbuffer[0] = location1;
318
	regbuffer[1] = location1 >> 8;
319
	regbuffer[2] = location2;
320
	regbuffer[3] = location2 >> 8;
321
	return Hp35x0c_set_register_immediate(iHandle,REG_DESTINATION_POSITION, 4, regbuffer);
322
}
323
324
/****************************************************************************/
325
SANE_Int
326
Hp35x0c_set_powersave_mode( SANE_Int iHandle,SANE_Int enable)
327
/****************************************************************************/
328
{
329
	SANE_Byte r;
330
331
	if (Hp35x0c_read_register_immediate(iHandle,REG_MOVE_CONTROL_TEST, 1, &r) < 0)
332
		return -1;
333
	if (r & 0x04)
334
	{
335
		if (enable == 1)
336
			return 0;
337
		r &= ~0x04;
338
	}
339
	else
340
	{
341
		if (enable == 0)
342
			return 0;
343
		r |= 0x04;
344
	}
345
	if (Hp_rts_RegWrite(iHandle,REG_MOVE_CONTROL_TEST, r) < 0 ||
346
	    Hp_rts_RegWrite(iHandle,REG_MOVE_CONTROL_TEST, r) < 0)
347
		return -1;
348
	return 0;
349
}
350
351
/****************************************************************************/
352
SANE_Int
353
Hp35x0c_lamp_ready( SANE_Int iHandle )
354
/****************************************************************************/
355
{
356
	SANE_Byte r;
357
358
	if (Hp35x0c_read_register_immediate(iHandle,0xd1, 1, &r) < 0)
359
		return -1;
360
	if (r & 0x40)
361
		return 0;
362
	return 1;
363
}
364
365
/****************************************************************************/
366
SANE_Int
367
Hp35x0c_turn_off_lamp( SANE_Int iHandle )
368
/****************************************************************************/
369
{
370
	return Hp_rts_RegWrite(iHandle,0x3a, 0);
371
}
372
373
/****************************************************************************/
374
SANE_Int
375
Hp35x0c_turn_on_lamp( SANE_Int iHandle )
376
/****************************************************************************/
377
{
378
	SANE_Byte r3a;
379
	SANE_Byte r10;
380
	SANE_Byte r58;
381
382
	if (Hp35x0c_read_register_immediate(iHandle,0x3a, 1, &r3a) < 0 ||
383
		Hp35x0c_read_register_immediate(iHandle,0x10, 1, &r10) < 0 ||
384
		Hp35x0c_read_register_immediate(iHandle,0x58, 1, &r58) < 0)
385
		return -1;
386
	r3a |= 0x80;
387
	r10 |= 0x01;
388
	r58 &= 0x0f;
389
	if (Hp_rts_RegWrite(iHandle,0x3a, r3a) < 0 ||
390
		Hp_rts_RegWrite(iHandle,0x10, r10) < 0 ||
391
		Hp_rts_RegWrite(iHandle,0x58, r58) < 0)
392
		return -1;
393
	return 0;
394
}
395
396
/****************************************************************************/
397
/****************************************************************************/
398
#if 0
399
static SANE_Int
400
Hp35x0c_set_value_msbfirst(	SANE_Byte	*regs,
401
			SANE_Int		firstreg,
402
			SANE_Int		totalregs,
403
			SANE_Word	value)
404
/****************************************************************************/
405
{
406
	while (totalregs--)
407
	{
408
		regs[firstreg + totalregs] = value & 0xff;
409
		value >>= 8;
410
	}
411
	return 0;
412
}
413
#endif
414
/****************************************************************************/
415
SANE_Int
416
Hp35x0c_set_ccd_shift_clock_multiplier(	SANE_Byte	*regs,
417
					SANE_Word	value)
418
/****************************************************************************/
419
{
420
	return Hp_rts_set_value_lsbfirst(regs, 0xf0, 3, value);
421
}
422
423
/****************************************************************************/
424
SANE_Int
425
Hp35x0c_set_ccd_sample_clock_multiplier(	SANE_Byte	*regs,
426
					SANE_Word	value)
427
/****************************************************************************/
428
{
429
	return Hp_rts_set_value_lsbfirst(regs, 0xf6, 3, value);
430
}
431
432
/****************************************************************************/
433
SANE_Int
434
Hp35x0c_set_ccd_clock_reset_interval(	SANE_Byte	*regs,
435
					SANE_Word	value)
436
/****************************************************************************/
437
{
438
	return Hp_rts_set_value_lsbfirst(regs, 0xf9, 3, value);
439
}
440
441
/****************************************************************************/
442
SANE_Int
443
Hp35x0c_set_ccd_clamp_clock_multiplier(	SANE_Byte	*regs,
444
					SANE_Word	value)
445
/****************************************************************************/
446
{
447
	return Hp_rts_set_value_lsbfirst(regs, 0xfc, 3, value);
448
}
449
450
/****************************************************************************/
451
SANE_Int
452
Hp35x0c_set_movement_pattern(		SANE_Byte	*regs,
453
					SANE_Word	value)
454
/****************************************************************************/
455
{
456
	return Hp_rts_set_value_lsbfirst(regs, 0xc0, 3, value);
457
}
458
459
/****************************************************************************/
460
SANE_Int
461
Hp35x0c_set_motor_movement_clock_multiplier(	SANE_Byte	*regs,
462
					SANE_Word	value)
463
/****************************************************************************/
464
{
465
	regs[0x40] = (regs[0x40] & ~0xc0) | (value << 6);
466
	return 0;
467
}
468
469
/****************************************************************************/
470
SANE_Int
471
Hp35x0c_set_motor_type(			SANE_Byte	*regs,
472
					SANE_Word	value)
473
/****************************************************************************/
474
{
475
	regs[0xc9] = (regs[0xc9] & 0xf8) | (value & 0x7);
476
	return 0;
477
}
478
479
/****************************************************************************/
480
SANE_Int
481
Hp35x0c_set_basic_calibration(		SANE_Byte *regs,
482
/****************************************************************************/
483
					SANE_Int	redoffset1,
484
					SANE_Int	redoffset2,
485
					SANE_Int	redgain,
486
					SANE_Int	greenoffset1,
487
					SANE_Int	greenoffset2,
488
					SANE_Int	greengain,
489
					SANE_Int	blueoffset1,
490
					SANE_Int	blueoffset2,
491
					SANE_Int	bluegain)
492
{
493
	regs[0x05] = redoffset1;
494
	regs[0x02] = redoffset2;
495
	regs[0x08] = redgain;
496
	regs[0x06] = greenoffset1;
497
	regs[0x03] = greenoffset2;
498
	regs[0x09] = greengain;
499
	regs[0x07] = blueoffset1;
500
	regs[0x04] = blueoffset2;
501
	regs[0x0a] = bluegain;
502
	return 0;
503
}
504
505
/****************************************************************************/
506
SANE_Int
507
Hp35x0c_set_calibration_addresses(		SANE_Byte *regs,
508
/****************************************************************************/
509
					SANE_Word	redaddr,
510
					SANE_Word	blueaddr,
511
					SANE_Word	greenaddr)
512
{
513
	regs[0x84] = redaddr;
514
	regs[0x8e] = (regs[0x8e] * 0x0f) | ((redaddr >> 4) & 0xf0);
515
	Hp_rts_set_value_lsbfirst(regs, 0x85, 2, blueaddr);
516
	Hp_rts_set_value_lsbfirst(regs, 0x87, 2, greenaddr);
517
	return 0;
518
}
519
520
/****************************************************************************/
521
SANE_Int
522
Hp35x0c_set_lamp_duty_cycle(			SANE_Byte *regs,
523
/****************************************************************************/
524
					SANE_Int	enable,
525
					SANE_Int	frequency,
526
					SANE_Int	offduty)
527
{
528
	if (enable)
529
		regs[0x3b] |= 0x80;
530
	else
531
		regs[0x3b] &= 0x7f;
532
533
	regs[0x3b] = (regs[0x3b] & 0x80) | ((frequency & 0x7) << 4) | (offduty & 0x0f);
534
	regs[0x3d] = (regs[0x3d] & 0x7f) | ((frequency & 0x8) << 4);
535
	return 0;
536
}
537
538
/****************************************************************************/
539
SANE_Int
540
Hp35x0c_set_data_feed_on(			SANE_Byte *regs)
541
/****************************************************************************/
542
{
543
	regs[0xb2] &= ~0x04;
544
	return 0;
545
}
546
547
/****************************************************************************/
548
SANE_Int
549
Hp35x0c_set_data_feed_off(			SANE_Byte *regs)
550
/****************************************************************************/
551
{
552
	regs[0xb2] |= 0x04;
553
	return 0;
554
}
555
556
/****************************************************************************/
557
SANE_Int
558
Hp35x0c_enable_ccd(				SANE_Byte *regs,
559
/****************************************************************************/
560
					SANE_Int enable)
561
{
562
	if (enable)
563
		regs[0x00] &= ~0x10;
564
	else
565
		regs[0x00] |= 0x10;
566
	return 0;
567
}
568
569
/****************************************************************************/
570
SANE_Int
571
Hp35x0c_set_cdss(				SANE_Byte *regs,
572
/****************************************************************************/
573
					SANE_Int	val1,
574
					SANE_Int	val2)
575
{
576
	regs[0x28] = (regs[0x28] & 0xe0) | (val1 & 0x1f);
577
	regs[0x2a] = (regs[0x2a] & 0xe0) | (val2 & 0x1f);
578
	return 0;
579
}
580
581
/****************************************************************************/
582
SANE_Int
583
Hp35x0c_set_cdsc(				SANE_Byte *regs,
584
/****************************************************************************/
585
					SANE_Int	val1,
586
					SANE_Int	val2)
587
{
588
	regs[0x29] = (regs[0x29] & 0xe0) | (val1 & 0x1f);
589
	regs[0x2b] = (regs[0x2b] & 0xe0) | (val2 & 0x1f);
590
	return 0;
591
}
592
593
/****************************************************************************/
594
SANE_Int
595
Hp35x0c_update_after_setting_cdss2(		SANE_Byte *regs)
596
/****************************************************************************/
597
{
598
	SANE_Int	fullcolour = (!(regs[0x2f] & 0xc0) && (regs[0x2f] & 0x04));
599
	SANE_Int value = regs[0x2a] & 0x1f;
600
601
	regs[0x2a] = (regs[0x2a] & 0xe0) | (value & 0x1f);
602
603
	if (fullcolour)
604
		value *= 3;
605
	if ((regs[0x40] & 0xc0) == 0x40)
606
		value += 17;
607
	else
608
		value += 16;
609
610
	regs[0x2c] = (regs[0x2c] & 0xe0) | (value  % 24);
611
	regs[0x2d] = (regs[0x2d] & 0xe0) | ((value + 2) % 24);
612
	return 0;
613
}
614
615
/****************************************************************************/
616
SANE_Int
617
Hp35x0c_set_cph0s(				SANE_Byte *regs,
618
/****************************************************************************/
619
					SANE_Int	on)
620
{
621
	if (on)
622
		regs[0x2d] |= 0x20;	/* 1200dpi horizontal coordinate space */
623
	else
624
		regs[0x2d] &= ~0x20;	/* 600dpi horizontal coordinate space */
625
	return 0;
626
}
627
628
/****************************************************************************/
629
SANE_Int
630
Hp35x0c_set_cvtr_lm(				SANE_Byte *regs,
631
/****************************************************************************/
632
					SANE_Int	val1,
633
					SANE_Int	val2,
634
					SANE_Int	val3)
635
{
636
	regs[0x28] = (regs[0x28] & ~0xe0) | (val1 << 5);
637
	regs[0x29] = (regs[0x29] & ~0xe0) | (val2 << 5);
638
	regs[0x2a] = (regs[0x2a] & ~0xe0) | (val3 << 5);
639
	return 0;
640
}
641
642
/****************************************************************************/
643
SANE_Int
644
Hp35x0c_set_cvtr_mpt(			SANE_Byte *regs,
645
/****************************************************************************/
646
					SANE_Int	val1,
647
					SANE_Int	val2,
648
					SANE_Int	val3)
649
{
650
	regs[0x3c] = (val1 & 0x0f) | (val2 << 4);
651
	regs[0x3d] = (regs[0x3d] & 0xf0) | (val3 & 0x0f);
652
	return 0;
653
}
654
655
/****************************************************************************/
656
SANE_Int
657
Hp35x0c_set_cvtr_wparams(			SANE_Byte *regs,
658
/****************************************************************************/
659
					SANE_Word fpw,
660
					SANE_Word bpw,
661
					SANE_Word w)
662
{
663
	regs[0x31] = (w & 0x0f) | ((bpw << 4) & 0x30) | (fpw << 6);
664
	return 0;
665
}
666
667
/****************************************************************************/
668
SANE_Int
669
Hp35x0c_enable_movement(			SANE_Byte *regs,
670
/****************************************************************************/
671
					SANE_Int	enable)
672
{
673
	if (enable)
674
		regs[0xc3] |= 0x80;
675
	else
676
		regs[0xc3] &= ~0x80;
677
	return 0;
678
}
679
680
/****************************************************************************/
681
SANE_Int
682
Hp35x0c_set_scan_frequency(			SANE_Byte *regs,
683
/****************************************************************************/
684
					SANE_Int	frequency)
685
{
686
	regs[0x64] = (regs[0x64] & 0xf0) | (frequency & 0x0f);
687
	return 0;
688
}
689
690
/****************************************************************************/
691
SANE_Int
692
Hp35x0c_set_merge_channels(			SANE_Byte *regs,
693
/****************************************************************************/
694
					SANE_Int	on)
695
{
696
	DBG( DBG_MSG , "start_scan: Hp35x0c_set_merge_channels\n");
697
	regs[0x2f] &= ~0x14;
698
	regs[0x2f] |= on ? 0x04 : 0x10;
699
#ifdef DEBUG
700
	Hp_rts_DumpBits(0x2f, regs[0x2f]);
701
#endif
702
	return 0;
703
}
704
705
/****************************************************************************/
706
SANE_Int
707
Hp35x0c_set_channel(				SANE_Byte *regs,
708
/****************************************************************************/
709
					SANE_Int	channel)
710
{
711
	DBG( DBG_MSG , "start_scan: Hp35x0c_set_channel %d\n",channel);
712
	regs[0x2f] = (regs[0x2f] & ~0xc0) | (channel << 6);
713
#ifdef DEBUG
714
	Hp_rts_DumpBits(0x2f, regs[0x2f]);
715
#endif
716
	return 0;
717
}
718
719
/****************************************************************************/
720
SANE_Int
721
Hp35x0c_set_single_channel_scanning(		SANE_Byte *regs,
722
/****************************************************************************/
723
					SANE_Int	on)
724
{
725
	if (on){
726
		regs[0x2f] |= 0x20;
727
		DBG( DBG_MSG , "start_scan: Hp35x0c_set_single_channel_scanning on\n");
728
	}else{
729
		regs[0x2f] &= ~0x20;
730
		DBG( DBG_MSG , "start_scan: Hp35x0c_set_single_channel_scanning off\n");
731
	}
732
#ifdef DEBUG
733
	Hp_rts_DumpBits(0x2f, regs[0x2f]);
734
#endif
735
	return 0;
736
}
737
738
/****************************************************************************/
739
SANE_Int
740
Hp35x0c_set_colour_mode(			SANE_Byte *regs,
741
/****************************************************************************/
742
					SANE_Int	on)
743
{
744
	if (on){
745
		DBG( DBG_MSG , "start_scan: Set register to color mode\n");
746
		regs[0x2f] |= 0x02;
747
	}else{
748
		DBG( DBG_MSG , "start_scan: Set register to gray mode\n");
749
		regs[0x2f] &= ~0x02;
750
	}
751
#ifdef DEBUG
752
	Hp_rts_DumpBits(0x2f, regs[0x2f]);
753
#endif
754
	return 0;
755
}
756
757
/****************************************************************************/
758
SANE_Int
759
Hp35x0c_set_horizontal_resolution(		SANE_Byte *regs,
760
/****************************************************************************/
761
					SANE_Int	resolution)
762
{
763
	if (regs[0x2d] & 0x20)
764
		regs[0x7a] = 1200 / resolution;
765
	else
766
		regs[0x7a] = 600 / resolution;
767
	return 0;
768
}
769
770
/****************************************************************************/
771
SANE_Int
772
Hp35x0c_set_last_sram_page(			SANE_Byte *regs,
773
/****************************************************************************/
774
					SANE_Int	pagenum)
775
{
776
	Hp_rts_set_value_lsbfirst(regs, 0x8b, 2, pagenum);
777
	return 0;
778
}
779
780
/****************************************************************************/
781
SANE_Int
782
Hp35x0c_set_step_size(			SANE_Byte *regs,
783
/****************************************************************************/
784
					SANE_Int	stepsize)
785
{
786
	Hp_rts_set_value_lsbfirst(regs, 0xe2, 2, stepsize);
787
	Hp_rts_set_value_lsbfirst(regs, 0xe0, 2, 0);
788
	return 0;
789
}
790
791
/****************************************************************************/
792
SANE_Int
793
Hp35x0c_set_all_registers( SANE_Int iHandle, void const *regs_)
794
/****************************************************************************/
795
{
796
	SANE_Byte	regs[255];
797
798
	memcpy(regs, regs_, 255);
799
	regs[32] &= ~0x40;
800
801
	if (Hp_rts_RegWrite(iHandle,0x32, regs[0x32]) < 0 ||
802
	    Hp35x0c_set_register_immediate(iHandle,0, 255, regs) < 0 ||
803
	    Hp_rts_RegWrite(iHandle,0x32, regs[0x32] | 0x40) < 0)
804
		return -1;
805
	return 0;
806
}
807
808
/****************************************************************************/
809
SANE_Int
810
Hp35x0c_adjust_misc_registers(SANE_Byte *regs)
811
/****************************************************************************/
812
{
813
	/* Mostly unknown purposes - probably no need to adjust */
814
	regs[0xc6] = (regs[0xc6] & 0x0f) | 0x20; /* Purpose unknown - appears to do nothing */
815
	regs[0x2e] = 0x86;			/* ???? - Always has this value */
816
	regs[0x30] = 2;				/* CCPL = 1 */
817
	regs[0xc9] |= 0x38;			/* Doesn't have any obvious effect, but the Windows driver does this */
818
	return 0;
819
}
820
821
822
#define NVR_MAX_ADDRESS_SIZE	11
823
#define NVR_MAX_OPCODE_SIZE		3
824
#define NVR_DATA_SIZE			8
825
#define	NVR_MAX_COMMAND_SIZE	((NVR_MAX_ADDRESS_SIZE + \
826
				  NVR_MAX_OPCODE_SIZE + \
827
				  NVR_DATA_SIZE) * 2 + 1)
828
829
/****************************************************************************/
830
static SANE_Int
831
Hp35x0c_nvram_enable_controller(SANE_Int iHandle,SANE_Int enable)
832
/****************************************************************************/
833
{
834
	SANE_Byte r;
835
836
	if (Hp35x0c_read_register_immediate(iHandle,0x1d, 1, &r) < 0)
837
		return -1;
838
	if (enable)
839
		r |= 1;
840
	else
841
		r &= ~1;
842
	return Hp_rts_RegWrite(iHandle,0x1d, r);
843
844
}
845
846
/****************************************************************************/
847
static SANE_Int
848
Hp35x0c_nvram_init_command(SANE_Int iHandle)
849
/****************************************************************************/
850
{
851
	SANE_Byte regs[13];
852
853
	if (Hp35x0c_read_register_immediate(iHandle,0x10, 13, regs) < 0)
854
		return -1;
855
	regs[2] |= 0xf0;
856
	regs[4] = regs[4] & 0x1f | 0x60;
857
	return Hp35x0c_set_register_immediate(iHandle,0x10, 13, regs);
858
}
859
860
/****************************************************************************/
861
static SANE_Int
862
Hp35x0c_nvram_init_stdvars(SANE_Int iHandle,SANE_Int block,
863
/****************************************************************************/
864
			SANE_Int *addrbits,
865
			SANE_Byte *basereg)
866
{
867
	SANE_Int	bitsneeded;
868
	SANE_Int	capacity;
869
870
	switch (block)
871
	{
872
	case 0:
873
		bitsneeded = 7;
874
		break;
875
876
	case 1:
877
		bitsneeded = 9;
878
		break;
879
880
	case 2:
881
		bitsneeded = 11;
882
		break;
883
884
	default:
885
		bitsneeded = 0;
886
		capacity = 1;
887
		while (capacity < block)
888
			capacity <<= 1, ++bitsneeded;
889
		break;
890
	}
891
892
	*addrbits = bitsneeded;
893
894
	if (Hp35x0c_read_register_immediate(iHandle,0x10, 1, basereg) < 0)
895
		return -1;
896
897
	*basereg &= ~0x60;
898
	return 0;
899
}
900
901
/****************************************************************************/
902
static void
903
Hp35x0c_nvram_set_half_bit(	SANE_Byte *buffer,
904
/****************************************************************************/
905
			SANE_Int	value,
906
			SANE_Byte stdbits,
907
			SANE_Int	whichhalf)
908
{
909
	*buffer = stdbits | (value ? 0x40 : 0) | (whichhalf ? 0x20 : 0);
910
}
911
912
/****************************************************************************/
913
static void
914
Hp35x0c_nvram_set_command_bit(SANE_Byte *buffer,
915
/****************************************************************************/
916
			 SANE_Int value,
917
			 SANE_Byte stdbits)
918
{
919
	Hp35x0c_nvram_set_half_bit(buffer, value, stdbits, 0);
920
	Hp35x0c_nvram_set_half_bit(buffer + 1, value, stdbits, 1);
921
}
922
923
/****************************************************************************/
924
void
925
Hp35x0c_nvram_set_addressing_bits(	SANE_Byte *buffer,
926
/****************************************************************************/
927
				SANE_Int	location,
928
				SANE_Int	addressingbits,
929
				SANE_Byte stdbits)
930
{
931
	SANE_Int	currentbit = 1 << (addressingbits - 1);
932
933
	while (addressingbits--)
934
	{
935
		Hp35x0c_nvram_set_command_bit(buffer,
936
					 (location & currentbit) ? 1 : 0,
937
					 stdbits);
938
		buffer += 2;
939
		currentbit >>= 1;
940
	}
941
}
942
943
/****************************************************************************/
944
SANE_Int
945
Hp35x0c_nvram_enable_write(SANE_Int iHandle,SANE_Int	addressingbits,
946
/****************************************************************************/
947
			SANE_Int	enable,
948
			SANE_Byte stdbits)
949
{
950
	SANE_Byte cmdbuffer[NVR_MAX_COMMAND_SIZE];
951
	SANE_Byte cmdsize = 6 + addressingbits * 2;
952
953
	Hp35x0c_nvram_set_command_bit(cmdbuffer, 1, stdbits);
954
	Hp35x0c_nvram_set_command_bit(cmdbuffer + 2, 0, stdbits);
955
	Hp35x0c_nvram_set_command_bit(cmdbuffer + 4, 0, stdbits);
956
	Hp35x0c_nvram_set_command_bit(cmdbuffer + 6, enable, stdbits);
957
	if (addressingbits > 1)
958
		Hp35x0c_nvram_set_addressing_bits(cmdbuffer + 8, 0, addressingbits - 1, stdbits);
959
960
	if (Hp35x0c_nvram_enable_controller(iHandle,1) < 0 ||
961
	    Hp35x0c_send_command_immediate(iHandle,RTCMD_NVRAMCONTROL, 0, cmdsize, cmdsize, cmdbuffer, 0, 0) < 0 ||
962
	    Hp35x0c_nvram_enable_controller(iHandle,0) < 0)
963
	{
964
		return -1;
965
	}
966
	return 0;
967
}
968
969
/****************************************************************************/
970
SANE_Int
971
Hp35x0c_nvram_write(SANE_Int iHandle, SANE_Int	block,
972
/****************************************************************************/
973
		SANE_Int	location,
974
		SANE_Char const *data,
975
		SANE_Int	bytes)
976
{
977
	SANE_Int addressingbits;
978
	SANE_Byte stdbits;
979
	SANE_Byte cmdbuffer[NVR_MAX_COMMAND_SIZE];
980
	SANE_Byte *address_bits;
981
	SANE_Byte *data_bits;
982
	SANE_Int	i;
983
	SANE_Int	cmdsize;
984
	SANE_Byte r;
985
	SANE_Byte cmd;
986
987
	/* This routine doesn't appear to work, but I can't see anything wrong with it */
988
	if (Hp35x0c_nvram_init_stdvars(iHandle,block, &addressingbits, &stdbits) < 0)
989
		return -1;
990
991
	cmdsize = (addressingbits + 8) * 2 + 6;
992
	address_bits = cmdbuffer + 6;
993
	data_bits = address_bits + (addressingbits * 2);
994
995
	Hp35x0c_nvram_set_command_bit(cmdbuffer, 1, stdbits);
996
	Hp35x0c_nvram_set_command_bit(cmdbuffer + 2, 0, stdbits);
997
	Hp35x0c_nvram_set_command_bit(cmdbuffer + 4, 1, stdbits);
998
999
	if (Hp35x0c_nvram_init_command(iHandle) < 0 ||
1000
	    Hp35x0c_nvram_enable_write(iHandle,addressingbits, 1, stdbits) < 0)
1001
		return -1;
1002
1003
	while (bytes--)
1004
	{
1005
		Hp35x0c_nvram_set_addressing_bits(address_bits, location, addressingbits, stdbits);
1006
		Hp35x0c_nvram_set_addressing_bits(data_bits, *data++, 8, stdbits);
1007
1008
		if (Hp35x0c_nvram_enable_controller(iHandle,1) < 0 ||
1009
		    Hp35x0c_send_command_immediate(iHandle,RTCMD_NVRAMCONTROL, 0, cmdsize, cmdsize, cmdbuffer, 0, 0) < 0 ||
1010
		    Hp35x0c_nvram_enable_controller(iHandle,0) < 0)
1011
			return -1;
1012
1013
		if (Hp35x0c_nvram_enable_controller(iHandle,1) < 0)
1014
			return -1;
1015
		for (i = 0; i < cmdsize; ++i)
1016
		{
1017
			Hp35x0c_nvram_set_half_bit(&cmd, 0, stdbits, i & 1);
1018
			if (Hp35x0c_send_command_immediate(iHandle,RTCMD_NVRAMCONTROL, 0, 1, 1, &cmd, 0, 0) < 0 ||
1019
			    Hp35x0c_read_register_immediate(iHandle,0x10, 1, &r) < 0)
1020
			{
1021
				return -1;
1022
			}
1023
			else if (r & 0x80)
1024
			{
1025
				break;
1026
			}
1027
		}
1028
		if (Hp35x0c_nvram_enable_controller(iHandle,0) < 0)
1029
			return -1;
1030
1031
		++location;
1032
	}
1033
1034
	if (Hp35x0c_nvram_enable_write(iHandle,addressingbits, 0, stdbits) < 0)
1035
		return -1;
1036
	return 0;
1037
}
1038
1039
/****************************************************************************/
1040
SANE_Int
1041
Hp35x0c_nvram_read(SANE_Int iHandle,SANE_Int	block,
1042
/****************************************************************************/
1043
		SANE_Int	location,
1044
		SANE_Byte	*data,
1045
		SANE_Int	bytes)
1046
{
1047
	SANE_Int addressingbits;
1048
	SANE_Byte stdbits;
1049
	SANE_Byte cmdbuffer[NVR_MAX_COMMAND_SIZE];
1050
	SANE_Byte *address_bits;
1051
	SANE_Byte readbit_command[2];
1052
	SANE_Int	cmdsize;
1053
	SANE_Byte r;
1054
	SANE_Int	i;
1055
	SANE_Char	c = 0;
1056
1057
	if (Hp35x0c_nvram_init_stdvars(iHandle,block, &addressingbits, &stdbits) < 0)
1058
		return -1;
1059
1060
	cmdsize = addressingbits * 2 + 7;
1061
	address_bits = cmdbuffer + 6;
1062
1063
	Hp35x0c_nvram_set_command_bit(cmdbuffer, 1, stdbits);
1064
	Hp35x0c_nvram_set_command_bit(cmdbuffer + 2, 1, stdbits);
1065
	Hp35x0c_nvram_set_command_bit(cmdbuffer + 4, 0, stdbits);
1066
	Hp35x0c_nvram_set_half_bit(cmdbuffer + cmdsize - 1, 0, stdbits, 0);
1067
1068
	Hp35x0c_nvram_set_half_bit(readbit_command, 0, stdbits, 1);
1069
	Hp35x0c_nvram_set_half_bit(readbit_command + 1, 0, stdbits, 0);
1070
1071
	if (Hp35x0c_nvram_init_command(iHandle) < 0)
1072
		return -1;
1073
1074
	while (bytes--)
1075
	{
1076
		Hp35x0c_nvram_set_addressing_bits(address_bits, location, addressingbits, stdbits);
1077
1078
		if (Hp35x0c_nvram_enable_controller(iHandle,1) < 0 ||
1079
		    Hp35x0c_send_command_immediate(iHandle,RTCMD_NVRAMCONTROL, 0x1d, cmdsize, cmdsize, cmdbuffer, 0, 0) < 0)
1080
			return -1;
1081
1082
		for (i = 0; i < 8; ++i)
1083
		{
1084
			c <<= 1;
1085
1086
			if (Hp35x0c_send_command_immediate(iHandle,RTCMD_NVRAMCONTROL, 0x1d, 2, 2, readbit_command, 0, 0) < 0 ||
1087
			    Hp35x0c_read_register_immediate(iHandle,0x10, 1, &r) < 0)
1088
				return -1;
1089
			if (r & 0x80)
1090
				c |= 1;
1091
		}
1092
		if (Hp35x0c_nvram_enable_controller(iHandle,0) < 0)
1093
			return -1;
1094
1095
		*data++ = c;
1096
		++location;
1097
	}
1098
	return 0;
1099
}
1100
1101
1102
/****************************************************************************/
1103
SANE_Int
1104
Hp35x0c_rewind(THWParams *pHWParams)
1105
/* Moves scanner to home position */
1106
/****************************************************************************/
1107
{
1108
	SANE_Byte regs[255];
1109
	SANE_Int iHandle;
1110
1111
	regs[1] = 0; /* only for the compiler */
1112
	iHandle = pHWParams->iXferHandle;
1113
	DBG(DBG_MSG,"Hp35x0c_rewind : park to home...");
1114
#ifdef DEBUG_HP3500
1115
	return 0;
1116
#endif
1117
  if (Hp35x0c_is_rewound(iHandle )){
1118
		DBG(DBG_MSG,"Hp35x0c_rewind : i'm home\n");
1119
		return 0;
1120
	}
1121
	DBG(DBG_MSG,"Hp35x0c_rewind : i must moving\n");
1122
#if 0
1123
	/* read all registers */
1124
	Hp35x0c_read_register_immediate(iHandle,0, 255, regs);
1125
1126
	/* set registes 60/1 and 62/3 */
1127
	Hp_rts_set_noscan_distance(regs, 59998);
1128
	Hp_rts_set_total_distance(regs, 59999);
1129
1130
	/* clear Bit 4 from register b2 */
1131
	Hp35x0c_set_stop_when_rewound(regs, 0);
1132
1133
	DBG(DBG_MSG,"Hp35x0c_rewind : Hp_rts_RegWrite 0xc6\n");
1134
	Hp_rts_RegWrite(iHandle,0xc6, 0);
1135
	DBG(DBG_MSG,"Hp35x0c_rewind : Hp_rts_RegWrite 0xc6\n");
1136
	Hp_rts_RegWrite(iHandle,0xc6, 0);
1137
1138
	/* set register e2 to stepsize, e0 to 0 */
1139
	Hp35x0c_set_step_size(regs, 0x0abd);
1140
1141
	/* set Bit 3 from register c6 to 0 */
1142
	Hp35x0c_set_direction_rewind(regs);
1143
1144
	/* fast move */
1145
	regs[0x39] = 15;
1146
	/* Motor enable: It set bit 7. clear bit 0-2 and set bit 0
1147
		regs[0xc3] = (regs[0xc3] & 0xf8) | 1; */
1148
	regs[0xc3] |= 0x80;
1149
1150
	/* setzt in Register c6 step size auf 3 */
1151
	regs[0xc6] = (regs[0xc6] & 0xf8) | 3;
1152
1153
	DBG(DBG_MSG,"Hp35x0c_rewind : Hp35x0c_set_all_registers\n");
1154
	Hp35x0c_set_all_registers(iHandle,regs);
1155
#else
1156
	memcpy(pHWParams->regs,Hp35x0c_rewind_regs,255);
1157
	/*-- motor resolution divisor*/
1158
	pHWParams->regs[0x39] =0x0f;
1159
1160
	/*-- motor movement clock multiplier*/
1161
	pHWParams->regs[0x40] =0xa0;
1162
1163
	/*-- noscan distance*/
1164
	pHWParams->regs[0x60] =0x70;
1165
	pHWParams->regs[0x61] =0xe7;
1166
1167
	/*-- total distance =noscan distance+1*/
1168
	pHWParams->regs[0x62] =0x71;
1169
	pHWParams->regs[0x63] =0xe7;
1170
1171
	/*-- no image data, stop when home*/
1172
	/*   (careful, value becomes 0x12 after write)*/
1173
	pHWParams->regs[0xb2] =0x14;
1174
1175
	/*-- coordinate space denominator=3D1, motor enable*/
1176
	pHWParams->regs[0xc3] =0x81;
1177
1178
	/*-- backward direction, step size 0.5 (0x01) or 1 (0x03)*/
1179
	/*    pHWParams->regs[0xc6] =0x21;*/
1180
	pHWParams->regs[0xc6] =0x23;
1181
1182
	/*-- bounds movement range 1*/
1183
	pHWParams->regs[0xe0] =0xf4;
1184
	pHWParams->regs[0xe1] =0x07;
1185
1186
	/*-- Step size movement range 1*/
1187
	pHWParams->regs[0xe2] =0xd0;
1188
	pHWParams->regs[0xe3] =0x00;
1189
1190
	Hp35x0c_set_all_registers(iHandle,pHWParams->regs);
1191
1192
#endif
1193
	Hp_rts_start_moving(iHandle);
1194
	DBG(DBG_MSG,"Hp35x0c_rewind : Test, if the scanner is moving\n");
1195
	while (!Hp35x0c_is_rewound(iHandle) /*&&
1196
		(Hp_rts_data_ready(iHandle,&n) ||
1197
		 Hp_rts_is_moving(iHandle) > 0)*/)
1198
	{
1199
		/*if (n)
1200
		{
1201
			SANE_Byte	buffer[0xffc0];
1202
1203
			if (n > (SANE_Int)sizeof(buffer))
1204
				n = (SANE_Int)sizeof(buffer);
1205
			Hp_rts_read_data(iHandle,n, buffer);
1206
			DBG(DBG_MSG,"====> has read data\n");
1207
		}
1208
		else
1209
		{*/
1210
			DBG(DBG_MSG,"w");
1211
			usleep(10000);
1212
#if 0 /* short fix, because the scanner doesn't move  */
1213
			break;
1214
#endif
1215
		/*}*/
1216
	}
1217
	DBG(DBG_MSG," moving done\n");
1218
	return(Hp_rts_stop_moving(iHandle));
1219
}
1220
1221
1222
/****************************************************************************/
1223
SANE_Bool Hp35x0c_init_scan(THWParams *pHWParams, TScanParams *pParams,
1224
                    TDataPipe *pDataPipe)
1225
/* code comes from rts8801_scan */
1226
/****************************************************************************/
1227
{
1228
	SANE_Int	iHandle;
1229
	SANE_Byte	offdutytime;
1230
	SANE_Int	ires;
1231
	SANE_Byte r93setting;
1232
	SANE_Int	tg_setting;
1233
	SANE_Word x1,x2,y,h;
1234
1235
	iHandle = pHWParams->iXferHandle;
1236
	r93setting = r93setting;
1237
1238
	for (ires = 0; Hp35x0c_resparms[ires].resolution &&
1239
								 Hp35x0c_resparms[ires].resolution != pParams->iDpi; ++ires);
1240
	if (Hp35x0c_resparms[ires].resolution == 0){
1241
		DBG(DBG_MSG,"Hp35x0c_init_scan: did not found this resolution %d\n",pParams->iDpi);
1242
		return SANE_FALSE;
1243
	}
1244
1245
	DBG(DBG_MSG,"Hp35x0c_init_scan: Use ires entry %d (%ddpi) for the resolution %d dpi\n",ires,
1246
			Hp35x0c_resparms[ires].resolution, pParams->iDpi);
1247
1248
#ifdef ENABLE_VI8920
1249
	DBG(DBG_MSG,"Vi8920 is enabled and will be run us a HP3500c\n");
1250
#endif
1251
1252
	/* Initialise and power up */
1253
#ifdef DEBUG_HP3500
1254
	Hp35x0c_set_all_registers(iHandle,Hp44x0_switch_on_regs);
1255
#else
1256
	Hp35x0c_set_all_registers(iHandle,Hp35x0c_initial_regs);
1257
	Hp35x0c_set_powersave_mode(iHandle,0);
1258
1259
	Hp35x0c_rewind(pHWParams);
1260
  /* Warm up the lamp */
1261
	Hp35x0c_detect_sram(iHandle,&sram_size, &r93setting);
1262
	Hp35x0c_turn_on_lamp(iHandle);
1263
	sleep(20);
1264
#endif
1265
1266
  /* Set scan parameters */
1267
	Hp35x0c_read_register_immediate(iHandle,0, 255, pHWParams->regs);
1268
	pHWParams->regs[255] = 0;
1269
1270
	Hp35x0c_enable_ccd(pHWParams->regs, 1);
1271
	Hp35x0c_enable_movement(pHWParams->regs, 1);
1272
	Hp35x0c_set_scan_frequency(pHWParams->regs, 1);
1273
1274
	Hp35x0c_adjust_misc_registers(pHWParams->regs);
1275
	Hp35x0c_set_cvtr_wparams(pHWParams->regs, 3, 0, 6);
1276
	Hp35x0c_set_cvtr_mpt(pHWParams->regs, 15, 15, 15);
1277
	Hp35x0c_set_cvtr_lm(pHWParams->regs, 7, 7, 7);
1278
	Hp35x0c_set_motor_type(pHWParams->regs, 2);
1279
1280
 	offdutytime = 0;
1281
	if (Hp35x0c_nvram_read(iHandle,0, 0x7b, &offdutytime, 1) < 0 ||
1282
      offdutytime >= 15)
1283
	{
1284
  	offdutytime = 6;
1285
	}
1286
	Hp35x0c_set_lamp_duty_cycle(pHWParams->regs,
1287
			1,		/* On */
1288
			10,		/* Frequency */
1289
			offdutytime);	/* Off duty time */
1290
1291
	Hp35x0c_set_movement_pattern(pHWParams->regs, 0x800000);
1292
1293
	tg_setting = Hp35x0c_resparms[ires].tg;
1294
	Hp35x0c_set_ccd_shift_clock_multiplier(pHWParams->regs,
1295
				tg_info[tg_setting].tg_cph0p);
1296
	Hp35x0c_set_ccd_clock_reset_interval(pHWParams->regs,
1297
				tg_info[tg_setting].tg_crsp);
1298
	Hp35x0c_set_ccd_clamp_clock_multiplier(pHWParams->regs,
1299
				tg_info[tg_setting].tg_cclpp);
1300
1301
	Hp_rts_RegWrite(iHandle,0xc6, 0);
1302
	Hp_rts_RegWrite(iHandle,0xc6, 0);
1303
1304
	Hp35x0c_set_step_size(pHWParams->regs, Hp35x0c_resparms[ires].step_size);
1305
	Hp35x0c_set_direction_forwards(pHWParams->regs);
1306
1307
	Hp35x0c_set_stop_when_rewound(pHWParams->regs, 0);
1308
	Hp35x0c_set_data_feed_on(pHWParams->regs);
1309
1310
	Hp35x0c_set_calibration_addresses(pHWParams->regs, 0, 0, 0);
1311
1312
	Hp35x0c_set_basic_calibration(pHWParams->regs,
1313
				0xc8, 0xc8, 0x0a,
1314
				0xc6, 0xc6, 0x0c,
1315
				0xc6, 0xc6, 0x0b);
1316
	pHWParams->regs[0x0b] = 0x70;/* If set to 0x71, the alternative, all values are low*/
1317
1318
	switch (pParams->mode) {
1319
		case GRAY:
1320
			DBG(DBG_ERR, "Hp35x0c_init_scan: Use gray parameter\n");
1321
			Hp35x0c_set_channel(pHWParams->regs, RT_CHANNEL_RED);
1322
			Hp35x0c_set_single_channel_scanning(pHWParams->regs, 1); /* 0x20 on / 0ff*/
1323
			Hp35x0c_set_merge_channels(pHWParams->regs, 1); /* 0x14 on / off */
1324
			Hp35x0c_set_colour_mode(pHWParams->regs, 0); /* 0x02 on / off */
1325
			break;
1326
		case COLOR:
1327
			DBG(DBG_ERR, "Hp35x0c_init_scan: use color parameter\n");
1328
			Hp35x0c_set_channel(pHWParams->regs, RT_CHANNEL_ALL);
1329
			Hp35x0c_set_single_channel_scanning(pHWParams->regs, 0); /* 0x20 on / 0ff*/
1330
			Hp35x0c_set_merge_channels(pHWParams->regs, 1); /* 0x14 on / off */
1331
			/*	Hp35x0c_set_merge_channels(pHWParams->regs, 0); * 0x14 on / off */
1332
			Hp35x0c_set_colour_mode(pHWParams->regs, 1); /* 0x02 on / off */
1333
			break;
1334
1335
		default:
1336
			DBG(DBG_ERR, "Hp35x0c_init_scan: Invalid parameter\n");
1337
			return SANE_FALSE;
1338
	}/* switch */
1339
1340
	Hp35x0c_set_motor_movement_clock_multiplier(pHWParams->regs,
1341
		Hp35x0c_resparms[ires].motor_movement_clock_multiplier);
1342
1343
	Hp35x0c_set_cdss(pHWParams->regs, tg_info[tg_setting].tg_cdss1,
1344
		tg_info[tg_setting].tg_cdss2);
1345
	Hp35x0c_set_cdsc(pHWParams->regs, tg_info[tg_setting].tg_cdsc1,
1346
		tg_info[tg_setting].tg_cdsc2);
1347
1348
	Hp35x0c_update_after_setting_cdss2(pHWParams->regs);
1349
1350
	Hp35x0c_set_last_sram_page(pHWParams->regs, (sram_size - 1) >> 5);
1351
1352
	pHWParams->regs[0x39] = Hp35x0c_resparms[ires].reg_39_value;
1353
	pHWParams->regs[0xc3] = (pHWParams->regs[0xc3] & 0xf8) |
1354
		 	Hp35x0c_resparms[ires].reg_c3_value;
1355
	pHWParams->regs[0xc6] = (pHWParams->regs[0xc6] & 0xf8) |
1356
			 Hp35x0c_resparms[ires].reg_c6_value;
1357
	Hp35x0c_set_scan_frequency(pHWParams->regs, Hp35x0c_resparms[ires].scan_frequency);
1358
	Hp35x0c_set_cph0s(pHWParams->regs, Hp35x0c_resparms[ires].cph0s);
1359
1360
	x1 = pParams->iX;
1361
	x2 = pParams->iWidth + pParams->iX;
1362
	y = pParams->iY;
1363
	h = pParams->iLenght;/* * 2;*/
1364
	DBG(DBG_MSG,"Hp35x0c_init_scan: calculate scandata x1 = %d; x2 = %d; lenght = %d\n",x1,x2,h);
1365
	pDataPipe->iScanned = h;
1366
	DBG(DBG_MSG,"Hp35x0c_init_scan: Hp35x0c_set_horizontal_resolution %d.\n",pParams->iDpi);
1367
	Hp35x0c_set_horizontal_resolution(pHWParams->regs, pParams->iDpi);
1368
1369
	/* modify reg 60 + 61 */
1370
/*	Hp_rts_set_noscan_distance(pHWParams->regs, y *
1371
			 Hp35x0c_resparms[ires].scan_frequency -  1);*/
1372
	Hp_rts_set_noscan_distance(pHWParams->regs, 0x01 );
1373
1374
	/* modify reg 62 + 63 */
1375
/*	Hp_rts_set_total_distance(pHWParams->regs, Hp35x0c_resparms[ires].scan_frequency *
1376
				(y + h + ((pParams->mode == COLOR) ? (Hp35x0c_resparms[ires].red_green_offset +
1377
				Hp35x0c_resparms[ires].green_blue_offset) : 0) +
1378
				Hp35x0c_resparms[ires].intra_channel_offset));*/
1379
	Hp_rts_set_total_distance(pHWParams->regs, h );
1380
1381
	/* modify reg 66 + 67 */
1382
/*	Hp_rts_set_scanline_start(pHWParams->regs, x1 * (1200 / pParams->iDpi) / (Hp35x0c_resparms[ires].cph0s ? 1 : 2));*/
1383
	Hp_rts_set_scanline_start(pHWParams->regs, x1 );
1384
1385
	/* modify reg 6C + 6D */
1386
/*	Hp_rts_set_scanline_end(pHWParams->regs, (x1 + x2) * (1200 / pParams->iDpi) / (Hp35x0c_resparms[ires].cph0s ? 1 : 2));*/
1387
	Hp_rts_set_scanline_end(pHWParams->regs, x2 );
1388
1389
#if 1
1390
	DBG(DBG_MSG,"Hp35x0c_init_scan: Hp35x0c_set_all_registers\n");
1391
	Hp_rts_DumpHex(pHWParams->regs,255,16,SANE_TRUE);
1392
	Hp_rts_DumpBits(0x2f, pHWParams->regs[0x2f]);
1393
#endif
1394
#ifdef DEBUG_HP3500
1395
	return SANE_FALSE;
1396
#endif
1397
	Hp35x0c_set_all_registers(iHandle, pHWParams->regs);
1398
1399
	Hp_rts_RegWrite(iHandle, 0x2c, pHWParams->regs[0x2c]);
1400
1401
	Hp_rts_start_moving(iHandle);
1402
	usleep(10000);
1403
	/* wait for moving and check it */
1404
	return(Hp_rts_Check_Moving (iHandle));
1405
}
1406
1407
/****************************************************************************/
1408
SANE_Bool Hp35x0c_init_power_on(THWParams *pHWParams)
1409
/****************************************************************************/
1410
{
1411
	SANE_Int	iHandle;
1412
1413
	iHandle = pHWParams->iXferHandle;
1414
	Hp35x0c_set_all_registers(iHandle,Hp35x0c_initial_regs);
1415
	Hp35x0c_set_powersave_mode(iHandle,0);
1416
#ifndef DEBUG_HP3500
1417
	return(Hp35x0c_rewind(pHWParams));
1418
#else
1419
	return 0;
1420
#endif
1421
}
(-)sane-backends-1.0.19/backend/hp_rts_35x0c.h (+445 lines)
Line 0 Link Here
1
 /* sane - Scanner Access Now Easy.
2
   Copyright (C) 2003 Johannes Hub (JohannesHub@t-online.de)
3
4
   This file was initially copied from the hp3300 backend.
5
   This file is part of the SANE package.
6
7
   This program is free software; you can redistribute it and/or
8
   modify it under the terms of the GNU General Public License
9
   as published by the Free Software Foundation; either version 2
10
   of the License, or (at your option) any later version.
11
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21
   As a special exception, the authors of SANE give permission for
22
   additional uses of the libraries contained in this release of SANE.
23
24
   The exception is that, if you link a SANE library with other files
25
   to produce an exutable, this does not by itself cause the
26
   resulting executable to be covered by the GNU General Public
27
   License.  Your use of that executable is in no way restricted on
28
   account of linking the SANE library code into it.
29
30
   This exception does not, however, invalidate any other reasons why
31
   the executable file might be covered by the GNU General Public
32
   License.
33
34
   If you submit changes to SANE to the maintainers to be included in
35
   a subsequent release, you agree by submitting the changes that
36
   those changes may be distributed with this exception intact.
37
38
   If you write modifications of your own for SANE, it is your choice
39
   whether to permit this exception to apply to your modifications.
40
   If you do not wish that, delete this exception notice.
41
*/
42
43
/*
44
    Concept for a backend for scanners based on the RTS88xx chipset,
45
    such as HP3500C, 3530C, and HP ScanJet 3570C.
46
    Parts of this source were inspired by other backends.
47
48
		History:
49
50
		Version 0.18  21.11.04 13.alpha,
51
				- source sorted,
52
				- now only SANEI_USB_SUPPORT for a better overview(xfermodules removed)
53
				- read and verify the MainBoardID 
54
		Version 0.17p 02.11.04 12.alpha, source sorted, little fixes, SANEI_USB_SUPPORT implemented
55
		Version 0.17p 02.11.04 12.alpha, source sourted, little fixes, SANEI_USB_SUPPORT implemented
56
		Version 0.17b 30.03.04 10.alpha, little fixes and libusb implemented
57
		Version 0.17  09.03.04 9. alpha, HP3500 included
58
		Version 0.16  06.02.04 8. alpha, wait counting on LCD
59
		Version 0.15a 29.01.04 7. alpha, CCD switch moved to config file
60
		Version 0.15  11.01.04 6. alpha, a second CCD implemented
61
		Version 0.13a 21.11.04 4. alpha, an little fix included
62
		Version 0.12  22.10.03 third alpha, Backend name changed to HP_RTS88xx
63
		Version 0.11  30.08.03 second alpha
64
		Version 0.10  19.07.03 first alpha
65
*/
66
67
/*
68
    Core HP35x0c functions.
69
*/
70
71
72
#ifndef _HP_RTS_HP35x0C_H_
73
#define _HP_RTS_HP35x0C_H_
74
75
#include <unistd.h>
76
77
SANE_Byte	Hp35x0c_initial_regs[] =
78
{
79
	0xf5,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,
80
	0xe1,0xfc,0xff,0xff,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,
81
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x19,
82
	0xd0,0x7a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x37,0xff,0x0f,0x00,0x00,
83
	0x80,0x00,0x00,0x00,0x8c,0x76,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
84
	0x20,0xbc,0x03,0x00,0x00,0x00,0x00,0x00,0x1d,0x1f,0x00,0x1f,0x00,0x00,0x00,0x00,
85
	0x5e,0xea,0x5f,0xea,0x00,0x80,0x64,0x00,0x00,0x00,0x00,0x00,0x84,0x04,0x00,0x00,
86
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
87
	0x0f,0x02,0x4b,0x02,0x00,0xec,0x19,0xd8,0x2d,0x87,0x02,0xff,0x3f,0x78,0x60,0x00,
88
	0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
89
	0x00,0x00,0x00,0x0c,0x27,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
90
	0x12,0x08,0x06,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
91
	0x00,0x00,0x80,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
92
	0xff,0xbf,0xff,0xff,0x00,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
93
	0x00,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
94
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
95
};
96
97
SANE_Byte	Hp35x0c_rewind_regs[] =
98
{
99
	0xe5,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,
100
	0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,
101
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xeb,0xed,0xe0,0x01,0x00,0x20,0x86,0x0b,
102
	0x02,0xa6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa6,0xff,0x8f,0x00,0x00,
103
	0x20,0x00,0x00,0x00,0x8c,0x76,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
104
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x10,0x00,0x00,0x00,0x00,0x00,
105
	0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
106
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
107
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x64,0x00,
108
	0x00,0x00,0x00,0x02,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
109
	0x00,0x00,0x01,0x0f,0x18,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
110
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
111
	0x00,0x00,0x80,0x00,0x10,0x0a,0x00,0x00,0x00,0x3a,0x0a,0x00,0x00,0x00,0x00,0x00,
112
	0x00,0x00,0x1f,0x4c,0x00,0x0c,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
113
	0x00,0x00,0xf8,0x2a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
114
	0xe0,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x00,0x30,0x00
115
};
116
117
struct Hp35x0c_tg_info__
118
{
119
	SANE_Word	tg_cph0p;
120
	SANE_Word	tg_crsp;
121
	SANE_Word	tg_cclpp;
122
	SANE_Word	tg_cdss1;
123
	SANE_Word	tg_cdsc1;
124
	SANE_Word	tg_cdss2;
125
	SANE_Word	tg_cdsc2;
126
} tg_info[] =
127
{
128
	/*	CPH0P		CRSP		CCLPP		CDSS1	CDSC1	CDSS2	CDSC2	*/
129
	{	0x01FFE0,	0x3c0000,	0x003000,	0xb,	0xd,	0x00,	0x01	},	/* NORMAL*/
130
	{	0x7ff800,	0xf00000,	0x01c000,	0xb,	0xc,	0x14,	0x15	}	/* DOUBLE*/
131
};
132
133
struct	Hp35x0c_resolution_parameters
134
{
135
	SANE_Int	resolution;
136
	SANE_Byte		reg_39_value;
137
	SANE_Byte		reg_c3_value;
138
	SANE_Byte		reg_c6_value;
139
	SANE_Byte		scan_frequency;
140
	SANE_Byte		cph0s;
141
	SANE_Byte		red_green_offset;
142
	SANE_Byte		green_blue_offset;
143
	SANE_Byte		intra_channel_offset;
144
	SANE_Byte		motor_movement_clock_multiplier;
145
	SANE_Byte		tg;
146
	SANE_Word		step_size;
147
};
148
149
static struct Hp35x0c_resolution_parameters Hp35x0c_resparms[] =
150
{
151
	/* My values - all work */
152
	/*res.,39, c3, c6, freq.chp,gre blu itr mm  tg  steps. */
153
	{	1200,	3,	6,	4,	2,	1,	22,	22,	4,	2,	0,	0x157b	},
154
	{	600,	3,	3,	1,	1,	0,	9,	10,	0,	2,	0,	0x157b	},
155
	{	400,	1,	1,	1,	1,	1,	6,	6,	1,	2,	0,	0x157b	},
156
	{	300,	3,	3,	3,	1,	0,	5,	4,	0,	2,	1,	0x157b	},
157
	{	200,	3,	1,	1,	1,	0,	3,	3,	0,	2,	1,	0x157b	},
158
	{	150,	3,	3,	3,	2,	0,	2,	2,	0,	2,	1,	0x157b	},
159
	{	100,	3,	1,	3,	1,	0,	1,	1,	0,	2,	1,	0x157b	},
160
	{	 75,	3,	3,	3,	4,	0,	1,	1,	0,	2,	1,	0x157b	},
161
	{	 50,	3,	1,	3,	2,	0,	0,	0,	0,	2,	1,	0x157b	},
162
	{	 25,	3,	1,	3,	4,	0,	0,	0,	0,	2,	1,	0x157b	},
163
	{	  0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0x157b	}
164
};
165
166
#define	REG_DESTINATION_POSITION 0x60
167
168
#define RTCMD_GETREG		0x80
169
#define	RTCMD_READSRAM		0x81
170
171
#define	RTCMD_SETREG		0x88
172
#define	RTCMD_WRITESRAM		0x89
173
174
#define	RTCMD_NVRAMCONTROL	0x8a
175
176
#define	RTCMD_BYTESAVAIL	0x90
177
#define	RTCMD_READBYTES		0x91
178
179
#define	RT_CHANNEL_ALL		0
180
#define	RT_CHANNEL_RED		1
181
#define	RT_CHANNEL_GREEN	2
182
#define	RT_CHANNEL_BLUE		3
183
184
#if 0
185
static SANE_Int
186
Hp35x0c_set_value_msbfirst(	SANE_Byte	*regs,
187
			SANE_Int		firstreg,
188
			SANE_Int		totalregs,
189
			SANE_Word	value);
190
#endif
191
SANE_Int
192
Hp35x0c_queue_read_register( SANE_Int iHandle, SANE_Byte reg, SANE_Int bytes, SANE_Byte *data);
193
194
SANE_Int
195
Hp35x0c_read_register_immediate( SANE_Int iHandle, SANE_Int reg, SANE_Int bytes, SANE_Byte *data);
196
197
SANE_Int
198
Hp35x0c_set_register_immediate( SANE_Int iHandle, SANE_Int reg, SANE_Int bytes, SANE_Byte *data);
199
200
SANE_Int
201
Hp35x0c_send_command_immediate( SANE_Int iHandle, SANE_Int command,
202
				SANE_Byte	reg,
203
				SANE_Int	count,
204
				SANE_Int	bytes,
205
				SANE_Byte	*data,
206
				SANE_Int	readbytes,
207
				SANE_Byte	*readdata);
208
209
SANE_Int
210
Hp35x0c_write_sram( SANE_Int iHandle, SANE_Word	bytes, SANE_Byte	*data);
211
212
SANE_Int
213
Hp35x0c_read_sram( SANE_Int iHandle, SANE_Int	bytes, SANE_Byte *data);
214
215
SANE_Int
216
Hp35x0c_set_sram_page( SANE_Int iHandle, SANE_Byte	page);
217
218
SANE_Int
219
Hp35x0c_detect_sram( SANE_Int iHandle, SANE_Word *totalbytes, SANE_Byte *r93setting);
220
221
SANE_Int
222
Hp35x0c_is_rewound( SANE_Int iHandle );
223
224
SANE_Int
225
Hp35x0c_set_direction_forwards(SANE_Byte *regs);
226
227
SANE_Int
228
Hp35x0c_set_direction_rewind(SANE_Byte *regs);
229
230
SANE_Int
231
Hp35x0c_set_stop_when_rewound( SANE_Byte *regs, SANE_Int	stop);
232
233
SANE_Int
234
Hp35x0c_set_distances( SANE_Int iHandle,SANE_Int location1,
235
		   SANE_Int location2);
236
237
SANE_Int
238
Hp35x0c_set_powersave_mode(SANE_Int iHandle,SANE_Int enable);
239
240
SANE_Int
241
Hp35x0c_lamp_ready( SANE_Int iHandle );
242
243
SANE_Int
244
Hp35x0c_turn_off_lamp( SANE_Int iHandle );
245
246
SANE_Int
247
Hp35x0c_turn_on_lamp( SANE_Int iHandle );
248
#if 0
249
static SANE_Int
250
Hp35x0c_set_value_msbfirst(	SANE_Byte	*regs,SANE_Int firstreg,
251
			SANE_Int		totalregs,SANE_Word	value);
252
#endif
253
SANE_Int
254
Hp35x0c_set_ccd_shift_clock_multiplier(	SANE_Byte	*regs,
255
					SANE_Word	value);
256
257
SANE_Int
258
Hp35x0c_set_ccd_sample_clock_multiplier(	SANE_Byte	*regs,
259
					SANE_Word	value);
260
261
SANE_Int
262
Hp35x0c_set_ccd_clock_reset_interval(	SANE_Byte	*regs,
263
					SANE_Word	value);
264
265
SANE_Int
266
Hp35x0c_set_ccd_clamp_clock_multiplier(	SANE_Byte	*regs,
267
					SANE_Word	value);
268
269
SANE_Int
270
Hp35x0c_set_movement_pattern(		SANE_Byte	*regs,
271
					SANE_Word	value);
272
273
SANE_Int
274
Hp35x0c_set_motor_movement_clock_multiplier(	SANE_Byte	*regs,
275
					SANE_Word	value);
276
277
SANE_Int
278
Hp35x0c_set_motor_type(			SANE_Byte	*regs,
279
					SANE_Word	value);
280
281
SANE_Int
282
Hp35x0c_set_basic_calibration(		SANE_Byte *regs,
283
					SANE_Int	redoffset1,
284
					SANE_Int	redoffset2,
285
					SANE_Int	redgain,
286
					SANE_Int	greenoffset1,
287
					SANE_Int	greenoffset2,
288
					SANE_Int	greengain,
289
					SANE_Int	blueoffset1,
290
					SANE_Int	blueoffset2,
291
					SANE_Int	bluegain);
292
293
SANE_Int
294
Hp35x0c_set_calibration_addresses(		SANE_Byte *regs,
295
					SANE_Word	redaddr,
296
					SANE_Word	blueaddr,
297
					SANE_Word	greenaddr);
298
299
SANE_Int
300
Hp35x0c_set_lamp_duty_cycle(			SANE_Byte *regs,
301
					SANE_Int	enable,
302
					SANE_Int	frequency,
303
					SANE_Int	offduty);
304
305
SANE_Int
306
Hp35x0c_set_data_feed_on(			SANE_Byte *regs);
307
308
SANE_Int
309
Hp35x0c_set_data_feed_off(			SANE_Byte *regs);
310
311
SANE_Int
312
Hp35x0c_enable_ccd(				SANE_Byte *regs,
313
					SANE_Int enable);
314
315
SANE_Int
316
Hp35x0c_set_cdss(				SANE_Byte *regs,
317
					SANE_Int	val1,
318
					SANE_Int	val2);
319
320
SANE_Int
321
Hp35x0c_set_cdsc(				SANE_Byte *regs,
322
					SANE_Int	val1,
323
					SANE_Int	val2);
324
325
SANE_Int
326
Hp35x0c_update_after_setting_cdss2(		SANE_Byte *regs);
327
328
SANE_Int
329
Hp35x0c_set_cph0s(				SANE_Byte *regs,
330
					SANE_Int	on);
331
332
SANE_Int
333
Hp35x0c_set_cvtr_lm(				SANE_Byte *regs,
334
					SANE_Int	val1,
335
					SANE_Int	val2,
336
					SANE_Int	val3);
337
338
SANE_Int
339
Hp35x0c_set_cvtr_mpt(			SANE_Byte *regs,
340
					SANE_Int	val1,
341
					SANE_Int	val2,
342
					SANE_Int	val3);
343
344
SANE_Int
345
Hp35x0c_set_cvtr_wparams(			SANE_Byte *regs,
346
					SANE_Word fpw,
347
					SANE_Word bpw,
348
					SANE_Word w);
349
350
SANE_Int
351
Hp35x0c_enable_movement(			SANE_Byte *regs,
352
					SANE_Int	enable);
353
354
SANE_Int
355
Hp35x0c_set_scan_frequency(			SANE_Byte *regs,
356
					SANE_Int	frequency);
357
358
SANE_Int
359
Hp35x0c_set_merge_channels(			SANE_Byte *regs,
360
					SANE_Int	on);
361
362
SANE_Int
363
Hp35x0c_set_channel(				SANE_Byte *regs,
364
					SANE_Int	channel);
365
366
SANE_Int
367
Hp35x0c_set_single_channel_scanning(		SANE_Byte *regs,
368
					SANE_Int	on);
369
370
SANE_Int
371
Hp35x0c_set_colour_mode(			SANE_Byte *regs,
372
					SANE_Int	on);
373
374
SANE_Int
375
Hp35x0c_set_horizontal_resolution(		SANE_Byte *regs,
376
					SANE_Int	resolution);
377
378
SANE_Int
379
Hp35x0c_set_last_sram_page(			SANE_Byte *regs,
380
					SANE_Int	pagenum);
381
382
SANE_Int
383
Hp35x0c_set_step_size(			SANE_Byte *regs,
384
					SANE_Int	stepsize);
385
386
SANE_Int
387
Hp35x0c_set_all_registers( SANE_Int iHandle, void const *regs_);
388
389
SANE_Int
390
Hp35x0c_adjust_misc_registers(SANE_Byte *regs);
391
392
static SANE_Int
393
Hp35x0c_nvram_enable_controller(SANE_Int iHandle,SANE_Int enable);
394
395
static SANE_Int
396
Hp35x0c_nvram_init_command(SANE_Int iHandle);
397
398
static SANE_Int
399
Hp35x0c_nvram_init_stdvars(SANE_Int iHandle,SANE_Int block,
400
			SANE_Int *addrbits,
401
			SANE_Byte *basereg);
402
403
static void
404
Hp35x0c_nvram_set_half_bit(	SANE_Byte *buffer,
405
			SANE_Int	value,
406
			SANE_Byte stdbits,
407
			SANE_Int	whichhalf);
408
409
static void
410
Hp35x0c_nvram_set_command_bit(SANE_Byte *buffer,
411
			 SANE_Int value,
412
			 SANE_Byte stdbits);
413
414
void
415
Hp35x0c_nvram_set_addressing_bits(	SANE_Byte *buffer,
416
				SANE_Int	location,
417
				SANE_Int	addressingbits,
418
				SANE_Byte stdbits);
419
420
SANE_Int
421
Hp35x0c_nvram_enable_write(SANE_Int iHandle,SANE_Int	addressingbits,
422
			SANE_Int	enable,
423
			SANE_Byte stdbits);
424
425
SANE_Int
426
Hp35x0c_nvram_write(SANE_Int iHandle,SANE_Int	block,
427
		SANE_Int	location,
428
		SANE_Char const *data,
429
		SANE_Int	bytes);
430
431
SANE_Int
432
Hp35x0c_nvram_read(SANE_Int iHandle,SANE_Int	block,
433
		SANE_Int	location,
434
		SANE_Byte	*data,
435
		SANE_Int	bytes);
436
437
SANE_Int  Hp35x0c_rewind(THWParams *pHWParams);
438
439
SANE_Bool Hp35x0c_init_scan(THWParams *pHWParams, TScanParams *pParams,
440
                    TDataPipe *pDataPipe);
441
442
SANE_Bool Hp35x0c_init_power_on(THWParams *pHWParams);
443
444
#endif /* NO _HP_RTS_HP35x0C_H_ */
445
(-)sane-backends-1.0.19/backend/hp_rts_44x0c.c (+949 lines)
Line 0 Link Here
1
 /* sane - Scanner Access Now Easy.
2
   Copyright (C) 2003 Johannes Hub (JohannesHub@t-online.de)
3
4
   This file was initially copied from the hp3300 backend.
5
   This file is part of the SANE package.
6
7
   This program is free software; you can redistribute it and/or
8
   modify it under the terms of the GNU General Public License
9
   as published by the Free Software Foundation; either version 2
10
   of the License, or (at your option) any later version.
11
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21
   As a special exception, the authors of SANE give permission for
22
   additional uses of the libraries contained in this release of SANE.
23
24
   The exception is that, if you link a SANE library with other files
25
   to produce an exutable, this does not by itself cause the
26
   resulting executable to be covered by the GNU General Public
27
   License.  Your use of that executable is in no way restricted on
28
   account of linking the SANE library code into it.
29
30
   This exception does not, however, invalidate any other reasons why
31
   the executable file might be covered by the GNU General Public
32
   License.
33
34
   If you submit changes to SANE to the maintainers to be included in
35
   a subsequent release, you agree by submitting the changes that
36
   those changes may be distributed with this exception intact.
37
38
   If you write modifications of your own for SANE, it is your choice
39
   whether to permit this exception to apply to your modifications.
40
   If you do not wish that, delete this exception notice.
41
*/
42
43
/*
44
    Concept for a backend for scanners based on the RTS88xx chipset,
45
    such as HP4400C, HP4470C.
46
    Parts of this source were inspired by other backends.
47
48
		History:
49
50
		Version 0.18  21.11.04 13.alpha,
51
				- source sorted,
52
				- now only SANEI_USB_SUPPORT for a better overview(xfermodules removed)
53
				- read and verify the MainBoardID 
54
		Version 0.17p 02.11.04 12.alpha, source sorted, little fixes, SANEI_USB_SUPPORT implemented
55
		Version 0.17p 02.11.04 12.alpha, source sourted, little fixes, SANEI_USB_SUPPORT implemented
56
		Version 0.17b 30.03.04 10.alpha, little fixes and libusb implemented
57
		Version 0.17  09.03.04 9. alpha, HP3500 included
58
		Version 0.16  06.02.04 8. alpha, wait counting on LCD
59
		Version 0.15a 29.01.04 7. alpha, CCD switch moved to config file
60
		Version 0.15  11.01.04 6. alpha, a second CCD implemented
61
		Version 0.13a 21.11.04 4. alpha, an little fix included
62
		Version 0.12  22.10.03 third alpha, Backend name changed to HP_RTS88xx
63
		Version 0.11  30.08.03 second alpha
64
		Version 0.10  19.07.03 first alpha
65
*/
66
67
/*
68
    Core HP44x0c functions.
69
*/
70
71
#include <stdio.h>  /* fopen, fread, fwrite, fclose etc */
72
#include <stdarg.h> /* va_list for vfprintf */
73
#include <string.h> /* memcpy, memset */
74
#include <unistd.h> /* unlink */
75
#include <stdlib.h> /* malloc, free */
76
#include <math.h>   /* exp, pow */
77
78
#include "hp_rts_xfer.h"
79
#include "hp_rts_44x0c.h"
80
81
82
/****************************************************************************/
83
SANE_Bool Hp44x0_Wakeup(THWParams *pHWParams,TScanParams *pParams)
84
/****************************************************************************/
85
{
86
	SANE_Byte Reg_10, Reg_11;
87
	SANE_Int iHandle;
88
89
	DBG(DBG_SCAN, "Hp44x0_Wakeup....\n");
90
	/* prevent compiler from complaining about unused parameters */
91
	pParams->mode = pParams->mode;
92
	iHandle = pHWParams->iXferHandle;
93
94
	if (iHandle < 0) {
95
		DBG(DBG_SCAN, "Hp44x0_Wakeup, wrong iHandle\n");
96
		return SANE_FALSE;
97
	}
98
	/* write magic startup sequence */
99
	if ( !(Hp_rts_RegWrite(iHandle,0xb3,0x00))) return SANE_FALSE;
100
	if ( !(Hp_rts_RegWrite(iHandle,0xb3,0x00))) return SANE_FALSE;
101
	/*  test_reg( 0xb2,0x00,20 );*/
102
	if ( !(Hp_rts_RegWrite(iHandle,0xb2,0x02))) return SANE_FALSE;
103
	if ( !(Hp_rts_RegWrite(iHandle,0xb1,0x00))) return SANE_FALSE;
104
	if (pParams->optXPA)
105
		Reg_11 = 0x08;
106
	else
107
		Reg_11 = 0x28;
108
	Reg_10 = 0x28;
109
	if ( !(Hp_rts_Set_double_reg(iHandle, LEDSTATUS, Reg_10, Reg_11 ))) return SANE_FALSE;
110
	usleep(1000);
111
	/*  test_double_reg( 0x20,0x3a,0xf2,21 );*/
112
	if ( !(Hp_rts_RegWrite(iHandle,0xb3,0x01))) return SANE_FALSE;
113
	if ( !(Hp_rts_RegWrite(iHandle,0xb3,0x01))) return SANE_FALSE;
114
	if ( !(Hp_rts_RegWrite(iHandle,0xb3,0x00))) return SANE_FALSE;
115
	if ( !(Hp_rts_RegWrite(iHandle,0xb3,0x00))) return SANE_FALSE;
116
	if ( !(Hp_rts_Set_double_reg(iHandle,0x12,0xff,0x20))) return SANE_FALSE;
117
	if ( !(Hp_rts_Set_double_reg(iHandle,0x14,0xf8,0x28))) return SANE_FALSE;
118
	if ( !(Hp_rts_RegWrite(iHandle,0xb3,0x00))) return SANE_FALSE;
119
	if ( !(Hp_rts_RegWrite(iHandle,0xb3,0x00))) return SANE_FALSE;
120
	if ( !(Hp_rts_Set_double_reg(iHandle, LEDSTATUS, Reg_10, Reg_11 ))) return SANE_FALSE;
121
	usleep(1000);
122
	if ( !(Hp_rts_RegWrite(iHandle,0xd9,0x80))) return SANE_FALSE;
123
	memcpy(pHWParams->regs,Hp44x0_switch_on_regs,254);
124
	pHWParams->regs[0x10] = Reg_10;
125
	pHWParams->regs[0x11] = Reg_11;
126
	if ( !(Hp_rts_BulkWrite (iHandle, 0x00,pHWParams->regs, 0xb3,SANE_TRUE))) return SANE_FALSE;
127
	return (Hp_rts_BulkWrite (iHandle, 0xb4,pHWParams->regs+0xb3, 0x3f,SANE_TRUE));
128
129
	/*  need we a new callibriation ? */
130
}
131
132
133
/****************************************************************************/
134
SANE_Bool Hp44x0_Down(SANE_Int iHandle)
135
/****************************************************************************/
136
{
137
	DBG(DBG_SCAN, "Hp44x0_Down....\n");
138
	if (iHandle <= 0) {
139
		return SANE_FALSE;
140
	}
141
	/* switch off the little green LEDs for color selector */
142
	if ( !(Hp_rts_Set_double_reg(iHandle,LEDSTATUS,0x08,0x28))) return SANE_FALSE;
143
	usleep(10000);
144
	/*test_reg( 0xb2, 0x02,13 ); */
145
	/* switch off the green power LED */
146
	if ( !(Hp_rts_RegWrite(iHandle,0xb2,0x00))) return SANE_FALSE;
147
	/* ?? */
148
	if ( !(Hp_rts_RegWrite(iHandle,0xb1,0x00))) return SANE_FALSE;
149
	/* switch off lamp, LCD and power LED */
150
	if ( !(Hp_rts_RegWrite(iHandle,0xb3,0x04))) return SANE_FALSE;
151
	return (Hp_rts_RegWrite(iHandle,0xb3,0x04));
152
}
153
154
/****************************************************************************/
155
SANE_Bool Hp44x0_patch_and_send_values(SANE_Int iHandle, SANE_Byte *my_values){
156
/****************************************************************************/
157
	/* read registers, patch and write out them */
158
	SANE_Byte v1,v2;
159
160
	DBG(DBG_SCAN, "Hp44x0_patch_and_send_values....\n");
161
	Hp_rts_BulkReadall(iHandle,registers);
162
	v1 = *my_values++;
163
	v2 = *my_values++;
164
	registers[v1] = v2;
165
	while(*my_values){
166
		v1 = *my_values++;
167
		v2 = *my_values++;
168
		registers[v1] = v2;
169
	}
170
	if ( !(Hp_rts_BulkWrite(iHandle,0x00,registers,0xb3,SANE_TRUE))) return SANE_FALSE;
171
	return (Hp_rts_BulkWrite(iHandle,0xb4,registers+0xb3,0x3f,SANE_TRUE));
172
}
173
174
/****************************************************************************/
175
void Hp44x0_patch_regs(THWParams *pHWParams,SANE_Byte *my_values){
176
/****************************************************************************/
177
	/* read registers, patch and write out them */
178
	SANE_Byte v1,v2;
179
180
	DBG(DBG_SCAN, "Hp44x0_patch_regs....\n");
181
	v1 = *my_values++;
182
	v2 = *my_values++;
183
	pHWParams->regs[v1] = v2;
184
	while(*my_values){
185
		v1 = *my_values++;
186
		v2 = *my_values++;
187
		pHWParams->regs[v1] = v2;
188
	}
189
}
190
191
/****************************************************************************/
192
SANE_Bool Hp44x0_set_display( SANE_Int iHandle, SANE_Byte val )
193
/****************************************************************************/
194
{
195
	static SANE_Word LcdValues_h []=
196
	/* left char       0,      1,     2,     3 */
197
			{ 0xa18f2,0x0890,0x10b3,0x18b1};
198
	static SANE_Word LcdValues_l []=
199
	/* right char       0,      1,     2,     3      4 */
200
			{ 0xa68c,0x2280,0xe484,0x6684,0x6288,
201
	/*                  5,      6,     7,     8      9 */
202
			  0x468c,0xc68c,0x2284,0xe68c,0x668c};
203
	SANE_Byte reg_20,reg_21;
204
205
	DBG(DBG_SCAN, "Hp44x0_set_display.to %d\n",val);
206
	if (val < 40){
207
		reg_20 = (LcdValues_l [val%10]  >> 8) & 0x00ff;
208
		reg_21 =  LcdValues_l [val%10] & 0x00ff;
209
		reg_20 = reg_20 | (LcdValues_h [val/10]  >> 8) & 0x00ff;
210
		reg_21 = reg_21 |  LcdValues_h [val/10] & 0x00ff;
211
		if ( !(Hp_rts_RegWrite(iHandle,MOVE_START_STOP,0x00))) return SANE_FALSE;
212
		return (Hp_rts_Set_double_reg(iHandle, LCD_CONTROL1, reg_20, reg_21 ));
213
	};
214
	return SANE_TRUE;
215
}
216
217
/****************************************************************************/
218
SANE_Bool Hp44x0_write_cal_bytes( THWParams *pHWParams, SANE_Byte b ) {
219
/****************************************************************************/
220
  SANE_Word i,n;
221
  SANE_Int iHandle;
222
223
	DBG(DBG_SCAN, "Hp44x0_write_cal_bytes....\n");
224
  iHandle = pHWParams->iXferHandle;
225
  callibration_buffer[0]=0x89;
226
  callibration_buffer[1]=0x00;
227
  callibration_buffer[2]=0x00;
228
  callibration_buffer[3]=0x20;
229
  callibration_buffer[4]=0;
230
  n = 2;
231
  for(i=5;i<36;i++) {
232
     callibration_buffer[i]   = b;
233
     callibration_buffer[i+1] = n;
234
     i++;
235
     n = n + 2;
236
  }
237
  return (Hp_rts_BulkWrite(iHandle,0x00,callibration_buffer,36,SANE_FALSE));
238
}
239
240
241
/****************************************************************************/
242
SANE_Bool Hp44x0_cal_scanner(THWParams *pHWParams, TScanParams *pParams) {
243
/****************************************************************************/
244
  SANE_Word i,n;
245
  SANE_Int iHandle;
246
  SANE_Byte Reg_10, Reg_11;
247
248
	DBG(DBG_SCAN, "Hp44x0_cal_scanner....\n");
249
  iHandle = pHWParams->iXferHandle;
250
  if ( !(Hp_rts_RegWrite(iHandle,MOVE_START_STOP,0x00))) return SANE_FALSE;
251
  if ( !(Hp_rts_RegWrite(iHandle,MOVE_START_STOP,0x00))) return SANE_FALSE;
252
  memcpy(registers,Hp44x0_init_1,0xf4);
253
  if (pParams->mode == COLOR){
254
     Reg_10 = 0x28;
255
  } else {
256
     Reg_10 = 0x18;}
257
  if (pParams->optXPA){
258
     Reg_11 = 0x1b;
259
  } else {
260
     Reg_11 = 0x3b;}
261
  registers[0x10] = Reg_10;
262
  registers[0x11] = Reg_11;
263
  if ( !(Hp_rts_BulkWrite(iHandle,0x00,registers,0xb3,SANE_TRUE))) return SANE_FALSE;
264
  if ( !(Hp_rts_BulkWrite(iHandle,0xb4,registers+0xb3,0x3f,SANE_TRUE))) return SANE_FALSE;
265
  if ( !(Hp44x0_patch_and_send_values(iHandle,Hp44x0_patch_2))) return SANE_FALSE;
266
  if ( !(Hp44x0_patch_and_send_values(iHandle,Hp44x0_patch_3))) return SANE_FALSE;
267
268
/*  if (pParams->mode == COLOR){*/
269
     if ( !(Hp_rts_Set_double_reg(iHandle, LEDSTATUS, 0x20, 0x28))) return SANE_FALSE;
270
/*     usleep(10000);*/
271
     if ( !(Hp_rts_Set_double_reg(iHandle, LEDSTATUS, 0x28, 0x28))) return SANE_FALSE;
272
/*
273
  } else {
274
     if ( !(Hp_rts_Set_double_reg(iHandle, LEDSTATUS, 0x10, 0x28))) return SANE_FALSE;
275
     usleep(10000);
276
     if ( !(Hp_rts_Set_double_reg(iHandle, LEDSTATUS, 0x18, 0x28))) return SANE_FALSE;
277
  }
278
*/
279
  usleep(10000);
280
  if ( !(Hp_rts_RegWrite(iHandle,MOVE_START_STOP,0x02))) return SANE_FALSE;
281
  if ( !(Hp_rts_RegWrite(iHandle,MOVE_START_STOP,0x02))) return SANE_FALSE;
282
  if ( !(Hp_rts_RegWrite(iHandle,MOVE_START_STOP,0x00))) return SANE_FALSE;
283
  if ( !(Hp_rts_RegWrite(iHandle,MOVE_START_STOP,0x00))) return SANE_FALSE;
284
  if ( !(Hp_rts_RegWrite(iHandle,MOVE_START_STOP,0x00))) return SANE_FALSE;
285
  if ( !(Hp_rts_RegWrite(iHandle,MOVE_START_STOP,0x00))) return SANE_FALSE;
286
  if ( !(Hp44x0_patch_and_send_values(iHandle,Hp44x0_patch_4))) return SANE_FALSE;
287
288
  for (n=0;n<3;n++){
289
    switch (n){
290
      case 0: if ( !(Hp_rts_RegWrite(iHandle,0x93,0x06))) return SANE_FALSE; break;
291
      case 1: if ( !(Hp_rts_RegWrite(iHandle,0x93,0x02))) return SANE_FALSE; break;
292
      case 2: if ( !(Hp_rts_RegWrite(iHandle,0x93,0x01))) return SANE_FALSE; break;
293
      default:;
294
    }
295
    if ( !(Hp_rts_Set_double_reg(iHandle,0x91, 0x81, 0x00))) return SANE_FALSE;
296
    callibration_buffer[0]=0x89;
297
    callibration_buffer[1]=0x00;
298
    callibration_buffer[2]=0x08;
299
    callibration_buffer[3]=0x18;
300
    callibration_buffer[4]=0;
301
    for(i=5;i<0x818;i++) {
302
       callibration_buffer[i]=callibration_buffer[i-1]+1;
303
       if(callibration_buffer[i]==0x61) callibration_buffer[i]=0;
304
    };
305
    if ( !(Hp_rts_BulkWrite(iHandle,0x00,callibration_buffer,0x818+4,SANE_FALSE))) return SANE_FALSE;
306
    if ( !(Hp35x0c_set_sram_page(iHandle,0x81))) return SANE_FALSE;
307
/*    Hp_rts_Set_double_reg(iHandle,0x91, 0x81, 0x00);*/
308
    if ( !(Hp_rts_Read_Sram (iHandle, callibration_buffer,0x0818))) return SANE_FALSE;
309
#if 0
310
    read_bulk_callibriation_data(callibration_buffer,0x0818);
311
/*    read_bulk_callibriation_data(buffer2,0x0818); and verify it*/
312
#endif
313
	};
314
  memcpy(registers,Hp44x0_init_5,0xf4);
315
/*
316
  if (pParams->mode == COLOR){
317
     registers[LEDSTATUS] = 0x28;
318
  } else {
319
     registers[LEDSTATUS] = 0x18;
320
  }*/
321
  if ( !(Hp_rts_BulkWrite(iHandle,0x00,registers,0xb3,SANE_TRUE))) return SANE_FALSE;
322
  if ( !(Hp_rts_BulkWrite(iHandle,0xb4,registers+0xb3,0x3f,SANE_TRUE))) return SANE_FALSE;
323
324
  for(i=0;i<5;i++) {
325
    if ( !(Hp44x0_write_cal_bytes( pHWParams, i ))) return SANE_FALSE;
326
    if ( !(Hp_rts_Set_double_reg(iHandle, 0x91, 0x00, 0x10 ))) return SANE_FALSE;
327
/*    read_bulk_callibriation_data(buffer2,0x20); and verify it*/
328
  };
329
  if ( !(Hp_rts_RegWrite(iHandle,LAMPREG,0x80))) return SANE_FALSE;
330
  if ( !(Hp_rts_RegWrite(iHandle,LAMPREG,0xad))) return SANE_FALSE;
331
  if ( !(Hp_rts_Set_double_reg(iHandle, 0x14, 0x78, 0x28 ))) return SANE_FALSE;
332
  if ( !(Hp_rts_RegWrite(iHandle,LAMP_INTENSITY,0xa0))) return SANE_FALSE;
333
  if ( !(Hp_rts_RegWrite(iHandle,LAMP_INTENSITY,0xa7))) return SANE_FALSE;
334
  if ( !(Hp_rts_RegWrite(iHandle,LAMPREG,0x8d))) return SANE_FALSE;
335
  if ( !(Hp_rts_RegWrite(iHandle,LAMPREG,0xad))) return SANE_FALSE;
336
  if ( !(Hp_rts_RegWrite(iHandle,BUTTON_1,0x00))) return SANE_FALSE;
337
  if ( !(Hp_rts_RegWrite(iHandle,BUTTON_2,0x00))) return SANE_FALSE;
338
  if ( !(Hp_rts_RegWrite(iHandle,BUTTON_1,0x00))) return SANE_FALSE;
339
  if ( !(Hp_rts_RegWrite(iHandle,BUTTON_2,0x00))) return SANE_FALSE;
340
  if ( !(Hp_rts_RegWrite(iHandle,LAMP_INTENSITY,0xa0))) return SANE_FALSE;
341
  if ( !(Hp_rts_RegWrite(iHandle,LAMP_INTENSITY,0xa7))) return SANE_FALSE;
342
  if ( !(Hp_rts_RegWrite(iHandle,MOVE_START_STOP,0x00))) return SANE_FALSE;
343
  if ( !(Hp_rts_RegWrite(iHandle,MOVE_START_STOP,0x00))) return SANE_FALSE;
344
345
  if (pParams->mode == COLOR){
346
     if ( !(Hp_rts_Set_double_reg(iHandle, 0x10, 0x28, 0x3f))) return SANE_FALSE;
347
  } else {
348
     if ( !(Hp_rts_Set_double_reg(iHandle, 0x10, 0x18, 0x3f))) return SANE_FALSE;
349
  }
350
  usleep(10000);
351
  if ( !(Hp_rts_RegWrite(iHandle,LAMPREG,0xad))) return SANE_FALSE;
352
  usleep(10000);
353
/*  if (pParams->mode == COLOR){*/
354
     if ( !(Hp_rts_Set_double_reg(iHandle, LEDSTATUS, 0x20, 0x3f))) return SANE_FALSE;
355
/*  } else {
356
     if ( !(Hp_rts_Set_double_reg(iHandle, LEDSTATUS, 0x10, 0x3f))) return SANE_FALSE;
357
  }*/
358
  usleep(10000);
359
  return(SANE_TRUE);
360
}
361
362
363
/****************************************************************************/
364
SANE_Int Hp44x0_park_to_home(THWParams *pHWParams,TScanParams *pParams){
365
/* Moves scanner to home position */
366
/****************************************************************************/
367
	SANE_Int n,iHandle;
368
	SANE_Byte	buffer[0xffc0];
369
370
	iHandle = pHWParams->iXferHandle;
371
372
	DBG(DBG_SCAN, "Hp44x0_park_to_home....");
373
	/* make shure the scaner is stoped */
374
	if ( !(Hp_rts_stop_moving(iHandle))) return SANE_FALSE;
375
376
  if (Hp35x0c_is_rewound(iHandle )){
377
		DBG(DBG_SCAN,"i'm home\n");
378
/*	if(read_reg(iHandle,MICROSWITCH) & 0x02) {
379
		DBG(DBG_MSG,"i'm home\n");*/
380
		return(SANE_TRUE);
381
	} else {
382
		DBG(DBG_SCAN,"i must moving\n");
383
		memcpy(pHWParams->regs,Hp44x0_move_back,255);
384
/*
385
		pHWParams->regs[0x32] = 0x80;
386
		pHWParams->regs[0x33] = 0x81;
387
		pHWParams->regs[0x34] = 0x10;
388
		pHWParams->regs[0x35] = 0x10;
389
		pHWParams->regs[0x36] = 0x21; *0x24;*
390
		pHWParams->regs[0x39] = 0x02; * ??*
391
		pHWParams->regs[0x3A] = 0x0e;
392
		pHWParams->regs[0x60] = 0x40;
393
		pHWParams->regs[0x61] = 0x1f;
394
		pHWParams->regs[0x62] = 0x41;
395
		pHWParams->regs[0x63] = 0x1f;
396
		pHWParams->regs[0xb2] = 0x16;
397
		pHWParams->regs[0xe2-1] = 0x17; * StepSize */
398
		#if 1
399
		if (pParams->optXPA)
400
			pHWParams->regs[0x11] = pHWParams->regs[0x11] & 0xdf;
401
		else
402
			pHWParams->regs[0x11] = pHWParams->regs[0x11] | 0x02;
403
		#endif
404
		if ( !(Hp_rts_BulkWrite(iHandle,0x00,pHWParams->regs,0xb3,SANE_TRUE))) return SANE_FALSE;
405
		if ( !(Hp_rts_BulkWrite(iHandle,0xb4,pHWParams->regs+0xb3,0x3f,SANE_TRUE))) return SANE_FALSE;
406
		if ( !(Hp_rts_RegWrite(iHandle,0xd3,0x00))) return SANE_FALSE;
407
		if ( !(Hp_rts_start_moving(iHandle))) return SANE_FALSE;
408
		usleep(1000);
409
		while (!Hp35x0c_is_rewound(iHandle)  &&
410
/*			(Hp_rts_data_ready(iHandle,&n) ||*/
411
			 Hp_rts_is_moving(iHandle) > 0)
412
		{
413
			/*if ( !(*/Hp_rts_data_ready(iHandle,&n);/*)) return SANE_FALSE;*/
414
			if (n)
415
			{
416
				if (n > (SANE_Word)sizeof(buffer))
417
					n = sizeof(buffer);
418
				/*if ( !(*/Hp_rts_read_data(iHandle, n, buffer);/*)) return SANE_FALSE;*/
419
			}
420
			else
421
			{
422
				usleep(10000);
423
			}
424
		}
425
		return(Hp_rts_stop_moving(iHandle));
426
	}
427
}
428
429
/****************************************************************************/
430
SANE_Int Hp44x0_move_to_pos(THWParams *pHWParams, TScanParams *pParams){
431
/* Moves scanner to position */
432
/****************************************************************************/
433
	SANE_Int iHandle;
434
	SANE_Word pos;
435
	SANE_Int ypos;
436
	SANE_Byte r;
437
438
	iHandle = pHWParams->iXferHandle;
439
440
	ypos = MM_TO_PIXEL(pHWParams->iTopLeftY,pParams->iDpi);
441
	DBG(DBG_MSG,"Hp44x0_move_to_pos: %d dpi pParams->iY = %d pHWParams->iTopLeftY = %d ypos=%d \n",
442
							pParams->iDpi,(SANE_Int)pParams->iY,pHWParams->iTopLeftY,ypos);
443
444
	if (pParams->iDpi == 600)
445
		pos = ((pParams->iY) / 2 )+ ypos;
446
	else
447
		pos = (pParams->iY) + ypos;
448
	pos = pos / 2;
449
450
/*	DBG(DBG_MSG,"Hp44x0_move_to_pos: move to pos %d (pixel) %x (hex)\n",pos,pos-1);*/
451
452
	pHWParams->regs[0x33] = 0x81; /* 81 move fast, 82 lower */
453
	pHWParams->regs[0x36] = 0x29; /*29 fast; * 2C slow forward, 24 reverse */
454
	pHWParams->regs[0x3A] = 0x1b; /* 1b scan, 0e quick move */
455
	pHWParams->regs[0x60] = 0x01;
456
	pHWParams->regs[0x61] = 0x00;
457
	pHWParams->regs[0x62] = (pos+1) & 0xff;
458
	pHWParams->regs[0x63] = ((pos+1) >> 8) & 0xff;
459
	pHWParams->regs[0x65] = 0x00;  /* switch to move only (no scan)*/
460
	pHWParams->regs[0xE2-1] = 0x07 ; /* Stepsize */
461
	if (pParams->optXPA)
462
		pHWParams->regs[0x11] = pHWParams->regs[0x11] & 0xdf;
463
	else
464
		pHWParams->regs[0x11] = pHWParams->regs[0x11] | 0x02;
465
466
	usleep(10000);
467
#if 0
468
		printf("start_scan: start the moving!\n");
469
		Hp_rts_DumpHex(pHWParams->regs,252,16,SANE_TRUE);
470
#endif
471
	if ( !(Hp_rts_BulkWrite(iHandle,0x00,pHWParams->regs,0xb3,SANE_TRUE))) return SANE_FALSE;
472
	if ( !(Hp_rts_BulkWrite(iHandle,0xb4,pHWParams->regs+0xb3,0x3f,SANE_TRUE))) return SANE_FALSE;
473
	if ( !(Hp_rts_RegWrite(iHandle,0xd3,0x03))) return SANE_FALSE;
474
475
	if ( !(Hp_rts_start_moving(iHandle))) return SANE_FALSE;
476
	usleep(1000);
477
	
478
	/*DBG(DBG_MSG,"move_to_pos: check moving\n");*/
479
	r = 0x08;
480
	if ( Hp_rts_Check_Moving (iHandle)){
481
		while( r == 0x08){
482
			usleep(10000);
483
			usleep(10000);
484
			Hp_rts_RegRead(iHandle,MOVE_START_STOP, &r);
485
		}
486
		/*DBG(DBG_MSG,"move_to_pos: move finish\n");*/
487
	}else
488
	{
489
		DBG(DBG_ERR,"start_scan: Error, stop the moving!\n");
490
		Hp_rts_stop_moving(iHandle);
491
		return(SANE_FALSE);
492
	} 
493
	return(SANE_TRUE);
494
}
495
496
497
/****************************************************************************/
498
SANE_Int Hp44x0_wait_for_WarmUp(SANE_Int iHandle,THWParams *pHWParams){
499
/****************************************************************************/
500
  /* Reads 11 bytes and check the last one */
501
SANE_Char i;
502
#ifdef DEBUG_L
503
SANE_Char c;
504
#endif
505
	DBG(DBG_SCAN, "Hp44x0_wait_for_WarmUp....\n");
506
  /* we must here implement a wait loop for the lamp */
507
  if ( !(Hp_rts_BulkRead(iHandle,0x84,read_buffer,0x0b,SANE_TRUE))) return SANE_FALSE;
508
#ifdef DEBUG_L
509
  c = read_buffer[0xa];
510
  DBG(DBG_MSG,"wait_for_WarmUp: read %x\n",c);
511
  i = 1;
512
#else
513
  i = 15;
514
#endif
515
  if ( pHWParams->lamp_warm == SANE_FALSE ){
516
    while (i--){
517
      if ( !(Hp44x0_set_display( iHandle, i ))) return SANE_FALSE;
518
      sleep(1);
519
    }
520
    pHWParams->lamp_warm = SANE_TRUE;
521
  }
522
  return( /*(read_buffer[0xa] & 0x60) == 0x60*/ SANE_TRUE );
523
}
524
525
/****************************************************************************/
526
SANE_Bool Hp44x0_start_scan(THWParams *pHWParams, TScanParams *pParams,
527
								TDataPipe *pDataPipe){
528
/****************************************************************************/
529
#ifdef DEBUG
530
	SANE_Word lengtha1,lengtha2;
531
#endif
532
	SANE_Int brightness, iHandle;
533
	SANE_Int ires/*,result*/;
534
	SANE_Word x1,x2,length;
535
536
	iHandle = pHWParams->iXferHandle;
537
	brightness = 0;
538
539
	DBG(DBG_SCAN, "Hp44x0_start_scan....\n");
540
	DBG(DBG_MSG,"Hp44x0_start_scan: check resolution %d\n",pParams->iDpi);
541
	for (ires = 0; Hp44x0c_resparms[ires].resolution &&
542
		 Hp44x0c_resparms[ires].resolution != pParams->iDpi; ++ires);
543
	if (Hp44x0c_resparms[ires].resolution == 0){
544
		DBG(DBG_MSG,"start_scan:  did not found this resolution %d\n",pParams->iDpi);
545
		return SANE_FALSE;
546
	}
547
548
	DBG(DBG_MSG,"start_scan: Use ires entry %d (%ddpi) for the resolution %d dpi\n",ires,
549
			Hp44x0c_resparms[ires].resolution, pParams->iDpi);
550
551
	memcpy(pHWParams->regs,Hp44x0_myinit33,254);  /* CCD_Type 0*/
552
	
553
	if ( !(Hp44x0_move_to_pos(pHWParams,pParams))) return SANE_FALSE;
554
	x1 = pParams->iX;
555
	x2 = pParams->iWidth + pParams->iX;
556
	length = pParams->iLenght * 2;
557
	pDataPipe->iScanned = pParams->iLenght;
558
	DBG(DBG_MSG,"start_scan: calculate scandata x1 = %d; x2 = %d; lenght = %d\n",x1,x2,length);
559
560
	switch (pParams->mode) {
561
562
		case BLACK_WHITE:
563
			DBG(DBG_MSG,"Copy 300 DPI BW Regs\n");
564
			if (pParams->oCCD_Type){
565
				DBG(DBG_MSG,"Use CCD_Type 1 Regs\n");
566
				memcpy(pHWParams->regs,Hp44x0_300_BW_1,254);  /* CCD_Type 1*/
567
			}else{
568
				DBG(DBG_MSG,"Use CCD_Type 0 Regs\n");
569
				memcpy(pHWParams->regs,Hp44x0_myinit33,254);  /* CCD_Type 0*/
570
			}
571
			pHWParams->regs[0xD2 ]= 0x03;
572
			pHWParams->regs[0xD3 ]= 0x05;
573
			pHWParams->regs[0xE4 ]= 0x1c;
574
			pHWParams->regs[0xE5 ]= 0x10;
575
			pHWParams->regs[0xd5 ]= 0xab;/* ab gray */
576
			break;
577
578
		case GRAY:
579
			DBG(DBG_MSG,"Copy 300 DPI Regs\n");
580
			brightness = 0;
581
			if (pParams->oCCD_Type){
582
				DBG(DBG_MSG,"Use CCD_Type 1 Regs\n");
583
				memcpy(pHWParams->regs,Hp44x0_300_true_1_3,254); /* CCD_Type 1*/
584
			}else{
585
				DBG(DBG_MSG,"Use CCD_Type 0 Regs\n");
586
				memcpy(pHWParams->regs,Hp44x0_myinit33,254);  /* CCD_Type 0*/
587
			}
588
			if (pParams->iDpi == 600){
589
				DBG(DBG_MSG,"Patch to 600 DPI\n");
590
				Hp44x0_patch_regs(pHWParams,Hp44x0_patch_600);
591
				brightness = 43;
592
			}
593
			pHWParams->regs[0xd5 ]= 0xab;/* ab gray */
594
#if 1
595
			pHWParams->regs[0x08] = brightness + pParams->brightness;
596
			pHWParams->regs[0x09] = brightness + pParams->brightness;
597
			pHWParams->regs[0x0a] = brightness + pParams->brightness;
598
#endif
599
			#if 1
600
			if (pParams->optXPA)
601
				pHWParams->regs[0x11] = pHWParams->regs[0x11] & 0xdf;
602
			else
603
				pHWParams->regs[0x11] = pHWParams->regs[0x11] | 0x02;
604
			#endif
605
			break;
606
607
		case COLOR:
608
			DBG(DBG_MSG,"Copy 300 DPI Regs\n");
609
			if (pParams->oCCD_Type)
610
				memcpy(pHWParams->regs,Hp44x0_300_true_1_3,254); /* CCD_Type 1*/
611
			else
612
				memcpy(pHWParams->regs,Hp44x0_myinit33,254);  /* CCD_Type 0*/
613
614
			if (pParams->iDpi == 200){
615
				DBG(DBG_MSG,"Patch to 200 DPI\n");
616
				memcpy(pHWParams->regs,Hp44x0_200_TRUE_1,254);  /* CCD_Type 0*/
617
/*				Hp44x0_patch_regs(pHWParams,Hp44x0_200_TRUE_1);*/
618
			}
619
620
			if (pParams->iDpi == 300){
621
				DBG(DBG_MSG,"Patch to 300 DPI\n");
622
/*				memcpy(pHWParams->regs,Hp44x0_300_TRUE_1,254);  * CCD_Type 1*/
623
				Hp44x0_patch_regs(pHWParams,Hp44x0_patch_600);
624
			}
625
626
			if (pParams->iDpi == 600){
627
				DBG(DBG_MSG,"Patch to 600 DPI\n");
628
				Hp44x0_patch_regs(pHWParams,Hp44x0_patch_600);
629
			}
630
			pHWParams->regs[0xd5 ]= 0x0f;/* 0f color*/
631
			#if 1
632
			if (pParams->optXPA)
633
				pHWParams->regs[0x11] = pHWParams->regs[0x11] & 0xdf;
634
			else
635
				pHWParams->regs[0x11] = pHWParams->regs[0x11] | 0x02;
636
			#endif
637
#if 1
638
			pHWParams->regs[0x32 ]=  Hp44x0c_resparms[ires].reg_32_value;
639
			pHWParams->regs[0x33 ]=  Hp44x0c_resparms[ires].reg_33_value;
640
#endif
641
#if DEBUG_L
642
/*			pHWParams->regs[0xd5 ]= 0x1B;* 0f color*/
643
			/* horizon resolution */
644
			pHWParams->regs[0x10 ]=  Hp44x0c_resparms[ires].reg_10_value;
645
			pHWParams->regs[0x32 ]=  Hp44x0c_resparms[ires].reg_32_value;
646
			pHWParams->regs[0x33 ]=  Hp44x0c_resparms[ires].reg_33_value;
647
			pHWParams->regs[0x36 ]=  Hp44x0c_resparms[ires].reg_36_value;
648
			printf("pHWParams->regs[0xE1]= 0x%x to 0x%x\n",pHWParams->regs[0xE1],Hp44x0c_resparms[ires].step_size);
649
			pHWParams->regs[0xE1]= Hp44x0c_resparms[ires].step_size;
650
			#if 1
651
			printf("pHWParams->regs[0xE4]= 0x%x to 0x%x\n",pHWParams->regs[0xE4],Hp44x0c_resparms[ires].reg_E4_value);
652
			pHWParams->regs[0xE4]=  Hp44x0c_resparms[ires].reg_E4_value;
653
			printf("pHWParams->regs[0xE5]= 0x%x to 0x%x\n",pHWParams->regs[0xE5],Hp44x0c_resparms[ires].reg_E5_value);
654
			pHWParams->regs[0xE5]=  Hp44x0c_resparms[ires].reg_E5_value;
655
			#endif
656
			#if 1
657
			/* color releated */
658
			pHWParams->regs[0x72 ]=  Hp44x0c_resparms[ires].reg_72_value;
659
			pHWParams->regs[0x73 ]=  Hp44x0c_resparms[ires].reg_73_value;
660
			pHWParams->regs[0x74 ]=  Hp44x0c_resparms[ires].reg_74_value;
661
			#endif
662
			#if 1
663
			pHWParams->regs[0x11 ]=  Hp44x0c_resparms[ires].reg_11_value;
664
			pHWParams->regs[0x3a ]= 0x0e;/* for test*/
665
			/*	pHWParams->regs[0xCC ]=  Hp44x0c_resparms[ires].reg_CC_value;
666
			pHWParams->regs[0xCD ]=  Hp44x0c_resparms[ires].reg_CD_value;
667
			pHWParams->regs[0xCE ]=  Hp44x0c_resparms[ires].reg_CE_value;
668
			pHWParams->regs[0xCF ]=  Hp44x0c_resparms[ires].reg_CF_value;
669
			pHWParams->regs[0xd0 ]=  Hp44x0c_resparms[ires].reg_D0_value;*/
670
			/*	pHWParams->regs[0xd7 ]=  Hp44x0c_resparms[ires].reg_D7_value;
671
			pHWParams->regs[0xC4 ]=  Hp44x0c_resparms[ires].reg_C4_value; * colors ? *
672
			pHWParams->regs[0xC5 ]=  Hp44x0c_resparms[ires].reg_C5_value; * colors ? *
673
			pHWParams->regs[0xd5 ]=  Hp44x0c_resparms[ires].reg_D5_value;
674
675
			pHWParams->regs[0x35 ]=  Hp44x0c_resparms[ires].reg_35_value;
676
			pHWParams->regs[0x3A ]=  Hp44x0c_resparms[ires].reg_3A_value; */
677
			#endif
678
			/* vertical resolution */
679
			#if 0
680
			pHWParams->regs[0x3A ]=  Hp44x0c_resparms[ires].reg_3A_value;
681
			#endif
682
/*			pHWParams->regs[0x02 ]= 0xbb;
683
			pHWParams->regs[0x03 ]= 0x7d;
684
			pHWParams->regs[0x04 ]= 0x3e;
685
			pHWParams->regs[0x05 ]= 0xbb;
686
			pHWParams->regs[0x06 ]= 0x7d;
687
			pHWParams->regs[0x07 ]= 0x3e;
688
689
			pHWParams->regs[0x08 ]= 0x00;
690
			pHWParams->regs[0x09 ]= 0x00;
691
			pHWParams->regs[0x0a ]= 0x00;*/
692
693
			pHWParams->regs[0xBF ]=  Hp44x0c_resparms[ires].reg_BF_value;
694
			pHWParams->regs[0xC0 ]=  Hp44x0c_resparms[ires].reg_C0_value;
695
			pHWParams->regs[0xC1 ]=  Hp44x0c_resparms[ires].reg_C1_value;
696
			pHWParams->regs[0xc2 ]= 0xff;/* for test*/
697
			pHWParams->regs[0xc3 ]= 0x00;/* for test*/
698
			pHWParams->regs[0xc4 ]= 0xf0;/* for test*/
699
			pHWParams->regs[0xc5 ]= 0x00;/* for test*/
700
			pHWParams->regs[0xc6 ]= 0x7f;/* for test*/
701
			pHWParams->regs[0xc7 ]= 0x0f;/* for test*/
702
/*			pHWParams->regs[0xc9 ]= 0xff;* for test*/
703
			pHWParams->regs[0xca ]= 0xf1;/* for test*/
704
			pHWParams->regs[0xcb ]= 0xff;/* for test*/
705
			pHWParams->regs[0xcc ]= 0x00;/* for test*/
706
			pHWParams->regs[0xcd ]= 0xf0;/* for test*/
707
			pHWParams->regs[0xce ]= 0xed;/* for test*/
708
			pHWParams->regs[0xcf ]= 0xef;/* for test*/
709
			pHWParams->regs[0xd0 ]= 0xe2;/* for test*/
710
/*			pHWParams->regs[0xd1 ]=  Hp44x0c_resparms[ires].reg_D1_value;
711
			pHWParams->regs[0xd2 ]=  Hp44x0c_resparms[ires].reg_D2_value;
712
			pHWParams->regs[0xd3 ]=  Hp44x0c_resparms[ires].reg_D3_value;*/
713
			pHWParams->regs[0xd1 ]= 0x03;/* for test*/
714
			pHWParams->regs[0xd2 ]= 0x17;/* for test*/
715
			pHWParams->regs[0xd3 ]= 0x01;/* for test*/
716
			pHWParams->regs[0xd6 ]= 0x10;/* for test*/
717
718
			pHWParams->regs[0x80 ]= 0x2b;/* for test*/
719
			pHWParams->regs[0x81 ]= 0x02;/* for test*/
720
			pHWParams->regs[0x82 ]= 0x2C;/* for test*/
721
			pHWParams->regs[0x83 ]= 0x02;/* for test*/
722
			pHWParams->regs[0x85 ]= 0x18;/* for test*/
723
			pHWParams->regs[0x86 ]= 0x1b;/* for test*/
724
			pHWParams->regs[0x87 ]= 0x30;/* for test*/
725
			pHWParams->regs[0x88 ]= 0x30;/* for test*/
726
			pHWParams->regs[0x89 ]= 0x2d;/* for test*/
727
			pHWParams->regs[0x8a ]= 0x02;/* for test*/
728
			pHWParams->regs[0x8d ]= 0x21;/* for test*/
729
			pHWParams->regs[0x8e ]= 0x60;/* for test*/
730
#endif
731
		break;
732
733
		default:
734
			DBG(DBG_ERR, "Hp44x0_init_scan: Invalid parameter\n");
735
			return SANE_FALSE;
736
	}/* switch */
737
738
739
740
741
#if 0
742
	if (pParams->optXPA)
743
		pHWParams->regs[0x11] = pHWParams->regs[0x11] & 0xdf;
744
	else
745
		pHWParams->regs[0x11] = pHWParams->regs[0x11] | 0x02;
746
#endif
747
748
#if 0
749
	if (pParams->mode == COLOR)
750
		pHWParams->regs[0xd5 ]= 0x0f;/* 0f color*/
751
	else
752
		pHWParams->regs[0xd5 ]= 0xab;/* ab gray */
753
#endif
754
755
	/* modify reg 60 + 61 */
756
	Hp_rts_set_noscan_distance(pHWParams->regs, 0x01 );
757
	/* modify reg 62 + 63 */
758
#if 1
759
	Hp_rts_set_total_distance(pHWParams->regs, length+1 );
760
#endif
761
#if 0
762
	Hp_rts_set_total_distance(pHWParams->regs, 0x02 );
763
#endif
764
765
	pHWParams->regs[0x65]= 0x20; /* Schan mode on */
766
767
	/* modify reg 66 + 67 */
768
	Hp_rts_set_scanline_start(pHWParams->regs, x1 );
769
	/* modify reg 6C + 6D */
770
	Hp_rts_set_scanline_end(pHWParams->regs, x2 );
771
772
	#ifdef DEBUG
773
		lengtha1 = 0;
774
		lengtha2 = 0;
775
		lengtha1 = pHWParams->regs[0x60];
776
		lengtha1 = lengtha1 + ((pHWParams->regs[0x61] <<8) & 0xFF00);
777
		lengtha2 = pHWParams->regs[0x62];
778
		lengtha2 = lengtha2 + ((pHWParams->regs[0x63] <<8) & 0xFF00);
779
		DBG(DBG_MSG,"start_scan: Init scan_region: dpi=%d iLenght=%d, iScanned=%d lenght=%d mode=%x xPDA=%x\n",
780
		pParams->iDpi,pParams->iLenght,pDataPipe->iScanned,length,pParams->mode,pParams->optXPA);
781
		#endif
782
783
#if 0
784
	pHWParams->regs[0xDA-1]= pParams->intensity2; /* Lamp density */
785
#endif
786
787
788
#if 0  /* do not use by graymode ! */
789
		pHWParams->regs[0x05] = 0x20 - pParams->GainR;
790
		pHWParams->regs[0x06] = 0x20 - pParams->GainG;
791
		pHWParams->regs[0x07] = 0x20 - pParams->GainB;
792
#endif
793
794
#if 0
795
		pHWParams->regs[0x08] = 0x20 - pParams->GainR;
796
		pHWParams->regs[0x09] = 0x20 - pParams->GainG;
797
		pHWParams->regs[0x0a] = 0x20 - pParams->GainB;
798
#endif
799
800
#if 0  /* moved to graymode */
801
	pHWParams->regs[0x08] = /*0x20 -*/ pParams->brightness;
802
	pHWParams->regs[0x09] = /*0x20 -*/ pParams->brightness;
803
	pHWParams->regs[0x0a] = /*0x20 -*/ pParams->brightness;
804
#endif
805
#if 0
806
		printf("start_scan: start the scanner!\n");
807
		Hp_rts_DumpHex(pHWParams->regs,255,16,SANE_TRUE);
808
#endif
809
810
	if ( !(Hp_rts_Set_double_reg(iHandle,0x10,pHWParams->regs[0x10],pHWParams->regs[0x11]))) return SANE_FALSE;
811
	usleep(10000);
812
813
	if ( !(Hp_rts_BulkWrite(iHandle,0x00,pHWParams->regs,0xb3,SANE_TRUE))) return SANE_FALSE;
814
	if ( !(Hp_rts_BulkWrite(iHandle,0xb4,pHWParams->regs+0xb3,0x3f,SANE_TRUE))) return SANE_FALSE;
815
#if 0
816
	if (pParams->mode == BLACK_WHITE)
817
		Hp_rts_RegWrite(iHandle,0xd3,0x17);
818
	else
819
		Hp_rts_RegWrite(iHandle,0xd3,0x03);
820
#endif
821
#if 0
822
	DBG(DBG_MSG,"pHWParams->regs[0xd3]= 0x%x to 0x%x\n",
823
		pHWParams->regs[0xd3-1],pHWParams->regs[0xd3-1]);
824
#endif	
825
	if ( !(Hp_rts_RegWrite(iHandle,0xd3,pHWParams->regs[0xd3-1]))) return SANE_FALSE;
826
827
	if ( !(Hp_rts_start_moving(iHandle))) return SANE_FALSE;
828
	usleep(10000);
829
	/* wait for moving and check it */
830
	return(Hp_rts_Check_Moving (iHandle));
831
}
832
833
834
/****************************************************************************/
835
SANE_Bool Hp44x0_init_scan(THWParams *pHWParams, TScanParams *pParams,
836
													TDataPipe *pDataPipe){
837
/****************************************************************************/
838
839
	SANE_Int iHandle;
840
	SANE_Int	ires;
841
842
	iHandle = pHWParams->iXferHandle;
843
	DBG(DBG_MSG,"Hp44x0_init_scan: check resolution %d\n",pParams->iDpi);
844
	for (ires = 0; Hp44x0c_resparms[ires].resolution &&
845
								 Hp44x0c_resparms[ires].resolution != pParams->iDpi; ++ires);
846
	if (Hp44x0c_resparms[ires].resolution == 0){
847
		DBG(DBG_MSG,"Hp44x0_init_scan: this resolution %d not found\n",pParams->iDpi);
848
		return SANE_FALSE;
849
	}
850
851
	if ( !(Hp_rts_RegWrite(iHandle,LAMP_INTENSITY,0xa7))) return SANE_FALSE;
852
	if ( !(Hp_rts_RegWrite(iHandle,LAMP_INTENSITY,0xa0))) return SANE_FALSE;
853
	if ( !(Hp_rts_RegWrite(iHandle,LAMP_INTENSITY,0xa7))) return SANE_FALSE;
854
	if ( !(Hp_rts_RegWrite(iHandle,0xb3,0x01))) return SANE_FALSE;
855
	if ( !(Hp_rts_RegWrite(iHandle,0xb3,0x01))) return SANE_FALSE;
856
	if ( !(Hp_rts_RegWrite(iHandle,0xb3,0x00))) return SANE_FALSE;
857
	if ( !(Hp_rts_RegWrite(iHandle,0xb3,0x00))) return SANE_FALSE;
858
	if ( !(Hp_rts_Set_double_reg(iHandle, 0x12, 0xff, 0x20 ))) return SANE_FALSE;
859
	if ( !(Hp_rts_Set_double_reg(iHandle, 0x14, 0xf8, 0x28 ))) return SANE_FALSE;
860
	if ( !(Hp_rts_RegWrite(iHandle,0xb3,0x00))) return SANE_FALSE;
861
	if ( !(Hp_rts_RegWrite(iHandle,0xb3,0x00))) return SANE_FALSE;
862
863
	memcpy(pHWParams->regs,Hp44x0_init_1,0xf4);
864
	pHWParams->regs[0x10 ]=  Hp44x0c_resparms[ires].reg_10_value;
865
	pHWParams->regs[0x11 ]=  Hp44x0c_resparms[ires].reg_11_value;
866
867
	if (pParams->optXPA)
868
		pHWParams->regs[0x11] = pHWParams->regs[0x11] & 0xdf;
869
	else
870
		pHWParams->regs[0x11] = pHWParams->regs[0x11] | 0x02;
871
872
	if ( !(Hp_rts_Set_double_reg(iHandle,0x10,pHWParams->regs[0x10],
873
																		pHWParams->regs[0x11]))) return SANE_FALSE;
874
	usleep(10000);
875
	if ( !(Hp_rts_RegWrite(iHandle,0xd9,0x80))) return SANE_FALSE;
876
877
	#ifndef WITH_TSTBACKEND
878
	if ( !(Hp44x0_wait_for_WarmUp(iHandle,pHWParams))) return SANE_FALSE;
879
	#endif
880
881
	if ( !(Hp_rts_BulkWrite(iHandle,0x00,pHWParams->regs,0xb3,SANE_TRUE))) return SANE_FALSE;
882
	if ( !(Hp_rts_BulkWrite(iHandle,0xb4,pHWParams->regs+0xb3,0x3f,SANE_TRUE))) return SANE_FALSE;
883
884
	if ( !(Hp_rts_RegWrite(iHandle,LAMP_INTENSITY,0xa7))) return SANE_FALSE;
885
	if ( !(Hp_rts_RegWrite(iHandle,0xd9,0x8d))) return SANE_FALSE;
886
	if ( !(Hp_rts_RegWrite(iHandle,0xd9,0xad))) return SANE_FALSE;
887
	if ( !(Hp_rts_RegWrite(iHandle,0xb3,0x00))) return SANE_FALSE;
888
	if ( !(Hp_rts_RegWrite(iHandle,0xb3,0x00))) return SANE_FALSE;
889
	/*  test_double_reg( LEDSTATUS, 0x28, 0x3f, 7 );  */
890
	usleep(10000);
891
	if ( !(Hp_rts_Set_double_reg(iHandle,0x10,pHWParams->regs[0x10],
892
																		pHWParams->regs[0x11]))) return SANE_FALSE;
893
	/*  if ( !(test_double_reg( LEDSTATUS, 0x28, 0x3f, 8 );  */
894
	if ( !(Hp_rts_RegWrite(iHandle,0xd9,0xad))) return SANE_FALSE;
895
896
	return(Hp44x0_start_scan(pHWParams,pParams,pDataPipe));
897
}
898
899
900
901
/****************************************************************************/
902
/*  Lamp control functions                                                  */
903
SANE_Bool Hp44x0_GetLamp(SANE_Int iHandle, SANE_Bool *pfLampIsOn)
904
/****************************************************************************/
905
{
906
	SANE_Byte bData;
907
908
	DBG(DBG_SCAN, "Hp44x0_GetLamp....\n");
909
	if ( !(Hp_rts_RegRead(iHandle, LAMPREG, &bData))) return SANE_FALSE;
910
	*pfLampIsOn = ((bData & 0x80) != 0);
911
	return SANE_TRUE;
912
}
913
914
915
/****************************************************************************/
916
SANE_Bool Hp44x0_SetLamp(SANE_Int iHandle, SANE_Bool fLampOn)
917
/****************************************************************************/
918
{
919
	SANE_Byte bData;
920
921
	DBG(DBG_SCAN, "Hp44x0_SetLamp....\n");
922
	if ( !(Hp_rts_RegRead(iHandle, LAMPREG, &bData))) return SANE_FALSE;
923
	if (fLampOn) {
924
		if ( !(Hp_rts_RegWrite(iHandle, LAMPREG, bData | 0x80))) return SANE_FALSE;
925
	}
926
	else {
927
		if ( !(Hp_rts_RegWrite(iHandle, LAMPREG, bData & ~0x80))) return SANE_FALSE;
928
	}
929
	return SANE_TRUE;
930
}
931
932
933
/****************************************************************************/
934
SANE_Int
935
Hp44x0c_nvram_enable_controller(SANE_Int iHandle,SANE_Int enable)
936
/****************************************************************************/
937
{
938
	SANE_Byte r;
939
940
	DBG(DBG_SCAN, "Hp44x0c_nvram_enable_controller....\n");
941
	if ( !(Hp_rts_RegRead(iHandle, 0x1d, &r))) return SANE_FALSE;
942
	if (enable)
943
		r |= 1;
944
	else
945
		r &= ~1;
946
	return Hp_rts_RegWrite(iHandle,0x1d, r);
947
948
}
949
(-)sane-backends-1.0.19/backend/hp_rts_44x0c.h (+485 lines)
Line 0 Link Here
1
 /* sane - Scanner Access Now Easy.
2
   Copyright (C) 2003 Johannes Hub (JohannesHub@t-online.de)
3
4
   This file was initially copied from the hp3300 backend.
5
   This file is part of the SANE package.
6
7
   This program is free software; you can redistribute it and/or
8
   modify it under the terms of the GNU General Public License
9
   as published by the Free Software Foundation; either version 2
10
   of the License, or (at your option) any later version.
11
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21
   As a special exception, the authors of SANE give permission for
22
   additional uses of the libraries contained in this release of SANE.
23
24
   The exception is that, if you link a SANE library with other files
25
   to produce an exutable, this does not by itself cause the
26
   resulting executable to be covered by the GNU General Public
27
   License.  Your use of that executable is in no way restricted on
28
   account of linking the SANE library code into it.
29
30
   This exception does not, however, invalidate any other reasons why
31
   the executable file might be covered by the GNU General Public
32
   License.
33
34
   If you submit changes to SANE to the maintainers to be included in
35
   a subsequent release, you agree by submitting the changes that
36
   those changes may be distributed with this exception intact.
37
38
   If you write modifications of your own for SANE, it is your choice
39
   whether to permit this exception to apply to your modifications.
40
   If you do not wish that, delete this exception notice.
41
*/
42
43
/*
44
    Concept for a backend for scanners based on the RTS88xx chipset,
45
    such as HP4400C, HP4470C.
46
    Parts of this source were inspired by other backends.
47
48
		History:
49
50
		Version 0.18  21.11.04 13.alpha,
51
				- source sorted,
52
				- now only SANEI_USB_SUPPORT for a better overview(xfermodules removed)
53
				- read and verify the MainBoardID 
54
		Version 0.17p 02.11.04 12.alpha, source sorted, little fixes, SANEI_USB_SUPPORT implemented
55
		Version 0.17p 02.11.04 12.alpha, source sourted, little fixes, SANEI_USB_SUPPORT implemented
56
		Version 0.17b 30.03.04 10.alpha, little fixes and libusb implemented
57
		Version 0.17  09.03.04 9. alpha, HP3500 included
58
		Version 0.16  06.02.04 8. alpha, wait counting on LCD
59
		Version 0.15a 29.01.04 7. alpha, CCD switch moved to config file
60
		Version 0.15  11.01.04 6. alpha, a second CCD implemented
61
		Version 0.13a 21.11.04 4. alpha, an little fix included
62
		Version 0.12  22.10.03 third alpha, Backend name changed to HP_RTS88xx
63
		Version 0.11  30.08.03 second alpha
64
		Version 0.10  19.07.03 first alpha
65
*/
66
67
/*
68
    Core HP44x0c functions.
69
*/
70
71
72
#ifndef _HP_RTS_HP44x0C_H_
73
#define _HP_RTS_HP44x0C_H_
74
75
#include <unistd.h>
76
77
#define XFER_BUF_SIZE  0xFF00
78
79
80
#define HW_PIXELS   2000   /* number of pixels supported by hardware */
81
#define HW_DPI      300    /* horizontal resolution of hardware */
82
#define HW_LPI      300    /* vertical resolution of hardware */
83
84
/* thise rts8891 registers are known */
85
#define LEDSTATUS            0x10
86
#define LIGHT_SOURCE         0x11
87
#define TAP                  0x14
88
#define LCD_CONTROL1         0x20
89
#define LCD_CONTROL2         0x21
90
#define LCD_CONTROL3         0x22
91
#define BUTTON_1             0x25
92
#define BUTTON_2             0x1a
93
#define MICROSWITCH          0x1d
94
#define MOVEMENT_DIRECTION   0x36
95
#define SCAN_OR_QUICK_MOVE   0x3a
96
#define CHECK_SCANNER_LINKED 0xb0
97
#define MAINBOARD_ID         0xb1
98
#define MOVEMENT_REG_1       0xb2
99
#define MOVE_START_STOP      0xb3
100
#define LAMPREG              0xd9
101
#define LAMP_INTENSITY       0xda
102
#define STEP_SIZE            0xe1
103
104
struct	Hp44x0c_resolution_parameters
105
{
106
	SANE_Int	resolution;
107
	SANE_Byte		reg_10_value;
108
	SANE_Byte		reg_11_value;
109
	SANE_Byte		reg_32_value;
110
	SANE_Byte		reg_33_value;
111
	SANE_Byte		reg_35_value;
112
	SANE_Byte		reg_36_value;
113
	SANE_Byte		reg_3A_value;
114
	SANE_Byte		reg_72_value;
115
	SANE_Byte		reg_73_value;
116
	SANE_Byte		reg_74_value;
117
	SANE_Byte		reg_BF_value;
118
	SANE_Byte		reg_C0_value;
119
	SANE_Byte		reg_C1_value;
120
	SANE_Byte		reg_C4_value;
121
	SANE_Byte		reg_C5_value;
122
	SANE_Byte		reg_CC_value;
123
	SANE_Byte		reg_CD_value;
124
	SANE_Byte		reg_CE_value;
125
	SANE_Byte		reg_CF_value;
126
	SANE_Byte		reg_D0_value;
127
	SANE_Byte		reg_D1_value;
128
	SANE_Byte		reg_D2_value;
129
	SANE_Byte		reg_D3_value;
130
	SANE_Byte		reg_D5_value;
131
	SANE_Byte		reg_D7_value;
132
	SANE_Byte		step_size;
133
	SANE_Byte		reg_E4_value;
134
	SANE_Byte		reg_E5_value;
135
};
136
137
static struct Hp44x0c_resolution_parameters Hp44x0c_resparms[] =
138
{
139
/*res. 10   11   32  33   35   36   3a   72   73   74   bf   c0   c1   c5   cb   cc   cd   ce   cf   d0   d1   d2   d3   d5   d7 Step   e4  e5*/
140
/*             0x00,0x03,0x45,     0x43 */
141
{600,0x28,0x3b,0x80,0x82,0x1b,0x2C,0x1b,0x3a,0x15,0x62,0x00,0xff,0x0f,0xf8,0x07,0x80,0xff,0xf2,0xf4,0xe7,0x08,0x0e,0x10,0x0f,0x52,0x01,0x56,0x01},
142
{300,0x20,0x3b,0x80,0x82,0x0e,0x22,0x0e,0xe1,0x14,0x18,0xff,0x0f,0xf0,0x00,0x00,0xf0,0xff,0xf5,0xf7,0xea,0x0b,0x03,0x05,0xab,0xf6,0x01,0x56,0x01},
143
{200,0x20,0x3b,0x00,0x03,0x0e,0x22,0x0e,0xe1,0x14,0x18,0xff,0x0f,0xf0,0x00,0x00,0xf0,0xff,0xf5,0xf7,0xea,0x0b,0x03,0x05,0xab,0xf6,0x01,0xbd,0x0a},
144
{150,0x20,0x3f,0x80,0x81,0x1b,0x29,0x1b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01},
145
{0,  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
146
};
147
148
149
150
SANE_Byte Hp44x0_switch_on_regs[] = {
151
/*0    1    2    3    4    5    6    7    8    9    a    b    c    d    e    f*/
152
0xe5,0x41,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x0a,0x0a,0x0a,0x70,0x00,0x00,0x00,0x00,
153
/*10   11   12   13   14   15   16   17   18   19   1a   1b   1c   1d   1e   1f*/
154
0x28,0x28,0xff,0x20,0xf8,0x28,0x07,0x00,0xff,0x00,0x00,0x00,0x00,0x20,0x00,0x00,
155
/*20   21   22   23   24   25   26   27   28   29   2a   2b   2c   2d   2e   2f*/
156
0x3a,0xf2,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
157
/*30   31   32   33   34   35   36   37   38   39   3a   3b   3c   3d   3e   3f*/
158
0x00,0x00,0x00,0x00,0x10,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
159
/*40 41   42   43   44   45   46   47   48   49   4a   4b   4c   4d   4e   4f*/
160
0x20,0x00,0x00,0x00,0x8c,0x76,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
161
/*50   51   52   53   54   55   56   57   58   59   5a   5b   5c  5d   5e   5f*/
162
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
163
/*60   61   62   63   64   65   66   67   68   69   6a   6b   6c   6d   6e   6f*/
164
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
165
/*70   71   72   73   74   75   76   77   78   79   7a   7b   7c   7d   7e   7f*/
166
0x00,0x00,0xe1,0x14,0x18,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
167
/*80   81   82   83   84   85   86   87   88   89   8a   8b   8c   8d   8e   8f*/
168
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x3f,0x80,0x68,0x00,
169
/*90   91   92   93   94   95   96   97   98   99   9a   9b   9c   9d   9e   9f*/
170
0x00,0x00,0x00,0x01,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
171
/*a0   a1   a2   a3   a4   a5   a6   a7   a8   a9   aa   ab   ac   ad   ae   af*/
172
0x00,0x00,0x00,0xcc,0x27,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
173
/*b0   b1   b2   b3   b4   b5   b6   b7   b8   b9   ba   bb   bc   bd   be   bf*/
174
0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
175
/*c0   c1   c2   c3   c4   c5   c6   c7   c8   c9   ca   cb   cc   cd   ce   cf*/
176
0x0f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x0e,0x00,0x00,0xf0,0xff,0xf5,0xf7,
177
/*d0   d1   d2   d3   d4   d5   d6   d7   d8   d9   da   db   dc   dd   de   df*/
178
0xea,0x0b,0x03,0x05,0x86,0x1b,0x30,0xf6,0xad,0x27,0x00,0x00,0x00,0x00,0x00,0x00,
179
/*e0   e1   e2   e3   e4   e5   e6   e7   e8   e9   ea   eb   ec   ed   ee   ef*/
180
0x00,0x01,0x00,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
181
/*f0   f1   f2*/
182
0x00,0x00,0x00};
183
184
SANE_Byte Hp44x0_move_back[] = {
185
0xf5,0x41,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x10,0x10,0x10,0x70,0x00,0x00,0x00,0x00,
186
0x20,0x28,0xff,0x20,0xf8,0x28,0x07,0x00,0xff,0x00,0x00,0x00,0x00,0x20,0x00,0x00,
187
0x3a,0xf2,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
188
0x00,0x00,0x80,0x81,0x10,0x10,0x24,0x00,0x00,0x02,0x0e,0x00,0x00,0x00,0x00,0x00,
189
0x20,0x00,0x00,0x00,0x8c,0x76,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
190
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
191
0x40,0x1f,0x41,0x1f,0x01,0x20,0x64,0x00,0x00,0x00,0x00,0x00,0xc8,0x00,0x00,0x00,
192
0x00,0x00,0xe1,0x14,0x18,0x15,0x00,0x00,0x00,0x20,0x01,0x00,0x00,0x00,0x00,0x00,
193
0x32,0x00,0x33,0x00,0x00,0x00,0x06,0x00,0x06,0x34,0x00,0xff,0x3f,0x80,0x68,0x00,
194
0x1c,0x00,0x00,0x01,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
195
0x00,0x00,0x00,0xcc,0x27,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
196
0x00,0x00,0x16,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
197
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
198
0x00,0x00,0x00,0x00,0x86,0x6b,0x00,0x00,0x80,0x27,0x00,0x00,0x00,0x00,0x00,0x00,
199
0x00,0x17,0x0d,0x06,0xf9,0x00,0x53,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
200
0x00,0x00,0x00};
201
202
SANE_Byte Hp44x0_init_1[] = {
203
0xe5,0x41,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x0a,0x0a,0x0a,0x70,0x00,0x00,0x00,0x00,
204
0x60,0x3b,0x00,0x20,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,
205
0x3a,0xf2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
206
0x00,0x00,0x00,0x00,0x10,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
207
0x20,0x00,0x00,0x00,0x8c,0x76,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
208
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
209
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
210
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
211
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x68,0x00,
212
0x00,0x00,0x00,0x02,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
213
0x00,0x00,0x00,0xcc,0x27,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
214
0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
215
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
216
0x00,0x00,0x00,0x00,0x86,0x1b,0x00,0xff,0x00,0x27,0x00,0x00,0x00,0x00,0x00,0x00,
217
0x00,0x01,0x00,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
218
0x00,0x00,0x00};
219
220
SANE_Byte Hp44x0_init_5[] = {
221
0xe5,0x41,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x0a,0x0a,0x0a,0x70,0x00,0x00,0x00,0x00,
222
0x28,0x28,0xff,0x20,0xf8,0x28,0x07,0x00,0xff,0x00,0x00,0x00,0x00,0x20,0x00,0x00,
223
0x3a,0xf2,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
224
0x00,0x00,0x00,0x00,0x10,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
225
0x20,0x00,0x00,0x00,0x8c,0x76,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
226
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
227
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
228
0x00,0x00,0xe1,0x14,0x18,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
229
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x68,0x00,
230
0x00,0x00,0x00,0x01,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
231
0x00,0x00,0x00,0xcc,0x27,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
232
0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
233
0x0f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x0e,0x00,0x00,0xf0,0xff,0xf5,0xf7,
234
0xea,0x0b,0x03,0x05,0x86,0x1b,0x30,0xf6,0x80,0x27,0x00,0x00,0x00,0x00,0x00,0x00,
235
0x00,0x01,0x00,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
236
0x00,0x00,0x00};
237
238
SANE_Byte Hp44x0_myinit33[] = {
239
/*0    1    2    3    4    5    6    7    8    9    a    b    c    d    e    f*/
240
0xe5,0x41,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x10,0x10,0x10,0x70,0x00,0x00,0x00,0x00,
241
/*10   11   12   13   14   15   16   17   18   19   1a   1b   1c   1d   1e   1f*/
242
0x20,0x3f,0xff,0x20,0xf8,0x28,0x07,0x00,0xff,0x00,0x00,0x00,0x00,0x20,0x00,0x00,
243
/*20   21   22   23   24   25   26   27   28   29   2a   2b   2c   2d   2e   2f*/
244
0x3a,0xf2,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
245
/*30   31   32   33   34   35   36   37   38   39   3a   3b   3c   3d   3e   3f*/
246
0x00,0x00,0x80,0x81,0x10,0x1b,0x29,0x00,0x00,0x02,0x1b,0x00,0x00,0x00,0x00,0x00,
247
/*40   41   42   43   44   45   46   47   48   49   4a   4b   4c   4d   4e   4f*/
248
0x20,0x00,0x00,0x00,0x8c,0x76,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
249
/*50   51   52   53   54   55   56   57   58   59   5a   5b   5c  5d   5e   5f*/
250
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
251
/*60   61   62   63   64   65   66   67   68   69   6a   6b   6c   6d   6e   6f*/
252
0x12,0x00,0xc6,0x00,0x01,0x20,0x2c,0x01,0x00,0x00,0x00,0x00,0xdc,0x05,0x00,0x00,
253
/*70   71   72   73   74   75   76   77   78   79   7a   7b   7c   7d   7e   7f*/
254
0x00,0x00,0xe1,0x14,0x18,0x15,0x00,0x00,0x00,0x20,0x01,0x00,0x00,0x00,0x00,0x00,
255
/*80   81   82   83   84   85   86   87   88   89   8a   8b   8c   8d   8e   8f*/
256
0x32,0x00,0x33,0x00,0x00,0x00,0x06,0x00,0x06,0x34,0x00,0xff,0x3f,0x80,0x68,0x00,
257
/*90   91   92   93   94   95   96   97   98   99   9a   9b   9c   9d   9e   9f*/
258
0x1c,0x00,0x00,0x01,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
259
/*a0   a1   a2   a3   a4   a5   a6   a7   a8   a9   aa   ab   ac   ad   ae   af*/
260
0x00,0x00,0x00,0xcc,0x27,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
261
/*b0   b1   b2   b3   b4   b5   b6   b7   b8   b9   ba   bb   bc   bd   be   bf*/
262
0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
263
/*c0   c1   c2   c3   c4   c5   c6   c7   c8   c9   ca   cb   cc   cd   ce   cf*/
264
0x0f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x0e,0x00,0x00,0xf0,0xff,0xf5,0xf7,
265
/*d0   d1   d2   d3   d4   d5   d6   d7   d8   d9   da   db   dc   dd   de   df*/
266
0xea,0x0b,0x03,0x05,0x86,0xab,0x30,0xf6,0xad,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,
267
/*e0   e1   e2   e3   e4   e5   e6   e7   e8   e9   ea   eb   ec   ed   ee   ef*/
268
0x00,0x01,0x00,0x00,0x1c,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
269
/*f0   f1   f2*/
270
0x00,0x00,0x00};
271
272
SANE_Byte Hp44x0_300_true_1_3[]  = {
273
0xe5,0x41,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x10,0x10,0x10,0x70,0x00,0x00,0x00,0x00,
274
0x20,0x3b,0xff,0x20,0xf8,0x28,0x07,0x00,0xff,0x00,0x00,0x00,0x00,0x20,0x00,0x00,
275
0x3a,0xf2,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
276
0x00,0x00,0x80,0x81,0x10,0x1b,0x29,0x00,0x00,0x02,0x1b,0x00,0x00,0x00,0x00,0x00,
277
0x20,0x00,0x00,0x00,0x8c,0x76,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
278
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
279
0x12,0x00,0xc6,0x00,0x01,0x20,0x2c,0x01,0x00,0x00,0x00,0x00,0xdc,0x05,0x00,0x00,
280
0x00,0x00,0xe1,0x14,0x18,0x15,0x00,0x00,0x00,0x20,0x01,0x00,0x00,0x00,0x00,0x00,
281
0x2b,0x02,0x2c,0x02,0x00,0x18,0x1b,0x30,0x30,0x2d,0x02,0xff,0x3f,0x21,0x60,0x00,
282
0x1c,0x00,0x00,0x01,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
283
0x00,0x00,0x00,0xcc,0x27,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
284
0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
285
0x0f,0x00,0x00,0xf0,0xff,0xff,0x0f,0x00,0xff,0xf1,0xff,0x00,0xf0,0xff,0xf5,0xf7,
286
0xea,0x0b,0x03,0x05,0x86,0xab,0x10,0xf6,0xad,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,
287
0x00,0x01,0x00,0x00,0x1c,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
288
0x00,0x00,0x00};
289
290
SANE_Byte Hp44x0_300_BW_1[]  = {
291
/*0    1    2    3    4    5    6    7    8    9    a    b    c    d    e    f*/
292
0xe5,0x41,0x82,0x86,0x81,0x82,0x86,0x81,0x07,0x05,0x0f,0x70,0x00,0x00,0x00,0x00,
293
/*10   11   12   13   14   15   16   17   18   19   1a   1b   1c   1d   1e   1f*/
294
0x20,0x3f,0xff,0x20,0xf8,0x28,0x07,0x00,0xff,0x00,0x00,0x00,0x00,0x20,0x00,0x00,
295
/*20   21   22   23   24   25   26   27   28   29   2a   2b   2c   2d   2e   2f*/
296
0x3a,0xf2,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
297
/*30   31   32   33   34   35   36   37   38   39   3a   3b   3c   3d   3e   3f*/
298
0x00,0x00,0x80,0x81,0x10,0x1b,0x29,0x00,0x00,0x02,0x1b,0x00,0x00,0x00,0x00,0x00,
299
/*0x00,0x00,0x20,0x83,0x10,0x0e,0x2c,0x00,0x00,0x02,0x0e,0x00,0x00,0x00,0x00,0x00,*/
300
/*40   41   42   43   44   45   46   47   48   49   4a   4b   4c   4d   4e   4f*/
301
0x20,0x00,0x00,0x00,0x8c,0x76,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
302
/*50   51   52   53   54   55   56   57   58   59   5a   5b   5c  5d   5e   5f*/
303
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
304
/*60   61   62   63   64   65   66   67   68   69   6a   6b   6c   6d   6e   6f*/
305
0x01,0x00,0x43,0x00,0x01,0x20,0x5e,0x00,0x00,0x00,0x00,0x00,0x54,0x0a,0x00,0x00,
306
/*70   71   72   73   74   75   76   77   78   79   7a   7b   7c   7d   7e   7f*/
307
0x00,0x00,0xe1,0x14,0x18,0x15,0x00,0x00,0x00,0x20,0x01,0x00,0x00,0x00,0x00,0x00,
308
/*80   81   82   83   84   85   86   87   88   89   8a   8b   8c   8d   8e   8f*/
309
0x32,0x00,0x33,0x00,0x00,0x00,0x06,0x00,0x06,0x34,0x00,0xff,0x3f,0x00,0x60,0x00,
310
/*90   91   92   93   94   95   96   97   98   99   9a   9b   9c   9d   9e   9f*/
311
0x1c,0x00,0x00,0x01,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
312
/*a0   a1   a2   a3   a4   a5   a6   a7   a8   a9   aa   ab   ac   ad   ae   af*/
313
0x00,0x00,0x00,0xcc,0x27,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
314
/*b0   b1   b2   b3   b4   b5   b6   b7   b8   b9   ba   bb   bc   bd   be   bf*/
315
0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
316
/*c0   c1   c2   c3   c4   c5   c6   c7   c8   c9   ca   cb   cc   cd   ce   cf*/
317
0x0f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x0e,0x00,0x00,0xf0,0xff,0xf5,0xf7,
318
/*d0   d1   d2   d3   d4   d5   d6   d7   d8   d9   da   db   dc   dd   de   df*/
319
0xea,0x0b,0x17,0x01,0x86,0x0f,0x30,0x52,0xad,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,
320
/*e0   e1   e2   e3   e4   e5   e6   e7   e8   e9   ea   eb   ec   ed   ee   ef*/
321
0x00,0x05,0x00,0x00,0xc9,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
322
/*f0   f1   f2*/
323
0x00,0x00,0x00};
324
325
SANE_Byte Hp44x0_200_BW_1[]  = {
326
0xe5,0x41,0x82,0x86,0x81,0x82,0x86,0x81,0x07,0x05,0x0f,0x70,0x00,0x00,0x00,0x00,
327
0x20,0x3f,0xff,0x20,0xf8,0x28,0x01,0x00,0xff,0x00,0x00,0x00,0x00,0x20,0x00,0x00,
328
0x3a,0xf2,0x00,0x80,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
329
0x00,0x00,0x20,0x83,0x10,0x0e,0x2c,0x00,0x00,0x02,0x0e,0x00,0x00,0x00,0x00,0x00,
330
0x2c,0x00,0x00,0x00,0x8c,0x76,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
331
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
332
0x2d,0x00,0xef,0x0d,0x01,0x20,0x5e,0x00,0x00,0x00,0x00,0x00,0x54,0x0a,0x00,0x00,
333
0x00,0x00,0xe1,0x14,0x18,0x15,0x00,0x00,0x00,0x20,0x01,0x00,0x00,0x00,0x00,0x00,
334
0x2b,0x02,0x2c,0x02,0x00,0x18,0x1b,0x30,0x30,0x2d,0x02,0xff,0x3f,0xef,0x60,0x00,
335
0x18,0x00,0x00,0x01,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
336
0x00,0x00,0x00,0xcc,0x27,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
337
0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
338
0x0f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x0e,0x00,0x00,0xf0,0xff,0xf5,0xf7,
339
0xea,0x0b,0x17,0x01,0x86,0x0f,0x30,0x52,0xad,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,
340
0x00,0x07,0x00,0x00,0x56,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
341
0x00,0x00,0x00};
342
343
SANE_Byte Hp44x0_200_BW_2[]  = {
344
0xe5,0x41,0x8c,0x8c,0x8c,0x8c,0x8c,0x8c,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,
345
0x20,0x3f,0xff,0x20,0xf8,0x28,0x07,0x00,0xff,0x00,0x00,0x00,0x00,0x20,0x00,0x00,
346
0x3a,0xf2,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
347
0x00,0x00,0x00,0x03,0x10,0x0e,0x22,0x00,0x00,0x02,0x0e,0x00,0x00,0x00,0x00,0x00,
348
0x20,0x00,0x00,0x00,0x8c,0x76,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
349
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
350
0x01,0x00,0x02,0x00,0x01,0x20,0x0d,0x00,0x00,0x00,0x00,0x00,0xfb,0x02,0x00,0x00,
351
0x00,0x00,0xe1,0x14,0x18,0x15,0x00,0x00,0x00,0x20,0x01,0x00,0x00,0x00,0x00,0x00,
352
0x32,0x00,0x33,0x00,0x00,0x00,0x06,0x00,0x06,0x34,0x00,0xff,0x3f,0x00,0x60,0x00,
353
0x1c,0x00,0x00,0x01,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
354
0x00,0x00,0x00,0xcc,0x27,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
355
0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,
356
0x0f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x0e,0x00,0x00,0xf0,0xff,0xf5,0xf7,
357
0xea,0x0b,0x17,0x01,0x86,0x0f,0x30,0x52,0xad,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,
358
0x00,0x07,0x00,0x00,0x56,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
359
0x00,0x00};
360
361
SANE_Byte Hp44x0_200_TRUE_1[]  = {
362
/*0    1    2    3    4    5    6    7    8    9    a    b    c    d    e    f*/
363
0xe5,0x41,0xfa,0xfa,0xfa,0xfa,0xfa,0xfa,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,
364
/*10   11   12   13   14   15   16   17   18   19   1a   1b   1c   1d   1e   1f*/
365
0x20,0x3b,0xff,0x20,0xf8,0x28,0x07,0x00,0xff,0x00,0x00,0x00,0x00,0x20,0x00,0x00,
366
/*20   21   22   23   24   25   26   27   28   29   2a   2b   2c   2d   2e   2f*/
367
0x3a,0xf2,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
368
/*30   31   32   33   34   35   36   37   38   39   3a   3b   3c   3d   3e   3f*/
369
0x00,0x00,0x00,0x03,0x10,0x0e,0x22,0x00,0x00,0x02,0x0e,0x00,0x00,0x00,0x00,0x00,
370
0x20,0x00,0x00,0x00,0x8c,0x76,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
371
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
372
0x01,0x00,0x02,0x00,0x01,0x20,0x15,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x00,0x00,
373
0x00,0x00,0xe1,0x14,0x18,0x15,0x00,0x00,0x00,0x20,0x01,0x00,0x00,0x00,0x00,0x00,
374
0x2b,0x02,0x2c,0x02,0x00,0x18,0x1b,0x30,0x30,0x2d,0x02,0xff,0x3f,0x21,0x60,0x00,
375
0x1c,0x00,0x00,0x01,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
376
0x00,0x00,0x00,0xcc,0x27,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
377
0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
378
0xff,0x0f,0xff,0x00,0xf0,0x00,0xff,0x0f,0xff,0xff,0xf1,0xff,0x00,0xf0,0xed,0xef,
379
0xe2,0x03,0x17,0x01,0x86,0x0f,0x10,0x52,0xad,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,
380
0x00,0x07,0x00,0x00,0x56,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
381
0x00,0x00};
382
383
SANE_Byte Hp44x0_300_TRUE_1[]  = {
384
/*0    1    2    3    4    5    6    7    8    9    a    b    c    d    e    f*/
385
0xe5,0x41,0xbb,0x7d,0x3e,0xbb,0x7d,0x3e,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,
386
/*10   11   12   13   14   15   16   17   18   19   1a   1b   1c   1d   1e   1f*/
387
0x20,0x3b,0xff,0x20,0xf8,0x28,0x07,0x00,0xff,0x00,0x00,0x00,0x00,0x20,0x00,0x00,
388
/*20   21   22   23   24   25   26   27   28   29   2a   2b   2c   2d   2e   2f*/
389
0x3a,0xf2,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
390
/*30   31   32   33   34   35   36   37   38   39   3a   3b   3c   3d   3e   3f*/
391
0x00,0x00,0x00,0x03,0x10,0x0e,0x22,0x00,0x00,0x02,0x0e,0x00,0x00,0x00,0x00,0x00,
392
0x20,0x00,0x00,0x00,0x8c,0x76,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
393
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
394
0x01,0x00,0x02,0x00,0x01,0x20,0x15,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x00,0x00,
395
0x00,0x00,0xe1,0x14,0x18,0x15,0x00,0x00,0x00,0x20,0x01,0x00,0x00,0x00,0x00,0x00,
396
0x2b,0x02,0x2c,0x02,0x00,0x18,0x1b,0x30,0x30,0x2d,0x02,0xff,0x3f,0x21,0x60,0x00,
397
0x1c,0x00,0x00,0x01,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
398
0x00,0x00,0x00,0xcc,0x27,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
399
/*b0   b1   b2   b3   b4   b5   b6   b7   b8   b9   ba   bb   bc   bd   be   bf*/
400
0x00,0x00,0x02,     0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
401
/*c0   c1   c2   c3   c4   c5   c6   c7   c8   c9   ca   cb   cc   cd   ce   cf*/
402
0x00,0xff,0x0f,0xff,0x00,0xf0,0x00,0xff,0x0f,0xff,0xff,0xf1,0xff,0x00,0xf0,0xed,
403
/*d0   d1   d2   d3   d4   d5   d6   d7   d8   d9   da   db   dc   dd   de   df*/
404
0xef,0xe2,0x03,0x17,0x01,0x86,0x0f,0x10,0x52,0xad,0xa7,0x00,0x00,0x00,0x00,0x00,
405
/*e0   e1   e2   e3   e4   e5   e6   e7   e8   e9   ea   eb   ec   ed   ee   ef*/
406
0x00,0x00,0x07,0x00,0x00,0x56,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
407
/*f0   f1   f2*/
408
0x00,0x00,0x00};
409
410
/* CCD CHANGES to CCD1  80,81,82,83,85,86,87,88,89,8a,8d,8e,c2,c3,c6,c7,c8,c9,ca,d6 */
411
412
413
SANE_Byte Hp44x0_patch_2[] = {
414
0x12,0x8,0x16,0x8,0x1d,0x20,0xb0,0x0,0xce,0xe0,0xd4,0x86,
415
0xd5,0x1b,0xd6,0x0,0xd7,0xff,0xd8,0x0,0xd9,0x27,0xda,0x0,
416
0xe1,0x1,0xe2,0x0,0xe4,0x14,0xe5,0x0,0xf4,0x0,0xf5,0x0,
417
0xf6,0x0,0xf7,0x0,0xf8,0x0,0xf9,0x0,0xfa,0x0,0xfb,0x0,
418
0xfc,0x0,0xfd,0x0,0xfe,0x0,0x0,0x0};
419
420
SANE_Byte Hp44x0_patch_3[] = {
421
0x1d,0x20,0xb0,0x0,0xd4,0x86,0xd5,0x1b,0xd6,0x0,0xd7,0xff,
422
0xd8,0x0,0xd9,0x27,0xda,0x0,0xe1,0x1,0xe2,0x0,0xe4,0x14,
423
0xe5,0x0,0xf4,0x0,0xf7,0x0,0xf8,0x0,0xf9,0x0,0xfa,0x0,
424
0xfb,0x0,0xfc,0x0,0xfd,0x0,0xfe,0x0,0x0,0x0};
425
426
SANE_Byte Hp44x0_patch_4[] = {
427
0x10,0x28,0x11,0x28,0x12,0xff,0x14,0xf8,0x15,0x28,0x16,0x7,
428
0x18,0xff,0x1a,0x0,0x1d,0x20,0x23,0xff,0x24,0xff,0x72,0xe1,
429
0x73,0x14,0x74,0x18,0x75,0x15,0xb0,0x0,0xbf,0xff,0xc0,0xf,
430
0xc2,0xff,0xc3,0xff,0xc4,0xff,0xc5,0xff,0xc6,0xff,0xc7,0xff,
431
0xc9,0xe,0xcc,0xf0,0xcd,0xff,0xce,0xf5,0xcf,0xf7,0xd0,0xea,
432
0xd1,0xb,0xd2,0x3,0xd3,0x5,0xd4,0x86,0xd5,0x1b,0xd6,0x30,
433
0xd7,0xf6,0xd8,0x80,0xd9,0x27,0xda,0x0,0xe1,0x1,0xe2,0x0,
434
0xe4,0x14,0xe5,0x0,0xf7,0x0,0xf8,0x0,0xf9,0x0,0xfa,0x0,
435
0xfb,0x0,0xfc,0x0,0xfd,0x0,0xfe,0x0,0x0,0x0};
436
437
SANE_Byte Hp44x0_patch_600[] = {
438
0x10,0x28, 0x11,0x3b, 0x36,0x2c,
439
0xe4,0xbd, 0xe5,0x0a,
440
441
0x72,0x3a, 0x73,0x15, 0x74,0x62,
442
0xbf,0xf8, 0xc0,0x7f,
443
0xc4,0x00, 0xc5,0xf8,
444
0xcb,0x07, 0xcc,0x80, 0xce,0xf2,
445
0xcf,0xf4, 0xd0,0xe7, 0xd1,0x08, 0xd2,0x0e, 0xd3,0x10,
446
0xd5,0x0f, 0xd7,0x52,
447
0x60,0x01, 0x62,0x02, 0x66,0x2b, 0x67,0x00, 0x6c,0x19, 0x6d,0x03
448
};
449
450
SANE_Byte callibration_buffer[0x818+4];
451
SANE_Byte registers[0xff];
452
SANE_Byte read_buffer[0xff];
453
454
SANE_Bool Hp44x0_Wakeup(THWParams *pHWParams,TScanParams *pParams);
455
SANE_Bool Hp44x0_Down(SANE_Int iHandle);
456
457
SANE_Bool Hp44x0_patch_and_send_values (SANE_Int iHandle, SANE_Byte *my_values);
458
void Hp44x0_patch_regs            (THWParams *pHWParams,SANE_Byte *my_values);
459
SANE_Bool Hp44x0_set_display    ( SANE_Int iHandle, SANE_Byte val );
460
461
SANE_Bool Hp44x0_write_cal_bytes       (THWParams *pHWParams, SANE_Byte b );
462
SANE_Bool Hp44x0_cal_scanner      (THWParams *pHWParams, TScanParams *pParams);
463
SANE_Int Hp44x0_park_to_home	(THWParams *pHWParams,TScanParams *pParams);
464
465
SANE_Int Hp44x0_move_to_pos (THWParams *pHWParams, TScanParams *pParams);
466
SANE_Int Hp44x0_wait_for_WarmUp   (SANE_Int iHandle, THWParams *pHWParams);
467
SANE_Bool Hp44x0_start_scan       (THWParams *pHWParams,TScanParams *pParams,
468
                            TDataPipe *pDataPipe);
469
SANE_Bool Hp44x0_init_scan        (THWParams *pHWParams, TScanParams *pParams,
470
                            TDataPipe *pDataPipe);
471
SANE_Bool Hp44x0_GetLamp   (SANE_Int iHandle, SANE_Bool *pfLampIsOn);
472
SANE_Bool Hp44x0_SetLamp   (SANE_Int iHandle, SANE_Bool fLampOn);
473
474
SANE_Int  Hp44x0c_nvram_enable_controller(SANE_Int iHandle,SANE_Int enable);
475
476
477
#if 0
478
void _UnscrambleLine       (SANE_Handle h,SANE_Byte *pabLine,
479
                            SANE_Byte *pabRed, SANE_Byte *pabGrn, SANE_Byte *pabBlu,
480
                            SANE_Int iWidth, SANE_Bool iReversedHead);
481
482
#endif
483
484
#endif /* NO _HP_RTS__H_ */
485
(-)sane-backends-1.0.19/backend/hp_rts_xfer.c (+1177 lines)
Line 0 Link Here
1
 /* sane - Scanner Access Now Easy.
2
   Copyright (C) 2003 Johannes Hub (JohannesHub@t-online.de)
3
4
   This file was initially copied from the hp3300 backend.
5
   This file is part of the SANE package.
6
7
   This program is free software; you can redistribute it and/or
8
   modify it under the terms of the GNU General Public License
9
   as published by the Free Software Foundation; either version 2
10
   of the License, or (at your option) any later version.
11
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21
   As a special exception, the authors of SANE give permission for
22
   additional uses of the libraries contained in this release of SANE.
23
24
   The exception is that, if you link a SANE library with other files
25
   to produce an exutable, this does not by itself cause the
26
   resulting executable to be covered by the GNU General Public
27
   License.  Your use of that executable is in no way restricted on
28
   account of linking the SANE library code into it.
29
30
   This exception does not, however, invalidate any other reasons why
31
   the executable file might be covered by the GNU General Public
32
   License.
33
34
   If you submit changes to SANE to the maintainers to be included in
35
   a subsequent release, you agree by submitting the changes that
36
   those changes may be distributed with this exception intact.
37
38
   If you write modifications of your own for SANE, it is your choice
39
   whether to permit this exception to apply to your modifications.
40
   If you do not wish that, delete this exception notice.
41
*/
42
43
/*
44
    Concept for a backend for scanners based on the RTS88xx chipset,
45
    such as HP4400C, HP4470C.
46
    Parts of this source were inspired by other backends.
47
48
		History:
49
50
		Version 0.18  21.11.04 13.alpha,
51
				- source sorted,
52
				- now only SANEI_USB_SUPPORT for a better overview(xfermodules removed)
53
				- read and verify the MainBoardID 
54
		Version 0.17p 02.11.04 12.alpha, source sorted, little fixes, SANEI_USB_SUPPORT implemented
55
		Version 0.17p 02.11.04 12.alpha, source sourted, little fixes, SANEI_USB_SUPPORT implemented
56
		Version 0.17b 30.03.04 10.alpha, little fixes and libusb implemented
57
		Version 0.17  09.03.04 9. alpha, HP3500 included
58
		Version 0.16  06.02.04 8. alpha, wait counting on LCD
59
		Version 0.15a 29.01.04 7. alpha, CCD switch moved to config file
60
		Version 0.15  11.01.04 6. alpha, a second CCD implemented
61
		Version 0.13a 21.11.04 4. alpha, an little fix included
62
		Version 0.12  22.10.03 third alpha, Backend name changed to HP_RTS88xx
63
		Version 0.11  30.08.03 second alpha
64
		Version 0.10  19.07.03 first alpha
65
*/
66
67
/*
68
		Provides a simple interface to read and write data from the scanner,
69
		without any knowledge whether it's a parallel or USB scanner
70
71
		enable DEDUG output:
72
		use a nomal shell (konsole) and type
73
		export SANE_DEBUG_HP_RTS88XX=32
74
		export XSANE_DEBUG=100
75
		xsane
76
*/
77
78
79
#include <unistd.h>    /* read, open, write */
80
#include <fcntl.h>     /* open */
81
#include <stdio.h>     /* printf */
82
#include <errno.h>     /* better error reports */
83
#include <string.h>    /* better error reports */
84
#include <stdlib.h>    /* malloc(), free() on FreeBSD */
85
#include "../include/sane/sanei_usb.h"
86
87
#include "hp_rts_xfer.h"
88
89
#ifdef STANDALONE
90
	#include "../include/sane/config.h"
91
	#include "hp_rts_35x0c.h"
92
	#include "hp_rts_44x0c.h"
93
#endif
94
95
96
static SANE_Int _fDeviceFound;
97
static TScannerModel *_pModel;
98
static TDevListEntry *_pFirstSaneDev = 0;
99
static SANE_Int iNumSaneDev = 0;
100
static const SANE_Device **_pSaneDevList = 0;
101
102
/* list of supported models */
103
TScannerModel ScannerModels[] = {
104
	{"Hewlett-Packard",	"UnknownModel",		0x3F0,	0x0000, eUnknownModel},
105
	{"Hewlett-Packard",	"ScanJet 3500C",	0x3F0,	0x2205, eHp3500c}, /*RTS8801C2*/
106
#ifdef DEBUG_HP3500
107
	{"Hewlett-Packard",	"ScanJet 3530C",	0x3F0,	0x0805, eHp3530c}, /*RTS8801C2*/
108
#else
109
	{"Hewlett-Packard",	"ScanJet 3530C",	0x3F0,	0x2005, eHp3530c}, /*RTS8801C2*/
110
#endif
111
	{"Hewlett-Packard",	"ScanJet 3570C",	0x3F0,	0x2005, eHp3570c}, /*RTS8801C2 is the same as 3500 */
112
	{"Hewlett-Packard",	"ScanJet 4400C",	0x3F0,	0x0705, eHp4400c}, /*RTS8891*/
113
	{"Hewlett-Packard",	"ScanJet 4470C",	0x3F0,	0x0805, eHp4470c}, /*RTS8891*/
114
#ifdef ENABLE_VI8920
115
	{"Visioneer",		"Onetouch 8920 USB",	0x0461,	0x0371, eVi8920}, /*RTS8801C2-004*/
116
#endif
117
#if 0
118
	{"Visioneer",		"Onetouch 8900 USB",	0x0461,	0x0371, eVi8900}, /*RTS8801C2-004*/
119
	{"Visioneer",		"Onetouch 8700 USB",	0x0461,	0x0371, eVi8700}, /*RTS8801C2-004*/
120
	{"Visioneer",		"OneTouch 5800 USB",	0x04a7,	0x0226, eVi5800}, /*RTS8801C2-004*/
121
	{"Visioneer",		"OneTouch 5300 USB",	0x04a7,	0x0226, eVi5300}, /*RTS8801C2-004*/
122
	{"Visioneer",		"OneTouch 4800 USB",	0x04a7,	0x0224, eVi4800}, /*RTS8801B-0001*/
123
	{"Vantas",			"3000",								0x04a7,	0x0224, eVa3000}, /*RTS8801B-0001*/
124
	{"Microtek",		"Scanport 3000",			0x04a7,	0x0224, eMi3000}, /*RTS8801B-0001*/
125
	{"Plustek",			"OpticPro S6",				0x0???,	0x????, ePlS6}, 	/*RTS8801D*/
126
	{"Prolink",			"Winscan Pro 2448U",	0x06dc,	0x0014, ePrlS6}, 	/*RTS8801C2-006*/
127
#endif
128
/* last entry all zeros */
129
  {0, 0, 0, 0, 0}
130
};
131
132
133
/****************************************************************************/
134
/* utility function to show a hexdump of a buffer */
135
void Hp_rts_DumpHex(SANE_Byte *pabData, SANE_Int iLen, SANE_Int iWidth, SANE_Int withLf)
136
/****************************************************************************/
137
{
138
  SANE_Int i;
139
140
  printf("    ");
141
  for (i = 0; i < iWidth ; i++) {
142
    printf(" %02X", i);
143
  }
144
  for (i = 0; i < iLen; i++) {
145
    if ((i % iWidth) == 0) {
146
      if (withLf) printf("\n");
147
      printf("%04X", i);
148
    }
149
    printf(" %02X", pabData[i]);
150
  }
151
  if (withLf) printf("\n");
152
}
153
154
/****************************************************************************/
155
/* utility function to show a bit dump of a byte */
156
void Hp_rts_DumpBits(SANE_Byte reg, SANE_Byte pabData)
157
/****************************************************************************/
158
{
159
	SANE_Int i = 0;
160
161
	printf("RegisterDump : Register %x will be set to the bits ", reg);
162
	for (i = 0; i < 8; i++) {
163
		if (pabData & 0x80)
164
			printf("1");
165
		else
166
			printf("0");
167
		if (i==3) printf(" ");
168
		pabData = pabData << 1;
169
	}
170
	printf("\n");
171
}
172
173
/****************************************************************************
174
  Hp_rts_MatchUsbDevice
175
  ==============
176
    Matches a given USB vendor and product id against a list of
177
    supported scanners.
178
179
  IN  iVendor   USB vendor ID
180
      iProduct  USB product ID
181
  OUT *ppModel  Pointer to TScannerModel structure
182
183
  Returns SANE_TRUE if a matching USB scanner was found
184
*/
185
SANE_Bool Hp_rts_MatchUsbDevice(SANE_Int iVendor, SANE_Int iProduct, TScannerModel **ppModel)
186
/****************************************************************************/
187
{
188
	TScannerModel *pModels = ScannerModels;
189
190
	DBG(DBG_MSG,"Hp_rts_MatchUsbDevice :Matching USB device 0x%04X-0x%04X ... \n", iVendor, iProduct);
191
	while (pModels->pszName != NULL)
192
	{
193
		if ((pModels->iVendor == iVendor) && (pModels->iProduct == iProduct))
194
		{
195
			DBG(DBG_MSG,"Hp_rts_MatchUsbDevice : found %s %s\n", pModels->pszVendor, pModels->pszName);
196
			*ppModel = pModels;
197
			return SANE_TRUE;
198
		}
199
		/* next model to match */
200
		pModels++;
201
	}
202
	DBG(DBG_MSG,"Hp_rts_MatchUsbDevice : nothing found\n");
203
	return SANE_FALSE;
204
}
205
206
207
208
/************************************************************************
209
  Public functions
210
************************************************************************/
211
212
213
/*static TFnReportDevice *_pfnReportDevice;*/
214
static TScannerModel *_pModel;
215
216
/****************************************************************************/
217
static int
218
_ReportDevice (TScannerModel * pModel, SANE_Char *pszDeviceName)
219
/****************************************************************************/
220
{
221
  TDevListEntry *pNew, *pDev;
222
#if 0
223
  DBG (DBG_MSG, "_ReportDevice '%s'", pszDeviceName);
224
#endif 
225
  pNew = malloc (sizeof (TDevListEntry));
226
  if (!pNew)
227
    {
228
      DBG (DBG_ERR, "_ReportDevice: no mem\n");
229
      return -1;
230
    }
231
232
  /* add new element to the end of the list */
233
  if (_pFirstSaneDev == 0)
234
    {
235
      _pFirstSaneDev = pNew;
236
    }
237
  else
238
    {
239
      for (pDev = _pFirstSaneDev; pDev->pNext; pDev = pDev->pNext)
240
	{
241
	  ;
242
	}
243
      pDev->pNext = pNew;
244
    }
245
246
  /* fill in new element */
247
  pNew->pNext = 0;
248
  pNew->dev.name = strdup (pszDeviceName);
249
  pNew->dev.vendor = pModel->pszVendor;
250
  pNew->dev.model = pModel->pszName;
251
  pNew->dev.type = "flatbed scanner";
252
253
  iNumSaneDev++;
254
255
  return 0;
256
}
257
258
/* callback for sanei_usb_attach_matching_devices */
259
/****************************************************************************/
260
static SANE_Status
261
_AttachUsb (SANE_String_Const devname)
262
/****************************************************************************/
263
{
264
  DBG (DBG_MSG, "_AttachUsb: found %s", devname);
265
266
	_fDeviceFound ++;
267
  _ReportDevice (_pModel, (SANE_Char *) devname);
268
/*  _pfnReportDevice (_pModel, (SANE_Char *) devname);*/
269
270
  return SANE_STATUS_GOOD;
271
}
272
273
/****************************************************************************
274
  Hp_rts_XferInit
275
  ===============
276
    Probes all registered modules to see if it can be used to access a
277
    compatible scanner. The first module that supports the scanner is
278
    used.
279
280
  Returns the handle to a TXferDev structure which was used to find the
281
  scanner, returns 0 or negative otherwise.
282
*/
283
SANE_Int Hp_rts_XferInit(/*EScannerModel *peModel*/void)
284
/****************************************************************************/
285
{
286
	TScannerModel *pModels = ScannerModels;
287
288
	DBG (DBG_MSG,"Hp_rts_XferInit ....\n");
289
290
  sanei_usb_init ();
291
	_fDeviceFound = 0;
292
/*	_pfnReportDevice = _ReportDevice;*/
293
294
	/* loop over all scanner models */
295
	while (pModels->pszName != NULL)
296
	{
297
		DBG (DBG_MSG, "Looking for %s...", pModels->pszName);
298
		_pModel = pModels;
299
		if (sanei_usb_find_devices ((SANE_Int) pModels->iVendor,
300
					(SANE_Int) pModels->iProduct,
301
					_AttachUsb) != SANE_STATUS_GOOD)
302
		{
303
			DBG (DBG_ERR, "Error invoking sanei_usb_find_devices\n");
304
			return SANE_FALSE;
305
		}
306
#if 0
307
		DBG(DBG_MSG, "Hp_rts_XferInit: found device ");
308
		if (pModels->eModel != eUnknownModel){
309
			_AttachUsb("libusb:001:002*");
310
		}
311
#endif
312
		DBG (DBG_MSG, "\n");
313
		pModels++;
314
	}
315
316
	if (_fDeviceFound)
317
		return SANE_TRUE;
318
	else
319
		return SANE_FALSE;
320
}
321
322
323
/****************************************************************************/
324
SANE_Int Hp_rts_XferOpen (SANE_String_Const devname,EScannerModel *peModel)
325
/****************************************************************************/
326
{
327
	SANE_Status status;
328
	SANE_Word vendor, product;
329
	int fd;
330
	TScannerModel *pModel;
331
332
	DBG (DBG_MSG, "Hp_rts_XferOpen, trying to open %s...\n", devname);
333
334
	status = sanei_usb_open (devname, &fd);
335
	if (status != SANE_STATUS_GOOD)
336
	{
337
		DBG (DBG_ERR, "Hp_rts_XferOpen: sanei_usb_open failed %s\n", devname);
338
		return -1;
339
	}
340
#if 0
341
	DBG (DBG_MSG, "Hp_rts_XferOpen, trying to get sanei_usb_get_vendor_product for fd %d\n", (int) fd);
342
#endif
343
	status = sanei_usb_get_vendor_product (fd, &vendor, &product);
344
	if (status == SANE_STATUS_GOOD)
345
	{
346
#if 0
347
		DBG (DBG_MSG, "Hp_rts_XferOpen, trying Hp_rts_MatchUsbDevice\n");
348
#endif		
349
		if (Hp_rts_MatchUsbDevice (vendor, product, &pModel)== SANE_TRUE)
350
		{
351
#if 0
352
			DBG (DBG_MSG, "pModel->eModel = %d\n",pModel->eModel);
353
#endif			
354
			*peModel = pModel->eModel;
355
		}else
356
		{
357
			DBG (DBG_ERR, "Hp_rts_XferOpen: Hp_rts_MatchUsbDevice failed %s\n", devname);
358
			sanei_usb_close (fd);
359
			return -1;
360
		}
361
	}else
362
	{
363
		DBG (DBG_ERR, "Hp_rts_XferOpen: sanei_usb_get_vendor_product failed %s\n", devname);
364
		sanei_usb_close (fd);
365
		return -1;
366
	}
367
#if 0
368
	DBG (DBG_MSG, "handle = %d\n", (int) fd);
369
#endif
370
	return fd;
371
}
372
373
/****************************************************************************/
374
SANE_Int Hp_rts_XferExit(SANE_Int iHandle)
375
/****************************************************************************/
376
{
377
378
	if (iHandle < 0) {
379
		return(-1);
380
	}
381
	/* close usb device */
382
	sanei_usb_close (iHandle);
383
	return SANE_TRUE;
384
}
385
386
387
/****************************************************************************/
388
SANE_Int Hp_rts_BulkWrite (SANE_Int iHandle, SANE_Byte reg, SANE_Byte *pabBuf,
389
                       SANE_Int iSize, SANE_Int wHeader)
390
/****************************************************************************/
391
{
392
	static SANE_Byte init[]={0x88,0,0x00,0x01};
393
	SANE_Char *request;     /* Compose a request string. */
394
	SANE_Int size;
395
396
#ifdef USBDEBUG
397
	DBG(DBG_USB,"UsbWriteBulk ...\n");
398
#endif
399
	if (iHandle == -1) {
400
		return(SANE_FALSE);
401
	}
402
403
	if (wHeader){
404
		request=malloc(iSize + 4);     /* Compose a request string. */
405
		init[1]=(SANE_Byte)reg;
406
		init[2]=(SANE_Byte)(iSize>>8); /* split count over these bytes.*/
407
		init[3]=(SANE_Byte)iSize;
408
		memcpy(request,init,4);        /* stick them together */
409
		memcpy(request+4,pabBuf,iSize);
410
		size = iSize + 4;
411
#ifdef USBDEBUG
412
		SANE_Byte *tmpw=request;
413
		SANE_Int tmp_size=size;
414
		fprintf(stderr,"WB1 transfer type=bulk size=%d dir=OUT\n",tmp_size);
415
		while(tmp_size--) fprintf(stderr,"%02hhx ",*tmpw++);
416
		fprintf(stderr,"\n");
417
#endif
418
		if (sanei_usb_write_bulk(iHandle, request,&size) != SANE_STATUS_GOOD) {
419
			DBG(DBG_ERR, "UsbWriteBulk: ERROR: Bulk write failed\n");
420
			return SANE_FALSE;
421
		}
422
		free(request);                  /* clean up */
423
	}else
424
	{
425
#ifdef USBDEBUG
426
		SANE_Byte *tmpw=pabBuf;
427
		SANE_Int tmp_size=iSize;
428
		fprintf(stderr,"WB2 transfer type=bulk size=%d dir=OUT\n",tmp_size);
429
		while(tmp_size--) fprintf(stderr,"%02hhx ",*tmpw++);
430
		fprintf(stderr,"\n");
431
#endif
432
    if (sanei_usb_write_bulk(iHandle,pabBuf,&iSize) != SANE_STATUS_GOOD) {
433
			DBG(DBG_ERR, "UsbWriteBulk: ERROR: Bulk write failed\n");
434
			return SANE_FALSE;
435
    }
436
  }
437
  return SANE_TRUE;
438
}
439
440
441
/****************************************************************************/
442
SANE_Int Hp_rts_BulkRead(SANE_Int iHandle, SANE_Byte reg, SANE_Byte *pabBuf,
443
                     SANE_Int iSize, SANE_Int wWrite)
444
/****************************************************************************/
445
{
446
	static SANE_Byte init[]={0x80,0,0x00,0x01};
447
	size_t size;
448
449
#ifdef USBDEBUG
450
	DBG(DBG_USB,"UsbReadBulk ...\n");
451
#endif
452
	if (iHandle == -1) {
453
		return SANE_FALSE;
454
	}
455
456
	if (wWrite){
457
#ifdef USBDEBUG
458
		DBG(DBG_USB,"UsbReadBulk with write\n");
459
#endif
460
		init[1] = reg;
461
		init[2] = (iSize>>8) & 0xFF; /*split count over these bytes.*/
462
		init[3] = (iSize) & 0xFF;
463
		size = 4;
464
#ifdef USBDEBUG
465
		SANE_Byte *tmpw=init;
466
		SANE_Int tmp_size=size;
467
		fprintf(stderr,"RR transfer type=bulk size=%d dir=OUT\n",tmp_size);
468
		while(tmp_size--) fprintf(stderr,"%02hhx ",*tmpw++);
469
		fprintf(stderr,"\n");
470
#endif
471
		if (sanei_usb_write_bulk(iHandle,(unsigned char *) init,&size) != SANE_STATUS_GOOD) {
472
			DBG(DBG_ERR,"UsbReadBulk: ERROR: Bulk write failed\n");
473
			return SANE_FALSE;
474
		}
475
	}
476
#ifdef USBDEBUG
477
	DBG(DBG_USB,"UsbReadBulk, now read ...\n");
478
#endif
479
	size = iSize;
480
	if (sanei_usb_read_bulk(iHandle, pabBuf,&size) != SANE_STATUS_GOOD) {
481
			DBG(DBG_ERR,"UsbReadBulk: ERROR: Bulk read failed\n");
482
			return SANE_FALSE;
483
	}
484
#ifdef USBDEBUG
485
	SANE_Byte *tmpr=pabBuf;
486
	SANE_Int tmp_size=size;
487
	fprintf(stderr,"RR transfer type=bulk size=%d dir=IN\n",tmp_size);
488
	while(tmp_size--) fprintf(stderr,"%02hhx ",*tmpr++);
489
	fprintf(stderr,"\n");
490
#endif
491
	return SANE_TRUE;
492
}
493
494
495
/****************************************************************************/
496
SANE_Int Hp_rts_RegWrite(SANE_Int iHandle, SANE_Byte bReg, SANE_Byte bData)
497
/****************************************************************************/
498
{
499
#ifdef USBDEBUG
500
	DBG(DBG_USB, "SaneiUsbWriteReg...\n");
501
#endif
502
	if (Hp_rts_BulkWrite(iHandle,bReg,&bData,1, SANE_TRUE))
503
		return(SANE_TRUE);
504
	else
505
		return(SANE_FALSE);
506
}
507
508
509
/****************************************************************************/
510
SANE_Int Hp_rts_RegRead(SANE_Int iHandle, SANE_Byte bReg, SANE_Byte *pbData)
511
/****************************************************************************/
512
{
513
#ifdef USBDEBUG
514
	DBG(DBG_USB, "SaneiUsbReadReg...\n");
515
#endif
516
	if (Hp_rts_BulkRead(iHandle,bReg,pbData,1,SANE_TRUE))
517
		return(SANE_TRUE);
518
	else
519
		return(SANE_FALSE);
520
}
521
522
523
/****************************************************************************/
524
SANE_Int Hp_rts_BulkReadall(SANE_Int iHandle, SANE_Byte *pabData)
525
/****************************************************************************/
526
{
527
	SANE_Byte init[]={0x80,0,0x00,0xf4};
528
529
#ifdef USBDEBUG
530
	DBG(DBG_USB, "SaneiUsbReadBulk_all_regs...\n");
531
#endif
532
	if (iHandle < 0) {
533
		return -1;
534
	}
535
536
	if (Hp_rts_BulkWrite(iHandle,1,(char *)init,4, SANE_FALSE))
537
	{
538
		if (Hp_rts_BulkRead(iHandle,0x81,pabData,192,SANE_FALSE))
539
		{
540
			if (Hp_rts_BulkRead(iHandle,0x81,pabData+192,52,SANE_FALSE))
541
				return(SANE_TRUE);
542
543
		} else return(SANE_FALSE);
544
	} else return(SANE_FALSE);
545
	return SANE_TRUE;
546
}
547
548
/*************************************************************************
549
  Returns SANE_TRUE if a known chipset was found. */
550
SANE_Bool Hp_rts_ProbeRegisters(THWParams *pHWParams)
551
/*************************************************************************/
552
{
553
	SANE_Byte bData1,r;
554
	SANE_Int iHandle;
555
556
	iHandle = pHWParams->iXferHandle;
557
	bData1 = 0;
558
	DBG(DBG_MSG, "Hp_rts_ProbeRegisters: iHandle = %d, Probing scanner...\n",(SANE_Int)iHandle);
559
	Hp_rts_RegRead( iHandle, 0x00, &bData1); /* read register 0x00 */
560
	if ((bData1 == 0xE5) || (bData1 == 0xF5)) {
561
		switch (pHWParams->ScannerModel) {
562
			case eHp3500c: case eHp3530c: case eHp3570c:
563
#ifdef ENABLE_VI8920
564
			case eVi8920:
565
#endif
566
				return SANE_STATUS_GOOD;
567
				break;
568
			case eHp4400c: case eHp4470c:
569
				Hp_rts_RegRead(iHandle,MAINBOARD_ID, &r);
570
				if (r == 0)
571
					return SANE_STATUS_GOOD;
572
				DBG(DBG_ERR, "Hp_rts_ProbeRegisters: Wrong MainBoardID = %d\n",r);
573
				DBG(DBG_ERR, "Hp_rts_ProbeRegisters: No valid scanner with RTS88xx chipset found!\n");
574
				Hp_rts_XferExit(iHandle);
575
				return SANE_STATUS_IO_ERROR ;
576
				break;
577
			default:
578
				DBG(DBG_ERR, "Hp_rts_ProbeRegisters: ERROR: unknown model! (%d) %s\n",
579
					(SANE_Int)pHWParams->ScannerModel, ScannerModels[(SANE_Int)pHWParams->ScannerModel].pszName);
580
			return SANE_STATUS_IO_ERROR;
581
		}
582
	}
583
	else
584
	{
585
		DBG(DBG_ERR, "Hp_rts_ProbeRegisters: No valid scanner with RTS88xx chipset found!\n");
586
		Hp_rts_XferExit(iHandle);
587
		return SANE_STATUS_IO_ERROR ;
588
	}
589
}
590
591
/****************************************************************************/
592
SANE_Int Hp_rts_Set_double_reg(SANE_Int iHandle, SANE_Byte reg,
593
                           SANE_Byte c1, SANE_Byte c2 )
594
/****************************************************************************/
595
{
596
  SANE_Byte regs[5];
597
598
#ifdef USBDEBUG
599
	DBG(DBG_SCAN, "Hp_rts_Set_double_reg....\n");
600
#endif
601
  regs[0] = c1;
602
  regs[1] = c2;
603
  return(Hp_rts_BulkWrite (iHandle, reg, regs, 2,SANE_TRUE));
604
}
605
606
/****************************************************************************/
607
SANE_Int Hp_rts_Read_double_reg(SANE_Int iHandle, SANE_Byte reg, SANE_Byte *pbData )
608
/****************************************************************************/
609
{
610
#ifdef USBDEBUG
611
	DBG(DBG_SCAN, "Hp_rts_Read_double_reg....\n");
612
#endif
613
	return(Hp_rts_BulkRead(iHandle,reg,pbData,2,SANE_TRUE));
614
}
615
616
/****************************************************************************/
617
/*Return the number of bytes ready for collection                           */
618
SANE_Word Hp_rts_data_ready(SANE_Int iHandle, SANE_Word *size){
619
/****************************************************************************/
620
	static SANE_Byte command[]={0x90,0x00,0x00,0x03};
621
	SANE_Byte data[5];
622
623
#if 0
624
	DBG(DBG_SCAN, "Hp_rts_data_ready....\n");
625
#endif
626
	/* check if the scanner is moving*/
627
	if (SANE_TRUE /*read_reg(iHandle,MOVE_START_STOP) & 0x08*/)
628
	{
629
		Hp_rts_BulkWrite(iHandle,0x00,command,4,SANE_FALSE);
630
		Hp_rts_BulkRead(iHandle,0x00,data,3,SANE_FALSE);
631
		*size = data[0];
632
		*size = *size + (data[1]<<8);
633
		*size = *size + (data[2]<<16);
634
		if(*size > 0xe500) *size=0xe500;
635
		DBG(DBG_SCAN, "     Hp_rts_data_ready....data %x\n",*size);
636
		if (*size > 0){
637
			return(SANE_TRUE); }
638
		else
639
			return(SANE_FALSE);
640
	}else return(SANE_FALSE);
641
}
642
643
644
/****************************************************************************/
645
SANE_Int Hp_rts_read_data(SANE_Int iHandle, SANE_Word size,SANE_Byte *data) {
646
/****************************************************************************/
647
  static SANE_Byte write_command[]={0x91,0x00,0x00,0x00};
648
649
  write_command[3]=size & 0xff;
650
  write_command[2]=(size>>8) & 0xff;
651
  write_command[1]=(size>>16) & 0xff;
652
653
#ifdef USBDEBUG
654
	DBG(DBG_SCAN, "Hp_rts_read_data..%x\n",size);
655
#endif
656
  Hp_rts_BulkWrite(iHandle,0x00,write_command,4,SANE_FALSE);
657
  Hp_rts_BulkRead(iHandle,0x00,data,size,SANE_FALSE);
658
  return(SANE_TRUE);
659
}
660
661
/****************************************************************************/
662
SANE_Bool
663
Hp_rts_is_moving( SANE_Int iHandle )
664
/****************************************************************************/
665
{
666
	SANE_Byte	r;
667
668
	Hp_rts_RegRead(iHandle,REG_MOVE_CONTROL_TEST, &r);
669
/*	if ( Hp_rts_RegRead(iHandle,REG_MOVE_CONTROL_TEST, &r) < 0)
670
		return -1;*/
671
	if (r == 0x08)
672
		return SANE_TRUE;
673
	return SANE_FALSE;
674
}
675
676
/****************************************************************************/
677
SANE_Int
678
Hp_rts_start_moving( SANE_Int iHandle )
679
/****************************************************************************/
680
{
681
	DBG(DBG_MSG,"Hp_rts_start_moving...");
682
	if (Hp_rts_RegWrite(iHandle,REG_MOVE_CONTROL_TEST, 2) &&
683
	    Hp_rts_RegWrite(iHandle,REG_MOVE_CONTROL_TEST, 2) &&
684
	    Hp_rts_RegWrite(iHandle,REG_MOVE_CONTROL_TEST, 0) &&
685
	    Hp_rts_RegWrite(iHandle,REG_MOVE_CONTROL_TEST, 0) &&
686
	    Hp_rts_RegWrite(iHandle,REG_MOVE_CONTROL_TEST, 8) &&
687
	    Hp_rts_RegWrite(iHandle,REG_MOVE_CONTROL_TEST, 8))
688
		{
689
			DBG(DBG_MSG,"Hp_rts_start_moving..TRUE\n");
690
			return SANE_TRUE;
691
		}
692
		else
693
		{
694
			DBG(DBG_MSG,"Hp_rts_start_moving..FALSE\n");
695
			return SANE_FALSE;
696
		}
697
}
698
699
/****************************************************************************/
700
SANE_Int
701
Hp_rts_stop_moving( SANE_Int iHandle )
702
/****************************************************************************/
703
{
704
	DBG(DBG_MSG,"Hp_rts_stop_moving...");
705
	if (Hp_rts_RegWrite(iHandle,REG_MOVE_CONTROL_TEST, 2) &&
706
	    Hp_rts_RegWrite(iHandle,REG_MOVE_CONTROL_TEST, 2) &&
707
	    Hp_rts_RegWrite(iHandle,REG_MOVE_CONTROL_TEST, 0) &&
708
	    Hp_rts_RegWrite(iHandle,REG_MOVE_CONTROL_TEST, 0))
709
		{
710
			DBG(DBG_MSG,"Hp_rts_stop_moving..TRUE\n");
711
			return SANE_TRUE;
712
		}
713
		else
714
		{
715
			DBG(DBG_MSG,"Hp_rts_stop_moving..FALSE\n");
716
			return SANE_FALSE;
717
		}
718
}
719
720
721
/****************************************************************************/
722
/* Write a gamma table */
723
void
724
Hp_rts_WriteGammaCalibTable (SANE_Int iHandle,
725
			const SANE_Int *pabGammaR, const SANE_Int *pabGammaG,  const SANE_Int *pabGammaB)
726
/****************************************************************************/
727
{
728
  SANE_Byte cmd[3];
729
  SANE_Byte *buffer;
730
  SANE_Int i, j;
731
732
  iHandle = iHandle;
733
734
  /* Setup dummy gamma correction table */
735
  buffer = malloc (2 * 65536);
736
737
  cmd[0] = 2;
738
  cmd[1] = 0;
739
  cmd[2] = 0;
740
741
  for (i = 0; i < 3; i++)
742
    {
743
      const SANE_Int *ptr = (i == 0) ? pabGammaR :
744
	(i == 1) ? pabGammaG : pabGammaB;
745
746
      for (j = 0; j < 65536; j++)	/* Truncate integers to shorts */
747
	buffer[j] = ptr[j];
748
749
/*      hp5400_bulk_command_write (iHandle, 0x2A01 + i, cmd, 3, 2 * 65536,
750
				 65536, (void *) buffer);*/
751
    }
752
  free (buffer);
753
754
  return;
755
}
756
757
/****************************************************************************
758
void
759
Hp_rts_SetDefaultGamma (SANE_Int iHandle)
760
****************************************************************************
761
{
762
  SANE_Int *buffer = malloc (sizeof (SANE_Int) * 65536);
763
  SANE_Int i;
764
765
  for (i = 0; i < 65336; i++)
766
    buffer[i] = i;
767
768
  Hp_rts_WriteGammaCalibTable (iHandle, buffer, buffer, buffer);
769
}*/
770
771
/****************************************************************************/
772
SANE_Bool
773
Hp_rts_Check_Moving (SANE_Int iHandle)
774
/****************************************************************************/
775
{
776
	SANE_Int i;
777
#if 0
778
	SANE_Word size;
779
#endif
780
781
	DBG(DBG_MSG,"Hp_rts_Check_Moving: wait for moving ...\n");
782
	i = 0;
783
	while( !(Hp_rts_is_moving(iHandle)) && ( i < 25 )){
784
		usleep(10000);
785
		i++;
786
		};
787
	if ( i >= 25 ){
788
		DBG(DBG_MSG,"Hp_rts_Check_Moving: Time over, no move : %d!, will stop the movement\n",i);
789
		/*stop it and make sure it stopped!!! */
790
		Hp_rts_stop_moving(iHandle);
791
		return(SANE_FALSE);
792
	}
793
#if 0
794
	/* the scanner is now moving. Check it */
795
	DBG(DBG_MSG,"Hp_rts_Check_Moving: the scanner is now scanning. Check it\n");
796
	i = 0;
797
	while( (Hp_rts_data_ready(iHandle,&size) == SANE_FALSE) && ( i < 25 )){
798
		usleep(10000);
799
		i++;
800
	}
801
	if ( i >= 25 ){
802
		DBG(DBG_MSG,"Hp_rts_Check_Scanning: Time over, scanner no data : %d, will stop the scanner!\n",i);
803
		/*stop it and make sure it stopped!!! */
804
		Hp_rts_stop_moving(iHandle);
805
		return(SANE_FALSE);
806
	}
807
#endif
808
	return(SANE_TRUE);
809
}
810
811
/****************************************************************************/
812
SANE_Int
813
Hp_rts_Read_Sram (SANE_Int iHandle, SANE_Byte *pabData,
814
                            SANE_Int iSize)
815
/****************************************************************************/
816
{
817
	SANE_Byte init[]={0x81,0x00,0x08,0x18};
818
819
	if (iHandle < 0) {
820
		return(-1);
821
	}
822
#ifdef USBDEBUG
823
	DBG(DBG_MSG,"Hp_rts_Read_Sram...\n");
824
#endif
825
	init[2]=(SANE_Byte)(iSize>>8); /*split count over these bytes.*/
826
	init[3]=(SANE_Byte)iSize;
827
828
	if (Hp_rts_BulkWrite(iHandle,0x00,/*(SANE_Byte *)*/init,4,SANE_FALSE)){
829
#if 0
830
		DBG(DBG_MSG,"Read SRAM, READ NOW %d bytes\n",iSize);
831
		if (iSize >= 0x800){
832
			DBG(DBG_MSG,"Read SRAM, READ the first %d bytes\n",2048);
833
			if (Hp_rts_BulkRead(iHandle,0x00,(SANE_Byte *)pabData, 2048,SANE_FALSE) == 0){
834
				DBG(DBG_MSG,"Read SRAM, READ the left %d bytes\n",iSize-2048);
835
				return (Hp_rts_BulkRead(iHandle,0x00,(SANE_Byte *)pabData, iSize-2048,SANE_FALSE));
836
			}
837
		}
838
		else{
839
#endif
840
			return (Hp_rts_BulkRead(iHandle,0x00,(SANE_Byte *)pabData, iSize,SANE_FALSE));
841
#if 0
842
		}
843
#endif
844
	}
845
	return(SANE_FALSE);
846
}
847
848
/****************************************************************************/
849
SANE_Int
850
Hp_rts_set_value_lsbfirst(	SANE_Byte	*regs,
851
			SANE_Int		firstreg,
852
			SANE_Int		totalregs,
853
			SANE_Word	value)
854
/****************************************************************************/
855
{
856
	while (totalregs--)
857
	{
858
		regs[firstreg++] = value & 0xff;
859
		value >>= 8;
860
	}
861
	return 0;
862
}
863
864
/****************************************************************************/
865
SANE_Int
866
Hp_rts_set_noscan_distance(			SANE_Byte	*regs,
867
					SANE_Word	value)
868
/****************************************************************************/
869
{
870
	return Hp_rts_set_value_lsbfirst(regs, 0x60, 2, value);
871
}
872
873
/****************************************************************************/
874
SANE_Int
875
Hp_rts_set_total_distance(			SANE_Byte	*regs,
876
					SANE_Word	value)
877
/****************************************************************************/
878
{
879
	return Hp_rts_set_value_lsbfirst(regs, 0x62, 2, value);
880
}
881
882
/****************************************************************************/
883
SANE_Int
884
Hp_rts_set_scanline_end(			SANE_Byte	*regs,
885
					SANE_Word	value)
886
/****************************************************************************/
887
{
888
	return Hp_rts_set_value_lsbfirst(regs, 0x6c, 2, value);
889
}
890
891
/****************************************************************************/
892
SANE_Int
893
Hp_rts_set_scanline_start(			SANE_Byte	*regs,
894
					SANE_Word	value)
895
/****************************************************************************/
896
{
897
	return Hp_rts_set_value_lsbfirst	(regs, 0x66, 2, value);
898
}
899
900
901
/****************************************************************************/
902
SANE_Status Hp_rts_CircBufferInit(SANE_Handle h, TDataPipe *p, SANE_Int iBytesPerLine,
903
													SANE_Int iMisAlignment, SANE_Bool mode)
904
/****************************************************************************/
905
{
906
	TScanner  *s;
907
	SANE_Int iHandle;
908
	SANE_Int bufsize;
909
910
	/* prevent compiler from complaining about unused parameters */
911
	mode = mode;
912
913
	s = (TScanner *)h;
914
	iHandle = s->HWParams.iXferHandle;
915
	p->iBytesPerLine = iBytesPerLine;
916
	bufsize = p->iBytesPerLine * 3;
917
	p->iLinesPerCircBuf = 1;
918
	p->iMisAlignment = iMisAlignment;
919
920
	DBG(DBG_SCAN, "Hp_rts_CircBufferInit: _iBytesPerLine = %d\n", p->iBytesPerLine);
921
	DBG(DBG_SCAN, "Hp_rts_CircBufferInit: _iLinesPerCircBuf = %d\n", p->iLinesPerCircBuf);
922
923
	p->pabCircBuf = (SANE_Byte *)malloc(bufsize+(3*p->iBytesPerLine));
924
	if (p->pabCircBuf == NULL) {
925
		DBG(DBG_ERR, "Hp_rts_CircBufferInit: Unable to allocate %d bytes for circular buffer (%x - %x)\n",
926
								(SANE_Int)bufsize,(unsigned int)p->pabCircBuf,(unsigned int)p->pabCircBuf+bufsize);
927
		return SANE_STATUS_NO_MEM;
928
	}
929
	DBG(DBG_SCAN,"Hp_rts_CircBufferInit: Allocate %d bytes for circular buffer (%x - %x)\n",
930
								(SANE_Int)bufsize,(unsigned int)p->pabCircBuf,(unsigned int)p->pabCircBuf+bufsize);
931
	/* init transfer buffer */
932
	return Hp_rts_XferBufferInit(h, p);
933
}
934
935
936
/****************************************************************************/
937
void Hp_rts_CircBufferExit(SANE_Handle h)
938
/****************************************************************************/
939
{
940
	TScanner  *s;
941
942
	s = (TScanner *)h;
943
	if (s->DataPipe.pabCircBuf != NULL) {
944
		free(s->DataPipe.pabCircBuf);
945
		s->DataPipe.pabCircBuf = NULL;
946
	}
947
	Hp_rts_XferBufferExit( h );
948
	DBG(DBG_SCAN,"Hp_rts_CircBufferExit\n");
949
}
950
951
952
/****************************************************************************/
953
/* gets an line from the circular buffer. */
954
SANE_Bool Hp_rts_CircBufferGetLine(SANE_Handle h, TDataPipe *p, SANE_Byte *pabLine,
955
												SANE_Bool mode){
956
/****************************************************************************/
957
958
	SANE_Int line_lenght,copy_lines;
959
	#ifdef DEBUG_FILE
960
	SANE_Word size_t,data_count;
961
	#endif
962
963
	TScanner  *s;
964
965
	s = (TScanner *)h;
966
967
	DBG(DBG_SCAN,"   Hp_rts_CircBufferGetLine starts here\n");
968
	mode = mode;
969
	line_lenght = p->iBytesPerLine;
970
	copy_lines = 0;
971
972
	if (pabLine != NULL) {
973
		if (Hp_rts_XferBufferGetLine(h, p, &p->pabCircBuf[0])){
974
			memcpy(pabLine, &p->pabCircBuf[0], p->iBytesPerLine);
975
			#ifdef DEBUG_FILE
976
				data_count = 0;
977
				size_t = p->iBytesPerLine;
978
				while(size_t--) fprintf(s->ScanParams.FD_r,"%c",p->pabCircBuf[data_count++]);
979
			#endif
980
			return SANE_TRUE;
981
		}
982
	}
983
	return SANE_FALSE;
984
}
985
986
987
/****************************************************************************/
988
SANE_Bool Hp_rts_XferBufferGetLine(SANE_Handle h, TDataPipe *p, SANE_Byte *pabLine)
989
/****************************************************************************/
990
{
991
	TScanner  *s;
992
	SANE_Word size;
993
	SANE_Word size_t;
994
	SANE_Word Lines, Skip, lBytes;
995
	SANE_Int iHandle,i,wt;
996
	SANE_Byte *buf;
997
998
	s = (TScanner *)h;
999
	iHandle = s->HWParams.iXferHandle;
1000
1001
	DBG(DBG_SCAN,"     Hp_rts_XferBufferGetLine in: = iBytesPerLine=%3d iLinesLeft=%3d\n",
1002
								(SANE_Int)p->iBytesPerLine,(SANE_Int)s->ScanParams.iLinesLeft);
1003
1004
	switch (s->ScanParams.iDpi) {
1005
		case 150:
1006
		case 200:
1007
		case 300:
1008
		case 600:
1009
			if (s->ScanParams.mode == COLOR)
1010
				Skip = 1;
1011
			else
1012
				Skip = 2;
1013
		break;
1014
		default:
1015
			Skip = 1;
1016
		break;
1017
	}
1018
	lBytes = p->iBytesPerLine;
1019
1020
	/* Step 1, check if we have to receive more data from the scanner */
1021
	if (p->iCurLine == 0){
1022
		i = 0;
1023
		while( i < 10 ){
1024
			Hp_rts_data_ready(iHandle,&size);
1025
			if (size > lBytes)
1026
				i = 9;
1027
			usleep(10);
1028
			i++;
1029
		}
1030
		#if 0
1031
			DBG(DBG_SCAN,"size %d  ",(SANE_Int) size);
1032
		#endif
1033
		Hp_rts_data_ready(iHandle,&size);
1034
		Lines = (size / lBytes) / Skip; /* make shure we can div. it */
1035
		size_t = (Lines * lBytes) * Skip;
1036
		#ifdef DEBUG_SCAN
1037
			DBG(DBG_SCAN,"     Hp_rts_XferBufferGetLine: size %d lBytes %d size_t %d\n",size,lBytes,size_t);
1038
			DBG(DBG_SCAN,"     Hp_rts_XferBufferGetLine: write to buffer at 0x%x %d Lines\n",
1039
									(unsigned int) p->pabXferBuf,Lines);
1040
		#endif
1041
		p->iLastLine = Lines * Skip;
1042
		if ( size_t > 0 ){
1043
			Hp_rts_read_data(iHandle,size_t,p->pabXferBuf);
1044
		}else
1045
		{ /* fix: the scanner is stoped.
1046
					we have to read all bytes to
1047
					restart him                  */
1048
			#ifdef DEBUG_SCAN
1049
				DBG(DBG_SCAN,"     Hp_rts_XferBufferGetLine: restart %d\n",size_t);
1050
			#endif
1051
			if ( size > 0 ){
1052
				Hp_rts_read_data(iHandle,size,p->pabXferBuf);
1053
				size_t = lBytes - size;
1054
				i = 0;
1055
				while( (Hp_rts_data_ready(iHandle,&size) == SANE_FALSE) && ( i < 3 )){
1056
					sleep(1);
1057
					i++;
1058
				}
1059
				#ifdef DEBUG_SCAN
1060
					DBG(DBG_SCAN,"     Hp_rts_XferBufferGetLine: restart read %d\n",size_t);
1061
				#endif
1062
				Hp_rts_read_data(iHandle,size,p->pabXferBuf);
1063
			}
1064
			else{ /* no more data aviable */
1065
				p->iLastLine = 0;
1066
				return(SANE_FALSE);
1067
			}
1068
		}
1069
		wt = (10 * (XFER_BUF_SIZE - size))/2;
1070
		if (wt < 1) wt = 1;
1071
		if (wt > 65000) wt = 65000;
1072
		#ifdef DEBUG_SCAN
1073
			DBG(DBG_SCAN,"     Wait %d s, size %d, iLastLine %d\n",wt, size,(SANE_Int)p->iLastLine);
1074
		#endif
1075
		usleep(wt);
1076
	}
1077
1078
	/* Step 2, copy one line */
1079
	if (pabLine != NULL) {
1080
		buf = p->pabXferBuf + (p->iCurLine * lBytes);
1081
		#ifdef DEBUG_SCAN
1082
			DBG(DBG_SCAN,"     Hp_rts_XferBufferGetLine: read from buffer at 0x%x (%d), iLinesLeft %d, iScanned %d\n",
1083
					(unsigned int) buf,p->iCurLine,(SANE_Int)s->ScanParams.iLinesLeft,(SANE_Int)p->iScanned);
1084
		#endif
1085
		memcpy(pabLine, buf, lBytes);
1086
	}
1087
1088
	/* Step 3, set the advance pointer */
1089
	p->iCurLine = p->iCurLine + Skip;
1090
	p->iScanned = p->iScanned + 1;
1091
1092
	if ( p->iCurLine >= p->iLastLine  ){
1093
		p->iCurLine = 0;
1094
		#ifdef DEBUG_SCAN
1095
			DBG(DBG_SCAN,"     Hp_rts_XferBufferGetLine: set p->iCurLine = 0\n");
1096
		#endif
1097
	}
1098
	#ifdef DEBUG_SCAN
1099
		DBG(DBG_SCAN,"     Hp_rts_XferBufferGetLine: exit\n");
1100
	#endif
1101
	return(SANE_TRUE);
1102
}
1103
1104
1105
/****************************************************************************/
1106
SANE_Status Hp_rts_XferBufferInit(SANE_Handle h, TDataPipe *p)
1107
/****************************************************************************/
1108
{
1109
	TScanner  *s;
1110
	#ifdef DEBUG_FILE
1111
	SANE_Word x1,x2,length ;
1112
	#endif
1113
1114
	SANE_Int bufsize;
1115
1116
	s = (TScanner *)h;
1117
	bufsize = XFER_BUF_SIZE/**10*/;
1118
1119
	p->iLinesPerXferBuf = bufsize / (p->iBytesPerLine);
1120
	p->iLastLine = 0;
1121
	DBG(DBG_SCAN,"Hp_rts_XferBufferInit: iLinesPerXferBuf = %d\n", p->iLinesPerXferBuf);
1122
	DBG(DBG_SCAN,"Hp_rts_XferBufferInit: Xfer block size = 0x%x\n", p->iLinesPerXferBuf *
1123
																													p->iBytesPerLine);
1124
1125
	#ifdef DEBUG_FILE
1126
		/* Opening the testfile for debuging */
1127
		if ( !s->ScanParams.DebugOpen ){
1128
			s->ScanParams.DebugOpen = SANE_TRUE;
1129
			s->ScanParams.FD_r = fopen("view_r.pnm","w");
1130
			x1 = s->ScanParams.iX;
1131
			x2 = s->ScanParams.iWidth ;
1132
			length = s->ScanParams.iLenght - 1;
1133
			DBG(DBG_SCAN,"TempFile, length:%d, x1:%d, x2:%d \n",length,x1,x2);
1134
			switch (s->ScanParams.mode) {
1135
				case BLACK_WHITE:
1136
				case GRAY:
1137
					fprintf(s->ScanParams.FD_r,"P5\n%d %d\n255\n",x2,length+100);
1138
				break;
1139
				case COLOR:
1140
					fprintf(s->ScanParams.FD_r,"P6\n%d %d\n255\n",x2,length+100);
1141
				break;
1142
			}
1143
		}
1144
	#endif
1145
	p->iCurLine = 0;
1146
1147
	p->pabXferBuf = (SANE_Byte *)malloc(bufsize);
1148
	if (p->pabXferBuf == 0){
1149
		DBG(DBG_ERR,"Hp_rts_XferBufferInit: MEM alloc is not not possible !\n");
1150
		return SANE_STATUS_NO_MEM;
1151
	} else{
1152
		DBG(DBG_SCAN,"Hp_rts_XferBufferInit alloc: p->pabXferBuf = 0x%x bytes at 0x%x\n",
1153
								bufsize,(unsigned int) p->pabXferBuf);
1154
		return SANE_STATUS_GOOD;
1155
	}
1156
}
1157
1158
1159
/****************************************************************************/
1160
void Hp_rts_XferBufferExit( SANE_Handle h )
1161
/****************************************************************************/
1162
{
1163
	TScanner *s;
1164
1165
	s = (TScanner *)h;
1166
	if (s->DataPipe.pabXferBuf != NULL) {
1167
		DBG(DBG_SCAN,"Hp_rts_XferBufferExit free: p->pabXferBuf at 0x%x\n",
1168
				(unsigned int) s->DataPipe.pabXferBuf);
1169
		free(s->DataPipe.pabXferBuf);
1170
		s->DataPipe.pabXferBuf = NULL;
1171
	}
1172
	else { ;
1173
		DBG(DBG_ERR, "Hp_rts_XferBufExit: Xfer buffer not initialised!\n");
1174
	}
1175
}
1176
1177
(-)sane-backends-1.0.19/backend/hp_rts_xfer.h (+214 lines)
Line 0 Link Here
1
 /* sane - Scanner Access Now Easy.
2
   Copyright (C) 2003 Johannes Hub (JohannesHub@t-online.de)
3
4
   This file was initially copied from the hp3300 backend.
5
   This file is part of the SANE package.
6
7
   This program is free software; you can redistribute it and/or
8
   modify it under the terms of the GNU General Public License
9
   as published by the Free Software Foundation; either version 2
10
   of the License, or (at your option) any later version.
11
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21
   As a special exception, the authors of SANE give permission for
22
   additional uses of the libraries contained in this release of SANE.
23
24
   The exception is that, if you link a SANE library with other files
25
   to produce an exutable, this does not by itself cause the
26
   resulting executable to be covered by the GNU General Public
27
   License.  Your use of that executable is in no way restricted on
28
   account of linking the SANE library code into it.
29
30
   This exception does not, however, invalidate any other reasons why
31
   the executable file might be covered by the GNU General Public
32
   License.
33
34
   If you submit changes to SANE to the maintainers to be included in
35
   a subsequent release, you agree by submitting the changes that
36
   those changes may be distributed with this exception intact.
37
38
   If you write modifications of your own for SANE, it is your choice
39
   whether to permit this exception to apply to your modifications.
40
   If you do not wish that, delete this exception notice.
41
*/
42
43
/*
44
    Concept for a backend for scanners based on the RTS88xx chipset,
45
    such as HP4400C, HP4470C.
46
    Parts of this source were inspired by other backends.
47
48
		History:
49
50
		Version 0.18  21.11.04 13.alpha,
51
				- source sorted,
52
				- now only SANEI_USB_SUPPORT for a better overview(xfermodules removed)
53
				- read and verify the MainBoardID 
54
		Version 0.17p 02.11.04 12.alpha, source sorted, little fixes, SANEI_USB_SUPPORT implemented
55
		Version 0.17p 02.11.04 12.alpha, source sourted, little fixes, SANEI_USB_SUPPORT implemented
56
		Version 0.17b 30.03.04 10.alpha, little fixes and libusb implemented
57
		Version 0.17  09.03.04 9. alpha, HP3500 included
58
		Version 0.16  06.02.04 8. alpha, wait counting on LCD
59
		Version 0.15a 29.01.04 7. alpha, CCD switch moved to config file
60
		Version 0.15  11.01.04 6. alpha, a second CCD implemented
61
		Version 0.13a 21.11.04 4. alpha, an little fix included
62
		Version 0.12  22.10.03 third alpha, Backend name changed to HP_RTS88xx
63
		Version 0.11  30.08.03 second alpha
64
		Version 0.10  19.07.03 first alpha
65
*/
66
67
/*
68
    Provides a simple interface to read and write data from the scanner,
69
    without any knowledge whether it's a parallel or USB scanner
70
*/
71
72
#ifndef _HP_RTS_XFER_H_
73
#define _HP_RTS_XFER_H_
74
75
#include <stdio.h> /* for FILE * */
76
77
#ifdef STANDALONE
78
79
	#include <ctype.h>
80
	#include "../include/sane/config.h"
81
	#include "../include/sane/sane.h"
82
83
	#include "hp_rts88xx.h"
84
	#undef DBG
85
	#undef DBG_MSG
86
	#undef DBG_USB
87
	#undef DBG_OPT
88
	#undef DBG_SCAN
89
	#undef DBG_ASSERT
90
	#undef DBG_ERR
91
92
	#define DBG          fprintf
93
	#define DBG_MSG      stdout
94
	#define DBG_USB      stdout
95
	#define DBG_OPT      stdout
96
	#define DBG_SCAN     stdout
97
	#define DBG_ASSERT   stdout
98
	#define DBG_ERR      stdout
99
100
#endif
101
102
103
#define MAINBOARD_ID          0xb1
104
#define	REG_MOVE_CONTROL_TEST	0xb3
105
106
#define MAX_READ_WRITE	0x3fff    /* 4096 */
107
#define TIMEOUT         10000
108
#define XFER_BUF_SIZE  0xFF00
109
110
#ifndef MIN
111
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
112
#endif
113
#ifndef MAX
114
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
115
#endif
116
117
118
typedef enum {
119
	eUnknownModel = 0,
120
	eHp3500c,
121
	eHp3530c,
122
	eHp3570c,
123
	eHp4400c,
124
	eHp4470c,
125
	eVi8920,
126
	eVi8900,
127
	eVi8700,
128
	eVi5800,
129
	eVi5300,
130
	eVi4800,
131
	eVa3000,
132
	eMi3000,
133
	ePlS6,
134
	ePrlS6
135
} EScannerModel;
136
137
138
typedef struct {
139
	SANE_Char     *pszVendor;
140
	SANE_Char     *pszName;
141
	SANE_Int      iVendor;
142
	SANE_Int      iProduct;
143
	EScannerModel eModel;
144
} TScannerModel;
145
146
147
/* linked list of SANE_Device structures */
148
typedef struct TDevListEntry
149
{
150
  struct TDevListEntry *pNext;
151
  SANE_Device dev;
152
}
153
TDevListEntry;
154
155
156
typedef SANE_Int (TFnReportDevice)(TScannerModel *pModel, SANE_Char *pszDeviceName);
157
158
/* USB device file name */
159
extern SANE_Char * usb_devfile;
160
161
/* list of supported models, the actual list is in hp_rts_xfer.c */
162
extern TScannerModel ScannerModels[];
163
164
/*  The number returned by Hp_rts_XferInit is a handle. This handle needs to
165
    be passed to all other transfer functions.
166
    Internally it is a pointer to structure containg function pointers
167
*/
168
void			Hp_rts_DumpHex(SANE_Byte *pabData, SANE_Int iLen, SANE_Int iWidth, SANE_Int withLf);
169
void			Hp_rts_DumpBits(SANE_Byte reg, SANE_Byte pabData);
170
171
SANE_Int Hp_rts_XferInit(/*EScannerModel *peModel*/void);
172
/*SANE_Int  Hp_rts_XferInit        (EScannerModel *peModel);*/
173
SANE_Int  Hp_rts_XferExit        (SANE_Int iXferHandle);
174
SANE_Int  Hp_rts_RegWrite        (SANE_Int iXferHandle, SANE_Byte reg, SANE_Byte bData);
175
SANE_Int  Hp_rts_RegRead         (SANE_Int iXferHandle, SANE_Byte reg, SANE_Byte *pbData);
176
SANE_Int  Hp_rts_BulkWrite       (SANE_Int iXferHandle, SANE_Byte reg, SANE_Byte *pabBuf, SANE_Int iSize, SANE_Int wHeader);
177
SANE_Int  Hp_rts_BulkRead        (SANE_Int iXferHandle, SANE_Byte reg, SANE_Byte *pabBuf, SANE_Int iSize, SANE_Int wWrite);
178
SANE_Int  Hp_rts_BulkReadall     (SANE_Int iHandle,     SANE_Byte *pabData);
179
SANE_Bool Hp_rts_MatchUsbDevice  (SANE_Int iVendor,     SANE_Int iProduct, TScannerModel **ppeModel);
180
SANE_Bool Hp_rts_ProbeRegisters  (THWParams *pHWParams);
181
SANE_Int  Hp_rts_Set_double_reg  (SANE_Int iHandle, SANE_Byte reg, SANE_Byte c1, SANE_Byte c2 );
182
SANE_Int  Hp_rts_Read_double_reg (SANE_Int iHandle, SANE_Byte reg, SANE_Byte *pbData );
183
SANE_Int  Hp_rts_data_ready      (SANE_Int iHandle, SANE_Int *size);
184
SANE_Int  Hp_rts_read_data       (SANE_Int iHandle, SANE_Int size,SANE_Byte *data);
185
SANE_Int Hp_rts_set_value_lsbfirst(	SANE_Byte	*regs,SANE_Int	firstreg,SANE_Int totalregs, SANE_Word	value);
186
187
SANE_Bool  Hp_rts_is_moving       (SANE_Int iHandle);
188
SANE_Int  Hp_rts_start_moving    (SANE_Int iHandle);
189
SANE_Int  Hp_rts_stop_moving     (SANE_Int iHandle);
190
void      Hp_rts_WriteGammaCalibTable   (SANE_Int iHandle,
191
																	const SANE_Int *pabGammaR, const SANE_Int *pabGammaG,const SANE_Int *pabGammaB);
192
/*void      Hp_rts_SetDefaultGamma (SANE_Int iHandle);*/
193
SANE_Bool  Hp_rts_Check_Moving  (SANE_Int iHandle);
194
SANE_Int  Hp_rts_Read_Sram       (SANE_Int iHandle, SANE_Byte *pabData,
195
                                  SANE_Int iSize);
196
SANE_Int  Hp_rts_set_noscan_distance(SANE_Byte	*regs,SANE_Word	value);
197
SANE_Int  Hp_rts_set_total_distance(SANE_Byte	*regs,SANE_Word	value);
198
SANE_Int  Hp_rts_set_scanline_end(SANE_Byte	*regs,SANE_Word	value);
199
SANE_Int  Hp_rts_set_scanline_start(SANE_Byte	*regs,SANE_Word	value);
200
201
SANE_Status Hp_rts_CircBufferInit (SANE_Handle h, TDataPipe *p, SANE_Int iBytesPerLine,
202
                            SANE_Int iMisAlignment, SANE_Bool mode);
203
204
SANE_Bool Hp_rts_CircBufferGetLine     (SANE_Handle h, TDataPipe *p, SANE_Byte *pabLine,
205
                            SANE_Bool mode);
206
207
void Hp_rts_CircBufferExit        (SANE_Handle h);
208
209
SANE_Bool Hp_rts_XferBufferGetLine(SANE_Handle h, TDataPipe *p, SANE_Byte *pabLine);
210
211
void Hp_rts_XferBufferExit        (SANE_Handle h);
212
SANE_Status Hp_rts_XferBufferInit (SANE_Handle h, TDataPipe *p);
213
214
#endif /* _HP_RTS_XFER_H_ */
(-)sane-backends-1.0.19/doc/Makefile.in (-2 / +2 lines)
Lines 39-45 Link Here
39
@SET_MAKE@
39
@SET_MAKE@
40
40
41
SECT1	= scanimage.1 sane-config.1 sane-find-scanner.1 gamma4scanimage.1
41
SECT1	= scanimage.1 sane-config.1 sane-find-scanner.1 gamma4scanimage.1
42
SECT5	= sane-abaton.5 sane-agfafocus.5 sane-apple.5 sane-as6e.5 sane-dll.5 \
42
SECT5	= sane-abaton.5 sane-agfafocus.5 sane-apple.5 sane-as6e.5 sane-dll.5 sane-hp_rts88xx.5 \
43
          sane-dc25.5 sane-dmc.5 sane-epson.5 sane-hp.5 sane-gphoto2.5 \
43
          sane-dc25.5 sane-dmc.5 sane-epson.5 sane-hp.5 sane-gphoto2.5 \
44
          sane-leo.5 sane-lexmark.5 sane-matsushita.5 sane-microtek.5 \
44
          sane-leo.5 sane-lexmark.5 sane-matsushita.5 sane-microtek.5 \
45
          sane-microtek2.5 sane-mustek.5 sane-nec.5 sane-net.5 sane-pie.5 \
45
          sane-microtek2.5 sane-mustek.5 sane-nec.5 sane-net.5 sane-pie.5 \
Lines 98-104 Link Here
98
  sane-artec.man sane-as6e.man sane-avision.man sane-bh.man \
98
  sane-artec.man sane-as6e.man sane-avision.man sane-bh.man \
99
  sane-canon.man sane-canon630u.man sane-config.man sane-coolscan.man \
99
  sane-canon.man sane-canon630u.man sane-config.man sane-coolscan.man \
100
  sane-coolscan2.man sane-dc210.man sane-dc240.man \
100
  sane-coolscan2.man sane-dc210.man sane-dc240.man \
101
  sane-dc25.man sane-dll.man sane-dmc.man sane-epson.man \
101
  sane-dc25.man sane-dll.man sane-hp_rts88xx.man sane-dmc.man sane-epson.man \
102
  sane-find-scanner.man sane-fujitsu.man sane-gphoto2.man sane-hp.man \
102
  sane-find-scanner.man sane-fujitsu.man sane-gphoto2.man sane-hp.man \
103
  sane-logo.png sane-logo2.jpg sane-matsushita.man sane-microtek.man \
103
  sane-logo.png sane-logo2.jpg sane-matsushita.man sane-microtek.man \
104
  sane-leo.man sane-lexmark.man sane-microtek2.man \
104
  sane-leo.man sane-lexmark.man sane-microtek2.man \
(-)sane-backends-1.0.19/doc/descriptions/hp_rts88xx.desc (+37 lines)
Line 0 Link Here
1
;
2
; SANE Backend specification file
3
;
4
:backend "hp_rts88xx"                                ; name of backend
5
;:version "(0.18)"                                   ; version of backend
6
;:manpage "sane-hp_rts88xx"                          ; name of manpage (if it exists)
7
:url "http://hp44x0backend.sourceforge.net" ; backend's web page
8
9
:devicetype :scanner                                  ; start of a list of devices....
10
11
:mfg "Hewlett-Packard"                                ; name a manufacturer
12
:url "http://www.hp.com/"
13
14
:model "HP4400C"                                      ; name models for above-specified mfg.
15
:interface "USB"
16
:status :basic
17
:comment "grayscale 300/600 DPI"
18
19
:model "HP4470C"
20
:interface "USB"
21
:status :basic
22
:comment "grayscale 300/600 DPI, XPA/bed mode"
23
24
:model "HP3500C"
25
:interface "USB"
26
:status :basic
27
:comment "not tested"
28
29
:model "HP3530C"
30
:interface "USB"
31
:status :basic
32
:comment "not tested"
33
34
:model "HP3570C"
35
:interface "USB"
36
:status :basic
37
:comment "not tested"
(-)sane-backends-1.0.19/doc/sane-hp_rts88xx.man (+108 lines)
Line 0 Link Here
1
.\" $Id: sane-hp_rts88xx.man,v 1.2 2004/22/10 10:35:31 jh Exp $
2
.TH sane-hp_rts88xx 5 "22 Oct 2004"
3
.IX sane-hp_rts88xx
4
5
.SH NAME
6
sane-hp_rts88xx - SANE backend for scanners based on the RTS8891 chipset.
7
8
.SH DESCRIPTION
9
The
10
.B sane-hp_rts88xx
11
implements a SANE (Scanner Access Now Easy) backend that
12
provides access to RTS8891 chipset based scanners. This backend will try to support
13
the following models:
14
15
MANUFACTURER:    MODEL:         USB ID:
16
.br
17
---------------  --------------  ---------
18
.br
19
Hewlett-Packard  Scanjet 4400c   03F0-0705
20
.br
21
Hewlett-Packard  Scanjet 4470c   03F0-0805
22
.br
23
Hewlett-Packard  Scanjet 3500C   03F0-2205
24
.br
25
Hewlett-Packard  Scanjet 3530c   03F0-2005
26
.br
27
Hewlett-Packard  Scanjet 3570c   03F0-2005
28
.br
29
.PP
30
.br
31
32
.SH "DEVICE NAMES"
33
This backend expects device names of the form:
34
.PP
35
.RS
36
.I special
37
.RE
38
.PP
39
Where
40
.I special
41
is a path-name for the special device that corresponds to a USB scanner.
42
With GNU/Linux systems, such a device name could be
43
.I /dev/usb/scanner0
44
or
45
.IR /dev/usbscanner1 ,
46
for example.
47
48
49
.SH CONFIGURATION
50
The
51
.I hp_rts88xx.conf
52
file contains the device name that correspond to the hp44x0c
53
scanner.  Empty lines and lines starting with a hash mark (#) are
54
ignored.
55
.PP
56
A sample configuration file is shown below:
57
.PP
58
.RS
59
# Comment
60
.br
61
/dev/usbscanner
62
# option_CCD
63
# CCD0 or CCD1 allowed
64
# if you receive a black image, change it to CCD1
65
option CCD0
66
.RE
67
.PP
68
The first line is ignored. The second line is the device filename to use
69
in order to access the hp44x0c Scanner. If no device is given, the
70
backend will use libUSB.
71
72
.SH FILES
73
.TP
74
.I @CONFIGDIR@/hp_rts88xx.conf
75
The backend configuration file (see also description of SANE_CONFIG_DIR below).
76
77
.TP
78
.I @LIBDIR@/libsane-hp_rts88xx.a
79
The static library implementing this backend.
80
81
.TP
82
.I @LIBDIR@/libsane-hp_rts88xx.so
83
The shared library implementing this backend (present on systems that
84
support dynamic loading).
85
.SH ENVIRONMENT
86
87
.TP
88
.B SANE_CONFIG_DIR
89
This environment variable specifies the list of directories that may
90
contain the configuration file.  Under UNIX, the directories are
91
separated by a colon (`:'), under OS/2, they are separated by a
92
semi-colon (`;').  If this variable is not set, the configuration file
93
is searched in two default directories: first, the current working
94
directory (".") and then in @CONFIGDIR@.  If the value of the
95
environment variable ends with the directory separator character, then
96
the default directories are searched after the explicitly specified
97
directories.  For example, setting
98
.B SANE_CONFIG_DIR
99
to "/tmp/config:" would result in directories "tmp/config", ".", and
100
"@CONFIGDIR@" being searched (in this order).
101
.TP
102
103
.SH "SEE ALSO"
104
sane(7), sane\-usb(5)
105
.br
106
http://hp44x0backend.sourceforge.net
107
.SH AUTHOR
108
Johannes Hub <johanneshub@t-online.det>

Return to bug 247605