kopia lustrzana https://gitlab.com/sane-project/backends
Remove "init device" usb request, add some support for Visioneer Strobe XP300.
Add support for uncalibrated scans in all modes for Visioneer Strobe XP300. Front- and backside are side-by-side, backside mirrored horizontally.merge-requests/1/head
rodzic
144b1a3cfb
commit
d167519e76
|
@ -1,3 +1,12 @@
|
||||||
|
2009-02-08 Pierre Willenbrock <pierre@pirsoft.dnsalias.org>
|
||||||
|
* backend/genesys_gl841.c: Remove "init device" usb request.
|
||||||
|
* backend/genesys_gl841.c, backend/genesys_devices.c,
|
||||||
|
backend/genesys_low.h: Add support for uncalibrated scans in all
|
||||||
|
modes for Visioneer Strobe XP300. Front- and backside are
|
||||||
|
side-by-side, backside mirrored horizontally.
|
||||||
|
* doc/descriptions/genesys.desc: Added XP300 to the genesys
|
||||||
|
desc file.
|
||||||
|
|
||||||
2009-02-06 Chris Bagwell <cbagwell-guest at users.alioth.debian.org>
|
2009-02-06 Chris Bagwell <cbagwell-guest at users.alioth.debian.org>
|
||||||
* configure.in, backend/Makefile.am: Add back in support for
|
* configure.in, backend/Makefile.am: Add back in support for
|
||||||
optionally linking in sanei_jpeg.lo under backend directory;
|
optionally linking in sanei_jpeg.lo under backend directory;
|
||||||
|
|
|
@ -109,6 +109,13 @@ static Genesys_Frontend Wolfson[] = {
|
||||||
, {0x00, 0x00, 0x00}
|
, {0x00, 0x00, 0x00}
|
||||||
}
|
}
|
||||||
, /* 7: XP200 */
|
, /* 7: XP200 */
|
||||||
|
{{0x00, 0x35, 0x20, 0x14}
|
||||||
|
, {0x00, 0x00, 0x00}
|
||||||
|
, {0xe1, 0xe1, 0xe1}
|
||||||
|
, {0x93, 0x93, 0x93}
|
||||||
|
, {0x07, 0x00, 0x00}
|
||||||
|
}
|
||||||
|
, /* 8: XP300 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -240,11 +247,35 @@ static Genesys_Sensor Sensor[] = {
|
||||||
,
|
,
|
||||||
2.1, 2.1, 2.1,
|
2.1, 2.1, 2.1,
|
||||||
NULL, NULL, NULL}
|
NULL, NULL, NULL}
|
||||||
|
,
|
||||||
|
/* 8: Strobe XP300 */
|
||||||
|
{600,
|
||||||
|
/*TODO: find a good reason for keeping all three following variables*/
|
||||||
|
87, /*(black) */
|
||||||
|
87, /* (dummy) */
|
||||||
|
0, /* (startxoffset) */
|
||||||
|
10240, /*sensor_pixels */
|
||||||
|
210,
|
||||||
|
200,
|
||||||
|
{0x00, 0x00, 0x00, 0x00},
|
||||||
|
{0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x02, 0x04, 0x50,
|
||||||
|
0x10, 0x00, 0x20, 0x02
|
||||||
|
},
|
||||||
|
{0x04, 0x05,
|
||||||
|
0x00, 0x00, 0x00, 0x00, /*[GB](HI|LOW) not needed for cis */
|
||||||
|
0x54, 0x03,
|
||||||
|
0x00, /*TODO: bit7 */
|
||||||
|
0x00, 0x00, 0x00, 0x01 /*TODO (these do no harm, but may be neccessery for CCD) */
|
||||||
|
}
|
||||||
|
,
|
||||||
|
1.0, 1.0, 1.0,
|
||||||
|
NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** for General Purpose Output specific settings:
|
/** for General Purpose Output specific settings:
|
||||||
* initial GPO value (registers 0x66-0x67/0x6c-0x6d)
|
* initial GPO value (registers 0x66-0x67/0x6c-0x6d)
|
||||||
* GPO enable mask (registers 0x68-0x69/0x6e-0x6f)
|
* GPO enable mask (registers 0x68-0x69/0x6e-0x6f)
|
||||||
|
* The first register is for GPIO9-GPIO16, the second for GPIO1-GPIO8
|
||||||
*/
|
*/
|
||||||
static Genesys_Gpo Gpo[] = {
|
static Genesys_Gpo Gpo[] = {
|
||||||
/* UMAX */
|
/* UMAX */
|
||||||
|
@ -310,11 +341,17 @@ static Genesys_Gpo Gpo[] = {
|
||||||
{0xb0, 0x00}
|
{0xb0, 0x00}
|
||||||
,
|
,
|
||||||
}
|
}
|
||||||
|
,
|
||||||
|
/* 8: XP300 */
|
||||||
|
{
|
||||||
|
{0x09, 0xc6},
|
||||||
|
{0xbb, 0x00},
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MOTOR_ST24 2
|
#define MOTOR_ST24 2
|
||||||
static Genesys_Motor Motor[] = {
|
static Genesys_Motor Motor[] = {
|
||||||
/* UMAX */
|
/* 0: UMAX */
|
||||||
{
|
{
|
||||||
1200, /* motor base steps */
|
1200, /* motor base steps */
|
||||||
2400, /* maximum motor resolution */
|
2400, /* maximum motor resolution */
|
||||||
|
@ -333,7 +370,7 @@ static Genesys_Motor Motor[] = {
|
||||||
1.0,
|
1.0,
|
||||||
},},},
|
},},},
|
||||||
},
|
},
|
||||||
{ /* MD5345/6228/6471 */
|
{ /* 1: MD5345/6228/6471 */
|
||||||
1200,
|
1200,
|
||||||
2400,
|
2400,
|
||||||
1,
|
1,
|
||||||
|
@ -351,7 +388,7 @@ static Genesys_Motor Motor[] = {
|
||||||
0.5,
|
0.5,
|
||||||
},},},
|
},},},
|
||||||
},
|
},
|
||||||
{ /* ST24 */
|
{ /* 2: ST24 */
|
||||||
2400,
|
2400,
|
||||||
2400,
|
2400,
|
||||||
1,
|
1,
|
||||||
|
@ -369,7 +406,7 @@ static Genesys_Motor Motor[] = {
|
||||||
0.3,
|
0.3,
|
||||||
},},},
|
},},},
|
||||||
},
|
},
|
||||||
{ /* HP 2400c */
|
{ /* 3: HP 2400c */
|
||||||
1200,
|
1200,
|
||||||
2400,
|
2400,
|
||||||
1,
|
1,
|
||||||
|
@ -387,7 +424,7 @@ static Genesys_Motor Motor[] = {
|
||||||
0.5,
|
0.5,
|
||||||
},},},
|
},},},
|
||||||
},
|
},
|
||||||
{ /* HP 2300c */
|
{ /* 4: HP 2300c */
|
||||||
600,
|
600,
|
||||||
1200,
|
1200,
|
||||||
1,
|
1,
|
||||||
|
@ -405,7 +442,7 @@ static Genesys_Motor Motor[] = {
|
||||||
0.5,
|
0.5,
|
||||||
},},},
|
},},},
|
||||||
},
|
},
|
||||||
{ /* Canon LiDE 35 */
|
{ /* 5: Canon LiDE 35 */
|
||||||
1200,
|
1200,
|
||||||
2400,
|
2400,
|
||||||
1,
|
1,
|
||||||
|
@ -423,7 +460,7 @@ static Genesys_Motor Motor[] = {
|
||||||
0.8,
|
0.8,
|
||||||
},},},
|
},},},
|
||||||
},
|
},
|
||||||
{ /* Strobe XP200 */
|
{ /* 6: Strobe XP200 */
|
||||||
600,
|
600,
|
||||||
600,
|
600,
|
||||||
1,
|
1,
|
||||||
|
@ -441,6 +478,24 @@ static Genesys_Motor Motor[] = {
|
||||||
0.5,
|
0.5,
|
||||||
},},},
|
},},},
|
||||||
},
|
},
|
||||||
|
{ /* 7: Visioneer Strobe XP300 */
|
||||||
|
300,
|
||||||
|
600,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
{{{ /* works best with GPIO10, GPIO14 off */
|
||||||
|
3700,
|
||||||
|
3700,
|
||||||
|
2,
|
||||||
|
0.8,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
11000,
|
||||||
|
11000,
|
||||||
|
2,
|
||||||
|
0.8,
|
||||||
|
},},},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* here we have the various device settings...
|
/* here we have the various device settings...
|
||||||
|
@ -922,6 +977,51 @@ static Genesys_Model medion_md5345_model = {
|
||||||
200
|
200
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static Genesys_Model visioneer_xp300_model = {
|
||||||
|
"visioneer-strobe-xp300", /* Name */
|
||||||
|
"Visioneer", /* Device vendor string */
|
||||||
|
"Strobe XP300", /* Device model name */
|
||||||
|
GENESYS_GL841,
|
||||||
|
NULL,
|
||||||
|
|
||||||
|
{600, 300, 150, 75, 0}, /* possible x-resolutions */
|
||||||
|
{600, 300, 150, 75, 0}, /* possible y-resolutions */
|
||||||
|
{16, 8, 0}, /* possible depths in gray mode */
|
||||||
|
{16, 8, 0}, /* possible depths in color mode */
|
||||||
|
|
||||||
|
SANE_FIX (0.0), /* Start of scan area in mm (x) */
|
||||||
|
SANE_FIX (3.0), /* Start of scan area in mm (y) */
|
||||||
|
SANE_FIX (435.0), /* Size of scan area in mm (x) */
|
||||||
|
SANE_FIX (511), /* Size of scan area in mm (y) */
|
||||||
|
|
||||||
|
SANE_FIX (3.0), /* Start of white strip in mm (y) */
|
||||||
|
SANE_FIX (0.0), /* Start of black mark in mm (x) */
|
||||||
|
|
||||||
|
SANE_FIX (0.0), /* Start of scan area in TA mode in mm (x) */
|
||||||
|
SANE_FIX (0.0), /* Start of scan area in TA mode in mm (y) */
|
||||||
|
SANE_FIX (100.0), /* Size of scan area in TA mode in mm (x) */
|
||||||
|
SANE_FIX (100.0), /* Size of scan area in TA mode in mm (y) */
|
||||||
|
|
||||||
|
SANE_FIX (0.0), /* Start of white strip in TA mode in mm (y) */
|
||||||
|
|
||||||
|
0, 0, 0, /* RGB CCD Line-distance correction in pixel */
|
||||||
|
|
||||||
|
COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */
|
||||||
|
|
||||||
|
SANE_TRUE, /* Is this a CIS scanner? */
|
||||||
|
SANE_TRUE, /* Is this a sheetfed scanner? */
|
||||||
|
CCD_XP300,
|
||||||
|
DAC_WOLFSON_XP300,
|
||||||
|
GPO_XP300,
|
||||||
|
MOTOR_XP300,
|
||||||
|
GENESYS_FLAG_LAZY_INIT /* Which flags are needed for this scanner? */
|
||||||
|
| GENESYS_FLAG_SKIP_WARMUP
|
||||||
|
| GENESYS_FLAG_NO_CALIBRATION,
|
||||||
|
GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW,
|
||||||
|
300,
|
||||||
|
400
|
||||||
|
};
|
||||||
|
|
||||||
static Genesys_USB_Device_Entry genesys_usb_device_list[] = {
|
static Genesys_USB_Device_Entry genesys_usb_device_list[] = {
|
||||||
{0x0638, 0x0a10, &umax_astra_4500_model},
|
{0x0638, 0x0a10, &umax_astra_4500_model},
|
||||||
{0x04a9, 0x2213, &canon_lide_50_model},
|
{0x04a9, 0x2213, &canon_lide_50_model},
|
||||||
|
@ -933,5 +1033,6 @@ static Genesys_USB_Device_Entry genesys_usb_device_list[] = {
|
||||||
{0x07b3, 0x0601, &plustek_st24_model},
|
{0x07b3, 0x0601, &plustek_st24_model},
|
||||||
{0x0461, 0x0377, &medion_md5345_model},
|
{0x0461, 0x0377, &medion_md5345_model},
|
||||||
{0x04a7, 0x0426, &visioneer_xp200_model},
|
{0x04a7, 0x0426, &visioneer_xp200_model},
|
||||||
|
{0x04a7, 0x0474, &visioneer_xp300_model},
|
||||||
{0, 0, NULL}
|
{0, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1532,6 +1532,11 @@ gl841_init_registers (Genesys_Device * dev)
|
||||||
dev->reg[reg_0x6b].value &= ~REG6B_GPO17;
|
dev->reg[reg_0x6b].value &= ~REG6B_GPO17;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dev->model->gpo_type == GPO_XP300)
|
||||||
|
{
|
||||||
|
dev->reg[reg_0x6b].value |= REG6B_GPO17;
|
||||||
|
}
|
||||||
|
|
||||||
DBG (DBG_proc, "gl841_init_registers complete\n");
|
DBG (DBG_proc, "gl841_init_registers complete\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2165,7 +2170,13 @@ gl841_init_motor_regs_scan(Genesys_Device * dev,
|
||||||
&fast_exposure,
|
&fast_exposure,
|
||||||
scan_power_mode);
|
scan_power_mode);
|
||||||
|
|
||||||
if (feed_steps < fast_slope_steps*2 + (slow_slope_steps >> scan_step_type)) {
|
if (dev->model->gpo_type == GPO_XP300)
|
||||||
|
{
|
||||||
|
/* quirk: looks like at least this scanner is unable to use
|
||||||
|
2-feed mode */
|
||||||
|
use_fast_fed = 0;
|
||||||
|
}
|
||||||
|
else if (feed_steps < fast_slope_steps*2 + (slow_slope_steps >> scan_step_type)) {
|
||||||
use_fast_fed = 0;
|
use_fast_fed = 0;
|
||||||
DBG(DBG_info,"gl841_init_motor_regs_scan: feed too short, slow move forced.\n");
|
DBG(DBG_info,"gl841_init_motor_regs_scan: feed too short, slow move forced.\n");
|
||||||
} else {
|
} else {
|
||||||
|
@ -2491,7 +2502,8 @@ gl841_init_optical_regs_scan(Genesys_Device * dev,
|
||||||
/* dev->reg[reg_0x01].value |= REG01_DVDSET | REG01_SCAN;*/
|
/* dev->reg[reg_0x01].value |= REG01_DVDSET | REG01_SCAN;*/
|
||||||
r = sanei_genesys_get_address (reg, 0x01);
|
r = sanei_genesys_get_address (reg, 0x01);
|
||||||
r->value |= REG01_SCAN;
|
r->value |= REG01_SCAN;
|
||||||
if (flags & OPTICAL_FLAG_DISABLE_SHADING)
|
if ((flags & OPTICAL_FLAG_DISABLE_SHADING) ||
|
||||||
|
(dev->model->flags & GENESYS_FLAG_NO_CALIBRATION))
|
||||||
r->value &= ~REG01_DVDSET;
|
r->value &= ~REG01_DVDSET;
|
||||||
else
|
else
|
||||||
r->value |= REG01_DVDSET;
|
r->value |= REG01_DVDSET;
|
||||||
|
@ -2602,6 +2614,8 @@ gl841_init_optical_regs_scan(Genesys_Device * dev,
|
||||||
else
|
else
|
||||||
words_per_line *= depth / 8;
|
words_per_line *= depth / 8;
|
||||||
|
|
||||||
|
dev->wpl = words_per_line;
|
||||||
|
|
||||||
r = sanei_genesys_get_address (reg, 0x35);
|
r = sanei_genesys_get_address (reg, 0x35);
|
||||||
r->value = LOBYTE (HIWORD (words_per_line));
|
r->value = LOBYTE (HIWORD (words_per_line));
|
||||||
r = sanei_genesys_get_address (reg, 0x36);
|
r = sanei_genesys_get_address (reg, 0x36);
|
||||||
|
@ -3054,7 +3068,7 @@ dummy \ scanned lines
|
||||||
dev->total_bytes_to_read =
|
dev->total_bytes_to_read =
|
||||||
dev->settings.pixels * dev->settings.lines * channels * (depth / 8);
|
dev->settings.pixels * dev->settings.lines * channels * (depth / 8);
|
||||||
|
|
||||||
DBG (DBG_info, "gl646_init_scan_regs: total bytes to send = %lu\n",
|
DBG (DBG_info, "gl841_init_scan_regs: total bytes to send = %lu\n",
|
||||||
(u_long) dev->total_bytes_to_read);
|
(u_long) dev->total_bytes_to_read);
|
||||||
/* END TODO */
|
/* END TODO */
|
||||||
|
|
||||||
|
@ -3300,6 +3314,339 @@ gl841_set_powersaving (Genesys_Device * dev,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SANE_Status
|
||||||
|
gl841_get_paper_sensor(Genesys_Device * dev, SANE_Bool * paper_loaded)
|
||||||
|
{
|
||||||
|
SANE_Status status;
|
||||||
|
u_int8_t val;
|
||||||
|
|
||||||
|
status = sanei_genesys_read_register(dev, 0x6d, &val);
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
{
|
||||||
|
DBG (DBG_error,
|
||||||
|
"gl841_get_paper_sensor: Failed to read gpio: %s\n",
|
||||||
|
sane_strstatus (status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
*paper_loaded = (val & 0x1) == 0;
|
||||||
|
return SANE_STATUS_GOOD;
|
||||||
|
|
||||||
|
return SANE_STATUS_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SANE_Status
|
||||||
|
gl841_eject_document (Genesys_Device * dev)
|
||||||
|
{
|
||||||
|
Genesys_Register_Set local_reg[GENESYS_GL841_MAX_REGS+1];
|
||||||
|
SANE_Status status;
|
||||||
|
u_int8_t val;
|
||||||
|
int i;
|
||||||
|
SANE_Bool paper_loaded;
|
||||||
|
|
||||||
|
DBG (DBG_proc, "gl841_eject_document\n");
|
||||||
|
|
||||||
|
if (!dev->model->is_sheetfed == SANE_TRUE)
|
||||||
|
{
|
||||||
|
DBG (DBG_proc, "gl841_eject_document: there is no \"eject sheet\"-concept for non sheet fed\n");
|
||||||
|
DBG (DBG_proc, "gl841_eject_document: finished\n");
|
||||||
|
return SANE_STATUS_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
memset (local_reg, 0, sizeof (local_reg));
|
||||||
|
val = 0;
|
||||||
|
|
||||||
|
status = sanei_genesys_get_status (dev, &val);
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
{
|
||||||
|
DBG (DBG_error,
|
||||||
|
"gl841_slow_back_home: Failed to read status register: %s\n",
|
||||||
|
sane_strstatus (status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* stop motor if needed */
|
||||||
|
if (val & REG41_MOTORENB)
|
||||||
|
{
|
||||||
|
status = sanei_genesys_stop_motor (dev);
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
{
|
||||||
|
DBG (DBG_error,
|
||||||
|
"gl841_eject_document: failed to stop motor: %s\n",
|
||||||
|
sane_strstatus (status));
|
||||||
|
return SANE_STATUS_IO_ERROR;
|
||||||
|
}
|
||||||
|
usleep (200 * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* when scanhead is moving then wait until scanhead stops or timeout */
|
||||||
|
DBG (DBG_info, "gl841_eject_document: ensuring that motor is off\n");
|
||||||
|
for (i = 400; i > 0; i--) /* do not wait longer than 40 seconds, count down to get i = 0 when busy */
|
||||||
|
{
|
||||||
|
status = sanei_genesys_get_status (dev, &val);
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
{
|
||||||
|
DBG (DBG_error,
|
||||||
|
"gl841_eject_document: Failed to read motor status: %s\n",
|
||||||
|
sane_strstatus (status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
if (!(val & REG41_MOTORENB)) /* motor is off */
|
||||||
|
{
|
||||||
|
DBG (DBG_info,
|
||||||
|
"gl841_eject_document: motor is off\n");
|
||||||
|
break; /* motor is off: continue */
|
||||||
|
}
|
||||||
|
|
||||||
|
usleep (100 * 1000); /* sleep 100 ms */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!i) /* the loop counted down to 0, scanner still is busy */
|
||||||
|
{
|
||||||
|
DBG (DBG_error,
|
||||||
|
"gl841_eject_document: motor is still on: device busy\n");
|
||||||
|
return SANE_STATUS_DEVICE_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (local_reg, dev->reg, (GENESYS_GL841_MAX_REGS+1) * sizeof (Genesys_Register_Set));
|
||||||
|
|
||||||
|
gl841_init_optical_regs_off(dev,local_reg);
|
||||||
|
|
||||||
|
gl841_init_motor_regs(dev,local_reg,
|
||||||
|
65536,MOTOR_ACTION_FEED,0);
|
||||||
|
|
||||||
|
status =
|
||||||
|
gl841_bulk_write_register (dev, local_reg, GENESYS_GL841_MAX_REGS);
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
{
|
||||||
|
DBG (DBG_error,
|
||||||
|
"gl841_eject_document: Failed to bulk write registers: %s\n",
|
||||||
|
sane_strstatus (status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = sanei_genesys_start_motor (dev);
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
{
|
||||||
|
DBG (DBG_error,
|
||||||
|
"gl841_eject_document: Failed to start motor: %s\n",
|
||||||
|
sane_strstatus (status));
|
||||||
|
sanei_genesys_stop_motor (dev);
|
||||||
|
/* send original registers */
|
||||||
|
gl841_bulk_write_register (dev, dev->reg, GENESYS_GL841_MAX_REGS);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
RIE(gl841_get_paper_sensor(dev, &paper_loaded));
|
||||||
|
if (paper_loaded)
|
||||||
|
{
|
||||||
|
DBG (DBG_info,
|
||||||
|
"gl841_eject_document: paper still loaded\n");
|
||||||
|
dev->scanhead_position_in_steps = 0;
|
||||||
|
|
||||||
|
|
||||||
|
int loop = 300;
|
||||||
|
while (loop > 0) /* do not wait longer then 30 seconds */
|
||||||
|
{
|
||||||
|
|
||||||
|
RIE(gl841_get_paper_sensor(dev, &paper_loaded));
|
||||||
|
|
||||||
|
if (!paper_loaded)
|
||||||
|
{
|
||||||
|
DBG (DBG_info,
|
||||||
|
"gl841_eject_document: reached home position\n");
|
||||||
|
DBG (DBG_proc, "gl841_eject_document: finished\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
usleep (100000); /* sleep 100 ms */
|
||||||
|
--loop;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loop == 0)
|
||||||
|
{
|
||||||
|
/* when we come here then the scanner needed too much time for this, so we better stop the motor */
|
||||||
|
sanei_genesys_stop_motor (dev);
|
||||||
|
DBG (DBG_error,
|
||||||
|
"gl841_eject_document: timeout while waiting for scanhead to go home\n");
|
||||||
|
return SANE_STATUS_IO_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int init_steps;
|
||||||
|
|
||||||
|
status = sanei_genesys_read_feed_steps(dev, &init_steps);
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
{
|
||||||
|
DBG (DBG_error,
|
||||||
|
"gl841_eject_document: Failed to read feed steps: %s\n",
|
||||||
|
sane_strstatus (status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now feed for extra <number> steps */
|
||||||
|
int loop = 0;
|
||||||
|
|
||||||
|
while (loop < 300) /* do not wait longer then 30 seconds */
|
||||||
|
{
|
||||||
|
unsigned int steps;
|
||||||
|
|
||||||
|
status = sanei_genesys_read_feed_steps(dev, &steps);
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
{
|
||||||
|
DBG (DBG_error,
|
||||||
|
"gl841_eject_document: Failed to read feed steps: %s\n",
|
||||||
|
sane_strstatus (status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG (DBG_info, "gl841_eject_document: init_steps: %d, steps: %d\n",
|
||||||
|
init_steps, steps);
|
||||||
|
|
||||||
|
if (steps > init_steps + 400)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
usleep (100000); /* sleep 100 ms */
|
||||||
|
++loop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reprogram for motor off */
|
||||||
|
gl841_init_motor_regs_off(dev,local_reg, 0);
|
||||||
|
status =
|
||||||
|
gl841_bulk_write_register (dev, local_reg, GENESYS_GL841_MAX_REGS);
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
{
|
||||||
|
DBG (DBG_error,
|
||||||
|
"gl841_eject_document: Failed to bulk write registers: %s\n",
|
||||||
|
sane_strstatus (status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
status = sanei_genesys_write_register (dev, 0x0f, 0x00); /* disable motor */
|
||||||
|
|
||||||
|
dev->document = SANE_FALSE;
|
||||||
|
|
||||||
|
DBG (DBG_proc, "gl841_eject_document: finished\n");
|
||||||
|
return SANE_STATUS_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static SANE_Status
|
||||||
|
gl841_load_document (Genesys_Device * dev)
|
||||||
|
{
|
||||||
|
SANE_Status status;
|
||||||
|
SANE_Bool paper_loaded;
|
||||||
|
int loop = 300;
|
||||||
|
DBG (DBG_proc, "gl841_load_document\n");
|
||||||
|
while (loop > 0) /* do not wait longer then 30 seconds */
|
||||||
|
{
|
||||||
|
|
||||||
|
RIE(gl841_get_paper_sensor(dev, &paper_loaded));
|
||||||
|
|
||||||
|
if (paper_loaded)
|
||||||
|
{
|
||||||
|
DBG (DBG_info,
|
||||||
|
"gl841_load_document: document inserted\n");
|
||||||
|
|
||||||
|
/* when loading OK, document is here */
|
||||||
|
dev->document = SANE_TRUE;
|
||||||
|
|
||||||
|
usleep (1000000); /* give user 1000ms to place document correctly */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
usleep (100000); /* sleep 100 ms */
|
||||||
|
--loop;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loop == 0)
|
||||||
|
{
|
||||||
|
/* when we come here then the user needed to much time for this */
|
||||||
|
DBG (DBG_error,
|
||||||
|
"gl841_load_document: timeout while waiting for document\n");
|
||||||
|
return SANE_STATUS_IO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG (DBG_proc, "gl841_load_document: finished\n");
|
||||||
|
return SANE_STATUS_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* detects end of document and adjust current scan
|
||||||
|
* to take it into account
|
||||||
|
* used by sheetfed scanners
|
||||||
|
*/
|
||||||
|
static SANE_Status
|
||||||
|
gl841_detect_document_end (Genesys_Device * dev)
|
||||||
|
{
|
||||||
|
SANE_Status status = SANE_STATUS_GOOD;
|
||||||
|
SANE_Bool paper_loaded;
|
||||||
|
int bytes_to_flush, lines, sub_bytes;
|
||||||
|
u_int32_t flines, channels, depth, bytes_remain, sublines;
|
||||||
|
DBG (DBG_proc, "%s: begin\n", __FUNCTION__);
|
||||||
|
|
||||||
|
RIE (gl841_get_paper_sensor (dev, &paper_loaded));
|
||||||
|
|
||||||
|
/* sheetfed scanner uses home sensor as paper present */
|
||||||
|
if ((dev->document == SANE_TRUE) && !paper_loaded)
|
||||||
|
{
|
||||||
|
DBG (DBG_info, "%s: no more document\n", __FUNCTION__);
|
||||||
|
dev->document = SANE_FALSE;
|
||||||
|
|
||||||
|
channels = dev->current_setup.channels;
|
||||||
|
depth = dev->current_setup.depth;
|
||||||
|
|
||||||
|
/* adjust number of bytes to read
|
||||||
|
* we need to read the final bytes which are word per line * number of last lines
|
||||||
|
* to have doc leaving feeder */
|
||||||
|
lines =
|
||||||
|
(29 * dev->current_setup.yres) /
|
||||||
|
MM_PER_INCH;
|
||||||
|
DBG (DBG_io, "gl841_detect_document_end: adding %d line to flush\n", lines);
|
||||||
|
/* number of bytes to read from scanner to get document out of it after
|
||||||
|
* end of document dectected by hardware sensor */
|
||||||
|
bytes_to_flush = lines * dev->wpl;
|
||||||
|
|
||||||
|
/* if we are already close to end of scan, flushing isn't needed */
|
||||||
|
if (bytes_to_flush < dev->read_bytes_left)
|
||||||
|
{
|
||||||
|
bytes_remain = dev->total_bytes_to_read - dev->total_bytes_read;
|
||||||
|
|
||||||
|
/* remaining lines to read by frontend for the current scan */
|
||||||
|
if (depth == 1 || dev->settings.scan_mode == 0)
|
||||||
|
flines = bytes_remain * 8
|
||||||
|
/ dev->settings.pixels / channels;
|
||||||
|
else
|
||||||
|
flines = bytes_remain / (depth / 8)
|
||||||
|
/ dev->settings.pixels / channels;
|
||||||
|
|
||||||
|
if (flines > lines)
|
||||||
|
{
|
||||||
|
/* change the value controlling communication with the frontend :
|
||||||
|
* total bytes to read is current value plus the number of remaining lines
|
||||||
|
* multiplied by bytes per line */
|
||||||
|
sublines = flines - lines;
|
||||||
|
|
||||||
|
if (depth == 1 || dev->settings.scan_mode == 0)
|
||||||
|
sub_bytes =
|
||||||
|
((dev->settings.pixels * sublines) / 8 +
|
||||||
|
(((dev->settings.pixels * sublines)%8)?1:0)
|
||||||
|
) * channels;
|
||||||
|
else
|
||||||
|
sub_bytes =
|
||||||
|
dev->settings.pixels * sublines * channels * (depth / 8);
|
||||||
|
|
||||||
|
dev->total_bytes_to_read -= sub_bytes;
|
||||||
|
|
||||||
|
/* then adjust the physical bytes to read */
|
||||||
|
dev->read_bytes_left -= sub_bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG (DBG_proc, "%s: finished\n", __FUNCTION__);
|
||||||
|
return SANE_STATUS_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
/* Send the low-level scan command */
|
/* Send the low-level scan command */
|
||||||
/* todo : is this that useful ? */
|
/* todo : is this that useful ? */
|
||||||
static SANE_Status
|
static SANE_Status
|
||||||
|
@ -3354,39 +3701,51 @@ gl841_end_scan (Genesys_Device * dev, Genesys_Register_Set * reg,
|
||||||
|
|
||||||
DBG (DBG_proc, "gl841_end_scan (check_stop = %d)\n", check_stop);
|
DBG (DBG_proc, "gl841_end_scan (check_stop = %d)\n", check_stop);
|
||||||
|
|
||||||
status = sanei_genesys_write_register (dev, 0x01, sanei_genesys_read_reg_from_set (reg, 0x01) & ~REG01_SCAN); /* disable scan */
|
if (dev->model->is_sheetfed == SANE_TRUE && dev->document == SANE_TRUE)
|
||||||
if (status != SANE_STATUS_GOOD)
|
|
||||||
{
|
{
|
||||||
DBG (DBG_error, "gl841_end_scan: Failed to write registers: %s\n",
|
status = gl841_eject_document (dev);
|
||||||
sane_strstatus (status));
|
if (status != SANE_STATUS_GOOD)
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (check_stop)
|
|
||||||
{
|
|
||||||
for (i = 0; i < 300; i++) /* do not wait longer than 3 seconds */
|
|
||||||
{
|
{
|
||||||
status = sanei_genesys_get_status (dev, &val);
|
DBG (DBG_error, "gl841_end_scan: failed to eject document\n");
|
||||||
if (status != SANE_STATUS_GOOD)
|
return status;
|
||||||
{
|
|
||||||
DBG (DBG_error,
|
|
||||||
"gl841_end_scan: Failed to read register: %s\n",
|
|
||||||
sane_strstatus (status));
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!(val & REG41_MOTORENB)) && (val & REG41_SCANFSH))
|
|
||||||
{
|
|
||||||
DBG (DBG_proc, "gl841_end_scan: scan finished\n");
|
|
||||||
break; /* leave while loop */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
usleep (10000); /* sleep 100 ms */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else /* flat bed scanners */
|
||||||
|
{
|
||||||
|
status = sanei_genesys_write_register (dev, 0x01, sanei_genesys_read_reg_from_set (reg, 0x01) & ~REG01_SCAN); /* disable scan */
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
{
|
||||||
|
DBG (DBG_error, "gl841_end_scan: Failed to write registers: %s\n",
|
||||||
|
sane_strstatus (status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_stop)
|
||||||
|
{
|
||||||
|
for (i = 0; i < 300; i++) /* do not wait longer than 3 seconds */
|
||||||
|
{
|
||||||
|
status = sanei_genesys_get_status (dev, &val);
|
||||||
|
if (status != SANE_STATUS_GOOD)
|
||||||
|
{
|
||||||
|
DBG (DBG_error,
|
||||||
|
"gl841_end_scan: Failed to read register: %s\n",
|
||||||
|
sane_strstatus (status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!(val & REG41_MOTORENB)) && (val & REG41_SCANFSH))
|
||||||
|
{
|
||||||
|
DBG (DBG_proc, "gl841_end_scan: scan finished\n");
|
||||||
|
break; /* leave while loop */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
usleep (10000); /* sleep 100 ms */
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DBG (DBG_proc, "gl841_end_scan: completed (i=%u)\n", i);
|
DBG (DBG_proc, "gl841_end_scan: completed (i=%u)\n", i);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
@ -3524,6 +3883,13 @@ gl841_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
|
||||||
DBG (DBG_proc, "gl841_slow_back_home (wait_until_home = %d)\n",
|
DBG (DBG_proc, "gl841_slow_back_home (wait_until_home = %d)\n",
|
||||||
wait_until_home);
|
wait_until_home);
|
||||||
|
|
||||||
|
if (dev->model->is_sheetfed == SANE_TRUE)
|
||||||
|
{
|
||||||
|
DBG (DBG_proc, "gl841_slow_back_home: there is no \"home\"-concept for sheet fed\n");
|
||||||
|
DBG (DBG_proc, "gl841_slow_back_home: finished\n");
|
||||||
|
return SANE_STATUS_GOOD;
|
||||||
|
}
|
||||||
|
|
||||||
memset (local_reg, 0, sizeof (local_reg));
|
memset (local_reg, 0, sizeof (local_reg));
|
||||||
val = 0;
|
val = 0;
|
||||||
status = sanei_genesys_get_status (dev, &val);
|
status = sanei_genesys_get_status (dev, &val);
|
||||||
|
@ -5135,11 +5501,6 @@ gl841_init (Genesys_Device * dev)
|
||||||
/* Set default values for registers */
|
/* Set default values for registers */
|
||||||
gl841_init_registers (dev);
|
gl841_init_registers (dev);
|
||||||
|
|
||||||
/* Init device */
|
|
||||||
val = 0x04;
|
|
||||||
RIE (sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_REGISTER,
|
|
||||||
VALUE_INIT, INDEX, 1, &val));
|
|
||||||
|
|
||||||
/* ASIC reset */
|
/* ASIC reset */
|
||||||
RIE (sanei_genesys_write_register (dev, 0x0e, 0x00));
|
RIE (sanei_genesys_write_register (dev, 0x0e, 0x00));
|
||||||
|
|
||||||
|
@ -5311,6 +5672,16 @@ gl841_update_hardware_sensors (Genesys_Scanner * s)
|
||||||
s->val[OPT_COPY_SW].b = (val & 0x08) == 0;
|
s->val[OPT_COPY_SW].b = (val & 0x08) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (s->dev->model->gpo_type == GPO_XP300)
|
||||||
|
{
|
||||||
|
RIE(sanei_genesys_read_register(s->dev, 0x6d, &val));
|
||||||
|
|
||||||
|
if (s->val[OPT_PAGE_LOADED_SW].b == s->last_val[OPT_PAGE_LOADED_SW].b)
|
||||||
|
s->val[OPT_PAGE_LOADED_SW].b = (val & 0x01) == 0;
|
||||||
|
if (s->val[OPT_SCAN_SW].b == s->last_val[OPT_SCAN_SW].b)
|
||||||
|
s->val[OPT_SCAN_SW].b = (val & 0x02) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5361,9 +5732,10 @@ static Genesys_Command_Set gl841_cmd_set = {
|
||||||
|
|
||||||
gl841_update_hardware_sensors,
|
gl841_update_hardware_sensors,
|
||||||
|
|
||||||
NULL,
|
gl841_load_document,
|
||||||
NULL,
|
gl841_detect_document_end,
|
||||||
NULL,
|
gl841_eject_document,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SANE_Status
|
SANE_Status
|
||||||
|
|
|
@ -246,6 +246,7 @@ Genesys_Color_Order;
|
||||||
#define DAC_WOLFSON_HP2300 5
|
#define DAC_WOLFSON_HP2300 5
|
||||||
#define DAC_CANONLIDE35 6
|
#define DAC_CANONLIDE35 6
|
||||||
#define DAC_AD_XP200 7 /* Analog Device frontend */
|
#define DAC_AD_XP200 7 /* Analog Device frontend */
|
||||||
|
#define DAC_WOLFSON_XP300 8
|
||||||
|
|
||||||
#define CCD_UMAX 0
|
#define CCD_UMAX 0
|
||||||
#define CCD_ST12 1 /* SONY ILX548: 5340 Pixel ??? */
|
#define CCD_ST12 1 /* SONY ILX548: 5340 Pixel ??? */
|
||||||
|
@ -255,6 +256,7 @@ Genesys_Color_Order;
|
||||||
#define CCD_HP2300 5
|
#define CCD_HP2300 5
|
||||||
#define CCD_CANONLIDE35 6
|
#define CCD_CANONLIDE35 6
|
||||||
#define CIS_XP200 7 /* CIS sensor for Strobe XP200 */
|
#define CIS_XP200 7 /* CIS sensor for Strobe XP200 */
|
||||||
|
#define CCD_XP300 8
|
||||||
|
|
||||||
#define GPO_UMAX 0
|
#define GPO_UMAX 0
|
||||||
#define GPO_ST12 1
|
#define GPO_ST12 1
|
||||||
|
@ -264,6 +266,7 @@ Genesys_Color_Order;
|
||||||
#define GPO_HP2300 5
|
#define GPO_HP2300 5
|
||||||
#define GPO_CANONLIDE35 6
|
#define GPO_CANONLIDE35 6
|
||||||
#define GPO_XP200 7
|
#define GPO_XP200 7
|
||||||
|
#define GPO_XP300 8
|
||||||
|
|
||||||
#define MOTOR_UMAX 0
|
#define MOTOR_UMAX 0
|
||||||
#define MOTOR_5345 1
|
#define MOTOR_5345 1
|
||||||
|
@ -272,7 +275,7 @@ Genesys_Color_Order;
|
||||||
#define MOTOR_HP2300 4
|
#define MOTOR_HP2300 4
|
||||||
#define MOTOR_CANONLIDE35 5
|
#define MOTOR_CANONLIDE35 5
|
||||||
#define MOTOR_XP200 6
|
#define MOTOR_XP200 6
|
||||||
|
#define MOTOR_XP300 7
|
||||||
|
|
||||||
/* Forward typedefs */
|
/* Forward typedefs */
|
||||||
typedef struct Genesys_Device Genesys_Device;
|
typedef struct Genesys_Device Genesys_Device;
|
||||||
|
|
|
@ -77,3 +77,14 @@
|
||||||
:usbid "0x04a7" "0x0426"
|
:usbid "0x04a7" "0x0426"
|
||||||
:status :basic
|
:status :basic
|
||||||
:comment "All resolution and mode supported, but uncorrected scans"
|
:comment "All resolution and mode supported, but uncorrected scans"
|
||||||
|
|
||||||
|
; -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
:mfg "Visioneer"
|
||||||
|
:url "http://www.visioneer.com/"
|
||||||
|
|
||||||
|
:model "Strobe XP 300"
|
||||||
|
:interface "USB"
|
||||||
|
:usbid "0x04a7" "0x0474"
|
||||||
|
:status :basic
|
||||||
|
:comment "All resolution and mode supported, but uncorrected scans, front- and backside side-by-side, with backside mirrored horizontally."
|
||||||
|
|
Ładowanie…
Reference in New Issue