kopia lustrzana https://gitlab.com/sane-project/backends
Updated Plustek backend and added code for alternative CIS calibration.
All the supported CanoScan devices should work now correctly. Moved the Plustek parallelport support into a separate backend: plustek_pp. Added new backend for Plustek ASIC 9600x/9800x based parallelport scanner.merge-requests/1/head
rodzic
86cead990d
commit
1eef5c8c60
27
ChangeLog
27
ChangeLog
|
@ -1,3 +1,30 @@
|
|||
2003-09-23 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
|
||||
* configure.in: added new backend plustek_pp
|
||||
* doc/descriptions/plustek_pp.desc : added
|
||||
* doc/plustek/*: added/updated various doc-files
|
||||
* doc/sane-plustek_pp.man doc/Makefile.in : added new man page
|
||||
* backend/dll.conf : added plustek_pp
|
||||
* backend/Makefile.in : added plustek_pp files, updated plustek files
|
||||
* backend/plustek-devs.c backend/pustek-pp.c : removed
|
||||
* backend/plustek-usbcalfile.c backend/plustek-usbcal.c
|
||||
backend/plustek-usbdevs.c: new files for the plustek usb backend
|
||||
* backend/plustek_pp.c backend/plustek_pp.conf
|
||||
* backend/plustek-pp.h backend/plustek-pp_dac.c backend/plustek-pp_dbg.h
|
||||
backend/plustek-pp_detect.c backend/plustek-pp_genericio.c
|
||||
backend/plustek-pp_hwdefs.h backend/plustek-pp_image.c
|
||||
backend/plustek-pp_io.c backend/plustek-pp_map.c backend/plustek-pp_misc.c
|
||||
backend/plustek-pp_models.c backend/plustek-pp_motor.c
|
||||
backend/plustek-pp_p12.c backend/plustek-pp_p12ccd.c
|
||||
backend/plustek-pp_p48xx.c backend/plustek-pp_p9636.c
|
||||
backend/plustek-pp_procfs.c backend/plustek-pp_procs.h
|
||||
backend/plustek-pp_ptdrv.c backend/plustek-pp_scale.c
|
||||
backend/plustek-pp_scan.h backend/plustek-pp_scandata.h
|
||||
backend/plustek-pp_sysdep.h backend/plustek-pp_tpa.c
|
||||
backend/plustek-pp_types.h backend/plustek-pp_wrapper.c :
|
||||
new added, contains all the code necessary for controlling various Plustek
|
||||
ASIC 9600x/9800x based parallelport scanner
|
||||
|
||||
2003-09-21 Henning Meier-Geinitz <henning@meier-geinitz.de>
|
||||
|
||||
* tools/sane-desc.c: PATH_MAX is too small for long comments on
|
||||
|
|
|
@ -119,9 +119,17 @@ DISTFILES = abaton.c abaton.conf abaton.h agfafocus.c agfafocus.conf \
|
|||
mustek_usb.h mustek_usb_high.c mustek_usb_high.h mustek_usb_low.c \
|
||||
mustek_usb_low.h mustek_usb_mid.c mustek_usb_mid.h nec.c nec.conf nec.h \
|
||||
net.c net.conf net.h pie.c pie.conf pie-scsidef.h pint.c pint.h plustek.c \
|
||||
plustek.conf plustek-devs.c plustek.h plustek-pp.c plustek-share.h \
|
||||
plustek.conf plustek-usbdevs.c plustek.h plustek-share.h \
|
||||
plustek-usb.c plustek-usb.h plustek-usbhw.c plustek-usbimg.c \
|
||||
plustek-usbio.c plustek-usbmap.c plustek-usbscan.c plustek-usbshading.c \
|
||||
plustek-usbcalfile.c plustek-usbcal.c \
|
||||
plustek-pp_dac.c plustek-pp_dbg.h plustek-pp_detect.c plustek-pp_genericio.c \
|
||||
plustek-pp_hwdefs.h plustek-pp_image.c plustek-pp_io.c plustek-pp_map.c \
|
||||
plustek-pp_misc.c plustek-pp_models.c plustek-pp_motor.c plustek-pp_p12.c \
|
||||
plustek-pp_p12ccd.c plustek-pp_p48xx.c plustek-pp_p9636.c plustek-pp_procfs.c \
|
||||
plustek-pp_procs.h plustek-pp_ptdrv.c plustek-pp_scale.c plustek-pp_scan.h \
|
||||
plustek-pp_scandata.h plustek-pp_sysdep.h plustek-pp_tpa.c plustek-pp_types.h \
|
||||
plustek_pp.c plustek-pp_wrapper.c plustek_pp.conf plustek-pp.h \
|
||||
pnm.c qcam.c qcam.conf qcam.h ricoh.c ricoh.conf ricoh.h \
|
||||
ricoh-scsi.c s9036.c s9036.conf s9036.h saned.conf sane_strstatus.c \
|
||||
sceptre.c sceptre.conf sceptre.h sharp.c sharp.conf sharp.h sm3600.c \
|
||||
|
@ -349,6 +357,7 @@ libsane-pint.la: ../sanei/sanei_constrain_value.lo
|
|||
libsane-plustek.la: ../sanei/sanei_constrain_value.lo
|
||||
libsane-plustek.la: ../sanei/sanei_usb.lo
|
||||
libsane-plustek.la: ../sanei/sanei_lm983x.lo
|
||||
libsane-plustekpp.la: ../sanei/sanei_constrain_value.lo
|
||||
libsane-pnm.la: ../sanei/sanei_constrain_value.lo
|
||||
libsane-qcam.la: ../sanei/sanei_constrain_value.lo
|
||||
libsane-ricoh.la: ../sanei/sanei_config2.lo
|
||||
|
|
|
@ -37,6 +37,7 @@ nec
|
|||
pie
|
||||
pint
|
||||
plustek
|
||||
#plustek_pp
|
||||
#pnm
|
||||
qcam
|
||||
ricoh
|
||||
|
|
|
@ -0,0 +1,379 @@
|
|||
/*.............................................................................
|
||||
* Project : SANE library for Plustek flatbed scanners.
|
||||
*.............................................................................
|
||||
*/
|
||||
|
||||
/** @file plustek-pp.h
|
||||
* @brief Definitions for the backend.
|
||||
*
|
||||
* Based on Kazuhiro Sasayama previous
|
||||
* Work on plustek.[ch] file from the SANE package.<br>
|
||||
*
|
||||
* original code taken from sane-0.71<br>
|
||||
* Copyright (C) 1997 Hypercore Software Design, Ltd.<br>
|
||||
* Copyright (C) 2001-2003 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
*
|
||||
* History:
|
||||
* - 0.01 - initial version
|
||||
* .
|
||||
* <hr>
|
||||
* 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.
|
||||
* <hr>
|
||||
*/
|
||||
#ifndef __PLUSTEKPP_H__
|
||||
#define __PLUSTEKPP_H__
|
||||
|
||||
/************************ some definitions ***********************************/
|
||||
|
||||
#define MM_PER_INCH 25.4
|
||||
|
||||
#define PLUSTEK_CONFIG_FILE "plustek_pp.conf"
|
||||
|
||||
#ifndef PATH_MAX
|
||||
# define PATH_MAX 1024
|
||||
#endif
|
||||
|
||||
/*
|
||||
* the default image size
|
||||
*/
|
||||
#define _DEFAULT_TLX 0 /* 0..216 mm */
|
||||
#define _DEFAULT_TLY 0 /* 0..297 mm */
|
||||
#define _DEFAULT_BRX 126 /* 0..216 mm*/
|
||||
#define _DEFAULT_BRY 76.21 /* 0..297 mm */
|
||||
|
||||
#define _DEFAULT_TP_TLX 3.5 /* 0..42.3 mm */
|
||||
#define _DEFAULT_TP_TLY 10.5 /* 0..43.1 mm */
|
||||
#define _DEFAULT_TP_BRX 38.5 /* 0..42.3 mm */
|
||||
#define _DEFAULT_TP_BRY 33.5 /* 0..43.1 mm */
|
||||
|
||||
#define _DEFAULT_NEG_TLX 1.5 /* 0..38.9 mm */
|
||||
#define _DEFAULT_NEG_TLY 1.5 /* 0..29.6 mm */
|
||||
#define _DEFAULT_NEG_BRX 37.5 /* 0..38.9 mm */
|
||||
#define _DEFAULT_NEG_BRY 25.5 /* 0..29.6 mm */
|
||||
|
||||
/*
|
||||
* image sizes for normal, transparent and negative modes
|
||||
*/
|
||||
#define _NORMAL_X 216.0
|
||||
#define _NORMAL_Y 297.0
|
||||
#define _TP_X ((double)_TPAPageWidth/300.0 * MM_PER_INCH)
|
||||
#define _TP_Y ((double)_TPAPageHeight/300.0 * MM_PER_INCH)
|
||||
#define _NEG_X ((double)_NegativePageWidth/300.0 * MM_PER_INCH)
|
||||
#define _NEG_Y ((double)_NegativePageHeight/300.0 * MM_PER_INCH)
|
||||
|
||||
#define _MAX_ID_LEN 20
|
||||
|
||||
/******************** from former plustek-share.h ***************************/
|
||||
|
||||
/*
|
||||
* for other OS than Linux, we might have to define the _IO macros
|
||||
*/
|
||||
#ifndef _IOC
|
||||
#define _IOC(dir,type,nr,size) \
|
||||
(((dir) << 30) | \
|
||||
((type) << 8) | \
|
||||
((nr) << 0) | \
|
||||
((size) << 16))
|
||||
#endif
|
||||
|
||||
#ifndef _IO
|
||||
#define _IO(type,nr) _IOC(0U,(type),(nr),0)
|
||||
#endif
|
||||
|
||||
#ifndef _IOR
|
||||
#define _IOR(type,nr,size) _IOC(2U,(type),(nr),sizeof(size))
|
||||
#endif
|
||||
|
||||
#ifndef _IOW
|
||||
#define _IOW(type,nr,size) _IOC(1U,(type),(nr),sizeof(size))
|
||||
#endif
|
||||
|
||||
#ifndef _IOWR
|
||||
#define _IOWR(type,nr,size) _IOC(3U,(type),(nr),sizeof(size))
|
||||
#endif
|
||||
|
||||
/*.............................................................................
|
||||
* the ioctl interface
|
||||
*/
|
||||
#define _PTDRV_OPEN_DEVICE _IOW('x', 1, unsigned short)/* open */
|
||||
#define _PTDRV_GET_CAPABILITIES _IOR('x', 2, ScannerCaps) /* get caps */
|
||||
#define _PTDRV_GET_LENSINFO _IOR('x', 3, LensInfo) /* get lenscaps */
|
||||
#define _PTDRV_PUT_IMAGEINFO _IOW('x', 4, ImgDef) /* put image info*/
|
||||
#define _PTDRV_GET_CROPINFO _IOR('x', 5, CropInfo) /* get crop */
|
||||
#define _PTDRV_SET_ENV _IOWR('x',6, ScanInfo) /* set env. */
|
||||
#define _PTDRV_START_SCAN _IOR('x', 7, StartScan) /* start scan */
|
||||
#define _PTDRV_STOP_SCAN _IOWR('x', 8, int) /* stop scan */
|
||||
#define _PTDRV_CLOSE_DEVICE _IO('x', 9) /* close */
|
||||
#define _PTDRV_ACTION_BUTTON _IOR('x', 10, int) /* rd act. button*/
|
||||
#define _PTDRV_ADJUST _IOR('x', 11, AdjDef) /* adjust driver */
|
||||
#define _PTDRV_SETMAP _IOR('x', 12, MapDef) /* download gamma*/
|
||||
|
||||
/*
|
||||
* this version MUST match the one inside the driver to make sure, that
|
||||
* both sides use the same structures. This version changes each time
|
||||
* the ioctl interface changes
|
||||
*/
|
||||
#define _PTDRV_COMPAT_IOCTL_VERSION 0x0102
|
||||
#define _PTDRV_IOCTL_VERSION 0x0103
|
||||
|
||||
|
||||
/* NOTE: needs to be kept in sync with table below */
|
||||
#define MODELSTR static char *ModelStr[] = { \
|
||||
"unknown", \
|
||||
"Primax 4800", \
|
||||
"Primax 4800 Direct", \
|
||||
"Primax 4800 Direct 30Bit", \
|
||||
"Primax 9600 Direct 30Bit", \
|
||||
"4800P", \
|
||||
"4830P", \
|
||||
"600P/6000P", \
|
||||
"4831P", \
|
||||
"9630P", \
|
||||
"9630PL", \
|
||||
"9636P", \
|
||||
"A3I", \
|
||||
"12000P/96000P", \
|
||||
"9636P+/Turbo", \
|
||||
"9636T/12000T", \
|
||||
"P8", \
|
||||
"P12", \
|
||||
"PT12", \
|
||||
"Genius Colorpage Vivid III V2", \
|
||||
"USB-Device" \
|
||||
}
|
||||
|
||||
/* the models */
|
||||
#define MODEL_OP_UNKNOWN 0 /* unknown */
|
||||
#define MODEL_PMX_4800 1 /* Primax Colorado 4800 like OP 4800 */
|
||||
#define MODEL_PMX_4800D 2 /* Primax Compact 4800 Direct, OP 600 R->G, G->R */
|
||||
#define MODEL_PMX_4800D3 3 /* Primax Compact 4800 Direct 30 */
|
||||
#define MODEL_PMX_9600D3 4 /* Primax Compact 9600 Direct 30 */
|
||||
#define MODEL_OP_4800P 5 /* 32k, 96001 ASIC, 24 bit, 300x600, 8.5x11.69 */
|
||||
#define MODEL_OP_4830P 6 /* 32k, 96003 ASIC, 30 bit, 300x600, 8.5x11.69 */
|
||||
#define MODEL_OP_600P 7 /* 32k, 96003 ASIC, 30 bit, 300x600, 8.5x11.69 */
|
||||
#define MODEL_OP_4831P 8 /* 128k, 96003 ASIC, 30 bit, 300x600, 8.5x11.69 */
|
||||
#define MODEL_OP_9630P 9 /* 128k, 96003 ASIC, 30 bit, 600x1200, 8.5x11.69 */
|
||||
#define MODEL_OP_9630PL 10 /* 128k, 96003 ASIC, 30 bit, 600x1200, 8.5x14 */
|
||||
#define MODEL_OP_9636P 11 /* 512k, 98001 ASIC, 36 bit, 600x1200, 8.5x11.69 */
|
||||
#define MODEL_OP_A3I 12 /* 128k, 96003 ASIC, 30 bit, 400x800, 11.69x17 */
|
||||
#define MODEL_OP_12000P 13 /* 128k, 96003 ASIC, 30 bit, 600x1200, 8.5x11.69 */
|
||||
#define MODEL_OP_9636PP 14 /* 512k, 98001 ASIC, 36 bit, 600x1200, 8.5x11.69 */
|
||||
#define MODEL_OP_9636T 15 /* like OP_9636PP + transparency */
|
||||
#define MODEL_OP_P8 16 /* 512k, 98003 ASIC, 36 bit, 300x600, 8.5x11.69 */
|
||||
#define MODEL_OP_P12 17 /* 512k, 98003 ASIC, 36 bit, 600x1200, 8.5x11.69 */
|
||||
#define MODEL_OP_PT12 18 /* like OP_P12 + transparency */
|
||||
#define MODEL_GEN_CPV2 19 /* Genius Colorpage Vivid III V2, ASIC 98003 */
|
||||
#define MODEL_UNKNOWN 20 /* not known/supported */
|
||||
|
||||
#define _NO_BASE 0xFFFF
|
||||
|
||||
/************************ some structures ************************************/
|
||||
|
||||
enum {
|
||||
OPT_NUM_OPTS = 0,
|
||||
OPT_MODE_GROUP,
|
||||
OPT_MODE,
|
||||
OPT_EXT_MODE,
|
||||
OPT_RESOLUTION,
|
||||
OPT_PREVIEW,
|
||||
OPT_GEOMETRY_GROUP,
|
||||
OPT_TL_X,
|
||||
OPT_TL_Y,
|
||||
OPT_BR_X,
|
||||
OPT_BR_Y,
|
||||
OPT_ENHANCEMENT_GROUP,
|
||||
OPT_HALFTONE,
|
||||
OPT_BRIGHTNESS,
|
||||
OPT_CONTRAST,
|
||||
OPT_CUSTOM_GAMMA,
|
||||
OPT_GAMMA_VECTOR,
|
||||
OPT_GAMMA_VECTOR_R,
|
||||
OPT_GAMMA_VECTOR_G,
|
||||
OPT_GAMMA_VECTOR_B,
|
||||
NUM_OPTIONS
|
||||
};
|
||||
|
||||
/** for compatiblity to version 0x0102 drivers
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
int lampOff;
|
||||
int lampOffOnEnd;
|
||||
int warmup;
|
||||
|
||||
OffsDef pos; /* for adjusting normal scan area */
|
||||
OffsDef tpa; /* for adjusting transparency scan area */
|
||||
OffsDef neg; /* for adjusting negative scan area */
|
||||
|
||||
} CompatAdjDef, *pCompatAdjDef;
|
||||
|
||||
/** for adjusting the parport stuff
|
||||
*/
|
||||
typedef struct {
|
||||
int lampOff;
|
||||
int lampOffOnEnd;
|
||||
int warmup;
|
||||
int enableTpa;
|
||||
|
||||
OffsDef pos; /* for adjusting normal scan area */
|
||||
OffsDef tpa; /* for adjusting transparency scan area */
|
||||
OffsDef neg; /* for adjusting negative scan area */
|
||||
|
||||
/* for adjusting the default gamma settings */
|
||||
double rgamma;
|
||||
double ggamma;
|
||||
double bgamma;
|
||||
|
||||
double graygamma;
|
||||
|
||||
} PPAdjDef, *pPPAdjDef;
|
||||
|
||||
/** for adjusting the scanner settings
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
int direct_io;
|
||||
int mov;
|
||||
|
||||
int lampOff;
|
||||
int lampOffOnEnd;
|
||||
int warmup;
|
||||
|
||||
OffsDef pos; /* for adjusting normal scan area */
|
||||
OffsDef tpa; /* for adjusting transparency scan area */
|
||||
OffsDef neg; /* for adjusting negative scan area */
|
||||
|
||||
/* for adjusting the default gamma settings */
|
||||
double rgamma;
|
||||
double ggamma;
|
||||
double bgamma;
|
||||
|
||||
double graygamma;
|
||||
|
||||
} AdjDef, *pAdjDef;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
typedef struct Plustek_Device
|
||||
{
|
||||
SANE_Int initialized; /* device already initialized? */
|
||||
struct Plustek_Device *next; /* pointer to next dev in list */
|
||||
int fd; /* device handle */
|
||||
char *name; /* (to avoid compiler warnings!)*/
|
||||
SANE_Device sane; /* info struct */
|
||||
SANE_Int max_x; /* max XY-extension of the scan-*/
|
||||
SANE_Int max_y; /* area */
|
||||
SANE_Range dpi_range; /* resolution range */
|
||||
SANE_Range x_range; /* x-range of the scan-area */
|
||||
SANE_Range y_range; /* y-range of the scan-area */
|
||||
SANE_Int *res_list; /* to hold the available phys. */
|
||||
SANE_Int res_list_size; /* resolution values */
|
||||
ScannerCaps caps; /* caps reported by the driver */
|
||||
AdjDef adj; /* for driver adjustment */
|
||||
|
||||
/*
|
||||
* each device we support may need other access functions...
|
||||
*/
|
||||
int (*open) ( const char*, void* );
|
||||
int (*close) ( struct Plustek_Device* );
|
||||
void (*shutdown) ( struct Plustek_Device* );
|
||||
int (*getCaps) ( struct Plustek_Device* );
|
||||
int (*getLensInfo)( struct Plustek_Device*, pLensInfo );
|
||||
int (*getCropInfo)( struct Plustek_Device*, pCropInfo );
|
||||
int (*putImgInfo) ( struct Plustek_Device*, pImgDef );
|
||||
int (*setScanEnv) ( struct Plustek_Device*, pScanInfo );
|
||||
int (*setMap) ( struct Plustek_Device*, SANE_Word*,
|
||||
SANE_Word, SANE_Word );
|
||||
int (*startScan) ( struct Plustek_Device*, pStartScan );
|
||||
int (*stopScan) ( struct Plustek_Device*, int* );
|
||||
int (*readImage) ( struct Plustek_Device*, SANE_Byte*, unsigned long );
|
||||
|
||||
int (*prepare) ( struct Plustek_Device*, SANE_Byte* );
|
||||
int (*readLine) ( struct Plustek_Device* );
|
||||
|
||||
} Plustek_Device, *pPlustek_Device;
|
||||
|
||||
#ifndef SANE_OPTION
|
||||
/* for compatibility with older versions */
|
||||
typedef union
|
||||
{
|
||||
SANE_Word w;
|
||||
SANE_Word *wa; /* word array */
|
||||
SANE_String s;
|
||||
} Option_Value;
|
||||
#endif
|
||||
|
||||
typedef struct Plustek_Scanner
|
||||
{
|
||||
struct Plustek_Scanner *next;
|
||||
pid_t reader_pid; /* process id of reader */
|
||||
SANE_Status exit_code; /* status of the reader process */
|
||||
int pipe; /* pipe to reader process */
|
||||
unsigned long bytes_read; /* number of bytes currently read*/
|
||||
Plustek_Device *hw; /* pointer to current device */
|
||||
Option_Value val[NUM_OPTIONS];
|
||||
SANE_Byte *buf; /* the image buffer */
|
||||
SANE_Bool scanning; /* TRUE during scan-process */
|
||||
SANE_Parameters params; /* for keeping the parameter */
|
||||
|
||||
/************************** gamma tables *********************************/
|
||||
|
||||
SANE_Word gamma_table[4][4096];
|
||||
SANE_Range gamma_range;
|
||||
int gamma_length;
|
||||
|
||||
SANE_Option_Descriptor opt[NUM_OPTIONS];
|
||||
|
||||
} Plustek_Scanner, *pPlustek_Scanner;
|
||||
|
||||
/** for collecting configuration info...
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
char devName[PATH_MAX];
|
||||
|
||||
/* contains the stuff to adjust... */
|
||||
AdjDef adj;
|
||||
|
||||
} CnfDef, *pCnfDef;
|
||||
|
||||
#endif /* guard __PLUSTEKPP_H__ */
|
||||
|
||||
/* END PLUSTEK-PP.H .........................................................*/
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,79 @@
|
|||
/*.............................................................................
|
||||
* Project : linux driver for Plustek parallel-port scanners
|
||||
*.............................................................................
|
||||
* File: plustek-pp_dbg.h - definition of some debug macros
|
||||
*.............................................................................
|
||||
*
|
||||
* Copyright (C) 2000-2003 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
*
|
||||
*.............................................................................
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef __DEBUG_H__
|
||||
#define __DEBUG_H__
|
||||
|
||||
/* uncomment this to have an SW-simulatet 98001 device - don't expect to scan*/
|
||||
/* #define _ASIC_98001_SIM */
|
||||
|
||||
/*
|
||||
* the print macros
|
||||
*/
|
||||
#ifdef __KERNEL__
|
||||
# define _PRINT printk
|
||||
#endif
|
||||
|
||||
/*
|
||||
* some debug definitions
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
# ifndef __KERNEL__
|
||||
# include <assert.h>
|
||||
# define _ASSERT(x) assert(x)
|
||||
# endif
|
||||
|
||||
# ifndef DBG
|
||||
# define DBG(level, msg, args...) if ((dbg_level) & (level)) { \
|
||||
_PRINT(msg, ##args); \
|
||||
}
|
||||
# endif
|
||||
#else
|
||||
# define _ASSERT(x)
|
||||
# ifndef DBG
|
||||
# define DBG(level, msg, args...)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* different debug level */
|
||||
#define DBG_LOW 0x01
|
||||
#define DBG_MEDIUM 0x02
|
||||
#define DBG_HIGH 0x04
|
||||
#define DBG_HELPERS 0x08
|
||||
#define DBG_TIMEOUT 0x10
|
||||
#define DBG_SCAN 0x20
|
||||
#define DBG_IO 0x40
|
||||
#define DBG_IOF 0x80
|
||||
#define DBG_ALL 0xFF
|
||||
|
||||
/*
|
||||
* standard debug level
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
static int dbg_level=(DBG_ALL & ~(DBG_IO | DBG_IOF));
|
||||
#endif
|
||||
|
||||
#endif /* guard __DEBUG_H__ */
|
||||
|
||||
/* END PLUSTEK-PP_DBG.H .....................................................*/
|
|
@ -0,0 +1,508 @@
|
|||
/*.............................................................................
|
||||
* Project : linux driver for Plustek parallel-port scanners
|
||||
*.............................................................................
|
||||
* File: plustek-pp_detect.c - automatic scanner detection
|
||||
*.............................................................................
|
||||
*
|
||||
* based on sources acquired from Plustek Inc.
|
||||
* Copyright (C) 1998 Plustek Inc.
|
||||
* Copyright (C) 2000-2003 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
* also based on the work done by Rick Bronson
|
||||
*.............................................................................
|
||||
* History:
|
||||
* 0.30 - initial version
|
||||
* 0.31 - no changes
|
||||
* 0.32 - no changes
|
||||
* 0.33 - added portmode check
|
||||
* 0.34 - no changes
|
||||
* 0.35 - no changes
|
||||
* 0.36 - added some debug messages
|
||||
* replace the old _OUTB/_INB macros
|
||||
* 0.37 - cosmetic changes
|
||||
* added speed-test for the parallel-port
|
||||
* 0.38 - added P12 stuff - replaced detectP9636 by detectAsic9800x
|
||||
* added detectResetPort() function
|
||||
* 0.39 - fixed problem in ASIC9800x detection
|
||||
* 0.40 - no changes
|
||||
* 0.41 - no changes
|
||||
* 0.42 - changed include names
|
||||
*
|
||||
*.............................................................................
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include "plustek-pp_scan.h"
|
||||
|
||||
/************************** local definitions ********************************/
|
||||
|
||||
/*************************** local functions *********************************/
|
||||
|
||||
/*.............................................................................
|
||||
* as the name says...
|
||||
*/
|
||||
static void detectResetPort( pScanData ps )
|
||||
{
|
||||
UChar control;
|
||||
|
||||
control = _INB_CTRL( ps );
|
||||
_DO_UDELAY( 2 );
|
||||
|
||||
_OUTB_CTRL( ps, _CTRL_RESERVED ); /* reset, 0xc0 */
|
||||
_DO_UDELAY( 2 );
|
||||
|
||||
_OUTB_CTRL( ps, control ); /* and restore... */
|
||||
_DO_UDELAY( 2 );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* Check will the status port changed between printer/scanner path changed?
|
||||
* Write out data and read in to compare
|
||||
*/
|
||||
static int detectScannerConnection( pScanData ps )
|
||||
{
|
||||
UChar data, control, status;
|
||||
int retval = _E_NO_CONN;
|
||||
|
||||
DBG( DBG_LOW, "Dataport = 0x%04x\n", ps->IO.pbSppDataPort );
|
||||
DBG( DBG_LOW, "Ctrlport = 0x%04x\n", ps->IO.pbControlPort );
|
||||
|
||||
detectResetPort( ps );
|
||||
|
||||
/*
|
||||
* as we´re called during InitPorts, we can be sure
|
||||
* to operate in EPP-mode (hopefuly ;-)
|
||||
*/
|
||||
control = _INB_CTRL( ps );
|
||||
|
||||
/*
|
||||
* go ahead and do some checks
|
||||
*/
|
||||
_OUTB_CTRL( ps, _CTRL_GENSIGNAL );
|
||||
_DO_UDELAY( 5 );
|
||||
|
||||
_OUTB_DATA( ps, 0x55 );
|
||||
_DO_UDELAY( 5 );
|
||||
|
||||
data = _INB_DATA( ps );
|
||||
|
||||
if (0x55 == data) {
|
||||
|
||||
DBG( DBG_HIGH, "Test 0x55\n" );
|
||||
|
||||
_OUTB_DATA( ps, 0xAA );
|
||||
_DO_UDELAY( 5 );
|
||||
|
||||
data = _INB_DATA( ps );
|
||||
|
||||
if (0xAA == data) {
|
||||
|
||||
DBG( DBG_HIGH, "Test 0xAA\n" );
|
||||
|
||||
_OUTB_DATA( ps, 0x0 );
|
||||
_DO_UDELAY( 5 );
|
||||
|
||||
data = _INB_STATUS( ps );
|
||||
|
||||
ps->OpenScanPath( ps );
|
||||
|
||||
_OUTB_DATA( ps, 0x0 );
|
||||
_DO_UDELAY( 5 );
|
||||
|
||||
status = _INB_STATUS( ps );
|
||||
|
||||
ps->CloseScanPath( ps );
|
||||
|
||||
/*
|
||||
* so we´re done ´til now...
|
||||
*/
|
||||
DBG( DBG_HIGH, "Compare data=0x%x and status=0x%x, port=0x%x\n",
|
||||
data, status, ps->IO.portBase );
|
||||
|
||||
if( data != status ) {
|
||||
_ASSERT( ps->ReadWriteTest );
|
||||
|
||||
/*
|
||||
* here we try to detect the operation speed of our
|
||||
* parallel port
|
||||
* if we have tested all the stuff and had no success, retval
|
||||
* will contain the error-code
|
||||
*/
|
||||
for( ps->IO.delay = 0; ps->IO.delay < 5; ps->IO.delay++ ) {
|
||||
|
||||
retval = ps->ReadWriteTest( ps );
|
||||
|
||||
/* break on OK or when the ASIC detection fails */
|
||||
if((_OK == retval) || (_E_NO_ASIC == retval))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* work on the result
|
||||
*/
|
||||
if ( _OK == retval ) {
|
||||
ps->sCaps.wIOBase = ps->IO.pbSppDataPort;
|
||||
ps->PutToIdleMode( ps );
|
||||
|
||||
} else {
|
||||
ps->sCaps.wIOBase = _NO_BASE;
|
||||
}
|
||||
|
||||
/*
|
||||
* restore control port value
|
||||
*/
|
||||
_OUTB_CTRL( ps, control );
|
||||
_DO_UDELAY( 5 );
|
||||
|
||||
DBG( DBG_HIGH, "detectScannerConnection() returns %i.\n", retval );
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*.............................................................................
|
||||
* we need some memory...
|
||||
*/
|
||||
static int detectSetupBuffers( pScanData ps )
|
||||
{
|
||||
DBG( DBG_LOW, "*** setupBuffers ***\n" );
|
||||
|
||||
/*
|
||||
* bad news ?
|
||||
*/
|
||||
if ( 0 == ps->TotalBufferRequire ) {
|
||||
|
||||
#ifdef __KERNEL__
|
||||
_PRINT(
|
||||
#else
|
||||
DBG( DBG_HIGH,
|
||||
#endif
|
||||
"pt_drv: asic 0x%x probably not supported\n", ps->sCaps.AsicID);
|
||||
|
||||
return _E_ALLOC; /* Out of memory */
|
||||
|
||||
} else {
|
||||
|
||||
/*
|
||||
* allocate and clear
|
||||
*/
|
||||
DBG(DBG_LOW,"Driverbuf(%lu bytes) needed !\n", ps->TotalBufferRequire);
|
||||
ps->driverbuf = (pUChar)_VMALLOC(ps->TotalBufferRequire);
|
||||
|
||||
if ( NULL == ps->driverbuf ) {
|
||||
|
||||
#ifdef __KERNEL__
|
||||
_PRINT(
|
||||
#else
|
||||
DBG( DBG_HIGH,
|
||||
#endif
|
||||
"pt_drv: Not enough kernel memory %ld\n",
|
||||
ps->TotalBufferRequire);
|
||||
return _E_ALLOC; /* Out of memory */
|
||||
}
|
||||
|
||||
memset( ps->driverbuf, 0, ps->TotalBufferRequire );
|
||||
}
|
||||
|
||||
ps->pPrescan16 = ps->driverbuf;
|
||||
ps->pPrescan8 = ps->pPrescan16 + ps->BufferFor1stColor;
|
||||
ps->pScanBuffer1 = ps->pPrescan8 + ps->BufferFor2ndColor;
|
||||
|
||||
/* CHECK: Should we adjust that !!!
|
||||
*/
|
||||
ps->pEndBufR = ps->pPrescan8;
|
||||
ps->pEndBufG = ps->pScanBuffer1;
|
||||
ps->pColorRunTable = ps->pScanBuffer1 + ps->BufferForDataRead1;
|
||||
|
||||
DBG( DBG_LOW, "pColorRunTab = 0x%0lx - 0x%0lx\n",
|
||||
(ULong)ps->pColorRunTable,
|
||||
(ULong)((pUChar)ps->driverbuf + ps->TotalBufferRequire));
|
||||
|
||||
if ( _ASIC_IS_98001 == ps->sCaps.AsicID ) {
|
||||
|
||||
DBG( DBG_LOW, "Adjust for 98001 ASIC\n" );
|
||||
|
||||
ps->pScanBuffer2 = ps->pPrescan16;
|
||||
ps->pScanBuffer1 = ps->pScanBuffer2 + _LINE_BUFSIZE1;
|
||||
ps->pColorRunTable = ps->pScanBuffer1 + _LINE_BUFSIZE * 2UL;
|
||||
ps->pProcessingBuf = ps->pColorRunTable + ps->BufferForColorRunTable;
|
||||
DBG( DBG_LOW, "sb2 = 0x%lx, sb1 = 0x%lx, Color = 0x%lx\n",
|
||||
(ULong)ps->pScanBuffer2, (ULong)ps->pScanBuffer1,
|
||||
(ULong)ps->pColorRunTable );
|
||||
DBG( DBG_LOW, "Pro = 0x%lx, size = %ld\n",
|
||||
(ULong)ps->pProcessingBuf, ps->TotalBufferRequire );
|
||||
|
||||
ps->dwShadow = (_DEF_BRIGHTEST_SKIP + _DEF_DARKEST_SKIP) * 5400UL * 2UL * 3UL;
|
||||
|
||||
ps->Shade.pHilight = _VMALLOC( ps->dwShadow );
|
||||
|
||||
if ( NULL != ps->Shade.pHilight ) {
|
||||
|
||||
memset( ps->Shade.pHilight, 0, ps->dwShadow );
|
||||
|
||||
ps->dwHilight = _DEF_BRIGHTEST_SKIP * 5400UL * 3UL;
|
||||
ps->dwShadow = _DEF_DARKEST_SKIP * 5400UL * 3UL;
|
||||
ps->pwShadow = (pUShort)ps->Shade.pHilight + ps->dwHilight;
|
||||
ps->Shade.dwDiv = 32UL - _DEF_BRIGHTEST_SKIP - _DEF_DARKEST_SKIP;
|
||||
|
||||
ps->dwHilightCh = ps->dwHilight / 3UL;
|
||||
ps->dwShadowCh = ps->dwShadow / 3UL;
|
||||
}
|
||||
} else if ( _ASIC_IS_98003 == ps->sCaps.AsicID ) {
|
||||
|
||||
DBG( DBG_LOW, "Adjust for 98003 ASIC\n" );
|
||||
|
||||
ps->Bufs.b1.pReadBuf = ps->driverbuf;
|
||||
ps->Bufs.b2.pSumBuf = ps->Bufs.b1.pReadBuf + _SizeDataBuf;
|
||||
ps->Bufs.TpaBuf.pb = &((pUChar)ps->Bufs.b2.pSumBuf)[_SizeShadingSumBuf];
|
||||
|
||||
/* CHECK: We might should play around with these values... */
|
||||
ps->Shade.skipHilight = _DEF_BRIGHTEST_SKIP;
|
||||
ps->Shade.skipShadow = _DEF_DARKEST_SKIP;
|
||||
|
||||
if( ps->Shade.skipHilight && ps->Shade.skipShadow ) {
|
||||
|
||||
ULong skipSize;
|
||||
|
||||
skipSize = (ULong)((ps->Shade.skipHilight + ps->Shade.skipShadow)
|
||||
* _SizeDataBuf * 3);
|
||||
|
||||
ps->Shade.pHilight = _VMALLOC( skipSize );
|
||||
|
||||
if( NULL != ps->Shade.pHilight ) {
|
||||
ps->Shade.dwDiv = (ULong)(32UL - ps->Shade.skipHilight -
|
||||
ps->Shade.skipShadow);
|
||||
}
|
||||
} else
|
||||
ps->Shade.pHilight = NULL;
|
||||
}
|
||||
|
||||
return _OK;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* model 48xx detection or any other model using the 96001/3 ASIC
|
||||
*/
|
||||
static int detectP48xx( pScanData ps )
|
||||
{
|
||||
int result;
|
||||
|
||||
DBG( DBG_LOW, "************ DETECTP48xx ************\n" );
|
||||
|
||||
/* increase the delay-time */
|
||||
ps->IO.delay = 4;
|
||||
|
||||
ModelSet4800( ps );
|
||||
|
||||
result = P48xxInitAsic( ps );
|
||||
if( _OK != result )
|
||||
return result;
|
||||
|
||||
return detectScannerConnection( ps );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* ASIC 98003 model detection
|
||||
*/
|
||||
static int detectAsic98003( pScanData ps )
|
||||
{
|
||||
int result;
|
||||
|
||||
DBG( DBG_LOW, "************* ASIC98003 *************\n" );
|
||||
|
||||
/* increase the delay-time */
|
||||
ps->IO.delay = 4;
|
||||
|
||||
ModelSetP12( ps );
|
||||
|
||||
result = P12InitAsic( ps );
|
||||
if( _OK != result )
|
||||
return result;
|
||||
|
||||
IOSoftwareReset( ps );
|
||||
|
||||
return detectScannerConnection( ps );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* ASIC 98001 model detection
|
||||
*/
|
||||
static int detectAsic98001( pScanData ps )
|
||||
{
|
||||
int result;
|
||||
|
||||
DBG( DBG_LOW, "************* ASIC98001 *************\n" );
|
||||
|
||||
/* increase the delay-time */
|
||||
ps->IO.delay = 4;
|
||||
|
||||
ModelSet9636( ps );
|
||||
|
||||
result = P9636InitAsic( ps );
|
||||
#ifndef _ASIC_98001_SIM
|
||||
if( _OK != result )
|
||||
return result;
|
||||
|
||||
return detectScannerConnection( ps );
|
||||
#else
|
||||
#ifdef __KERNEL__
|
||||
_PRINT(
|
||||
#else
|
||||
DBG( DBG_HIGH,
|
||||
#endif
|
||||
|
||||
"!!!! WARNING, have a look at function detectAsic98001() !!!!\n" );
|
||||
ps->sCaps.AsicID = _ASIC_IS_98001;
|
||||
ps->sCaps.wIOBase = ps->IO.pbSppDataPort;
|
||||
return _OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
/************************ exported functions *********************************/
|
||||
|
||||
/*.............................................................................
|
||||
* here we try to find the scanner, depending on the mode
|
||||
*/
|
||||
int DetectScanner( pScanData ps, int mode )
|
||||
{
|
||||
Byte asic;
|
||||
int result = _E_INTERNAL;
|
||||
|
||||
/*
|
||||
* before doing anything else, check the port-mode
|
||||
*/
|
||||
if((ps->IO.portMode != _PORT_EPP) && (ps->IO.portMode != _PORT_SPP) &&
|
||||
(ps->IO.portMode != _PORT_BIDI)) {
|
||||
|
||||
DBG( DBG_LOW, "!!! Portmode (%u)not supported !!!\n", ps->IO.portMode );
|
||||
return _E_INTERNAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* autodetection ?
|
||||
*/
|
||||
if( 0 == mode ) {
|
||||
|
||||
DBG( DBG_HIGH, "Starting Scanner-Autodetection\n" );
|
||||
|
||||
/*
|
||||
* try to find a 48xx Scanner
|
||||
* (or even a scanner based on the 96001/3) ASIC
|
||||
*/
|
||||
result = detectP48xx( ps );
|
||||
|
||||
if( _OK != result ) {
|
||||
|
||||
DBG( DBG_LOW, "************* ASIC9800x *************\n" );
|
||||
|
||||
/*
|
||||
* get the ASIC ID by using the OpenScanPath stuff from Asic9600x based
|
||||
* models - only difference: change the ReadHigh/ReadLow signals before
|
||||
*/
|
||||
ps->CtrlReadHighNibble = _CTRL_GENSIGNAL+_CTRL_AUTOLF+_CTRL_STROBE;
|
||||
ps->CtrlReadLowNibble = _CTRL_GENSIGNAL+_CTRL_AUTOLF;
|
||||
|
||||
/* read Register 0x18 (AsicID Register) of Asic9800x based devices */
|
||||
#ifdef _ASIC_98001_SIM
|
||||
#ifdef __KERNEL__
|
||||
_PRINT(
|
||||
#else
|
||||
DBG( DBG_HIGH,
|
||||
#endif
|
||||
"!!!! WARNING, SW-Emulation active !!!!\n" );
|
||||
asic = _ASIC_IS_98001;
|
||||
#else
|
||||
detectResetPort( ps );
|
||||
|
||||
/* do some presettings to make IODataRegisterFromScanner() work */
|
||||
ps->RegAsicID = 0x18;
|
||||
ps->IO.useEPPCmdMode = _FALSE;
|
||||
ps->sCaps.AsicID = _ASIC_IS_98001;
|
||||
IOInitialize( ps );
|
||||
|
||||
asic = IODataRegisterFromScanner( ps, ps->RegAsicID );
|
||||
|
||||
DBG( DBG_HIGH, "ASIC = 0x%02X\n", asic );
|
||||
#endif
|
||||
|
||||
/* depending on what we have found, perform some extra tests */
|
||||
switch( asic ) {
|
||||
|
||||
case _ASIC_IS_98001:
|
||||
result = detectAsic98001( ps );
|
||||
break;
|
||||
|
||||
case _ASIC_IS_98003:
|
||||
|
||||
/* as the reading of the ASIC ID causes trouble,
|
||||
* we reset the device
|
||||
*/
|
||||
ps->IO.useEPPCmdMode = _FALSE;
|
||||
ps->sCaps.AsicID = _ASIC_IS_98003;
|
||||
IOInitialize( ps );
|
||||
IOSoftwareReset( ps );
|
||||
|
||||
result = detectAsic98003( ps );
|
||||
break;
|
||||
|
||||
default:
|
||||
DBG( DBG_HIGH, "Unknown ASIC-ID\n" );
|
||||
result = _E_NO_DEV;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* this will be called each time before operating on a previously
|
||||
* detected device, to make sure we're already operating on the same one
|
||||
*/
|
||||
if( _ASIC_IS_98001 == mode ) {
|
||||
|
||||
DBG( DBG_HIGH, "Starting Scanner-detection (ASIC 98001)\n" );
|
||||
result = detectAsic98001( ps );
|
||||
|
||||
} else if( _ASIC_IS_98003 == mode ) {
|
||||
|
||||
DBG( DBG_HIGH, "Starting Scanner-detection (ASIC 98003)\n" );
|
||||
result = detectAsic98003( ps );
|
||||
|
||||
} else {
|
||||
|
||||
DBG( DBG_HIGH, "Starting Scanner-detection (ASIC 96001/3)\n" );
|
||||
result = detectP48xx( ps );
|
||||
}
|
||||
}
|
||||
|
||||
if( _OK == result ) {
|
||||
|
||||
_ASSERT( ps->SetupScannerVariables );
|
||||
ps->SetupScannerVariables( ps );
|
||||
|
||||
detectSetupBuffers( ps );
|
||||
|
||||
} else {
|
||||
/* CHECK - we should not need that anymore - paranoia code ??!!!!
|
||||
*/
|
||||
ps->sCaps.wIOBase = _NO_BASE;
|
||||
}
|
||||
|
||||
DBG( DBG_LOW, "*** DETECTION DONE, result: %i ***\n", result );
|
||||
return result;
|
||||
}
|
||||
|
||||
/* END PLUSTEK-PP_DETECT.C ..................................................*/
|
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,980 @@
|
|||
/*.............................................................................
|
||||
* Project : linux driver for Plustek parallel-port scanners
|
||||
*.............................................................................
|
||||
* File: plustekpp-io.c - as the name says, here we have all the I/O
|
||||
* functions according to the parallel port hardware
|
||||
*.............................................................................
|
||||
*
|
||||
* based on sources acquired from Plustek Inc.
|
||||
* Copyright (C) 1998 Plustek Inc.
|
||||
* Copyright (C) 2000-2003 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
*.............................................................................
|
||||
* History:
|
||||
* 0.37 - initial version
|
||||
* added Kevins' suggestions
|
||||
* 0.38 - added Asic 98003 stuff and ioP98ReadWriteTest()
|
||||
* added IODataRegisterToDAC()
|
||||
* replaced function IOSPPWrite by IOMoveDataToScanner
|
||||
* modified ioP98OpenScanPath again and reuse V0.36 stuff again
|
||||
* added IO functions
|
||||
* 0.39 - added IO functions
|
||||
* added f97003 stuff from A3I code
|
||||
* 0.40 - no changes
|
||||
* 0.41 - no changes
|
||||
* 0.42 - changed include names
|
||||
*
|
||||
*.............................................................................
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include "plustek-pp_scan.h"
|
||||
|
||||
/*************************** some prototypes *********************************/
|
||||
|
||||
static Bool fnEPPRead ( pScanData ps, pUChar pBuffer, ULong ulSize );
|
||||
static Bool fnSPPRead ( pScanData ps, pUChar pBuffer, ULong ulSize );
|
||||
static Bool fnBiDirRead( pScanData ps, pUChar pBuffer, ULong ulSize );
|
||||
|
||||
static pFnReadData ioReadFunc[3] = {
|
||||
fnEPPRead,
|
||||
fnSPPRead,
|
||||
fnBiDirRead
|
||||
};
|
||||
|
||||
/*************************** some definitions ********************************/
|
||||
|
||||
#define _MEMTEST_SIZE 1280
|
||||
|
||||
/*************************** local functions *********************************/
|
||||
|
||||
/*.............................................................................
|
||||
* we provide some functions to read data from SPP port according to
|
||||
* the speed we have detected (ReadWriteTest!!)
|
||||
*/
|
||||
static Byte ioDataFromSPPFast( pScanData ps )
|
||||
{
|
||||
Byte bData, tmp;
|
||||
|
||||
/* notify asic we will read the high nibble data from status port */
|
||||
if( _FALSE == ps->f97003 ) {
|
||||
_OUTB_CTRL( ps, ps->CtrlReadHighNibble );
|
||||
_DO_UDELAY( 1 );
|
||||
}
|
||||
|
||||
/* read high nibble */
|
||||
bData = _INB_STATUS( ps );
|
||||
bData &= 0xf0;
|
||||
|
||||
_OUTB_CTRL( ps, ps->CtrlReadLowNibble );
|
||||
_DO_UDELAY( 1 );
|
||||
|
||||
/* read low nibble */
|
||||
tmp = _INB_STATUS( ps );
|
||||
|
||||
/* combine with low nibble */
|
||||
bData |= (tmp >> 4);
|
||||
|
||||
_OUTB_CTRL( ps, _CTRL_GENSIGNAL );
|
||||
_DO_UDELAY( 1 );
|
||||
|
||||
return bData;
|
||||
}
|
||||
|
||||
static Byte ioDataFromSPPMiddle( pScanData ps )
|
||||
{
|
||||
Byte bData, tmp;
|
||||
|
||||
/* notify asic we will read the high nibble data from status port */
|
||||
if( _FALSE == ps->f97003 ) {
|
||||
_OUTB_CTRL( ps, ps->CtrlReadHighNibble );
|
||||
_DO_UDELAY( 1 );
|
||||
}
|
||||
|
||||
/* read high nibble */
|
||||
_INB_STATUS( ps );
|
||||
bData = _INB_STATUS( ps );
|
||||
bData &= 0xf0;
|
||||
|
||||
_OUTB_CTRL( ps, ps->CtrlReadLowNibble );
|
||||
_DO_UDELAY( 1 );
|
||||
|
||||
/* read low nibble */
|
||||
_INB_STATUS( ps );
|
||||
tmp = _INB_STATUS( ps );
|
||||
|
||||
/* combine with low nibble */
|
||||
bData |= (tmp >> 4);
|
||||
|
||||
_OUTB_CTRL( ps, _CTRL_GENSIGNAL );
|
||||
_DO_UDELAY( 1 );
|
||||
|
||||
return bData;
|
||||
}
|
||||
|
||||
static UChar ioDataFromSPPSlow( pScanData ps )
|
||||
{
|
||||
Byte bData, tmp;
|
||||
|
||||
/* notify asic we will read the high nibble data from status port */
|
||||
if( _FALSE == ps->f97003 ) {
|
||||
_OUTB_CTRL( ps, ps->CtrlReadHighNibble );
|
||||
_DO_UDELAY( 2 );
|
||||
}
|
||||
|
||||
/* read high nibble */
|
||||
_INB_STATUS( ps );
|
||||
_INB_STATUS( ps );
|
||||
bData = _INB_STATUS( ps );
|
||||
bData &= 0xf0;
|
||||
|
||||
_OUTB_CTRL( ps, ps->CtrlReadLowNibble );
|
||||
_DO_UDELAY( 2 );
|
||||
|
||||
/* read low nibble */
|
||||
_INB_STATUS( ps );
|
||||
_INB_STATUS( ps );
|
||||
tmp = _INB_STATUS( ps );
|
||||
|
||||
/* combine with low nibble */
|
||||
bData |= (tmp >> 4);
|
||||
|
||||
_OUTB_CTRL( ps, _CTRL_GENSIGNAL );
|
||||
_DO_UDELAY( 2 );
|
||||
|
||||
return bData;
|
||||
}
|
||||
|
||||
static UChar ioDataFromSPPSlowest( pScanData ps )
|
||||
{
|
||||
Byte bData, tmp;
|
||||
|
||||
/* notify asic we will read the high nibble data from status port */
|
||||
if( _FALSE == ps->f97003 ) {
|
||||
_OUTB_CTRL( ps, ps->CtrlReadHighNibble );
|
||||
_DO_UDELAY( 3 );
|
||||
}
|
||||
|
||||
/* read high nibble */
|
||||
_INB_STATUS( ps );
|
||||
_INB_STATUS( ps );
|
||||
_INB_STATUS( ps );
|
||||
bData = _INB_STATUS( ps );
|
||||
bData &= 0xf0;
|
||||
|
||||
_OUTB_CTRL( ps, ps->CtrlReadLowNibble );
|
||||
_DO_UDELAY( 3 );
|
||||
|
||||
/* read low nibble */
|
||||
_INB_STATUS( ps );
|
||||
_INB_STATUS( ps );
|
||||
_INB_STATUS( ps );
|
||||
tmp = _INB_STATUS( ps );
|
||||
|
||||
/* combine with low nibble */
|
||||
bData |= (tmp >> 4);
|
||||
|
||||
_OUTB_CTRL( ps, _CTRL_GENSIGNAL );
|
||||
_DO_UDELAY( 3 );
|
||||
|
||||
return bData;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* Using buffer I/O to read data from EPP Data Port
|
||||
*/
|
||||
static Bool fnEPPRead( pScanData ps, pUChar pBuffer, ULong ulSize )
|
||||
{
|
||||
register ULong i;
|
||||
|
||||
if( _IS_ASIC98(ps->sCaps.AsicID)) {
|
||||
|
||||
_OUTB_CTRL( ps, (_CTRL_GENSIGNAL + _CTRL_DIRECTION));
|
||||
_DO_UDELAY( 1 );
|
||||
|
||||
for( i = 0; i < ulSize; i++ )
|
||||
pBuffer[i] = _INB_EPPDATA( ps );
|
||||
|
||||
_OUTB_CTRL( ps, _CTRL_GENSIGNAL );
|
||||
_DO_UDELAY( 1 );
|
||||
|
||||
} else {
|
||||
|
||||
for( i = 0; i < ulSize; i++ )
|
||||
pBuffer[i] = _INB_EPPDATA( ps );
|
||||
}
|
||||
|
||||
return _TRUE;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* Read data from STATUS port. We have to read twice and combine two nibble
|
||||
* data to one byte
|
||||
*/
|
||||
static Bool fnSPPRead( pScanData ps, pUChar pBuffer, ULong ulSize )
|
||||
{
|
||||
switch( ps->IO.delay ) {
|
||||
|
||||
case 0:
|
||||
for (; ulSize; ulSize--, pBuffer++)
|
||||
*pBuffer = ioDataFromSPPFast( ps );
|
||||
break;
|
||||
|
||||
case 1:
|
||||
for (; ulSize; ulSize--, pBuffer++)
|
||||
*pBuffer = ioDataFromSPPMiddle( ps );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
for (; ulSize; ulSize--, pBuffer++)
|
||||
*pBuffer = ioDataFromSPPSlow( ps );
|
||||
break;
|
||||
|
||||
default:
|
||||
for (; ulSize; ulSize--, pBuffer++)
|
||||
*pBuffer = ioDataFromSPPSlowest( ps );
|
||||
break;
|
||||
}
|
||||
|
||||
return _TRUE;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
*
|
||||
*/
|
||||
static Bool fnBiDirRead( pScanData ps, pUChar pBuffer, ULong ulSize )
|
||||
{
|
||||
if( _IS_ASIC98(ps->sCaps.AsicID))
|
||||
_OUTB_CTRL( ps, (_CTRL_GENSIGNAL + _CTRL_DIRECTION));
|
||||
|
||||
switch( ps->IO.delay ) {
|
||||
|
||||
case 0:
|
||||
for(; ulSize; ulSize--, pBuffer++ ) {
|
||||
_OUTB_CTRL( ps, _CTRL_SIGNAL_BIDIREAD); /* 0xe6 */
|
||||
*pBuffer = _INB_DATA( ps );
|
||||
_OUTB_CTRL( ps, _CTRL_END_BIDIREAD ); /* 0xe4 */
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
_DO_UDELAY( 1 );
|
||||
for(; ulSize; ulSize--, pBuffer++ ) {
|
||||
_OUTB_CTRL( ps, _CTRL_SIGNAL_BIDIREAD); /* 0xe6 */
|
||||
_DO_UDELAY( 1 );
|
||||
|
||||
*pBuffer = _INB_DATA( ps );
|
||||
|
||||
_OUTB_CTRL( ps, _CTRL_END_BIDIREAD ); /* 0xe4 */
|
||||
_DO_UDELAY( 1 );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
_DO_UDELAY( 2 );
|
||||
for(; ulSize; ulSize--, pBuffer++ ) {
|
||||
_OUTB_CTRL( ps, _CTRL_SIGNAL_BIDIREAD); /* 0xe6 */
|
||||
_DO_UDELAY( 2 );
|
||||
|
||||
*pBuffer = _INB_DATA( ps );
|
||||
|
||||
_OUTB_CTRL( ps, _CTRL_END_BIDIREAD ); /* 0xe4 */
|
||||
_DO_UDELAY( 2 );
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if( _IS_ASIC98(ps->sCaps.AsicID))
|
||||
_OUTB_CTRL( ps, _CTRL_END_DATAREAD ); /* 0xc4 */
|
||||
|
||||
return _TRUE;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* as the name says, we switch to SPP mode
|
||||
*/
|
||||
static void ioSwitchToSPPMode( pScanData ps )
|
||||
{
|
||||
/*
|
||||
* save the control and data port value
|
||||
*/
|
||||
ps->IO.bOldControlValue = _INB_CTRL( ps );
|
||||
ps->IO.bOldDataValue = _INB_DATA( ps );
|
||||
|
||||
_OUTB_CTRL( ps, _CTRL_NORMAL ); /* 0xc4 */
|
||||
_DO_UDELAY( 2 );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* restore the settings
|
||||
*/
|
||||
static void ioRestoreParallelMode( pScanData ps )
|
||||
{
|
||||
_OUTB_CTRL( ps, ps->IO.bOldControlValue & 0x3f );
|
||||
_DO_UDELAY( 1 );
|
||||
|
||||
_OUTB_DATA( ps, ps->IO.bOldDataValue );
|
||||
_DO_UDELAY( 1 );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* try to connect to scanner
|
||||
*/
|
||||
static void ioP98001EstablishScannerConnection( pScanData, ULong );
|
||||
|
||||
|
||||
inline void ioP98001EstablishScannerConnection( pScanData ps, ULong delTime )
|
||||
{
|
||||
_OUTB_DATA( ps, _ID_TO_PRINTER );
|
||||
_DO_UDELAY( delTime );
|
||||
|
||||
_OUTB_DATA( ps, _ID1ST );
|
||||
_DO_UDELAY( delTime );
|
||||
|
||||
_OUTB_DATA( ps, _ID2ND );
|
||||
_DO_UDELAY( delTime );
|
||||
|
||||
_OUTB_DATA( ps, _ID3RD );
|
||||
_DO_UDELAY( delTime );
|
||||
|
||||
_OUTB_DATA( ps, _ID4TH );
|
||||
_DO_UDELAY( delTime );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* switch the printer interface to scanner
|
||||
*/
|
||||
static Bool ioP96OpenScanPath( pScanData ps )
|
||||
{
|
||||
if( 0 == ps->IO.bOpenCount ) {
|
||||
|
||||
/* not established */
|
||||
ioSwitchToSPPMode( ps );
|
||||
|
||||
/* Scanner command sequence to open scanner path */
|
||||
ioP98001EstablishScannerConnection( ps, 5 );
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else
|
||||
DBG( DBG_IO, "!!!! Path already open (%u)!!!!\n", ps->IO.bOpenCount );
|
||||
#endif
|
||||
|
||||
ps->IO.bOpenCount++; /* increment the opened count */
|
||||
|
||||
/*
|
||||
* CHECK to we really need that !!
|
||||
*/
|
||||
ps->IO.useEPPCmdMode = _FALSE;
|
||||
return _TRUE;
|
||||
}
|
||||
|
||||
static void ioP98003EstablishScannerConnection( pScanData ps, ULong delTime )
|
||||
{
|
||||
_OUTB_DATA( ps, _ID1ST );
|
||||
_DO_UDELAY( delTime );
|
||||
|
||||
_OUTB_DATA( ps, _ID2ND );
|
||||
_DO_UDELAY( delTime );
|
||||
|
||||
_OUTB_DATA( ps, _ID3RD );
|
||||
_DO_UDELAY( delTime );
|
||||
|
||||
_OUTB_DATA( ps, _ID4TH );
|
||||
_DO_UDELAY( delTime );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* try to connect to scanner
|
||||
*/
|
||||
static Bool ioP98OpenScanPath( pScanData ps )
|
||||
{
|
||||
Byte tmp;
|
||||
ULong dw;
|
||||
ULong dwTime = 1;
|
||||
|
||||
if( 0 == ps->IO.bOpenCount ) {
|
||||
|
||||
/* not established */
|
||||
ioSwitchToSPPMode( ps );
|
||||
|
||||
for( dw = 10; dw; dw-- ) {
|
||||
|
||||
/*
|
||||
* this seems to be necessary...
|
||||
*/
|
||||
if( _ASIC_IS_98001 == ps->sCaps.AsicID ) {
|
||||
ioP98001EstablishScannerConnection( ps, dw );
|
||||
#if 0
|
||||
ioP98001EstablishScannerConnection( ps, dw );
|
||||
ioP98001EstablishScannerConnection( ps, dw );
|
||||
#endif
|
||||
} else {
|
||||
ioP98003EstablishScannerConnection( ps, dw );
|
||||
}
|
||||
|
||||
_INB_STATUS( ps );
|
||||
tmp = _INB_STATUS( ps );
|
||||
|
||||
if( 0x50 == ( tmp & 0xf0 )) {
|
||||
|
||||
ps->IO.bOpenCount = 1;
|
||||
|
||||
if( ps->sCaps.AsicID == IODataFromRegister(ps, ps->RegAsicID)) {
|
||||
return _TRUE;
|
||||
}
|
||||
ps->IO.bOpenCount = 0;
|
||||
}
|
||||
|
||||
dwTime++;
|
||||
}
|
||||
DBG( DBG_IO, "ioP98OpenScanPath() failed!\n" );
|
||||
return _FALSE;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else
|
||||
DBG( DBG_IO, "!!!! Path already open (%u)!!!!\n", ps->IO.bOpenCount );
|
||||
#endif
|
||||
|
||||
ps->IO.bOpenCount++; /* increment the opened count */
|
||||
return _TRUE;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* Switch back to printer mode
|
||||
* Restore the printer control/data port value.
|
||||
*/
|
||||
static void ioCloseScanPath( pScanData ps )
|
||||
{
|
||||
if( ps->IO.bOpenCount && !(--ps->IO.bOpenCount)) {
|
||||
|
||||
#ifdef DEBUG
|
||||
ps->IO.bOpenCount = 1;
|
||||
#endif
|
||||
IORegisterToScanner( ps, 0xff );
|
||||
|
||||
/*
|
||||
* back to pass-through printer mode
|
||||
*/
|
||||
IORegisterToScanner( ps, ps->RegSwitchBus );
|
||||
#ifdef DEBUG
|
||||
ps->IO.bOpenCount = 0;
|
||||
#endif
|
||||
ps->IO.useEPPCmdMode = _FALSE;
|
||||
|
||||
ioRestoreParallelMode( ps );
|
||||
}
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* check the memory to see that the data-transfers will work
|
||||
* ASIC 9800x only
|
||||
*/
|
||||
static int ioP98ReadWriteTest( pScanData ps )
|
||||
{
|
||||
UChar tmp;
|
||||
ULong ul;
|
||||
pUChar buffer;
|
||||
int retval;
|
||||
|
||||
DBG( DBG_LOW, "ioP98ReadWriteTest()\n" );
|
||||
|
||||
/* _MEMTEST_SIZE: Read, _MEMTEST_SIZE:Write */
|
||||
buffer = _KALLOC( sizeof(UChar) * _MEMTEST_SIZE*2, GFP_KERNEL );
|
||||
|
||||
if( NULL == buffer )
|
||||
return _E_ALLOC;
|
||||
|
||||
/* prepare content */
|
||||
for( ul = 0; ul < _MEMTEST_SIZE; ul++ )
|
||||
buffer[ul] = (UChar)ul;
|
||||
|
||||
ps->OpenScanPath(ps);
|
||||
|
||||
/* avoid switching to Lamp0, when previously scanned in transp./neg mode */
|
||||
tmp = ps->bLastLampStatus + _SCAN_BYTEMODE;
|
||||
IODataToRegister( ps, ps->RegScanControl, tmp );
|
||||
|
||||
IODataToRegister( ps, ps->RegModelControl, (_LED_ACTIVITY | _LED_CONTROL));
|
||||
|
||||
IODataToRegister( ps, ps->RegModeControl, _ModeMappingMem );
|
||||
IODataToRegister( ps, ps->RegMemoryLow, 0 );
|
||||
IODataToRegister( ps, ps->RegMemoryHigh, 0 );
|
||||
|
||||
/* fill to buffer */
|
||||
IOMoveDataToScanner( ps, buffer, 1280 );
|
||||
|
||||
IODataToRegister( ps, ps->RegModeControl, _ModeMappingMem );
|
||||
IODataToRegister( ps, ps->RegMemoryLow, 0 );
|
||||
IODataToRegister( ps, ps->RegMemoryHigh, 0 );
|
||||
IODataToRegister( ps, ps->RegWidthPixelsLow, 0 );
|
||||
IODataToRegister( ps, ps->RegWidthPixelsHigh, 5 );
|
||||
|
||||
ps->AsicReg.RD_ModeControl = _ModeReadMappingMem;
|
||||
|
||||
if( _ASIC_IS_98001 == ps->sCaps.AsicID )
|
||||
ps->CloseScanPath( ps );
|
||||
|
||||
IOReadScannerImageData( ps, buffer + _MEMTEST_SIZE, _MEMTEST_SIZE );
|
||||
|
||||
if( _ASIC_IS_98003 == ps->sCaps.AsicID )
|
||||
ps->CloseScanPath( ps );
|
||||
|
||||
/*
|
||||
* check the result !
|
||||
*/
|
||||
retval = _OK;
|
||||
|
||||
for( ul = 0; ul < _MEMTEST_SIZE; ul++ ) {
|
||||
if( buffer[ul] != buffer[ul+_MEMTEST_SIZE] ) {
|
||||
DBG( DBG_HIGH, "Error in memory test at pos %lu (%u != %u)\n",
|
||||
ul, buffer[ul], buffer[ul+_MEMTEST_SIZE] );
|
||||
retval = _E_NO_DEV;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_KFREE(buffer);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* Put data to DATA port and trigger hardware through CONTROL port to read it.
|
||||
*/
|
||||
static void ioSPPWrite( pScanData ps, pUChar pBuffer, ULong size )
|
||||
{
|
||||
DBG( DBG_IO , "IODELAY = %u\n", ps->IO.delay );
|
||||
switch( ps->IO.delay ) {
|
||||
|
||||
case 0:
|
||||
for (; size; size--, pBuffer++) {
|
||||
_OUTB_DATA( ps, *pBuffer );
|
||||
_OUTB_CTRL( ps, _CTRL_SIGNAL_DATAWRITE );
|
||||
_OUTB_CTRL( ps, _CTRL_END_DATAWRITE );
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
case 2:
|
||||
for (; size; size--, pBuffer++) {
|
||||
_OUTB_DATA( ps, *pBuffer );
|
||||
_DO_UDELAY( 1 );
|
||||
_OUTB_CTRL( ps, _CTRL_SIGNAL_DATAWRITE );
|
||||
_DO_UDELAY( 1 );
|
||||
_OUTB_CTRL( ps, _CTRL_END_DATAWRITE );
|
||||
_DO_UDELAY( 2 );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
for (; size; size--, pBuffer++) {
|
||||
_OUTB_DATA( ps, *pBuffer );
|
||||
_DO_UDELAY( 1 );
|
||||
_OUTB_CTRL( ps, _CTRL_SIGNAL_DATAWRITE );
|
||||
_DO_UDELAY( 2 );
|
||||
_OUTB_CTRL( ps, _CTRL_END_DATAWRITE );
|
||||
_DO_UDELAY( 3 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
*
|
||||
*/
|
||||
static void ioEnterReadMode( pScanData ps )
|
||||
{
|
||||
if( ps->IO.portMode != _PORT_SPP ) {
|
||||
|
||||
_DO_UDELAY( 1 );
|
||||
|
||||
IORegisterToScanner( ps, ps->RegEPPEnable );
|
||||
|
||||
if( _IS_ASIC98( ps->sCaps.AsicID ))
|
||||
ps->IO.useEPPCmdMode = _TRUE;
|
||||
}
|
||||
|
||||
if( _ASIC_IS_98003 == ps->sCaps.AsicID )
|
||||
ps->IO.bOldControlValue = _INB_CTRL( ps );
|
||||
|
||||
/* ask ASIC to enter read mode */
|
||||
IORegisterToScanner( ps, ps->RegReadDataMode );
|
||||
}
|
||||
|
||||
/************************ exported functions *********************************/
|
||||
|
||||
/*.............................................................................
|
||||
* here we do some init work
|
||||
*/
|
||||
int IOInitialize( pScanData ps )
|
||||
{
|
||||
DBG( DBG_HIGH, "IOInitialize()\n" );
|
||||
|
||||
if( NULL == ps )
|
||||
return _E_NULLPTR;
|
||||
|
||||
if( _IS_ASIC98(ps->sCaps.AsicID)) {
|
||||
|
||||
ps->OpenScanPath = ioP98OpenScanPath;
|
||||
ps->ReadWriteTest = ioP98ReadWriteTest;
|
||||
|
||||
} else if( _IS_ASIC96(ps->sCaps.AsicID)) {
|
||||
|
||||
ps->OpenScanPath = ioP96OpenScanPath;
|
||||
|
||||
} else {
|
||||
|
||||
DBG( DBG_HIGH , "NOT SUPPORTED ASIC !!!\n" );
|
||||
return _E_NOSUPP;
|
||||
}
|
||||
|
||||
ps->CloseScanPath = ioCloseScanPath;
|
||||
ps->Device.ReadData = ioReadFunc[ps->IO.portMode];
|
||||
|
||||
return _OK;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* Write specific length buffer to scanner
|
||||
* The scan path is already established
|
||||
*/
|
||||
void IOMoveDataToScanner( pScanData ps, pUChar pBuffer, ULong size )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if( 0 == ps->IO.bOpenCount )
|
||||
DBG( DBG_IO, "IOMoveDataToScanner - no connection!\n" );
|
||||
#endif
|
||||
|
||||
IORegisterToScanner( ps, ps->RegInitDataFifo );
|
||||
IORegisterToScanner( ps, ps->RegWriteDataMode );
|
||||
|
||||
ioSPPWrite( ps, pBuffer, size );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* Calling SITUATION: Scanner path is established.
|
||||
* download a scanstate-table
|
||||
*/
|
||||
void IODownloadScanStates( pScanData ps )
|
||||
{
|
||||
TimerDef timer;
|
||||
#ifdef DEBUG
|
||||
if( 0 == ps->IO.bOpenCount )
|
||||
DBG( DBG_IO, "IODownloadScanStates - no connection!\n" );
|
||||
#endif
|
||||
|
||||
IORegisterToScanner( ps, ps->RegScanStateControl );
|
||||
|
||||
ioSPPWrite( ps, ps->a_nbNewAdrPointer, _SCANSTATE_BYTES );
|
||||
|
||||
if( ps->Scan.fRefreshState ) {
|
||||
|
||||
IORegisterToScanner( ps, ps->RegRefreshScanState );
|
||||
|
||||
MiscStartTimer( &timer, (_SECOND/2));
|
||||
do {
|
||||
|
||||
if (!( IOGetScanState( ps, _TRUE) & _SCANSTATE_STOP))
|
||||
break;
|
||||
}
|
||||
while( !MiscCheckTimer(&timer));
|
||||
}
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* Calling SITUATION: Scanner path is established.
|
||||
* Write a data to asic
|
||||
*/
|
||||
void IODataToScanner( pScanData ps, Byte bValue )
|
||||
{
|
||||
ULong deltime = 4;
|
||||
|
||||
#ifdef DEBUG
|
||||
if( 0 == ps->IO.bOpenCount )
|
||||
DBG( DBG_IO, "IODataToScanner - no connection!\n" );
|
||||
#endif
|
||||
|
||||
if( ps->IO.delay < 2 )
|
||||
deltime = 2;
|
||||
|
||||
/* output data */
|
||||
_OUTB_DATA( ps, bValue );
|
||||
_DO_UDELAY( deltime );
|
||||
|
||||
/* notify asic there is data */
|
||||
_OUTB_CTRL( ps, _CTRL_SIGNAL_DATAWRITE );
|
||||
_DO_UDELAY( deltime );
|
||||
|
||||
/* end write cycle */
|
||||
_OUTB_CTRL( ps, _CTRL_END_DATAWRITE );
|
||||
_DO_UDELAY( deltime-1 );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* Calling SITUATION: Scanner path is established.
|
||||
* Write a data to specific asic's register
|
||||
*/
|
||||
void IODataToRegister( pScanData ps, Byte bReg, Byte bData )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if( 0 == ps->IO.bOpenCount )
|
||||
DBG( DBG_IO, "IODataToRegister - no connection!\n" );
|
||||
#endif
|
||||
|
||||
/* specify register */
|
||||
IORegisterToScanner( ps, bReg );
|
||||
|
||||
/* then write the content */
|
||||
IODataToScanner( ps, bData );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* Calling SITUATION: Scanner path is established.
|
||||
* Read the content of specific asic's register
|
||||
*/
|
||||
Byte IODataFromRegister( pScanData ps, Byte bReg )
|
||||
{
|
||||
IORegisterToScanner( ps, bReg );
|
||||
|
||||
if( 0 == ps->IO.delay )
|
||||
return ioDataFromSPPFast( ps );
|
||||
else if( 1 == ps->IO.delay )
|
||||
return ioDataFromSPPMiddle( ps );
|
||||
else if( 2 == ps->IO.delay )
|
||||
return ioDataFromSPPSlow( ps );
|
||||
else
|
||||
return ioDataFromSPPSlowest( ps );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* Calling SITUATION: Scanner path is established.
|
||||
* Write a register to asic (used for a command without parameter)
|
||||
*/
|
||||
void IORegisterToScanner( pScanData ps, Byte bReg )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if( 0 == ps->IO.bOpenCount )
|
||||
DBG( DBG_IO, "IORegisterToScanner - no connection!\n" );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* write data to port
|
||||
*/
|
||||
_OUTB_DATA( ps, bReg );
|
||||
|
||||
/*
|
||||
* depending on the mode, generate the trigger signals
|
||||
*/
|
||||
if( ps->IO.useEPPCmdMode ) {
|
||||
|
||||
_DO_UDELAY( 5 );
|
||||
|
||||
_OUTB_CTRL( ps, _CTRL_EPPSIGNAL_WRITE); /* 0xc5 */
|
||||
_DO_UDELAY( 5 );
|
||||
|
||||
_OUTB_CTRL( ps, _CTRL_EPPTRIG_REGWRITE);/* 0xcd */
|
||||
_DO_UDELAY( 5 );
|
||||
|
||||
_OUTB_CTRL( ps, _CTRL_EPPSIGNAL_WRITE); /* 0xc5 */
|
||||
_DO_UDELAY( 5 );
|
||||
|
||||
_OUTB_CTRL( ps, _CTRL_END_REGWRITE); /* 0xc4 */
|
||||
|
||||
} else {
|
||||
if( ps->IO.delay < 2 ) {
|
||||
|
||||
_DO_UDELAY( 1 );
|
||||
_OUTB_CTRL( ps, _CTRL_SIGNAL_REGWRITE);
|
||||
_DO_UDELAY( 1 );
|
||||
_OUTB_CTRL( ps, _CTRL_END_REGWRITE);
|
||||
} else {
|
||||
|
||||
_DO_UDELAY( 2 );
|
||||
_OUTB_CTRL( ps, _CTRL_SIGNAL_REGWRITE);
|
||||
_DO_UDELAY( 2 );
|
||||
_OUTB_CTRL( ps, _CTRL_END_REGWRITE);
|
||||
_DO_UDELAY( 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* write data to the DAC - ASIC 98001/3 only
|
||||
*/
|
||||
void IODataRegisterToDAC( pScanData ps, Byte bReg, Byte bData )
|
||||
{
|
||||
ULong i;
|
||||
|
||||
IODataToRegister( ps, ps->RegADCAddress, bReg );
|
||||
IODataToRegister( ps, ps->RegADCData, bData );
|
||||
IODataToRegister( ps, ps->RegADCSerialOutStr, bData );
|
||||
|
||||
/* TEST: ORG was 1 ms for ASIC 98001 */
|
||||
_DO_UDELAY( 12 );
|
||||
|
||||
for( i = 4; i; i-- ) {
|
||||
|
||||
_OUTB_CTRL( ps, _CTRL_SIGNAL_DATAWRITE );
|
||||
_DO_UDELAY( 5 );
|
||||
_OUTB_CTRL( ps, _CTRL_NORMAL );
|
||||
_DO_UDELAY( 12 );
|
||||
}
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* Calling SITUATION: Scanner path was not established.
|
||||
* Read the content of specific asics' register
|
||||
*/
|
||||
Byte IODataRegisterFromScanner( pScanData ps, Byte bReg )
|
||||
{
|
||||
Byte bData;
|
||||
|
||||
ps->OpenScanPath( ps );
|
||||
bData = IODataFromRegister( ps, bReg );
|
||||
ps->CloseScanPath( ps );
|
||||
|
||||
return bData;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* Calling SITUATION: Scanner path not established.
|
||||
* Write a value of register to asic
|
||||
*/
|
||||
void IOCmdRegisterToScanner( pScanData ps, Byte bReg, Byte bData )
|
||||
{
|
||||
ps->OpenScanPath( ps );
|
||||
IODataToRegister( ps, bReg, bData );
|
||||
ps->CloseScanPath( ps );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* Calling SITUATION: Scanner path not established.
|
||||
* Write a register to asic (used for a command without parameter)
|
||||
*/
|
||||
void IORegisterDirectToScanner( pScanData ps, Byte bReg )
|
||||
{
|
||||
ps->OpenScanPath( ps ); /* establish the connection */
|
||||
IORegisterToScanner( ps, bReg ); /* write register to asic */
|
||||
ps->CloseScanPath( ps ); /* disconnect */
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* perform a SW reset of ASIC 98003 models
|
||||
*/
|
||||
void IOSoftwareReset( pScanData ps )
|
||||
{
|
||||
if( _ASIC_IS_98003 != ps->sCaps.AsicID )
|
||||
return;
|
||||
|
||||
ps->OpenScanPath( ps );
|
||||
|
||||
IODataToRegister( ps, ps->RegTestMode, _SW_TESTMODE );
|
||||
|
||||
ioSwitchToSPPMode( ps );
|
||||
|
||||
_OUTB_DATA( ps, _RESET1ST );
|
||||
_DODELAY( 5 );
|
||||
|
||||
_OUTB_DATA( ps, _RESET2ND );
|
||||
_DODELAY( 5 );
|
||||
|
||||
_OUTB_DATA( ps, _RESET3RD );
|
||||
_DODELAY( 5 );
|
||||
|
||||
_OUTB_DATA( ps, _RESET4TH );
|
||||
_DODELAY( 5 );
|
||||
|
||||
ioRestoreParallelMode( ps );
|
||||
|
||||
/* reset test mode register */
|
||||
IODataToRegister( ps, ps->RegTestMode, 0 );
|
||||
IODataToRegister( ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl );
|
||||
|
||||
ps->CloseScanPath( ps );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* Read specific length data from scanner and the method depends on the
|
||||
* mode defined in registry.
|
||||
*/
|
||||
void IOReadScannerImageData( pScanData ps, pUChar pBuf, ULong size )
|
||||
{
|
||||
if( _ASIC_IS_98003 != ps->sCaps.AsicID )
|
||||
ps->OpenScanPath( ps);
|
||||
|
||||
if( _IS_ASIC98( ps->sCaps.AsicID))
|
||||
IODataToRegister(ps, ps->RegModeControl, ps->AsicReg.RD_ModeControl );
|
||||
|
||||
/* enter read mode */
|
||||
ioEnterReadMode( ps );
|
||||
|
||||
/* call corresponding read proc */
|
||||
ps->Device.ReadData( ps, pBuf, size );
|
||||
|
||||
/* Clear EPP/ECP read mode by simplely close scanner path and re-open it */
|
||||
ps->CloseScanPath( ps );
|
||||
|
||||
if( _ASIC_IS_98003 == ps->sCaps.AsicID )
|
||||
ps->OpenScanPath( ps );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* to program the ASIC 97003 on some scanner devices
|
||||
*/
|
||||
void IOFill97003Register( pScanData ps, Byte bDecode1, Byte bDecode2 )
|
||||
{
|
||||
IODataToRegister( ps, ps->RegWriteIOBusDecode2, bDecode2 );
|
||||
IODataToRegister( ps, ps->RegWriteIOBusDecode1, bDecode1 );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* the wrapper functions to support delayed and non-delayed I/O
|
||||
*/
|
||||
void IOOut( Byte data, UShort port )
|
||||
{
|
||||
DBG( DBG_IOF, "outb(0x%04x, 0x%02x)\n", port, data );
|
||||
outb( data, port );
|
||||
}
|
||||
|
||||
void IOOutDelayed( Byte data, UShort port )
|
||||
{
|
||||
DBG( DBG_IOF, "outb_p(0x%04x, 0x%02x)\n", port, data );
|
||||
outb_p( data, port );
|
||||
}
|
||||
|
||||
Byte IOIn( UShort port )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Byte data = inb( port );
|
||||
|
||||
DBG( DBG_IOF, "inb(0x%04x) = 0x%02x\n", port, data );
|
||||
return data;
|
||||
#else
|
||||
return inb( port );
|
||||
#endif
|
||||
}
|
||||
|
||||
Byte IOInDelayed( UShort port )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Byte data = inb_p( port );
|
||||
|
||||
DBG( DBG_IOF, "inb_p(0x%04x) = 0x%02x\n", port, data );
|
||||
return data;
|
||||
#else
|
||||
return inb_p( port );
|
||||
#endif
|
||||
}
|
||||
|
||||
/* END PLUSTEK-PP_IO.C ......................................................*/
|
|
@ -0,0 +1,286 @@
|
|||
/*.............................................................................
|
||||
* Project : linux driver for Plustek parallel-port scanners
|
||||
*.............................................................................
|
||||
* File: plustek-pp_map.c - functions to create and manipulate
|
||||
* lookup tables.
|
||||
*.............................................................................
|
||||
*
|
||||
* based on sources acquired from Plustek Inc.
|
||||
* Copyright (C) 1998 Plustek Inc.
|
||||
* Copyright (C) 2000-2003 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
* also based on the work done by Rick Bronson
|
||||
*.............................................................................
|
||||
* History:
|
||||
* 0.30 - initial version
|
||||
* 0.31 - brightness and contrast is working (see mapAdjust)
|
||||
* 0.32 - no changes
|
||||
* 0.33 - disabled a few functions
|
||||
* 0.34 - added new dither matrix for checking
|
||||
* 0.35 - no changes
|
||||
* 0.36 - activated Dithermap 1
|
||||
* removed some unused functions
|
||||
* added additional SCANDEF_Inverse check to MapSetupDither()
|
||||
* fixed the double inversion bug, the map always compensates
|
||||
* the scanner hw-settings
|
||||
* 0.37 - code cleanup
|
||||
* 0.38 - added P12 stuff
|
||||
* 0.39 - no changes
|
||||
* 0.40 - no changes
|
||||
* 0.41 - no changes
|
||||
* 0.42 - made MapAdjust global
|
||||
* changed include names
|
||||
*
|
||||
*.............................................................................
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include "plustek-pp_scan.h"
|
||||
|
||||
/*************************** local vars **************************************/
|
||||
|
||||
/*WORK:
|
||||
* create other thresholds for the dither maps
|
||||
*/
|
||||
static Byte mapDitherMatrix0[_DITHERSIZE] =
|
||||
{
|
||||
0, 32, 8, 40, 2, 34, 10, 42,
|
||||
48, 16, 56, 24, 50, 18, 58, 26,
|
||||
12, 44, 4, 36, 14, 46, 6, 38,
|
||||
60, 28, 52, 20, 62, 30, 54, 22,
|
||||
3, 35, 11, 43, 1, 33, 9, 41,
|
||||
51, 19, 59, 27, 49, 17, 57, 25,
|
||||
15, 47, 7, 39, 13, 45, 5, 37,
|
||||
63, 31, 55, 23, 61, 29, 53, 21
|
||||
};
|
||||
|
||||
static Byte mapDitherMatrix1[_DITHERSIZE] =
|
||||
{
|
||||
2, 60, 16, 56, 3, 57, 13, 53,
|
||||
34, 18, 48, 32, 35, 19, 45, 29,
|
||||
10, 50, 6, 63, 11, 51, 7, 61,
|
||||
42, 26, 38, 22, 43, 27, 39, 23,
|
||||
4, 58, 14, 54, 1, 59, 15, 55,
|
||||
36, 20, 46, 30, 33, 17, 47, 31,
|
||||
12, 52, 8, 62, 9, 49, 5, 63,
|
||||
44, 28, 40, 24, 41, 25, 37, 21
|
||||
};
|
||||
|
||||
/*************************** local functions *********************************/
|
||||
|
||||
/** set the selected dither maps...
|
||||
*/
|
||||
static void mapSetDitherMap( pScanData ps )
|
||||
{
|
||||
ULong i;
|
||||
pUChar pDitherSource;
|
||||
pUChar pDither = ps->a_bDitherPattern;
|
||||
|
||||
if( 0 == ps->DataInf.wDither ) {
|
||||
DBG( DBG_LOW, "Using Dithermatrix 0\n" );
|
||||
pDitherSource = mapDitherMatrix0;
|
||||
} else {
|
||||
DBG( DBG_LOW, "Using Dithermatrix 1\n" );
|
||||
pDitherSource = mapDitherMatrix1;
|
||||
}
|
||||
|
||||
for( i = 0; i < _DITHERSIZE; i++ ) {
|
||||
pDither[i] = pDitherSource[i];
|
||||
}
|
||||
}
|
||||
|
||||
/** nothing more to say
|
||||
*/
|
||||
static void mapInvertMap( pScanData ps )
|
||||
{
|
||||
pULong pdw;
|
||||
ULong dw, size;
|
||||
|
||||
DBG( DBG_LOW, "mapInvertMap()\n" );
|
||||
|
||||
if( _IS_ASIC98(ps->sCaps.AsicID)) {
|
||||
size = 4096;
|
||||
} else {
|
||||
size = 256;
|
||||
}
|
||||
|
||||
for (pdw = (pULong)ps->a_bMapTable, dw = size * 3 / 4; dw; dw--, pdw++) {
|
||||
*pdw = ~(*pdw);
|
||||
}
|
||||
}
|
||||
|
||||
/** as the name says...
|
||||
*/
|
||||
static void mapInvertDitherMap( pScanData ps )
|
||||
{
|
||||
if( ps->DataInf.dwScanFlag & SCANDEF_Inverse ) {
|
||||
|
||||
ULong dw;
|
||||
pULong pDither = (pULong)ps->a_bDitherPattern;
|
||||
|
||||
DBG( DBG_LOW, "mapInvertDitherMap()\n" );
|
||||
|
||||
mapInvertMap( ps );
|
||||
for (dw = 0; dw < 16; dw++) {
|
||||
pDither[dw] = ~pDither[dw];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** build linear map...
|
||||
*/
|
||||
static void mapBuildLinearMap( pScanData ps )
|
||||
{
|
||||
ULong i;
|
||||
|
||||
DBG( DBG_LOW, "mapBuildLinearMap()\n" );
|
||||
|
||||
if( _IS_ASIC98(ps->sCaps.AsicID)) {
|
||||
|
||||
for( i = 0; i < 4096; i++ ) {
|
||||
ps->a_bMapTable[i] = (UChar)(i >> 4);
|
||||
ps->a_bMapTable[4096+i] = (UChar)(i >> 4);
|
||||
ps->a_bMapTable[8192+i] = (UChar)(i >> 4);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
for( i = 0; i < 256; i++ ) {
|
||||
ps->a_bMapTable[i] = (UChar)(i & 0xff);
|
||||
ps->a_bMapTable[256+i] = (UChar)(i & 0xff);
|
||||
ps->a_bMapTable[512+i] = (UChar)(i & 0xff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/************************ exported functions *********************************/
|
||||
|
||||
/** create a mapping table
|
||||
* in the original code this map will be created by the TWAIN application
|
||||
* and the is being downloaded to the driver, as I don't have the code
|
||||
* we have to try to build up such a table here
|
||||
*/
|
||||
void MapInitialize( pScanData ps )
|
||||
{
|
||||
mapBuildLinearMap( ps );
|
||||
MapAdjust( ps, _MAP_MASTER );
|
||||
}
|
||||
|
||||
/** setup dither maps
|
||||
*/
|
||||
void MapSetupDither( pScanData ps )
|
||||
{
|
||||
DBG( DBG_LOW, "MapSetupDither() - %u\n", ps->DataInf.wAppDataType );
|
||||
|
||||
if( COLOR_HALFTONE == ps->DataInf.wAppDataType ) {
|
||||
|
||||
mapSetDitherMap( ps );
|
||||
if (ps->DataInf.dwScanFlag & SCANDEF_Inverse)
|
||||
mapInvertDitherMap( ps );
|
||||
}
|
||||
}
|
||||
|
||||
/** adjust acording to brightness and contrast
|
||||
*/
|
||||
void MapAdjust( pScanData ps, int which )
|
||||
{
|
||||
ULong i, tabLen;
|
||||
pULong pdw;
|
||||
double b, c, dw, tmp;
|
||||
|
||||
DBG( DBG_LOW, "MapAdjust(%u)\n", which );
|
||||
|
||||
if( _IS_ASIC98(ps->sCaps.AsicID)) {
|
||||
tabLen = 4096;
|
||||
} else {
|
||||
tabLen = 256;
|
||||
}
|
||||
|
||||
/*
|
||||
* adjust brightness (b) and contrast (c) using the function:
|
||||
*
|
||||
* s´(x,y) = (s(x,y) + b) * c
|
||||
* b = [-127, 127]
|
||||
* c = [0,2]
|
||||
*/
|
||||
|
||||
/*
|
||||
* scale brightness and contrast...
|
||||
*/
|
||||
b = ((double)ps->wBrightness * 192.0)/100.0;
|
||||
c = ((double)ps->wContrast + 100.0)/100.0;
|
||||
|
||||
DBG( DBG_LOW, "brightness = %i -> %i\n", ps->wBrightness, (UChar)b);
|
||||
DBG( DBG_LOW, "contrast*100 = %i -> %i\n", ps->wContrast, (int)(c*100));
|
||||
|
||||
for( i = 0; i < tabLen; i++ ) {
|
||||
|
||||
if((_MAP_MASTER == which) || (_MAP_RED == which)) {
|
||||
tmp = ((double)(ps->a_bMapTable[i] + b)) * c;
|
||||
if( tmp < 0 ) tmp = 0;
|
||||
if( tmp > 255 ) tmp = 255;
|
||||
ps->a_bMapTable[i] = (UChar)tmp;
|
||||
}
|
||||
|
||||
if((_MAP_MASTER == which) || (_MAP_GREEN == which)) {
|
||||
tmp = ((double)(ps->a_bMapTable[tabLen+i] + b)) * c;
|
||||
if( tmp < 0 ) tmp = 0;
|
||||
if( tmp > 255 ) tmp = 255;
|
||||
ps->a_bMapTable[tabLen+i] = (UChar)tmp;
|
||||
}
|
||||
|
||||
if((_MAP_MASTER == which) || (_MAP_BLUE == which)) {
|
||||
tmp = ((double)(ps->a_bMapTable[tabLen*2+i] + b)) * c;
|
||||
if( tmp < 0 ) tmp = 0;
|
||||
if( tmp > 255 ) tmp = 255;
|
||||
ps->a_bMapTable[tabLen*2+i] = (UChar)tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if( ps->DataInf.dwScanFlag & SCANDEF_Negative ) {
|
||||
DBG( DBG_LOW, "inverting...\n" );
|
||||
|
||||
if((_MAP_MASTER == which) || (_MAP_RED == which)) {
|
||||
|
||||
DBG( DBG_LOW, "inverting RED map\n" );
|
||||
|
||||
pdw = (pULong)ps->a_bMapTable;
|
||||
|
||||
for( dw = tabLen / 4; dw; dw--, pdw++ )
|
||||
*pdw = ~(*pdw);
|
||||
}
|
||||
|
||||
if((_MAP_MASTER == which) || (_MAP_GREEN == which)) {
|
||||
|
||||
DBG( DBG_LOW, "inverting GREEN map\n" );
|
||||
|
||||
pdw = (pULong)&ps->a_bMapTable[tabLen];
|
||||
|
||||
for( dw = tabLen / 4; dw; dw--, pdw++ )
|
||||
*pdw = ~(*pdw);
|
||||
}
|
||||
|
||||
if((_MAP_MASTER == which) || (_MAP_BLUE == which)) {
|
||||
|
||||
DBG( DBG_LOW, "inverting BLUE map\n" );
|
||||
|
||||
pdw = (pULong)&ps->a_bMapTable[tabLen*2];
|
||||
|
||||
for( dw = tabLen / 4; dw; dw--, pdw++ )
|
||||
*pdw = ~(*pdw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* END PLUSTEK-PP_MAP.C .....................................................*/
|
|
@ -0,0 +1,938 @@
|
|||
/*.............................................................................
|
||||
* Project : linux driver for Plustek parallel-port scanners
|
||||
*.............................................................................
|
||||
* File: plustek-pp_misc.c - here we have some helpful functions
|
||||
*.............................................................................
|
||||
*
|
||||
* based on sources acquired from Plustek Inc.
|
||||
* Copyright (C) 1998 Plustek Inc.
|
||||
* Copyright (C) 2000-2003 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
* also based on the work done by Rick Bronson
|
||||
*.............................................................................
|
||||
* History:
|
||||
* 0.30 - initial version
|
||||
* 0.31 - no changes
|
||||
* 0.32 - moved the parport functions inside this module
|
||||
* now using the information, the parport-driver provides
|
||||
* for selecting the port-mode this driver uses
|
||||
* 0.33 - added code to use faster portmodes
|
||||
* 0.34 - added sample code for changing from ECP to PS/2 bidi mode
|
||||
* 0.35 - added Kevins´ changes (new function miscSetFastMode())
|
||||
* moved function initPageSettings() to module models.c
|
||||
* 0.36 - added random generator
|
||||
* added additional debug messages
|
||||
* changed prototype of MiscInitPorts()
|
||||
* added miscPreemptionCallback()
|
||||
* 0.37 - changed inb_p/outb_p to macro calls (kernel-mode)
|
||||
* added MiscGetModelName()
|
||||
* added miscShowPortModes()
|
||||
* 0.38 - fixed a small bug in MiscGetModelName()
|
||||
* 0.39 - added forceMode support
|
||||
* 0.40 - no changes
|
||||
* 0.41 - merged Kevins' patch to make EPP(ECP) work
|
||||
* 0.42 - changed get_fast_time to _GET_TIME
|
||||
* changed include names
|
||||
*
|
||||
*.............................................................................
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include "plustek-pp_scan.h"
|
||||
|
||||
/*************************** some definitions ********************************/
|
||||
|
||||
#ifndef __KERNEL__
|
||||
#define PPA_PROBE_SPP 0x0001
|
||||
#define PPA_PROBE_PS2 0x0002
|
||||
#define PPA_PROBE_ECR 0x0010
|
||||
#define PPA_PROBE_EPP17 0x0100
|
||||
#define PPA_PROBE_EPP19 0x0200
|
||||
#else
|
||||
|
||||
/*
|
||||
* the parport driver in Kernel 2.4 has changed. It does report the
|
||||
* possible modes in a different, more general way. As long, as
|
||||
* we do not use the parport-module change mode facility, I assume
|
||||
* the following correlations
|
||||
*/
|
||||
#if defined LINUX_24 || defined LINUX_26
|
||||
# define PARPORT_MODE_PCPS2 PARPORT_MODE_TRISTATE
|
||||
# define PARPORT_MODE_PCEPP PARPORT_MODE_EPP
|
||||
# define PARPORT_MODE_PCECPPS2 PARPORT_MODE_TRISTATE
|
||||
# define PARPORT_MODE_PCECPEPP PARPORT_MODE_EPP
|
||||
# define PARPORT_MODE_PCECR PARPORT_MODE_ECP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define _A 16807 /* multiplier */
|
||||
#define _M 2147483647L /* 2**31 - 1 */
|
||||
#define _Q 127773L /* m div a */
|
||||
#define _R 2836 /* m mod a */
|
||||
|
||||
/*************************** some local vars *********************************/
|
||||
|
||||
static int port_feature;
|
||||
static long randomnum = 1;
|
||||
|
||||
static int portIsClaimed[_MAX_PTDEVS] = { [0 ... (_MAX_PTDEVS-1)] = 0 };
|
||||
|
||||
#ifdef __KERNEL__
|
||||
MODELSTR; /* is a static char array (see plustek-share.h) */
|
||||
#endif
|
||||
|
||||
/*************************** local functions *********************************/
|
||||
|
||||
/** display the avaialable port-modes
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
static void miscShowPortModes( int modes )
|
||||
{
|
||||
DBG( DBG_LOW, "parport-modi:" );
|
||||
|
||||
#ifdef __KERNEL__
|
||||
if( modes & PARPORT_MODE_PCSPP )
|
||||
DBG( DBG_LOW, " SPP" );
|
||||
|
||||
if( modes & PARPORT_MODE_PCPS2 )
|
||||
DBG( DBG_LOW, " PS/2" );
|
||||
|
||||
if( modes & PARPORT_MODE_PCEPP )
|
||||
DBG( DBG_LOW, " EPP" );
|
||||
|
||||
if( modes & PARPORT_MODE_PCECR )
|
||||
DBG( DBG_LOW, " ECP" );
|
||||
|
||||
if( modes & PARPORT_MODE_PCECPEPP )
|
||||
DBG( DBG_LOW, " EPP(ECP)" );
|
||||
|
||||
if( modes & PARPORT_MODE_PCECPPS2 )
|
||||
DBG( DBG_LOW, " PS/2(ECP)" );
|
||||
#else
|
||||
if( modes & PPA_PROBE_SPP )
|
||||
DBG( DBG_LOW, " SPP" );
|
||||
|
||||
if( modes & PPA_PROBE_PS2 )
|
||||
DBG( DBG_LOW, " PS/2" );
|
||||
|
||||
if( modes & PPA_PROBE_EPP17 )
|
||||
DBG( DBG_LOW, " EPP17" );
|
||||
|
||||
if( modes & PPA_PROBE_EPP19 )
|
||||
DBG( DBG_LOW, " EPP19" );
|
||||
|
||||
if( modes & PPA_PROBE_ECR )
|
||||
DBG( DBG_LOW, " ECP" );
|
||||
#endif
|
||||
|
||||
DBG( DBG_LOW, "\n" );
|
||||
}
|
||||
#endif
|
||||
|
||||
/** probe the parallel port
|
||||
*/
|
||||
static int initPortProbe( pScanData ps )
|
||||
{
|
||||
int retv = 0;
|
||||
#ifndef __KERNEL__
|
||||
UShort port;
|
||||
UChar a, b, c;
|
||||
UInt i, j;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* clear the controls
|
||||
*/
|
||||
ps->IO.lastPortMode = 0xFFFF;
|
||||
|
||||
#ifdef __KERNEL__
|
||||
if( NULL != ps->pardev )
|
||||
retv = ps->pardev->port->modes;
|
||||
#else
|
||||
port = ps->IO.portBase;
|
||||
|
||||
DBG(DBG_SCAN, "Probing port 0x%04x\n", port);
|
||||
|
||||
/* ##### ###### ######
|
||||
* # # # # # #
|
||||
* # # # # #
|
||||
* ##### ###### ######
|
||||
* # # #
|
||||
* # # # #
|
||||
* ##### # #
|
||||
*/
|
||||
|
||||
outb(0x0c, port + 0x402);
|
||||
outb(0x0c, port + 0x002);
|
||||
outb(0x55, port);
|
||||
a = inb(port);
|
||||
if (a != 0x55)
|
||||
return retv;
|
||||
|
||||
DBG(DBG_SCAN, " SPP port present\n");
|
||||
|
||||
retv += PPA_PROBE_SPP;
|
||||
|
||||
/* ####### ##### ######
|
||||
* # # # # #
|
||||
* # # # #
|
||||
* ##### # ######
|
||||
* # # #
|
||||
* # # # #
|
||||
* ####### ##### #
|
||||
*/
|
||||
|
||||
for (i = 1024; i > 0; i--) { /* clear at most 1k of data from FIFO */
|
||||
a = inb(port + 0x402);
|
||||
if ((a & 0x03) == 0x03)
|
||||
goto no_ecp;
|
||||
if (a & 0x01)
|
||||
break;
|
||||
inb(port + 0x400); /* Remove byte from FIFO */
|
||||
}
|
||||
|
||||
if (i <= 0)
|
||||
goto no_ecp;
|
||||
|
||||
b = a ^ 3;
|
||||
outb(b, port + 0x402);
|
||||
c = inb(port + 0x402);
|
||||
|
||||
if (a == c) {
|
||||
outb(0xc0, port + 0x402); /* FIFO test */
|
||||
j = 0;
|
||||
while (!(inb(port + 0x402) & 0x01) && (j < 1024)) {
|
||||
inb(port + 0x400);
|
||||
j++;
|
||||
}
|
||||
if (j >= 1024)
|
||||
goto no_ecp;
|
||||
i = 0;
|
||||
j = 0;
|
||||
while (!(inb(port + 0x402) & 0x02) && (j < 1024)) {
|
||||
outb(0x00, port + 0x400);
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
if (j >= 1024)
|
||||
goto no_ecp;
|
||||
j = 0;
|
||||
while (!(inb(port + 0x402) & 0x01) && (j < 1024)) {
|
||||
inb(port + 0x400);
|
||||
j++;
|
||||
}
|
||||
if (j >= 1024)
|
||||
goto no_ecp;
|
||||
|
||||
DBG(DBG_SCAN, " ECP with a %i byte FIFO present\n", i);
|
||||
|
||||
retv += PPA_PROBE_ECR;
|
||||
}
|
||||
/* ###### ##### #####
|
||||
* # # # # # #
|
||||
* # # # #
|
||||
* ###### ##### #####
|
||||
* # # #
|
||||
* # # # #
|
||||
* # ##### #######
|
||||
*/
|
||||
|
||||
no_ecp:
|
||||
if (retv & PPA_PROBE_ECR)
|
||||
outb(0x20, port + 0x402);
|
||||
|
||||
outb(0x55, port);
|
||||
outb(0x0c, port + 2);
|
||||
a = inb(port);
|
||||
outb(0x55, port);
|
||||
outb(0x2c, port + 2);
|
||||
b = inb(port);
|
||||
if (a != b) {
|
||||
DBG(DBG_SCAN, " PS/2 bidirectional port present\n");
|
||||
retv += PPA_PROBE_PS2;
|
||||
}
|
||||
/* ####### ###### ######
|
||||
* # # # # #
|
||||
* # # # # #
|
||||
* ##### ###### ######
|
||||
* # # #
|
||||
* # # #
|
||||
* ####### # #
|
||||
*/
|
||||
|
||||
if (port & 0x007) {
|
||||
DBG(DBG_SCAN, " EPP not supported at this address\n");
|
||||
return retv;
|
||||
}
|
||||
if (retv & PPA_PROBE_ECR) {
|
||||
for (i = 0x00; i < 0x80; i += 0x20) {
|
||||
outb(i, port + 0x402);
|
||||
|
||||
a = inb(port + 1);
|
||||
outb(a, port + 1);
|
||||
outb(a & 0xfe, port + 1);
|
||||
a = inb(port + 1);
|
||||
if (!(a & 0x01)) {
|
||||
DBG(DBG_SCAN, " Failed Intel bug check. (Phony EPP in ECP)\n");
|
||||
return retv;
|
||||
}
|
||||
}
|
||||
DBG(DBG_SCAN, " Passed Intel bug check.\n");
|
||||
outb(0x80, port + 0x402);
|
||||
}
|
||||
a = inb(port + 1);
|
||||
outb(a, port + 1);
|
||||
outb(a & 0xfe, port + 1);
|
||||
a = inb(port + 1);
|
||||
|
||||
if (a & 0x01) {
|
||||
outb(0x0c, port + 0x402);
|
||||
outb(0x0c, port + 0x002);
|
||||
return retv;
|
||||
}
|
||||
|
||||
outb(0x04, port + 2);
|
||||
inb(port + 4);
|
||||
a = inb(port + 1);
|
||||
outb(a, port + 1);
|
||||
outb(a & 0xfe, port + 1);
|
||||
|
||||
if (a & 0x01) {
|
||||
DBG(DBG_SCAN, " EPP 1.9 with hardware direction protocol\n");
|
||||
retv += PPA_PROBE_EPP19;
|
||||
} else {
|
||||
/* The EPP timeout bit was not set, this could either be:
|
||||
* EPP 1.7
|
||||
* EPP 1.9 with software direction
|
||||
*/
|
||||
outb(0x24, port + 2);
|
||||
inb(port + 4);
|
||||
a = inb(port + 1);
|
||||
outb(a, port + 1);
|
||||
outb(a & 0xfe, port + 1);
|
||||
if (a & 0x01) {
|
||||
DBG(DBG_SCAN, " EPP 1.9 with software direction protocol\n");
|
||||
retv += PPA_PROBE_EPP19;
|
||||
} else {
|
||||
DBG(DBG_SCAN, " EPP 1.7\n");
|
||||
retv += PPA_PROBE_EPP17;
|
||||
}
|
||||
}
|
||||
|
||||
outb(0x0c, port + 0x402);
|
||||
outb(0x0c, port + 0x002);
|
||||
#endif
|
||||
|
||||
return retv;
|
||||
}
|
||||
|
||||
#ifdef __KERNEL__
|
||||
/** will be called by the parport module when we already have access, but
|
||||
* another module wants access to the port...
|
||||
*/
|
||||
static int miscPreemptionCallback( pVoid data )
|
||||
{
|
||||
pScanData ps = (pScanData)data;
|
||||
|
||||
if( NULL != ps ) {
|
||||
|
||||
/* never release during scanning */
|
||||
if( ps->DataInf.dwScanFlag & _SCANNER_SCANNING ) {
|
||||
DBG( DBG_LOW, "no way!!!\n" );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* let the port go...*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** depending on the reported possible port modes, we try to set a faster mode
|
||||
* than SPP
|
||||
*/
|
||||
static int miscSetFastMode( pScanData ps )
|
||||
{
|
||||
UChar a, b;
|
||||
|
||||
/*
|
||||
* when previously found the EPP mode, break right here
|
||||
*/
|
||||
if (( _PORT_EPP == ps->IO.portMode ) && (!(port_feature & PARPORT_MODE_PCECR)))
|
||||
return _OK;
|
||||
|
||||
/* CHECK REMOVE: from here we should have SPP (Paranoia Code !) */
|
||||
if (( _PORT_SPP != ps->IO.portMode ) && (!(port_feature & PARPORT_MODE_PCECR)))
|
||||
return _OK;
|
||||
|
||||
DBG(DBG_LOW, "Trying faster mode...\n" );
|
||||
|
||||
/*
|
||||
* ECP mode usually has sub-modes of EPP and/or PS2.
|
||||
* First we try to set EPP
|
||||
*/
|
||||
if((port_feature & PARPORT_MODE_PCECR) &&
|
||||
(port_feature & PARPORT_MODE_PCECPEPP)){
|
||||
|
||||
DBG(DBG_LOW, "Attempting to set EPP from ECP mode.\n" );
|
||||
|
||||
a = _INB_ECTL(ps); /* get current ECR */
|
||||
ps->IO.lastPortMode = a; /* save it for restoring later */
|
||||
a = (a & 0x1F) | 0x80; /* set to EPP */
|
||||
_OUTB_ECTL(ps, a); /* write it back */
|
||||
_DO_UDELAY(1);
|
||||
|
||||
/*
|
||||
* It is probably unnecessary to
|
||||
* do this check but it makes me feel better
|
||||
*/
|
||||
b = _INB_ECTL(ps); /* check to see if port set */
|
||||
if( a == b ) {
|
||||
DBG( DBG_LOW, "Port is set to (ECP) EPP mode.\n" );
|
||||
ps->IO.portMode = _PORT_EPP;
|
||||
return _OK;
|
||||
|
||||
} else {
|
||||
DBG( DBG_LOW, "Port could not be set to (ECP) EPP mode. "
|
||||
"Using SPP mode.\n" );
|
||||
_OUTB_ECTL(ps,(Byte)ps->IO.lastPortMode); /* restore */
|
||||
_DO_UDELAY(1);
|
||||
ps->IO.portMode = _PORT_SPP;
|
||||
|
||||
/* go ahead and try with other settings...*/
|
||||
}
|
||||
}
|
||||
|
||||
/* If port cannot be set to EPP, try PS2 */
|
||||
if((port_feature & PARPORT_MODE_PCECR) &&
|
||||
(port_feature & PARPORT_MODE_PCECPPS2)) {
|
||||
|
||||
DBG(DBG_LOW, "Attempting to set PS2 from ECPPS2 mode.\n" );
|
||||
|
||||
a = _INB_ECTL(ps); /* get current ECR */
|
||||
ps->IO.lastPortMode = a; /* save it for restoring later */
|
||||
|
||||
/* set to Fast Centronics/bi-directional/PS2 */
|
||||
a = (a & 0x1F) | 0x20;
|
||||
_OUTB_ECTL(ps,a); /* write it back */
|
||||
_DO_UDELAY(1);
|
||||
|
||||
/*
|
||||
* It is probably unnecessary to do this check
|
||||
* but it makes me feel better
|
||||
*/
|
||||
b = _INB_ECTL(ps); /* check to see if port set */
|
||||
if (a == b) {
|
||||
DBG(DBG_LOW, "Port is set to (ECP) PS2 bidirectional mode.\n");
|
||||
ps->IO.portMode = _PORT_BIDI;
|
||||
return _OK;
|
||||
} else {
|
||||
DBG(DBG_LOW, "Port could not be set to (ECP) PS2 mode. "
|
||||
"Using SPP mode.\n");
|
||||
_OUTB_ECTL(ps,ps->IO.lastPortMode); /* restore */
|
||||
_DO_UDELAY(1);
|
||||
ps->IO.portMode = _PORT_SPP;
|
||||
|
||||
/* next mode, last attempt... */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Some BIOS/cards have only a Bi-directional/PS2 mode (no EPP).
|
||||
* Make one last attemp to set to PS2 mode.
|
||||
*/
|
||||
if ( port_feature & PARPORT_MODE_PCPS2 ){
|
||||
|
||||
DBG(DBG_LOW, "Attempting to set PS2 mode.\n" );
|
||||
|
||||
a = _INB_CTRL(ps); /* get current setting of control register*/
|
||||
ps->IO.lastPortMode = a; /* save it for restoring later */
|
||||
a = a | 0x20; /* set bit 5 of control reg */
|
||||
_OUTB_CTRL(ps,a); /* set to Fast Centronics/bi-directional/PS2 */
|
||||
_DO_UDELAY(1);
|
||||
a = 0;
|
||||
|
||||
_OUTB_DATA(ps,0x55);
|
||||
_DO_UDELAY(1);
|
||||
if ((inb(ps->IO.portBase)) != 0x55) /* read data */
|
||||
a++;
|
||||
|
||||
_OUTB_DATA(ps,0xAA);
|
||||
_DO_UDELAY(1);
|
||||
|
||||
if (_INB_DATA(ps) != 0xAA) /* read data */
|
||||
a++;
|
||||
|
||||
if (2 == a) {
|
||||
DBG(DBG_LOW, "Port is set to PS2 bidirectional mode.\n");
|
||||
ps->IO.portMode = _PORT_BIDI;
|
||||
return _OK;
|
||||
}
|
||||
else {
|
||||
DBG(DBG_LOW, "Port could not be set to PS2 mode. "
|
||||
"Using SPP mode.\n");
|
||||
_OUTB_CTRL(ps,(Byte)ps->IO.lastPortMode); /* restore */
|
||||
_DO_UDELAY(1);
|
||||
ps->IO.portMode = _PORT_SPP;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* reaching this point, we´re back in SPP mode and there´s no need
|
||||
* to restore at shutdown...
|
||||
*/
|
||||
ps->IO.lastPortMode = 0xFFFF;
|
||||
|
||||
return _OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** check the state of the par-port and switch to EPP-mode if possible
|
||||
*/
|
||||
static int miscSetPortMode( pScanData ps )
|
||||
{
|
||||
#ifndef __KERNEL__
|
||||
if (iopl(3)) {
|
||||
DBG( DBG_HIGH, "Could not unlock IO ports. Are you superuser?\n" );
|
||||
return _E_LOCK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* try to detect the port settings, SPP seems to work in any case !
|
||||
*/
|
||||
port_feature = initPortProbe( ps );
|
||||
|
||||
#ifdef DEBUG
|
||||
miscShowPortModes( port_feature );
|
||||
#endif
|
||||
|
||||
switch( ps->IO.forceMode ) {
|
||||
|
||||
case 1:
|
||||
DBG( DBG_LOW, "Use of SPP-mode enforced\n" );
|
||||
ps->IO.portMode = _PORT_SPP;
|
||||
return _OK;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
DBG( DBG_LOW, "Use of EPP-mode enforced\n" );
|
||||
ps->IO.portMode = _PORT_EPP;
|
||||
return _OK;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef __KERNEL__
|
||||
if( !(port_feature & PARPORT_MODE_PCEPP)) {
|
||||
|
||||
if( !(port_feature & PARPORT_MODE_PCSPP )) {
|
||||
_PRINT("\nThis Port supports not the SPP- or EPP-Mode\n" );
|
||||
_PRINT("Please activate SPP-Mode, EPP-Mode or\nEPP + ECP-Mode!\n");
|
||||
return _E_NOSUPP;
|
||||
} else {
|
||||
DBG(DBG_LOW, "Using SPP-mode\n" );
|
||||
ps->IO.portMode = _PORT_SPP;
|
||||
}
|
||||
#else
|
||||
if (!(port_feature & (PPA_PROBE_EPP17 | PPA_PROBE_EPP19))){
|
||||
|
||||
if( !(port_feature & PPA_PROBE_SPP )) {
|
||||
DBG(DBG_HIGH,"\nThis Port supports not the SPP- or EPP-Mode\n");
|
||||
DBG(DBG_HIGH,"Please activate SPP-Mode, EPP-Mode or\n"
|
||||
"EPP + ECP-Mode!\n");
|
||||
return _E_NOSUPP;
|
||||
} else {
|
||||
DBG(DBG_LOW, "Using SPP-mode\n" );
|
||||
ps->IO.portMode = _PORT_SPP;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
DBG(DBG_LOW, "Using EPP-mode\n" );
|
||||
ps->IO.portMode = _PORT_EPP;
|
||||
}
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/* else try to set to a faster mode than SPP */
|
||||
return miscSetFastMode( ps );
|
||||
#else
|
||||
return _OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** miscNextLongRand() -- generate 2**31-2 random numbers
|
||||
**
|
||||
** public domain by Ray Gardner
|
||||
**
|
||||
** based on "Random Number Generators: Good Ones Are Hard to Find",
|
||||
** S.K. Park and K.W. Miller, Communications of the ACM 31:10 (Oct 1988),
|
||||
** and "Two Fast Implementations of the 'Minimal Standard' Random
|
||||
** Number Generator", David G. Carta, Comm. ACM 33, 1 (Jan 1990), p. 87-88
|
||||
**
|
||||
** linear congruential generator f(z) = 16807 z mod (2 ** 31 - 1)
|
||||
**
|
||||
** uses L. Schrage's method to avoid overflow problems
|
||||
*/
|
||||
static Long miscNextLongRand( Long seed )
|
||||
{
|
||||
ULong lo, hi;
|
||||
|
||||
lo = _A * (Long)(seed & 0xFFFF);
|
||||
hi = _A * (Long)((ULong)seed >> 16);
|
||||
lo += (hi & 0x7FFF) << 16;
|
||||
if (lo > _M) {
|
||||
|
||||
lo &= _M;
|
||||
++lo;
|
||||
}
|
||||
lo += hi >> 15;
|
||||
if (lo > _M) {
|
||||
lo &= _M;
|
||||
++lo;
|
||||
}
|
||||
|
||||
return (Long)lo;
|
||||
}
|
||||
|
||||
/** initialize the random number generator
|
||||
*/
|
||||
static void miscSeedLongRand( ULong seed )
|
||||
{
|
||||
randomnum = seed ? (seed & _M) : 1; /* nonzero seed */
|
||||
}
|
||||
|
||||
/************************ exported functions *********************************/
|
||||
|
||||
/** allocate and initialize some memory for the scanner structure
|
||||
*/
|
||||
pScanData MiscAllocAndInitStruct( void )
|
||||
{
|
||||
pScanData ps;
|
||||
|
||||
ps = (pScanData)_KALLOC(sizeof(ScanData), GFP_KERNEL);
|
||||
|
||||
if( NULL != ps ) {
|
||||
MiscReinitStruct( ps );
|
||||
}
|
||||
|
||||
DBG( DBG_HIGH, "ScanData = 0x%08lx\n", (ULong)ps );
|
||||
|
||||
return ps;
|
||||
}
|
||||
|
||||
/** re-initialize the memory for the scanner structure
|
||||
*/
|
||||
int MiscReinitStruct( pScanData ps )
|
||||
{
|
||||
if( NULL == ps )
|
||||
return _E_NULLPTR;
|
||||
|
||||
memset( ps, 0, sizeof(ScanData));
|
||||
|
||||
/*
|
||||
* first init all constant stuff in ScanData
|
||||
*/
|
||||
ps->sCaps.Version = ((_PTDRV_V1 << 8) | _PTDRV_V0);
|
||||
|
||||
ps->bCurrentSpeed = 1;
|
||||
ps->sCaps.wLens = 1; /* set wNumberOfLens */
|
||||
|
||||
ps->pbMapRed = ps->a_bMapTable;
|
||||
ps->pbMapGreen = &ps->a_bMapTable[256];
|
||||
ps->pbMapBlue = &ps->a_bMapTable[512];
|
||||
ps->sCaps.wIOBase = _NO_BASE;
|
||||
|
||||
/* use memory address to seed the generator */
|
||||
miscSeedLongRand((Long)ps);
|
||||
|
||||
DBG( DBG_HIGH, "Init settings done\n" );
|
||||
|
||||
return _OK;
|
||||
}
|
||||
|
||||
/** in USER-Mode: probe the specified port and try to get the port-mode
|
||||
* in KERNEL-Mode: only use the modes, the driver returns
|
||||
*/
|
||||
int MiscInitPorts( pScanData ps, int port )
|
||||
{
|
||||
int status;
|
||||
|
||||
if( NULL == ps )
|
||||
return _E_NULLPTR;
|
||||
|
||||
/*
|
||||
* Get access to the ports
|
||||
*/
|
||||
ps->IO.portBase = (UShort)port;
|
||||
|
||||
status = miscSetPortMode(ps);
|
||||
|
||||
if( _OK != status ) {
|
||||
ps->sCaps.wIOBase = _NO_BASE;
|
||||
ps->IO.portBase = _NO_BASE;
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* the port settings
|
||||
*/
|
||||
ps->IO.pbSppDataPort = (UShort)port;
|
||||
ps->IO.pbStatusPort = (UShort)port+1;
|
||||
ps->IO.pbControlPort = (UShort)port+2;
|
||||
ps->IO.pbEppDataPort = (UShort)port+_EPPDATA_PORT;
|
||||
|
||||
return _OK;
|
||||
}
|
||||
|
||||
/** here we restore the port
|
||||
*/
|
||||
void MiscRestorePort( pScanData ps )
|
||||
{
|
||||
if( 0 == ps->IO.pbSppDataPort )
|
||||
return;
|
||||
|
||||
DBG(DBG_LOW,"MiscRestorePort()\n");
|
||||
|
||||
/* don´t restore if not necessary */
|
||||
if( 0xFFFF == ps->IO.lastPortMode ) {
|
||||
DBG(DBG_LOW,"- no need to restore portmode !\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*Restore Port-Mode*/
|
||||
#ifdef __KERNEL__
|
||||
if (port_feature & PARPORT_MODE_PCECR ){
|
||||
_OUTB_ECTL( ps, (Byte)ps->IO.lastPortMode );
|
||||
_DO_UDELAY(1);
|
||||
} else {
|
||||
_OUTB_CTRL( ps, (Byte)ps->IO.lastPortMode );
|
||||
_DO_UDELAY(1);
|
||||
}
|
||||
#else
|
||||
if (port_feature & PPA_PROBE_ECR ){
|
||||
outb( ps->IO.lastPortMode, ps->IO.pbSppDataPort + 0x402);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** starts a timer
|
||||
*/
|
||||
inline void MiscStartTimer( pTimerDef timer , unsigned long us)
|
||||
{
|
||||
struct timeval start_time;
|
||||
|
||||
#ifdef __KERNEL__
|
||||
_GET_TIME( &start_time );
|
||||
#else
|
||||
gettimeofday(&start_time, NULL);
|
||||
#endif
|
||||
|
||||
*timer = start_time.tv_sec * 1e6 + start_time.tv_usec + us;
|
||||
}
|
||||
|
||||
/** checks for timeout
|
||||
*/
|
||||
inline int MiscCheckTimer( pTimerDef timer )
|
||||
{
|
||||
struct timeval current_time;
|
||||
|
||||
#ifdef __KERNEL__
|
||||
_GET_TIME( ¤t_time );
|
||||
#else
|
||||
gettimeofday(¤t_time, NULL);
|
||||
#endif
|
||||
|
||||
if (current_time.tv_sec * 1e6 + current_time.tv_usec > *timer) {
|
||||
return _E_TIMEOUT;
|
||||
} else {
|
||||
#ifdef __KERNEL__
|
||||
schedule();
|
||||
#else
|
||||
sched_yield();
|
||||
#endif
|
||||
return _OK;
|
||||
}
|
||||
}
|
||||
|
||||
/** checks the function pointers
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
Bool MiscAllPointersSet( pScanData ps )
|
||||
{
|
||||
ULong i;
|
||||
pULong ptr;
|
||||
|
||||
for( ptr = (pULong)&ps->OpenScanPath, i = 1;
|
||||
ptr <= (pULong)&ps->ReadOneImageLine; ptr++, i++ ) {
|
||||
|
||||
if( NULL == (pVoid)*ptr ) {
|
||||
DBG( DBG_HIGH, "Function pointer not set (pos = %lu) !\n", i );
|
||||
return _FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return _TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** registers this driver to use port "portAddr" (KERNEL-Mode only)
|
||||
*/
|
||||
int MiscRegisterPort( pScanData ps, int portAddr )
|
||||
{
|
||||
#ifndef __KERNEL__
|
||||
int i;
|
||||
Bool found;
|
||||
ULong pref[] = { 0x378, 0x278, 0x3bc, 0xFFFFFFFF };
|
||||
|
||||
DBG( DBG_LOW, "Requested port at 0x%02x\n", portAddr );
|
||||
_VAR_NOT_USED( ps );
|
||||
|
||||
/*
|
||||
* check the port address !!!!
|
||||
*/
|
||||
found = _FALSE;
|
||||
for( i = 0; 0xFFFFFFFF != pref[i]; i++ ) {
|
||||
|
||||
if(((ULong)portAddr != 0xFFFFFFFF) && (pref[i] == (ULong)portAddr)) {
|
||||
found = _TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !found )
|
||||
return _E_INVALID;
|
||||
#else
|
||||
struct parport *pp;
|
||||
|
||||
DBG( DBG_LOW, "Requested port at 0x%02x\n", portAddr );
|
||||
|
||||
pp = parport_enumerate();
|
||||
ps->pardev = NULL;
|
||||
|
||||
if( NULL == pp ) {
|
||||
return _E_PORTSEARCH;
|
||||
}
|
||||
|
||||
/*
|
||||
* go through the list
|
||||
*/
|
||||
for( ps->pp = NULL; NULL != pp; ) {
|
||||
|
||||
if( pp->base == portAddr ) {
|
||||
DBG( DBG_LOW, "Requested port (0x%02x) found\n", portAddr );
|
||||
DBG( DBG_LOW, "Port mode reported: (0x%04x)\n", pp->modes );
|
||||
ps->pp = pp;
|
||||
break;
|
||||
}
|
||||
|
||||
pp = pp->next;
|
||||
}
|
||||
|
||||
if( NULL == ps->pp ) {
|
||||
return _E_NO_PORT;
|
||||
}
|
||||
|
||||
/*
|
||||
* register this device
|
||||
*/
|
||||
ps->pardev = parport_register_device( ps->pp, "Plustek Driver",
|
||||
miscPreemptionCallback, NULL, NULL, 0, (pVoid)ps );
|
||||
|
||||
if( NULL == ps->pardev ) {
|
||||
return _E_REGISTER;
|
||||
}
|
||||
|
||||
DBG( DBG_LOW, "Port for device %lu registered\n", ps->devno );
|
||||
#endif
|
||||
|
||||
portIsClaimed[ps->devno] = 0;
|
||||
|
||||
return _OK;
|
||||
}
|
||||
|
||||
/** unregisters the port from driver (KERNEL-Mode only)
|
||||
*/
|
||||
void MiscUnregisterPort( pScanData ps )
|
||||
{
|
||||
#ifdef __KERNEL__
|
||||
if( NULL != ps->pardev ) {
|
||||
DBG( DBG_LOW, "Port unregistered\n" );
|
||||
parport_unregister_device( ps->pardev );
|
||||
}
|
||||
#else
|
||||
_VAR_NOT_USED( ps );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* try to claim the port (KERNEL-Mode only)
|
||||
*/
|
||||
int MiscClaimPort( pScanData ps )
|
||||
{
|
||||
#ifdef __KERNEL__
|
||||
if( 0 == portIsClaimed[ps->devno] ) {
|
||||
|
||||
DBG( DBG_HIGH, "Try to claim the parport\n" );
|
||||
if( 0 != parport_claim( ps->pardev ))
|
||||
return _E_BUSY;
|
||||
}
|
||||
#endif
|
||||
portIsClaimed[ps->devno]++;
|
||||
|
||||
return _OK;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* release previously claimed port (KERNEL-Mode only)
|
||||
*/
|
||||
void MiscReleasePort( pScanData ps )
|
||||
{
|
||||
if( portIsClaimed[ps->devno] > 0 ) {
|
||||
portIsClaimed[ps->devno]--;
|
||||
|
||||
#ifdef __KERNEL__
|
||||
if( 0 == portIsClaimed[ps->devno] ) {
|
||||
DBG( DBG_HIGH, "Releasing parport\n" );
|
||||
parport_release( ps->pardev );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* get random number
|
||||
*/
|
||||
Long MiscLongRand( void )
|
||||
{
|
||||
randomnum = miscNextLongRand( randomnum );
|
||||
|
||||
return randomnum;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* according to the id, the function returns a pointer to the model name
|
||||
*/
|
||||
const char *MiscGetModelName( UShort id )
|
||||
{
|
||||
DBG( DBG_HIGH, "MiscGetModelName - id = %i\n", id );
|
||||
|
||||
if( MODEL_OP_PT12 < id )
|
||||
return ModelStr[0];
|
||||
|
||||
return ModelStr[id];
|
||||
}
|
||||
|
||||
/* END PLUSTEK-PP_MISC.C ....................................................*/
|
|
@ -0,0 +1,611 @@
|
|||
/*.............................................................................
|
||||
* Project : linux driver for Plustek parallel-port scanners
|
||||
*.............................................................................
|
||||
* File: plustek-pp_models.c - model specific stuff
|
||||
*.............................................................................
|
||||
*
|
||||
* based on sources acquired from Plustek Inc.
|
||||
* Copyright (C) 1998 Plustek Inc.
|
||||
* Copyright (C) 2000-2003 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
* also based on the work done by Rick Bronson
|
||||
*.............................................................................
|
||||
* History:
|
||||
* 0.30 - initial version
|
||||
* 0.31 - no changes
|
||||
* 0.32 - no changes
|
||||
* 0.33 - no changes
|
||||
* 0.34 - no changes
|
||||
* 0.35 - added some comments
|
||||
* did some fine tuning on the 9630P and 12000P/9600P models
|
||||
* moved function initPageSettings() to this module
|
||||
* 0.36 - as the ps->MaxWideLineBlks and ps->MaxWideLineLen are only used
|
||||
* for the OP 4800, it has been removed from pScanData
|
||||
* changed settings of OP600 according to the Primax Direct 4800 tests
|
||||
* removed dwPreferSize from struct ScannerCaps
|
||||
* fixed the 5seconds bed-hit problem for ASIC 96001/3 based models
|
||||
* changes, due to define renaming
|
||||
* 0.37 - added ButtonCount init
|
||||
* added A3I model
|
||||
* added functions modelInitCaps(), modelInitMotor() and
|
||||
* modelSetBufferSizes()
|
||||
* 0.38 - added P12 stuff
|
||||
* code cleanup
|
||||
* 0.39 - no changes
|
||||
* 0.40 - changed back to build 0.39-3 (disabled A3I stuff)
|
||||
* 0.41 - added _OVR_PLUSTEK_4800P switch
|
||||
* 0.42 - added SFLAG_CUSTOM_GAMMA to capabilities
|
||||
* added _OVR_PRIMAX_4800D30 switch
|
||||
* changed include names
|
||||
*
|
||||
*.............................................................................
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include "plustek-pp_scan.h"
|
||||
|
||||
/*************************** local functions *********************************/
|
||||
|
||||
/*.............................................................................
|
||||
* initialize the extension according to the page size...
|
||||
*/
|
||||
static void modelInitPageSettings( pScanData ps )
|
||||
{
|
||||
DBG(DBG_LOW, "modelInitPageSettings()\n" );
|
||||
|
||||
if( MODEL_OP_9630PL == ps->sCaps.Model )
|
||||
ps->dwScannerSize = _SCANSIZE_LEGAL;
|
||||
else if( MODEL_OP_A3I == ps->sCaps.Model )
|
||||
ps->dwScannerSize = _SCANSIZE_A3;
|
||||
else
|
||||
ps->dwScannerSize = _SCANSIZE_A4;
|
||||
|
||||
/* default width for all but A3 - 8.5"* 300dpi (_MEASURE_BASE) */
|
||||
ps->sCaps.wMaxExtentX = 2550;
|
||||
|
||||
/* this applies to all scanners but the A3 model */
|
||||
ps->LensInf.rExtentX.wMin = 150;
|
||||
ps->LensInf.rExtentX.wDef = 2550;
|
||||
ps->LensInf.rExtentX.wMax = 2550;
|
||||
ps->LensInf.rExtentX.wPhyMax = 2500;
|
||||
|
||||
ps->LensInf.rExtentY.wMin = 150;
|
||||
|
||||
ps->LensInf.wBeginX = 0;
|
||||
ps->LensInf.wBeginY = 0;
|
||||
|
||||
switch( ps->dwScannerSize ) {
|
||||
|
||||
case _SCANSIZE_A4:
|
||||
/* 11.69 inches */
|
||||
DBG( DBG_LOW, "A4 set\n" );
|
||||
ps->sCaps.wMaxExtentY =
|
||||
ps->LensInf.rExtentY.wDef =
|
||||
ps->LensInf.rExtentY.wMax =
|
||||
ps->LensInf.rExtentY.wPhyMax = _MEASURE_BASE * 11.6934;
|
||||
break;
|
||||
|
||||
case _SCANSIZE_A3:
|
||||
/* 17 inches */
|
||||
DBG( DBG_LOW, "A3 set\n" );
|
||||
ps->sCaps.wMaxExtentY =
|
||||
ps->LensInf.rExtentY.wMax =
|
||||
ps->LensInf.rExtentY.wDef =
|
||||
ps->LensInf.rExtentY.wPhyMax = _MEASURE_BASE * 17;
|
||||
|
||||
/* _MEASURE_BASE * 11.69 */
|
||||
ps->sCaps.wMaxExtentX =
|
||||
ps->LensInf.rExtentX.wDef =
|
||||
ps->LensInf.rExtentX.wMax = 3507;
|
||||
ps->LensInf.rExtentX.wPhyMax = 3500;
|
||||
break;
|
||||
|
||||
case _SCANSIZE_LETTER:
|
||||
/* 11 inches */
|
||||
DBG( DBG_LOW, "Letter set\n" );
|
||||
ps->sCaps.wMaxExtentY =
|
||||
ps->LensInf.rExtentY.wDef =
|
||||
ps->LensInf.rExtentY.wMax =
|
||||
ps->LensInf.rExtentY.wPhyMax = _MEASURE_BASE * 11;
|
||||
break;
|
||||
|
||||
case _SCANSIZE_LEGAL:
|
||||
/* 14 inches */
|
||||
DBG( DBG_LOW, "Legal set\n" );
|
||||
ps->sCaps.wMaxExtentY =
|
||||
ps->LensInf.rExtentY.wDef =
|
||||
ps->LensInf.rExtentY.wMax =
|
||||
ps->LensInf.rExtentY.wPhyMax = _MEASURE_BASE * 14;
|
||||
}
|
||||
|
||||
/*
|
||||
* add this value to avoid the problems in binary mode
|
||||
*/
|
||||
ps->LensInf.rExtentY.wMax += 64;
|
||||
|
||||
/* set the DPI stuff */
|
||||
ps->LensInf.rDpiX.wMin = 16;
|
||||
ps->LensInf.rDpiX.wDef = 50;
|
||||
ps->LensInf.rDpiX.wMax = (ps->PhysicalDpi * 16);
|
||||
ps->LensInf.rDpiX.wPhyMax = ps->PhysicalDpi;
|
||||
ps->LensInf.rDpiY.wMin = 16;
|
||||
ps->LensInf.rDpiY.wDef = 50;
|
||||
ps->LensInf.rDpiY.wMax = (ps->PhysicalDpi * 16);
|
||||
ps->LensInf.rDpiY.wPhyMax = (ps->PhysicalDpi * 2);
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* set the scanner capabilities
|
||||
*/
|
||||
static void modelInitCaps( pScanData ps )
|
||||
{
|
||||
if( _ASIC_IS_96001 == ps->sCaps.AsicID )
|
||||
ps->sCaps.dwBits = _BITS_8;
|
||||
else
|
||||
ps->sCaps.dwBits = _BITS_10;
|
||||
|
||||
ps->sCaps.rDataType.wMin = 0;
|
||||
ps->sCaps.rDataType.wDef = COLOR_TRUE24;
|
||||
ps->sCaps.rDataType.wMax = COLOR_TRUE24;
|
||||
ps->sCaps.rDataType.wPhyMax = COLOR_TRUE24;
|
||||
ps->sCaps.wIOBase = _NO_BASE;
|
||||
ps->sCaps.wLens = 1;
|
||||
ps->sCaps.dwFlag = (SFLAG_SCANNERDEV +
|
||||
SFLAG_FLATBED + SFLAG_CUSTOM_GAMMA);
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* set the motor stuff
|
||||
*/
|
||||
static void modelInitMotor( pScanData ps )
|
||||
{
|
||||
if( _ASIC_IS_96001 == ps->sCaps.AsicID ) {
|
||||
ps->FullStep = _MotorFullStep96001;
|
||||
ps->MotorOn = _MotorOn96001;
|
||||
ps->IgnorePF = _MotorIgnorePF96001;
|
||||
ps->StepMask = ~ps->FullStep;
|
||||
} else {
|
||||
ps->FullStep = _Motor1FullStep;
|
||||
ps->MotorOn = _MotorOn;
|
||||
ps->IgnorePF = _MotorIgnorePF;
|
||||
ps->StepMask = _MotorStepMask;
|
||||
}
|
||||
|
||||
ps->BackwardSteps = 4000;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* according to the models' capabilities, set the buffer stuff
|
||||
*/
|
||||
static void modelSetBufferSizes( pScanData ps )
|
||||
{
|
||||
/* should depend on the scan-area !!!! */
|
||||
if( 400 == ps->PhysicalDpi ) {
|
||||
|
||||
/* assuming a A3I */
|
||||
ps->BufferSizeBase = 3517;
|
||||
ps->BufferForColorRunTable = (5500 * 4); /* might be 17" * 800dpi !!! */
|
||||
|
||||
} else if( 600 == ps->PhysicalDpi ) {
|
||||
|
||||
ps->BufferSizeBase = 2560;
|
||||
ps->BufferForColorRunTable = (5500 * 4);
|
||||
|
||||
} else {
|
||||
ps->BufferSizeBase = 1280;
|
||||
ps->BufferForColorRunTable = 9000;
|
||||
}
|
||||
|
||||
ps->BufferSizePerModel = ps->BufferSizeBase * 2;
|
||||
ps->BufferForDataRead1 = ps->BufferSizePerModel * 3;
|
||||
|
||||
/* patch that for the 600 DPI models OP9630 etc.*/
|
||||
if(( 300 != ps->PhysicalDpi) && (_ASIC_IS_96003 == ps->sCaps.AsicID))
|
||||
ps->BufferForDataRead1 += 300;
|
||||
|
||||
ps->BufferFor1stColor = (ps->BufferSizePerModel * 17);
|
||||
ps->BufferFor2ndColor = (ps->BufferSizePerModel * 9);
|
||||
ps->TotalBufferRequire = (ps->BufferFor1stColor +
|
||||
ps->BufferFor2ndColor +
|
||||
ps->BufferForDataRead1 +
|
||||
ps->BufferForColorRunTable );
|
||||
}
|
||||
|
||||
/************************ exported functions *********************************/
|
||||
|
||||
/*.............................................................................
|
||||
* set the model to 4800
|
||||
*/
|
||||
void ModelSet4800( pScanData ps )
|
||||
{
|
||||
DBG( DBG_LOW, "ModelSet4800()\n" );
|
||||
|
||||
/* has 96001 ASIC */
|
||||
ps->sCaps.AsicID = _ASIC_IS_96001;
|
||||
ps->sCaps.Model = MODEL_OP_4800P;
|
||||
ps->Device.buttons = 0;
|
||||
ps->Device.ModelCtrl = (_ModelDpi300 | _ModelMemSize32k96001 | _ModelWhiteIs0);
|
||||
ps->Device.DataOriginX = 72;
|
||||
|
||||
ps->PhysicalDpi = 300;
|
||||
ps->TimePerLine = 0x30;
|
||||
ps->Offset70 = 70;
|
||||
|
||||
modelSetBufferSizes( ps );
|
||||
|
||||
ps->a_wGrayInitTime[0] = 220; /* _EppTimeForOthers */
|
||||
ps->a_wGrayInitTime[1] = 720; /* _SppTimeForOthers */
|
||||
ps->a_wGrayInitTime[2] = 360; /* _BidirTimeForOthers */
|
||||
ps->a_wColorInitTime[0] = 500; /* _EppTimeForColor */
|
||||
ps->a_wColorInitTime[1] = 1680; /* _SppTimeForColor */
|
||||
ps->a_wColorInitTime[2] = 1100; /* _BidirTimeForColor */
|
||||
|
||||
ps->AsicRedColor = _ASIC_REDCOLOR;
|
||||
ps->AsicGreenColor = _ASIC_GREENCOLOR;
|
||||
ps->RedDataReady = _RED_DATA_READY;
|
||||
ps->GreenDataReady = _GREEN_DATA_READY;
|
||||
|
||||
/*
|
||||
* used for shading stuff (see dac.c)
|
||||
*/
|
||||
ps->FBKScanLineBlks = 5;
|
||||
ps->FBKScanLineLenBase = 1024;
|
||||
ps->FBKScanLineLen = (ps->FBKScanLineLenBase * 3);
|
||||
|
||||
ps->ShadingBufferSize = ps->FBKScanLineLen;
|
||||
ps->ShadingBankSize = (ps->FBKScanLineLenBase * 4);
|
||||
ps->ShadingBankRed = (_MemBankSize4k96001 | 0x3a);
|
||||
ps->ShadingBankGreen = (_MemBankSize4k96001 | 0x3e);
|
||||
ps->ShadingBankBlue = (_MemBankSize4k96001 | 0x3c);
|
||||
ps->ShadingScanLineBlks = 6;
|
||||
ps->ShadingScanLineLen = (ps->BufferSizeBase * 3);
|
||||
ps->OneScanLineLen = (ps->BufferSizePerModel * 3);
|
||||
|
||||
modelInitMotor( ps );
|
||||
modelInitCaps ( ps );
|
||||
modelInitPageSettings( ps );
|
||||
|
||||
DBG( DBG_LOW, "ModelSet4800() done.\n" );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* set the model to 4830
|
||||
*/
|
||||
void ModelSet4830( pScanData ps )
|
||||
{
|
||||
DBG( DBG_LOW, "ModelSet4830()\n" );
|
||||
|
||||
/* has 96003 ASIC */
|
||||
ps->sCaps.Model = MODEL_OP_4830P;
|
||||
if( _OVR_PRIMAX_4800D30 == ps->ModelOverride ) {
|
||||
DBG( DBG_LOW, "Model Override --> Primax 4800D 30\n" );
|
||||
ps->sCaps.Model = MODEL_PMX_4800D3;
|
||||
}
|
||||
ps->sCaps.AsicID = _ASIC_IS_96003;
|
||||
ps->Device.buttons = 1;
|
||||
ps->Device.ModelCtrl = (_ModelDpi300 | _ModelMemSize32k3 | _ModelWhiteIs0);
|
||||
ps->Device.DataOriginX = 72;
|
||||
|
||||
ps->PhysicalDpi = 300;
|
||||
ps->TimePerLine = 0x30;
|
||||
ps->Offset70 = 70;
|
||||
|
||||
modelSetBufferSizes( ps );
|
||||
|
||||
ps->a_wGrayInitTime[0] = 220; /* _EppTimeForOthers */
|
||||
ps->a_wGrayInitTime[1] = 720; /* _SppTimeForOthers */
|
||||
ps->a_wGrayInitTime[2] = 360; /* _BidirTimeForOthers */
|
||||
ps->a_wColorInitTime[0] = 500; /* _EppTimeForColor */
|
||||
ps->a_wColorInitTime[1] = 1680; /* _SppTimeForColor */
|
||||
ps->a_wColorInitTime[2] = 1100; /* _BidirTimeForColor */
|
||||
|
||||
ps->AsicRedColor = _ASIC_REDCOLOR;
|
||||
ps->AsicGreenColor = _ASIC_GREENCOLOR;
|
||||
ps->RedDataReady = _RED_DATA_READY;
|
||||
ps->GreenDataReady = _GREEN_DATA_READY;
|
||||
|
||||
/*
|
||||
* used for shading stuff (see dac.c)
|
||||
*/
|
||||
ps->FBKScanLineBlks = 5;
|
||||
ps->FBKScanLineLenBase = 1024;
|
||||
ps->FBKScanLineLen = (ps->FBKScanLineLenBase * 3);
|
||||
|
||||
ps->ShadingBufferSize = ps->FBKScanLineLen;
|
||||
ps->ShadingBankSize = (ps->FBKScanLineLenBase * 4);
|
||||
ps->ShadingBankRed = (_MemBankSize4k | 0x3a);
|
||||
ps->ShadingBankGreen = (_MemBankSize4k | 0x3e);
|
||||
ps->ShadingBankBlue = (_MemBankSize4k | 0x3c);
|
||||
ps->ShadingScanLineBlks = 6;
|
||||
ps->ShadingScanLineLen = (ps->BufferSizeBase * 3);
|
||||
ps->OneScanLineLen = (ps->BufferSizePerModel * 3);
|
||||
|
||||
modelInitMotor( ps );
|
||||
modelInitCaps ( ps );
|
||||
modelInitPageSettings( ps );
|
||||
|
||||
DBG( DBG_LOW, "ModelSet4830() done.\n" );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* set the model to 600, tested on a Primax Direct 4800 and OP600
|
||||
*/
|
||||
void ModelSet600( pScanData ps )
|
||||
{
|
||||
DBG( DBG_LOW, "ModelSet600()\n" );
|
||||
|
||||
/*
|
||||
* set to 4830 first, then do the differences
|
||||
*/
|
||||
ModelSet4830( ps );
|
||||
ps->Device.buttons = 0;
|
||||
|
||||
if( _OVR_PLUSTEK_4800P == ps->ModelOverride ) {
|
||||
|
||||
DBG( DBG_LOW, "Model Override --> OpticPro4800\n" );
|
||||
ps->sCaps.Model = MODEL_OP_4800P;
|
||||
|
||||
} else if( _OVR_PRIMAX_4800D == ps->ModelOverride ) {
|
||||
|
||||
DBG( DBG_LOW, "Model Override --> Primax 4800D\n" );
|
||||
ps->sCaps.Model = MODEL_PMX_4800D;
|
||||
|
||||
} else {
|
||||
|
||||
ps->sCaps.Model = MODEL_OP_600P;
|
||||
|
||||
/* for Plustek OpticPro 600P it's necessary to swap Red and Green
|
||||
* changed by mh moloch@nikocity.de
|
||||
*/
|
||||
ps->AsicRedColor = _ASIC_GREENCOLOR;
|
||||
ps->AsicGreenColor = _ASIC_REDCOLOR;
|
||||
}
|
||||
|
||||
DBG( DBG_LOW, "ModelSet600() done.\n" );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* set the model to 12000P, 96000P (tested on a OP96000P)
|
||||
*/
|
||||
void ModelSet12000( pScanData ps )
|
||||
{
|
||||
DBG( DBG_LOW, "ModelSet12000()\n" );
|
||||
|
||||
/*
|
||||
* set to 9630 first, then do the differences
|
||||
*/
|
||||
ModelSet9630( ps );
|
||||
ps->Device.buttons = 0;
|
||||
ps->sCaps.Model = MODEL_OP_12000P;
|
||||
|
||||
/*
|
||||
* swapped Red and Green for 12000P/96000P
|
||||
*/
|
||||
ps->AsicRedColor = _ASIC_GREENCOLOR;
|
||||
ps->AsicGreenColor = _ASIC_REDCOLOR;
|
||||
ps->RedDataReady = _GREEN_DATA_READY;
|
||||
ps->GreenDataReady = _RED_DATA_READY;
|
||||
|
||||
DBG( DBG_LOW, "ModelSet12000() done.\n" );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* set the model to A3I
|
||||
*/
|
||||
void ModelSetA3I( pScanData ps )
|
||||
{
|
||||
DBG( DBG_LOW, "ModelSetA3I()\n" );
|
||||
|
||||
/*
|
||||
* has 96003 ASIC
|
||||
*/
|
||||
ps->Device.buttons = 1;
|
||||
ps->sCaps.Model = MODEL_OP_A3I;
|
||||
ps->sCaps.AsicID = _ASIC_IS_96003;
|
||||
|
||||
ps->Device.ModelCtrl = (_ModelDpi400 | _ModelMemSize128k4 | _ModelWhiteIs0);
|
||||
ps->Device.DataOriginX = 164;
|
||||
|
||||
ps->PhysicalDpi = 400;
|
||||
ps->TimePerLine = 0x50;
|
||||
ps->Offset70 = 145;
|
||||
|
||||
modelSetBufferSizes( ps );
|
||||
|
||||
ps->a_wGrayInitTime[0] = 133; /* _EppTimeForOthers */
|
||||
ps->a_wGrayInitTime[1] = 720; /* _SppTimeForOthers */
|
||||
ps->a_wGrayInitTime[2] = 300; /* _BidirTimeForOthers */
|
||||
ps->a_wColorInitTime[0] = 400; /* _EppTimeForColor */
|
||||
ps->a_wColorInitTime[1] = 1800; /* _SppTimeForColor */
|
||||
ps->a_wColorInitTime[2] = 800; /* _BidirTimeForColor */
|
||||
|
||||
ps->AsicRedColor = _ASIC_GREENCOLOR;
|
||||
ps->AsicGreenColor = _ASIC_REDCOLOR;
|
||||
ps->RedDataReady = _GREEN_DATA_READY;
|
||||
ps->GreenDataReady = _RED_DATA_READY;
|
||||
|
||||
ps->FBKScanLineBlks = 10;
|
||||
ps->FBKScanLineLenBase = 2048;
|
||||
ps->FBKScanLineLen = (ps->FBKScanLineLenBase * 3);
|
||||
|
||||
ps->ShadingBufferSize = (1024 * 7);
|
||||
ps->ShadingBankSize = 8192;
|
||||
ps->ShadingBankRed = (_MemBankSize8k | 0x34);
|
||||
ps->ShadingBankGreen = (_MemBankSize8k | 0x3c);
|
||||
ps->ShadingBankBlue = (_MemBankSize8k | 0x38);
|
||||
ps->ShadingScanLineBlks = 10;
|
||||
ps->ShadingScanLineLen = (ps->BufferSizeBase * 3);
|
||||
ps->OneScanLineLen = (ps->ShadingScanLineLen * 2);
|
||||
|
||||
modelInitMotor( ps );
|
||||
ps->BackwardSteps = 9000;
|
||||
|
||||
modelInitCaps( ps );
|
||||
modelInitPageSettings( ps );
|
||||
|
||||
/*
|
||||
* need to double the vals
|
||||
*/
|
||||
ps->LensInf.rExtentX.wMax *= 2;
|
||||
ps->LensInf.rExtentX.wPhyMax *= 2;
|
||||
ps->LensInf.rExtentY.wMax *= 2;
|
||||
ps->LensInf.rExtentY.wPhyMax *= 2;
|
||||
|
||||
DBG( DBG_LOW, "ModelSetA3I() done.\n" );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* set the model to 9630
|
||||
*/
|
||||
void ModelSet9630( pScanData ps )
|
||||
{
|
||||
DBG( DBG_LOW, "ModelSet9360()\n" );
|
||||
|
||||
/*
|
||||
* has 96003 ASIC
|
||||
*/
|
||||
if( _OVR_PLUSTEK_9630PL == ps->ModelOverride ) {
|
||||
DBG( DBG_LOW, "Model Override --> 9630PL\n" );
|
||||
ps->sCaps.Model = MODEL_OP_9630PL;
|
||||
} else {
|
||||
ps->sCaps.Model = MODEL_OP_9630P;
|
||||
}
|
||||
|
||||
ps->Device.buttons = 1;
|
||||
ps->sCaps.AsicID = _ASIC_IS_96003;
|
||||
|
||||
ps->Device.ModelCtrl = (_ModelDpi600 | _ModelMemSize128k4 | _ModelWhiteIs0);
|
||||
ps->Device.DataOriginX = 64;
|
||||
|
||||
ps->PhysicalDpi = 600;
|
||||
ps->TimePerLine = 0x5a;
|
||||
ps->Offset70 = 95;
|
||||
|
||||
modelSetBufferSizes( ps );
|
||||
|
||||
ps->a_wGrayInitTime[0] = 133; /* _EppTimeForOthers */
|
||||
ps->a_wGrayInitTime[1] = 720; /* _SppTimeForOthers */
|
||||
ps->a_wGrayInitTime[2] = 300; /* _BidirTimeForOthers */
|
||||
ps->a_wColorInitTime[0] = 400; /* _EppTimeForColor */
|
||||
ps->a_wColorInitTime[1] = 1800; /* _SppTimeForColor */
|
||||
ps->a_wColorInitTime[2] = 800; /* _BidirTimeForColor */
|
||||
|
||||
ps->AsicRedColor = _ASIC_REDCOLOR;
|
||||
ps->AsicGreenColor = _ASIC_GREENCOLOR;
|
||||
ps->RedDataReady = _RED_DATA_READY;
|
||||
ps->GreenDataReady = _GREEN_DATA_READY;
|
||||
|
||||
ps->ShadingBufferSize = (1024 * 7);
|
||||
ps->ShadingBankSize = 8192;
|
||||
ps->ShadingBankRed = (_MemBankSize8k | 0x34);
|
||||
ps->ShadingBankGreen = (_MemBankSize8k | 0x3c);
|
||||
ps->ShadingBankBlue = (_MemBankSize8k | 0x38);
|
||||
ps->ShadingScanLineBlks = 10;
|
||||
ps->ShadingScanLineLen = (2560 * 3);
|
||||
|
||||
ps->FBKScanLineBlks = 10;
|
||||
ps->FBKScanLineLenBase = 2048;
|
||||
ps->FBKScanLineLen = (ps->FBKScanLineLenBase * 6);
|
||||
|
||||
ps->OneScanLineLen = (5120 * 3);
|
||||
|
||||
modelInitMotor( ps );
|
||||
ps->BackwardSteps = 9000;
|
||||
|
||||
modelInitCaps( ps );
|
||||
modelInitPageSettings( ps );
|
||||
|
||||
/*
|
||||
* need to double the vals
|
||||
*/
|
||||
ps->LensInf.rExtentX.wMax *= 2;
|
||||
ps->LensInf.rExtentX.wPhyMax *= 2;
|
||||
ps->LensInf.rExtentY.wMax *= 2;
|
||||
ps->LensInf.rExtentY.wPhyMax *= 2;
|
||||
|
||||
DBG( DBG_LOW, "ModelSet9630() done.\n" );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* set the model to 9636 (ASIC 98001 models)
|
||||
* works for 9636P Turbo and 9636T /12000T
|
||||
*/
|
||||
void ModelSet9636( pScanData ps )
|
||||
{
|
||||
DBG( DBG_LOW, "ModelSet9636()\n" );
|
||||
|
||||
/*
|
||||
*set to 9630 first, then do the differences
|
||||
*/
|
||||
ModelSet9630( ps );
|
||||
ps->Device.buttons = 0;
|
||||
|
||||
/*
|
||||
* has 98001 ASIC
|
||||
*/
|
||||
if( _OVR_PLUSTEK_9636 == ps->ModelOverride ) {
|
||||
DBG( DBG_LOW, "Model Override --> 9636P+/Turbo\n" );
|
||||
ps->sCaps.Model = MODEL_OP_9636PP;
|
||||
} else if( _OVR_PLUSTEK_9636P == ps->ModelOverride ) {
|
||||
DBG( DBG_LOW, "Model Override --> 9636P\n" );
|
||||
ps->sCaps.Model = MODEL_OP_9636P;
|
||||
} else {
|
||||
ps->sCaps.Model = MODEL_OP_9636T;
|
||||
ps->sCaps.dwFlag |= SFLAG_TPA;
|
||||
}
|
||||
|
||||
ps->Device.DataOriginX = 72;
|
||||
ps->sCaps.AsicID = _ASIC_IS_98001;
|
||||
|
||||
ps->sCaps.dwBits = _BITS_12;
|
||||
ps->sCaps.rDataType.wMax = COLOR_TRUE48;
|
||||
ps->sCaps.rDataType.wPhyMax = COLOR_TRUE48;
|
||||
|
||||
ps->TotalBufferRequire = _LINE_BUFSIZE * 2 + _LINE_BUFSIZE1 +
|
||||
ps->BufferForColorRunTable + _PROCESS_BUFSIZE;
|
||||
|
||||
/* do it again, as ModelSet9630() changes the result of this function !*/
|
||||
modelInitPageSettings( ps );
|
||||
|
||||
DBG( DBG_LOW, "ModelSet9636() done.\n" );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* set the model to P12 (ASIC 98003 models)
|
||||
*/
|
||||
void ModelSetP12( pScanData ps )
|
||||
{
|
||||
DBG( DBG_LOW, "ModelSetP12()\n" );
|
||||
|
||||
/*
|
||||
* set to 9630 first, then do the differences
|
||||
*/
|
||||
ModelSet9630( ps );
|
||||
ps->Device.DataOriginX = 72;
|
||||
ps->sCaps.Model = MODEL_OP_PT12;
|
||||
ps->sCaps.AsicID = _ASIC_IS_98003;
|
||||
|
||||
ps->sCaps.dwBits = _BITS_12;
|
||||
ps->sCaps.rDataType.wMax = COLOR_TRUE48;
|
||||
ps->sCaps.rDataType.wPhyMax = COLOR_TRUE48;
|
||||
|
||||
ps->TotalBufferRequire = _SizeTotalBufTpa;
|
||||
|
||||
/* do it again, as ModelSet9630() changes the result of this function !*/
|
||||
modelInitPageSettings( ps );
|
||||
|
||||
DBG( DBG_LOW, "ModelSetP12() done.\n" );
|
||||
}
|
||||
|
||||
/* END PLUSTEK-PP_MODEL.C ...................................................*/
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,757 @@
|
|||
/*.............................................................................
|
||||
* Project : linux driver for Plustek parallel-port scanners
|
||||
*.............................................................................
|
||||
* File: plustek-pp_p12.c - p12 and pt12 specific stuff
|
||||
*.............................................................................
|
||||
*
|
||||
* based on sources acquired from Plustek Inc.
|
||||
* Copyright (C) 2000 Plustek Inc.
|
||||
* Copyright (C) 2001-2003 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
*.............................................................................
|
||||
* History:
|
||||
* 0.38 - initial version
|
||||
* 0.39 - added Genius Colorpage Vivid III V2 stuff
|
||||
* 0.40 - no changes
|
||||
* 0.41 - no changes
|
||||
* 0.42 - removed setting of ps->sCaps.dwFlag in p12InitiateComponentModel()
|
||||
*
|
||||
*.............................................................................
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include "plustek-pp_scan.h"
|
||||
|
||||
/*************************** some local vars *********************************/
|
||||
|
||||
static RegDef p12CcdStop[] = {
|
||||
{0x41, 0xff}, {0x42, 0xff}, {0x60, 0xff}, {0x61, 0xff},
|
||||
{0x4b, 0xff}, {0x4c, 0xff}, {0x4d, 0xff}, {0x4e, 0xff},
|
||||
{0x2a, 0x01}, {0x2b, 0x00}, {0x2d, 0x00}, {0x1b, 0x19}, {0x15, 0x00}
|
||||
};
|
||||
|
||||
/*************************** local functions *********************************/
|
||||
|
||||
/*.............................................................................
|
||||
* init the stuff according to the buttons
|
||||
*/
|
||||
static void p12ButtonSetup( pScanData ps, Byte nrOfButtons )
|
||||
{
|
||||
ps->Device.buttons = nrOfButtons;
|
||||
|
||||
ps->Device.Model1Mono &= ~_BUTTON_MODE;
|
||||
ps->Device.Model1Color &= ~_BUTTON_MODE;
|
||||
|
||||
ps->AsicReg.RD_MotorDriverType |= _BUTTON_DISABLE;
|
||||
ps->Scan.motorPower |= _BUTTON_DISABLE;
|
||||
ps->sCaps.dwFlag |= (SFLAG_MULTIFUNC | SFLAG_BUTTONOPT);
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* According to what we have detected, set the other stuff
|
||||
*/
|
||||
static void p12InitiateComponentModel( pScanData ps )
|
||||
{
|
||||
/* preset some stuff and do te differences later */
|
||||
ps->Device.buttons = 0;
|
||||
ps->Device.Model1Mono = _BUTTON_MODE + _CCD_SHIFT_GATE + _SCAN_GRAYTYPE;
|
||||
ps->Device.Model1Color = _BUTTON_MODE + _CCD_SHIFT_GATE;
|
||||
ps->Device.dwModelOriginY = 64;
|
||||
ps->Device.fTpa = _FALSE;
|
||||
ps->Device.ModelCtrl = (_LED_ACTIVITY | _LED_CONTROL);
|
||||
|
||||
/* ps->sCaps.dwFlag should have been set correctly in models.c */
|
||||
|
||||
switch( ps->Device.bPCBID ) {
|
||||
|
||||
case _PLUSTEK_SCANNER:
|
||||
DBG( DBG_LOW, "We have a Plustek Scanner\n" );
|
||||
ps->sCaps.Model = MODEL_OP_P12;
|
||||
break;
|
||||
|
||||
case _SCANNER_WITH_TPA:
|
||||
DBG( DBG_LOW, "Scanner has TPA\n" );
|
||||
ps->Device.fTpa = _TRUE;
|
||||
ps->sCaps.dwFlag |= SFLAG_TPA;
|
||||
break;
|
||||
|
||||
case _SCANNER4Button:
|
||||
DBG( DBG_LOW, "Scanner has 4 Buttons\n" );
|
||||
p12ButtonSetup( ps, 4 );
|
||||
break;
|
||||
|
||||
case _SCANNER4ButtonTPA:
|
||||
DBG( DBG_LOW, "Scanner has 4 Buttons & TPA\n" );
|
||||
ps->Device.fTpa = _TRUE;
|
||||
ps->sCaps.dwFlag |= SFLAG_TPA;
|
||||
p12ButtonSetup( ps, 4 );
|
||||
break;
|
||||
|
||||
case _SCANNER5Button:
|
||||
DBG( DBG_LOW, "Scanner has 5 Buttons\n" );
|
||||
ps->Device.dwModelOriginY = 64 + 20;
|
||||
p12ButtonSetup( ps, 5 );
|
||||
break;
|
||||
|
||||
case _SCANNER5ButtonTPA:
|
||||
DBG( DBG_LOW, "Scanner has 5 Buttons & TPA\n" );
|
||||
ps->Device.dwModelOriginY = 64 + 20;
|
||||
ps->Device.fTpa = _TRUE;
|
||||
ps->sCaps.dwFlag |= SFLAG_TPA;
|
||||
p12ButtonSetup( ps, 5 );
|
||||
break;
|
||||
|
||||
case _SCANNER1Button:
|
||||
DBG( DBG_LOW, "Scanner has 1 Button\n" );
|
||||
p12ButtonSetup( ps, 1 );
|
||||
break;
|
||||
|
||||
case _SCANNER1ButtonTPA:
|
||||
DBG( DBG_LOW, "Scanner has 1 Button & TPA\n" );
|
||||
ps-> Device.fTpa = _TRUE;
|
||||
ps->sCaps.dwFlag |= SFLAG_TPA;
|
||||
p12ButtonSetup( ps, 1 );
|
||||
break;
|
||||
|
||||
case _AGFA_SCANNER:
|
||||
DBG( DBG_LOW, "Agfa Scanner\n" );
|
||||
ps->Device.dwModelOriginY = 24; /* 1200 dpi */
|
||||
break;
|
||||
|
||||
case _SCANNER2Button:
|
||||
DBG( DBG_LOW, "Scanner has 2 Buttons\n" );
|
||||
DBG( DBG_LOW, "Seems we have a Genius Colorpage Vivid III V2\n" );
|
||||
ps->Device.dwModelOriginY = 64 - 33;
|
||||
p12ButtonSetup( ps, 2 );
|
||||
ps->sCaps.Model = MODEL_GEN_CPV2;
|
||||
break;
|
||||
|
||||
default:
|
||||
DBG( DBG_LOW, "Default Model: P12\n" );
|
||||
ps->sCaps.Model = MODEL_OP_P12;
|
||||
break;
|
||||
}
|
||||
|
||||
if( _MOTOR0_2003 == ps->Device.bMotorID ) {
|
||||
ps->Device.f2003 = _TRUE;
|
||||
ps->Device.XStepMono = 10;
|
||||
ps->Device.XStepColor = 6;
|
||||
ps->Device.XStepBack = 5;
|
||||
ps->AsicReg.RD_MotorDriverType |= _MOTORR_STRONG;
|
||||
} else {
|
||||
ps->Device.f2003 = _FALSE;
|
||||
ps->Device.XStepMono = 8;
|
||||
ps->Device.XStepColor = 4;
|
||||
ps->Device.XStepBack = 5;
|
||||
ps->AsicReg.RD_MotorDriverType |= _MOTORR_WEAK;
|
||||
}
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* prepare all the necessary variables -
|
||||
*/
|
||||
static void p12SetupScannerVariables( pScanData ps )
|
||||
{
|
||||
DBG( DBG_LOW, "p12SetupScannerVariables()\n" );
|
||||
|
||||
/*
|
||||
* these values were originally altered by registry entries (NT-driver)
|
||||
* and used to adjust the picture position...
|
||||
*/
|
||||
ps->Device.lUpNormal = 0;
|
||||
ps->Device.lUpNegative = 20;
|
||||
ps->Device.lUpPositive = -30;
|
||||
|
||||
ps->Device.lLeftNormal = 51;
|
||||
|
||||
ps->OpenScanPath( ps );
|
||||
ps->ReInitAsic( ps, _FALSE );
|
||||
ps->CloseScanPath( ps );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
*
|
||||
*/
|
||||
static void p12SetupScanningCondition( pScanData ps )
|
||||
{
|
||||
TimerDef timer;
|
||||
ULong channel;
|
||||
Byte bState;
|
||||
pUChar pState = ps->Bufs.b1.pReadBuf;
|
||||
|
||||
DBG( DBG_LOW, "p12SetupScanningCondition()\n" );
|
||||
|
||||
P12SetGeneralRegister( ps );
|
||||
|
||||
IORegisterToScanner( ps, ps->RegResetMTSC );
|
||||
|
||||
/* ------- Setup MinRead/MaxRead Fifo size ------- */
|
||||
if( ps->DataInf.wPhyDataType <= COLOR_TRUE24 ) {
|
||||
ps->Scan.dwMaxReadFifo =
|
||||
ps->Scan.dwMinReadFifo = ps->DataInf.dwAsicBytesPerPlane * 2;
|
||||
} else {
|
||||
ps->Scan.dwMaxReadFifo =
|
||||
ps->Scan.dwMinReadFifo = ps->DataInf.dwAppPixelsPerLine << 1;
|
||||
}
|
||||
|
||||
if( ps->Scan.dwMinReadFifo < 1024)
|
||||
ps->Scan.dwMinReadFifo = ps->Scan.dwMaxReadFifo = 1024;
|
||||
|
||||
ps->Scan.dwMaxReadFifo += (ps->DataInf.dwAsicBytesPerPlane / 2);
|
||||
|
||||
|
||||
DBG( DBG_LOW, "MinReadFifo=%lu, MaxReadFifo=%lu\n",
|
||||
ps->Scan.dwMinReadFifo, ps->Scan.dwMaxReadFifo );
|
||||
|
||||
/* ------- Set the max. read fifo to asic ------- */
|
||||
if( ps->DataInf.wPhyDataType > COLOR_256GRAY ) {
|
||||
|
||||
ps->Scan.bFifoSelect = ps->RegBFifoOffset;
|
||||
|
||||
if( !ps->Scan.p48BitBuf.pb ) {
|
||||
|
||||
Long lRed, lGreen;
|
||||
|
||||
lRed = (_SIZE_REDFIFO - _SIZE_BLUEFIFO) /
|
||||
ps->DataInf.dwAsicBytesPerPlane - ps->Scan.bd_rk.wRedKeep;
|
||||
|
||||
lGreen = (_SIZE_GREENFIFO - _SIZE_BLUEFIFO) /
|
||||
ps->DataInf.dwAsicBytesPerPlane - ps->Scan.gd_gk.wGreenKeep;
|
||||
|
||||
if((lRed < 0) || (lGreen < 0)) {
|
||||
|
||||
if( lRed < lGreen ) {
|
||||
channel = _RED_FULLSIZE << 16;
|
||||
ps->AsicReg.RD_BufFullSize = _SIZE_REDFIFO;
|
||||
lGreen = lRed;
|
||||
} else {
|
||||
channel = _GREEN_FULLSIZE << 16;
|
||||
ps->AsicReg.RD_BufFullSize = _SIZE_GREENFIFO;
|
||||
}
|
||||
|
||||
lGreen = (ULong)(-lGreen * ps->DataInf.dwAsicBytesPerPlane);
|
||||
|
||||
if( ps->DataInf.wPhyDataType > COLOR_TRUE24 )
|
||||
lGreen >>= 1;
|
||||
|
||||
ps->Scan.dwMinReadFifo += (ULong)lGreen;
|
||||
ps->Scan.dwMaxReadFifo += (ULong)lGreen;
|
||||
|
||||
} else {
|
||||
channel = _BLUE_FULLSIZE << 16;
|
||||
ps->AsicReg.RD_BufFullSize = _SIZE_BLUEFIFO;
|
||||
}
|
||||
} else {
|
||||
channel = _BLUE_FULLSIZE << 16;
|
||||
ps->AsicReg.RD_BufFullSize = _SIZE_BLUEFIFO;
|
||||
}
|
||||
} else {
|
||||
ps->Scan.bFifoSelect = ps->RegGFifoOffset;
|
||||
channel = _GREEN_FULLSIZE << 16;
|
||||
ps->AsicReg.RD_BufFullSize = _SIZE_GRAYFIFO;
|
||||
}
|
||||
|
||||
ps->AsicReg.RD_BufFullSize -= (ps->DataInf.dwAsicBytesPerPlane << 1);
|
||||
|
||||
if( ps->DataInf.wPhyDataType > COLOR_TRUE24 )
|
||||
ps->AsicReg.RD_BufFullSize >>= 1;
|
||||
|
||||
ps->AsicReg.RD_BufFullSize |= channel;
|
||||
|
||||
ps->Scan.bRefresh = (Byte)(ps->Scan.dwInterval << 1);
|
||||
ps->AsicReg.RD_LineControl = (_LOBYTE (ps->Shade.wExposure));
|
||||
ps->AsicReg.RD_ExtLineControl = (_HIBYTE (ps->Shade.wExposure));
|
||||
ps->AsicReg.RD_XStepTime = (_LOBYTE (ps->Shade.wXStep));
|
||||
ps->AsicReg.RD_ExtXStepTime = (_HIBYTE (ps->Shade.wXStep));
|
||||
ps->AsicReg.RD_Motor0Control = _FORWARD_MOTOR;
|
||||
ps->AsicReg.RD_StepControl = _MOTOR0_SCANSTATE;
|
||||
ps->AsicReg.RD_ModeControl = (_ModeScan | _ModeFifoGSel);
|
||||
|
||||
DBG( DBG_LOW, "bRefresh = %i\n", ps->Scan.bRefresh );
|
||||
|
||||
if( ps->DataInf.wPhyDataType == COLOR_BW ) {
|
||||
ps->AsicReg.RD_ScanControl = _SCAN_BITMODE;
|
||||
|
||||
if( !(ps->DataInf.dwScanFlag & SCANDEF_Inverse))
|
||||
ps->AsicReg.RD_ScanControl |= _P98_SCANDATA_INVERT;
|
||||
|
||||
} else if( ps->DataInf.wPhyDataType <= COLOR_TRUE24 )
|
||||
ps->AsicReg.RD_ScanControl = _SCAN_BYTEMODE;
|
||||
else {
|
||||
ps->AsicReg.RD_ScanControl = _SCAN_12BITMODE;
|
||||
|
||||
if(!(ps->DataInf.dwScanFlag & SCANDEF_RightAlign))
|
||||
ps->AsicReg.RD_ScanControl |= _BITALIGN_LEFT;
|
||||
|
||||
if( ps->DataInf.dwScanFlag & SCANDEF_Inverse)
|
||||
ps->AsicReg.RD_ScanControl |= _P98_SCANDATA_INVERT;
|
||||
}
|
||||
|
||||
ps->AsicReg.RD_ScanControl |= _SCAN_1ST_AVERAGE;
|
||||
IOSelectLampSource( ps );
|
||||
|
||||
DBG( DBG_LOW, "RD_ScanControl = 0x%02x\n", ps->AsicReg.RD_ScanControl );
|
||||
|
||||
ps->AsicReg.RD_MotorTotalSteps = (ULong)ps->DataInf.crImage.cy * 4 +
|
||||
((ps->Device.f0_8_16) ? 32 : 16) +
|
||||
((ps->Scan.bDiscardAll) ? 32 : 0);
|
||||
|
||||
ps->AsicReg.RD_ScanControl1 = (_MTSC_ENABLE | _SCANSTOPONBUFFULL |
|
||||
_MFRC_RUNSCANSTATE | _MFRC_BY_XSTEP);
|
||||
|
||||
ps->AsicReg.RD_Dpi = ps->DataInf.xyPhyDpi.x;
|
||||
|
||||
if(!(ps->DataInf.dwScanFlag & SCANDEF_TPA )) {
|
||||
|
||||
ps->AsicReg.RD_Origin = (UShort)(ps->Device.lLeftNormal * 2 +
|
||||
ps->Device.DataOriginX +
|
||||
ps->DataInf.crImage.x );
|
||||
|
||||
} else if( ps->DataInf.dwScanFlag & SCANDEF_Transparency ) {
|
||||
ps->AsicReg.RD_Origin =
|
||||
(UShort)(ps->Scan.posBegin + ps->DataInf.crImage.x);
|
||||
} else {
|
||||
ps->AsicReg.RD_Origin =
|
||||
(UShort)(ps->Scan.negBegin + ps->DataInf.crImage.x);
|
||||
}
|
||||
|
||||
if( ps->Shade.bIntermediate & _ScanMode_AverageOut )
|
||||
ps->AsicReg.RD_Origin >>= 1;
|
||||
|
||||
if( ps->DataInf.wPhyDataType == COLOR_BW )
|
||||
ps->AsicReg.RD_Pixels = (UShort)ps->DataInf.dwAsicBytesPerPlane;
|
||||
else
|
||||
ps->AsicReg.RD_Pixels = (UShort)ps->DataInf.dwAppPixelsPerLine;
|
||||
|
||||
DBG( DBG_LOW, "RD_Origin = %u, RD_Pixels = %u\n",
|
||||
ps->AsicReg.RD_Origin, ps->AsicReg.RD_Pixels );
|
||||
|
||||
/* ------- Prepare scan states ------- */
|
||||
memset( ps->a_nbNewAdrPointer, 0, _SCANSTATE_BYTES );
|
||||
memset( ps->Bufs.b1.pReadBuf, 0, _NUMBER_OF_SCANSTEPS );
|
||||
|
||||
if( ps->DataInf.wPhyDataType <= COLOR_256GRAY )
|
||||
bState = (_SS_MONO | _SS_STEP);
|
||||
else
|
||||
bState = (_SS_COLOR | _SS_STEP);
|
||||
|
||||
for( channel = _NUMBER_OF_SCANSTEPS;
|
||||
channel; channel -= ps->Scan.dwInterval ) {
|
||||
*pState = bState;
|
||||
if( ps->Scan.dwInterlace )
|
||||
pState[ ps->Scan.dwInterlace] = _SS_STEP;
|
||||
pState += ps->Scan.dwInterval;
|
||||
}
|
||||
for( channel = 0, pState = ps->Bufs.b1.pReadBuf;
|
||||
channel < _SCANSTATE_BYTES; channel++) {
|
||||
ps->a_nbNewAdrPointer[channel] = pState [0] | (pState [1] << 4);
|
||||
pState += 2;
|
||||
}
|
||||
|
||||
/* ------- Wait for scan state stop ------- */
|
||||
MiscStartTimer( &timer, _SECOND * 2 );
|
||||
|
||||
while(!(IOGetScanState( ps, _FALSE ) & _SCANSTATE_STOP) &&
|
||||
!MiscCheckTimer(&timer));
|
||||
|
||||
/* CHECK: Replace by IOPutAll.... */
|
||||
IODownloadScanStates( ps );
|
||||
IODataToRegister( ps, ps->RegLineControl, ps->AsicReg.RD_LineControl);
|
||||
IODataToRegister( ps, ps->RegExtendedLineControl,
|
||||
ps->AsicReg.RD_ExtLineControl);
|
||||
IODataToRegister( ps, ps->RegXStepTime, ps->AsicReg.RD_XStepTime);
|
||||
IODataToRegister( ps, ps->RegExtendedXStep, ps->AsicReg.RD_ExtXStepTime);
|
||||
IODataToRegister( ps, ps->RegMotorDriverType,
|
||||
ps->AsicReg.RD_MotorDriverType);
|
||||
IODataToRegister( ps, ps->RegStepControl, ps->AsicReg.RD_StepControl);
|
||||
IODataToRegister( ps, ps->RegMotor0Control, ps->AsicReg.RD_Motor0Control);
|
||||
IODataToRegister( ps, ps->RegModelControl,ps->AsicReg.RD_ModelControl);
|
||||
IODataToRegister( ps, ps->RegDpiLow, (_LOBYTE(ps->AsicReg.RD_Dpi)));
|
||||
IODataToRegister( ps, ps->RegDpiHigh, (_HIBYTE(ps->AsicReg.RD_Dpi)));
|
||||
IODataToRegister( ps, ps->RegScanPosLow, (_LOBYTE(ps->AsicReg.RD_Origin)));
|
||||
IODataToRegister( ps, ps->RegScanPosHigh,(_HIBYTE(ps->AsicReg.RD_Origin)));
|
||||
IODataToRegister( ps, ps->RegWidthPixelsLow,
|
||||
(_LOBYTE(ps->AsicReg.RD_Pixels)));
|
||||
IODataToRegister( ps, ps->RegWidthPixelsHigh,
|
||||
(_HIBYTE(ps->AsicReg.RD_Pixels)));
|
||||
IODataToRegister( ps, ps->RegThresholdLow,
|
||||
(_LOBYTE(ps->AsicReg.RD_ThresholdControl)));
|
||||
IODataToRegister( ps, ps->RegThresholdHigh,
|
||||
(_HIBYTE(ps->AsicReg.RD_ThresholdControl)));
|
||||
IODataToRegister( ps, ps->RegMotorTotalStep0,
|
||||
(_LOBYTE(ps->AsicReg.RD_MotorTotalSteps)));
|
||||
IODataToRegister( ps, ps->RegMotorTotalStep1,
|
||||
(_HIBYTE(ps->AsicReg.RD_MotorTotalSteps)));
|
||||
IODataToRegister( ps, ps->RegScanControl, ps->AsicReg.RD_ScanControl);
|
||||
|
||||
IORegisterToScanner( ps, ps->RegInitDataFifo);
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* program the CCD relevant stuff
|
||||
*/
|
||||
static void p12ProgramCCD( pScanData ps)
|
||||
{
|
||||
UShort w;
|
||||
pRegDef rp;
|
||||
|
||||
DBG( DBG_IO, "p12ProgramCCD: 0x%08lx[%lu]\n",
|
||||
(ULong)ps->Device.pCCDRegisters,
|
||||
((ULong)ps->Device.wNumCCDRegs * ps->Shade.bIntermediate));
|
||||
|
||||
DBG( DBG_IO, " %u regs * %u (intermediate)\n",
|
||||
ps->Device.wNumCCDRegs, ps->Shade.bIntermediate );
|
||||
|
||||
rp = ps->Device.pCCDRegisters +
|
||||
(ULong)ps->Device.wNumCCDRegs * ps->Shade.bIntermediate;
|
||||
|
||||
for( w = ps->Device.wNumCCDRegs; w--; rp++ ) {
|
||||
|
||||
DBG( DBG_IO, "[0x%02x] = 0x%02x\n", rp->bReg, rp->bParam );
|
||||
IODataToRegister( ps, rp->bReg, rp->bParam );
|
||||
}
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* this initializes the ASIC and prepares the different functions for shading
|
||||
* and scanning
|
||||
*/
|
||||
static void p12Init98003( pScanData ps, Bool shading )
|
||||
{
|
||||
DBG( DBG_LOW, "p12InitP98003(%d)\n", shading );
|
||||
|
||||
/* get DAC and motor stuff */
|
||||
ps->Device.bDACType = IODataFromRegister( ps, ps->RegResetConfig );
|
||||
ps->Device.bMotorID = (Byte)(ps->Device.bDACType & _MOTOR0_MASK);
|
||||
|
||||
ps->AsicReg.RD_MotorDriverType =
|
||||
(Byte)((ps->Device.bDACType & _MOTOR0_MASK) >> 3);
|
||||
ps->AsicReg.RD_MotorDriverType |=
|
||||
(Byte)((ps->Device.bDACType & _MOTOR1_MASK) >> 1);
|
||||
|
||||
|
||||
ps->Scan.motorPower = ps->AsicReg.RD_MotorDriverType | _MOTORR_STRONG;
|
||||
|
||||
ps->Device.bDACType &= _ADC_MASK;
|
||||
|
||||
/*get CCD and PCB ID */
|
||||
ps->Device.bPCBID = IODataFromRegister( ps, ps->RegConfiguration );
|
||||
ps->Device.bCCDID = ps->Device.bPCBID & 0x07;
|
||||
ps->Device.bPCBID &= 0xf0;
|
||||
|
||||
if( _AGFA_SCANNER == ps->Device.bPCBID )
|
||||
ps->Device.bDACType = _DA_WOLFSON8141;
|
||||
|
||||
DBG( DBG_LOW, "PCB-ID=0x%02x, CCD-ID=0x%02x, DAC-TYPE=0x%02x\n",
|
||||
ps->Device.bPCBID, ps->Device.bCCDID, ps->Device.bDACType );
|
||||
|
||||
p12InitiateComponentModel( ps );
|
||||
|
||||
/* encode the CCD-id into the flag parameter */
|
||||
ps->sCaps.dwFlag |= ((ULong)(ps->Device.bCCDID | ps->Device.bPCBID) << 16);
|
||||
|
||||
P12InitCCDandDAC( ps, shading );
|
||||
|
||||
if( ps->Shade.bIntermediate & _ScanMode_Mono )
|
||||
ps->AsicReg.RD_Model1Control = ps->Device.Model1Mono;
|
||||
else
|
||||
ps->AsicReg.RD_Model1Control = ps->Device.Model1Color;
|
||||
|
||||
IODataToRegister( ps, ps->RegPllPredivider, 1 );
|
||||
IODataToRegister( ps, ps->RegPllMaindivider, 0x20 );
|
||||
IODataToRegister( ps, ps->RegPllPostdivider, 2 );
|
||||
IODataToRegister( ps, ps->RegClockSelector, 3 ); /* 2 */
|
||||
IODataToRegister( ps, ps->RegMotorDriverType,
|
||||
ps->AsicReg.RD_MotorDriverType );
|
||||
|
||||
/* this might be changed, def value is 11 */
|
||||
IODataToRegister( ps, ps->RegWaitStateInsert, 11 );
|
||||
IODataToRegister( ps, ps->RegModel1Control, ps->AsicReg.RD_Model1Control );
|
||||
|
||||
p12ProgramCCD( ps );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* initialize the register values for the 98003 asic and preset other stuff
|
||||
*/
|
||||
static void p12InitializeAsicRegister( pScanData ps )
|
||||
{
|
||||
memset( &ps->AsicReg, 0, sizeof(RegData));
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* as the function name says
|
||||
*/
|
||||
static void p12PutToIdleMode( pScanData ps )
|
||||
{
|
||||
ULong i;
|
||||
|
||||
ps->OpenScanPath( ps );
|
||||
|
||||
DBG( DBG_IO, "CCD-Stop\n" );
|
||||
|
||||
for( i = 0; i < 13; i++ ) {
|
||||
|
||||
DBG( DBG_IO, "[0x%02x] = 0x%02x\n",
|
||||
p12CcdStop[i].bReg, p12CcdStop[i].bParam );
|
||||
|
||||
IODataToRegister( ps, p12CcdStop[i].bReg, p12CcdStop[i].bParam );
|
||||
}
|
||||
|
||||
ps->CloseScanPath( ps );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* here we simply call the WaitForShading function which performs this topic
|
||||
*/
|
||||
static int p12Calibration( pScanData ps )
|
||||
{
|
||||
Bool result;
|
||||
|
||||
DBG( DBG_LOW, "p12Calibration()\n" );
|
||||
|
||||
/*
|
||||
* wait for shading to be done
|
||||
*/
|
||||
ps->OpenScanPath( ps );
|
||||
|
||||
_ASSERT(ps->WaitForShading);
|
||||
result = ps->WaitForShading( ps );
|
||||
ps->CloseScanPath( ps );
|
||||
|
||||
if( !result )
|
||||
return _E_TIMEOUT;
|
||||
|
||||
return _OK;
|
||||
}
|
||||
|
||||
/************************ exported functions *********************************/
|
||||
|
||||
/*.............................................................................
|
||||
* initialize the register values and function calls for the 98003 asic
|
||||
*/
|
||||
int P12InitAsic( pScanData ps )
|
||||
{
|
||||
int result;
|
||||
|
||||
DBG( DBG_LOW, "P12InitAsic()\n" );
|
||||
|
||||
/*
|
||||
* preset the asic shadow registers
|
||||
*/
|
||||
p12InitializeAsicRegister( ps );
|
||||
|
||||
ps->IO.bOpenCount = 0;
|
||||
|
||||
/*
|
||||
* setup the register values
|
||||
*/
|
||||
ps->RegSwitchBus = 0;
|
||||
ps->RegEPPEnable = 1;
|
||||
ps->RegECPEnable = 2;
|
||||
ps->RegReadDataMode = 3;
|
||||
ps->RegWriteDataMode = 4;
|
||||
ps->RegInitDataFifo = 5;
|
||||
ps->RegForceStep = 6;
|
||||
ps->RegInitScanState = 7;
|
||||
ps->RegRefreshScanState = 8;
|
||||
ps->RegWaitStateInsert = 0x0a;
|
||||
ps->RegRFifoOffset = 0x0a;
|
||||
ps->RegGFifoOffset = 0x0b;
|
||||
ps->RegBFifoOffset = 0x0c;
|
||||
ps->RegBitDepth = 0x13;
|
||||
ps->RegStepControl = 0x14;
|
||||
ps->RegMotor0Control = 0x15;
|
||||
ps->RegXStepTime = 0x16;
|
||||
ps->RegGetScanState = 0x17;
|
||||
ps->RegAsicID = 0x18;
|
||||
ps->RegMemoryLow = 0x19;
|
||||
ps->RegMemoryHigh = 0x1a;
|
||||
ps->RegModeControl = 0x1b;
|
||||
ps->RegLineControl = 0x1c;
|
||||
ps->RegScanControl = 0x1d;
|
||||
ps->RegConfiguration = 0x1e;
|
||||
ps->RegModelControl = 0x1f;
|
||||
ps->RegModel1Control = 0x20;
|
||||
ps->RegDpiLow = 0x21;
|
||||
ps->RegDpiHigh = 0x22;
|
||||
ps->RegScanPosLow = 0x23;
|
||||
ps->RegScanPosHigh = 0x24;
|
||||
ps->RegWidthPixelsLow = 0x25;
|
||||
ps->RegWidthPixelsHigh = 0x26;
|
||||
ps->RegThresholdLow = 0x27;
|
||||
ps->RegThresholdHigh = 0x28;
|
||||
ps->RegThresholdGapControl = 0x29;
|
||||
ps->RegADCAddress = 0x2a;
|
||||
ps->RegADCData = 0x2b;
|
||||
ps->RegADCPixelOffset = 0x2c;
|
||||
ps->RegADCSerialOutStr = 0x2d;
|
||||
ps->RegResetConfig = 0x2e;
|
||||
ps->RegLensPosition = 0x2f;
|
||||
ps->RegStatus = 0x30;
|
||||
ps->RegScanStateControl = 0x31;
|
||||
ps->RegRedChDarkOffsetLow = 0x33;
|
||||
ps->RegRedChDarkOffsetHigh = 0x34;
|
||||
ps->RegGreenChDarkOffsetLow = 0x35;
|
||||
ps->RegGreenChDarkOffsetHigh= 0x36;
|
||||
ps->RegBlueChDarkOffsetLow = 0x37;
|
||||
ps->RegBlueChDarkOffsetHigh = 0x38;
|
||||
ps->RegResetPulse0 = 0x39;
|
||||
ps->RegResetPulse1 = 0x3a;
|
||||
ps->RegCCDClampTiming0 = 0x3b;
|
||||
ps->RegCCDClampTiming1 = 0x3c;
|
||||
ps->RegVSMPTiming0 = 0x41;
|
||||
ps->RegVSMPTiming1 = 0x42;
|
||||
ps->RegCCDQ1Timing0 = 0x43;
|
||||
ps->RegCCDQ1Timing1 = 0x44;
|
||||
ps->RegCCDQ1Timing2 = 0x45;
|
||||
ps->RegCCDQ1Timing3 = 0x46;
|
||||
ps->RegCCDQ2Timing0 = 0x47;
|
||||
ps->RegCCDQ2Timing1 = 0x48;
|
||||
ps->RegCCDQ2Timing2 = 0x49;
|
||||
ps->RegCCDQ2Timing3 = 0x4a;
|
||||
ps->RegADCclockTiming0 = 0x4b;
|
||||
ps->RegADCclockTiming1 = 0x4c;
|
||||
ps->RegADCclockTiming2 = 0x4d;
|
||||
ps->RegADCclockTiming3 = 0x4e;
|
||||
ps->RegADCDVTiming0 = 0x50;
|
||||
ps->RegADCDVTiming1 = 0x51;
|
||||
ps->RegADCDVTiming2 = 0x52;
|
||||
ps->RegADCDVTiming3 = 0x53;
|
||||
|
||||
ps->RegFifoFullLength0 = 0x54;
|
||||
ps->RegFifoFullLength1 = 0x55;
|
||||
ps->RegFifoFullLength2 = 0x56;
|
||||
|
||||
ps->RegMotorTotalStep0 = 0x57;
|
||||
ps->RegMotorTotalStep1 = 0x58;
|
||||
ps->RegMotorFreeRunCount0 = 0x59;
|
||||
ps->RegMotorFreeRunCount1 = 0x5a;
|
||||
ps->RegScanControl1 = 0x5b;
|
||||
ps->RegMotorFreeRunTrigger = 0x5c;
|
||||
|
||||
ps->RegResetMTSC = 0x5d;
|
||||
|
||||
ps->RegMotor1Control = 0x62;
|
||||
ps->RegMotor2Control = 0x63;
|
||||
ps->RegMotorDriverType = 0x64;
|
||||
|
||||
ps->RegStatus2 = 0x66;
|
||||
|
||||
ps->RegExtendedLineControl = 0x6d;
|
||||
ps->RegExtendedXStep = 0x6e;
|
||||
|
||||
ps->RegPllPredivider = 0x71;
|
||||
ps->RegPllMaindivider = 0x72;
|
||||
ps->RegPllPostdivider = 0x73;
|
||||
ps->RegClockSelector = 0x74;
|
||||
ps->RegTestMode = 0xf0;
|
||||
|
||||
/*
|
||||
* setup function calls
|
||||
*/
|
||||
ps->SetupScannerVariables = p12SetupScannerVariables;
|
||||
ps->SetupScanningCondition = p12SetupScanningCondition;
|
||||
ps->Calibration = p12Calibration;
|
||||
ps->PutToIdleMode = p12PutToIdleMode;
|
||||
ps->ReInitAsic = p12Init98003;
|
||||
|
||||
ps->CtrlReadHighNibble = _CTRL_GENSIGNAL + _CTRL_AUTOLF + _CTRL_STROBE;
|
||||
ps->CtrlReadLowNibble = _CTRL_GENSIGNAL + _CTRL_AUTOLF;
|
||||
|
||||
ps->IO.useEPPCmdMode = _FALSE;
|
||||
|
||||
/*
|
||||
* initialize the other modules and set some
|
||||
* function pointer
|
||||
*/
|
||||
result = DacInitialize( ps );
|
||||
if( _OK != result )
|
||||
return result;
|
||||
|
||||
result = ImageInitialize( ps );
|
||||
if( _OK != result )
|
||||
return result;
|
||||
|
||||
result = IOFuncInitialize( ps );
|
||||
if( _OK != result )
|
||||
return result;
|
||||
|
||||
result = IOInitialize( ps );
|
||||
if( _OK != result )
|
||||
return result;
|
||||
|
||||
result = MotorInitialize( ps );
|
||||
if( _OK != result )
|
||||
return result;
|
||||
|
||||
if( _FALSE == ps->OpenScanPath( ps )) {
|
||||
DBG( DBG_LOW, "P12InitAsic() failed.\n" );
|
||||
return _E_NO_DEV;
|
||||
}
|
||||
|
||||
/*get CCD and PCB ID */
|
||||
ps->Device.bPCBID = IODataFromRegister( ps, ps->RegConfiguration );
|
||||
ps->Device.bCCDID = ps->Device.bPCBID & 0x07;
|
||||
ps->Device.bPCBID &= 0xf0;
|
||||
|
||||
DBG( DBG_LOW, "PCB-ID=0x%02x, CCD-ID=0x%02x\n", ps->Device.bPCBID, ps->Device.bCCDID );
|
||||
|
||||
/* get a more closer model description...*/
|
||||
p12InitiateComponentModel( ps );
|
||||
|
||||
ps->CloseScanPath( ps );
|
||||
|
||||
/* here we check for the OpticWorks 2000, which is not supported */
|
||||
if( _OPTICWORKS2000 == ps->Device.bPCBID ) {
|
||||
DBG( DBG_LOW, "OpticWorks 2000 not supported!\n" );
|
||||
return _E_NOSUPP;
|
||||
}
|
||||
|
||||
DBG( DBG_LOW, "P12InitAsic() done.\n" );
|
||||
return _OK;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* set all necessary register contents
|
||||
*/
|
||||
void P12SetGeneralRegister( pScanData ps )
|
||||
{
|
||||
DBG( DBG_LOW, "P12SetGeneralRegister()\n" );
|
||||
|
||||
ps->Scan.fMotorBackward = _FALSE;
|
||||
ps->Scan.fRefreshState = _FALSE;
|
||||
|
||||
if( COLOR_BW == ps->DataInf.wPhyDataType )
|
||||
ps->AsicReg.RD_ScanControl = _SCAN_BITMODE;
|
||||
else {
|
||||
if( ps->DataInf.wPhyDataType <= COLOR_TRUE24 )
|
||||
ps->AsicReg.RD_ScanControl = _SCAN_BYTEMODE;
|
||||
else
|
||||
ps->AsicReg.RD_ScanControl = _SCAN_12BITMODE;
|
||||
}
|
||||
|
||||
IOSelectLampSource( ps );
|
||||
|
||||
if( ps->Shade.bIntermediate & _ScanMode_AverageOut )
|
||||
ps->AsicReg.RD_ModelControl = ps->Device.ModelCtrl | _ModelDpi300;
|
||||
else
|
||||
ps->AsicReg.RD_ModelControl = ps->Device.ModelCtrl | _ModelDpi600;
|
||||
|
||||
ps->AsicReg.RD_Motor0Control = _MotorOn | _MotorHQuarterStep | _MotorPowerEnable;
|
||||
ps->AsicReg.RD_ScanControl1 = _SCANSTOPONBUFFULL | _MFRC_BY_XSTEP;
|
||||
ps->AsicReg.RD_StepControl = _MOTOR0_SCANSTATE;
|
||||
}
|
||||
|
||||
/* END PLUSTEK-PP_P12.C .....................................................*/
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,853 @@
|
|||
/*.............................................................................
|
||||
* Project : linux driver for Plustek parallel-port scanners
|
||||
*.............................................................................
|
||||
* File: plustek-pp_p48xx.c - here we have all functionality according to
|
||||
* the ASIC96001/3 basedmodels
|
||||
*.............................................................................
|
||||
*
|
||||
* based on sources acquired from Plustek Inc.
|
||||
* Copyright (C) 1998 Plustek Inc.
|
||||
* Copyright (C) 2000-2003 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
* also based on the work done by Rick Bronson
|
||||
*.............................................................................
|
||||
* History:
|
||||
* 0.30 - initial version
|
||||
* 0.31 - fixed a bug for the return value in p48xxDoTest
|
||||
* added additional debug messages
|
||||
* added function p48xxCheck4800Memory
|
||||
* 0.32 - added debug messages
|
||||
* fixed a bug in p48xxDoTest
|
||||
* disabled RD_WatchDogControl, lamp will be controlled by driver
|
||||
* 0.33 - added function p48xxSetAsicRegisters()
|
||||
* fixed a bug in p48xxDoTest (reset the ASIC registers)
|
||||
* removed p48xxPositionLamp
|
||||
* 0.34 - added some comments
|
||||
* 0.35 - added some comments
|
||||
* 0.36 - added function p48xxInitAllModules() to allow reinit of the modules
|
||||
* switching from Full- to Halfstep at ps->PhysicalDpi now in
|
||||
* p48xxSetGeneralRegister
|
||||
* fixed the color-inverse problem for model OP4800
|
||||
* 0.37 - move p48xxOpenScanPath, p48xxCloseScanPath
|
||||
* and p48xxRegisterToScanner to io.c
|
||||
* removed // comments
|
||||
* added override for A3I scanner
|
||||
* 0.38 - added function p48xxPutToIdleMode()
|
||||
* added function p48xxCalibration
|
||||
* 0.39 - added A3I stuff
|
||||
* 0.40 - disabled A3I stuff
|
||||
* 0.41 - no changes
|
||||
* 0.42 - changed include names
|
||||
*
|
||||
*.............................................................................
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include "plustek-pp_scan.h"
|
||||
|
||||
/*************************** some definitions ********************************/
|
||||
|
||||
#define _TEST_SZ 2048 /* always use 2048 for mem size (= one bank) */
|
||||
#define _START_VAL 0x12345678 /* pick a non-zero starting value for our long */
|
||||
|
||||
#define _BankAndSizeForTest _MemBankSize2k /* always use 2k for mem test */
|
||||
|
||||
/*************************** local functions *********************************/
|
||||
|
||||
/*.............................................................................
|
||||
* 1) Set asic to PROGRAM mode
|
||||
* 2) Select the memory bank and size
|
||||
* 3) Initiate data fifo
|
||||
*/
|
||||
static void p48xxSetMemoryBankForProgram( pScanData ps , Byte bBankAndSize )
|
||||
{
|
||||
/* enter program mode */
|
||||
IODataToRegister( ps, ps->RegModeControl, _ModeProgram );
|
||||
|
||||
/* bank and size */
|
||||
IODataToRegister( ps, ps->RegMemAccessControl, bBankAndSize );
|
||||
|
||||
/* initiate data fifo */
|
||||
IORegisterToScanner( ps, ps->RegInitDataFifo );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* use the internal memory of a scanner to find the model
|
||||
*/
|
||||
static int p48xxDoTest( pScanData ps )
|
||||
{
|
||||
UChar tmpByte;
|
||||
int retval;
|
||||
ULong adder, ul, cntr;
|
||||
pULong buffer;
|
||||
|
||||
DBG( DBG_LOW, "p48xxDoTest()\n" );
|
||||
|
||||
buffer = _KALLOC( sizeof(UChar) * _TEST_SZ, GFP_KERNEL );
|
||||
if( NULL == buffer )
|
||||
return _E_ALLOC;
|
||||
|
||||
retval = _E_NO_DEV;
|
||||
|
||||
/*
|
||||
* do a memory test to determine how much memory this unit has, in the
|
||||
* process we can figure out if it's a 4830 or a 9630. NOTE: the ram
|
||||
* seems to be mirrored such that if you have a unit with only 32k it's
|
||||
* mirrored 4 times to fill the 128k (2k * (_MemBankMask + 1)) space,
|
||||
* so we will run a 32 bit incrementing pattern over the entire 128k and
|
||||
* look for the 1st page (2k) to fail
|
||||
*/
|
||||
adder = 0;
|
||||
for (cntr = _BankAndSizeForTest;
|
||||
cntr < _BankAndSizeForTest + _MemBanks; cntr++) {
|
||||
|
||||
ps->OpenScanPath( ps );
|
||||
|
||||
p48xxSetMemoryBankForProgram( ps, cntr );
|
||||
|
||||
/* prepare content, incrementing 32 val */
|
||||
for (ul = 0; ul < _TEST_SZ / sizeof(ULong); ul++)
|
||||
buffer[ul] = ul + adder + _START_VAL;
|
||||
|
||||
/* fill to buffer */
|
||||
IOMoveDataToScanner( ps, (pUChar)buffer, _TEST_SZ );
|
||||
|
||||
/*
|
||||
* now check bank 0 to see if it got overwritten
|
||||
* bank 0, size 2k
|
||||
*/
|
||||
p48xxSetMemoryBankForProgram( ps, _BankAndSizeForTest );
|
||||
|
||||
ps->CloseScanPath( ps );
|
||||
|
||||
/* read data back */
|
||||
IOReadScannerImageData( ps, (pUChar)buffer, _TEST_SZ );
|
||||
|
||||
/* check */
|
||||
for (ul = 0; ul < _TEST_SZ / sizeof(ULong); ul++) {
|
||||
if (buffer[ul] != ul + _START_VAL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if fail */
|
||||
if (ul != _TEST_SZ / sizeof (ULong)) {
|
||||
DBG( DBG_LOW, "Bank 0 overwritten\n" );
|
||||
break;
|
||||
}
|
||||
|
||||
/* now check current bank */
|
||||
ps->OpenScanPath( ps );
|
||||
p48xxSetMemoryBankForProgram( ps, cntr );
|
||||
ps->CloseScanPath( ps );
|
||||
|
||||
/* read data back */
|
||||
IOReadScannerImageData( ps, (pUChar)buffer, _TEST_SZ);
|
||||
|
||||
/* check if fail */
|
||||
for( ul = 0; ul < _TEST_SZ / sizeof(ULong); ul++ ) {
|
||||
if( buffer[ul] != ul + adder + _START_VAL )
|
||||
break;
|
||||
}
|
||||
|
||||
/* check if fail */
|
||||
if (ul != _TEST_SZ / sizeof(ULong)) {
|
||||
DBG( DBG_LOW, "Bank not present, error at pos %lu (%u)\n", ul,
|
||||
_TEST_SZ / sizeof(ULong));
|
||||
break;
|
||||
}
|
||||
|
||||
adder += _TEST_SZ / sizeof(ULong);
|
||||
}
|
||||
|
||||
_KFREE( buffer );
|
||||
|
||||
DBG( DBG_LOW, "found %ld bytes of memory\n",
|
||||
_TEST_SZ * (cntr - _BankAndSizeForTest));
|
||||
|
||||
if( cntr == _BankAndSizeForTest ) {
|
||||
DBG( DBG_LOW, "No memory ! No scanner...\n" );
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
tmpByte = IODataRegisterFromScanner( ps, 0x18 );
|
||||
DBG( DBG_LOW, "tmpByte[0x18] = 0x%02x\n",tmpByte );
|
||||
#endif
|
||||
|
||||
tmpByte = IODataRegisterFromScanner( ps, 0x0e );
|
||||
DBG( DBG_LOW, "tmpByte = 0x%02x, cntr = %lu, AsicId = 0x%02x\n",
|
||||
tmpByte, cntr, ps->sCaps.AsicID );
|
||||
|
||||
/* 128k */
|
||||
if ((_TEST_SZ * (cntr - _BankAndSizeForTest) == 1 << 17) &&
|
||||
(ps->sCaps.AsicID == _ASIC_IS_96003)) {
|
||||
|
||||
/*
|
||||
* if 128k then must be a 9630 or above
|
||||
* hack, test for 12000P, The 9630 returns an 0x08
|
||||
*/
|
||||
if ( tmpByte == 0x02 ) {
|
||||
|
||||
/*
|
||||
* as we currently can't automagically detect an A3I we have to
|
||||
* use the override switch
|
||||
*/
|
||||
if( _OVR_PLUSTEK_A3I == ps->ModelOverride ) {
|
||||
|
||||
DBG( DBG_LOW, "Model Override --> A3I\n" );
|
||||
ModelSetA3I( ps );
|
||||
} else {
|
||||
ModelSet12000( ps );
|
||||
DBG( DBG_LOW, "It seems we have a 12000P/96000P\n" );
|
||||
}
|
||||
|
||||
} else {
|
||||
ModelSet9630( ps );
|
||||
DBG( DBG_LOW, "It seems we have a 9630\n" );
|
||||
}
|
||||
|
||||
retval = _OK;
|
||||
|
||||
} else {
|
||||
|
||||
DBG( DBG_LOW, "Scanner is not a 9630 or above\n");
|
||||
|
||||
if ( tmpByte != 0x0f ) {
|
||||
|
||||
DBG( DBG_LOW, "Looks like a 600!\n" );
|
||||
|
||||
if (( 0x08 == tmpByte ) &&
|
||||
((_TEST_SZ * (cntr - _BankAndSizeForTest)) == 32768 )) {
|
||||
DBG( DBG_LOW, "But it is a 4830P!!! "
|
||||
"(by mkochano@ee.pw.edu.pl)\n" );
|
||||
ModelSet4830( ps );
|
||||
} else {
|
||||
ModelSet600( ps );
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else
|
||||
DBG( DBG_LOW, "It seems we have a 4830\n" );
|
||||
#endif
|
||||
|
||||
retval = _OK;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* setup ASIC registers and clear all scan states (no stepping)
|
||||
*/
|
||||
static void p48xxSetAsicRegisters( pScanData ps )
|
||||
{
|
||||
memset( &ps->AsicReg, 0, sizeof(ps->AsicReg));
|
||||
memset( &ps->Asic96Reg, 0, sizeof(ps->Asic96Reg));
|
||||
memset( ps->a_nbNewAdrPointer, 0, _SCANSTATE_BYTES );
|
||||
|
||||
ps->AsicReg.RD_LineControl = ps->TimePerLine;
|
||||
ps->AsicReg.RD_ScanControl = _SCAN_LAMP_ON;
|
||||
ps->AsicReg.RD_ModelControl = ps->Device.ModelCtrl | _ModelWhiteIs0;
|
||||
ps->AsicReg.RD_Origin = 0;
|
||||
ps->AsicReg.RD_Pixels = 5110; /*ps->RdPix;*/
|
||||
ps->Asic96Reg.RD_MotorControl = 0;
|
||||
ps->Asic96Reg.RD_WatchDogControl = 0; /* org. val = 0x8f; */
|
||||
|
||||
IOPutOnAllRegisters( ps );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* use the internal memory of a scanner to find the model
|
||||
*/
|
||||
static int p48xxCheck4800Memory( pScanData ps )
|
||||
{
|
||||
int retval;
|
||||
ULong ul;
|
||||
pUChar buffer;
|
||||
|
||||
DBG( DBG_LOW, "p48xxCheck4800Memory()\n" );
|
||||
|
||||
buffer = _KALLOC( 2560, GFP_KERNEL ); /* 1280: Read,1280:Write */
|
||||
if( NULL == buffer )
|
||||
return _E_ALLOC;
|
||||
|
||||
retval = _OK;
|
||||
|
||||
/* bank 0, size 2k */
|
||||
ps->OpenScanPath( ps );
|
||||
p48xxSetMemoryBankForProgram( ps, _BankAndSizeForTest );
|
||||
|
||||
for (ul = 0; ul < 1280; ul++)
|
||||
buffer[ul] = (UChar)ul; /* prepare content */
|
||||
|
||||
IOMoveDataToScanner( ps, buffer, 1280 ); /* fill to buffer */
|
||||
p48xxSetMemoryBankForProgram( ps, _BankAndSizeForTest );
|
||||
ps->CloseScanPath( ps );
|
||||
|
||||
/* read data back */
|
||||
IOReadScannerImageData( ps, buffer + 1280, 1280 );
|
||||
|
||||
for( ul = 0; ul < 1280; ul++ ) {
|
||||
if( buffer[ul] != buffer[ul+1280] ) {
|
||||
DBG( DBG_HIGH, "Error in memory test at pos %lu (%u != %u)\n",
|
||||
ul, buffer[ul], buffer[ul+1280] );
|
||||
retval = _E_NO_DEV;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_KFREE(buffer);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* call all other modules, to initialize themselves
|
||||
*/
|
||||
static int p48xxInitAllModules( pScanData ps )
|
||||
{
|
||||
int result;
|
||||
|
||||
result = DacInitialize( ps );
|
||||
if( _OK != result )
|
||||
return result;
|
||||
|
||||
result = ImageInitialize( ps );
|
||||
if( _OK != result )
|
||||
return result;
|
||||
|
||||
result = IOFuncInitialize( ps );
|
||||
if( _OK != result )
|
||||
return result;
|
||||
|
||||
result = IOInitialize( ps );
|
||||
if( _OK != result )
|
||||
return result;
|
||||
|
||||
result = MotorInitialize( ps );
|
||||
if( _OK != result )
|
||||
return result;
|
||||
|
||||
/*
|
||||
* in debug version, check all function pointers
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
if( _FALSE == MiscAllPointersSet( ps ))
|
||||
return _E_INTERNAL;
|
||||
#endif
|
||||
return _OK;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
*
|
||||
*/
|
||||
static int p48xxReadWriteTest( pScanData ps )
|
||||
{
|
||||
int retval;
|
||||
|
||||
DBG( DBG_LOW, "p48xxReadWriteTest()\n" );
|
||||
|
||||
/*
|
||||
* determine the model by the ASIC type (except for 4830/9630)
|
||||
* might want to make a SetModelCommon() someday for this...
|
||||
*/
|
||||
ps->RedDataReady = 0x01; /* normal for Red and Green */
|
||||
ps->GreenDataReady = 0x02;
|
||||
ps->AsicRedColor = 0x01;
|
||||
ps->AsicGreenColor = 0x03;
|
||||
|
||||
/*
|
||||
* if not already set, try to find ASIC type (96001 or 96003)
|
||||
*/
|
||||
if ( _NO_BASE == ps->sCaps.wIOBase ) {
|
||||
|
||||
/* get copy of asic id */
|
||||
ps->sCaps.AsicID = IODataRegisterFromScanner( ps, ps->RegAsicID );
|
||||
|
||||
if ( _ASIC_IS_96003 == ps->sCaps.AsicID ) {
|
||||
|
||||
/* actually either a 4830, 9630, 12000, find out later */
|
||||
DBG( DBG_LOW, "Found a 96003 ASIC at Reg 0x%x\n", ps->RegAsicID );
|
||||
ModelSet4830( ps );
|
||||
|
||||
} else {
|
||||
|
||||
if ( _ASIC_IS_96001 == ps->sCaps.AsicID ) {
|
||||
DBG( DBG_LOW, "Found a 96001 ASIC at Reg 0x%x\n",
|
||||
ps->RegAsicID );
|
||||
ModelSet4800( ps );
|
||||
} else {
|
||||
DBG( DBG_LOW, "Can't find your model, asic = 0x%x\n",
|
||||
ps->sCaps.AsicID );
|
||||
return _E_NO_ASIC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* set the registers according to the assumptions above
|
||||
*/
|
||||
p48xxSetAsicRegisters( ps );
|
||||
|
||||
if ( _ASIC_IS_96003 == ps->sCaps.AsicID ) {
|
||||
retval = p48xxDoTest( ps );
|
||||
|
||||
/*
|
||||
* as we may now have detected another model, we have to set
|
||||
* the registers to their new values...
|
||||
* and maybe the modules have to be reset as well
|
||||
*/
|
||||
if( _OK == retval ) {
|
||||
p48xxSetAsicRegisters( ps );
|
||||
retval = p48xxInitAllModules( ps );
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* this part will be reached only for the 4800 - ASIC 96001
|
||||
* we check only the memory as the original driver does
|
||||
*/
|
||||
return p48xxCheck4800Memory( ps );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* 1) Setup the registers of asic.
|
||||
* 2) Determine which type of CCD we are using
|
||||
* 3) According to the CCD, prepare the CCD dependent veriables
|
||||
* SONY CCD:
|
||||
* The color exposure sequence: Red, Green (after 11 red lines),
|
||||
* Blue (after 8 green lines)
|
||||
* TOSHIBA CCD:
|
||||
* The color exposure sequence: Red, Blue (after 11 red lines),
|
||||
* Green (after 8 blue lines)
|
||||
*/
|
||||
static void p48xxSetupScannerVariables( pScanData ps )
|
||||
{
|
||||
UChar tmp;
|
||||
TimerDef timer;
|
||||
|
||||
DBG( DBG_LOW, "p48xxSetupScannerVariables()\n" );
|
||||
|
||||
ps->OpenScanPath( ps );
|
||||
|
||||
IODataToRegister( ps, ps->RegModelControl2, _Model2ChannelMult );
|
||||
|
||||
if( 2 == IODataFromRegister( ps, ps->RegWriteIOBusDecode1 )) {
|
||||
|
||||
DBG( DBG_LOW, "Scanner has 97003 ASIC too.\n" );
|
||||
ps->f97003 = _TRUE;
|
||||
ps->b97003DarkR = 8;
|
||||
ps->b97003DarkG = 8;
|
||||
ps->b97003DarkB = 8;
|
||||
|
||||
ps->Asic96Reg.u26.RD_ModelControl2 = _Model2ChannelMult;
|
||||
} else {
|
||||
|
||||
DBG( DBG_LOW, "No ASIC 97003 found.\n" );
|
||||
ps->f97003 = _FALSE;
|
||||
ps->Asic96Reg.u26.RD_ModelControl2 = _Model2DirectOutPort;
|
||||
}
|
||||
|
||||
IODataToRegister( ps, ps->RegModelControl2,
|
||||
ps->Asic96Reg.u26.RD_ModelControl2 );
|
||||
|
||||
tmp = IODataFromRegister( ps, ps->RegStatus );
|
||||
DBG( DBG_LOW, "Status-Register = 0x%02X\n", tmp );
|
||||
#ifdef DEBUG
|
||||
if( tmp & _FLAG_P96_MOTORTYPE ) {
|
||||
DBG( DBG_LOW, "Scanner has Full/Half Stepping drive\n" );
|
||||
} else {
|
||||
DBG( DBG_LOW, "Scanner has Micro Stepping drive\n" );
|
||||
}
|
||||
#endif
|
||||
|
||||
if( tmp & _FLAG_P96_CCDTYPE) {
|
||||
ps->fSonyCCD = _FALSE;
|
||||
DBG( DBG_LOW, "CCD is NEC/TOSHIBA Type\n" );
|
||||
} else {
|
||||
ps->fSonyCCD = _TRUE;
|
||||
DBG( DBG_LOW, "CCD is SONY Type\n" );
|
||||
}
|
||||
|
||||
ps->CloseScanPath( ps );
|
||||
|
||||
ps->b1stColorByte = ps->AsicRedColor;
|
||||
ps->b1stColor = ps->RedDataReady;
|
||||
|
||||
if (ps->fSonyCCD) {
|
||||
|
||||
ps->b2ndColorByte = ps->AsicGreenColor;
|
||||
ps->b2ndColor = ps->GreenDataReady;
|
||||
ps->b3rdColorByte = _ASIC_BLUECOLOR;
|
||||
ps->b3rdColor = _BLUE_DATA_READY;
|
||||
|
||||
} else { /* NEC/Toshiba CCD */
|
||||
|
||||
ps->b2ndColorByte = _ASIC_BLUECOLOR;
|
||||
ps->b2ndColor = _BLUE_DATA_READY;
|
||||
ps->b3rdColorByte = ps->AsicGreenColor;
|
||||
ps->b3rdColor = ps->GreenDataReady;
|
||||
}
|
||||
|
||||
ps->b1stMask = (Byte)~ps->b1stColor;
|
||||
ps->b2ndMask = (Byte)~ps->b2ndColor;
|
||||
ps->b3rdMask = (Byte)~ps->b3rdColor;
|
||||
|
||||
ps->b1stLinesOffset = 17;
|
||||
ps->b2ndLinesOffset = 9;
|
||||
|
||||
/*
|
||||
* calculate I/O Timer
|
||||
* if we cannot read 200 lines within 1 second, the I/O time has to add 2
|
||||
* CalculateIOTime ()
|
||||
*/
|
||||
if( _PORT_SPP != ps->IO.portMode ) {
|
||||
|
||||
UShort wLines = 200;
|
||||
pUChar pBuf;
|
||||
|
||||
pBuf = _KALLOC((_BUF_SIZE_BASE_CONST * 2), GFP_KERNEL );
|
||||
|
||||
if ( NULL != pBuf ) {
|
||||
|
||||
MiscStartTimer( &timer, _SECOND );
|
||||
|
||||
do {
|
||||
IOReadScannerImageData( ps, pBuf, (_BUF_SIZE_BASE_CONST * 2));
|
||||
|
||||
wLines--;
|
||||
} while (!MiscCheckTimer( &timer) && wLines);
|
||||
|
||||
if( !wLines )
|
||||
ps->bExtraAdd = 0;
|
||||
else
|
||||
ps->bExtraAdd = 2;
|
||||
|
||||
_KFREE( pBuf );
|
||||
|
||||
} else {
|
||||
ps->bExtraAdd = 2; /* poor resource */
|
||||
}
|
||||
} else {
|
||||
ps->bExtraAdd = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
*
|
||||
*/
|
||||
static void p48xxSetGeneralRegister( pScanData ps )
|
||||
{
|
||||
if( MODEL_OP_A3I == ps->sCaps.Model ) {
|
||||
ps->AsicReg.RD_ModelControl = _ModelDpi400 | _ModelWhiteIs0 |
|
||||
_ModelMemSize128k4;
|
||||
}
|
||||
|
||||
ps->AsicReg.RD_ModeControl = _ModeScan;
|
||||
|
||||
/* WORK: ps->PhysicalDpi should be correct, but the we have to work
|
||||
* on motor.c again to use other running-tables
|
||||
* if ( ps->DataInf.xyAppDpi.y <= ps->PhysicalDpi ) {
|
||||
*/
|
||||
if ( ps->DataInf.xyAppDpi.y <= 300 ) {
|
||||
/* HEINER:A3I
|
||||
if ( ps->DataInf.xyAppDpi.y <= ps->PhysicalDpi ) {
|
||||
*/
|
||||
ps->Asic96Reg.RD_MotorControl = (ps->FullStep | ps->IgnorePF |
|
||||
ps->MotorOn | _MotorDirForward);
|
||||
} else {
|
||||
ps->Asic96Reg.RD_MotorControl = (ps->IgnorePF | ps->MotorOn |
|
||||
_MotorDirForward);
|
||||
}
|
||||
|
||||
if ( ps->DataInf.wPhyDataType == COLOR_BW ) {
|
||||
ps->AsicReg.RD_ScanControl = ps->bLampOn;
|
||||
|
||||
if (!(ps->DataInf.dwScanFlag & SCANDEF_Inverse))
|
||||
ps->AsicReg.RD_ScanControl |= _P96_SCANDATA_INVERT;
|
||||
|
||||
} else {
|
||||
|
||||
ps->AsicReg.RD_ScanControl = ps->bLampOn | _SCAN_BYTEMODE;
|
||||
|
||||
if (ps->DataInf.dwScanFlag & SCANDEF_Inverse)
|
||||
ps->AsicReg.RD_ScanControl |= _P96_SCANDATA_INVERT;
|
||||
}
|
||||
|
||||
if (ps->DataInf.xyPhyDpi.x <= 200)
|
||||
ps->AsicReg.RD_ScanControl |= _SCAN_1ST_AVERAGE;
|
||||
|
||||
DBG( DBG_LOW, "RD_ModeControl = 0x%02x\n", ps->AsicReg.RD_ModeControl );
|
||||
DBG( DBG_LOW, "RD_MotorControl = 0x%02x\n", ps->Asic96Reg.RD_MotorControl );
|
||||
DBG( DBG_LOW, "RD_ScanControl = 0x%02x\n", ps->AsicReg.RD_ScanControl );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
*
|
||||
*/
|
||||
static void p48xxSetupScanningCondition( pScanData ps )
|
||||
{
|
||||
DBG( DBG_LOW, "p48xxSetupScanningCondition()\n" );
|
||||
|
||||
IORegisterDirectToScanner( ps, ps->RegInitDataFifo );
|
||||
|
||||
/* Cal64kTime (); */
|
||||
if( MODEL_OP_A3I == ps->sCaps.Model )
|
||||
ps->wLinesPer64kTime = (UShort)(65555UL / ps->DataInf.dwAsicBytesPerPlane *
|
||||
5UL);
|
||||
else
|
||||
ps->wLinesPer64kTime = (UShort)(65555UL / ps->DataInf.dwAsicBytesPerPlane *
|
||||
10UL / 3UL);
|
||||
|
||||
DBG( DBG_LOW, "wLinesPer64kTime = %u\n", ps->wLinesPer64kTime );
|
||||
|
||||
ps->InitialSetCurrentSpeed( ps );
|
||||
|
||||
DBG( DBG_LOW, "Current Speed = %u\n", ps->bCurrentSpeed );
|
||||
|
||||
ps->bMinReadFifo = (Byte)((ps->DataInf.dwAsicBytesPerPlane + 511) / 512);
|
||||
DBG( DBG_LOW, "MinReadFifo = %u\n", ps->bMinReadFifo );
|
||||
|
||||
p48xxSetGeneralRegister( ps );
|
||||
|
||||
/*
|
||||
* if speed is not the fastest and DPI is less than 400, do half steps
|
||||
*/
|
||||
if( ps->DataInf.wPhyDataType >= COLOR_256GRAY &&
|
||||
!(ps->bCurrentSpeed & 1) && (ps->DataInf.xyAppDpi.y <= 300)) {
|
||||
/* HEINER:A3I
|
||||
if( !(ps->bCurrentSpeed & 1) && (ps->DataInf.xyAppDpi.y <= ps->PhysicalDpi)) {
|
||||
*/
|
||||
ps->fHalfStepTableFlag = _TRUE;
|
||||
ps->Asic96Reg.RD_MotorControl &= ps->StepMask;
|
||||
}
|
||||
|
||||
ps->AsicReg.RD_Dpi = ps->DataInf.xyPhyDpi.x;
|
||||
DBG( DBG_LOW, "RD_Dpi = %u\n", ps->AsicReg.RD_Dpi );
|
||||
|
||||
/* SetStartStopRegister (ps) */
|
||||
ps->AsicReg.RD_Origin = (UShort)(ps->Offset70 + ps->Device.DataOriginX +
|
||||
ps->DataInf.crImage.x);
|
||||
|
||||
if (ps->DataInf.wPhyDataType < COLOR_256GRAY) {
|
||||
ps->AsicReg.RD_Pixels =
|
||||
(UShort)(ps->DataInf.dwAsicPixelsPerPlane + 7) & 0xfff8;
|
||||
} else {
|
||||
ps->AsicReg.RD_Pixels = (UShort)ps->DataInf.dwAsicPixelsPerPlane;
|
||||
}
|
||||
|
||||
DBG( DBG_LOW, "RD_Pixels = %u\n", ps->AsicReg.RD_Pixels );
|
||||
|
||||
/* SetupMotorStart () */
|
||||
IORegisterDirectToScanner( ps, ps->RegInitDataFifo);
|
||||
ps->SetupMotorRunTable( ps );
|
||||
|
||||
IOSetToMotorRegister( ps );
|
||||
|
||||
ps->pCurrentColorRunTable = ps->pColorRunTable;
|
||||
ps->bCurrentLineCount = 0;
|
||||
|
||||
IOPutOnAllRegisters( ps );
|
||||
|
||||
ps->OpenScanPath( ps );
|
||||
|
||||
/*
|
||||
* when using the full-step speed on 600 dpi models, then set
|
||||
* the motor into half-step mode, to avoid that the scanner hits
|
||||
* the back of its cover
|
||||
*/
|
||||
if((600 == ps->PhysicalDpi) && (1 == ps->bCurrentSpeed)) {
|
||||
|
||||
ps->Asic96Reg.RD_MotorControl &= ~ps->FullStep;
|
||||
}
|
||||
|
||||
IODataToRegister( ps, ps->RegMotorControl,
|
||||
(Byte)(ps->Asic96Reg.RD_MotorControl & ~ps->MotorOn));
|
||||
IODataToRegister( ps, ps->RegMotorControl, ps->Asic96Reg.RD_MotorControl);
|
||||
IORegisterToScanner( ps, ps->RegInitDataFifo );
|
||||
|
||||
ps->CloseScanPath( ps );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* switch the motor off and put the scanner into idle mode
|
||||
*/
|
||||
static void p48xxPutToIdleMode( pScanData ps )
|
||||
{
|
||||
DBG( DBG_LOW, "Putting Scanner (ASIC 96001/3) into Idle-Mode\n" );
|
||||
|
||||
/*
|
||||
* turn off motor
|
||||
*/
|
||||
ps->Asic96Reg.RD_MotorControl = 0;
|
||||
IOCmdRegisterToScanner( ps, ps->RegMotorControl, 0 );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* for P96001/3 ASIC
|
||||
* do all the preliminary stuff here (calibrate the scanner and move the
|
||||
* sensor to it´s start position, also setup the driver for the
|
||||
* current run)
|
||||
*/
|
||||
static int p48xxCalibration( pScanData ps )
|
||||
{
|
||||
DBG( DBG_LOW, "p48xxCalibration()\n" );
|
||||
|
||||
ps->Scan.bFifoSelect = ps->RegGFifoOffset;
|
||||
|
||||
while (_TRUE) {
|
||||
|
||||
_ASSERT(ps->WaitForShading);
|
||||
if (ps->WaitForShading( ps )) {
|
||||
|
||||
if(!(ps->DataInf.dwScanFlag & SCANDEF_TPA)) {
|
||||
|
||||
/* HEINER:A3I disable !! */
|
||||
MotorP96AheadToDarkArea( ps );
|
||||
|
||||
if( ps->Scan.fRefreshState ) {
|
||||
ps->Scan.fRefreshState = _FALSE;
|
||||
|
||||
if (!ps->fReshaded) {
|
||||
ps->fReshaded = _TRUE;
|
||||
|
||||
if (ps->fColorMoreRedFlag || ps->fColorMoreBlueFlag) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
} else {
|
||||
ps->fScanningStatus = _FALSE;
|
||||
ps->DataInf.dwAppLinesPerArea = 0;
|
||||
return _E_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
if((ps->sCaps.AsicID != _ASIC_IS_96001) &&
|
||||
(ps->DataInf.wPhyDataType != COLOR_BW)) {
|
||||
DacP96WriteBackToGammaShadingRAM(ps);
|
||||
}
|
||||
|
||||
if( ps->DataInf.dwScanFlag & SCANDEF_TPA ) {
|
||||
ps->bExtraMotorCtrl = 0;
|
||||
ps->Scan.fMotorBackward = _TRUE;
|
||||
MotorP96ConstantMoveProc( ps, 4000 );
|
||||
}
|
||||
|
||||
/*
|
||||
* move sensor and setup scanner for grabbing the picture
|
||||
*/
|
||||
_ASSERT(ps->WaitForPositionY);
|
||||
ps->WaitForPositionY(ps);
|
||||
return _OK;
|
||||
}
|
||||
|
||||
/************************ exported functions *********************************/
|
||||
|
||||
/*.............................................................................
|
||||
* initialize the register values and function calls for the 96001/3 asic
|
||||
*/
|
||||
int P48xxInitAsic( pScanData ps )
|
||||
{
|
||||
DBG( DBG_LOW, "P48xxInitAsic()\n" );
|
||||
|
||||
ps->IO.bOpenCount = 0;
|
||||
|
||||
ps->RegSwitchBus = 0;
|
||||
ps->RegReadDataMode = 1;
|
||||
ps->RegWriteDataMode = 2;
|
||||
ps->RegEPPEnable = 3;
|
||||
ps->RegInitDataFifo = 4;
|
||||
ps->RegForceStep = 5;
|
||||
ps->RegInitScanState = 6;
|
||||
ps->RegRefreshScanState = 7;
|
||||
ps->RegStatus = 0x10;
|
||||
ps->RegFifoOffset = 0x11;
|
||||
ps->RegGetScanState = 0x12;
|
||||
ps->RegAsicID = 0x13; /* Determine the asic */
|
||||
ps->RegReadIOBufBus = 0x17;
|
||||
ps->RegModeControl = 0x18;
|
||||
ps->RegLineControl = 0x19;
|
||||
ps->RegScanControl = 0x1a;
|
||||
ps->RegMotorControl = 0x1b;
|
||||
ps->RegModelControl = 0x1c;
|
||||
ps->RegMemAccessControl = 0x1d;
|
||||
ps->RegDpiLow = 0x1e;
|
||||
ps->RegDpiHigh = 0x1f;
|
||||
ps->RegScanPosLow = 0x20;
|
||||
ps->RegScanPosHigh = 0x21;
|
||||
ps->RegWidthPixelsLow = 0x22;
|
||||
ps->RegWidthPixelsHigh = 0x23;
|
||||
ps->RegThresholdControl = 0x24;
|
||||
ps->RegWatchDogControl = 0x25;
|
||||
ps->RegModelControl2 = 0x26;
|
||||
ps->RegThresholdGapControl = 0x27;
|
||||
ps->RegRedChShadingOffset = 0x28;
|
||||
ps->RegGreenChShadingOffset = 0x29;
|
||||
ps->RegRedDCAdjust = 0x27; /* not sure why these are dup's */
|
||||
ps->RegGreenDCAdjust = 0x28;
|
||||
ps->RegBlueDCAdjust = 0x29;
|
||||
ps->RegBlueChShadingOffset = 0x2a;
|
||||
ps->RegRedChDarkOffset = 0x2b;
|
||||
ps->RegGreenChDarkOffset = 0x2c;
|
||||
ps->RegBlueChDarkOffset = 0x2d;
|
||||
ps->RegWriteIOBusDecode1 = 0x2e;
|
||||
ps->RegWriteIOBusDecode2 = 0x2f;
|
||||
ps->RegScanStateControl = 0x30;
|
||||
ps->RegRedChEvenOffset = 0x31;
|
||||
ps->RegGreenChEvenOffset = 0x32;
|
||||
ps->RegBlueChEvenOffset = 0x33;
|
||||
ps->RegRedChOddOffset = 0x34;
|
||||
ps->RegGreenChOddOffset = 0x35;
|
||||
ps->RegBlueChOddOffset = 0x36;
|
||||
ps->RegRedGainOutDirect = 0x37;
|
||||
ps->RegGreenGainOutDirect = 0x38;
|
||||
ps->RegBlueGainOutDirect = 0x39;
|
||||
ps->RegLedControl = 0x3a;
|
||||
ps->RegShadingCorrectCtrl = 0x3b;
|
||||
ps->RegScanStateBegin = 0x40; /* (0, 1) */
|
||||
ps->RegScanStateEnd = 0x5f; /* (62, 63) */
|
||||
|
||||
/*
|
||||
* setup function calls
|
||||
*/
|
||||
ps->ReadWriteTest = p48xxReadWriteTest;
|
||||
ps->SetupScannerVariables = p48xxSetupScannerVariables;
|
||||
ps->SetupScanningCondition = p48xxSetupScanningCondition;
|
||||
ps->PutToIdleMode = p48xxPutToIdleMode;
|
||||
ps->Calibration = p48xxCalibration;
|
||||
|
||||
/*
|
||||
* setup misc
|
||||
*/
|
||||
ps->CtrlReadHighNibble = _CTRL_GENSIGNAL + _CTRL_AUTOLF;
|
||||
ps->CtrlReadLowNibble = _CTRL_GENSIGNAL + _CTRL_AUTOLF + _CTRL_STROBE;
|
||||
|
||||
ps->MotorFreeRun = 0x80;
|
||||
ps->bLampOn = _SCAN_LAMP_ON;
|
||||
ps->f97003 = _FALSE;
|
||||
|
||||
/*
|
||||
* initialize the other modules
|
||||
*/
|
||||
return p48xxInitAllModules( ps );
|
||||
}
|
||||
|
||||
/* END PLUSTEK-PP_P48xx.C ...................................................*/
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,456 @@
|
|||
/*.............................................................................
|
||||
* Project : linux driver for Plustek parallel-port scanners
|
||||
*.............................................................................
|
||||
* File: plustek-pp_procfs.c - this is the interface to the proc filesystem
|
||||
*.............................................................................
|
||||
*
|
||||
* Copyright (C) 2000-2003 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
*.............................................................................
|
||||
* History:
|
||||
* 0.37 - initial version
|
||||
* 0.38 - changes according to generic structure changes
|
||||
* 0.39 - added info about forceMode and slowIO
|
||||
* 0.40 - no changes
|
||||
* 0.41 - no changes
|
||||
* 0.42 - changed include names
|
||||
*
|
||||
*.............................................................................
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/proc_fs.h>
|
||||
|
||||
#include "plustek-pp_scan.h"
|
||||
|
||||
/* toggled by your kernel configuration */
|
||||
#ifdef CONFIG_PROC_FS
|
||||
|
||||
/****************************** static vars **********************************/
|
||||
|
||||
/*
|
||||
* for the proc filesystem
|
||||
*/
|
||||
extern struct proc_dir_entry proc_root;
|
||||
static struct proc_dir_entry *base = NULL;
|
||||
static struct proc_dir_entry *binfo = NULL;
|
||||
static ULong devcount;
|
||||
|
||||
/* parallel port modes... */
|
||||
static char *procfsPortModes[] = {
|
||||
"EPP",
|
||||
"SPP",
|
||||
"BiDi (PS/2)",
|
||||
"ECP"
|
||||
"unknown",
|
||||
NULL
|
||||
};
|
||||
|
||||
/* CCD-Types (as for ASIC 98001 based series) */
|
||||
static TabDef procfsCCDTypes98001[] = {
|
||||
|
||||
{ _CCD_3797, "3797" },
|
||||
{ _CCD_3717, "3717" },
|
||||
{ _CCD_535, "535" },
|
||||
{ _CCD_2556, "2556" },
|
||||
{ _CCD_518, "518" },
|
||||
{ _CCD_539, "539" },
|
||||
{ -1 , "unknown" }
|
||||
};
|
||||
|
||||
/* CCD-Types (as for ASIC 98003 based series) */
|
||||
static TabDef procfsCCDTypes98003[] = {
|
||||
|
||||
{ _CCD_3797, "3797" },
|
||||
{ _CCD_3799, "3799" },
|
||||
{ _CCD_535, "535" },
|
||||
{ _CCD_2556, "2556" },
|
||||
{ _CCD_518, "518" },
|
||||
{ _CCD_539, "539" },
|
||||
{ _CCD_3777, "3777" },
|
||||
{ _CCD_548 , "548" },
|
||||
{ -1 , "unknown" }
|
||||
};
|
||||
|
||||
|
||||
/****************************** local functions ******************************/
|
||||
|
||||
#ifndef LINUX_24
|
||||
/*.............................................................................
|
||||
* This is called as the fill_inode function when an inode
|
||||
* is going into (fill = 1) or out of service (fill = 0).
|
||||
*
|
||||
* Note: only the top-level directory needs to do this; if
|
||||
* a lower level is referenced, the parent will be as well.
|
||||
*
|
||||
* Here simply a dummy function
|
||||
*/
|
||||
static void procfsFillFunc( struct inode *inode, int fill )
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/*.............................................................................
|
||||
* returns a pointer to the port-mode string
|
||||
*/
|
||||
static const char* procfsGetMode( int mode )
|
||||
{
|
||||
if((mode < _PORT_EPP) || (mode > _PORT_ECP))
|
||||
return procfsPortModes[_PORT_ECP+1];
|
||||
|
||||
return procfsPortModes[mode];
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* determines CCD-Type string
|
||||
*/
|
||||
static const char* procfsGetCCDType( pScanData ps )
|
||||
{
|
||||
int i;
|
||||
int ccd_id = ps->Device.bCCDID;
|
||||
pTabDef tab = procfsCCDTypes98001;
|
||||
|
||||
if( _IS_ASIC98(ps->sCaps.AsicID)) {
|
||||
|
||||
if(_ASIC_IS_98003 == ps->sCaps.AsicID)
|
||||
tab = procfsCCDTypes98003;
|
||||
|
||||
/* seek down the description table */
|
||||
for( i = 0; -1 != tab[i].id; i++ ) {
|
||||
|
||||
if( tab[i].id == ccd_id )
|
||||
return tab[i].desc;
|
||||
}
|
||||
} else {
|
||||
|
||||
/* for older scanners only this info is available */
|
||||
if( ps->fSonyCCD )
|
||||
return "SONY Type";
|
||||
else
|
||||
return "NEC/TOSHIBA Type";
|
||||
}
|
||||
|
||||
/* return the last entry if nothing applies! */
|
||||
return tab[(sizeof(procfsCCDTypes98001)/sizeof(TabDef)-1)].desc;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* will be called when reading the proc filesystem:
|
||||
* cat /proc/pt_drv/info
|
||||
*/
|
||||
static int procfsBInfoReadProc( char *buf, char **start, off_t offset,
|
||||
int count, int *eof, void *data )
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
len += sprintf( buf, "Plustek Flatbed Scanner Driver version %d.%d-%d\n",
|
||||
_PTDRV_V1, _PTDRV_V0, _PTDRV_BUILD );
|
||||
|
||||
len += sprintf( buf + len, "Devices : %lu\n", *((pULong)data) );
|
||||
len += sprintf( buf + len, "IOCTL-Version: 0x%08x\n", _PTDRV_IOCTL_VERSION );
|
||||
return len;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* will be called when reading the proc filesystem:
|
||||
* cat /proc/pt_drv/deviceX/info
|
||||
*/
|
||||
static int procfsInfoReadProc( char *buf, char **start, off_t offset,
|
||||
int count, int *eof, void *data )
|
||||
{
|
||||
int len = 0;
|
||||
pScanData ps = (pScanData)data;
|
||||
|
||||
/* Tell us something about the device... */
|
||||
if( NULL != ps ) {
|
||||
len += sprintf( buf+len, "Model : %s\n",
|
||||
MiscGetModelName(ps->sCaps.Model));
|
||||
len += sprintf( buf+len, "Portaddress : 0x%X\n", ps->IO.portBase );
|
||||
len += sprintf( buf+len, "Portmode : %s (%s I/O, %s)\n",
|
||||
procfsGetMode(ps->IO.portMode),
|
||||
(ps->IO.slowIO == _TRUE?"delayed":"fast"),
|
||||
(ps->IO.forceMode == 0?"autodetect":"forced"));
|
||||
len += sprintf( buf+len, "Buttons : %u\n", ps->Device.buttons);
|
||||
len += sprintf( buf+len, "Warmuptime : %us\n", ps->warmup );
|
||||
len += sprintf( buf+len, "Lamp timeout: %us\n", ps->lampoff );
|
||||
len += sprintf( buf+len, "mov-switch : %u\n", ps->ModelOverride );
|
||||
len += sprintf( buf+len, "I/O-delay : %u\n", ps->IO.delay );
|
||||
len += sprintf( buf+len, "CCD-Type : %s\n", procfsGetCCDType(ps));
|
||||
len += sprintf( buf+len, "TPA : %s\n",
|
||||
(ps->sCaps.dwFlag & SFLAG_TPA) ? "yes":"no" );
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* will be called when reading the proc filesystem:
|
||||
* cat /proc/pt_drv/devicex/buttony
|
||||
*/
|
||||
static int procfsButtonsReadProc( char *buf, char **start, off_t offset,
|
||||
int count, int *eof, void *data )
|
||||
{
|
||||
Byte b;
|
||||
int bc = 0;
|
||||
int len = 0;
|
||||
pScanData ps = (pScanData)data;
|
||||
|
||||
if( NULL != ps ) {
|
||||
bc = ps->Device.buttons;
|
||||
}
|
||||
|
||||
/* Check the buttons... */
|
||||
if( 0 != bc ) {
|
||||
|
||||
if ( _ASIC_IS_96003 == ps->sCaps.AsicID ) {
|
||||
MiscClaimPort( ps );
|
||||
b = IODataRegisterFromScanner( ps, ps->RegStatus );
|
||||
if(_FLAG_P96_KEY == (b & _FLAG_P96_KEY))
|
||||
b = 0;
|
||||
else
|
||||
b = 1;
|
||||
MiscReleasePort( ps );
|
||||
len += sprintf( buf + len, "%u\n", b );
|
||||
} else
|
||||
bc = 0;
|
||||
}
|
||||
|
||||
if( 0 == bc )
|
||||
len += sprintf( buf + len, "none\n" );
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* create a procfs entry
|
||||
*/
|
||||
static struct proc_dir_entry *new_entry( const char *name, mode_t mode,
|
||||
struct proc_dir_entry *parent )
|
||||
{
|
||||
#ifndef LINUX_24
|
||||
int len;
|
||||
#endif
|
||||
struct proc_dir_entry *ent;
|
||||
|
||||
if (mode == S_IFDIR)
|
||||
mode |= S_IRUGO | S_IXUGO;
|
||||
else if (mode == 0)
|
||||
mode = S_IFREG | S_IRUGO;
|
||||
|
||||
#ifndef LINUX_24
|
||||
len = strlen(name) + 1;
|
||||
|
||||
/* allocate memory for the entry and the name */
|
||||
ent = kmalloc(sizeof(struct proc_dir_entry) + len, GFP_KERNEL);
|
||||
if( NULL == ent )
|
||||
return NULL;
|
||||
|
||||
memset(ent, 0, sizeof(struct proc_dir_entry));
|
||||
|
||||
/* position pointer of name to end of the structure*/
|
||||
ent->name = ((char *) ent) + sizeof(*ent);
|
||||
strcpy((char *)ent->name, name );
|
||||
|
||||
ent->namelen = strlen(name);
|
||||
ent->mode = mode;
|
||||
|
||||
if (S_ISDIR(mode)) {
|
||||
ent->nlink = 2;
|
||||
ent->fill_inode = &procfsFillFunc;
|
||||
} else {
|
||||
ent->nlink = 1;
|
||||
}
|
||||
|
||||
proc_register( parent, ent );
|
||||
#else
|
||||
if (mode == S_IFDIR)
|
||||
ent = proc_mkdir( name, parent );
|
||||
else
|
||||
ent = create_proc_entry( name, mode, parent );
|
||||
#endif
|
||||
|
||||
return ent;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* shutdown one proc fs entry
|
||||
*/
|
||||
static inline void destroy_proc_entry( struct proc_dir_entry *root,
|
||||
struct proc_dir_entry **d )
|
||||
{
|
||||
#ifndef LINUX_24
|
||||
proc_unregister( root, (*d)->low_ino );
|
||||
kfree(*d);
|
||||
#else
|
||||
DBG(DBG_HIGH, "pt_drv: proc del '%s' root='%s'\n", (*d)->name, root->name);
|
||||
|
||||
remove_proc_entry((*d)->name, root );
|
||||
#endif
|
||||
|
||||
*d = NULL;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* shutdown the proc-tree for one device
|
||||
*/
|
||||
static void destroy_proc_tree( pScanData ps )
|
||||
{
|
||||
int i;
|
||||
|
||||
DBG( DBG_HIGH, "pt_drv: destroy_proc_tree !\n" );
|
||||
|
||||
if( ps ) {
|
||||
|
||||
if( ps->procDir.entry ) {
|
||||
|
||||
if( ps->procDir.info )
|
||||
destroy_proc_entry( ps->procDir.entry, &ps->procDir.info );
|
||||
|
||||
for( i = 0; i < ps->Device.buttons; i++ ) {
|
||||
|
||||
if( ps->procDir.buttons[i] )
|
||||
destroy_proc_entry(ps->procDir.entry, &ps->procDir.buttons[i]);
|
||||
}
|
||||
|
||||
destroy_proc_entry( base, &ps->procDir.entry );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************************** exported functions ******************************/
|
||||
|
||||
/*.............................................................................
|
||||
* initialize our proc-fs stuff
|
||||
*/
|
||||
int ProcFsInitialize( void )
|
||||
{
|
||||
DBG( DBG_HIGH, "ProcFsInitialize()\n" );
|
||||
|
||||
base = new_entry( _DRV_NAME, S_IFDIR, &proc_root );
|
||||
|
||||
if( NULL != base ) {
|
||||
|
||||
devcount = 0;
|
||||
|
||||
binfo = new_entry( "info", 0, base );
|
||||
if( NULL != binfo ) {
|
||||
binfo->read_proc = procfsBInfoReadProc;
|
||||
binfo->data = &devcount;
|
||||
}
|
||||
}
|
||||
|
||||
return _OK;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* cleanup the base entry
|
||||
*/
|
||||
void ProcFsShutdown( void )
|
||||
{
|
||||
DBG( DBG_HIGH, "ProcFsShutdown()\n" );
|
||||
|
||||
if( NULL != base ) {
|
||||
|
||||
if( NULL != binfo )
|
||||
destroy_proc_entry( base, &binfo );
|
||||
|
||||
destroy_proc_entry( &proc_root, &base );
|
||||
}
|
||||
|
||||
devcount = 0;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* will be called for each device, that has been found
|
||||
*/
|
||||
void ProcFsRegisterDevice( pScanData ps )
|
||||
{
|
||||
int i;
|
||||
char str[20];
|
||||
|
||||
if( NULL == base ) {
|
||||
printk( KERN_ERR "pt_drv : proc not initialised yet!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memset( &ps->procDir, 0, sizeof(ProcDirDef));
|
||||
|
||||
sprintf( str, "device%lu", ps->devno );
|
||||
|
||||
ps->procDir.entry = new_entry( str, S_IFDIR, base );
|
||||
if( NULL == ps->procDir.entry )
|
||||
goto error_exit;
|
||||
|
||||
ps->procDir.info = new_entry( "info", 0, ps->procDir.entry );
|
||||
if( NULL == ps->procDir.info )
|
||||
goto error_exit;
|
||||
|
||||
ps->procDir.info->read_proc = procfsInfoReadProc;
|
||||
ps->procDir.info->data = ps;
|
||||
|
||||
for( i = 0; i < ps->Device.buttons; i++ ) {
|
||||
|
||||
sprintf( str, "button%u", i );
|
||||
|
||||
ps->procDir.buttons[i] = new_entry( str, 0, ps->procDir.entry );
|
||||
if( NULL == ps->procDir.buttons[i] )
|
||||
goto error_exit;
|
||||
|
||||
ps->procDir.buttons[i]->read_proc = procfsButtonsReadProc;
|
||||
ps->procDir.buttons[i]->data = ps;
|
||||
}
|
||||
|
||||
devcount++;
|
||||
return;
|
||||
|
||||
|
||||
error_exit:
|
||||
|
||||
printk(KERN_ERR "pt_drv: failure registering /proc/ entry %s.\n", str );
|
||||
destroy_proc_tree( ps );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
* cleanup the proc-fs for a certain device
|
||||
*/
|
||||
void ProcFsUnregisterDevice( pScanData ps )
|
||||
{
|
||||
destroy_proc_tree( ps );
|
||||
}
|
||||
|
||||
#else /* CONFIG_PROC_FS */
|
||||
|
||||
int ProcFsInitialize( void )
|
||||
{
|
||||
return _OK;
|
||||
}
|
||||
|
||||
void ProcFsShutdown( void )
|
||||
{
|
||||
}
|
||||
|
||||
void ProcFsRegisterDevice( pScanData ps )
|
||||
{
|
||||
}
|
||||
|
||||
void ProcFsUnregisterDevice( pScanData ps )
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* guard __KERNEL__ */
|
||||
|
||||
/* END PLUSTEK-PP_PROCFS.C ..................................................*/
|
|
@ -0,0 +1,228 @@
|
|||
/*.............................................................................
|
||||
* Project : linux driver for Plustek parallel-port scanners
|
||||
*.............................................................................
|
||||
* File: plustek-pp_procs.h
|
||||
* here are the prototypes of all exported functions
|
||||
*.............................................................................
|
||||
*
|
||||
* based on sources acquired from Plustek Inc.
|
||||
* Copyright (C) 1998 Plustek Inc.
|
||||
* Copyright (C) 2000-2003 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
* also based on the work done by Rick Bronson <rick@efn.org>
|
||||
*.............................................................................
|
||||
* History:
|
||||
* 0.30 - initial version
|
||||
* 0.31 - no changes
|
||||
* 0.32 - no changes
|
||||
* 0.33 - no changes
|
||||
* 0.34 - added this history
|
||||
* 0.35 - added Kevins´ changes to MiscRestorePort
|
||||
* changed prototype of MiscReinitStruct
|
||||
* added prototype for function PtDrvLegalRequested()
|
||||
* 0.36 - added prototype for function MiscLongRand()
|
||||
* removed PtDrvLegalRequested()
|
||||
* changed prototype of function MiscInitPorts()
|
||||
* 0.37 - added io.c and procfs.c
|
||||
* added MiscGetModelName()
|
||||
* added ModelSetA3I()
|
||||
* 0.38 - added P12 stuff
|
||||
* removed prototype of IOScannerIdleMode()
|
||||
* removed prototype of IOSPPWrite()
|
||||
* 0.39 - moved prototypes for the user space stuff to plustek-share.h
|
||||
* 0.40 - no changes
|
||||
* 0.41 - no changes
|
||||
* 0.42 - added MapAdjust
|
||||
*
|
||||
*.............................................................................
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef __PROCS_H__
|
||||
#define __PROCS_H__
|
||||
|
||||
/*
|
||||
* implementation in plustekpp-misc.c
|
||||
*/
|
||||
pScanData MiscAllocAndInitStruct( void );
|
||||
int MiscReinitStruct ( pScanData ps );
|
||||
|
||||
int MiscInitPorts ( pScanData ps, int port );
|
||||
void MiscRestorePort ( pScanData ps );
|
||||
inline void MiscStartTimer ( pTimerDef timer, unsigned long us );
|
||||
inline int MiscCheckTimer ( pTimerDef timer );
|
||||
|
||||
int MiscRegisterPort ( pScanData ps, int portAddr );
|
||||
void MiscUnregisterPort ( pScanData ps );
|
||||
int MiscClaimPort ( pScanData ps );
|
||||
void MiscReleasePort ( pScanData ps );
|
||||
Long MiscLongRand ( void );
|
||||
const char *MiscGetModelName( UShort id );
|
||||
|
||||
#ifdef DEBUG
|
||||
Bool MiscAllPointersSet( pScanData ps );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* implementation in plustekpp-detect.c
|
||||
*/
|
||||
int DetectScanner( pScanData ps, int mode );
|
||||
|
||||
/*
|
||||
* implementation in plustekpp-p48xx.c
|
||||
*/
|
||||
int P48xxInitAsic( pScanData ps );
|
||||
|
||||
/*
|
||||
* implementation in plustekpp-p9636.c
|
||||
*/
|
||||
int P9636InitAsic( pScanData ps );
|
||||
|
||||
/*
|
||||
* implementation in plustekpp-p12.c
|
||||
*/
|
||||
int P12InitAsic ( pScanData ps );
|
||||
void P12SetGeneralRegister( pScanData ps );
|
||||
|
||||
/*
|
||||
* implementation in plustekpp-p12ccd.c
|
||||
*/
|
||||
void P12InitCCDandDAC( pScanData ps, Bool shading );
|
||||
|
||||
/*
|
||||
* implementation in plustekpp-models.c
|
||||
*/
|
||||
void ModelSet4800 ( pScanData ps );
|
||||
void ModelSet4830 ( pScanData ps );
|
||||
void ModelSet600 ( pScanData ps );
|
||||
void ModelSet12000( pScanData ps );
|
||||
void ModelSetA3I ( pScanData ps );
|
||||
void ModelSet9630 ( pScanData ps );
|
||||
void ModelSet9636 ( pScanData ps );
|
||||
void ModelSetP12 ( pScanData ps );
|
||||
|
||||
/*
|
||||
* implementation in plustekpp-dac.c
|
||||
*/
|
||||
int DacInitialize( pScanData ps );
|
||||
|
||||
void DacP98AdjustDark ( pScanData ps );
|
||||
void DacP98FillGainOutDirectPort ( pScanData ps );
|
||||
void DacP98FillShadingDarkToShadingRegister( pScanData ps );
|
||||
|
||||
void DacP96WriteBackToGammaShadingRAM( pScanData ps );
|
||||
|
||||
void DacP98003FillToDAC ( pScanData ps, pRGBByteDef regs, pColorByte data );
|
||||
void DacP98003AdjustGain( pScanData ps, ULong color, Byte hilight );
|
||||
Byte DacP98003SumGains ( pUChar pb, ULong pixelsLine );
|
||||
|
||||
/*
|
||||
* implementation in plustekpp-motor.c
|
||||
*/
|
||||
int MotorInitialize ( pScanData ps );
|
||||
void MotorSetConstantMove( pScanData ps, Byte bMovePerStep );
|
||||
void MotorToHomePosition ( pScanData ps );
|
||||
|
||||
void MotorP98GoFullStep ( pScanData ps, ULong dwStep );
|
||||
|
||||
void MotorP96SetSpeedToStopProc( pScanData ps );
|
||||
void MotorP96ConstantMoveProc ( pScanData ps, ULong dwLines );
|
||||
Bool MotorP96AheadToDarkArea ( pScanData ps );
|
||||
void MotorP96AdjustCurrentSpeed( pScanData ps, Byte bSpeed );
|
||||
|
||||
void MotorP98003BackToHomeSensor ( pScanData ps );
|
||||
void MotorP98003ModuleForwardBackward( pScanData ps );
|
||||
void MotorP98003ForceToLeaveHomePos ( pScanData ps );
|
||||
void MotorP98003PositionYProc ( pScanData ps, ULong steps);
|
||||
|
||||
/*
|
||||
* implementation in plustekpp-map.c
|
||||
*/
|
||||
void MapInitialize ( pScanData ps );
|
||||
void MapSetupDither( pScanData ps );
|
||||
void MapAdjust ( pScanData ps, int which );
|
||||
|
||||
/*
|
||||
* implementation in plustekpp-image.c
|
||||
*/
|
||||
int ImageInitialize( pScanData ps );
|
||||
|
||||
/*
|
||||
* implementation in plustekpp-genericio.c
|
||||
*/
|
||||
int IOFuncInitialize ( pScanData ps );
|
||||
Byte IOSetToMotorRegister ( pScanData ps );
|
||||
Byte IOGetScanState ( pScanData ps, Bool fOpenned );
|
||||
Byte IOGetExtendedStatus ( pScanData ps );
|
||||
void IOGetCurrentStateCount( pScanData, pScanState pScanStep);
|
||||
int IOIsReadyForScan ( pScanData ps );
|
||||
|
||||
void IOSetXStepLineScanTime( pScanData ps, Byte b );
|
||||
void IOSetToMotorStepCount ( pScanData ps );
|
||||
void IOSelectLampSource ( pScanData ps );
|
||||
Bool IOReadOneShadingLine ( pScanData ps, pUChar pBuf, ULong len );
|
||||
ULong IOReadFifoLength ( pScanData ps );
|
||||
void IOPutOnAllRegisters ( pScanData ps );
|
||||
void IOReadColorData ( pScanData ps, pUChar pBuf, ULong len );
|
||||
|
||||
/*
|
||||
* implementation in plustekpp-io.c
|
||||
*/
|
||||
int IOInitialize ( pScanData ps );
|
||||
void IOMoveDataToScanner ( pScanData ps, pUChar pBuffer, ULong size );
|
||||
void IODownloadScanStates( pScanData ps );
|
||||
void IODataToScanner ( pScanData, Byte bValue );
|
||||
void IODataToRegister ( pScanData ps, Byte bReg, Byte bData );
|
||||
Byte IODataFromRegister ( pScanData ps, Byte bReg );
|
||||
void IORegisterToScanner ( pScanData ps, Byte bReg );
|
||||
void IODataRegisterToDAC ( pScanData ps, Byte bReg, Byte bData );
|
||||
|
||||
Byte IODataRegisterFromScanner( pScanData ps, Byte bReg );
|
||||
void IOCmdRegisterToScanner ( pScanData ps, Byte bReg, Byte bData );
|
||||
void IORegisterDirectToScanner( pScanData, Byte bReg );
|
||||
void IOSoftwareReset ( pScanData ps );
|
||||
void IOReadScannerImageData ( pScanData ps, pUChar pBuf, ULong size );
|
||||
void IOFill97003Register ( pScanData ps, Byte bDecode1, Byte bDecode2 );
|
||||
|
||||
void IOOut ( Byte data, UShort port );
|
||||
void IOOutDelayed( Byte data, UShort port );
|
||||
Byte IOIn ( UShort port );
|
||||
Byte IOInDelayed ( UShort port );
|
||||
|
||||
|
||||
/*
|
||||
* implementation in plustekpp-tpa.c
|
||||
*/
|
||||
void TPAP98001AverageShadingData( pScanData ps );
|
||||
void TPAP98003FindCenterPointer ( pScanData ps );
|
||||
void TPAP98003Reshading ( pScanData ps );
|
||||
|
||||
/*
|
||||
* implementation in plustekpp-scale.c
|
||||
*/
|
||||
void ScaleX( pScanData ps, pUChar inBuf, pUChar outBuf );
|
||||
|
||||
/*
|
||||
* implementation in plustekpp-procfs.c (Kernel-mode only)
|
||||
*/
|
||||
#ifdef __KERNEL__
|
||||
int ProcFsInitialize ( void );
|
||||
void ProcFsShutdown ( void );
|
||||
void ProcFsRegisterDevice ( pScanData ps );
|
||||
void ProcFsUnregisterDevice( pScanData ps );
|
||||
#endif
|
||||
|
||||
#endif /* guard __PROCS_H__ */
|
||||
|
||||
/* END PLUSTEK-PP_PROCS.H ...................................................*/
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,134 @@
|
|||
/*.............................................................................
|
||||
* Project : linux driver for Plustek parallel-port scanners
|
||||
*.............................................................................
|
||||
* File: plustek-pp_scale.c
|
||||
*.............................................................................
|
||||
*
|
||||
* Scaling functionality
|
||||
* Copyright (C) 2000-2003 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
*.............................................................................
|
||||
* History:
|
||||
* 0.32 - initial version
|
||||
* 0.33 - no changes
|
||||
* 0.34 - no changes
|
||||
* 0.35 - no changes
|
||||
* 0.36 - no changes
|
||||
* 0.37 - no changes
|
||||
* 0.38 - no changes
|
||||
* 0.39 - no changes
|
||||
* 0.40 - no changes
|
||||
* 0.41 - no changes
|
||||
* 0.42 - changed include names
|
||||
*
|
||||
*.............................................................................
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include "plustek-pp_scan.h"
|
||||
|
||||
/************************ exported functions *********************************/
|
||||
|
||||
/*.............................................................................
|
||||
* scaling picture data in x-direction, using a DDA algo
|
||||
* (digital differential analyzer).
|
||||
*/
|
||||
void ScaleX( pScanData ps, pUChar inBuf, pUChar outBuf )
|
||||
{
|
||||
UChar tmp;
|
||||
int step;
|
||||
int izoom;
|
||||
int ddax;
|
||||
register ULong i, j, x;
|
||||
|
||||
#ifdef DEBUG
|
||||
_VAR_NOT_USED( dbg_level );
|
||||
#endif
|
||||
|
||||
/* scale... */
|
||||
izoom = (int)(1.0/ps->DataInf.XYRatio * 1000);
|
||||
|
||||
switch( ps->DataInf.wAppDataType ) {
|
||||
|
||||
case COLOR_BW : step = 0; break;
|
||||
case COLOR_HALFTONE: step = 0; break;
|
||||
case COLOR_256GRAY : step = 1; break;
|
||||
case COLOR_TRUE24 : step = 3; break; /*NOTE: COLOR_TRUE32 is the same !*/
|
||||
case COLOR_TRUE48 : step = 6; break;
|
||||
default : step = 99; break;
|
||||
}
|
||||
|
||||
/*
|
||||
* when not supported, only copy the data
|
||||
*/
|
||||
if( 99 == step ) {
|
||||
memcpy( outBuf, inBuf, ps->DataInf.dwAppBytesPerLine );
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* now scale...
|
||||
*/
|
||||
if( 0 == step ) {
|
||||
/*
|
||||
* binary scaling
|
||||
*/
|
||||
ddax = 0;
|
||||
x = 0;
|
||||
memset( outBuf, 0, ps->DataInf.dwAppBytesPerLine );
|
||||
|
||||
for( i = 0; i < ps->DataInf.dwPhysBytesPerLine*8; i++ ) {
|
||||
|
||||
ddax -= 1000;
|
||||
|
||||
while( ddax < 0 ) {
|
||||
|
||||
tmp = inBuf[(i>>3)];
|
||||
|
||||
if((x>>3) < ps->DataInf.dwAppBytesPerLine ) {
|
||||
if( 0 != (tmp &= (1 << ((~(i & 0x7))&0x7))))
|
||||
outBuf[x>>3] |= (1 << ((~(x & 0x7))&0x7));
|
||||
}
|
||||
x++;
|
||||
ddax += izoom;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/*
|
||||
* color and gray scaling
|
||||
*/
|
||||
ddax = 0;
|
||||
x = 0;
|
||||
for( i = 0; i < ps->DataInf.dwPhysBytesPerLine*step; i+=step ) {
|
||||
|
||||
ddax -= 1000;
|
||||
|
||||
while( ddax < 0 ) {
|
||||
|
||||
for( j = 0; j < (ULong)step; j++ ) {
|
||||
|
||||
if((x+j) < ps->DataInf.dwAppBytesPerLine ) {
|
||||
outBuf[x+j] = inBuf[i+j];
|
||||
}
|
||||
}
|
||||
x += step;
|
||||
ddax += izoom;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* END PLUSTEK-PP_SCALE.C ...................................................*/
|
|
@ -0,0 +1,185 @@
|
|||
/*.............................................................................
|
||||
* Project : linux driver for Plustek parallel-port scanners
|
||||
*.............................................................................
|
||||
* File: plustek-pp_scan.h - the global header for the plustek driver
|
||||
*.............................................................................
|
||||
*
|
||||
* Copyright (C) 2000-2003 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
*.............................................................................
|
||||
* History:
|
||||
* 0.30 - initial version
|
||||
* 0.31 - no changes
|
||||
* 0.32 - changed _DODELAY macro to work properly for delays > 5 ms
|
||||
* 0.33 - no changes
|
||||
* 0.34 - no changes
|
||||
* 0.35 - removed _PTDRV_PUT_SCANNER_MODEL from ioctl interface
|
||||
* 0.36 - now including plustek-share.h from the backend path
|
||||
* changed _INB/_OUTB to _INB_STATUS, _INB_CTRL, _INB_DATA ...
|
||||
* 0.37 - added _OUTB_ECTL/_INB_ECTL, _MAX_PTDEVS, _DRV_NAME and _MAX_BTNS
|
||||
* added _OUTB_STATUS
|
||||
* 0.38 - added _IS_ASIC96() and _IS_ASIC98() macros
|
||||
* 0.39 - no changes
|
||||
* 0.40 - no changes
|
||||
* 0.41 - no changes
|
||||
* 0.42 - changed include names
|
||||
*
|
||||
*.............................................................................
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef __PLUSTEK_SCAN_H__
|
||||
#define __PLUSTEK_SCAN_H__
|
||||
|
||||
#ifndef __KERNEL__
|
||||
|
||||
# include <stdlib.h>
|
||||
# include <stdarg.h>
|
||||
# include <string.h>
|
||||
# include <stdio.h>
|
||||
# include <unistd.h>
|
||||
# include <sched.h>
|
||||
# include <sys/time.h>
|
||||
# include <sys/signal.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include <sys/io.h>
|
||||
|
||||
#else
|
||||
|
||||
# include <linux/version.h>
|
||||
# include "plustek-pp_sysdep.h"
|
||||
# include <linux/delay.h>
|
||||
# include <linux/parport.h>
|
||||
|
||||
#ifdef LINUX_24
|
||||
# include <linux/parport_pc.h>
|
||||
#endif /* LINUX_24 */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
/*.............................................................................
|
||||
* driver properties
|
||||
*/
|
||||
#define _DRV_NAME "pt_drv" /* driver's name */
|
||||
#define _MAX_PTDEVS 4 /* support for 4 devices */
|
||||
#define _MAX_BTNS 6 /* support for 6 buttons */
|
||||
#define _PTDRV_MAJOR 40 /* our major number */
|
||||
|
||||
/*.............................................................................
|
||||
* for port operations
|
||||
*/
|
||||
# define _OPF ps->IO.fnOut
|
||||
# define _IPF ps->IO.fnIn
|
||||
|
||||
#if 1
|
||||
|
||||
#define _OUTB_CTRL(pSD,port_value) _OPF(port_value,pSD->IO.pbControlPort)
|
||||
#define _OUTB_DATA(pSD,port_value) _OPF(port_value,pSD->IO.pbSppDataPort)
|
||||
#define _OUTB_ECTL(pSD,port_value) _OPF(port_value,(pSD->IO.portBase+0x402))
|
||||
#define _OUTB_STATUS(pSD,port_value) _OPF(port_value,pSD->IO.pbStatusPort)
|
||||
|
||||
#define _INB_CTRL(pSD) _IPF(pSD->IO.pbControlPort)
|
||||
#define _INB_DATA(pSD) _IPF(pSD->IO.pbSppDataPort)
|
||||
#define _INB_EPPDATA(pSD) _IPF(pSD->IO.pbEppDataPort)
|
||||
#define _INB_STATUS(pSD) _IPF(pSD->IO.pbStatusPort)
|
||||
#define _INB_ECTL(pSD) _IPF((pSD->IO.portBase+0x402))
|
||||
|
||||
#else
|
||||
|
||||
#define _OUTB_CTRL(pSD,port_value) parport_pc_write_control(pSD->pp, port_value)
|
||||
#define _OUTB_DATA(pSD,port_value) parport_pc_write_data(pSD->pp, port_value)
|
||||
#define _OUTB_STATUS(pSD,port_value) parport_pc_write_status(pSD->pp, port_value)
|
||||
|
||||
#define _INB_CTRL(pSD) parport_pc_read_control(pSD->pp)
|
||||
#define _INB_DATA(pSD) parport_pc_read_data(pSD->pp)
|
||||
#define _INB_STATUS(pSD) parport_pc_read_status(pSD->pp)
|
||||
|
||||
#ifdef LINUX_24
|
||||
# define _OUTB_ECTL(pSD,port_value) outb_p(port_value,(pSD->IO.portBase+0x402))
|
||||
# define _INB_EPPDATA(pSD) inb_p(pSD->IO.pbEppDataPort)
|
||||
# define _INB_ECTL(pSD) inb_p((pSD->IO.portBase+0x402))
|
||||
#else
|
||||
# define _OUTB_ECTL(pSD,port_value) parport_pc_write_econtrol(pSD->pp, port_value)
|
||||
# define _INB_EPPDATA(pSD) parport_pc_read_epp(pSD->pp)
|
||||
# define _INB_ECTL(pSD) parport_pc_read_econtrol(pSD->pp)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*.............................................................................
|
||||
* for memory allocation
|
||||
*/
|
||||
#ifndef __KERNEL__
|
||||
# define _KALLOC(x,y) malloc(x)
|
||||
# define _KFREE(x) free(x)
|
||||
# define _VMALLOC(x) malloc(x)
|
||||
# define _VFREE(x) free(x)
|
||||
#else
|
||||
# define _KALLOC(x,y) kmalloc(x,y)
|
||||
# define _KFREE(x) kfree(x)
|
||||
# define _VMALLOC(x) vmalloc(x)
|
||||
# define _VFREE(x) vfree(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* WARNING - never use the _SECOND define with the _DODELAY macro !!
|
||||
* they are for use the the MiscStartTimer function and the _DO_UDELAY macro
|
||||
*/
|
||||
#ifndef __KERNEL__
|
||||
typedef long long TimerDef, *pTimerDef;
|
||||
#else
|
||||
typedef long long TimerDef, *pTimerDef;
|
||||
#endif
|
||||
|
||||
#define _MSECOND 1000 /* based on 1 us */
|
||||
#define _SECOND (1000*_MSECOND)
|
||||
|
||||
|
||||
/*.............................................................................
|
||||
* timer topics
|
||||
*/
|
||||
#ifndef __KERNEL__
|
||||
#define _DO_UDELAY(usecs) { int i; for( i = usecs; i--; ) outb(0x80,0); }
|
||||
#define _DODELAY(msecs) { int i; for( i = msecs; i--; ) _DO_UDELAY(1); }
|
||||
#else
|
||||
#define _DO_UDELAY(usecs) udelay(usecs)
|
||||
#define _DODELAY(msecs) mdelay(msecs)
|
||||
#endif
|
||||
|
||||
/*.............................................................................
|
||||
* include the shared stuff right here, this concerns the ioctl interface
|
||||
* and the communication stuff
|
||||
*/
|
||||
#include "plustek-share.h"
|
||||
|
||||
/*.............................................................................
|
||||
* WARNING: don't move the following headers above the previous defines !!!!!!!
|
||||
*
|
||||
* the include files for user-mode and kernel-mode program
|
||||
*/
|
||||
#include "plustek-pp_types.h"
|
||||
#include "plustek-pp_hwdefs.h"
|
||||
#include "plustek-pp_scandata.h"
|
||||
#include "plustek-pp_procs.h"
|
||||
#include "plustek-pp_dbg.h"
|
||||
|
||||
/*.............................................................................
|
||||
* some macros for convenience
|
||||
*/
|
||||
#define _IS_ASIC96(aid) ((_ASIC_IS_96001 == aid) || (_ASIC_IS_96003 == aid))
|
||||
#define _IS_ASIC98(aid) ((_ASIC_IS_98001 == aid) || (_ASIC_IS_98003 == aid))
|
||||
|
||||
#endif /* guard __PLUSTEK_SCAN_H__ */
|
||||
|
||||
/* END PLUSTEK-PP_SCAN.H ....................................................*/
|
|
@ -0,0 +1,645 @@
|
|||
/*.............................................................................
|
||||
* Project : linux driver for Plustek parallel-port scanners
|
||||
*.............................................................................
|
||||
* File: plustek-pp_scandata.h - here we define the ScanData structure...
|
||||
* and a lot of register settings
|
||||
*.............................................................................
|
||||
*
|
||||
* based on sources acquired from Plustek Inc.
|
||||
* Copyright (C) 1998 Plustek Inc.
|
||||
* Copyright (C) 2000-2003 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
* also based on the work done by Rick Bronson <rick@efn.org>
|
||||
*.............................................................................
|
||||
* History:
|
||||
* 0.30 - initial version
|
||||
* 0.31 - no changes
|
||||
* 0.32 - added fWarmupNeeded to struct ScanData
|
||||
* - removed function FillDataToColorTable from struct ScanData
|
||||
* - removed dwLampDelay from struct ScanData
|
||||
* 0.33 - cosmetic changes
|
||||
* - removed PositionLamp from structure
|
||||
* - added dwLastPortMode to struct ScanData
|
||||
* 0.34 - removed WaitBack() function from pScanData structure
|
||||
* removed wStayMaxStep from pScanData structure
|
||||
* 0.35 - removed SetInitialGainRAM from pScanData structure
|
||||
* changed ModelStr list
|
||||
* 0.36 - added some defines for the ASIC 96001 (model 4800)
|
||||
* added wDither to DataInfo structure
|
||||
* removed dwPreferSize from struct ScannerCaps
|
||||
* cleanup
|
||||
* moved all stuff that is used by the backend and the driver
|
||||
* to plustek-share.h which is in the backend directory
|
||||
* added ModelOverride parameter to struct
|
||||
* added strcut pardevice to struct
|
||||
* 0.37 - added bIODelay for SPP/BIDI port operations
|
||||
* added ReadData to struct
|
||||
* added ProcDirDef
|
||||
* added ButtonCount
|
||||
* removed RegisterToScanner from struct
|
||||
* removed MaxDpiByInterpolation from struct
|
||||
* 0.38 - added function PutToIdleMode() to struct
|
||||
* added function Calibration() to struct
|
||||
* changed interface of the ReInitAsic() function
|
||||
* major changes: moved a lot of stuff to hwdefs.h
|
||||
* added IO, Device, Shade, Scan and Bufs to struct
|
||||
* 0.39 - added forceMode to struct
|
||||
* added f97003, b97003DarkR, b97003DarkB, b97003DarkG to struct
|
||||
* 0.40 - no changes
|
||||
* 0.41 - no changes
|
||||
* 0.42 - no changes
|
||||
*
|
||||
*.............................................................................
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef __SCANDATA_H__
|
||||
#define __SCANDATA_H__
|
||||
|
||||
/*
|
||||
*Directory information for the /proc interface
|
||||
*/
|
||||
typedef struct {
|
||||
struct proc_dir_entry *entry; /* Directory /proc/pt_drv/X */
|
||||
struct proc_dir_entry *info; /* .../info */
|
||||
struct proc_dir_entry *buttons[_MAX_BTNS]; /* .../buttons */
|
||||
} ProcDirDef, *pProcDirDef;
|
||||
|
||||
/*
|
||||
* here we have some structs internally used
|
||||
*/
|
||||
/* CHECK: replace current stuff by this - looks much better !!! */
|
||||
#if 0
|
||||
|
||||
typedef struct _IMAGESIZE
|
||||
{
|
||||
DWORD dwPixels;
|
||||
DWORD dwBytes;
|
||||
DWORD dwLines;
|
||||
DWORD dwBytesCh;
|
||||
} IMAGESIZE, *PIMAGESIZE;
|
||||
|
||||
|
||||
typedef struct _IMAGEDEF
|
||||
{
|
||||
IMAGESIZE Image;
|
||||
DWORD dwVxDFlag;
|
||||
DWORD dwScanFlag;
|
||||
CROPRECT Area;
|
||||
XY Dpi;
|
||||
WORD wDataType;
|
||||
WORD wBrightness;
|
||||
WORD wPhyDpiY;
|
||||
WORD wResult;
|
||||
WORD Reserved;
|
||||
} IMAGEDEF, *PIMAGEDEF;
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
ULong dwVxdFlag;
|
||||
ULong dwScanFlag;
|
||||
|
||||
/*
|
||||
* CHECK: why there are dups ?
|
||||
*/
|
||||
ULong dwAppLinesPerArea;
|
||||
ULong dwAppPixelsPerLine;
|
||||
ULong dwAppPhyBytesPerLine;
|
||||
ULong dwAppBytesPerLine;
|
||||
ULong dwAsicPixelsPerPlane;
|
||||
ULong dwAsicBytesPerPlane;
|
||||
ULong dwAsicBytesPerLine;
|
||||
CropRect crImage;
|
||||
XY xyAppDpi;
|
||||
XY xyPhyDpi;
|
||||
pUChar pCurrentBuffer;
|
||||
UShort wPhyDataType;
|
||||
UShort wAppDataType;
|
||||
UShort wYSum;
|
||||
|
||||
short siBrightness;
|
||||
|
||||
/*
|
||||
* CHANGE added these vars for scaling
|
||||
*/
|
||||
double XYRatio;
|
||||
ULong dwPhysBytesPerLine;
|
||||
|
||||
/*
|
||||
* CHANGE added this for selecting dither method
|
||||
*/
|
||||
UShort wDither;
|
||||
|
||||
} DataInfo, *pDataInfo;
|
||||
|
||||
|
||||
/*
|
||||
* here it is, the great structure
|
||||
*/
|
||||
typedef struct scandata
|
||||
{
|
||||
#ifdef __KERNEL__
|
||||
UInt flags; /* as follows: */
|
||||
#define _PTDRV_INITALIZED 0x00000001
|
||||
#define _PTDRV_OPEN 0x00000002
|
||||
|
||||
struct pardevice *pardev; /* for accessing parport... */
|
||||
struct parport *pp;
|
||||
ProcDirDef procDir;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* device control
|
||||
*/
|
||||
ULong devno;
|
||||
int lampoff;
|
||||
int warmup;
|
||||
int lOffonEnd;
|
||||
|
||||
/*
|
||||
* CHECK for controlling the ECP-mode (not used now)
|
||||
*/
|
||||
#if 0
|
||||
Byte bOldECR;
|
||||
Bool fECPReadWriteTest;
|
||||
Bool fSkipEcpFlag;
|
||||
Bool fECPFlag;
|
||||
Bool fECPtoEPP;
|
||||
Bool fECRFIFO;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* the following stuff gets changed on a per model basis
|
||||
*/
|
||||
UShort ModelOverride; /* for non-auto detection stuff */
|
||||
|
||||
UShort Offset70; /* CHECK: --> to Device */
|
||||
UShort BufferSizeBase; /* --> to Device */
|
||||
UShort BufferSizePerModel; /* --> to Device */
|
||||
UShort TimePerLine; /* --> to Device */
|
||||
|
||||
/*
|
||||
* scanner properties
|
||||
*/
|
||||
RegData AsicReg; /* here we have the 98001/3 register set */
|
||||
Reg96 Asic96Reg; /* here we hold the 96001/3 specific regs */
|
||||
|
||||
LensInfo LensInf;
|
||||
ScannerCaps sCaps;
|
||||
ULong dwScannerSize;
|
||||
Byte bCurrentSpeed;
|
||||
pUChar pbMapRed;
|
||||
pUChar pbMapGreen;
|
||||
pUChar pbMapBlue;
|
||||
|
||||
ULong TotalBufferRequire;
|
||||
ULong BufferForColorRunTable;
|
||||
UShort PhysicalDpi;
|
||||
UShort RdPix; /* for ASIC 96003 devices */
|
||||
|
||||
Byte a_bMapTable[4096 * 3]; /* pre 98001 was 256 * 3 */
|
||||
Byte a_nbNewAdrPointer[_SCANSTATE_BYTES];
|
||||
|
||||
/*
|
||||
* for P9600x ASIC based scanners
|
||||
*/
|
||||
Bool fColorMoreRedFlag;
|
||||
Bool fColorMoreBlueFlag;
|
||||
Bool fSonyCCD;
|
||||
Bool f97003;
|
||||
Byte AsicRedColor;
|
||||
Byte AsicGreenColor;
|
||||
Byte RedDataReady;
|
||||
Byte GreenDataReady;
|
||||
Byte b1stColorByte;
|
||||
Byte b1stColor;
|
||||
Byte b1stMask;
|
||||
Byte b2ndColorByte;
|
||||
Byte b2ndColor;
|
||||
Byte b2ndMask;
|
||||
Byte b3rdColorByte;
|
||||
Byte b3rdColor;
|
||||
Byte b3rdMask;
|
||||
Byte b1stLinesOffset;
|
||||
Byte b2ndLinesOffset;
|
||||
Byte bLampOn;
|
||||
Byte bExtraAdd;
|
||||
Byte bFifoCount;
|
||||
Byte bMinReadFifo;
|
||||
Byte FullStep;
|
||||
Byte StepMask;
|
||||
Byte MotorOn;
|
||||
Byte MotorFreeRun;
|
||||
Byte IgnorePF;
|
||||
Byte bMotorStepTableNo;
|
||||
|
||||
/* for ASIC 97003... */
|
||||
Byte b97003DarkR;
|
||||
Byte b97003DarkG;
|
||||
Byte b97003DarkB;
|
||||
|
||||
/* CHECK: to Scan!!!! */
|
||||
pUChar pGetBufR; /* NOTE: these aren't actually Red/Green buffer */
|
||||
pUChar pGetBufG; /* pointers but instead are used */
|
||||
pUChar pPutBufR; /* generically to point to the first 2 */
|
||||
pUChar pPutBufG; /* color buffers as temp storage */
|
||||
|
||||
pUChar pCurrentColorRunTable;
|
||||
UShort a_wGrayInitTime[3];
|
||||
UShort a_wColorInitTime[3];
|
||||
UShort BackwardSteps;
|
||||
UShort wLinesPer64kTime;
|
||||
UShort ShadingBufferSize;
|
||||
UShort ShadingBankSize;
|
||||
UShort ShadingBankRed;
|
||||
UShort ShadingBankGreen;
|
||||
UShort ShadingBankBlue;
|
||||
UShort ShadingScanLineBlks;
|
||||
UShort ShadingScanLineLen;
|
||||
UShort wOverBlue;
|
||||
UShort FBKScanLineBlks;
|
||||
UShort FBKScanLineLenBase;
|
||||
UShort FBKScanLineLen;
|
||||
UShort OneScanLineLen;
|
||||
|
||||
/*
|
||||
* the DAC part - to Shade !!!
|
||||
*/
|
||||
UShort wsDACCompareHighRed, wsDACCompareLowRed;
|
||||
UShort wsDACCompareHighGreen, wsDACCompareLowGreen;
|
||||
UShort wsDACCompareHighBlue, wsDACCompareLowBlue;
|
||||
UShort wsDACOffsetRed, wsDACOffsetGreen, wsDACOffsetBlue;
|
||||
Byte bsPreRedDAC, bsPreGreenDAC, bsPreBlueDAC;
|
||||
Byte bRedDAC, bGreenDAC, bBlueDAC;
|
||||
Byte bRedGainIndex, bGreenGainIndex, bBlueGainIndex;
|
||||
|
||||
/*
|
||||
* for image description
|
||||
*/
|
||||
DataInfo DataInf;
|
||||
Bool fReshaded;
|
||||
ULong dwDitherIndex;
|
||||
Bool fDoFilter, fFilterFirstLine;
|
||||
ULong dwDivFilter;
|
||||
ULong dwMul;
|
||||
Byte bOffsetFilter;
|
||||
ULong dwLinesFilter;
|
||||
pUChar pFilterBuf, pEndBuf;
|
||||
pUChar pGet1, pGet2, pGet3;
|
||||
|
||||
Byte bSetScanModeFlag; /* see Section 5 - Scanmodes --> ps->Shade.bIntermediate*/
|
||||
|
||||
/*
|
||||
* some admin vals (they used to be global vars in the original driver)
|
||||
*/
|
||||
Bool fScanningStatus;
|
||||
Byte bLastLampStatus;
|
||||
Bool fWarmupNeeded;
|
||||
ULong dwOffset70;
|
||||
ULong dwMaxReadFifoData;
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
pUChar pColorRunTable;
|
||||
pUChar pPrescan16;
|
||||
pUChar pPrescan8;
|
||||
UShort BufferForDataRead1;
|
||||
ULong BufferFor1stColor;
|
||||
ULong BufferFor2ndColor;
|
||||
pUChar driverbuf;
|
||||
pUChar pEndBufR;
|
||||
pUChar pEndBufG;
|
||||
pUChar pProcessingBuf;
|
||||
|
||||
/*
|
||||
* formerly used as global vars in ioproc.c, now in genericio.c
|
||||
*/
|
||||
pUChar pScanBuffer1;
|
||||
pUChar pScanBuffer2;
|
||||
|
||||
pModeTypeVar lpEppColorHomePos;
|
||||
pModeTypeVar lpEppColorExposure;
|
||||
pModeTypeVar lpBppColorHomePos;
|
||||
pModeTypeVar lpSppColorHomePos;
|
||||
UShort wMinCmpDpi;
|
||||
pModeTypeVar a_ColorSettings;
|
||||
pDiffModeVar a_tabDiffParam;
|
||||
|
||||
Byte bSpeed48;
|
||||
Byte bSpeed32;
|
||||
Byte bSpeed24;
|
||||
Byte bSpeed16;
|
||||
Byte bSpeed12;
|
||||
Byte bSpeed8;
|
||||
Byte bSpeed6;
|
||||
Byte bSpeed4;
|
||||
Byte bSpeed3;
|
||||
Byte bSpeed2;
|
||||
Byte bSpeed1;
|
||||
|
||||
Byte bHpMotor;
|
||||
Byte bStepSpeed;
|
||||
ULong dwFullStateSpeed;
|
||||
|
||||
/*
|
||||
* reference to globals from motor.c
|
||||
*/
|
||||
Bool fHalfStepTableFlag;
|
||||
Bool fFullLength;
|
||||
Byte bMoveDataOutFlag;
|
||||
Byte bExtraMotorCtrl;
|
||||
Byte bFastMoveFlag;
|
||||
Byte bOldStateCount;
|
||||
Byte bMotorSpeedData;
|
||||
Byte bCurrentLineCount;
|
||||
Byte bNewGap;
|
||||
Byte bNewCurrentLineCountGap;
|
||||
UShort wMaxMoveStep;
|
||||
ULong dwScanStateCount;
|
||||
ULong dwColorRunIndex;
|
||||
pByte a_bColorByteTable;
|
||||
pUChar pScanState;
|
||||
pUShort a_wMoveStepTable;
|
||||
|
||||
/*
|
||||
* for shading - dac.c
|
||||
* CHECK: move to ps->Shade
|
||||
*/
|
||||
Byte bShadingTimeFlag;
|
||||
ULong dwShadow, dwShadowCh;
|
||||
ULong dwHilight, dwHilightCh;
|
||||
ULong dwShadingLen, dwShadingPixels;
|
||||
pUShort pwShadow;
|
||||
|
||||
/*
|
||||
* from transform.c
|
||||
*/
|
||||
Byte bRedHigh, bGreenHigh, bBlueHigh;
|
||||
UShort wPosAdjustX;
|
||||
UShort wNegAdjustX;
|
||||
UShort wReduceRedFactor;
|
||||
UShort wReduceGreenFactor;
|
||||
UShort wReduceBlueFactor;
|
||||
ULong dwOffsetNegative;
|
||||
|
||||
/*
|
||||
* reference to globals from map.c
|
||||
*/
|
||||
#define _DITHERSIZE 64
|
||||
Byte a_bDitherPattern[_DITHERSIZE];
|
||||
Short wBrightness;
|
||||
Short wContrast;
|
||||
UShort wInitialStep;
|
||||
ULong dwSizeMustProcess;
|
||||
|
||||
/*
|
||||
* here we have pointers to the functions to call
|
||||
*/
|
||||
Bool (*OpenScanPath) (pScanData);
|
||||
void (*CloseScanPath) (pScanData);
|
||||
int (*ReadWriteTest) (pScanData);
|
||||
void (*PutToIdleMode) (pScanData);
|
||||
int (*Calibration) (pScanData);
|
||||
void (*SetupScannerVariables) (pScanData);
|
||||
int (*SetupScanSettings) (pScanData, pScanInfo pInf );
|
||||
void (*GetImageInfo) (pScanData, pImgDef pInf );
|
||||
Bool (*WaitForShading) (pScanData);
|
||||
void (*WaitForPositionY) (pScanData);
|
||||
void (*InitialSetCurrentSpeed) (pScanData);
|
||||
Bool (*GotoShadingPosition) (pScanData);
|
||||
void (*SetupScanningCondition) (pScanData);
|
||||
void (*SetMotorSpeed) (pScanData,Byte bSpeed,Bool fSetRunState);
|
||||
void (*FillRunNewAdrPointer) (pScanData);
|
||||
void (*SetupMotorRunTable) (pScanData);
|
||||
void (*PauseColorMotorRunStates) (pScanData);
|
||||
void (*UpdateDataCurrentReadLine)(pScanData);
|
||||
Bool (*ReadOneImageLine) (pScanData);
|
||||
|
||||
/* used only by ASIC9800x Part of the driver ! */
|
||||
void (*ReInitAsic) (pScanData, Bool shading);
|
||||
|
||||
/* value used to read nibble's */
|
||||
Byte CtrlReadHighNibble;
|
||||
Byte CtrlReadLowNibble;
|
||||
|
||||
/*
|
||||
* asic register offset values
|
||||
*/
|
||||
Byte RegSwitchBus;
|
||||
Byte RegEPPEnable;
|
||||
Byte RegECPEnable;
|
||||
Byte RegReadDataMode;
|
||||
Byte RegWriteDataMode;
|
||||
Byte RegInitDataFifo;
|
||||
Byte RegForceStep;
|
||||
Byte RegInitScanState;
|
||||
Byte RegRefreshScanState;
|
||||
Byte RegThresholdGapControl;
|
||||
Byte RegADCAddress;
|
||||
Byte RegADCData;
|
||||
Byte RegADCPixelOffset;
|
||||
Byte RegADCSerialOutStr;
|
||||
Byte RegResetConfig;
|
||||
Byte RegLensPosition;
|
||||
Byte RegStatus;
|
||||
Byte RegWaitStateInsert;
|
||||
Byte RegFifoOffset;
|
||||
Byte RegRFifoOffset;
|
||||
Byte RegGFifoOffset;
|
||||
Byte RegBFifoOffset;
|
||||
Byte RegBitDepth;
|
||||
Byte RegStepControl;
|
||||
Byte RegMotor0Control;
|
||||
Byte RegXStepTime;
|
||||
Byte RegGetScanState;
|
||||
Byte RegAsicID;
|
||||
Byte RegReadIOBufBus;
|
||||
Byte RegMemoryLow;
|
||||
Byte RegMemoryHigh;
|
||||
Byte RegModeControl;
|
||||
Byte RegLineControl;
|
||||
Byte RegScanControl;
|
||||
Byte RegMotorControl;
|
||||
#define _MotorDirForward 0x01 /* go forward */
|
||||
#define _MotorOn 0x02 /* turn on motor */
|
||||
#define _MotorIgnorePF 0x04 /* motor rolling don't care */
|
||||
/* paper define flag */
|
||||
#define _MotorFreeRun 0x80 /*ScanState count don't stop */
|
||||
/* Following bits (bit 3 & 4 are depended on StatusPort */
|
||||
/* bit-7:MotorType when it is 1: */
|
||||
#define _Motor1FullStep 0x08 /* bit 4 is ignored */
|
||||
/* When it is 0: */
|
||||
#define _Motor0FullStepWeak 0 /* Full step (driving weak) */
|
||||
#define _Motor0HalfStep 0x10 /* 1/2 step */
|
||||
#define _Motor0QuarterStep 0x08 /* 1/4 step */
|
||||
#define _Motor0FullStepStrong 0x18 /* Full step (driving strong)*/
|
||||
#define _MotorStepMask 0xe7
|
||||
/* for 96001 */
|
||||
#define _MotorFullStep96001 0x02
|
||||
#define _MotorOn96001 0x04
|
||||
#define _MotorIgnorePF96001 0x08
|
||||
|
||||
Byte RegConfiguration;
|
||||
Byte RegModelControl;
|
||||
Byte RegModel1Control;
|
||||
Byte RegMemAccessControl;
|
||||
#define _MemBanks 64 /* the number of banks, 5 ls bits */
|
||||
#define _MemBankMask (_MemBanks - 1)
|
||||
#define _MemBankSize1k 0
|
||||
#define _MemBankSize2k 0x40
|
||||
#define _MemBankSize4k 0x80
|
||||
#define _MemBankSize8k 0xc0
|
||||
/* 96001 specific */
|
||||
#define _MemBankSize2k96001 0x00
|
||||
#define _MemBankSize4k96001 0x40
|
||||
#define _MemBankSize8k96001 0x80
|
||||
|
||||
Byte RegDpiLow;
|
||||
Byte RegDpiHigh;
|
||||
Byte RegScanPosLow;
|
||||
Byte RegScanPosHigh;
|
||||
Byte RegWidthPixelsLow;
|
||||
Byte RegWidthPixelsHigh;
|
||||
Byte RegThresholdLow;
|
||||
Byte RegThresholdHigh;
|
||||
Byte RegThresholdControl;
|
||||
Byte RegWatchDogControl;
|
||||
#define _WDOnIntervalMask 0x0f /* WD * 8192 scan lines to turn
|
||||
off Lamp */
|
||||
#define _WDMotorLongInterval 0x40 /* short = 8192 lines time
|
||||
long = 32768 lines time */
|
||||
#define _WDEnable 0x80
|
||||
Byte RegModelControl2;
|
||||
#define _Model2ChannelSlct 0
|
||||
#define _Model2ChannelMult 0x01 /* bit on/off accords to JONES */
|
||||
#define _Model2CCSInvert 0x02
|
||||
#define _Model2DirectOutPort 0x04
|
||||
#define _Model2PipeLineDelayN 0x08
|
||||
#define _Model2ShiftGapTiming10 0x10
|
||||
#define _Model2BtnKeyPassThrough 0x20
|
||||
Byte RegRedDCAdjust;
|
||||
Byte RegGreenDCAdjust;
|
||||
Byte RegBlueDCAdjust;
|
||||
Byte RegRedChShadingOffset;
|
||||
Byte RegGreenChShadingOffset;
|
||||
Byte RegBlueChShadingOffset;
|
||||
Byte RegRedChDarkOffset;
|
||||
Byte RegGreenChDarkOffset;
|
||||
Byte RegBlueChDarkOffset;
|
||||
Byte RegWriteIOBusDecode1;
|
||||
Byte RegWriteIOBusDecode2;
|
||||
Byte RegScanStateControl;
|
||||
#define _ScanStateEvenMask 0x0f
|
||||
#define _ScanStateOddMask 0xf0
|
||||
Byte RegRedChEvenOffset;
|
||||
Byte RegGreenChEvenOffset;
|
||||
Byte RegBlueChEvenOffset;
|
||||
Byte RegRedChOddOffset;
|
||||
Byte RegGreenChOddOffset;
|
||||
Byte RegBlueChOddOffset;
|
||||
Byte RegRedGainOutDirect;
|
||||
Byte RegGreenGainOutDirect;
|
||||
Byte RegBlueGainOutDirect;
|
||||
Byte RegLedControl;
|
||||
#define _LedCmdActEnable 0x04
|
||||
#define _LedMotorActEnable 0x08
|
||||
#define _LedClrChActEnable 0x10 /* Color Channel Action */
|
||||
#define _LedLightOnActEnable 0x20
|
||||
#define _LedHostTurnOnEnable 0x40
|
||||
#define _LedActControl 0x80
|
||||
Byte RegShadingCorrectCtrl;
|
||||
#define _ShadingRCorrectX1 0
|
||||
#define _ShadingRCorrectX2 0x01
|
||||
#define _ShadingRCorrectX3 0x02
|
||||
#define _ShadingRCorrectX4 0x03
|
||||
#define _ShadingGCorrectX1 0
|
||||
#define _ShadingGCorrectX2 0x04
|
||||
#define _ShadingGCorrectX3 0x08
|
||||
#define _ShadingGCorrectX4 0x0c
|
||||
#define _ShadingBCorrectX1 0
|
||||
#define _ShadingBCorrectX2 0x10
|
||||
#define _ShadingBCorrectX3 0x20
|
||||
#define _ShadingBCorrectX4 0x30
|
||||
Byte RegScanStateBegin;
|
||||
Byte RegRedChDarkOffsetLow;
|
||||
Byte RegRedChDarkOffsetHigh;
|
||||
Byte RegGreenChDarkOffsetLow;
|
||||
Byte RegGreenChDarkOffsetHigh;
|
||||
Byte RegBlueChDarkOffsetLow;
|
||||
Byte RegBlueChDarkOffsetHigh;
|
||||
Byte RegResetPulse0;
|
||||
Byte RegResetPulse1;
|
||||
Byte RegCCDClampTiming0;
|
||||
Byte RegCCDClampTiming1;
|
||||
Byte RegVSMPTiming0;
|
||||
Byte RegVSMPTiming1;
|
||||
Byte RegCCDQ1Timing0;
|
||||
Byte RegCCDQ1Timing1;
|
||||
Byte RegCCDQ1Timing2;
|
||||
Byte RegCCDQ1Timing3;
|
||||
Byte RegCCDQ2Timing0;
|
||||
Byte RegCCDQ2Timing1;
|
||||
Byte RegCCDQ2Timing2;
|
||||
Byte RegCCDQ2Timing3;
|
||||
Byte RegADCclockTiming0;
|
||||
Byte RegADCclockTiming1;
|
||||
Byte RegADCclockTiming2;
|
||||
Byte RegADCclockTiming3;
|
||||
Byte RegADCDVTiming0;
|
||||
Byte RegADCDVTiming1;
|
||||
Byte RegADCDVTiming2;
|
||||
Byte RegADCDVTiming3;
|
||||
Byte RegScanStateEnd;
|
||||
|
||||
/* ASIC 98003 specific*/
|
||||
Byte RegFifoFullLength0;
|
||||
Byte RegFifoFullLength1;
|
||||
Byte RegFifoFullLength2;
|
||||
|
||||
Byte RegMotorTotalStep0;
|
||||
Byte RegMotorTotalStep1;
|
||||
Byte RegMotorFreeRunCount0;
|
||||
Byte RegMotorFreeRunCount1;
|
||||
Byte RegScanControl1;
|
||||
Byte RegMotorFreeRunTrigger;
|
||||
|
||||
Byte RegResetMTSC;
|
||||
|
||||
Byte RegMotor1Control;
|
||||
Byte RegMotor2Control;
|
||||
Byte RegMotorDriverType;
|
||||
Byte RegStatus2;
|
||||
Byte RegExtendedLineControl;
|
||||
Byte RegExtendedXStep;
|
||||
|
||||
Byte RegPllPredivider;
|
||||
Byte RegPllMaindivider;
|
||||
Byte RegPllPostdivider;
|
||||
Byte RegClockSelector;
|
||||
Byte RegTestMode;
|
||||
|
||||
/* CHECK: subject to change */
|
||||
IODef IO;
|
||||
DeviceDef Device;
|
||||
ShadingDef Shade;
|
||||
ScanDef Scan;
|
||||
BufferDef Bufs;
|
||||
|
||||
} ScanData;
|
||||
|
||||
#endif /* guard __SCANDATA_H__ */
|
||||
|
||||
/* END PLUTSEK-PP_SCANDATA.H ................................................*/
|
|
@ -0,0 +1,279 @@
|
|||
/*.............................................................................
|
||||
* Project : linux driver for Plustek parallel-port scanners
|
||||
*.............................................................................
|
||||
* File: plustek-pp_sysdep.h
|
||||
* a trial to centralize changes between the different
|
||||
* kernel-versions some stuff is maybe not relevant, but anyway...
|
||||
*.............................................................................
|
||||
*
|
||||
* Copyright (C) 2000-2003 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
*.............................................................................
|
||||
* History:
|
||||
* 0.30 - initial version
|
||||
* 0.38 - added this header
|
||||
* 0.39 - added kernel 2.4 stuff
|
||||
* 0.40 - added slab.h/malloc.h stuff for kernel >= 2.4.17
|
||||
* 0.41 - no changes
|
||||
* 0.42 - added _GET_TIME
|
||||
* - added LINUX_26 for new kernel
|
||||
*
|
||||
*.............................................................................
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef _SYSDEP_H_
|
||||
#define _SYSDEP_H_
|
||||
|
||||
#ifndef LINUX_VERSION_CODE
|
||||
# include <linux/version.h>
|
||||
#endif
|
||||
|
||||
#ifndef VERSION_CODE
|
||||
# define VERSION_CODE(vers,rel,seq) ( ((vers)<<16) | ((rel)<<8) | (seq) )
|
||||
#endif
|
||||
|
||||
/* only allow > 2.0.x */
|
||||
#if LINUX_VERSION_CODE < VERSION_CODE(2,0,0)
|
||||
# error "This kernel is too old: not supported by this file"
|
||||
#endif
|
||||
#if LINUX_VERSION_CODE < VERSION_CODE(2,1,0)
|
||||
# define LINUX_20
|
||||
#elif LINUX_VERSION_CODE < VERSION_CODE(2,4,0)
|
||||
# define LINUX_21
|
||||
#elif LINUX_VERSION_CODE < VERSION_CODE(2,6,0)
|
||||
# define LINUX_24
|
||||
#else
|
||||
# define LINUX_24
|
||||
# define LINUX_26
|
||||
#endif
|
||||
|
||||
#include <linux/types.h> /* used later in this header */
|
||||
|
||||
|
||||
/* Modularization issues */
|
||||
#if LINUX_VERSION_CODE < VERSION_CODE(2,1,18)
|
||||
# define __USE_OLD_SYMTAB__
|
||||
# define EXPORT_NO_SYMBOLS register_symtab(NULL);
|
||||
# define REGISTER_SYMTAB(tab) register_symtab(tab)
|
||||
#else
|
||||
# define REGISTER_SYMTAB(tab) /* nothing */
|
||||
#endif
|
||||
|
||||
#ifdef __USE_OLD_SYMTAB__
|
||||
# define __MODULE_STRING(s) /* nothing */
|
||||
# define MODULE_PARM(v,t) /* nothing */
|
||||
# define MODULE_PARM_DESC(v,t) /* nothing */
|
||||
# define MODULE_AUTHOR(n) /* nothing */
|
||||
# define MODULE_DESCRIPTION(d) /* nothing */
|
||||
# define MODULE_SUPPORTED_DEVICE(n) /* nothing */
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < VERSION_CODE(2,1,31)
|
||||
# define CLOSETYPE void
|
||||
# define CLOSERETURN(arg)
|
||||
#else
|
||||
# define CLOSETYPE int
|
||||
# define CLOSERETURN(arg) return arg
|
||||
#endif
|
||||
|
||||
/*
|
||||
* "select" changed in 2.1.23. The implementation is twin, but this
|
||||
* header is new
|
||||
*/
|
||||
#if LINUX_VERSION_CODE > VERSION_CODE(2,1,22)
|
||||
# include <linux/poll.h>
|
||||
#else
|
||||
# define __USE_OLD_SELECT__
|
||||
#endif
|
||||
|
||||
/* Other change in the fops are solved using pseudo-types */
|
||||
#if defined(LINUX_21) || defined(LINUX_24) || defined(LINUX_26)
|
||||
# define lseek_t long long
|
||||
# define lseek_off_t long long
|
||||
#else
|
||||
# define lseek_t int
|
||||
# define lseek_off_t off_t
|
||||
#endif
|
||||
|
||||
/* changed the prototype of read/write */
|
||||
#if defined(LINUX_21) || defined (LINUX_24) || defined(LINUX_26) || defined(__alpha__)
|
||||
# define count_t unsigned long
|
||||
# define read_write_t long
|
||||
#else
|
||||
# define count_t int
|
||||
# define read_write_t int
|
||||
#endif
|
||||
|
||||
|
||||
#if LINUX_VERSION_CODE < VERSION_CODE(2,1,31)
|
||||
# define release_t void
|
||||
# define release_return(x) return
|
||||
#else
|
||||
# define release_t int
|
||||
# define release_return(x) return (x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* access to user space: use the 2.1 functions,
|
||||
* and implement them as macros for 2.0
|
||||
*/
|
||||
|
||||
#ifdef LINUX_20
|
||||
# include <asm/segment.h>
|
||||
# define access_ok(t,a,sz) (verify_area((t),(a),(sz)) ? 0 : 1)
|
||||
# define verify_area_20 verify_area
|
||||
# define copy_to_user(t,f,n) (memcpy_tofs(t,f,n), 0)
|
||||
# define __copy_to_user(t,f,n) copy_to_user((t),(f),(n))
|
||||
# define copy_to_user_ret(t,f,n,r) copy_to_user((t),(f),(n))
|
||||
# define copy_from_user(t,f,n) (memcpy_fromfs((t),(f),(n)), 0)
|
||||
# define __copy_from_user(t,f,n) copy_from_user((t),(f),(n))
|
||||
# define copy_from_user_ret(t,f,n,r) copy_from_user((t),(f),(n))
|
||||
# define PUT_USER(val,add) (put_user((val),(add)), 0)
|
||||
# define __PUT_USER(val,add) PUT_USER((val),(add))
|
||||
# define PUT_USER_RET(val,add,ret) PUT_USER((val),(add))
|
||||
# define GET_USER(dest,add) ((dest)=get_user((add)), 0)
|
||||
# define __GET_USER(dest,add) GET_USER((dest),(add))
|
||||
# define GET_USER_RET(dest,add,ret) GET_USER((dest),(add))
|
||||
#else
|
||||
# include <asm/uaccess.h>
|
||||
# include <asm/io.h>
|
||||
# define verify_area_20(t,a,sz) (0) /* == success */
|
||||
# define PUT_USER put_user
|
||||
# define __PUT_USER __put_user
|
||||
# define PUT_USER_RET put_user_ret
|
||||
# define GET_USER get_user
|
||||
# define __GET_USER __get_user
|
||||
# define GET_USER_RET get_user_ret
|
||||
|
||||
/* starting with 2.4.0-test8, they removed the put_user_ret and get_user_ret
|
||||
* macros, so we recode'em
|
||||
*/
|
||||
#if defined(LINUX_24) || defined(LINUX_26)
|
||||
#ifndef put_user_ret
|
||||
# define put_user_ret(x,ptr,ret) ({ if (put_user(x,ptr)) return ret; })
|
||||
#endif
|
||||
|
||||
#ifndef get_user_ret
|
||||
# define get_user_ret(x,ptr,ret) ({ if (get_user(x,ptr)) return ret; })
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* ioremap */
|
||||
#ifdef LINUX_20
|
||||
# define ioremap vremap
|
||||
# define iounmap vfree
|
||||
#endif
|
||||
|
||||
/* The use_count of exec_domain and binfmt changed in 2.1.23 */
|
||||
|
||||
#ifdef LINUX_20
|
||||
# define INCRCOUNT(p) ((p)->module ? __MOD_INC_USE_COUNT((p)->module) : 0)
|
||||
# define CURRCOUNT(p) ((p)->module && (p)->module->usecount)
|
||||
# define DECRCOUNT(p) ((p)->module ? __MOD_DEC_USE_COUNT((p)->module) : 0)
|
||||
#else
|
||||
# define INCRCOUNT(p) ((p)->use_count++)
|
||||
# define CURRCOUNT(p) ((p)->use_count)
|
||||
# define DECRCOUNT(p) ((p)->use_count--)
|
||||
#endif
|
||||
|
||||
/* register_dynamic no more existent -- just have 0 as inum */
|
||||
#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,29)
|
||||
# define proc_register_dynamic proc_register
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < VERSION_CODE(2,1,37)
|
||||
# define test_and_set_bit(nr,addr) test_bit((nr),(addr))
|
||||
# define test_and_clear_bit(nr,addr) clear_bit((nr),(addr))
|
||||
# define test_and_change_bit(nr,addr) change_bit((nr),(addr))
|
||||
#endif
|
||||
|
||||
/* 2.1.30 removed these functions. Let's define them, just in case */
|
||||
#if LINUX_VERSION_CODE > VERSION_CODE(2,1,29)
|
||||
# define queue_task_irq queue_task
|
||||
# define queue_task_irq_off queue_task
|
||||
#endif
|
||||
|
||||
/* 2.1.10 and 2.1.43 introduced new functions. They are worth using */
|
||||
|
||||
#if LINUX_VERSION_CODE < VERSION_CODE(2,1,10)
|
||||
|
||||
# include <asm/byteorder.h>
|
||||
# ifdef __LITTLE_ENDIAN
|
||||
# define cpu_to_le16(x) (x)
|
||||
# define cpu_to_le32(x) (x)
|
||||
# define cpu_to_be16(x) htons((x))
|
||||
# define cpu_to_be32(x) htonl((x))
|
||||
# else
|
||||
# define cpu_to_be16(x) (x)
|
||||
# define cpu_to_be32(x) (x)
|
||||
extern inline __u16 cpu_to_le16(__u16 x) { return (x<<8) | (x>>8);}
|
||||
extern inline __u32 cpu_to_le32(__u32 x) { return((x>>24) |
|
||||
((x>>8)&0xff00) | ((x<<8)&0xff0000) | (x<<24));}
|
||||
# endif
|
||||
|
||||
# define le16_to_cpu(x) cpu_to_le16(x)
|
||||
# define le32_to_cpu(x) cpu_to_le32(x)
|
||||
# define be16_to_cpu(x) cpu_to_be16(x)
|
||||
# define be32_to_cpu(x) cpu_to_be32(x)
|
||||
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < VERSION_CODE(2,1,43)
|
||||
# define cpu_to_le16p(addr) (cpu_to_le16(*(addr)))
|
||||
# define cpu_to_le32p(addr) (cpu_to_le32(*(addr)))
|
||||
# define cpu_to_be16p(addr) (cpu_to_be16(*(addr)))
|
||||
# define cpu_to_be32p(addr) (cpu_to_be32(*(addr)))
|
||||
|
||||
extern inline void cpu_to_le16s(__u16 *a) {*a = cpu_to_le16(*a);}
|
||||
extern inline void cpu_to_le32s(__u16 *a) {*a = cpu_to_le32(*a);}
|
||||
extern inline void cpu_to_be16s(__u16 *a) {*a = cpu_to_be16(*a);}
|
||||
extern inline void cpu_to_be32s(__u16 *a) {*a = cpu_to_be32(*a);}
|
||||
|
||||
# define le16_to_cpup(x) cpu_to_le16p(x)
|
||||
# define le32_to_cpup(x) cpu_to_le32p(x)
|
||||
# define be16_to_cpup(x) cpu_to_be16p(x)
|
||||
# define be32_to_cpup(x) cpu_to_be32p(x)
|
||||
|
||||
# define le16_to_cpus(x) cpu_to_le16s(x)
|
||||
# define le32_to_cpus(x) cpu_to_le32s(x)
|
||||
# define be16_to_cpus(x) cpu_to_be16s(x)
|
||||
# define be32_to_cpus(x) cpu_to_be32s(x)
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < VERSION_CODE(2,1,15)
|
||||
# define __USE_OLD_REBUILD_HEADER__
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < VERSION_CODE(2,1,30)
|
||||
# define in_interrupt() (intr_count!=0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* from 2.4.17 on, they decided to use slab.h instead of malloc.h... so what...
|
||||
* somewhere from 2.4.18-pre9 they skipped get_fast_time...
|
||||
*/
|
||||
#if LINUX_VERSION_CODE < VERSION_CODE(2,4,17)
|
||||
# include "linux/malloc.h"
|
||||
# define _GET_TIME get_fast_time
|
||||
#else
|
||||
# include "linux/slab.h"
|
||||
# define _GET_TIME do_gettimeofday
|
||||
#endif
|
||||
|
||||
#endif /* _SYSDEP_H_ */
|
||||
|
||||
/* END PLUSTEK-PP_SYSDEP.H ..................................................*/
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,161 @@
|
|||
/*.............................................................................
|
||||
* Project : linux driver for Plustek parallel-port scanners
|
||||
*.............................................................................
|
||||
* File: plustek-pp_types.h - some typedefs and error codes
|
||||
*.............................................................................
|
||||
*
|
||||
* Copyright (C) 2000-2003 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
*.............................................................................
|
||||
* History:
|
||||
* 0.30 - initial version
|
||||
* 0.31 - no changes
|
||||
* 0.32 - added _VAR_NOT_USED()
|
||||
* 0.33 - no changes
|
||||
* 0.34 - no changes
|
||||
* 0.35 - no changes
|
||||
* 0.36 - added _E_ABORT and _E_VERSION
|
||||
* 0.37 - moved _MAX_DEVICES to plustek_scan.h
|
||||
* added pChar and TabDef
|
||||
* 0.38 - comment change for _E_NOSUPP
|
||||
* added RGBByteDef, RGBWordDef and RGBULongDef
|
||||
* replaced AllPointer by DataPointer
|
||||
* replaced AllType by DataType
|
||||
* added _LOBYTE and _HIBYTE stuff
|
||||
* added _E_NO_ASIC and _E_NORESOURCE
|
||||
* 0.39 - no changes
|
||||
* 0.40 - moved _VAR_NOT_USED and TabDef to plustek-share.h
|
||||
* 0.41 - no changes
|
||||
* 0.42 - moved errorcodes to plustek-share.h
|
||||
*
|
||||
*.............................................................................
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef __DRV_TYPES_H__
|
||||
#define __DRV_TYPES_H__
|
||||
|
||||
/* define some useful types */
|
||||
typedef int Bool;
|
||||
typedef char Char;
|
||||
typedef char *pChar;
|
||||
typedef unsigned char UChar;
|
||||
typedef UChar *pUChar;
|
||||
typedef unsigned char Byte;
|
||||
typedef Byte *pByte;
|
||||
|
||||
typedef short Short;
|
||||
typedef unsigned short UShort;
|
||||
typedef UShort *pUShort;
|
||||
|
||||
typedef unsigned int UInt;
|
||||
typedef UInt *pUInt;
|
||||
|
||||
typedef long Long;
|
||||
typedef long *pLong;
|
||||
typedef unsigned long ULong;
|
||||
typedef ULong *pULong;
|
||||
|
||||
typedef void *pVoid;
|
||||
|
||||
/*
|
||||
* the boolean values
|
||||
*/
|
||||
#ifndef _TRUE
|
||||
# define _TRUE 1
|
||||
#endif
|
||||
#ifndef _FALSE
|
||||
# define _FALSE 0
|
||||
#endif
|
||||
|
||||
#define _LOWORD(x) ((UShort)(x & 0xffff))
|
||||
#define _HIWORD(x) ((UShort)(x >> 16))
|
||||
#define _LOBYTE(x) ((Byte)((x) & 0xFF))
|
||||
#define _HIBYTE(x) ((Byte)((x) >> 8))
|
||||
|
||||
/*
|
||||
* some useful things...
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Byte b1st;
|
||||
Byte b2nd;
|
||||
} WordVal, *pWordVal;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WordVal w1st;
|
||||
WordVal w2nd;
|
||||
} DWordVal, *pDWordVal;
|
||||
|
||||
/* useful for RGB-values */
|
||||
typedef struct {
|
||||
Byte Red;
|
||||
Byte Green;
|
||||
Byte Blue;
|
||||
} RGBByteDef, *pRGBByteDef;
|
||||
|
||||
typedef struct {
|
||||
UShort Red;
|
||||
UShort Green;
|
||||
UShort Blue;
|
||||
} RGBUShortDef, *pRGBUShortDef;
|
||||
|
||||
typedef struct {
|
||||
|
||||
union {
|
||||
pUChar bp;
|
||||
pUShort usp;
|
||||
pULong ulp;
|
||||
} red;
|
||||
union {
|
||||
pUChar bp;
|
||||
pUShort usp;
|
||||
pULong ulp;
|
||||
} green;
|
||||
union {
|
||||
pUChar bp;
|
||||
pUShort usp;
|
||||
pULong ulp;
|
||||
} blue;
|
||||
|
||||
} RBGPtrDef;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ULong Red;
|
||||
ULong Green;
|
||||
ULong Blue;
|
||||
} RGBULongDef, *pRGBULongDef;
|
||||
|
||||
typedef union {
|
||||
pUChar pb;
|
||||
pUShort pw;
|
||||
pULong pdw;
|
||||
pRGBByteDef pbrgb;
|
||||
pRGBUShortDef pusrgb;
|
||||
pRGBULongDef pulrgb;
|
||||
} DataPointer, *pDataPointer;
|
||||
|
||||
typedef union {
|
||||
WordVal wOverlap;
|
||||
DWordVal dwOverlap;
|
||||
ULong dwValue;
|
||||
UShort wValue;
|
||||
Byte bValue;
|
||||
} DataType, *pDataType;
|
||||
|
||||
#endif /* guard __DRV_TYPES_H__ */
|
||||
|
||||
/* END PLUSTEK-PP_TYPES.H ...................................................*/
|
|
@ -3,8 +3,8 @@
|
|||
*.............................................................................
|
||||
*/
|
||||
|
||||
/** @file plustek-pp.c
|
||||
* @brief The interface to the parport driver.
|
||||
/** @file plustek-pp_wrapper.c
|
||||
* @brief The interface to the parport driver-code and the kernel module.
|
||||
*
|
||||
* Based on sources acquired from Plustek Inc.<br>
|
||||
* Copyright (C) 2001-2003 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
|
@ -17,6 +17,7 @@
|
|||
* - 0.43 - no changes
|
||||
* - 0.44 - added initialized setting
|
||||
* - 0.45 - no changes
|
||||
* - 0.46 - cleanup
|
||||
* .
|
||||
* <hr>
|
||||
* This file is part of the SANE package.
|
||||
|
@ -61,8 +62,28 @@
|
|||
|
||||
/******************* wrapper functions for parport device ********************/
|
||||
|
||||
/*.............................................................................
|
||||
*
|
||||
/*
|
||||
* stuff needed for user space stuff
|
||||
*/
|
||||
int PtDrvInit ( int portAddr, unsigned short model_override );
|
||||
int PtDrvShutdown ( void );
|
||||
int PtDrvOpen ( void );
|
||||
int PtDrvClose ( void );
|
||||
int PtDrvIoctl ( unsigned int cmd, void *arg );
|
||||
int PtDrvRead ( unsigned char *buffer, int count );
|
||||
|
||||
#ifdef _USER_MODE
|
||||
|
||||
|
||||
#define _IOCTL(hd,cmd,arg) PtDrvIoctl(cmd,arg)
|
||||
|
||||
#else
|
||||
|
||||
#define _IOCTL(hd,cmd,arg) ioctl(hd,cmd,arg)
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
static int ppDev_open( const char *dev_name, void *misc )
|
||||
{
|
||||
|
@ -73,14 +94,30 @@ static int ppDev_open( const char *dev_name, void *misc )
|
|||
unsigned short version = _PTDRV_IOCTL_VERSION;
|
||||
Plustek_Device *dev = (Plustek_Device *)misc;
|
||||
|
||||
_INIT(0x378,190,15);
|
||||
|
||||
if ((handle = _OPEN(dev_name)) < 0) {
|
||||
if( dev->adj.direct_io ) {
|
||||
|
||||
/* convert device name to port-address... */
|
||||
long portaddr = strtol( dev_name, 0, 0 );
|
||||
|
||||
PtDrvInit((int)portaddr, dev->adj.mov );
|
||||
}
|
||||
|
||||
if( dev->adj.direct_io )
|
||||
handle = PtDrvOpen();
|
||||
else
|
||||
handle = open( dev_name, O_RDONLY );
|
||||
|
||||
if ( handle < 0 ) {
|
||||
DBG(_DBG_ERROR, "open: can't open %s as a device\n", dev_name);
|
||||
return handle;
|
||||
}
|
||||
|
||||
result = _IOCTL( handle, _PTDRV_OPEN_DEVICE, &version );
|
||||
|
||||
if( dev->adj.direct_io )
|
||||
result = PtDrvIoctl( _PTDRV_OPEN_DEVICE, &version );
|
||||
else
|
||||
result = ioctl( handle, _PTDRV_OPEN_DEVICE, &version );
|
||||
|
||||
if( result < 0 ) {
|
||||
|
||||
if( -9019 == result ) {
|
||||
|
@ -91,9 +128,18 @@ static int ppDev_open( const char *dev_name, void *misc )
|
|||
|
||||
version = _PTDRV_COMPAT_IOCTL_VERSION;
|
||||
|
||||
result = _IOCTL( handle, _PTDRV_OPEN_DEVICE, &version );
|
||||
if( dev->adj.direct_io )
|
||||
result = PtDrvIoctl( _PTDRV_OPEN_DEVICE, &version );
|
||||
else
|
||||
result = ioctl( handle, _PTDRV_OPEN_DEVICE, &version );
|
||||
|
||||
if( result < 0 ) {
|
||||
_CLOSE( handle );
|
||||
|
||||
if( dev->adj.direct_io )
|
||||
PtDrvClose();
|
||||
else
|
||||
close( dev->fd );
|
||||
|
||||
DBG( _DBG_ERROR,
|
||||
"ioctl PT_DRV_OPEN_DEVICE failed(%d)\n", result );
|
||||
|
||||
|
@ -113,7 +159,10 @@ static int ppDev_open( const char *dev_name, void *misc )
|
|||
memcpy( &compatAdj.neg, &dev->adj.neg, sizeof(OffsDef));
|
||||
memcpy( &compatAdj.tpa, &dev->adj.tpa, sizeof(OffsDef));
|
||||
|
||||
_IOCTL( handle, _PTDRV_ADJUST, &compatAdj );
|
||||
if( dev->adj.direct_io )
|
||||
PtDrvIoctl( _PTDRV_ADJUST, &compatAdj );
|
||||
else
|
||||
ioctl( handle, _PTDRV_ADJUST, &compatAdj );
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
@ -135,71 +184,85 @@ static int ppDev_open( const char *dev_name, void *misc )
|
|||
adj.bgamma = dev->adj.bgamma;
|
||||
adj.graygamma = dev->adj.graygamma;
|
||||
|
||||
_IOCTL( handle, _PTDRV_ADJUST, &adj );
|
||||
dev->initialized = SANE_TRUE;
|
||||
if( dev->adj.direct_io )
|
||||
PtDrvIoctl( _PTDRV_ADJUST, &adj );
|
||||
else
|
||||
ioctl( handle, _PTDRV_ADJUST, &adj );
|
||||
|
||||
dev->initialized = SANE_TRUE;
|
||||
return handle;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
*
|
||||
/**
|
||||
*/
|
||||
static int ppDev_close( Plustek_Device *dev )
|
||||
{
|
||||
return _CLOSE( dev->fd );
|
||||
if( dev->adj.direct_io )
|
||||
return PtDrvClose();
|
||||
else
|
||||
return close( dev->fd );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
*
|
||||
/**
|
||||
*/
|
||||
static int ppDev_getCaps( Plustek_Device *dev )
|
||||
{
|
||||
return _IOCTL( dev->fd, _PTDRV_GET_CAPABILITIES, &dev->caps );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
*
|
||||
/**
|
||||
*/
|
||||
static int ppDev_getLensInfo( Plustek_Device *dev, pLensInfo lens )
|
||||
{
|
||||
#ifdef _USER_MODE
|
||||
_VAR_NOT_USED( dev );
|
||||
#endif
|
||||
return _IOCTL( dev->fd, _PTDRV_GET_LENSINFO, lens );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
*
|
||||
/**
|
||||
*/
|
||||
static int ppDev_getCropInfo( Plustek_Device *dev, pCropInfo crop )
|
||||
{
|
||||
#ifdef _USER_MODE
|
||||
_VAR_NOT_USED( dev );
|
||||
#endif
|
||||
return _IOCTL( dev->fd, _PTDRV_GET_CROPINFO, crop );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
*
|
||||
/**
|
||||
*/
|
||||
static int ppDev_putImgInfo( Plustek_Device *dev, pImgDef img )
|
||||
{
|
||||
#ifdef _USER_MODE
|
||||
_VAR_NOT_USED( dev );
|
||||
#endif
|
||||
return _IOCTL( dev->fd, _PTDRV_PUT_IMAGEINFO, img );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static int ppDev_setScanEnv( Plustek_Device *dev, pScanInfo sinfo )
|
||||
{
|
||||
#ifdef _USER_MODE
|
||||
_VAR_NOT_USED( dev );
|
||||
#endif
|
||||
return _IOCTL( dev->fd, _PTDRV_SET_ENV, sinfo );
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
*
|
||||
/**
|
||||
*/
|
||||
static int ppDev_startScan( Plustek_Device *dev, pStartScan start )
|
||||
{
|
||||
#ifdef _USER_MODE
|
||||
_VAR_NOT_USED( dev );
|
||||
#endif
|
||||
return _IOCTL( dev->fd, _PTDRV_START_SCAN, start );
|
||||
}
|
||||
|
||||
/**
|
||||
* function to send a gamma table to the kernel module. As the default table
|
||||
* entry is 16-bit, but the maps are 8-bit, we have to copy the values...
|
||||
/** function to send a gamma table to the kernel module. As the default table
|
||||
* entry is 16-bit, but the maps are 8-bit, we have to copy the values...
|
||||
*/
|
||||
static int ppDev_setMap( Plustek_Device *dev, SANE_Word *map,
|
||||
SANE_Word length, SANE_Word channel )
|
||||
|
@ -229,7 +292,11 @@ static int ppDev_setMap( Plustek_Device *dev, SANE_Word *map,
|
|||
|
||||
m.map = buf;
|
||||
|
||||
_IOCTL( dev->fd, _PTDRV_SETMAP, &m );
|
||||
if( dev->adj.direct_io )
|
||||
PtDrvIoctl( _PTDRV_SETMAP, &m );
|
||||
else
|
||||
ioctl( dev->fd, _PTDRV_SETMAP, &m );
|
||||
|
||||
/* we ignore the return values */
|
||||
|
||||
free( buf );
|
||||
|
@ -237,8 +304,7 @@ static int ppDev_setMap( Plustek_Device *dev, SANE_Word *map,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
*
|
||||
/**
|
||||
*/
|
||||
static int ppDev_stopScan( Plustek_Device *dev, int *mode )
|
||||
{
|
||||
|
@ -247,24 +313,32 @@ static int ppDev_stopScan( Plustek_Device *dev, int *mode )
|
|||
/* save this one... */
|
||||
tmp = *mode;
|
||||
|
||||
retval = _IOCTL( dev->fd, _PTDRV_STOP_SCAN, mode );
|
||||
|
||||
/* ... and use it here */
|
||||
if( 0 == tmp )
|
||||
_IOCTL( dev->fd, _PTDRV_CLOSE_DEVICE, 0);
|
||||
if( dev->adj.direct_io )
|
||||
retval = PtDrvIoctl( _PTDRV_STOP_SCAN, mode );
|
||||
else
|
||||
retval = ioctl( dev->fd, _PTDRV_STOP_SCAN, mode );
|
||||
|
||||
/* ... and use it here */
|
||||
if( 0 == tmp ) {
|
||||
if( dev->adj.direct_io )
|
||||
PtDrvIoctl( _PTDRV_CLOSE_DEVICE, 0 );
|
||||
else
|
||||
ioctl( dev->fd, _PTDRV_CLOSE_DEVICE, 0);
|
||||
}else
|
||||
sleep( 1 );
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
*
|
||||
/**
|
||||
*/
|
||||
static int ppDev_readImage( Plustek_Device *dev,
|
||||
SANE_Byte *buf, unsigned long data_length )
|
||||
{
|
||||
return _READ( dev->fd, buf, data_length );
|
||||
if( dev->adj.direct_io )
|
||||
return PtDrvRead( buf, data_length );
|
||||
else
|
||||
return read( dev->fd, buf, data_length );
|
||||
}
|
||||
|
||||
/* END PLUSTEK_PP.C .........................................................*/
|
||||
/* END PLUSTEK-PP_WRAPPER.C .................................................*/
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
|
||||
/** @file plustek-share.h
|
||||
* @brief Common definitions for the backend and the kernel driver
|
||||
* @brief Common definitions for the usb backend and parport backend
|
||||
*
|
||||
* Copyright (C) 2001-2003 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
*
|
||||
|
@ -27,6 +27,8 @@
|
|||
* - 0.43 - added tpa entry for AdjDef
|
||||
* - 0.44 - extended AdjDef
|
||||
* - 0.45 - added skipFine and skipFineWhite to AdjDef
|
||||
* - 0.46 - added altCalibrate and cacheCalData to AdjDef
|
||||
* - moved some stuff to the specific backend headers
|
||||
* .
|
||||
* <hr>
|
||||
* This file is part of the SANE package.
|
||||
|
@ -71,57 +73,6 @@
|
|||
#ifndef __PLUSTEK_SHARE_H__
|
||||
#define __PLUSTEK_SHARE_H__
|
||||
|
||||
/*
|
||||
* for other OS than Linux, we might have to define the _IO macros
|
||||
*/
|
||||
#ifndef _IOC
|
||||
#define _IOC(dir,type,nr,size) \
|
||||
(((dir) << 30) | \
|
||||
((type) << 8) | \
|
||||
((nr) << 0) | \
|
||||
((size) << 16))
|
||||
#endif
|
||||
|
||||
#ifndef _IO
|
||||
#define _IO(type,nr) _IOC(0U,(type),(nr),0)
|
||||
#endif
|
||||
|
||||
#ifndef _IOR
|
||||
#define _IOR(type,nr,size) _IOC(2U,(type),(nr),sizeof(size))
|
||||
#endif
|
||||
|
||||
#ifndef _IOW
|
||||
#define _IOW(type,nr,size) _IOC(1U,(type),(nr),sizeof(size))
|
||||
#endif
|
||||
|
||||
#ifndef _IOWR
|
||||
#define _IOWR(type,nr,size) _IOC(3U,(type),(nr),sizeof(size))
|
||||
#endif
|
||||
|
||||
/*.............................................................................
|
||||
* the ioctl interface
|
||||
*/
|
||||
#define _PTDRV_OPEN_DEVICE _IOW('x', 1, unsigned short)/* open */
|
||||
#define _PTDRV_GET_CAPABILITIES _IOR('x', 2, ScannerCaps) /* get caps */
|
||||
#define _PTDRV_GET_LENSINFO _IOR('x', 3, LensInfo) /* get lenscaps */
|
||||
#define _PTDRV_PUT_IMAGEINFO _IOW('x', 4, ImgDef) /* put image info*/
|
||||
#define _PTDRV_GET_CROPINFO _IOR('x', 5, CropInfo) /* get crop */
|
||||
#define _PTDRV_SET_ENV _IOWR('x',6, ScanInfo) /* set env. */
|
||||
#define _PTDRV_START_SCAN _IOR('x', 7, StartScan) /* start scan */
|
||||
#define _PTDRV_STOP_SCAN _IOWR('x', 8, int) /* stop scan */
|
||||
#define _PTDRV_CLOSE_DEVICE _IO('x', 9) /* close */
|
||||
#define _PTDRV_ACTION_BUTTON _IOR('x', 10, int) /* rd act. button*/
|
||||
#define _PTDRV_ADJUST _IOR('x', 11, AdjDef) /* adjust driver */
|
||||
#define _PTDRV_SETMAP _IOR('x', 12, MapDef) /* download gamma*/
|
||||
|
||||
/*
|
||||
* this version MUST match the one inside the driver to make sure, that
|
||||
* both sides use the same structures. This version changes each time
|
||||
* the ioctl interface changes
|
||||
*/
|
||||
#define _PTDRV_COMPAT_IOCTL_VERSION 0x0102
|
||||
#define _PTDRV_IOCTL_VERSION 0x0103
|
||||
|
||||
/*.............................................................................
|
||||
* the structures for driver communication
|
||||
*/
|
||||
|
@ -217,132 +168,21 @@ typedef struct {
|
|||
int y;
|
||||
} OffsDef, *pOffsDef;
|
||||
|
||||
/*
|
||||
* for compatiblity to version 0x0102 drivers
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
int lampOff;
|
||||
int lampOffOnEnd;
|
||||
int warmup;
|
||||
|
||||
OffsDef pos; /* for adjusting normal scan area */
|
||||
OffsDef tpa; /* for adjusting transparency scan area */
|
||||
OffsDef neg; /* for adjusting negative scan area */
|
||||
|
||||
} CompatAdjDef, *pCompatAdjDef;
|
||||
|
||||
/*
|
||||
* for adjusting the parport-drivers
|
||||
*/
|
||||
typedef struct {
|
||||
int lampOff;
|
||||
int lampOffOnEnd;
|
||||
int warmup;
|
||||
int enableTpa;
|
||||
|
||||
OffsDef pos; /* for adjusting normal scan area */
|
||||
OffsDef tpa; /* for adjusting transparency scan area */
|
||||
OffsDef neg; /* for adjusting negative scan area */
|
||||
|
||||
/* for adjusting the default gamma settings */
|
||||
double rgamma;
|
||||
double ggamma;
|
||||
double bgamma;
|
||||
|
||||
double graygamma;
|
||||
|
||||
} PPAdjDef, *pPPAdjDef;
|
||||
|
||||
/*
|
||||
* for adjusting the usb stuff
|
||||
*/
|
||||
typedef struct {
|
||||
int lampOff;
|
||||
int lampOffOnEnd;
|
||||
int warmup;
|
||||
int enableTpa;
|
||||
int skipCalibration;
|
||||
int skipFine;
|
||||
int skipFineWhite;
|
||||
int invertNegatives;
|
||||
|
||||
int rgain;
|
||||
int ggain;
|
||||
int bgain;
|
||||
|
||||
OffsDef pos; /* for adjusting normal scan area */
|
||||
OffsDef tpa; /* for adjusting transparency scan area */
|
||||
OffsDef neg; /* for adjusting negative scan area */
|
||||
|
||||
int posShadingY;
|
||||
int tpaShadingY;
|
||||
int negShadingY;
|
||||
|
||||
/* for adjusting the default gamma settings */
|
||||
double rgamma;
|
||||
double ggamma;
|
||||
double bgamma;
|
||||
|
||||
double graygamma;
|
||||
|
||||
} AdjDef, *pAdjDef;
|
||||
|
||||
/*
|
||||
* useful for description tables
|
||||
/** useful for description tables
|
||||
*/
|
||||
typedef struct {
|
||||
int id;
|
||||
char *desc;
|
||||
} TabDef, *pTabDef;
|
||||
|
||||
/* NOTE: needs to be kept in sync with table below */
|
||||
#define MODELSTR static char *ModelStr[] = { \
|
||||
"unknown", \
|
||||
"Primax 4800", \
|
||||
"Primax 4800 Direct", \
|
||||
"Primax 4800 Direct 30Bit", \
|
||||
"Primax 9600 Direct 30Bit", \
|
||||
"4800P", \
|
||||
"4830P", \
|
||||
"600P/6000P", \
|
||||
"4831P", \
|
||||
"9630P", \
|
||||
"9630PL", \
|
||||
"9636P", \
|
||||
"A3I", \
|
||||
"12000P/96000P", \
|
||||
"9636P+/Turbo", \
|
||||
"9636T/12000T", \
|
||||
"P8", \
|
||||
"P12", \
|
||||
"PT12", \
|
||||
"Genius Colorpage Vivid III V2", \
|
||||
"USB-Device" \
|
||||
}
|
||||
|
||||
/* the models */
|
||||
#define MODEL_OP_UNKNOWN 0 /* unknown */
|
||||
#define MODEL_PMX_4800 1 /* Primax Colorado 4800 like OP 4800 */
|
||||
#define MODEL_PMX_4800D 2 /* Primax Compact 4800 Direct, OP 600 R->G, G->R */
|
||||
#define MODEL_PMX_4800D3 3 /* Primax Compact 4800 Direct 30 */
|
||||
#define MODEL_PMX_9600D3 4 /* Primax Compact 9600 Direct 30 */
|
||||
#define MODEL_OP_4800P 5 /* 32k, 96001 ASIC, 24 bit, 300x600, 8.5x11.69 */
|
||||
#define MODEL_OP_4830P 6 /* 32k, 96003 ASIC, 30 bit, 300x600, 8.5x11.69 */
|
||||
#define MODEL_OP_600P 7 /* 32k, 96003 ASIC, 30 bit, 300x600, 8.5x11.69 */
|
||||
#define MODEL_OP_4831P 8 /* 128k, 96003 ASIC, 30 bit, 300x600, 8.5x11.69 */
|
||||
#define MODEL_OP_9630P 9 /* 128k, 96003 ASIC, 30 bit, 600x1200, 8.5x11.69 */
|
||||
#define MODEL_OP_9630PL 10 /* 128k, 96003 ASIC, 30 bit, 600x1200, 8.5x14 */
|
||||
#define MODEL_OP_9636P 11 /* 512k, 98001 ASIC, 36 bit, 600x1200, 8.5x11.69 */
|
||||
#define MODEL_OP_A3I 12 /* 128k, 96003 ASIC, 30 bit, 400x800, 11.69x17 */
|
||||
#define MODEL_OP_12000P 13 /* 128k, 96003 ASIC, 30 bit, 600x1200, 8.5x11.69 */
|
||||
#define MODEL_OP_9636PP 14 /* 512k, 98001 ASIC, 36 bit, 600x1200, 8.5x11.69 */
|
||||
#define MODEL_OP_9636T 15 /* like OP_9636PP + transparency */
|
||||
#define MODEL_OP_P8 16 /* 512k, 98003 ASIC, 36 bit, 300x600, 8.5x11.69 */
|
||||
#define MODEL_OP_P12 17 /* 512k, 98003 ASIC, 36 bit, 600x1200, 8.5x11.69 */
|
||||
#define MODEL_OP_PT12 18 /* like OP_P12 + transparency */
|
||||
#define MODEL_GEN_CPV2 19 /* Genius Colorpage Vivid III V2, ASIC 98003 */
|
||||
#define MODEL_OP_USB 20 /* some USB scanner device */
|
||||
/** for defining the scanmodes
|
||||
*/
|
||||
typedef const struct mode_param
|
||||
{
|
||||
int color;
|
||||
int depth;
|
||||
int scanmode;
|
||||
} ModeParam, *pModeParam;
|
||||
|
||||
/******************************************************************************
|
||||
* Section 1
|
||||
|
@ -366,16 +206,10 @@ typedef struct {
|
|||
|
||||
#define SFLAG_CUSTOM_GAMMA 0x00000200 /* driver supports custom gamma */
|
||||
|
||||
/*
|
||||
* (1.2.1) Provide the scanner ID. This field is valid when the wIOBase
|
||||
* field of ScannerCaps is not _NO_BASE
|
||||
*/
|
||||
#define SFLAG_CCDTypeMask 0x000f0000 /* CCD type, system reserved*/
|
||||
#define SFLAG_IDMask 0x00f00000 /* Scanner ID */
|
||||
|
||||
/* (1.3): SCANNERINFO.wIOBase */
|
||||
#define _NO_BASE 0xFFFF
|
||||
|
||||
#if 0
|
||||
/******************************************************************************
|
||||
* Section 2
|
||||
* (2.1): MAPINFO.wRGB
|
||||
|
@ -383,6 +217,8 @@ typedef struct {
|
|||
#define RGB_Master 1
|
||||
#define RGB_RGB 3
|
||||
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Section 3
|
||||
* (3.1): SCANINFO.dwFlag
|
||||
|
@ -416,7 +252,7 @@ typedef struct {
|
|||
#define _SCANNER_SCANNING 0x8000000
|
||||
#define _SCANNER_PAPEROUT 0x4000000
|
||||
|
||||
|
||||
#if 0
|
||||
/* (3.2): SCANINFO.wMapType */
|
||||
#define CHANNEL_Master 0 /* used only MAPINFO.wRGB == RGB_Master */
|
||||
/* or scan gray */
|
||||
|
@ -424,6 +260,7 @@ typedef struct {
|
|||
#define CHANNEL_RGB 1
|
||||
#define CHANNEL_Default 2
|
||||
|
||||
|
||||
/* these are used only to pointer out which color are used as gray map
|
||||
* It also pointers out which channel will be used to scan gray data
|
||||
* (CHANNEL_Default = Device default)
|
||||
|
@ -439,6 +276,9 @@ typedef struct {
|
|||
#define DITHER_VerticalLine 3
|
||||
#define DITHER_UserDefine 4
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* (3.4): SCANINFO.wBits */
|
||||
#define OUTPUT_8Bits 0
|
||||
#define OUTPUT_10Bits 1
|
||||
|
@ -497,7 +337,6 @@ typedef struct {
|
|||
#define _ASIC_IS_96003 0x10 /* value for 96003 */
|
||||
#define _ASIC_IS_98001 0x81 /* value for 98001 */
|
||||
#define _ASIC_IS_98003 0x83 /* value for 98003 */
|
||||
#define _ASIC_IS_USB 0x42 /* for the USB stuff*/
|
||||
|
||||
/*
|
||||
* transparency/negative mode set ranges
|
||||
|
@ -515,8 +354,8 @@ typedef struct {
|
|||
#define _Transparency96OriginOffsetX 0x03DB /* org. was 0x0430 */
|
||||
#define _Negative96OriginOffsetX 0x03F3 /* org. was 0x0428 */
|
||||
|
||||
#define _NegativePageWidth 460U /* 38.9 mm */
|
||||
#define _NegativePageHeight 350U /* 29.6 mm */
|
||||
#define _NegativePageWidth 460UL /* 38.9 mm */
|
||||
#define _NegativePageHeight 350UL /* 29.6 mm */
|
||||
|
||||
#define _DEF_DPI 50
|
||||
|
||||
|
@ -567,37 +406,6 @@ typedef struct {
|
|||
#define _E_BUFFER_TOO_SMALL (_FIRST_ERR-43)
|
||||
#define _E_DATAREAD (_FIRST_ERR-44)
|
||||
|
||||
/*
|
||||
* stuff needed for user space stuff
|
||||
*/
|
||||
#ifdef _USER_MODE
|
||||
|
||||
int PtDrvInit ( int portAddr, int lamp_off, int warm_up );
|
||||
int PtDrvShutdown ( void );
|
||||
int PtDrvOpen ( void );
|
||||
int PtDrvClose ( void );
|
||||
int PtDrvIoctl ( unsigned int cmd, void *arg );
|
||||
int PtDrvRead ( unsigned char *buffer, int count );
|
||||
|
||||
#define _INIT(portAddr,lamp_off,warmup) PtDrvInit(portAddr,lamp_off,warmup)
|
||||
#define _DOWN() PtDrvShutdown()
|
||||
|
||||
#define _OPEN(dev) PtDrvOpen()
|
||||
#define _CLOSE(hd) PtDrvClose()
|
||||
#define _IOCTL(hd,cmd,arg) PtDrvIoctl(cmd,arg)
|
||||
#define _READ(hd,buf,len) PtDrvRead(buf,len)
|
||||
|
||||
#else
|
||||
|
||||
#define _INIT(portAddr,lamp_off,warmup)
|
||||
#define _DOWN()
|
||||
|
||||
#define _OPEN(dev) open(dev,O_RDONLY)
|
||||
#define _CLOSE(hd) close(hd)
|
||||
#define _IOCTL(hd,cmd,arg) ioctl(hd,cmd,arg)
|
||||
#define _READ(hd,buf,len) read(hd,buf,len)
|
||||
#endif
|
||||
|
||||
#endif /* guard __PLUSTEK_SHARE_H__ */
|
||||
|
||||
/* END PLUSTEK-SHARE.H.......................................................*/
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
* - removed the scaler stuff for CIS devices
|
||||
* - removed homeing stuff from readline function
|
||||
* - fixed flag setting in usbDev_startScan()
|
||||
* - 0.46 - added additional branch to support alternate calibration
|
||||
* .
|
||||
* <hr>
|
||||
* This file is part of the SANE package.
|
||||
|
@ -74,8 +75,11 @@
|
|||
* <hr>
|
||||
*/
|
||||
|
||||
/**
|
||||
* to allow different vendors...
|
||||
#ifndef PATH_MAX
|
||||
# define PATH_MAX 1024
|
||||
#endif
|
||||
|
||||
/** to allow different vendors...
|
||||
*/
|
||||
static TabDef usbVendors[] = {
|
||||
|
||||
|
@ -99,19 +103,51 @@ static SANE_Char USB_devname[1024];
|
|||
|
||||
/********************** the USB scanner interface ****************************/
|
||||
|
||||
/** remove the slash out of the model-name to obtain a valid filename
|
||||
*/
|
||||
static SANE_Bool usb_normFileName( char *fname, char* buffer, u_long max_len )
|
||||
{
|
||||
char *src, *dst;
|
||||
|
||||
if( NULL == fname )
|
||||
return SANE_FALSE;
|
||||
|
||||
if( strlen( fname ) >= max_len )
|
||||
return SANE_FALSE;
|
||||
|
||||
src = fname;
|
||||
dst = buffer;
|
||||
while( *src != '\0' ) {
|
||||
|
||||
if((*src == '/') || isspace(*src))
|
||||
*dst = '_';
|
||||
else
|
||||
*dst = *src;
|
||||
|
||||
*dst++;
|
||||
*src++;
|
||||
}
|
||||
*dst = '\0';
|
||||
|
||||
return SANE_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* assign the values to the structures used by the currently found scanner
|
||||
*/
|
||||
static void usb_initDev( pPlustek_Device dev, int idx, int handle, int vendor )
|
||||
{
|
||||
char *ptr;
|
||||
char tmp_str1[PATH_MAX];
|
||||
char tmp_str2[PATH_MAX];
|
||||
int i;
|
||||
ScanParam sParam;
|
||||
u_short tmp = 0;
|
||||
|
||||
DBG( _DBG_INFO, "usb_initDev(%d,0x%04x,%u)\n",
|
||||
DBG( _DBG_INFO, "usb_initDev(%d,0x%04x,%i)\n",
|
||||
idx, vendor, dev->initialized );
|
||||
/* save capability flags... */
|
||||
if( dev->initialized ) {
|
||||
if( dev->initialized >= 0 ) {
|
||||
tmp = DEVCAPSFLAG_TPA;
|
||||
}
|
||||
|
||||
|
@ -120,7 +156,7 @@ static void usb_initDev( pPlustek_Device dev, int idx, int handle, int vendor )
|
|||
memcpy( &dev->usbDev.HwSetting, Settings[idx].pHwDef, sizeof(HWDef));
|
||||
|
||||
/* restore capability flags... */
|
||||
if( dev->initialized ) {
|
||||
if( dev->initialized >= 0 ) {
|
||||
dev->usbDev.Caps.wFlags |= tmp;
|
||||
}
|
||||
|
||||
|
@ -182,7 +218,7 @@ static void usb_initDev( pPlustek_Device dev, int idx, int handle, int vendor )
|
|||
|
||||
/* check for TPA on EPSON device
|
||||
*/
|
||||
if( !dev->initialized && vendor == 0x04B8 ) {
|
||||
if((dev->initialized < 0) && vendor == 0x04B8 ) {
|
||||
|
||||
u_char t;
|
||||
|
||||
|
@ -221,9 +257,11 @@ static void usb_initDev( pPlustek_Device dev, int idx, int handle, int vendor )
|
|||
}
|
||||
|
||||
dev->usbDev.currentLamp = usb_GetLampStatus( dev );
|
||||
|
||||
usb_ResetRegisters( dev );
|
||||
|
||||
if( dev->initialized >= 0 )
|
||||
return;
|
||||
|
||||
usbio_ResetLM983x ( dev );
|
||||
usb_IsScannerReady( dev );
|
||||
|
||||
|
@ -240,6 +278,23 @@ static void usb_initDev( pPlustek_Device dev, int idx, int handle, int vendor )
|
|||
sParam.dMCLK = 4;
|
||||
sParam.Size.dwPixels = 0;
|
||||
|
||||
/* create calibration-filename */
|
||||
ptr = getenv ("HOME");
|
||||
if( !usb_normFileName( dev->usbDev.ModelStr, tmp_str1, PATH_MAX )) {
|
||||
strcpy( tmp_str1, "plustek-default" );
|
||||
}
|
||||
|
||||
if( NULL == ptr ) {
|
||||
sprintf( tmp_str2, "/tmp/%s-%s.cal",
|
||||
dev->sane.vendor, tmp_str1 );
|
||||
} else {
|
||||
sprintf( tmp_str2, "%s/.sane/%s-%s.cal",
|
||||
ptr, dev->sane.vendor, tmp_str1 );
|
||||
}
|
||||
dev->calFile = strdup( tmp_str2 );
|
||||
DBG( _DBG_INFO, "Calibration file-name set to:\n" );
|
||||
DBG( _DBG_INFO, ">%s<\n", dev->calFile );
|
||||
|
||||
/* initialize the ASIC registers */
|
||||
usb_SetScanParameters( dev, &sParam );
|
||||
|
||||
|
@ -247,7 +302,7 @@ static void usb_initDev( pPlustek_Device dev, int idx, int handle, int vendor )
|
|||
usb_ModuleToHome( dev, SANE_FALSE );
|
||||
|
||||
/* set the global flag, that we are initialized so far */
|
||||
dev->initialized = SANE_TRUE;
|
||||
dev->initialized = idx;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -354,7 +409,7 @@ static void usbDev_shutdown( Plustek_Device *dev )
|
|||
dev->fd = -1;
|
||||
sanei_usb_close( handle );
|
||||
}
|
||||
|
||||
|
||||
usb_StopLampTimer( dev );
|
||||
}
|
||||
|
||||
|
@ -631,14 +686,9 @@ static int usbDev_getCaps( Plustek_Device *dev )
|
|||
dev->caps.dwFlag |= SFLAG_TPA;
|
||||
}
|
||||
|
||||
dev->caps.wIOBase = 0;
|
||||
dev->caps.wLens = 1;
|
||||
|
||||
dev->caps.wMaxExtentX = scaps->Normal.Size.x;
|
||||
dev->caps.wMaxExtentY = scaps->Normal.Size.y;
|
||||
dev->caps.AsicID = _ASIC_IS_USB;
|
||||
dev->caps.Model = MODEL_OP_USB;
|
||||
dev->caps.Version = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -941,7 +991,7 @@ static int usbDev_startScan( Plustek_Device *dev, pStartScan start )
|
|||
return 0;
|
||||
}
|
||||
|
||||
return _E_ALLOC;
|
||||
return _E_ALLOC;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -963,12 +1013,27 @@ static int usbDev_Prepare( struct Plustek_Device *dev, SANE_Byte *buf )
|
|||
*/
|
||||
usb_ModuleStatus( dev );
|
||||
|
||||
result = usb_DoCalibration( dev );
|
||||
/* the CanoScan CIS devices need special handling... */
|
||||
if((dev->usbDev.vendor == 0x04A9) &&
|
||||
(dev->usbDev.product==0x2206 || dev->usbDev.product==0x2207 ||
|
||||
dev->usbDev.product==0x220D || dev->usbDev.product==0x220E)) {
|
||||
result = cano_DoCalibration( dev );
|
||||
|
||||
} else {
|
||||
|
||||
if( dev->adj.altCalibrate )
|
||||
result = cano_DoCalibration( dev );
|
||||
else
|
||||
result = usb_DoCalibration( dev );
|
||||
}
|
||||
|
||||
if( SANE_TRUE != result ) {
|
||||
DBG( _DBG_INFO, "calibration failed!!!\n" );
|
||||
return result;
|
||||
}
|
||||
|
||||
if( dev->adj.cacheCalData )
|
||||
usb_SaveCalData( dev );
|
||||
DBG( _DBG_INFO, "calibration done.\n" );
|
||||
|
||||
if( !( scanning->dwFlag & SCANFLAG_Scanning )) {
|
||||
|
@ -1309,7 +1374,6 @@ static int usbDev_readLine( struct Plustek_Device *dev )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
* - added _WAF_SKIP_WHITEFINE for skipping fine white calibration
|
||||
* - added MCLK setting for 16 bit modes
|
||||
* - added _WAF_FIX_GAIN and _WAF_FIX_OFS
|
||||
* - 0.46 - added UMAX1200 for 5400 model
|
||||
* - removed _WAF_FIX_GAIN and _WAF_FIX_OFS
|
||||
* - added skipCoarseCalib to ScanDef
|
||||
* .
|
||||
* <hr>
|
||||
* This file is part of the SANE package.
|
||||
|
@ -77,7 +80,8 @@
|
|||
#define kNECSLIM 5
|
||||
#define kCIS650 6
|
||||
#define kCIS670 7
|
||||
#define kCIS1240 8
|
||||
#define kCIS1220 8
|
||||
#define kCIS1240 9
|
||||
|
||||
/*********************************** plustek_types.h!!! ************************/
|
||||
|
||||
|
@ -213,9 +217,7 @@ enum _WORKAROUNDS
|
|||
_WAF_BYPASS_CALIBRATION = 0x00000008, /* no calibration,use linear gamma */
|
||||
_WAF_INV_NEGATIVE_MAP = 0x00000010, /* the backend does the neg. stuff */
|
||||
_WAF_SKIP_FINE = 0x00000020, /* skip the fine calbration */
|
||||
_WAF_SKIP_WHITEFINE = 0x00000040, /* skip the fine white calbration */
|
||||
_WAF_FIX_GAIN = 0x00000080, /* use fixed gain for coarse cal. */
|
||||
_WAF_FIX_OFS = 0x00000100 /* use fixed offset for coarse cal.*/
|
||||
_WAF_SKIP_WHITEFINE = 0x00000040 /* skip the fine white calbration */
|
||||
};
|
||||
|
||||
/** for lamps connected to the misc I/O pins*/
|
||||
|
@ -537,6 +539,7 @@ struct Plustek_Device;
|
|||
typedef struct ScanDef
|
||||
{
|
||||
SANE_Bool fCalibrated; /**< calibrated or not */
|
||||
SANE_Bool skipCoarseCalib;/**< skip coarse calibration or not */
|
||||
u_long dwFlag; /**< scan attributes */
|
||||
|
||||
ScanParam sParam; /**< all we need to scan */
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,416 @@
|
|||
/*.............................................................................
|
||||
* Project : SANE library for Plustek flatbed scanners.
|
||||
*.............................................................................
|
||||
*/
|
||||
|
||||
/** @file plustek-usbcalfile.c
|
||||
* @brief Functions for saving/restoring calibration settings
|
||||
*
|
||||
* Based on sources acquired from Plustek Inc.<br>
|
||||
* Copyright (C) 2001-2003 Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
*
|
||||
* History:
|
||||
* - 0.46 - first version
|
||||
* .
|
||||
* <hr>
|
||||
* 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.
|
||||
* <hr>
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
u_long red_light_on;
|
||||
u_long red_light_off;
|
||||
u_long green_light_on;
|
||||
u_long green_light_off;
|
||||
u_long blue_light_on;
|
||||
u_long blue_light_off;
|
||||
u_long green_pwm_duty;
|
||||
|
||||
} LightCtrl, *pLightCtrl;
|
||||
|
||||
typedef struct {
|
||||
u_short version;
|
||||
|
||||
u_short red_gain;
|
||||
u_short green_gain;
|
||||
u_short blue_gain;
|
||||
|
||||
u_short red_offs;
|
||||
u_short green_offs;
|
||||
u_short blue_offs;
|
||||
|
||||
LightCtrl light;
|
||||
|
||||
} CalData, *pCalData;
|
||||
|
||||
#define _PT_CF_VERSION 0x0001
|
||||
|
||||
/** function to read a text file and returns the string which starts which
|
||||
* 'id' string.
|
||||
* no duplicate entries where detected, always the first occurance will be
|
||||
* red.
|
||||
* @param fp - file pointer of file to read
|
||||
* @param id - what to search for
|
||||
* @param res - where to store the result upon success
|
||||
* @return SANE_TRUE on success, SANE_FALSE on any error
|
||||
*/
|
||||
static SANE_Bool usb_ReadSpecLine( FILE *fp, char *id, char* res )
|
||||
{
|
||||
char tmp[1024];
|
||||
char *ptr;
|
||||
|
||||
/* rewind file pointer */
|
||||
if( 0 != fseek( fp, 0L, SEEK_SET)) {
|
||||
DBG( _DBG_ERROR, "fseek: %s\n", strerror(errno));
|
||||
return SANE_FALSE;
|
||||
}
|
||||
|
||||
/* roam through the file and examine each line... */
|
||||
while( !feof( fp )) {
|
||||
|
||||
if( NULL != fgets( tmp, 1024, fp )) {
|
||||
|
||||
if( 0 == strncmp( tmp, id, strlen(id))) {
|
||||
|
||||
ptr = &tmp[strlen(id)];
|
||||
if( '\0' == *ptr )
|
||||
break;
|
||||
|
||||
strcpy( res, ptr );
|
||||
res[strlen(res)-1] = '\0';
|
||||
return SANE_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SANE_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
static char *usb_ReadOtherLines( FILE *fp, char *except )
|
||||
{
|
||||
char tmp[1024];
|
||||
char *ptr, *ptr_base;
|
||||
int len;
|
||||
|
||||
if( 0 != fseek( fp, 0L, SEEK_END))
|
||||
return NULL;
|
||||
|
||||
len = ftell(fp);
|
||||
|
||||
/* rewind file pointer */
|
||||
if( 0 != fseek( fp, 0L, SEEK_SET))
|
||||
return NULL;
|
||||
|
||||
if( len == 0 )
|
||||
return NULL;
|
||||
|
||||
ptr = (char*)malloc(len);
|
||||
if( NULL == ptr )
|
||||
return NULL;
|
||||
|
||||
ptr_base = ptr;
|
||||
*ptr = '\0';
|
||||
/* roam through the file and examine each line... */
|
||||
while( !feof( fp )) {
|
||||
|
||||
if( NULL != fgets( tmp, 1024, fp )) {
|
||||
|
||||
if( 0 == strncmp( tmp, "version=", 8 ))
|
||||
continue;
|
||||
|
||||
if( 0 != strncmp( tmp, except, strlen(except))) {
|
||||
|
||||
if( strlen( tmp ) > 0 ) {
|
||||
strcpy( ptr, tmp );
|
||||
ptr += strlen(tmp);
|
||||
*ptr = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ptr_base;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
static void usb_RestoreCalData( pCalData cal )
|
||||
{
|
||||
a_bRegs[0x3b] = (u_char)cal->red_gain;
|
||||
a_bRegs[0x3c] = (u_char)cal->green_gain;
|
||||
a_bRegs[0x3d] = (u_char)cal->blue_gain;
|
||||
a_bRegs[0x38] = (u_char)cal->red_offs;
|
||||
a_bRegs[0x39] = (u_char)cal->green_offs;
|
||||
a_bRegs[0x3a] = (u_char)cal->blue_offs;
|
||||
|
||||
a_bRegs[0x2a] = _HIBYTE((u_short)cal->light.green_pwm_duty);
|
||||
a_bRegs[0x2b] = _LOBYTE((u_short)cal->light.green_pwm_duty);
|
||||
|
||||
a_bRegs[0x2c] = _HIBYTE((u_short)cal->light.red_light_on);
|
||||
a_bRegs[0x2d] = _LOBYTE((u_short)cal->light.red_light_on);
|
||||
a_bRegs[0x2e] = _HIBYTE((u_short)cal->light.red_light_off);
|
||||
a_bRegs[0x2f] = _LOBYTE((u_short)cal->light.red_light_off);
|
||||
|
||||
a_bRegs[0x30] = _HIBYTE((u_short)cal->light.green_light_on);
|
||||
a_bRegs[0x31] = _LOBYTE((u_short)cal->light.green_light_on);
|
||||
a_bRegs[0x32] = _HIBYTE((u_short)cal->light.green_light_off);
|
||||
a_bRegs[0x33] = _LOBYTE((u_short)cal->light.green_light_off);
|
||||
|
||||
a_bRegs[0x34] = _HIBYTE((u_short)cal->light.blue_light_on);
|
||||
a_bRegs[0x35] = _LOBYTE((u_short)cal->light.blue_light_on);
|
||||
a_bRegs[0x36] = _HIBYTE((u_short)cal->light.blue_light_off);
|
||||
a_bRegs[0x37] = _LOBYTE((u_short)cal->light.blue_light_off);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
static void usb_CreatePrefix( pPlustek_Device dev, char *pfx )
|
||||
{
|
||||
char bd[5];
|
||||
pScanDef scanning = &dev->scanning;
|
||||
pScanParam param = &scanning->sParam;
|
||||
|
||||
switch( scanning->sParam.bSource ) {
|
||||
|
||||
case SOURCE_Transparency: strcpy( pfx, "tpa-" ); break;
|
||||
case SOURCE_Negative: strcpy( pfx, "neg-" ); break;
|
||||
case SOURCE_ADF: strcpy( pfx, "adf-" ); break;
|
||||
default: pfx[0] = '\0'; break;
|
||||
}
|
||||
|
||||
sprintf( bd, "%u=", param->bBitDepth );
|
||||
if( param->bDataType == SCANDATATYPE_Color )
|
||||
strcat( pfx, "color" );
|
||||
else
|
||||
strcat( pfx, "gray" );
|
||||
|
||||
strcat( pfx, bd );
|
||||
}
|
||||
|
||||
/** function to read and set the calibration data from external file
|
||||
*/
|
||||
static SANE_Bool usb_ReadAndSetCalData( pPlustek_Device dev )
|
||||
{
|
||||
char pfx[20];
|
||||
char tmp[1024];
|
||||
u_short version;
|
||||
int res;
|
||||
FILE *fp;
|
||||
CalData cal;
|
||||
SANE_Bool ret;
|
||||
|
||||
DBG( _DBG_INFO, "usb_ReadAndSetCalData()\n" );
|
||||
|
||||
if( NULL == dev->calFile ) {
|
||||
DBG( _DBG_ERROR, "- No calibration filename set!\n" );
|
||||
return SANE_FALSE;
|
||||
}
|
||||
|
||||
DBG( _DBG_INFO, "- Reading calibration data from file\n");
|
||||
DBG( _DBG_INFO, " %s\n", dev->calFile );
|
||||
|
||||
fp = fopen( dev->calFile, "r" );
|
||||
if( NULL == fp ) {
|
||||
DBG( _DBG_ERROR, "File %s not found\n", dev->calFile );
|
||||
return SANE_FALSE;
|
||||
}
|
||||
|
||||
/* check version */
|
||||
if( !usb_ReadSpecLine( fp, "version=", tmp )) {
|
||||
DBG( _DBG_ERROR, "Could not find version info!\n" );
|
||||
fclose( fp );
|
||||
return SANE_FALSE;
|
||||
}
|
||||
|
||||
DBG( _DBG_INFO, "- Calibration file version: %s\n", tmp );
|
||||
if( 1 != sscanf( tmp, "0x%04hx", &version )) {
|
||||
DBG( _DBG_ERROR, "Could not decode version info!\n" );
|
||||
fclose( fp );
|
||||
return SANE_FALSE;
|
||||
}
|
||||
|
||||
if( version != _PT_CF_VERSION ) {
|
||||
DBG( _DBG_ERROR, "Versions do not match!\n" );
|
||||
fclose( fp );
|
||||
return SANE_FALSE;
|
||||
}
|
||||
|
||||
usb_CreatePrefix( dev, pfx );
|
||||
|
||||
ret = SANE_FALSE;
|
||||
if( usb_ReadSpecLine( fp, pfx, tmp )) {
|
||||
DBG( _DBG_INFO, "- Calibration data: %s\n", tmp );
|
||||
|
||||
res = sscanf( tmp, "%hu,%hu,%hu,%hu,%hu,%hu,"
|
||||
"%lu,%lu,%lu,%lu,%lu,%lu,%lu\n",
|
||||
&cal.red_gain, &cal.red_offs,
|
||||
&cal.green_gain, &cal.green_offs,
|
||||
&cal.blue_gain, &cal.blue_offs,
|
||||
&cal.light.red_light_on, &cal.light.red_light_off,
|
||||
&cal.light.green_light_on, &cal.light.green_light_off,
|
||||
&cal.light.blue_light_on, &cal.light.blue_light_off,
|
||||
&cal.light.green_pwm_duty );
|
||||
|
||||
if( 13 == res ) {
|
||||
usb_RestoreCalData( &cal );
|
||||
ret = SANE_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
fclose( fp );
|
||||
DBG( _DBG_INFO, "usb_ReadAndSetCalData() done -> %u\n", ret );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
static void usb_PrepCalData( pCalData cal )
|
||||
{
|
||||
memset( cal, 0, sizeof(CalData));
|
||||
cal->version = _PT_CF_VERSION;
|
||||
|
||||
cal->red_gain = (u_short)a_bRegs[0x3b];
|
||||
cal->green_gain = (u_short)a_bRegs[0x3c];
|
||||
cal->blue_gain = (u_short)a_bRegs[0x3d];
|
||||
cal->red_offs = (u_short)a_bRegs[0x38];
|
||||
cal->green_offs = (u_short)a_bRegs[0x39];
|
||||
cal->blue_offs = (u_short)a_bRegs[0x3a];
|
||||
|
||||
cal->light.green_pwm_duty = a_bRegs[0x2a] * 256 + a_bRegs[0x2b];
|
||||
|
||||
cal->light.red_light_on = a_bRegs[0x2c] * 256 + a_bRegs[0x2d];
|
||||
cal->light.red_light_off = a_bRegs[0x2e] * 256 + a_bRegs[0x2f];
|
||||
cal->light.green_light_on = a_bRegs[0x30] * 256 + a_bRegs[0x31];
|
||||
cal->light.green_light_off = a_bRegs[0x32] * 256 + a_bRegs[0x33];
|
||||
cal->light.blue_light_on = a_bRegs[0x34] * 256 + a_bRegs[0x35];
|
||||
cal->light.blue_light_off = a_bRegs[0x36] * 256 + a_bRegs[0x37];
|
||||
}
|
||||
|
||||
/** function to save/update the calibration data
|
||||
*/
|
||||
static void usb_SaveCalData( pPlustek_Device dev )
|
||||
{
|
||||
char pfx[20];
|
||||
char tmp[1024];
|
||||
char set_tmp[1024];
|
||||
char *other_tmp;
|
||||
u_short version;
|
||||
FILE *fp;
|
||||
CalData cal;
|
||||
pScanDef scanning = &dev->scanning;
|
||||
|
||||
DBG( _DBG_INFO, "usb_SaveCalData()\n" );
|
||||
|
||||
/* no new data, so skip this step too */
|
||||
if( SANE_TRUE == scanning->skipCoarseCalib ) {
|
||||
DBG( _DBG_INFO, "- No calibration data to save!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( NULL == dev->calFile ) {
|
||||
DBG( _DBG_ERROR, "- No calibration filename set!\n" );
|
||||
return;
|
||||
}
|
||||
DBG( _DBG_INFO, "- Saving calibration data to file\n" );
|
||||
DBG( _DBG_INFO, " %s\n", dev->calFile );
|
||||
|
||||
usb_PrepCalData ( &cal );
|
||||
usb_CreatePrefix( dev, pfx );
|
||||
|
||||
sprintf( set_tmp, "%s%u,%u,%u,%u,%u,%u,"
|
||||
"%lu,%lu,%lu,%lu,%lu,%lu,%lu\n", pfx,
|
||||
cal.red_gain, cal.red_offs,
|
||||
cal.green_gain, cal.green_offs,
|
||||
cal.blue_gain, cal.blue_offs,
|
||||
cal.light.red_light_on, cal.light.red_light_off,
|
||||
cal.light.green_light_on, cal.light.green_light_off,
|
||||
cal.light.blue_light_on, cal.light.blue_light_off,
|
||||
cal.light.green_pwm_duty );
|
||||
|
||||
/* read complete old file if compatible... */
|
||||
other_tmp = NULL;
|
||||
fp = fopen( dev->calFile, "r+" );
|
||||
if( NULL != fp ) {
|
||||
|
||||
if( usb_ReadSpecLine( fp, "version=", tmp )) {
|
||||
DBG( _DBG_INFO, "- Calibration file version: %s\n", tmp );
|
||||
|
||||
if( 1 == sscanf( tmp, "0x%04hx", &version )) {
|
||||
|
||||
if( version == cal.version ) {
|
||||
DBG( _DBG_INFO, "- Versions do match\n" );
|
||||
|
||||
/* read the rest... */
|
||||
other_tmp = usb_ReadOtherLines( fp, pfx );
|
||||
} else {
|
||||
DBG( _DBG_INFO2, "- Versions do not match (0x%04x)\n", version );
|
||||
}
|
||||
} else {
|
||||
DBG( _DBG_INFO2, "- cannot decode version\n" );
|
||||
}
|
||||
} else {
|
||||
DBG( _DBG_INFO2, "- Version not found\n" );
|
||||
}
|
||||
fclose( fp );
|
||||
}
|
||||
fp = fopen( dev->calFile, "w+" );
|
||||
if( NULL == fp ) {
|
||||
DBG( _DBG_ERROR, "- Cannot create file %s\n", dev->calFile );
|
||||
DBG( _DBG_ERROR, "- -> %s\n", strerror(errno));
|
||||
if( other_tmp )
|
||||
free( other_tmp );
|
||||
return;
|
||||
}
|
||||
|
||||
/* rewrite the file again... */
|
||||
fprintf( fp, "version=0x%04X\n", cal.version );
|
||||
if( strlen( set_tmp ))
|
||||
fprintf( fp, "%s", set_tmp );
|
||||
|
||||
if( other_tmp ) {
|
||||
fprintf( fp, "%s", other_tmp );
|
||||
free( other_tmp );
|
||||
}
|
||||
fclose( fp );
|
||||
DBG( _DBG_INFO, "usb_SaveCalData() done.\n" );
|
||||
}
|
||||
|
||||
/* END PLUSTEK-USBCALFILE.C .................................................*/
|
|
@ -3,7 +3,7 @@
|
|||
*.............................................................................
|
||||
*/
|
||||
|
||||
/** @file plustek-devs.c
|
||||
/** @file plustek-usbdevs.c
|
||||
* @brief Here we have our USB device definitions.
|
||||
*
|
||||
* Based on sources acquired from Plustek Inc.<br>
|
||||
|
@ -38,6 +38,9 @@
|
|||
* - removed EPSON 660 stuff
|
||||
* - added Canon 1220U entry
|
||||
* - added entry for Compaq S4-100
|
||||
* -0.46 - fine-tuning for the CanoScan devices
|
||||
* - fixed HP2200 shading position
|
||||
* - renamed to plustek-usbdevs.c
|
||||
* .
|
||||
* <hr>
|
||||
* This file is part of the SANE package.
|
||||
|
@ -491,11 +494,10 @@ static DCapsDef Cap0x03F0_0x0505 =
|
|||
static DCapsDef Cap0x03F0_0x0605 =
|
||||
{
|
||||
/* DataOrigin (x, y), ShadingOriginY */
|
||||
{{ 0, 209}, 0, -1, {2550, 3508}, { 50, 50}, COLOR_BW },
|
||||
{{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, /* No film scanner module */
|
||||
{{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, /* No film scanner module */
|
||||
{{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, /* No ADF */
|
||||
|
||||
{{ 0, 209}, 40, -1, {2550, 3508}, { 50, 50}, COLOR_BW },
|
||||
{{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, /* No film scanner module */
|
||||
{{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, /* No film scanner module */
|
||||
{{ 0, 0}, 0, -1, {0, 0}, { 0, 0 }, 0 }, /* No ADF */
|
||||
{600, 600}, /* Motor can handle 1200 DPI */
|
||||
0, /* OK */
|
||||
SENSORORDER_rgb, /* OK */
|
||||
|
@ -543,7 +545,7 @@ static DCapsDef Cap0x0400_0x1001_0 =
|
|||
static DCapsDef Cap0x04B8_0x010F_0 =
|
||||
{
|
||||
/* Normal */
|
||||
{{ 25, 80}, 10, -1, {2550, 3508}, { 100, 100 }, COLOR_BW },
|
||||
{{ 25, 85}, 10, -1, {2550, 3508}, { 100, 100 }, COLOR_BW },
|
||||
/* Positive */
|
||||
{{ 1100, 972}, 720, -1, { 473, 414}, { 150, 150 }, COLOR_GRAY16 },
|
||||
/* Negative */
|
||||
|
@ -618,7 +620,7 @@ static DCapsDef Cap0x04A9_0x2206_0 =
|
|||
1, /* number of buttons */
|
||||
kCIS650, /* use default settings during calibration */
|
||||
0, /* not used here... */
|
||||
_WAF_MISC_IO_LAMPS | _WAF_BLACKFINE | _WAF_FIX_OFS, _NO_MIO
|
||||
_WAF_MISC_IO_LAMPS | _WAF_BLACKFINE, _NO_MIO
|
||||
};
|
||||
|
||||
/* Canon N1220U
|
||||
|
@ -634,9 +636,9 @@ static DCapsDef Cap0x04A9_0x2207_0 =
|
|||
SENSORORDER_rgb,
|
||||
16, /* sensor distance */
|
||||
1, /* number of buttons */
|
||||
kCIS650, /* use default settings during calibration */
|
||||
kCIS1220, /* use default settings during calibration */
|
||||
0, /* not used here... */
|
||||
_WAF_MISC_IO_LAMPS | _WAF_BLACKFINE | _WAF_FIX_OFS, _NO_MIO
|
||||
_WAF_MISC_IO_LAMPS | _WAF_BLACKFINE, _NO_MIO
|
||||
};
|
||||
|
||||
/* Canon N670U/N676U/LiDE20
|
||||
|
@ -654,7 +656,7 @@ static DCapsDef Cap0x04A9_0x220D_0 =
|
|||
3, /* number of buttons */
|
||||
kCIS670,
|
||||
0, /* not used here... */
|
||||
_WAF_MISC_IO_LAMPS | _WAF_BLACKFINE | _WAF_FIX_OFS, _NO_MIO
|
||||
_WAF_MISC_IO_LAMPS | _WAF_BLACKFINE, _NO_MIO
|
||||
};
|
||||
|
||||
/* Canon N1240U
|
||||
|
@ -672,7 +674,7 @@ static DCapsDef Cap0x04A9_0x220E_0 =
|
|||
3, /* number of buttons */
|
||||
kCIS1240, /* use default settings during calibration */
|
||||
0, /* not used here... */
|
||||
_WAF_MISC_IO_LAMPS | _WAF_BLACKFINE | _WAF_FIX_OFS, _NO_MIO
|
||||
_WAF_MISC_IO_LAMPS | _WAF_BLACKFINE, _NO_MIO
|
||||
};
|
||||
|
||||
/******************* additional Hardware descriptions ************************/
|
||||
|
@ -1854,8 +1856,8 @@ static HWDef Hw0x04A9_0x2206_0 =
|
|||
0x00, /* bReg 0x27 color mode */
|
||||
2, /* bReg 0x29 illumination mode (runtime) */
|
||||
/* illumination mode settings */
|
||||
{ 3, 0, 0, 23, 1500, 0, 0 },
|
||||
{ 2, 23, 4000, 23, 2600, 23, 1600 },
|
||||
{ 3, 0, 0, 23, 1300, 0, 0 },
|
||||
{ 2, 23, 4000, 23, 2600, 23, 850 },
|
||||
|
||||
1, /* StepperPhaseCorrection (reg 0x1a + 0x1b) */
|
||||
0, /* bOpticBlackStart (reg 0x1c) */
|
||||
|
@ -1863,12 +1865,12 @@ static HWDef Hw0x04A9_0x2206_0 =
|
|||
89, /* ? wActivePixelsStart (reg 0x1e + 0x1f) */
|
||||
6074, /* wLineEnd (reg 0x20 + 0x21) */
|
||||
|
||||
23, /* red lamp on (reg 0x2c + 0x2d) */
|
||||
2416, /* red lamp off (reg 0x2e + 0x2f) */
|
||||
23, /* green lamp on (reg 0x30 + 0x31) */
|
||||
1801, /* green lamp off (reg 0x32 + 0x33) */
|
||||
23, /* blue lamp on (reg 0x34 + 0x35) */
|
||||
1472, /* blue lamp off (reg 0x36 + 0x37) */
|
||||
23, /* red lamp on (reg 0x2c + 0x2d) */
|
||||
4000, /* red lamp off (reg 0x2e + 0x2f) */
|
||||
23, /* green lamp on (reg 0x30 + 0x31) */
|
||||
2600, /* green lamp off (reg 0x32 + 0x33) */
|
||||
23, /* blue lamp on (reg 0x34 + 0x35) */
|
||||
850, /* blue lamp off (reg 0x36 + 0x37) */
|
||||
|
||||
3, /* stepper motor control (reg 0x45) */
|
||||
0, /* wStepsAfterPaperSensor2 (reg 0x4c + 0x4d) */
|
||||
|
@ -1920,8 +1922,8 @@ static HWDef Hw0x04A9_0x2207_0 =
|
|||
|
||||
0x00, /* bReg 0x27 color mode */
|
||||
2, /* bReg 0x29 illumination mode */
|
||||
{ 3, 0, 0, 23, 3937, 0, 0 },
|
||||
{ 2, 23, 14000, 23, 7500, 23, 5900 },
|
||||
{ 3, 0, 0, 23, 4950, 0, 0 },
|
||||
{ 2, 23, 16383, 23, 15000, 23, 6600 },
|
||||
|
||||
1, /* StepperPhaseCorrection (reg 0x1a + 0x1b) */
|
||||
0, /* bOpticBlackStart (reg 0x1c) */
|
||||
|
@ -1930,11 +1932,11 @@ static HWDef Hw0x04A9_0x2207_0 =
|
|||
10586, /* wLineEnd (reg 0x20 + 0x21) */
|
||||
|
||||
23, /* red lamp on (reg 0x2c + 0x2d) */
|
||||
8870, /* red lamp off (reg 0x2e + 0x2f) */
|
||||
16383, /* red lamp off (reg 0x2e + 0x2f) */
|
||||
23, /* green lamp on (reg 0x30 + 0x31) */
|
||||
5055, /* green lamp off (reg 0x32 + 0x33) */
|
||||
15000, /* green lamp off (reg 0x32 + 0x33) */
|
||||
23, /* blue lamp on (reg 0x34 + 0x35) */
|
||||
2828, /* blue lamp off (reg 0x36 + 0x37) */
|
||||
6600, /* blue lamp off (reg 0x36 + 0x37) */
|
||||
|
||||
3, /* stepper motor control (reg 0x45) */
|
||||
0, /* wStepsAfterPaperSensor2 (reg 0x4c + 0x4d) */
|
||||
|
@ -1996,14 +1998,12 @@ static HWDef Hw0x04A9_0x220D_0 =
|
|||
75, /* wActivePixelsStart (reg 0x1e + 0x1f) */
|
||||
6074, /* wLineEnd (reg 0x20 + 0x21) */
|
||||
|
||||
/* ??0x17ba = 6074 bis 100dpi, 0x14ba = 5306 */
|
||||
|
||||
23, /* red lamp on (reg 0x2c + 0x2d) */
|
||||
4562, /* red lamp off (reg 0x2e + 0x2f) */
|
||||
3800, /* red lamp off (reg 0x2e + 0x2f) */
|
||||
23, /* green lamp on (reg 0x30 + 0x31) */
|
||||
4315, /* green lamp off (reg 0x32 + 0x33) */
|
||||
3300, /* green lamp off (reg 0x32 + 0x33) */
|
||||
23, /* blue lamp on (reg 0x34 + 0x35) */
|
||||
3076, /* blue lamp off (reg 0x36 + 0x37) */
|
||||
2700, /* blue lamp off (reg 0x36 + 0x37) */
|
||||
|
||||
3, /* stepper motor control (reg 0x45) */
|
||||
0, /* wStepsAfterPaperSensor2 (reg 0x4c + 0x4d) */
|
||||
|
@ -2055,28 +2055,22 @@ static HWDef Hw0x04A9_0x220E_0 =
|
|||
|
||||
0x00, /* bReg 0x27 color mode */
|
||||
2, /* bReg 0x29 illumination mode */
|
||||
#if 1
|
||||
{ 3, 0, 0, 23, 3937, 0, 0 },
|
||||
{ 2, 23, 13000, 23, 6500, 23, 4900 },
|
||||
#else
|
||||
{ 3, 0, 0, 23, 16383, 0, 0 },
|
||||
{ 2, 23, 16383, 23, 16383, 23, 16383 },
|
||||
#endif
|
||||
|
||||
|
||||
{ 3, 0, 0, 23, 4000, 0, 0 },
|
||||
{ 2, 23, 16383, 23, 6500, 23, 4900 },
|
||||
|
||||
1, /* StepperPhaseCorrection (reg 0x1a + 0x1b) */
|
||||
0, /* bOpticBlackStart (reg 0x1c) */
|
||||
0, /* bOpticBlackEnd (reg 0x1d) */
|
||||
52, /* wActivePixelsStart (reg 0x1e + 0x1f) */
|
||||
10586, /* wLineEnd (reg 0x20 + 0x21) */
|
||||
|
||||
/* 0x2f7a = 12154 bis 100dpi, 0x295a = 10586 */
|
||||
10586, /* wLineEnd (reg 0x20 + 0x21) */
|
||||
|
||||
23, /* red lamp on (reg 0x2c + 0x2d) */
|
||||
10581, /* red lamp off (reg 0x2e + 0x2f) */
|
||||
16383, /* red lamp off (reg 0x2e + 0x2f) */
|
||||
23, /* green lamp on (reg 0x30 + 0x31) */
|
||||
5096, /* green lamp off (reg 0x32 + 0x33) */
|
||||
6500, /* green lamp off (reg 0x32 + 0x33) */
|
||||
23, /* blue lamp on (reg 0x34 + 0x35) */
|
||||
3735, /* blue lamp off (reg 0x36 + 0x37) */
|
||||
4900, /* blue lamp off (reg 0x36 + 0x37) */
|
||||
|
||||
3, /* stepper motor control (reg 0x45) */
|
||||
0, /* wStepsAfterPaperSensor2 (reg 0x4c + 0x4d) */
|
||||
|
@ -2146,7 +2140,7 @@ static SetDef Settings[] =
|
|||
{"0x0458-0x2016", &Cap0x07B3_0x0005_4, &Hw0x07B3_0x0007_0, "ColorPage-HR6X" },
|
||||
|
||||
/* Hewlett Packard... */
|
||||
{"0x03F0-0x0505", &Cap0x03F0_0x0505, &Hw0x03F0_0x0505, "Scanjet 2100c" },
|
||||
{"0x03F0-0x0505", &Cap0x03F0_0x0505, &Hw0x03F0_0x0505, "Scanjet 2100c" },
|
||||
{"0x03F0-0x0605", &Cap0x03F0_0x0605, &Hw0x03F0_0x0605, "Scanjet 2200c" },
|
||||
|
||||
/* EPSON... */
|
||||
|
@ -2154,18 +2148,18 @@ static SetDef Settings[] =
|
|||
{"0x04B8-0x011D", &Cap0x04B8_0x010F_0, &Hw0x04B8_0x011D_0, "Perfection 1260/Photo" },
|
||||
|
||||
/* UMAX... */
|
||||
{"0x1606-0x0060", &Cap0x1606_0x0060_0, &Hw0x1606_0x0060_0, "3400/3450" },
|
||||
{"0x1606-0x0160", &Cap0x1606_0x0160_0, &Hw0x1606_0x0160_0, "5400" },
|
||||
{"0x1606-0x0060", &Cap0x1606_0x0060_0, &Hw0x1606_0x0060_0, "3400/3450" },
|
||||
{"0x1606-0x0160", &Cap0x1606_0x0160_0, &Hw0x1606_0x0160_0, "5400" },
|
||||
|
||||
/* COMPAQ... */
|
||||
{"0x049F-0x001A", &Cap0x1606_0x0060_0, &Hw0x1606_0x0060_0, "S4-100" },
|
||||
{"0x049F-0x001A", &Cap0x1606_0x0060_0, &Hw0x1606_0x0060_0, "S4-100" },
|
||||
|
||||
/* CANON... */
|
||||
{"0x04A9-0x2206", &Cap0x04A9_0x2206_0, &Hw0x04A9_0x2206_0, "N650U/N656U" },
|
||||
{"0x04A9-0x2207", &Cap0x04A9_0x2207_0, &Hw0x04A9_0x2207_0, "N1220U" },
|
||||
{"0x04A9-0x220D", &Cap0x04A9_0x220D_0, &Hw0x04A9_0x220D_0, "N670U/N676U/LiDE20" },
|
||||
{"0x04A9-0x220E", &Cap0x04A9_0x220E_0, &Hw0x04A9_0x220E_0, "N1240U/LiDE30" },
|
||||
|
||||
|
||||
/* Please add other devices here...
|
||||
* The first entry is a string, composed out of the vendor and product id,
|
||||
* it's used by the driver to select the device settings. For other devices
|
||||
|
@ -2351,4 +2345,4 @@ static ClkMotorDef Motors[] = {
|
|||
},
|
||||
};
|
||||
|
||||
/* END PLUSTEK-DEVS.C .......................................................*/
|
||||
/* END PLUSTEK-USBDEVS.C ....................................................*/
|
|
@ -27,6 +27,8 @@
|
|||
* - 0.45 - added function usb_AdjustLamps() to tweak CIS lamp settings
|
||||
* - fixed NULL pointer problem in lamp-off ISR
|
||||
* - added usb_AdjustCISLampSettings()
|
||||
* - skipping warmup for CIS devices
|
||||
* - 0.46 - no changes
|
||||
* .
|
||||
* <hr>
|
||||
* This file is part of the SANE package.
|
||||
|
@ -1070,6 +1072,8 @@ static SANE_Bool usb_LampOn( pPlustek_Device dev,
|
|||
* 0x0f - 0x18 - Sensor Configuration - directly from the HwDef<br>
|
||||
* 0x1a - 0x1b - Stepper Phase Correction<br>
|
||||
* 0x20 - 0x21 - Line End<br>
|
||||
* 0x21 - 0x22 - Data Pixel start<br>
|
||||
* 0x23 - 0x24 - Data Pixel end<br>
|
||||
* 0x45 - Stepper Motor Mode<br>
|
||||
* 0x4c - 0x4d - Full Steps to Scan after PAPER SENSE 2 trips<br>
|
||||
* 0x50 - Steps to reverse when buffer is full<br>
|
||||
|
@ -1082,19 +1086,37 @@ static SANE_Bool usb_LampOn( pPlustek_Device dev,
|
|||
*/
|
||||
static void usb_ResetRegisters( pPlustek_Device dev )
|
||||
{
|
||||
int linend;
|
||||
|
||||
pHWDef hw = &dev->usbDev.HwSetting;
|
||||
|
||||
DBG( _DBG_INFO, "RESETTING REGISTERS(%u)\n", dev->initialized );
|
||||
DBG( _DBG_INFO, "RESETTING REGISTERS(%i)\n", dev->initialized );
|
||||
memset( a_bRegs, 0, sizeof(a_bRegs));
|
||||
|
||||
memcpy( a_bRegs+0x0b, &hw->bSensorConfiguration, 4 );
|
||||
memcpy( a_bRegs+0x0f, &hw->bReg_0x0f_Color, 10 );
|
||||
a_bRegs[0x1a] = _HIBYTE( hw->StepperPhaseCorrection );
|
||||
a_bRegs[0x1b] = _LOBYTE( hw->StepperPhaseCorrection );
|
||||
#if 0
|
||||
a_bRegs[0x1e] = _HIBYTE( hw->wActivePixelsStart );
|
||||
a_bRegs[0x1f] = _LOBYTE( hw->wActivePixelsStart );
|
||||
#endif
|
||||
a_bRegs[0x20] = _HIBYTE( hw->wLineEnd );
|
||||
a_bRegs[0x21] = _LOBYTE( hw->wLineEnd );
|
||||
|
||||
a_bRegs[0x22] = _HIBYTE( hw->bOpticBlackStart );
|
||||
a_bRegs[0x22] = _LOBYTE( hw->bOpticBlackStart );
|
||||
|
||||
linend = hw->bOpticBlackStart + hw->wLineEnd;
|
||||
if( linend < (hw->wLineEnd-20))
|
||||
linend = hw->wLineEnd-20;
|
||||
|
||||
a_bRegs[0x24] = _HIBYTE( linend );
|
||||
a_bRegs[0x25] = _LOBYTE( linend );
|
||||
|
||||
a_bRegs[0x2a] = _HIBYTE( hw->wGreenPWMDutyCycleHigh );
|
||||
a_bRegs[0x2b] = _LOBYTE( hw->wGreenPWMDutyCycleHigh );
|
||||
|
||||
a_bRegs[0x45] = hw->bReg_0x45;
|
||||
a_bRegs[0x4c] = _HIBYTE( hw->wStepsAfterPaperSensor2 );
|
||||
a_bRegs[0x4d] = _LOBYTE( hw->wStepsAfterPaperSensor2 );
|
||||
|
@ -1104,21 +1126,25 @@ static void usb_ResetRegisters( pPlustek_Device dev )
|
|||
/* if already initialized, we ignore the MISC I/O settings as
|
||||
* they are used to determine the current lamp settings...
|
||||
*/
|
||||
if( dev->initialized ) {
|
||||
if( dev->initialized >= 0 ) {
|
||||
|
||||
DBG( _DBG_INFO2, "USING MISC I/O settings\n" );
|
||||
memcpy( a_bRegs+0x54, &hw->bReg_0x54, 0x58 - 0x54 + 1 );
|
||||
a_bRegs[0x5c] = hw->bReg_0x5c;
|
||||
a_bRegs[0x5d] = hw->bReg_0x5d;
|
||||
a_bRegs[0x5e] = hw->bReg_0x5e;
|
||||
sanei_lm983x_read( dev->fd, 0x59, &a_bRegs[0x59], 3, SANE_TRUE );
|
||||
} else {
|
||||
|
||||
DBG( _DBG_INFO2, "SETTING THE MISC I/Os\n" );
|
||||
memcpy( a_bRegs+0x54, &hw->bReg_0x54, 0x5e - 0x54 + 1 );
|
||||
sanei_lm983x_write( dev->fd, 0x59, &a_bRegs[0x59], 3, SANE_TRUE );
|
||||
}
|
||||
DBG( _DBG_INFO, "MISC I/O after RESET: 0x%02x, 0x%02x, 0x%02x\n",
|
||||
a_bRegs[0x59], a_bRegs[0x5a], a_bRegs[0x5b] );
|
||||
}
|
||||
|
||||
/** usb_ModuleStatus
|
||||
*
|
||||
*/
|
||||
static SANE_Bool usb_ModuleStatus( pPlustek_Device dev )
|
||||
{
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
* - fixed a bug in usb_GrayScalePseudo16 function
|
||||
* - fixed a bug in usb_GrayDuplicatePseudo16 function
|
||||
* - removed the scaler stuff for CIS devices
|
||||
* - 0.46 - no changes
|
||||
* .
|
||||
* <hr>
|
||||
* This file is part of the SANE package.
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
* - beautyfied output of ASIC detection
|
||||
* - 0.45 - fixed dumpRegs
|
||||
* - added dimension stuff to dumpPic
|
||||
* - 0.46 - disabled reset prior to the detection of Merlin
|
||||
* .
|
||||
* <hr>
|
||||
* This file is part of the SANE package.
|
||||
|
@ -262,8 +263,7 @@ static SANE_Bool usbio_WriteReg( SANE_Int handle,
|
|||
return SANE_FALSE;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
*
|
||||
/**
|
||||
*/
|
||||
static SANE_Status usbio_DetectLM983x( SANE_Int fd, SANE_Byte *version )
|
||||
{
|
||||
|
@ -273,10 +273,12 @@ static SANE_Status usbio_DetectLM983x( SANE_Int fd, SANE_Byte *version )
|
|||
|
||||
DBG( _DBG_INFO, "usbio_DetectLM983x\n");
|
||||
|
||||
#if 0
|
||||
_UIO( sanei_lm983x_write_byte(fd, 0x07, 0x00));
|
||||
_UIO( sanei_lm983x_write_byte(fd, 0x08, 0x02));
|
||||
_UIO( usbio_ReadReg(fd, 0x07, &value));
|
||||
_UIO( usbio_ReadReg(fd, 0x08, &value));
|
||||
#endif
|
||||
_UIO( usbio_ReadReg(fd, 0x69, &value));
|
||||
|
||||
value &= 7;
|
||||
|
@ -303,8 +305,7 @@ static SANE_Status usbio_DetectLM983x( SANE_Int fd, SANE_Byte *version )
|
|||
return res;
|
||||
}
|
||||
|
||||
/*.............................................................................
|
||||
*
|
||||
/**
|
||||
*/
|
||||
static SANE_Status usbio_ResetLM983x( pPlustek_Device dev )
|
||||
{
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
* - 0.43 - no changes
|
||||
* - 0.44 - map inversion for negatatives now only upon user request
|
||||
* - 0.45 - no changes
|
||||
* - 0.46 - no changes
|
||||
* .
|
||||
* <hr>
|
||||
* This file is part of the SANE package.
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
* - fixed cancel hang problem
|
||||
* - fixed CIS PhyBytes adjustment
|
||||
* - removed CanoScan specific setting stuff
|
||||
* - 0.46 - fixed problem in usb_SetScanParameters()
|
||||
* .
|
||||
* <hr>
|
||||
* This file is part of the SANE package.
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
* - 0.45 - added coarse calibration for CIS devices
|
||||
* - added _WAF_SKIP_FINE to skip the results of fine calibration
|
||||
* - CanoScan fixes and fine-tuning
|
||||
* - 0.46 - CanoScan will now be calibrated by code in plustek-usbcal.c
|
||||
* - added functions to save and restore calibration data from a file
|
||||
* .
|
||||
* <hr>
|
||||
* This file is part of the SANE package.
|
||||
|
@ -332,63 +334,33 @@ static void usb_GetSoftwareOffsetGain( pPlustek_Device dev )
|
|||
break;
|
||||
|
||||
case kCIS650:
|
||||
DBG( _DBG_INFO2, "kCIS650 adjustments\n" );
|
||||
if(pParam->bDataType == SCANDATATYPE_Color) {
|
||||
pParam->swGain[0] = 1160;
|
||||
pParam->swGain[1] = 1160;
|
||||
pParam->swGain[2] = 1160;
|
||||
} else {
|
||||
pParam->swOffset[0] =
|
||||
pParam->swOffset[1] =
|
||||
pParam->swOffset[2] = -1500;
|
||||
|
||||
pParam->swGain[0] =
|
||||
pParam->swGain[1] =
|
||||
pParam->swGain[2] = 1000;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case kCIS670:
|
||||
DBG( _DBG_INFO2, "kCIS670 adjustments\n" );
|
||||
case kCIS1220:
|
||||
DBG( _DBG_INFO2, "kCIS adjustments\n" );
|
||||
if(pParam->bDataType == SCANDATATYPE_Color) {
|
||||
pParam->swOffset[0] = -2650;
|
||||
pParam->swOffset[1] = -2800;
|
||||
pParam->swOffset[2] = -2850;
|
||||
|
||||
pParam->swGain[0] = 1150;
|
||||
pParam->swGain[1] = 1150;
|
||||
pParam->swGain[2] = 1150;
|
||||
} else {
|
||||
pParam->swOffset[0] =
|
||||
pParam->swOffset[1] =
|
||||
pParam->swOffset[2] = -2800;
|
||||
|
||||
pParam->swGain[0] =
|
||||
pParam->swGain[1] =
|
||||
pParam->swGain[2] = 980;
|
||||
pParam->swGain[2] = 952;
|
||||
|
||||
pParam->swOffset[0] =
|
||||
pParam->swOffset[1] =
|
||||
pParam->swOffset[2] = 1000;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case kCIS1240:
|
||||
DBG( _DBG_INFO2, "kCIS1240 adjustments\n" );
|
||||
if(pParam->bDataType == SCANDATATYPE_Color) {
|
||||
pParam->swOffset[0] = -1650;
|
||||
pParam->swOffset[1] = -1500;
|
||||
pParam->swOffset[2] = -1500;
|
||||
|
||||
pParam->swGain[0] = 1010;
|
||||
pParam->swGain[1] = 1050;
|
||||
pParam->swGain[2] = 1030;
|
||||
} else {
|
||||
pParam->swOffset[0] = -1000;
|
||||
pParam->swOffset[1] = -1000;
|
||||
pParam->swOffset[2] = -1000;
|
||||
pParam->swGain[0] = 950;
|
||||
pParam->swGain[1] = 950;
|
||||
pParam->swGain[2] = 900;
|
||||
|
||||
pParam->swGain[0] = 1100;
|
||||
pParam->swGain[1] = 1100;
|
||||
pParam->swGain[2] = 1100;
|
||||
}
|
||||
pParam->swOffset[0] =
|
||||
pParam->swOffset[1] =
|
||||
pParam->swOffset[2] = 0; /*1000;*/
|
||||
}
|
||||
break;
|
||||
|
||||
case kNEC3799:
|
||||
|
@ -702,14 +674,6 @@ static SANE_Bool usb_AdjustGain( pPlustek_Device dev, int fNegative )
|
|||
bMaxITA = 0xff;
|
||||
|
||||
DBG( _DBG_INFO2, "usb_AdjustGain()\n" );
|
||||
if( scaps->workaroundFlag & _WAF_FIX_GAIN ) {
|
||||
a_bRegs[0x3b] =
|
||||
a_bRegs[0x3c] =
|
||||
a_bRegs[0x3d] = _CIS_GAIN;
|
||||
|
||||
/* don't blame on me - I know it's shitty... */
|
||||
goto show_sets;
|
||||
}
|
||||
|
||||
/*
|
||||
* define the strip to scan for coarse calibration
|
||||
|
@ -1074,7 +1038,6 @@ TOGAIN:
|
|||
}
|
||||
}
|
||||
|
||||
show_sets:
|
||||
DBG( _DBG_INFO2, "REG[0x3b] = %u\n", a_bRegs[0x3b] );
|
||||
DBG( _DBG_INFO2, "REG[0x3c] = %u\n", a_bRegs[0x3c] );
|
||||
DBG( _DBG_INFO2, "REG[0x3d] = %u\n", a_bRegs[0x3d] );
|
||||
|
@ -1164,19 +1127,12 @@ static SANE_Bool usb_AdjustOffset( pPlustek_Device dev )
|
|||
u_long dw, dwPixels;
|
||||
u_long dwDiff[3], dwSum[3];
|
||||
|
||||
pDCapsDef scaps = &dev->usbDev.Caps;
|
||||
pHWDef hw = &dev->usbDev.HwSetting;
|
||||
pHWDef hw = &dev->usbDev.HwSetting;
|
||||
|
||||
if( usb_IsEscPressed())
|
||||
return SANE_FALSE;
|
||||
|
||||
DBG( _DBG_INFO2, "usb_AdjustOffset()\n" );
|
||||
if( scaps->workaroundFlag & _WAF_FIX_OFS ) {
|
||||
a_bRegs[0x38] =
|
||||
a_bRegs[0x39] =
|
||||
a_bRegs[0x3a] = _CIS_OFFS;
|
||||
return SANE_TRUE;
|
||||
}
|
||||
|
||||
m_ScanParam.Size.dwLines = 1; /* for gain */
|
||||
m_ScanParam.Size.dwPixels = 2550;
|
||||
|
@ -2017,7 +1973,6 @@ static void usb_ResizeWhiteShading( double dAmp, u_short *pwShading, int iGain )
|
|||
pwShading[dw] = (u_short)_LOBYTE(w) * 256 + _HIBYTE(w);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
static void usb_PrepareCalibration( pPlustek_Device dev )
|
||||
|
@ -2053,10 +2008,15 @@ static void usb_PrepareCalibration( pPlustek_Device dev )
|
|||
|
||||
memset( a_wWhiteShading, 0, _SHADING_BUF );
|
||||
memset( a_wDarkShading, 0, _SHADING_BUF );
|
||||
|
||||
scanning->skipCoarseCalib = SANE_FALSE;
|
||||
|
||||
if( dev->adj.cacheCalData )
|
||||
if( usb_ReadAndSetCalData( dev ))
|
||||
scanning->skipCoarseCalib = SANE_TRUE;
|
||||
}
|
||||
|
||||
/** usb_DoCalibration
|
||||
*
|
||||
*/
|
||||
static int usb_DoCalibration( pPlustek_Device dev )
|
||||
{
|
||||
|
@ -2071,14 +2031,12 @@ static int usb_DoCalibration( pPlustek_Device dev )
|
|||
|
||||
/* Go to shading position
|
||||
*/
|
||||
if( !(scaps->workaroundFlag & (_WAF_FIX_GAIN & _WAF_FIX_OFS))) {
|
||||
|
||||
DBG( _DBG_INFO, "goto shading position\n" );
|
||||
DBG( _DBG_INFO, "goto shading position\n" );
|
||||
|
||||
/* HEINER: Currently not clear why Plustek didn't use the ShadingOriginY
|
||||
* for all modes
|
||||
* It should be okay to remove this and reference to the ShadingOriginY
|
||||
*/
|
||||
/* HEINER: Currently not clear why Plustek didn't use the ShadingOriginY
|
||||
* for all modes
|
||||
* It should be okay to remove this and reference to the ShadingOriginY
|
||||
*/
|
||||
#if 0
|
||||
if( scanning->sParam.bSource == SOURCE_Negative ) {
|
||||
|
||||
|
@ -2092,22 +2050,21 @@ static int usb_DoCalibration( pPlustek_Device dev )
|
|||
|
||||
} else {
|
||||
#endif
|
||||
DBG( _DBG_INFO, "ShadingOriginY=%lu\n",
|
||||
(u_long)dev->usbDev.pSource->ShadingOriginY );
|
||||
DBG( _DBG_INFO, "ShadingOriginY=%lu\n",
|
||||
(u_long)dev->usbDev.pSource->ShadingOriginY );
|
||||
|
||||
if((hw->motorModel == MODEL_HuaLien) && (scaps->OpticDpi.x==600)) {
|
||||
if (!usb_ModuleMove(dev, MOVE_ToShading,
|
||||
(u_long)dev->usbDev.pSource->ShadingOriginY)) {
|
||||
return _E_LAMP_NOT_IN_POS;
|
||||
}
|
||||
} else {
|
||||
if( !usb_ModuleMove(dev, MOVE_Forward,
|
||||
(u_long)dev->usbDev.pSource->ShadingOriginY)) {
|
||||
return _E_LAMP_NOT_IN_POS;
|
||||
}
|
||||
if((hw->motorModel == MODEL_HuaLien) && (scaps->OpticDpi.x==600)) {
|
||||
if (!usb_ModuleMove(dev, MOVE_ToShading,
|
||||
(u_long)dev->usbDev.pSource->ShadingOriginY)) {
|
||||
return _E_LAMP_NOT_IN_POS;
|
||||
}
|
||||
/* }*/
|
||||
}
|
||||
} else {
|
||||
if( !usb_ModuleMove(dev, MOVE_Forward,
|
||||
(u_long)dev->usbDev.pSource->ShadingOriginY)) {
|
||||
return _E_LAMP_NOT_IN_POS;
|
||||
}
|
||||
}
|
||||
/* }*/
|
||||
|
||||
DBG( _DBG_INFO, "shading position reached\n" );
|
||||
|
||||
|
@ -2474,7 +2431,8 @@ static int usb_DoCalibration( pPlustek_Device dev )
|
|||
}
|
||||
|
||||
scanning->fCalibrated = SANE_TRUE;
|
||||
DBG( _DBG_INFO, "Calibration done\n-----------------------\n" );
|
||||
DBG( _DBG_INFO, "Calibration done\n" );
|
||||
DBG( _DBG_INFO, "-----------------------\n" );
|
||||
DBG( _DBG_INFO, "Static Gain:\n" );
|
||||
DBG( _DBG_INFO, "REG[0x3b] = %u\n", a_bRegs[0x3b] );
|
||||
DBG( _DBG_INFO, "REG[0x3c] = %u\n", a_bRegs[0x3c] );
|
||||
|
|
|
@ -58,6 +58,10 @@
|
|||
* - added WIFSIGNALED to check result of child termination
|
||||
* - changed readImage interface for USB devices
|
||||
* - homeing of USB scanner is now working correctly
|
||||
* - 0.46 - added plustek-usbcal.c for extra CIS device calibration
|
||||
* based in Montys' great work
|
||||
* - added altCalibration option
|
||||
* - removed parallelport support
|
||||
*.
|
||||
* <hr>
|
||||
* This file is part of the SANE package.
|
||||
|
@ -131,7 +135,7 @@
|
|||
#include "sane/sanei.h"
|
||||
#include "sane/saneopts.h"
|
||||
|
||||
#define BACKEND_VERSION "0.45-7"
|
||||
#define BACKEND_VERSION "0.46-TEST2"
|
||||
#define BACKEND_NAME plustek
|
||||
#include "sane/sanei_backend.h"
|
||||
#include "sane/sanei_config.h"
|
||||
|
@ -161,7 +165,8 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _DEFAULT_DEVICE "/dev/pt_drv"
|
||||
#define _SECTION "[merlin-device]"
|
||||
#define _DEFAULT_DEVICE "/dev/usb/scanner0"
|
||||
|
||||
/* declare it here, as it's used in plustek-usbscan.c too :-( */
|
||||
static SANE_Bool cancelRead;
|
||||
|
@ -169,18 +174,17 @@ static SANE_Bool cancelRead;
|
|||
/* the USB-stuff... I know this is in general no good idea, but it works */
|
||||
#ifdef _PLUSTEK_USB
|
||||
# include "plustek-usbio.c"
|
||||
# include "plustek-devs.c"
|
||||
# include "plustek-usbdevs.c"
|
||||
# include "plustek-usbhw.c"
|
||||
# include "plustek-usbmap.c"
|
||||
# include "plustek-usbscan.c"
|
||||
# include "plustek-usbimg.c"
|
||||
# include "plustek-usbcalfile.c"
|
||||
# include "plustek-usbshading.c"
|
||||
# include "plustek-usbcal.c"
|
||||
# include "plustek-usb.c"
|
||||
#endif
|
||||
|
||||
/* the parport wrapper... */
|
||||
#include "plustek-pp.c"
|
||||
|
||||
/************************** global vars **************************************/
|
||||
|
||||
static int num_devices;
|
||||
|
@ -190,25 +194,6 @@ static const SANE_Device **devlist = 0;
|
|||
static unsigned long tsecs = 0;
|
||||
|
||||
static ModeParam mode_params[] =
|
||||
{
|
||||
{0, 1, COLOR_BW},
|
||||
{0, 1, COLOR_HALFTONE},
|
||||
{0, 8, COLOR_256GRAY},
|
||||
{1, 8, COLOR_TRUE24},
|
||||
{1, 16, COLOR_TRUE32},
|
||||
{1, 16, COLOR_TRUE36}
|
||||
};
|
||||
|
||||
static ModeParam mode_9800x_params[] =
|
||||
{
|
||||
{0, 1, COLOR_BW},
|
||||
{0, 1, COLOR_HALFTONE},
|
||||
{0, 8, COLOR_256GRAY},
|
||||
{1, 8, COLOR_TRUE24},
|
||||
{1, 16, COLOR_TRUE48}
|
||||
};
|
||||
|
||||
static ModeParam mode_usb_params[] =
|
||||
{
|
||||
{0, 1, COLOR_BW},
|
||||
{0, 8, COLOR_256GRAY},
|
||||
|
@ -227,16 +212,6 @@ static const SANE_String_Const mode_list[] =
|
|||
NULL
|
||||
};
|
||||
|
||||
static const SANE_String_Const mode_9800x_list[] =
|
||||
{
|
||||
SANE_I18N("Binary"),
|
||||
SANE_I18N("Halftone"),
|
||||
SANE_I18N("Gray"),
|
||||
SANE_I18N("Color"),
|
||||
SANE_I18N("Color36"),
|
||||
NULL
|
||||
};
|
||||
|
||||
static const SANE_String_Const mode_usb_list[] =
|
||||
{
|
||||
SANE_I18N("Binary"),
|
||||
|
@ -275,16 +250,13 @@ static const SANE_Range percentage_range =
|
|||
*/
|
||||
static LensInfo lens = {{0,0,0,0,},{0,0,0,0,},{0,0,0,0,},{0,0,0,0,},0,0};
|
||||
|
||||
/*
|
||||
* see plustek-share.h
|
||||
*/
|
||||
MODELSTR;
|
||||
|
||||
/* authorization stuff */
|
||||
static SANE_Auth_Callback auth = NULL;
|
||||
|
||||
/****************************** the backend... *******************************/
|
||||
|
||||
#define _YN(x) (x?"yes":"no")
|
||||
|
||||
/**
|
||||
* function to display the configuration options for the current device
|
||||
* @param cnf - pointer to the configuration structure whose content should be
|
||||
|
@ -292,34 +264,35 @@ static SANE_Auth_Callback auth = NULL;
|
|||
*/
|
||||
static void show_cnf( pCnfDef cnf )
|
||||
{
|
||||
DBG( _DBG_SANE_INIT, "Device configuration:\n" );
|
||||
DBG( _DBG_SANE_INIT, "device name : >%s<\n", cnf->devName );
|
||||
DBG( _DBG_SANE_INIT, "porttype : %d\n", cnf->porttype );
|
||||
DBG( _DBG_SANE_INIT, "USB-ID : >%s<\n", cnf->usbId );
|
||||
DBG( _DBG_SANE_INIT, "warmup : %ds\n", cnf->adj.warmup );
|
||||
DBG( _DBG_SANE_INIT, "lampOff : %d\n", cnf->adj.lampOff );
|
||||
DBG( _DBG_SANE_INIT, "lampOffOnEnd : %d\n", cnf->adj.lampOffOnEnd );
|
||||
DBG( _DBG_SANE_INIT, "skipCalibr. : %d\n", cnf->adj.skipCalibration );
|
||||
DBG( _DBG_SANE_INIT, "skipFine : %d\n", cnf->adj.skipFine );
|
||||
DBG( _DBG_SANE_INIT, "skipFineWhite: %d\n", cnf->adj.skipFineWhite );
|
||||
DBG( _DBG_SANE_INIT, "invertNegs. : %d\n", cnf->adj.invertNegatives );
|
||||
DBG( _DBG_SANE_INIT, "pos_x : %d\n", cnf->adj.pos.x );
|
||||
DBG( _DBG_SANE_INIT, "pos_y : %d\n", cnf->adj.pos.y );
|
||||
DBG( _DBG_SANE_INIT, "pos_shading_y: %d\n", cnf->adj.posShadingY );
|
||||
DBG( _DBG_SANE_INIT, "neg_x : %d\n", cnf->adj.neg.x );
|
||||
DBG( _DBG_SANE_INIT, "neg_y : %d\n", cnf->adj.neg.y );
|
||||
DBG( _DBG_SANE_INIT, "neg_shading_y: %d\n", cnf->adj.negShadingY );
|
||||
DBG( _DBG_SANE_INIT, "tpa_x : %d\n", cnf->adj.tpa.x );
|
||||
DBG( _DBG_SANE_INIT, "tpa_y : %d\n", cnf->adj.tpa.y );
|
||||
DBG( _DBG_SANE_INIT, "tpa_shading_y: %d\n", cnf->adj.tpaShadingY );
|
||||
DBG( _DBG_SANE_INIT, "red gain : %d\n", cnf->adj.rgain );
|
||||
DBG( _DBG_SANE_INIT, "green gain : %d\n", cnf->adj.ggain );
|
||||
DBG( _DBG_SANE_INIT, "blue gain : %d\n", cnf->adj.bgain );
|
||||
DBG( _DBG_SANE_INIT, "red Gamma : %.2f\n", cnf->adj.rgamma );
|
||||
DBG( _DBG_SANE_INIT, "green Gamma : %.2f\n", cnf->adj.ggamma );
|
||||
DBG( _DBG_SANE_INIT, "blue Gamma : %.2f\n", cnf->adj.bgamma );
|
||||
DBG( _DBG_SANE_INIT, "gray Gamma : %.2f\n", cnf->adj.graygamma );
|
||||
DBG( _DBG_SANE_INIT, "---------------------\n" );
|
||||
DBG( _DBG_SANE_INIT,"Device configuration:\n" );
|
||||
DBG( _DBG_SANE_INIT,"device name : >%s<\n",cnf->devName );
|
||||
DBG( _DBG_SANE_INIT,"USB-ID : >%s<\n",cnf->usbId );
|
||||
DBG( _DBG_SANE_INIT,"warmup : %ds\n", cnf->adj.warmup );
|
||||
DBG( _DBG_SANE_INIT,"lampOff : %d\n", cnf->adj.lampOff );
|
||||
DBG( _DBG_SANE_INIT,"lampOffOnEnd : %s\n", _YN(cnf->adj.lampOffOnEnd ));
|
||||
DBG( _DBG_SANE_INIT,"cacheCalData : %s\n", _YN(cnf->adj.cacheCalData ));
|
||||
DBG( _DBG_SANE_INIT,"altCalibrate : %s\n", _YN(cnf->adj.altCalibrate ));
|
||||
DBG( _DBG_SANE_INIT,"skipCalibr. : %s\n", _YN(cnf->adj.skipCalibration));
|
||||
DBG( _DBG_SANE_INIT,"skipFine : %s\n", _YN(cnf->adj.skipFine ));
|
||||
DBG( _DBG_SANE_INIT,"skipFineWhite: %s\n", _YN(cnf->adj.skipFineWhite ));
|
||||
DBG( _DBG_SANE_INIT,"invertNegs. : %s\n", _YN(cnf->adj.invertNegatives));
|
||||
DBG( _DBG_SANE_INIT,"pos_x : %d\n", cnf->adj.pos.x );
|
||||
DBG( _DBG_SANE_INIT,"pos_y : %d\n", cnf->adj.pos.y );
|
||||
DBG( _DBG_SANE_INIT,"pos_shading_y: %d\n", cnf->adj.posShadingY );
|
||||
DBG( _DBG_SANE_INIT,"neg_x : %d\n", cnf->adj.neg.x );
|
||||
DBG( _DBG_SANE_INIT,"neg_y : %d\n", cnf->adj.neg.y );
|
||||
DBG( _DBG_SANE_INIT,"neg_shading_y: %d\n", cnf->adj.negShadingY );
|
||||
DBG( _DBG_SANE_INIT,"tpa_x : %d\n", cnf->adj.tpa.x );
|
||||
DBG( _DBG_SANE_INIT,"tpa_y : %d\n", cnf->adj.tpa.y );
|
||||
DBG( _DBG_SANE_INIT,"tpa_shading_y: %d\n", cnf->adj.tpaShadingY );
|
||||
DBG( _DBG_SANE_INIT,"red gain : %d\n", cnf->adj.rgain );
|
||||
DBG( _DBG_SANE_INIT,"green gain : %d\n", cnf->adj.ggain );
|
||||
DBG( _DBG_SANE_INIT,"blue gain : %d\n", cnf->adj.bgain );
|
||||
DBG( _DBG_SANE_INIT,"red Gamma : %.2f\n",cnf->adj.rgamma );
|
||||
DBG( _DBG_SANE_INIT,"green Gamma : %.2f\n",cnf->adj.ggamma );
|
||||
DBG( _DBG_SANE_INIT,"blue Gamma : %.2f\n",cnf->adj.bgamma );
|
||||
DBG( _DBG_SANE_INIT,"gray Gamma : %.2f\n",cnf->adj.graygamma );
|
||||
DBG( _DBG_SANE_INIT,"---------------------\n" );
|
||||
}
|
||||
|
||||
/** open the device specific driver and reset the internal timing stuff
|
||||
|
@ -372,29 +345,13 @@ static SANE_Status drvclose( Plustek_Device *dev )
|
|||
*/
|
||||
static pModeParam getModeList( Plustek_Scanner *scanner )
|
||||
{
|
||||
pModeParam mp;
|
||||
|
||||
if( _ASIC_IS_USB == scanner->hw->caps.AsicID ) {
|
||||
mp = mode_usb_params;
|
||||
} else {
|
||||
|
||||
if((_ASIC_IS_98003 == scanner->hw->caps.AsicID) ||
|
||||
(_ASIC_IS_98001 == scanner->hw->caps.AsicID)) {
|
||||
mp = mode_9800x_params;
|
||||
} else {
|
||||
mp = mode_params;
|
||||
}
|
||||
}
|
||||
pModeParam mp= mode_params;
|
||||
|
||||
/*
|
||||
* the transparency/negative mode supports only GRAY/COLOR/COLOR32/COLOR48
|
||||
*/
|
||||
if( 0 != scanner->val[OPT_EXT_MODE].w ) {
|
||||
|
||||
if( _ASIC_IS_USB == scanner->hw->caps.AsicID )
|
||||
mp = &mp[_TPAModeSupportMin];
|
||||
else
|
||||
mp = &mp[_TPAModeSupportMin];
|
||||
mp = &mp[_TPAModeSupportMin];
|
||||
}
|
||||
|
||||
return mp;
|
||||
|
@ -505,10 +462,8 @@ static int reader_process( Plustek_Scanner *scanner, int pipe_fd )
|
|||
act.sa_handler = reader_process_sigterm_handler;
|
||||
sigaction( SIGTERM, &act, 0 );
|
||||
|
||||
if( _ASIC_IS_USB == scanner->hw->caps.AsicID ) {
|
||||
act.sa_handler = usb_reader_process_sigterm_handler;
|
||||
sigaction( SIGUSR1, &act, 0 );
|
||||
}
|
||||
act.sa_handler = usb_reader_process_sigterm_handler;
|
||||
sigaction( SIGUSR1, &act, 0 );
|
||||
|
||||
data_length = scanner->params.lines * scanner->params.bytes_per_line;
|
||||
|
||||
|
@ -580,7 +535,6 @@ static SANE_Status do_cancel( Plustek_Scanner *scanner, SANE_Bool closepipe )
|
|||
{
|
||||
struct SIGACTION act;
|
||||
pid_t res;
|
||||
int int_cnt;
|
||||
|
||||
DBG( _DBG_PROC,"do_cancel\n" );
|
||||
|
||||
|
@ -590,14 +544,6 @@ static SANE_Status do_cancel( Plustek_Scanner *scanner, SANE_Bool closepipe )
|
|||
|
||||
DBG( _DBG_PROC, ">>>>>>>> killing reader_process <<<<<<<<\n" );
|
||||
|
||||
/* tell the driver to stop scanning */
|
||||
if( _ASIC_IS_USB != scanner->hw->caps.AsicID ) {
|
||||
if( -1 != scanner->hw->fd ) {
|
||||
int_cnt = 1;
|
||||
scanner->hw->stopScan( scanner->hw, &int_cnt );
|
||||
}
|
||||
}
|
||||
|
||||
cancelRead = SANE_TRUE;
|
||||
|
||||
sigemptyset(&(act.sa_mask));
|
||||
|
@ -607,10 +553,7 @@ static SANE_Status do_cancel( Plustek_Scanner *scanner, SANE_Bool closepipe )
|
|||
sigaction( SIGALRM, &act, 0 );
|
||||
|
||||
/* kill our child process and wait until done */
|
||||
if( _ASIC_IS_USB == scanner->hw->caps.AsicID )
|
||||
kill( scanner->reader_pid, SIGUSR1 );
|
||||
else
|
||||
kill( scanner->reader_pid, SIGTERM );
|
||||
kill( scanner->reader_pid, SIGUSR1 );
|
||||
|
||||
/* give'em 10 seconds 'til done...*/
|
||||
alarm(10);
|
||||
|
@ -652,18 +595,7 @@ static SANE_Status limitResolution( Plustek_Device *dev )
|
|||
if( dev->dpi_range.min < _DEF_DPI )
|
||||
dev->dpi_range.min = _DEF_DPI;
|
||||
|
||||
/*
|
||||
* CHANGE: limit resolution to max. physical available one
|
||||
* Note: the resolution for the Asic 96001/3 models is limited to
|
||||
* the X-Resolution
|
||||
*/
|
||||
if((_ASIC_IS_96003 == dev->caps.AsicID) ||
|
||||
(_ASIC_IS_96001 == dev->caps.AsicID)) {
|
||||
dev->dpi_range.max = lens.rDpiX.wPhyMax;
|
||||
} else {
|
||||
dev->dpi_range.max = lens.rDpiY.wPhyMax;
|
||||
}
|
||||
|
||||
dev->dpi_range.max = lens.rDpiY.wPhyMax;
|
||||
dev->dpi_range.quant = 0;
|
||||
dev->x_range.min = 0;
|
||||
dev->x_range.max = SANE_FIX(dev->max_x);
|
||||
|
@ -695,12 +627,6 @@ static SANE_Status initGammaSettings( Plustek_Scanner *s )
|
|||
s->gamma_range.max = 255;
|
||||
s->gamma_range.quant = 0;
|
||||
|
||||
if((_ASIC_IS_96003 == s->hw->caps.AsicID) ||
|
||||
(_ASIC_IS_96001 == s->hw->caps.AsicID)) {
|
||||
|
||||
s->gamma_length = 256;
|
||||
}
|
||||
|
||||
DBG( _DBG_INFO, "Presetting Gamma tables (len=%u)\n", s->gamma_length );
|
||||
DBG( _DBG_INFO, "----------------------------------\n" );
|
||||
|
||||
|
@ -785,20 +711,8 @@ static SANE_Status init_options( Plustek_Scanner *s )
|
|||
s->opt[OPT_MODE].type = SANE_TYPE_STRING;
|
||||
s->opt[OPT_MODE].size = 32;
|
||||
s->opt[OPT_MODE].constraint_type = SANE_CONSTRAINT_STRING_LIST;
|
||||
|
||||
if( _ASIC_IS_USB == s->hw->caps.AsicID ) {
|
||||
s->opt[OPT_MODE].constraint.string_list = mode_usb_list;
|
||||
s->val[OPT_MODE].w = 3; /* Color */
|
||||
|
||||
} else {
|
||||
if((_ASIC_IS_98001 == s->hw->caps.AsicID) ||
|
||||
(_ASIC_IS_98003 == s->hw->caps.AsicID)) {
|
||||
s->opt[OPT_MODE].constraint.string_list = mode_9800x_list;
|
||||
} else {
|
||||
s->opt[OPT_MODE].constraint.string_list = mode_list;
|
||||
}
|
||||
s->val[OPT_MODE].w = 3; /* Color */
|
||||
}
|
||||
s->opt[OPT_MODE].constraint.string_list = mode_usb_list;
|
||||
s->val[OPT_MODE].w = 3; /* Color */
|
||||
|
||||
/* scan source */
|
||||
s->opt[OPT_EXT_MODE].name = SANE_NAME_SCAN_SOURCE;
|
||||
|
@ -993,17 +907,18 @@ static void decodeUsbIDs( char *src, char **dest )
|
|||
{
|
||||
const char *name;
|
||||
char *tmp = *dest;
|
||||
int len = strlen(_SECTION);
|
||||
|
||||
if( isspace(src[5])) {
|
||||
strncpy( tmp, &src[6], (strlen(src)-6));
|
||||
tmp[(strlen(src)-6)] = '\0';
|
||||
if( isspace(src[len])) {
|
||||
strncpy( tmp, &src[len+1], (strlen(src)-(len+1)));
|
||||
tmp[(strlen(src)-(len+1))] = '\0';
|
||||
}
|
||||
|
||||
name = tmp;
|
||||
name = sanei_config_skip_whitespace( name );
|
||||
|
||||
if( '\0' == name[0] ) {
|
||||
DBG( _DBG_SANE_INIT, "next device is a USB device (autodetection)\n" );
|
||||
DBG( _DBG_SANE_INIT, "next device uses autodetection\n" );
|
||||
} else {
|
||||
|
||||
u_short pi = 0, vi = 0;
|
||||
|
@ -1178,69 +1093,47 @@ static SANE_Status attach( const char *dev_name, pCnfDef cnf,
|
|||
dev->name = strdup(dev_name); /* hold it double to avoid */
|
||||
dev->sane.name = dev->name; /* compiler warnings */
|
||||
dev->sane.vendor = "Plustek";
|
||||
dev->initialized = SANE_FALSE;
|
||||
dev->initialized = -1; /* will be used as index too */
|
||||
dev->calFile = NULL;
|
||||
|
||||
memcpy( &dev->adj, &cnf->adj, sizeof(AdjDef));
|
||||
|
||||
show_cnf( cnf );
|
||||
|
||||
if( PARPORT == cnf->porttype ) {
|
||||
|
||||
dev->sane.type = "parallel port flatbed scanner";
|
||||
|
||||
dev->open = ppDev_open;
|
||||
dev->close = ppDev_close;
|
||||
dev->getCaps = ppDev_getCaps;
|
||||
dev->getLensInfo = ppDev_getLensInfo;
|
||||
dev->getCropInfo = ppDev_getCropInfo;
|
||||
dev->putImgInfo = ppDev_putImgInfo;
|
||||
dev->setScanEnv = ppDev_setScanEnv;
|
||||
dev->startScan = ppDev_startScan;
|
||||
dev->stopScan = ppDev_stopScan;
|
||||
dev->setMap = ppDev_setMap;
|
||||
dev->readImage = ppDev_readImage;
|
||||
dev->shutdown = NULL;
|
||||
dev->readLine = NULL;
|
||||
dev->prepare = NULL;
|
||||
|
||||
} else {
|
||||
|
||||
dev->sane.type = "USB flatbed scanner";
|
||||
dev->sane.type = "USB flatbed scanner";
|
||||
|
||||
#ifdef _PLUSTEK_USB
|
||||
dev->open = usbDev_open;
|
||||
dev->close = usbDev_close;
|
||||
dev->getCaps = usbDev_getCaps;
|
||||
dev->getLensInfo = usbDev_getLensInfo;
|
||||
dev->getCropInfo = usbDev_getCropInfo;
|
||||
dev->putImgInfo = NULL;
|
||||
dev->setScanEnv = usbDev_setScanEnv;
|
||||
dev->startScan = usbDev_startScan;
|
||||
dev->stopScan = usbDev_stopScan;
|
||||
dev->setMap = usbDev_setMap;
|
||||
dev->readImage = NULL;
|
||||
dev->readLine = usbDev_readLine;
|
||||
dev->prepare = usbDev_Prepare;
|
||||
dev->shutdown = usbDev_shutdown;
|
||||
dev->open = usbDev_open;
|
||||
dev->close = usbDev_close;
|
||||
dev->getCaps = usbDev_getCaps;
|
||||
dev->getLensInfo = usbDev_getLensInfo;
|
||||
dev->getCropInfo = usbDev_getCropInfo;
|
||||
dev->putImgInfo = NULL;
|
||||
dev->setScanEnv = usbDev_setScanEnv;
|
||||
dev->startScan = usbDev_startScan;
|
||||
dev->stopScan = usbDev_stopScan;
|
||||
dev->setMap = usbDev_setMap;
|
||||
dev->readImage = NULL;
|
||||
dev->readLine = usbDev_readLine;
|
||||
dev->prepare = usbDev_Prepare;
|
||||
dev->shutdown = usbDev_shutdown;
|
||||
|
||||
strncpy( dev->usbId, cnf->usbId, _MAX_ID_LEN );
|
||||
strncpy( dev->usbId, cnf->usbId, _MAX_ID_LEN );
|
||||
|
||||
if( cnf->adj.warmup >= 0 )
|
||||
dev->usbDev.dwWarmup = cnf->adj.warmup;
|
||||
if( cnf->adj.warmup >= 0 )
|
||||
dev->usbDev.dwWarmup = cnf->adj.warmup;
|
||||
|
||||
if( cnf->adj.lampOff >= 0 )
|
||||
dev->usbDev.dwLampOnPeriod = cnf->adj.lampOff;
|
||||
if( cnf->adj.lampOff >= 0 )
|
||||
dev->usbDev.dwLampOnPeriod = cnf->adj.lampOff;
|
||||
|
||||
if( cnf->adj.lampOffOnEnd >= 0 )
|
||||
dev->usbDev.bLampOffOnEnd = cnf->adj.lampOffOnEnd;
|
||||
if( cnf->adj.lampOffOnEnd >= 0 )
|
||||
dev->usbDev.bLampOffOnEnd = cnf->adj.lampOffOnEnd;
|
||||
#else
|
||||
free( dev->name );
|
||||
free( dev );
|
||||
DBG( _DBG_ERROR, "Portmode %u not supported\n", cnf->porttype );
|
||||
return SANE_STATUS_INVAL;
|
||||
free( dev->name );
|
||||
free( dev );
|
||||
DBG( _DBG_ERROR, "Backend non-functional on this platform :-(\n" );
|
||||
return SANE_STATUS_INVAL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* go ahead and open the scanner device
|
||||
|
@ -1277,28 +1170,16 @@ static SANE_Status attach( const char *dev_name, pCnfDef cnf,
|
|||
|
||||
/* save the info we got from the driver */
|
||||
DBG( _DBG_INFO, "Scanner information:\n" );
|
||||
if( dev->caps.Model == MODEL_OP_USB ) {
|
||||
|
||||
#ifdef _PLUSTEK_USB
|
||||
if( NULL != dev->usbDev.ModelStr )
|
||||
dev->sane.model = dev->usbDev.ModelStr;
|
||||
else
|
||||
#endif
|
||||
dev->sane.model = ModelStr[MODEL_OP_USB];
|
||||
|
||||
} else if( dev->caps.Model < MODEL_OP_USB ) {
|
||||
|
||||
dev->sane.model = ModelStr[dev->caps.Model];
|
||||
} else {
|
||||
|
||||
dev->sane.model = ModelStr[0];
|
||||
}
|
||||
if( NULL != dev->usbDev.ModelStr )
|
||||
dev->sane.model = dev->usbDev.ModelStr;
|
||||
else
|
||||
#endif
|
||||
dev->sane.model = "USB-Device";
|
||||
|
||||
DBG( _DBG_INFO, "Vendor : %s\n", dev->sane.vendor );
|
||||
DBG( _DBG_INFO, "Model : %s\n", dev->sane.model );
|
||||
DBG( _DBG_INFO, "Asic : 0x%02x\n", dev->caps.AsicID );
|
||||
DBG( _DBG_INFO, "Flags : 0x%08lx\n", dev->caps.dwFlag );
|
||||
DBG( _DBG_INFO, "Version: 0x%08x\n", dev->caps.Version );
|
||||
|
||||
dev->max_x = dev->caps.wMaxExtentX*MM_PER_INCH/_MEASURE_BASE;
|
||||
dev->max_y = dev->caps.wMaxExtentY*MM_PER_INCH/_MEASURE_BASE;
|
||||
|
@ -1433,7 +1314,11 @@ SANE_Status sane_init( SANE_Int *version_code, SANE_Auth_Callback authorize )
|
|||
decodeVal( str, "blue_gain", _INT, &config.adj.bgain, &ival);
|
||||
|
||||
ival = 0;
|
||||
decodeVal( str, "enableTPA", _INT, &config.adj.enableTpa, &ival);
|
||||
decodeVal( str, "enableTPA", _INT, &config.adj.enableTpa, &ival);
|
||||
decodeVal( str, "cacheCalData",
|
||||
_INT, &config.adj.cacheCalData,&ival);
|
||||
decodeVal( str, "altCalibrate",
|
||||
_INT, &config.adj.altCalibrate,&ival);
|
||||
decodeVal( str, "skipCalibration",
|
||||
_INT, &config.adj.skipCalibration,&ival);
|
||||
decodeVal( str, "skipFine",
|
||||
|
@ -1460,7 +1345,7 @@ SANE_Status sane_init( SANE_Int *version_code, SANE_Auth_Callback authorize )
|
|||
continue;
|
||||
|
||||
/* check for sections: */
|
||||
} else if( 0 == strncmp( str, "[usb]", 5)) {
|
||||
} else if( 0 == strncmp( str, _SECTION, strlen(_SECTION))) {
|
||||
|
||||
char *tmp;
|
||||
|
||||
|
@ -1474,21 +1359,9 @@ SANE_Status sane_init( SANE_Int *version_code, SANE_Auth_Callback authorize )
|
|||
tmp = config.usbId;
|
||||
decodeUsbIDs( str, &tmp );
|
||||
|
||||
config.porttype = USB;
|
||||
DBG( _DBG_SANE_INIT, "next device is an USB device\n" );
|
||||
continue;
|
||||
|
||||
} else if(( 0 == strncmp( str, "[parport]", 10))&&( '\0' == str[10])) {
|
||||
|
||||
/* new section, try and attach previous device */
|
||||
if( config.devName[0] != '\0' )
|
||||
attach( config.devName, &config, 0 );
|
||||
|
||||
/* re-initialize the configuration structure */
|
||||
init_config_struct( &config, SANE_FALSE );
|
||||
DBG( _DBG_SANE_INIT, "next device is a PARPORT device\n" );
|
||||
continue;
|
||||
|
||||
} else if( SANE_TRUE == decodeDevName( str, config.devName )) {
|
||||
continue;
|
||||
}
|
||||
|
@ -1527,6 +1400,9 @@ void sane_exit( void )
|
|||
*/
|
||||
if( dev->sane.name )
|
||||
free( dev->name );
|
||||
|
||||
if( dev->calFile )
|
||||
free( dev->calFile );
|
||||
|
||||
if( dev->res_list )
|
||||
free( dev->res_list );
|
||||
|
@ -1538,9 +1414,6 @@ void sane_exit( void )
|
|||
if( devlist )
|
||||
free( devlist );
|
||||
|
||||
/* call driver specific shutdown function... */
|
||||
_DOWN();
|
||||
|
||||
devlist = NULL;
|
||||
auth = NULL;
|
||||
first_dev = NULL;
|
||||
|
@ -1596,16 +1469,9 @@ SANE_Status sane_open( SANE_String_Const devicename, SANE_Handle* handle )
|
|||
|
||||
memset( &config, 0, sizeof(CnfDef));
|
||||
|
||||
/* check if a valid parport-device is meant... */
|
||||
status = attach( devicename, &config, &dev );
|
||||
if( SANE_STATUS_GOOD != status ) {
|
||||
|
||||
/* check if a valid usb-device is meant... */
|
||||
config.porttype = USB;
|
||||
status = attach( devicename, &config, &dev );
|
||||
if( SANE_STATUS_GOOD != status )
|
||||
return status;
|
||||
}
|
||||
if( SANE_STATUS_GOOD != status )
|
||||
return status;
|
||||
}
|
||||
} else {
|
||||
/* empty devicename -> use first device */
|
||||
|
@ -1851,17 +1717,9 @@ SANE_Status sane_control_option( SANE_Handle handle, SANE_Int option,
|
|||
|
||||
case OPT_MODE: {
|
||||
|
||||
int idx = (optval - mode_list);
|
||||
int idx = (optval - mode_usb_list);
|
||||
|
||||
if((_ASIC_IS_98001 == s->hw->caps.AsicID) ||
|
||||
(_ASIC_IS_98003 == s->hw->caps.AsicID)) {
|
||||
idx = optval - mode_9800x_list;
|
||||
} else if( _ASIC_IS_USB == s->hw->caps.AsicID ) {
|
||||
idx = optval - mode_usb_list;
|
||||
}
|
||||
|
||||
mp = getModeList( s );
|
||||
|
||||
mp = getModeList( s );
|
||||
if( mp[idx].scanmode != COLOR_HALFTONE ){
|
||||
s->opt[OPT_HALFTONE].cap |= SANE_CAP_INACTIVE;
|
||||
s->opt[OPT_CONTRAST].cap &= ~SANE_CAP_INACTIVE;
|
||||
|
@ -1922,15 +1780,8 @@ SANE_Status sane_control_option( SANE_Handle handle, SANE_Int option,
|
|||
s->val[OPT_BR_Y].w = SANE_FIX(_DEFAULT_BRY);
|
||||
s->val[OPT_MODE].w = 3; /* COLOR_TRUE24 */
|
||||
|
||||
if((_ASIC_IS_98001 == s->hw->caps.AsicID) ||
|
||||
(_ASIC_IS_98003 == s->hw->caps.AsicID)) {
|
||||
s->opt[OPT_MODE].constraint.string_list = mode_9800x_list;
|
||||
} else if( _ASIC_IS_USB == s->hw->caps.AsicID ) {
|
||||
s->opt[OPT_MODE].constraint.string_list = mode_usb_list;
|
||||
s->val[OPT_MODE].w = 3; /* COLOR_TRUE24 */
|
||||
} else {
|
||||
s->opt[OPT_MODE].constraint.string_list = mode_list;
|
||||
}
|
||||
s->opt[OPT_MODE].constraint.string_list = mode_usb_list;
|
||||
s->val[OPT_MODE].w = 3; /* COLOR_TRUE24 */
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -1955,12 +1806,8 @@ SANE_Status sane_control_option( SANE_Handle handle, SANE_Int option,
|
|||
|
||||
if( s->hw->caps.dwFlag & SFLAG_TPA ) {
|
||||
|
||||
if( _ASIC_IS_USB == s->hw->caps.AsicID )
|
||||
s->opt[OPT_MODE].constraint.string_list =
|
||||
s->opt[OPT_MODE].constraint.string_list =
|
||||
&mode_usb_list[_TPAModeSupportMin];
|
||||
else
|
||||
s->opt[OPT_MODE].constraint.string_list =
|
||||
&mode_9800x_list[_TPAModeSupportMin];
|
||||
} else {
|
||||
s->opt[OPT_MODE].constraint.string_list =
|
||||
&mode_list[_TPAModeSupportMin];
|
||||
|
@ -2230,11 +2077,9 @@ SANE_Status sane_start( SANE_Handle handle )
|
|||
/* build a SCANINFO block and get ready to scan it */
|
||||
sinfo.ImgDef.dwFlag |= (SCANDEF_BuildBwMap | SCANDEF_QualityScan);
|
||||
|
||||
/* remove that for preview scans (USB only) */
|
||||
if( _ASIC_IS_USB == s->hw->caps.AsicID ) {
|
||||
if( s->val[OPT_PREVIEW].w )
|
||||
sinfo.ImgDef.dwFlag &= (~SCANDEF_QualityScan);
|
||||
}
|
||||
/* remove that for preview scans */
|
||||
if( s->val[OPT_PREVIEW].w )
|
||||
sinfo.ImgDef.dwFlag &= (~SCANDEF_QualityScan);
|
||||
|
||||
/* set adjustments for brightness and contrast */
|
||||
sinfo.siBrightness = s->val[OPT_BRIGHTNESS].w;
|
||||
|
|
|
@ -1,27 +1,12 @@
|
|||
# Plustek-SANE Backend configuration file
|
||||
# For use with Plustek parallel-port scanners and
|
||||
# LM9831/2/3 based USB scanners
|
||||
# For use with LM9831/2/3 based USB scanners
|
||||
#
|
||||
# For parport devices use the parport section
|
||||
#
|
||||
[parport]
|
||||
device /dev/pt_drv
|
||||
|
||||
#
|
||||
# leave the default values as specified in /etc/modules.conf
|
||||
#
|
||||
option warmup -1
|
||||
option lOffOnEnd -1
|
||||
option lampOff -1
|
||||
|
||||
|
||||
#
|
||||
# The USB section:
|
||||
# each device needs at least two lines:
|
||||
# - [usb] vendor-ID and product-ID
|
||||
# - [merlin-device] vendor-ID and product-ID
|
||||
# - device devicename
|
||||
# i.e. for Plustek (0x07B3) UT12/16/24 (0x0017)
|
||||
# [usb] 0x07B3 0x0017
|
||||
# [merlin-device] 0x07B3 0x0017
|
||||
# device /dev/usbscanner
|
||||
# or
|
||||
# device libusb:bbb:ddd
|
||||
|
@ -32,15 +17,15 @@ option lampOff -1
|
|||
# warmup, lOffOnEnd, lampOff
|
||||
#
|
||||
# For autodetection use
|
||||
# [usb]
|
||||
# [merlin-device]
|
||||
# device /dev/usbscanner
|
||||
#
|
||||
# or simply
|
||||
# [usb]
|
||||
# [merlin-device]
|
||||
#
|
||||
# or if you want a specific device but you have no idea about
|
||||
# the device node or you use libusb, simply set vendor- and product-ID
|
||||
# [usb] 0x07B3 0x0017
|
||||
# [merlin-device] 0x07B3 0x0017
|
||||
# device auto
|
||||
#
|
||||
# NOTE: autodetection is safe, as it uses the info it got
|
||||
|
@ -49,7 +34,7 @@ option lampOff -1
|
|||
# at your USB-port, that you have specified...
|
||||
#
|
||||
|
||||
[usb]
|
||||
[merlin-device]
|
||||
|
||||
#
|
||||
# options for the previous USB entry
|
||||
|
@ -95,6 +80,16 @@ option negShadingY -1
|
|||
#
|
||||
option invertNegatives 0
|
||||
|
||||
#
|
||||
# to save/restore coarse calibration data
|
||||
#
|
||||
option cacheCalData 0
|
||||
|
||||
#
|
||||
# use alternate calibration routines
|
||||
#
|
||||
option altCalibration 0
|
||||
|
||||
# for skipping whole calibration step
|
||||
option skipCalibration 0
|
||||
|
||||
|
@ -134,5 +129,5 @@ device auto
|
|||
|
||||
#
|
||||
# to define a new device, start with a new section:
|
||||
# [usb] or [parport]
|
||||
# [merlin-device]
|
||||
#
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
* - 0.43 - no changes
|
||||
* - 0.44 - added flag initialized
|
||||
* - 0.45 - added readLine function
|
||||
* - 0.46 - flag initialized is now used as device index
|
||||
* - added calFile to Plustek_Device
|
||||
* .
|
||||
* <hr>
|
||||
* This file is part of the SANE package.
|
||||
|
@ -159,12 +161,50 @@ typedef enum {
|
|||
NUM_PORTTYPES
|
||||
} PORTTYPE;
|
||||
|
||||
/** for adjusting the scanner settings
|
||||
*/
|
||||
typedef struct {
|
||||
int lampOff;
|
||||
int lampOffOnEnd;
|
||||
int warmup;
|
||||
int enableTpa;
|
||||
int skipCalibration;
|
||||
int skipFine;
|
||||
int skipFineWhite;
|
||||
int invertNegatives;
|
||||
int cacheCalData;
|
||||
int altCalibrate; /* force use of the alternate canoscan
|
||||
autocal; perhaps other Canon
|
||||
scanners require the alternate
|
||||
autocalibration as well */
|
||||
int rgain;
|
||||
int ggain;
|
||||
int bgain;
|
||||
|
||||
OffsDef pos; /* for adjusting normal scan area */
|
||||
OffsDef tpa; /* for adjusting transparency scan area */
|
||||
OffsDef neg; /* for adjusting negative scan area */
|
||||
|
||||
int posShadingY;
|
||||
int tpaShadingY;
|
||||
int negShadingY;
|
||||
|
||||
/* for adjusting the default gamma settings */
|
||||
double rgamma;
|
||||
double ggamma;
|
||||
double bgamma;
|
||||
|
||||
double graygamma;
|
||||
|
||||
} AdjDef, *pAdjDef;
|
||||
|
||||
typedef struct Plustek_Device
|
||||
{
|
||||
SANE_Bool initialized; /* device already initialized? */
|
||||
SANE_Int initialized; /* device already initialized? */
|
||||
struct Plustek_Device *next; /* pointer to next dev in list */
|
||||
int fd; /* device handle */
|
||||
char *name; /* (to avoid compiler warnings!)*/
|
||||
char *calFile; /* for saving calibration data */
|
||||
SANE_Device sane; /* info struct */
|
||||
SANE_Int max_x; /* max XY-extension of the scan-*/
|
||||
SANE_Int max_y; /* area */
|
||||
|
@ -185,7 +225,6 @@ typedef struct Plustek_Device
|
|||
DeviceDef usbDev;
|
||||
struct itimerval saveSettings; /* for lamp timer */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* each device we support may need other access functions...
|
||||
*/
|
||||
|
@ -208,6 +247,16 @@ typedef struct Plustek_Device
|
|||
|
||||
} Plustek_Device, *pPlustek_Device;
|
||||
|
||||
#ifndef SANE_OPTION
|
||||
/* for compatibility with older versions */
|
||||
typedef union
|
||||
{
|
||||
SANE_Word w;
|
||||
SANE_Word *wa; /* word array */
|
||||
SANE_String s;
|
||||
} Option_Value;
|
||||
#endif
|
||||
|
||||
typedef struct Plustek_Scanner
|
||||
{
|
||||
struct Plustek_Scanner *next;
|
||||
|
@ -232,20 +281,11 @@ typedef struct Plustek_Scanner
|
|||
} Plustek_Scanner, *pPlustek_Scanner;
|
||||
|
||||
|
||||
typedef const struct mode_param {
|
||||
int color;
|
||||
int depth;
|
||||
int scanmode;
|
||||
} ModeParam, *pModeParam;
|
||||
|
||||
|
||||
/*
|
||||
* for collecting configuration info...
|
||||
/** for collecting configuration info...
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
char devName[PATH_MAX];
|
||||
PORTTYPE porttype;
|
||||
char usbId[_MAX_ID_LEN];
|
||||
|
||||
/* contains the stuff to adjust... */
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,33 @@
|
|||
# Plustek-PP SANE Backend configuration file
|
||||
# For use with Plustek parallel-port scanners
|
||||
#
|
||||
|
||||
#
|
||||
# user either [direct] or [kernel] to access the scanner
|
||||
# when using [kernel], device specifies the device-node, which is created
|
||||
# by the kernel-modules loader
|
||||
# when using [direct], device is used to set the parallel-port base address
|
||||
#
|
||||
[direct]
|
||||
device 0x378
|
||||
|
||||
#
|
||||
# leave the default values as specified in /etc/modules.conf
|
||||
#
|
||||
option warmup -1
|
||||
option lOffOnEnd -1
|
||||
option lampOff -1
|
||||
|
||||
# model override switch, mostly for cosmetic changes, if the autodetection
|
||||
# does not work or could not work correctly
|
||||
#option mov 7
|
||||
|
||||
#
|
||||
# example for accessing the scanner via the kernel module
|
||||
#
|
||||
[kernel]
|
||||
device /dev/pt_drv
|
||||
|
||||
option warmup -1
|
||||
option lOffOnEnd -1
|
||||
option lampOff -1
|
|
@ -269,7 +269,7 @@ else
|
|||
BACKENDS="abaton agfafocus apple artec as6e avision bh canon \
|
||||
canon630u coolscan coolscan2 dc25 dmc \
|
||||
epson fujitsu gt68xx hp leo matsushita microtek \
|
||||
microtek2 mustek mustek_pp mustek_usb nec pie plustek \
|
||||
microtek2 mustek mustek_pp mustek_usb nec pie plustek plustek_pp \
|
||||
ricoh s9036 sceptre sharp \
|
||||
sp15c st400 tamarack test teco1 teco2 teco3 umax umax_pp umax1220u \
|
||||
artec_eplus48u ma1509 ibm hp5400"
|
||||
|
|
|
@ -51,7 +51,7 @@ SECT5 = sane-abaton.5 sane-agfafocus.5 sane-apple.5 sane-as6e.5 sane-dll.5 \
|
|||
sane-mustek_usb.5 sane-sceptre.5 sane-canon_pp.5 sane-canon630u.5 \
|
||||
sane-teco1.5 sane-teco2.5 sane-teco3.5 sane-test.5 sane-sp15c.5 \
|
||||
sane-coolscan2.5 sane-hpsj5s.5 sane-gt68xx.5 sane-artec_eplus48u.5 \
|
||||
sane-ma1509.5 sane-ibm.5 sane-hp5400.5
|
||||
sane-ma1509.5 sane-ibm.5 sane-hp5400.5 sane-plustek_pp.5
|
||||
SECT7 = sane.7
|
||||
MANPAGES = $(SECT1) $(SECT5) $(SECT7)
|
||||
READMES = README AUTHORS COPYING ChangeLog LICENSE NEWS PROBLEMS \
|
||||
|
@ -102,7 +102,7 @@ DISTFILES = Makefile.in backend-writing.txt descriptions.txt \
|
|||
sane.tex saned.man scanimage.man sane-sceptre.man sane-canon_pp.man \
|
||||
sane-teco1.man sane-teco2.man sane-teco3.man sane-test.man sane-sp15c.man \
|
||||
sane-hpsj5s.man gamma4scanimage.man sane-gt68xx.man sane-artec_eplus48u.man \
|
||||
sane-ma1509.man sane-ibm.man sane-hp5400.man
|
||||
sane-ma1509.man sane-ibm.man sane-hp5400.man sane-plustek_pp.man
|
||||
|
||||
.PHONY: all clean depend dist distclean html html-man install \
|
||||
install-mostang sane-html uninstall
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
;
|
||||
; SANE Backend description file for Plustek backend
|
||||
; SANE Backend description file for Plustek backend (USB only)
|
||||
;
|
||||
|
||||
:backend "plustek"
|
||||
:version "0.45"
|
||||
:version "0.46"
|
||||
:manpage "sane-plustek"
|
||||
; backend's web page
|
||||
:url "http://www.gjaeger.de/scanner/plustek.html"
|
||||
|
@ -17,79 +17,6 @@
|
|||
:url "http://www.plustek.com/"
|
||||
|
||||
;name models for above-specified mfg.
|
||||
:model "OpticPro 4800P"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
:model "OpticPro 4830P"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
:model "OpticPro 600P/6000P"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
:model "OpticPro 4831P"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
:model "OpticPro 9630P"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
:model "OpticPro 9630PL"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
:comment "use driver-switch mov=1"
|
||||
|
||||
:model "OpticPro 9600P"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
:model "OpticPro 1236P"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
:comment "reported as OpticPro 12000P/96000P"
|
||||
|
||||
:model "OpticPro 12000P/96000P"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
:model "OpticPro 9636P"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
:comment "use driver-switch mov=4"
|
||||
|
||||
:model "OpticPro 9636P+/Turbo"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
:comment "use driver-switch mov=3"
|
||||
|
||||
:model "OpticPro 9636T"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
:model "OpticPro 12000T"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
:model "OpticPro AI3"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :basic
|
||||
:comment "use driver-switch mov=5, poor picture quality"
|
||||
|
||||
:model "OpticPro P8"
|
||||
:interface "Parport"
|
||||
:status :untested
|
||||
|
||||
:model "OpticPro P12"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
:model "OpticPro PT12"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
:model "OpticPro U12"
|
||||
:interface "USB"
|
||||
:status :complete
|
||||
|
@ -119,51 +46,11 @@
|
|||
:status :unsupported
|
||||
:comment "rebadged Artec AM12S (supported by Artec Backend)"
|
||||
|
||||
;* Primax ***********************************************************************************
|
||||
|
||||
:mfg "Primax" ; name of manufacturer
|
||||
:url "http://www.primax.nl/"
|
||||
|
||||
;name models for above-specified mfg.
|
||||
:model "Colorado 4800"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :untested
|
||||
:comment "same as OpticPro 4800P"
|
||||
|
||||
:model "Compact 4800 Direct"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
:comment "use driver-switch mov=2"
|
||||
|
||||
:model "Compact 4800 Direct-30"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :untested
|
||||
:comment "same as OpticPro 4830P"
|
||||
|
||||
:model "Compact 9600 Direct-30"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
:comment "same as OpticPro 9630P"
|
||||
|
||||
;* Genius/KYE *******************************************************************************************
|
||||
|
||||
:mfg "Genius"
|
||||
:url "http://www.geniusnet.com.tw/"
|
||||
|
||||
:model "Colorpage Vivid III V2"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
:comment "Reported as PT12"
|
||||
|
||||
:model "Colorpage Vivid Pro II Film"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
:comment "Reported as OP9636T/12000T"
|
||||
|
||||
:model "Colorpage HR6X EPP"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :untested
|
||||
|
||||
:model "Colorpage HR6 V2"
|
||||
:interface "USB"
|
||||
:status :complete
|
||||
|
@ -184,24 +71,6 @@
|
|||
:interface "USB"
|
||||
:status :untested
|
||||
|
||||
;********************************************************************************************
|
||||
|
||||
:mfg "Aries"
|
||||
|
||||
:model "Scan-It Pro 4800"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
:comment "use driver-switch mov=2"
|
||||
|
||||
;********************************************************************************************
|
||||
|
||||
:mfg "BrightScan"
|
||||
|
||||
:model "BrighScan OpticPro"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
:comment "Reported as P12"
|
||||
|
||||
;* MUSTEK ***********************************************************************************
|
||||
|
||||
:mfg "Mustek"
|
||||
|
@ -286,30 +155,25 @@
|
|||
|
||||
:model "CanoScan N650U/N656U"
|
||||
:interface "USB"
|
||||
:status :basic
|
||||
:status :complete
|
||||
|
||||
:model "CanoScan N1220U"
|
||||
:interface "USB"
|
||||
:status :basic
|
||||
:comment "Poor color picture quality"
|
||||
:status :complete
|
||||
|
||||
:model "CanoScan N670U/N676U"
|
||||
:interface "USB"
|
||||
:status :basic
|
||||
:comment "Poor color picture quality"
|
||||
:status :complete
|
||||
|
||||
:model "CanoScan N1240U"
|
||||
:interface "USB"
|
||||
:status :basic
|
||||
:comment "Poor color picture quality"
|
||||
:status :complete
|
||||
|
||||
:model "CanoScan LiDE20"
|
||||
:interface "USB"
|
||||
:status :basic
|
||||
:comment "Poor color picture quality"
|
||||
:status :complete
|
||||
|
||||
:model "CanoScan LiDE30"
|
||||
:interface "USB"
|
||||
:status :basic
|
||||
:comment "Poor color picture quality"
|
||||
:status :complete
|
||||
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
;
|
||||
; SANE Backend description file for Plustek_pp backend
|
||||
;
|
||||
|
||||
:backend "plustek_pp"
|
||||
:version "0.01"
|
||||
:manpage "sane-plustek_pp"
|
||||
; backend's web page
|
||||
:url "http://www.gjaeger.de/scanner/plustek.html"
|
||||
|
||||
:devicetype :scanner
|
||||
|
||||
;* Plustek **********************************************************************************
|
||||
|
||||
:mfg "Plustek"
|
||||
:url "http://www.plustek.de/"
|
||||
:url "http://www.plustek.com/"
|
||||
|
||||
;name models for above-specified mfg.
|
||||
:model "OpticPro 4800P"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
:model "OpticPro 4830P"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
:model "OpticPro 600P/6000P"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
:model "OpticPro 4831P"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
:model "OpticPro 9630P"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
:model "OpticPro 9630PL"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
:comment "use driver-switch mov=1"
|
||||
|
||||
:model "OpticPro 9600P"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
:model "OpticPro 1236P"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
:comment "reported as OpticPro 12000P/96000P"
|
||||
|
||||
:model "OpticPro 12000P/96000P"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
:model "OpticPro 9636P"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
:comment "use driver-switch mov=4"
|
||||
|
||||
:model "OpticPro 9636P+/Turbo"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
:comment "use driver-switch mov=3"
|
||||
|
||||
:model "OpticPro 9636T"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
:model "OpticPro 12000T"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
:model "OpticPro AI3"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :basic
|
||||
:comment "use driver-switch mov=5, poor picture quality"
|
||||
|
||||
:model "OpticPro P8"
|
||||
:interface "Parport"
|
||||
:status :untested
|
||||
|
||||
:model "OpticPro P12"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
:model "OpticPro PT12"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
|
||||
;* Primax ***********************************************************************************
|
||||
|
||||
:mfg "Primax" ; name of manufacturer
|
||||
:url "http://www.primax.nl/"
|
||||
|
||||
;name models for above-specified mfg.
|
||||
:model "Colorado 4800"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :untested
|
||||
:comment "same as OpticPro 4800P"
|
||||
|
||||
:model "Compact 4800 Direct"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
:comment "use driver-switch mov=2"
|
||||
|
||||
:model "Compact 4800 Direct-30"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :untested
|
||||
:comment "same as OpticPro 4830P, use driver-switch mov=7"
|
||||
|
||||
:model "Compact 9600 Direct-30"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
:comment "same as OpticPro 9630P"
|
||||
|
||||
;* Genius/KYE *******************************************************************************************
|
||||
|
||||
:mfg "Genius"
|
||||
:url "http://www.geniusnet.com.tw/"
|
||||
|
||||
:model "Colorpage Vivid III V2"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
:comment "Reported as PT12"
|
||||
|
||||
:model "Colorpage Vivid Pro II Film"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
:comment "Reported as OP9636T/12000T"
|
||||
|
||||
:model "Colorpage HR6X EPP"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :untested
|
||||
|
||||
;********************************************************************************************
|
||||
|
||||
:mfg "Aries"
|
||||
|
||||
:model "Scan-It Pro 4800"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
:comment "use driver-switch mov=2"
|
||||
|
||||
;********************************************************************************************
|
||||
|
||||
:mfg "BrightScan"
|
||||
|
||||
:model "BrighScan OpticPro"
|
||||
:interface "Parport (SPP, EPP)"
|
||||
:status :complete
|
||||
:comment "Reported as P12"
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
.TH sane-plustek 5 "30 May 2003" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
|
||||
.TH sane-plustek 5 "17 September 2003" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
|
||||
.IX sane-plustek
|
||||
.SH NAME
|
||||
sane-plustek \- SANE backend for Plustek parallel port and
|
||||
|
@ -76,7 +76,7 @@ Colorado 4800 OpticPro 4800 not tested
|
|||
.br
|
||||
Compact 4800 Direct OpticPro 600 mov=2
|
||||
.br
|
||||
Compact 4800 Direct 30bit OpticPro 4830 not tested
|
||||
Compact 4800 Direct 30bit OpticPro 4830 mov=7
|
||||
.br
|
||||
Compact 9600 Direct 30bit OpticPro 9630 works
|
||||
.PP
|
||||
|
@ -268,7 +268,15 @@ backend.
|
|||
.br
|
||||
Only the National Semiconductor LM9831/2 based devices of Plustek
|
||||
are supported by this driver. Older versions of the U12, the UT12,
|
||||
the U1212 and U1248 (GrandTech chipset are not supported)
|
||||
the U1212 and U1248 (GrandTech chipset) are not supported.
|
||||
.PP
|
||||
Model Chipset backend
|
||||
.br
|
||||
---------------------------
|
||||
.br
|
||||
U1248 GrandTech gt68xx
|
||||
.br
|
||||
UT16B GrandTech gt68xx
|
||||
.PP
|
||||
|
||||
.SH "DEVICE NAMES"
|
||||
|
@ -433,6 +441,11 @@ mov=m
|
|||
.br
|
||||
has been detected) swaps red/green color
|
||||
.br
|
||||
.I m
|
||||
=7 - Primax 4800Direct 30bit override (works if OP4830
|
||||
.br
|
||||
has been detected)
|
||||
.br
|
||||
.RE
|
||||
.PP
|
||||
Sample entry for file
|
||||
|
|
|
@ -0,0 +1,753 @@
|
|||
.TH sane-plustek 5 "17 September 2003" "@PACKAGEVERSION@" "SANE Scanner Access Now Easy"
|
||||
.IX sane-plustek
|
||||
.SH NAME
|
||||
sane-plustek \- SANE backend for Plustek parallel port and
|
||||
LM983[1/2/3] based USB flatbed scanners
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.B sane-plustek
|
||||
library implements a SANE (Scanner Access Now Easy) backend that
|
||||
provides access to Plustek parallel port and USB flatbed scanners.
|
||||
The USB support is part of the SANE package but for usage with
|
||||
parallel port scanners you will need a kernel module, called
|
||||
pt_drv which currently can be downloaded from
|
||||
.br
|
||||
.B http://www.gjaeger.de/scanner/plustek.html
|
||||
.PP
|
||||
.B !!!Please note that you need the kernel module only for
|
||||
.B parallel port scanners!!!
|
||||
|
||||
.SH "PARALLEL PORT SUPPORT"
|
||||
|
||||
At present, the following scanners should work with this backend
|
||||
and the corresponding kernel module:
|
||||
.PP
|
||||
.B "PLUSTEK SCANNERS"
|
||||
.PP
|
||||
Parallelport Model: ASIC: Properties:
|
||||
.br
|
||||
---------------------- ----- ------------------------
|
||||
.br
|
||||
OpticPro PT12 98003 600x1200 dpi 36bit 512Kb
|
||||
.br
|
||||
OpticPro P12 98003 600x1200 dpi 36bit 512Kb
|
||||
.br
|
||||
OpticPro 9636T/12000T 98001 600x1200 dpi 36bit 512Kb
|
||||
.br
|
||||
OpticPro 12000P Turbo 98001 600x1200 dpi 36bit 512Kb
|
||||
.br
|
||||
OpticPro 9636P+/Turbo 98001 600x1200 dpi 36bit 512Kb
|
||||
.br
|
||||
OpticPro 9636P 96003 600x1200 dpi 36bit 128Kb
|
||||
.br
|
||||
OpticPro 12000P/96000P 96003 600x1200 dpi 36bit 128Kb
|
||||
.br
|
||||
OpticPro 1236P 96003 600x1200 dpi 30bit 128Kb
|
||||
.br
|
||||
OpticPro 9600P 96003 600x1200 dpi 30bit 128Kb
|
||||
.br
|
||||
OpticPro 9630P/FBIV 96003 600x1200 dpi 30bit 128Kb
|
||||
.br
|
||||
OpticPro 9630PL (14") 96003 600x1200 dpi 30bit 128Kb
|
||||
.br
|
||||
OpticPro A3I 96003 400x800 dpi 36bit 128Kb
|
||||
.br
|
||||
OpticPro 600P/6000P 96003 300x600 dpi 30bit 32Kb
|
||||
.br
|
||||
OpticPro 4831P 96003 300x600 dpi 30bit 32Kb
|
||||
.br
|
||||
OpticPro 4830P/FBIII 96003 300x600 dpi 30bit 32Kb
|
||||
.br
|
||||
OpticPro 4800P/FBII 96001 300x600 dpi 24bit 32Kb
|
||||
.br
|
||||
.PP
|
||||
|
||||
.B "PRIMAX SCANNERS"
|
||||
|
||||
There are some scanners sold by Primax, but they are in fact
|
||||
Plustek devices. These scanners are also supported.
|
||||
The following table will show the relationship:
|
||||
.PP
|
||||
Model: Plustek Model: Remarks:
|
||||
.br
|
||||
--------------------------- -------------- ------------
|
||||
.br
|
||||
Colorado 4800 OpticPro 4800 not tested
|
||||
.br
|
||||
Compact 4800 Direct OpticPro 600 mov=2
|
||||
.br
|
||||
Compact 4800 Direct 30bit OpticPro 4830 mov=7
|
||||
.br
|
||||
Compact 9600 Direct 30bit OpticPro 9630 works
|
||||
.PP
|
||||
|
||||
.B "GENIUS SCANNERS"
|
||||
|
||||
The following devices are sold as Genius Scanners, but are in fact
|
||||
Plustek devices.
|
||||
The table will show the relationship:
|
||||
.PP
|
||||
Model: Remarks:
|
||||
.br
|
||||
--------------------------- ----------------------------
|
||||
.br
|
||||
Colorpage Vivid III V2 Like P12 but has two buttons
|
||||
.br
|
||||
and Wolfson DAC
|
||||
.PP
|
||||
|
||||
.B "ARIES SCANNERS"
|
||||
|
||||
There's one scanner sold as Aries Scanner, but is in fact a
|
||||
Plustek device.
|
||||
The following table will show the relationship:
|
||||
.PP
|
||||
Model: Plustek Model: Remarks:
|
||||
.br
|
||||
--------------------------- -------------- ------------
|
||||
.br
|
||||
Scan-It 4800 OpticPro 600 mov=2
|
||||
.PP
|
||||
|
||||
.B "BrightScan SCANNERS"
|
||||
|
||||
There's one scanner sold as BrightScan OpticPro Scanner, this is also
|
||||
rebadged Plustek device.
|
||||
The following table will show the relationship:
|
||||
.PP
|
||||
Model: Remarks:
|
||||
.br
|
||||
--------------------------- ----------------------------
|
||||
.br
|
||||
BrightScan OpticPro OpticPro P12
|
||||
|
||||
.SH "USB SUPPORT"
|
||||
|
||||
The Backend is able to support USB scanner based on the National
|
||||
Semiconductor chipset LM9831, LM9832 and LM9833. The following tables
|
||||
show various devices which are currently reported to work. If your
|
||||
Plustek scanner has another Product ID, then the device is
|
||||
.B NOT
|
||||
supported, as it contains unsupported ASICs inside.
|
||||
.br
|
||||
|
||||
Vendor Plustek - ID: 0x07B3
|
||||
.br
|
||||
----------------------------------------------------------
|
||||
.br
|
||||
USB Model: ASIC: Properties: Prod-ID
|
||||
.br
|
||||
----------------------------------------------------------
|
||||
.br
|
||||
OpticPro U12 LM9831 600x1200dpi 42bit 512Kb 0x0010
|
||||
.br
|
||||
OpticPro UT12 LM9831 600x1200dpi 42bit 512Kb 0x0013
|
||||
.br
|
||||
OpticPro UT12 LM9832 600x1200dpi 42bit 512Kb 0x0017
|
||||
.br
|
||||
OpticPro UT16 LM9832 600x1200dpi 42bit 512Kb 0x0017
|
||||
.br
|
||||
OpticPro U24 LM9831 1200x2400dpi 42bit 2Mb 0x0011
|
||||
.br
|
||||
OpticPro U24 LM9832 1200x2400dpi 42bit 2Mb 0x0015
|
||||
.br
|
||||
OpticPro UT24 LM9832 1200x2400dpi 42bit 2Mb 0x0017
|
||||
.PP
|
||||
|
||||
Vendor KYE/Genius - ID: 0x0458
|
||||
.br
|
||||
----------------------------------------------------------
|
||||
.br
|
||||
USB Model: ASIC: Properties: Prod-ID
|
||||
.br
|
||||
----------------------------------------------------------
|
||||
.br
|
||||
Colorpage HR6 V2 LM9832 600x1200dpi 42bit 512Kb 0x2007
|
||||
.br
|
||||
Colorpage HR6 V2 LM9832 600x1200dpi 42bit 512Kb 0x2008
|
||||
.br
|
||||
Colorpage HR6A LM9832 600x1200dpi 42bit 512Kb 0x2009
|
||||
.br
|
||||
Colorpage HR7 LM9832 600x1200dpi 42bit 512Kb 0x2013
|
||||
.br
|
||||
Colorpage HR7LE LM9832 600x1200dpi 42bit 512Kb 0x2015
|
||||
.br
|
||||
Colorpage HR6X LM9832 600x1200dpi 42bit 512Kb 0x2016
|
||||
.PP
|
||||
|
||||
Vendor Hewlett-Packard - ID: 0x03F0
|
||||
.br
|
||||
----------------------------------------------------------
|
||||
.br
|
||||
USB Model: ASIC: Properties: Prod-ID
|
||||
.br
|
||||
----------------------------------------------------------
|
||||
.br
|
||||
ScanJet 2100C LM9831 600x1200dpi 42bit 512Kb 0x0505
|
||||
.br
|
||||
ScanJet 2200C LM9832 600x1200dpi 42bit 512Kb 0x0605
|
||||
.PP
|
||||
|
||||
Vendor Mustek - ID: 0x0400
|
||||
.br
|
||||
----------------------------------------------------------
|
||||
.br
|
||||
USB Model: ASIC: Properties: Prod-ID
|
||||
.br
|
||||
----------------------------------------------------------
|
||||
.br
|
||||
BearPaw 1200 LM9831 600x1200dpi 42bit 512Kb 0x1000
|
||||
.br
|
||||
BearPaw 2400 LM9832 1200x2400dpi 42bit 2Mb 0x1001
|
||||
.PP
|
||||
|
||||
Vendor UMAX - ID: 0x1606
|
||||
.br
|
||||
----------------------------------------------------------
|
||||
.br
|
||||
USB Model: ASIC: Properties: Prod-ID
|
||||
.br
|
||||
----------------------------------------------------------
|
||||
.br
|
||||
UMAX 3400/3450 LM9832 600x1200dpi 42bit 512Kb 0x0060
|
||||
.br
|
||||
UMAX 5400 LM9832 1200x2400dpi 42bit 512Kb 0x0160
|
||||
.PP
|
||||
|
||||
Vendor COMPAQ - ID: 0x049F
|
||||
.br
|
||||
----------------------------------------------------------
|
||||
.br
|
||||
USB Model: ASIC: Properties: Prod-ID
|
||||
.br
|
||||
----------------------------------------------------------
|
||||
.br
|
||||
S4-100 LM9832 600x1200dpi 42bit 512Kb 0x001A
|
||||
.PP
|
||||
|
||||
Vendor Epson - ID: 0x04B8
|
||||
.br
|
||||
----------------------------------------------------------
|
||||
.br
|
||||
USB Model: ASIC: Properties: Prod-ID
|
||||
.br
|
||||
----------------------------------------------------------
|
||||
.br
|
||||
Perfection 1250 LM9832 1200x2400dpi 42bit 512Kb 0x010F
|
||||
.br
|
||||
Perfection 1260 LM9832 1200x2400dpi 42bit 512Kb 0x011D
|
||||
.PP
|
||||
|
||||
Vendor CANON - ID: 0x04A9
|
||||
.br
|
||||
----------------------------------------------------------
|
||||
.br
|
||||
USB Model: ASIC: Properties: Prod-ID
|
||||
.br
|
||||
----------------------------------------------------------
|
||||
.br
|
||||
CanoScan N650/656U LM9832 600x1200dpi 42bit 512Kb 0x2206
|
||||
.br
|
||||
CanoScan N1220U LM9832 1200x2400dpi 42bit 512Kb 0x2207
|
||||
.br
|
||||
CanoScan N670/676U LM9833 600x1200dpi 48bit 512Kb 0x220D
|
||||
.br
|
||||
CanoScan N1240U LM9833 1200x2400dpi 48bit 512Kb 0x220E
|
||||
.br
|
||||
CanoScan LIDE20 LM9833 600x1200dpi 48bit 512Kb 0x220D
|
||||
.br
|
||||
CanoScan LIDE30 LM9833 1200x2400dpi 48bit 512Kb 0x220E
|
||||
.PP
|
||||
|
||||
.SH "OTHER PLUSTEK SCANNERS"
|
||||
|
||||
The SCSI scanner OpticPro 19200S is a rebadged Artec AM12S scanner
|
||||
and is supported by the
|
||||
.B Artec
|
||||
backend.
|
||||
.br
|
||||
Only the National Semiconductor LM9831/2 based devices of Plustek
|
||||
are supported by this driver. Older versions of the U12, the UT12,
|
||||
the U1212 and U1248 (GrandTech chipset) are not supported.
|
||||
.PP
|
||||
Model Chipset backend
|
||||
.br
|
||||
---------------------------
|
||||
.br
|
||||
U1248 GrandTech gt68xx
|
||||
.br
|
||||
UT16B GrandTech gt68xx
|
||||
.PP
|
||||
|
||||
.SH "DEVICE NAMES"
|
||||
This backend expects a default device called:
|
||||
.PP
|
||||
.RS
|
||||
.I /dev/pt_drv
|
||||
.RE
|
||||
.PP
|
||||
This default device will be used, if no configuration
|
||||
file can be found.
|
||||
.PP
|
||||
The device-driver is currently not part of the SANE distribution.
|
||||
It has to be downloaded from:
|
||||
.br
|
||||
.B http://www.gjaeger.de/scanner/plustek.html
|
||||
.br
|
||||
See the INSTALL file there for a proper setup. Currently only Linux
|
||||
is supported by this driver (Kernel 2.2.x and higher).
|
||||
.PP
|
||||
As the backend and the driver support up to four devices
|
||||
per system, it is possible to specify them in the configuration
|
||||
file
|
||||
.PP
|
||||
.RS
|
||||
.I @CONFIGDIR@/plustek.conf
|
||||
.RE
|
||||
.PP
|
||||
See the plustek.conf file for examples.
|
||||
.PP
|
||||
|
||||
.SH "CONFIGURATION"
|
||||
.PP
|
||||
The configuration of this backend can be divided into two sections:
|
||||
.br
|
||||
.PP
|
||||
.B "CONFIGURATION - parallel port scanner"
|
||||
.PP
|
||||
.br
|
||||
.B "CONFIGURATION - USB scanner"
|
||||
.PP
|
||||
.br
|
||||
Please make sure, that the configuration matches the real world,
|
||||
namely your configuration. And note again, .I pt_drv is only needed
|
||||
.PP
|
||||
|
||||
.SH "CONFIGURATION - PARALLEL PORT SCANNER"
|
||||
.PP
|
||||
Beside the kernel-module options, which are described below, you
|
||||
need to enable the parallel port device in the configuration file
|
||||
.PP
|
||||
.RS
|
||||
.I @CONFIGDIR@/plustek.conf
|
||||
.RE
|
||||
.PP
|
||||
For a proper setup, you will need at least two entries:
|
||||
|
||||
.TP
|
||||
.I [parport]
|
||||
.TP
|
||||
.I device /dev/pt_drv
|
||||
.PP
|
||||
.I parport
|
||||
tells the backend, that the following devicename (here
|
||||
.I /dev/pt_drv
|
||||
) has to be interpreted as parallel port scanner device.
|
||||
.PP
|
||||
To have this device, you will need to setup the kernel module.
|
||||
As the driver is a loadable kernel module, it is configured
|
||||
by invoking insmod with the appropriate parameters or
|
||||
appending the options to the file
|
||||
.B /etc/conf.modules
|
||||
.PP
|
||||
.B
|
||||
The Options:
|
||||
.br
|
||||
lampoff=lll
|
||||
.RS
|
||||
The value
|
||||
.I lll
|
||||
tells the driver, after how many seconds to
|
||||
switch-off the lamp(s). The default value is 180.
|
||||
0 will disable this feature.
|
||||
.br
|
||||
.B HINT:
|
||||
Do not use a value that is too small, because often
|
||||
switching on/off the lamps will reduce their lifetime.
|
||||
.RE
|
||||
.PP
|
||||
port=ppp
|
||||
.RS
|
||||
.I ppp
|
||||
specifies the port base address, where the scanner
|
||||
is connected to. The default value is 0x378 which
|
||||
normaly is standard.
|
||||
.RE
|
||||
.PP
|
||||
warmup=www
|
||||
.RS
|
||||
.I www
|
||||
specifies the time in seconds, how long a lamp has to be on,
|
||||
until the driver will start to scan. The default value is 30.
|
||||
.RE
|
||||
.PP
|
||||
lOffonEnd=e
|
||||
.RS
|
||||
.I e
|
||||
specifies the behaviour when unloading the driver, 1 --> switch
|
||||
lamps off, 0 --> do not change lamp status
|
||||
.RE
|
||||
.PP
|
||||
slowIO=s
|
||||
.RS
|
||||
.I s
|
||||
specifies which I/O functions the driver should use, 1 --> use
|
||||
delayed functions, 0 --> use the non-delayed ones
|
||||
.RE
|
||||
.PP
|
||||
forceMode=fm
|
||||
.RS
|
||||
.I fm
|
||||
specifies port mode which should be used, 0 --> autodetection,
|
||||
1 --> use SPP mode and 2 --> use EPP mode
|
||||
.RE
|
||||
.PP
|
||||
mov=m
|
||||
.RS
|
||||
.I m
|
||||
=0 - default: no override
|
||||
.br
|
||||
.I m
|
||||
=1 - OpticPro 9630PL override (works if OP9630
|
||||
.br
|
||||
has been detected) forces legal size (14")
|
||||
.br
|
||||
.I m
|
||||
=2 - Primax 4800Direct override (works if OP600
|
||||
.br
|
||||
has been detected) swaps red/green color
|
||||
.br
|
||||
.I m
|
||||
=3 - OpticPro 9636 override (works if OP9636 has
|
||||
.br
|
||||
been detected) disables backends
|
||||
.br
|
||||
transparency/negativ capabilities
|
||||
.br
|
||||
.I m
|
||||
=4 - OpticPro 9636P override (works if OP9636 has
|
||||
.br
|
||||
been detected) disables backends
|
||||
.br
|
||||
transparency/negativ capabilities
|
||||
.br
|
||||
.I m
|
||||
=5 - OpticPro A3I override (works if OP12000 has
|
||||
.br
|
||||
been detected) enables A3 scanning
|
||||
.br
|
||||
.I m
|
||||
=6 - OpticPro 4800P override (works if OP600
|
||||
.br
|
||||
has been detected) swaps red/green color
|
||||
.br
|
||||
.I m
|
||||
=7 - Primax 4800Direct 30bit override (works if OP4830
|
||||
.br
|
||||
has been detected)
|
||||
.br
|
||||
.RE
|
||||
.PP
|
||||
Sample entry for file
|
||||
.B "/etc/modules.conf"
|
||||
:
|
||||
.br
|
||||
.I alias char-major-40 pt_drv
|
||||
.br
|
||||
.I pre-install pt_drv modprobe -k parport
|
||||
.br
|
||||
.I options pt_drv lampoff=180 warmup=15 port=0x378 lOffonEnd=0 mov=0 slowIO=0 forceMode=0
|
||||
.PP
|
||||
For multidevice support, simply add values separated by commas to
|
||||
the different options
|
||||
.br
|
||||
.I options pt_drv port=0x378,0x278 mov=0,4 slowIO=0,1 forceMode=0,1
|
||||
.PP
|
||||
Remember to call depmod after changing /etc/conf.modules.
|
||||
.PP
|
||||
.B "PARALLEL PORT MODES"
|
||||
.PP
|
||||
The current driver works best, when the parallel port
|
||||
has been set to EPP-mode. When detecting any other
|
||||
mode such as ECP or PS/2 the driver tries to set to a
|
||||
faster, supported mode. If this fails, it will use the
|
||||
SPP mode, as this mode should work with all Linux supported
|
||||
parallel ports.
|
||||
.PP
|
||||
Former Plustek scanner models (4830, 9630) supplied a
|
||||
ISA parallel port adapter card. This card is
|
||||
.BR not
|
||||
supported by the driver.
|
||||
.PP
|
||||
The ASIC 96001/3 based models have sometimes trouble with
|
||||
high resolution modes. If you encounter sporadic corrupted
|
||||
images (parts duplicated or shifted horizontally) kill all
|
||||
other applications before scanning and (if sufficient
|
||||
memory available) disable swapping.
|
||||
.PP
|
||||
|
||||
.SH "CONFIGURATION - USB SCANNER"
|
||||
.PP
|
||||
To use the USB device with this backend, you need at least
|
||||
two entries in the configuration file
|
||||
.br
|
||||
.I @CONFIGDIR@/plustek.conf
|
||||
.TP
|
||||
.I [usb] vendor-id product-id
|
||||
.TP
|
||||
.I device /dev/usbscanner
|
||||
.PP
|
||||
.I usb
|
||||
tells the backend, that the following devicename (here
|
||||
.I /dev/usbscanner
|
||||
) has to be interpreted as USB scanner device. If vendor- and
|
||||
product-id has not been specified, the backend tries to
|
||||
detect this by its own. If device ist set to
|
||||
.I auto
|
||||
then the next matching device is used.
|
||||
.PP
|
||||
.B
|
||||
The Options:
|
||||
.PP
|
||||
option warmup t
|
||||
.RS
|
||||
.I t
|
||||
specifies the warmup period in seconds
|
||||
.RE
|
||||
.PP
|
||||
option lampOff t
|
||||
.RS
|
||||
.I t
|
||||
is the time in seconds for switching off the lamps in
|
||||
standby mode
|
||||
.RE
|
||||
.PP
|
||||
option lOffonEnd b
|
||||
.RS
|
||||
.I b
|
||||
specifies the behaviour when closing the backend, 1 --> switch
|
||||
lamps off, 0 --> do not change lamp status
|
||||
.RE
|
||||
.PP
|
||||
option invertNegatives b
|
||||
.RS
|
||||
.I b
|
||||
0 --> do not invert the picture during negativ scans,
|
||||
1 --> invert picture
|
||||
.RE
|
||||
.PP
|
||||
option skipCalibration b
|
||||
.RS
|
||||
.I b
|
||||
0 --> perform calibration,
|
||||
1 --> skip calibration (only non Plustek devices)
|
||||
.RE
|
||||
.PP
|
||||
option enableTPA b
|
||||
.RS
|
||||
.I b
|
||||
0 --> default behaviour, specified by the internal tables,
|
||||
1 --> override internal tables and allow TPA mode (EPSON only)
|
||||
.RE
|
||||
|
||||
.PP
|
||||
option posOffX x
|
||||
.br
|
||||
option posOffY y
|
||||
.br
|
||||
option tpaOffX x
|
||||
.br
|
||||
option tpaOffY y
|
||||
.br
|
||||
option negOffX x
|
||||
.br
|
||||
option negOffY y
|
||||
.RS
|
||||
.I x y
|
||||
By using this settings, the user can adjust the given image
|
||||
positions.
|
||||
.B Please note, that there's no internal range checking for
|
||||
.B this feature.
|
||||
.RE
|
||||
.PP
|
||||
option posShadingY p
|
||||
.br
|
||||
option tpaShadingY p
|
||||
.br
|
||||
option negShadingY p
|
||||
.RS
|
||||
.I p
|
||||
overrides the internal shading position. The values are in steps.
|
||||
.B Please note, that there's no internal range checking for
|
||||
.B this feature.
|
||||
.RE
|
||||
.PP
|
||||
option redGamma r
|
||||
.br
|
||||
option greenGamma g
|
||||
.br
|
||||
option blueGamma b
|
||||
.br
|
||||
option grayGamma gr
|
||||
.RS
|
||||
.I r g b gr
|
||||
.RE
|
||||
By using these values, the internal linear gamma table (r,g,b,gr = 1.0)
|
||||
can be adjusted.
|
||||
.PP
|
||||
option red_gain r
|
||||
.br
|
||||
option green_gain g
|
||||
.br
|
||||
option blue_gain b
|
||||
.RS
|
||||
.I r g b
|
||||
These values can be used to adjust the internally detected gain values of
|
||||
the AFE for each channel. The range is between 0 and 63.
|
||||
.RE
|
||||
|
||||
.PP
|
||||
See the plustek.conf file for examples.
|
||||
.PP
|
||||
.B Note:
|
||||
.br
|
||||
You have to make sure, that the USB subsystem is loaded
|
||||
correctly and the module
|
||||
.I scanner
|
||||
has been loaded too. To make this module recognize your
|
||||
scanner, you might have to add the following line to
|
||||
your
|
||||
.B "/etc/modules.conf"
|
||||
:
|
||||
.br
|
||||
.I options scanner vendor=0x7b3 product=0x17
|
||||
.PP
|
||||
.br
|
||||
If you're not sure about the vendor and product id of your
|
||||
device, simply load the USB subsystem and plug in your
|
||||
scanner. Then do a
|
||||
.I cat /proc/bus/usb/devices
|
||||
and look for the scanner.
|
||||
.PP
|
||||
|
||||
.SH FILES
|
||||
.TP
|
||||
.I @CONFIGDIR@/plustek.conf
|
||||
The backend configuration file
|
||||
.TP
|
||||
.I @LIBDIR@/libsane-plustek.a
|
||||
The static library implementing this backend.
|
||||
.TP
|
||||
.I @LIBDIR@/libsane-plustek.so
|
||||
The shared library implementing this backend (present on systems that
|
||||
support dynamic loading).
|
||||
.TP
|
||||
.I /lib/modules/<Kernel-Version>/misc/pt_drv.o
|
||||
The Linux Kernelmodule.
|
||||
.PP
|
||||
|
||||
.SH "CONTACT AND BUG-REPORTS"
|
||||
.PP
|
||||
Please send any information and bug-reports to:
|
||||
.br
|
||||
.B Plustek Driver Mailing List <plustek@linuxhacker.org>
|
||||
.br
|
||||
or directly to:
|
||||
.br
|
||||
.B Gerhard Jaeger <gerhard@gjaeger.de>
|
||||
.PP
|
||||
Additional info and hints can be obtained from our
|
||||
.br
|
||||
Mailing-List archive at:
|
||||
.br
|
||||
.B http://www.linuxhacker.org/cgi-bin/ezmlm-cgi/3
|
||||
.PP
|
||||
or directly from the projects' homepage at:
|
||||
.br
|
||||
.B http://www.gjaeger.de/scanner/plustek.html
|
||||
.PP
|
||||
To obtain debug messages from the backend, please set the
|
||||
environment-variable
|
||||
.I SANE_DEBUG_PLUSTEK
|
||||
before calling your favorite scan-frontend (i.e. xscanimage).
|
||||
.br
|
||||
.B i.e.: export SANE_DEBUG_PLUSTEK=20 ; xscanimage
|
||||
.PP
|
||||
The value controls the verbosity of the backend. Please note, that
|
||||
values greater than 19 force the backend to output raw data files,
|
||||
which could be rather large. The ending of these files is ".raw".
|
||||
For problem reports it should be enough the set the verbosity to
|
||||
13.
|
||||
.PP
|
||||
|
||||
.SH "KNOWN BUGS & RESTRICTIONS"
|
||||
.PP
|
||||
.br
|
||||
* The Halftoning works, but the quality is poor
|
||||
.br
|
||||
* Printers (especially HP models) will start to
|
||||
.br
|
||||
print during scanning. This in fact is a problem
|
||||
.br
|
||||
to other printers too, using bidirectional protocol
|
||||
.br
|
||||
(see www.plustek.com (TAIWAN) page for further details)
|
||||
.br
|
||||
* The driver does not support these manic scalings up
|
||||
.br
|
||||
to 16 times the physical resolution. The only scaling
|
||||
.br
|
||||
is done on resolutions between the physical resolution
|
||||
.br
|
||||
of the CDD-sensor and the stepper motor i.e. you have a
|
||||
.br
|
||||
600x1200 dpi scanner and you are scanning using 800dpi,
|
||||
.br
|
||||
so scaling is necesary, because the sensor only delivers
|
||||
.br
|
||||
600dpi but the motor is capable to perform 800dpi steps.
|
||||
.br
|
||||
* On some devices, the pictures seems to be bluished
|
||||
.PP
|
||||
ASIC 98001 based models:
|
||||
.br
|
||||
* The 300dpi transparency and negative mode does not work
|
||||
.br
|
||||
correctly.
|
||||
.br
|
||||
* There is currently no way to distinguish a model with
|
||||
.br
|
||||
and without transpareny unit.
|
||||
.br
|
||||
* The scanned images seem to be too dark (P9636T)
|
||||
.PP
|
||||
ASIC 96003/1 based models:
|
||||
.br
|
||||
* 30bit mode is currently not supported.
|
||||
.br
|
||||
* On low-end systems and under heavy system load, the
|
||||
.br
|
||||
driver will loosing data, this might causes the sensor
|
||||
.br
|
||||
to hit the scan-bed and/or the picture is corrupted.
|
||||
.br
|
||||
* The scanspeed on 600x1200 dpi models is slow.
|
||||
.br
|
||||
* The scanquality of the A3I is poor
|
||||
.br
|
||||
.PP
|
||||
USB models:
|
||||
.br
|
||||
* Plusteks' model policy is somewhat inconsistent. This
|
||||
.br
|
||||
means, they sell technical different devices under the
|
||||
.br
|
||||
same product name. Therefore it is possible that some
|
||||
.br
|
||||
devices like the UT12 or U12 won't work - please check
|
||||
.br
|
||||
the model list above and compare the product-id to
|
||||
.br
|
||||
the one your device has.
|
||||
.br
|
||||
* Negative scanning quality is poor.
|
Ładowanie…
Reference in New Issue