• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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