• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* sane - Scanner Access Now Easy.
2 
3    Copyright (C) 2002 Sergey Vlasov <vsu@altlinux.ru>
4    GT6801 support by Andreas Nowack <nowack.andreas@gmx.de>
5    Copyright (C) 2002-2007 Henning Geinitz <sane@geinitz.org>
6 
7    This file is part of the SANE package.
8 
9    This program is free software; you can redistribute it and/or
10    modify it under the terms of the GNU General Public License as
11    published by the Free Software Foundation; either version 2 of the
12    License, or (at your option) any later version.
13 
14    This program is distributed in the hope that it will be useful, but
15    WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <https://www.gnu.org/licenses/>.
21 
22    As a special exception, the authors of SANE give permission for
23    additional uses of the libraries contained in this release of SANE.
24 
25    The exception is that, if you link a SANE library with other files
26    to produce an executable, this does not by itself cause the
27    resulting executable to be covered by the GNU General Public
28    License.  Your use of that executable is in no way restricted on
29    account of linking the SANE library code into it.
30 
31    This exception does not, however, invalidate any other reasons why
32    the executable file might be covered by the GNU General Public
33    License.
34 
35    If you submit changes to SANE to the maintainers to be included in
36    a subsequent release, you agree by submitting the changes that
37    those changes may be distributed with this exception intact.
38 
39    If you write modifications of your own for SANE, it is your choice
40    whether to permit this exception to apply to your modifications.
41    If you do not wish that, delete this exception notice.
42 */
43 
44 /** @file
45  * @brief Implementation of the GT6801 specific functions.
46  */
47 
48 #include "gt68xx_gt6801.h"
49 
50 /* doesn't work with plustek scanner */
51 SANE_Status
gt6801_check_firmware(GT68xx_Device * dev,SANE_Bool * loaded)52 gt6801_check_firmware (GT68xx_Device * dev, SANE_Bool * loaded)
53 {
54   SANE_Status status;
55   GT68xx_Packet req;
56 
57   memset (req, 0, sizeof (req));
58   req[0] = 0x50;
59   req[1] = 0x01;
60   req[2] = 0x80;
61 
62   RIE (gt68xx_device_req (dev, req, req));
63 
64   if (req[0] == 0x00 && req[1] == 0x50)
65     *loaded = SANE_TRUE;
66   else
67     *loaded = SANE_FALSE;
68 
69   return SANE_STATUS_GOOD;
70 }
71 
72 /* doesn't work with at least cytron scanner */
73 SANE_Status
gt6801_check_plustek_firmware(GT68xx_Device * dev,SANE_Bool * loaded)74 gt6801_check_plustek_firmware (GT68xx_Device * dev, SANE_Bool * loaded)
75 {
76   SANE_Status status;
77   GT68xx_Packet req;
78 
79   memset (req, 0, sizeof (req));
80 
81   req[0] = 0x73;
82   req[1] = 0x01;
83 
84   status = gt68xx_device_small_req (dev, req, req);
85   if (status != SANE_STATUS_GOOD)
86     {
87       /* Assume that firmware is not loaded */
88       *loaded = SANE_FALSE;
89       return SANE_STATUS_GOOD;
90     }
91 
92   /* check for correct answer */
93   if ((req[0] == 0) && (req[1] == 0x12) && (req[3] == 0x80))
94     /* req[3] is 0 if fw is not loaded, if loaded it's 0x80
95      * at least on my 1284u (gerhard@gjaeger.de)
96      *
97      * With the Genius scanners req[3] is 0x02/0x82. (hmg)
98      */
99     *loaded = SANE_TRUE;
100   else
101     *loaded = SANE_FALSE;
102 
103   /* Until I find out if testing for req[3] & 0x80 is save, load the firmware
104      every time */
105   *loaded = SANE_FALSE;
106 
107   return SANE_STATUS_GOOD;
108 }
109 
110 #define MAX_DOWNLOAD_BLOCK_SIZE 64
111 
112 SANE_Status
gt6801_download_firmware(GT68xx_Device * dev,SANE_Byte * data,SANE_Word size)113 gt6801_download_firmware (GT68xx_Device * dev,
114 			  SANE_Byte * data, SANE_Word size)
115 {
116   SANE_Status status;
117   SANE_Byte download_buf[MAX_DOWNLOAD_BLOCK_SIZE];
118   SANE_Byte check_buf[MAX_DOWNLOAD_BLOCK_SIZE];
119   SANE_Byte *block;
120   SANE_Word addr, bytes_left;
121   GT68xx_Packet boot_req;
122   SANE_Word block_size = MAX_DOWNLOAD_BLOCK_SIZE;
123 
124   CHECK_DEV_ACTIVE (dev, "gt6801_download_firmware");
125 
126   for (addr = 0; addr < size; addr += block_size)
127     {
128       bytes_left = size - addr;
129       if (bytes_left > block_size)
130 	block = data + addr;
131       else
132 	{
133 	  memset (download_buf, 0, block_size);
134 	  memcpy (download_buf, data + addr, bytes_left);
135 	  block = download_buf;
136 	}
137       RIE (gt68xx_device_memory_write (dev, addr, block_size, block));
138       RIE (gt68xx_device_memory_read (dev, 0x3f00, block_size, check_buf));
139 
140       /*
141        * For GT6816 this was:
142        *   if (memcmp (block, check_buf, block_size) != 0) ...
143        * Apparently the GT6801 does something different...
144        *
145        * hmg: For my BP 1200 CU the result is 00 09 so maybe only the 0 is
146        * relevant?
147        */
148       if ((check_buf[0] != 0) && (check_buf[1] != 0x40))
149 	{
150 	  DBG (3, "gt6801_download_firmware: mismatch at block 0x%0x\n",
151 	       addr);
152 	  return SANE_STATUS_IO_ERROR;
153 	}
154     }
155 
156   memset (boot_req, 0, sizeof (boot_req));
157   boot_req[0] = 0x69;
158   boot_req[1] = 0x01;
159   boot_req[2] = 0xc0;
160   boot_req[3] = 0x1c;
161   RIE (gt68xx_device_req (dev, boot_req, boot_req));
162 
163 #if 0
164   /* hmg: the following isn't in my log: */
165   memset (boot_req, 0, sizeof (boot_req));	/* I don't know if this is needed */
166   boot_req[0] = 0x01;
167   boot_req[1] = 0x01;
168   RIE (gt68xx_device_small_req (dev, boot_req, boot_req));
169 #endif
170 
171   return SANE_STATUS_GOOD;
172 }
173 
174 SANE_Status
gt6801_get_power_status(GT68xx_Device * dev,SANE_Bool * power_ok)175 gt6801_get_power_status (GT68xx_Device * dev, SANE_Bool * power_ok)
176 {
177   SANE_Status status;
178   GT68xx_Packet req;
179 
180   memset (req, 0, sizeof (req));
181   req[0] = 0x10;
182   req[1] = 0x01;
183 
184   RIE (gt68xx_device_req (dev, req, req));
185 
186   /* I don't know what power_ok = SANE_FALSE looks like... */
187   /* hmg: let's assume it's different from the usual 00 10 */
188   if (gt68xx_device_check_result (req, 0x10) == SANE_STATUS_GOOD)
189     *power_ok = SANE_TRUE;
190   else
191     *power_ok = SANE_FALSE;
192 
193   return SANE_STATUS_GOOD;
194 }
195 
196 
197 SANE_Status
gt6801_lamp_control(GT68xx_Device * dev,SANE_Bool fb_lamp,SANE_Bool ta_lamp)198 gt6801_lamp_control (GT68xx_Device * dev, SANE_Bool fb_lamp,
199 		     SANE_Bool ta_lamp)
200 {
201   if (!dev->model->is_cis)
202     {
203       GT68xx_Packet req;
204 
205       memset (req, 0, sizeof (req));
206       req[0] = 0x25;
207       req[1] = 0x01;
208       req[2] = 0;
209       if (fb_lamp)
210 	req[2] |= 0x01;
211       if (ta_lamp)
212 	req[2] |= 0x02;
213       return gt68xx_device_req (dev, req, req);
214     }
215   return SANE_STATUS_GOOD;
216 }
217 
218 
219 SANE_Status
gt6801_is_moving(GT68xx_Device * dev,SANE_Bool * moving)220 gt6801_is_moving (GT68xx_Device * dev, SANE_Bool * moving)
221 {
222   /* this seems not to be supported by the scanner */
223   (void) dev;
224 
225   *moving = SANE_FALSE;
226 
227   return SANE_STATUS_GOOD;
228 }
229 
230 
231 SANE_Status
gt6801_carriage_home(GT68xx_Device * dev)232 gt6801_carriage_home (GT68xx_Device * dev)
233 {
234   GT68xx_Packet req;
235   SANE_Status status;
236 
237   memset (req, 0, sizeof (req));
238 
239   if (dev->model->flags & GT68XX_FLAG_MOTOR_HOME)
240     {
241       req[0] = 0x34;
242       req[1] = 0x01;
243       status = gt68xx_device_req (dev, req, req);
244     }
245   else
246     {
247       req[0] = 0x12;
248       req[1] = 0x01;
249       if ((status = gt68xx_device_req (dev, req, req)) == SANE_STATUS_GOOD)
250 	{
251 	  RIE (gt68xx_device_check_result (req, 0x12));
252 	  memset (req, 0, sizeof (req));
253 	  req[0] = 0x24;
254 	  req[1] = 0x01;
255 	  status = gt68xx_device_req (dev, req, req);
256 	  RIE (gt68xx_device_check_result (req, 0x24));
257 	}
258     }
259   return status;
260 }
261 
262 
263 SANE_Status
gt6801_stop_scan(GT68xx_Device * dev)264 gt6801_stop_scan (GT68xx_Device * dev)
265 {
266   GT68xx_Packet req;
267   SANE_Status status;
268 
269   memset (req, 0, sizeof (req));
270   req[0] = 0x42;
271   req[1] = 0x01;
272 
273   RIE (gt68xx_device_req (dev, req, req));
274   RIE (gt68xx_device_check_result (req, 0x42));
275   return SANE_STATUS_GOOD;
276 }
277