1 /* sane - Scanner Access Now Easy.
2
3 This file is part of the SANE package.
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
17
18 As a special exception, the authors of SANE give permission for
19 additional uses of the libraries contained in this release of SANE.
20
21 The exception is that, if you link a SANE library with other files
22 to produce an executable, this does not by itself cause the
23 resulting executable to be covered by the GNU General Public
24 License. Your use of that executable is in no way restricted on
25 account of linking the SANE library code into it.
26
27 This exception does not, however, invalidate any other reasons why
28 the executable file might be covered by the GNU General Public
29 License.
30
31 If you submit changes to SANE to the maintainers to be included in
32 a subsequent release, you agree by submitting the changes that
33 those changes may be distributed with this exception intact.
34
35 If you write modifications of your own for SANE, it is your choice
36 whether to permit this exception to apply to your modifications.
37 If you do not wish that, delete this exception notice.
38
39 --------------------------------------------------------------------------
40
41 This file implements a SANE backend for HP ScanJet 3500 series scanners.
42 Currently supported:
43 - HP ScanJet 3500C
44 - HP ScanJet 3530C
45 - HP ScanJet 3570C
46
47 SANE FLOW DIAGRAM
48
49 - sane_init() : initialize backend, attach scanners
50 . - sane_get_devices() : query list of scanner devices
51 . - sane_open() : open a particular scanner device
52 . . - sane_set_io_mode : set blocking mode
53 . . - sane_get_select_fd : get scanner fd
54 . . - sane_get_option_descriptor() : get option information
55 . . - sane_control_option() : change option values
56 . .
57 . . - sane_start() : start image acquisition
58 . . - sane_get_parameters() : returns actual scan parameters
59 . . - sane_read() : read image data (from pipe)
60 . .
61 . . - sane_cancel() : cancel operation
62 . - sane_close() : close opened scanner device
63 - sane_exit() : terminate use of backend
64
65
66 There are some device specific routines in this file that are in "#if 0"
67 sections - these are left in place for documentation purposes in case
68 somebody wants to implement features that use those routines.
69
70 */
71
72 /* ------------------------------------------------------------------------- */
73
74 #include "../include/sane/config.h"
75
76 #include <errno.h>
77 #include <fcntl.h>
78 #include <limits.h>
79 #include <signal.h>
80 #include <stdio.h>
81 #include <stdlib.h>
82 #include <string.h>
83 #include <ctype.h>
84 #include <time.h>
85 #include <math.h>
86
87 #include <sys/types.h>
88 #include <unistd.h>
89 #ifdef HAVE_LIBC_H
90 # include <libc.h> /* NeXTStep/OpenStep */
91 #endif
92
93 #include "../include/sane/sane.h"
94 #include "../include/sane/sanei_usb.h"
95 #include "../include/sane/saneopts.h"
96 #include "../include/sane/sanei_config.h"
97 #include "../include/sane/sanei_thread.h"
98 #include "../include/sane/sanei_backend.h"
99
100 #define RTCMD_GETREG 0x80
101 #define RTCMD_READSRAM 0x81
102
103 #define RTCMD_SETREG 0x88
104 #define RTCMD_WRITESRAM 0x89
105
106 #define RTCMD_NVRAMCONTROL 0x8a
107
108 #define RTCMD_BYTESAVAIL 0x90
109 #define RTCMD_READBYTES 0x91
110
111 #define RT_CHANNEL_ALL 0
112 #define RT_CHANNEL_RED 1
113 #define RT_CHANNEL_GREEN 2
114 #define RT_CHANNEL_BLUE 3
115
116 typedef int (*rts8801_callback) (void *param, unsigned bytes, void *data);
117
118 #define DEBUG 1
119 #define SCANNER_UNIT_TO_FIXED_MM(number) SANE_FIX(number * MM_PER_INCH / 1200)
120 #define FIXED_MM_TO_SCANNER_UNIT(number) SANE_UNFIX(number) * 1200 / MM_PER_INCH
121
122 #define MSG_ERR 1
123 #define MSG_USER 5
124 #define MSG_INFO 6
125 #define FLOW_CONTROL 10
126 #define MSG_IO 15
127 #define MSG_IO_READ 17
128 #define IO_CMD 20
129 #define IO_CMD_RES 20
130 #define MSG_GET 25
131 /* ------------------------------------------------------------------------- */
132
133 enum hp3500_option
134 {
135 OPT_NUM_OPTS = 0,
136
137 OPT_RESOLUTION,
138 OPT_GEOMETRY_GROUP,
139 OPT_TL_X,
140 OPT_TL_Y,
141 OPT_BR_X,
142 OPT_BR_Y,
143 OPT_MODE_GROUP,
144 OPT_MODE,
145 OPT_BRIGHTNESS,
146 OPT_CONTRAST,
147 OPT_GAMMA,
148
149 NUM_OPTIONS
150 };
151
152 typedef struct
153 {
154 int left;
155 int top;
156 int right;
157 int bottom;
158 } hp3500_rect;
159
160 struct hp3500_data
161 {
162 struct hp3500_data *next;
163 char *devicename;
164
165 int sfd;
166 int pipe_r;
167 int pipe_w;
168 SANE_Pid reader_pid;
169
170 int resolution;
171 int mode;
172
173 time_t last_scan;
174
175 hp3500_rect request_mm;
176 hp3500_rect actual_mm;
177 hp3500_rect fullres_pixels;
178 hp3500_rect actres_pixels;
179
180 int rounded_left;
181 int rounded_top;
182 int rounded_right;
183 int rounded_bottom;
184
185 int bytes_per_scan_line;
186 int scan_width_pixels;
187 int scan_height_pixels;
188
189 int brightness;
190 int contrast;
191
192 double gamma;
193
194 SANE_Option_Descriptor opt[NUM_OPTIONS];
195 SANE_Device sane;
196 };
197
198 struct hp3500_write_info
199 {
200 struct hp3500_data *scanner;
201 int bytesleft;
202 };
203
204 typedef struct detailed_calibration_data
205 {
206 unsigned char const *channeldata[3];
207 unsigned resolution_divisor;
208 } detailed_calibration_data;
209
210 static struct hp3500_data *first_dev = 0;
211 static struct hp3500_data **new_dev = &first_dev;
212 static int num_devices = 0;
213 static SANE_Int res_list[] =
214 { 9, 50, 75, 100, 150, 200, 300, 400, 600, 1200 };
215 static const SANE_Range range_x =
216 { 0, SANE_FIX (215.9), SANE_FIX (MM_PER_INCH / 1200) };
217 static const SANE_Range range_y =
218 { 0, SANE_FIX (298.7), SANE_FIX (MM_PER_INCH / 1200) };
219 static const SANE_Range range_brightness =
220 { 0, 255, 0 };
221 static const SANE_Range range_contrast =
222 { 0, 255, 0 };
223 static const SANE_Range range_gamma =
224 { SANE_FIX (0.2), SANE_FIX(4.0), SANE_FIX(0.01) };
225
226
227 #define HP3500_COLOR_SCAN 0
228 #define HP3500_GRAY_SCAN 1
229 #define HP3500_LINEART_SCAN 2
230 #define HP3500_TOTAL_SCANS 3
231
232 static char const *scan_mode_list[HP3500_TOTAL_SCANS + 1] = { 0 };
233
234 static SANE_Status attachScanner (const char *name);
235 static SANE_Status init_options (struct hp3500_data *scanner);
236 static int reader_process (void *);
237 static void calculateDerivedValues (struct hp3500_data *scanner);
238 static void do_reset (struct hp3500_data *scanner);
239 static void do_cancel (struct hp3500_data *scanner);
240 static size_t max_string_size(char const **);
241
242 /*
243 * used by sane_get_devices
244 */
245 static const SANE_Device **devlist = 0;
246
247 /*
248 * SANE Interface
249 */
250
251
252 /**
253 * Called by SANE initially.
254 *
255 * From the SANE spec:
256 * This function must be called before any other SANE function can be
257 * called. The behavior of a SANE backend is undefined if this
258 * function is not called first. The version code of the backend is
259 * returned in the value pointed to by version_code. If that pointer
260 * is NULL, no version code is returned. Argument authorize is either
261 * a pointer to a function that is invoked when the backend requires
262 * authentication for a specific resource or NULL if the frontend does
263 * not support authentication.
264 */
265 SANE_Status
sane_init(SANE_Int * version_code, SANE_Auth_Callback authorize)266 sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
267 {
268 (void) authorize; /* get rid of compiler warning */
269
270 DBG_INIT ();
271 DBG (10, "sane_init\n");
272
273 sanei_usb_init ();
274 sanei_thread_init ();
275
276 if (version_code)
277 *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, 0);
278
279 sanei_usb_find_devices (0x03f0, 0x2205, attachScanner);
280 sanei_usb_find_devices (0x03f0, 0x2005, attachScanner);
281
282 return SANE_STATUS_GOOD;
283 }
284
285
286 /**
287 * Called by SANE to find out about supported devices.
288 *
289 * From the SANE spec:
290 * This function can be used to query the list of devices that are
291 * available. If the function executes successfully, it stores a
292 * pointer to a NULL terminated array of pointers to SANE_Device
293 * structures in *device_list. The returned list is guaranteed to
294 * remain unchanged and valid until (a) another call to this function
295 * is performed or (b) a call to sane_exit() is performed. This
296 * function can be called repeatedly to detect when new devices become
297 * available. If argument local_only is true, only local devices are
298 * returned (devices directly attached to the machine that SANE is
299 * running on). If it is false, the device list includes all remote
300 * devices that are accessible to the SANE library.
301 *
302 * SANE does not require that this function is called before a
303 * sane_open() call is performed. A device name may be specified
304 * explicitly by a user which would make it unnecessary and
305 * undesirable to call this function first.
306 */
307 SANE_Status
sane_get_devices(const SANE_Device *** device_list, SANE_Bool local_only)308 sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
309 {
310 int i;
311 struct hp3500_data *dev;
312
313 DBG (10, "sane_get_devices %d\n", local_only);
314
315 if (devlist)
316 free (devlist);
317 devlist = calloc (num_devices + 1, sizeof (SANE_Device *));
318 if (!devlist)
319 return SANE_STATUS_NO_MEM;
320
321 for (dev = first_dev, i = 0; i < num_devices; dev = dev->next)
322 devlist[i++] = &dev->sane;
323 devlist[i++] = 0;
324
325 *device_list = devlist;
326
327 return SANE_STATUS_GOOD;
328 }
329
330
331 /**
332 * Called to establish connection with the scanner. This function will
333 * also establish meaningful defaults and initialize the options.
334 *
335 * From the SANE spec:
336 * This function is used to establish a connection to a particular
337 * device. The name of the device to be opened is passed in argument
338 * name. If the call completes successfully, a handle for the device
339 * is returned in *h. As a special case, specifying a zero-length
340 * string as the device requests opening the first available device
341 * (if there is such a device).
342 */
343 SANE_Status
sane_open(SANE_String_Const name, SANE_Handle * handle)344 sane_open (SANE_String_Const name, SANE_Handle * handle)
345 {
346 struct hp3500_data *dev = NULL;
347 struct hp3500_data *scanner = NULL;
348
349 if (name[0] == 0)
350 {
351 DBG (10, "sane_open: no device requested, using default\n");
352 if (first_dev)
353 {
354 scanner = (struct hp3500_data *) first_dev;
355 DBG (10, "sane_open: device %s found\n", first_dev->sane.name);
356 }
357 }
358 else
359 {
360 DBG (10, "sane_open: device %s requested\n", name);
361
362 for (dev = first_dev; dev; dev = dev->next)
363 {
364 if (strcmp (dev->sane.name, name) == 0)
365 {
366 DBG (10, "sane_open: device %s found\n", name);
367 scanner = (struct hp3500_data *) dev;
368 }
369 }
370 }
371
372 if (!scanner)
373 {
374 DBG (10, "sane_open: no device found\n");
375 return SANE_STATUS_INVAL;
376 }
377
378 *handle = scanner;
379
380 init_options (scanner);
381
382 scanner->resolution = 200;
383 scanner->request_mm.left = 0;
384 scanner->request_mm.top = 0;
385 scanner->request_mm.right = SCANNER_UNIT_TO_FIXED_MM (10200);
386 scanner->request_mm.bottom = SCANNER_UNIT_TO_FIXED_MM (14100);
387 scanner->mode = 0;
388 scanner->brightness = 128;
389 scanner->contrast = 64;
390 scanner->gamma = 2.2;
391 calculateDerivedValues (scanner);
392
393 return SANE_STATUS_GOOD;
394
395 }
396
397
398 /**
399 * An advanced method we don't support but have to define.
400 */
401 SANE_Status
sane_set_io_mode(SANE_Handle h, SANE_Bool non_blocking)402 sane_set_io_mode (SANE_Handle h, SANE_Bool non_blocking)
403 {
404 DBG (10, "sane_set_io_mode\n");
405 DBG (99, "%d %p\n", non_blocking, h);
406 return SANE_STATUS_UNSUPPORTED;
407 }
408
409
410 /**
411 * An advanced method we don't support but have to define.
412 */
413 SANE_Status
sane_get_select_fd(SANE_Handle h, SANE_Int * fdp)414 sane_get_select_fd (SANE_Handle h, SANE_Int * fdp)
415 {
416 struct hp3500_data *scanner = (struct hp3500_data *) h;
417 DBG (10, "sane_get_select_fd\n");
418 *fdp = scanner->pipe_r;
419 DBG (99, "%p %d\n", h, *fdp);
420 return SANE_STATUS_GOOD;
421 }
422
423
424 /**
425 * Returns the options we know.
426 *
427 * From the SANE spec:
428 * This function is used to access option descriptors. The function
429 * returns the option descriptor for option number n of the device
430 * represented by handle h. Option number 0 is guaranteed to be a
431 * valid option. Its value is an integer that specifies the number of
432 * options that are available for device handle h (the count includes
433 * option 0). If n is not a valid option index, the function returns
434 * NULL. The returned option descriptor is guaranteed to remain valid
435 * (and at the returned address) until the device is closed.
436 */
437 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle handle, SANE_Int option)438 sane_get_option_descriptor (SANE_Handle handle, SANE_Int option)
439 {
440 struct hp3500_data *scanner = handle;
441
442 DBG (MSG_GET,
443 "sane_get_option_descriptor: \"%s\"\n", scanner->opt[option].name);
444
445 if ((unsigned) option >= NUM_OPTIONS)
446 return NULL;
447 return &scanner->opt[option];
448 }
449
450
451 /**
452 * Gets or sets an option value.
453 *
454 * From the SANE spec:
455 * This function is used to set or inquire the current value of option
456 * number n of the device represented by handle h. The manner in which
457 * the option is controlled is specified by parameter action. The
458 * possible values of this parameter are described in more detail
459 * below. The value of the option is passed through argument val. It
460 * is a pointer to the memory that holds the option value. The memory
461 * area pointed to by v must be big enough to hold the entire option
462 * value (determined by member size in the corresponding option
463 * descriptor).
464 *
465 * The only exception to this rule is that when setting the value of a
466 * string option, the string pointed to by argument v may be shorter
467 * since the backend will stop reading the option value upon
468 * encountering the first NUL terminator in the string. If argument i
469 * is not NULL, the value of *i will be set to provide details on how
470 * well the request has been met.
471 */
472 SANE_Status
sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action, void *val, SANE_Int * info)473 sane_control_option (SANE_Handle handle, SANE_Int option,
474 SANE_Action action, void *val, SANE_Int * info)
475 {
476 struct hp3500_data *scanner = (struct hp3500_data *) handle;
477 SANE_Status status;
478 SANE_Word cap;
479 SANE_Int dummy;
480 int i;
481
482 /* Make sure that all those statements involving *info cannot break (better
483 * than having to do "if (info) ..." everywhere!)
484 */
485 if (info == 0)
486 info = &dummy;
487
488 *info = 0;
489
490 if (option >= NUM_OPTIONS)
491 return SANE_STATUS_INVAL;
492
493 cap = scanner->opt[option].cap;
494
495 /*
496 * SANE_ACTION_GET_VALUE: We have to find out the current setting and
497 * return it in a human-readable form (often, text).
498 */
499 if (action == SANE_ACTION_GET_VALUE)
500 {
501 DBG (MSG_GET, "sane_control_option: get value \"%s\"\n",
502 scanner->opt[option].name);
503 DBG (11, "\tcap = %d\n", cap);
504
505 if (!SANE_OPTION_IS_ACTIVE (cap))
506 {
507 DBG (10, "\tinactive\n");
508 return SANE_STATUS_INVAL;
509 }
510
511 switch (option)
512 {
513 case OPT_NUM_OPTS:
514 *(SANE_Word *) val = NUM_OPTIONS;
515 return SANE_STATUS_GOOD;
516
517 case OPT_RESOLUTION:
518 *(SANE_Word *) val = scanner->resolution;
519 return SANE_STATUS_GOOD;
520
521 case OPT_TL_X:
522 *(SANE_Word *) val = scanner->request_mm.left;
523 return SANE_STATUS_GOOD;
524
525 case OPT_TL_Y:
526 *(SANE_Word *) val = scanner->request_mm.top;
527 return SANE_STATUS_GOOD;
528
529 case OPT_BR_X:
530 *(SANE_Word *) val = scanner->request_mm.right;
531 return SANE_STATUS_GOOD;
532
533 case OPT_BR_Y:
534 *(SANE_Word *) val = scanner->request_mm.bottom;
535 return SANE_STATUS_GOOD;
536
537 case OPT_MODE:
538 strcpy ((SANE_Char *) val, scan_mode_list[scanner->mode]);
539 return SANE_STATUS_GOOD;
540
541 case OPT_CONTRAST:
542 *(SANE_Word *) val = scanner->contrast;
543 return SANE_STATUS_GOOD;
544
545 case OPT_GAMMA:
546 *(SANE_Word *) val = SANE_FIX(scanner->gamma);
547 return SANE_STATUS_GOOD;
548
549 case OPT_BRIGHTNESS:
550 *(SANE_Word *) val = scanner->brightness;
551 return SANE_STATUS_GOOD;
552 }
553 }
554 else if (action == SANE_ACTION_SET_VALUE)
555 {
556 DBG (10, "sane_control_option: set value \"%s\"\n",
557 scanner->opt[option].name);
558
559 if (!SANE_OPTION_IS_ACTIVE (cap))
560 {
561 DBG (10, "\tinactive\n");
562 return SANE_STATUS_INVAL;
563 }
564
565 if (!SANE_OPTION_IS_SETTABLE (cap))
566 {
567 DBG (10, "\tnot settable\n");
568 return SANE_STATUS_INVAL;
569 }
570
571 status = sanei_constrain_value (scanner->opt + option, val, info);
572 if (status != SANE_STATUS_GOOD)
573 {
574 DBG (10, "\tbad value\n");
575 return status;
576 }
577
578 /*
579 * Note - for those options which can assume one of a list of
580 * valid values, we can safely assume that they will have
581 * exactly one of those values because that's what
582 * sanei_constrain_value does. Hence no "else: invalid" branches
583 * below.
584 */
585 switch (option)
586 {
587 case OPT_RESOLUTION:
588 if (scanner->resolution == *(SANE_Word *) val)
589 {
590 return SANE_STATUS_GOOD;
591 }
592 scanner->resolution = (*(SANE_Word *) val);
593 calculateDerivedValues (scanner);
594 *info |= SANE_INFO_RELOAD_PARAMS;
595 return SANE_STATUS_GOOD;
596
597 case OPT_TL_X:
598 if (scanner->request_mm.left == *(SANE_Word *) val)
599 return SANE_STATUS_GOOD;
600 scanner->request_mm.left = *(SANE_Word *) val;
601 calculateDerivedValues (scanner);
602 if (scanner->actual_mm.left != scanner->request_mm.left)
603 *info |= SANE_INFO_INEXACT;
604 *info |= SANE_INFO_RELOAD_PARAMS;
605 return SANE_STATUS_GOOD;
606
607 case OPT_TL_Y:
608 if (scanner->request_mm.top == *(SANE_Word *) val)
609 return SANE_STATUS_GOOD;
610 scanner->request_mm.top = *(SANE_Word *) val;
611 calculateDerivedValues (scanner);
612 if (scanner->actual_mm.top != scanner->request_mm.top)
613 *info |= SANE_INFO_INEXACT;
614 *info |= SANE_INFO_RELOAD_PARAMS;
615 return SANE_STATUS_GOOD;
616
617 case OPT_BR_X:
618 if (scanner->request_mm.right == *(SANE_Word *) val)
619 {
620 return SANE_STATUS_GOOD;
621 }
622 scanner->request_mm.right = *(SANE_Word *) val;
623 calculateDerivedValues (scanner);
624 if (scanner->actual_mm.right != scanner->request_mm.right)
625 *info |= SANE_INFO_INEXACT;
626 *info |= SANE_INFO_RELOAD_PARAMS;
627 return SANE_STATUS_GOOD;
628
629 case OPT_BR_Y:
630 if (scanner->request_mm.bottom == *(SANE_Word *) val)
631 {
632 return SANE_STATUS_GOOD;
633 }
634 scanner->request_mm.bottom = *(SANE_Word *) val;
635 calculateDerivedValues (scanner);
636 if (scanner->actual_mm.bottom != scanner->request_mm.bottom)
637 *info |= SANE_INFO_INEXACT;
638 *info |= SANE_INFO_RELOAD_PARAMS;
639 return SANE_STATUS_GOOD;
640
641 case OPT_MODE:
642 for (i = 0; scan_mode_list[i]; ++i)
643 {
644 if (!strcmp ((SANE_Char const *) val, scan_mode_list[i]))
645 {
646 DBG (10, "Setting scan mode to %s (request: %s)\n",
647 scan_mode_list[i], (SANE_Char const *) val);
648 scanner->mode = i;
649 return SANE_STATUS_GOOD;
650 }
651 }
652 /* Impossible */
653 return SANE_STATUS_INVAL;
654
655 case OPT_BRIGHTNESS:
656 scanner->brightness = *(SANE_Word *) val;
657 return SANE_STATUS_GOOD;
658
659 case OPT_CONTRAST:
660 scanner->contrast = *(SANE_Word *) val;
661 return SANE_STATUS_GOOD;
662
663 case OPT_GAMMA:
664 scanner->gamma = SANE_UNFIX(*(SANE_Word *) val);
665 return SANE_STATUS_GOOD;
666 } /* switch */
667 } /* else */
668 return SANE_STATUS_INVAL;
669 }
670
671 /**
672 * Called by SANE when a page acquisition operation is to be started.
673 *
674 */
675 SANE_Status
sane_start(SANE_Handle handle)676 sane_start (SANE_Handle handle)
677 {
678 struct hp3500_data *scanner = handle;
679 int defaultFds[2];
680 int ret;
681
682 DBG (10, "sane_start\n");
683
684 if (scanner->sfd < 0)
685 {
686 /* first call */
687 DBG (10, "sane_start opening USB device\n");
688 if (sanei_usb_open (scanner->sane.name, &(scanner->sfd)) !=
689 SANE_STATUS_GOOD)
690 {
691 DBG (MSG_ERR,
692 "sane_start: open of %s failed:\n", scanner->sane.name);
693 return SANE_STATUS_INVAL;
694 }
695 }
696
697 calculateDerivedValues (scanner);
698
699 DBG (10, "\tbytes per line = %d\n", scanner->bytes_per_scan_line);
700 DBG (10, "\tpixels_per_line = %d\n", scanner->scan_width_pixels);
701 DBG (10, "\tlines = %d\n", scanner->scan_height_pixels);
702
703
704 /* create a pipe, fds[0]=read-fd, fds[1]=write-fd */
705 if (pipe (defaultFds) < 0)
706 {
707 DBG (MSG_ERR, "ERROR: could not create pipe\n");
708 do_cancel (scanner);
709 return SANE_STATUS_IO_ERROR;
710 }
711
712 scanner->pipe_r = defaultFds[0];
713 scanner->pipe_w = defaultFds[1];
714
715 ret = SANE_STATUS_GOOD;
716
717 scanner->reader_pid = sanei_thread_begin (reader_process, scanner);
718 time (&scanner->last_scan);
719
720 if (!sanei_thread_is_valid (scanner->reader_pid))
721 {
722 DBG (MSG_ERR, "cannot fork reader process.\n");
723 DBG (MSG_ERR, "%s", strerror (errno));
724 ret = SANE_STATUS_IO_ERROR;
725 }
726
727 if (sanei_thread_is_forked ())
728 {
729 close (scanner->pipe_w);
730 }
731
732 if (ret == SANE_STATUS_GOOD)
733 {
734 DBG (10, "sane_start: ok\n");
735 }
736
737 return ret;
738 }
739
740
741 /**
742 * Called by SANE to retrieve information about the type of data
743 * that the current scan will return.
744 *
745 * From the SANE spec:
746 * This function is used to obtain the current scan parameters. The
747 * returned parameters are guaranteed to be accurate between the time
748 * a scan has been started (sane_start() has been called) and the
749 * completion of that request. Outside of that window, the returned
750 * values are best-effort estimates of what the parameters will be
751 * when sane_start() gets invoked.
752 *
753 * Calling this function before a scan has actually started allows,
754 * for example, to get an estimate of how big the scanned image will
755 * be. The parameters passed to this function are the handle h of the
756 * device for which the parameters should be obtained and a pointer p
757 * to a parameter structure.
758 */
759 SANE_Status
sane_get_parameters(SANE_Handle handle, SANE_Parameters * params)760 sane_get_parameters (SANE_Handle handle, SANE_Parameters * params)
761 {
762 struct hp3500_data *scanner = (struct hp3500_data *) handle;
763
764
765 DBG (10, "sane_get_parameters\n");
766
767 calculateDerivedValues (scanner);
768
769 params->format =
770 (scanner->mode == HP3500_COLOR_SCAN) ? SANE_FRAME_RGB : SANE_FRAME_GRAY;
771 params->depth = (scanner->mode == HP3500_LINEART_SCAN) ? 1 : 8;
772
773 params->pixels_per_line = scanner->scan_width_pixels;
774 params->lines = scanner->scan_height_pixels;
775
776 params->bytes_per_line = scanner->bytes_per_scan_line;
777
778 params->last_frame = 1;
779 DBG (10, "\tdepth %d\n", params->depth);
780 DBG (10, "\tlines %d\n", params->lines);
781 DBG (10, "\tpixels_per_line %d\n", params->pixels_per_line);
782 DBG (10, "\tbytes_per_line %d\n", params->bytes_per_line);
783 return SANE_STATUS_GOOD;
784 }
785
786
787 /**
788 * Called by SANE to read data.
789 *
790 * In this implementation, sane_read does nothing much besides reading
791 * data from a pipe and handing it back. On the other end of the pipe
792 * there's the reader process which gets data from the scanner and
793 * stuffs it into the pipe.
794 *
795 * From the SANE spec:
796 * This function is used to read image data from the device
797 * represented by handle h. Argument buf is a pointer to a memory
798 * area that is at least maxlen bytes long. The number of bytes
799 * returned is stored in *len. A backend must set this to zero when
800 * the call fails (i.e., when a status other than SANE_STATUS_GOOD is
801 * returned).
802 *
803 * When the call succeeds, the number of bytes returned can be
804 * anywhere in the range from 0 to maxlen bytes.
805 */
806 SANE_Status
sane_read(SANE_Handle handle, SANE_Byte * buf, SANE_Int max_len, SANE_Int * len)807 sane_read (SANE_Handle handle, SANE_Byte * buf,
808 SANE_Int max_len, SANE_Int * len)
809 {
810 struct hp3500_data *scanner = (struct hp3500_data *) handle;
811 ssize_t nread;
812 int source = scanner->pipe_r;
813
814 *len = 0;
815
816 nread = read (source, buf, max_len);
817 DBG (30, "sane_read: read %ld bytes of %ld\n",
818 (long) nread, (long) max_len);
819
820 if (nread < 0)
821 {
822 if (errno == EAGAIN)
823 {
824 return SANE_STATUS_GOOD;
825 }
826 else
827 {
828 do_cancel (scanner);
829 return SANE_STATUS_IO_ERROR;
830 }
831 }
832
833 *len = nread;
834
835 if (nread == 0)
836 {
837 close (source);
838 DBG (10, "sane_read: pipe closed\n");
839 return SANE_STATUS_EOF;
840 }
841
842 return SANE_STATUS_GOOD;
843 } /* sane_read */
844
845
846 /**
847 * Cancels a scan.
848 *
849 * It has been said on the mailing list that sane_cancel is a bit of a
850 * misnomer because it is routinely called to signal the end of a
851 * batch - quoting David Mosberger-Tang:
852 *
853 * > In other words, the idea is to have sane_start() be called, and
854 * > collect as many images as the frontend wants (which could in turn
855 * > consist of multiple frames each as indicated by frame-type) and
856 * > when the frontend is done, it should call sane_cancel().
857 * > Sometimes it's better to think of sane_cancel() as "sane_stop()"
858 * > but that name would have had some misleading connotations as
859 * > well, that's why we stuck with "cancel".
860 *
861 * The current consensus regarding duplex and ADF scans seems to be
862 * the following call sequence: sane_start; sane_read (repeat until
863 * EOF); sane_start; sane_read... and then call sane_cancel if the
864 * batch is at an end. I.e. do not call sane_cancel during the run but
865 * as soon as you get a SANE_STATUS_NO_DOCS.
866 *
867 * From the SANE spec:
868 * This function is used to immediately or as quickly as possible
869 * cancel the currently pending operation of the device represented by
870 * handle h. This function can be called at any time (as long as
871 * handle h is a valid handle) but usually affects long-running
872 * operations only (such as image is acquisition). It is safe to call
873 * this function asynchronously (e.g., from within a signal handler).
874 * It is important to note that completion of this operation does not
875 * imply that the currently pending operation has been cancelled. It
876 * only guarantees that cancellation has been initiated. Cancellation
877 * completes only when the cancelled call returns (typically with a
878 * status value of SANE_STATUS_CANCELLED). Since the SANE API does
879 * not require any other operations to be re-entrant, this implies
880 * that a frontend must not call any other operation until the
881 * cancelled operation has returned.
882 */
883 void
sane_cancel(SANE_Handle h)884 sane_cancel (SANE_Handle h)
885 {
886 DBG (10, "sane_cancel\n");
887 do_cancel ((struct hp3500_data *) h);
888 }
889
890
891 /**
892 * Ends use of the scanner.
893 *
894 * From the SANE spec:
895 * This function terminates the association between the device handle
896 * passed in argument h and the device it represents. If the device is
897 * presently active, a call to sane_cancel() is performed first. After
898 * this function returns, handle h must not be used anymore.
899 */
900 void
sane_close(SANE_Handle handle)901 sane_close (SANE_Handle handle)
902 {
903 DBG (10, "sane_close\n");
904 do_reset (handle);
905 do_cancel (handle);
906 }
907
908
909 /**
910 * Terminates the backend.
911 *
912 * From the SANE spec:
913 * This function must be called to terminate use of a backend. The
914 * function will first close all device handles that still might be
915 * open (it is recommended to close device handles explicitly through
916 * a call to sane_clo-se(), but backends are required to release all
917 * resources upon a call to this function). After this function
918 * returns, no function other than sane_init() may be called
919 * (regardless of the status value returned by sane_exit(). Neglecting
920 * to call this function may result in some resources not being
921 * released properly.
922 */
923 void
sane_exit(void)924 sane_exit (void)
925 {
926 struct hp3500_data *dev, *next;
927
928 DBG (10, "sane_exit\n");
929
930 for (dev = first_dev; dev; dev = next)
931 {
932 next = dev->next;
933 free (dev->devicename);
934 free (dev);
935 }
936
937 if (devlist)
938 free (devlist);
939 }
940
941 /*
942 * The scanning code
943 */
944
945 static SANE_Status
attachScanner(const char *devicename)946 attachScanner (const char *devicename)
947 {
948 struct hp3500_data *dev;
949
950 DBG (15, "attach_scanner: %s\n", devicename);
951
952 for (dev = first_dev; dev; dev = dev->next)
953 {
954 if (strcmp (dev->sane.name, devicename) == 0)
955 {
956 DBG (5, "attach_scanner: scanner already attached (is ok)!\n");
957 return SANE_STATUS_GOOD;
958 }
959 }
960
961
962 if (NULL == (dev = malloc (sizeof (*dev))))
963 return SANE_STATUS_NO_MEM;
964 memset (dev, 0, sizeof (*dev));
965
966 dev->devicename = strdup (devicename);
967 dev->sfd = -1;
968 dev->last_scan = 0;
969 dev->reader_pid = (SANE_Pid) -1;
970 dev->pipe_r = dev->pipe_w = -1;
971
972 dev->sane.name = dev->devicename;
973 dev->sane.vendor = "Hewlett-Packard";
974 dev->sane.model = "ScanJet 3500";
975 dev->sane.type = "scanner";
976
977 ++num_devices;
978 *new_dev = dev;
979
980 DBG (15, "attach_scanner: done\n");
981
982 return SANE_STATUS_GOOD;
983 }
984
985 static SANE_Status
init_options(struct hp3500_data *scanner)986 init_options (struct hp3500_data *scanner)
987 {
988 int i;
989 SANE_Option_Descriptor *opt;
990
991 memset (scanner->opt, 0, sizeof (scanner->opt));
992
993 for (i = 0; i < NUM_OPTIONS; ++i)
994 {
995 scanner->opt[i].name = "filler";
996 scanner->opt[i].size = sizeof (SANE_Word);
997 scanner->opt[i].cap = SANE_CAP_INACTIVE;
998 }
999
1000 opt = scanner->opt + OPT_NUM_OPTS;
1001 opt->title = SANE_TITLE_NUM_OPTIONS;
1002 opt->desc = SANE_DESC_NUM_OPTIONS;
1003 opt->type = SANE_TYPE_INT;
1004 opt->cap = SANE_CAP_SOFT_DETECT;
1005
1006 opt = scanner->opt + OPT_RESOLUTION;
1007 opt->name = SANE_NAME_SCAN_RESOLUTION;
1008 opt->title = SANE_TITLE_SCAN_RESOLUTION;
1009 opt->desc = SANE_DESC_SCAN_RESOLUTION;
1010 opt->type = SANE_TYPE_INT;
1011 opt->constraint_type = SANE_CONSTRAINT_WORD_LIST;
1012 opt->constraint.word_list = res_list;
1013 opt->unit = SANE_UNIT_DPI;
1014 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1015
1016 opt = scanner->opt + OPT_GEOMETRY_GROUP;
1017 opt->title = SANE_I18N ("Geometry");
1018 opt->desc = SANE_I18N ("Geometry Group");
1019 opt->type = SANE_TYPE_GROUP;
1020 opt->constraint_type = SANE_CONSTRAINT_NONE;
1021
1022 opt = scanner->opt + OPT_TL_X;
1023 opt->name = SANE_NAME_SCAN_TL_X;
1024 opt->title = SANE_TITLE_SCAN_TL_X;
1025 opt->desc = SANE_DESC_SCAN_TL_X;
1026 opt->type = SANE_TYPE_FIXED;
1027 opt->unit = SANE_UNIT_MM;
1028 opt->constraint_type = SANE_CONSTRAINT_RANGE;
1029 opt->constraint.range = &range_x;
1030 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1031
1032 opt = scanner->opt + OPT_TL_Y;
1033 opt->name = SANE_NAME_SCAN_TL_Y;
1034 opt->title = SANE_TITLE_SCAN_TL_Y;
1035 opt->desc = SANE_DESC_SCAN_TL_Y;
1036 opt->type = SANE_TYPE_FIXED;
1037 opt->unit = SANE_UNIT_MM;
1038 opt->constraint_type = SANE_CONSTRAINT_RANGE;
1039 opt->constraint.range = &range_y;
1040 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1041
1042 opt = scanner->opt + OPT_BR_X;
1043 opt->name = SANE_NAME_SCAN_BR_X;
1044 opt->title = SANE_TITLE_SCAN_BR_X;
1045 opt->desc = SANE_DESC_SCAN_BR_X;
1046 opt->type = SANE_TYPE_FIXED;
1047 opt->unit = SANE_UNIT_MM;
1048 opt->constraint_type = SANE_CONSTRAINT_RANGE;
1049 opt->constraint.range = &range_x;
1050 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1051
1052 opt = scanner->opt + OPT_BR_Y;
1053 opt->name = SANE_NAME_SCAN_BR_Y;
1054 opt->title = SANE_TITLE_SCAN_BR_Y;
1055 opt->desc = SANE_DESC_SCAN_BR_Y;
1056 opt->type = SANE_TYPE_FIXED;
1057 opt->unit = SANE_UNIT_MM;
1058 opt->constraint_type = SANE_CONSTRAINT_RANGE;
1059 opt->constraint.range = &range_y;
1060 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1061
1062 if (!scan_mode_list[0])
1063 {
1064 scan_mode_list[HP3500_COLOR_SCAN] = SANE_VALUE_SCAN_MODE_COLOR;
1065 scan_mode_list[HP3500_GRAY_SCAN] = SANE_VALUE_SCAN_MODE_GRAY;
1066 scan_mode_list[HP3500_LINEART_SCAN] = SANE_VALUE_SCAN_MODE_LINEART;
1067 scan_mode_list[HP3500_TOTAL_SCANS] = 0;
1068 }
1069
1070 opt = scanner->opt + OPT_MODE_GROUP;
1071 opt->title = SANE_I18N ("Scan Mode Group");
1072 opt->desc = SANE_I18N ("Scan Mode Group");
1073 opt->type = SANE_TYPE_GROUP;
1074 opt->constraint_type = SANE_CONSTRAINT_NONE;
1075
1076 opt = scanner->opt + OPT_MODE;
1077 opt->name = SANE_NAME_SCAN_MODE;
1078 opt->title = SANE_TITLE_SCAN_MODE;
1079 opt->desc = SANE_DESC_SCAN_MODE;
1080 opt->type = SANE_TYPE_STRING;
1081 opt->size = max_string_size(scan_mode_list);
1082 opt->constraint_type = SANE_CONSTRAINT_STRING_LIST;
1083 opt->constraint.string_list = (SANE_String_Const *) scan_mode_list;
1084 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1085
1086 opt = scanner->opt + OPT_BRIGHTNESS;
1087 opt->name = SANE_NAME_BRIGHTNESS;
1088 opt->title = SANE_TITLE_BRIGHTNESS;
1089 opt->desc = SANE_DESC_BRIGHTNESS;
1090 opt->type = SANE_TYPE_INT;
1091 opt->constraint_type = SANE_CONSTRAINT_RANGE;
1092 opt->constraint.range = &range_brightness;
1093 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1094
1095 opt = scanner->opt + OPT_CONTRAST;
1096 opt->name = SANE_NAME_CONTRAST;
1097 opt->title = SANE_TITLE_CONTRAST;
1098 opt->desc = SANE_DESC_CONTRAST;
1099 opt->type = SANE_TYPE_INT;
1100 opt->constraint_type = SANE_CONSTRAINT_RANGE;
1101 opt->constraint.range = &range_contrast;
1102 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1103
1104 opt = scanner->opt + OPT_GAMMA;
1105 opt->name = SANE_NAME_ANALOG_GAMMA;
1106 opt->title = SANE_TITLE_ANALOG_GAMMA;
1107 opt->desc = SANE_DESC_ANALOG_GAMMA;
1108 opt->type = SANE_TYPE_FIXED;
1109 opt->unit = SANE_UNIT_NONE;
1110 opt->constraint_type = SANE_CONSTRAINT_RANGE;
1111 opt->constraint.range = &range_gamma;
1112 opt->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
1113
1114 return SANE_STATUS_GOOD;
1115 }
1116
1117 static void
do_reset(struct hp3500_data *scanner)1118 do_reset (struct hp3500_data *scanner)
1119 {
1120 (void) scanner; /* kill warning */
1121 }
1122
1123 static void
do_cancel(struct hp3500_data *scanner)1124 do_cancel (struct hp3500_data *scanner)
1125 {
1126 if (sanei_thread_is_valid (scanner->reader_pid))
1127 {
1128
1129 if (sanei_thread_kill (scanner->reader_pid) == 0)
1130 {
1131 int exit_status;
1132
1133 sanei_thread_waitpid (scanner->reader_pid, &exit_status);
1134 }
1135 sanei_thread_invalidate (scanner->reader_pid);
1136 }
1137 if (scanner->pipe_r >= 0)
1138 {
1139 close (scanner->pipe_r);
1140 scanner->pipe_r = -1;
1141 }
1142 }
1143
1144 static void
calculateDerivedValues(struct hp3500_data *scanner)1145 calculateDerivedValues (struct hp3500_data *scanner)
1146 {
1147
1148 DBG (12, "calculateDerivedValues\n");
1149
1150 /* Convert the SANE_FIXED values for the scan area into 1/1200 inch
1151 * scanner units */
1152
1153 scanner->fullres_pixels.left =
1154 FIXED_MM_TO_SCANNER_UNIT (scanner->request_mm.left);
1155 scanner->fullres_pixels.top =
1156 FIXED_MM_TO_SCANNER_UNIT (scanner->request_mm.top);
1157 scanner->fullres_pixels.right =
1158 FIXED_MM_TO_SCANNER_UNIT (scanner->request_mm.right);
1159 scanner->fullres_pixels.bottom =
1160 FIXED_MM_TO_SCANNER_UNIT (scanner->request_mm.bottom);
1161
1162 DBG (12, "\tleft margin: %u\n", scanner->fullres_pixels.left);
1163 DBG (12, "\ttop margin: %u\n", scanner->fullres_pixels.top);
1164 DBG (12, "\tright margin: %u\n", scanner->fullres_pixels.right);
1165 DBG (12, "\tbottom margin: %u\n", scanner->fullres_pixels.bottom);
1166
1167
1168 scanner->scan_width_pixels =
1169 scanner->resolution * (scanner->fullres_pixels.right -
1170 scanner->fullres_pixels.left) / 1200;
1171 scanner->scan_height_pixels =
1172 scanner->resolution * (scanner->fullres_pixels.bottom -
1173 scanner->fullres_pixels.top) / 1200;
1174 if (scanner->mode == HP3500_LINEART_SCAN)
1175 scanner->bytes_per_scan_line = (scanner->scan_width_pixels + 7) / 8;
1176 else if (scanner->mode == HP3500_GRAY_SCAN)
1177 scanner->bytes_per_scan_line = scanner->scan_width_pixels;
1178 else
1179 scanner->bytes_per_scan_line = scanner->scan_width_pixels * 3;
1180
1181 if (scanner->scan_width_pixels < 1)
1182 scanner->scan_width_pixels = 1;
1183 if (scanner->scan_height_pixels < 1)
1184 scanner->scan_height_pixels = 1;
1185
1186 scanner->actres_pixels.left =
1187 scanner->fullres_pixels.left * scanner->resolution / 1200;
1188 scanner->actres_pixels.top =
1189 scanner->fullres_pixels.top * scanner->resolution / 1200;
1190 scanner->actres_pixels.right =
1191 scanner->actres_pixels.left + scanner->scan_width_pixels;
1192 scanner->actres_pixels.bottom =
1193 scanner->actres_pixels.top + scanner->scan_height_pixels;
1194
1195 scanner->actual_mm.left =
1196 SCANNER_UNIT_TO_FIXED_MM (scanner->fullres_pixels.left);
1197 scanner->actual_mm.top =
1198 SCANNER_UNIT_TO_FIXED_MM (scanner->fullres_pixels.top);
1199 scanner->actual_mm.bottom =
1200 SCANNER_UNIT_TO_FIXED_MM (scanner->scan_width_pixels * 1200 /
1201 scanner->resolution);
1202 scanner->actual_mm.right =
1203 SCANNER_UNIT_TO_FIXED_MM (scanner->scan_height_pixels * 1200 /
1204 scanner->resolution);
1205
1206 DBG (12, "calculateDerivedValues: ok\n");
1207 }
1208
1209 /* From here on in we have the original code written for the scanner demo */
1210
1211 #define MAX_COMMANDS_BYTES 131072
1212 #define MAX_READ_COMMANDS 1 /* Issuing more than one register
1213 * read command in a single request
1214 * seems to put the device in an
1215 * unpredictable state.
1216 */
1217 #define MAX_READ_BYTES 0xffc0
1218
1219 #define REG_DESTINATION_POSITION 0x60
1220 #define REG_MOVE_CONTROL_TEST 0xb3
1221
1222 static int command_reads_outstanding = 0;
1223 static int command_bytes_outstanding = 0;
1224 static unsigned char command_buffer[MAX_COMMANDS_BYTES];
1225 static int receive_bytes_outstanding = 0;
1226 static char *command_readmem_outstanding[MAX_READ_COMMANDS];
1227 static int command_readbytes_outstanding[MAX_READ_COMMANDS];
1228 static unsigned char sram_access_method = 0;
1229 static unsigned sram_size = 0;
1230 static int udh;
1231
1232 static int
rt_execute_commands(void)1233 rt_execute_commands (void)
1234 {
1235 SANE_Status result;
1236 size_t bytes;
1237
1238 if (!command_bytes_outstanding)
1239 return 0;
1240
1241 bytes = command_bytes_outstanding;
1242
1243 result = sanei_usb_write_bulk (udh, /* 0x02, */ command_buffer, &bytes);
1244
1245 if (result == SANE_STATUS_GOOD && receive_bytes_outstanding)
1246 {
1247 unsigned char readbuf[MAX_READ_BYTES];
1248 int total_read = 0;
1249
1250 do
1251 {
1252 bytes = receive_bytes_outstanding - total_read;
1253 result = sanei_usb_read_bulk (udh,
1254 /* 0x81, */
1255 readbuf + total_read, &bytes);
1256 if (result == SANE_STATUS_GOOD)
1257 total_read += bytes;
1258 else
1259 break;
1260 }
1261 while (total_read < receive_bytes_outstanding);
1262 if (result == SANE_STATUS_GOOD)
1263 {
1264 unsigned char *readptr;
1265 int i;
1266
1267 for (i = 0, readptr = readbuf;
1268 i < command_reads_outstanding;
1269 readptr += command_readbytes_outstanding[i++])
1270 {
1271 memcpy (command_readmem_outstanding[i],
1272 readptr, command_readbytes_outstanding[i]);
1273 }
1274 }
1275 }
1276 receive_bytes_outstanding = command_reads_outstanding =
1277 command_bytes_outstanding = 0;
1278 return (result == SANE_STATUS_GOOD) ? 0 : -1;
1279 }
1280
1281 static int
rt_queue_command(int command, int reg, int count, int bytes, void const *data_, int readbytes, void *readdata)1282 rt_queue_command (int command,
1283 int reg,
1284 int count,
1285 int bytes, void const *data_, int readbytes, void *readdata)
1286 {
1287 int len = 4 + bytes;
1288 unsigned char *buffer;
1289 unsigned char const *data = data_;
1290
1291 /* We add "bytes" here to account for the possibility that all of the
1292 * data bytes are 0xaa and hence require a following 0x00 byte.
1293 */
1294 if (command_bytes_outstanding + len + bytes > MAX_COMMANDS_BYTES ||
1295 (readbytes &&
1296 ((command_reads_outstanding >= MAX_READ_COMMANDS) ||
1297 (receive_bytes_outstanding >= MAX_READ_BYTES))))
1298 {
1299 if (rt_execute_commands () < 0)
1300 return -1;
1301 }
1302
1303 buffer = command_buffer + command_bytes_outstanding;
1304
1305 *buffer++ = command;
1306 *buffer++ = reg;
1307 *buffer++ = count >> 8;
1308 *buffer++ = count;
1309 while (bytes--)
1310 {
1311 *buffer++ = *data;
1312 if (*data++ == 0xaa)
1313 {
1314 *buffer++ = 0;
1315 ++len;
1316 }
1317 }
1318 command_bytes_outstanding += len;
1319 if (readbytes)
1320 {
1321 command_readbytes_outstanding[command_reads_outstanding] = readbytes;
1322 command_readmem_outstanding[command_reads_outstanding] = readdata;
1323 receive_bytes_outstanding += readbytes;
1324 ++command_reads_outstanding;
1325 }
1326
1327 return 0;
1328 }
1329
1330 static int
rt_send_command_immediate(int command, int reg, int count, int bytes, void *data, int readbytes, void *readdata)1331 rt_send_command_immediate (int command,
1332 int reg,
1333 int count,
1334 int bytes,
1335 void *data, int readbytes, void *readdata)
1336 {
1337 rt_queue_command (command, reg, count, bytes, data, readbytes, readdata);
1338 return rt_execute_commands ();
1339 }
1340
1341 static int
rt_queue_read_register(int reg, int bytes, void *data)1342 rt_queue_read_register (int reg, int bytes, void *data)
1343 {
1344 return rt_queue_command (RTCMD_GETREG, reg, bytes, 0, 0, bytes, data);
1345 }
1346
1347 static int
rt_read_register_immediate(int reg, int bytes, void *data)1348 rt_read_register_immediate (int reg, int bytes, void *data)
1349 {
1350 if (rt_queue_read_register (reg, bytes, data) < 0)
1351 return -1;
1352 return rt_execute_commands ();
1353 }
1354
1355 static int
rt_queue_set_register(int reg, int bytes, void *data)1356 rt_queue_set_register (int reg, int bytes, void *data)
1357 {
1358 return rt_queue_command (RTCMD_SETREG, reg, bytes, bytes, data, 0, 0);
1359 }
1360
1361 static int
rt_set_register_immediate(int reg, int bytes, void *data)1362 rt_set_register_immediate (int reg, int bytes, void *data)
1363 {
1364 if (reg < 0xb3 && reg + bytes > 0xb3)
1365 {
1366 int bytes_in_first_block = 0xb3 - reg;
1367
1368 if (rt_set_register_immediate (reg, bytes_in_first_block, data) < 0 ||
1369 rt_set_register_immediate (0xb4, bytes - bytes_in_first_block - 1,
1370 (char *) data + bytes_in_first_block +
1371 1) < 0)
1372 return -1;
1373 return 0;
1374 }
1375 if (rt_queue_set_register (reg, bytes, data) < 0)
1376 return -1;
1377 return rt_execute_commands ();
1378 }
1379
1380 static int
rt_set_one_register(int reg, int val)1381 rt_set_one_register (int reg, int val)
1382 {
1383 char r = val;
1384
1385 return rt_set_register_immediate (reg, 1, &r);
1386 }
1387
1388 static int
rt_write_sram(int bytes, void *data_)1389 rt_write_sram (int bytes, void *data_)
1390 {
1391 unsigned char *data = (unsigned char *) data_;
1392
1393 /* The number of bytes passed in could be much larger than we can transmit
1394 * (0xffc0) bytes. With 0xaa escapes it could be even larger. Accordingly
1395 * we need to count the 0xaa escapes and write in chunks if the number of
1396 * bytes would otherwise exceed a limit (I have used 0xf000 as the limit).
1397 */
1398 while (bytes > 0)
1399 {
1400 int now = 0;
1401 int bufsize = 0;
1402
1403 while (now < bytes && bufsize < 0xf000)
1404 {
1405 int i;
1406
1407 /* Try to avoid writing part pages */
1408 for (i = 0; i < 32 && now < bytes; ++i)
1409 {
1410 ++bufsize;
1411 if (data[now++] == 0xaa)
1412 ++bufsize;
1413 }
1414 }
1415
1416 if (rt_send_command_immediate (RTCMD_WRITESRAM, 0, now, now, data, 0,
1417 0) < 0)
1418 return -1;
1419 bytes -= now;
1420 data += now;
1421 }
1422 return 0;
1423 }
1424
1425 static int
rt_read_sram(int bytes, void *data_)1426 rt_read_sram (int bytes, void *data_)
1427 {
1428 unsigned char *data = (unsigned char *) data_;
1429
1430 while (bytes > 0)
1431 {
1432 int now = (bytes > 0xf000) ? 0xf000 : bytes;
1433 if (rt_send_command_immediate (RTCMD_READSRAM, 0, bytes, 0, 0, bytes,
1434 data) < 0)
1435 return -1;
1436 bytes -= now;
1437 data += now;
1438 }
1439 return 0;
1440 }
1441
1442 static int
rt_set_sram_page(int page)1443 rt_set_sram_page (int page)
1444 {
1445 unsigned char regs[2];
1446
1447 regs[0] = page;
1448 regs[1] = page >> 8;
1449
1450 return rt_set_register_immediate (0x91, 2, regs);
1451 }
1452
1453 static int
rt_detect_sram(unsigned *totalbytes, unsigned char *r93setting)1454 rt_detect_sram (unsigned *totalbytes, unsigned char *r93setting)
1455 {
1456 char data[0x818];
1457 char testbuf[0x818];
1458 unsigned i;
1459 int test_values[] = { 6, 2, 1, -1 };
1460
1461 for (i = 0; i < sizeof (data); ++i)
1462 data[i] = i % 0x61;
1463
1464
1465 for (i = 0; test_values[i] != -1; ++i)
1466 {
1467 if (rt_set_one_register (0x93, test_values[i]) ||
1468 rt_set_sram_page (0x81) ||
1469 rt_write_sram (0x818, data) ||
1470 rt_set_sram_page (0x81) || rt_read_sram (0x818, testbuf))
1471 return -1;
1472 if (!memcmp (testbuf, data, 0x818))
1473 {
1474 sram_access_method = test_values[i];
1475 if (r93setting)
1476 *r93setting = sram_access_method;
1477 break;
1478 }
1479 }
1480 if (!sram_access_method)
1481 return -1;
1482
1483 for (i = 0; i < 16; ++i)
1484 {
1485 int j;
1486 char write_data[32];
1487 char read_data[32];
1488 int pagesetting;
1489
1490 for (j = 0; j < 16; j++)
1491 {
1492 write_data[j * 2] = j * 2;
1493 write_data[j * 2 + 1] = i;
1494 }
1495
1496 pagesetting = i * 4096;
1497
1498
1499 if (rt_set_sram_page (pagesetting) < 0 ||
1500 rt_write_sram (32, write_data) < 0)
1501 return -1;
1502 if (i)
1503 {
1504 if (rt_set_sram_page (0) < 0 || rt_read_sram (32, read_data) < 0)
1505 return -1;
1506 if (!memcmp (read_data, write_data, 32))
1507 {
1508 sram_size = i * 0x20000;
1509 if (totalbytes)
1510 *totalbytes = sram_size;
1511 return 0;
1512 }
1513 }
1514 }
1515 return -1;
1516 }
1517
1518 static int
rt_get_available_bytes(void)1519 rt_get_available_bytes (void)
1520 {
1521 unsigned char data[3];
1522
1523 if (rt_queue_command (RTCMD_BYTESAVAIL, 0, 3, 0, 0, 3, data) < 0 ||
1524 rt_execute_commands () < 0)
1525 return -1;
1526 return ((unsigned) data[0]) |
1527 ((unsigned) data[1] << 8) | ((unsigned) data[2] << 16);
1528 }
1529
1530 static int
rt_get_data(int bytes, void *data)1531 rt_get_data (int bytes, void *data)
1532 {
1533 while (bytes)
1534 {
1535 int bytesnow = bytes;
1536
1537 if (bytesnow > 0xffc0)
1538 bytesnow = 0xffc0;
1539 if (rt_queue_command
1540 (RTCMD_READBYTES, 0, bytesnow, 0, 0, bytesnow, data) < 0
1541 || rt_execute_commands () < 0)
1542 return -1;
1543 bytes -= bytesnow;
1544 data = (char *) data + bytesnow;
1545 }
1546 return 0;
1547 }
1548
1549 static int
rt_is_moving(void)1550 rt_is_moving (void)
1551 {
1552 char r;
1553
1554 if (rt_read_register_immediate (REG_MOVE_CONTROL_TEST, 1, &r) < 0)
1555 return -1;
1556 if (r == 0x08)
1557 return 1;
1558 return 0;
1559 }
1560
1561 static int
rt_is_rewound(void)1562 rt_is_rewound (void)
1563 {
1564 char r;
1565
1566 if (rt_read_register_immediate (0x1d, 1, &r) < 0)
1567 return -1;
1568 if (r & 0x02)
1569 return 1;
1570 return 0;
1571 }
1572
1573 static int
rt_set_direction_forwards(unsigned char *regs)1574 rt_set_direction_forwards (unsigned char *regs)
1575 {
1576 regs[0xc6] |= 0x08;
1577 return 0;
1578 }
1579
1580 static int
rt_set_direction_rewind(unsigned char *regs)1581 rt_set_direction_rewind (unsigned char *regs)
1582 {
1583 regs[0xc6] &= 0xf7;
1584 return 0;
1585 }
1586
1587 static int
rt_set_stop_when_rewound(unsigned char *regs, int stop)1588 rt_set_stop_when_rewound (unsigned char *regs, int stop)
1589 {
1590 if (stop)
1591 regs[0xb2] |= 0x10;
1592 else
1593 regs[0xb2] &= 0xef;
1594 return 0;
1595 }
1596
1597 static int
rt_start_moving(void)1598 rt_start_moving (void)
1599 {
1600 if (rt_set_one_register (REG_MOVE_CONTROL_TEST, 2) < 0 ||
1601 rt_set_one_register (REG_MOVE_CONTROL_TEST, 2) < 0 ||
1602 rt_set_one_register (REG_MOVE_CONTROL_TEST, 0) < 0 ||
1603 rt_set_one_register (REG_MOVE_CONTROL_TEST, 0) < 0 ||
1604 rt_set_one_register (REG_MOVE_CONTROL_TEST, 8) < 0 ||
1605 rt_set_one_register (REG_MOVE_CONTROL_TEST, 8) < 0)
1606 return -1;
1607 return 0;
1608 }
1609
1610 static int
rt_stop_moving(void)1611 rt_stop_moving (void)
1612 {
1613 if (rt_set_one_register (REG_MOVE_CONTROL_TEST, 2) < 0 ||
1614 rt_set_one_register (REG_MOVE_CONTROL_TEST, 2) < 0 ||
1615 rt_set_one_register (REG_MOVE_CONTROL_TEST, 0) < 0 ||
1616 rt_set_one_register (REG_MOVE_CONTROL_TEST, 0) < 0)
1617 return -1;
1618 return 0;
1619 }
1620
1621 static int
rt_set_powersave_mode(int enable)1622 rt_set_powersave_mode (int enable)
1623 {
1624 unsigned char r;
1625
1626 if (rt_read_register_immediate (REG_MOVE_CONTROL_TEST, 1, &r) < 0)
1627 return -1;
1628 if (r & 0x04)
1629 {
1630 if (enable == 1)
1631 return 0;
1632 r &= ~0x04;
1633 }
1634 else
1635 {
1636 if (enable == 0)
1637 return 0;
1638 r |= 0x04;
1639 }
1640 if (rt_set_one_register (REG_MOVE_CONTROL_TEST, r) < 0 ||
1641 rt_set_one_register (REG_MOVE_CONTROL_TEST, r) < 0)
1642 return -1;
1643 return 0;
1644 }
1645
1646 static int
rt_turn_off_lamp(void)1647 rt_turn_off_lamp (void)
1648 {
1649 return rt_set_one_register (0x3a, 0);
1650 }
1651
1652 static int
rt_turn_on_lamp(void)1653 rt_turn_on_lamp (void)
1654 {
1655 char r3ab[2];
1656 char r10;
1657 char r58;
1658
1659 if (rt_read_register_immediate (0x3a, 1, r3ab) < 0 ||
1660 rt_read_register_immediate (0x10, 1, &r10) < 0 ||
1661 rt_read_register_immediate (0x58, 1, &r58) < 0)
1662 return -1;
1663 r3ab[0] |= 0x80;
1664 r3ab[1] = 0x40;
1665 r10 |= 0x01;
1666 r58 &= 0x0f;
1667 if (rt_set_register_immediate (0x3a, 2, r3ab) < 0 ||
1668 rt_set_one_register (0x10, r10) < 0 ||
1669 rt_set_one_register (0x58, r58) < 0)
1670 return -1;
1671 return 0;
1672 }
1673
1674 static int
rt_set_value_lsbfirst(unsigned char *regs, int firstreg, int totalregs, unsigned value)1675 rt_set_value_lsbfirst (unsigned char *regs,
1676 int firstreg, int totalregs, unsigned value)
1677 {
1678 while (totalregs--)
1679 {
1680 regs[firstreg++] = value & 0xff;
1681 value >>= 8;
1682 }
1683 return 0;
1684 }
1685
1686 #if 0
1687 static int
1688 rt_set_value_msbfirst (unsigned char *regs,
1689 int firstreg, int totalregs, unsigned value)
1690 {
1691 while (totalregs--)
1692 {
1693 regs[firstreg + totalregs] = value & 0xff;
1694 value >>= 8;
1695 }
1696 return 0;
1697 }
1698 #endif
1699
1700 static int
rt_set_ccd_shift_clock_multiplier(unsigned char *regs, unsigned value)1701 rt_set_ccd_shift_clock_multiplier (unsigned char *regs, unsigned value)
1702 {
1703 return rt_set_value_lsbfirst (regs, 0xf0, 3, value);
1704 }
1705
1706 static int
rt_set_ccd_clock_reset_interval(unsigned char *regs, unsigned value)1707 rt_set_ccd_clock_reset_interval (unsigned char *regs, unsigned value)
1708 {
1709 return rt_set_value_lsbfirst (regs, 0xf9, 3, value);
1710 }
1711
1712 static int
rt_set_ccd_clamp_clock_multiplier(unsigned char *regs, unsigned value)1713 rt_set_ccd_clamp_clock_multiplier (unsigned char *regs, unsigned value)
1714 {
1715 return rt_set_value_lsbfirst (regs, 0xfc, 3, value);
1716 }
1717
1718 static int
rt_set_movement_pattern(unsigned char *regs, unsigned value)1719 rt_set_movement_pattern (unsigned char *regs, unsigned value)
1720 {
1721 return rt_set_value_lsbfirst (regs, 0xc0, 3, value);
1722 }
1723
1724 static int
rt_set_motor_movement_clock_multiplier(unsigned char *regs, unsigned value)1725 rt_set_motor_movement_clock_multiplier (unsigned char *regs, unsigned value)
1726 {
1727 regs[0x40] = (regs[0x40] & ~0xc0) | (value << 6);
1728 return 0;
1729 }
1730
1731 static int
rt_set_motor_type(unsigned char *regs, unsigned value)1732 rt_set_motor_type (unsigned char *regs, unsigned value)
1733 {
1734 regs[0xc9] = (regs[0xc9] & 0xf8) | (value & 0x7);
1735 return 0;
1736 }
1737
1738 static int
rt_set_noscan_distance(unsigned char *regs, unsigned value)1739 rt_set_noscan_distance (unsigned char *regs, unsigned value)
1740 {
1741 DBG (10, "Setting distance without scanning to %d\n", value);
1742 return rt_set_value_lsbfirst (regs, 0x60, 2, value);
1743 }
1744
1745 static int
rt_set_total_distance(unsigned char *regs, unsigned value)1746 rt_set_total_distance (unsigned char *regs, unsigned value)
1747 {
1748 DBG (10, "Setting total distance to %d\n", value);
1749 return rt_set_value_lsbfirst (regs, 0x62, 2, value);
1750 }
1751
1752 static int
rt_set_scanline_start(unsigned char *regs, unsigned value)1753 rt_set_scanline_start (unsigned char *regs, unsigned value)
1754 {
1755 return rt_set_value_lsbfirst (regs, 0x66, 2, value);
1756 }
1757
1758 static int
rt_set_scanline_end(unsigned char *regs, unsigned value)1759 rt_set_scanline_end (unsigned char *regs, unsigned value)
1760 {
1761 return rt_set_value_lsbfirst (regs, 0x6c, 2, value);
1762 }
1763
1764 static int
rt_set_basic_calibration(unsigned char *regs, int redoffset1, int redoffset2, int redgain, int greenoffset1, int greenoffset2, int greengain, int blueoffset1, int blueoffset2, int bluegain)1765 rt_set_basic_calibration (unsigned char *regs,
1766 int redoffset1,
1767 int redoffset2,
1768 int redgain,
1769 int greenoffset1,
1770 int greenoffset2,
1771 int greengain,
1772 int blueoffset1, int blueoffset2, int bluegain)
1773 {
1774 regs[0x02] = redoffset1;
1775 regs[0x05] = redoffset2;
1776 regs[0x08] = redgain;
1777 regs[0x03] = greenoffset1;
1778 regs[0x06] = greenoffset2;
1779 regs[0x09] = greengain;
1780 regs[0x04] = blueoffset1;
1781 regs[0x07] = blueoffset2;
1782 regs[0x0a] = bluegain;
1783 return 0;
1784 }
1785
1786 static int
rt_set_calibration_addresses(unsigned char *regs, unsigned redaddr, unsigned greenaddr, unsigned blueaddr, unsigned endaddr, unsigned width)1787 rt_set_calibration_addresses (unsigned char *regs,
1788 unsigned redaddr,
1789 unsigned greenaddr,
1790 unsigned blueaddr,
1791 unsigned endaddr,
1792 unsigned width)
1793 {
1794 unsigned endpage = (endaddr + 31) / 32;
1795 unsigned scanline_pages = ((width + 1) * 3 + 31) / 32;
1796
1797 /* Red, green and blue detailed calibration addresses */
1798
1799 regs[0x84] = redaddr;
1800 regs[0x8e] = (regs[0x8e] & 0x0f) | ((redaddr >> 4) & 0xf0);
1801 rt_set_value_lsbfirst (regs, 0x85, 2, greenaddr);
1802 rt_set_value_lsbfirst (regs, 0x87, 2, blueaddr);
1803
1804 /* I don't know what the next three are used for, but each buffer commencing
1805 * at 0x80 and 0x82 needs to hold a full scan line.
1806 */
1807
1808 rt_set_value_lsbfirst (regs, 0x80, 2, endpage);
1809 rt_set_value_lsbfirst (regs, 0x82, 2, endpage + scanline_pages);
1810 rt_set_value_lsbfirst (regs, 0x89, 2, endpage + scanline_pages * 2);
1811
1812 /* I don't know what this is, but it seems to be a number of pages that can hold
1813 * 16 complete scan lines, but not calculated as an offset from any other page
1814 */
1815
1816 rt_set_value_lsbfirst (regs, 0x51, 2, (48 * (width + 1) + 31) / 32);
1817
1818 /* I don't know what this is either, but this is what the Windows driver does */
1819 rt_set_value_lsbfirst (regs, 0x8f, 2, 0x1c00);
1820 return 0;
1821 }
1822
1823 static int
rt_set_lamp_duty_cycle(unsigned char *regs, int enable, int frequency, int offduty)1824 rt_set_lamp_duty_cycle (unsigned char *regs,
1825 int enable, int frequency, int offduty)
1826 {
1827 if (enable)
1828 regs[0x3b] |= 0x80;
1829 else
1830 regs[0x3b] &= 0x7f;
1831
1832 regs[0x3b] =
1833 (regs[0x3b] & 0x80) | ((frequency & 0x7) << 4) | (offduty & 0x0f);
1834 regs[0x3d] = (regs[0x3d] & 0x7f) | ((frequency & 0x8) << 4);
1835 return 0;
1836 }
1837
1838 static int
rt_set_data_feed_on(unsigned char *regs)1839 rt_set_data_feed_on (unsigned char *regs)
1840 {
1841 regs[0xb2] &= ~0x04;
1842 return 0;
1843 }
1844
1845 static int
rt_set_data_feed_off(unsigned char *regs)1846 rt_set_data_feed_off (unsigned char *regs)
1847 {
1848 regs[0xb2] |= 0x04;
1849 return 0;
1850 }
1851
1852 static int
rt_enable_ccd(unsigned char *regs, int enable)1853 rt_enable_ccd (unsigned char *regs, int enable)
1854 {
1855 if (enable)
1856 regs[0x00] &= ~0x10;
1857 else
1858 regs[0x00] |= 0x10;
1859 return 0;
1860 }
1861
1862 static int
rt_set_cdss(unsigned char *regs, int val1, int val2)1863 rt_set_cdss (unsigned char *regs, int val1, int val2)
1864 {
1865 regs[0x28] = (regs[0x28] & 0xe0) | (val1 & 0x1f);
1866 regs[0x2a] = (regs[0x2a] & 0xe0) | (val2 & 0x1f);
1867 return 0;
1868 }
1869
1870 static int
rt_set_cdsc(unsigned char *regs, int val1, int val2)1871 rt_set_cdsc (unsigned char *regs, int val1, int val2)
1872 {
1873 regs[0x29] = (regs[0x29] & 0xe0) | (val1 & 0x1f);
1874 regs[0x2b] = (regs[0x2b] & 0xe0) | (val2 & 0x1f);
1875 return 0;
1876 }
1877
1878 static int
rt_update_after_setting_cdss2(unsigned char *regs)1879 rt_update_after_setting_cdss2 (unsigned char *regs)
1880 {
1881 int fullcolour = (!(regs[0x2f] & 0xc0) && (regs[0x2f] & 0x04));
1882 int value = regs[0x2a] & 0x1f;
1883
1884 regs[0x2a] = (regs[0x2a] & 0xe0) | (value & 0x1f);
1885
1886 if (fullcolour)
1887 value *= 3;
1888 if ((regs[0x40] & 0xc0) == 0x40)
1889 value += 17;
1890 else
1891 value += 16;
1892
1893 regs[0x2c] = (regs[0x2c] & 0xe0) | (value % 24);
1894 regs[0x2d] = (regs[0x2d] & 0xe0) | ((value + 2) % 24);
1895 return 0;
1896 }
1897
1898 static int
rt_set_cph0s(unsigned char *regs, int on)1899 rt_set_cph0s (unsigned char *regs, int on)
1900 {
1901 if (on)
1902 regs[0x2d] |= 0x20; /* 1200dpi horizontal coordinate space */
1903 else
1904 regs[0x2d] &= ~0x20; /* 600dpi horizontal coordinate space */
1905 return 0;
1906 }
1907
1908 static int
rt_set_cvtr_lm(unsigned char *regs, int val1, int val2, int val3)1909 rt_set_cvtr_lm (unsigned char *regs, int val1, int val2, int val3)
1910 {
1911 regs[0x28] = (regs[0x28] & ~0xe0) | (val1 << 5);
1912 regs[0x29] = (regs[0x29] & ~0xe0) | (val2 << 5);
1913 regs[0x2a] = (regs[0x2a] & ~0xe0) | (val3 << 5);
1914 return 0;
1915 }
1916
1917 static int
rt_set_cvtr_mpt(unsigned char *regs, int val1, int val2, int val3)1918 rt_set_cvtr_mpt (unsigned char *regs, int val1, int val2, int val3)
1919 {
1920 regs[0x3c] = (val1 & 0x0f) | (val2 << 4);
1921 regs[0x3d] = (regs[0x3d] & 0xf0) | (val3 & 0x0f);
1922 return 0;
1923 }
1924
1925 static int
rt_set_cvtr_wparams(unsigned char *regs, unsigned fpw, unsigned bpw, unsigned w)1926 rt_set_cvtr_wparams (unsigned char *regs,
1927 unsigned fpw, unsigned bpw, unsigned w)
1928 {
1929 regs[0x31] = (w & 0x0f) | ((bpw << 4) & 0x30) | (fpw << 6);
1930 return 0;
1931 }
1932
1933 static int
rt_enable_movement(unsigned char *regs, int enable)1934 rt_enable_movement (unsigned char *regs, int enable)
1935 {
1936 if (enable)
1937 regs[0xc3] |= 0x80;
1938 else
1939 regs[0xc3] &= ~0x80;
1940 return 0;
1941 }
1942
1943 static int
rt_set_scan_frequency(unsigned char *regs, int frequency)1944 rt_set_scan_frequency (unsigned char *regs, int frequency)
1945 {
1946 regs[0x64] = (regs[0x64] & 0xf0) | (frequency & 0x0f);
1947 return 0;
1948 }
1949
1950 static int
rt_set_merge_channels(unsigned char *regs, int on)1951 rt_set_merge_channels (unsigned char *regs, int on)
1952 {
1953 /* RGBRGB instead of RRRRR...GGGGG...BBBB */
1954 regs[0x2f] &= ~0x14;
1955 regs[0x2f] |= on ? 0x04 : 0x10;
1956 return 0;
1957 }
1958
1959 static int
rt_set_channel(unsigned char *regs, int channel)1960 rt_set_channel (unsigned char *regs, int channel)
1961 {
1962 regs[0x2f] = (regs[0x2f] & ~0xc0) | (channel << 6);
1963 return 0;
1964 }
1965
1966 static int
rt_set_single_channel_scanning(unsigned char *regs, int on)1967 rt_set_single_channel_scanning (unsigned char *regs, int on)
1968 {
1969 if (on)
1970 regs[0x2f] |= 0x20;
1971 else
1972 regs[0x2f] &= ~0x20;
1973 return 0;
1974 }
1975
1976 static int
rt_set_colour_mode(unsigned char *regs, int on)1977 rt_set_colour_mode (unsigned char *regs, int on)
1978 {
1979 if (on)
1980 regs[0x2f] |= 0x02;
1981 else
1982 regs[0x2f] &= ~0x02;
1983 return 0;
1984 }
1985
1986 static int
rt_set_horizontal_resolution(unsigned char *regs, int resolution)1987 rt_set_horizontal_resolution (unsigned char *regs, int resolution)
1988 {
1989 int base_resolution = 300;
1990
1991 if (regs[0x2d] & 0x20)
1992 base_resolution *= 2;
1993 if (regs[0xd3] & 0x08)
1994 base_resolution *= 2;
1995 regs[0x7a] = base_resolution / resolution;
1996 return 0;
1997 }
1998
1999 static int
rt_set_last_sram_page(unsigned char *regs, int pagenum)2000 rt_set_last_sram_page (unsigned char *regs, int pagenum)
2001 {
2002 rt_set_value_lsbfirst (regs, 0x8b, 2, pagenum);
2003 return 0;
2004 }
2005
2006 static int
rt_set_step_size(unsigned char *regs, int stepsize)2007 rt_set_step_size (unsigned char *regs, int stepsize)
2008 {
2009 rt_set_value_lsbfirst (regs, 0xe2, 2, stepsize);
2010 rt_set_value_lsbfirst (regs, 0xe0, 2, 0);
2011 return 0;
2012 }
2013
2014 static int
rt_set_all_registers(void const *regs_)2015 rt_set_all_registers (void const *regs_)
2016 {
2017 char regs[255];
2018
2019 memcpy (regs, regs_, 255);
2020 regs[0x32] &= ~0x40;
2021
2022 if (rt_set_one_register (0x32, regs[0x32]) < 0 ||
2023 rt_set_register_immediate (0, 255, regs) < 0 ||
2024 rt_set_one_register (0x32, regs[0x32] | 0x40) < 0)
2025 return -1;
2026 return 0;
2027 }
2028
2029 static int
rt_adjust_misc_registers(unsigned char *regs)2030 rt_adjust_misc_registers (unsigned char *regs)
2031 {
2032 /* Mostly unknown purposes - probably no need to adjust */
2033 regs[0xc6] = (regs[0xc6] & 0x0f) | 0x20; /* Purpose unknown - appears to do nothing */
2034 regs[0x2e] = 0x86; /* ???? - Always has this value */
2035 regs[0x30] = 2; /* CCPL = 1 */
2036 regs[0xc9] |= 0x38; /* Doesn't have any obvious effect, but the Windows driver does this */
2037 return 0;
2038 }
2039
2040
2041 #define NVR_MAX_ADDRESS_SIZE 11
2042 #define NVR_MAX_OPCODE_SIZE 3
2043 #define NVR_DATA_SIZE 8
2044 #define NVR_MAX_COMMAND_SIZE ((NVR_MAX_ADDRESS_SIZE + \
2045 NVR_MAX_OPCODE_SIZE + \
2046 NVR_DATA_SIZE) * 2 + 1)
2047
2048 static int
rt_nvram_enable_controller(int enable)2049 rt_nvram_enable_controller (int enable)
2050 {
2051 unsigned char r;
2052
2053 if (rt_read_register_immediate (0x1d, 1, &r) < 0)
2054 return -1;
2055 if (enable)
2056 r |= 1;
2057 else
2058 r &= ~1;
2059 return rt_set_one_register (0x1d, r);
2060
2061 }
2062
2063 static int
rt_nvram_init_command(void)2064 rt_nvram_init_command (void)
2065 {
2066 unsigned char regs[13];
2067
2068 if (rt_read_register_immediate (0x10, 13, regs) < 0)
2069 return -1;
2070 regs[2] |= 0xf0;
2071 regs[4] = (regs[4] & 0x1f) | 0x60;
2072 return rt_set_register_immediate (0x10, 13, regs);
2073 }
2074
2075 static int
rt_nvram_init_stdvars(int block, int *addrbits, unsigned char *basereg)2076 rt_nvram_init_stdvars (int block, int *addrbits, unsigned char *basereg)
2077 {
2078 int bitsneeded;
2079 int capacity;
2080
2081 switch (block)
2082 {
2083 case 0:
2084 bitsneeded = 7;
2085 break;
2086
2087 case 1:
2088 bitsneeded = 9;
2089 break;
2090
2091 case 2:
2092 bitsneeded = 11;
2093 break;
2094
2095 default:
2096 bitsneeded = 0;
2097 capacity = 1;
2098 while (capacity < block)
2099 capacity <<= 1, ++bitsneeded;
2100 break;
2101 }
2102
2103 *addrbits = bitsneeded;
2104
2105 if (rt_read_register_immediate (0x10, 1, basereg) < 0)
2106 return -1;
2107
2108 *basereg &= ~0x60;
2109 return 0;
2110 }
2111
2112 static void
rt_nvram_set_half_bit(unsigned char *buffer, int value, unsigned char stdbits, int whichhalf)2113 rt_nvram_set_half_bit (unsigned char *buffer,
2114 int value, unsigned char stdbits, int whichhalf)
2115 {
2116 *buffer = stdbits | (value ? 0x40 : 0) | (whichhalf ? 0x20 : 0);
2117 }
2118
2119 static void
rt_nvram_set_command_bit(unsigned char *buffer, int value, unsigned char stdbits)2120 rt_nvram_set_command_bit (unsigned char *buffer,
2121 int value, unsigned char stdbits)
2122 {
2123 rt_nvram_set_half_bit (buffer, value, stdbits, 0);
2124 rt_nvram_set_half_bit (buffer + 1, value, stdbits, 1);
2125 }
2126
2127 static void
rt_nvram_set_addressing_bits(unsigned char *buffer, int location, int addressingbits, unsigned char stdbits)2128 rt_nvram_set_addressing_bits (unsigned char *buffer,
2129 int location,
2130 int addressingbits, unsigned char stdbits)
2131 {
2132 int currentbit = 1 << (addressingbits - 1);
2133
2134 while (addressingbits--)
2135 {
2136 rt_nvram_set_command_bit (buffer,
2137 (location & currentbit) ? 1 : 0, stdbits);
2138 buffer += 2;
2139 currentbit >>= 1;
2140 }
2141 }
2142
2143 #if 0
2144 static int
2145 rt_nvram_enable_write (int addressingbits, int enable, unsigned char stdbits)
2146 {
2147 unsigned char cmdbuffer[NVR_MAX_COMMAND_SIZE];
2148 int cmdsize = 6 + addressingbits * 2;
2149
2150 rt_nvram_set_command_bit (cmdbuffer, 1, stdbits);
2151 rt_nvram_set_command_bit (cmdbuffer + 2, 0, stdbits);
2152 rt_nvram_set_command_bit (cmdbuffer + 4, 0, stdbits);
2153 rt_nvram_set_command_bit (cmdbuffer + 6, enable, stdbits);
2154 if (addressingbits > 1)
2155 rt_nvram_set_addressing_bits (cmdbuffer + 8, 0, addressingbits - 1,
2156 stdbits);
2157
2158 if (rt_nvram_enable_controller (1) < 0 ||
2159 rt_send_command_immediate (RTCMD_NVRAMCONTROL, 0, cmdsize, cmdsize,
2160 cmdbuffer, 0, 0) < 0
2161 || rt_nvram_enable_controller (0) < 0)
2162 {
2163 return -1;
2164 }
2165 return 0;
2166 }
2167
2168 static int
2169 rt_nvram_write (int block, int location, char const *data, int bytes)
2170 {
2171 int addressingbits;
2172 unsigned char stdbits;
2173 unsigned char cmdbuffer[NVR_MAX_COMMAND_SIZE];
2174 unsigned char *address_bits;
2175 unsigned char *data_bits;
2176 int cmdsize;
2177
2178 /* This routine doesn't appear to work, but I can't see anything wrong with it */
2179 if (rt_nvram_init_stdvars (block, &addressingbits, &stdbits) < 0)
2180 return -1;
2181
2182 cmdsize = (addressingbits + 8) * 2 + 6;
2183 address_bits = cmdbuffer + 6;
2184 data_bits = address_bits + (addressingbits * 2);
2185
2186 rt_nvram_set_command_bit (cmdbuffer, 1, stdbits);
2187 rt_nvram_set_command_bit (cmdbuffer + 2, 0, stdbits);
2188 rt_nvram_set_command_bit (cmdbuffer + 4, 1, stdbits);
2189
2190 if (rt_nvram_init_command () < 0 ||
2191 rt_nvram_enable_write (addressingbits, 1, stdbits) < 0)
2192 return -1;
2193
2194 while (bytes--)
2195 {
2196 int i;
2197
2198 rt_nvram_set_addressing_bits (address_bits, location, addressingbits,
2199 stdbits);
2200 rt_nvram_set_addressing_bits (data_bits, *data++, 8, stdbits);
2201
2202 if (rt_nvram_enable_controller (1) < 0 ||
2203 rt_send_command_immediate (RTCMD_NVRAMCONTROL, 0, cmdsize, cmdsize,
2204 cmdbuffer, 0, 0) < 0
2205 || rt_nvram_enable_controller (0) < 0)
2206 return -1;
2207
2208 if (rt_nvram_enable_controller (1) < 0)
2209 return -1;
2210 for (i = 0; i < cmdsize; ++i)
2211 {
2212 unsigned char r;
2213 unsigned char cmd;
2214
2215 rt_nvram_set_half_bit (&cmd, 0, stdbits, i & 1);
2216 if (rt_send_command_immediate
2217 (RTCMD_NVRAMCONTROL, 0, 1, 1, &cmd, 0, 0) < 0
2218 || rt_read_register_immediate (0x10, 1, &r) < 0)
2219 {
2220 return -1;
2221 }
2222 else if (r & 0x80)
2223 {
2224 break;
2225 }
2226 }
2227 if (rt_nvram_enable_controller (0) < 0)
2228 return -1;
2229
2230 ++location;
2231 }
2232
2233 if (rt_nvram_enable_write (addressingbits, 0, stdbits) < 0)
2234 return -1;
2235 return 0;
2236 }
2237 #endif
2238
2239 static int
rt_nvram_read(int block, int location, unsigned char *data, int bytes)2240 rt_nvram_read (int block, int location, unsigned char *data, int bytes)
2241 {
2242 int addressingbits;
2243 unsigned char stdbits;
2244 unsigned char cmdbuffer[NVR_MAX_COMMAND_SIZE];
2245 unsigned char *address_bits;
2246 unsigned char readbit_command[2];
2247 int cmdsize;
2248
2249 if (rt_nvram_init_stdvars (block, &addressingbits, &stdbits) < 0)
2250 return -1;
2251
2252 cmdsize = addressingbits * 2 + 7;
2253 address_bits = cmdbuffer + 6;
2254
2255 rt_nvram_set_command_bit (cmdbuffer, 1, stdbits);
2256 rt_nvram_set_command_bit (cmdbuffer + 2, 1, stdbits);
2257 rt_nvram_set_command_bit (cmdbuffer + 4, 0, stdbits);
2258 rt_nvram_set_half_bit (cmdbuffer + cmdsize - 1, 0, stdbits, 0);
2259
2260 rt_nvram_set_half_bit (readbit_command, 0, stdbits, 1);
2261 rt_nvram_set_half_bit (readbit_command + 1, 0, stdbits, 0);
2262
2263 if (rt_nvram_init_command () < 0)
2264 return -1;
2265
2266 while (bytes--)
2267 {
2268 char c = 0;
2269 unsigned char r;
2270 int i;
2271
2272 rt_nvram_set_addressing_bits (address_bits, location, addressingbits,
2273 stdbits);
2274
2275 if (rt_nvram_enable_controller (1) < 0 ||
2276 rt_send_command_immediate (RTCMD_NVRAMCONTROL, 0x1d, cmdsize,
2277 cmdsize, cmdbuffer, 0, 0) < 0)
2278 return -1;
2279
2280 for (i = 0; i < 8; ++i)
2281 {
2282 c <<= 1;
2283
2284 if (rt_send_command_immediate
2285 (RTCMD_NVRAMCONTROL, 0x1d, 2, 2, readbit_command, 0, 0) < 0
2286 || rt_read_register_immediate (0x10, 1, &r) < 0)
2287 return -1;
2288 if (r & 0x80)
2289 c |= 1;
2290 }
2291 if (rt_nvram_enable_controller (0) < 0)
2292 return -1;
2293
2294 *data++ = c;
2295 ++location;
2296 }
2297 return 0;
2298 }
2299
2300 /* This is what we want as the initial registers, not what they
2301 * are at power on time. In particular 13 bytes at 0x10 are
2302 * different, and the byte at 0x94 is different.
2303 */
2304 static unsigned char initial_regs[] = {
2305 /* 0x00 */ 0xf5, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2306 /* 0x08 */ 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00,
2307 /* 0x10 */ 0x81, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
2308 /* 0x18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
2309 /* 0x20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2310 /* 0x28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x19,
2311 /* 0x30 */ 0xd0, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2312 /* 0x38 */ 0x00, 0x00, 0xa0, 0x37, 0xff, 0x0f, 0x00, 0x00,
2313 /* 0x40 */ 0x80, 0x00, 0x00, 0x00, 0x8c, 0x76, 0x00, 0x00,
2314 /* 0x48 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2315 /* 0x50 */ 0x20, 0xbc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
2316 /* 0x58 */ 0x1d, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00,
2317 /* 0x60 */ 0x5e, 0xea, 0x5f, 0xea, 0x00, 0x80, 0x64, 0x00,
2318 /* 0x68 */ 0x00, 0x00, 0x00, 0x00, 0x84, 0x04, 0x00, 0x00,
2319 /* 0x70 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2320 /* 0x78 */ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2321 /* 0x80 */ 0x0f, 0x02, 0x4b, 0x02, 0x00, 0xec, 0x19, 0xd8,
2322 /* 0x88 */ 0x2d, 0x87, 0x02, 0xff, 0x3f, 0x78, 0x60, 0x00,
2323 /* 0x90 */ 0x1c, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
2324 /* 0x98 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2325 /* 0xa0 */ 0x00, 0x00, 0x00, 0x0c, 0x27, 0x64, 0x00, 0x00,
2326 /* 0xa8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2327 /* 0xb0 */ 0x12, 0x08, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00,
2328 /* 0xb8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2329 /* 0xc0 */ 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00,
2330 /* 0xc8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2331 /* 0xd0 */ 0xff, 0xbf, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
2332 /* 0xd8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2333 /* 0xe0 */ 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
2334 /* 0xe8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2335 /* 0xf0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2336 /* 0xf8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2337 };
2338
2339 #define RT_NORMAL_TG 0
2340 #define RT_DOUBLE_TG 1
2341 #define RT_TRIPLE_TG 2
2342 #define RT_DDOUBLE_TG 3
2343 #define RT_300_TG 4
2344 #define RT_150_TG 5
2345 #define RT_TEST_TG 6
2346 static struct tg_info__
2347 {
2348 int tg_cph0p;
2349 int tg_crsp;
2350 int tg_cclpp;
2351 int tg_cph0s;
2352 int tg_cdss1;
2353 int tg_cdsc1;
2354 int tg_cdss2;
2355 int tg_cdsc2;
2356 } tg_info[] =
2357 {
2358 /* CPH CCD Shifting Clock
2359 * 0P ??? Perhaps CCD rising edge position
2360 * 0S ???
2361 * CRS Reset CCD Clock
2362 * P ??? Perhaps CCD falling edge position
2363 * CCLP CCD Clamp Clock
2364 * P ???
2365 * CDS ???
2366 * S1 ???
2367 * S2 ???
2368 * C1 ???
2369 * C2 ???
2370 */
2371 /*CPH0P CRSP CCLPP CPH0S CDSS1 CDSC1 CDSS2 CDSC2 */
2372 {
2373 0x01FFE0, 0x3c0000, 0x003000, 1, 0xb, 0xd, 0x00, 0x01}, /* NORMAL */
2374 {
2375 0x7ff800, 0xf00000, 0x01c000, 0, 0xb, 0xc, 0x14, 0x15}, /* DOUBLE */
2376 {
2377 0x033fcc, 0x300000, 0x060000, 1, 0x8, 0xa, 0x00, 0x01}, /* TRIPLE */
2378 {
2379 0x028028, 0x300000, 0x060000, 1, 0x8, 0xa, 0x00, 0x01}, /* DDOUBLE */
2380 {
2381 0x7ff800, 0x030000, 0x060000, 0, 0xa, 0xc, 0x17, 0x01}, /* 300 */
2382 {
2383 0x7fc700, 0x030000, 0x060000, 0, 0x7, 0x9, 0x17, 0x01}, /* 150 */
2384 {
2385 0x7ff800, 0x300000, 0x060000, 0, 0xa, 0xc, 0x17, 0x01}, /* TEST */
2386 };
2387
2388 struct resolution_parameters
2389 {
2390 unsigned resolution;
2391 int reg_39_value;
2392 int reg_c3_value;
2393 int reg_c6_value;
2394 int scan_frequency;
2395 int cph0s;
2396 int red_green_offset;
2397 int green_blue_offset;
2398 int intra_channel_offset;
2399 int motor_movement_clock_multiplier;
2400 int d3_bit_3_value;
2401 int tg;
2402 int step_size;
2403 };
2404
2405 /* The TG value sets seem to affect the exposure time:
2406 * At 200dpi:
2407 * NORMAL gets higher values than DOUBLE
2408 * DDOUBLE gives a crazy spike in the data
2409 * TRIPLE gives a black result
2410 * TEST gives a black result
2411 * 300 gives a black result
2412 * 150 gives a black result
2413 */
2414
2415 static struct resolution_parameters resparms[] = {
2416 /* Acceptable values for stepsz are:
2417 * 0x157b 0xabd, 0x55e, 0x2af, 0x157, 0xab, 0x55
2418 */
2419 /* My values - all work */
2420 /*res r39 rC3 rC6 freq cph0s rgo gbo intra mmcm d3 tg stepsz */
2421 {1200, 3, 6, 4, 2, 1, 22, 22, 4, 2, 1, RT_NORMAL_TG, 0x157b},
2422 {600, 15, 6, 4, 1, 1, 9, 10, 0, 2, 1, RT_NORMAL_TG, 0x055e},
2423 {400, 3, 1, 4, 1, 1, 6, 6, 1, 2, 1, RT_NORMAL_TG, 0x157b},
2424 {300, 15, 3, 4, 1, 1, 5, 4, 0, 2, 1, RT_NORMAL_TG, 0x02af},
2425 {200, 7, 1, 4, 1, 1, 3, 3, 0, 2, 1, RT_NORMAL_TG, 0x055e},
2426 {150, 15, 3, 1, 1, 1, 2, 2, 0, 2, 1, RT_NORMAL_TG, 0x02af},
2427 {100, 3, 1, 3, 1, 1, 1, 1, 0, 2, 1, RT_NORMAL_TG, 0x0abd},
2428 {75, 15, 3, 3, 1, 1, 1, 1, 0, 2, 1, RT_NORMAL_TG, 0x02af},
2429 {50, 15, 1, 1, 1, 1, 0, 0, 0, 2, 1, RT_NORMAL_TG, 0x055e},
2430 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
2431 };
2432
2433 struct dcalibdata
2434 {
2435 unsigned char *buffers[3];
2436 int pixelsperrow;
2437 int pixelnow;
2438 int channelnow;
2439 int firstrowdone;
2440 };
2441
2442 static void dump_registers (unsigned char const *);
2443 static int
rts8801_rewind(void)2444 rts8801_rewind (void)
2445 {
2446 unsigned char regs[255];
2447 int n;
2448 int tg_setting = RT_DOUBLE_TG;
2449
2450 rt_read_register_immediate (0, 255, regs);
2451
2452 rt_set_noscan_distance (regs, 59998);
2453 rt_set_total_distance (regs, 59999);
2454
2455 rt_set_stop_when_rewound (regs, 0);
2456
2457 rt_set_one_register (0xc6, 0);
2458 rt_set_one_register (0xc6, 0);
2459
2460
2461 rt_set_direction_rewind (regs);
2462
2463 rt_set_step_size (regs, 0x55);
2464 regs[0x39] = 3;
2465 regs[0xc3] = (regs[0xc3] & 0xf8) | 0x86;
2466 regs[0xc6] = (regs[0xc6] & 0xf8) | 4;
2467
2468 rt_set_horizontal_resolution (regs, 25);
2469 rt_set_ccd_shift_clock_multiplier (regs, tg_info[tg_setting].tg_cph0p);
2470 rt_set_ccd_clock_reset_interval (regs, tg_info[tg_setting].tg_crsp);
2471 rt_set_ccd_clamp_clock_multiplier (regs, tg_info[tg_setting].tg_cclpp);
2472 rt_set_cdss (regs, tg_info[tg_setting].tg_cdss1,
2473 tg_info[tg_setting].tg_cdss2);
2474 rt_set_cdsc (regs, tg_info[tg_setting].tg_cdsc1,
2475 tg_info[tg_setting].tg_cdsc2);
2476 rt_update_after_setting_cdss2 (regs);
2477 rt_set_cvtr_wparams (regs, 3, 0, 6);
2478 rt_set_cvtr_mpt (regs, 15, 15, 15);
2479 rt_set_cvtr_lm (regs, 7, 7, 7);
2480 rt_set_motor_type (regs, 2);
2481
2482 if (DBG_LEVEL >= 5)
2483 dump_registers (regs);
2484
2485 rt_set_all_registers (regs);
2486 rt_set_one_register (0x2c, regs[0x2c]);
2487
2488 rt_start_moving ();
2489
2490 while (!rt_is_rewound () &&
2491 ((n = rt_get_available_bytes ()) > 0 || rt_is_moving () > 0))
2492 {
2493 if (n)
2494 {
2495 char buffer[0xffc0];
2496
2497 if (n > (int) sizeof (buffer))
2498 n = sizeof (buffer);
2499 rt_get_data (n, buffer);
2500 }
2501 else
2502 {
2503 usleep (10000);
2504 }
2505 }
2506
2507 rt_stop_moving ();
2508 return 0;
2509 }
2510
2511 static int cancelled_scan = 0;
2512
2513 static unsigned
get_lsbfirst_int(unsigned char const *p, int n)2514 get_lsbfirst_int (unsigned char const *p, int n)
2515 {
2516 unsigned value = *p++;
2517 int shift = 8;
2518
2519 while (--n)
2520 {
2521 unsigned now = *p++;
2522 value |= now << shift;
2523 shift += 8;
2524 }
2525 return value;
2526 }
2527
2528 static int
convert_c6(int i)2529 convert_c6 (int i)
2530 {
2531 switch (i)
2532 {
2533 case 3:
2534 return 1;
2535
2536 case 1:
2537 return 2;
2538
2539 case 4:
2540 return 4;
2541 }
2542 return -1;
2543 }
2544
2545 static void
dump_registers(unsigned char const *regs)2546 dump_registers (unsigned char const *regs)
2547 {
2548 int i = 0;
2549 long pixels;
2550
2551 DBG (5, "Scan commencing with registers:\n");
2552 while (i < 255)
2553 {
2554 int j = 0;
2555 char buffer[80];
2556
2557 buffer[0] = 0;
2558
2559 sprintf (buffer + strlen (buffer), "%02x:", i);
2560 while (j < 8)
2561 {
2562 sprintf (buffer + strlen (buffer), " %02x", regs[i++]);
2563 j++;
2564 }
2565 sprintf (buffer + strlen (buffer), " -");
2566 while (j++ < 16 && i < 255)
2567 sprintf (buffer + strlen (buffer), " %02x", regs[i++]);
2568 DBG (5, " %s\n", buffer);
2569 }
2570
2571 DBG (5, " Position:\n");
2572 DBG (5, " Distance without scanning: %u\n",
2573 get_lsbfirst_int (regs + 0x60, 2));
2574 DBG (5, " Total distance: %u\n",
2575 get_lsbfirst_int (regs + 0x62, 2));
2576 DBG (5, " Scanning distance: %u\n",
2577 get_lsbfirst_int (regs + 0x62, 2) - get_lsbfirst_int (regs + 0x60, 2));
2578 DBG (5, " Direction: %s\n",
2579 (regs[0xc6] & 0x08) ? "forward" : "rewind");
2580 DBG (5, " Motor: %s\n",
2581 (regs[0xc3] & 0x80) ? "enabled" : "disabled");
2582 if (regs[0x7a])
2583 DBG (5, " X range: %u-%u\n",
2584 get_lsbfirst_int (regs + 0x66, 2) / regs[0x7a],
2585 get_lsbfirst_int (regs + 0x6c, 2) / regs[0x7a]);
2586 DBG (5, " TG Info:\n");
2587 DBG (5, " CPH0P: %06x\n",
2588 get_lsbfirst_int (regs + 0xf0, 3));
2589 DBG (5, " CRSP: %06x\n",
2590 get_lsbfirst_int (regs + 0xf9, 3));
2591 DBG (5, " CCLPP: %06x\n",
2592 get_lsbfirst_int (regs + 0xfc, 3));
2593 DBG (5, " CPH0S: %d\n",
2594 (regs[0x2d] & 0x20) ? 1 : 0);
2595 DBG (5, " CDSS1: %02x\n", regs[0x28] & 0x1f);
2596 DBG (5, " CDSC1: %02x\n", regs[0x29] & 0x1f);
2597 DBG (5, " CDSS2: %02x\n", regs[0x2a] & 0x1f);
2598 DBG (5, " CDSC2: %02x\n", regs[0x2b] & 0x1f);
2599
2600 DBG (5, " Resolution specific:\n");
2601 if (!regs[0x7a])
2602 DBG (5, " Horizontal resolution: Denominator is zero!\n");
2603 else
2604 DBG (5, " Horizontal resolution: %u\n", 300
2605 * ((regs[0x2d] & 0x20) ? 2 : 1)
2606 * ((regs[0xd3] & 0x08) ? 2 : 1) / regs[0x7a]);
2607 DBG (5, " Derived vertical resolution: %u\n",
2608 400 * (regs[0xc3] & 0x1f) * convert_c6 (regs[0xc6] & 0x7) /
2609 (regs[0x39] + 1));
2610 DBG (5, " Register D3:3 %u\n",
2611 (regs[0xd3] & 0x08) ? 1 : 0);
2612 DBG (5, " Register 39: %u\n", regs[0x39]);
2613 DBG (5, " Register C3:0-5: %u\n", regs[0xc3] & 0x1f);
2614 DBG (5, " Register C6:0-2: %u\n", regs[0xc6] & 0x7);
2615 DBG (5, " Motor movement clock multiplier: %u\n", regs[0x40] >> 6);
2616 DBG (5, " Step Size: %04x\n",
2617 get_lsbfirst_int (regs + 0xe2, 2));
2618 DBG (5, " Frequency: %u\n", regs[0x64] & 0xf);
2619 DBG (5, " Colour registers\n");
2620 DBG (5, " Register 2F: %02x\n", regs[0x2f]);
2621 DBG (5, " Register 2C: %02x\n", regs[0x2c]);
2622 if (regs[0x7a])
2623 {
2624 DBG (5, " Scan data estimates:\n");
2625 pixels =
2626 (long) (get_lsbfirst_int (regs + 0x62, 2) -
2627 get_lsbfirst_int (regs + 0x60,
2628 2)) * (long) (get_lsbfirst_int (regs + 0x6c,
2629 2) -
2630 get_lsbfirst_int (regs + 0x66,
2631 2)) /
2632 regs[0x7a];
2633 DBG (5, " Pixels: %ld\n", pixels);
2634 DBG (5, " Bytes at 24BPP: %ld\n", pixels * 3);
2635 DBG (5, " Bytes at 1BPP: %ld\n", pixels / 8);
2636 }
2637 DBG (5, "\n");
2638 }
2639
2640 static int
constrain(int val, int min, int max)2641 constrain (int val, int min, int max)
2642 {
2643 if (val < min)
2644 {
2645 DBG (10, "Clipped %d to %d\n", val, min);
2646 val = min;
2647 }
2648 else if (val > max)
2649 {
2650 DBG (10, "Clipped %d to %d\n", val, max);
2651 val = max;
2652 }
2653 return val;
2654 }
2655
2656 #if 0
2657 static void
2658 sram_dump_byte(FILE *fp,
2659 unsigned char const *left,
2660 unsigned leftstart,
2661 unsigned leftlimit,
2662 unsigned char const *right,
2663 unsigned rightstart,
2664 unsigned rightlimit,
2665 unsigned idx)
2666 {
2667 unsigned ridx = rightstart + idx;
2668 unsigned lidx = leftstart + idx;
2669
2670 putc(' ', fp);
2671 if (rightstart < rightlimit && leftstart < leftlimit && left[lidx] != right[ridx])
2672 fputs("<b>", fp);
2673 if (leftstart < leftlimit)
2674 fprintf(fp, "%02x", left[lidx]);
2675 else
2676 fputs(" ", fp);
2677 if (rightstart < rightlimit && leftstart < leftlimit && left[lidx] != right[ridx])
2678 fputs("</b>", fp);
2679 }
2680
2681 static void
2682 dump_sram_to_file(char const *fname,
2683 unsigned char const *expected,
2684 unsigned end_calibration_offset)
2685 {
2686 FILE *fp = fopen(fname, "w");
2687 rt_set_sram_page(0);
2688
2689 if (fp)
2690 {
2691 unsigned char buf[1024];
2692 unsigned loc = 0;
2693
2694 fprintf(fp, "<html><head></head><body><pre>\n");
2695 while (loc < end_calibration_offset)
2696 {
2697 unsigned byte = 0;
2698
2699 rt_read_sram(1024, buf);
2700
2701 while (byte < 1024)
2702 {
2703 unsigned idx = 0;
2704
2705 fprintf(fp, "%06x:", loc);
2706 do
2707 {
2708 sram_dump_byte(fp, buf, byte, 1024, expected, loc, end_calibration_offset, idx);
2709 } while (++idx & 0x7);
2710 fprintf(fp, " -");
2711 do
2712 {
2713 sram_dump_byte(fp, buf, byte, 1024, expected, loc, end_calibration_offset, idx);
2714 } while (++idx & 0x7);
2715
2716 idx = 0;
2717 fputs(" ", fp);
2718
2719 do
2720 {
2721 sram_dump_byte(fp, expected, loc, end_calibration_offset, buf, byte, 1024, idx);
2722 } while (++idx & 0x7);
2723 fprintf(fp, " -");
2724 do
2725 {
2726 sram_dump_byte(fp, expected, loc, end_calibration_offset, buf, byte, 1024, idx);
2727 } while (++idx & 0x7);
2728
2729
2730 fputs("\n", fp);
2731 byte += 16;
2732 loc += 16;
2733 }
2734 }
2735 fprintf(fp, "</pre></body></html>");
2736 fclose(fp);
2737 }
2738 }
2739 #endif
2740
2741 static int
rts8801_doscan(unsigned width, unsigned height, unsigned colour, unsigned red_green_offset, unsigned green_blue_offset, unsigned intra_channel_offset, rts8801_callback cbfunc, void *params, int oddfirst, unsigned char const *calib_info, int merged_channels, double *postprocess_offsets, double *postprocess_gains)2742 rts8801_doscan (unsigned width,
2743 unsigned height,
2744 unsigned colour,
2745 unsigned red_green_offset,
2746 unsigned green_blue_offset,
2747 unsigned intra_channel_offset,
2748 rts8801_callback cbfunc,
2749 void *params,
2750 int oddfirst,
2751 unsigned char const *calib_info,
2752 int merged_channels,
2753 double *postprocess_offsets,
2754 double *postprocess_gains)
2755 {
2756 unsigned rowbytes = 0;
2757 unsigned output_rowbytes = 0;
2758 unsigned channels = 0;
2759 unsigned total_rows = 0;
2760 unsigned char *row_buffer;
2761 unsigned char *output_buffer;
2762 unsigned buffered_rows;
2763 int rows_to_begin;
2764 int rowbuffer_bytes;
2765 int n;
2766 unsigned rownow = 0;
2767 unsigned bytenow = 0;
2768 unsigned char *channel_data[3][2];
2769 unsigned i;
2770 unsigned j;
2771 int result = 0;
2772 unsigned rows_supplied = 0;
2773
2774 (void) calib_info; /* Kill warning */
2775 if (cancelled_scan)
2776 return -1;
2777 rt_start_moving ();
2778
2779 channels = 3;
2780 rowbytes = width * 3;
2781
2782 switch (colour)
2783 {
2784 case HP3500_GRAY_SCAN:
2785 output_rowbytes = width;
2786 break;
2787
2788 case HP3500_COLOR_SCAN:
2789 output_rowbytes = rowbytes;
2790 break;
2791
2792 case HP3500_LINEART_SCAN:
2793 output_rowbytes = (width + 7) / 8;
2794 break;
2795 }
2796
2797 buffered_rows =
2798 red_green_offset + green_blue_offset + intra_channel_offset + 1;
2799 rows_to_begin = buffered_rows;
2800 rowbuffer_bytes = buffered_rows * rowbytes;
2801 row_buffer = (unsigned char *) malloc (rowbuffer_bytes);
2802 output_buffer = (unsigned char *) malloc (rowbytes);
2803
2804 for (i = j = 0; i < channels; ++i)
2805 {
2806 if (i == 1)
2807 j += red_green_offset;
2808 else if (i == 2)
2809 j += green_blue_offset;
2810 if (merged_channels)
2811 channel_data[i][1 - oddfirst] = row_buffer + rowbytes * j + i;
2812 else
2813 channel_data[i][1 - oddfirst] = row_buffer + rowbytes * j + width * i;
2814 channel_data[i][oddfirst] =
2815 channel_data[i][1 - oddfirst] + rowbytes * intra_channel_offset;
2816 }
2817
2818 while (((n = rt_get_available_bytes ()) > 0 || rt_is_moving () > 0)
2819 && !cancelled_scan)
2820 {
2821 if (n == 1 && (rt_is_moving () || rt_get_available_bytes () != 1))
2822 n = 0;
2823 if (n > 0)
2824 {
2825 unsigned char buffer[0xffc0];
2826
2827 if (n > 0xffc0)
2828 n = 0xffc0;
2829 else if ((n > 1) && (n & 1))
2830 --n;
2831 if (rt_get_data (n, buffer) >= 0)
2832 {
2833 unsigned char *bufnow = buffer;
2834
2835 while (n)
2836 {
2837 int numcopy = rowbytes - bytenow;
2838
2839 if (numcopy > n)
2840 numcopy = n;
2841
2842 memcpy (row_buffer + rownow * rowbytes + bytenow,
2843 bufnow, numcopy);
2844 bytenow += numcopy;
2845 bufnow += numcopy;
2846 n -= numcopy;
2847
2848 if (bytenow == rowbytes)
2849 {
2850 if (!rows_to_begin || !--rows_to_begin)
2851 {
2852 unsigned char *outnow = output_buffer;
2853 unsigned x;
2854
2855 for (i = x = 0;
2856 x < width;
2857 ++x, i += merged_channels ? channels : 1)
2858 {
2859 for (j = 0; j < channels; ++j)
2860 {
2861 unsigned pix =
2862 (unsigned char) channel_data[j][i & 1][i];
2863
2864 if (postprocess_gains && postprocess_offsets)
2865 {
2866 int ppidx = j * width + x;
2867
2868 pix = constrain ( pix
2869 * postprocess_gains[ppidx]
2870 - postprocess_offsets[ppidx],
2871 0,
2872 255);
2873 }
2874 *outnow++ = pix;
2875 }
2876 }
2877
2878 if (colour == HP3500_GRAY_SCAN || colour == HP3500_LINEART_SCAN)
2879 {
2880 unsigned char const *in_now = output_buffer;
2881 int bit = 7;
2882
2883 outnow = output_buffer;
2884 for (i = 0; i < width; ++i)
2885 {
2886
2887 if (colour == HP3500_GRAY_SCAN)
2888 {
2889 *outnow++ = ((unsigned) in_now[0] * 2989 +
2890 (unsigned) in_now[1] * 5870 +
2891 (unsigned) in_now[2] * 1140) / 10000;
2892 }
2893 else
2894 {
2895 if (bit == 7)
2896 *outnow = ((in_now[1] < 0x80) ? 0x80 : 0);
2897 else if (in_now[1] < 0x80)
2898 *outnow |= (1 << bit);
2899 if (bit == 0)
2900 {
2901 ++outnow;
2902 bit = 7;
2903 }
2904 else
2905 {
2906 --bit;
2907 }
2908 }
2909 in_now += 3;
2910 }
2911 }
2912 if (rows_supplied++ < height &&
2913 !((*cbfunc) (params, output_rowbytes, output_buffer)))
2914 break;
2915
2916 for (i = 0; i < channels; ++i)
2917 {
2918 for (j = 0; j < 2; ++j)
2919 {
2920 channel_data[i][j] += rowbytes;
2921 if (channel_data[i][j] - row_buffer >=
2922 rowbuffer_bytes)
2923 channel_data[i][j] -= rowbuffer_bytes;
2924 }
2925 }
2926 }
2927 ++total_rows;
2928 if (++rownow == buffered_rows)
2929 rownow = 0;
2930 bytenow = 0;
2931 }
2932 }
2933 }
2934 DBG (30, "total_rows = %d\r", total_rows);
2935 }
2936 else
2937 {
2938 usleep (10000);
2939 }
2940 }
2941 DBG (10, "\n");
2942 if (n < 0)
2943 result = -1;
2944
2945 free (output_buffer);
2946 free (row_buffer);
2947
2948 rt_stop_moving ();
2949 return result;
2950 }
2951
2952 static unsigned local_sram_size;
2953 static unsigned char r93setting;
2954
2955 #define RTS8801_F_SUPPRESS_MOVEMENT 1
2956 #define RTS8801_F_LAMP_OFF 2
2957 #define RTS8801_F_NO_DISPLACEMENTS 4
2958 #define RTS8801_F_ODDX 8
2959
2960 static int
find_resolution_index(unsigned resolution)2961 find_resolution_index (unsigned resolution)
2962 {
2963 int res = 0;
2964
2965 for (res = 0; resparms[res].resolution != resolution; ++res)
2966 {
2967 if (!resparms[res].resolution)
2968 return -1;
2969 }
2970 return res;
2971 }
2972
2973 static int
rts8801_fullscan(unsigned x, unsigned y, unsigned w, unsigned h, unsigned xresolution, unsigned yresolution, unsigned colour, rts8801_callback cbfunc, void *param, unsigned char *calib_info, int flags, int red_calib_offset, int green_calib_offset, int blue_calib_offset, int end_calib_offset, double *postprocess_offsets, double *postprocess_gains)2974 rts8801_fullscan (unsigned x,
2975 unsigned y,
2976 unsigned w,
2977 unsigned h,
2978 unsigned xresolution,
2979 unsigned yresolution,
2980 unsigned colour,
2981 rts8801_callback cbfunc,
2982 void *param,
2983 unsigned char *calib_info,
2984 int flags,
2985 int red_calib_offset,
2986 int green_calib_offset,
2987 int blue_calib_offset,
2988 int end_calib_offset,
2989 double *postprocess_offsets,
2990 double *postprocess_gains)
2991 {
2992 int ires, jres;
2993 int tg_setting;
2994 unsigned char regs[256];
2995 unsigned char offdutytime;
2996 int result;
2997 int scan_frequency;
2998 unsigned intra_channel_offset;
2999 unsigned red_green_offset;
3000 unsigned green_blue_offset;
3001 unsigned total_offsets;
3002
3003 ires = find_resolution_index (xresolution);
3004 jres = find_resolution_index (yresolution);
3005
3006 if (ires < 0 || jres < 0)
3007 return -1;
3008
3009 /* Set scan parameters */
3010
3011 rt_read_register_immediate (0, 255, regs);
3012 regs[255] = 0;
3013
3014 rt_enable_ccd (regs, 1);
3015 rt_enable_movement (regs, 1);
3016 rt_set_scan_frequency (regs, 1);
3017
3018 rt_adjust_misc_registers (regs);
3019
3020 rt_set_cvtr_wparams (regs, 3, 0, 6);
3021 rt_set_cvtr_mpt (regs, 15, 15, 15);
3022 rt_set_cvtr_lm (regs, 7, 7, 7);
3023 rt_set_motor_type (regs, 2);
3024
3025 if (rt_nvram_read (0, 0x7b, &offdutytime, 1) < 0 || offdutytime >= 15)
3026 {
3027 offdutytime = 6;
3028 }
3029 rt_set_lamp_duty_cycle (regs, 1, /* On */
3030 10, /* Frequency */
3031 offdutytime); /* Off duty time */
3032
3033 rt_set_movement_pattern (regs, 0x800000);
3034
3035 rt_set_direction_forwards (regs);
3036 rt_set_stop_when_rewound (regs, 0);
3037
3038 rt_set_calibration_addresses (regs, 0, 0, 0, 0, 0);
3039
3040 rt_set_basic_calibration (regs,
3041 calib_info[0], calib_info[1], calib_info[2],
3042 calib_info[3], calib_info[4], calib_info[5],
3043 calib_info[6], calib_info[7], calib_info[8]);
3044 regs[0x0b] = 0x70; /* If set to 0x71, the alternative, all values are low */
3045 regs[0x40] &= 0xc0;
3046
3047 if (red_calib_offset >= 0
3048 && green_calib_offset >= 0
3049 && blue_calib_offset >= 0)
3050 {
3051 rt_set_calibration_addresses (regs, red_calib_offset,
3052 green_calib_offset, blue_calib_offset,
3053 end_calib_offset,
3054 w);
3055 regs[0x40] |= 0x2f;
3056 }
3057 else if (end_calib_offset >= 0)
3058 {
3059 rt_set_calibration_addresses (regs, 0x600, 0x600, 0x600,
3060 end_calib_offset, w);
3061 }
3062
3063 rt_set_channel (regs, RT_CHANNEL_ALL);
3064 rt_set_single_channel_scanning (regs, 0);
3065 rt_set_merge_channels (regs, 1);
3066 rt_set_colour_mode (regs, 1);
3067
3068 rt_set_last_sram_page (regs, (local_sram_size - 1) >> 5);
3069
3070 scan_frequency = resparms[jres].scan_frequency;
3071 rt_set_cph0s (regs, resparms[ires].cph0s);
3072 if (resparms[ires].d3_bit_3_value)
3073 regs[0xd3] |= 0x08;
3074 else
3075 regs[0xd3] &= 0xf7;
3076
3077 if (flags & RTS8801_F_SUPPRESS_MOVEMENT)
3078 regs[0xc3] &= 0x7f;
3079
3080 regs[0xb2] &= 0xf7;
3081
3082 rt_set_horizontal_resolution (regs, xresolution);
3083
3084 rt_set_scanline_start (regs,
3085 x * (1200 / xresolution) /
3086 (resparms[ires].cph0s ? 1 : 2) /
3087 (resparms[ires].d3_bit_3_value ? 1 : 2));
3088 rt_set_scanline_end (regs,
3089 (x +
3090 w) * (1200 / xresolution) /
3091 (resparms[ires].cph0s ? 1 : 2) /
3092 (resparms[ires].d3_bit_3_value ? 1 : 2));
3093
3094 if (flags & RTS8801_F_NO_DISPLACEMENTS)
3095 {
3096 red_green_offset = green_blue_offset = intra_channel_offset = 0;
3097 }
3098 else
3099 {
3100 red_green_offset = resparms[jres].red_green_offset;
3101 green_blue_offset = resparms[jres].green_blue_offset;
3102 intra_channel_offset = resparms[jres].intra_channel_offset;
3103 }
3104 total_offsets = red_green_offset + green_blue_offset + intra_channel_offset;
3105 if (y > total_offsets + 2)
3106 y -= total_offsets;
3107 h += total_offsets;
3108
3109 if (yresolution > 75 && !(flags & RTS8801_F_SUPPRESS_MOVEMENT))
3110 {
3111 int rmres = find_resolution_index (50);
3112
3113 if (rmres >= 0)
3114 {
3115 int factor = yresolution / 50;
3116 int fastres = y / factor;
3117 int remainder = y % factor;
3118
3119 while (remainder < 2)
3120 {
3121 --fastres;
3122 remainder += factor;
3123 }
3124
3125 if (fastres >= 3)
3126 {
3127 y = remainder;
3128
3129 rt_set_noscan_distance(regs, fastres * resparms[rmres].scan_frequency - 2);
3130 rt_set_total_distance(regs, fastres * resparms[rmres].scan_frequency - 1);
3131
3132 rt_set_scan_frequency(regs, 1);
3133
3134 tg_setting = resparms[rmres].tg;
3135 rt_set_ccd_shift_clock_multiplier (regs, tg_info[tg_setting].tg_cph0p);
3136 rt_set_ccd_clock_reset_interval (regs, tg_info[tg_setting].tg_crsp);
3137 rt_set_ccd_clamp_clock_multiplier (regs, tg_info[tg_setting].tg_cclpp);
3138
3139 rt_set_one_register (0xc6, 0);
3140 rt_set_one_register (0xc6, 0);
3141
3142 rt_set_step_size (regs, resparms[rmres].step_size);
3143
3144 rt_set_motor_movement_clock_multiplier (regs,
3145 resparms[rmres].
3146 motor_movement_clock_multiplier);
3147
3148 rt_set_cdss (regs, tg_info[tg_setting].tg_cdss1,
3149 tg_info[tg_setting].tg_cdss2);
3150 rt_set_cdsc (regs, tg_info[tg_setting].tg_cdsc1,
3151 tg_info[tg_setting].tg_cdsc2);
3152 rt_update_after_setting_cdss2 (regs);
3153
3154 regs[0x39] = resparms[rmres].reg_39_value;
3155 regs[0xc3] = (regs[0xc3] & 0xf8) | resparms[rmres].reg_c3_value;
3156 regs[0xc6] = (regs[0xc6] & 0xf8) | resparms[rmres].reg_c6_value;
3157
3158 rt_set_data_feed_off (regs);
3159
3160 rt_set_all_registers (regs);
3161
3162 rt_set_one_register (0x2c, regs[0x2c]);
3163
3164 if (DBG_LEVEL >= 5)
3165 dump_registers (regs);
3166
3167 rt_start_moving ();
3168 while (rt_is_moving ());
3169 }
3170 }
3171 }
3172
3173
3174 rt_set_noscan_distance (regs, y * scan_frequency - 1);
3175 rt_set_total_distance (regs, scan_frequency * (y + h) - 1);
3176
3177 rt_set_scan_frequency (regs, scan_frequency);
3178
3179 tg_setting = resparms[jres].tg;
3180
3181 rt_set_ccd_shift_clock_multiplier (regs, tg_info[tg_setting].tg_cph0p);
3182 rt_set_ccd_clock_reset_interval (regs, tg_info[tg_setting].tg_crsp);
3183 rt_set_ccd_clamp_clock_multiplier (regs, tg_info[tg_setting].tg_cclpp);
3184
3185 rt_set_one_register (0xc6, 0);
3186 rt_set_one_register (0xc6, 0);
3187
3188 rt_set_step_size (regs, resparms[jres].step_size);
3189
3190 rt_set_motor_movement_clock_multiplier (regs,
3191 resparms[jres].
3192 motor_movement_clock_multiplier);
3193
3194 rt_set_cdss (regs, tg_info[tg_setting].tg_cdss1,
3195 tg_info[tg_setting].tg_cdss2);
3196 rt_set_cdsc (regs, tg_info[tg_setting].tg_cdsc1,
3197 tg_info[tg_setting].tg_cdsc2);
3198 rt_update_after_setting_cdss2 (regs);
3199
3200 regs[0x39] = resparms[jres].reg_39_value;
3201 regs[0xc3] = (regs[0xc3] & 0xf8) | resparms[jres].reg_c3_value;
3202 regs[0xc6] = (regs[0xc6] & 0xf8) | resparms[jres].reg_c6_value;
3203
3204 rt_set_data_feed_on (regs);
3205
3206 rt_set_all_registers (regs);
3207
3208 rt_set_one_register (0x2c, regs[0x2c]);
3209
3210 if (DBG_LEVEL >= 5)
3211 dump_registers (regs);
3212
3213 result = rts8801_doscan (w,
3214 h,
3215 colour,
3216 red_green_offset,
3217 green_blue_offset,
3218 intra_channel_offset,
3219 cbfunc, param, (x & 1), calib_info,
3220 (regs[0x2f] & 0x04) != 0,
3221 postprocess_offsets,
3222 postprocess_gains);
3223 return result;
3224 }
3225
3226 static int
accumfunc(struct dcalibdata *dcd, int bytes, char *data)3227 accumfunc (struct dcalibdata *dcd, int bytes, char *data)
3228 {
3229 unsigned char *c = (unsigned char *) data;
3230
3231 while (bytes > 0)
3232 {
3233 if (dcd->firstrowdone)
3234 dcd->buffers[dcd->channelnow][dcd->pixelnow - dcd->pixelsperrow] = *c;
3235 if (++dcd->channelnow >= 3)
3236 {
3237 dcd->channelnow = 0;
3238 if (++dcd->pixelnow == dcd->pixelsperrow)
3239 ++dcd->firstrowdone;
3240 }
3241 c++;
3242 bytes--;
3243 }
3244 return 1;
3245 }
3246
3247 static int
calcmedian(unsigned char const *data, int pixel, int pixels_per_row, int elements)3248 calcmedian (unsigned char const *data,
3249 int pixel, int pixels_per_row, int elements)
3250 {
3251 int tallies[256];
3252 int i;
3253 int elemstogo = elements / 2;
3254
3255 memset (tallies, 0, sizeof (tallies));
3256 data += pixel;
3257 for (i = 0; i < elements; ++i)
3258 {
3259 ++tallies[*data];
3260 data += pixels_per_row;
3261 }
3262 i = 0;
3263 while (elemstogo - tallies[i] > 0)
3264 elemstogo -= tallies[i++];
3265 return i;
3266 }
3267
3268 struct calibdata
3269 {
3270 unsigned char *buffer;
3271 int space;
3272 };
3273
3274 static int
storefunc(struct calibdata *cd, int bytes, char *data)3275 storefunc (struct calibdata *cd, int bytes, char *data)
3276 {
3277 if (cd->space > 0)
3278 {
3279 if (bytes > cd->space)
3280 bytes = cd->space;
3281 memcpy (cd->buffer, data, bytes);
3282 cd->buffer += bytes;
3283 cd->space -= bytes;
3284 }
3285 return 1;
3286 }
3287
3288 static unsigned
sum_channel(unsigned char *p, int n, int bytwo)3289 sum_channel (unsigned char *p, int n, int bytwo)
3290 {
3291 unsigned v = 0;
3292
3293 while (n-- > 0)
3294 {
3295 v += *p;
3296 p += 3;
3297 if (bytwo)
3298 p += 3;
3299 }
3300 return v;
3301 }
3302
3303 static int do_warmup = 1;
3304
3305 #define DETAILED_PASS_COUNT 3
3306 #define DETAILED_PASS_OFFSETS 0
3307 #define DETAILED_PASS_GAINS_FIRSTPASS 1
3308 #define DETAILED_PASS_GAINS_SECONDPASS 2
3309
3310 static int
rts8801_scan(unsigned x, unsigned y, unsigned w, unsigned h, unsigned resolution, unsigned colour, unsigned brightness, unsigned contrast, rts8801_callback cbfunc, void *param, double gamma)3311 rts8801_scan (unsigned x,
3312 unsigned y,
3313 unsigned w,
3314 unsigned h,
3315 unsigned resolution,
3316 unsigned colour,
3317 unsigned brightness,
3318 unsigned contrast,
3319 rts8801_callback cbfunc,
3320 void *param,
3321 double gamma)
3322 {
3323 unsigned char calib_info[9];
3324 unsigned char calibbuf[2400];
3325 struct dcalibdata dcd;
3326 struct calibdata cd;
3327 unsigned char *detail_buffer = 0;
3328 int iCalibY;
3329 int iCalibTarget;
3330 int iMoveFlags = 0;
3331 unsigned aiBestOffset[6];
3332 int aiPassed[6];
3333 int i;
3334 unsigned j;
3335 int k;
3336 int calibration_size;
3337 unsigned char *pDetailedCalib;
3338 int red_calibration_offset;
3339 int green_calibration_offset;
3340 int blue_calibration_offset;
3341 int end_calibration_offset;
3342 int base_resolution;
3343 int resolution_divisor;
3344 int resolution_index;
3345 int detailed_calibration_rows = 50;
3346 unsigned char *tdetail_buffer;
3347 int pass;
3348 int onechanged;
3349 double *postprocess_gains;
3350 double *postprocess_offsets;
3351 int needs_postprocessed_calibration = 0;
3352 double contrast_adjust = (double) contrast / 64;
3353 int brightness_adjust = brightness - 0x80;
3354
3355 /* Initialise and power up */
3356
3357 rt_set_all_registers (initial_regs);
3358 rt_set_powersave_mode (0);
3359
3360 /* Initial rewind in case scanner is stuck away from home position */
3361
3362 rts8801_rewind ();
3363
3364 /* Detect SRAM */
3365
3366 rt_detect_sram (&local_sram_size, &r93setting);
3367
3368 /* Warm up the lamp */
3369
3370 DBG (10, "Warming up the lamp\n");
3371
3372 rt_turn_on_lamp ();
3373 if (do_warmup)
3374 sleep (25);
3375
3376 /* Basic calibration */
3377
3378 DBG (10, "Calibrating (stage 1)\n");
3379
3380 calib_info[2] = calib_info[5] = calib_info[8] = 1;
3381
3382 iCalibY = (resolution == 25) ? 1 : 2;
3383 iCalibTarget = 550;
3384
3385 rt_turn_off_lamp();
3386
3387 for (i = 0; i < 6; ++i)
3388 {
3389 aiBestOffset[i] = 0xbf;
3390 aiPassed[i] = 0;
3391 }
3392
3393 do
3394 {
3395 DBG (30, "Initial calibration pass commences\n");
3396
3397 onechanged = 0;
3398 for (i = 0; i < 3; ++i)
3399 {
3400 calib_info[i * 3] = aiBestOffset[i];
3401 calib_info[i * 3 + 1] = aiBestOffset[i + 3];
3402 }
3403
3404 cd.buffer = calibbuf;
3405 cd.space = sizeof (calibbuf);
3406 DBG (30, "Commencing scan for initial calibration pass\n");
3407 rts8801_fullscan (1401, iCalibY, 100, 2, 400, resolution,
3408 HP3500_COLOR_SCAN, (rts8801_callback) storefunc, &cd,
3409 calib_info, iMoveFlags, -1, -1, -1, -1, 0, 0);
3410 DBG (30, "Completed scan for initial calibration pass\n");
3411 iMoveFlags = RTS8801_F_SUPPRESS_MOVEMENT | RTS8801_F_NO_DISPLACEMENTS;
3412 iCalibY = 2;
3413
3414 for (i = 0; i < 6; ++i)
3415 {
3416 int sum;
3417
3418 if (aiBestOffset[i] >= 255 || aiPassed[i] > 2)
3419 continue;
3420 sum = sum_channel (calibbuf + i, 50, 1);
3421 DBG (20, "channel[%d] sum = %d (target %d)\n", i, sum,
3422 iCalibTarget);
3423
3424 if (sum < iCalibTarget)
3425 {
3426 onechanged = 1;
3427 ++aiBestOffset[i];
3428 }
3429 else
3430 {
3431 ++aiPassed[i];
3432 }
3433 }
3434 DBG (30, "Initial calibration pass completed\n");
3435 }
3436 while (onechanged);
3437
3438 DBG (20, "Offsets calculated\n");
3439
3440 rt_turn_on_lamp();
3441 usleep(500000);
3442
3443 tdetail_buffer =
3444 (unsigned char *) malloc (w * 3 * detailed_calibration_rows);
3445
3446 for (i = 0; i < 3; ++i)
3447 {
3448 calib_info[i * 3 + 2] = 1;
3449 aiPassed[i] = 0;
3450 }
3451
3452 do
3453 {
3454 struct dcalibdata dcdt;
3455
3456 dcdt.buffers[0] = tdetail_buffer;
3457 dcdt.buffers[1] = (tdetail_buffer + w * detailed_calibration_rows);
3458 dcdt.buffers[2] = (dcdt.buffers[1] + w * detailed_calibration_rows);
3459 dcdt.pixelsperrow = w;
3460 dcdt.pixelnow = dcdt.channelnow = dcdt.firstrowdone = 0;
3461 DBG (20, "Scanning for part 2 of initial calibration\n");
3462 rts8801_fullscan (x, 4, w, detailed_calibration_rows + 1, resolution,
3463 resolution, HP3500_COLOR_SCAN,
3464 (rts8801_callback) accumfunc, &dcdt, calib_info,
3465 RTS8801_F_SUPPRESS_MOVEMENT | RTS8801_F_NO_DISPLACEMENTS, -1, -1, -1, -1, 0, 0);
3466 DBG (20, "Scan for part 2 of initial calibration completed\n");
3467
3468 onechanged = 0;
3469 for (i = 0; i < 3; ++i)
3470 {
3471 int largest = 1;
3472
3473 if (aiPassed[i] > 2 || calib_info[i * 3 + 2] >= 63)
3474 continue;
3475
3476 for (j = 0; j < w; ++j)
3477 {
3478 int val =
3479 calcmedian (dcdt.buffers[i], j, w, detailed_calibration_rows);
3480
3481 if (val > largest)
3482 largest = val;
3483 }
3484
3485 if (largest < 0xe0)
3486 {
3487 ++calib_info[i * 3 + 2];
3488 onechanged = 1;
3489 }
3490 else
3491 {
3492 ++aiPassed[i];
3493 }
3494 }
3495 }
3496 while (onechanged);
3497
3498 for (i = 0; i < 3; ++i)
3499 {
3500 DBG (10, "Channel [%d] gain=%02x offset=%02x\n",
3501 i, calib_info[i * 3] + 2, calib_info[i * 3]);
3502 }
3503
3504 DBG (20, "Gain factors calculated\n");
3505
3506 /* Stage 2 calibration */
3507
3508 DBG (10, "Calibrating (stage 2)\n");
3509
3510 detail_buffer =
3511 (unsigned char *) malloc (w * 3 * detailed_calibration_rows);
3512
3513 dcd.buffers[0] = detail_buffer;
3514 dcd.buffers[1] = (detail_buffer + w * detailed_calibration_rows);
3515 dcd.buffers[2] = (dcd.buffers[1] + w * detailed_calibration_rows);
3516 dcd.pixelsperrow = w;
3517
3518
3519 /* And now for the detailed calibration */
3520 resolution_index = find_resolution_index (resolution);
3521 base_resolution = 300;
3522 if (resparms[resolution_index].cph0s)
3523 base_resolution *= 2;
3524 if (resparms[resolution_index].d3_bit_3_value)
3525 base_resolution *= 2;
3526 resolution_divisor = base_resolution / resolution;
3527
3528 calibration_size = w * resolution_divisor * 6 + 1568 + 96;
3529 red_calibration_offset = 0x600;
3530 green_calibration_offset =
3531 red_calibration_offset + w * resolution_divisor * 2;
3532 blue_calibration_offset =
3533 green_calibration_offset + w * resolution_divisor * 2;
3534 end_calibration_offset =
3535 blue_calibration_offset + w * resolution_divisor * 2;
3536 pDetailedCalib = (unsigned char *) malloc (calibration_size);
3537
3538 memset (pDetailedCalib, 0, calibration_size);
3539
3540 for (i = 0; i < 3; ++i)
3541 {
3542 int idx =
3543 (i == 0) ? red_calibration_offset :
3544 (i == 1) ? green_calibration_offset :
3545 blue_calibration_offset;
3546
3547 for (j = 0; j < 256; j++)
3548 {
3549 /* Gamma table - appears to be 256 byte pairs for each input
3550 * range (so the first entry cover inputs in the range 0 to 1,
3551 * the second 1 to 2, and so on), mapping that input range
3552 * (including the fractional parts within it) to an output
3553 * range.
3554 */
3555 pDetailedCalib[i * 512 + j * 2] = j;
3556 pDetailedCalib[i * 512 + j * 2 + 1] = j;
3557 }
3558
3559 for (j = 0; j < w; ++j)
3560 {
3561 for (k = 0; k < resolution_divisor; ++k)
3562 {
3563 pDetailedCalib[idx++] = 0;
3564 pDetailedCalib[idx++] = 0x80;
3565 }
3566 }
3567 }
3568
3569 rt_set_sram_page (0);
3570 rt_set_one_register (0x93, r93setting);
3571 rt_write_sram (calibration_size, pDetailedCalib);
3572
3573 postprocess_gains = (double *) malloc(sizeof(double) * 3 * w);
3574 postprocess_offsets = (double *) malloc(sizeof(double) * 3 * w);
3575
3576 for (pass = 0; pass < DETAILED_PASS_COUNT; ++pass)
3577 {
3578 int ppidx = 0;
3579
3580 DBG (10, "Performing detailed calibration scan %d\n", pass);
3581
3582 switch (pass)
3583 {
3584 case DETAILED_PASS_OFFSETS:
3585 rt_turn_off_lamp();
3586 usleep(500000); /* To be sure it has gone off */
3587 break;
3588
3589 case DETAILED_PASS_GAINS_FIRSTPASS:
3590 rt_turn_on_lamp();
3591 usleep(500000); /* Give the lamp time to settle */
3592 break;
3593 }
3594
3595 dcd.pixelnow = dcd.channelnow = dcd.firstrowdone = 0;
3596 rts8801_fullscan (x, iCalibY, w, detailed_calibration_rows + 1,
3597 resolution, resolution, HP3500_COLOR_SCAN,
3598 (rts8801_callback) accumfunc, &dcd,
3599 calib_info,
3600 RTS8801_F_SUPPRESS_MOVEMENT | RTS8801_F_NO_DISPLACEMENTS,
3601 red_calibration_offset,
3602 green_calibration_offset,
3603 blue_calibration_offset,
3604 end_calibration_offset,
3605 0, 0);
3606
3607 DBG (10, " Detailed calibration scan %d completed\n", pass);
3608
3609 for (i = 0; i < 3; ++i)
3610 {
3611 int idx =
3612 (i == 0) ? red_calibration_offset :
3613 (i == 1) ? green_calibration_offset :
3614 blue_calibration_offset;
3615
3616 for (j = 0; j < w; ++j)
3617 {
3618 double multnow = 0x80;
3619 int offnow = 0;
3620
3621 /* This seems to be the approach for reg 0x40 & 0x3f == 0x27, which allows detailed
3622 * calibration to return either higher or lower values.
3623 */
3624
3625 {
3626 double denom1 =
3627 calcmedian (dcd.buffers[i], j, w, detailed_calibration_rows);
3628
3629 switch (pass)
3630 {
3631 case DETAILED_PASS_OFFSETS:
3632 /* The offset is the number needed to be subtracted from "black" at detailed gain = 0x80,
3633 * which is the value we started with. For the next round, pull the gain down to 0x20. Our
3634 * next scan is a test scan to confirm the offset works.
3635 */
3636 multnow = 0x20;
3637 offnow = denom1;
3638 break;
3639
3640 case DETAILED_PASS_GAINS_FIRSTPASS:
3641 multnow = 128.0 / denom1 * 0x20; /* Then bring it up to whatever we need to hit 192 */
3642 if (multnow > 255)
3643 multnow = 255;
3644 offnow = pDetailedCalib[idx];
3645 break;
3646
3647 case DETAILED_PASS_GAINS_SECONDPASS:
3648 multnow = 255.0 / denom1 * contrast_adjust * pDetailedCalib[idx+1]; /* And finally to 255 */
3649 offnow = pDetailedCalib[idx] - brightness_adjust * 0x80 / multnow;
3650
3651 if (offnow < 0)
3652 {
3653 postprocess_offsets[ppidx] = multnow * offnow / 0x80;
3654 offnow = 0;
3655 needs_postprocessed_calibration = 1;
3656 }
3657 else if (offnow > 255)
3658 {
3659 postprocess_offsets[ppidx] = multnow * (offnow - 255) / 0x80;
3660 offnow = 255;
3661 needs_postprocessed_calibration = 1;
3662 }
3663 else
3664 {
3665 postprocess_offsets[ppidx] = 0;
3666 }
3667 if (multnow > 255)
3668 {
3669 postprocess_gains[ppidx] = multnow / 255;
3670 multnow = 255;
3671 needs_postprocessed_calibration = 1;
3672 }
3673 else
3674 {
3675 postprocess_gains[ppidx] = 1.0;
3676 }
3677 break;
3678 }
3679 }
3680 if (offnow > 255)
3681 offnow = 255;
3682
3683 for (k = 0; k < resolution_divisor; ++k)
3684 {
3685 pDetailedCalib[idx++] = offnow; /* Subtract this value from the result at gains = 0x80*/
3686 pDetailedCalib[idx++] = multnow; /* Then multiply by this value divided by 0x80 */
3687 }
3688 ++ppidx;
3689 }
3690 }
3691
3692 if (pass == DETAILED_PASS_GAINS_SECONDPASS)
3693 {
3694 /* Build gamma table */
3695 unsigned char *redgamma = pDetailedCalib;
3696 unsigned char *greengamma = redgamma + 512;
3697 unsigned char *bluegamma = greengamma + 512;
3698 double val;
3699 double invgamma = 1.0l / gamma;
3700
3701 *redgamma++ = *bluegamma++ = *greengamma++ = 0;
3702
3703 /* The windows driver does a linear interpolation for the next 19 boundaries */
3704 val = pow (20.0l / 255, invgamma) * 255;
3705
3706 for (j = 1; j <= 20; ++j)
3707 {
3708 *redgamma++ = *bluegamma++ = *greengamma++ = val * j / 20 + 0.5;
3709 *redgamma++ = *bluegamma++ = *greengamma++ = val * j / 20 + 0.5;
3710 }
3711
3712 for (; j <= 255; ++j)
3713 {
3714 val = pow((double) j / 255, invgamma) * 255;
3715
3716 *redgamma++ = *bluegamma++ = *greengamma++ = val + 0.5;
3717 *redgamma++ = *bluegamma++ = *greengamma++ = val + 0.5;
3718 }
3719 *redgamma++ = *bluegamma++ = *greengamma++ = 255;
3720 }
3721
3722 DBG (10, "\n");
3723
3724 rt_set_sram_page (0);
3725 rt_set_one_register (0x93, r93setting);
3726 rt_write_sram (calibration_size, pDetailedCalib);
3727 }
3728
3729 /* And finally, perform the scan */
3730 DBG (10, "Scanning\n");
3731
3732 rts8801_rewind ();
3733
3734 rts8801_fullscan (x, y, w, h, resolution, resolution, colour, cbfunc, param,
3735 calib_info, 0,
3736 red_calibration_offset, green_calibration_offset,
3737 blue_calibration_offset, end_calibration_offset,
3738 needs_postprocessed_calibration ? postprocess_offsets : 0,
3739 needs_postprocessed_calibration ? postprocess_gains : 0);
3740
3741 rt_turn_off_lamp ();
3742
3743 rts8801_rewind ();
3744 rt_set_powersave_mode (1);
3745
3746 if (pDetailedCalib)
3747 free (pDetailedCalib);
3748 if (detail_buffer)
3749 free (detail_buffer);
3750 if (tdetail_buffer)
3751 free(tdetail_buffer);
3752 if (postprocess_gains)
3753 free(postprocess_gains);
3754 if (postprocess_offsets)
3755 free(postprocess_offsets);
3756 return 0;
3757 }
3758
3759 static int
writefunc(struct hp3500_write_info *winfo, int bytes, char *data)3760 writefunc (struct hp3500_write_info *winfo, int bytes, char *data)
3761 {
3762 static int warned = 0;
3763
3764 if (bytes > winfo->bytesleft)
3765 {
3766 if (!warned)
3767 {
3768 warned = 1;
3769 DBG (1, "Overflow protection triggered\n");
3770 rt_stop_moving ();
3771 }
3772 bytes = winfo->bytesleft;
3773 if (!bytes)
3774 return 0;
3775 }
3776 winfo->bytesleft -= bytes;
3777 return write (winfo->scanner->pipe_w, data, bytes) == bytes;
3778 }
3779
3780 #ifdef _POSIX_SOURCE
3781 static void
sigtermHandler(int signal)3782 sigtermHandler (int signal)
3783 {
3784 (void) signal; /* get rid of compiler warning */
3785 cancelled_scan = 1;
3786 }
3787 #endif
3788
3789 static int
reader_process(void *pv)3790 reader_process (void *pv)
3791 {
3792 struct hp3500_data *scanner = pv;
3793 time_t t;
3794 sigset_t ignore_set;
3795 sigset_t sigterm_set;
3796 struct SIGACTION act;
3797 struct hp3500_write_info winfo;
3798 int status;
3799
3800 if (sanei_thread_is_forked ())
3801 {
3802 close (scanner->pipe_r);
3803
3804 sigfillset (&ignore_set);
3805 sigdelset (&ignore_set, SIGTERM);
3806 #if defined (__APPLE__) && defined (__MACH__)
3807 sigdelset (&ignore_set, SIGUSR2);
3808 #endif
3809 sigprocmask (SIG_SETMASK, &ignore_set, 0);
3810
3811 sigemptyset (&sigterm_set);
3812 sigaddset (&sigterm_set, SIGTERM);
3813
3814 memset (&act, 0, sizeof (act));
3815 #ifdef _POSIX_SOURCE
3816 act.sa_handler = sigtermHandler;
3817 #endif
3818 sigaction (SIGTERM, &act, 0);
3819 }
3820
3821 /* Warm up the lamp again if our last scan ended more than 5 minutes ago. */
3822 time (&t);
3823 do_warmup = (t - scanner->last_scan) > 300;
3824
3825 if (getenv ("HP3500_NOWARMUP") && atoi (getenv ("HP3500_NOWARMUP")) > 0)
3826 do_warmup = 0;
3827
3828 udh = scanner->sfd;
3829
3830 cancelled_scan = 0;
3831
3832 winfo.scanner = scanner;
3833 winfo.bytesleft =
3834 scanner->bytes_per_scan_line * scanner->scan_height_pixels;
3835
3836 if (getenv ("HP3500_SLEEP"))
3837 {
3838 int seconds = atoi (getenv ("HP3500_SLEEP"));
3839
3840 DBG (1, "Backend process %d sleeping for %d seconds\n", getpid (),
3841 seconds);
3842 sleep (seconds);
3843 }
3844 DBG (10, "Scanning at %ddpi, mode=%s\n", scanner->resolution,
3845 scan_mode_list[scanner->mode]);
3846 if (rts8801_scan
3847 (scanner->actres_pixels.left + 250 * scanner->resolution / 1200,
3848 scanner->actres_pixels.top + 599 * scanner->resolution / 1200,
3849 scanner->actres_pixels.right - scanner->actres_pixels.left,
3850 scanner->actres_pixels.bottom - scanner->actres_pixels.top,
3851 scanner->resolution, scanner->mode, scanner->brightness,
3852 scanner->contrast, (rts8801_callback) writefunc, &winfo,
3853 scanner->gamma) >= 0)
3854 status = SANE_STATUS_GOOD;
3855 status = SANE_STATUS_IO_ERROR;
3856 close (scanner->pipe_w);
3857 return status;
3858 }
3859
3860 static size_t
max_string_size(char const **strings)3861 max_string_size (char const **strings)
3862 {
3863 size_t size, max_size = 0;
3864 SANE_Int i;
3865
3866 for (i = 0; strings[i]; ++i)
3867 {
3868 size = strlen (strings[i]) + 1;
3869 if (size > max_size)
3870 max_size = size;
3871 }
3872 return max_size;
3873 }
3874