1 /* sane - Scanner Access Now Easy.
2
3 Copyright (C) 2002 Sergey Vlasov <vsu@altlinux.ru>
4 Copyright (C) 2002-2007 Henning Geinitz <sane@geinitz.org>
5
6 This file is part of the SANE package.
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <https://www.gnu.org/licenses/>.
20
21 As a special exception, the authors of SANE give permission for
22 additional uses of the libraries contained in this release of SANE.
23
24 The exception is that, if you link a SANE library with other files
25 to produce an executable, this does not by itself cause the
26 resulting executable to be covered by the GNU General Public
27 License. Your use of that executable is in no way restricted on
28 account of linking the SANE library code into it.
29
30 This exception does not, however, invalidate any other reasons why
31 the executable file might be covered by the GNU General Public
32 License.
33
34 If you submit changes to SANE to the maintainers to be included in
35 a subsequent release, you agree by submitting the changes that
36 those changes may be distributed with this exception intact.
37
38 If you write modifications of your own for SANE, it is your choice
39 whether to permit this exception to apply to your modifications.
40 If you do not wish that, delete this exception notice.
41 */
42
43 /** @file
44 * @brief Implementation of the gt6816 specific functions.
45 */
46
47 #include "gt68xx_gt6816.h"
48
49 SANE_Status
gt6816_check_firmware(GT68xx_Device * dev,SANE_Bool * loaded)50 gt6816_check_firmware (GT68xx_Device * dev, SANE_Bool * loaded)
51 {
52 SANE_Status status;
53 GT68xx_Packet req;
54
55 memset (req, 0, sizeof (req));
56 req[0] = 0x70;
57 req[1] = 0x01;
58
59 status = gt68xx_device_small_req (dev, req, req);
60 if (status != SANE_STATUS_GOOD)
61 {
62 /* Assume that firmware is not loaded because without firmware, we need
63 64 bytes for the result, not 8 */
64 *loaded = SANE_FALSE;
65 return SANE_STATUS_GOOD;
66 }
67 /* check anyway */
68 if (req[0] == 0x00 && req[1] == 0x70 && req[2] == 0xff)
69 *loaded = SANE_TRUE;
70 else
71 *loaded = SANE_FALSE;
72
73 return SANE_STATUS_GOOD;
74 }
75
76
77 #define MAX_DOWNLOAD_BLOCK_SIZE 64
78
79 SANE_Status
gt6816_download_firmware(GT68xx_Device * dev,SANE_Byte * data,SANE_Word size)80 gt6816_download_firmware (GT68xx_Device * dev,
81 SANE_Byte * data, SANE_Word size)
82 {
83 SANE_Status status;
84 SANE_Byte download_buf[MAX_DOWNLOAD_BLOCK_SIZE];
85 SANE_Byte check_buf[MAX_DOWNLOAD_BLOCK_SIZE];
86 SANE_Byte *block;
87 SANE_Word addr, bytes_left;
88 GT68xx_Packet boot_req;
89 SANE_Word block_size = MAX_DOWNLOAD_BLOCK_SIZE;
90
91 CHECK_DEV_ACTIVE (dev, "gt6816_download_firmware");
92
93 for (addr = 0; addr < size; addr += block_size)
94 {
95 bytes_left = size - addr;
96 if (bytes_left > block_size)
97 block = data + addr;
98 else
99 {
100 memset (download_buf, 0, block_size);
101 memcpy (download_buf, data + addr, bytes_left);
102 block = download_buf;
103 }
104 RIE (gt68xx_device_memory_write (dev, addr, block_size, block));
105 RIE (gt68xx_device_memory_read (dev, addr, block_size, check_buf));
106 if (memcmp (block, check_buf, block_size) != 0)
107 {
108 DBG (3, "gt6816_download_firmware: mismatch at block 0x%0x\n",
109 addr);
110 return SANE_STATUS_IO_ERROR;
111 }
112 }
113
114 memset (boot_req, 0, sizeof (boot_req));
115 boot_req[0] = 0x69;
116 boot_req[1] = 0x01;
117 boot_req[2] = LOBYTE (addr);
118 boot_req[3] = HIBYTE (addr);
119 RIE (gt68xx_device_req (dev, boot_req, boot_req));
120
121 return SANE_STATUS_GOOD;
122 }
123
124
125 SANE_Status
gt6816_get_power_status(GT68xx_Device * dev,SANE_Bool * power_ok)126 gt6816_get_power_status (GT68xx_Device * dev, SANE_Bool * power_ok)
127 {
128 SANE_Status status;
129 GT68xx_Packet req;
130
131 memset (req, 0, sizeof (req));
132 req[0] = 0x3f;
133 req[1] = 0x01;
134
135 RIE (gt68xx_device_req (dev, req, req));
136
137 if ((req[0] == 0x00 && req[1] == 0x3f && req[2] == 0x01)
138 || (dev->model->flags & GT68XX_FLAG_NO_POWER_STATUS))
139 *power_ok = SANE_TRUE;
140 else
141 *power_ok = SANE_FALSE;
142
143 return SANE_STATUS_GOOD;
144 }
145
146 SANE_Status
gt6816_get_ta_status(GT68xx_Device * dev,SANE_Bool * ta_attached)147 gt6816_get_ta_status (GT68xx_Device * dev, SANE_Bool * ta_attached)
148 {
149 SANE_Status status;
150 GT68xx_Packet req;
151
152 memset (req, 0, sizeof (req));
153 req[0] = 0x28;
154 req[1] = 0x01;
155
156 RIE (gt68xx_device_req (dev, req, req));
157
158 if (req[0] == 0x00 && req[1] == 0x28 && (req[8] & 0x01) != 0
159 && !dev->model->is_cis)
160 *ta_attached = SANE_TRUE;
161 else
162 *ta_attached = SANE_FALSE;
163
164 return SANE_STATUS_GOOD;
165 }
166
167
168 SANE_Status
gt6816_lamp_control(GT68xx_Device * dev,SANE_Bool fb_lamp,SANE_Bool ta_lamp)169 gt6816_lamp_control (GT68xx_Device * dev, SANE_Bool fb_lamp,
170 SANE_Bool ta_lamp)
171 {
172 GT68xx_Packet req;
173
174 memset (req, 0, sizeof (req));
175 req[0] = 0x25;
176 req[1] = 0x01;
177 req[2] = 0;
178 if (fb_lamp)
179 req[2] |= 0x01;
180 if (ta_lamp)
181 req[2] |= 0x02;
182
183 return gt68xx_device_req (dev, req, req);
184 }
185
186
187 SANE_Status
gt6816_is_moving(GT68xx_Device * dev,SANE_Bool * moving)188 gt6816_is_moving (GT68xx_Device * dev, SANE_Bool * moving)
189 {
190 SANE_Status status;
191 GT68xx_Packet req;
192
193 memset (req, 0, sizeof (req));
194 req[0] = 0x17;
195 req[1] = 0x01;
196
197 RIE (gt68xx_device_req (dev, req, req));
198
199 if (req[0] == 0x00 && req[1] == 0x17)
200 {
201 if (req[2] == 0 && (req[3] == 0 || req[3] == 2))
202 *moving = SANE_FALSE;
203 else
204 *moving = SANE_TRUE;
205 }
206 else
207 return SANE_STATUS_IO_ERROR;
208
209 return SANE_STATUS_GOOD;
210 }
211
212
213 SANE_Status
gt6816_carriage_home(GT68xx_Device * dev)214 gt6816_carriage_home (GT68xx_Device * dev)
215 {
216 GT68xx_Packet req;
217
218 memset (req, 0, sizeof (req));
219 req[0] = 0x24;
220 req[1] = 0x01;
221
222 return gt68xx_device_req (dev, req, req);
223 }
224
225
226 SANE_Status
gt6816_stop_scan(GT68xx_Device * dev)227 gt6816_stop_scan (GT68xx_Device * dev)
228 {
229 GT68xx_Packet req;
230
231 memset (req, 0, sizeof (req));
232 req[0] = 0x41;
233 req[1] = 0x01;
234
235 return gt68xx_device_small_req (dev, req, req);
236 }
237
238 SANE_Status
gt6816_document_present(GT68xx_Device * dev,SANE_Bool * present)239 gt6816_document_present (GT68xx_Device * dev, SANE_Bool * present)
240 {
241 SANE_Status status;
242 GT68xx_Packet req;
243
244 memset (req, 0, sizeof (req));
245 req[0] = 0x59;
246 req[1] = 0x01;
247
248 RIE (gt68xx_device_req (dev, req, req));
249
250 if (req[0] == 0x00 && req[1] == 0x59)
251 {
252 if (req[2] == 0)
253 *present = SANE_FALSE;
254 else
255 *present = SANE_TRUE;
256 }
257 else
258 return SANE_STATUS_IO_ERROR;
259
260 return SANE_STATUS_GOOD;
261 }
262