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