Merge branch 'genesys-canoscan-8400f' into 'master'

genesys: Implement regular and transparency scans for Canon CanoScan 8400F

See merge request sane-project/backends!100
merge-requests/102/head
Povilas Kanapickas 2019-08-08 20:09:54 +00:00
commit 7d1617e4c0
8 zmienionych plików z 255 dodań i 78 usunięć

Wyświetl plik

@ -3156,16 +3156,19 @@ genesys_flatbed_calibration(Genesys_Device * dev, Genesys_Sensor& sensor)
{
SANE_Status status = SANE_STATUS_GOOD;
uint32_t pixels_per_line;
int yres;
DBG(DBG_info, "%s\n", __func__);
yres = sensor.optical_res;
if (dev->settings.yres <= sensor.optical_res / 2)
yres /= 2;
unsigned coarse_res = sensor.optical_res;
if (dev->settings.yres <= sensor.optical_res / 2) {
coarse_res /= 2;
}
if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F)
yres = 1200;
if (dev->model->model_id == MODEL_CANON_CANOSCAN_8400F ||
dev->model->model_id == MODEL_CANON_CANOSCAN_8600F)
{
coarse_res = 1200;
}
/* do offset calibration if needed */
if (dev->model->flags & GENESYS_FLAG_OFFSET_CALIBRATION)
@ -3180,7 +3183,7 @@ genesys_flatbed_calibration(Genesys_Device * dev, Genesys_Sensor& sensor)
/* since all the registers are set up correctly, just use them */
sanei_usb_testing_record_message("coarse_gain_calibration");
status = dev->model->cmd_set->coarse_gain_calibration(dev, sensor, dev->calib_reg, yres);
status = dev->model->cmd_set->coarse_gain_calibration(dev, sensor, dev->calib_reg, coarse_res);
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: coarse gain calibration: %s\n", __func__, sane_strstatus(status));
@ -3237,7 +3240,7 @@ genesys_flatbed_calibration(Genesys_Device * dev, Genesys_Sensor& sensor)
/* since all the registers are set up correctly, just use them */
sanei_usb_testing_record_message("coarse_gain_calibration");
status = dev->model->cmd_set->coarse_gain_calibration(dev, sensor, dev->calib_reg, yres);
status = dev->model->cmd_set->coarse_gain_calibration(dev, sensor, dev->calib_reg, coarse_res);
if (status != SANE_STATUS_GOOD)
{
DBG(DBG_error, "%s: coarse gain calibration: %s\n", __func__, sane_strstatus(status));

Wyświetl plik

@ -66,6 +66,9 @@ usb 0x04a9 0x190f
# Canon 5600F
usb 0x04a9 0x1906
# Canon 8400F
usb 0x04a9 0x221e
# Canon 8600F
usb 0x04a9 0x2229

Wyświetl plik

@ -1565,45 +1565,184 @@ void genesys_init_sensor_tables()
sensor = Genesys_Sensor();
sensor.sensor_id = CCD_CS8400F;
sensor.optical_res = 4800;
sensor.ccd_size_divisor = 2;
sensor.black_pixels = 50*8;
// 31 at 600 dpi, 58 at 1200 dpi
sensor.dummy_pixel = 20;
sensor.CCD_start_xoffset = 152;
// 5360 max at 600 dpi
sensor.sensor_pixels = 5360*8;
sensor.sensor_pixels = 13600*4;
sensor.fau_gain_white_ref = 160;
sensor.gain_white_ref = 160;
sensor.exposure = { 0x9c40, 0x9c40, 0x9c40 };
sensor.exposure_lperiod = 7200;
sensor.custom_regs = {
{ 0x74, 0x00 }, { 0x75, 0x0e }, { 0x76, 0x3f },
{ 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
{ 0x7a, 0x01 }, { 0x7b, 0xb6 }, { 0x7c, 0xdb },
{ 0x0c, 0x00 },
{ 0x70, 0x01 },
{ 0x71, 0x02 },
{ 0x9e, 0x00 },
{ 0xaa, 0x00 },
{ 0x16, 0x33 },
{ 0x17, 0x0c },
{ 0x18, 0x13 },
{ 0x19, 0x2a },
{ 0x1a, 0x30 },
{ 0x1b, 0x00 },
{ 0x1c, 0x00 },
{ 0x1d, 0x84 },
{ 0x52, 0x0d },
{ 0x53, 0x10 },
{ 0x54, 0x01 },
{ 0x55, 0x04 },
{ 0x56, 0x07 },
{ 0x57, 0x0a },
{ 0x58, 0x6b },
{ 0x59, 0x00 },
{ 0x5a, 0x40 },
};
sensor.custom_regs = {};
sensor.gamma = {1.0, 1.0, 1.0};
s_sensors->push_back(sensor);
{
struct CustomSensorSettings {
int min_resolution;
int max_resolution;
int exposure_lperiod;
ScanMethod method;
GenesysRegisterSettingSet extra_custom_regs;
GenesysRegisterSettingSet custom_fe_regs;
};
CustomSensorSettings custom_settings[] = {
{ -1, 600, 7200, ScanMethod::FLATBED, {
{ 0x74, 0x00 }, { 0x75, 0x0e }, { 0x76, 0x3f },
{ 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
{ 0x7a, 0x01 }, { 0x7b, 0xb6 }, { 0x7c, 0xdb },
{ 0x70, 0x01 },
{ 0x71, 0x02 },
{ 0x72, 0x03 },
{ 0x73, 0x04 },
{ 0x16, 0x33 },
{ 0x17, 0x0c },
{ 0x18, 0x13 },
{ 0x19, 0x2a },
{ 0x1a, 0x30 },
{ 0x1b, 0x00 },
{ 0x1c, 0x00 },
{ 0x1d, 0x84 },
{ 0x52, 0x0d },
{ 0x53, 0x10 },
{ 0x54, 0x01 },
{ 0x55, 0x04 },
{ 0x56, 0x07 },
{ 0x57, 0x0a },
{ 0x58, 0x6b },
{ 0x59, 0x00 },
{ 0x5a, 0x40 },
{ 0x1e, 0xa0 },
{ 0x80, 0x20 },
}, {}
},
{ 1200, 1200, 14400, ScanMethod::FLATBED, {
{ 0x74, 0x00 }, { 0x75, 0x01 }, { 0x76, 0xff },
{ 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
{ 0x7a, 0x02 }, { 0x7b, 0x49 }, { 0x7c, 0x24 },
{ 0x70, 0x01 },
{ 0x71, 0x02 },
{ 0x72, 0x02 },
{ 0x73, 0x03 },
{ 0x16, 0x33 },
{ 0x17, 0x0c },
{ 0x18, 0x11 },
{ 0x19, 0x2a },
{ 0x1a, 0x30 },
{ 0x1b, 0x00 },
{ 0x1c, 0x00 },
{ 0x1d, 0x84 },
{ 0x52, 0x0b },
{ 0x53, 0x0e },
{ 0x54, 0x11 },
{ 0x55, 0x02 },
{ 0x56, 0x05 },
{ 0x57, 0x08 },
{ 0x58, 0x63 },
{ 0x59, 0x00 },
{ 0x5a, 0x40 },
{ 0x1e, 0xa1 },
{ 0x80, 0x28 },
}, {
{ 0x03, 0x1f },
}
},
{ -1, 600, 14400, ScanMethod::TRANSPARENCY, {
{ 0x16, 0x33 },
{ 0x17, 0x0c },
{ 0x18, 0x13 },
{ 0x19, 0x2a },
{ 0x1a, 0x30 },
{ 0x1b, 0x00 },
{ 0x1c, 0x00 },
{ 0x1d, 0x84 },
{ 0x1e, 0xa0 },
{ 0x52, 0x0d },
{ 0x53, 0x10 },
{ 0x54, 0x01 },
{ 0x55, 0x04 },
{ 0x56, 0x07 },
{ 0x57, 0x0a },
{ 0x58, 0x6b },
{ 0x59, 0x00 },
{ 0x5a, 0x40 },
{ 0x74, 0x00 }, { 0x75, 0x0e }, { 0x76, 0x3f },
{ 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
{ 0x7a, 0x01 }, { 0x7b, 0xb6 }, { 0x7c, 0xdb },
{ 0x70, 0x01 }, { 0x71, 0x02 }, { 0x72, 0x03 }, { 0x73, 0x04 },
{ 0x80, 0x20 },
}, {}
},
{ 1200, 1200, 28800, ScanMethod::TRANSPARENCY, {
{ 0x16, 0x33 },
{ 0x17, 0x0c },
{ 0x18, 0x11 },
{ 0x19, 0x2a },
{ 0x1a, 0x30 },
{ 0x1b, 0x00 },
{ 0x1c, 0x00 },
{ 0x1d, 0x84 },
{ 0x1e, 0xa0 },
{ 0x52, 0x0b },
{ 0x53, 0x0e },
{ 0x54, 0x11 },
{ 0x55, 0x02 },
{ 0x56, 0x05 },
{ 0x57, 0x08 },
{ 0x58, 0x63 },
{ 0x59, 0x00 },
{ 0x5a, 0x40 },
{ 0x70, 0x00 }, { 0x71, 0x01 }, { 0x72, 0x02 }, { 0x73, 0x03 },
{ 0x74, 0x00 }, { 0x75, 0x01 }, { 0x76, 0xff },
{ 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
{ 0x7a, 0x02 }, { 0x7b, 0x49 }, { 0x7c, 0x24 },
{ 0x80, 0x29 },
}, {
{ 0x03, 0x1f },
},
},
{ 2400, 2400, 28800, ScanMethod::TRANSPARENCY, {
{ 0x16, 0x33 },
{ 0x17, 0x0c },
{ 0x18, 0x10 },
{ 0x19, 0x2a },
{ 0x1a, 0x30 },
{ 0x1b, 0x00 },
{ 0x1c, 0x20 },
{ 0x1d, 0x84 },
{ 0x1e, 0xa0 },
{ 0x52, 0x02 },
{ 0x53, 0x05 },
{ 0x54, 0x08 },
{ 0x55, 0x0b },
{ 0x56, 0x0e },
{ 0x57, 0x11 },
{ 0x58, 0x1b },
{ 0x59, 0x00 },
{ 0x5a, 0x40 },
{ 0x70, 0x09 }, { 0x71, 0x0a }, { 0x72, 0x0b }, { 0x73, 0x0c },
{ 0x74, 0x00 }, { 0x75, 0x00 }, { 0x76, 0x00 },
{ 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 },
{ 0x7a, 0x02 }, { 0x7b, 0x49 }, { 0x7c, 0x24 },
{ 0x80, 0x2b },
}, {
{ 0x03, 0x1f },
},
},
};
for (const CustomSensorSettings& setting : custom_settings)
{
sensor.min_resolution = setting.min_resolution;
sensor.max_resolution = setting.max_resolution;
sensor.exposure_lperiod = setting.exposure_lperiod;
sensor.method = setting.method;
sensor.custom_regs = setting.extra_custom_regs;
sensor.custom_fe_regs = setting.custom_fe_regs;
s_sensors->push_back(sensor);
}
}
sensor = Genesys_Sensor();
@ -2638,7 +2777,7 @@ static Genesys_Motor Motor[] = {
},
},
{MOTOR_CS8400F,
2400,
1200,
9600,
2,
1,
@ -3162,21 +3301,21 @@ static Genesys_Model canon_8400f_model = {
{16, 8, 0}, /* possible depths in gray mode */
{16, 8, 0}, /* possible depths in color mode */
SANE_FIX (4.0), /* Start of scan area in mm (x) */
SANE_FIX (13.00), /* Start of scan area in mm (y) */
SANE_FIX (217.9), /* Size of scan area in mm (x) 5148 pixels at 600 dpi*/
SANE_FIX (315.0), /* Size of scan area in mm (y) */
SANE_FIX(3.5), // x_offset
SANE_FIX(17.00), // y_offset
SANE_FIX(219.9), // x_size
SANE_FIX(315.0), // y_size
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), // y_offset_calib
SANE_FIX(10.0), // x_offset_mark
SANE_FIX (8.0), /* Start of scan area in TA mode in mm (x) */
SANE_FIX (13.00), /* Start of scan area in TA mode in mm (y) */
SANE_FIX (217.9), /* Size of scan area in TA mode in mm (x) */
SANE_FIX (250.0), /* Size of scan area in TA mode in mm (y) */
SANE_FIX(100.0), // x_offset_ta
SANE_FIX(50.00), // y_offset_ta
SANE_FIX(100.0), // x_size_ta
SANE_FIX(230.0), // y_size_ta
SANE_FIX(0.0), // y_offset_sensor_to_ta
SANE_FIX (40.0), /* Start of white strip in TA mode in mm (y) */
SANE_FIX(22.0), // y_offset_sensor_to_ta
SANE_FIX(25.0), // y_offset_calib_ta
SANE_FIX (0.0), /* Size of scan area after paper sensor stops
sensing document in mm */
@ -3195,17 +3334,18 @@ static Genesys_Model canon_8400f_model = {
DAC_CS8400F,
GPO_CS8400F,
MOTOR_CS8400F,
GENESYS_FLAG_NO_CALIBRATION |
GENESYS_FLAG_HAS_UTA |
GENESYS_FLAG_LAZY_INIT |
GENESYS_FLAG_OFFSET_CALIBRATION |
GENESYS_FLAG_STAGGERED_LINE |
GENESYS_FLAG_SKIP_WARMUP |
GENESYS_FLAG_DARK_CALIBRATION |
GENESYS_FLAG_FULL_HWDPI_MODE |
GENESYS_FLAG_CUSTOM_GAMMA,
GENESYS_FLAG_CUSTOM_GAMMA |
GENESYS_FLAG_SHADING_REPARK,
GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW,
100,
0, // shading_ta_lines
50, // shading_ta_lines
100
};

Wyświetl plik

@ -1709,7 +1709,12 @@ gl843_calculate_current_setup(Genesys_Device * dev, const Genesys_Sensor& sensor
start = SANE_UNFIX(dev->model->x_offset);
}
start /= ccd_size_divisor;
if (dev->model->model_id == MODEL_CANON_CANOSCAN_8400F ||
dev->model->model_id == MODEL_CANON_CANOSCAN_8600F)
{
// FIXME: this is probably just an artifact of a bug elsewhere
start /= ccd_size_divisor;
}
start += dev->settings.tl_x;
start = (start * sensor.optical_res) / MM_PER_INCH;
@ -2112,7 +2117,28 @@ static SANE_Status gl843_set_xpa_motor_power(Genesys_Device *dev, bool set)
DBGSTART;
if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) {
if (dev->model->model_id == MODEL_CANON_CANOSCAN_8400F) {
if (set) {
RIE(sanei_genesys_read_register(dev, 0x6c, &val));
val &= ~(REG6C_GPIO16 | REG6C_GPIO13);
RIE(sanei_genesys_write_register(dev, 0x6c, val));
RIE(sanei_genesys_read_register(dev, 0xa9, &val));
val |= REGA9_GPO30;
val &= ~REGA9_GPO29;
RIE(sanei_genesys_write_register(dev, 0xa9,val));
} else {
RIE(sanei_genesys_read_register(dev, 0x6c, &val));
val |= REG6C_GPIO16 | REG6C_GPIO13;
RIE(sanei_genesys_write_register(dev, 0x6c, val));
RIE(sanei_genesys_read_register(dev, 0xa9, &val));
val &= ~REGA9_GPO30;
val |= REGA9_GPO29;
RIE(sanei_genesys_write_register(dev, 0xa9, val));
}
} else if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) {
if (set) {
RIE(sanei_genesys_read_register(dev, REG6C, &val));
@ -2137,11 +2163,7 @@ static SANE_Status gl843_set_xpa_motor_power(Genesys_Device *dev, bool set)
val &= ~REGA6_GPIO23;
RIE(sanei_genesys_write_register(dev, REGA6,val));
}
DBGCOMPLETED;
return status;
}
if (dev->model->model_id == MODEL_HP_SCANJET_G4050) {
} else if (dev->model->model_id == MODEL_HP_SCANJET_G4050) {
if (set) {
/* set MULTFILM et GPOADF */
@ -2179,12 +2201,10 @@ static SANE_Status gl843_set_xpa_motor_power(Genesys_Device *dev, bool set)
val &= ~REGA9_GPO31;
RIE (sanei_genesys_write_register (dev, REGA9, val));
}
DBGCOMPLETED;
return status;
}
DBGCOMPLETED;
return status;
return SANE_STATUS_GOOD;
}
@ -2301,6 +2321,7 @@ gl843_begin_scan (Genesys_Device * dev, const Genesys_Sensor& sensor, Genesys_Re
/* blinking led */
RIE (sanei_genesys_write_register (dev, REG7E, 0x01));
break;
case GPO_CS8400F:
case GPO_CS8600F:
if (reg->state.is_xpa_on && reg->state.is_lamp_on) {
RIE(gl843_set_xpa_lamp_power(dev, true));
@ -2311,7 +2332,6 @@ gl843_begin_scan (Genesys_Device * dev, const Genesys_Sensor& sensor, Genesys_Re
}
break;
case GPO_CS4400F:
case GPO_CS8400F:
default:
break;
}
@ -3071,7 +3091,13 @@ gl843_init_regs_for_scan (Genesys_Device * dev, const Genesys_Sensor& sensor)
start = SANE_UNFIX(dev->model->x_offset);
}
start /= sensor.get_ccd_size_divisor_for_dpi(dev->settings.xres);
if (dev->model->model_id == MODEL_CANON_CANOSCAN_8400F ||
dev->model->model_id == MODEL_CANON_CANOSCAN_8600F)
{
// FIXME: this is probably just an artifact of a bug elsewhere
start /= sensor.get_ccd_size_divisor_for_dpi(dev->settings.xres);
}
start += dev->settings.tl_x;
start = (start * sensor.optical_res) / MM_PER_INCH;
@ -3978,9 +4004,13 @@ gl843_boot (Genesys_Device * dev, SANE_Bool cold)
RIE (sanei_genesys_write_register (dev, REG0B, val));
dev->reg.find_reg(0x0b).value = val;
if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F)
{
RIE (sanei_genesys_write_0x8c (dev, 0x10, 0xc8));
if (dev->model->model_id == MODEL_CANON_CANOSCAN_8400F) {
RIE(sanei_genesys_write_0x8c(dev, 0x1e, 0x01));
RIE(sanei_genesys_write_0x8c(dev, 0x10, 0xb4));
RIE(sanei_genesys_write_0x8c(dev, 0x0f, 0x02));
}
else if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) {
RIE(sanei_genesys_write_0x8c(dev, 0x10, 0xc8));
}
else
{

Wyświetl plik

@ -466,7 +466,7 @@ static Motor_Profile gl843_motors[]={
{MOTOR_G4050, 42752, 2, g4050_max},
{MOTOR_G4050, 56064, 1, g4050_high},
/* CS8400F */
{MOTOR_CS8400F, 7200, 0, cs8400f_fast},
{MOTOR_CS8400F, 50000, 2, cs8400f_fast},
{ MOTOR_CS8600F, 0x59d8, 2, motor_speeds_cs8600f }, // FIXME: if the exposure is lower then we'll select another motor
{ 0, 0, 0, NULL },
};

Wyświetl plik

@ -1517,7 +1517,8 @@ int sanei_genesys_compute_dpihw(Genesys_Device *dev, const Genesys_Sensor& senso
int sanei_genesys_compute_dpihw_calibration(Genesys_Device *dev, const Genesys_Sensor& sensor,
int xres)
{
if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F)
if (dev->model->model_id == MODEL_CANON_CANOSCAN_8400F ||
dev->model->model_id == MODEL_CANON_CANOSCAN_8600F)
{
// real resolution is half of the "official" resolution - half_ccd mode
int hwres = sensor.optical_res / sensor.get_ccd_size_divisor_for_dpi(xres);

Wyświetl plik

@ -181,6 +181,13 @@
:status :unsupported
:comment "GL847 based, to be added to the genesys backend"
:model "CanoScan 8400F"
:url "unsupported/canon-8400f.html"
:interface "USB"
:usbid "0x04a9" "0x221e"
:status :basic
:comment "GL841 based, to be added to genesys backend"
:model "CanoScan 8600F"
:url "unsupported/canon-8600.html"
:interface "USB"

Wyświetl plik

@ -333,13 +333,6 @@
:status :unsupported
:comment "Not supported. See link for more information. With transparency adapter."
:model "CanoScan 8400F"
:url "unsupported/canon-8400f.html"
:interface "USB"
:usbid "0x04a9" "0x221e"
:status :unsupported
:comment "GL841 based, to be added to genesys backend"
:model "CanoScan 9900F"
:url "unsupported/canon-9900f.html"
:interface "USB"