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 49SANE_Status 50gt6816_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 79SANE_Status 80gt6816_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 125SANE_Status 126gt6816_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 146SANE_Status 147gt6816_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 168SANE_Status 169gt6816_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 187SANE_Status 188gt6816_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 213SANE_Status 214gt6816_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 226SANE_Status 227gt6816_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 238SANE_Status 239gt6816_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