kopia lustrzana https://gitlab.com/sane-project/backends
- rts8891 backend inclusion
rodzic
2330d122e0
commit
b85ec879da
5
AUTHORS
5
AUTHORS
|
@ -35,7 +35,7 @@ Backends:
|
|||
fujitsu: Randolph Bentson, Frederik Ramm, Oliver Schirrmeister (*),
|
||||
m. allan noah (*)
|
||||
gphoto2: Peter Fales (*)
|
||||
genesys: Henning Geinitz (*), Gerhard Jaeger (*), Stephane Voltz (*),
|
||||
genesys: Henning Geinitz (*), Gerhard Jaeger (*), Stéphane Voltz (*),
|
||||
Pierre Willenbrock (*)
|
||||
gt68xx: Sergey Vlasov, Andreas Nowack, David Stevenson, and
|
||||
Henning Geinitz (*)
|
||||
|
@ -52,7 +52,7 @@ Backends:
|
|||
hs2p: Jeremy Johnson
|
||||
ibm: M.F., Henning Geinitz (*)
|
||||
leo: Frank Zago (*)
|
||||
lexmark: Fred Odendaal (*)
|
||||
lexmark: Fred Odendaal, Stéphane Voltz (*)
|
||||
ma1509: Henning Geinitz (*)
|
||||
matsushita: Frank Zago (*)
|
||||
microtek: Matthew Marjanovic (*)
|
||||
|
@ -77,6 +77,7 @@ Backends:
|
|||
despeckling filter by Patrick Reynolds,
|
||||
B&W fixes by Andrew Kuchling
|
||||
ricoh: Feico W. Dillema
|
||||
rts8891: Stéphane Voltz (*)
|
||||
s9036: Ingo Schneider
|
||||
sceptre: Frank Zago (*)
|
||||
sharp: Kazuya Fukuda (*) and Abel Deuring (*)
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
2008-03-02 Stéphane Voltz <stef.dev@free.fr>
|
||||
* AUTHORS configure configure.in backend/dll.conf.in
|
||||
backend/Makefile.in backend/rts8891.c backend/rts8891.conf.in
|
||||
backend/rts8891_devices.c backend/rts8891.h backend/rts8891_low.c
|
||||
backend/rts8891_low.h backend/rts88xx_lib.c backend/rts88xx_lib.h
|
||||
doc/descriptions/rts8891.desc doc/descriptions/unsupported.desc
|
||||
doc/sane-rts8891.man:
|
||||
rts8891 backend inclusion
|
||||
|
||||
2008-03-20 Julien Blache <jb@jblache.org>
|
||||
* include/Makefile.in: remove _stdint.h and byteorder.h in
|
||||
distclean target, autogenerated cruft.
|
||||
|
|
|
@ -181,6 +181,8 @@ DISTFILES = Makefile.in saned.conf.in sane_strstatus.c stubs.c \
|
|||
pnm.c \
|
||||
qcam.c qcam.conf.in qcam.h \
|
||||
ricoh.c ricoh.conf.in ricoh.h ricoh-scsi.c \
|
||||
rts8891.c rts8891.h rts8891_low.h rts88xx_lib.c \
|
||||
rts8891_devices.c rts8891_low.c rts88xx_lib.h rts8891.conf.in \
|
||||
s9036.c s9036.conf.in s9036.h \
|
||||
sceptre.c sceptre.conf.in sceptre.h \
|
||||
sharp.c sharp.conf.in sharp.h \
|
||||
|
@ -347,6 +349,7 @@ EXTRA_epson = epson_scsi epson_usb
|
|||
EXTRA_epson2 = epson2_scsi epson_usb epson2_net epson2-io epson2-commands
|
||||
EXTRA_lexmark = lexmark_low
|
||||
EXTRA_pixma = pixma_io_sanei pixma_common pixma_mp150 pixma_mp730 pixma_mp750
|
||||
EXTRA_rts8891 = rts88xx_lib
|
||||
|
||||
# When preloading dll, we need to add in all preloaded objects:
|
||||
libsane-dll.la: $(addsuffix .lo,$(DLL_PRELOAD))
|
||||
|
@ -516,6 +519,9 @@ libsane-qcam.la: ../sanei/sanei_constrain_value.lo
|
|||
libsane-ricoh.la: ../sanei/sanei_config2.lo
|
||||
libsane-ricoh.la: ../sanei/sanei_constrain_value.lo
|
||||
libsane-ricoh.la: ../sanei/sanei_scsi.lo
|
||||
libsane-rts8891.la: $(addsuffix .lo,$(EXTRA_rts8891))
|
||||
libsane-rts8891.la: ../sanei/sanei_constrain_value.lo
|
||||
libsane-rts8891.la: ../sanei/sanei_usb.lo
|
||||
libsane-s9036.la: ../sanei/sanei_config2.lo
|
||||
libsane-s9036.la: ../sanei/sanei_constrain_value.lo
|
||||
libsane-s9036.la: ../sanei/sanei_scsi.lo
|
||||
|
|
|
@ -57,6 +57,7 @@ plustek
|
|||
#pnm
|
||||
qcam
|
||||
ricoh
|
||||
rts8891
|
||||
s9036
|
||||
sceptre
|
||||
sharp
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,7 @@
|
|||
# rts8891.conf: Configuration file for the rts8891 backend
|
||||
|
||||
# MODEL
|
||||
# HP scanjet 4470c
|
||||
usb 0x03f0 0x0805
|
||||
# UMAX Astra 4400/4450
|
||||
usb 0x1606 0x0070
|
|
@ -0,0 +1,142 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
Copyright (C) 2007-2008 stef.dev@free.fr
|
||||
|
||||
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 RTS8891_H
|
||||
#define RTS8891_H
|
||||
|
||||
#define ENABLE(OPTION) s->opt[OPTION].cap &= ~SANE_CAP_INACTIVE
|
||||
#define DISABLE(OPTION) s->opt[OPTION].cap |= SANE_CAP_INACTIVE
|
||||
#define IS_ACTIVE(OPTION) (((s->opt[OPTION].cap) & SANE_CAP_INACTIVE) == 0)
|
||||
|
||||
#define RTS8891_CONFIG_FILE "rts8891.conf"
|
||||
|
||||
#ifndef SANE_I18N
|
||||
#define SANE_I18N(text) text
|
||||
#endif /* */
|
||||
|
||||
#define COLOR_MODE "Color"
|
||||
#define GRAY_MODE "Gray"
|
||||
#define LINEART_MODE "Lineart"
|
||||
|
||||
/* preferred number of bytes to keep in buffer */
|
||||
#define PREFERED_BUFFER_SIZE 2097152 /* all scanner memory */
|
||||
|
||||
/** List of SANE options
|
||||
*/
|
||||
enum Rts8891_Option
|
||||
{ OPT_NUM_OPTS = 0,
|
||||
OPT_MODE_GROUP,
|
||||
OPT_MODE,
|
||||
OPT_PREVIEW,
|
||||
OPT_RESOLUTION,
|
||||
OPT_GEOMETRY_GROUP,
|
||||
OPT_TL_X, /* top-left x */
|
||||
OPT_TL_Y, /* top-left y */
|
||||
OPT_BR_X, /* bottom-right x */
|
||||
OPT_BR_Y, /* bottom-right y */
|
||||
|
||||
/* advanced image enhancement options */
|
||||
OPT_ENHANCEMENT_GROUP,
|
||||
OPT_THRESHOLD,
|
||||
OPT_CUSTOM_GAMMA, /* toggle to enable custom gamma tables */
|
||||
OPT_GAMMA_VECTOR,
|
||||
OPT_GAMMA_VECTOR_R,
|
||||
OPT_GAMMA_VECTOR_G,
|
||||
OPT_GAMMA_VECTOR_B,
|
||||
|
||||
/* advanced options */
|
||||
OPT_ADVANCED_GROUP,
|
||||
OPT_LAMP_ON,
|
||||
OPT_LAMP_OFF,
|
||||
|
||||
/* button group */
|
||||
OPT_BUTTON_GROUP,
|
||||
OPT_BUTTON_1,
|
||||
OPT_BUTTON_2,
|
||||
OPT_BUTTON_3,
|
||||
OPT_BUTTON_4,
|
||||
OPT_BUTTON_5,
|
||||
OPT_BUTTON_6,
|
||||
OPT_BUTTON_7,
|
||||
OPT_BUTTON_8,
|
||||
OPT_BUTTON_9,
|
||||
OPT_BUTTON_10,
|
||||
OPT_BUTTON_11,
|
||||
/* must come last: */
|
||||
NUM_OPTIONS
|
||||
};
|
||||
|
||||
/** Scanner object. This struct holds informations usefull for
|
||||
* the functions defined in SANE's standard. Informations closer
|
||||
* to the hardware are in the Rts8891_Device structure.
|
||||
*/
|
||||
typedef struct Rts8891_Scanner
|
||||
{
|
||||
|
||||
/**< Next handle in linked list */
|
||||
struct Rts8891_Scanner *next;
|
||||
|
||||
/**< Low-level device object */
|
||||
struct Rts8891_Device *dev;
|
||||
|
||||
/* SANE data */
|
||||
|
||||
/**< We are currently scanning */
|
||||
SANE_Bool scanning;
|
||||
/**< Data read is in non blocking mode */
|
||||
SANE_Bool non_blocking;
|
||||
/**< Gray scans are emulated */
|
||||
SANE_Bool emulated_gray;
|
||||
SANE_Option_Descriptor opt[NUM_OPTIONS];
|
||||
/**< Option descriptors */
|
||||
Option_Value val[NUM_OPTIONS]; /**< Option values */
|
||||
SANE_Parameters params; /**< SANE Parameters */
|
||||
|
||||
/**< bytes to send to frontend for the scan */
|
||||
SANE_Int to_send;
|
||||
|
||||
/**< bytes currently sent to frontend during the scan */
|
||||
SANE_Int sent;
|
||||
} Rts8891_Scanner;
|
||||
|
||||
#endif /* not RTS8891_H */
|
|
@ -0,0 +1,177 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
Copyright (C) 2007-2008 stef.dev@free.fr
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
/* here we have the various device settings...
|
||||
*/
|
||||
static Rts8891_Model hp4470c_model = {
|
||||
"HP4470c", /* Name */
|
||||
"Hewlett-Packard", /* Device vendor string */
|
||||
"4470c", /* Device model name */
|
||||
"flatbed scanner", /* Device type */
|
||||
{1200, 600, 300, 150, 75, 0}, /* possible x-resolutions */
|
||||
{600, 300, 150, 0}, /* possible y-resolutions */
|
||||
1200, /* max physical x dpi */
|
||||
600, /* max physical y dpi */
|
||||
150, /* min physical y dpi */
|
||||
|
||||
SANE_FIX (8.3), /* Start of scan area in mm (x) */
|
||||
SANE_FIX (3.0), /* Start of scan area in mm (y) */
|
||||
SANE_FIX (215.9), /* Size of scan area in mm (x) */
|
||||
SANE_FIX (298.1), /* Size of scan area in mm (y) */
|
||||
|
||||
SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */
|
||||
SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */
|
||||
SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */
|
||||
SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */
|
||||
|
||||
24, 12, 0, /* R, G, and B CCD Line-distance correction in lines at
|
||||
max motor resolution */
|
||||
/* default gamma table */
|
||||
{0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c, 0x20, 0x24, 0x28, 0x2c,
|
||||
0x30, 0x34, 0x38, 0x3c, 0x40, 0x44, 0x48, 0x4c, 0x50, 0x52, 0x53, 0x55,
|
||||
0x57, 0x58, 0x5a, 0x5c, 0x5d, 0x5f, 0x60, 0x62, 0x63, 0x64, 0x66, 0x67,
|
||||
0x68, 0x6a, 0x6b, 0x6c, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x74, 0x75, 0x76,
|
||||
0x77, 0x78, 0x79, 0x7a, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
|
||||
0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8d, 0x8e,
|
||||
0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x96, 0x97, 0x98, 0x99,
|
||||
0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3,
|
||||
0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac,
|
||||
0xac, 0xad, 0xae, 0xaf, 0xaf, 0xb0, 0xb1, 0xb1, 0xb2, 0xb3, 0xb4, 0xb4,
|
||||
0xb5, 0xb6, 0xb6, 0xb7, 0xb8, 0xb8, 0xb9, 0xba, 0xba, 0xbb, 0xbc, 0xbc,
|
||||
0xbd, 0xbe, 0xbe, 0xbf, 0xc0, 0xc0, 0xc1, 0xc1, 0xc2, 0xc3, 0xc3, 0xc4,
|
||||
0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xcb, 0xcb,
|
||||
0xcc, 0xcc, 0xcd, 0xce, 0xce, 0xcf, 0xcf, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2,
|
||||
0xd3, 0xd3, 0xd4, 0xd5, 0xd5, 0xd6, 0xd6, 0xd7, 0xd7, 0xd8, 0xd9, 0xd9,
|
||||
0xda, 0xda, 0xdb, 0xdb, 0xdc, 0xdc, 0xdd, 0xdd, 0xde, 0xdf, 0xdf, 0xe0,
|
||||
0xe0, 0xe1, 0xe1, 0xe2, 0xe2, 0xe3, 0xe3, 0xe4, 0xe4, 0xe5, 0xe5, 0xe6,
|
||||
0xe6, 0xe7, 0xe7, 0xe8, 0xe8, 0xe9, 0xe9, 0xea, 0xea, 0xeb, 0xeb, 0xec,
|
||||
0xec, 0xed, 0xed, 0xee, 0xee, 0xef, 0xef, 0xf0, 0xf0, 0xf1, 0xf1, 0xf2,
|
||||
0xf2, 0xf3, 0xf3, 0xf4, 0xf4, 0xf5, 0xf5, 0xf6, 0xf6, 0xf7, 0xf7, 0xf8,
|
||||
0xf8, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfc, 0xfc, 0xfd, 0xfd,
|
||||
0xfe, 0xfe, 0xff, 0xff},
|
||||
|
||||
/* number of buttons */
|
||||
11,
|
||||
|
||||
/* button names */
|
||||
{"plus", "minus", "copy", "mail", "image-copy", "www", "scan", "power",
|
||||
"cancel", "options", "toggle-mode"},
|
||||
|
||||
/* button titles */
|
||||
{"plus", "minus", "copy", "mail", "image copy", "www", "scan", "power",
|
||||
"cancel", "options", "toggle color/gray mode"},
|
||||
|
||||
/* flags */
|
||||
RTS8891_FLAG_EMULATED_GRAY_MODE
|
||||
};
|
||||
|
||||
static Rts8891_Model astra4400_model = {
|
||||
"Astra 4400", /* Name */
|
||||
"UMAX", /* Device vendor string */
|
||||
"Astra 4400", /* Device model name */
|
||||
"flatbed scanner", /* Device type */
|
||||
|
||||
{1200, 600, 300, 150, 75, 0}, /* possible x-resolutions */
|
||||
{600, 300, 150, 0}, /* possible y-resolutions */
|
||||
1200, /* max physical x dpi */
|
||||
600, /* max physical y dpi */
|
||||
150, /* min physical y dpi */
|
||||
|
||||
SANE_FIX (8.3), /* Start of scan area in mm (x) */
|
||||
SANE_FIX (3.0), /* Start of scan area in mm (y) */
|
||||
SANE_FIX (215.9), /* Size of scan area in mm (x) */
|
||||
SANE_FIX (298.1), /* Size of scan area in mm (y) */
|
||||
|
||||
SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */
|
||||
SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */
|
||||
SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */
|
||||
SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */
|
||||
|
||||
24, 12, 0, /* R, G, and B CCD Line-distance correction in lines at
|
||||
max motor resolution */
|
||||
/* default gamma table */
|
||||
{0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c, 0x20, 0x24, 0x28, 0x2c,
|
||||
0x30, 0x34, 0x38, 0x3c, 0x40, 0x44, 0x48, 0x4c, 0x50, 0x52, 0x53, 0x55,
|
||||
0x57, 0x58, 0x5a, 0x5c, 0x5d, 0x5f, 0x60, 0x62, 0x63, 0x64, 0x66, 0x67,
|
||||
0x68, 0x6a, 0x6b, 0x6c, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x74, 0x75, 0x76,
|
||||
0x77, 0x78, 0x79, 0x7a, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
|
||||
0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8d, 0x8e,
|
||||
0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x96, 0x97, 0x98, 0x99,
|
||||
0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3,
|
||||
0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac,
|
||||
0xac, 0xad, 0xae, 0xaf, 0xaf, 0xb0, 0xb1, 0xb1, 0xb2, 0xb3, 0xb4, 0xb4,
|
||||
0xb5, 0xb6, 0xb6, 0xb7, 0xb8, 0xb8, 0xb9, 0xba, 0xba, 0xbb, 0xbc, 0xbc,
|
||||
0xbd, 0xbe, 0xbe, 0xbf, 0xc0, 0xc0, 0xc1, 0xc1, 0xc2, 0xc3, 0xc3, 0xc4,
|
||||
0xc5, 0xc5, 0xc6, 0xc6, 0xc7, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xcb, 0xcb,
|
||||
0xcc, 0xcc, 0xcd, 0xce, 0xce, 0xcf, 0xcf, 0xd0, 0xd1, 0xd1, 0xd2, 0xd2,
|
||||
0xd3, 0xd3, 0xd4, 0xd5, 0xd5, 0xd6, 0xd6, 0xd7, 0xd7, 0xd8, 0xd9, 0xd9,
|
||||
0xda, 0xda, 0xdb, 0xdb, 0xdc, 0xdc, 0xdd, 0xdd, 0xde, 0xdf, 0xdf, 0xe0,
|
||||
0xe0, 0xe1, 0xe1, 0xe2, 0xe2, 0xe3, 0xe3, 0xe4, 0xe4, 0xe5, 0xe5, 0xe6,
|
||||
0xe6, 0xe7, 0xe7, 0xe8, 0xe8, 0xe9, 0xe9, 0xea, 0xea, 0xeb, 0xeb, 0xec,
|
||||
0xec, 0xed, 0xed, 0xee, 0xee, 0xef, 0xef, 0xf0, 0xf0, 0xf1, 0xf1, 0xf2,
|
||||
0xf2, 0xf3, 0xf3, 0xf4, 0xf4, 0xf5, 0xf5, 0xf6, 0xf6, 0xf7, 0xf7, 0xf8,
|
||||
0xf8, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfc, 0xfc, 0xfd, 0xfd,
|
||||
0xfe, 0xfe, 0xff, 0xff},
|
||||
|
||||
/* number of buttons */
|
||||
11,
|
||||
|
||||
/* button names */
|
||||
{"plus", "minus", "copy", "mail", "image-copy", "www", "scan", "power",
|
||||
"cancel", "options", "toggle-mode"},
|
||||
|
||||
/* button titles */
|
||||
{"plus", "minus", "copy", "mail", "image copy", "www", "scan", "power",
|
||||
"cancel", "options", "toggle color/gray mode"},
|
||||
|
||||
/* flags */
|
||||
RTS8891_FLAG_EMULATED_GRAY_MODE
|
||||
};
|
||||
|
||||
/* full list of supported devices: vendor, product, description structure */
|
||||
static Rts8891_USB_Device_Entry rts8891_usb_device_list[] = {
|
||||
{0x03f0, 0x0805, &hp4470c_model},
|
||||
{0x1606, 0x0070, &astra4400_model},
|
||||
{0, 0, NULL}
|
||||
};
|
|
@ -0,0 +1,771 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
Copyright (C) 2007-2008 stef.dev@free.fr
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/* this file contains all the low level functions needed for the higher level
|
||||
* functions of the sane standard. They are put there to keep files smaller
|
||||
* and separate functions with different goals.
|
||||
*/
|
||||
|
||||
#include "sane/config.h"
|
||||
#include "sane/sane.h"
|
||||
#include "sane/sanei_backend.h"
|
||||
#include "sane/sanei_usb.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include "rts8891_low.h"
|
||||
|
||||
#define RTS8891_BUILD 2
|
||||
#define RTS8891_MAX_REGISTERS 244
|
||||
|
||||
/* init rts8891 library */
|
||||
static void
|
||||
rts8891_low_init (void)
|
||||
{
|
||||
DBG_INIT ();
|
||||
DBG (DBG_info, "RTS8891 low-level functions, version %d.%d-rc-%d\n",
|
||||
V_MAJOR, V_MINOR, RTS8891_BUILD);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
/* ASIC specific functions */
|
||||
/****************************************************************/
|
||||
|
||||
/* write all registers, taking care of the special 0xaa value which
|
||||
* must be escaped with a zero
|
||||
*/
|
||||
static SANE_Status
|
||||
rts8891_write_all (SANE_Int devnum, SANE_Byte * regs, SANE_Int count)
|
||||
{
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
SANE_Byte local_regs[RTS8891_MAX_REGISTERS];
|
||||
size_t size = 0;
|
||||
SANE_Byte buffer[260];
|
||||
unsigned int i, j;
|
||||
char message[256 * 5];
|
||||
|
||||
if (DBG_LEVEL > DBG_io)
|
||||
{
|
||||
for (i = 0; i < (unsigned int) count; i++)
|
||||
{
|
||||
if (i != 0xb3)
|
||||
sprintf (message + 5 * i, "0x%02x ", regs[i]);
|
||||
else
|
||||
sprintf (message + 5 * i, "---- ");
|
||||
}
|
||||
DBG (DBG_io, "rts8891_write_all : write_all(0x00,%d)=%s\n", count,
|
||||
message);
|
||||
}
|
||||
|
||||
/* copy register set and escaping 0xaa values */
|
||||
/* b0, b1 abd b3 values may be scribled, but that isn't important */
|
||||
/* since they are read-only registers */
|
||||
j = 0;
|
||||
for (i = 0; i < 0xb3; i++)
|
||||
{
|
||||
local_regs[j] = regs[i];
|
||||
if (local_regs[j] == 0xaa && i < 0xb3)
|
||||
{
|
||||
j++;
|
||||
local_regs[j] = 0x00;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
buffer[0] = 0x88;
|
||||
buffer[1] = 0;
|
||||
buffer[2] = 0x00;
|
||||
buffer[3] = 0xb3;
|
||||
for (i = 0; i < j; i++)
|
||||
buffer[i + 4] = local_regs[i];
|
||||
/* the USB block is size + 4 bytes of header long */
|
||||
size = j + 4;
|
||||
if (sanei_usb_write_bulk (devnum, buffer, &size) != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"rts88xx_write_all : write registers part 1 failed ...\n");
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
|
||||
size = count - 0xb4; /* we need to substract one reg since b3 won't be written */
|
||||
buffer[0] = 0x88;
|
||||
buffer[1] = 0xb4;
|
||||
buffer[2] = 0x00;
|
||||
buffer[3] = size;
|
||||
for (i = 0; i < size; i++)
|
||||
buffer[i + 4] = regs[0xb4 + i];
|
||||
/* the USB block is size + 4 bytes of header long */
|
||||
size += 4;
|
||||
if (sanei_usb_write_bulk (devnum, buffer, &size) != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"rts88xx_write_all : write registers part 2 failed ...\n");
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* this functions "commits" pending scan command */
|
||||
static SANE_Status
|
||||
rts8891_commit (SANE_Int devnum, SANE_Byte value)
|
||||
{
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
SANE_Byte reg;
|
||||
|
||||
reg = value;
|
||||
status = sanei_rts88xx_write_reg (devnum, 0xd3, ®);
|
||||
status = sanei_rts88xx_cancel (devnum);
|
||||
status = sanei_rts88xx_write_control (devnum, 0x08);
|
||||
status = sanei_rts88xx_write_control (devnum, 0x08);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* this functions reads button status */
|
||||
static SANE_Status
|
||||
rts8891_read_buttons (SANE_Int devnum, SANE_Int * mask)
|
||||
{
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
SANE_Byte reg;
|
||||
|
||||
/* check CONTROL_REG */
|
||||
sanei_rts88xx_read_reg (devnum, CONTROL_REG, ®);
|
||||
|
||||
/* read 'base' button status */
|
||||
sanei_rts88xx_read_reg (devnum, 0x25, ®);
|
||||
DBG (DBG_io, "rts8891_read_buttons: r25=0x%02x\n", reg);
|
||||
*mask |= reg;
|
||||
|
||||
/* read 'extended' button status */
|
||||
sanei_rts88xx_read_reg (devnum, 0x1a, ®);
|
||||
DBG (DBG_io, "rts8891_read_buttons: r1a=0x%02x\n", reg);
|
||||
*mask |= reg << 8;
|
||||
|
||||
/* clear register r25 */
|
||||
reg = 0x00;
|
||||
status = sanei_rts88xx_write_reg (devnum, 0x25, ®);
|
||||
|
||||
/* clear register r1a */
|
||||
sanei_rts88xx_read_reg (devnum, 0x1a, ®);
|
||||
reg = 0x00;
|
||||
status = sanei_rts88xx_write_reg (devnum, 0x1a, ®);
|
||||
|
||||
DBG (DBG_info, "rts8891_read_buttons: mask=0x%04x\n", *mask);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Does a simple scan based on the given register set, returning data in a
|
||||
* preallocated buffer of the claimed size.
|
||||
* sanei_rts88xx_data_count cannot be made reliable, when the announced data
|
||||
* amount is read, it may no be ready, leading to errors. To work around
|
||||
* it, we read data count one more time before reading.
|
||||
*/
|
||||
static SANE_Status
|
||||
rts8891_simple_scan (SANE_Int devnum, SANE_Byte * regs, int regcount,
|
||||
SANE_Int format, SANE_Word total, unsigned char *image)
|
||||
{
|
||||
SANE_Word count, read, len, dummy;
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
SANE_Byte control;
|
||||
|
||||
rts8891_write_all (devnum, regs, regcount);
|
||||
rts8891_commit (devnum, format);
|
||||
|
||||
read = 0;
|
||||
count = 0;
|
||||
while (count == 0)
|
||||
{
|
||||
status = sanei_rts88xx_data_count (devnum, &count);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "simple_scan: failed to wait for data\n");
|
||||
return status;
|
||||
}
|
||||
if (count == 0)
|
||||
{
|
||||
status = sanei_rts88xx_read_reg (devnum, CONTROL_REG, &control);
|
||||
if (((control & 0x08) == 0) || (status != SANE_STATUS_GOOD))
|
||||
{
|
||||
DBG (DBG_error, "simple_scan: failed to wait for data\n");
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* data reading */
|
||||
read = 0;
|
||||
while ((read < total) && (count != 0 || (control & 0x08) == 0x08))
|
||||
{
|
||||
/* sync ? */
|
||||
status = sanei_rts88xx_data_count (devnum, &dummy);
|
||||
|
||||
/* read */
|
||||
if (count > 0)
|
||||
{
|
||||
len = count;
|
||||
/* read even size unless last chunk */
|
||||
if ((len & 1) && (read + len < total))
|
||||
{
|
||||
len++;
|
||||
}
|
||||
if (len > RTS88XX_MAX_XFER_SIZE)
|
||||
{
|
||||
len = RTS88XX_MAX_XFER_SIZE;
|
||||
}
|
||||
if (len > 0)
|
||||
{
|
||||
status = sanei_rts88xx_read_data (devnum, &len, image + read);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"simple_scan: failed to read from scanner\n");
|
||||
return status;
|
||||
}
|
||||
read += len;
|
||||
}
|
||||
}
|
||||
|
||||
/* don't try to read data count if we have enough data */
|
||||
if (read < total)
|
||||
{
|
||||
status = sanei_rts88xx_data_count (devnum, &count);
|
||||
}
|
||||
else
|
||||
{
|
||||
count = 0;
|
||||
}
|
||||
if (count == 0)
|
||||
{
|
||||
sanei_rts88xx_read_reg (devnum, CONTROL_REG, &control);
|
||||
}
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
if (read < total)
|
||||
{
|
||||
DBG (DBG_io2, "simple_scan: ERROR, %d bytes missing ... \n",
|
||||
total - read);
|
||||
}
|
||||
|
||||
/* wait for the motor to stop */
|
||||
do
|
||||
{
|
||||
sanei_rts88xx_read_reg (devnum, CONTROL_REG, &control);
|
||||
}
|
||||
while ((control & 0x08) == 0x08);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the data format. Is part of the commit sequence
|
||||
*/
|
||||
static SANE_Int
|
||||
rts8891_data_format (SANE_Int dpi)
|
||||
{
|
||||
SANE_Byte reg = 0x00;
|
||||
|
||||
switch (dpi)
|
||||
{
|
||||
case 75:
|
||||
reg = 0x02;
|
||||
break;
|
||||
case 150:
|
||||
reg = 0x0e; /* 0x0b : gray */
|
||||
break;
|
||||
case 300:
|
||||
reg = 0x17;
|
||||
break;
|
||||
case 600:
|
||||
reg = 0x02; /* 0x0e : gray */
|
||||
break;
|
||||
case 1200:
|
||||
reg = 0x17; /* 0x05 : gray */
|
||||
break;
|
||||
}
|
||||
return reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* set up default values for a 75xdpy, 150 ydpi scan
|
||||
*/
|
||||
static void
|
||||
rts8891_set_default_regs (SANE_Byte * scanner_regs)
|
||||
{
|
||||
SANE_Byte default_75[RTS8891_MAX_REGISTERS] =
|
||||
{ 0xe5, 0x41, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x0a, 0x0a, 0x0a, 0x70,
|
||||
0x00, 0x00, 0x00, 0x00, 0x28, 0x3f, 0xff, 0x20, 0xf8, 0x28, 0x07, 0x00,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x00, 0x3a, 0xf2, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x8c,
|
||||
0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x14, 0x18, 0x15, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0x3f, 0x80, 0x68, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc,
|
||||
0x27, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||
0x0e, 0x00, 0x00, 0xf0, 0xff, 0xf5, 0xf7, 0xea, 0x0b, 0x03, 0x05, 0x86,
|
||||
0x1b, 0x30, 0xf6, 0xa2, 0x27, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
unsigned int i;
|
||||
for (i = 0; i < RTS8891_MAX_REGISTERS; i++)
|
||||
scanner_regs[i] = default_75[i];
|
||||
}
|
||||
|
||||
static SANE_Status
|
||||
rts8891_move (SANE_Int devnum, SANE_Byte * regs, SANE_Int distance,
|
||||
SANE_Bool forward)
|
||||
{
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
|
||||
DBG (DBG_proc, "rts8891_move: start\n");
|
||||
DBG (DBG_io, "rts8891_move: %d lines %s\n", distance,
|
||||
forward == SANE_TRUE ? "forward" : "backward");
|
||||
|
||||
/* prepare scan */
|
||||
rts8891_set_default_regs (regs);
|
||||
regs[0x10] = 0x20;
|
||||
regs[0x11] = 0x28;
|
||||
|
||||
regs[0x32] = 0x80;
|
||||
regs[0x33] = 0x81;
|
||||
regs[0x35] = 0x10;
|
||||
regs[0x36] = 0x24;
|
||||
regs[0x39] = 0x02;
|
||||
regs[0x3a] = 0x0e;
|
||||
|
||||
regs[0x64] = 0x01;
|
||||
regs[0x65] = 0x20;
|
||||
|
||||
regs[0x79] = 0x20;
|
||||
regs[0x7a] = 0x01;
|
||||
|
||||
regs[0x80] = 0x32;
|
||||
regs[0x82] = 0x33;
|
||||
regs[0x85] = 0x46;
|
||||
regs[0x86] = 0x0b;
|
||||
regs[0x87] = 0x8c;
|
||||
regs[0x88] = 0x10;
|
||||
regs[0x89] = 0xb2;
|
||||
regs[0x8d] = 0x3b;
|
||||
regs[0x8e] = 0x60;
|
||||
|
||||
regs[0x90] = 0x1c;
|
||||
regs[0xb2] = 0x16; /* 0x10 : stop when at home, 0x04: no data */
|
||||
regs[0xc0] = 0x00;
|
||||
regs[0xc1] = 0x00;
|
||||
regs[0xc3] = 0x00;
|
||||
regs[0xc4] = 0x00;
|
||||
regs[0xc5] = 0x00;
|
||||
regs[0xc6] = 0x00;
|
||||
regs[0xc7] = 0x00;
|
||||
regs[0xc8] = 0x00;
|
||||
regs[0xca] = 0x00;
|
||||
regs[0xcd] = 0x00;
|
||||
regs[0xce] = 0x00;
|
||||
regs[0xcf] = 0x00;
|
||||
regs[0xd0] = 0x00;
|
||||
regs[0xd1] = 0x00;
|
||||
regs[0xd2] = 0x00;
|
||||
regs[0xd3] = 0x00;
|
||||
regs[0xd4] = 0x00;
|
||||
regs[0xd6] = 0x6b;
|
||||
regs[0xd7] = 0x00;
|
||||
regs[0xd8] = 0x00;
|
||||
regs[0xd9] = 0xad;
|
||||
regs[0xda] = 0xa7;
|
||||
regs[0xe2] = 0x17;
|
||||
regs[0xe3] = 0x0d;
|
||||
regs[0xe4] = 0x06;
|
||||
regs[0xe5] = 0xf9;
|
||||
regs[0xe7] = 0x53;
|
||||
regs[0xe8] = 0x02;
|
||||
regs[0xe9] = 0x02;
|
||||
|
||||
/* disable CCD */
|
||||
regs[0] = 0xf5;
|
||||
|
||||
sanei_rts88xx_set_status (devnum, regs, 0x20, 0x28);
|
||||
sanei_rts88xx_set_scan_area (regs, distance, distance + 1, 100, 200);
|
||||
sanei_rts88xx_set_gain (regs, 16, 16, 16);
|
||||
sanei_rts88xx_set_offset (regs, 127, 127, 127);
|
||||
|
||||
/* forward/backward */
|
||||
/* 0x2c is forward, 0x24 backward */
|
||||
if (forward == SANE_TRUE)
|
||||
{ /* forward */
|
||||
regs[0x36] = regs[0x36] | 0x08;
|
||||
}
|
||||
else
|
||||
{ /* backward */
|
||||
regs[0x36] = regs[0x36] & 0xf7;
|
||||
}
|
||||
|
||||
/* write regiters values */
|
||||
status = rts8891_write_all (devnum, regs, RTS8891_MAX_REGISTERS);
|
||||
|
||||
/* commit it */
|
||||
rts8891_commit (devnum, 0x00);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* move the head backward by a huge line number then poll home sensor until
|
||||
* head has get back home. We have our own copy of the registers to avoid
|
||||
* messing scanner status
|
||||
*/
|
||||
static SANE_Status
|
||||
rts8891_park (SANE_Int devnum, SANE_Byte * regs)
|
||||
{
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
SANE_Byte motor, sensor, reg;
|
||||
|
||||
DBG (DBG_proc, "rts8891_park: start\n");
|
||||
|
||||
rts8891_move (devnum, regs, 8000, SANE_FALSE);
|
||||
|
||||
/* wait for controller home bit to raise, no timeout */
|
||||
/* at each loop we check that motor is on, then that the sensor bit it cleared */
|
||||
do
|
||||
{
|
||||
sanei_rts88xx_read_reg (devnum, CONTROL_REG, &motor);
|
||||
sanei_rts88xx_read_reg (devnum, CONTROLER_REG, &sensor);
|
||||
}
|
||||
while ((motor & 0x08) && ((sensor & 0x02) == 0));
|
||||
|
||||
/* check for error */
|
||||
if (((motor & 0x08) == 0x00) && ((sensor & 0x02) == 0))
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"rts8891_park: error, motor stopped before head parked\n");
|
||||
status = SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
/* re-enable CCD */
|
||||
regs[0] = regs[0] & 0xef;
|
||||
|
||||
sanei_rts88xx_cancel (devnum);
|
||||
|
||||
/* reset ? so we don't need to read data */
|
||||
reg = 0;
|
||||
/* b7: movement on/off, b3-b0 : movement divisor */
|
||||
sanei_rts88xx_write_reg (devnum, 0x33, ®);
|
||||
sanei_rts88xx_write_reg (devnum, 0x33, ®);
|
||||
/* movement direction */
|
||||
sanei_rts88xx_write_reg (devnum, 0x36, ®);
|
||||
sanei_rts88xx_cancel (devnum);
|
||||
|
||||
DBG (DBG_proc, "rts8891_park: end\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* reads data from scanner.
|
||||
* First we wait for some data to be available and then loop reading
|
||||
* from scanner until the required amount is reached.
|
||||
* We handle non blocking I/O by returning immediatly (with SANE_STATUS_BUSY)
|
||||
* if there is no data available from scanner. But once read is started,
|
||||
* all the required amount is read. Once wait for data succeeded, we still poll
|
||||
* for data in order no to read it too fast, but we don' take care of non blocking
|
||||
* mode since we cope with it on first data wait.
|
||||
*/
|
||||
static SANE_Status
|
||||
read_data (struct Rts8891_Scanner *scanner, SANE_Byte * dest, SANE_Int length)
|
||||
{
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
SANE_Int count, read, len, dummy;
|
||||
struct Rts8891_Device *dev = scanner->dev;
|
||||
static FILE *raw = NULL; /* for debugging purpose we need it static */
|
||||
SANE_Byte control = 0x08;
|
||||
unsigned char buffer[RTS88XX_MAX_XFER_SIZE];
|
||||
|
||||
DBG (DBG_proc, "read_data: start\n");
|
||||
DBG (DBG_proc, "read_data: requiring %d bytes\n", length);
|
||||
|
||||
/* wait for data being available and handle non blocking mode */
|
||||
/* only when data reading hasn't produce any data yet */
|
||||
if (dev->read == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
status = sanei_rts88xx_data_count (dev->devnum, &count);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "read_data: failed to wait for data\n");
|
||||
return status;
|
||||
}
|
||||
if (count == 0)
|
||||
{
|
||||
sanei_rts88xx_read_reg (dev->devnum, CONTROL_REG, &control);
|
||||
if ((control & 0x08) == 0 && (count == 0))
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"read_data: scanner stopped being busy before data are available\n");
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* in case there is no data, we return BUSY since this mean */
|
||||
/* that scanning head hasn't reach is position and data hasn't */
|
||||
/* come yet */
|
||||
if (scanner->non_blocking && count == 0)
|
||||
{
|
||||
|
||||
dev->regs[LAMP_REG] = 0x8d;
|
||||
sanei_rts88xx_write_reg (dev->devnum, LAMP_REG,
|
||||
&(dev->regs[LAMP_REG]));
|
||||
DBG (DBG_io, "read_data: no data vailable\n");
|
||||
DBG (DBG_proc, "read_data: end\n");
|
||||
return SANE_STATUS_DEVICE_BUSY;
|
||||
}
|
||||
}
|
||||
while (count == 0);
|
||||
}
|
||||
else
|
||||
{ /* start of read for a new block */
|
||||
status = sanei_rts88xx_data_count (dev->devnum, &count);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "read_data: failed to wait for data\n");
|
||||
return status;
|
||||
}
|
||||
if (count == 0)
|
||||
{
|
||||
sanei_rts88xx_read_reg (dev->devnum, CONTROL_REG, &control);
|
||||
if ((control & 0x08) == 0 && (count == 0))
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"read_data: scanner stopped being busy before data are available\n");
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* fill scanned data buffer */
|
||||
read = 0;
|
||||
|
||||
/* now loop reading data until we have the amount requested */
|
||||
/* we also take care of not reading too much data */
|
||||
while (read < length && dev->read < dev->to_read
|
||||
&& ((control & 0x08) == 0x08))
|
||||
{
|
||||
/* used to sync */
|
||||
if (dev->read == 0)
|
||||
{
|
||||
status = sanei_rts88xx_data_count (dev->devnum, &dummy);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "read_data: failed to read data count\n");
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* if there is data to read, read it */
|
||||
if (count > 0)
|
||||
{
|
||||
len = count;
|
||||
|
||||
if (len > RTS88XX_MAX_XFER_SIZE)
|
||||
{
|
||||
len = RTS88XX_MAX_XFER_SIZE;
|
||||
}
|
||||
|
||||
/* we only read even size blocks of data */
|
||||
if (len & 1)
|
||||
{
|
||||
DBG (DBG_io, "read_data: round to next even number\n");
|
||||
len++;
|
||||
}
|
||||
|
||||
if (len > length - read)
|
||||
{
|
||||
len = length - read;
|
||||
}
|
||||
|
||||
status = sanei_rts88xx_read_data (dev->devnum, &len, dest + read);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "read_data: failed to read from scanner\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
/* raw data tracing */
|
||||
if (DBG_LEVEL >= DBG_io2)
|
||||
{
|
||||
/* open a new file only when no data scanned */
|
||||
if (dev->read == 0)
|
||||
{
|
||||
raw = fopen ("raw_data.pnm", "wb");
|
||||
if (raw != NULL)
|
||||
{
|
||||
/* PNM header */
|
||||
fprintf (raw, "P%c\n%d %d\n255\n",
|
||||
scanner->params.format ==
|
||||
SANE_FRAME_RGB
|
||||
|| scanner->emulated_gray ==
|
||||
SANE_TRUE ? '6' : '5', dev->pixels,
|
||||
dev->lines);
|
||||
}
|
||||
}
|
||||
if (raw != NULL)
|
||||
{
|
||||
fwrite (dest + read, 1, len, raw);
|
||||
}
|
||||
}
|
||||
|
||||
/* move pointer and counter */
|
||||
read += len;
|
||||
dev->read += len;
|
||||
DBG (DBG_io2, "read_data: %d/%d\n", dev->read, dev->to_read);
|
||||
}
|
||||
|
||||
/* in fast scan mode, read data count
|
||||
* in slow scan, head moves by the amount of data read */
|
||||
status = sanei_rts88xx_data_count (dev->devnum, &count);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "read_data: failed to read data count\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
/* if no data, check if still scanning */
|
||||
if (count == 0 && dev->read < dev->to_read)
|
||||
{
|
||||
sanei_rts88xx_read_reg (dev->devnum, CONTROL_REG, &control);
|
||||
if ((control & 0x08) == 0x00)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"read_data: scanner stopped being busy before data are available\n");
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* end of physical reads */
|
||||
if (dev->read >= dev->to_read)
|
||||
{
|
||||
/* check there is no more data in case of a bug */
|
||||
sanei_rts88xx_data_count (dev->devnum, &count);
|
||||
if (count > 0)
|
||||
{
|
||||
DBG (DBG_warn,
|
||||
"read_data: %d bytes are still available from scanner\n",
|
||||
count);
|
||||
|
||||
/* flush left-over data */
|
||||
while (count > 0)
|
||||
{
|
||||
len = count;
|
||||
if (len > RTS88XX_MAX_XFER_SIZE)
|
||||
{
|
||||
len = RTS88XX_MAX_XFER_SIZE;
|
||||
}
|
||||
|
||||
/* we only read even size blocks of data */
|
||||
if (len & 1)
|
||||
{
|
||||
len++;
|
||||
}
|
||||
sanei_rts88xx_read_data (dev->devnum, &len, buffer);
|
||||
sanei_rts88xx_data_count (dev->devnum, &count);
|
||||
}
|
||||
}
|
||||
|
||||
/* wait for motor to stop at the end of the scan */
|
||||
do
|
||||
{
|
||||
sanei_rts88xx_read_reg (dev->devnum, CONTROL_REG, &control);
|
||||
}
|
||||
while ((control & 0x08) != 0);
|
||||
|
||||
/* close log file if needed */
|
||||
if (DBG_LEVEL >= DBG_io2)
|
||||
{
|
||||
if (raw != NULL)
|
||||
{
|
||||
fclose (raw);
|
||||
raw = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DBG (DBG_io, "read_data: read %d bytes from scanner\n", length);
|
||||
DBG (DBG_proc, "read_data: end\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* set scanner idle before leaving xxx_quiet()
|
||||
write_reg(0x33,1)=0x00
|
||||
write_reg(0x33,1)=0x00
|
||||
write_reg(0x36,1)=0x00
|
||||
prepare();
|
||||
------
|
||||
write_reg(LAMP_REG,1)=0x80
|
||||
write_reg(LAMP_REG,1)=0xad
|
||||
read_reg(0x14,2)=0xf8 0x28
|
||||
write_reg(0x14,2)=0x78 0x28
|
||||
get_status()=0x20 0x3f
|
||||
read_reg(0xb1,1)=0x00
|
||||
read_control()=0x00
|
||||
reset_lamp()=(0x20,0x3f)
|
||||
write_reg(LAMP_REG,1)=0x8d
|
||||
write_reg(LAMP_REG,1)=0xad
|
||||
*/
|
|
@ -0,0 +1,242 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
Copyright (C) 2007-2008 stef.dev@free.fr
|
||||
|
||||
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 RTS8891_LOW_H
|
||||
#define RTS8891_LOW_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include "../include/sane/sane.h"
|
||||
|
||||
#define DBG_error0 0 /* errors/warnings printed even with devuglevel 0 */
|
||||
#define DBG_error 1 /* fatal errors */
|
||||
#define DBG_init 2 /* initialization and scanning time messages */
|
||||
#define DBG_warn 3 /* warnings and non-fatal errors */
|
||||
#define DBG_info 4 /* informational messages */
|
||||
#define DBG_proc 5 /* starting/finishing functions */
|
||||
#define DBG_io 6 /* io functions */
|
||||
#define DBG_io2 7 /* io functions that are called very often */
|
||||
#define DBG_data 8 /* log image data */
|
||||
|
||||
#define MM_PER_INCH 25.4
|
||||
|
||||
/* Flags */
|
||||
#define RTS8891_FLAG_UNTESTED (1 << 0) /* Print a warning for these scanners */
|
||||
#define RTS8891_FLAG_EMULATED_GRAY_MODE (2 << 0) /* gray scans are emulated using comor modes */
|
||||
|
||||
#define LOWORD(x) ((u_int16_t)(x & 0xffff))
|
||||
#define HIWORD(x) ((u_int16_t)(x >> 16))
|
||||
#define LOBYTE(x) ((u_int8_t)((x) & 0xFF))
|
||||
#define HIBYTE(x) ((u_int8_t)((x) >> 8))
|
||||
|
||||
#define MAX_SCANNERS 32
|
||||
#define MAX_RESOLUTIONS 16
|
||||
|
||||
#define SENSOR_TYPE_BARE 0 /* sensor for hp4470 sold bare */
|
||||
#define SENSOR_TYPE_XPA 1 /* sensor for hp4470 sold with XPA */
|
||||
|
||||
/* Forward typedefs */
|
||||
typedef struct Rts8891_Device Rts8891_Device;
|
||||
|
||||
/*
|
||||
* defines for RTS8891 registers name
|
||||
*/
|
||||
#define BUTTONS_REG2 0x1a
|
||||
#define LINK_REG 0xb1
|
||||
#define LAMP_REG 0xd9
|
||||
#define LAMP_BRIGHT_REG 0xda
|
||||
|
||||
|
||||
/* this struc describes a particular model which is handled by the backend */
|
||||
/* available resolutions, physical goemetry, scanning area, ... */
|
||||
typedef struct Rts8891_Model
|
||||
{
|
||||
SANE_String_Const name;
|
||||
SANE_String_Const vendor;
|
||||
SANE_String_Const product;
|
||||
SANE_String_Const type;
|
||||
|
||||
SANE_Int xdpi_values[MAX_RESOLUTIONS]; /* possible x resolutions */
|
||||
SANE_Int ydpi_values[MAX_RESOLUTIONS]; /* possible y resolutions */
|
||||
|
||||
SANE_Int max_xdpi; /* physical maximum x dpi */
|
||||
SANE_Int max_ydpi; /* physical maximum y dpi */
|
||||
SANE_Int min_ydpi; /* physical minimum y dpi */
|
||||
|
||||
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 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 */
|
||||
|
||||
/* Line-distance correction (in pixel at max optical dpi) for CCD scanners */
|
||||
SANE_Int ld_shift_r; /* red */
|
||||
SANE_Int ld_shift_g; /* green */
|
||||
SANE_Int ld_shift_b; /* blue */
|
||||
|
||||
/* default gamma table */
|
||||
SANE_Word gamma[256];
|
||||
SANE_Int buttons; /* number of buttons for the scanner */
|
||||
char *button_name[11]; /* option names for buttons */
|
||||
char *button_title[11]; /* option titles for buttons */
|
||||
SANE_Word flags; /* allow per model behaviour control */
|
||||
} Rts8891_Model;
|
||||
|
||||
|
||||
struct Rts8891_Device
|
||||
{
|
||||
/**< Next device in linked list */
|
||||
struct Rts8891_Device *next;
|
||||
|
||||
/**< USB device number for libusb */
|
||||
SANE_Int devnum;
|
||||
SANE_String file_name;
|
||||
Rts8891_Model *model; /* points to a structure that decribes model specifics */
|
||||
|
||||
SANE_Int sensor; /* sensor id */
|
||||
|
||||
SANE_Bool initialized; /* true if device has been intialized */
|
||||
SANE_Bool needs_warming; /* true if device needs warming up */
|
||||
|
||||
/* values detected during find origin */
|
||||
/* TODO these are currently unused after detection */
|
||||
SANE_Int left_offset; /* pixels to skip to be on left start of the scanning area */
|
||||
SANE_Int top_offset; /* lines to skip to be at top of the scanning area */
|
||||
|
||||
/* gains from calibration */
|
||||
SANE_Int red_gain;
|
||||
SANE_Int green_gain;
|
||||
SANE_Int blue_gain;
|
||||
|
||||
/* offsets from calibration */
|
||||
SANE_Int red_offset;
|
||||
SANE_Int green_offset;
|
||||
SANE_Int blue_offset;
|
||||
|
||||
/* actual dpi used at hardware level may differ from the one
|
||||
* at SANE level */
|
||||
SANE_Int xdpi;
|
||||
SANE_Int ydpi;
|
||||
|
||||
/* the effective scan area at hardware level may be different from
|
||||
* the one at the SANE level*/
|
||||
SANE_Int lines; /* lines to scan */
|
||||
SANE_Int pixels; /* width of scan area */
|
||||
SANE_Int bytes_per_line; /* number of bytes per line */
|
||||
SANE_Int xstart; /* x start coordinate */
|
||||
SANE_Int ystart; /* y start coordinate */
|
||||
|
||||
/* line distance shift for the active scan */
|
||||
SANE_Int lds_r;
|
||||
SANE_Int lds_g;
|
||||
SANE_Int lds_b;
|
||||
|
||||
/* threshold to give 0/1 nit in lineart */
|
||||
SANE_Int threshold;
|
||||
|
||||
/* max value from lds_r, lds_g and lds_b */
|
||||
SANE_Int lds_max;
|
||||
|
||||
/* amount of data needed to correct ripple effect at highest dpi */
|
||||
SANE_Int ripple;
|
||||
|
||||
/* register set of the scanner */
|
||||
SANE_Int reg_count;
|
||||
SANE_Byte regs[255];
|
||||
|
||||
/* shading calibration data */
|
||||
SANE_Byte *shading_data;
|
||||
|
||||
/* data buffer read from scanner */
|
||||
SANE_Byte *scanned_data;
|
||||
|
||||
/* size of the buffer */
|
||||
SANE_Int data_size;
|
||||
|
||||
/* start of the data within scanned data */
|
||||
SANE_Byte *start;
|
||||
|
||||
/* current pointer within scanned data */
|
||||
SANE_Byte *current;
|
||||
|
||||
/* end of the data buffer */
|
||||
SANE_Byte *end;
|
||||
|
||||
/* amount of bytes read from scanner */
|
||||
SANE_Int read;
|
||||
|
||||
/* total amount of bytes to read for the scan */
|
||||
SANE_Int to_read;
|
||||
};
|
||||
|
||||
/*
|
||||
* This struct is used to build a static list of USB IDs and link them
|
||||
* to a struct that describes the corresponding model.
|
||||
*/
|
||||
typedef struct Rts8891_USB_Device_Entry
|
||||
{
|
||||
SANE_Word vendor_id; /**< USB vendor identifier */
|
||||
SANE_Word product_id; /**< USB product identifier */
|
||||
Rts8891_Model *model; /**< Scanner model information */
|
||||
} Rts8891_USB_Device_Entry;
|
||||
|
||||
/* this function init the rts8891 library */
|
||||
void rts8891_lib_init (void);
|
||||
|
||||
/***********************************/
|
||||
/* RTS8891 ASIC specific functions */
|
||||
/***********************************/
|
||||
|
||||
/* this functions commits pending scan command */
|
||||
static SANE_Status rts8891_commit (SANE_Int devnum, SANE_Byte value);
|
||||
|
||||
/**
|
||||
* move the head backward by a huge line number then poll home sensor until
|
||||
* head has get back home
|
||||
*/
|
||||
static SANE_Status rts8891_park (SANE_Int devnum, SANE_Byte * regs);
|
||||
|
||||
#endif /* not RTS8891_LOW_H */
|
|
@ -0,0 +1,858 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
Copyright (C) 2007-2008 stef.dev@free.fr
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/* this file contains functions common to rts88xx ASICs */
|
||||
|
||||
#include "sane/config.h"
|
||||
#include "sane/sane.h"
|
||||
#include "sane/sanei_backend.h"
|
||||
#include "sane/sanei_usb.h"
|
||||
#include "rts88xx_lib.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define RTS88XX_LIB_BUILD 2
|
||||
|
||||
/* init rts88xx library */
|
||||
void
|
||||
sanei_rts88xx_lib_init (void)
|
||||
{
|
||||
DBG_INIT ();
|
||||
DBG (DBG_info, "RTS88XX library, version %d.%d-rc-%d\n", V_MAJOR, V_MINOR,
|
||||
RTS88XX_LIB_BUILD);
|
||||
}
|
||||
|
||||
/*
|
||||
* registers helpers to avoid direct access
|
||||
*/
|
||||
SANE_Bool
|
||||
sanei_rts88xx_is_color (SANE_Byte * regs)
|
||||
{
|
||||
if ((regs[0x2f] & 0x11) == 0x11)
|
||||
return SANE_TRUE;
|
||||
return SANE_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
sanei_rts88xx_set_gray_scan (SANE_Byte * regs)
|
||||
{
|
||||
regs[0x2f] = (regs[0x2f] & 0x0f) | 0x20;
|
||||
}
|
||||
|
||||
void
|
||||
sanei_rts88xx_set_color_scan (SANE_Byte * regs)
|
||||
{
|
||||
regs[0x2f] = (regs[0x2f] & 0x0f) | 0x10;
|
||||
}
|
||||
|
||||
void
|
||||
sanei_rts88xx_set_offset (SANE_Byte * regs, SANE_Byte red, SANE_Byte green,
|
||||
SANE_Byte blue)
|
||||
{
|
||||
/* offset for odd pixels */
|
||||
regs[0x02] = red;
|
||||
regs[0x03] = green;
|
||||
regs[0x04] = blue;
|
||||
|
||||
/* offset for even pixels */
|
||||
regs[0x05] = red;
|
||||
regs[0x06] = green;
|
||||
regs[0x07] = blue;
|
||||
}
|
||||
|
||||
void
|
||||
sanei_rts88xx_set_gain (SANE_Byte * regs, SANE_Byte red, SANE_Byte green,
|
||||
SANE_Byte blue)
|
||||
{
|
||||
regs[0x08] = red;
|
||||
regs[0x09] = green;
|
||||
regs[0x0a] = blue;
|
||||
}
|
||||
|
||||
void
|
||||
sanei_rts88xx_set_scan_frequency (SANE_Byte * regs, int frequency)
|
||||
{
|
||||
regs[0x64] = (regs[0x64] & 0xf0) | (frequency & 0x0f);
|
||||
}
|
||||
|
||||
/*
|
||||
* read one register at given index
|
||||
*/
|
||||
SANE_Status
|
||||
sanei_rts88xx_read_reg (SANE_Int devnum, SANE_Int index, SANE_Byte * reg)
|
||||
{
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
unsigned char cmd[] = { 0x80, 0x00, 0x00, 0x01 };
|
||||
size_t size;
|
||||
|
||||
cmd[1] = index;
|
||||
|
||||
size = 4;
|
||||
status = sanei_usb_write_bulk (devnum, cmd, &size);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "sanei_rts88xx_read_reg: bulk write failed\n");
|
||||
return status;
|
||||
}
|
||||
size = 1;
|
||||
status = sanei_usb_read_bulk (devnum, reg, &size);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "sanei_rts88xx_read_reg: bulk read failed\n");
|
||||
return status;
|
||||
}
|
||||
DBG (DBG_io2, "sanei_rts88xx_read_reg: reg[0x%02x]=0x%02x\n", index, *reg);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* write one register at given index
|
||||
*/
|
||||
SANE_Status
|
||||
sanei_rts88xx_write_reg (SANE_Int devnum, SANE_Int index, SANE_Byte * reg)
|
||||
{
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
unsigned char cmd[] = { 0x88, 0x00, 0x00, 0x01, 0xff };
|
||||
size_t size;
|
||||
|
||||
cmd[1] = index;
|
||||
cmd[4] = *reg;
|
||||
|
||||
size = 5;
|
||||
status = sanei_usb_write_bulk (devnum, cmd, &size);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "sanei_rts88xx_write_reg: bulk write failed\n");
|
||||
return status;
|
||||
}
|
||||
DBG (DBG_io2, "sanei_rts88xx_write_reg: reg[0x%02x]=0x%02x\n", index, *reg);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* write length consecutive registers, starting at index
|
||||
* register 0xb3 is never wrote in bulk register write, so we split
|
||||
* write if it belongs to the register set sent
|
||||
*/
|
||||
SANE_Status
|
||||
sanei_rts88xx_write_regs (SANE_Int devnum, SANE_Int start,
|
||||
SANE_Byte * source, SANE_Int length)
|
||||
{
|
||||
size_t size = 0;
|
||||
size_t i;
|
||||
SANE_Byte buffer[260];
|
||||
char message[256 * 5];
|
||||
|
||||
if (DBG_LEVEL > DBG_io)
|
||||
{
|
||||
for (i = 0; i < (size_t) length; i++)
|
||||
{
|
||||
sprintf (message + 5 * i, "0x%02x ", source[i]);
|
||||
}
|
||||
DBG (DBG_io, "sanei_rts88xx_write_regs : write_regs(0x%02x,%d)=%s\n",
|
||||
start, length, message);
|
||||
}
|
||||
|
||||
/* when writing several registers at a time, we avoid writing the 0xb3 register
|
||||
* which is used to control the status of the scanner */
|
||||
if ((start + length > 0xb3) && (length > 1))
|
||||
{
|
||||
size = 0xb3 - start;
|
||||
buffer[0] = 0x88;
|
||||
buffer[1] = start;
|
||||
buffer[2] = 0x00;
|
||||
buffer[3] = size;
|
||||
for (i = 0; i < size; i++)
|
||||
buffer[i + 4] = source[i];
|
||||
/* the USB block is size + 4 bytes of header long */
|
||||
size += 4;
|
||||
if (sanei_usb_write_bulk (devnum, buffer, &size) != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"sanei_rts88xx_write_regs : write registers part 1 failed ...\n");
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
|
||||
/* skip 0xb3 register */
|
||||
size -= 3;
|
||||
start = 0xb4;
|
||||
source = source + size;
|
||||
}
|
||||
size = length - size;
|
||||
buffer[0] = 0x88;
|
||||
buffer[1] = start;
|
||||
buffer[2] = 0x00;
|
||||
buffer[3] = size;
|
||||
for (i = 0; i < size; i++)
|
||||
buffer[i + 4] = source[i];
|
||||
/* the USB block is size + 4 bytes of header long */
|
||||
size += 4;
|
||||
if (sanei_usb_write_bulk (devnum, buffer, &size) != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"sanei_rts88xx_write_regs : write registers part 2 failed ...\n");
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
|
||||
}
|
||||
|
||||
/* read several registers starting at the given index */
|
||||
SANE_Status
|
||||
sanei_rts88xx_read_regs (SANE_Int devnum, SANE_Int start,
|
||||
SANE_Byte * dest, SANE_Int length)
|
||||
{
|
||||
SANE_Status status;
|
||||
static SANE_Byte command_block[] = { 0x80, 0, 0x00, 0xFF };
|
||||
size_t size, i;
|
||||
char message[256 * 5];
|
||||
|
||||
if (start + length > 255)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"sanei_rts88xx_read_regs: start and length must be within [0..255]\n");
|
||||
return SANE_STATUS_INVAL;
|
||||
}
|
||||
|
||||
/* write header */
|
||||
size = 4;
|
||||
command_block[1] = start;
|
||||
command_block[3] = length;
|
||||
status = sanei_usb_write_bulk (devnum, command_block, &size);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "sanei_rts88xx_read_regs: failed to write header\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
/* read data */
|
||||
size = length;
|
||||
status = sanei_usb_read_bulk (devnum, dest, &size);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "sanei_rts88xx_read_regs: failed to read data\n");
|
||||
return status;
|
||||
}
|
||||
if (size != (size_t) length)
|
||||
{
|
||||
DBG (DBG_warn, "sanei_rts88xx_read_regs: read got only %d bytes\n",
|
||||
size);
|
||||
}
|
||||
if (DBG_LEVEL >= DBG_io)
|
||||
{
|
||||
for (i = 0; i < size; i++)
|
||||
sprintf (message + 5 * i, "0x%02x ", dest[i]);
|
||||
DBG (DBG_io, "sanei_rts88xx_read_regs: read_regs(0x%02x,%d)=%s\n",
|
||||
start, length, message);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* get status by reading registers 0x10 and 0x11
|
||||
*/
|
||||
SANE_Status
|
||||
sanei_rts88xx_get_status (SANE_Int devnum, SANE_Byte * regs)
|
||||
{
|
||||
SANE_Status status;
|
||||
status = sanei_rts88xx_read_regs (devnum, 0x10, regs + 0x10, 2);
|
||||
DBG (DBG_io, "sanei_rts88xx_get_status: get_status()=0x%02x 0x%02x\n",
|
||||
regs[0x10], regs[0x11]);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* set status by writing registers 0x10 and 0x11
|
||||
*/
|
||||
SANE_Status
|
||||
sanei_rts88xx_set_status (SANE_Int devnum, SANE_Byte * regs,
|
||||
SANE_Byte reg10, SANE_Byte reg11)
|
||||
{
|
||||
SANE_Status status;
|
||||
|
||||
regs[0x10] = reg10;
|
||||
regs[0x11] = reg11;
|
||||
status = sanei_rts88xx_write_regs (devnum, 0x10, regs + 0x10, 2);
|
||||
DBG (DBG_io, "sanei_rts88xx_set_status: 0x%02x 0x%02x\n", regs[0x10],
|
||||
regs[0x11]);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* get lamp status by reading registers 0x84 to 0x8f, only 0x8F is currently usefull
|
||||
* 0x84 and following could "on" timers
|
||||
*/
|
||||
SANE_Status
|
||||
sanei_rts88xx_get_lamp_status (SANE_Int devnum, SANE_Byte * regs)
|
||||
{
|
||||
SANE_Status status;
|
||||
status = sanei_rts88xx_read_regs (devnum, 0x84, regs + 0x84, 11);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* resets lamp */
|
||||
SANE_Status
|
||||
sanei_rts88xx_reset_lamp (SANE_Int devnum, SANE_Byte * regs)
|
||||
{
|
||||
SANE_Status status;
|
||||
SANE_Byte reg;
|
||||
|
||||
/* read the 0xda register, then clear lower nibble and write it back */
|
||||
status = sanei_rts88xx_read_reg (devnum, 0xda, ®);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"sanei_rts88xx_reset_lamp: failed to read 0xda register\n");
|
||||
return status;
|
||||
}
|
||||
reg = 0xa0;
|
||||
status = sanei_rts88xx_write_reg (devnum, 0xda, ®);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"sanei_rts88xx_reset_lamp: failed to write 0xda register\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
/* on cleared, get status */
|
||||
status = sanei_rts88xx_get_status (devnum, regs);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "sanei_rts88xx_reset_lamp: failed to get status\n");
|
||||
return status;
|
||||
}
|
||||
DBG (DBG_io, "sanei_rts88xx_reset_lamp: status=0x%02x 0x%02x\n", regs[0x10],
|
||||
regs[0x11]);
|
||||
|
||||
/* set low nibble to 7 and write it */
|
||||
reg = reg | 0x07;
|
||||
status = sanei_rts88xx_write_reg (devnum, 0xda, ®);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"sanei_rts88xx_reset_lamp: failed to write 0xda register\n");
|
||||
return status;
|
||||
}
|
||||
status = sanei_rts88xx_read_reg (devnum, 0xda, ®);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"sanei_rts88xx_reset_lamp: failed to read 0xda register\n");
|
||||
return status;
|
||||
}
|
||||
if (reg != 0xa7)
|
||||
{
|
||||
DBG (DBG_warn,
|
||||
"sanei_rts88xx_reset_lamp: expected reg[0xda]=0xa7, got 0x%02x\n",
|
||||
reg);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* get lcd status by reading registers 0x20, 0x21 and 0x22
|
||||
*/
|
||||
SANE_Status
|
||||
sanei_rts88xx_get_lcd (SANE_Int devnum, SANE_Byte * regs)
|
||||
{
|
||||
SANE_Status status;
|
||||
status = sanei_rts88xx_read_regs (devnum, 0x20, regs + 0x20, 3);
|
||||
DBG (DBG_io, "sanei_rts88xx_get_lcd: 0x%02x 0x%02x 0x%02x\n", regs[0x20],
|
||||
regs[0x21], regs[0x22]);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* write to special control register CONTROL_REG=0xb3
|
||||
*/
|
||||
SANE_Status
|
||||
sanei_rts88xx_write_control (SANE_Int devnum, SANE_Byte value)
|
||||
{
|
||||
SANE_Status status;
|
||||
status = sanei_rts88xx_write_reg (devnum, CONTROL_REG, &value);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* send the cancel control sequence
|
||||
*/
|
||||
SANE_Status
|
||||
sanei_rts88xx_cancel (SANE_Int devnum)
|
||||
{
|
||||
SANE_Status status;
|
||||
|
||||
status = sanei_rts88xx_write_control (devnum, 0x02);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
return status;
|
||||
status = sanei_rts88xx_write_control (devnum, 0x02);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
return status;
|
||||
status = sanei_rts88xx_write_control (devnum, 0x00);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
return status;
|
||||
status = sanei_rts88xx_write_control (devnum, 0x00);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* write the given number of bytes pointed by value into memory
|
||||
* length is payload length
|
||||
* extra is number of bytes to add to the usb write length
|
||||
*/
|
||||
SANE_Status
|
||||
sanei_rts88xx_write_mem (SANE_Int devnum, SANE_Int length, SANE_Int extra,
|
||||
SANE_Byte * value)
|
||||
{
|
||||
SANE_Status status;
|
||||
SANE_Byte *buffer;
|
||||
size_t i, size;
|
||||
char message[(0xFFC0 + 10) * 3] = "";
|
||||
|
||||
buffer = (SANE_Byte *) malloc (length + 10);
|
||||
memset (buffer, 0, length + 10);
|
||||
if (buffer == NULL)
|
||||
return SANE_STATUS_NO_MEM;
|
||||
|
||||
buffer[0] = 0x89;
|
||||
buffer[1] = 0x00;
|
||||
buffer[2] = HIBYTE (length);
|
||||
buffer[3] = LOBYTE (length);
|
||||
for (i = 0; i < (size_t) length; i++)
|
||||
{
|
||||
buffer[i + 4] = value[i];
|
||||
|
||||
if (DBG_LEVEL > DBG_io2)
|
||||
{
|
||||
sprintf (message + 3 * i, "%02x ", buffer[i + 4]);
|
||||
}
|
||||
}
|
||||
DBG (DBG_io, "sanei_rts88xx_write_mem: %02x %02x %02x %02x -> %s\n",
|
||||
buffer[0], buffer[1], buffer[2], buffer[3], message);
|
||||
|
||||
size = length + 4 + extra;
|
||||
status = sanei_usb_write_bulk (devnum, buffer, &size);
|
||||
free (buffer);
|
||||
if ((status == SANE_STATUS_GOOD) && (size != (size_t) length + 4 + extra))
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"sanei_rts88xx_write_mem: only wrote %d bytes out of %d\n", size,
|
||||
length + 4);
|
||||
status = SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* set memory with the given data
|
||||
*/
|
||||
SANE_Status
|
||||
sanei_rts88xx_set_mem (SANE_Int devnum, SANE_Byte ctrl1,
|
||||
SANE_Byte ctrl2, SANE_Int length, SANE_Byte * value)
|
||||
{
|
||||
SANE_Status status;
|
||||
SANE_Byte regs[2];
|
||||
regs[0] = ctrl1;
|
||||
regs[1] = ctrl2;
|
||||
|
||||
status = sanei_rts88xx_write_regs (devnum, 0x91, regs, 2);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"sanei_rts88xx_set_mem: failed to write 0x91/0x92 registers\n");
|
||||
return status;
|
||||
}
|
||||
status = sanei_rts88xx_write_mem (devnum, length, 0, value);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "sanei_rts88xx_set_mem: failed to write memory\n");
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* read length bytes of memory into area pointed by value
|
||||
*/
|
||||
SANE_Status
|
||||
sanei_rts88xx_read_mem (SANE_Int devnum, SANE_Int length, SANE_Byte * value)
|
||||
{
|
||||
SANE_Status status;
|
||||
size_t size, read, want;
|
||||
SANE_Byte header[4];
|
||||
|
||||
/* build and write length header */
|
||||
header[0] = 0x81;
|
||||
header[1] = 0x00;
|
||||
header[2] = HIBYTE (length);
|
||||
header[3] = LOBYTE (length);
|
||||
size = 4;
|
||||
status = sanei_usb_write_bulk (devnum, header, &size);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"sanei_rts88xx_read_mem: failed to write length header\n");
|
||||
return status;
|
||||
}
|
||||
DBG (DBG_io, "sanei_rts88xx_read_mem: %02x %02x %02x %02x -> ...\n",
|
||||
header[0], header[1], header[2], header[3]);
|
||||
read = 0;
|
||||
while (length > 0)
|
||||
{
|
||||
if (length > 2048)
|
||||
want = 2048;
|
||||
else
|
||||
want = length;
|
||||
size = want;
|
||||
status = sanei_usb_read_bulk (devnum, value + read, &size);
|
||||
if (size != want)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"sanei_rts88xx_read_mem: only read %d bytes out of %d\n", size,
|
||||
want);
|
||||
status = SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
length -= size;
|
||||
read += size;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* set memory with the given data
|
||||
*/
|
||||
SANE_Status
|
||||
sanei_rts88xx_get_mem (SANE_Int devnum, SANE_Byte ctrl1,
|
||||
SANE_Byte ctrl2, SANE_Int length, SANE_Byte * value)
|
||||
{
|
||||
SANE_Status status;
|
||||
SANE_Byte regs[2];
|
||||
regs[0] = ctrl1;
|
||||
regs[1] = ctrl2;
|
||||
|
||||
status = sanei_rts88xx_write_regs (devnum, 0x91, regs, 2);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"sanei_rts88xx_get_mem: failed to write 0x91/0x92 registers\n");
|
||||
return status;
|
||||
}
|
||||
status = sanei_rts88xx_read_mem (devnum, length, value);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "sanei_rts88xx_get_mem: failed to read memory\n");
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* write to the nvram controler
|
||||
*/
|
||||
SANE_Status
|
||||
sanei_rts88xx_nvram_ctrl (SANE_Int devnum, SANE_Int length, SANE_Byte * value)
|
||||
{
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
SANE_Int size = 0;
|
||||
SANE_Int i;
|
||||
SANE_Byte buffer[60];
|
||||
char message[60 * 5];
|
||||
|
||||
if (DBG_LEVEL > DBG_io)
|
||||
{
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
sprintf (message + 5 * i, "0x%02x ", value[i]);
|
||||
}
|
||||
DBG (DBG_io, "sanei_rts88xx_nvram_ctrl : nvram_ctrl(0x00,%d)=%s\n",
|
||||
length, message);
|
||||
}
|
||||
|
||||
buffer[0] = 0x8a;
|
||||
buffer[1] = 0x00;
|
||||
buffer[2] = 0x00;
|
||||
buffer[3] = length;
|
||||
for (i = 0; i < size; i++)
|
||||
buffer[i + 4] = value[i];
|
||||
/* the USB block is size + 4 bytes of header long */
|
||||
size = length + 4;
|
||||
#ifdef HAZARDOUS_EXPERIMENT
|
||||
status = sanei_usb_write_bulk (devnum, buffer, &size);
|
||||
#else
|
||||
devnum = devnum;
|
||||
status = SANE_STATUS_GOOD;
|
||||
#endif
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "sanei_rts88xx_nvram_ctrl : write failed ...\n");
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* setup nvram
|
||||
*/
|
||||
SANE_Status
|
||||
sanei_rts88xx_setup_nvram (SANE_Int devnum, SANE_Int length,
|
||||
SANE_Byte * value)
|
||||
{
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
SANE_Byte local[2], reg;
|
||||
int i;
|
||||
|
||||
status = sanei_rts88xx_nvram_ctrl (devnum, length, value);
|
||||
|
||||
#ifndef HAZARDOUS_EXPERIMENT
|
||||
return SANE_STATUS_GOOD;
|
||||
#endif
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "sanei_rts88xx_setup_nvram : failed step #1 ...\n");
|
||||
return status;
|
||||
}
|
||||
local[0] = 0x18;
|
||||
local[1] = 0x08;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
status = sanei_rts88xx_nvram_ctrl (devnum, 2, local);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "sanei_rts88xx_setup_nvram : failed loop #%d ...\n",
|
||||
i);
|
||||
return status;
|
||||
}
|
||||
status = sanei_rts88xx_read_reg (devnum, 0x10, ®);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"sanei_rts88xx_setup_nvram : register reading failed loop #%d ...\n",
|
||||
i);
|
||||
return status;
|
||||
}
|
||||
DBG (DBG_io, "sanei_rts88xx_setup_nvram: reg[0x10]=0x%02x\n", reg);
|
||||
}
|
||||
reg = 0;
|
||||
status = sanei_rts88xx_write_reg (devnum, CONTROLER_REG, ®);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"sanei_rts88xx_setup_nvram : controler register write failed\n");
|
||||
return status;
|
||||
}
|
||||
reg = 1;
|
||||
status = sanei_rts88xx_write_reg (devnum, CONTROLER_REG, ®);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"sanei_rts88xx_setup_nvram : controler register write failed\n");
|
||||
return status;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets scan area, no checks are being done, so watch your steps
|
||||
*/
|
||||
void
|
||||
sanei_rts88xx_set_scan_area (SANE_Byte * regs, SANE_Int ystart,
|
||||
SANE_Int yend, SANE_Int xstart, SANE_Int xend)
|
||||
{
|
||||
/* vertical lines to move before scan */
|
||||
regs[START_LINE] = LOBYTE (ystart);
|
||||
regs[START_LINE + 1] = HIBYTE (ystart);
|
||||
|
||||
/* total number of line to move */
|
||||
regs[END_LINE] = LOBYTE (yend);
|
||||
regs[END_LINE + 1] = HIBYTE (yend);
|
||||
|
||||
/* set horizontal start position */
|
||||
regs[START_PIXEL] = LOBYTE (xstart);
|
||||
regs[START_PIXEL + 1] = HIBYTE (xstart);
|
||||
|
||||
/* set horizontal end position */
|
||||
regs[END_PIXEL] = LOBYTE (xend);
|
||||
regs[END_PIXEL + 1] = HIBYTE (xend);
|
||||
}
|
||||
|
||||
/**
|
||||
* read available data count from scanner
|
||||
* from tests it appears that advertised data
|
||||
* may not be really available, and that a pause must be made
|
||||
* before reading data so that it is really there.
|
||||
* Such as reading data twice.
|
||||
*/
|
||||
SANE_Status
|
||||
sanei_rts88xx_data_count (SANE_Int devnum, SANE_Word * count)
|
||||
{
|
||||
SANE_Status status;
|
||||
size_t size;
|
||||
static SANE_Byte header[4] = { 0x90, 0x00, 0x00, 3 };
|
||||
SANE_Byte result[3];
|
||||
|
||||
/* set count in case of failure */
|
||||
*count = 0;
|
||||
|
||||
size = 4;
|
||||
status = sanei_usb_write_bulk (devnum, header, &size);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "sanei_rts88xx_data_count : failed to write header\n");
|
||||
return status;
|
||||
}
|
||||
size = 3;
|
||||
status = sanei_usb_read_bulk (devnum, result, &size);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"sanei_rts88xx_data_count : failed to read data count\n");
|
||||
return status;
|
||||
}
|
||||
*count = result[0] + (result[1] << 8) + (result[2] << 16);
|
||||
DBG (DBG_io2, "sanei_rts88xx_data_count: %d bytes available (0x%06x)\n",
|
||||
*count, *count);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for data being available while optionally polling motor. There is a timeout
|
||||
* to prevent scanner waiting forever non coming data.
|
||||
*/
|
||||
SANE_Status
|
||||
sanei_rts88xx_wait_data (SANE_Int devnum, SANE_Bool busy, SANE_Word * count)
|
||||
{
|
||||
SANE_Status status;
|
||||
SANE_Byte control;
|
||||
|
||||
/* poll the available byte count until not 0 */
|
||||
while (SANE_TRUE)
|
||||
{
|
||||
status = sanei_rts88xx_data_count (devnum, count);
|
||||
if (*count != 0)
|
||||
{
|
||||
DBG (DBG_io, "sanei_rts88xx_wait_data: %d bytes available\n",
|
||||
*count);
|
||||
return SANE_STATUS_GOOD;
|
||||
}
|
||||
|
||||
/* check that the scanner is busy scanning */
|
||||
if (busy)
|
||||
{
|
||||
sanei_rts88xx_read_reg (devnum, CONTROL_REG, &control);
|
||||
if ((control & 0x08) == 0 && (*count == 0))
|
||||
{
|
||||
DBG (DBG_error,
|
||||
"sanei_rts88xx_wait_data: scanner stopped being busy before data are available\n");
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* we hit timeout */
|
||||
return SANE_STATUS_IO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* read scanned data from scanner up to the size given. The actual length read is returned.
|
||||
*/
|
||||
SANE_Status
|
||||
sanei_rts88xx_read_data (SANE_Int devnum, SANE_Word * length,
|
||||
unsigned char *dest)
|
||||
{
|
||||
SANE_Status status = SANE_STATUS_GOOD;
|
||||
SANE_Byte header[4];
|
||||
size_t size, len, remain, read;
|
||||
|
||||
/* do not read too much data */
|
||||
if (*length > RTS88XX_MAX_XFER_SIZE)
|
||||
len = RTS88XX_MAX_XFER_SIZE;
|
||||
else
|
||||
len = *length;
|
||||
|
||||
/* write command header first */
|
||||
header[0] = 0x91;
|
||||
header[1] = 0x00;
|
||||
header[2] = HIBYTE (len);
|
||||
header[3] = LOBYTE (len);
|
||||
size = 4;
|
||||
|
||||
status = sanei_usb_write_bulk (devnum, header, &size);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "sanei_rts88xx_read_data: failed to write header\n");
|
||||
}
|
||||
read = 0;
|
||||
|
||||
/* first read blocks aligned on 64 bytes boundary */
|
||||
while (len - read > 64)
|
||||
{
|
||||
size = (len - read) & 0xFFC0;
|
||||
status = sanei_usb_read_bulk (devnum, dest + read, &size);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "sanei_rts88xx_read_data: failed to read data\n");
|
||||
return status;
|
||||
}
|
||||
DBG (DBG_io2, "sanei_rts88xx_read_data: read %d bytes\n", size);
|
||||
read += size;
|
||||
}
|
||||
|
||||
/* then read remainder */
|
||||
remain = len - read;
|
||||
if (remain > 0)
|
||||
{
|
||||
status = sanei_usb_read_bulk (devnum, dest + read, &remain);
|
||||
if (status != SANE_STATUS_GOOD)
|
||||
{
|
||||
DBG (DBG_error, "sanei_rts88xx_read_data: failed to read data\n");
|
||||
return status;
|
||||
}
|
||||
DBG (DBG_io2, "sanei_rts88xx_read_data: read %d bytes\n", remain);
|
||||
read += remain;
|
||||
}
|
||||
|
||||
/* update actual read length */
|
||||
DBG (DBG_io, "sanei_rts88xx_read_data: read %d bytes, %d required\n",
|
||||
read, *length);
|
||||
*length = read;
|
||||
return status;
|
||||
}
|
|
@ -0,0 +1,213 @@
|
|||
/* sane - Scanner Access Now Easy.
|
||||
|
||||
Copyright (C) 2007-2008 stef.dev@free.fr
|
||||
|
||||
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 RTS88XX_LIB_H
|
||||
#define RTS88XX_LIB_H
|
||||
#include "sane/sane.h"
|
||||
#include "sane/sanei_usb.h"
|
||||
#include "unistd.h"
|
||||
#include "string.h"
|
||||
|
||||
/* TODO put his in a place where it can be reused */
|
||||
|
||||
#define DBG_error0 0 /* errors/warnings printed even with debuglevel 0 */
|
||||
#define DBG_error 1 /* fatal errors */
|
||||
#define DBG_init 2 /* initialization and scanning time messages */
|
||||
#define DBG_warn 3 /* warnings and non-fatal errors */
|
||||
#define DBG_info 4 /* informational messages */
|
||||
#define DBG_proc 5 /* starting/finishing functions */
|
||||
#define DBG_io 6 /* io functions */
|
||||
#define DBG_io2 7 /* io functions that are called very often */
|
||||
#define DBG_data 8 /* log data sent and received */
|
||||
|
||||
/*
|
||||
* defines for registers name
|
||||
*/
|
||||
#define CONTROL_REG 0xb3
|
||||
#define CONTROLER_REG 0x1d
|
||||
|
||||
/* geometry registers */
|
||||
#define START_LINE 0x60
|
||||
#define END_LINE 0x62
|
||||
#define START_PIXEL 0x66
|
||||
#define END_PIXEL 0x6c
|
||||
|
||||
#define RTS88XX_MAX_XFER_SIZE 0xFFC0
|
||||
|
||||
#define LOBYTE(x) ((u_int8_t)((x) & 0xFF))
|
||||
#define HIBYTE(x) ((u_int8_t)((x) >> 8))
|
||||
|
||||
/* this function init the rts88xx library */
|
||||
void sanei_rts88xx_lib_init (void);
|
||||
SANE_Bool sanei_rts88xx_is_color (SANE_Byte * regs);
|
||||
|
||||
void sanei_rts88xx_set_gray_scan (SANE_Byte * regs);
|
||||
void sanei_rts88xx_set_color_scan (SANE_Byte * regs);
|
||||
void sanei_rts88xx_set_offset (SANE_Byte * regs, SANE_Byte red,
|
||||
SANE_Byte green, SANE_Byte blue);
|
||||
void sanei_rts88xx_set_gain (SANE_Byte * regs, SANE_Byte red, SANE_Byte green,
|
||||
SANE_Byte blue);
|
||||
void sanei_rts88xx_set_scan_frequency (SANE_Byte * regs, int frequency);
|
||||
|
||||
/*
|
||||
* set scan area
|
||||
*/
|
||||
void sanei_rts88xx_set_scan_area (SANE_Byte * reg, SANE_Int ystart,
|
||||
SANE_Int yend, SANE_Int xstart,
|
||||
SANE_Int xend);
|
||||
|
||||
/*
|
||||
* read one register at given index
|
||||
*/
|
||||
SANE_Status sanei_rts88xx_read_reg (SANE_Int devnum, SANE_Int index,
|
||||
SANE_Byte * reg);
|
||||
|
||||
/*
|
||||
* read scanned data from scanner up to the size given. The actual length read is returned.
|
||||
*/
|
||||
SANE_Status sanei_rts88xx_read_data (SANE_Int devnum, SANE_Word * length,
|
||||
unsigned char *dest);
|
||||
|
||||
/*
|
||||
* write one register at given index
|
||||
*/
|
||||
SANE_Status sanei_rts88xx_write_reg (SANE_Int devnum, SANE_Int index,
|
||||
SANE_Byte * reg);
|
||||
|
||||
/*
|
||||
* write length consecutive registers, starting at index
|
||||
* register 0xb3 is never wrote in bulk register write, so we split
|
||||
* write if it belongs to the register set sent
|
||||
*/
|
||||
SANE_Status sanei_rts88xx_write_regs (SANE_Int devnum, SANE_Int start,
|
||||
SANE_Byte * source, SANE_Int length);
|
||||
|
||||
/* read several registers starting at the given index */
|
||||
SANE_Status sanei_rts88xx_read_regs (SANE_Int devnum, SANE_Int start,
|
||||
SANE_Byte * dest, SANE_Int length);
|
||||
|
||||
/*
|
||||
* get status by reading registers 0x10 and 0x11
|
||||
*/
|
||||
SANE_Status sanei_rts88xx_get_status (SANE_Int devnum, SANE_Byte * regs);
|
||||
/*
|
||||
* set status by writing registers 0x10 and 0x11
|
||||
*/
|
||||
SANE_Status sanei_rts88xx_set_status (SANE_Int devnum, SANE_Byte * regs,
|
||||
SANE_Byte reg10, SANE_Byte reg11);
|
||||
|
||||
/*
|
||||
* get lamp status by reading registers 0x84 to 0x8d
|
||||
*/
|
||||
SANE_Status sanei_rts88xx_get_lamp_status (SANE_Int devnum, SANE_Byte * regs);
|
||||
|
||||
/* reset lamp */
|
||||
SANE_Status sanei_rts88xx_reset_lamp (SANE_Int devnum, SANE_Byte * regs);
|
||||
|
||||
/* get lcd panel status */
|
||||
SANE_Status sanei_rts88xx_get_lcd (SANE_Int devnum, SANE_Byte * regs);
|
||||
|
||||
/*
|
||||
* write to special control register CONTROL_REG=0xb3
|
||||
*/
|
||||
SANE_Status sanei_rts88xx_write_control (SANE_Int devnum, SANE_Byte value);
|
||||
|
||||
/*
|
||||
* send the cancel control sequence
|
||||
*/
|
||||
SANE_Status sanei_rts88xx_cancel (SANE_Int devnum);
|
||||
|
||||
/*
|
||||
* read available data count from scanner
|
||||
*/
|
||||
SANE_Status sanei_rts88xx_data_count (SANE_Int devnum, SANE_Word * count);
|
||||
|
||||
/*
|
||||
* wait for scanned data to be available, if busy is true, check is scanner is busy
|
||||
* while waiting. The number of data bytes of available data is returned in 'count'.
|
||||
*/
|
||||
SANE_Status sanei_rts88xx_wait_data (SANE_Int devnum, SANE_Bool busy,
|
||||
SANE_Word * count);
|
||||
|
||||
/*
|
||||
* write the given number of bytes pointed by value into memory
|
||||
*/
|
||||
SANE_Status sanei_rts88xx_write_mem (SANE_Int devnum, SANE_Int length,
|
||||
SANE_Int extra, SANE_Byte * value);
|
||||
|
||||
/*
|
||||
* set memory with the given data
|
||||
*/
|
||||
SANE_Status sanei_rts88xx_set_mem (SANE_Int devnum, SANE_Byte ctrl1,
|
||||
SANE_Byte ctrl2, SANE_Int length,
|
||||
SANE_Byte * value);
|
||||
|
||||
/*
|
||||
* read the given number of bytes from memory into buffer
|
||||
*/
|
||||
SANE_Status sanei_rts88xx_read_mem (SANE_Int devnum, SANE_Int length,
|
||||
SANE_Byte * value);
|
||||
|
||||
/*
|
||||
* get memory
|
||||
*/
|
||||
SANE_Status sanei_rts88xx_get_mem (SANE_Int devnum, SANE_Byte ctrl1,
|
||||
SANE_Byte ctrl2, SANE_Int length,
|
||||
SANE_Byte * value);
|
||||
|
||||
/*
|
||||
* write to the nvram controler
|
||||
*/
|
||||
SANE_Status sanei_rts88xx_nvram_ctrl (SANE_Int devnum, SANE_Int length,
|
||||
SANE_Byte * value);
|
||||
|
||||
/*
|
||||
* setup nvram
|
||||
*/
|
||||
SANE_Status sanei_rts88xx_setup_nvram (SANE_Int devnum, SANE_Int length,
|
||||
SANE_Byte * value);
|
||||
|
||||
|
||||
/* does a simple scan, putting data in image */
|
||||
/* SANE_Status sanei_rts88xx_simple_scan (SANE_Int devnum, SANE_Byte * regs, int regcount, SANE_Word size, unsigned char *image); */
|
||||
#endif /* not RTS88XX_LIB_H */
|
|
@ -27050,7 +27050,7 @@ echo "$as_me: Manually selected backends: ${BACKENDS}" >&6;}
|
|||
hp hp3500 hp3900 hp4200 hp5400 hp5590 hpljm1005 hs2p \
|
||||
ibm leo lexmark \
|
||||
ma1509 matsushita microtek microtek2 mustek mustek_usb \
|
||||
nec niash pie pixma plustek ricoh \
|
||||
nec niash pie pixma plustek ricoh rts8891 \
|
||||
s9036 sceptre sharp sm3600 sm3840 snapscan sp15c st400 stv680 \
|
||||
tamarack teco1 teco2 teco3 test u12 umax umax_pp umax1220u"
|
||||
|
||||
|
|
|
@ -366,7 +366,7 @@ else
|
|||
hp hp3500 hp3900 hp4200 hp5400 hp5590 hpljm1005 hs2p \
|
||||
ibm leo lexmark \
|
||||
ma1509 matsushita microtek microtek2 mustek mustek_usb \
|
||||
nec niash pie pixma plustek ricoh \
|
||||
nec niash pie pixma plustek ricoh rts8891 \
|
||||
s9036 sceptre sharp sm3600 sm3840 snapscan sp15c st400 stv680 \
|
||||
tamarack teco1 teco2 teco3 test u12 umax umax_pp umax1220u"
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
;
|
||||
; SANE Backend specification file
|
||||
;
|
||||
; It's basically emacs-lisp --- so ";" indicates comment to end of line.
|
||||
; All syntactic elements are keyword tokens, followed by a string or
|
||||
; keyword argument, as specified.
|
||||
;
|
||||
; ":backend" *must* be specified.
|
||||
; All other information is optional (but what good is the file without it?).
|
||||
|
||||
|
||||
:backend "rts8891" ; name of backend
|
||||
:version "1.0-0" ; version of backend (or "unmaintained")
|
||||
:manpage "rts8891" ; name of manpage (if it exists)
|
||||
:url "http://stef.dev.free.fr/sane/rts8891/index.html"
|
||||
; backend's web page
|
||||
|
||||
:comment "This backend supports Realtek RTS8891 ASIC bases scanners."
|
||||
; comment about the backend
|
||||
|
||||
:devicetype :scanner ; start of a list of devices....
|
||||
; other types: :stillcam, :vidcam,
|
||||
; :meta, :api
|
||||
|
||||
:mfg "UMAX" ; name a manufacturer
|
||||
:url "http://www.umax.com.tw/" ; manufacturer's URL
|
||||
|
||||
:model "Astra 4400"
|
||||
:interface "USB"
|
||||
:usbid "0x1606" "0x0070"
|
||||
:status :good
|
||||
:comment "Supports 75, 150, 300, 600 and 1200 dpi"
|
||||
|
||||
:model "Astra 4450"
|
||||
:interface "USB"
|
||||
:usbid "0x1606" "0x0070"
|
||||
:status :untested
|
||||
|
||||
:mfg "Hewlett-Packard" ; name a manufacturer
|
||||
:url "http://www.hp.com/"
|
||||
|
||||
:model "scanjet 4470c"
|
||||
:interface "USB"
|
||||
:usbid "0x03f0" "0x0805"
|
||||
:status :good
|
||||
:comment "re-branded Astra 4400"
|
|
@ -2517,20 +2517,6 @@
|
|||
:status :unsupported
|
||||
:comment "Not supported, to be added to genesys backend."
|
||||
|
||||
:model "Astra 4400"
|
||||
:url "/unsupported/umax-astra-4400.html"
|
||||
:interface "USB"
|
||||
:usbid "0x1606" "0x0070"
|
||||
:status :unsupported
|
||||
:comment "Probably not supported. See link for details."
|
||||
|
||||
:model "Astra 4450"
|
||||
:url "/unsupported/umax-astra-4450.html"
|
||||
:interface "USB"
|
||||
:usbid "0x1606" "0x0070"
|
||||
:status :unsupported
|
||||
:comment "Probably not supported. See link for details."
|
||||
|
||||
:model "Astra 4500"
|
||||
:url "/unsupported/umax-astra-4500.html"
|
||||
:interface "USB"
|
||||
|
|
|
@ -0,0 +1,198 @@
|
|||
.\" .IX sane-rts8891
|
||||
.TH "sane-rts8891" "5" "16 March 2008" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
|
||||
.SH "NAME"
|
||||
sane\-rts8891 \- SANE backend for Umax Astra 4400/4450 and Hewlett-Packard Scanjet 4470c scanners
|
||||
.SH "DESCRIPTION"
|
||||
The
|
||||
.B sane\-rts8891
|
||||
library implements a SANE (Scanner Access Now Easy) backend that
|
||||
provides access to scanner based on Realtek RTS8891 ASIC.
|
||||
.PP
|
||||
The scanners that should work with this backend are:
|
||||
.PP
|
||||
.RS
|
||||
.ft CR
|
||||
.nf
|
||||
Vendor Model status
|
||||
\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \-\-\-\-\-\-\-\-\-\-\-
|
||||
Umax 4400 good
|
||||
Umax 4450 untested
|
||||
HP 4470c good re-badged Astra 4400
|
||||
.fi
|
||||
.ft R
|
||||
.RE
|
||||
|
||||
The options the backend supports can either be selected through
|
||||
command line options to programs like scanimage or through GUI
|
||||
elements in xscanimage or xsane.
|
||||
|
||||
.br
|
||||
If you have any strange behavior, please report to the backend
|
||||
maintainer or to the SANE mailing list.
|
||||
|
||||
Valid command line options and their syntax can be listed by using
|
||||
.RS
|
||||
scanimage \-\-help \-d rts8891
|
||||
.RE
|
||||
|
||||
.TP
|
||||
.B Scan Mode Options
|
||||
|
||||
.TP
|
||||
.B \-\-mode
|
||||
selects the basic mode of operation of the scanner valid choices are
|
||||
.I auto
|
||||
.R ,
|
||||
.I Color
|
||||
.R ,
|
||||
.I Gray
|
||||
and
|
||||
.I Lineart
|
||||
The default or automatic mode is Color. The Lineart mode is black and white only (1 bit).
|
||||
Grayscale will produce 256 levels of gray (8 bits). Gray and Lineart mode are emulated.
|
||||
Color mode allows for over 16 million different colors produced from 24 bits of color information.
|
||||
|
||||
.TP
|
||||
.B \-\-resolution
|
||||
selects the resolution for a scan. The horizontal and vertical resolutions are set
|
||||
by the value of this option. Default value is 150 dpi, automatic value is 75 dpi.
|
||||
The scanner is capable of the following resolutions for the specified option value:
|
||||
.PP
|
||||
.RS
|
||||
.ft CR
|
||||
.nf
|
||||
Value Hor. Resolution Vert. Resolution
|
||||
\-\-\-\-\- \-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-
|
||||
75 75dpi 150dpi lines are averaged to match dpi
|
||||
150 150dpi 150dpi
|
||||
300 300dpi 300dpi
|
||||
600 600dpi 600dpi
|
||||
1200 1200dpi 600dpi lines are duplicated to match dpi
|
||||
.fi
|
||||
.ft R
|
||||
.RE
|
||||
|
||||
.TP
|
||||
.B \-\-preview
|
||||
requests a preview scan. The resolution used for that scan is 75 dpi
|
||||
and the scan area and the scan mode are as specified through their options,
|
||||
or the default if not specified. The default and automatic value for preview mode is "no".
|
||||
|
||||
.TP
|
||||
.B Image Enhancement Options
|
||||
|
||||
.TP
|
||||
.B \-\-threshold
|
||||
selects the minimum\-brightness to get a white point. The threshold is only used with Lineart mode scans.
|
||||
It is specified as a percentage in the range 0..100% (in steps of 1).
|
||||
The default or automatic value of the threshold option is 50.
|
||||
|
||||
.TP
|
||||
.B --custom-gamma
|
||||
allows the user to specify a gamma table (see gamma-table options). The default and automatic
|
||||
value is 'no'.
|
||||
|
||||
.TP
|
||||
.B --gamma-table
|
||||
(gray and lineart modes) can be used to download a user defined
|
||||
gamma table for the gray channel. The table must be 256 SANE_Word long.
|
||||
Valid values are in the [0..255] range.
|
||||
The automatic or default value is a builtin gamma table. This option
|
||||
is active only if custom-gamma is set to yes.
|
||||
|
||||
.TP
|
||||
.B --red-gamma-table
|
||||
(color mode only) can be used to download a user defined
|
||||
gamma table for the red channel. The table must be 256 SANE_Word long.
|
||||
Valid values are in the [0..255] range.
|
||||
The automatic or default value is a builtin gamma table. This option
|
||||
is active only if custom-gamma is set to yes.
|
||||
|
||||
.TP
|
||||
.B --green-gamma-table
|
||||
(color mode only) can be used to download a user defined
|
||||
gamma table for the green channel. The table must be 256 SANE_Word long.
|
||||
Valid values are in the [0..255] range.
|
||||
The automatic or default value is a builtin gamma table. This option
|
||||
is active only if custom-gamma is set to yes.
|
||||
|
||||
.TP
|
||||
.B --blue-gamma-table
|
||||
(color mode only) can be used to download a user defined gamma table
|
||||
for the blue channel. The table must be 256 SANE_Word long.
|
||||
Valid values are in the [0..255] range.
|
||||
The automatic or default value is a builtin gamma table. This option
|
||||
is active only if custom-gamma is set to yes.
|
||||
|
||||
.TP
|
||||
.B Utility Options
|
||||
|
||||
.TP
|
||||
.B \-\-lamp\-on
|
||||
this advanced option switches the lamp on. It is a set only option.
|
||||
|
||||
.TP
|
||||
.B \-\-lamp\-off
|
||||
this advanced option switches the lamp off. It is a set only option.
|
||||
|
||||
.SH "CONFIGURATION FILE"
|
||||
The configuration file @CONFIGDIR@/rts8891.conf contains only the usb device id (eg usb 0x043d 0x007c).
|
||||
|
||||
|
||||
.SH "FILES"
|
||||
.TP
|
||||
.I @LIBDIR@/libsane\-rts8891.a
|
||||
The static library implementing this backend.
|
||||
.TP
|
||||
.I @LIBDIR@/libsane\-rts8891.so
|
||||
The shared library implementing this backend (present on systems that
|
||||
support dynamic loading).
|
||||
|
||||
|
||||
.SH "ENVIRONMENT"
|
||||
.TP
|
||||
.B SANE_DEBUG_RTS88XX_LIB
|
||||
rts88xx library debugging messages control.
|
||||
.TP
|
||||
.B SANE_DEBUG_RTS8891_LOW
|
||||
rts8891 low-level access debugging messages control.
|
||||
.TP
|
||||
.B SANE_DEBUG_RTS8891
|
||||
rts8891 backend debugging messages control.
|
||||
.br
|
||||
.br
|
||||
If the library or backend was compiled with debug support enabled, these
|
||||
environment variables controls the debug level for this backend. E.g.,
|
||||
a value of 255 requests all debug output to be printed. Smaller levels
|
||||
reduce verbosity. Higher levels of debugging also gives PNM files holding
|
||||
data scanned at various stages of calibration and during final scan. In case
|
||||
you find a bug and want ot report about it, it is recommended to reproduce
|
||||
the bug whit these values set to 255, and join the debugging output to the
|
||||
report.
|
||||
|
||||
|
||||
.SH "LIMITATIONS"
|
||||
There is no support for transparency adaptor.
|
||||
|
||||
.SH "BUGS"
|
||||
.br
|
||||
No bugs are currently known. In case you find a bug, you may report it to the maintainer,
|
||||
the sane-devel mailing list or fill a bug report at
|
||||
https://alioth.debian.org/tracker/?atid=410366&group_id=30186&func=browse
|
||||
|
||||
|
||||
.SH "SEE ALSO"
|
||||
sane\-usb(5), scanimage(1), xscanimage(1), xsane(1), sane(7)
|
||||
|
||||
|
||||
.SH "AUTHOR"
|
||||
.TP
|
||||
This backend is currently developped by Stéphane Voltz.
|
||||
.I http://stef.dev.free.fr/sane/rts8891
|
||||
.SH "CREDITS"
|
||||
.TP
|
||||
Many thanks go to:
|
||||
Laurent Fournier who lent me his scanjet 4470c.
|
||||
Henry Wieland for the time spent recording USB activity and testing the experimental version.
|
||||
The ASIC registers analysis by Troy Rollo and Johannes Hub did provide me of some important
|
||||
hints on the operation of the RTS8891.
|
Ładowanie…
Reference in New Issue