1/*
2   (c) 2001,2002 Nathan Rutman  nathan@gordian.com  10/17/01
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 as
6   published by the Free Software Foundation; either version 2 of the
7   License, or (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful, but
10   WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   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   As a special exception, the authors of SANE give permission for
18   additional uses of the libraries contained in this release of SANE.
19
20   The exception is that, if you link a SANE library with other files
21   to produce an executable, this does not by itself cause the
22   resulting executable to be covered by the GNU General Public
23   License.  Your use of that executable is in no way restricted on
24   account of linking the SANE library code into it.
25
26   This exception does not, however, invalidate any other reasons why
27   the executable file might be covered by the GNU General Public
28   License.
29
30   If you submit changes to SANE to the maintainers to be included in
31   a subsequent release, you agree by submitting the changes that
32   those changes may be distributed with this exception intact.
33
34   If you write modifications of your own for SANE, it is your choice
35   whether to permit this exception to apply to your modifications.
36   If you do not wish that, delete this exception notice.
37*/
38
39/*
40   Communication, calibration, and scanning with the Canon CanoScan FB630U
41   flatbed scanner under linux.
42
43   Reworked into SANE-compatible format.
44
45   The usb-parallel port interface chip is GL640usb, on the far side of
46   which is an LM9830 parallel-port scanner-on-a-chip.
47
48   This code has not been tested on anything other than Linux/i386.
49*/
50
51#include <errno.h>
52#include <fcntl.h>		/* open */
53#include <stdio.h>
54#include <stdlib.h>
55#include <string.h>
56#include <unistd.h>		/* usleep */
57#include <time.h>
58#include <math.h>               /* exp() */
59#ifdef HAVE_OS2_H
60#include <sys/types.h> 		/* mode_t */
61#endif
62#include <sys/stat.h>
63#include "lm9830.h"
64
65#define USB_TYPE_VENDOR                 (0x02 << 5)
66#define USB_RECIP_DEVICE                0x00
67#define USB_DIR_OUT                     0x00
68#define USB_DIR_IN                      0x80
69
70/* Assign status and verify a good return code */
71#define CHK(A) {if( (status = A) != SANE_STATUS_GOOD ) { \
72                 DBG( 1, "Failure on line of %s: %d\n", __FILE__, \
73                      __LINE__ ); return A; }}
74
75
76typedef SANE_Byte byte;
77
78
79/*****************************************************
80            GL640 communication primitives
81   Provides I/O routines to Genesys Logic GL640USB USB-IEEE1284 parallel
82   port bridge.  Used in HP3300c, Canon FB630u.
83******************************************************/
84
85/* Register codes for the bridge.  These are NOT the registers for the
86   scanner chip on the other side of the bridge. */
87typedef enum
88{
89  GL640_BULK_SETUP = 0x82,
90  GL640_EPP_ADDR = 0x83,
91  GL640_EPP_DATA_READ = 0x84,
92  GL640_EPP_DATA_WRITE = 0x85,
93  GL640_SPP_STATUS = 0x86,
94  GL640_SPP_CONTROL = 0x87,
95  GL640_SPP_DATA = 0x88,
96  GL640_GPIO_OE = 0x89,
97  GL640_GPIO_READ = 0x8a,
98  GL640_GPIO_WRITE = 0x8b
99}
100GL640_Request;
101
102/* Write to the usb-parallel port bridge. */
103static SANE_Status
104gl640WriteControl (int fd, GL640_Request req, byte * data, unsigned int size)
105{
106  SANE_Status status;
107  status = sanei_usb_control_msg (fd,
108				  /* rqttype */ USB_TYPE_VENDOR |
109				  USB_RECIP_DEVICE | USB_DIR_OUT /*0x40? */ ,
110				  /* rqt */ (size > 1) ? 0x04 : 0x0C,
111				  /* val */ (SANE_Int) req,
112				  /* ind */ 0,
113				  /* len */ size,
114				  /* dat */ data);
115  if (status != SANE_STATUS_GOOD)
116    DBG (1, "gl640WriteControl error\n");
117  return status;
118}
119
120
121/* Read from the usb-parallel port bridge. */
122static SANE_Status
123gl640ReadControl (int fd, GL640_Request req, byte * data, unsigned int size)
124{
125  SANE_Status status;
126  status = sanei_usb_control_msg (fd,
127				  /* rqttype */ USB_TYPE_VENDOR |
128				  USB_RECIP_DEVICE | USB_DIR_IN /*0xc0? */ ,
129				  /* rqt */ (size > 1) ? 0x04 : 0x0C,
130				  /* val */ (SANE_Int) req,
131				  /* ind */ 0,
132				  /* len */ size,
133				  /* dat */ data);
134  if (status != SANE_STATUS_GOOD)
135    DBG (1, "gl640ReadControl error\n");
136  return status;
137}
138
139
140/* Wrappers to read or write a single byte to the bridge */
141static inline SANE_Status
142gl640WriteReq (int fd, GL640_Request req, byte data)
143{
144  return gl640WriteControl (fd, req, &data, 1);
145}
146
147static inline SANE_Status
148gl640ReadReq (int fd, GL640_Request req, byte * data)
149{
150  return gl640ReadControl (fd, req, data, 1);
151}
152
153
154/* Write USB bulk data
155   setup is an apparently scanner-specific sequence:
156   {(0=read, 1=write), 0x00, 0x00, 0x00, sizelo, sizehi, 0x00, 0x00}
157   hp3400: setup[1] = 0x01
158   fb630u: setup[2] = 0x80
159*/
160static SANE_Status
161gl640WriteBulk (int fd, byte * setup, byte * data, size_t size)
162{
163  SANE_Status status;
164  setup[0] = 1;
165  setup[4] = (size) & 0xFF;
166  setup[5] = (size >> 8) & 0xFF;
167
168  CHK (gl640WriteControl (fd, GL640_BULK_SETUP, setup, 8));
169
170  status = sanei_usb_write_bulk (fd, data, &size);
171  if (status != SANE_STATUS_GOOD)
172    DBG (1, "gl640WriteBulk error\n");
173
174  return status;
175}
176
177
178/* Read USB bulk data
179   setup is an apparently scanner-specific sequence:
180   {(0=read, 1=write), 0x00, 0x00, 0x00, sizelo, sizehi, 0x00, 0x00}
181   fb630u: setup[2] = 0x80
182*/
183static SANE_Status
184gl640ReadBulk (int fd, byte * setup, byte * data, size_t size)
185{
186  SANE_Status status;
187  setup[0] = 0;
188  setup[4] = (size) & 0xFF;
189  setup[5] = (size >> 8) & 0xFF;
190
191  CHK (gl640WriteControl (fd, GL640_BULK_SETUP, setup, 8));
192
193  status = sanei_usb_read_bulk (fd, data, &size);
194  if (status != SANE_STATUS_GOOD)
195    DBG (1, "gl640ReadBulk error\n");
196
197  return status;
198}
199
200
201/*****************************************************
202            LM9830 communication primitives
203	    parallel-port scanner-on-a-chip.
204******************************************************/
205
206/* write 1 byte to a LM9830 register address */
207static SANE_Status
208write_byte (int fd, byte addr, byte val)
209{
210  SANE_Status status;
211  DBG (14, "write_byte(fd, 0x%02x, 0x%02x);\n", addr, val);
212  CHK (gl640WriteReq (fd, GL640_EPP_ADDR, addr));
213  CHK (gl640WriteReq (fd, GL640_EPP_DATA_WRITE, val));
214  return status;
215}
216
217
218/* read 1 byte from a LM9830 register address */
219static SANE_Status
220read_byte (int fd, byte addr, byte * val)
221{
222  SANE_Status status;
223  CHK (gl640WriteReq (fd, GL640_EPP_ADDR, addr));
224  CHK (gl640ReadReq (fd, GL640_EPP_DATA_READ, val));
225  DBG (14, "read_byte(fd, 0x%02x, &result); /* got %02x */\n", addr, *val);
226  return status;
227}
228
229
230static byte bulk_setup_data[] = { 0, 0, 0x80, 0, 0, 0, 0, 0 };
231
232/* Bulk write */
233static SANE_Status
234write_bulk (int fd, unsigned int addr, void *src, size_t count)
235{
236  SANE_Status status;
237
238  DBG (13, "write_bulk(fd, 0x%02x, buf, 0x%04lx);\n", addr, (u_long) count);
239
240  if (!src)
241    {
242      DBG (1, "write_bulk: bad src\n");
243      return SANE_STATUS_INVAL;
244    }
245
246  /* destination address */
247  CHK (gl640WriteReq (fd, GL640_EPP_ADDR, addr));
248  /* write */
249  CHK (gl640WriteBulk (fd, bulk_setup_data, src, count));
250  return status;
251}
252
253
254/* Bulk read */
255static SANE_Status
256read_bulk (int fd, unsigned int addr, void *dst, size_t count)
257{
258  SANE_Status status;
259
260  DBG (13, "read_bulk(fd, 0x%02x, buf, 0x%04lx);\n", addr, (u_long) count);
261
262  if (!dst)
263    {
264      DBG (1, "read_bulk: bad dest\n");
265      return SANE_STATUS_INVAL;
266    }
267
268  /* destination address */
269  CHK (gl640WriteReq (fd, GL640_EPP_ADDR, addr));
270  /* read */
271  CHK (gl640ReadBulk (fd, bulk_setup_data, dst, count));
272  return status;
273}
274
275
276
277/*****************************************************
278            useful macro routines
279******************************************************/
280
281/* write a 16-bit int to two sequential registers */
282static SANE_Status
283write_word (int fd, unsigned int addr, unsigned int data)
284{
285  SANE_Status status;
286  /* MSB */
287  CHK (write_byte (fd, addr, (data >> 8) & 0xff));
288  /* LSB */
289  CHK (write_byte (fd, addr + 1, data & 0xff));
290  return status;
291}
292
293
294/* write multiple bytes, one at a time (non-bulk) */
295static SANE_Status
296write_many (int fd, unsigned int addr, const byte *src, size_t count)
297{
298  SANE_Status status;
299  size_t i;
300
301  DBG (14, "multi write %lu\n", (u_long) count);
302  for (i = 0; i < count; i++)
303    {
304      DBG (15, " %04lx:%02x", (u_long) (addr + i), src[i]);
305      status = write_byte (fd, addr + i, src[i]);
306      if (status != SANE_STATUS_GOOD)
307	{
308	  DBG (15, "\n");
309	  return status;
310	}
311    }
312  DBG (15, "\n");
313  return SANE_STATUS_GOOD;
314}
315
316
317/* read multiple bytes, one at a time (non-bulk) */
318static SANE_Status
319read_many (int fd, unsigned int addr, void *dst, size_t count)
320{
321  SANE_Status status;
322  size_t i;
323  byte val;
324
325  DBG (14, "multi read %lu\n", (u_long) count);
326  for (i = 0; i < count; i++)
327    {
328      status = read_byte (fd, addr + i, &val);
329      ((byte *) dst)[i] = val;
330      DBG (15, " %04lx:%02x", (u_long) (addr + i), ((byte *) dst)[i]);
331      /* on err, return number of success */
332      if (status != SANE_STATUS_GOOD)
333	{
334	  DBG (15, "\n");
335	  return status;
336	}
337    }
338  DBG (15, "\n");
339  return SANE_STATUS_GOOD;
340}
341
342
343/* Poll addr until result & mask = val */
344static int
345read_poll_flag (int fd,
346		unsigned int addr, unsigned int mask, unsigned int val)
347{
348  SANE_Status status;
349  byte result = 0;
350  time_t start_time = time (NULL);
351
352  DBG (12, "read_poll_flag...\n");
353  do
354    {
355      status = read_byte (fd, addr, &result);
356      if (status != SANE_STATUS_GOOD)
357	return -1;
358      /* Give it a minute */
359      if ((time (NULL) - start_time) > 60)
360	{
361	  DBG (1, "read_poll_flag: timed out (%d)\n", result);
362	  return -1;
363	}
364      usleep (100000);
365    }
366  while ((result & mask) != val);
367  return result;
368}
369
370
371/* Keep reading addr until results >= min */
372static int
373read_poll_min (int fd, unsigned int addr, unsigned int min)
374{
375  SANE_Status status;
376  byte result;
377  time_t start_time = time (NULL);
378
379  DBG (12, "waiting...\n");
380  do
381    {
382      status = read_byte (fd, addr, &result);
383      if (status != SANE_STATUS_GOOD)
384	return -1;
385      /* Give it a minute */
386      if ((time (NULL) - start_time) > 60)
387	{
388	  DBG (1, "read_poll_min: timed out (%d < %d)\n", result, min);
389	  return -1;
390	}
391      /* no sleep here, or calibration gets unhappy. */
392    }
393  while (result < min);
394  return result;
395}
396
397
398/* Bulk read "ks" kilobytes + "remainder" bytes of data, to a buffer if the
399   buffer is valid. */
400static int
401read_bulk_size (int fd, int ks, int remainder, byte * dest, int destsize)
402{
403  byte *buf;
404  int bytes = (ks - 1) * 1024 + remainder;
405  int dropdata = ((dest == 0) || (destsize < bytes));
406
407  if (bytes < 0)
408    {
409      DBG (1, "read_bulk_size: invalid size %02x (%d)\n", ks, bytes);
410      return -1;
411    }
412  if (destsize && (destsize < bytes))
413    {
414      DBG (3, "read_bulk_size: more data than buffer (%d/%d)\n",
415	   destsize, bytes);
416      bytes = destsize;
417    }
418
419  if (bytes == 0)
420    return 0;
421
422  if (dropdata)
423    {
424      buf = malloc (bytes);
425      DBG (3, " ignoring data ");
426    }
427  else
428    buf = dest;
429
430  read_bulk (fd, 0x00, buf, bytes);
431
432  if (dropdata)
433    free (buf);
434  return bytes;
435}
436
437
438
439/*****************************************************
440
441            fb630u calibration and scan
442
443******************************************************/
444
445/* data structures and constants */
446
447typedef struct CANON_Handle
448{
449  int fd;			/* scanner fd */
450  int x1, x2, y1, y2;		/* in pixels, 600 dpi */
451  int width, height;		/* at scan resolution */
452  int resolution;		/* dpi */
453  char *fname;			/* output file name */
454  FILE *fp;			/* output file pointer (for reading) */
455  char *buf, *ptr;		/* data buffer */
456  unsigned char gain;		/* static analog gain, 0 - 31 */
457  double gamma;		        /* gamma correction */
458  int flags;
459#define FLG_GRAY	0x01	/* grayscale */
460#define FLG_FORCE_CAL	0x02	/* force calibration */
461#define FLG_BUF		0x04	/* save scan to buffer instead of file */
462#define FLG_NO_INTERLEAVE 0x08	/* don't interleave r,g,b pixels; leave them
463				   in row format */
464#define FLG_PPM_HEADER	0x10	/* include PPM header in scan file */
465}
466CANON_Handle;
467
468
469/* offset/gain calibration file name */
470#define CAL_FILE_OGN "/tmp/canon.cal"
471
472/* at 600 dpi */
473#define CANON_MAX_WIDTH    5100	/* 8.5in */
474/* this may not be right */
475#define CANON_MAX_HEIGHT   7000	/* 11.66in */
476
477/* scanline end-of-line data byte, returned after each r,g,b segment,
478   specific to the FB630u */
479#define SCANLINE_END	0x0c
480
481
482static const byte seq002[] =
483  { /*r08 */ 0x04, /*300 dpi */ 0x1a, 0x00, 0x0d, 0x4c, 0x2f, 0x00, 0x01,
484/*r10 */ 0x07, 0x04, 0x05, 0x06, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x25, 0x00,
4850x4b, /*r20 */ 0x15, 0xe0, /*data px start */ 0x00, 0x4b, /*data px end */ 0x14, 0x37, 0x15, 0x00 };
486
487static const byte seq003[] =
488  { 0x02, 0x00, 0x00, /*lights out */ 0x03, 0xff, 0x00, 0x01, 0x03, 0xff,
4890x00, 0x01, 0x03, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
4900x1d, 0x00, 0x13, 0x04, 0x1a, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x57, 0x02, 0x00, 0x3c, 0x35, 0x94,
4910x00, 0x10, 0x08, 0x3f, 0x2b, 0x91, 0x00, 0x00, 0x01, 0x00, 0x80, 0x00 };
492
493
494/* Scanner init, called at calibration and scan time.  Returns 1 if this
495   was the first time the scanner was plugged in, 0 afterward, and
496   -1 on error. */
497static int
498init (int fd)
499{
500  byte result, rv;
501
502  if (gl640WriteReq (fd, GL640_GPIO_OE, 0x71) != SANE_STATUS_GOOD) {
503      DBG(1, "Initial write request failed.\n");
504      return -1;
505  }
506  /* Gets 0x04 or 0x05 first run, gets 0x64 subsequent runs. */
507  if (gl640ReadReq (fd, GL640_GPIO_READ, &rv) != SANE_STATUS_GOOD) {
508      DBG(1, "Initial read request failed.\n");
509      return -1;
510  }
511  gl640WriteReq (fd, GL640_GPIO_OE, 0x70);
512
513  DBG (2, "init query: %x\n", rv);
514  if (rv != 0x64)
515    {
516      gl640WriteReq (fd, GL640_GPIO_WRITE, 0x00);
517      gl640WriteReq (fd, GL640_GPIO_WRITE, 0x40);
518    }
519
520  gl640WriteReq (fd, GL640_SPP_DATA, 0x99);
521  gl640WriteReq (fd, GL640_SPP_DATA, 0x66);
522  gl640WriteReq (fd, GL640_SPP_DATA, 0xcc);
523  gl640WriteReq (fd, GL640_SPP_DATA, 0x33);
524  /* parallel port setting */
525  write_byte (fd, PARALLEL_PORT, 0x06);
526  /* sensor control settings */
527  write_byte (fd, 0x0b, 0x0d);
528  write_byte (fd, 0x0c, 0x4c);
529  write_byte (fd, 0x0d, 0x2f);
530  read_byte (fd, 0x0b, &result);	/* wants 0d */
531  read_byte (fd, 0x0c, &result);	/* wants 4c */
532  read_byte (fd, 0x0d, &result);	/* wants 2f */
533  /* parallel port noise filter */
534  write_byte (fd, 0x70, 0x73);
535
536  DBG (2, "init post-reset: %x\n", rv);
537  /* Returns 1 if this was the first time the scanner was plugged in. */
538  return (rv != 0x64);
539}
540
541
542/* Turn off the lamps */
543static void
544lights_out (int fd)
545{
546  write_word (fd, LAMP_R_ON, 0x3fff);
547  write_word (fd, LAMP_R_OFF, 0x0001);
548  write_word (fd, LAMP_G_ON, 0x3fff);
549  write_word (fd, LAMP_G_OFF, 0x0001);
550  write_word (fd, LAMP_B_ON, 0x3fff);
551  write_word (fd, LAMP_B_OFF, 0x0001);
552}
553
554
555/* Do the scan and save the resulting image as r,g,b interleaved PPM
556   file.  */
557static SANE_Status
558do_scan (CANON_Handle * s)
559{
560  SANE_Status status = SANE_STATUS_GOOD;
561  int numbytes, datasize, level = 0, line = 0, pixel = 0;
562  byte *buf, *ptr, *redptr;
563  FILE *fp;
564
565#define BUFSIZE 0xf000
566  buf = malloc (BUFSIZE);
567  if (!buf)
568    return SANE_STATUS_NO_MEM;
569
570  if (s->flags & FLG_BUF)
571    {
572      /* read the whole thing into buf */
573      if (!s->buf)
574	return SANE_STATUS_NO_MEM;
575      s->ptr = s->buf;
576      fp = NULL;
577    }
578  else
579    {
580      fp = fopen (s->fname, "w");
581      if (!fp)
582	{
583	  free (buf);
584	  DBG (1, "err:%s when opening %s\n", strerror (errno), s->fname);
585	  return SANE_STATUS_IO_ERROR;
586	}
587    }
588  if (fp && (s->flags & FLG_PPM_HEADER))
589    /* PPM format header */
590    fprintf (fp, "P6\n%d %d\n255\n", s->width, s->height);
591
592  /* lights off */
593  write_byte (s->fd, COMMAND, 0x08);
594  /* lights on */
595  write_byte (s->fd, COMMAND, 0x00);
596  /* begin scan */
597  write_byte (s->fd, COMMAND, 0x03);
598
599  ptr = redptr = buf;
600  while (line < s->height)
601    {
602      datasize = read_poll_min (s->fd, IMAGE_DATA_AVAIL, 2);
603      if (datasize < 0)
604	{
605	  DBG (1, "no data\n");
606	  break;
607	}
608      DBG (12, "scan line %d %dk\n", line, datasize - 1);
609      /* Read may cause scan head to move */
610      numbytes = read_bulk_size (s->fd, datasize, 0, ptr, BUFSIZE - level);
611      if (numbytes < 0)
612	{
613	  status = SANE_STATUS_INVAL;
614	  break;
615	}
616      /* Data coming back is "width" bytes Red data followed by 0x0c,
617         width bytes Green, 0x0c, width bytes Blue, 0x0c, repeat for
618         "height" lines. */
619      if (s->flags & FLG_NO_INTERLEAVE)
620	{
621	  /* number of full lines */
622	  line += (numbytes + level) / (s->width * 3);
623	  /* remainder (partial line) */
624	  level = (numbytes + level) % (s->width * 3);
625	  /* but if last line, don't store extra */
626	  if (line >= s->height)
627	    numbytes -= (line - s->height) * s->width * 3 + level;
628	  if (fp)
629	    fwrite (buf, 1, numbytes, fp);
630	  else
631	    {
632	      memcpy (s->ptr, buf, numbytes);
633	      s->ptr += numbytes;
634	    }
635	}
636      else
637	{
638	  /* Contorsions to convert data from line-by-line RGB to
639	     byte-by-byte RGB, without reading in the whole buffer first.
640	     We use the sliding window redptr with the temp buffer buf. */
641	  ptr += numbytes;	/* point to the end of data */
642	  /* while we have RGB triple data */
643	  while (redptr + s->width + s->width <= ptr)
644	    {
645	      if (*redptr == SCANLINE_END)
646		DBG (13, "-%d- ", pixel);
647	      if (fp)
648		{
649		  /* for PPM binary (P6), 3-byte RGB pixel */
650		  fwrite (redptr, 1, 1, fp);	/* Red */
651		  fwrite (redptr + s->width, 1, 1, fp);	/* Green */
652		  fwrite (redptr + s->width + s->width, 1, 1, fp);	/* Blue */
653		  /* for PPM ascii (P3)
654		     fprintf(fp, "%3d %3d %3d\n",  *redptr,
655		     *(redptr + s->width),
656		     *(redptr + s->width + s->width));
657		   */
658		}
659	      else
660		{
661		  /* R */ *s->ptr = *redptr;
662		  s->ptr++;
663		  /* G */ *s->ptr = *(redptr + s->width);
664		  s->ptr++;
665		  /* B */ *s->ptr = *(redptr + s->width + s->width);
666		  s->ptr++;
667		}
668	      redptr++;
669	      pixel++;
670	      if (pixel && !(pixel % s->width))
671		{
672		  /* end of a line, move redptr to the next Red section */
673		  line++;
674		  redptr += s->width + s->width;
675#if 0
676		  /* progress */
677		  printf ("%2d%%\r", line * 100 / s->height);
678		  fflush (stdout);
679#endif
680		  /* don't record any extra */
681		  if (line >= s->height)
682		    break;
683		}
684	    }
685	  /* keep the extra around for next time */
686	  level = ptr - redptr;
687	  if (level < 0)
688	    level = 0;
689	  memmove (buf, redptr, level);
690	  ptr = buf + level;
691	  redptr = buf;
692	}
693    }
694
695  if (fp)
696    {
697      fclose (fp);
698      DBG (6, "created scan file %s\n", s->fname);
699    }
700  free (buf);
701  DBG (6, "%d lines, %d pixels, %d extra bytes\n", line, pixel, level);
702
703  /* motor off */
704  write_byte (s->fd, COMMAND, 0x00);
705
706  return status;
707}
708
709
710static int
711wait_for_return (int fd)
712{
713  return read_poll_flag (fd, STATUS, STATUS_HOME, STATUS_HOME);
714}
715
716
717static SANE_Status compute_ogn (char *calfilename);
718
719
720/* This is the calibration routine Win2k goes through when the scanner is
721   first plugged in.
722   Original usb trace from Win2k with USBSnoopy ("usb sniffer for w2k"
723   http://benoit.papillault.free.fr/speedtouch/sniff-2000.en.php3)
724 */
725static int
726plugin_cal (CANON_Handle * s)
727{
728  SANE_Status status;
729  unsigned int temp;
730  byte result;
731  byte *buf;
732  int fd = s->fd;
733
734  DBG (6, "Calibrating\n");
735
736  /* reserved? */
737  read_byte (fd, 0x69, &result);	/* wants 02 */
738
739  /* parallel port setting */
740  write_byte (fd, PARALLEL_PORT, 0x06);
741
742  write_many (fd, 0x08, seq002, sizeof (seq002));
743  /* addr 0x28 isn't written */
744  write_many (fd, 0x29, seq003, sizeof (seq003));
745  /* Verification */
746  buf = malloc (0x400);
747  read_many (fd, 0x08, buf, sizeof (seq002));
748  if (memcmp (seq002, buf, sizeof (seq002)))
749    DBG (1, "seq002 verification error\n");
750  /* addr 0x28 isn't read */
751  read_many (fd, 0x29, buf, sizeof (seq003));
752  if (memcmp (seq003, buf, sizeof (seq003)))
753    DBG (1, "seq003 verification error\n");
754
755  /* parallel port noise filter */
756  write_byte (fd, 0x70, 0x73);
757
758  lights_out (fd);
759
760  /* Home motor */
761  read_byte (fd, STATUS, &result);	/* wants 2f or 2d */
762  if (!(result & STATUS_HOME) /*0x2d */ )
763    write_byte (fd, COMMAND, 0x02);
764
765  wait_for_return (fd);
766
767  /* Motor forward */
768  write_byte (fd, COMMAND, 0x01);
769  usleep (600000);
770  read_byte (fd, STATUS, &result);	/* wants 0c or 2c */
771  read_byte (fd, STATUS, &result);	/* wants 0c */
772  /* Return home */
773  write_byte (fd, COMMAND, 0x02);
774
775  /* Gamma tables */
776  /* Linear gamma */
777  for (temp = 0; temp < 0x0400; temp++)
778    buf[temp] = temp / 4;
779  /* Gamma Red */
780  write_byte (fd, DATAPORT_TARGET, DP_R | DP_GAMMA);
781  write_word (fd, DATAPORT_ADDR, DP_WRITE);
782  write_bulk (fd, DATAPORT, buf, 0x0400);
783  /* Gamma Green */
784  write_byte (fd, DATAPORT_TARGET, DP_G | DP_GAMMA);
785  write_word (fd, DATAPORT_ADDR, DP_WRITE);
786  write_bulk (fd, DATAPORT, buf, 0x0400);
787  /* Gamma Blue */
788  write_byte (fd, DATAPORT_TARGET, DP_B | DP_GAMMA);
789  write_word (fd, DATAPORT_ADDR, DP_WRITE);
790  write_bulk (fd, DATAPORT, buf, 0x0400);
791
792  /* Read back gamma tables.  I suppose I should check results... */
793  /* Gamma Red */
794  write_byte (fd, DATAPORT_TARGET, DP_R | DP_GAMMA);
795  write_word (fd, DATAPORT_ADDR, DP_READ);
796  read_bulk (fd, DATAPORT, buf, 0x0400);
797  /* Gamma Green */
798  write_byte (fd, DATAPORT_TARGET, DP_G | DP_GAMMA);
799  write_word (fd, DATAPORT_ADDR, DP_READ);
800  read_bulk (fd, DATAPORT, buf, 0x0400);
801  /* Gamma Blue */
802  write_byte (fd, DATAPORT_TARGET, DP_B | DP_GAMMA);
803  write_word (fd, DATAPORT_ADDR, DP_READ);
804  read_bulk (fd, DATAPORT, buf, 0x0400);
805  free (buf);
806
807  /* Make sure STATUS_HOME */
808  read_byte (fd, STATUS, &result);	/* wants 0e */
809  /* stepper forward */
810  write_byte (fd, COMMAND, 0x01);
811  read_byte (fd, STATUS, &result);	/* wants 0c */
812  /* not sure if this rigid read/write pattern is required */
813  read_byte (fd, CLOCK_DIV, &result);	/* wants 04 */
814  write_byte (fd, CLOCK_DIV, 0x04);
815  read_byte (fd, STEP_SIZE, &result);	/* wants 04 */
816  write_byte (fd, STEP_SIZE, 0x3f);
817  read_byte (fd, 0x47, &result);	/* wants 1a */
818  write_byte (fd, 0x47, 0xff);
819  read_byte (fd, FAST_STEP, &result);	/* wants 01 */
820  write_byte (fd, FAST_STEP, 0x01);
821  read_byte (fd, 0x49, &result);	/* wants 04 */
822  write_byte (fd, 0x49, 0x04);
823  read_byte (fd, SKIP_STEPS, &result);	/* wants 00 */
824  write_byte (fd, SKIP_STEPS, 0x00);
825  read_byte (fd, 0x4b, &result);	/* wants 00 */
826  write_byte (fd, 0x4b, 0xc8);
827  read_byte (fd, BUFFER_LIMIT, &result);	/* wants 57 */
828  write_byte (fd, BUFFER_LIMIT, 0x04);
829  read_byte (fd, BUFFER_RESUME, &result);	/* wants 02 */
830  write_byte (fd, BUFFER_RESUME, 0x02);
831  read_byte (fd, REVERSE_STEPS, &result);	/* wants 00 */
832  write_byte (fd, REVERSE_STEPS, 0x00);
833  write_byte (fd, STEP_PWM, 0x1f);
834
835  /* Reset motor */
836  write_byte (fd, COMMAND, 0x08);
837  write_byte (fd, COMMAND, 0x00);
838  /* Scan */
839  write_byte (fd, COMMAND, 0x03);
840  /* Wants 02 or 03, gets a bunch of 0's first */
841  read_poll_min (fd, IMAGE_DATA_AVAIL, 2);
842  write_byte (fd, COMMAND, 0x00);
843
844  write_byte (fd, STEP_PWM, 0x3f);
845  write_byte (fd, CLOCK_DIV, 0x04);
846  /* 300 dpi */
847  write_word (fd, STEP_SIZE, 0x041a);
848  write_word (fd, FAST_STEP, 0x0104);
849  /* Don't skip the black/white calibration area at the bottom of the
850     scanner. */
851  write_word (fd, SKIP_STEPS, 0x0000);
852  write_byte (fd, BUFFER_LIMIT, 0x57);
853  write_byte (fd, BUFFER_RESUME, 0x02);
854  write_byte (fd, REVERSE_STEPS, 0x00);
855  write_byte (fd, BUFFER_LIMIT, 0x09);
856  write_byte (fd, STEP_PWM, 0x1f);
857  read_byte (fd, MICROSTEP, &result);	/* wants 13, active */
858  write_byte (fd, MICROSTEP, 0x03 /* tristate */ );
859
860  /* Calibration data taken under 3 different lighting conditions */
861  /* dark */
862  write_word (fd, LAMP_R_ON, 0x0017);
863  write_word (fd, LAMP_R_OFF, 0x0100);
864  write_word (fd, LAMP_G_ON, 0x0017);
865  write_word (fd, LAMP_G_OFF, 0x0100);
866  write_word (fd, LAMP_B_ON, 0x0017);
867  write_word (fd, LAMP_B_OFF, 0x0100);
868  /* coming in, we've got 300dpi,
869     data px start : 0x004b
870     data px end  : 0x1437 for a total of 5100(13ec) 600-dpi pixels,
871     (8.5 inches) or 2550 300-dpi pixels (7653 bytes).
872     Interestingly, the scan head never moves, no matter how many rows
873     are read. */
874  s->width = 2551;
875  s->height = 1;
876  s->flags = FLG_BUF | FLG_NO_INTERLEAVE;
877  s->buf = malloc (s->width * s->height * 3);
878  /* FIXME do something with this data */
879  CHK (do_scan (s));
880
881  /* Lighting */
882  /* medium */
883  write_word (fd, LAMP_R_ON, 0x0017);
884  write_word (fd, LAMP_R_OFF, 0x0200);
885  write_word (fd, LAMP_G_ON, 0x0017);
886  write_word (fd, LAMP_G_OFF, 0x01d7 /* also 01db */ );
887  write_word (fd, LAMP_B_ON, 0x0017);
888  write_word (fd, LAMP_B_OFF, 0x01af /* also 01b2 */ );
889  /* FIXME do something with this data */
890  CHK (do_scan (s));
891
892  /* Lighting */
893  /* bright */
894  write_word (fd, LAMP_R_ON, 0x0017);
895  write_word (fd, LAMP_R_OFF, 0x0e8e /* also 1040 */ );
896  write_word (fd, LAMP_G_ON, 0x0017);
897  write_word (fd, LAMP_G_OFF, 0x0753 /* also 0718 */ );
898  write_word (fd, LAMP_B_ON, 0x0017);
899  write_word (fd, LAMP_B_OFF, 0x03f8 /* also 040d */ );
900  /* FIXME do something with this data */
901  CHK (do_scan (s));
902  free (s->buf);
903  s->buf = NULL;
904
905  /* The trace gets a little iffy from here on out since the log files
906     are missing different urb's.  This is kind of a puzzled-out
907     compilation. */
908
909  write_byte (fd, MICROSTEP, 0x13 /* pins active */ );
910  write_byte (fd, STEP_PWM, 0x3f);
911  read_byte (fd, STATUS, &result);	/* wants 0c */
912
913  /* Stepper home */
914  write_byte (fd, COMMAND, 0x02);
915  /* Step size */
916  write_word (fd, STEP_SIZE, 0x041a /* 300 dpi */ );
917  /* Skip steps */
918  write_word (fd, SKIP_STEPS, 0x0000);
919  /* Pause buffer levels */
920  write_byte (fd, BUFFER_LIMIT, 0x57);
921  /* Resume buffer levels */
922  write_byte (fd, BUFFER_RESUME, 0x02);
923
924  wait_for_return (fd);
925  /* stepper forward small */
926  write_byte (fd, COMMAND, 0x01);
927  read_byte (fd, STATUS, &result);	/* wants 0c */
928  usleep (200000);
929  write_byte (fd, STEP_PWM, 0x1f);
930
931  /* Read in cal strip at bottom of scanner (to adjust gain/offset
932     tables.  Note that this isn't the brightest lighting condition.)
933     At 300 dpi: black rows 0-25; white rows 30-75; beginning
934     of glass 90.
935     This produces 574k of data, so save it to a temp file. */
936  if (!s->fname)
937    {
938      DBG (1, "No temp filename!\n");
939      s->fname = strdup ("/tmp/cal.XXXXXX");
940
941      /* FIXME: we should be using fd, not discarding it, and also checking for error! */
942      int fd = mkstemp (s->fname);
943      close(fd);
944    }
945  s->width = 2551;
946  s->height = 75;
947  s->flags = FLG_PPM_HEADER | FLG_NO_INTERLEAVE;
948  CHK (do_scan (s));
949  compute_ogn (s->fname);
950  unlink (s->fname);
951
952  write_byte (fd, STEP_PWM, 0x3f);
953  /* stepper home */
954  write_byte (fd, COMMAND, 0x02);
955
956  /* discard the remaining data */
957  read_byte (fd, IMAGE_DATA_AVAIL, &result);	/* wants 42,4c */
958  if (result > 1)
959    {
960      read_bulk_size (fd, result, 0, 0, 0);
961      DBG (11, "read %dk extra\n", result);
962    }
963  read_byte (fd, 0x69, &result);	/* wants 02 */
964  write_byte (fd, 0x69, 0x0a);
965
966  lights_out (fd);
967  init (fd);
968
969#if 0
970  /* Repeatedly send this every 1 second.  Button scan?  FIXME */
971  gl640ReadReq (fd, GL640_GPIO_READ, &result);	/* wants 00 */
972#endif
973
974  return 0;
975}
976
977
978/* The number of regions in the calibration strip (black & white). */
979#define NREGIONS 2
980
981/* Compute the offset/gain table from the calibration strip.  This is
982   somewhat more complicated than necessary because I don't hard-code the
983   strip widths; I try to figure out the regions based on the scan data.
984   Theoretically, the region-finder should work for any number of distinct
985   regions (but there are only 2 on this scanner.)
986   This produces the CAL_FILE_OGN file, the final offset/gain table. */
987static SANE_Status
988compute_ogn (char *calfilename)
989{
990  byte *linebuf, *oldline, *newline;
991  mode_t oldmask;
992  FILE *fp;
993  int width, height, nlines = 0, region = -1, i, transition = 1, badcnt;
994  int pct;
995  int reglines[NREGIONS];
996  float *avg;
997  float max_range[3], tmp1, tmp2;
998
999  fp = fopen (calfilename, "r");
1000  if (!fp)
1001    {
1002      DBG (1, "open %s\n", calfilename);
1003      return SANE_STATUS_EOF;
1004    }
1005  fscanf (fp, "P6 %d %d %*d ", &width, &height);
1006  DBG (12, "cal file %s %dx%d\n", calfilename, width, height);
1007  width = width * 3;		/* 1 byte each of r, g, b */
1008  /* make a buffer holding 2 lines of data */
1009  linebuf = calloc (width * 2, sizeof (linebuf[0]));
1010  /* first line is data read buffer */
1011  newline = linebuf;
1012  /* second line is a temporary holding spot in case the next line read
1013     is the black/white transition, in which case we'll disregard this
1014     one. */
1015  oldline = linebuf + width;
1016  /* column averages per region */
1017  avg = calloc (width * NREGIONS, sizeof (avg[0]));
1018
1019  while (nlines < height)
1020    {
1021      if (fread (newline, 1, width, fp) != (size_t) width)
1022	break;
1023      nlines++;
1024      /* Check if new line is majorly different than old.
1025         Criteria is 10 pixels differing by more than 10%. */
1026      badcnt = 0;
1027      for (i = 0; i < width; i++)
1028	{
1029	  pct = newline[i] - oldline[i];
1030	  /* Fix by M.Reinelt <reinelt@eunet.at>
1031	   * do NOT use 10% (think of a dark area with
1032	   * oldline=4 and newline=5, which is a change of 20% !!
1033	   * Use an absolute difference of 10 as criteria
1034	   */
1035	  if (pct < -10 || pct > 10)
1036	    {
1037	      badcnt++;
1038	      DBG (16, "pix%d[%d/%d] ", i, newline[i], oldline[i]);
1039	    }
1040	}
1041      DBG (13, "line %d changed %d\n", nlines, badcnt);
1042      if ((badcnt > 10) || (nlines == height))
1043	{
1044	  /* End of region.  Lines are different or end of data. */
1045	  transition++;
1046	  if (transition == 1)
1047	    DBG (12, "Region %d lines %d-%d\n",
1048		 region, nlines - reglines[region], nlines - 1);
1049	}
1050      else
1051	{
1052	  /* Lines are similar, so still in region.  */
1053	  if (transition)
1054	    {
1055	      /* There was just a transition, so this is the start of a
1056	         new region. */
1057	      region++;
1058	      if (region >= NREGIONS)
1059		/* Too many regions detected.  Err below. */
1060		break;
1061	      transition = 0;
1062	      reglines[region] = 0;
1063	    }
1064	  /* Add oldline to the current region's average */
1065	  for (i = 0; i < width; i++)
1066	    avg[i + region * width] += oldline[i];
1067	  reglines[region]++;
1068	}
1069      /* And newline becomes old */
1070      memcpy (oldline, newline, width);
1071    }
1072  fclose (fp);
1073  free (linebuf);
1074  region++;			/* now call it number of regions instead of index */
1075  DBG (11, "read %d lines as %d regions\n", nlines, region);
1076
1077  /* Check to see if we screwed up */
1078  if (region != NREGIONS)
1079    {
1080      DBG (1, "Warning: gain/offset compute failed.\n"
1081	   "Found %d regions instead of %d.\n", region, NREGIONS);
1082      for (i = 0; i < region; i++)
1083	DBG (1, "   Region %d: %d lines\n",
1084	     i, (i >= NREGIONS) ? -1 : reglines[i]);
1085      free (avg);
1086      return SANE_STATUS_UNSUPPORTED;
1087    }
1088
1089  /* Now we've got regions and sums.  Find averages and range. */
1090  max_range[0] = max_range[1] = max_range[2] = 0.0;
1091  for (i = 0; i < width; i++)
1092    {
1093      /* Convert sums to averages */
1094      /* black region */
1095      tmp1 = avg[i] /= reglines[0];
1096      /* white region */
1097      tmp2 = avg[i + width] /= reglines[1];
1098      /* Track largest range for each color.
1099         If image is interleaved, use 'i%3', if not, 'i/(width/3)' */
1100      if ((tmp2 - tmp1) > max_range[i / (width / 3)])
1101	{
1102	  max_range[i / (width / 3)] = tmp2 - tmp1;
1103	  DBG (14, "max %d@%d %f-%f=%f\n",
1104	       i / (width / 3), i, tmp2, tmp1, tmp2 - tmp1);
1105	}
1106    }
1107  DBG (13, "max range r %f\n", max_range[0]);
1108  DBG (13, "max range g %f\n", max_range[1]);
1109  DBG (13, "max range b %f\n", max_range[2]);
1110
1111  /* Set umask to world r/w so other users can overwrite common cal... */
1112  oldmask = umask (0);
1113  fp = fopen (CAL_FILE_OGN, "w");
1114  /* ... and set it back. */
1115  umask (oldmask);
1116  if (!fp)
1117    {
1118      DBG (1, "open " CAL_FILE_OGN);
1119      free (avg);
1120      return SANE_STATUS_IO_ERROR;
1121    }
1122
1123  /* Finally, compute offset and gain */
1124  for (i = 0; i < width; i++)
1125    {
1126      int gain, offset;
1127      byte ogn[2];
1128
1129      /* skip line termination flags */
1130      if (!((i + 1) % (width / 3)))
1131	{
1132	  DBG (13, "skip scanline EOL %d/%d\n", i, width);
1133	  continue;
1134	}
1135
1136      /* Gain multiplier:
1137         255 : 1.5 times brighter
1138         511 : 2 times brighter
1139         1023: 3 times brighter */
1140#if 1
1141      /* Original gain/offset */
1142      gain = 512 * ((max_range[i / (width / 3)] /
1143		     (avg[i + width] - avg[i])) - 1);
1144      offset = avg[i];
1145#else
1146      /* This doesn't work for some people.  For instance, a negative
1147         offset would be bad.  */
1148
1149      /* Enhanced offset and gain calculation by M.Reinelt <reinelt@eunet.at>
1150       * These expressions were found by an iterative calibration process,
1151       * by changing gain and offset values for every pixel until the desired
1152       * values for black and white were reached, and finding an approximation
1153       * formula.
1154       * Note that offset is linear, but gain isn't!
1155       */
1156      offset = (double)3.53 * avg[i] - 125;
1157      gain = (double)3861.0 * exp(-0.0168 * (avg[i + width] - avg[i]));
1158#endif
1159
1160      DBG (14, "%d wht=%f blk=%f diff=%f gain=%d offset=%d\n", i,
1161	   avg[i + width], avg[i], avg[i + width] - avg[i], gain, offset);
1162      /* 10-bit gain, 6-bit offset (subtractor) in two bytes */
1163      ogn[0] = (byte) (((offset << 2) + (gain >> 8)) & 0xFF);
1164      ogn[1] = (byte) (gain & 0xFF);
1165      fwrite (ogn, sizeof (byte), 2, fp);
1166      /* Annoyingly, we seem to use ogn data at 600dpi, while we scanned
1167         at 300, so double our file.  Much easier than doubling at the
1168         read. */
1169      fwrite (ogn, sizeof (byte), 2, fp);
1170    }
1171
1172  fclose (fp);
1173  free (avg);
1174  return SANE_STATUS_GOOD;
1175}
1176
1177static int
1178check_ogn_file (void)
1179{
1180  FILE *fp;
1181  fp = fopen (CAL_FILE_OGN, "r");
1182  if (fp)
1183    {
1184      fclose (fp);
1185      return 1;
1186    }
1187  return 0;
1188}
1189
1190/* Load or fake the offset/gain table */
1191static void
1192install_ogn (int fd)
1193{
1194  int temp;
1195  byte *buf;
1196  FILE *fp;
1197
1198  /* 8.5in at 600dpi = 5104 pixels in scan head
1199     10-bit gain + 6-bit offset = 2 bytes per pixel, so 10208 bytes */
1200  buf = malloc (10208);
1201
1202  fp = fopen (CAL_FILE_OGN, "r");
1203  if (fp)
1204    {
1205      fread (buf, 2, 5100, fp);
1206      /* screw the last 4 pixels */
1207    }
1208  else
1209    {
1210      /* Make up the gain/offset data. */
1211#define GAIN 256		/* 1.5x */
1212#define OFFSET 0
1213      for (temp = 0; temp < 10208; temp += 2)
1214	{
1215	  buf[temp] = (byte) ((OFFSET << 2) + (GAIN >> 8));
1216	  buf[temp + 1] = (byte) (GAIN & 0xFF);
1217	}
1218    }
1219  /* Gain/offset table (r,g,b) */
1220  write_byte (fd, DATAPORT_TARGET, DP_R | DP_OFFSET);
1221  write_word (fd, DATAPORT_ADDR, DP_WRITE);
1222  write_bulk (fd, DATAPORT, buf, 10208);
1223  if (fp)
1224    fread (buf, 2, 5100, fp);
1225  write_byte (fd, DATAPORT_TARGET, DP_G | DP_OFFSET);
1226  write_word (fd, DATAPORT_ADDR, DP_WRITE);
1227  write_bulk (fd, DATAPORT, buf, 10208);
1228  if (fp)
1229    {
1230      fread (buf, 2, 5100, fp);
1231      fclose (fp);
1232    }
1233  write_byte (fd, DATAPORT_TARGET, DP_B | DP_OFFSET);
1234  write_word (fd, DATAPORT_ADDR, DP_WRITE);
1235  write_bulk (fd, DATAPORT, buf, 10208);
1236
1237  free (buf);
1238  return;
1239}
1240
1241
1242/* Scan sequence */
1243/* resolution is 75,150,300,600,1200
1244   scan coordinates in 600-dpi pixels */
1245static SANE_Status
1246scan (CANON_Handle * opt)
1247{
1248  SANE_Status status;
1249  const int left_edge = 0x004b;	/* Just for my scanner, or is this
1250				   universal?  Calibrate? */
1251  int temp;
1252  int fd = opt->fd;
1253  byte result;
1254  byte *buf;
1255
1256  /* Check status. (not in w2k driver) */
1257  read_byte (fd, STATUS, &result);	/* wants 2f or 2d */
1258  if (!(result & STATUS_HOME) /*0x2d */ )
1259    return SANE_STATUS_DEVICE_BUSY;
1260  /* or force it to return?
1261     write_byte(fd, COMMAND, 0x02);
1262     wait_for_return(fd);
1263   */
1264
1265  /* reserved? */
1266  read_byte (fd, 0x69, &result);	/* wants 0a */
1267
1268  read_byte (fd, STATUS, &result);	/* wants 0e */
1269  read_byte (fd, PAPER_SENSOR, &result);	/* wants 2b */
1270  write_byte (fd, PAPER_SENSOR, 0x2b);
1271  /* Color mode:
1272     1-Channel Line Rate Color 0x15.
1273     1-Channel Grayscale 0x14 (and we skip some of these tables) */
1274  write_byte (fd, COLOR_MODE, 0x15);
1275
1276  /* install the offset/gain table */
1277  install_ogn (fd);
1278
1279  read_byte (fd, STATUS, &result);	/* wants 0e */
1280  /* move forward to "glass 0" */
1281  write_byte (fd, COMMAND, 0x01);
1282  read_byte (fd, STATUS, &result);	/* wants 0c */
1283
1284  /* create gamma table */
1285  buf = malloc (0x400);
1286  for (temp = 0; temp < 0x0400; temp++)
1287    /* gamma calculation by M.Reinelt <reinelt@eunet.at> */
1288    buf[temp] = (double) 255.0 * exp(log((temp + 0.5) / 1023.0) / opt->gamma)
1289	+ 0.5;
1290
1291  /* Gamma R, write and verify */
1292  write_byte (fd, DATAPORT_TARGET, DP_R | DP_GAMMA);
1293  write_word (fd, DATAPORT_ADDR, DP_WRITE);
1294  write_bulk (fd, DATAPORT, buf, 0x0400);
1295  write_byte (fd, DATAPORT_TARGET, DP_R | DP_GAMMA);
1296  write_word (fd, DATAPORT_ADDR, DP_READ);
1297  read_bulk (fd, DATAPORT, buf, 0x0400);
1298  /* Gamma G */
1299  write_byte (fd, DATAPORT_TARGET, DP_G | DP_GAMMA);
1300  write_word (fd, DATAPORT_ADDR, DP_WRITE);
1301  write_bulk (fd, DATAPORT, buf, 0x0400);
1302  write_byte (fd, DATAPORT_TARGET, DP_G | DP_GAMMA);
1303  write_word (fd, DATAPORT_ADDR, DP_READ);
1304  read_bulk (fd, DATAPORT, buf, 0x0400);
1305  /* Gamma B */
1306  write_byte (fd, DATAPORT_TARGET, DP_B | DP_GAMMA);
1307  write_word (fd, DATAPORT_ADDR, DP_WRITE);
1308  write_bulk (fd, DATAPORT, buf, 0x0400);
1309  write_byte (fd, DATAPORT_TARGET, DP_B | DP_GAMMA);
1310  write_word (fd, DATAPORT_ADDR, DP_READ);
1311  read_bulk (fd, DATAPORT, buf, 0x0400);
1312  free (buf);
1313
1314  write_byte (fd, CLOCK_DIV, 0x04);
1315  /* Resolution: dpi 75(ie) 100,150(1c) 200,300(1a) 600,1200(18) */
1316  switch (opt->resolution)
1317    {
1318    case 150:
1319      write_byte (fd, 0x09, 0x1c);
1320      break;
1321    case 300:
1322      write_byte (fd, 0x09, 0x1a);
1323      break;
1324    case 600:
1325    case 1200:
1326      /* actually 600 dpi horiz max */
1327      write_byte (fd, 0x09, 0x18);
1328      break;
1329    default:			/* 75 */
1330      write_byte (fd, 0x09, 0x1e);
1331      opt->resolution = 75;
1332    }
1333
1334  write_word (fd, ACTIVE_PX_START, left_edge);
1335  /* Data pixel start.  Measured at 600dpi regardless of
1336     scan resolution.  0-position is 0x004b */
1337  write_word (fd, DATA_PX_START, left_edge + opt->x1);
1338  /* Data pixel end.  Measured at 600dpi regardless of scan
1339     resolution. */
1340  write_word (fd, DATA_PX_END, left_edge + opt->x2);
1341  /* greyscale has 14,03, different lights */
1342  write_byte (fd, COLOR_MODE, 0x15);
1343  write_byte (fd, 0x29, 0x02);
1344  /* Lights */
1345  write_word (fd, LAMP_R_ON, 0x0017);
1346  /* "Hi-low color" selection from windows driver.  low(1437) hi(1481) */
1347  write_word (fd, LAMP_R_OFF, 0x1437);
1348  write_word (fd, LAMP_G_ON, 0x0017);
1349  write_word (fd, LAMP_G_OFF, 0x094e);
1350  write_word (fd, LAMP_B_ON, 0x0017);
1351  write_word (fd, LAMP_B_OFF, 0x0543);
1352
1353  /* Analog static offset R,G,B.  Greyscale has 0,0,0 */
1354  write_byte (fd, 0x38, 0x3f);
1355  write_byte (fd, 0x39, 0x3f);
1356  write_byte (fd, 0x3a, 0x3f);
1357  /* Analog static gain R,G,B (normally 0x01) */
1358  write_byte (fd, 0x3b, opt->gain);
1359  write_byte (fd, 0x3c, opt->gain);
1360  write_byte (fd, 0x3d, opt->gain);
1361  /* Digital gain/offset settings.  Greyscale has 0 */
1362  write_byte (fd, 0x3e, 0x1a);
1363
1364  {
1365    /* Stepper motion setup. */
1366    int stepsize, faststep = 0x0104, reverse = 0x28, phase, pwm = 0x1f;
1367    switch (opt->resolution)
1368      {
1369      case 75:
1370	stepsize = 0x0106;
1371	faststep = 0x0106;
1372	reverse = 0;
1373	phase = 0x39a8;
1374	pwm = 0x3f;
1375	break;
1376      case 150:
1377	stepsize = 0x020d;
1378	phase = 0x3198;
1379	break;
1380      case 300:
1381	stepsize = 0x041a;
1382	phase = 0x2184;
1383	break;
1384      case 600:
1385	stepsize = 0x0835;
1386	phase = 0x0074;
1387	break;
1388      case 1200:
1389	/* 1200 dpi y only, x is 600 dpi */
1390	stepsize = 0x106b;
1391	phase = 0x41ac;
1392	break;
1393      default:
1394	DBG (1, "BAD RESOLUTION");
1395	return SANE_STATUS_UNSUPPORTED;
1396      }
1397
1398    write_word (fd, STEP_SIZE, stepsize);
1399    write_word (fd, FAST_STEP, faststep);
1400    /* There sounds like a weird step disjoint at the end of skipsteps
1401       at 75dpi, so I think that's why skipsteps=0 at 75dpi in the
1402       Windows driver.  It still works at the normal 0x017a though. */
1403    /* cal strip is 0x17a steps, plus 2 300dpi microsteps per pixel */
1404    write_word (fd, SKIP_STEPS, 0x017a /* cal strip */  + opt->y1 * 2);
1405    /* FIXME could be 0x57, why not? */
1406    write_byte (fd, BUFFER_LIMIT, 0x20);
1407    write_byte (fd, BUFFER_RESUME, 0x02);
1408    write_byte (fd, REVERSE_STEPS, reverse);
1409    /* motor resume phasing */
1410    write_word (fd, 0x52, phase);
1411    write_byte (fd, STEP_PWM, pwm);
1412  }
1413
1414  read_byte (fd, PAPER_SENSOR, &result);	/* wants 2b */
1415  write_byte (fd, PAPER_SENSOR, 0x0b);
1416
1417  opt->width = (opt->x2 - opt->x1) * opt->resolution / 600 + 1;
1418  opt->height = (opt->y2 - opt->y1) * opt->resolution / 600;
1419  opt->flags = 0;
1420  DBG (1, "width=%d height=%d dpi=%d\n", opt->width, opt->height,
1421       opt->resolution);
1422  CHK (do_scan (opt));
1423
1424  read_byte (fd, PAPER_SENSOR, &result);	/* wants 0b */
1425  write_byte (fd, PAPER_SENSOR, 0x2b);
1426  write_byte (fd, STEP_PWM, 0x3f);
1427
1428  lights_out (fd);
1429  /* home */
1430  write_byte (fd, COMMAND, 0x02);
1431
1432  return status;
1433}
1434
1435
1436static SANE_Status
1437CANON_set_scan_parameters (CANON_Handle * scan,
1438			   const int forceCal,
1439			   const int gray,
1440			   const int left,
1441			   const int top,
1442			   const int right,
1443			   const int bottom,
1444			   const int res,
1445			   const int gain,
1446			   const double gamma)
1447{
1448  DBG (2, "CANON_set_scan_parameters:\n");
1449  DBG (2, "cal   = %d\n", forceCal);
1450  DBG (2, "gray  = %d (ignored)\n", gray);
1451  DBG (2, "res   = %d\n", res);
1452  DBG (2, "gain  = %d\n", gain);
1453  DBG (2, "gamma = %f\n", gamma);
1454  DBG (2, "in 600dpi pixels:\n");
1455  DBG (2, "left  = %d, top    = %d\n", left, top);
1456  DBG (2, "right = %d, bottom = %d\n", right, bottom);
1457
1458  /* Validate the input parameters */
1459  if ((left < 0) || (right > CANON_MAX_WIDTH))
1460    return SANE_STATUS_INVAL;
1461
1462  if ((top < 0) || (bottom > CANON_MAX_HEIGHT))
1463    return SANE_STATUS_INVAL;
1464
1465  if (((right - left) < 10) || ((bottom - top) < 10))
1466    return SANE_STATUS_INVAL;
1467
1468  if ((res != 75) && (res != 150) && (res != 300)
1469      && (res != 600) && (res != 1200))
1470    return SANE_STATUS_INVAL;
1471
1472  if ((gain < 0) || (gain > 64))
1473    return SANE_STATUS_INVAL;
1474
1475  if (gamma <= 0.0)
1476    return SANE_STATUS_INVAL;
1477
1478  /* Store params */
1479  scan->resolution = res;
1480  scan->x1 = left;
1481  scan->x2 = right - /* subtract 1 pixel */ 600 / scan->resolution;
1482  scan->y1 = top;
1483  scan->y2 = bottom;
1484  scan->gain = gain;
1485  scan->gamma = gamma;
1486  scan->flags = forceCal ? FLG_FORCE_CAL : 0;
1487
1488  return SANE_STATUS_GOOD;
1489}
1490
1491
1492static SANE_Status
1493CANON_close_device (CANON_Handle * scan)
1494{
1495  DBG (3, "CANON_close_device:\n");
1496  sanei_usb_close (scan->fd);
1497  return SANE_STATUS_GOOD;
1498}
1499
1500
1501static SANE_Status
1502CANON_open_device (CANON_Handle * scan, const char *dev)
1503{
1504  SANE_Word vendor;
1505  SANE_Word product;
1506  SANE_Status res;
1507
1508  DBG (3, "CANON_open_device: `%s'\n", dev);
1509
1510  scan->fname = NULL;
1511  scan->fp = NULL;
1512  scan->flags = 0;
1513
1514  res = sanei_usb_open (dev, &scan->fd);
1515  if (res != SANE_STATUS_GOOD)
1516    {
1517      DBG (1, "CANON_open_device: couldn't open device `%s': %s\n", dev,
1518	   sane_strstatus (res));
1519      return res;
1520    }
1521
1522#ifndef NO_AUTODETECT
1523  /* We have opened the device. Check that it is a USB scanner. */
1524  if (sanei_usb_get_vendor_product (scan->fd, &vendor, &product) !=
1525      SANE_STATUS_GOOD)
1526    {
1527      DBG (1, "CANON_open_device: sanei_usb_get_vendor_product failed\n");
1528      /* This is not a USB scanner, or SANE or the OS doesn't support it. */
1529      sanei_usb_close (scan->fd);
1530      scan->fd = -1;
1531      return SANE_STATUS_UNSUPPORTED;
1532    }
1533
1534  /* Make sure we have a CANON scanner */
1535  if ((vendor != 0x04a9) || (product != 0x2204))
1536    {
1537      DBG (1, "CANON_open_device: incorrect vendor/product (0x%x/0x%x)\n",
1538	   vendor, product);
1539      sanei_usb_close (scan->fd);
1540      scan->fd = -1;
1541      return SANE_STATUS_UNSUPPORTED;
1542    }
1543#endif
1544
1545  return SANE_STATUS_GOOD;
1546}
1547
1548
1549static const char *
1550CANON_get_device_name (CANON_Handle * scanner)
1551{
1552  (void) scanner;		/* Eliminate warning about unused parameters */
1553  return "Canoscan FB630U";
1554}
1555
1556
1557static SANE_Status
1558CANON_finish_scan (CANON_Handle * scanner)
1559{
1560  DBG (3, "CANON_finish_scan:\n");
1561  if (scanner->fp)
1562    fclose (scanner->fp);
1563  scanner->fp = NULL;
1564
1565  /* remove temp file */
1566  if (scanner->fname)
1567    {
1568      DBG (4, "removing temp file %s\n", scanner->fname);
1569      unlink (scanner->fname);
1570      free (scanner->fname);
1571    }
1572  scanner->fname = NULL;
1573
1574  return SANE_STATUS_GOOD;
1575}
1576
1577
1578static SANE_Status
1579CANON_start_scan (CANON_Handle * scanner)
1580{
1581  int rv;
1582  SANE_Status status;
1583  DBG (3, "CANON_start_scan called\n");
1584
1585  /* choose a temp file name for scan data */
1586  scanner->fname = strdup ("/tmp/scan.XXXXXX");
1587
1588  /* FIXME: we should be using fd, not discarding it! */
1589  int fd = mkstemp (scanner->fname);
1590  if (fd == -1)
1591    return SANE_STATUS_IO_ERROR;
1592  close(fd);
1593
1594  /* calibrate if needed */
1595  rv = init (scanner->fd);
1596  if (rv < 0) {
1597      DBG(1, "Can't talk on USB.\n");
1598      return SANE_STATUS_IO_ERROR;
1599  }
1600  if ((rv == 1)
1601      || !check_ogn_file ()
1602      || (scanner->flags & FLG_FORCE_CAL)) {
1603      plugin_cal (scanner);
1604      wait_for_return (scanner->fd);
1605  }
1606
1607  /* scan */
1608  if ((status = scan (scanner)) != SANE_STATUS_GOOD)
1609    {
1610      CANON_finish_scan (scanner);
1611      return status;
1612    }
1613
1614  /* read the temp file back out */
1615  scanner->fp = fopen (scanner->fname, "r");
1616  DBG (4, "reading %s\n", scanner->fname);
1617  if (!scanner->fp)
1618    {
1619      DBG (1, "open %s", scanner->fname);
1620      return SANE_STATUS_IO_ERROR;
1621    }
1622  return SANE_STATUS_GOOD;
1623}
1624
1625
1626static SANE_Status
1627CANON_read (CANON_Handle * scanner, SANE_Byte * data,
1628	    SANE_Int max_length, SANE_Int * length)
1629{
1630  SANE_Status status;
1631  int red_len;
1632
1633  DBG (5, "CANON_read called\n");
1634  if (!scanner->fp)
1635    return SANE_STATUS_INVAL;
1636  red_len = fread (data, 1, max_length, scanner->fp);
1637  /* return some data */
1638  if (red_len > 0)
1639    {
1640      *length = red_len;
1641      DBG (5, "CANON_read returned (%d/%d)\n", *length, max_length);
1642      return SANE_STATUS_GOOD;
1643    }
1644
1645  /* EOF or file err */
1646  *length = 0;
1647  if (feof (scanner->fp))
1648    {
1649      DBG (4, "EOF\n");
1650      status = SANE_STATUS_EOF;
1651    }
1652  else
1653    {
1654      DBG (4, "IO ERR\n");
1655      status = SANE_STATUS_IO_ERROR;
1656    }
1657
1658  CANON_finish_scan (scanner);
1659  DBG (5, "CANON_read returned (%d/%d)\n", *length, max_length);
1660  return status;
1661}
1662