1 /* sane - Scanner Access Now Easy.
2 
3    Copyright (C) 2007-2012 stef.dev@free.fr
4 
5    This file is part of the SANE package.
6 
7    This program is free software; you can redistribute it and/or
8    modify it under the terms of the GNU General Public License as
9    published by the Free Software Foundation; either version 2 of the
10    License, or (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <https://www.gnu.org/licenses/>.
19 
20    As a special exception, the authors of SANE give permission for
21    additional uses of the libraries contained in this release of SANE.
22 
23    The exception is that, if you link a SANE library with other files
24    to produce an executable, this does not by itself cause the
25    resulting executable to be covered by the GNU General Public
26    License.  Your use of that executable is in no way restricted on
27    account of linking the SANE library code into it.
28 
29    This exception does not, however, invalidate any other reasons why
30    the executable file might be covered by the GNU General Public
31    License.
32 
33    If you submit changes to SANE to the maintainers to be included in
34    a subsequent release, you agree by submitting the changes that
35    those changes may be distributed with this exception intact.
36 
37    If you write modifications of your own for SANE, it is your choice
38    whether to permit this exception to apply to your modifications.
39    If you do not wish that, delete this exception notice.
40 */
41 
42 /* this file contains functions common to rts88xx ASICs */
43 
44 #undef BACKEND_NAME
45 #define BACKEND_NAME rts88xx_lib
46 
47 #include "../include/sane/config.h"
48 #include "../include/sane/sane.h"
49 #include "../include/sane/sanei_backend.h"
50 #include "../include/sane/sanei_usb.h"
51 #include "rts88xx_lib.h"
52 
53 #include <stdio.h>
54 #include <sys/time.h>
55 #include <sys/types.h>
56 
57 #include "../include/_stdint.h"
58 
59 #define RTS88XX_LIB_BUILD 30
60 
61 /* init rts88xx library */
62 void
sanei_rts88xx_lib_init(void)63 sanei_rts88xx_lib_init (void)
64 {
65   DBG_INIT ();
66   DBG (DBG_info, "RTS88XX library, version %d.%d-%d\n", SANE_CURRENT_MAJOR, V_MINOR,
67        RTS88XX_LIB_BUILD);
68 }
69 
70 /*
71  * registers helpers to avoid direct access
72  */
73 SANE_Bool
sanei_rts88xx_is_color(SANE_Byte * regs)74 sanei_rts88xx_is_color (SANE_Byte * regs)
75 {
76   if ((regs[0x2f] & 0x11) == 0x11)
77     return SANE_TRUE;
78   return SANE_FALSE;
79 }
80 
81 void
sanei_rts88xx_set_gray_scan(SANE_Byte * regs)82 sanei_rts88xx_set_gray_scan (SANE_Byte * regs)
83 {
84   regs[0x2f] = (regs[0x2f] & 0x0f) | 0x20;
85 }
86 
87 void
sanei_rts88xx_set_color_scan(SANE_Byte * regs)88 sanei_rts88xx_set_color_scan (SANE_Byte * regs)
89 {
90   regs[0x2f] = (regs[0x2f] & 0x0f) | 0x10;
91 }
92 
93 void
sanei_rts88xx_set_offset(SANE_Byte * regs,SANE_Byte red,SANE_Byte green,SANE_Byte blue)94 sanei_rts88xx_set_offset (SANE_Byte * regs, SANE_Byte red, SANE_Byte green,
95                           SANE_Byte blue)
96 {
97   /* offset for odd pixels */
98   regs[0x02] = red;
99   regs[0x03] = green;
100   regs[0x04] = blue;
101 
102   /* offset for even pixels */
103   regs[0x05] = red;
104   regs[0x06] = green;
105   regs[0x07] = blue;
106 }
107 
108 void
sanei_rts88xx_set_gain(SANE_Byte * regs,SANE_Byte red,SANE_Byte green,SANE_Byte blue)109 sanei_rts88xx_set_gain (SANE_Byte * regs, SANE_Byte red, SANE_Byte green,
110                         SANE_Byte blue)
111 {
112   regs[0x08] = red;
113   regs[0x09] = green;
114   regs[0x0a] = blue;
115 }
116 
117 void
sanei_rts88xx_set_scan_frequency(SANE_Byte * regs,int frequency)118 sanei_rts88xx_set_scan_frequency (SANE_Byte * regs, int frequency)
119 {
120   regs[0x64] = (regs[0x64] & 0xf0) | (frequency & 0x0f);
121 }
122 
123 /*
124  * read one register at given index
125  */
126 SANE_Status
sanei_rts88xx_read_reg(SANE_Int devnum,SANE_Int index,SANE_Byte * reg)127 sanei_rts88xx_read_reg (SANE_Int devnum, SANE_Int index, SANE_Byte * reg)
128 {
129   SANE_Status status = SANE_STATUS_GOOD;
130   unsigned char cmd[] = { 0x80, 0x00, 0x00, 0x01 };
131   size_t size;
132 
133   cmd[1] = index;
134 
135   size = 4;
136   status = sanei_usb_write_bulk (devnum, cmd, &size);
137   if (status != SANE_STATUS_GOOD)
138     {
139       DBG (DBG_error, "sanei_rts88xx_read_reg: bulk write failed\n");
140       return status;
141     }
142   size = 1;
143   status = sanei_usb_read_bulk (devnum, reg, &size);
144   if (status != SANE_STATUS_GOOD)
145     {
146       DBG (DBG_error, "sanei_rts88xx_read_reg: bulk read failed\n");
147       return status;
148     }
149   DBG (DBG_io2, "sanei_rts88xx_read_reg: reg[0x%02x]=0x%02x\n", index, *reg);
150   return status;
151 }
152 
153 /*
154  * write one register at given index
155  */
156 SANE_Status
sanei_rts88xx_write_reg(SANE_Int devnum,SANE_Int index,SANE_Byte * reg)157 sanei_rts88xx_write_reg (SANE_Int devnum, SANE_Int index, SANE_Byte * reg)
158 {
159   SANE_Status status = SANE_STATUS_GOOD;
160   unsigned char cmd[] = { 0x88, 0x00, 0x00, 0x01, 0xff };
161   size_t size;
162 
163   cmd[1] = index;
164   cmd[4] = *reg;
165 
166   size = 5;
167   status = sanei_usb_write_bulk (devnum, cmd, &size);
168   if (status != SANE_STATUS_GOOD)
169     {
170       DBG (DBG_error, "sanei_rts88xx_write_reg: bulk write failed\n");
171       return status;
172     }
173   DBG (DBG_io2, "sanei_rts88xx_write_reg: reg[0x%02x]=0x%02x\n", index, *reg);
174   return status;
175 }
176 
177 /*
178  * write length consecutive registers, starting at index
179  * register 0xb3 is never wrote in bulk register write, so we split
180  * write if it belongs to the register set sent
181  */
182 SANE_Status
sanei_rts88xx_write_regs(SANE_Int devnum,SANE_Int start,SANE_Byte * source,SANE_Int length)183 sanei_rts88xx_write_regs (SANE_Int devnum, SANE_Int start,
184                           SANE_Byte * source, SANE_Int length)
185 {
186   size_t size = 0;
187   size_t i;
188   SANE_Byte buffer[260];
189   char message[256 * 5];
190 
191   if (DBG_LEVEL > DBG_io)
192     {
193       for (i = 0; i < (size_t) length; i++)
194         {
195           sprintf (message + 5 * i, "0x%02x ", source[i]);
196         }
197       DBG (DBG_io, "sanei_rts88xx_write_regs : write_regs(0x%02x,%d)=%s\n",
198            start, length, message);
199     }
200 
201   /* when writing several registers at a time, we avoid writing the 0xb3 register
202    * which is used to control the status of the scanner */
203   if ((start + length > 0xb3) && (length > 1))
204     {
205       size = 0xb3 - start;
206       buffer[0] = 0x88;
207       buffer[1] = start;
208       buffer[2] = 0x00;
209       buffer[3] = size;
210       for (i = 0; i < size; i++)
211         buffer[i + 4] = source[i];
212       /* the USB block is size + 4 bytes of header long */
213       size += 4;
214       if (sanei_usb_write_bulk (devnum, buffer, &size) != SANE_STATUS_GOOD)
215         {
216           DBG (DBG_error,
217                "sanei_rts88xx_write_regs : write registers part 1 failed ...\n");
218           return SANE_STATUS_IO_ERROR;
219         }
220 
221       /* skip 0xb3 register */
222       size -= 3;
223       start = 0xb4;
224       source = source + size;
225     }
226   size = length - size;
227   buffer[0] = 0x88;
228   buffer[1] = start;
229   buffer[2] = 0x00;
230   buffer[3] = size;
231   for (i = 0; i < size; i++)
232     buffer[i + 4] = source[i];
233   /* the USB block is size + 4 bytes of header long */
234   size += 4;
235   if (sanei_usb_write_bulk (devnum, buffer, &size) != SANE_STATUS_GOOD)
236     {
237       DBG (DBG_error,
238            "sanei_rts88xx_write_regs : write registers part 2 failed ...\n");
239       return SANE_STATUS_IO_ERROR;
240     }
241 
242   return SANE_STATUS_GOOD;
243 
244 }
245 
246 /* read several registers starting at the given index */
247 SANE_Status
sanei_rts88xx_read_regs(SANE_Int devnum,SANE_Int start,SANE_Byte * dest,SANE_Int length)248 sanei_rts88xx_read_regs (SANE_Int devnum, SANE_Int start,
249                          SANE_Byte * dest, SANE_Int length)
250 {
251   SANE_Status status;
252   static SANE_Byte command_block[] = { 0x80, 0, 0x00, 0xFF };
253   size_t size, i;
254   char message[256 * 5];
255 
256   if (start + length > 255)
257     {
258       DBG (DBG_error,
259            "sanei_rts88xx_read_regs: start and length must be within [0..255]\n");
260       return SANE_STATUS_INVAL;
261     }
262 
263   /* write header */
264   size = 4;
265   command_block[1] = start;
266   command_block[3] = length;
267   status = sanei_usb_write_bulk (devnum, command_block, &size);
268   if (status != SANE_STATUS_GOOD)
269     {
270       DBG (DBG_error, "sanei_rts88xx_read_regs: failed to write header\n");
271       return status;
272     }
273 
274   /* read data */
275   size = length;
276   status = sanei_usb_read_bulk (devnum, dest, &size);
277   if (status != SANE_STATUS_GOOD)
278     {
279       DBG (DBG_error, "sanei_rts88xx_read_regs: failed to read data\n");
280       return status;
281     }
282   if (size != (size_t) length)
283     {
284       DBG (DBG_warn, "sanei_rts88xx_read_regs: read got only %lu bytes\n",
285            (u_long) size);
286     }
287   if (DBG_LEVEL >= DBG_io)
288     {
289       for (i = 0; i < size; i++)
290         sprintf (message + 5 * i, "0x%02x ", dest[i]);
291       DBG (DBG_io, "sanei_rts88xx_read_regs: read_regs(0x%02x,%d)=%s\n",
292            start, length, message);
293     }
294   return status;
295 }
296 
297 /*
298  * get status by reading registers 0x10 and 0x11
299  */
300 SANE_Status
sanei_rts88xx_get_status(SANE_Int devnum,SANE_Byte * regs)301 sanei_rts88xx_get_status (SANE_Int devnum, SANE_Byte * regs)
302 {
303   SANE_Status status;
304   status = sanei_rts88xx_read_regs (devnum, 0x10, regs + 0x10, 2);
305   DBG (DBG_io, "sanei_rts88xx_get_status: get_status()=0x%02x 0x%02x\n",
306        regs[0x10], regs[0x11]);
307   return status;
308 }
309 
310 /*
311  * set status by writing registers 0x10 and 0x11
312  */
313 SANE_Status
sanei_rts88xx_set_status(SANE_Int devnum,SANE_Byte * regs,SANE_Byte reg10,SANE_Byte reg11)314 sanei_rts88xx_set_status (SANE_Int devnum, SANE_Byte * regs,
315                           SANE_Byte reg10, SANE_Byte reg11)
316 {
317   SANE_Status status;
318 
319   regs[0x10] = reg10;
320   regs[0x11] = reg11;
321   status = sanei_rts88xx_write_regs (devnum, 0x10, regs + 0x10, 2);
322   DBG (DBG_io, "sanei_rts88xx_set_status: 0x%02x 0x%02x\n", regs[0x10],
323        regs[0x11]);
324   return status;
325 }
326 
327 /*
328  * get lamp status by reading registers 0x84 to 0x8f, only 0x8F is currently useful
329  * 0x84 and following could "on" timers
330  */
331 SANE_Status
sanei_rts88xx_get_lamp_status(SANE_Int devnum,SANE_Byte * regs)332 sanei_rts88xx_get_lamp_status (SANE_Int devnum, SANE_Byte * regs)
333 {
334   SANE_Status status;
335   status = sanei_rts88xx_read_regs (devnum, 0x84, regs + 0x84, 11);
336   return status;
337 }
338 
339 /* resets lamp */
340 SANE_Status
sanei_rts88xx_reset_lamp(SANE_Int devnum,SANE_Byte * regs)341 sanei_rts88xx_reset_lamp (SANE_Int devnum, SANE_Byte * regs)
342 {
343   SANE_Status status;
344   SANE_Byte reg;
345 
346   /* read the 0xda register, then clear lower nibble and write it back */
347   status = sanei_rts88xx_read_reg (devnum, 0xda, &reg);
348   if (status != SANE_STATUS_GOOD)
349     {
350       DBG (DBG_error,
351            "sanei_rts88xx_reset_lamp: failed to read 0xda register\n");
352       return status;
353     }
354   reg = 0xa0;
355   status = sanei_rts88xx_write_reg (devnum, 0xda, &reg);
356   if (status != SANE_STATUS_GOOD)
357     {
358       DBG (DBG_error,
359            "sanei_rts88xx_reset_lamp: failed to write 0xda register\n");
360       return status;
361     }
362 
363   /* on cleared, get status */
364   status = sanei_rts88xx_get_status (devnum, regs);
365   if (status != SANE_STATUS_GOOD)
366     {
367       DBG (DBG_error, "sanei_rts88xx_reset_lamp: failed to get status\n");
368       return status;
369     }
370   DBG (DBG_io, "sanei_rts88xx_reset_lamp: status=0x%02x 0x%02x\n", regs[0x10],
371        regs[0x11]);
372 
373   /* set low nibble to 7 and write it */
374   reg = reg | 0x07;
375   status = sanei_rts88xx_write_reg (devnum, 0xda, &reg);
376   if (status != SANE_STATUS_GOOD)
377     {
378       DBG (DBG_error,
379            "sanei_rts88xx_reset_lamp: failed to write 0xda register\n");
380       return status;
381     }
382   status = sanei_rts88xx_read_reg (devnum, 0xda, &reg);
383   if (status != SANE_STATUS_GOOD)
384     {
385       DBG (DBG_error,
386            "sanei_rts88xx_reset_lamp: failed to read 0xda register\n");
387       return status;
388     }
389   if (reg != 0xa7)
390     {
391       DBG (DBG_warn,
392            "sanei_rts88xx_reset_lamp: expected reg[0xda]=0xa7, got 0x%02x\n",
393            reg);
394     }
395 
396   /* store read value in shadow register */
397   regs[0xda] = reg;
398 
399   return status;
400 }
401 
402 /*
403  * get lcd status by reading registers 0x20, 0x21 and 0x22
404  */
405 SANE_Status
sanei_rts88xx_get_lcd(SANE_Int devnum,SANE_Byte * regs)406 sanei_rts88xx_get_lcd (SANE_Int devnum, SANE_Byte * regs)
407 {
408   SANE_Status status;
409   status = sanei_rts88xx_read_regs (devnum, 0x20, regs + 0x20, 3);
410   DBG (DBG_io, "sanei_rts88xx_get_lcd: 0x%02x 0x%02x 0x%02x\n", regs[0x20],
411        regs[0x21], regs[0x22]);
412   return status;
413 }
414 
415 /*
416  * write to special control register CONTROL_REG=0xb3
417  */
418 SANE_Status
sanei_rts88xx_write_control(SANE_Int devnum,SANE_Byte value)419 sanei_rts88xx_write_control (SANE_Int devnum, SANE_Byte value)
420 {
421   SANE_Status status;
422   status = sanei_rts88xx_write_reg (devnum, CONTROL_REG, &value);
423   return status;
424 }
425 
426 /*
427  * send the cancel control sequence
428  */
429 SANE_Status
sanei_rts88xx_cancel(SANE_Int devnum)430 sanei_rts88xx_cancel (SANE_Int devnum)
431 {
432   SANE_Status status;
433 
434   status = sanei_rts88xx_write_control (devnum, 0x02);
435   if (status != SANE_STATUS_GOOD)
436     return status;
437   status = sanei_rts88xx_write_control (devnum, 0x02);
438   if (status != SANE_STATUS_GOOD)
439     return status;
440   status = sanei_rts88xx_write_control (devnum, 0x00);
441   if (status != SANE_STATUS_GOOD)
442     return status;
443   status = sanei_rts88xx_write_control (devnum, 0x00);
444   return status;
445 }
446 
447 /*
448  * write the given number of bytes pointed by value into memory
449  * length is payload length
450  * extra is number of bytes to add to the usb write length
451  */
452 SANE_Status
sanei_rts88xx_write_mem(SANE_Int devnum,SANE_Int length,SANE_Int extra,SANE_Byte * value)453 sanei_rts88xx_write_mem (SANE_Int devnum, SANE_Int length, SANE_Int extra,
454                          SANE_Byte * value)
455 {
456   SANE_Status status;
457   SANE_Byte *buffer;
458   size_t i, size;
459   char message[(0xFFC0 + 10) * 3] = "";
460 
461   buffer = (SANE_Byte *) malloc (length + 10);
462   if (buffer == NULL)
463     return SANE_STATUS_NO_MEM;
464   memset (buffer, 0, length + 10);
465 
466   buffer[0] = 0x89;
467   buffer[1] = 0x00;
468   buffer[2] = HIBYTE (length);
469   buffer[3] = LOBYTE (length);
470   for (i = 0; i < (size_t) length; i++)
471     {
472       buffer[i + 4] = value[i];
473 
474       if (DBG_LEVEL > DBG_io2)
475         {
476           sprintf (message + 3 * i, "%02x ", buffer[i + 4]);
477         }
478     }
479   DBG (DBG_io, "sanei_rts88xx_write_mem: %02x %02x %02x %02x -> %s\n",
480        buffer[0], buffer[1], buffer[2], buffer[3], message);
481 
482   size = length + 4 + extra;
483   status = sanei_usb_write_bulk (devnum, buffer, &size);
484   free (buffer);
485   if ((status == SANE_STATUS_GOOD) && (size != (size_t) length + 4 + extra))
486     {
487       DBG (DBG_error,
488            "sanei_rts88xx_write_mem: only wrote %lu bytes out of %d\n",
489            (u_long) size, length + 4);
490       status = SANE_STATUS_IO_ERROR;
491     }
492   return status;
493 }
494 
495 /*
496  * set memory with the given data
497  */
498 SANE_Status
sanei_rts88xx_set_mem(SANE_Int devnum,SANE_Byte ctrl1,SANE_Byte ctrl2,SANE_Int length,SANE_Byte * value)499 sanei_rts88xx_set_mem (SANE_Int devnum, SANE_Byte ctrl1,
500                        SANE_Byte ctrl2, SANE_Int length, SANE_Byte * value)
501 {
502   SANE_Status status;
503   SANE_Byte regs[2];
504   regs[0] = ctrl1;
505   regs[1] = ctrl2;
506 
507   status = sanei_rts88xx_write_regs (devnum, 0x91, regs, 2);
508   if (status != SANE_STATUS_GOOD)
509     {
510       DBG (DBG_error,
511            "sanei_rts88xx_set_mem: failed to write 0x91/0x92 registers\n");
512       return status;
513     }
514   status = sanei_rts88xx_write_mem (devnum, length, 0, value);
515   if (status != SANE_STATUS_GOOD)
516     {
517       DBG (DBG_error, "sanei_rts88xx_set_mem: failed to write memory\n");
518     }
519   return status;
520 }
521 
522 /*
523  * read length bytes of memory into area pointed by value
524  */
525 SANE_Status
sanei_rts88xx_read_mem(SANE_Int devnum,SANE_Int length,SANE_Byte * value)526 sanei_rts88xx_read_mem (SANE_Int devnum, SANE_Int length, SANE_Byte * value)
527 {
528   SANE_Status status;
529   size_t size, read, want;
530   SANE_Byte header[4];
531 
532   /* build and write length header */
533   header[0] = 0x81;
534   header[1] = 0x00;
535   header[2] = HIBYTE (length);
536   header[3] = LOBYTE (length);
537   size = 4;
538   status = sanei_usb_write_bulk (devnum, header, &size);
539   if (status != SANE_STATUS_GOOD)
540     {
541       DBG (DBG_error,
542            "sanei_rts88xx_read_mem: failed to write length header\n");
543       return status;
544     }
545   DBG (DBG_io, "sanei_rts88xx_read_mem: %02x %02x %02x %02x -> ...\n",
546        header[0], header[1], header[2], header[3]);
547   read = 0;
548   while (length > 0)
549     {
550       if (length > 2048)
551         want = 2048;
552       else
553         want = length;
554       size = want;
555       status = sanei_usb_read_bulk (devnum, value + read, &size);
556       if (size != want)
557         {
558           DBG (DBG_error,
559                "sanei_rts88xx_read_mem: only read %lu bytes out of %lu\n",
560                (u_long) size, (u_long) want);
561           status = SANE_STATUS_IO_ERROR;
562         }
563       length -= size;
564       read += size;
565     }
566   return status;
567 }
568 
569 /*
570  * set memory with the given data
571  */
572 SANE_Status
sanei_rts88xx_get_mem(SANE_Int devnum,SANE_Byte ctrl1,SANE_Byte ctrl2,SANE_Int length,SANE_Byte * value)573 sanei_rts88xx_get_mem (SANE_Int devnum, SANE_Byte ctrl1,
574                        SANE_Byte ctrl2, SANE_Int length, SANE_Byte * value)
575 {
576   SANE_Status status;
577   SANE_Byte regs[2];
578   regs[0] = ctrl1;
579   regs[1] = ctrl2;
580 
581   status = sanei_rts88xx_write_regs (devnum, 0x91, regs, 2);
582   if (status != SANE_STATUS_GOOD)
583     {
584       DBG (DBG_error,
585            "sanei_rts88xx_get_mem: failed to write 0x91/0x92 registers\n");
586       return status;
587     }
588   status = sanei_rts88xx_read_mem (devnum, length, value);
589   if (status != SANE_STATUS_GOOD)
590     {
591       DBG (DBG_error, "sanei_rts88xx_get_mem: failed to read memory\n");
592     }
593   return status;
594 }
595 
596 /*
597  * write to the nvram controller
598  */
599 SANE_Status
sanei_rts88xx_nvram_ctrl(SANE_Int devnum,SANE_Int length,SANE_Byte * value)600 sanei_rts88xx_nvram_ctrl (SANE_Int devnum, SANE_Int length, SANE_Byte * value)
601 {
602   SANE_Status status;
603   SANE_Int i;
604   char message[60 * 5];
605 #ifdef HAZARDOUS_EXPERIMENT
606   SANE_Int size = 0;
607   SANE_Byte buffer[60];
608 #endif
609 
610   if (DBG_LEVEL > DBG_io)
611     {
612       for (i = 0; i < length; i++)
613         {
614           sprintf (message + 5 * i, "0x%02x ", value[i]);
615         }
616       DBG (DBG_io, "sanei_rts88xx_nvram_ctrl : devnum=%d, nvram_ctrl(0x00,%d)=%s\n",
617 	   devnum, length, message);
618     }
619 
620 #ifdef HAZARDOUS_EXPERIMENT
621   buffer[0] = 0x8a;
622   buffer[1] = 0x00;
623   buffer[2] = 0x00;
624   buffer[3] = length;
625   for (i = 0; i < size; i++)
626     buffer[i + 4] = value[i];
627   /* the USB block is size + 4 bytes of header long */
628   size = length + 4;
629   status = sanei_usb_write_bulk (devnum, buffer, &size);
630 #else
631   status = SANE_STATUS_GOOD;
632 #endif
633   if (status != SANE_STATUS_GOOD)
634     {
635       DBG (DBG_error, "sanei_rts88xx_nvram_ctrl : write failed ...\n");
636     }
637   return status;
638 }
639 
640 /*
641  * setup nvram
642  */
643 SANE_Status
sanei_rts88xx_setup_nvram(SANE_Int devnum,SANE_Int length,SANE_Byte * value)644 sanei_rts88xx_setup_nvram (SANE_Int devnum, SANE_Int length,
645                            SANE_Byte * value)
646 {
647   SANE_Status status = SANE_STATUS_GOOD;
648   SANE_Byte local[2], reg;
649   int i;
650 
651   status = sanei_rts88xx_nvram_ctrl (devnum, length, value);
652 
653 #ifndef HAZARDOUS_EXPERIMENT
654   return SANE_STATUS_GOOD;
655 #endif
656   if (status != SANE_STATUS_GOOD)
657     {
658       DBG (DBG_error, "sanei_rts88xx_setup_nvram : failed step #1 ...\n");
659       return status;
660     }
661   local[0] = 0x18;
662   local[1] = 0x08;
663   for (i = 0; i < 8; i++)
664     {
665       status = sanei_rts88xx_nvram_ctrl (devnum, 2, local);
666       if (status != SANE_STATUS_GOOD)
667         {
668           DBG (DBG_error, "sanei_rts88xx_setup_nvram : failed loop #%d ...\n",
669                i);
670           return status;
671         }
672       status = sanei_rts88xx_read_reg (devnum, 0x10, &reg);
673       if (status != SANE_STATUS_GOOD)
674         {
675           DBG (DBG_error,
676                "sanei_rts88xx_setup_nvram : register reading failed loop #%d ...\n",
677                i);
678           return status;
679         }
680       DBG (DBG_io, "sanei_rts88xx_setup_nvram: reg[0x10]=0x%02x\n", reg);
681     }
682   reg = 0;
683   status = sanei_rts88xx_write_reg (devnum, CONTROLER_REG, &reg);
684   if (status != SANE_STATUS_GOOD)
685     {
686       DBG (DBG_error,
687            "sanei_rts88xx_setup_nvram : controller register write failed\n");
688       return status;
689     }
690   reg = 1;
691   status = sanei_rts88xx_write_reg (devnum, CONTROLER_REG, &reg);
692   if (status != SANE_STATUS_GOOD)
693     {
694       DBG (DBG_error,
695            "sanei_rts88xx_setup_nvram : controller register write failed\n");
696       return status;
697     }
698   return status;
699 }
700 
701 /*
702  * Sets scan area, no checks are being done, so watch your steps
703  */
704 void
sanei_rts88xx_set_scan_area(SANE_Byte * regs,SANE_Int ystart,SANE_Int yend,SANE_Int xstart,SANE_Int xend)705 sanei_rts88xx_set_scan_area (SANE_Byte * regs, SANE_Int ystart,
706                              SANE_Int yend, SANE_Int xstart, SANE_Int xend)
707 {
708   /* vertical lines to move before scan */
709   regs[START_LINE] = LOBYTE (ystart);
710   regs[START_LINE + 1] = HIBYTE (ystart);
711 
712   /* total number of line to move */
713   regs[END_LINE] = LOBYTE (yend);
714   regs[END_LINE + 1] = HIBYTE (yend);
715 
716   /* set horizontal start position */
717   regs[START_PIXEL] = LOBYTE (xstart);
718   regs[START_PIXEL + 1] = HIBYTE (xstart);
719 
720   /* set horizontal end position */
721   regs[END_PIXEL] = LOBYTE (xend);
722   regs[END_PIXEL + 1] = HIBYTE (xend);
723 }
724 
725 /**
726  * read available data count from scanner
727  * from tests it appears that advertised data
728  * may not be really available, and that a pause must be made
729  * before reading data so that it is really there.
730  * Such as reading data twice.
731  */
732 SANE_Status
sanei_rts88xx_data_count(SANE_Int devnum,SANE_Word * count)733 sanei_rts88xx_data_count (SANE_Int devnum, SANE_Word * count)
734 {
735   SANE_Status status;
736   size_t size;
737   static SANE_Byte header[4] = { 0x90, 0x00, 0x00, 3 };
738   SANE_Byte result[3];
739 
740   /* set count in case of failure */
741   *count = 0;
742 
743   size = 4;
744   status = sanei_usb_write_bulk (devnum, header, &size);
745   if (status != SANE_STATUS_GOOD)
746     {
747       DBG (DBG_error, "sanei_rts88xx_data_count : failed to write header\n");
748       return status;
749     }
750   size = 3;
751   status = sanei_usb_read_bulk (devnum, result, &size);
752   if (status != SANE_STATUS_GOOD)
753     {
754       DBG (DBG_error,
755            "sanei_rts88xx_data_count : failed to read data count\n");
756       return status;
757     }
758   *count = result[0] + (result[1] << 8) + (result[2] << 16);
759   DBG (DBG_io2, "sanei_rts88xx_data_count: %d bytes available (0x%06x)\n",
760        *count, *count);
761   return status;
762 }
763 
764 /**
765  * Waits for data being available while optionally polling motor. There is a timeout
766  * to prevent scanner waiting forever non coming data.
767  */
768 SANE_Status
sanei_rts88xx_wait_data(SANE_Int devnum,SANE_Bool busy,SANE_Word * count)769 sanei_rts88xx_wait_data (SANE_Int devnum, SANE_Bool busy, SANE_Word * count)
770 {
771   SANE_Status status;
772   SANE_Byte control;
773 
774   /* poll the available byte count until not 0 */
775   while (SANE_TRUE)
776     {
777       status = sanei_rts88xx_data_count (devnum, count);
778       if (*count != 0)
779         {
780           DBG (DBG_io, "sanei_rts88xx_wait_data: %d bytes available\n",
781                *count);
782           return status;
783         }
784 
785       /* check that the scanner is busy scanning */
786       if (busy)
787         {
788           sanei_rts88xx_read_reg (devnum, CONTROL_REG, &control);
789           if ((control & 0x08) == 0 && (*count == 0))
790             {
791               DBG (DBG_error,
792                    "sanei_rts88xx_wait_data: scanner stopped being busy before data are available\n");
793               return SANE_STATUS_IO_ERROR;
794             }
795         }
796     }
797 
798   /* we hit timeout */
799   return SANE_STATUS_IO_ERROR;
800 }
801 
802 /*
803  * read scanned data from scanner up to the size given. The actual length read is returned.
804  */
805 SANE_Status
sanei_rts88xx_read_data(SANE_Int devnum,SANE_Word * length,unsigned char * dest)806 sanei_rts88xx_read_data (SANE_Int devnum, SANE_Word * length,
807                          unsigned char *dest)
808 {
809   SANE_Status status = SANE_STATUS_GOOD;
810   SANE_Byte header[4];
811   size_t size, len, remain, read;
812 
813   /* do not read too much data */
814   if (*length > RTS88XX_MAX_XFER_SIZE)
815     len = RTS88XX_MAX_XFER_SIZE;
816   else
817     len = *length;
818 
819   /* write command header first */
820   header[0] = 0x91;
821   header[1] = 0x00;
822   header[2] = HIBYTE (len);
823   header[3] = LOBYTE (len);
824   size = 4;
825 
826   status = sanei_usb_write_bulk (devnum, header, &size);
827   if (status != SANE_STATUS_GOOD)
828     {
829       DBG (DBG_error, "sanei_rts88xx_read_data: failed to write header\n");
830     }
831   read = 0;
832 
833   /* first read blocks aligned on 64 bytes boundary */
834   while (len - read > 64)
835     {
836       size = (len - read) & 0xFFC0;
837       status = sanei_usb_read_bulk (devnum, dest + read, &size);
838       if (status != SANE_STATUS_GOOD)
839         {
840           DBG (DBG_error, "sanei_rts88xx_read_data: failed to read data\n");
841           return status;
842         }
843       DBG (DBG_io2, "sanei_rts88xx_read_data: read %lu bytes\n",
844            (u_long) size);
845       read += size;
846     }
847 
848   /* then read remainder */
849   remain = len - read;
850   if (remain > 0)
851     {
852       status = sanei_usb_read_bulk (devnum, dest + read, &remain);
853       if (status != SANE_STATUS_GOOD)
854         {
855           DBG (DBG_error, "sanei_rts88xx_read_data: failed to read data\n");
856           return status;
857         }
858       DBG (DBG_io2, "sanei_rts88xx_read_data: read %lu bytes\n",
859            (u_long) remain);
860       read += remain;
861     }
862 
863   /* update actual read length */
864   DBG (DBG_io, "sanei_rts88xx_read_data: read %lu bytes, %d required\n",
865        (u_long) read, *length);
866   *length = read;
867   return status;
868 }
869