1 /*
2 Copyright (C) 2000 by Adrian Perez Jorge
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18 /* Developers:
19
20 Adrian Perez Jorge (APJ) -
21 Creator of the original HP4200C backend code.
22 adrianpj@easynews.com
23
24 Andrew John Lewis (AJL) -
25 lewi0235@tc.umn.edu
26
27 Arnar Mar Hrafnkelsson (AMH) -
28 addi@umich.edu
29
30 Frank Zago
31 some cleanups and integration into SANE
32
33 Henning Meier-Geinitz <henning@meier-geinitz.de>
34 more cleanups, bug fixes
35
36 TODO:
37
38 - support more scanning resolutions.
39 - support different color depths.
40 - support gray and lineart.
41 - improve scanning speed. Compute scanning parameters based on the
42 image size and the scanner-to-host bandwidth.
43 - improve image quality.
44 - fix problem concerning mangled images
45
46 */
47
48 #define BUILD 2
49 #define BACKEND_NAME hp4200
50
51 #include "../include/sane/config.h"
52
53 #include <sys/ioctl.h>
54 #include <stdio.h>
55 #include <sys/types.h>
56 #include <sys/stat.h>
57 #include <fcntl.h>
58 #include <unistd.h>
59 #include <string.h>
60 #include <math.h>
61 #include <sys/time.h>
62 #include <stdlib.h>
63 #include <getopt.h>
64 #include <ctype.h>
65 #include <assert.h>
66
67 #include "../include/sane/sane.h"
68 #include "../include/sane/sanei.h"
69 #include "../include/sane/sanei_debug.h"
70 #include "../include/sane/sanei_config.h"
71 #include "../include/sane/sanei_usb.h"
72 #include "../include/sane/sanei_pv8630.h"
73 #include "../include/sane/saneopts.h"
74 #include "../include/sane/sanei_backend.h"
75 #include "hp4200.h"
76
77 #include "hp4200_lm9830.c"
78
79 #define HP4200_CONFIG_FILE "hp4200.conf"
80
81 /*--------------------------------------------------------------------------*/
82
83 #if 0
84 /* Some of these resolution need work in color shifting. */
85 static const SANE_Int dpi_list[] =
86 { 8, 50, 75, 100, 150, 200, 300, 400, 600 };
87 #else
88 static const SANE_Int dpi_list[] = { 4, 75, 150, 300, 600 };
89 #endif
90 static SANE_Range x_range = { SANE_FIX (0), SANE_FIX (8.5 * MM_PER_INCH), 0 };
91 static SANE_Range y_range =
92 { SANE_FIX (0), SANE_FIX (11.75 * MM_PER_INCH), 0 };
93 static const SANE_Range u8_range = { 0, 255, 0 };
94
95 struct coarse_t
96 {
97 int min_red;
98 int min_green;
99 int min_blue;
100 int max_red;
101 int max_green;
102 int max_blue;
103 int red_gain;
104 int red_offset;
105 int green_gain;
106 int green_offset;
107 int blue_gain;
108 int blue_offset;
109 };
110
111 static const double hdpi_mapping[8] = { 1, 1.5, 2, 3, 4, 6, 8, 12 };
112
113 static HP4200_Device *first_device = NULL; /* device list head */
114 static int n_devices = 0; /* the device count */
115 static const SANE_Device **devlist = NULL;
116
117 static unsigned char
getreg(HP4200_Scanner * s,unsigned char reg)118 getreg (HP4200_Scanner * s, unsigned char reg)
119 {
120 unsigned char reg_value;
121
122 if ((reg > 0x08) && (reg < 0x5b))
123 return (unsigned char) LOBYTE (s->regs[reg]);
124 else
125 {
126 lm9830_read_register (s->fd, reg, ®_value);
127 return reg_value;
128 }
129 }
130
131 static void
setreg(HP4200_Scanner * s,unsigned char reg,unsigned char reg_value)132 setreg (HP4200_Scanner * s, unsigned char reg, unsigned char reg_value)
133 {
134 s->regs[reg] = reg_value; /* dirty bit should be clear with this */
135 if ((reg < 0x08) || (reg > 0x5b))
136 {
137 lm9830_write_register (s->fd, reg, reg_value);
138 }
139 }
140
141 static void
setbits(HP4200_Scanner * s,unsigned char reg,unsigned char bitmap)142 setbits (HP4200_Scanner * s, unsigned char reg, unsigned char bitmap)
143 {
144 s->regs[reg] = (s->regs[reg] & 0xff) | bitmap;
145 if ((reg < 0x08) || (reg > 0x5b))
146 {
147 lm9830_write_register (s->fd, reg, LOBYTE (s->regs[reg]));
148 }
149 }
150
151 static void
clearbits(HP4200_Scanner * s,unsigned char reg,unsigned char mask)152 clearbits (HP4200_Scanner * s, unsigned char reg, unsigned char mask)
153 {
154 s->regs[reg] = (s->regs[reg] & ~mask) & 0xff;
155 if ((reg < 0x08) || (reg > 0x5b))
156 {
157 lm9830_write_register (s->fd, reg, LOBYTE (s->regs[reg]));
158 }
159 }
160
161 static int
cache_write(HP4200_Scanner * s)162 cache_write (HP4200_Scanner * s)
163 {
164 int i;
165 #ifdef DEBUG_REG_CACHE
166 int counter = 0;
167 #endif
168
169 DBG (DBG_proc, "Writing registers\n");
170
171 for (i = 0; i < 0x80; i++)
172 if (!(s->regs[i] & 0x100))
173 { /* modified register */
174 #ifdef DEBUG_REG_CACHE
175 fprintf (stderr, "%.2x", i);
176 if (counter == 8)
177 fprintf (stderr, "\n");
178 else
179 fprintf (stderr, ", ");
180 counter = (counter + 1) % 9;
181 #endif
182 lm9830_write_register (s->fd, i, s->regs[i]);
183 s->regs[i] |= 0x100; /* register is updated */
184 }
185 return 0;
186 }
187
188 /*
189 * HP4200-dependent register initialization.
190 */
191
192 static int
hp4200_init_registers(HP4200_Scanner * s)193 hp4200_init_registers (HP4200_Scanner * s)
194 {
195 /* set up hardware parameters */
196
197 s->hw_parms.crystal_frequency = 48000000;
198 s->hw_parms.SRAM_size = 128; /* Kb */
199 s->hw_parms.scan_area_width = 5100; /* pixels */
200 s->hw_parms.scan_area_length = 11; /* inches */
201 s->hw_parms.min_pixel_data_buffer_limit = 1024; /* bytes */
202 s->hw_parms.sensor_line_separation = 4; /* lines */
203 s->hw_parms.sensor_max_integration_time = 12; /* milliseconds */
204 s->hw_parms.home_sensor = 2;
205 s->hw_parms.sensor_resolution = 1; /* 600 dpi */
206 s->hw_parms.motor_full_steps_per_inch = 300;
207 s->hw_parms.motor_max_speed = 1.4; /* inches/second */
208 s->hw_parms.num_tr_pulses = 1;
209 s->hw_parms.guard_band_duration = 1;
210 s->hw_parms.pulse_duration = 3;
211 s->hw_parms.fsteps_25_speed = 3;
212 s->hw_parms.fsteps_50_speed = 3;
213 s->hw_parms.target_value.red = 1000;
214 s->hw_parms.target_value.green = 1000;
215 s->hw_parms.target_value.blue = 1000;
216
217 {
218 int i;
219
220 /*
221 * we are using a cache-like data structure so registers whose
222 * values were written to the lm9830 and aren't volatile, have
223 * bit 0x100 activated. This bit must be cleared if you want the
224 * value to be written to the chip once cache_write() is called.
225 */
226
227 /* clears the registers cache */
228 memset (s->regs, 0, sizeof (s->regs));
229
230 /*
231 * registers 0x00 - 0x07 are non-cacheable/volatile, so don't
232 * read the values using the cache. Instead use direct functions
233 * to read/write registers.
234 */
235
236 for (i = 0; i < 0x08; i++)
237 s->regs[i] = 0x100;
238 }
239
240 setreg (s, 0x70, 0x70); /* noise filter */
241
242 setreg (s, 0x0b,
243 INPUT_SIGNAL_POLARITY_NEGATIVE |
244 CDS_ON |
245 SENSOR_STANDARD |
246 SENSOR_RESOLUTION_600 | LINE_SKIPPING_COLOR_PHASE_DELAY (0));
247
248 setreg (s, 0x0c,
249 PHI1_POLARITY_POSITIVE |
250 PHI2_POLARITY_POSITIVE |
251 RS_POLARITY_POSITIVE |
252 CP1_POLARITY_POSITIVE |
253 CP2_POLARITY_POSITIVE |
254 TR1_POLARITY_NEGATIVE | TR2_POLARITY_NEGATIVE);
255
256 setreg (s, 0x0d,
257 PHI1_ACTIVE |
258 PHI2_ACTIVE |
259 RS_ACTIVE |
260 CP1_ACTIVE |
261 CP2_OFF |
262 TR1_ACTIVE |
263 TR2_OFF | NUMBER_OF_TR_PULSES (s->hw_parms.num_tr_pulses));
264
265 setreg (s, 0x0e,
266 TR_PULSE_DURATION (s->hw_parms.pulse_duration) |
267 TR_PHI1_GUARDBAND_DURATION (s->hw_parms.guard_band_duration));
268
269 /* for pixel rate timing */
270 setreg (s, 0x0f, 6);
271 setreg (s, 0x10, 23);
272 setreg (s, 0x11, 1);
273 setreg (s, 0x12, 3);
274 setreg (s, 0x13, 3); /* 0 */
275 setreg (s, 0x14, 5); /* 0 */
276 setreg (s, 0x15, 0);
277 setreg (s, 0x16, 0);
278 setreg (s, 0x17, 11);
279 setreg (s, 0x18, 2); /* 1 */
280
281 setreg (s, 0x19, CIS_TR1_TIMING_OFF | FAKE_OPTICAL_BLACK_PIXELS_OFF);
282
283 setreg (s, 0x1a, 0);
284 setreg (s, 0x1b, 0);
285
286 setreg (s, 0x1c, 0x0d);
287 setreg (s, 0x1d, 0x21);
288
289 setreg (s, 0x27, TR_RED_DROP (0) | TR_GREEN_DROP (0) | TR_BLUE_DROP (0));
290
291 setreg (s, 0x28, 0x00);
292
293 setreg (s, 0x29, ILLUMINATION_MODE (1));
294 setreg (s, 0x2a, HIBYTE (0)); /* 0 */
295 setreg (s, 0x2b, LOBYTE (0)); /* 0 */
296
297 setreg (s, 0x2c, HIBYTE (16383));
298 setreg (s, 0x2d, LOBYTE (16383));
299
300 setreg (s, 0x2e, HIBYTE (2)); /* 2 */
301 setreg (s, 0x2f, LOBYTE (2)); /* 1 */
302
303 setreg (s, 0x30, HIBYTE (0));
304 setreg (s, 0x31, LOBYTE (0));
305
306 setreg (s, 0x32, HIBYTE (0));
307 setreg (s, 0x33, LOBYTE (0));
308
309 setreg (s, 0x34, HIBYTE (32));
310 setreg (s, 0x35, LOBYTE (32));
311
312 setreg (s, 0x36, HIBYTE (48));
313 setreg (s, 0x37, LOBYTE (48));
314
315 setreg (s, 0x42, EPP_MODE | PPORT_DRIVE_CURRENT (3));
316
317 setreg (s, 0x43,
318 RAM_SIZE_128 |
319 SRAM_DRIVER_CURRENT (3) | SRAM_BANDWIDTH_8 | SCANNING_FULL_DUPLEX);
320
321 setreg (s, 0x45,
322 MICRO_STEPPING |
323 CURRENT_SENSING_PHASES (2) |
324 PHASE_A_POLARITY_POSITIVE |
325 PHASE_B_POLARITY_POSITIVE | STEPPER_MOTOR_OUTPUT);
326
327 setreg (s, 0x4a, HIBYTE (100));
328 setreg (s, 0x4b, LOBYTE (100));
329
330 setreg (s, 0x4c, HIBYTE (0));
331 setreg (s, 0x4d, LOBYTE (0));
332
333 /* resume scan threshold */
334 setreg (s, 0x4f, 64);
335 /* steps to reverse */
336 setreg (s, 0x50, 40);
337 setreg (s, 0x51,
338 ACCELERATION_PROFILE_STOPPED (3) |
339 ACCELERATION_PROFILE_25P (s->hw_parms.fsteps_25_speed) |
340 ACCELERATION_PROFILE_50P (s->hw_parms.fsteps_50_speed));
341 setreg (s, 0x54, NON_REVERSING_EXTRA_LINES (0) | FIRST_LINE_TO_PROCESS (0));
342 setreg (s, 0x55, KICKSTART_STEPS (0) | HOLD_CURRENT_TIMEOUT (2));
343
344 /* stepper PWM frequency */
345 setreg (s, 0x56, 8);
346 /* stepper pwm duty cycle */
347 setreg (s, 0x57, 23);
348
349 setreg (s, 0x58,
350 PAPER_SENSOR_1_POLARITY_HIGH |
351 PAPER_SENSOR_1_TRIGGER_EDGE |
352 PAPER_SENSOR_1_NO_STOP_SCAN |
353 PAPER_SENSOR_2_POLARITY_HIGH |
354 PAPER_SENSOR_2_TRIGGER_EDGE | PAPER_SENSOR_2_STOP_SCAN);
355 setreg (s, 0x59,
356 MISCIO_1_TYPE_OUTPUT |
357 MISCIO_1_POLARITY_HIGH |
358 MISCIO_1_TRIGGER_EDGE |
359 MISCIO_1_OUTPUT_STATE_HIGH |
360 MISCIO_2_TYPE_OUTPUT |
361 MISCIO_2_POLARITY_HIGH |
362 MISCIO_2_TRIGGER_EDGE | MISCIO_2_OUTPUT_STATE_HIGH);
363
364 return 0;
365 }
366
367 #ifdef DEBUG
368 static int
dump_register_cache(HP4200_Scanner * s)369 dump_register_cache (HP4200_Scanner * s)
370 {
371 int i;
372
373 for (i = 0; i < 0x80; i++)
374 {
375 fprintf (stderr, "%.2x:0x%.2x", i, s->regs[i]);
376 if ((i + 1) % 8)
377 fprintf (stderr, ", ");
378 else
379 fprintf (stderr, "\n");
380 }
381 fputs ("", stderr);
382 return 0;
383 }
384 #endif
385
386 /*
387 * returns the scanner head to home position
388 */
389
390 static int
hp4200_goto_home(HP4200_Scanner * s)391 hp4200_goto_home (HP4200_Scanner * s)
392 {
393 unsigned char cmd_reg;
394 unsigned char status_reg;
395 unsigned char old_paper_sensor_reg;
396
397 cmd_reg = getreg (s, 0x07);
398 if (cmd_reg != 2)
399 {
400 unsigned char paper_sensor_reg;
401 unsigned char sensor_bit[2] = { 0x02, 0x10 };
402 /* sensor head is not returning */
403
404 /* let's see if it's already at home */
405 /* first put paper (head) sensor level sensitive */
406 paper_sensor_reg = getreg (s, 0x58);
407 old_paper_sensor_reg = paper_sensor_reg;
408 paper_sensor_reg &= ~sensor_bit[s->hw_parms.home_sensor - 1];
409 setreg (s, 0x58, paper_sensor_reg);
410 cache_write (s);
411
412 /* if the scan head is not at home then move motor backwards */
413 status_reg = getreg (s, 0x02);
414 setreg (s, 0x58, old_paper_sensor_reg);
415 cache_write (s);
416 if (!(status_reg & s->hw_parms.home_sensor))
417 {
418 setreg (s, 0x07, 0x08);
419 usleep (10 * 1000);
420 setreg (s, 0x07, 0x00);
421 usleep (10 * 1000);
422 setreg (s, 0x07, 0x02);
423 }
424 }
425 return 0;
426 }
427
428 #define HP4200_CHECK_INTERVAL 1000 /* usecs between status checks */
429 static int
hp4200_wait_homed(HP4200_Scanner * s)430 hp4200_wait_homed (HP4200_Scanner * s)
431 {
432 unsigned char cmd_reg;
433
434 cmd_reg = getreg (s, 0x07);
435 while (cmd_reg != 0)
436 {
437 usleep (HP4200_CHECK_INTERVAL);
438 cmd_reg = getreg (s, 0x07);
439 }
440 return 0;
441 }
442
443 static int
compute_fastfeed_step_size(unsigned long crystal_freq,int mclk,float max_speed,int steps_per_inch,int color_mode)444 compute_fastfeed_step_size (unsigned long crystal_freq, int mclk,
445 float max_speed, int steps_per_inch,
446 int color_mode)
447 {
448 int aux;
449 int r;
450
451 if (color_mode == 0)
452 r = 24;
453 else
454 r = 8;
455
456 aux = floor (crystal_freq / ((double) mclk * max_speed * 4.0 *
457 steps_per_inch * r));
458
459
460 if (aux < 2)
461 aux = 2;
462 return aux;
463 }
464
465 static SANE_Status
read_available_data(HP4200_Scanner * s,SANE_Byte * buffer,size_t * byte_count)466 read_available_data (HP4200_Scanner * s, SANE_Byte * buffer,
467 size_t * byte_count)
468 {
469 SANE_Status status;
470 unsigned char scankb1;
471 unsigned char scankb2;
472 size_t to_read;
473 size_t really_read;
474 size_t chunk;
475
476 assert (buffer != NULL);
477
478 *byte_count = 0;
479 do
480 {
481 scankb1 = getreg (s, 0x01);
482 scankb2 = getreg (s, 0x01);
483 if (s->aborted_by_user)
484 return SANE_STATUS_CANCELLED;
485 }
486 while ((scankb1 != scankb2) || (scankb1 < 12));
487
488 to_read = scankb1 * 1024;
489
490 while (to_read)
491 {
492 if (s->aborted_by_user)
493 return SANE_STATUS_CANCELLED;
494 chunk = (to_read > 0xffff) ? 0xffff : to_read;
495
496 sanei_pv8630_write_byte (s->fd, PV8630_REPPADDRESS, 0x00);
497 sanei_pv8630_prep_bulkread (s->fd, chunk);
498 really_read = chunk;
499 if ((status = sanei_usb_read_bulk (s->fd, buffer, &really_read)) !=
500 SANE_STATUS_GOOD)
501 {
502 DBG (DBG_error, "sanei_usb_read_bulk failed (%s)\n",
503 sane_strstatus (status));
504 return status;
505 }
506 if (really_read > to_read)
507 {
508 DBG (DBG_error, "USB stack read more bytes than requested!\n");
509 return SANE_STATUS_IO_ERROR;
510 }
511 *byte_count += really_read;
512 buffer += really_read;
513 to_read -= really_read;
514 #ifdef DEBUG
515 fprintf (stderr, "read %zu bytes\n", really_read);
516 #endif
517 }
518 return SANE_STATUS_GOOD;
519 }
520
521 #ifdef unused
522 static int
compute_datalink_bandwidth(HP4200_Scanner * s)523 compute_datalink_bandwidth (HP4200_Scanner * s)
524 {
525 int line_size;
526 int pause_limit;
527 unsigned int color_mode;
528
529 /*
530 * Line size for 8 bpp, the entire scan area width (plus the
531 * status byte) at optical resolution.
532 */
533
534 if (s->user_parms.color)
535 {
536 line_size = 3 * s->hw_parms.scan_area_width + 1;
537 color_mode = 0;
538 setreg (s, 0x26, color_mode); /* 3 channel pixel rate color */
539 }
540 else
541 {
542 line_size = s->hw_parms.scan_area_width + 1;
543 color_mode = 4;
544 setreg (s, 0x26, 0x08 | color_mode); /* 1 channel mode A (green) */
545 }
546 setreg (s, 0x09, (3 << 3)); /* h-divider = 1, 8 bpp */
547
548 {
549 int first_white_pixel;
550 unsigned int line_end;
551
552 first_white_pixel = s->hw_parms.sensor_pixel_end - 10;
553 line_end = first_white_pixel + s->hw_parms.scan_area_width;
554 if (line_end > (s->hw_parms.sensor_num_pixels - 20))
555 line_end = s->hw_parms.sensor_num_pixels - 20;
556
557 setreg (s, 0x1c, HIBYTE (s->hw_parms.sensor_pixel_start));
558 setreg (s, 0x1d, LOBYTE (s->hw_parms.sensor_pixel_end));
559 setreg (s, 0x1e, HIBYTE (first_white_pixel));
560 setreg (s, 0x1f, LOBYTE (first_white_pixel));
561 setreg (s, 0x20, HIBYTE (s->hw_parms.sensor_num_pixels));
562 setreg (s, 0x21, LOBYTE (s->hw_parms.sensor_num_pixels));
563 setreg (s, 0x22, getreg (s, 0x1e));
564 setreg (s, 0x23, getreg (s, 0x1f));
565 setreg (s, 0x24, HIBYTE (line_end));
566 setreg (s, 0x25, LOBYTE (line_end));
567 }
568
569 /*
570 * During transfer rate calculation don't forward scanner sensor.
571 * Stay in the calibration region.
572 */
573
574 setreg (s, 0x4f, 0);
575 clearbits (s, 0x45, 0x10);
576
577 /*
578 * Pause the scan when memory is full.
579 */
580
581 pause_limit = s->hw_parms.SRAM_size - (line_size / 1024) - 1;
582 setreg (s, 0x4e, pause_limit & 0xff);
583
584 s->mclk = compute_min_mclk (s->hw_parms.SRAM_bandwidth,
585 s->hw_parms.crystal_frequency);
586
587
588 /*
589 * Set step size to fast speed.
590 */
591
592 {
593 int step_size;
594
595 step_size =
596 compute_fastfeed_step_size (s->hw_parms.crystal_frequency,
597 s->mclk,
598 s->hw_parms.scan_bar_max_speed,
599 s->hw_parms.motor_full_steps_per_inch,
600 color_mode);
601
602 setreg (s, 0x46, HIBYTE (step_size));
603 setreg (s, 0x47, LOBYTE (step_size));
604 setreg (s, 0x48, HIBYTE (step_size));
605 setreg (s, 0x49, LOBYTE (step_size));
606 }
607
608 cache_write (s);
609
610 /* dump_register_cache (s); */
611
612 /*
613 * scan during 1 sec. aprox.
614 */
615
616 setreg (s, 0x07, 0x08);
617 setreg (s, 0x07, 0x03);
618
619 {
620 struct timeval tv_before;
621 struct timeval tv_after;
622 int elapsed_time_ms = 0;
623 long bytes_read_total;
624 SANE_Byte *buffer;
625
626 buffer = malloc (2 * 98304); /* check this */
627 if (!buffer)
628 {
629 DBG (DBG_error, "compute_datalink_bandwidth: malloc failed\n");
630 return 0;
631 }
632 bytes_read_total = 0;
633 gettimeofday (&tv_before, NULL);
634 do
635 {
636 size_t bytes_read;
637 SANE_Status status;
638
639 status = read_available_data (s, buffer, &bytes_read);
640 if (status != SANE_STATUS_GOOD)
641 {
642 DBG (DBG_error, "read_available_data failed (%s)\n",
643 sane_strstatus (status));
644 return 0;
645 }
646 bytes_read_total += bytes_read;
647 gettimeofday (&tv_after, NULL);
648 elapsed_time_ms = (tv_after.tv_sec - tv_before.tv_sec) * 1000;
649 elapsed_time_ms += (tv_after.tv_usec - tv_before.tv_usec) / 1000;
650 }
651 while (elapsed_time_ms < 1000);
652
653 setreg (s, 0x07, 0x00);
654 free (buffer);
655
656 s->msrd_parms.datalink_bandwidth = bytes_read_total /
657 (elapsed_time_ms / 1000);
658
659 #ifdef DEBUG
660 fprintf (stderr, "PC Transfer rate = %d bytes/sec. (%ld/%d)\n",
661 s->msrd_parms.datalink_bandwidth, bytes_read_total,
662 elapsed_time_ms);
663 #endif
664 }
665 return 0;
666 }
667 #endif
668
669 static void
compute_first_gain_offset(int target,int max,int min,int * gain,int * offset,int * max_gain,int * min_offset)670 compute_first_gain_offset (int target, int max, int min, int *gain,
671 int *offset, int *max_gain, int *min_offset)
672 {
673 *gain = (int) 15.0 *(target / (max - min) - 0.933);
674 *offset = (int) (-1.0 * min / (512.0 * 0.0195));
675 if (*gain >= 32)
676 {
677 *gain = (int) 15.0 *(target / 3.0 / (max - min) - 0.933);
678 *offset = (int) -3.0 * min / (512.0 * 0.0195);
679 }
680 if (*gain < 0)
681 *gain = 0;
682 else if (*gain > 63)
683 *gain = 63;
684
685 if (*offset < -31)
686 *offset = -31;
687 else if (*offset > 31)
688 *offset = 31;
689
690 *max_gain = 63;
691 *min_offset = -31;
692 }
693
694 #define DATA_PORT_READ (1 << 5)
695 #define DATA_PORT_WRITE 0
696
697 static int
write_gamma(HP4200_Scanner * s)698 write_gamma (HP4200_Scanner * s)
699 {
700 int color;
701 int i;
702 unsigned char gamma[1024];
703 unsigned char read_gamma[1024];
704 int retval;
705 size_t to_read;
706 size_t to_write;
707
708 for (color = 0; color < 3; color++)
709 {
710 for (i = 0; i < 1024; i++)
711 gamma[i] = s->user_parms.gamma[color][i];
712
713 setreg (s, 0x03, color << 1);
714 setreg (s, 0x04, DATA_PORT_WRITE);
715 setreg (s, 0x05, 0x00);
716 sanei_pv8630_write_byte (s->fd, PV8630_REPPADDRESS, 0x06);
717 sanei_pv8630_prep_bulkwrite (s->fd, sizeof (gamma));
718 to_write = sizeof (gamma);
719 sanei_usb_write_bulk (s->fd, gamma, &to_write);
720
721 /* check if gamma vector was correctly written */
722
723 setreg (s, 0x03, color << 1);
724 setreg (s, 0x04, DATA_PORT_READ);
725 setreg (s, 0x05, 0x00);
726 sanei_pv8630_write_byte (s->fd, PV8630_REPPADDRESS, 0x06);
727 sanei_pv8630_prep_bulkread (s->fd, sizeof (read_gamma));
728 to_read = sizeof (read_gamma);
729 sanei_usb_read_bulk (s->fd, read_gamma, &to_read);
730 retval = memcmp (read_gamma, gamma, sizeof (read_gamma));
731 if (retval != 0)
732 {
733 DBG (DBG_error, "error: color %d has bad gamma table\n", color);
734 }
735 #ifdef DEBUG
736 else
737 fprintf (stderr, "color %d gamma table is good\n", color);
738 #endif
739 }
740
741 return 0;
742 }
743
744 static int
write_default_offset_gain(HP4200_Scanner * s,SANE_Byte * gain_offset,int size,int color)745 write_default_offset_gain (HP4200_Scanner * s, SANE_Byte * gain_offset,
746 int size, int color)
747 {
748 SANE_Byte *check_data;
749 int retval;
750 size_t to_read;
751 size_t to_write;
752
753 setreg (s, 0x03, (color << 1) | 1);
754 setreg (s, 0x04, DATA_PORT_WRITE);
755 setreg (s, 0x05, 0x00);
756 sanei_pv8630_write_byte (s->fd, PV8630_REPPADDRESS, 0x06);
757 sanei_pv8630_prep_bulkwrite (s->fd, size);
758 to_write = size;
759 sanei_usb_write_bulk (s->fd, gain_offset, &to_write);
760
761 check_data = malloc (size);
762 setreg (s, 0x03, (color << 1) | 1);
763 setreg (s, 0x04, DATA_PORT_READ);
764 setreg (s, 0x05, 0x00);
765 sanei_pv8630_write_byte (s->fd, PV8630_REPPADDRESS, 0x06);
766 sanei_pv8630_prep_bulkread (s->fd, size);
767 to_read = size;
768 sanei_usb_read_bulk (s->fd, check_data, &to_read);
769 retval = memcmp (gain_offset, check_data, size);
770 free (check_data);
771 if (retval != 0)
772 {
773 DBG (DBG_error, "error: color %d has bad gain/offset table\n", color);
774 }
775 #ifdef DEBUG
776 else
777 fprintf (stderr, "color %d gain/offset table is good\n", color);
778 #endif
779
780 return 0;
781 }
782
783 static int
compute_gain_offset(int target,int max,int min,int * gain,int * offset,int * max_gain,int * min_offset)784 compute_gain_offset (int target, int max, int min, int *gain,
785 int *offset, int *max_gain, int *min_offset)
786 {
787 int gain_stable;
788 int is_unstable;
789
790 gain_stable = 1; /* unless the opposite is said */
791 is_unstable = 0;
792
793 if (max > target)
794 {
795 if (*gain > 0)
796 {
797 (*gain)--;
798 *max_gain = *gain;
799 gain_stable = 0;
800 is_unstable |= 1;
801 }
802 else
803 {
804 DBG (DBG_error, "error: integration time too long.\n");
805 return -1;
806 }
807 }
808 else
809 {
810 if (*gain < *max_gain)
811 {
812 (*gain)++;
813 gain_stable = 0;
814 is_unstable |= 1;
815 }
816 }
817
818 if (min == 0)
819 {
820 if (*offset < 31)
821 {
822 (*offset)++;
823 if (gain_stable)
824 *min_offset = *offset;
825 is_unstable |= 1;
826 }
827 else
828 {
829 DBG (DBG_error, "error: max static has pixel value == 0\n");
830 return -1;
831 }
832 }
833 else
834 {
835 if (*offset > *min_offset)
836 {
837 (*offset)--;
838 is_unstable |= 1;
839 }
840 }
841 return is_unstable;
842 }
843
844 static int
compute_bytes_per_line(int width_in_pixels,unsigned char hdpi_code,unsigned char pixel_packing,unsigned char data_mode,unsigned char AFE_operation,int m)845 compute_bytes_per_line (int width_in_pixels, unsigned char hdpi_code,
846 unsigned char pixel_packing,
847 unsigned char data_mode,
848 unsigned char AFE_operation, int m)
849 {
850 const int dpi_qot_mul[] = { 1, 2, 1, 1, 1, 1, 1, 1 };
851 const int dpi_qot_div[] = { 1, 3, 2, 3, 4, 6, 8, 12 };
852 int pixels_per_line;
853 int bytes_per_line;
854 int pixels_per_byte;
855 int status_bytes;
856 const int pixels_per_byte_mapping[] = { 8, 4, 2, 1 };
857
858 assert (hdpi_code <= 7);
859 pixels_per_line = (width_in_pixels * dpi_qot_mul[hdpi_code]) /
860 dpi_qot_div[hdpi_code];
861 if ((width_in_pixels * dpi_qot_mul[hdpi_code]) % dpi_qot_div[hdpi_code])
862 pixels_per_line++;
863
864
865 status_bytes = (m == 0) ? 1 : m;
866
867 if (data_mode == 1)
868 pixels_per_byte = 1; /* should be 0.5 but later
869 bytes_per_line will be multiplied
870 by 2, and also the number of status
871 bytes, that in this case should be
872 2.
873 umm.. maybe this should be done in
874 the cleaner way.
875 */
876 else
877 {
878 assert (pixel_packing <= 3);
879 pixels_per_byte = pixels_per_byte_mapping[pixel_packing];
880 }
881
882 switch (AFE_operation)
883 {
884 case PIXEL_RATE_3_CHANNELS:
885 bytes_per_line = ((pixels_per_line * 3) / pixels_per_byte) +
886 status_bytes;
887 break;
888 case MODEA_1_CHANNEL:
889 bytes_per_line = (pixels_per_line / pixels_per_byte) + status_bytes;
890 break;
891 default:
892 /* Not implemented! (yet?) and not used.
893 * This case should not happen. */
894 assert (0);
895 }
896
897 if (data_mode == 1) /* see big note above */
898 bytes_per_line *= 2;
899
900 return bytes_per_line;
901 }
902
903 static int
compute_pause_limit(hardware_parameters_t * hw_parms,int bytes_per_line)904 compute_pause_limit (hardware_parameters_t * hw_parms, int bytes_per_line)
905 {
906 int coef_size;
907 const int coef_mapping[] = { 16, 32 };
908 int pause_limit;
909
910 coef_size = coef_mapping[hw_parms->sensor_resolution & 0x01];
911 pause_limit = hw_parms->SRAM_size - coef_size - (bytes_per_line / 1024) - 1;
912
913 if (pause_limit > 2)
914 pause_limit -= 2;
915
916 return pause_limit;
917 }
918
919 static int
compute_dpd(HP4200_Scanner * s,int step_size,int line_end)920 compute_dpd (HP4200_Scanner * s, int step_size, int line_end)
921 {
922 int tr, dpd;
923
924 tr = 1 /* color mode */ *
925 (line_end + ((s->hw_parms.num_tr_pulses + 1) *
926 (2 * s->hw_parms.guard_band_duration +
927 s->hw_parms.pulse_duration + 1) +
928 3 - s->hw_parms.num_tr_pulses));
929
930 if (tr == 0)
931 return 0;
932
933 dpd = (((s->hw_parms.fsteps_25_speed * 4) +
934 (s->hw_parms.fsteps_50_speed * 2) +
935 s->hw_parms.steps_to_reverse) * 4 * step_size) % tr;
936 dpd = tr - dpd;
937
938 return dpd;
939 }
940
941 static SANE_Status
read_required_bytes(HP4200_Scanner * s,int required,SANE_Byte * buffer)942 read_required_bytes (HP4200_Scanner * s, int required, SANE_Byte * buffer)
943 {
944 unsigned char scankb1;
945 unsigned char scankb2;
946 size_t to_read;
947 size_t really_read;
948 size_t chunk;
949 SANE_Status status;
950
951 assert (buffer != NULL);
952
953 while (required)
954 {
955 do
956 {
957 scankb1 = getreg (s, 0x01);
958 scankb2 = getreg (s, 0x01);
959 if (s->aborted_by_user)
960 return SANE_STATUS_CANCELLED;
961 }
962 while ((scankb1 != scankb2) || (scankb1 < 12));
963
964 to_read = min (required, (scankb1 * 1024));
965 while (to_read)
966 {
967 if (s->aborted_by_user)
968 return SANE_STATUS_CANCELLED;
969 chunk = (to_read > 0xffff) ? 0xffff : to_read;
970
971 sanei_pv8630_write_byte (s->fd, PV8630_REPPADDRESS, 0x00);
972 sanei_pv8630_prep_bulkread (s->fd, chunk);
973 really_read = chunk;
974 if ((status = sanei_usb_read_bulk (s->fd, buffer, &really_read)) !=
975 SANE_STATUS_GOOD)
976 {
977 DBG (DBG_error, "sanei_usb_read_bulk failed (%s)\n",
978 sane_strstatus (status));
979 return status;
980 }
981 if (really_read > chunk)
982 {
983 DBG (DBG_error, "USB stack read more bytes than requested!\n");
984 return SANE_STATUS_IO_ERROR;
985 }
986 buffer += really_read;
987 required -= really_read;
988 to_read -= really_read;
989 }
990 }
991
992 return SANE_STATUS_GOOD;
993 }
994
995 static SANE_Status
scanner_buffer_init(scanner_buffer_t * sb,int size_in_kb)996 scanner_buffer_init (scanner_buffer_t * sb, int size_in_kb)
997 {
998
999 sb->size = size_in_kb * 1024 + 3;
1000 sb->buffer = malloc (sb->size);
1001 if (!sb->buffer)
1002 return SANE_STATUS_NO_MEM;
1003 sb->num_bytes = 0;
1004 sb->data_ptr = sb->buffer;
1005
1006 return SANE_STATUS_GOOD;
1007 }
1008
1009 static SANE_Status
scanner_buffer_read(HP4200_Scanner * s)1010 scanner_buffer_read (HP4200_Scanner * s)
1011 {
1012 SANE_Status status;
1013 size_t num_bytes_read_now;
1014
1015 assert (s->scanner_buffer.num_bytes <= 3);
1016
1017 memcpy (s->scanner_buffer.buffer, s->scanner_buffer.data_ptr, 3);
1018
1019 status = read_available_data (s, s->scanner_buffer.buffer +
1020 s->scanner_buffer.num_bytes,
1021 &num_bytes_read_now);
1022 s->scanner_buffer.data_ptr = s->scanner_buffer.buffer;
1023 s->scanner_buffer.num_bytes += num_bytes_read_now;
1024 return status;
1025 }
1026
1027 #define OFFSET_CODE_SIGN(off) (((off) < 0) ? (-(off) & 0x1f) | 0x20 : (off))
1028 #define OFFSET_DECODE_SIGN(off) (((off) & 0x20) ? -(off & 0x1f) : (off))
1029
1030 static SANE_Status
do_coarse_calibration(HP4200_Scanner * s,struct coarse_t * coarse)1031 do_coarse_calibration (HP4200_Scanner * s, struct coarse_t *coarse)
1032 {
1033 SANE_Status status;
1034 unsigned char *cal_line = NULL;
1035 unsigned char *cal_line_ptr;
1036 int cal_line_size;
1037 /* local scanning params */
1038 int active_pixels_start;
1039 int line_end;
1040 int data_pixels_start;
1041 int data_pixels_end;
1042 int dpd;
1043 int step_size;
1044 int ff_step_size;
1045 char steps_to_reverse;
1046 char line_rate_color;
1047 int vdpi; /* vertical dots per inch */
1048 int hdpi_code;
1049 int calibrated;
1050 int first_time;
1051
1052 int red_offset = 0;
1053 int green_offset = 0;
1054 int blue_offset = 0;
1055
1056 int red_gain = 1;
1057 int green_gain = 1;
1058 int blue_gain = 1;
1059
1060 int min_red_offset = -31;
1061 int min_green_offset = -31;
1062 int min_blue_offset = -31;
1063
1064 int max_red_gain = 63;
1065 int max_green_gain = 63;
1066 int max_blue_gain = 63;
1067
1068 int max_red;
1069 int min_red;
1070 int max_green;
1071 int min_green;
1072 int max_blue;
1073 int min_blue;
1074 static char me[] = "do_coarse_calibration";
1075
1076 DBG (DBG_proc, "%s\n", me);
1077
1078 setreg (s, 0x07, 0x00);
1079 usleep (10 * 1000);
1080
1081 vdpi = 150;
1082 hdpi_code = 0;
1083 active_pixels_start = 0x40;
1084 line_end = 0x2ee0;
1085 s->mclk_div = 2;
1086 data_pixels_start = 0x40;
1087 data_pixels_end = (int) (data_pixels_start + s->hw_parms.scan_area_width);
1088 data_pixels_end = min (data_pixels_end, line_end - 20);
1089
1090 cal_line_size = s->hw_parms.scan_area_width * 3 * 2 + 2;
1091
1092 setreg (s, 0x1e, HIBYTE (active_pixels_start));
1093 setreg (s, 0x1f, LOBYTE (active_pixels_start));
1094 setreg (s, 0x20, HIBYTE (line_end));
1095 setreg (s, 0x21, LOBYTE (line_end));
1096 setreg (s, 0x22, HIBYTE (data_pixels_start));
1097 setreg (s, 0x23, LOBYTE (data_pixels_start));
1098 setreg (s, 0x24, HIBYTE (data_pixels_end));
1099 setreg (s, 0x25, LOBYTE (data_pixels_end));
1100
1101 setreg (s, 0x26,
1102 PIXEL_RATE_3_CHANNELS |
1103 GRAY_CHANNEL_RED | TR_RED (0) | TR_GREEN (0) | TR_BLUE (0));
1104
1105
1106 setreg (s, 0x08, (s->mclk_div - 1) * 2);
1107 setreg (s, 0x09, hdpi_code | PIXEL_PACKING (3) | DATAMODE (1));
1108 setreg (s, 0x0a, 0); /* reserved and strange register */
1109
1110 setreg (s, 0x38, red_offset);
1111 setreg (s, 0x39, green_offset);
1112 setreg (s, 0x3a, blue_offset);
1113 setreg (s, 0x3b, red_gain);
1114 setreg (s, 0x3c, green_gain);
1115 setreg (s, 0x3d, blue_gain);
1116
1117 setreg (s, 0x5e, 0x80);
1118
1119 setreg (s, 0x3e, 0x00); /* 1.5:1, 6/10 bits, 2*fixed */
1120 setreg (s, 0x3f, 0x00);
1121 setreg (s, 0x40, 0x00);
1122 setreg (s, 0x41, 0x00);
1123
1124 setreg (s, 0x4e, 0x5b - 0x3c); /* max Kb to pause */
1125 setreg (s, 0x4f, 0x02); /* min Kb to resume */
1126
1127 line_rate_color = 1;
1128 step_size = (vdpi * line_end * line_rate_color) /
1129 (4 * s->hw_parms.motor_full_steps_per_inch);
1130
1131 dpd = compute_dpd (s, step_size, line_end); /* 0x0ada; */
1132 #ifdef DEBUG
1133 fprintf (stderr, "dpd = %d\n", dpd);
1134 #endif
1135 setreg (s, 0x52, HIBYTE (dpd));
1136 setreg (s, 0x53, LOBYTE (dpd));
1137
1138 setreg (s, 0x46, HIBYTE (step_size));
1139 setreg (s, 0x47, LOBYTE (step_size));
1140
1141 ff_step_size = compute_fastfeed_step_size (s->hw_parms.crystal_frequency, s->mclk_div, s->hw_parms.motor_max_speed, s->hw_parms.motor_full_steps_per_inch, 0); /* 0x0190; */
1142 setreg (s, 0x48, HIBYTE (ff_step_size));
1143 setreg (s, 0x49, LOBYTE (ff_step_size));
1144 setreg (s, 0x4b, 0x15);
1145 steps_to_reverse = 0x3f;
1146 setreg (s, 0x50, steps_to_reverse);
1147 setreg (s, 0x51, 0x15); /* accel profile */
1148
1149 /* this is to stay the motor stopped */
1150 clearbits (s, 0x45, (1 << 4));
1151
1152 cache_write (s);
1153
1154 calibrated = 0;
1155 first_time = 1;
1156 cal_line = malloc (cal_line_size + 1024);
1157
1158 do
1159 {
1160 unsigned char cmd_reg;
1161
1162 /* resets the lm9830 before start scanning */
1163 setreg (s, 0x07, 0x08);
1164 do
1165 {
1166 setreg (s, 0x07, 0x03);
1167 cmd_reg = getreg (s, 0x07);
1168 }
1169 while (cmd_reg != 0x03);
1170
1171 cal_line_ptr = cal_line;
1172 status = read_required_bytes (s, cal_line_size, cal_line_ptr);
1173 if (status != SANE_STATUS_GOOD)
1174 goto done;
1175
1176 setreg (s, 0x07, 0x00);
1177 {
1178 unsigned int i;
1179 min_red = max_red = (cal_line[0] * 256 + cal_line[1]) >> 2;
1180 min_green = max_green = (cal_line[2] * 256 + cal_line[3]) >> 2;
1181 min_blue = max_blue = (cal_line[4] * 256 + cal_line[5]) >> 2;
1182 for (i = 6; i < (s->hw_parms.scan_area_width * 3 * 2); i += 6)
1183 {
1184 int value;
1185
1186 value = cal_line[i] * 256 + cal_line[i + 1];
1187 value >>= 2;
1188 if (value > max_red)
1189 max_red = value;
1190 value = cal_line[i + 2] * 256 + cal_line[i + 3];
1191 value >>= 2;
1192 if (value > max_green)
1193 max_green = value;
1194 value = cal_line[i + 4] * 256 + cal_line[i + 5];
1195 value >>= 2;
1196 if (value > max_blue)
1197 max_blue = value;
1198 value = cal_line[i] * 256 + cal_line[i + 1];
1199 value >>= 2;
1200 if (value < min_red)
1201 min_red = value;
1202 value = cal_line[i + 2] * 256 + cal_line[i + 3];
1203 value >>= 2;
1204 if (value < min_green)
1205 min_green = value;
1206 value = cal_line[i + 4] * 256 + cal_line[i + 5];
1207 value >>= 2;
1208 if (value < min_blue)
1209 min_blue = value;
1210 }
1211 #ifdef DEBUG
1212 fprintf (stderr, "max_red:%d max_green:%d max_blue:%d\n",
1213 max_red, max_green, max_blue);
1214 fprintf (stderr, "min_red:%d min_green:%d min_blue:%d\n",
1215 min_red, min_green, min_blue);
1216 #endif
1217
1218 if (first_time)
1219 {
1220 first_time = 0;
1221 compute_first_gain_offset (s->hw_parms.target_value.red,
1222 max_red, min_red,
1223 &red_gain, &red_offset,
1224 &max_red_gain, &min_red_offset);
1225 compute_first_gain_offset (s->hw_parms.target_value.green,
1226 max_green, min_green,
1227 &green_gain, &green_offset,
1228 &max_green_gain, &min_green_offset);
1229 compute_first_gain_offset (s->hw_parms.target_value.blue,
1230 max_blue, min_blue, &blue_gain,
1231 &blue_offset, &max_blue_gain,
1232 &min_blue_offset);
1233 }
1234 else
1235 {
1236 int retval;
1237
1238 /* this code should check return value -1 for error */
1239
1240 retval = compute_gain_offset (s->hw_parms.target_value.red,
1241 max_red, min_red,
1242 &red_gain, &red_offset,
1243 &max_red_gain, &min_red_offset);
1244 if (retval < 0)
1245 break;
1246 retval |= compute_gain_offset (s->hw_parms.target_value.green,
1247 max_green, min_green,
1248 &green_gain, &green_offset,
1249 &max_green_gain,
1250 &min_green_offset);
1251 if (retval < 0)
1252 break;
1253 retval |= compute_gain_offset (s->hw_parms.target_value.blue,
1254 max_blue, min_blue,
1255 &blue_gain, &blue_offset,
1256 &max_blue_gain, &min_blue_offset);
1257 if (retval < 0)
1258 break;
1259 calibrated = !retval;
1260 }
1261
1262 setreg (s, 0x3b, red_gain);
1263 setreg (s, 0x3c, green_gain);
1264 setreg (s, 0x3d, blue_gain);
1265
1266 setreg (s, 0x38, OFFSET_CODE_SIGN (red_offset));
1267 setreg (s, 0x39, OFFSET_CODE_SIGN (green_offset));
1268 setreg (s, 0x3a, OFFSET_CODE_SIGN (blue_offset));
1269
1270 #ifdef DEBUG
1271 fprintf (stderr, "%d, %d, %d %d, %d, %d\n", red_gain,
1272 green_gain, blue_gain, red_offset, green_offset,
1273 blue_offset);
1274 #endif
1275 cache_write (s);
1276 }
1277 }
1278 while (!calibrated);
1279 coarse->min_red = min_red;
1280 coarse->min_green = min_green;
1281 coarse->min_blue = min_blue;
1282 coarse->max_red = max_red;
1283 coarse->max_green = max_green;
1284 coarse->max_blue = max_blue;
1285 coarse->red_gain = red_gain;
1286 coarse->green_gain = green_gain;
1287 coarse->blue_gain = blue_gain;
1288 coarse->red_offset = red_offset;
1289 coarse->green_offset = green_offset;
1290 coarse->blue_offset = blue_offset;
1291
1292 status = SANE_STATUS_GOOD;
1293
1294 done:
1295 if (cal_line)
1296 free (cal_line);
1297
1298 return status;
1299 }
1300
1301 static int
compute_corr_code(int average,int min_color,int range,int target)1302 compute_corr_code (int average, int min_color, int range, int target)
1303 {
1304 int value;
1305 int corr_code;
1306
1307 value = average - min_color;
1308 if (value > 0)
1309 corr_code =
1310 (int) (range * ((double) target / (double) value - 1.0) + 0.5);
1311 else
1312 corr_code = 0;
1313 if (corr_code < 0)
1314 corr_code = 0;
1315 else if (corr_code > 2048)
1316 corr_code = 0;
1317 else if (corr_code > 1023)
1318 corr_code = 1023;
1319 return corr_code;
1320 }
1321
1322 static int
compute_hdpi_code(int hres)1323 compute_hdpi_code (int hres)
1324 {
1325 int hdpi_code;
1326
1327 /* Calculate the horizontal DPI code based on the requested
1328 horizontal resolution. Defaults to 150dpi. */
1329 switch (hres)
1330 {
1331 case 600:
1332 hdpi_code = 0;
1333 break;
1334 case 400:
1335 hdpi_code = 1;
1336 break;
1337 case 300:
1338 hdpi_code = 2;
1339 break;
1340 case 200:
1341 hdpi_code = 3;
1342 break;
1343 case 150:
1344 hdpi_code = 4;
1345 break;
1346 case 100:
1347 hdpi_code = 5;
1348 break;
1349 case 75:
1350 hdpi_code = 6;
1351 break;
1352 case 50:
1353 hdpi_code = 7;
1354 break;
1355 default:
1356 hdpi_code = 4;
1357 }
1358 return hdpi_code;
1359 }
1360
1361
1362 static SANE_Status
do_fine_calibration(HP4200_Scanner * s,struct coarse_t * coarse)1363 do_fine_calibration (HP4200_Scanner * s, struct coarse_t *coarse)
1364 {
1365 SANE_Status status;
1366 unsigned char *cal_line;
1367 unsigned char *cal_line_ptr;
1368 int *average;
1369 SANE_Byte red_gain_offset[5460 * 2];
1370 SANE_Byte green_gain_offset[5460 * 2];
1371 SANE_Byte blue_gain_offset[5460 * 2];
1372 int *corr_red = NULL;
1373 int *corr_green = NULL;
1374 int *corr_blue = NULL;
1375 int registro[30][5460 * 3];
1376 int cal_line_size;
1377 /* local scanning params */
1378 int active_pixels_start;
1379 int line_end;
1380 int line_length;
1381 int data_pixels_start;
1382 int data_pixels_end;
1383 int dpd;
1384 int step_size;
1385 int ff_step_size;
1386 char steps_to_reverse;
1387 char hdpi_div;
1388 char line_rate_color;
1389 int vdpi; /* vertical dots per inch */
1390 int hdpi_code;
1391 int calibrated;
1392 int lines_to_process;
1393
1394 static char me[] = "do_fine_calibration";
1395
1396 DBG (DBG_proc, "%s\n", me);
1397
1398 setreg (s, 0x07, 0x00);
1399 usleep (10 * 1000);
1400
1401 vdpi = 150;
1402 hdpi_code = compute_hdpi_code (s->user_parms.horizontal_resolution);
1403
1404 /* figure out which horizontal divider to use based on the
1405 calculated horizontal dpi code */
1406 hdpi_div = hdpi_mapping[hdpi_code];
1407 active_pixels_start = 0x40;
1408 line_end = 0x2ee0;
1409 line_length = s->user_parms.image_width * hdpi_div;
1410 s->mclk_div = 2;
1411 data_pixels_start = 0x72 + s->runtime_parms.first_pixel * hdpi_div;
1412 data_pixels_end =
1413 (int) (data_pixels_start + s->user_parms.image_width * hdpi_div);
1414 data_pixels_end = min (data_pixels_end, line_end - 20);
1415
1416 cal_line_size = line_length * 3 * 2 + 2;
1417
1418 setreg (s, 0x1e, HIBYTE (active_pixels_start));
1419 setreg (s, 0x1f, LOBYTE (active_pixels_start));
1420 setreg (s, 0x20, HIBYTE (line_end));
1421 setreg (s, 0x21, LOBYTE (line_end));
1422 setreg (s, 0x22, HIBYTE (data_pixels_start));
1423 setreg (s, 0x23, LOBYTE (data_pixels_start));
1424 setreg (s, 0x24, HIBYTE (data_pixels_end));
1425 setreg (s, 0x25, LOBYTE (data_pixels_end));
1426
1427 setreg (s, 0x26,
1428 PIXEL_RATE_3_CHANNELS |
1429 GRAY_CHANNEL_RED | TR_RED (0) | TR_GREEN (0) | TR_BLUE (0));
1430
1431
1432 setreg (s, 0x08, (s->mclk_div - 1) * 2);
1433 setreg (s, 0x09, 0 | PIXEL_PACKING (3) | DATAMODE (1));
1434 setreg (s, 0x0a, 0); /* reserved and strange register */
1435
1436 setreg (s, 0x38, 1);
1437 setreg (s, 0x39, 1);
1438 setreg (s, 0x3a, 1);
1439 setreg (s, 0x3b, coarse->red_gain);
1440 setreg (s, 0x3c, coarse->green_gain);
1441 setreg (s, 0x3d, coarse->blue_gain);
1442
1443 setreg (s, 0x5e, 0x80);
1444
1445 setreg (s, 0x3e, 0x00); /* 1.5:1, 6/10 bits, 2*fixed */
1446 setreg (s, 0x3f, 0x00);
1447 setreg (s, 0x40, 0x00);
1448 setreg (s, 0x41, 0x00);
1449
1450 setreg (s, 0x4e, 0x5b - 0x3c); /* max Kb to pause */
1451 setreg (s, 0x4f, 0x02); /* min Kb to resume */
1452
1453 line_rate_color = 1;
1454 step_size = (vdpi * line_end * line_rate_color) /
1455 (4 * s->hw_parms.motor_full_steps_per_inch);
1456
1457 dpd = compute_dpd (s, step_size, line_end); /* 0x0ada; */
1458 #ifdef DEBUG
1459 fprintf (stderr, "dpd = %d\n", dpd);
1460 #endif
1461 setreg (s, 0x52, HIBYTE (dpd));
1462 setreg (s, 0x53, LOBYTE (dpd));
1463
1464 setreg (s, 0x46, HIBYTE (step_size));
1465 setreg (s, 0x47, LOBYTE (step_size));
1466
1467 ff_step_size = compute_fastfeed_step_size (s->hw_parms.crystal_frequency, s->mclk_div, s->hw_parms.motor_max_speed, s->hw_parms.motor_full_steps_per_inch, 0); /* 0x0190; */
1468 setreg (s, 0x48, HIBYTE (ff_step_size));
1469 setreg (s, 0x49, LOBYTE (ff_step_size));
1470 setreg (s, 0x4b, 0x15);
1471 steps_to_reverse = 0x3f;
1472 setreg (s, 0x50, steps_to_reverse);
1473 setreg (s, 0x51, 0x15); /* accel profile */
1474
1475 /* this is to activate the motor */
1476 setbits (s, 0x45, (1 << 4));
1477
1478 lines_to_process = 8 * step_size * 4 / line_end;
1479 if (lines_to_process < 1)
1480 lines_to_process = 1;
1481
1482 #ifdef DEBUG
1483 fprintf (stderr, "lines to process = %d\n", lines_to_process);
1484 #endif
1485
1486 setreg (s, 0x58, 0);
1487
1488 cache_write (s);
1489
1490 calibrated = 0;
1491 cal_line = malloc (cal_line_size + 1024);
1492 average = malloc (sizeof (int) * line_length * 3);
1493 memset (average, 0, sizeof (int) * line_length * 3);
1494 {
1495 int i;
1496 for (i = 0; i < 12; i++)
1497 {
1498 memset (registro[i], 0, 5460 * 3 * sizeof(int));
1499 }
1500 }
1501
1502 /* resets the lm9830 before start scanning */
1503 setreg (s, 0x07, 0x08);
1504 setreg (s, 0x07, 0x03);
1505
1506 usleep (100);
1507
1508 do
1509 {
1510
1511 cal_line_ptr = cal_line;
1512
1513 status = read_required_bytes (s, cal_line_size, cal_line_ptr);
1514 if (status != SANE_STATUS_GOOD)
1515 goto done;
1516 {
1517 int i, j;
1518
1519 if (calibrated == 0)
1520 for (j = 0, i = 0; i < (line_length * 3); i++, j += 2)
1521 {
1522 average[i] = (cal_line[j] * 256 + cal_line[j + 1]) >> 2;
1523 registro[calibrated][i] = average[i];
1524 }
1525 else
1526 for (j = 0, i = 0; i < (line_length * 3); i++, j += 2)
1527 {
1528 int value;
1529 value = (cal_line[j] * 256 + cal_line[j + 1]) >> 2;
1530 average[i] += value;
1531 average[i] /= 2;
1532 registro[calibrated][i] = value;
1533 }
1534 }
1535 calibrated++;
1536 }
1537 while (calibrated < lines_to_process);
1538 lm9830_write_register (s->fd, 0x07, 0x00);
1539 usleep (10 * 1000);
1540
1541 #if 0
1542 {
1543 int i;
1544 int j = 0;
1545 do
1546 {
1547 for (i = 3; (i + 6) < (line_length * 3); i += 3)
1548 {
1549 average[i] =
1550 (2 * average[i - 3] + average[i] + 2 * average[i + 3]) / 5;
1551 average[i + 1] =
1552 (2 * average[i - 2] + average[i + 1] + 2 * average[i + 4]) / 5;
1553 average[i + 2] =
1554 (2 * average[i - 1] + average[i + 2] + 2 * average[i + 5]) / 5;
1555 }
1556 j++;
1557 }
1558 while (j < 3);
1559 }
1560 #endif
1561 {
1562 int i;
1563 int max_red;
1564 int min_red;
1565 int max_green;
1566 int min_green;
1567 int max_blue;
1568 int min_blue;
1569 min_red = max_red = average[0];
1570 min_green = max_green = average[1];
1571 min_blue = max_blue = average[2];
1572 for (i = 3; i < (line_length * 3); i += 3)
1573 {
1574 int value;
1575
1576 value = average[i];
1577 if (value > max_red)
1578 max_red = value;
1579 value = average[i + 1];
1580 if (value > max_green)
1581 max_green = value;
1582 value = average[i + 2];
1583 if (value > max_blue)
1584 max_blue = value;
1585 value = average[i];
1586 if (value < min_red)
1587 min_red = value;
1588 value = average[i + 1];
1589 if (value < min_green)
1590 min_green = value;
1591 value = average[i + 2];
1592 if (value < min_blue)
1593 min_blue = value;
1594 }
1595 #ifdef DEBUG
1596 fprintf (stderr, "max_red:%d max_green:%d max_blue:%d\n",
1597 max_red, max_green, max_blue);
1598 fprintf (stderr, "min_red:%d min_green:%d min_blue:%d\n",
1599 min_red, min_green, min_blue);
1600 #endif
1601
1602 /* do fine calibration */
1603 {
1604 int min_white_red;
1605 int min_white_green;
1606 int min_white_blue;
1607 double ratio;
1608 int range;
1609 double aux;
1610 int min_white_err;
1611 int j;
1612
1613 min_white_red = min_white_green = min_white_blue = 0x3ff;
1614 for (i = 0; i < (line_length * 3); i += 3)
1615 {
1616 int value;
1617
1618 value = average[i] - coarse->min_red;
1619 if ((value > 0) && (value < min_white_red))
1620 min_white_red = value;
1621 value = average[i + 1] - coarse->min_green;
1622 if ((value > 0) && (value < min_white_green))
1623 min_white_green = value;
1624 value = average[i + 2] - coarse->min_blue;
1625 if ((value > 0) && (value < min_white_blue))
1626 min_white_blue = value;
1627 }
1628
1629 ratio = 0;
1630 min_white_err = 0x3ff;
1631
1632 aux = (double) s->hw_parms.target_value.red / min_white_red;
1633 if (aux > ratio)
1634 ratio = aux;
1635 if (min_white_err > min_white_red)
1636 min_white_err = min_white_red;
1637 aux = (double) s->hw_parms.target_value.green / min_white_green;
1638 if (aux > ratio)
1639 ratio = aux;
1640 if (min_white_err > min_white_green)
1641 min_white_err = min_white_green;
1642 aux = (double) s->hw_parms.target_value.blue / min_white_blue;
1643 if (aux > ratio)
1644 ratio = aux;
1645 if (min_white_err > min_white_blue)
1646 min_white_err = min_white_blue;
1647
1648 #ifdef DEBUG
1649 fprintf (stderr, "min_white_err = %d, ratio = %f\n",
1650 min_white_err, ratio);
1651 #endif
1652 if (ratio <= 1.5)
1653 range = 2048;
1654 else if (ratio <= 2.0)
1655 range = 1024;
1656 else
1657 range = 512;
1658
1659 corr_red = malloc (sizeof (int) * line_length);
1660 corr_green = malloc (sizeof (int) * line_length);
1661 corr_blue = malloc (sizeof (int) * line_length);
1662
1663 for (i = 0, j = 0; i < (line_length * 3); i += 3, j++)
1664 {
1665 corr_red[j] = compute_corr_code (average[i],
1666 coarse->min_red,
1667 range,
1668 s->hw_parms.target_value.red);
1669 corr_green[j] =
1670 compute_corr_code (average[i + 1], coarse->min_green,
1671 range, s->hw_parms.target_value.green);
1672 corr_blue[j] =
1673 compute_corr_code (average[i + 2], coarse->min_blue,
1674 range, s->hw_parms.target_value.blue);
1675 }
1676 #ifdef DEBUG
1677 {
1678 FILE *kaka;
1679 int i;
1680 kaka = fopen ("corr.raw", "w");
1681 for (i = 0; i < line_length; i++)
1682 {
1683 fprintf (kaka, "%d %d %d %d %d %d ",
1684 corr_red[i], corr_green[i], corr_blue[i],
1685 average[3 * i], average[3 * i + 1], average[3 * i + 2]);
1686 fprintf (kaka, "%d %d %d %d %d %d %d %d %d ",
1687 registro[0][3 * i], registro[0][3 * i + 1],
1688 registro[0][3 * i + 2], registro[1][3 * i],
1689 registro[1][3 * i + 1], registro[1][3 * i + 2],
1690 registro[2][3 * i], registro[2][3 * i + 1],
1691 registro[2][3 * i + 2]);
1692 fprintf (kaka, "%d %d %d %d %d %d %d %d %d\n",
1693 registro[3][3 * i], registro[3][3 * i + 1],
1694 registro[3][3 * i + 2], registro[4][3 * i],
1695 registro[4][3 * i + 1], registro[4][3 * i + 2],
1696 registro[5][3 * i], registro[5][3 * i + 1],
1697 registro[5][3 * i + 2]);
1698 }
1699 fclose (kaka);
1700 }
1701 #endif
1702 {
1703 int max_black;
1704 int use_six_eight_bits;
1705
1706 max_black = max (coarse->min_red, coarse->min_green);
1707 max_black = max (max_black, coarse->min_blue);
1708 use_six_eight_bits = (max_black < 64);
1709
1710 if (use_six_eight_bits)
1711 {
1712 setreg (s, 0x3e, (1 << 4) | (1 << 3) | (1024 / range));
1713 }
1714 else
1715 {
1716 setreg (s, 0x3e, (1 << 4) | (1 << 3) | (1 << 2) | (1024 / range));
1717 }
1718 memset (red_gain_offset, 0, sizeof (red_gain_offset));
1719 memset (green_gain_offset, 0, sizeof (green_gain_offset));
1720 memset (blue_gain_offset, 0, sizeof (blue_gain_offset));
1721 for (i = 0, j = (data_pixels_start - active_pixels_start) * 2;
1722 i < line_length; i++, j += 2)
1723 {
1724 if (use_six_eight_bits)
1725 {
1726 red_gain_offset[j] = (coarse->min_red << 2) |
1727 ((corr_red[i] >> 8) & 0x03);
1728 red_gain_offset[j + 1] = corr_red[i] & 0xff;
1729 green_gain_offset[j] = (coarse->min_green << 2) |
1730 ((corr_green[i] >> 8) & 0x03);
1731 green_gain_offset[j + 1] = corr_green[i] & 0xff;
1732 blue_gain_offset[j] = (coarse->min_blue << 2) |
1733 ((corr_blue[i] >> 8) & 0x03);
1734 blue_gain_offset[j + 1] = corr_blue[i] & 0xff;
1735 }
1736 else
1737 {
1738 red_gain_offset[j] = coarse->min_red;
1739 red_gain_offset[j + 1] = corr_red[j] >> 2;
1740 green_gain_offset[j] = coarse->min_green;
1741 green_gain_offset[j + 1] = corr_green[j] >> 2;
1742 blue_gain_offset[j] = coarse->min_blue;
1743 blue_gain_offset[j + 1] = corr_blue[j] >> 2;
1744 }
1745 }
1746 write_default_offset_gain (s, red_gain_offset, 5460 * 2, 0);
1747 write_default_offset_gain (s, green_gain_offset, 5460 * 2, 1);
1748 write_default_offset_gain (s, blue_gain_offset, 5460 * 2, 2);
1749 }
1750 }
1751 }
1752
1753 status = SANE_STATUS_GOOD;
1754
1755 done:
1756 if (corr_red)
1757 free (corr_red);
1758 if (corr_green)
1759 free (corr_green);
1760 if (corr_blue)
1761 free (corr_blue);
1762 if (cal_line)
1763 free (cal_line);
1764 if (average)
1765 free (average);
1766
1767 return status;
1768 }
1769
1770 static void
ciclic_buffer_init_offset_correction(ciclic_buffer_t * cb,int vres)1771 ciclic_buffer_init_offset_correction (ciclic_buffer_t * cb, int vres)
1772 {
1773 cb->blue_idx = 0;
1774 switch (vres)
1775 {
1776 case 600:
1777 cb->green_idx = 4;
1778 cb->red_idx = 8;
1779 cb->first_good_line = 8;
1780 break;
1781 case 400:
1782 cb->green_idx = 3;
1783 cb->red_idx = 6;
1784 cb->first_good_line = 6;
1785 break;
1786 case 300:
1787 cb->green_idx = 2;
1788 cb->red_idx = 4;
1789 cb->first_good_line = 4;
1790 break;
1791 case 200:
1792 cb->blue_idx = 0;
1793 cb->green_idx = 1;
1794 cb->red_idx = 2;
1795 cb->first_good_line = 4;
1796 break;
1797 case 150:
1798 cb->green_idx = 1;
1799 cb->red_idx = 2;
1800 cb->first_good_line = 2;
1801 break;
1802 case 75:
1803 cb->green_idx = 1;
1804 cb->red_idx = 2;
1805 cb->first_good_line = 2;
1806 break;
1807 default:
1808 cb->green_idx = 0;
1809 cb->red_idx = 0;
1810 cb->first_good_line = 0;
1811 break;
1812 }
1813
1814 cb->buffer_position = cb->buffer_ptrs[cb->first_good_line];
1815 }
1816
1817 static SANE_Status
ciclic_buffer_init(ciclic_buffer_t * cb,SANE_Int bytes_per_line,int vres,int status_bytes)1818 ciclic_buffer_init (ciclic_buffer_t * cb, SANE_Int bytes_per_line,
1819 int vres, int status_bytes)
1820 {
1821 cb->good_bytes = 0;
1822 cb->num_lines = 12;
1823 cb->size = bytes_per_line * cb->num_lines;
1824 cb->can_consume = cb->size + cb->num_lines * status_bytes;
1825
1826 cb->buffer = malloc (cb->size);
1827 if (!cb->buffer)
1828 return SANE_STATUS_NO_MEM;
1829
1830 {
1831 int i;
1832 unsigned char *buffer;
1833 unsigned char **ptrs;
1834
1835 ptrs = cb->buffer_ptrs = (unsigned char **)
1836 malloc (sizeof (unsigned char *) * cb->num_lines);
1837 if (!cb->buffer_ptrs)
1838 return SANE_STATUS_NO_MEM;
1839
1840 buffer = cb->buffer;
1841 for (i = 0; i < cb->num_lines; i++)
1842 {
1843 ptrs[i] = buffer;
1844 buffer += bytes_per_line;
1845 }
1846 }
1847
1848 cb->current_line = 0;
1849 cb->pixel_position = 0;
1850 ciclic_buffer_init_offset_correction (cb, vres);
1851
1852 return SANE_STATUS_GOOD;
1853 }
1854
1855 static int
prepare_for_a_scan(HP4200_Scanner * s)1856 prepare_for_a_scan (HP4200_Scanner * s)
1857 {
1858 /* local scanning params */
1859 int active_pixels_start;
1860 int line_end;
1861 int data_pixels_start;
1862 int data_pixels_end;
1863 int ff_step_size;
1864 int dpd;
1865 int step_size;
1866 char steps_to_reverse;
1867 char hdpi_div;
1868 char line_rate_color;
1869 int hdpi_code;
1870 unsigned char pixel_packing;
1871 unsigned char data_mode;
1872 unsigned char AFE_operation;
1873 int pause_limit;
1874 int n = 0, m = 0;
1875
1876 setreg (s, 0x07, 0x00);
1877 usleep (10 * 1000);
1878
1879 hdpi_code = compute_hdpi_code (s->user_parms.horizontal_resolution);
1880 /* figure out which horizontal divider to use based on the
1881 calculated horizontal dpi code */
1882 hdpi_div = hdpi_mapping[hdpi_code];
1883
1884 /* image_width is set to the correct number of pixels by calling
1885 fxn. This might be the reason we can't do high res full width
1886 scans though...not sure. */
1887 /*s->user_parms.image_width /= 4; */
1888 active_pixels_start = 0x40;
1889 line_end = 0x2ee0; /* 2ee0 */
1890 s->mclk_div = 2;
1891 data_pixels_start = 0x72 + s->runtime_parms.first_pixel * hdpi_div;
1892 data_pixels_end =
1893 (int) (data_pixels_start + s->user_parms.image_width * hdpi_div);
1894 data_pixels_end = min (data_pixels_end, line_end - 20);
1895 setreg (s, 0x1e, HIBYTE (active_pixels_start));
1896 setreg (s, 0x1f, LOBYTE (active_pixels_start));
1897 setreg (s, 0x20, HIBYTE (line_end));
1898 setreg (s, 0x21, LOBYTE (line_end));
1899 setreg (s, 0x22, HIBYTE (data_pixels_start));
1900 setreg (s, 0x23, LOBYTE (data_pixels_start));
1901 setreg (s, 0x24, HIBYTE (data_pixels_end));
1902 setreg (s, 0x25, LOBYTE (data_pixels_end));
1903
1904 AFE_operation = PIXEL_RATE_3_CHANNELS;
1905 setreg (s, 0x26,
1906 AFE_operation |
1907 GRAY_CHANNEL_RED | TR_RED (0) | TR_GREEN (0) | TR_BLUE (0));
1908
1909 setreg (s, 0x08, (s->mclk_div - 1) * 2);
1910 pixel_packing = 3;
1911 data_mode = 0;
1912 setreg (s, 0x09, hdpi_code | PIXEL_PACKING (pixel_packing) |
1913 DATAMODE (data_mode));
1914 setreg (s, 0x0a, 0); /* reserved and strange register */
1915
1916 setreg (s, 0x5c, 0x00);
1917 setreg (s, 0x5d, 0x00);
1918 setreg (s, 0x5e, 0x00);
1919
1920 if (s->user_parms.vertical_resolution == 1200)
1921 {
1922 /* 1 out of 2 */
1923 n = 1;
1924 m = 2;
1925 }
1926 setreg (s, 0x44, (256 - n) & 0xff);
1927 setreg (s, 0x5a, m);
1928 s->runtime_parms.status_bytes = (m == 0) ? 1 : m;
1929 if (data_mode == 1)
1930 s->runtime_parms.status_bytes *= 2;
1931
1932 s->runtime_parms.scanner_line_size =
1933 compute_bytes_per_line (data_pixels_end - data_pixels_start,
1934 hdpi_code, pixel_packing, data_mode,
1935 AFE_operation, m);
1936 pause_limit = compute_pause_limit (&(s->hw_parms),
1937 s->runtime_parms.scanner_line_size);
1938
1939 #ifdef DEBUG
1940 fprintf (stderr, "scanner_line_size = %d\npause_limit = %d\n",
1941 s->runtime_parms.scanner_line_size, pause_limit);
1942 #endif
1943
1944 setreg (s, 0x4e, pause_limit); /* max Kb to pause */
1945 setreg (s, 0x4f, 0x02); /* min Kb to resume */
1946
1947 line_rate_color = 1;
1948 step_size =
1949 (s->user_parms.vertical_resolution * line_end * line_rate_color) /
1950 (4 * s->hw_parms.motor_full_steps_per_inch);
1951
1952 if (s->val[OPT_BACKTRACK].b)
1953 {
1954 steps_to_reverse = 0x3f;
1955 setreg (s, 0x50, steps_to_reverse);
1956 setreg (s, 0x51, 0x15); /* accel profile */
1957 }
1958 else
1959 {
1960 s->hw_parms.steps_to_reverse = 0;
1961 setreg (s, 0x50, s->hw_parms.steps_to_reverse);
1962 setreg (s, 0x51, 0); /* accel profile */
1963 s->hw_parms.fsteps_25_speed = 0;
1964 s->hw_parms.fsteps_50_speed = 0;
1965 }
1966
1967 dpd = compute_dpd (s, step_size, line_end); /* 0x0ada; */
1968 #ifdef DEBUG
1969 fprintf (stderr, "dpd = %d\n", dpd);
1970 #endif
1971 setreg (s, 0x52, HIBYTE (dpd));
1972 setreg (s, 0x53, LOBYTE (dpd));
1973
1974 setreg (s, 0x46, HIBYTE (step_size));
1975 setreg (s, 0x47, LOBYTE (step_size));
1976
1977 ff_step_size = compute_fastfeed_step_size (s->hw_parms.crystal_frequency,
1978 s->mclk_div,
1979 s->hw_parms.motor_max_speed,
1980 s->hw_parms.
1981 motor_full_steps_per_inch, 0);
1982 setreg (s, 0x48, HIBYTE (ff_step_size));
1983 setreg (s, 0x49, LOBYTE (ff_step_size));
1984 setreg (s, 0x4b, 0x15);
1985 /* this is to stay the motor running */
1986 setbits (s, 0x45, (1 << 4));
1987
1988 setreg (s, 0x4a, HIBYTE (47 + s->runtime_parms.steps_to_skip));
1989 setreg (s, 0x4b, LOBYTE (47 + s->runtime_parms.steps_to_skip));
1990
1991 setreg (s, 0x58, 0);
1992
1993 ciclic_buffer_init (&(s->ciclic_buffer),
1994 s->runtime_parms.image_line_size,
1995 s->user_parms.vertical_resolution,
1996 s->runtime_parms.status_bytes);
1997
1998 s->runtime_parms.num_bytes_left_to_scan =
1999 s->user_parms.lines_to_scan * s->runtime_parms.image_line_size;
2000
2001 #ifdef DEBUG
2002 fprintf (stderr, "bytes to scan = %ld\n",
2003 s->runtime_parms.num_bytes_left_to_scan);
2004 #endif
2005
2006 cache_write (s);
2007
2008 #ifdef DEBUG
2009 lm9830_dump_registers (s->fd);
2010 #endif
2011
2012 lm9830_reset (s->fd);
2013
2014 setreg (s, 0x07, 0x03);
2015 usleep (100);
2016
2017 return SANE_STATUS_GOOD;
2018 }
2019
2020 static SANE_Status
end_scan(HP4200_Scanner * s)2021 end_scan (HP4200_Scanner * s)
2022 {
2023 s->scanning = SANE_FALSE;
2024 setreg (s, 0x07, 0x00);
2025 lm9830_reset (s->fd);
2026 setbits (s, 0x58, PAPER_SENSOR_2_STOP_SCAN);
2027 cache_write (s);
2028 setreg (s, 0x07, 0x02);
2029
2030 /* Free some buffers */
2031 if (s->ciclic_buffer.buffer)
2032 {
2033 free (s->ciclic_buffer.buffer);
2034 s->ciclic_buffer.buffer = NULL;
2035 }
2036 if (s->ciclic_buffer.buffer_ptrs)
2037 {
2038 free (s->ciclic_buffer.buffer_ptrs);
2039 s->ciclic_buffer.buffer_ptrs = NULL;
2040 }
2041 if (s->scanner_buffer.buffer)
2042 {
2043 free (s->scanner_buffer.buffer);
2044 s->scanner_buffer.buffer = NULL;
2045 }
2046
2047 return SANE_STATUS_GOOD;
2048 }
2049
2050 static int
hp4200_init_scanner(HP4200_Scanner * s)2051 hp4200_init_scanner (HP4200_Scanner * s)
2052 {
2053 int ff_step_size;
2054 int mclk_div;
2055
2056 lm9830_ini_scanner (s->fd, NULL);
2057 hp4200_init_registers (s);
2058 scanner_buffer_init (&(s->scanner_buffer), s->hw_parms.SRAM_size);
2059 setreg (s, 0x07, 0x08);
2060 usleep (10 * 1000);
2061 setreg (s, 0x07, 0x00);
2062 usleep (10 * 1000);
2063 mclk_div = 2;
2064
2065 setreg (s, 0x08, (mclk_div - 1) * 2);
2066 ff_step_size =
2067 compute_fastfeed_step_size (s->hw_parms.crystal_frequency,
2068 mclk_div,
2069 s->hw_parms.motor_max_speed,
2070 s->hw_parms.motor_full_steps_per_inch, 0);
2071 setreg (s, 0x48, HIBYTE (ff_step_size));
2072 setreg (s, 0x49, LOBYTE (ff_step_size));
2073 setbits (s, 0x45, (1 << 4));
2074 cache_write (s);
2075 return 0;
2076 }
2077
2078 static void
ciclic_buffer_copy(ciclic_buffer_t * cb,SANE_Byte * buf,SANE_Int num_bytes,int image_line_size,int status_bytes)2079 ciclic_buffer_copy (ciclic_buffer_t * cb, SANE_Byte * buf,
2080 SANE_Int num_bytes, int image_line_size, int status_bytes)
2081 {
2082 int biggest_upper_block_size;
2083 int upper_block_size;
2084 int lower_block_size;
2085 int bytes_to_be_a_entire_line;
2086
2087 /* copy the upper block */
2088 biggest_upper_block_size = cb->size - (cb->buffer_position - cb->buffer);
2089 upper_block_size = min (biggest_upper_block_size, num_bytes);
2090 memcpy (buf, cb->buffer_position, upper_block_size);
2091 cb->good_bytes -= upper_block_size;
2092
2093 bytes_to_be_a_entire_line = (cb->buffer_position - cb->buffer) %
2094 image_line_size;
2095 cb->can_consume += upper_block_size +
2096 status_bytes * (((bytes_to_be_a_entire_line + upper_block_size) /
2097 image_line_size) - 1);
2098
2099 if (num_bytes < biggest_upper_block_size)
2100 {
2101 cb->buffer_position += num_bytes;
2102 return;
2103 }
2104
2105 /* copy the lower block */
2106 lower_block_size = num_bytes - biggest_upper_block_size;
2107 if (lower_block_size > 0)
2108 {
2109 memcpy (buf + biggest_upper_block_size, cb->buffer, lower_block_size);
2110 cb->good_bytes -= lower_block_size;
2111 cb->can_consume += lower_block_size + status_bytes *
2112 (lower_block_size / image_line_size);
2113 cb->buffer_position = cb->buffer + lower_block_size;
2114 }
2115 else
2116 {
2117 cb->buffer_position = cb->buffer;
2118 }
2119 assert (cb->good_bytes >= 0);
2120 assert (lower_block_size >= 0);
2121 }
2122
2123 static void
ciclic_buffer_consume(ciclic_buffer_t * cb,scanner_buffer_t * scanner_buffer,int image_width,int status_bytes)2124 ciclic_buffer_consume (ciclic_buffer_t * cb,
2125 scanner_buffer_t * scanner_buffer,
2126 int image_width, int status_bytes)
2127 {
2128 int to_consume;
2129 int to_consume_now;
2130 int i;
2131 int processed;
2132
2133 to_consume = min (cb->can_consume, scanner_buffer->num_bytes);
2134
2135 while (to_consume)
2136 {
2137
2138 if (cb->pixel_position == image_width)
2139 {
2140 if (scanner_buffer->num_bytes >= status_bytes)
2141 {
2142 /* forget status bytes */
2143 scanner_buffer->data_ptr += status_bytes;
2144 scanner_buffer->num_bytes -= status_bytes;
2145 cb->can_consume -= status_bytes;
2146 to_consume -= status_bytes;
2147
2148 cb->pixel_position = 0; /* back to the start pixel */
2149
2150 cb->red_idx = (cb->red_idx + 1) % cb->num_lines;
2151 cb->green_idx = (cb->green_idx + 1) % cb->num_lines;
2152 cb->blue_idx = (cb->blue_idx + 1) % cb->num_lines;
2153 cb->current_line++;
2154 }
2155 else
2156 break;
2157 }
2158
2159 to_consume_now = min ((image_width - cb->pixel_position) * 3,
2160 to_consume);
2161
2162 if (to_consume_now < 3)
2163 break;
2164
2165 for (i = cb->pixel_position * 3; to_consume_now >= 3;
2166 i += 3, to_consume_now -= 3)
2167 {
2168 cb->buffer_ptrs[cb->red_idx][i] = scanner_buffer->data_ptr[0];
2169 cb->buffer_ptrs[cb->green_idx][i + 1] = scanner_buffer->data_ptr[1];
2170 cb->buffer_ptrs[cb->blue_idx][i + 2] = scanner_buffer->data_ptr[2];
2171 scanner_buffer->data_ptr += 3;
2172 }
2173 processed = i - (cb->pixel_position * 3);
2174 cb->pixel_position = i / 3;
2175 to_consume -= processed;
2176 cb->can_consume -= processed;
2177 scanner_buffer->num_bytes -= processed;
2178 if (cb->current_line > cb->first_good_line)
2179 cb->good_bytes += processed;
2180 }
2181 }
2182
2183 SANE_Status
sane_read(SANE_Handle h,SANE_Byte * buf,SANE_Int maxlen,SANE_Int * len)2184 sane_read (SANE_Handle h, SANE_Byte * buf, SANE_Int maxlen, SANE_Int * len)
2185 {
2186 SANE_Status status;
2187 int to_copy_now;
2188 int bytes_to_copy_to_frontend;
2189 HP4200_Scanner *s = h;
2190
2191 static char me[] = "sane_read";
2192 DBG (DBG_proc, "%s\n", me);
2193
2194 if (!(s->scanning))
2195 {
2196 /* OOPS, not scanning */
2197 return SANE_STATUS_CANCELLED;
2198 }
2199
2200 if (!buf || !len)
2201 return SANE_STATUS_INVAL;
2202
2203 *len = 0;
2204
2205 if (s->runtime_parms.num_bytes_left_to_scan == 0)
2206 {
2207 end_scan (s);
2208 return SANE_STATUS_EOF;
2209 }
2210
2211 bytes_to_copy_to_frontend = min (s->runtime_parms.num_bytes_left_to_scan,
2212 maxlen);
2213
2214 /* first copy available data from the ciclic buffer */
2215 to_copy_now = min (s->ciclic_buffer.good_bytes, bytes_to_copy_to_frontend);
2216
2217 if (to_copy_now > 0)
2218 {
2219 ciclic_buffer_copy (&(s->ciclic_buffer), buf, to_copy_now,
2220 s->runtime_parms.image_line_size,
2221 s->runtime_parms.status_bytes);
2222 buf += to_copy_now;
2223 bytes_to_copy_to_frontend -= to_copy_now;
2224 *len += to_copy_now;
2225 }
2226
2227 /* if not enough bytes, get data from the scanner */
2228 while (bytes_to_copy_to_frontend)
2229 {
2230 if (s->scanner_buffer.num_bytes < 3)
2231 { /* cicl buf consumes modulo 3
2232 bytes at least now for rgb
2233 color 8 bpp fixme: but this
2234 is ugly and not generic
2235 */
2236 status = scanner_buffer_read (s);
2237
2238 if (status == SANE_STATUS_CANCELLED)
2239 {
2240 end_scan (s);
2241 s->aborted_by_user = SANE_FALSE;
2242 return status;
2243 }
2244 if (status != SANE_STATUS_GOOD)
2245 return status;
2246 }
2247
2248 while ((s->scanner_buffer.num_bytes > 3) && bytes_to_copy_to_frontend)
2249 {
2250 ciclic_buffer_consume (&(s->ciclic_buffer), &(s->scanner_buffer),
2251 s->user_parms.image_width,
2252 s->runtime_parms.status_bytes);
2253 to_copy_now = min (s->ciclic_buffer.good_bytes,
2254 bytes_to_copy_to_frontend);
2255
2256 if (to_copy_now > 0)
2257 {
2258 ciclic_buffer_copy (&(s->ciclic_buffer), buf, to_copy_now,
2259 s->runtime_parms.image_line_size,
2260 s->runtime_parms.status_bytes);
2261 buf += to_copy_now;
2262 bytes_to_copy_to_frontend -= to_copy_now;
2263 *len += to_copy_now;
2264 }
2265 }
2266 }
2267
2268 s->runtime_parms.num_bytes_left_to_scan -= *len;
2269
2270 if (s->runtime_parms.num_bytes_left_to_scan < 0)
2271 *len += s->runtime_parms.num_bytes_left_to_scan;
2272
2273 return SANE_STATUS_GOOD;
2274 }
2275
2276 static HP4200_Device *
find_device(SANE_String_Const name)2277 find_device (SANE_String_Const name)
2278 {
2279 static char me[] = "find_device";
2280 HP4200_Device *dev;
2281
2282 DBG (DBG_proc, "%s\n", me);
2283
2284 for (dev = first_device; dev; dev = dev->next)
2285 {
2286 if (strcmp (dev->dev.name, name) == 0)
2287 {
2288 return dev;
2289 }
2290 }
2291 return NULL;
2292 }
2293
2294 static SANE_Status
add_device(SANE_String_Const name,HP4200_Device ** argpd)2295 add_device (SANE_String_Const name, HP4200_Device ** argpd)
2296 {
2297 int fd;
2298 HP4200_Device *pd;
2299 static const char me[] = "add_device";
2300 SANE_Status status;
2301
2302 DBG (DBG_proc, "%s(%s)\n", me, name);
2303
2304 /* Avoid adding the same device more than once */
2305 if ((pd = find_device (name)))
2306 {
2307 if (argpd)
2308 *argpd = pd;
2309 return SANE_STATUS_GOOD;
2310 }
2311
2312 /* open the device file, but read only or read/write to perform
2313 ioctl's ? */
2314 if ((status = sanei_usb_open (name, &fd)) != SANE_STATUS_GOOD)
2315 {
2316 DBG (DBG_error, "%s: open(%s) failed: %s\n", me, name,
2317 sane_strstatus (status));
2318 return SANE_STATUS_INVAL;
2319 }
2320
2321 /* put here some code to probe that the device attached to the
2322 device file is a supported scanner. Maybe some ioctl */
2323 sanei_usb_close (fd);
2324
2325 pd = (HP4200_Device *) calloc (1, sizeof (HP4200_Device));
2326 if (!pd)
2327 {
2328 DBG (DBG_error, "%s: out of memory allocating device.\n", me);
2329 return SANE_STATUS_NO_MEM;
2330 }
2331
2332 pd->dev.name = strdup (name);
2333 pd->dev.vendor = "Hewlett-Packard";
2334 pd->dev.model = "HP-4200";
2335 pd->dev.type = "flatbed scanner";
2336
2337 if (!pd->dev.name || !pd->dev.vendor || !pd->dev.model || !pd->dev.type)
2338 {
2339 DBG (DBG_error,
2340 "%s: out of memory allocating device descriptor strings.\n", me);
2341 free (pd);
2342 return SANE_STATUS_NO_MEM;
2343 }
2344
2345 pd->handle = NULL;
2346 pd->next = first_device;
2347 first_device = pd;
2348 n_devices++;
2349 if (argpd)
2350 *argpd = pd;
2351
2352 return SANE_STATUS_GOOD;
2353 }
2354
2355 static SANE_Status
attach(SANE_String_Const name)2356 attach (SANE_String_Const name)
2357 {
2358 static char me[] = "attach";
2359 DBG (DBG_proc, "%s\n", me);
2360 return add_device (name, NULL);
2361 }
2362
2363 SANE_Status
sane_init(SANE_Int * version_code,SANE_Auth_Callback authorize)2364 sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
2365 {
2366 static const char me[] = "sane_hp4200_init";
2367 char dev_name[PATH_MAX];
2368 FILE *fp;
2369
2370 (void) authorize; /* keep gcc quiet */
2371
2372 DBG_INIT ();
2373
2374 DBG (DBG_proc, "%s\n", me);
2375 DBG (DBG_error, "SANE hp4200 backend version %d.%d build %d from %s\n",
2376 SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, BUILD, PACKAGE_STRING);
2377 /* put some version_code checks here */
2378
2379 if (NULL != version_code)
2380 {
2381 *version_code = SANE_VERSION_CODE (SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, 0);
2382 }
2383
2384 sanei_usb_init ();
2385 sanei_pv8630_init ();
2386
2387 fp = sanei_config_open (HP4200_CONFIG_FILE);
2388 if (!fp)
2389 {
2390 DBG (DBG_error, "%s: configuration file not found!\n", me);
2391
2392 return SANE_STATUS_INVAL;
2393 }
2394 else
2395 {
2396 while (sanei_config_read (dev_name, sizeof (dev_name), fp))
2397 {
2398 if (dev_name[0] == '#') /* ignore line comments */
2399 continue;
2400
2401 if (strlen (dev_name) == 0)
2402 continue; /* ignore empty lines */
2403
2404 DBG (DBG_info, "%s: looking for devices matching %s\n",
2405 me, dev_name);
2406
2407 sanei_usb_attach_matching_devices (dev_name, attach);
2408 }
2409
2410 fclose (fp);
2411 }
2412
2413 return SANE_STATUS_GOOD;
2414 }
2415
2416 void
sane_exit(void)2417 sane_exit (void)
2418 {
2419 HP4200_Device *device, *next;
2420
2421 DBG (DBG_proc, "sane_hp4200_exit\n");
2422
2423 for (device = first_device; device; device = next)
2424 {
2425 next = device->next;
2426 if (device->handle)
2427 {
2428 sane_close (device->handle);
2429 }
2430 if (device->dev.name)
2431 {
2432 free ((void *) device->dev.name);
2433 }
2434 free (device);
2435 }
2436 first_device = NULL;
2437
2438 if (devlist)
2439 {
2440 free (devlist);
2441 devlist = NULL;
2442 }
2443
2444 n_devices = 0;
2445
2446 DBG (DBG_proc, "sane_exit: exit\n");
2447 }
2448
2449 SANE_Status
sane_get_devices(const SANE_Device *** device_list,SANE_Bool local_only)2450 sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
2451 {
2452 int i;
2453 HP4200_Device *pdev;
2454
2455 DBG (DBG_proc, "sane_get_devices (%p, %d)\n", (void *) device_list,
2456 local_only);
2457
2458 /* Waste the last list returned from this function */
2459 if (devlist)
2460 free (devlist);
2461
2462 devlist = (const SANE_Device **)
2463 malloc ((n_devices + 1) * sizeof (SANE_Device *));
2464
2465 if (!devlist)
2466 {
2467 DBG (DBG_error, "sane_get_devices: out of memory\n");
2468 return SANE_STATUS_NO_MEM;
2469 }
2470
2471 for (i = 0, pdev = first_device; pdev; i++, pdev = pdev->next)
2472 {
2473 devlist[i] = &(pdev->dev);
2474 }
2475 devlist[i] = NULL;
2476
2477 *device_list = devlist;
2478
2479 DBG (DBG_proc, "sane_get_devices: exit\n");
2480
2481 return SANE_STATUS_GOOD;
2482 }
2483
2484 static void
init_options(HP4200_Scanner * s)2485 init_options (HP4200_Scanner * s)
2486 {
2487 s->opt[OPT_NUM_OPTS].name = "";
2488 s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
2489 s->opt[OPT_NUM_OPTS].desc = SANE_DESC_NUM_OPTIONS;
2490 s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
2491 s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
2492 s->opt[OPT_NUM_OPTS].unit = SANE_UNIT_NONE;
2493 s->opt[OPT_NUM_OPTS].size = sizeof (SANE_Word);
2494 s->opt[OPT_NUM_OPTS].constraint_type = SANE_CONSTRAINT_NONE;
2495 s->val[OPT_NUM_OPTS].w = NUM_OPTIONS;
2496
2497 s->opt[OPT_RES].name = SANE_NAME_SCAN_RESOLUTION;
2498 s->opt[OPT_RES].title = SANE_TITLE_SCAN_RESOLUTION;
2499 s->opt[OPT_RES].desc = SANE_DESC_SCAN_RESOLUTION;
2500 s->opt[OPT_RES].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2501 s->opt[OPT_RES].type = SANE_TYPE_INT;
2502 s->opt[OPT_RES].size = sizeof (SANE_Word);
2503 s->opt[OPT_RES].unit = SANE_UNIT_DPI;
2504 s->opt[OPT_RES].constraint_type = SANE_CONSTRAINT_WORD_LIST;
2505 s->opt[OPT_RES].constraint.word_list = dpi_list;
2506 s->val[OPT_RES].w = 150;
2507
2508 s->opt[OPT_TL_X].name = SANE_NAME_SCAN_TL_X;
2509 s->opt[OPT_TL_X].title = SANE_TITLE_SCAN_TL_X;
2510 s->opt[OPT_TL_X].desc = SANE_DESC_SCAN_TL_X;
2511 s->opt[OPT_TL_X].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2512 s->opt[OPT_TL_X].type = SANE_TYPE_FIXED;
2513 s->opt[OPT_TL_X].size = sizeof (SANE_Fixed);
2514 s->opt[OPT_TL_X].unit = SANE_UNIT_MM;
2515 s->opt[OPT_TL_X].constraint_type = SANE_CONSTRAINT_RANGE;
2516 s->opt[OPT_TL_X].constraint.range = &x_range;
2517 s->val[OPT_TL_X].w = x_range.min;
2518
2519 s->opt[OPT_TL_Y].name = SANE_NAME_SCAN_TL_Y;
2520 s->opt[OPT_TL_Y].title = SANE_TITLE_SCAN_TL_Y;
2521 s->opt[OPT_TL_Y].desc = SANE_DESC_SCAN_TL_Y;
2522 s->opt[OPT_TL_Y].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2523 s->opt[OPT_TL_Y].type = SANE_TYPE_FIXED;
2524 s->opt[OPT_TL_Y].size = sizeof (SANE_Fixed);
2525 s->opt[OPT_TL_Y].unit = SANE_UNIT_MM;
2526 s->opt[OPT_TL_Y].constraint_type = SANE_CONSTRAINT_RANGE;
2527 s->opt[OPT_TL_Y].constraint.range = &y_range;
2528 s->val[OPT_TL_Y].w = y_range.min;
2529
2530 s->opt[OPT_BR_X].name = SANE_NAME_SCAN_BR_X;
2531 s->opt[OPT_BR_X].title = SANE_TITLE_SCAN_BR_X;
2532 s->opt[OPT_BR_X].desc = SANE_DESC_SCAN_BR_X;
2533 s->opt[OPT_BR_X].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2534 s->opt[OPT_BR_X].type = SANE_TYPE_FIXED;
2535 s->opt[OPT_BR_X].size = sizeof (SANE_Fixed);
2536 s->opt[OPT_BR_X].unit = SANE_UNIT_MM;
2537 s->opt[OPT_BR_X].constraint_type = SANE_CONSTRAINT_RANGE;
2538 s->opt[OPT_BR_X].constraint.range = &x_range;
2539 s->val[OPT_BR_X].w = x_range.max;
2540
2541 s->opt[OPT_BR_Y].name = SANE_NAME_SCAN_BR_Y;
2542 s->opt[OPT_BR_Y].title = SANE_TITLE_SCAN_BR_Y;
2543 s->opt[OPT_BR_Y].desc = SANE_DESC_SCAN_BR_Y;
2544 s->opt[OPT_BR_Y].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2545 s->opt[OPT_BR_Y].type = SANE_TYPE_FIXED;
2546 s->opt[OPT_BR_Y].size = sizeof (SANE_Fixed);
2547 s->opt[OPT_BR_Y].unit = SANE_UNIT_MM;
2548 s->opt[OPT_BR_Y].constraint_type = SANE_CONSTRAINT_RANGE;
2549 s->opt[OPT_BR_Y].constraint.range = &y_range;
2550 s->val[OPT_BR_Y].w = y_range.max;
2551
2552 s->opt[OPT_BACKTRACK].name = SANE_NAME_BACKTRACK;
2553 s->opt[OPT_BACKTRACK].title = SANE_TITLE_BACKTRACK;
2554 s->opt[OPT_BACKTRACK].desc = SANE_DESC_BACKTRACK;
2555 s->opt[OPT_BACKTRACK].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2556 s->opt[OPT_BACKTRACK].type = SANE_TYPE_BOOL;
2557 s->opt[OPT_BACKTRACK].size = sizeof (SANE_Bool);
2558 s->opt[OPT_BACKTRACK].unit = SANE_UNIT_NONE;
2559 s->opt[OPT_BACKTRACK].constraint_type = SANE_CONSTRAINT_NONE;
2560 s->val[OPT_BACKTRACK].b = SANE_TRUE;
2561
2562 s->opt[OPT_GAMMA_VECTOR_R].name = SANE_NAME_GAMMA_VECTOR_R;
2563 s->opt[OPT_GAMMA_VECTOR_R].title = SANE_TITLE_GAMMA_VECTOR_R;
2564 s->opt[OPT_GAMMA_VECTOR_R].desc = SANE_DESC_GAMMA_VECTOR_R;
2565 s->opt[OPT_GAMMA_VECTOR_R].cap =
2566 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2567 s->opt[OPT_GAMMA_VECTOR_R].type = SANE_TYPE_INT;
2568 s->opt[OPT_GAMMA_VECTOR_R].size = 1024 * sizeof (SANE_Word);
2569 s->opt[OPT_GAMMA_VECTOR_R].unit = SANE_UNIT_NONE;
2570 s->opt[OPT_GAMMA_VECTOR_R].constraint_type = SANE_CONSTRAINT_RANGE;
2571 s->opt[OPT_GAMMA_VECTOR_R].constraint.range = &u8_range;
2572 s->val[OPT_GAMMA_VECTOR_R].wa = s->user_parms.gamma[0];
2573
2574 s->opt[OPT_GAMMA_VECTOR_G].name = SANE_NAME_GAMMA_VECTOR_G;
2575 s->opt[OPT_GAMMA_VECTOR_G].title = SANE_TITLE_GAMMA_VECTOR_G;
2576 s->opt[OPT_GAMMA_VECTOR_G].desc = SANE_DESC_GAMMA_VECTOR_G;
2577 s->opt[OPT_GAMMA_VECTOR_G].cap =
2578 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2579 s->opt[OPT_GAMMA_VECTOR_G].type = SANE_TYPE_INT;
2580 s->opt[OPT_GAMMA_VECTOR_G].size = 1024 * sizeof (SANE_Word);
2581 s->opt[OPT_GAMMA_VECTOR_G].unit = SANE_UNIT_NONE;
2582 s->opt[OPT_GAMMA_VECTOR_G].constraint_type = SANE_CONSTRAINT_RANGE;
2583 s->opt[OPT_GAMMA_VECTOR_G].constraint.range = &u8_range;
2584 s->val[OPT_GAMMA_VECTOR_G].wa = s->user_parms.gamma[1];
2585
2586 s->opt[OPT_GAMMA_VECTOR_B].name = SANE_NAME_GAMMA_VECTOR_B;
2587 s->opt[OPT_GAMMA_VECTOR_B].title = SANE_TITLE_GAMMA_VECTOR_B;
2588 s->opt[OPT_GAMMA_VECTOR_B].desc = SANE_DESC_GAMMA_VECTOR_B;
2589 s->opt[OPT_GAMMA_VECTOR_B].cap =
2590 SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
2591 s->opt[OPT_GAMMA_VECTOR_B].type = SANE_TYPE_INT;
2592 s->opt[OPT_GAMMA_VECTOR_B].size = 1024 * sizeof (SANE_Word);
2593 s->opt[OPT_GAMMA_VECTOR_B].unit = SANE_UNIT_NONE;
2594 s->opt[OPT_GAMMA_VECTOR_B].constraint_type = SANE_CONSTRAINT_RANGE;
2595 s->opt[OPT_GAMMA_VECTOR_B].constraint.range = &u8_range;
2596 s->val[OPT_GAMMA_VECTOR_B].wa = s->user_parms.gamma[2];
2597
2598 {
2599 int i;
2600 double gamma = 2.0;
2601 for (i = 0; i < 1024; i++)
2602 {
2603 s->user_parms.gamma[0][i] =
2604 255 * pow (((double) i + 1) / 1024, 1.0 / gamma);
2605 s->user_parms.gamma[1][i] = s->user_parms.gamma[0][i];
2606 s->user_parms.gamma[2][i] = s->user_parms.gamma[0][i];
2607 #ifdef DEBUG
2608 printf ("%d %d\n", i, s->user_parms.gamma[0][i]);
2609 #endif
2610 }
2611 }
2612
2613 /* preview */
2614 s->opt[OPT_PREVIEW].name = SANE_NAME_PREVIEW;
2615 s->opt[OPT_PREVIEW].title = SANE_TITLE_PREVIEW;
2616 s->opt[OPT_PREVIEW].desc = SANE_DESC_PREVIEW;
2617 s->opt[OPT_PREVIEW].type = SANE_TYPE_BOOL;
2618 s->opt[OPT_PREVIEW].size = sizeof (SANE_Word);
2619 s->opt[OPT_PREVIEW].cap = SANE_CAP_SOFT_DETECT | SANE_CAP_SOFT_SELECT;
2620 s->val[OPT_PREVIEW].w = SANE_FALSE;
2621 }
2622
2623 SANE_Status
sane_open(SANE_String_Const name,SANE_Handle * h)2624 sane_open (SANE_String_Const name, SANE_Handle * h)
2625 {
2626 static const char me[] = "sane_hp4200_open";
2627 SANE_Status status;
2628 HP4200_Device *dev;
2629 HP4200_Scanner *s;
2630
2631 DBG (DBG_proc, "%s (%s, %p)\n", me, name, (void *) h);
2632
2633 if (name && name[0])
2634 {
2635 dev = find_device (name);
2636 if (!dev)
2637 {
2638 status = add_device (name, &dev);
2639 if (status != SANE_STATUS_GOOD)
2640 return status;
2641 }
2642 }
2643 else
2644 {
2645 dev = first_device;
2646 }
2647 if (!dev)
2648 return SANE_STATUS_INVAL;
2649
2650 if (!h)
2651 return SANE_STATUS_INVAL;
2652
2653 s = *h = (HP4200_Scanner *) calloc (1, sizeof (HP4200_Scanner));
2654 if (!s)
2655 {
2656 DBG (DBG_error, "%s: out of memory creating scanner structure.\n", me);
2657 return SANE_STATUS_NO_MEM;
2658 }
2659
2660 dev->handle = s;
2661 s->aborted_by_user = SANE_FALSE;
2662 s->ciclic_buffer.buffer = NULL;
2663 s->scanner_buffer.buffer = NULL;
2664 s->dev = dev;
2665 s->user_parms.image_width = 0;
2666 s->user_parms.lines_to_scan = 0;
2667 s->user_parms.vertical_resolution = 0;
2668 s->scanning = SANE_FALSE;
2669 s->fd = -1;
2670
2671 init_options (s);
2672
2673 if ((sanei_usb_open (dev->dev.name, &s->fd) != SANE_STATUS_GOOD))
2674 {
2675 DBG (DBG_error, "%s: Can't open %s.\n", me, dev->dev.name);
2676 return SANE_STATUS_IO_ERROR; /* fixme: return busy when file is
2677 being accessed already */
2678 }
2679
2680 return SANE_STATUS_GOOD;
2681 }
2682
2683 void
sane_close(SANE_Handle h)2684 sane_close (SANE_Handle h)
2685 {
2686 HP4200_Scanner *s = (HP4200_Scanner *) h;
2687 DBG (DBG_proc, "sane_hp4200_close (%p)\n", (void *) h);
2688
2689 if (s)
2690 {
2691 s->dev->handle = NULL;
2692 if (s->fd != -1)
2693 {
2694 sanei_usb_close (s->fd);
2695 }
2696 free (s);
2697 }
2698 }
2699
2700 const SANE_Option_Descriptor *
sane_get_option_descriptor(SANE_Handle h,SANE_Int n)2701 sane_get_option_descriptor (SANE_Handle h, SANE_Int n)
2702 {
2703 static char me[] = "sane_get_option_descriptor";
2704 HP4200_Scanner *s = (HP4200_Scanner *) h;
2705
2706 DBG (DBG_proc, "%s\n", me);
2707
2708 if ((n < 0) || (n >= NUM_OPTIONS))
2709 return NULL;
2710
2711 return s->opt + n;
2712 }
2713
2714 SANE_Status
sane_control_option(SANE_Handle handle,SANE_Int option,SANE_Action action,void * val,SANE_Int * info)2715 sane_control_option (SANE_Handle handle, SANE_Int option,
2716 SANE_Action action, void *val, SANE_Int * info)
2717 {
2718 HP4200_Scanner *s = (HP4200_Scanner *) handle;
2719 SANE_Status status;
2720 SANE_Int myinfo = 0;
2721 SANE_Word cap;
2722
2723 DBG (DBG_proc, "sane_control_option\n");
2724
2725 if (info)
2726 *info = 0;
2727
2728 if (s->scanning)
2729 {
2730 return SANE_STATUS_DEVICE_BUSY;
2731 }
2732
2733 if (option < 0 || option >= NUM_OPTIONS)
2734 {
2735 return SANE_STATUS_INVAL;
2736 }
2737
2738 cap = s->opt[option].cap;
2739 if (!SANE_OPTION_IS_ACTIVE (cap))
2740 {
2741 return SANE_STATUS_INVAL;
2742 }
2743
2744 if (action == SANE_ACTION_GET_VALUE)
2745 {
2746
2747 switch (option)
2748 {
2749 case OPT_NUM_OPTS:
2750 case OPT_RES:
2751 case OPT_TL_X:
2752 case OPT_TL_Y:
2753 case OPT_BR_X:
2754 case OPT_BR_Y:
2755 case OPT_PREVIEW:
2756 *(SANE_Word *) val = s->val[option].w;
2757 break;
2758
2759 case OPT_BACKTRACK:
2760 *(SANE_Bool *) val = s->val[option].b;
2761 break;
2762
2763 case OPT_GAMMA_VECTOR_R:
2764 case OPT_GAMMA_VECTOR_G:
2765 case OPT_GAMMA_VECTOR_B:
2766 memcpy (val, s->val[option].wa, s->opt[option].size);
2767 break;
2768 default:
2769 return SANE_STATUS_UNSUPPORTED;
2770 }
2771 }
2772 else if (action == SANE_ACTION_SET_VALUE)
2773 {
2774
2775 if (!SANE_OPTION_IS_SETTABLE (cap))
2776 {
2777 DBG (DBG_error, "could not set option, not settable\n");
2778 return SANE_STATUS_INVAL;
2779 }
2780
2781 status = sanei_constrain_value (s->opt + option, val, &myinfo);
2782 if (status != SANE_STATUS_GOOD)
2783 return status;
2784
2785 switch (option)
2786 {
2787
2788 /* Numeric side-effect free options */
2789 case OPT_PREVIEW:
2790 s->val[option].w = *(SANE_Word *) val;
2791 return SANE_STATUS_GOOD;
2792
2793 /* Numeric side-effect options */
2794 case OPT_RES:
2795 case OPT_TL_X:
2796 case OPT_TL_Y:
2797 case OPT_BR_X:
2798 case OPT_BR_Y:
2799 myinfo |= SANE_INFO_RELOAD_PARAMS;
2800 s->val[option].w = *(SANE_Word *) val;
2801 break;
2802
2803 case OPT_BACKTRACK:
2804 s->val[option].b = *(SANE_Bool *) val;
2805 break;
2806
2807 case OPT_GAMMA_VECTOR_R:
2808 case OPT_GAMMA_VECTOR_G:
2809 case OPT_GAMMA_VECTOR_B:
2810 memcpy (s->val[option].wa, val, s->opt[option].size);
2811 break;
2812 default:
2813 return SANE_STATUS_UNSUPPORTED;
2814 }
2815 }
2816 else
2817 {
2818 return SANE_STATUS_UNSUPPORTED;
2819 }
2820
2821 if (info)
2822 *info = myinfo;
2823
2824 return SANE_STATUS_GOOD;
2825 }
2826
2827 static void
compute_parameters(HP4200_Scanner * s)2828 compute_parameters (HP4200_Scanner * s)
2829 {
2830 int resolution;
2831 int opt_tl_x;
2832 int opt_br_x;
2833 int opt_tl_y;
2834 int opt_br_y;
2835
2836 if (s->val[OPT_PREVIEW].w == SANE_TRUE)
2837 {
2838 resolution = 50;
2839 opt_tl_x = SANE_UNFIX (x_range.min);
2840 opt_tl_y = SANE_UNFIX (y_range.min);
2841 opt_br_x = SANE_UNFIX (x_range.max);
2842 opt_br_y = SANE_UNFIX (y_range.max);
2843 }
2844 else
2845 {
2846 resolution = s->val[OPT_RES].w;
2847 opt_tl_x = SANE_UNFIX (s->val[OPT_TL_X].w);
2848 opt_tl_y = SANE_UNFIX (s->val[OPT_TL_Y].w);
2849 opt_br_x = SANE_UNFIX (s->val[OPT_BR_X].w);
2850 opt_br_y = SANE_UNFIX (s->val[OPT_BR_Y].w);
2851 }
2852
2853 s->user_parms.horizontal_resolution = resolution;
2854 s->user_parms.vertical_resolution = resolution;
2855
2856 s->runtime_parms.steps_to_skip = floor (300.0 / MM_PER_INCH * opt_tl_y);
2857 s->user_parms.lines_to_scan =
2858 floor ((opt_br_y - opt_tl_y) / MM_PER_INCH * resolution);
2859 s->user_parms.image_width =
2860 floor ((opt_br_x - opt_tl_x) / MM_PER_INCH * resolution);
2861 s->runtime_parms.first_pixel = floor (opt_tl_x / MM_PER_INCH * resolution);
2862
2863 /* fixme: add support for more depth's and bpp's. */
2864 s->runtime_parms.image_line_size = s->user_parms.image_width * 3;
2865 }
2866
2867 SANE_Status
sane_get_parameters(SANE_Handle h,SANE_Parameters * p)2868 sane_get_parameters (SANE_Handle h, SANE_Parameters * p)
2869 {
2870 static char me[] = "sane_get_parameters";
2871 HP4200_Scanner *s = (HP4200_Scanner *) h;
2872
2873 DBG (DBG_proc, "%s\n", me);
2874 if (!p)
2875 return SANE_STATUS_INVAL;
2876
2877 p->format = SANE_FRAME_RGB;
2878 p->last_frame = SANE_TRUE;
2879 p->depth = 8;
2880 if (!s->scanning)
2881 {
2882 compute_parameters (s);
2883 }
2884
2885 p->lines = s->user_parms.lines_to_scan;
2886 p->pixels_per_line = s->user_parms.image_width;
2887 p->bytes_per_line = s->runtime_parms.image_line_size;
2888
2889 return SANE_STATUS_GOOD;
2890 }
2891
2892 SANE_Status
sane_start(SANE_Handle h)2893 sane_start (SANE_Handle h)
2894 {
2895 HP4200_Scanner *s = (HP4200_Scanner *) h;
2896 struct coarse_t coarse;
2897
2898 static char me[] = "sane_start";
2899 DBG (DBG_proc, "%s\n", me);
2900
2901 s->scanning = SANE_TRUE;
2902 s->aborted_by_user = SANE_FALSE;
2903 s->user_parms.color = SANE_TRUE;
2904
2905 compute_parameters (s);
2906
2907 hp4200_init_scanner (s);
2908 hp4200_goto_home (s);
2909 hp4200_wait_homed (s);
2910 /* restore default register values here... */
2911 write_gamma (s);
2912 hp4200_init_registers (s);
2913 lm9830_ini_scanner (s->fd, NULL);
2914 /* um... do not call cache_write() here, don't know why :( */
2915 do_coarse_calibration (s, &coarse);
2916 do_fine_calibration (s, &coarse);
2917 prepare_for_a_scan (s);
2918
2919 return SANE_STATUS_GOOD;
2920 }
2921
2922 void
sane_cancel(SANE_Handle h)2923 sane_cancel (SANE_Handle h)
2924 {
2925 static char me[] = "sane_cancel";
2926 HP4200_Scanner *s = (HP4200_Scanner *) h;
2927 DBG (DBG_proc, "%s\n", me);
2928
2929 s->aborted_by_user = SANE_TRUE;
2930
2931 end_scan (s);
2932 }
2933
2934 SANE_Status
sane_set_io_mode(SANE_Handle handle,SANE_Bool non_blocking)2935 sane_set_io_mode (SANE_Handle handle, SANE_Bool non_blocking)
2936 {
2937 HP4200_Scanner *dev = handle;
2938 SANE_Status status;
2939
2940 (void) non_blocking; /* silence gcc */
2941
2942 if (dev->scanning == SANE_FALSE)
2943 {
2944 return SANE_STATUS_INVAL;
2945 }
2946
2947 if (non_blocking == SANE_FALSE)
2948 {
2949 status = SANE_STATUS_GOOD;
2950 }
2951 else
2952 {
2953 status = SANE_STATUS_UNSUPPORTED;
2954 }
2955
2956 DBG (DBG_proc, "sane_set_io_mode: exit\n");
2957
2958 return status;
2959 }
2960
2961 SANE_Status
sane_get_select_fd(SANE_Handle h,SANE_Int * fd)2962 sane_get_select_fd (SANE_Handle h, SANE_Int * fd)
2963 {
2964 static char me[] = "sane_get_select_fd";
2965
2966 (void) h; /* keep gcc quiet */
2967 (void) fd; /* keep gcc quiet */
2968
2969 DBG (DBG_proc, "%s\n", me);
2970 return SANE_STATUS_UNSUPPORTED;
2971 }
2972