1 /* sane - Scanner Access Now Easy.
2
3 Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
4
5 This file is part of the SANE package.
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <https://www.gnu.org/licenses/>.
19
20 As a special exception, the authors of SANE give permission for
21 additional uses of the libraries contained in this release of SANE.
22
23 The exception is that, if you link a SANE library with other files
24 to produce an executable, this does not by itself cause the
25 resulting executable to be covered by the GNU General Public
26 License. Your use of that executable is in no way restricted on
27 account of linking the SANE library code into it.
28
29 This exception does not, however, invalidate any other reasons why
30 the executable file might be covered by the GNU General Public
31 License.
32
33 If you submit changes to SANE to the maintainers to be included in
34 a subsequent release, you agree by submitting the changes that
35 those changes may be distributed with this exception intact.
36
37 If you write modifications of your own for SANE, it is your choice
38 whether to permit this exception to apply to your modifications.
39 If you do not wish that, delete this exception notice.
40 */
41
42 #define DEBUG_DECLARE_ONLY
43
44 #include "scanner_interface_usb.h"
45 #include "low.h"
46 #include <thread>
47
48 namespace genesys {
49
50 ScannerInterfaceUsb::~ScannerInterfaceUsb() = default;
51
ScannerInterfaceUsb(Genesys_Device * dev)52 ScannerInterfaceUsb::ScannerInterfaceUsb(Genesys_Device* dev) : dev_{dev} {}
53
is_mock() const54 bool ScannerInterfaceUsb::is_mock() const
55 {
56 return false;
57 }
58
read_register(std::uint16_t address)59 std::uint8_t ScannerInterfaceUsb::read_register(std::uint16_t address)
60 {
61 DBG_HELPER(dbg);
62
63 std::uint8_t value = 0;
64
65 if (dev_->model->asic_type == AsicType::GL847 ||
66 dev_->model->asic_type == AsicType::GL845 ||
67 dev_->model->asic_type == AsicType::GL846 ||
68 dev_->model->asic_type == AsicType::GL124)
69 {
70 std::uint8_t value2x8[2];
71 std::uint16_t address16 = 0x22 + (address << 8);
72
73 std::uint16_t usb_value = VALUE_GET_REGISTER;
74 if (address > 0xff) {
75 usb_value |= 0x100;
76 }
77
78 usb_dev_.control_msg(REQUEST_TYPE_IN, REQUEST_BUFFER, usb_value, address16, 2, value2x8);
79
80 // check usb link status
81 if (value2x8[1] != 0x55) {
82 throw SaneException(SANE_STATUS_IO_ERROR, "invalid read, scanner unplugged?");
83 }
84
85 DBG(DBG_io, "%s (0x%02x, 0x%02x) completed\n", __func__, address, value2x8[0]);
86
87 value = value2x8[0];
88
89 } else {
90
91 if (address > 0xff) {
92 throw SaneException("Invalid register address 0x%04x", address);
93 }
94
95 std::uint8_t address8 = address & 0xff;
96
97 usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_SET_REGISTER, INDEX,
98 1, &address8);
99 usb_dev_.control_msg(REQUEST_TYPE_IN, REQUEST_REGISTER, VALUE_READ_REGISTER, INDEX,
100 1, &value);
101 }
102 return value;
103 }
104
write_register(std::uint16_t address,std::uint8_t value)105 void ScannerInterfaceUsb::write_register(std::uint16_t address, std::uint8_t value)
106 {
107 DBG_HELPER_ARGS(dbg, "address: 0x%04x, value: 0x%02x", static_cast<unsigned>(address),
108 static_cast<unsigned>(value));
109
110 if (dev_->model->asic_type == AsicType::GL847 ||
111 dev_->model->asic_type == AsicType::GL845 ||
112 dev_->model->asic_type == AsicType::GL846 ||
113 dev_->model->asic_type == AsicType::GL124)
114 {
115 std::uint8_t buffer[2];
116
117 buffer[0] = address & 0xff;
118 buffer[1] = value;
119
120 std::uint16_t usb_value = VALUE_SET_REGISTER;
121 if (address > 0xff) {
122 usb_value |= 0x100;
123 }
124
125 usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_BUFFER, usb_value, INDEX,
126 2, buffer);
127
128 } else {
129 if (address > 0xff) {
130 throw SaneException("Invalid register address 0x%04x", address);
131 }
132
133 std::uint8_t address8 = address & 0xff;
134
135 usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_SET_REGISTER, INDEX,
136 1, &address8);
137
138 usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_WRITE_REGISTER, INDEX,
139 1, &value);
140
141 }
142 DBG(DBG_io, "%s (0x%02x, 0x%02x) completed\n", __func__, address, value);
143 }
144
write_registers(const Genesys_Register_Set & regs)145 void ScannerInterfaceUsb::write_registers(const Genesys_Register_Set& regs)
146 {
147 DBG_HELPER(dbg);
148 if (dev_->model->asic_type == AsicType::GL646 ||
149 dev_->model->asic_type == AsicType::GL841)
150 {
151 uint8_t outdata[8];
152 std::vector<uint8_t> buffer;
153 buffer.reserve(regs.size() * 2);
154
155 /* copy registers and values in data buffer */
156 for (const auto& r : regs) {
157 buffer.push_back(r.address);
158 buffer.push_back(r.value);
159 }
160
161 DBG(DBG_io, "%s (elems= %zu, size = %zu)\n", __func__, regs.size(), buffer.size());
162
163 if (dev_->model->asic_type == AsicType::GL646) {
164 outdata[0] = BULK_OUT;
165 outdata[1] = BULK_REGISTER;
166 outdata[2] = 0x00;
167 outdata[3] = 0x00;
168 outdata[4] = (buffer.size() & 0xff);
169 outdata[5] = ((buffer.size() >> 8) & 0xff);
170 outdata[6] = ((buffer.size() >> 16) & 0xff);
171 outdata[7] = ((buffer.size() >> 24) & 0xff);
172
173 usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_BUFFER, VALUE_BUFFER, INDEX,
174 sizeof(outdata), outdata);
175
176 size_t write_size = buffer.size();
177
178 usb_dev_.bulk_write(buffer.data(), &write_size);
179 } else {
180 for (std::size_t i = 0; i < regs.size();) {
181 std::size_t c = regs.size() - i;
182 if (c > 32) /*32 is max on GL841. checked that.*/
183 c = 32;
184
185 usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_BUFFER, VALUE_SET_REGISTER,
186 INDEX, c * 2, buffer.data() + i * 2);
187
188 i += c;
189 }
190 }
191 } else {
192 for (const auto& r : regs) {
193 write_register(r.address, r.value);
194 }
195 }
196
197 DBG(DBG_io, "%s: wrote %zu registers\n", __func__, regs.size());
198 }
199
write_0x8c(std::uint8_t index,std::uint8_t value)200 void ScannerInterfaceUsb::write_0x8c(std::uint8_t index, std::uint8_t value)
201 {
202 DBG_HELPER_ARGS(dbg, "0x%02x,0x%02x", index, value);
203 usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_BUF_ENDACCESS, index, 1, &value);
204 }
205
bulk_read_data_send_header(UsbDevice & usb_dev,AsicType asic_type,size_t size)206 static void bulk_read_data_send_header(UsbDevice& usb_dev, AsicType asic_type, size_t size)
207 {
208 DBG_HELPER(dbg);
209
210 uint8_t outdata[8];
211 if (asic_type == AsicType::GL124 ||
212 asic_type == AsicType::GL845 ||
213 asic_type == AsicType::GL846 ||
214 asic_type == AsicType::GL847)
215 {
216 // hard coded 0x10000000 address
217 outdata[0] = 0;
218 outdata[1] = 0;
219 outdata[2] = 0;
220 outdata[3] = 0x10;
221 } else if (asic_type == AsicType::GL841 ||
222 asic_type == AsicType::GL842 ||
223 asic_type == AsicType::GL843)
224 {
225 outdata[0] = BULK_IN;
226 outdata[1] = BULK_RAM;
227 outdata[2] = 0x82; //
228 outdata[3] = 0x00;
229 } else {
230 outdata[0] = BULK_IN;
231 outdata[1] = BULK_RAM;
232 outdata[2] = 0x00;
233 outdata[3] = 0x00;
234 }
235
236 /* data size to transfer */
237 outdata[4] = (size & 0xff);
238 outdata[5] = ((size >> 8) & 0xff);
239 outdata[6] = ((size >> 16) & 0xff);
240 outdata[7] = ((size >> 24) & 0xff);
241
242 usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_BUFFER, VALUE_BUFFER, 0x00,
243 sizeof(outdata), outdata);
244 }
245
bulk_read_data(std::uint8_t addr,std::uint8_t * data,std::size_t size)246 void ScannerInterfaceUsb::bulk_read_data(std::uint8_t addr, std::uint8_t* data, std::size_t size)
247 {
248 // currently supported: GL646, GL841, GL843, GL845, GL846, GL847, GL124
249 DBG_HELPER(dbg);
250
251 unsigned is_addr_used = 1;
252 unsigned has_header_before_each_chunk = 0;
253 if (dev_->model->asic_type == AsicType::GL124 ||
254 dev_->model->asic_type == AsicType::GL845 ||
255 dev_->model->asic_type == AsicType::GL846 ||
256 dev_->model->asic_type == AsicType::GL847)
257 {
258 is_addr_used = 0;
259 has_header_before_each_chunk = 1;
260 }
261
262 if (is_addr_used) {
263 DBG(DBG_io, "%s: requesting %zu bytes from 0x%02x addr\n", __func__, size, addr);
264 } else {
265 DBG(DBG_io, "%s: requesting %zu bytes\n", __func__, size);
266 }
267
268 if (size == 0)
269 return;
270
271 if (is_addr_used) {
272 usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_SET_REGISTER, 0x00,
273 1, &addr);
274 }
275
276 std::size_t target_size = size;
277
278 std::size_t max_in_size = sanei_genesys_get_bulk_max_size(dev_->model->asic_type);
279
280 if (!has_header_before_each_chunk) {
281 bulk_read_data_send_header(usb_dev_, dev_->model->asic_type, size);
282 }
283
284 // loop until computed data size is read
285 while (target_size > 0) {
286 std::size_t block_size = std::min(target_size, max_in_size);
287
288 if (has_header_before_each_chunk) {
289 bulk_read_data_send_header(usb_dev_, dev_->model->asic_type, block_size);
290 }
291
292 DBG(DBG_io2, "%s: trying to read %zu bytes of data\n", __func__, block_size);
293
294 usb_dev_.bulk_read(data, &block_size);
295
296 DBG(DBG_io2, "%s: read %zu bytes, %zu remaining\n", __func__, block_size, target_size - block_size);
297
298 target_size -= block_size;
299 data += block_size;
300 }
301 }
302
bulk_write_data(std::uint8_t addr,std::uint8_t * data,std::size_t len)303 void ScannerInterfaceUsb::bulk_write_data(std::uint8_t addr, std::uint8_t* data, std::size_t len)
304 {
305 DBG_HELPER_ARGS(dbg, "writing %zu bytes", len);
306
307 // supported: GL646, GL841, GL843
308 std::size_t size;
309 std::uint8_t outdata[8];
310
311 usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_SET_REGISTER, INDEX,
312 1, &addr);
313
314 std::size_t max_out_size = sanei_genesys_get_bulk_max_size(dev_->model->asic_type);
315
316 while (len) {
317 if (len > max_out_size)
318 size = max_out_size;
319 else
320 size = len;
321
322 if (dev_->model->asic_type == AsicType::GL841) {
323 outdata[0] = BULK_OUT;
324 outdata[1] = BULK_RAM;
325 // both 0x82 and 0x00 works on GL841.
326 outdata[2] = 0x82;
327 outdata[3] = 0x00;
328 } else {
329 outdata[0] = BULK_OUT;
330 outdata[1] = BULK_RAM;
331 // 8600F uses 0x82, but 0x00 works too. 8400F uses 0x02 for certain transactions.
332 outdata[2] = 0x00;
333 outdata[3] = 0x00;
334 }
335
336 outdata[4] = (size & 0xff);
337 outdata[5] = ((size >> 8) & 0xff);
338 outdata[6] = ((size >> 16) & 0xff);
339 outdata[7] = ((size >> 24) & 0xff);
340
341 usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_BUFFER, VALUE_BUFFER, 0x00,
342 sizeof(outdata), outdata);
343
344 usb_dev_.bulk_write(data, &size);
345
346 DBG(DBG_io2, "%s: wrote %zu bytes, %zu remaining\n", __func__, size, len - size);
347
348 len -= size;
349 data += size;
350 }
351 }
352
write_buffer(std::uint8_t type,std::uint32_t addr,std::uint8_t * data,std::size_t size)353 void ScannerInterfaceUsb::write_buffer(std::uint8_t type, std::uint32_t addr, std::uint8_t* data,
354 std::size_t size)
355 {
356 DBG_HELPER_ARGS(dbg, "type: 0x%02x, addr: 0x%08x, size: 0x%08zx", type, addr, size);
357 if (dev_->model->asic_type != AsicType::GL646 &&
358 dev_->model->asic_type != AsicType::GL841 &&
359 dev_->model->asic_type != AsicType::GL842 &&
360 dev_->model->asic_type != AsicType::GL843)
361 {
362 throw SaneException("Unsupported transfer mode");
363 }
364
365 if (dev_->model->asic_type == AsicType::GL843) {
366 write_register(0x2b, ((addr >> 4) & 0xff));
367 write_register(0x2a, ((addr >> 12) & 0xff));
368 write_register(0x29, ((addr >> 20) & 0xff));
369 } else {
370 write_register(0x2b, ((addr >> 4) & 0xff));
371 write_register(0x2a, ((addr >> 12) & 0xff));
372 }
373 bulk_write_data(type, data, size);
374 }
375
write_gamma(std::uint8_t type,std::uint32_t addr,std::uint8_t * data,std::size_t size)376 void ScannerInterfaceUsb::write_gamma(std::uint8_t type, std::uint32_t addr, std::uint8_t* data,
377 std::size_t size)
378 {
379 DBG_HELPER_ARGS(dbg, "type: 0x%02x, addr: 0x%08x, size: 0x%08zx", type, addr, size);
380 if (dev_->model->asic_type != AsicType::GL841 &&
381 dev_->model->asic_type != AsicType::GL842 &&
382 dev_->model->asic_type != AsicType::GL843)
383 {
384 throw SaneException("Unsupported transfer mode");
385 }
386
387 write_register(0x5b, ((addr >> 12) & 0xff));
388 write_register(0x5c, ((addr >> 4) & 0xff));
389 bulk_write_data(type, data, size);
390
391 if (dev_->model->asic_type == AsicType::GL842 ||
392 dev_->model->asic_type == AsicType::GL843)
393 {
394 // it looks like we need to reset the address so that subsequent buffer operations work.
395 // Most likely the MTRTBL register is to blame.
396 write_register(0x5b, 0);
397 write_register(0x5c, 0);
398 }
399 }
400
write_ahb(std::uint32_t addr,std::uint32_t size,std::uint8_t * data)401 void ScannerInterfaceUsb::write_ahb(std::uint32_t addr, std::uint32_t size, std::uint8_t* data)
402 {
403 DBG_HELPER_ARGS(dbg, "address: 0x%08x, size: %d", static_cast<unsigned>(addr),
404 static_cast<unsigned>(size));
405
406 if (dev_->model->asic_type != AsicType::GL845 &&
407 dev_->model->asic_type != AsicType::GL846 &&
408 dev_->model->asic_type != AsicType::GL847 &&
409 dev_->model->asic_type != AsicType::GL124)
410 {
411 throw SaneException("Unsupported transfer type");
412 }
413 std::uint8_t outdata[8];
414 outdata[0] = addr & 0xff;
415 outdata[1] = ((addr >> 8) & 0xff);
416 outdata[2] = ((addr >> 16) & 0xff);
417 outdata[3] = ((addr >> 24) & 0xff);
418 outdata[4] = (size & 0xff);
419 outdata[5] = ((size >> 8) & 0xff);
420 outdata[6] = ((size >> 16) & 0xff);
421 outdata[7] = ((size >> 24) & 0xff);
422
423 // write addr and size for AHB
424 usb_dev_.control_msg(REQUEST_TYPE_OUT, REQUEST_BUFFER, VALUE_BUFFER, 0x01, 8, outdata);
425
426 std::size_t max_out_size = sanei_genesys_get_bulk_max_size(dev_->model->asic_type);
427
428 // write actual data
429 std::size_t written = 0;
430 do {
431 std::size_t block_size = std::min(size - written, max_out_size);
432
433 usb_dev_.bulk_write(data + written, &block_size);
434
435 written += block_size;
436 } while (written < size);
437 }
438
read_fe_register(std::uint8_t address)439 std::uint16_t ScannerInterfaceUsb::read_fe_register(std::uint8_t address)
440 {
441 DBG_HELPER(dbg);
442 Genesys_Register_Set reg;
443
444 reg.init_reg(0x50, address);
445
446 // set up read address
447 write_registers(reg);
448
449 // read data
450 std::uint16_t value = read_register(0x46) << 8;
451 value |= read_register(0x47);
452
453 DBG(DBG_io, "%s (0x%02x, 0x%04x)\n", __func__, address, value);
454 return value;
455 }
456
write_fe_register(std::uint8_t address,std::uint16_t value)457 void ScannerInterfaceUsb::write_fe_register(std::uint8_t address, std::uint16_t value)
458 {
459 DBG_HELPER_ARGS(dbg, "0x%02x, 0x%04x", address, value);
460 Genesys_Register_Set reg(Genesys_Register_Set::SEQUENTIAL);
461
462 reg.init_reg(0x51, address);
463 if (dev_->model->asic_type == AsicType::GL124) {
464 reg.init_reg(0x5d, (value / 256) & 0xff);
465 reg.init_reg(0x5e, value & 0xff);
466 } else {
467 reg.init_reg(0x3a, (value / 256) & 0xff);
468 reg.init_reg(0x3b, value & 0xff);
469 }
470
471 write_registers(reg);
472 }
473
get_usb_device()474 IUsbDevice& ScannerInterfaceUsb::get_usb_device()
475 {
476 return usb_dev_;
477 }
478
sleep_us(unsigned microseconds)479 void ScannerInterfaceUsb::sleep_us(unsigned microseconds)
480 {
481 if (sanei_usb_is_replay_mode_enabled()) {
482 return;
483 }
484 std::this_thread::sleep_for(std::chrono::microseconds{microseconds});
485 }
486
record_progress_message(const char * msg)487 void ScannerInterfaceUsb::record_progress_message(const char* msg)
488 {
489 sanei_usb_testing_record_message(msg);
490 }
491
record_slope_table(unsigned table_nr,const std::vector<std::uint16_t> & steps)492 void ScannerInterfaceUsb::record_slope_table(unsigned table_nr,
493 const std::vector<std::uint16_t>& steps)
494 {
495 (void) table_nr;
496 (void) steps;
497 }
498
record_key_value(const std::string & key,const std::string & value)499 void ScannerInterfaceUsb::record_key_value(const std::string& key, const std::string& value)
500 {
501 (void) key;
502 (void) value;
503 }
504
test_checkpoint(const std::string & name)505 void ScannerInterfaceUsb::test_checkpoint(const std::string& name)
506 {
507 (void) name;
508 }
509
510 } // namespace genesys
511