add support for Plustek Opticbook 3600 by Chris Berry & Michael Rickmann

merge-requests/1/head
Stphane Voltz 2010-12-26 16:40:43 +01:00
rodzic 9106e0f7fa
commit 86c8214e93
4 zmienionych plików z 438 dodań i 16 usunięć

Wyświetl plik

@ -2746,6 +2746,100 @@ compute_planar_coefficients (Genesys_Device * dev,
}
}
#ifndef UNIT_TESTING
static
#endif
void
compute_shifted_coefficients (Genesys_Device * dev,
uint8_t * shading_data,
unsigned int pixels_per_line,
unsigned int channels,
int cmat[3],
int offset,
unsigned int coeff,
unsigned int target_dark,
unsigned int target_bright,
unsigned int patch_size) /* contigous extent */
{
unsigned int x, avgpixels, i, j, val1, val2;
unsigned int br_tmp [3], dk_tmp [3];
uint8_t *ptr = shading_data + offset * 3 * 4; /* contain 16bit words in little endian */
unsigned int patch_cnt = offset * 3; /* at start, offset of first patch */
x = dev->settings.xres;
if ((dev->model->flags & GENESYS_FLAG_HALF_CCD_MODE) &&
(dev->settings.xres <= dev->sensor.optical_res / 2))
x *= 2; /* scanner is using half-ccd mode */
avgpixels = dev->sensor.optical_res / x; /*this should be evenly dividable */
/* gl841 supports 1/1 1/2 1/3 1/4 1/5 1/6 1/8 1/10 1/12 1/15 averaging */
if (avgpixels < 1)
avgpixels = 1;
else if (avgpixels < 6)
avgpixels = avgpixels;
else if (avgpixels < 8)
avgpixels = 6;
else if (avgpixels < 10)
avgpixels = 8;
else if (avgpixels < 12)
avgpixels = 10;
else if (avgpixels < 15)
avgpixels = 12;
else
avgpixels = 15;
DBG (DBG_info, "compute_shifted_coefficients: pixels_per_line=%d, coeff=0x%04x, averaging over %d pixels\n", pixels_per_line, coeff, avgpixels);
for (x = 0; x <= pixels_per_line - avgpixels; x += avgpixels) {
memset (&br_tmp, 0, sizeof(br_tmp));
memset (&dk_tmp, 0, sizeof(dk_tmp));
for (i = 0; i < avgpixels; i++) {
for (j = 0; j < channels; j++) {
br_tmp[j] += (dev->white_average_data[((x + i) * channels + j) * 2] |
(dev->white_average_data[((x + i) * channels + j) * 2 + 1] << 8));
dk_tmp[i] += (dev->dark_average_data[((x + i) * channels + j) * 2] |
(dev->dark_average_data[((x + i) * channels + j) * 2 + 1] << 8));
}
}
for (j = 0; j < channels; j++) {
br_tmp[j] /= avgpixels;
dk_tmp[j] /= avgpixels;
if (br_tmp[j] * target_dark > dk_tmp[j] * target_bright)
val1 = 0;
else if (dk_tmp[j] * target_bright - br_tmp[j] * target_dark > 65535 * (target_bright - target_dark))
val1 = 65535;
else
val1 = (dk_tmp[j] * target_bright - br_tmp[j] * target_dark) / (target_bright - target_dark);
val2 = br_tmp[j] - dk_tmp[j];
if (65535 * val2 > (target_bright - target_dark) * coeff)
val2 = (coeff * (target_bright - target_dark)) / val2;
else
val2 = 65535;
br_tmp[j] = val1;
dk_tmp[j] = val2;
}
for (i = 0; i < avgpixels; i++) {
for (j = 0; j < channels; j++) {
* ptr++ = br_tmp[ cmat[j] ] & 0xff;
* ptr++ = br_tmp[ cmat[j] ] >> 8;
* ptr++ = dk_tmp[ cmat[j] ] & 0xff;
* ptr++ = dk_tmp[ cmat[j] ] >> 8;
patch_cnt++;
if (patch_cnt == patch_size) {
patch_cnt = 0;
val1 = cmat[2];
cmat[2] = cmat[1];
cmat[1] = cmat[0];
cmat[0] = val1;
}
}
}
}
}
static SANE_Status
genesys_send_shading_coefficient (Genesys_Device * dev)
{
@ -3143,6 +3237,18 @@ genesys_send_shading_coefficient (Genesys_Device * dev)
}
*/
break;
case CCD_PLUSTEK_3600:
compute_shifted_coefficients (dev,
shading_data,
pixels_per_line,
channels,
cmat,
12, /* offset */
coeff,
0x0001, /* target_dark */
0xf900, /* target_bright */
256); /* patch_size: contigous extent */
break;
default:
DBG (DBG_error,
"genesys_send_shading_coefficient: sensor %d not supported\n",

Wyświetl plik

@ -170,6 +170,14 @@ static Genesys_Frontend Wolfson[] = {
, {0x00, 0x00, 0x00}
}
,
{DAC_PLUSTEK_3600,
{0x70, 0x80, 0x00, 0x00}
, {0x00, 0x00, 0x00}
, {0x00, 0x00, 0x00}
, {0x3f, 0x3d, 0x3d}
, {0x00, 0x00, 0x00}
}
,
};
@ -533,6 +541,28 @@ static Genesys_Sensor Sensor[] = {
1.7, 1.7, 1.7,
NULL, NULL, NULL}
,
{CCD_PLUSTEK_3600, 1200,
/*TODO: find a good reason for keeping all three following variables*/
87, /*(black) */
87, /* (dummy) */
0, /* (startxoffset) */
10100, /*sensor_pixels */
210,
230,
{0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x0b, 0x11, 0x2a,
0x00, 0x00, 0x00, 0xc4 /* TODO(these do no harm, but may be neccessery for CCD) */
},
{0x07, 0x0a,
0x0c, 0x00, 0x02, 0x06, /*[GB](HI|LOW) not needed for cis */
0x22, 0x69,
0x40, /*TODO: bit7 */
0x00, 0x00, 0x00, 0x02 /*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:
@ -653,6 +683,11 @@ static Genesys_Gpo Gpo[] = {
{0xff, 0x00},
}
,
/* Plustek 3600 */
{GPO_PLUSTEK_3600,
{0x02, 0x00},
{0x1e, 0x80},
}
};
static Genesys_Motor Motor[] = {
@ -936,6 +971,17 @@ static Genesys_Motor Motor[] = {
},
},
},
{MOTOR_PLUSTEK_3600, /* PLUSTEK 3600 */
1200,
2400,
1,
1,
{
{
{ 3500, 1300, 60, 0.8 },
{ 3500, 3250, 60, 0.8 },
},
},},
};
/* here we have the various device settings...
@ -2523,26 +2569,83 @@ static Genesys_Model xerox_travelscanner_model = {
400
};
static Genesys_Model plustek_3600_model = {
"plustek-opticbook-3600", /* Name */
"PLUSTEK", /* Device vendor string */
"OpticBook 3600", /* Device model name */
GENESYS_GL841,
NULL,
{/*1200,*/ 600, 400, 300, 200, 150, 100, 75, 0}, /* possible x-resolutions */
{/*2400,*/ 1200, 600, 400, 300, 200, 150, 100, 75, 0}, /* possible y-resolutions */
{16, 8, 0}, /* possible depths in gray mode */
{16, 8, 0}, /* possible depths in color mode */
SANE_FIX (0.42),/*SANE_FIX (0.42), Start of scan area in mm (x) */
SANE_FIX (6.75),/*SANE_FIX (7.9), Start of scan area in mm (y) */
SANE_FIX (216.0),/*SANE_FIX (216.0), Size of scan area in mm (x) */
SANE_FIX (297.0),/*SANE_FIX (297.0), Size of scan area in mm (y) */
SANE_FIX (0.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 (0.0), /* Size of scan area in TA mode in mm (x) */
SANE_FIX (0.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) */
SANE_FIX (0.0), /* Size of scan area after paper sensor stops
sensing document in mm */
SANE_FIX (0.0), /* Amount of feeding needed to eject document
after finishing scanning in mm */
0, 24, 48, /* RGB CCD Line-distance correction in pixel */
COLOR_ORDER_RGB, /* Order of the CCD/CIS colors */
SANE_FALSE, /* Is this a CIS scanner? */
SANE_FALSE, /* Is this a sheetfed scanner? */
CCD_PLUSTEK_3600,
DAC_PLUSTEK_3600,
GPO_PLUSTEK_3600,
MOTOR_PLUSTEK_3600,
GENESYS_FLAG_UNTESTED /* not fully working yet */
| GENESYS_FLAG_CUSTOM_GAMMA
| GENESYS_FLAG_SKIP_WARMUP
| GENESYS_FLAG_DARK_CALIBRATION
| GENESYS_FLAG_OFFSET_CALIBRATION
| GENESYS_FLAG_LAZY_INIT
| GENESYS_FLAG_HALF_CCD_MODE,/*
| GENESYS_FLAG_NO_CALIBRATION,*/
GENESYS_HAS_NO_BUTTONS,
7,
200
};
static Genesys_USB_Device_Entry genesys_usb_device_list[] = {
/* GL646 devices */
{0x03f0, 0x0901, &hp2300c_model},
{0x03f0, 0x0a01, &hp2400c_model},
{0x03f0, 0x1405, &hp3670c_model},
{0x0461, 0x0377, &medion_md5345_model},
{0x04a7, 0x0229, &visioneer_7100_model},
{0x04a7, 0x0426, &visioneer_xp200_model},
{0x0638, 0x0a10, &umax_astra_4500_model},
{0x07b3, 0x0600, &plustek_st12_model},
{0x07b3, 0x0601, &plustek_st24_model},
/* GL841 devices */
{0x04a7, 0x0474, &visioneer_xp300_model},
{0x04a7, 0x0494, &visioneer_roadwarrior_model},
{0x04a7, 0x049b, &visioneer_xp100_r3_model},
{0x04a7, 0x04ac, &xerox_travelscanner_model},
{0x04a9, 0x2213, &canon_lide_50_model},
{0x04a9, 0x221c, &canon_lide_60_model},
{0x0638, 0x0a10, &umax_astra_4500_model},
{0x07b3, 0x0600, &plustek_st12_model},
{0x07b3, 0x0601, &plustek_st24_model},
{0x07b3, 0x0900, &plustek_3600_model},
{0x0a17, 0x3210, &pentax_dsmobile_600_model},
{0x04f9, 0x2038, &pentax_dsmobile_600_model},
{0x04f9, 0x2038, &pentax_dsmobile_600_model}, /* clone, only usb id is different */
{0x0a82, 0x4800, &syscan_docketport_485_model},
{0x0a82, 0x4802, &syscan_docketport_465_model},
{0x0a82, 0x4803, &syscan_docketport_665_model},

Wyświetl plik

@ -1444,9 +1444,16 @@ gl841_init_registers (Genesys_Device * dev)
dev->reg[reg_0x01].value = 0x20; /* (enable shading), CCD, color, 1M */
dev->reg[reg_0x01].value |= REG01_CISSET;
if (dev->model->is_cis == SANE_TRUE)
{
dev->reg[reg_0x01].value |= REG01_CISSET;
}
else
{
dev->reg[reg_0x01].value &= ~REG01_CISSET;
}
dev->reg[reg_0x02].value = 0x30 /*0x38 */ ; /* auto home, one-table-move, full step */
dev->reg[reg_0x02].value = 0x30 /*0x38 */ ; /* auto home, one-table-move, full step */
dev->reg[reg_0x02].value |= REG02_AGOHOME;
dev->reg[reg_0x02].value |= REG02_MTRPWR;
dev->reg[reg_0x02].value |= REG02_FASTFED;
@ -1454,7 +1461,14 @@ gl841_init_registers (Genesys_Device * dev)
dev->reg[reg_0x03].value = 0x1f /*0x17 */ ; /* lamp on */
dev->reg[reg_0x03].value |= REG03_AVEENB;
dev->reg[reg_0x04].value |= 1 << REG04S_AFEMOD;
if (dev->model->ccd_type == CCD_PLUSTEK_3600) /* AD front end */
{
dev->reg[reg_0x04].value = (2 << REG04S_AFEMOD) | 0x02;
}
else /* Wolfson front end */
{
dev->reg[reg_0x04].value |= 1 << REG04S_AFEMOD;
}
dev->reg[reg_0x05].value = 0x00; /* disable gamma, 24 clocks/pixel */
if (dev->sensor.sensor_pixels < 0x1500)
@ -1476,7 +1490,8 @@ gl841_init_registers (Genesys_Device * dev)
dev->reg[reg_0x06].value |= REG06_GAIN4;
/* XP300 CCD needs different clock and clock/pixels values */
if (dev->model->ccd_type != CCD_XP300 && dev->model->ccd_type != CCD_DP685)
if (dev->model->ccd_type != CCD_XP300 && dev->model->ccd_type != CCD_DP685
&& dev->model->ccd_type != CCD_PLUSTEK_3600)
{
dev->reg[reg_0x06].value |= 0 << REG06S_SCANMOD;
dev->reg[reg_0x09].value |= 1 << REG09S_CLKSET;
@ -1630,6 +1645,132 @@ gl841_send_slope_table (Genesys_Device * dev, int table_nr,
return status;
}
/* Set values of Analog Device type frontend */
static SANE_Status
gl841_set_ad_fe (Genesys_Device * dev, uint8_t set)
{
SANE_Status status = SANE_STATUS_GOOD;
int i;
DBG (DBG_proc, "gl841_set_ad_fe(): start\n");
if (set == AFE_INIT)
{
DBG (DBG_proc, "gl841_set_ad_fe(): setting DAC %u\n",
dev->model->dac_type);
/* sets to default values */
sanei_genesys_init_fe (dev);
/* write them to analog frontend */
status = sanei_genesys_fe_write_data (dev, 0x00, dev->frontend.reg[0]);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "gl841_set_ad_fe: writing reg 0x00 failed: %s\n",
sane_strstatus (status));
return status;
}
status = sanei_genesys_fe_write_data (dev, 0x01, dev->frontend.reg[1]);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "gl841_set_ad_fe: writing reg 0x01 failed: %s\n",
sane_strstatus (status));
return status;
}
for (i = 0; i < 6; i++)
{
status =
sanei_genesys_fe_write_data (dev, 0x02 + i, 0x00);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error,
"gl841_set_ad_fe: writing sign[%d] failed: %s\n", 0x02 + i,
sane_strstatus (status));
return status;
}
}
}
if (set == AFE_SET)
{
/* write them to analog frontend */
status = sanei_genesys_fe_write_data (dev, 0x00, dev->frontend.reg[0]);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "gl841_set_ad_fe: writing reg 0x00 failed: %s\n",
sane_strstatus (status));
return status;
}
status = sanei_genesys_fe_write_data (dev, 0x01, dev->frontend.reg[1]);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "gl841_set_ad_fe: writing reg 0x01 failed: %s\n",
sane_strstatus (status));
return status;
}
/* Write fe 0x02 (red gain)*/
status = sanei_genesys_fe_write_data (dev, 0x02, dev->frontend.gain[0]);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "gl841_set_ad_fe: writing fe 0x02 (gain r) fail: %s\n",
sane_strstatus (status));
return status;
}
/* Write fe 0x03 (green gain)*/
status = sanei_genesys_fe_write_data (dev, 0x03, dev->frontend.gain[1]);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "gl841_set_ad_fe: writing fe 0x03 (gain g) fail: %s\n",
sane_strstatus (status));
return status;
}
/* Write fe 0x04 (blue gain)*/
status = sanei_genesys_fe_write_data (dev, 0x04, dev->frontend.gain[2]);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "gl841_set_ad_fe: writing fe 0x04 (gain b) fail: %s\n",
sane_strstatus (status));
return status;
}
/* Write fe 0x05 (red offset)*/
status =
sanei_genesys_fe_write_data (dev, 0x05, dev->frontend.offset[0]);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "gl841_set_ad_fe: write fe 0x05 (offset r) fail: %s\n",
sane_strstatus (status));
return status;
}
/* Write fe 0x06 (green offset)*/
status =
sanei_genesys_fe_write_data (dev, 0x06, dev->frontend.offset[1]);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "gl841_set_ad_fe: write fe 0x06 (offset g) fail: %s\n",
sane_strstatus (status));
return status;
}
/* Write fe 0x07 (blue offset)*/
status =
sanei_genesys_fe_write_data (dev, 0x07, dev->frontend.offset[2]);
if (status != SANE_STATUS_GOOD)
{
DBG (DBG_error, "gl841_set_ad_fe: write fe 0x07 (offset b) fail: %s\n",
sane_strstatus (status));
return status;
}
}
DBG (DBG_proc, "gl841_set_ad_fe(): end\n");
return status;
}
/* Set values of analog frontend */
static SANE_Status
gl841_set_fe (Genesys_Device * dev, uint8_t set)
@ -1642,6 +1783,12 @@ gl841_set_fe (Genesys_Device * dev, uint8_t set)
set == AFE_INIT ? "init" : set == AFE_SET ? "set" : set ==
AFE_POWER_SAVE ? "powersave" : "huh?");
/* Analog Device type frontend */
if ((dev->reg[reg_0x04].value & REG04_FESET) == 0x02)
{
return gl841_set_ad_fe (dev, set);
}
if ((dev->reg[reg_0x04].value & REG04_FESET) != 0x00)
{
DBG (DBG_proc, "gl841_set_fe(): unsupported frontend type %d\n",
@ -2517,7 +2664,6 @@ gl841_init_optical_regs_scan(Genesys_Device * dev,
}
/* enable shading */
/* dev->reg[reg_0x01].value |= REG01_DVDSET | REG01_SCAN;*/
r = sanei_genesys_get_address (reg, 0x01);
r->value |= REG01_SCAN;
if ((flags & OPTICAL_FLAG_DISABLE_SHADING) ||
@ -2542,10 +2688,12 @@ gl841_init_optical_regs_scan(Genesys_Device * dev,
if (flags & OPTICAL_FLAG_DISABLE_LAMP)
r->value = 0x01;/* 0x0101 is as off as possible */
else
{ /* EXP[R,G,B] only matter for CIS scanners */
if (dev->sensor.regs_0x10_0x1d[i] == 0x00)
r->value = 0x01;/*0x00 will not be accepted*/
r->value = 0x01; /*0x00 will not be accepted*/
else
r->value = dev->sensor.regs_0x10_0x1d[i];
}
}
r = sanei_genesys_get_address (reg, 0x19);
@ -2578,8 +2726,10 @@ gl841_init_optical_regs_scan(Genesys_Device * dev,
}
r->value &= ~(REG04_FILTER | REG04_AFEMOD);
if (channels == 1) {
switch (color_filter) {
if (channels == 1)
{
switch (color_filter)
{
case 0:
r->value |= 0x14; /* red filter */
break;
@ -2590,8 +2740,18 @@ gl841_init_optical_regs_scan(Genesys_Device * dev,
r->value |= 0x18; /* green filter */
break;
}
} else
r->value |= 0x10; /* color pixel by pixel */
}
else
{
if (dev->model->ccd_type == CCD_PLUSTEK_3600)
{
r->value |= 0x22; /* slow color pixel by pixel */
}
else
{
r->value |= 0x10; /* color pixel by pixel */
}
}
/* CIS scanners can do true gray by setting LEDADD */
if (dev->model->is_cis == SANE_TRUE)
@ -4030,7 +4190,14 @@ gl841_begin_scan (Genesys_Device * dev, Genesys_Register_Set * reg,
DBG (DBG_proc, "gl841_begin_scan\n");
local_reg[0].address = 0x03;
local_reg[0].value = sanei_genesys_read_reg_from_set (reg, 0x03) | REG03_LAMPPWR;
if (dev->model->ccd_type != CCD_PLUSTEK_3600)
{
local_reg[0].value = sanei_genesys_read_reg_from_set (reg, 0x03) | REG03_LAMPPWR;
}
else
{
local_reg[0].value = sanei_genesys_read_reg_from_set (reg, 0x03); /* TODO PLUSTEK_3600: why ?? */
}
local_reg[1].address = 0x01;
local_reg[1].value = sanei_genesys_read_reg_from_set (reg, 0x01) | REG01_SCAN; /* set scan bit */
@ -4487,15 +4654,22 @@ static SANE_Status
gl841_init_regs_for_shading (Genesys_Device * dev)
{
SANE_Status status;
SANE_Int ydpi;
DBG (DBG_proc, "gl841_init_regs_for_shading: lines = %d\n",
dev->model->shading_lines);
ydpi = dev->motor.base_ydpi;
if (dev->motor.motor_id == MOTOR_PLUSTEK_3600) /* TODO PLUSTEK_3600: 1200dpi not yet working, produces dark bar */
{
ydpi = 600;
}
dev->calib_channels = 3;
status = gl841_init_scan_regs (dev,
dev->calib_reg,
dev->settings.xres,
dev->motor.base_ydpi,
ydpi,
0,
0,
(dev->sensor.sensor_pixels * dev->settings.xres) / dev->sensor.optical_res,
@ -4954,6 +5128,29 @@ gl841_led_calibration (Genesys_Device * dev)
return status;
}
/** @brief calibration for AD frontend devices
* experiments show that modifying offset is of little (if no) influence
* so we just return
* CHRIS: This was added from gl646.c as again offset seems to make no
* difference
*
* TODO PLUSTEK_3600 Michael Rickmann:
* offset calibration makes a lot of a difference but currently
* makes everything to dark
*/
static SANE_Status
ad_fe_offset_calibration (Genesys_Device * dev)
{
SANE_Status status = SANE_STATUS_GOOD;
DBG (DBG_proc, "ad_fe_offset_calibration: start\n");
DBG (DBG_info, "ad_fe_offset_calibration: offset=(%d,%d,%d)\n",
dev->frontend.offset[0], dev->frontend.offset[1],
dev->frontend.offset[2]);
DBG (DBG_proc, "ad_fe_offset_calibration: end\n");
return status;
}
/* this function does the offset calibration by scanning one line of the calibration
area below scanner's top. There is a black margin and the remaining is white.
sanei_genesys_search_start() must have been called so that the offsets and margins
@ -4980,6 +5177,12 @@ gl841_offset_calibration (Genesys_Device * dev)
SANE_Bool acceptable = SANE_FALSE;
int mintgt = 0x400;
/* Analog Device fronted have a different calibration */
if (dev->model->dac_type == DAC_PLUSTEK_3600)
{
return ad_fe_offset_calibration (dev);
}
DBG (DBG_proc, "gl841_offset_calibration\n");
/* offset calibration is always done in color mode */
@ -5637,6 +5840,12 @@ gl841_is_compatible_calibration (Genesys_Device * dev,
DBG (DBG_proc, "gl841_is_compatible_calibration\n");
/* calibration cache not working yet for this model */
if (dev->model->ccd_type == CCD_PLUSTEK_3600)
{
return SANE_STATUS_UNSUPPORTED;
}
status = gl841_calculate_current_setup (dev);
if (status != SANE_STATUS_GOOD)

Wyświetl plik

@ -266,6 +266,7 @@ Genesys_Color_Order;
#define DAC_KVSS080 12
#define DAC_G4050 13
#define DAC_CANONLIDE110 14
#define DAC_PLUSTEK_3600 15
#define CCD_UMAX 0
#define CCD_ST12 1 /* SONY ILX548: 5340 Pixel ??? */
@ -287,6 +288,7 @@ Genesys_Color_Order;
#define CCD_KVSS080 17
#define CCD_G4050 18
#define CIS_CANONLIDE110 19
#define CCD_PLUSTEK_3600 20
#define GPO_UMAX 0
#define GPO_ST12 1
@ -304,6 +306,7 @@ Genesys_Color_Order;
#define GPO_KVSS080 13
#define GPO_G4050 14
#define GPO_CANONLIDE110 15
#define GPO_PLUSTEK_3600 16
#define MOTOR_UMAX 0
#define MOTOR_5345 1
@ -322,6 +325,7 @@ Genesys_Color_Order;
#define MOTOR_KVSS080 15
#define MOTOR_G4050 16
#define MOTOR_CANONLIDE110 17
#define MOTOR_PLUSTEK_3600 18
/* Forward typedefs */