• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &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