summaryrefslogtreecommitdiff
path: root/backend/gt68xx_low.h
diff options
context:
space:
mode:
Diffstat (limited to 'backend/gt68xx_low.h')
-rw-r--r--backend/gt68xx_low.h1099
1 files changed, 1099 insertions, 0 deletions
diff --git a/backend/gt68xx_low.h b/backend/gt68xx_low.h
new file mode 100644
index 0000000..68cd7c5
--- /dev/null
+++ b/backend/gt68xx_low.h
@@ -0,0 +1,1099 @@
+/* sane - Scanner Access Now Easy.
+
+ Copyright (C) 2002 Sergey Vlasov <vsu@altlinux.ru>
+ Copyright (C) 2002 - 2007 Henning Geinitz <sane@geinitz.org>
+
+ This file is part of the SANE package.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, the authors of SANE give permission for
+ additional uses of the libraries contained in this release of SANE.
+
+ The exception is that, if you link a SANE library with other files
+ to produce an executable, this does not by itself cause the
+ resulting executable to be covered by the GNU General Public
+ License. Your use of that executable is in no way restricted on
+ account of linking the SANE library code into it.
+
+ This exception does not, however, invalidate any other reasons why
+ the executable file might be covered by the GNU General Public
+ License.
+
+ If you submit changes to SANE to the maintainers to be included in
+ a subsequent release, you agree by submitting the changes that
+ those changes may be distributed with this exception intact.
+
+ If you write modifications of your own for SANE, it is your choice
+ whether to permit this exception to apply to your modifications.
+ If you do not wish that, delete this exception notice.
+*/
+
+#ifndef GT68XX_LOW_H
+#define GT68XX_LOW_H
+
+/** @file
+ * @brief Low-level scanner interface functions.
+ */
+
+#include "../include/sane/sane.h"
+
+#include <stddef.h>
+
+#ifdef USE_FORK
+#include <sys/types.h>
+#include "gt68xx_shm_channel.h"
+#endif
+
+#ifdef NDEBUG
+#undef MAX_DEBUG
+#endif
+
+/* calculate the minimum/maximum values */
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+/* return the lower/upper 8 bits of a 16 bit word */
+#define HIBYTE(w) ((SANE_Byte)(((SANE_Word)(w) >> 8) & 0xFF))
+#define LOBYTE(w) ((SANE_Byte)(w))
+
+
+/* return if an error occured while the function was called */
+#ifdef MAX_DEBUG
+# ifndef __FUNCTION__
+# define __FUNCTION__ "somewhere"
+# endif
+
+# define RIE(function) \
+ do \
+ { \
+ status = function; \
+ if (status != SANE_STATUS_GOOD) \
+ { \
+ DBG (7, "%s: %s: %s\n", __FUNCTION__, STRINGIFY(function), \
+ sane_strstatus (status)); \
+ return status; \
+ } \
+ } \
+ while (SANE_FALSE)
+
+#else
+
+# define RIE(function) \
+ do { status = function; \
+ if (status != SANE_STATUS_GOOD) return status; \
+ } while (SANE_FALSE)
+
+#endif
+
+/* Flags */
+#define GT68XX_FLAG_MIRROR_X (1 << 0) /* CIS unit mounted the other way round? */
+#define GT68XX_FLAG_MOTOR_HOME (1 << 1) /* Use motor_home command (0x34) */
+#define GT68XX_FLAG_OFFSET_INV (1 << 2) /* Offset control is inverted */
+#define GT68XX_FLAG_UNTESTED (1 << 3) /* Print a warning for these scanners */
+#define GT68XX_FLAG_SE_2400 (1 << 4) /* Special quirks for SE 2400USB */
+#define GT68XX_FLAG_NO_STOP (1 << 5) /* Don't call stop_scan before the scan */
+#define GT68XX_FLAG_CIS_LAMP (1 << 6) /* CIS sensor with lamp */
+#define GT68XX_FLAG_NO_POWER_STATUS (1 << 7) /* get_power_status_doesn't work */
+#define GT68XX_FLAG_NO_LINEMODE (1 << 8) /* Linemode does not work with this scanner */
+#define GT68XX_FLAG_SCAN_FROM_HOME (1 << 9) /* Move home after calibration */
+#define GT68XX_FLAG_USE_OPTICAL_X (1 << 10) /* Use optical xdpi for 50 dpi and below */
+#define GT68XX_FLAG_ALWAYS_LINEMODE (1 << 11) /* Linemode must be used for any resolution */
+#define GT68XX_FLAG_SHEET_FED (1 << 12) /* we have a sheet fed scanner */
+#define GT68XX_FLAG_HAS_CALIBRATE (1 << 13) /* for sheet fed scanners that be calibrated with
+ an calibration sheet */
+
+/* Forward typedefs */
+typedef struct GT68xx_USB_Device_Entry GT68xx_USB_Device_Entry;
+typedef struct GT68xx_Command_Set GT68xx_Command_Set;
+typedef struct GT68xx_Model GT68xx_Model;
+typedef struct GT68xx_Device GT68xx_Device;
+typedef struct GT68xx_Scan_Request GT68xx_Scan_Request;
+typedef struct GT68xx_Scan_Parameters GT68xx_Scan_Parameters;
+typedef struct GT68xx_AFE_Parameters GT68xx_AFE_Parameters;
+typedef struct GT68xx_Exposure_Parameters GT68xx_Exposure_Parameters;
+
+typedef enum GT68xx_Color_Order
+{
+ COLOR_ORDER_RGB,
+ COLOR_ORDER_BGR
+}
+GT68xx_Color_Order;
+
+#define GT68XX_COLOR_RED SANE_I18N ("Red")
+#define GT68XX_COLOR_GREEN SANE_I18N ("Green")
+#define GT68XX_COLOR_BLUE SANE_I18N ("Blue")
+
+/** Scan action code (purpose of the scan).
+ *
+ * The scan action code affects various scanning mode fields in the setup
+ * command.
+ */
+typedef enum GT68xx_Scan_Action
+{
+ SA_CALIBRATE, /**< Calibration scan, no offsets, no LD
+ correction */
+ SA_CALIBRATE_ONE_LINE, /**< Same, but only one line for auto AFE */
+ SA_SCAN /**< Normal scan */
+}
+GT68xx_Scan_Action;
+
+/** USB device list entry. */
+struct GT68xx_USB_Device_Entry
+{
+ SANE_Word vendor; /**< USB vendor identifier */
+ SANE_Word product; /**< USB product identifier */
+ GT68xx_Model *model; /**< Scanner model information */
+};
+
+#define MAX_SCANNERS 50
+/* Looks like gcc doesn't like declarations without specificating the number
+ of array elements at least when --enable-warnings is active */
+
+/** List of all supported devices.
+ *
+ * This is an array of GT68xx_USB_Device_Entry structures which describe
+ * USB devices supported by this backend. The array is terminated by an
+ * entry with model = NULL.
+ *
+ */
+static GT68xx_USB_Device_Entry gt68xx_usb_device_list[MAX_SCANNERS];
+
+/** GT68xx analog front-end (AFE) parameters.
+ */
+struct GT68xx_AFE_Parameters
+{
+ SANE_Byte r_offset; /**< Red channel offset */
+ SANE_Byte r_pga; /**< Red channel PGA gain */
+ SANE_Byte g_offset; /**< Green channel offset (also used for mono) */
+ SANE_Byte g_pga; /**< Green channel PGA gain (also used for mono) */
+ SANE_Byte b_offset; /**< Blue channel offset */
+ SANE_Byte b_pga; /**< Blue channel PGA gain */
+};
+
+/** GT68xx exposure time parameters.
+ */
+struct GT68xx_Exposure_Parameters
+{
+ SANE_Int r_time; /**< Red exposure time */
+ SANE_Int g_time; /**< Red exposure time */
+ SANE_Int b_time; /**< Red exposure time */
+};
+
+
+/**
+ * Scanner command set description.
+ *
+ * This description contains parts which are common to all scanners with the
+ * same command set, but may have different optical resolution and other
+ * parameters.
+ */
+struct GT68xx_Command_Set
+{
+ /** @name Identification */
+ /*@{ */
+
+ /** Name of this command set */
+ SANE_String_Const name;
+
+ /*@} */
+
+ /** @name USB request parameters
+ *
+ * These values are used in the USB control transfer parameters (wValue and
+ * wIndex fields, as in the USB specification).
+ */
+ /*@{ */
+
+ SANE_Byte request_type; /**< Request type (should be 0x40, vendor spec) */
+ SANE_Byte request; /**< Vendor spec resquest (0x01 or 0x04) */
+ SANE_Word memory_read_value; /**< Memory read - wValue */
+ SANE_Word memory_write_value; /**< Memory write - wValue */
+ SANE_Word send_cmd_value; /**< Send normal command - wValue */
+ SANE_Word send_cmd_index; /**< Send normal command - wIndex */
+ SANE_Word recv_res_value; /**< Receive normal result - wValue */
+ SANE_Word recv_res_index; /**< Receive normal result - wIndex */
+ SANE_Word send_small_cmd_value; /**< Send small command - wValue */
+ SANE_Word send_small_cmd_index; /**< Send small command - wIndex */
+ SANE_Word recv_small_res_value; /**< Receive small result - wValue */
+ SANE_Word recv_small_res_index; /**< Receive small result - wIndex */
+
+ /*@} */
+
+ /** @name Activation/deactivation hooks
+ *
+ * These hooks can be used to perform additional actions when the device is
+ * activated and deactivated.
+ */
+ /*@{ */
+
+ /** Activate the device.
+ *
+ * This function may allocate a command-set-specific data structure and place
+ * the pointer to it into the GT68xx_Device::command_set_private field.
+ */
+ SANE_Status (*activate) (GT68xx_Device * dev);
+
+ /** Deactivate the device.
+ *
+ * If the activate function has allocated a command-set-specific data
+ * structure, this function must free all corresponding resources and set the
+ * GT68xx_Device::command_set_private pointer to #NULL.
+ */
+ SANE_Status (*deactivate) (GT68xx_Device * dev);
+
+ /*@} */
+
+ /** @name Low-level command implementation functions
+ *
+ * These functions should implement the corresponding commands for the
+ * particular command set. If a function cannot be implemented because there
+ * is no corresponding command in the command set, the function pointer
+ * should be set to #NULL; the wrapper will return #SANE_STATUS_UNSUPPORTED
+ * in this case.
+ */
+ /*@{ */
+
+ /** Check whether the firmware is already downloaded.
+ *
+ * @param dev Device object.
+ * @param loaded Returned firmware status:
+ * - #SANE_TRUE - the firmware is already loaded.
+ * - #SANE_FALSE - the firmware is not loaded.
+ */
+ SANE_Status (*check_firmware) (GT68xx_Device * dev, SANE_Bool * loaded);
+
+ /** Download the firmware */
+ SANE_Status (*download_firmware) (GT68xx_Device * dev,
+ SANE_Byte * data, SANE_Word size);
+
+ /** Check whether the external power supply is connected.
+ *
+ * @param dev Device object.
+ * @param power_ok Returned power status:
+ * - #SANE_TRUE - the external power supply is connected, or the scanner does
+ * not need external power.
+ * - #SANE_FALSE - the external power supply is not connected, so the scanner
+ * will not work.
+ */
+ SANE_Status (*get_power_status) (GT68xx_Device * dev,
+ SANE_Bool * power_ok);
+
+ /** Check whether a transparency adapter is attached to the scanner.
+ *
+ * @param dev Device object.
+ * @param ta_attached Returned transparency adapter status:
+ * - #SANE_TRUE - the transparency adapter is connected.
+ * - #SANE_FALSE - the transparency adapter is not connected.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - transparency adapter status was checked
+ * successfully; check @a *ta_attached for the result.
+ * - #SANE_STATUS_UNSUPPORTED - this scanner model does not support the
+ * transparency adapter.
+ * */
+ SANE_Status (*get_ta_status) (GT68xx_Device * dev,
+ SANE_Bool * ta_attached);
+
+ /** Turn the lamps in the scanner and/or the transparency adapter on or off.
+ *
+ * @param dev Device object.
+ * @param fb_lamp #SANE_TRUE turns on the flatbed lamp.
+ * @param ta_lamp #SANE_TRUE turns on the transparency adapter lamp.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - the command completed successfully.
+ * - #SANE_STATUS_UNSUPPORTED - unsupported request was made (like attempt to
+ * turn on the TA lamp on a scanner which does not support TA).
+ */
+ SANE_Status (*lamp_control) (GT68xx_Device * dev, SANE_Bool fb_lamp,
+ SANE_Bool ta_lamp);
+
+ /** Check whether the scanner carriage is still moving.
+ *
+ * @param dev Device object.
+ * @param moving Returned state of the scanner:
+ * - #SANE_TRUE - the scanner carriage is still moving.
+ * - #SANE_FALSE - the scanner carriage has stopped.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - the command completed successfully, the status in @a
+ * *moving is valid.
+ */
+ SANE_Status (*is_moving) (GT68xx_Device * dev, SANE_Bool * moving);
+
+
+ /** Move the scanner carriage by the specified number of steps.
+ *
+ * @param dev Device object.
+ * @param distance Number of steps to move (positive to move forward,
+ * negative to move backward). The measurement unit is model-dependent;
+ * number of steps per inch is found in the GT68xx_Model::base_ydpi field.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - the command completed successfully; the movement is
+ * started. Call gt68xx_device_is_moving() periodically to determine when
+ * the movement is complete.
+ */
+ SANE_Status (*move_relative) (GT68xx_Device * dev, SANE_Int distance);
+
+ /** Move the scanner carriage to the home position.
+ *
+ * @param dev Device object.
+ */
+ SANE_Status (*carriage_home) (GT68xx_Device * dev);
+
+ /** Eject the paper at the end of the scan.
+ *
+ * @param dev Device object.
+ */
+ SANE_Status (*paperfeed) (GT68xx_Device * dev);
+
+ /** Start scanning the image.
+ *
+ * @param dev Device object.
+ */
+ SANE_Status (*start_scan) (GT68xx_Device * dev);
+
+ /** Start reading the scanned image data from the scanner.
+ *
+ * @param dev Device object.
+ * */
+ SANE_Status (*read_scanned_data) (GT68xx_Device * dev, SANE_Bool * ready);
+
+ /** Stop scanning the image and reading the data. */
+ SANE_Status (*stop_scan) (GT68xx_Device * dev);
+
+ /** Set parameters for the next scan. */
+ SANE_Status (*setup_scan) (GT68xx_Device * dev,
+ GT68xx_Scan_Request * request,
+ GT68xx_Scan_Action action,
+ GT68xx_Scan_Parameters * params);
+
+ SANE_Status (*set_afe) (GT68xx_Device * dev,
+ GT68xx_AFE_Parameters * params);
+
+ SANE_Status (*set_exposure_time) (GT68xx_Device * dev,
+ GT68xx_Exposure_Parameters * params);
+
+ /** Get the vendor, product and some more ids from the scanner */
+ SANE_Status (*get_id) (GT68xx_Device * dev);
+
+ /** Move the paper by the amount of y offset needed to reach scan area
+ *
+ * @param dev Device object.
+ * @param request scan request used to compute move to reach scan area
+ */
+ SANE_Status (*move_paper) (GT68xx_Device * dev,
+ GT68xx_Scan_Request * request);
+
+ /** Detect if a document is inserted in the feeder
+ *
+ * @param dev Device object.
+ * @param present
+ */
+ SANE_Status (*document_present) (GT68xx_Device * dev,
+ SANE_Bool *present);
+ /*@} */
+};
+
+#define MAX_RESOLUTIONS 12
+#define MAX_DPI 4
+
+/** Model-specific scanner data.
+ */
+struct GT68xx_Model
+{
+ /** @name Identification */
+ /*@{ */
+
+ /** A single lowercase word to be used in the configuration file. */
+ SANE_String_Const name;
+
+ /** Device vendor string. */
+ SANE_String_Const vendor;
+
+ /** Device model name. */
+ SANE_String_Const model;
+
+ /** Name of the firmware file. */
+ SANE_String_Const firmware_name;
+
+ /** Dynamic allocation flag.
+ *
+ * This flag must be set to SANE_TRUE if the structure is dynamically
+ * allocated; in this case the structure will be freed when the GT68xx_Device
+ * is freed.
+ */
+ SANE_Bool allocated;
+ /*@} */
+
+ /** @name Scanner model parameters */
+ /*@{ */
+
+ GT68xx_Command_Set *command_set;
+
+ SANE_Int optical_xdpi; /* maximum resolution in x-direction */
+ SANE_Int optical_ydpi; /* maximum resolution in y-direction */
+ SANE_Int base_xdpi; /* x-resolution used to calculate geometry */
+ SANE_Int base_ydpi; /* y-resolution used to calculate geometry */
+ SANE_Int ydpi_no_backtrack; /* if ydpi is equal or higher, disable backtracking */
+ SANE_Bool constant_ydpi; /* Use base_ydpi for all resolutions */
+
+ SANE_Int xdpi_values[MAX_RESOLUTIONS]; /* possible x resolutions */
+ SANE_Int ydpi_values[MAX_RESOLUTIONS]; /* possible y resolutions */
+ SANE_Int bpp_gray_values[MAX_DPI]; /* possible depths in gray mode */
+ SANE_Int bpp_color_values[MAX_DPI]; /* possible depths in color mode */
+
+ SANE_Fixed x_offset; /* Start of scan area in mm */
+ SANE_Fixed y_offset; /* Start of scan area in mm */
+ SANE_Fixed x_size; /* Size of scan area in mm */
+ SANE_Fixed y_size; /* Size of scan area in mm */
+
+ SANE_Fixed y_offset_calib; /* Start of white strip in mm */
+ SANE_Fixed x_offset_mark; /* Start of black mark in mm */
+
+ SANE_Fixed x_offset_ta; /* Start of scan area in TA mode in mm */
+ SANE_Fixed y_offset_ta; /* Start of scan area in TA mode in mm */
+ SANE_Fixed x_size_ta; /* Size of scan area in TA mode in mm */
+ SANE_Fixed y_size_ta; /* Size of scan area in TA mode in mm */
+
+ SANE_Fixed y_offset_calib_ta; /* Start of white strip in TA mode in mm */
+
+ /* Line-distance correction (in pixel at optical_ydpi) for CCD scanners */
+ SANE_Int ld_shift_r; /* red */
+ SANE_Int ld_shift_g; /* green */
+ SANE_Int ld_shift_b; /* blue */
+ SANE_Int ld_shift_double; /* distance between two CCD lines of one color
+ (only applicable for CCD with 6 lines) */
+
+ GT68xx_Color_Order line_mode_color_order; /* Order of the CCD/CIS colors */
+
+ GT68xx_AFE_Parameters afe_params; /* Default offset/gain */
+ GT68xx_Exposure_Parameters exposure; /* Default exposure parameters */
+ SANE_Fixed default_gamma_value; /* Default gamma value */
+
+ SANE_Bool is_cis; /* Is this a CIS or CCD scanner? */
+
+ SANE_Word flags; /* Which hacks are needed for this scanner? */
+ /*@} */
+};
+
+/** GT68xx device instance.
+ *
+ */
+struct GT68xx_Device
+{
+ /** Device file descriptor. */
+ int fd;
+
+ /** Device activation flag. */
+ SANE_Bool active;
+
+ /** Device missing to flag devices that are unplugged
+ * after sane_init and befor sane_exit */
+ SANE_Bool missing;
+
+ /** Scanner model data. */
+ GT68xx_Model *model;
+
+ /** Pointer to command-set-specific data. */
+ void *command_set_private;
+
+ GT68xx_AFE_Parameters *afe;
+ GT68xx_Exposure_Parameters *exposure;
+ SANE_Fixed gamma_value;
+
+ SANE_Bool read_active;
+ SANE_Bool final_scan;
+ SANE_Byte *read_buffer;
+ size_t requested_buffer_size;
+ size_t read_buffer_size;
+ size_t read_pos;
+ size_t read_bytes_in_buffer;
+ size_t read_bytes_left;
+ SANE_Byte gray_mode_color;
+ SANE_Bool manual_selection;
+#ifdef USE_FORK
+ Shm_Channel *shm_channel;
+ pid_t reader_pid;
+#endif /* USE_FORK */
+
+ /** Pointer to next device */
+ struct GT68xx_Device *next;
+
+ /** Device file name */
+ SANE_String file_name;
+};
+
+/** Parameters for the high-level scan request.
+ *
+ * These parameters describe the scan request sent by the SANE frontend.
+ */
+struct GT68xx_Scan_Request
+{
+ SANE_Fixed x0; /**< Left boundary */
+ SANE_Fixed y0; /**< Top boundary */
+ SANE_Fixed xs; /**< Width */
+ SANE_Fixed ys; /**< Height */
+ SANE_Int xdpi; /**< Horizontal resolution */
+ SANE_Int ydpi; /**< Vertical resolution */
+ SANE_Int depth; /**< Number of bits per channel */
+ SANE_Bool color; /**< Color mode flag */
+ SANE_Bool mbs; /**< Move before scan */
+ SANE_Bool mds; /**< Move during scan */
+ SANE_Bool mas; /**< Move after scan */
+ SANE_Bool lamp; /**< Lamp on/off */
+ SANE_Bool calculate; /**< Don't scan, only calculate parameters */
+ SANE_Bool use_ta; /**< Use the tansparency adapter */
+ SANE_Bool backtrack; /**< Enable backtracking */
+ SANE_Bool backtrack_lines; /**< How many lines to backtrack */
+};
+
+/** Scan parameters for gt68xx_device_setup_scan().
+ *
+ * These parameters describe a low-level scan request; many such requests are
+ * executed during calibration, and they need to have parameters separate from
+ * the main request (GT68xx_Scan_Request).
+ */
+struct GT68xx_Scan_Parameters
+{
+ SANE_Int xdpi; /**< Horizontal resolution */
+ SANE_Int ydpi; /**< Vertical resolution */
+ SANE_Int depth; /**< Number of bits per channel */
+ SANE_Bool color; /**< Color mode flag */
+
+ SANE_Int pixel_xs; /**< Logical width in pixels */
+ SANE_Int pixel_ys; /**< Logical height in pixels */
+ SANE_Int scan_xs; /**< Physical width in pixels */
+ SANE_Int scan_ys; /**< Physical height in pixels */
+ SANE_Int scan_bpl; /**< Number of bytes per scan line */
+ SANE_Bool line_mode; /**< Use line mode instead of pixel mode */
+ SANE_Int overscan_lines; /**< Number of extra scan lines */
+ SANE_Int ld_shift_r;
+ SANE_Int ld_shift_g;
+ SANE_Int ld_shift_b;
+ SANE_Int ld_shift_double;
+ SANE_Int double_column;
+ SANE_Int pixel_x0; /**< x start postion */
+};
+
+
+#define GT68XX_PACKET_SIZE 64
+
+typedef SANE_Byte GT68xx_Packet[GT68XX_PACKET_SIZE];
+
+/** Create a new GT68xx_Device object.
+ *
+ * The newly created device object is in the closed state.
+ *
+ * @param dev_return Returned pointer to the created device object.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - the device object was created.
+ * - #SANE_STATUS_NO_MEM - not enough system resources to create the object.
+ */
+static SANE_Status gt68xx_device_new (GT68xx_Device ** dev_return);
+
+/** Destroy the device object and release all associated resources.
+ *
+ * If the device was active, it will be deactivated; if the device was open, it
+ * will be closed.
+ *
+ * @param dev Device object.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - success.
+ */
+static SANE_Status gt68xx_device_free (GT68xx_Device * dev);
+
+/** Open the scanner device.
+ *
+ * This function opens the device special file @a dev_name and tries to detect
+ * the device model by its USB ID.
+ *
+ * If the device is detected successfully (its USB ID is found in the supported
+ * device list), this function sets the appropriate model parameters.
+ *
+ * If the USB ID is not recognized, the device remains unconfigured; an attempt
+ * to activate it will fail unless gt68xx_device_set_model() is used to force
+ * the parameter set. Note that the open is considered to be successful in
+ * this case.
+ *
+ * @param dev Device object.
+ * @param dev_name Scanner device name.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - the device was opened successfully (it still may be
+ * unconfigured).
+ */
+static SANE_Status
+gt68xx_device_open (GT68xx_Device * dev, const char *dev_name);
+
+/** Close the scanner device.
+ *
+ * @param dev Device object.
+ */
+static SANE_Status gt68xx_device_close (GT68xx_Device * dev);
+
+/** Check if the device is configured.
+ *
+ * A device is considered configured when it has a model parameters structure
+ * (GT68xx_Model) and a command set (GT68xx_Command_Set). Normally these
+ * parameters are assigned automatically by gt68xx_device_open(), if the device
+ * is known. If the USB ID of the device is not found in the list, or the OS
+ * does not support identification of USB devices, the device will be
+ * unconfigured after opening.
+ *
+ * @param dev Device object.
+ *
+ * @return
+ * - #SANE_TRUE - device is configured and can be activated.
+ * - #SANE_FALSE - device is not configured; attempt to activate it will fail.
+ */
+static SANE_Bool gt68xx_device_is_configured (GT68xx_Device * dev);
+
+/** Change the device model structure.
+ *
+ * This function can be used to change all model-dependent parameters at once
+ * by supplying a whole model data structure. The model may be changed only
+ * when the device is not active.
+ *
+ * If the device already had a model structure which was dynamically allocated,
+ * the old structure is freed.
+ *
+ * If the new model structure @a model is dynamically allocated, the device @a
+ * dev takes ownership of it: @a model will be freed when @a dev is destroyed
+ * or gt68xx_device_set_model() is called again.
+ *
+ * @param dev Device object.
+ * @param model Device model data.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - model successfully changed.
+ * - #SANE_STATUS_INVAL - invalid request (attempt to change model when the
+ * device is already active, or not yet opened).
+ */
+static SANE_Status
+gt68xx_device_set_model (GT68xx_Device * dev, GT68xx_Model * model);
+
+/** Get model by name.
+ *
+ * This function can be used to find a model by its name.
+ *
+ * @param name Device model name.
+ * @param model Device model data.
+ *
+ * @return
+ * - #SANE_TRUE - model successfully found.
+ * - #SANE_FALSE - model not found.
+ */
+static SANE_Bool
+gt68xx_device_get_model (SANE_String name, GT68xx_Model ** model);
+
+#if 0
+/** Create a new private copy of the model data for this device.
+ *
+ * Normally the model data structures can be shared between several devices.
+ * If the program needs to modify some model parameters for a device, it must
+ * call this function to make a private copy of parameters. This private copy
+ * will be automatically freed when the device is destroyed.
+ *
+ * @param dev Device object.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - a private copy was made successfully.
+ * - #SANE_STATUS_INVAL - invalid request (the device was already active, or
+ * not yet opened).
+ * - #SANE_STATUS_NO_MEM - not enough memory for copy of the model parameters.
+ */
+static SANE_Status gt68xx_device_unshare_model (GT68xx_Device * dev);
+#endif
+
+/** Activate the device.
+ *
+ * The device must be activated before performing any I/O operations with it.
+ * All device model parameters must be configured before activation; it is
+ * impossible to change them after the device is active.
+ *
+ * This function might need to acquire resources (it calls
+ * GT68xx_Command_Set::activate). These resources will be released when
+ * gt68xx_device_deactivate() is called.
+ *
+ * @param dev Device object.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - device activated successfully.
+ * - #SANE_STATUS_INVAL - invalid request (attempt to activate a closed or
+ * unconfigured device).
+ */
+static SANE_Status gt68xx_device_activate (GT68xx_Device * dev);
+
+/** Deactivate the device.
+ *
+ * This function reverses the action of gt68xx_device_activate().
+ *
+ * @param dev Device object.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - device deactivated successfully.
+ * - #SANE_STATUS_INVAL - invalid request (the device was not activated).
+ */
+static SANE_Status gt68xx_device_deactivate (GT68xx_Device * dev);
+
+/** Write a data block to the GT68xx memory.
+ *
+ * @param dev Device object.
+ * @param addr Start address in the GT68xx memory.
+ * @param size Size of the data block in bytes.
+ * @param data Data block to write.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - success.
+ * - #SANE_STATUS_IO_ERROR - a communication error occured.
+ *
+ * @warning
+ * @a size must be a multiple of 64 (at least with GT6816), otherwise the
+ * scanner (and possibly the entire USB bus) will lock up.
+ */
+static SANE_Status
+gt68xx_device_memory_write (GT68xx_Device * dev, SANE_Word addr,
+ SANE_Word size, SANE_Byte * data);
+
+/** Read a data block from the GT68xx memory.
+ *
+ * @param dev Device object.
+ * @param addr Start address in the GT68xx memory.
+ * @param size Size of the data block in bytes.
+ * @param data Buffer for the read data.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - success.
+ * - #SANE_STATUS_IO_ERROR - a communication error occured.
+ *
+ * @warning
+ * @a size must be a multiple of 64 (at least with GT6816), otherwise the
+ * scanner (and possibly the entire USB bus) will lock up.
+ */
+static SANE_Status
+gt68xx_device_memory_read (GT68xx_Device * dev, SANE_Word addr,
+ SANE_Word size, SANE_Byte * data);
+
+/** Execute a control command.
+ *
+ * @param dev Device object.
+ * @param cmd Command packet.
+ * @param res Result packet (may point to the same buffer as @a cmd).
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - success.
+ * - #SANE_STATUS_IO_ERROR - a communication error occured.
+ */
+static SANE_Status
+gt68xx_device_req (GT68xx_Device * dev, GT68xx_Packet cmd, GT68xx_Packet res);
+
+/** Execute a "small" control command.
+ *
+ * @param dev Device object.
+ * @param cmd Command packet; only first 8 bytes are used.
+ * @param res Result packet (may point to the same buffer as @a cmd).
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - success.
+ * - #SANE_STATUS_IO_ERROR - a communication error occured.
+ */
+static SANE_Status
+gt68xx_device_small_req (GT68xx_Device * dev, GT68xx_Packet cmd,
+ GT68xx_Packet res);
+
+#if 0
+/** Check whether the firmware is downloaded into the scanner.
+ *
+ * @param dev Device object.
+ * @param loaded Returned firmware status:
+ * - #SANE_TRUE - the firmware is already loaded.
+ * - #SANE_FALSE - the firmware is not loaded.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - success.
+ * - #SANE_STATUS_IO_ERROR - a communication error occured.
+ */
+static SANE_Status
+gt68xx_device_check_firmware (GT68xx_Device * dev, SANE_Bool * loaded);
+#endif
+
+static SANE_Status
+gt68xx_device_download_firmware (GT68xx_Device * dev,
+ SANE_Byte * data, SANE_Word size);
+
+/** Check whether the external power supply is connected.
+ *
+ * @param dev Device object.
+ * @param power_ok Returned power status:
+ * - #SANE_TRUE - the external power supply is connected, or the scanner does
+ * not need external power.
+ * - #SANE_FALSE - the external power supply is not connected, so the scanner
+ * will not work.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - success.
+ * - #SANE_STATUS_IO_ERROR - a communication error occured.
+ */
+static SANE_Status
+gt68xx_device_get_power_status (GT68xx_Device * dev, SANE_Bool * power_ok);
+
+/** Check whether the transparency adapter is connected.
+ *
+ * @param dev Device object.
+ * @param ta_attached Returned TA status:
+ * - #SANE_TRUE - the TA is connected.
+ * - #SANE_FALSE - the TA is not connected.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - success.
+ * - #SANE_STATUS_UNSUPPORTED - the scanner does not support TA connection.
+ * - #SANE_STATUS_IO_ERROR - a communication error occured.
+ */
+static SANE_Status
+gt68xx_device_get_ta_status (GT68xx_Device * dev, SANE_Bool * ta_attached);
+
+/** Turn the lamps in the scanner and/or the transparency adapter on or off.
+ *
+ * @param dev Device object.
+ * @param fb_lamp #SANE_TRUE turns on the flatbed lamp.
+ * @param ta_lamp #SANE_TRUE turns on the transparency adapter lamp.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - success.
+ * - #SANE_STATUS_IO_ERROR - a communication error occured.
+ * - #SANE_STATUS_UNSUPPORTED - unsupported request was made (like attempt to
+ * turn on the TA lamp on a scanner which does not support TA).
+ */
+static SANE_Status
+gt68xx_device_lamp_control (GT68xx_Device * dev, SANE_Bool fb_lamp,
+ SANE_Bool ta_lamp);
+
+/** Check whether the scanner carriage is still moving.
+ *
+ * @param dev Device object.
+ * @param moving Returned state of the scanner:
+ * - #SANE_TRUE - the scanner carriage is still moving.
+ * - #SANE_FALSE - the scanner carriage has stopped.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - success; the status in @a *moving is valid.
+ * - #SANE_STATUS_IO_ERROR - a communication error occured.
+ */
+static SANE_Status
+gt68xx_device_is_moving (GT68xx_Device * dev, SANE_Bool * moving);
+
+#if 0
+/** Move the scanner carriage by the specified number of steps.
+ *
+ * @param dev Device object.
+ * @param distance Number of steps to move (positive to move forward, negative
+ * to move backward). The measurement unit is model-dependent; number of steps
+ * per inch is found in the GT68xx_Model::base_ydpi field.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - success; the movement is started. Call
+ * gt68xx_device_is_moving() periodically to determine when the movement is
+ * complete.
+ * - #SANE_STATUS_IO_ERROR - a communication error occured.
+ */
+static SANE_Status
+gt68xx_device_move_relative (GT68xx_Device * dev, SANE_Int distance);
+#endif
+
+/** Move the scanner carriage to the home position.
+ *
+ * This function starts moving the scanner carriage to the home position, but
+ * deos not wait for finishing the movement. To determine when the carriage
+ * returned to the home position, the program should periodically call
+ * gt68xx_device_is_moving().
+ *
+ * @param dev Device object.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - success; the movement is started.
+ * - #SANE_STATUS_IO_ERROR - a communication error occured.
+ */
+static SANE_Status gt68xx_device_carriage_home (GT68xx_Device * dev);
+
+/** Eject the paper after the end of scanning.
+ *
+ *
+ * @param dev Device object.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - success; the movement is started.
+ * - #SANE_STATUS_IO_ERROR - a communication error occured.
+ */
+static SANE_Status gt68xx_device_paperfeed (GT68xx_Device * dev);
+
+/** Start scanning the image.
+ *
+ * This function initiates scanning with parameters set by
+ * gt68xx_device_setup_scan() (which should be called before). In particular,
+ * it starts the carriage movement to the start of the scanning window.
+ *
+ * After calling this function, gt68xx_device_read_scanned_data() should be
+ * called repeatedly until the scanner signals that it is ready to deliver the
+ * data.
+ *
+ * @param dev Device object.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - success.
+ * - #SANE_STATUS_IO_ERROR - a communication error occured.
+ */
+static SANE_Status gt68xx_device_start_scan (GT68xx_Device * dev);
+
+/** Start reading the scanned image data.
+ *
+ * This function should be used only after gt68xx_device_start_scan(). It
+ * should be called repeatedly until @a *ready flag becomes true, at which
+ * point reading the image data should be started using
+ * gt68xx_device_read_prepare().
+ *
+ * @param dev Device object.
+ * @param ready Returned status of the scanner:
+ * - #SANE_TRUE - the scanner is ready to send data.
+ * - #SANE_FALSE - the scanner is not ready (e.g., the carriage has not reached
+ * the start of the scanning window).
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - success; the value in @a *ready is valid.
+ * - #SANE_STATUS_IO_ERROR - a communication error occured.
+ */
+static SANE_Status
+gt68xx_device_read_scanned_data (GT68xx_Device * dev, SANE_Bool * ready);
+
+/** Stop scanning the image.
+ *
+ * This function should be used after reading all image data from the scanner,
+ * or in the middle of scan to abort the scanning process.
+ *
+ * @param dev Device object.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - success.
+ * - #SANE_STATUS_IO_ERROR - a communication error occured.
+ */
+static SANE_Status gt68xx_device_stop_scan (GT68xx_Device * dev);
+
+/** Set parameters for the next scan.
+ *
+ * This function calculates the hardware-dependent scanning parameters and,
+ * unless @a calculate_only is set, sends the command to prepare for scanning
+ * with the specified window and parameters.
+ *
+ * @param dev Device object.
+ * @param request High-level scanning request.
+ * @param action Action code describing the phase of calibration or scanning
+ * process.
+ * @param params Returned structure with hardware-dependent scanning
+ * parameters.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - success.
+ * - #SANE_STATUS_UNSUPPORTED - the requested scanning parameters in @a request
+ * are not supported by hardware.
+ * - #SANE_STATUS_INVAL - some of the parameters in @a request, or the @a
+ * action code, are completely invalid.
+ * - #SANE_STATUS_IO_ERROR - a communication error occured.
+ */
+static SANE_Status
+gt68xx_device_setup_scan (GT68xx_Device * dev,
+ GT68xx_Scan_Request * request,
+ GT68xx_Scan_Action action,
+ GT68xx_Scan_Parameters * params);
+
+/** Configure the analog front-end (AFE) of the GT68xx.
+ *
+ * @param dev Device object.
+ * @param params AFE parameters.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - success.
+ * - #SANE_STATUS_IO_ERROR - a communication error occured.
+ */
+static SANE_Status
+gt68xx_device_set_afe (GT68xx_Device * dev, GT68xx_AFE_Parameters * params);
+
+static SANE_Status
+gt68xx_device_set_exposure_time (GT68xx_Device * dev,
+ GT68xx_Exposure_Parameters * params);
+
+/** Read raw data from the bulk-in scanner pipe.
+ *
+ * @param dev Device object.
+ * @param buffer Buffer for the read data.
+ * @param size Pointer to the variable which must be set to the requested data
+ * size before call. After completion this variable will hold the number of
+ * bytes actually read.
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - success.
+ * - #SANE_STATUS_IO_ERROR - a communication error occured.
+ */
+static SANE_Status
+gt68xx_device_read_raw (GT68xx_Device * dev, SANE_Byte * buffer,
+ size_t * size);
+
+static SANE_Status
+gt68xx_device_set_read_buffer_size (GT68xx_Device * dev, size_t buffer_size);
+
+static SANE_Status
+gt68xx_device_read_prepare (GT68xx_Device * dev, size_t expected_count,
+ SANE_Bool final_scan);
+
+static SANE_Status
+gt68xx_device_read (GT68xx_Device * dev, SANE_Byte * buffer, size_t * size);
+
+static SANE_Status gt68xx_device_read_finish (GT68xx_Device * dev);
+
+/** Make sure that the result of a command is ok.
+ *
+ * @param res Result packet from the last command
+ * @param command Command
+ *
+ * @return
+ * - #SANE_STATUS_GOOD - success.
+ * - #SANE_STATUS_IO_ERROR - the command wasn't successful
+*/
+static SANE_Status
+gt68xx_device_check_result (GT68xx_Packet res, SANE_Byte command);
+
+
+static SANE_Status
+gt68xx_device_get_id (GT68xx_Device * dev);
+
+/** Read the device descriptor of the scanner.
+ *
+ * This function should be called before closing the device to make sure
+ * that the device descriptor is propperly stored in the scanner's memory.
+ * If that's not done, the next try to get the config descriptor will
+ * result in a corrupted descriptor.
+ *
+ * @param dev device
+*/
+static void
+gt68xx_device_fix_descriptor (GT68xx_Device * dev);
+
+#endif /* not GT68XX_LOW_H */
+
+/* vim: set sw=2 cino=>2se-1sn-1s{s^-1st0(0u0 smarttab expandtab: */