1 /* sane - Scanner Access Now Easy.
2 
3    Copyright (C) 2003 Oliver Rauch
4    Copyright (C) 2003, 2004 Henning Meier-Geinitz <henning@meier-geinitz.de>
5    Copyright (C) 2004, 2005 Gerhard Jaeger <gerhard@gjaeger.de>
6    Copyright (C) 2004-2013 Stéphane Voltz <stef.dev@free.fr>
7    Copyright (C) 2005-2009 Pierre Willenbrock <pierre@pirsoft.dnsalias.org>
8    Copyright (C) 2006 Laurent Charpentier <laurent_pubs@yahoo.com>
9    Parts of the structs have been taken from the gt68xx backend by
10    Sergey Vlasov <vsu@altlinux.ru> et al.
11 
12    This file is part of the SANE package.
13 
14    This program is free software; you can redistribute it and/or
15    modify it under the terms of the GNU General Public License as
16    published by the Free Software Foundation; either version 2 of the
17    License, or (at your option) any later version.
18 
19    This program is distributed in the hope that it will be useful, but
20    WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22    General Public License for more details.
23 
24    You should have received a copy of the GNU General Public License
25    along with this program.  If not, see <https://www.gnu.org/licenses/>.
26 
27    As a special exception, the authors of SANE give permission for
28    additional uses of the libraries contained in this release of SANE.
29 
30    The exception is that, if you link a SANE library with other files
31    to produce an executable, this does not by itself cause the
32    resulting executable to be covered by the GNU General Public
33    License.  Your use of that executable is in no way restricted on
34    account of linking the SANE library code into it.
35 
36    This exception does not, however, invalidate any other reasons why
37    the executable file might be covered by the GNU General Public
38    License.
39 
40    If you submit changes to SANE to the maintainers to be included in
41    a subsequent release, you agree by submitting the changes that
42    those changes may be distributed with this exception intact.
43 
44    If you write modifications of your own for SANE, it is your choice
45    whether to permit this exception to apply to your modifications.
46    If you do not wish that, delete this exception notice.
47 */
48 
49 #ifndef GENESYS_LOW_H
50 #define GENESYS_LOW_H
51 
52 
53 #include "../include/sane/config.h"
54 
55 #include <errno.h>
56 #include <string.h>
57 #include <stdlib.h>
58 #include <unistd.h>
59 #include <math.h>
60 #include <stddef.h>
61 #ifdef HAVE_SYS_TIME_H
62 #include <sys/time.h>
63 #endif
64 #ifdef HAVE_SYS_TYPES_H
65 #include <sys/types.h>
66 #endif
67 #ifdef HAVE_MKDIR
68 #include <sys/stat.h>
69 #include <sys/types.h>
70 #endif
71 
72 #include "../include/sane/sane.h"
73 #include "../include/sane/sanei.h"
74 #include "../include/sane/saneopts.h"
75 
76 #include "../include/sane/sanei_backend.h"
77 #include "../include/sane/sanei_usb.h"
78 
79 #include "../include/_stdint.h"
80 
81 #include "device.h"
82 #include "enums.h"
83 #include "error.h"
84 #include "fwd.h"
85 #include "usb_device.h"
86 #include "sensor.h"
87 #include "serialize.h"
88 #include "settings.h"
89 #include "static_init.h"
90 #include "status.h"
91 #include "register.h"
92 
93 #include <algorithm>
94 #include <array>
95 #include <cstring>
96 #include <functional>
97 #include <iostream>
98 #include <sstream>
99 #include <limits>
100 #include <memory>
101 #include <stdexcept>
102 #include <string>
103 #include <vector>
104 
105 #define GENESYS_RED   0
106 #define GENESYS_GREEN 1
107 #define GENESYS_BLUE  2
108 
109 #define GENESYS_HAS_NO_BUTTONS       0              /**< scanner has no supported button */
110 #define GENESYS_HAS_SCAN_SW          (1 << 0)       /**< scanner has SCAN button */
111 #define GENESYS_HAS_FILE_SW          (1 << 1)       /**< scanner has FILE button */
112 #define GENESYS_HAS_COPY_SW          (1 << 2)       /**< scanner has COPY button */
113 #define GENESYS_HAS_EMAIL_SW         (1 << 3)       /**< scanner has EMAIL button */
114 #define GENESYS_HAS_PAGE_LOADED_SW   (1 << 4)       /**< scanner has paper in detection */
115 #define GENESYS_HAS_OCR_SW           (1 << 5)       /**< scanner has OCR button */
116 #define GENESYS_HAS_POWER_SW         (1 << 6)       /**< scanner has power button */
117 #define GENESYS_HAS_CALIBRATE        (1 << 7)       /**< scanner has 'calibrate' software button to start calibration */
118 #define GENESYS_HAS_EXTRA_SW         (1 << 8)       /**< scanner has extra function button */
119 
120 /* USB control message values */
121 #define REQUEST_TYPE_IN		(USB_TYPE_VENDOR | USB_DIR_IN)
122 #define REQUEST_TYPE_OUT	(USB_TYPE_VENDOR | USB_DIR_OUT)
123 #define REQUEST_REGISTER	0x0c
124 #define REQUEST_BUFFER		0x04
125 #define VALUE_BUFFER		0x82
126 #define VALUE_SET_REGISTER	0x83
127 #define VALUE_READ_REGISTER	0x84
128 #define VALUE_WRITE_REGISTER	0x85
129 #define VALUE_INIT		0x87
130 #define GPIO_OUTPUT_ENABLE	0x89
131 #define GPIO_READ		0x8a
132 #define GPIO_WRITE		0x8b
133 #define VALUE_BUF_ENDACCESS	0x8c
134 #define VALUE_GET_REGISTER	0x8e
135 #define INDEX			0x00
136 
137 /* todo: used?
138 #define VALUE_READ_STATUS	0x86
139 */
140 
141 /* Read/write bulk data/registers */
142 #define BULK_OUT		0x01
143 #define BULK_IN			0x00
144 #define BULK_RAM		0x00
145 #define BULK_REGISTER		0x11
146 
147 #define BULKOUT_MAXSIZE         0xF000
148 
149 /* AFE values */
150 #define AFE_INIT       1
151 #define AFE_SET        2
152 #define AFE_POWER_SAVE 4
153 
154 namespace genesys {
155 
156 class UsbDeviceEntry {
157 public:
158     static constexpr std::uint16_t BCD_DEVICE_NOT_SET = 0xffff;
159 
UsbDeviceEntry(std::uint16_t vendor_id,std::uint16_t product_id,const Genesys_Model & model)160     UsbDeviceEntry(std::uint16_t vendor_id, std::uint16_t product_id,
161                    const Genesys_Model& model) :
162         vendor_{vendor_id}, product_{product_id},
163         bcd_device_{BCD_DEVICE_NOT_SET}, model_{model}
164     {}
165 
UsbDeviceEntry(std::uint16_t vendor_id,std::uint16_t product_id,std::uint16_t bcd_device,const Genesys_Model & model)166     UsbDeviceEntry(std::uint16_t vendor_id, std::uint16_t product_id, std::uint16_t bcd_device,
167                    const Genesys_Model& model) :
168         vendor_{vendor_id}, product_{product_id},
169         bcd_device_{bcd_device}, model_{model}
170     {}
171 
vendor_id()172     std::uint16_t vendor_id() const { return vendor_; }
product_id()173     std::uint16_t product_id() const { return product_; }
bcd_device()174     std::uint16_t bcd_device() const { return bcd_device_; }
175 
model()176     const Genesys_Model& model() const { return model_; }
177 
matches(std::uint16_t vendor_id,std::uint16_t product_id,std::uint16_t bcd_device)178     bool matches(std::uint16_t vendor_id, std::uint16_t product_id, std::uint16_t bcd_device)
179     {
180         if (vendor_ != vendor_id)
181             return false;
182         if (product_ != product_id)
183             return false;
184         if (bcd_device_ != BCD_DEVICE_NOT_SET && bcd_device != BCD_DEVICE_NOT_SET &&
185             bcd_device_ != bcd_device)
186         {
187             return false;
188         }
189         return true;
190     }
191 
192 private:
193     // USB vendor identifier
194     std::uint16_t vendor_;
195     // USB product identifier
196     std::uint16_t product_;
197     // USB bcdProduct identifier
198     std::uint16_t bcd_device_;
199     // Scanner model information
200     Genesys_Model model_;
201 };
202 
203 /*--------------------------------------------------------------------------*/
204 /*       common functions needed by low level specific functions            */
205 /*--------------------------------------------------------------------------*/
206 
207 std::unique_ptr<CommandSet> create_cmd_set(AsicType asic_type);
208 
209 // reads the status of the scanner
210 Status scanner_read_status(Genesys_Device& dev);
211 
212 // reads the status of the scanner reliably. This is done by reading the status twice. The first
213 // read sometimes returns the home sensor as engaged when this is not true.
214 Status scanner_read_reliable_status(Genesys_Device& dev);
215 
216 // reads and prints the scanner status
217 void scanner_read_print_status(Genesys_Device& dev);
218 
219 void debug_print_status(DebugMessageHelper& dbg, Status status);
220 
221 void scanner_register_rw_clear_bits(Genesys_Device& dev, std::uint16_t address, std::uint8_t mask);
222 void scanner_register_rw_set_bits(Genesys_Device& dev, std::uint16_t address, std::uint8_t mask);
223 void scanner_register_rw_bits(Genesys_Device& dev, std::uint16_t address,
224                               std::uint8_t value, std::uint8_t mask);
225 
226 extern void sanei_genesys_write_ahb(Genesys_Device* dev, uint32_t addr, uint32_t size,
227                                     uint8_t* data);
228 
229 extern void sanei_genesys_init_structs (Genesys_Device * dev);
230 
231 const Genesys_Sensor& sanei_genesys_find_sensor_any(const Genesys_Device* dev);
232 const Genesys_Sensor& sanei_genesys_find_sensor(const Genesys_Device* dev, unsigned dpi,
233                                                 unsigned channels, ScanMethod scan_method);
234 bool sanei_genesys_has_sensor(const Genesys_Device* dev, unsigned dpi, unsigned channels,
235                               ScanMethod scan_method);
236 Genesys_Sensor& sanei_genesys_find_sensor_for_write(Genesys_Device* dev, unsigned dpi,
237                                                     unsigned channels, ScanMethod scan_method);
238 
239 std::vector<std::reference_wrapper<const Genesys_Sensor>>
240     sanei_genesys_find_sensors_all(const Genesys_Device* dev, ScanMethod scan_method);
241 std::vector<std::reference_wrapper<Genesys_Sensor>>
242     sanei_genesys_find_sensors_all_for_write(Genesys_Device* dev, ScanMethod scan_method);
243 
244 extern void sanei_genesys_init_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor,
245                                             int pixels_per_line);
246 
247 extern void sanei_genesys_read_valid_words(Genesys_Device* dev, unsigned int* steps);
248 
249 extern void sanei_genesys_read_scancnt(Genesys_Device* dev, unsigned int* steps);
250 
251 extern void sanei_genesys_read_feed_steps(Genesys_Device* dev, unsigned int* steps);
252 
253 void sanei_genesys_set_lamp_power(Genesys_Device* dev, const Genesys_Sensor& sensor,
254                                   Genesys_Register_Set& regs, bool set);
255 
256 void sanei_genesys_set_motor_power(Genesys_Register_Set& regs, bool set);
257 
258 bool should_enable_gamma(const ScanSession& session, const Genesys_Sensor& sensor);
259 
260 /** Calculates the values of the Z{1,2}MOD registers. They are a phase correction to synchronize
261     with the line clock during acceleration and deceleration.
262 
263     two_table is true if moving is done by two tables, false otherwise.
264 
265     acceleration_steps is the number of steps for acceleration, i.e. the number written to
266     REG_STEPNO.
267 
268     move_steps number of steps to move, i.e. the number written to REG_FEEDL.
269 
270     buffer_acceleration_steps, the number of steps for acceleration when buffer condition is met,
271     i.e. the number written to REG_FWDSTEP.
272 */
273 void sanei_genesys_calculate_zmod(bool two_table,
274                                   uint32_t exposure_time,
275                                   const std::vector<uint16_t>& slope_table,
276                                   unsigned acceleration_steps,
277                                   unsigned move_steps,
278                                   unsigned buffer_acceleration_steps,
279                                   uint32_t* out_z1, uint32_t* out_z2);
280 
281 extern void sanei_genesys_set_buffer_address(Genesys_Device* dev, uint32_t addr);
282 
283 unsigned sanei_genesys_get_bulk_max_size(AsicType asic_type);
284 
285 SANE_Int sanei_genesys_exposure_time2(Genesys_Device* dev, const MotorProfile& profile, float ydpi,
286                                       int endpixel, int led_exposure);
287 
288 void sanei_genesys_create_default_gamma_table(Genesys_Device* dev,
289                                               std::vector<uint16_t>& gamma_table, float gamma);
290 
291 std::vector<uint16_t> get_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor,
292                                       int color);
293 
294 void sanei_genesys_send_gamma_table(Genesys_Device* dev, const Genesys_Sensor& sensor);
295 
296 extern void sanei_genesys_stop_motor(Genesys_Device* dev);
297 
298 // moves the scan head by the specified steps at the motor base dpi
299 void scanner_move(Genesys_Device& dev, ScanMethod scan_method, unsigned steps, Direction direction);
300 
301 void scanner_move_back_home(Genesys_Device& dev, bool wait_until_home);
302 void scanner_move_back_home_ta(Genesys_Device& dev);
303 
304 /** Search for a full width black or white strip.
305     This function searches for a black or white stripe across the scanning area.
306     When searching backward, the searched area must completely be of the desired
307     color since this area will be used for calibration which scans forward.
308 
309     @param dev scanner device
310     @param forward true if searching forward, false if searching backward
311     @param black true if searching for a black strip, false for a white strip
312  */
313 void scanner_search_strip(Genesys_Device& dev, bool forward, bool black);
314 
315 bool should_calibrate_only_active_area(const Genesys_Device& dev,
316                                        const Genesys_Settings& settings);
317 
318 void scanner_offset_calibration(Genesys_Device& dev, const Genesys_Sensor& sensor,
319                                 Genesys_Register_Set& regs);
320 
321 void scanner_coarse_gain_calibration(Genesys_Device& dev, const Genesys_Sensor& sensor,
322                                      Genesys_Register_Set& regs, unsigned dpi);
323 
324 SensorExposure scanner_led_calibration(Genesys_Device& dev, const Genesys_Sensor& sensor,
325                                        Genesys_Register_Set& regs);
326 
327 void scanner_clear_scan_and_feed_counts(Genesys_Device& dev);
328 
329 void scanner_send_slope_table(Genesys_Device* dev, const Genesys_Sensor& sensor, unsigned table_nr,
330                               const std::vector<uint16_t>& slope_table);
331 
332 extern void sanei_genesys_write_file(const char* filename, const std::uint8_t* data,
333                                      std::size_t length);
334 
335 void wait_until_buffer_non_empty(Genesys_Device* dev, bool check_status_twice = false);
336 
337 extern void sanei_genesys_read_data_from_scanner(Genesys_Device* dev, uint8_t* data, size_t size);
338 
339 Image read_unshuffled_image_from_scanner(Genesys_Device* dev, const ScanSession& session,
340                                          std::size_t total_bytes);
341 
342 void regs_set_exposure(AsicType asic_type, Genesys_Register_Set& regs,
343                        const SensorExposure& exposure);
344 
345 void regs_set_optical_off(AsicType asic_type, Genesys_Register_Set& regs);
346 
347 void sanei_genesys_set_dpihw(Genesys_Register_Set& regs, unsigned dpihw);
348 
sanei_genesys_fixup_exposure(SensorExposure exposure)349 inline SensorExposure sanei_genesys_fixup_exposure(SensorExposure exposure)
350 {
351     exposure.red = std::max<std::uint16_t>(1, exposure.red);
352     exposure.green = std::max<std::uint16_t>(1, exposure.green);
353     exposure.blue = std::max<std::uint16_t>(1, exposure.blue);
354     return exposure;
355 }
356 
357 bool get_registers_gain4_bit(AsicType asic_type, const Genesys_Register_Set& regs);
358 
359 extern void sanei_genesys_wait_for_home(Genesys_Device* dev);
360 
361 extern void sanei_genesys_asic_init(Genesys_Device* dev);
362 
363 void scanner_start_action(Genesys_Device& dev, bool start_motor);
364 void scanner_stop_action(Genesys_Device& dev);
365 void scanner_stop_action_no_move(Genesys_Device& dev, Genesys_Register_Set& regs);
366 
367 bool scanner_is_motor_stopped(Genesys_Device& dev);
368 
369 void scanner_setup_sensor(Genesys_Device& dev, const Genesys_Sensor& sensor,
370                           Genesys_Register_Set& regs);
371 
372 const MotorProfile* get_motor_profile_ptr(const std::vector<MotorProfile>& profiles,
373                                           unsigned exposure,
374                                           const ScanSession& session);
375 
376 const MotorProfile& get_motor_profile(const std::vector<MotorProfile>& profiles,
377                                       unsigned exposure,
378                                       const ScanSession& session);
379 
380 MotorSlopeTable create_slope_table(AsicType asic_type, const Genesys_Motor& motor, unsigned ydpi,
381                                    unsigned exposure, unsigned step_multiplier,
382                                    const MotorProfile& motor_profile);
383 
384 MotorSlopeTable create_slope_table_fastest(AsicType asic_type, unsigned step_multiplier,
385                                            const MotorProfile& motor_profile);
386 
387 /** @brief find lowest motor resolution for the device.
388  * Parses the resolution list for motor and
389  * returns the lowest value.
390  * @param dev for which to find the lowest motor resolution
391  * @return the lowest available motor resolution for the device
392  */
393 extern
394 int sanei_genesys_get_lowest_ydpi(Genesys_Device *dev);
395 
396 /** @brief find lowest resolution for the device.
397  * Parses the resolution list for motor and sensor and
398  * returns the lowest value.
399  * @param dev for which to find the lowest resolution
400  * @return the lowest available resolution for the device
401  */
402 extern
403 int sanei_genesys_get_lowest_dpi(Genesys_Device *dev);
404 
405 bool sanei_genesys_is_compatible_calibration(Genesys_Device* dev,
406                                              const ScanSession& session,
407                                              const Genesys_Calibration_Cache* cache,
408                                              bool for_overwrite);
409 
410 extern void sanei_genesys_load_lut(unsigned char* lut,
411                                    int in_bits, int out_bits,
412                                    int out_min, int out_max,
413                                    int slope, int offset);
414 
415 extern void sanei_genesys_generate_gamma_buffer(Genesys_Device* dev,
416                                     const Genesys_Sensor& sensor,
417                                     int bits,
418                                     int max,
419                                     int size,
420                                     uint8_t* gamma);
421 
422 unsigned session_adjust_output_pixels(unsigned output_pixels,
423                                       const Genesys_Device& dev, const Genesys_Sensor& sensor,
424                                       unsigned output_xresolution, unsigned output_yresolution,
425                                       bool adjust_output_pixels);
426 
427 void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Sensor& sensor);
428 
429 ImagePipelineStack build_image_pipeline(const Genesys_Device& dev, const ScanSession& session,
430                                         unsigned pipeline_index, bool log_image_data);
431 
432 // sets up a image pipeline for device `dev`
433 void setup_image_pipeline(Genesys_Device& dev, const ScanSession& session);
434 
435 std::uint8_t compute_frontend_gain(float value, float target_value,
436                                    FrontendType frontend_type);
437 
438 /*---------------------------------------------------------------------------*/
439 /*                ASIC specific functions declarations                       */
440 /*---------------------------------------------------------------------------*/
441 
442 extern StaticInit<std::vector<Genesys_Sensor>> s_sensors;
443 extern StaticInit<std::vector<Genesys_Frontend>> s_frontends;
444 extern StaticInit<std::vector<Genesys_Gpo>> s_gpo;
445 extern StaticInit<std::vector<MemoryLayout>> s_memory_layout;
446 extern StaticInit<std::vector<Genesys_Motor>> s_motors;
447 extern StaticInit<std::vector<UsbDeviceEntry>> s_usb_devices;
448 
449 void genesys_init_sensor_tables();
450 void genesys_init_frontend_tables();
451 void genesys_init_gpo_tables();
452 void genesys_init_memory_layout_tables();
453 void genesys_init_motor_tables();
454 void genesys_init_usb_device_tables();
455 void verify_sensor_tables();
456 void verify_usb_device_tables();
457 
458 template<class T>
debug_dump(unsigned level,const T & value)459 void debug_dump(unsigned level, const T& value)
460 {
461     std::stringstream out;
462     out << value;
463     DBG(level, "%s\n", out.str().c_str());
464 }
465 
466 } // namespace genesys
467 
468 #endif /* not GENESYS_LOW_H */
469