diff --git a/backend/genesys.cc b/backend/genesys.cc index ea1882195..ecc0343bc 100644 --- a/backend/genesys.cc +++ b/backend/genesys.cc @@ -917,6 +917,7 @@ genesys_send_offset_and_shading (Genesys_Device * dev, uint8_t * data, && dev->model->ccd_type != CCD_G4050 && dev->model->ccd_type != CCD_CS4400F && dev->model->ccd_type != CCD_CS8400F + && dev->model->ccd_type != CCD_CS8600F && dev->model->ccd_type != CCD_DSMOBILE600 && dev->model->ccd_type != CCD_XP300 && dev->model->ccd_type != CCD_DP665 @@ -1715,7 +1716,9 @@ genesys_dark_shading_calibration (Genesys_Device * dev) // FIXME: the current calculation is likely incorrect on non-GENESYS_GL843 implementations, // but this needs checking - if (dev->model->asic_type == GENESYS_GL843) { + if (dev->calib_total_bytes_to_read > 0) { + size = dev->calib_total_bytes_to_read; + } else if (dev->model->asic_type == GENESYS_GL843) { size = channels * 2 * pixels_per_line * dev->calib_lines; } else { size = channels * 2 * pixels_per_line * (dev->calib_lines + 1); @@ -1904,7 +1907,9 @@ genesys_white_shading_calibration (Genesys_Device * dev) // FIXME: the current calculation is likely incorrect on non-GENESYS_GL843 implementations, // but this needs checking - if (dev->model->asic_type == GENESYS_GL843) { + if (dev->calib_total_bytes_to_read > 0) { + size = dev->calib_total_bytes_to_read; + } else if (dev->model->asic_type == GENESYS_GL843) { size = channels * 2 * pixels_per_line * dev->calib_lines; } else { size = channels * 2 * pixels_per_line * (dev->calib_lines + 1); @@ -1931,6 +1936,10 @@ genesys_white_shading_calibration (Genesys_Device * dev) status = (dev->model->cmd_set->rewind ? dev->model->cmd_set->rewind (dev) : dev->model->cmd_set->slow_back_home (dev, SANE_TRUE)); + if (dev->settings.scan_method == SCAN_METHOD_TRANSPARENCY) + { + dev->model->cmd_set->move_to_ta(dev); + } } status = @@ -2032,7 +2041,10 @@ genesys_dark_white_shading_calibration (Genesys_Device * dev) dev->dark_average_data.clear(); dev->dark_average_data.resize(channels * 2 * pixels_per_line); - size = channels * 2 * pixels_per_line * dev->calib_lines; + if (dev->calib_total_bytes_to_read > 0) + size = dev->calib_total_bytes_to_read; + else + size = channels * 2 * pixels_per_line * dev->calib_lines; std::vector calibration_data(size); @@ -2829,6 +2841,7 @@ genesys_send_shading_coefficient (Genesys_Device * dev) case CCD_G4050: case CCD_CS4400F: case CCD_CS8400F: + case CCD_CS8600F: target_code = 0xe000; o = 0; compute_coefficients (dev, @@ -3085,6 +3098,9 @@ genesys_flatbed_calibration (Genesys_Device * dev) if (dev->settings.yres <= dev->sensor.optical_res / 2) yres /= 2; + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + yres = 1200; + /* do offset calibration if needed */ if (dev->model->flags & GENESYS_FLAG_OFFSET_CALIBRATION) { diff --git a/backend/genesys.conf.in b/backend/genesys.conf.in index 5273d51ea..b1a0861f6 100644 --- a/backend/genesys.conf.in +++ b/backend/genesys.conf.in @@ -69,6 +69,9 @@ usb 0x04a9 0x190f # Canon 5600f usb 0x04a9 0x1906 +# Canon 8600F +usb 0x04a9 0x2229 + # Visioneer Strobe XP200 usb 0x04a7 0x0426 diff --git a/backend/genesys_devices.cc b/backend/genesys_devices.cc index 201fda3d4..21c9499ac 100644 --- a/backend/genesys_devices.cc +++ b/backend/genesys_devices.cc @@ -8,7 +8,7 @@ Copyright (C) 2007 Luke Copyright (C) 2010 Jack McGill Copyright (C) 2010 Andrey Loginov , - xerox travelscan device entry + xerox travelscan device entry Copyright (C) 2010 Chris Berry and Michael Rickmann for Plustek Opticbook 3600 support @@ -213,8 +213,15 @@ static Genesys_Frontend Wolfson[] = { , {0x60, 0x5c, 0x6c} /* 0x20, 0x21, 0x22 */ , {0x8a, 0x9f, 0xc2} /* 0x28, 0x29, 0x2a */ , {0x00, 0x00, 0x00} - } - , + }, + { + DAC_CS8600F, + { 0x00, 0x23, 0x24, 0x2f }, + { 0x00, 0x00, 0x00 }, + { 0x67, 0x69, 0x68 }, // 0x20, 0x21, 0x22 + { 0xdb, 0xda, 0xd7 }, // 0x28, 0x29, 0x2a + { 0x00, 0x00, 0x00 }, + }, {DAC_IMG101, {0x78, 0xf0, 0x00, 0x00} , {0x00, 0x00, 0x00} @@ -724,6 +731,29 @@ void genesys_init_sensor_tables() s_sensors->push_back(sensor); + sensor = Genesys_Sensor(); + sensor.sensor_id = CCD_CS8600F; + sensor.optical_res = 4800; + sensor.black_pixels = 31; + sensor.dummy_pixel = 20; + sensor.CCD_start_xoffset = 0; // not used at the moment + // 11372 pixels at 1200 dpi + sensor.sensor_pixels = 11372*4; + sensor.fau_gain_white_ref = 160; + sensor.gain_white_ref = 160; + sensor.regs_0x08_0x0b = { 0x00, 0x00, 0x00, 0x00 }; // not used + // 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d + sensor.regs_0x10_0x1d = { + 0x9c, 0x40, 0x9c, 0x40, 0x9c, 0x40, 0x13, 0x15, 0x10, 0x2a, 0x30, 0x00, 0x20, 0x75 + }; + // 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e + sensor.regs_0x52_0x5e = { + 0x0c, 0x0f, 0x00, 0x03, 0x06, 0x09, 0x6b, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1f + }; + sensor.gamma = {1.0, 1.0, 1.0}; + s_sensors->push_back(sensor); + + sensor = Genesys_Sensor(); sensor.sensor_id = CCD_HP_N6310; sensor.optical_res = 2400; @@ -1083,6 +1113,12 @@ static Genesys_Gpo Gpo[] = { {0x9a, 0xdf}, {0xfe, 0x60}, } + /* CanoScan 8600F */ + , + { GPO_CS8600F, + { 0x20, 0x7c }, + { 0xff, 0x00 }, + } /* Canon Image formula 101 */ , {GPO_IMG101, @@ -1098,8 +1134,8 @@ static Genesys_Gpo Gpo[] = { /* Canon LiDE 80 */ { GPO_CANONLIDE80, - {0x28, 0x90}, /* 6c, 6d */ - {0x75, 0x80}, /* 6e, 6f */ + {0x28, 0x90}, + {0x75, 0x80}, } }; @@ -1389,6 +1425,20 @@ static Genesys_Motor Motor[] = { }, }, }, + { + MOTOR_CS8600F, + 2400, + 9600, + 2, + 1, + { /* motor slopes */ + { /* power mode 0 */ + { 3961, 240, 246, 0.8 }, /* full step */ + { 3961, 240, 246, 0.8 }, /* half step */ + { 3961, 240, 246, 0.8 }, /* quarter step */ + }, + }, + }, {MOTOR_CANONLIDE110, /* Canon LiDE 110 */ 4800, 9600, @@ -1521,6 +1571,7 @@ static Genesys_Model umax_astra_4500_model = { /* untested, values set by hmg */ GENESYS_HAS_NO_BUTTONS, /* no buttons supported */ 20, + 0, // shading_ta_lines 200 }; @@ -1578,6 +1629,7 @@ static Genesys_Model canon_lide_50_model = { GENESYS_HAS_EMAIL_SW | GENESYS_HAS_COPY_SW, 280, + 0, // shading_ta_lines 400 }; @@ -1630,6 +1682,7 @@ static Genesys_Model panasonic_kvss080_model = { GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_SCAN_SW , 100, + 0, // shading_ta_lines 100 }; @@ -1686,6 +1739,7 @@ static Genesys_Model hp4850c_model = { GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW, 100, + 0, // shading_ta_lines 100 }; @@ -1742,6 +1796,7 @@ static Genesys_Model hpg4010_model = { GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW, 100, + 0, // shading_ta_lines 100 }; @@ -1798,6 +1853,7 @@ static Genesys_Model hpg4050_model = { GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW, 100, + 0, // shading_ta_lines 100 }; @@ -1858,6 +1914,7 @@ static Genesys_Model canon_4400f_model = { GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW, 100, + 0, // shading_ta_lines 100 }; @@ -1917,10 +1974,70 @@ static Genesys_Model canon_8400f_model = { GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW, 100, + 0, // shading_ta_lines 100 }; +static Genesys_Model canon_8600f_model = { + "canon-canoscan-8600f", // name + "Canon", // Device vendor string + "Canoscan 8600f", // Device model name + MODEL_CANON_CANOSCAN_8600F, + GENESYS_GL843, // ASIC type + NULL, + + { 4800, 2400, 1200, 600, 400, 300, 0}, // TODO: resolutions for non-XPA mode + { 4800, 2400, 1200, 600, 400, 300, 0}, // TODO: resolutions for non-XPA mode + { 16, 8, 0 }, // possible depths in gray mode + { 16, 8, 0 }, // possible depths in color mode + + SANE_FIX(24.0), // Start of scan area in mm (x) + SANE_FIX(10.0), // Start of scan area in mm (y) + SANE_FIX(216.0), // Size of scan area in mm (x) + SANE_FIX(297.0), // Size of scan area in mm (y) + + SANE_FIX(0.0), // Start of white strip in mm (y) + SANE_FIX(8.0), // Start of black mark in mm (x) + + SANE_FIX(95.0), // x_offset_ta + SANE_FIX(26.0), // y_offset_ta + SANE_FIX(70.0), // x_size_ta + SANE_FIX(230.0), // y_size_ta + + SANE_FIX(12.5), // y_offset_calib + + 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, 48, 96, // RGB CCD Line-distance correction in line number + + COLOR_ORDER_RGB, // Order of the CCD/CIS colors + + SANE_FALSE, // Is this a CIS scanner? + SANE_FALSE, // Is this a sheetfed scanner? + CCD_CS8600F, + DAC_CS8600F, + GPO_CS8600F, + MOTOR_CS8600F, + 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_SHADING_REPARK | + GENESYS_FLAG_HALF_CCD_MODE, + GENESYS_HAS_SCAN_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_COPY_SW, + 50, // shading_lines + 50, // shading_ta_lines + 100 +}; + static Genesys_Model canon_lide_100_model = { "canon-lide-100", /* Name */ @@ -1974,6 +2091,7 @@ static Genesys_Model canon_lide_100_model = { | GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_FILE_SW, 50, + 0, // shading_ta_lines 400 }; @@ -2028,6 +2146,7 @@ static Genesys_Model canon_lide_110_model = { | GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_FILE_SW, 50, + 0, // shading_ta_lines 400 }; @@ -2082,6 +2201,7 @@ static Genesys_Model canon_lide_120_model = { | GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_FILE_SW, 50, + 0, // shading_ta_lines 400 }; @@ -2137,6 +2257,7 @@ static Genesys_Model canon_lide_210_model = { | GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_EXTRA_SW, 60, + 0, // shading_ta_lines 400 }; @@ -2191,6 +2312,7 @@ static Genesys_Model canon_lide_220_model = { | GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_FILE_SW | GENESYS_HAS_EXTRA_SW, 60, + 0, // shading_ta_lines 400 }; @@ -2245,6 +2367,7 @@ static Genesys_Model canon_5600f_model = { | GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_FILE_SW, 50, + 0, // shading_ta_lines 400 }; @@ -2299,6 +2422,7 @@ static Genesys_Model canon_lide_700f_model = { | GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_FILE_SW, 70, + 0, // shading_ta_lines 400 }; @@ -2355,6 +2479,7 @@ static Genesys_Model canon_lide_200_model = { | GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_FILE_SW, 50, + 0, // shading_ta_lines 400 }; @@ -2414,6 +2539,7 @@ static Genesys_Model canon_lide_60_model = { | GENESYS_HAS_FILE_SW | GENESYS_HAS_EMAIL_SW, 300, + 0, // shading_ta_lines 400 }; /* this is completely untested -- hmg */ @@ -2470,6 +2596,7 @@ static Genesys_Model canon_lide_80_model = { GENESYS_HAS_EMAIL_SW | GENESYS_HAS_COPY_SW, 160, /* 280 @2400 */ + 0, // shading_ta_lines 400 }; @@ -2527,6 +2654,7 @@ static Genesys_Model hp2300c_model = { | GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW, 40, + 0, // shading_ta_lines 132 }; @@ -2583,6 +2711,7 @@ Genesys_Model hp2400c_model = { | GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_SCAN_SW, 20, + 0, // shading_ta_lines 132 }; @@ -2638,6 +2767,7 @@ Genesys_Model visioneer_xp200_model = { | GENESYS_FLAG_OFFSET_CALIBRATION, GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, 120, + 0, // shading_ta_lines 132 }; @@ -2693,6 +2823,7 @@ static Genesys_Model hp3670c_model = { | GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_SCAN_SW, 20, + 0, // shading_ta_lines 200 }; @@ -2742,6 +2873,7 @@ static Genesys_Model plustek_st12_model = { GENESYS_FLAG_UNTESTED | GENESYS_FLAG_14BIT_GAMMA, /* Which flags are needed for this scanner? */ GENESYS_HAS_NO_BUTTONS, /* no buttons supported */ 20, + 0, // shading_ta_lines 200 }; @@ -2796,6 +2928,7 @@ static Genesys_Model plustek_st24_model = { | GENESYS_FLAG_OFFSET_CALIBRATION, GENESYS_HAS_NO_BUTTONS, /* no buttons supported */ 20, + 0, // shading_ta_lines 200 }; @@ -2852,6 +2985,7 @@ static Genesys_Model medion_md5345_model = { | GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_POWER_SW | GENESYS_HAS_OCR_SW | GENESYS_HAS_SCAN_SW, 40, + 0, // shading_ta_lines 200 }; @@ -2906,6 +3040,7 @@ static Genesys_Model visioneer_xp300_model = { | GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, 100, + 0, // shading_ta_lines 400 }; @@ -2959,6 +3094,7 @@ static Genesys_Model syscan_docketport_665_model = { | GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, 100, + 0, // shading_ta_lines 400 }; @@ -3012,6 +3148,7 @@ static Genesys_Model visioneer_roadwarrior_model = { | GENESYS_FLAG_DARK_CALIBRATION, GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, 100, + 0, // shading_ta_lines 400 }; @@ -3065,6 +3202,7 @@ static Genesys_Model syscan_docketport_465_model = { | GENESYS_FLAG_UNTESTED, GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW, 300, + 0, // shading_ta_lines 400 }; @@ -3118,6 +3256,7 @@ static Genesys_Model visioneer_xp100_r3_model = { | GENESYS_FLAG_DARK_CALIBRATION, GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, 100, + 0, // shading_ta_lines 400 }; @@ -3171,6 +3310,7 @@ static Genesys_Model pentax_dsmobile_600_model = { | GENESYS_FLAG_DARK_CALIBRATION, GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, 100, + 0, // shading_ta_lines 400 }; @@ -3224,6 +3364,7 @@ static Genesys_Model syscan_docketport_467_model = { | GENESYS_FLAG_DARK_CALIBRATION, GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, 100, + 0, // shading_ta_lines 400 }; @@ -3278,6 +3419,7 @@ static Genesys_Model syscan_docketport_685_model = { | GENESYS_FLAG_DARK_CALIBRATION, GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, 100, + 0, // shading_ta_lines 400 }; @@ -3332,6 +3474,7 @@ static Genesys_Model syscan_docketport_485_model = { | GENESYS_FLAG_DARK_CALIBRATION, GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, 100, + 0, // shading_ta_lines 400 }; @@ -3387,6 +3530,7 @@ static Genesys_Model dct_docketport_487_model = { | GENESYS_FLAG_UNTESTED, GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, 100, + 0, // shading_ta_lines 400 }; @@ -3443,6 +3587,7 @@ static Genesys_Model visioneer_7100_model = { | GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_POWER_SW | GENESYS_HAS_OCR_SW | GENESYS_HAS_SCAN_SW, 40, + 0, // shading_ta_lines 200 }; @@ -3499,6 +3644,7 @@ static Genesys_Model xerox_2400_model = { | GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_POWER_SW | GENESYS_HAS_OCR_SW | GENESYS_HAS_SCAN_SW, 40, + 0, // shading_ta_lines 200 }; @@ -3553,6 +3699,7 @@ static Genesys_Model xerox_travelscanner_model = { | GENESYS_FLAG_DARK_CALIBRATION, GENESYS_HAS_SCAN_SW | GENESYS_HAS_PAGE_LOADED_SW | GENESYS_HAS_CALIBRATE, 100, + 0, // shading_ta_lines 400 }; @@ -3608,6 +3755,7 @@ static Genesys_Model plustek_3600_model = { | GENESYS_FLAG_NO_CALIBRATION,*/ GENESYS_HAS_NO_BUTTONS, 7, + 0, // shading_ta_lines 200 }; @@ -3667,6 +3815,7 @@ static Genesys_Model hpn6310_model = { GENESYS_HAS_NO_BUTTONS, 100, + 0, // shading_ta_lines 100 }; @@ -3720,6 +3869,7 @@ static Genesys_Model plustek_3800_model = { GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_NO_BUTTONS, /* TODO there are 4 buttons to support */ 100, + 0, // shading_ta_lines 100 }; @@ -3773,6 +3923,7 @@ static Genesys_Model canon_formula101_model = { GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_NO_BUTTONS , 100, + 0, // shading_ta_lines 100 }; @@ -3813,6 +3964,7 @@ static Genesys_USB_Device_Entry genesys_usb_device_list[] = { {0x03f0, 0x4605, &hpg4050_model}, {0x04a9, 0x2228, &canon_4400f_model}, {0x04a9, 0x221e, &canon_8400f_model}, + {0x04a9, 0x2229, &canon_8600f_model}, /* GL845 devices */ {0x07b3, 0x1300, &plustek_3800_model}, /* GL846 devices */ diff --git a/backend/genesys_gl124.cc b/backend/genesys_gl124.cc index 8bcbf9c37..9b4ad56dd 100644 --- a/backend/genesys_gl124.cc +++ b/backend/genesys_gl124.cc @@ -2488,6 +2488,7 @@ gl124_init_regs_for_shading (Genesys_Device * dev) dev->calib_lines /= 2; } dev->calib_resolution = resolution; + dev->calib_total_bytes_to_read = 0; factor=dev->sensor.optical_res/resolution; dev->calib_pixels = dev->sensor.sensor_pixels/factor; diff --git a/backend/genesys_gl843.cc b/backend/genesys_gl843.cc index 7fc3468db..815a7682f 100644 --- a/backend/genesys_gl843.cc +++ b/backend/genesys_gl843.cc @@ -383,106 +383,290 @@ gl843_bulk_full_size (void) static void gl843_init_registers (Genesys_Device * dev) { + // Within this function SENSOR_DEF marker documents that a register is part + // of the sensors definition and the actual value is set in + // gl843_setup_sensor(). + DBGSTART; memset (dev->reg, 0, GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set)); /* default to KV-SS080 */ SETREG (0xa2, 0x0f); + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + SETREG(0xa2, 0x1f); + } SETREG (0x01, 0x00); SETREG (0x02, 0x78); SETREG (0x03, 0x1f); SETREG (0x04, 0x10); + + // fine tune upon device description SETREG (0x05, 0x80); + if (dev->model->model_id == MODEL_HP_SCANJET_G4010 || + dev->model->model_id == MODEL_HP_SCANJET_G4050 || + dev->model->model_id == MODEL_HP_SCANJET_4850C) + { + SETREG (0x05, 0x08); + } + + dev->reg[reg_0x05].value &= ~REG05_DPIHW; + switch (dev->sensor.optical_res) + { + case 600: + dev->reg[reg_0x05].value |= REG05_DPIHW_600; + break; + case 1200: + dev->reg[reg_0x05].value |= REG05_DPIHW_1200; + break; + case 2400: + dev->reg[reg_0x05].value |= REG05_DPIHW_2400; + break; + case 4800: + dev->reg[reg_0x05].value |= REG05_DPIHW_4800; + break; + } + + // TODO: on 8600F the windows driver turns off GAIN4 which is recommended SETREG (0x06, 0xd8); /* SCANMOD=110, PWRBIT and GAIN4 */ SETREG (0x08, 0x00); SETREG (0x09, 0x00); SETREG (0x0a, 0x00); + + // This register controls clock and RAM settings and is further modified in + // gl843_boot SETREG (0x0b, 0x6a); - SETREG (0x10, 0x00); - SETREG (0x11, 0x00); - SETREG (0x12, 0x00); - SETREG (0x13, 0x00); - SETREG (0x14, 0x00); - SETREG (0x15, 0x00); - SETREG (0x16, 0x33); - SETREG (0x17, 0x1c); - SETREG (0x18, 0x10); - SETREG (0x19, 0x2a); - SETREG (0x1a, 0x04); - SETREG (0x1b, 0x00); - SETREG (0x1c, 0x20); - SETREG (0x1d, 0x04); + + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + SETREG(0x0b, 0x89); + } + + // EXPR[0:15], EXPG[0:15], EXPB[0:15]: Exposure time settings. + SETREG(0x10, 0x00); // SENSOR_DEF + SETREG(0x11, 0x00); // SENSOR_DEF + SETREG(0x12, 0x00); // SENSOR_DEF + SETREG(0x13, 0x00); // SENSOR_DEF + SETREG(0x14, 0x00); // SENSOR_DEF + SETREG(0x15, 0x00); // SENSOR_DEF + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + sanei_genesys_set_double(dev->reg,REG_EXPR,0x9c40); + sanei_genesys_set_double(dev->reg,REG_EXPG,0x9c40); + sanei_genesys_set_double(dev->reg,REG_EXPB,0x9c40); + } + // CCD signal settings. + SETREG(0x16, 0x33); // SENSOR_DEF + SETREG(0x17, 0x1c); // SENSOR_DEF + SETREG(0x18, 0x10); // SENSOR_DEF + + // EXPDMY[0:7]: Exposure time of dummy lines. + SETREG(0x19, 0x2a); // SENSOR_DEF + + // Various CCD clock settings. + SETREG(0x1a, 0x04); // SENSOR_DEF + SETREG(0x1b, 0x00); // SENSOR_DEF + SETREG(0x1c, 0x20); // SENSOR_DEF + SETREG(0x1d, 0x04); // SENSOR_DEF + SETREG (0x1e, 0x10); + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + SETREG(0x1e, 0x20); + } + SETREG (0x1f, 0x01); + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + SETREG(0x1f, 0xff); + } + SETREG (0x20, 0x10); SETREG (0x21, 0x04); SETREG (0x22, 0x01); + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + SETREG(0x22, 0xc8); + } + SETREG (0x23, 0x01); + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + SETREG(0x23, 0xc8); + } + SETREG (0x24, 0x04); SETREG (0x25, 0x00); SETREG (0x26, 0x00); SETREG (0x27, 0x00); SETREG (0x2c, 0x02); SETREG (0x2d, 0x58); + // BWHI[0:7]: high level of black and white threshold SETREG (0x2e, 0x80); + // BWLOW[0:7]: low level of black and white threshold SETREG (0x2f, 0x80); SETREG (0x30, 0x00); SETREG (0x31, 0x14); SETREG (0x32, 0x27); SETREG (0x33, 0xec); + + // DUMMY: CCD dummy and optically black pixel count SETREG (0x34, 0x24); + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + SETREG(0x34, 0x14); + } + + // MAXWD: If available buffer size is less than 2*MAXWD words, then + // "buffer full" state will be set. SETREG (0x35, 0x00); SETREG (0x36, 0xff); SETREG (0x37, 0xff); - SETREG (0x38, 0x55); - SETREG (0x39, 0xf0); - SETREG (0x3d, 0x00); + + // LPERIOD: Line period or exposure time for CCD or CIS. + SETREG(0x38, 0x55); // SENSOR_DEF + SETREG(0x39, 0xf0); // SENSOR_DEF + + // FEEDL[0:24]: The number of steps of motor movement. + SETREG(0x3d, 0x00); SETREG (0x3e, 0x00); SETREG (0x3f, 0x01); - SETREG (0x52, 0x01); - SETREG (0x53, 0x04); - SETREG (0x54, 0x07); - SETREG (0x55, 0x0a); - SETREG (0x56, 0x0d); - SETREG (0x57, 0x10); - SETREG (0x58, 0x1b); - SETREG (0x59, 0x00); - SETREG (0x5a, 0x40); + + // Latch points for high and low bytes of R, G and B channels of AFE. If + // multiple clocks per pixel are consumed, then the setting defines during + // which clock the corresponding value will be read. + // RHI[0:4]: The latch point for high byte of R channel. + // RLOW[0:4]: The latch point for low byte of R channel. + // GHI[0:4]: The latch point for high byte of G channel. + // GLOW[0:4]: The latch point for low byte of G channel. + // BHI[0:4]: The latch point for high byte of B channel. + // BLOW[0:4]: The latch point for low byte of B channel. + SETREG(0x52, 0x01); // SENSOR_DEF + SETREG(0x53, 0x04); // SENSOR_DEF + SETREG(0x54, 0x07); // SENSOR_DEF + SETREG(0x55, 0x0a); // SENSOR_DEF + SETREG(0x56, 0x0d); // SENSOR_DEF + SETREG(0x57, 0x10); // SENSOR_DEF + + // VSMP[0:4]: The position of the image sampling pulse for AFE in cycles. + // VSMPW[0:2]: The length of the image sampling pulse for AFE in cycles. + SETREG(0x58, 0x1b); // SENSOR_DEF + + SETREG(0x59, 0x00); // SENSOR_DEF + SETREG(0x5a, 0x40); // SENSOR_DEF + + // 0x5b-0x5c: GMMADDR[0:15] address for gamma or motor tables download + // SENSOR_DEF + + // DECSEL[0:2]: The number of deceleratino steps after touching home sensor + // STOPTIM[0:4]: The stop duration between change of directions in + // backtracking SETREG (0x5e, 0x23); + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + SETREG(0x5e, 0x1f); + } + + // FMOVDEC: The number of deceleration steps in table 5 for auto-go-home SETREG (0x5f, 0x01); + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + SETREG(0x5f, 0xf0); + } + + // Z1MOD[0:20] SETREG (0x60, 0x00); SETREG (0x61, 0x00); SETREG (0x62, 0x00); + + // Z2MOD[0:20] SETREG (0x63, 0x00); SETREG (0x64, 0x00); SETREG (0x65, 0x00); + + // STEPSEL[0:1]. Motor movement step mode selection for tables 1-3 in + // scanning mode. + // MTRPWM[0:5]. Motor phase PWM duty cycle setting for tables 1-3 SETREG (0x67, 0x7f); + // FSTPSEL[0:1]: Motor movement step mode selection for tables 4-5 in + // command mode. + // FASTPWM[5:0]: Motor phase PWM duty cycle setting for tables 4-5 SETREG (0x68, 0x7f); + + // FSHDEC[0:7]: The number of deceleration steps after scanning is finished + // (table 3) SETREG (0x69, 0x01); + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + SETREG(0x69, 64); + } + + // FMOVNO[0:7] The number of acceleration or deceleration steps for fast + // moving (table 4) SETREG (0x6a, 0x04); + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + SETREG(0x69, 64); + } + + // GPIO-related register bits SETREG (0x6b, 0x30); - SETREG (0x70, 0x01); - SETREG (0x71, 0x03); + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + SETREG(0x6b, 0x72); + } + + // 0x6c, 0x6d, 0x6e, 0x6f are set according to gpio tables. See + // gl843_init_gpio. + + // RSH[0:4]: The position of rising edge of CCD RS signal in cycles + // RSL[0:4]: The position of falling edge of CCD RS signal in cycles + // CPH[0:4]: The position of rising edge of CCD CP signal in cycles. + // CPL[0:4]: The position of falling edge of CCD CP signal in cycles + SETREG(0x70, 0x01); // SENSOR_DEF + SETREG(0x71, 0x03); // SENSOR_DEF SETREG (0x72, 0x04); SETREG (0x73, 0x05); - /* CKxMAP */ - SETREG (0x74, 0x00); - SETREG (0x75, 0x00); - SETREG (0x76, 0x3c); - SETREG (0x77, 0x00); - SETREG (0x78, 0x00); - SETREG (0x79, 0x9f); - SETREG (0x7a, 0x00); - SETREG (0x7b, 0x00); - SETREG (0x7c, 0x55); + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + SETREG(0x70, 0x00); + SETREG(0x71, 0x02); + SETREG(0x72, 0x02); + SETREG(0x73, 0x04); + } - SETREG (0x7d, 0x00); + // CK1MAP[0:17], CK3MAP[0:17], CK4MAP[0:17]: CCD clock bit mapping setting. + SETREG(0x74, 0x00); // SENSOR_DEF + SETREG(0x75, 0x00); // SENSOR_DEF + SETREG(0x76, 0x3c); // SENSOR_DEF + SETREG(0x77, 0x00); // SENSOR_DEF + SETREG(0x78, 0x00); // SENSOR_DEF + SETREG(0x79, 0x9f); // SENSOR_DEF + SETREG(0x7a, 0x00); // SENSOR_DEF + SETREG(0x7b, 0x00); // SENSOR_DEF + SETREG(0x7c, 0x55); // SENSOR_DEF + + // various AFE settings + SETREG(0x7d, 0x00); + + // GPOLED[x]: LED vs GPIO settings + SETREG(0x7e, 0x00); + + // BSMPDLY, VSMPDLY + // LEDCNT[0:1]: Controls led blinking and its period SETREG (0x7f, 0x00); + + // VRHOME, VRMOVE, VRBACK, VRSCAN: Vref settings of the motor driver IC for + // moving in various situations. SETREG (0x80, 0x00); + if (dev->model->model_id != MODEL_CANON_CANOSCAN_4400F) { + // NOTE: Historical code. None of the following 6 registers are + // documented in the datasheet. Their default value is 0, so probably it's + // not a bad idea to leave this here. SETREG (0x81, 0x00); SETREG (0x82, 0x00); SETREG (0x83, 0x00); @@ -490,9 +674,65 @@ gl843_init_registers (Genesys_Device * dev) SETREG (0x85, 0x00); SETREG (0x86, 0x00); } + SETREG (0x87, 0x00); - SETREG (0x9d, 0x04); - SETREG (0x9e, 0x00); + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + SETREG(0x87, 0x02); + } + + // MTRPLS[0:7]: The width of the ADF motor trigger signal pulse. + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + SETREG(0x94, 0xff); + } + + // 0x95-0x97: SCANLEN[0:19]: Controls when paper jam bit is set in sheetfed + // scanners. + + // ONDUR[0:15]: The duration of PWM ON phase for LAMP control + // OFFDUR[0:15]: The duration of PWM OFF phase for LAMP control + // both of the above are in system clocks + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + SETREG(0x98, 0x00); + SETREG(0x99, 0x00); + SETREG(0x9a, 0x00); + SETREG(0x9b, 0x00); + } + + // RMADLY[0:1], MOTLAG, CMODE, STEPTIM, MULDMYLN, IFRS + SETREG(0x9d, 0x04); + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + SETREG(0x9d, 0x08); // additionally sets the multiplier for slope tables + } + + + // SEL3INV, TGSTIME[0:2], TGWTIME[0:2] + SETREG (0x9e, 0x00); // SENSOR_DEF + + // RFHSET[0:4]: Refresh time of SDRAM in units of 2us + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + SETREG(0xa2, 0x1f); + } + + // 0xa6-0xa9: controls gpio, see gl843_gpio_init + + // GPOM9, MULSTOP[0-2], NODECEL, TB3TB1, TB5TB2, FIX16CLK. + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + SETREG(0xab, 0x00); + } + + // VRHOME[3:2], VRMOVE[3:2], VRBACK[3:2]: Vref setting of the motor driver IC + // for various situations. + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + SETREG(0xac, 0x00); + } + if (dev->model->model_id != MODEL_CANON_CANOSCAN_8400F) { SETREG (0x0c, 0x00); @@ -500,7 +740,6 @@ gl843_init_registers (Genesys_Device * dev) SETREG (0xab, 0x50); } - /* so many time burnt for this register ....*/ if (dev->model->model_id != MODEL_CANON_CANOSCAN_4400F && dev->model->model_id != MODEL_CANON_CANOSCAN_8400F) { @@ -513,7 +752,6 @@ gl843_init_registers (Genesys_Device * dev) dev->model->model_id == MODEL_HP_SCANJET_4850C) { SETREG (0x03, 0x1d); - SETREG (0x05, 0x08); SETREG (0x06, 0xd0); /* SCANMOD=110, PWRBIT and no GAIN4 */ SETREG (0x06, 0xd8); /* SCANMOD=110, PWRBIT and GAIN4 */ SETREG (0x0a, 0x18); @@ -586,24 +824,6 @@ gl843_init_registers (Genesys_Device * dev) SETREG (0x9d, 0x08); /* STEPTIM=2 */ } - /* fine tune upon device description */ - dev->reg[reg_0x05].value &= ~REG05_DPIHW; - switch (dev->sensor.optical_res) - { - case 600: - dev->reg[reg_0x05].value |= REG05_DPIHW_600; - break; - case 1200: - dev->reg[reg_0x05].value |= REG05_DPIHW_1200; - break; - case 2400: - dev->reg[reg_0x05].value |= REG05_DPIHW_2400; - break; - case 4800: - dev->reg[reg_0x05].value |= REG05_DPIHW_4800; - break; - } - /* initalize calibration reg */ memcpy (dev->calib_reg, dev->reg, GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set)); @@ -673,6 +893,7 @@ gl843_set_fe (Genesys_Device * dev, uint8_t set) } /* check analog frontend type */ + // FIXME: looks like we write to that register with initial data RIE (sanei_genesys_read_register (dev, REG04, &val)); if ((val & REG04_FESET) != 0x00) { @@ -1059,7 +1280,11 @@ gl843_init_optical_regs_scan (Genesys_Device * dev, } r = sanei_genesys_get_address (reg, REG03); - r->value &= ~REG03_AVEENB; + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + r->value |= REG03_AVEENB; + else + r->value &= ~REG03_AVEENB; + if (flags & OPTICAL_FLAG_DISABLE_LAMP) r->value &= ~REG03_LAMPPWR; else @@ -1194,6 +1419,114 @@ gl843_init_optical_regs_scan (Genesys_Device * dev, return SANE_STATUS_GOOD; } +struct GenesysPhysicalParams { + float xres; + + // whether CCD operates as half-resolution or full resolution at a specific resolution + SANE_Bool half_ccd; + + // the optical resolution of the scanner. + unsigned optical_resolution; + + // the number of pixels at the optical resolution. + unsigned optical_pixels; + + // the number of bytes in the output of a single line directly from scanner + unsigned optical_line_bytes; + + // the resolution of the output data. + unsigned output_resolution; + + // the number of pixels in output data + unsigned output_pixels; + + // the number of bytes in the output of a single line + unsigned output_line_bytes; + + // the number of lines in the output of the scanner. This must be larger than the user + // requested number due to line staggering and color channel shifting. + unsigned output_line_count; + + // the number of staggered lines (i.e. lines that overlap during scanning due to line being + // thinner than the CCD element) + unsigned num_staggered_lines; + + // the number of lines that color channels shift due to different physical positions of + // different color channels + unsigned max_color_shift_lines; +}; + +// computes physical parameters for specific scan setup +static struct GenesysPhysicalParams + gl843_compute_physical_params(Genesys_Device* dev, float xres, float yres, float pixels, + float lines, + unsigned depth, unsigned channels, unsigned flags) +{ + struct GenesysPhysicalParams params; + memset(¶ms, 0, sizeof(params)); + + params.xres = xres; + + if (dev->sensor.optical_res < 4 * xres || + !(dev->model->flags & GENESYS_FLAG_HALF_CCD_MODE)) + { + params.half_ccd = SANE_FALSE; + } else { + params.half_ccd = SANE_TRUE; + } + + params.optical_resolution = dev->sensor.optical_res; + if (params.half_ccd) + params.optical_resolution /= 4; + + if (flags & SCAN_FLAG_USE_OPTICAL_RES) { + params.output_resolution = params.optical_resolution; + } else { + // resolution is choosen from a fixed list and can be used directly + // unless we have ydpi higher than sensor's maximum one + if (xres > params.optical_resolution) + params.output_resolution = params.optical_resolution; + else + params.output_resolution = xres; + } + + // compute rounded up number of optical pixels + params.optical_pixels = (pixels * params.optical_resolution) / xres; + if (params.optical_pixels * xres < pixels * params.optical_resolution) + params.optical_pixels++; + + // ensure the number of optical pixels is divisible by 2. + // In half-CCD mode optical_pixels is 4x larger than the actual physical number + if (params.half_ccd) { + if (params.optical_pixels & 0x7) + params.optical_pixels = (params.optical_pixels & ~0x7) + 8; + } else { + if (params.optical_pixels & 1) + params.optical_pixels++; + } + + params.output_pixels = + (params.optical_pixels * params.output_resolution) / params.optical_resolution; + + // Note: staggering is not applied for calibration. Staggering starts at 2400 dpi + params.num_staggered_lines = 0; + if ((yres > 1200) && + ((flags & SCAN_FLAG_IGNORE_LINE_DISTANCE) == 0) && + (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE)) + { + params.num_staggered_lines = (4 * yres) / dev->motor.base_ydpi; + } + + params.max_color_shift_lines = sanei_genesys_compute_max_shift(dev, channels, yres, flags); + + params.output_line_count = lines + params.max_color_shift_lines + params.num_staggered_lines; + + params.optical_line_bytes = (params.optical_pixels * channels * depth) / 8; + params.output_line_bytes = (params.output_pixels * channels * depth) / 8; + + return params; +} + /* set up registers for an actual scan * * this function sets up the scanner to scan in normal or single line mode @@ -1213,24 +1546,17 @@ gl843_init_scan_regs (Genesys_Device * dev, int color_filter, unsigned int flags) { - int used_res; - int start, used_pixels; - int bytes_per_line; + int start; int move; - unsigned int lincnt; /**> line count to scan */ unsigned int oflags, mflags; /**> optical and motor flags */ int exposure; - int stagger; int slope_dpi = 0; int dummy = 0; int scan_step_type = 1; int scan_power_mode = 0; - int max_shift; size_t requested_buffer_size, read_buffer_size; - SANE_Bool half_ccd; /* false: full CCD res is used, true, half max CCD res is used */ - int optical_res; SANE_Status status; DBG(DBG_info, "%s:\n" @@ -1242,32 +1568,10 @@ gl843_init_scan_regs (Genesys_Device * dev, "Flags : %x\n\n", __func__, xres, yres, lines, pixels, startx, starty, depth, channels, flags); + struct GenesysPhysicalParams params = + gl843_compute_physical_params(dev, xres, yres, pixels, lines, depth, channels, flags); - /* we have 2 domains for ccd: xres below or above half ccd max dpi */ - if (dev->sensor.optical_res < 4 * xres || - !(dev->model->flags & GENESYS_FLAG_HALF_CCD_MODE)) - { - half_ccd = SANE_FALSE; - } - else - { - half_ccd = SANE_TRUE; - } - - /* optical_res */ - optical_res = dev->sensor.optical_res; - if (half_ccd) - optical_res /= 4; - - /* stagger starting at 2400, and not applied for calibration */ - stagger = 0; - if ( (yres>1200) - && ((flags & SCAN_FLAG_IGNORE_LINE_DISTANCE)==0) - && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE)) - { - stagger = (4 * yres) / dev->motor.base_ydpi; - } - DBG(DBG_info, "%s : stagger=%d lines\n", __func__, stagger); + DBG(DBG_info, "%s : stagger=%d lines\n", __func__, params.num_staggered_lines); /* we enable true gray for cis scanners only, and just when doing * scan since color calibration is OK for this mode @@ -1281,25 +1585,11 @@ gl843_init_scan_regs (Genesys_Device * dev, oflags |= OPTICAL_FLAG_DISABLE_LAMP; if (flags & SCAN_FLAG_CALIBRATION) oflags |= OPTICAL_FLAG_DISABLE_DOUBLE; - if(stagger) + if (params.num_staggered_lines) oflags |= OPTICAL_FLAG_STAGGER; if (flags & SCAN_FLAG_USE_XPA) oflags |= OPTICAL_FLAG_USE_XPA; - /** @brief compute used resolution */ - if (flags & SCAN_FLAG_USE_OPTICAL_RES) - { - used_res = optical_res; - } - else - { - /* resolution is choosen from a fixed list and can be used directly - * unless we have ydpi higher than sensor's maximum one */ - if(xres>optical_res) - used_res=optical_res; - else - used_res = xres; - } /* compute scan parameters values */ /* pixels are allways given at full optical resolution */ @@ -1307,18 +1597,6 @@ gl843_init_scan_regs (Genesys_Device * dev, /* start */ start = startx; - /* compute correct pixels number */ - used_pixels = (pixels * optical_res) / xres; - DBG(DBG_info, "%s: used_pixels=%d\n", __func__, used_pixels); - - /* round up pixels number if needed */ - if (used_pixels * xres < pixels * optical_res) - used_pixels++; - - /* we want even number of pixels here */ - if(used_pixels & 1) - used_pixels++; - dummy = 0; /* dummy = 1; XXX STEF XXX */ @@ -1338,7 +1616,7 @@ gl843_init_scan_regs (Genesys_Device * dev, } else { - exposure = gl843_compute_exposure (dev, used_res, oflags); + exposure = gl843_compute_exposure (dev, params.output_resolution, oflags); scan_step_type = sanei_genesys_compute_step_type(gl843_motors, dev->model->motor_type, exposure); } @@ -1363,12 +1641,12 @@ gl843_init_scan_regs (Genesys_Device * dev, status = gl843_init_optical_regs_scan (dev, reg, exposure, - used_res, + params.output_resolution, start, - used_pixels, + params.optical_pixels, channels, depth, - half_ccd, + params.half_ccd, color_filter, oflags); if (status != SANE_STATUS_GOOD) @@ -1390,13 +1668,6 @@ gl843_init_scan_regs (Genesys_Device * dev, dev->ld_shift_b = dev->model->ld_shift_b; } - /* max_shift */ - /* scanned area must be enlarged by max color shift needed */ - max_shift=sanei_genesys_compute_max_shift(dev,channels,yres,flags); - - /* lines to scan */ - lincnt = lines + max_shift + stagger; - /* add tl_y to base movement */ move = starty; DBG(DBG_info, "%s: move=%d steps\n", __func__, move); @@ -1415,7 +1686,8 @@ gl843_init_scan_regs (Genesys_Device * dev, exposure, slope_dpi, scan_step_type, - dev->model->is_cis ? lincnt * channels : lincnt, + dev->model->is_cis ? params.output_line_count * channels + : params.output_line_count, dummy, move, scan_power_mode, @@ -1423,20 +1695,14 @@ gl843_init_scan_regs (Genesys_Device * dev, if (status != SANE_STATUS_GOOD) return status; - /*** prepares data reordering ***/ - - /* words_per_line */ - bytes_per_line = (used_pixels * used_res) / optical_res; - bytes_per_line = (bytes_per_line * channels * depth) / 8; - /* since we don't have sheetfed scanners to handle, * use huge read buffer */ /* TODO find the best size according to settings */ - requested_buffer_size = 16 * bytes_per_line; + requested_buffer_size = 16 * params.output_line_bytes; read_buffer_size = 2 * requested_buffer_size + - ((max_shift + stagger) * used_pixels * channels * depth) / 8; + (params.max_color_shift_lines + params.num_staggered_lines) * params.optical_line_bytes; dev->read_buffer.clear(); dev->read_buffer.alloc(read_buffer_size); @@ -1450,23 +1716,22 @@ gl843_init_scan_regs (Genesys_Device * dev, dev->out_buffer.clear(); dev->out_buffer.alloc((8 * dev->settings.pixels * channels * depth) / 8); - dev->read_bytes_left = bytes_per_line * lincnt; + dev->read_bytes_left = params.output_line_bytes * params.output_line_count; DBG(DBG_info, "%s: physical bytes to read = %lu\n", __func__, (u_long) dev->read_bytes_left); dev->read_active = SANE_TRUE; - - dev->current_setup.pixels = (used_pixels * used_res) / optical_res; + dev->current_setup.pixels = params.output_pixels; DBG(DBG_info, "%s: current_setup.pixels=%d\n", __func__, dev->current_setup.pixels); - dev->current_setup.lines = lincnt; + dev->current_setup.lines = params.output_line_count; dev->current_setup.depth = depth; dev->current_setup.channels = channels; dev->current_setup.exposure_time = exposure; - dev->current_setup.xres = used_res; + dev->current_setup.xres = params.output_resolution; dev->current_setup.yres = yres; - dev->current_setup.half_ccd = half_ccd; - dev->current_setup.stagger = stagger; - dev->current_setup.max_shift = max_shift + stagger; + dev->current_setup.half_ccd = params.half_ccd; + dev->current_setup.stagger = params.num_staggered_lines; + dev->current_setup.max_shift = params.max_color_shift_lines + params.num_staggered_lines; dev->total_bytes_read = 0; if (depth == 1) @@ -1519,6 +1784,20 @@ gl843_calculate_current_setup (Genesys_Device * dev) dev->settings.yres, dev->settings.lines, dev->settings.pixels, dev->settings.tl_x, dev->settings.tl_y, dev->settings.scan_mode); + xres = dev->settings.xres; + yres = dev->settings.yres; + + /* we have 2 domains for ccd: xres below or above half ccd max dpi */ + if ((dev->sensor.optical_res < 4 * xres) || + !(dev->model->flags & GENESYS_FLAG_HALF_CCD_MODE)) + { + half_ccd = SANE_FALSE; + } + else + { + half_ccd = SANE_TRUE; + } + /* channels */ if (dev->settings.scan_mode == SCAN_MODE_COLOR) /* single pass color */ channels = 3; @@ -1531,7 +1810,14 @@ gl843_calculate_current_setup (Genesys_Device * dev) depth = 1; /* start */ - start = SANE_UNFIX (dev->model->x_offset); + if(dev->settings.scan_method==SCAN_METHOD_TRANSPARENCY) + start = SANE_UNFIX (dev->model->x_offset_ta); + else + start = SANE_UNFIX (dev->model->x_offset); + + if (half_ccd) + start /= 4; + start += dev->settings.tl_x; start = (start * dev->sensor.optical_res) / MM_PER_INCH; @@ -1542,8 +1828,6 @@ gl843_calculate_current_setup (Genesys_Device * dev) oflags=OPTICAL_FLAG_USE_XPA; } - xres = dev->settings.xres; - yres = dev->settings.yres; startx = start; pixels = dev->settings.pixels; lines = dev->settings.lines; @@ -1556,19 +1840,6 @@ gl843_calculate_current_setup (Genesys_Device * dev) "Depth/Channels: %u/%u\n\n", __func__, xres, yres, lines, pixels, startx, depth, channels); -/* half_ccd */ - /* we have 2 domains for ccd: xres below or above half ccd max dpi */ - if ((dev->sensor.optical_res < 4 * xres) || - !(dev->model->flags & GENESYS_FLAG_HALF_CCD_MODE)) - { - half_ccd = SANE_FALSE; - } - else - { - half_ccd = SANE_TRUE; - } - - /* optical_res */ optical_res = dev->sensor.optical_res; if (half_ccd) @@ -1679,11 +1950,15 @@ gl843_set_lamp_power (Genesys_Device * dev, { val &= ~REG03_LAMPPWR; sanei_genesys_set_reg_from_set (regs, REG03, val); - for (i = 0; i < 6; i++) - { - r = sanei_genesys_get_address (regs, 0x10 + i); - r->value = 0x00; - } + if (dev->model->model_id != MODEL_CANON_CANOSCAN_8600F) + { + // FIXME: datasheet says we shouldn't set exposure to zero + for (i = 0; i < 6; i++) + { + r = sanei_genesys_get_address (regs, 0x10 + i); + r->value = 0x00; + } + } } } @@ -1736,6 +2011,17 @@ gl843_start_action (Genesys_Device * dev) return sanei_genesys_write_register (dev, 0x0f, 0x01); } +static SANE_Status +gl843_stop_action_no_move(Genesys_Device* dev, Genesys_Register_Set* reg) +{ + uint8_t val = sanei_genesys_read_reg_from_set(reg, REG01); + val &= ~REG01_SCAN; + sanei_genesys_set_reg_from_set(reg, REG01, val); + SANE_Status ret = sanei_genesys_write_register(dev, REG01, val); + sanei_genesys_sleep_ms(100); + return ret; +} + static SANE_Status gl843_stop_action (Genesys_Device * dev) { @@ -1989,21 +2275,30 @@ static SANE_Status gl843_xpa_motor_off(Genesys_Device *dev) DBGSTART; - /* unset GPOADF */ - RIE (sanei_genesys_read_register (dev, REG6B, &val)); - val &= ~REG6B_GPOADF; - RIE (sanei_genesys_write_register (dev, REG6B, val)); + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) { + RIE(sanei_genesys_read_register(dev, REG6C, &val)); + val |= REG6C_GPIO14; + RIE(sanei_genesys_write_register(dev, REG6C, val)); - RIE (sanei_genesys_read_register (dev, REGA8, &val)); - val |= REGA8_GPO27; - RIE (sanei_genesys_write_register (dev, REGA8, val)); + RIE(sanei_genesys_read_register(dev, REGA6, &val)); + val &= ~REGA6_GPIO17; + RIE(sanei_genesys_write_register(dev, REGA6,val)); + } else { + /* unset GPOADF */ + RIE (sanei_genesys_read_register (dev, REG6B, &val)); + val &= ~REG6B_GPOADF; + RIE (sanei_genesys_write_register (dev, REG6B, val)); - RIE (sanei_genesys_read_register (dev, REGA9, &val)); - val &= ~REGA9_GPO31; - RIE (sanei_genesys_write_register (dev, REGA9, val)); + RIE (sanei_genesys_read_register (dev, REGA8, &val)); + val |= REGA8_GPO27; + RIE (sanei_genesys_write_register (dev, REGA8, val)); - DBGCOMPLETED; - return status; + RIE (sanei_genesys_read_register (dev, REGA9, &val)); + val &= ~REGA9_GPO31; + RIE (sanei_genesys_write_register (dev, REGA9, val)); + } + DBGCOMPLETED; + return status; } @@ -2013,35 +2308,45 @@ static SANE_Status gl843_xpa_motor_off(Genesys_Device *dev) */ static SANE_Status gl843_xpa_motor_on(Genesys_Device *dev) { - uint8_t val; - SANE_Status status=SANE_STATUS_GOOD; + uint8_t val; + SANE_Status status=SANE_STATUS_GOOD; - DBGSTART; + DBGSTART; - /* set MULTFILM et GPOADF */ - RIE (sanei_genesys_read_register (dev, REG6B, &val)); - val |=REG6B_MULTFILM|REG6B_GPOADF; - RIE (sanei_genesys_write_register (dev, REG6B, val)); + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) { + RIE(sanei_genesys_read_register(dev, REG6C, &val)); + val &= ~REG6C_GPIO14; + RIE(sanei_genesys_write_register(dev, REG6C, val)); - RIE (sanei_genesys_read_register (dev, REG6C, &val)); - val &= ~REG6C_GPIO15; - RIE (sanei_genesys_write_register (dev, REG6C, val)); + RIE(sanei_genesys_read_register(dev, REGA6, &val)); + val |= REGA6_GPIO17; + RIE(sanei_genesys_write_register(dev, REGA6,val)); + } else { + /* set MULTFILM et GPOADF */ + RIE (sanei_genesys_read_register (dev, REG6B, &val)); + val |=REG6B_MULTFILM|REG6B_GPOADF; + RIE (sanei_genesys_write_register (dev, REG6B, val)); - /* Motor power ? No move at all without this one */ - RIE (sanei_genesys_read_register (dev, REGA6, &val)); - val |= REGA6_GPIO20; - RIE (sanei_genesys_write_register(dev,REGA6,val)); + RIE (sanei_genesys_read_register (dev, REG6C, &val)); + val &= ~REG6C_GPIO15; + RIE (sanei_genesys_write_register (dev, REG6C, val)); - RIE (sanei_genesys_read_register (dev, REGA8, &val)); - val &= ~REGA8_GPO27; - RIE (sanei_genesys_write_register (dev, REGA8, val)); + /* Motor power ? No move at all without this one */ + RIE (sanei_genesys_read_register (dev, REGA6, &val)); + val |= REGA6_GPIO20; + RIE (sanei_genesys_write_register(dev,REGA6,val)); - RIE (sanei_genesys_read_register (dev, REGA9, &val)); - val |= REGA9_GPO32|REGA9_GPO31; - RIE (sanei_genesys_write_register (dev, REGA9, val)); + RIE (sanei_genesys_read_register (dev, REGA8, &val)); + val &= ~REGA8_GPO27; + RIE (sanei_genesys_write_register (dev, REGA8, val)); - DBGCOMPLETED; - return status; + RIE (sanei_genesys_read_register (dev, REGA9, &val)); + val |= REGA9_GPO32|REGA9_GPO31; + RIE (sanei_genesys_write_register (dev, REGA9, val)); + } + + DBGCOMPLETED; + return status; } @@ -2130,12 +2435,22 @@ gl843_begin_scan (Genesys_Device * dev, Genesys_Register_Set * reg, /* enable XPA lamp motor */ if (r03 & REG03_XPASEL) { + dev->needs_home_ta = SANE_TRUE; RIE(gl843_xpa_motor_on(dev)); } /* blinking led */ RIE (sanei_genesys_write_register (dev, REG7E, 0x01)); break; + case GPO_CS8600F: + r03 = sanei_genesys_read_reg_from_set (reg, REG03); + /* enable XPA lamp motor */ + if (r03 & REG03_XPASEL) + { + dev->needs_home_ta = SANE_TRUE; + RIE(gl843_xpa_motor_on(dev)); + } + break; case GPO_CS4400F: case GPO_CS8400F: default: @@ -2273,14 +2588,10 @@ static SANE_Status gl843_park_xpa_lamp (Genesys_Device * dev) DBG(DBG_info, "%s: reached home position\n", __func__); DBG(DBG_proc, "%s: finished\n", __func__); - /* clear GPOADF to avoid reparking again */ - sanei_genesys_read_register (dev, REG6B, &val); - val &= ~REG6B_GPOADF; - sanei_genesys_write_register (dev, REG6B, val); + gl843_xpa_motor_off(dev); + dev->needs_home_ta = SANE_FALSE; - /* disable XPA slider motor */ - gl843_xpa_motor_off(dev); - return SANE_STATUS_GOOD; + return SANE_STATUS_GOOD; } sanei_genesys_sleep_ms(100); ++loop; @@ -2306,15 +2617,9 @@ gl843_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home) DBG(DBG_proc, "%s (wait_until_home = %d)\n", __func__, wait_until_home); - if (dev->model->gpo_type == GPO_G4050) - { - /* test if we need to park XPA lamp, we check GPOADF */ - RIE (sanei_genesys_read_register (dev, REG6B, &val)); - if(val & REG6B_GPOADF) - { - RIE(gl843_park_xpa_lamp(dev)); - } - } + if (dev->needs_home_ta) { + RIE(gl843_park_xpa_lamp(dev)); + } /* regular slow back home */ dev->scanhead_position_in_steps = 0; @@ -2480,7 +2785,7 @@ gl843_search_start_position (Genesys_Device * dev) return status; } - size = pixels * dev->model->search_lines; + size = dev->read_bytes_left; std::vector data(size); @@ -2503,6 +2808,7 @@ gl843_search_start_position (Genesys_Device * dev) DBG(DBG_error, "%s: failed to read data: %s\n", __func__, sane_strstatus(status)); return status; } + RIE(gl843_stop_action_no_move(dev, local_reg)); if (DBG_LEVEL >= DBG_data) sanei_genesys_write_pnm_file("gl843_search_position.pnm", data.data(), 8, 1, pixels, @@ -2550,6 +2856,14 @@ gl843_init_regs_for_coarse_calibration (Genesys_Device * dev) else channels = 1; + int flags = SCAN_FLAG_DISABLE_SHADING | + SCAN_FLAG_DISABLE_GAMMA | + SCAN_FLAG_SINGLE_LINE | + SCAN_FLAG_IGNORE_LINE_DISTANCE; + + if (dev->settings.scan_method == SCAN_METHOD_TRANSPARENCY) + flags |= SCAN_FLAG_USE_XPA; + status = gl843_init_scan_regs (dev, dev->calib_reg, dev->settings.xres, @@ -2562,11 +2876,8 @@ gl843_init_regs_for_coarse_calibration (Genesys_Device * dev) 16, channels, dev->settings.scan_mode, - dev->settings.color_filter, - SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE); + dev->settings.color_filter, + flags); if (status != SANE_STATUS_GOOD) { DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); @@ -2660,10 +2971,14 @@ gl843_feed (Genesys_Device * dev, unsigned int steps) } while (status == SANE_STATUS_GOOD && !(val & FEEDFSH)); + // looks like the scanner locks up if we scan immediately after feeding + sanei_genesys_sleep_ms(100); + DBGCOMPLETED; return SANE_STATUS_GOOD; } +static SANE_Status gl843_move_to_ta (Genesys_Device * dev); /* init registers for shading calibration */ /* shading calibration is done at dpihw */ @@ -2680,17 +2995,36 @@ gl843_init_regs_for_shading (Genesys_Device * dev) memcpy (dev->calib_reg, dev->reg, GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set)); dev->calib_channels = 3; - dev->calib_lines = dev->model->shading_lines; - dpihw=sanei_genesys_compute_dpihw(dev,dev->settings.xres); + if (dev->settings.scan_method == SCAN_METHOD_TRANSPARENCY) + dev->calib_lines = dev->model->shading_ta_lines; + else + dev->calib_lines = dev->model->shading_lines; + dpihw=sanei_genesys_compute_dpihw_calibration(dev,dev->settings.xres); factor=dev->sensor.optical_res/dpihw; resolution=dpihw; + dev->calib_resolution = resolution; dev->calib_pixels = dev->sensor.sensor_pixels/factor; - /* distance to move to reach white target */ - move = SANE_UNFIX (dev->model->y_offset_calib); + int flags = SCAN_FLAG_DISABLE_SHADING | + SCAN_FLAG_DISABLE_GAMMA | + SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE | + SCAN_FLAG_IGNORE_LINE_DISTANCE; + + if (dev->settings.scan_method == SCAN_METHOD_TRANSPARENCY) + { + // FIXME: we should handle moving to TA in the caller, this function should only setup the + // registers. + gl843_move_to_ta(dev); + move = 0; // already at dev->model->y_offset_calib_ta implicitly + flags |= SCAN_FLAG_USE_XPA; + } + else + move = SANE_UNFIX(dev->model->y_offset_calib); + move = (move * resolution) / MM_PER_INCH; + status = gl843_init_scan_regs (dev, dev->calib_reg, resolution, @@ -2702,11 +3036,11 @@ gl843_init_regs_for_shading (Genesys_Device * dev) 16, dev->calib_channels, dev->settings.scan_mode, - dev->settings.color_filter, - SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE | - SCAN_FLAG_IGNORE_LINE_DISTANCE); + dev->settings.color_filter, + flags); + + // the pixel number may be updated to conform to scanner constraints + dev->calib_pixels = dev->current_setup.pixels; if (status != SANE_STATUS_GOOD) { @@ -2714,6 +3048,8 @@ gl843_init_regs_for_shading (Genesys_Device * dev) return status; } + dev->calib_total_bytes_to_read = dev->read_bytes_left; + dev->scanhead_position_in_steps += dev->calib_lines + move; sanei_genesys_get_double(dev->calib_reg,REG_STRPIXEL,&strpixel); DBG(DBG_info, "%s: STRPIXEL=%d\n", __func__, strpixel); @@ -2769,18 +3105,34 @@ gl843_init_regs_for_scan (Genesys_Device * dev) move_dpi = dev->motor.base_ydpi; - move = SANE_UNFIX (dev->model->y_offset); + flags = 0; + if (dev->settings.scan_method == SCAN_METHOD_TRANSPARENCY) + { + // FIXME: we should handle moving to TA in the caller, this function should only setup the + // registers. + gl843_move_to_ta(dev); + move = SANE_UNFIX(dev->model->y_offset_ta) - SANE_UNFIX(dev->model->y_offset_calib_ta); + flags |= SCAN_FLAG_USE_XPA; + } + else + move = SANE_UNFIX(dev->model->y_offset); + move += dev->settings.tl_y; move = (move * move_dpi) / MM_PER_INCH; DBG(DBG_info, "%s: move=%f steps\n", __func__, move); /* start */ - start = SANE_UNFIX (dev->model->x_offset); + if(dev->settings.scan_method==SCAN_METHOD_TRANSPARENCY) + start = SANE_UNFIX (dev->model->x_offset_ta); + else + start = SANE_UNFIX (dev->model->x_offset); + + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + start /= 4; // FIXME: compute half_mode here and check it instead of specific model + start += dev->settings.tl_x; start = (start * dev->sensor.optical_res) / MM_PER_INCH; - flags = 0; - /* enable emulated lineart from gray data */ if(dev->settings.scan_mode == SCAN_MODE_LINEART && dev->settings.dynamic_lineart) @@ -2919,7 +3271,7 @@ gl843_led_calibration (Genesys_Device * dev) (dev, dev->calib_reg, GENESYS_GL843_MAX_REGS)); - total_size = num_pixels * channels * (depth / 8) * 1; /* colors * bytes_per_color * scan lines */ + total_size = dev->read_bytes_left; std::vector line(total_size); @@ -2959,6 +3311,7 @@ gl843_led_calibration (Genesys_Device * dev) DBG(DBG_info, "%s: starting first line reading\n", __func__); RIE (gl843_begin_scan (dev, dev->calib_reg, SANE_TRUE)); RIE (sanei_genesys_read_data_from_scanner(dev, line.data(), total_size)); + RIE(gl843_stop_action_no_move(dev, dev->calib_reg)); if (DBG_LEVEL >= DBG_data) { @@ -3061,7 +3414,9 @@ dark_average_channel (uint8_t * data, unsigned int pixels, unsigned int lines, { avg[k] = 0; count = 0; - for (i = 0; i < lines; i++) + // FIXME: start with the second line because the black pixels often have noise on the first + // line; the cause is probably incorrectly cleaned up previous scan + for (i = 1; i < lines; i++) { for (j = 0; j < black; j++) { @@ -3100,33 +3455,48 @@ gl843_offset_calibration (Genesys_Device * dev) bpp = 8; /* compute divider factor to compute final pixels number */ - dpihw = sanei_genesys_compute_dpihw (dev, dev->settings.xres); + dpihw = sanei_genesys_compute_dpihw_calibration (dev, dev->settings.xres); factor = dev->sensor.optical_res / dpihw; resolution = dpihw; - pixels = dev->sensor.sensor_pixels / factor; + + int target_pixels = dev->sensor.sensor_pixels / factor; black_pixels = dev->sensor.black_pixels / factor; + + struct GenesysPhysicalParams params = + gl843_compute_physical_params(dev, dev->settings.xres, dev->settings.xres, target_pixels, lines, + bpp, channels, 0); + + pixels = params.output_pixels; + DBG(DBG_io, "%s: dpihw =%d\n", __func__, dpihw); DBG(DBG_io, "%s: factor =%d\n", __func__, factor); DBG(DBG_io, "%s: resolution =%d\n", __func__, resolution); DBG(DBG_io, "%s: pixels =%d\n", __func__, pixels); DBG(DBG_io, "%s: black_pixels=%d\n", __func__, black_pixels); + int flags = SCAN_FLAG_DISABLE_SHADING | + SCAN_FLAG_DISABLE_GAMMA | + SCAN_FLAG_SINGLE_LINE | + SCAN_FLAG_IGNORE_LINE_DISTANCE; + + if (dev->settings.scan_method == SCAN_METHOD_TRANSPARENCY) + { + flags |= SCAN_FLAG_USE_XPA; + } + status = gl843_init_scan_regs (dev, dev->calib_reg, resolution, resolution, 0, 0, - pixels, + target_pixels, lines, bpp, channels, SCAN_MODE_COLOR, 0, - SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE); + flags); if (status != SANE_STATUS_GOOD) { DBG(DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus(status)); @@ -3135,7 +3505,7 @@ gl843_offset_calibration (Genesys_Device * dev) gl843_set_motor_power (dev->calib_reg, SANE_FALSE); /* allocate memory for scans */ - total_size = pixels * channels * lines * (bpp / 8); /* colors * bytes_per_color * scan lines */ + total_size = dev->read_bytes_left; std::vector first_line(total_size); std::vector second_line(total_size); @@ -3154,6 +3524,8 @@ gl843_offset_calibration (Genesys_Device * dev) DBG(DBG_info, "%s: starting first line reading\n", __func__); RIE(gl843_begin_scan(dev, dev->calib_reg, SANE_TRUE)); RIE(sanei_genesys_read_data_from_scanner(dev, first_line.data(), total_size)); + RIE(gl843_stop_action_no_move(dev, dev->calib_reg)); + if (DBG_LEVEL >= DBG_data) { char fn[40]; @@ -3181,6 +3553,7 @@ gl843_offset_calibration (Genesys_Device * dev) DBG(DBG_info, "%s: starting second line reading\n", __func__); RIE(gl843_begin_scan (dev, dev->calib_reg, SANE_TRUE)); RIE(sanei_genesys_read_data_from_scanner(dev, second_line.data(), total_size)); + RIE(gl843_stop_action_no_move(dev, dev->calib_reg)); for (i = 0; i < 3; i++) { @@ -3216,6 +3589,7 @@ gl843_offset_calibration (Genesys_Device * dev) DBG(DBG_info, "%s: starting second line reading\n", __func__); RIE(gl843_begin_scan (dev, dev->calib_reg, SANE_TRUE)); RIE(sanei_genesys_read_data_from_scanner(dev, second_line.data(), total_size)); + RIE(gl843_stop_action_no_move(dev, dev->calib_reg)); if (DBG_LEVEL >= DBG_data) { @@ -3283,13 +3657,13 @@ gl843_coarse_gain_calibration (Genesys_Device * dev, int dpi) int i, j, channels; SANE_Status status = SANE_STATUS_GOOD; int max[3]; - float gain[3],coeff; - int val, code, lines; + float coeff; + int val, lines; int resolution; int bpp; DBG(DBG_proc, "%s: dpi = %d\n", __func__, dpi); - dpihw=sanei_genesys_compute_dpihw(dev, dpi); + dpihw=sanei_genesys_compute_dpihw_calibration(dev, dpi); factor=dev->sensor.optical_res/dpihw; /* coarse gain calibration is always done in color mode */ @@ -3314,7 +3688,22 @@ gl843_coarse_gain_calibration (Genesys_Device * dev, int dpi) resolution=dpihw; lines=10; bpp=8; - pixels = dev->sensor.sensor_pixels / factor; + int target_pixels = dev->sensor.sensor_pixels / factor; + + struct GenesysPhysicalParams params = + gl843_compute_physical_params(dev, dpi, dpi, target_pixels, lines, bpp, channels, 0); + + pixels = params.output_pixels; + + int flags = SCAN_FLAG_DISABLE_SHADING | + SCAN_FLAG_DISABLE_GAMMA | + SCAN_FLAG_SINGLE_LINE | + SCAN_FLAG_IGNORE_LINE_DISTANCE; + + if (dev->settings.scan_method == SCAN_METHOD_TRANSPARENCY) + { + flags |= SCAN_FLAG_USE_XPA; + } status = gl843_init_scan_regs (dev, dev->calib_reg, @@ -3322,16 +3711,13 @@ gl843_coarse_gain_calibration (Genesys_Device * dev, int dpi) resolution, 0, 0, - pixels, + target_pixels, lines, bpp, channels, SCAN_MODE_COLOR, dev->settings.color_filter, - SCAN_FLAG_DISABLE_SHADING | - SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_SINGLE_LINE | - SCAN_FLAG_IGNORE_LINE_DISTANCE); + flags); gl843_set_motor_power (dev->calib_reg, SANE_FALSE); if (status != SANE_STATUS_GOOD) @@ -3343,13 +3729,14 @@ gl843_coarse_gain_calibration (Genesys_Device * dev, int dpi) RIE (dev->model->cmd_set->bulk_write_register (dev, dev->calib_reg, GENESYS_GL843_MAX_REGS)); - total_size = pixels * channels * (bpp/8) * lines; + total_size = dev->read_bytes_left; std::vector line(total_size); RIE(gl843_set_fe(dev, AFE_SET)); RIE(gl843_begin_scan (dev, dev->calib_reg, SANE_TRUE)); RIE(sanei_genesys_read_data_from_scanner (dev, line.data(), total_size)); + RIE(gl843_stop_action_no_move(dev, dev->calib_reg)); if (DBG_LEVEL >= DBG_data) sanei_genesys_write_pnm_file("gl843_coarse.pnm", line.data(), bpp, channels, pixels, lines); @@ -3358,7 +3745,9 @@ gl843_coarse_gain_calibration (Genesys_Device * dev, int dpi) for (j = 0; j < channels; j++) { max[j] = 0; - for (i = pixels/4; i < (pixels*3/4); i++) + // FIXME: start from the second line because the first line often has artifacts. Probably + // caused by unclean cleanup of previous scans + for (i = pixels/4 + pixels; i < (pixels*3/4) + pixels; i++) { if(bpp==16) { @@ -3383,18 +3772,35 @@ gl843_coarse_gain_calibration (Genesys_Device * dev, int dpi) } max[j] = max[j] / (pixels/2); - gain[j] = ((float) dev->sensor.gain_white_ref*coeff) / max[j]; + /* the flow of data through the frontend ADC is as follows (see e.g. VM8192 datasheet) + input + -> apply offset (o = i + 260mV * (DAC[7:0]-127.5)/127.5) -> + -> apply gain (o = i * 208/(283-PGA[7:0]) + -> ADC - /* turn logical gain value into gain code, checking for overflow */ - code = 283 - 208 / gain[j]; + Here we have some input data that was acquired with zero gain (PGA==0). + We want to compute gain such that the output would approach full ADC range (controlled by + gain_white_ref). + + We want to solve the following for {PGA}: + + {input} * 208 / (283 - 0) = {output} + {input} * 208 / (283 - {PGA}) = {target output} + + The solution is the following equation: + + {PGA} = 283 * (1 - {output} / {target output}) + */ + float gain = ((float) max[j] / (dev->sensor.gain_white_ref*coeff)); + int code = 283 * (1 - gain); if (code > 255) code = 255; else if (code < 0) code = 0; dev->frontend.gain[j] = code; - DBG(DBG_proc, "%s: channel %d, max=%d, gain = %f, setting:%d\n", __func__, j, max[j], gain[j], - dev->frontend.gain[j]); + DBG(DBG_proc, "%s: channel %d, max=%d, gain = %f, setting:%d\n", __func__, j, max[j], gain, + code); } if (dev->model->is_cis) @@ -3442,7 +3848,8 @@ gl843_init_regs_for_warmup (Genesys_Device * dev, /* setup scan */ *channels=3; resolution=600; - dpihw=sanei_genesys_compute_dpihw(dev, resolution); + dpihw=sanei_genesys_compute_dpihw_calibration(dev, resolution); + resolution=dpihw; factor=dev->sensor.optical_res/dpihw; num_pixels=dev->sensor.sensor_pixels/(factor*2); *total_size = num_pixels * 3 * 1; @@ -3558,30 +3965,54 @@ gl843_boot (Genesys_Device * dev, SANE_Bool cold) /* Set default values for registers */ gl843_init_registers (dev); - RIE (sanei_genesys_write_register (dev, REG6B, 0x02)); + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + // turns on vref control for maximum current of the motor driver + RIE(sanei_genesys_write_register (dev, REG6B, 0x72)); + } + else + { + RIE(sanei_genesys_write_register (dev, REG6B, 0x02)); + } /* Write initial registers */ RIE (dev->model->cmd_set->bulk_write_register (dev, dev->reg, GENESYS_GL843_MAX_REGS)); - /* Enable DRAM by setting a rising edge on bit 3 of reg 0x0b */ + // Enable DRAM by setting a rising edge on bit 3 of reg 0x0b val = dev->reg[reg_0x0b].value & REG0B_DRAMSEL; val = (val | REG0B_ENBDRAM); RIE (sanei_genesys_write_register (dev, REG0B, val)); dev->reg[reg_0x0b].value = val; - /* URB 14 control 0x40 0x0c 0x8c 0x10 len 1 wrote 0xb4 */ - RIE (sanei_genesys_write_0x8c (dev, 0x10, 0xb4)); + + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + RIE (sanei_genesys_write_0x8c (dev, 0x10, 0xc8)); + } + else + { + RIE (sanei_genesys_write_0x8c (dev, 0x10, 0xb4)); + } /* CLKSET */ - val = (dev->reg[reg_0x0b].value & ~REG0B_CLKSET) | REG0B_48MHZ; + int clock_freq = REG0B_48MHZ; + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + clock_freq = REG0B_60MHZ; + + val = (dev->reg[reg_0x0b].value & ~REG0B_CLKSET) | clock_freq; + RIE (sanei_genesys_write_register (dev, REG0B, val)); dev->reg[reg_0x0b].value = val; /* prevent further writings by bulk write register */ dev->reg[reg_0x0b].address = 0x00; - /* set up end access */ - sanei_genesys_write_register (dev, REGA7, 0x04); - sanei_genesys_write_register (dev, REGA9, 0x00); + if (dev->model->model_id != MODEL_CANON_CANOSCAN_8600F) + { + // set up end access + // FIXME: this is overwritten in gl843_init_gpio + sanei_genesys_write_register(dev, REGA7, 0x04); + sanei_genesys_write_register(dev, REGA9, 0x00); + } /* set RAM read address */ RIE (sanei_genesys_write_register (dev, REG29, 0x00)); @@ -3719,8 +4150,6 @@ gl843_search_strip (Genesys_Device * dev, SANE_Bool forward, SANE_Bool black) lines = (dev->model->shading_lines * dpi) / dev->motor.base_ydpi; depth = 8; pixels = (dev->sensor.sensor_pixels * dpi) / dev->sensor.optical_res; - size = pixels * channels * lines * (depth / 8); - std::vector data(size); dev->scanhead_position_in_steps = 0; @@ -3747,6 +4176,9 @@ gl843_search_strip (Genesys_Device * dev, SANE_Bool forward, SANE_Bool black) return status; } + size = dev->read_bytes_left; + std::vector data(size); + /* set up for reverse or forward */ r = sanei_genesys_get_address (local_reg, REG02); if (forward) @@ -3984,6 +4416,16 @@ gl843_send_shading_data (Genesys_Device * dev, uint8_t * data, int size) strpixel*=tgtime; endpixel*=tgtime; + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F && dev->current_setup.half_ccd) + { + int optical_res = dev->sensor.optical_res / 4; + int dpiset_real = dpiset / 4; + int half_ccd_factor = optical_res / + sanei_genesys_compute_dpihw_calibration(dev, dpiset_real); + strpixel /= half_ccd_factor; + endpixel /= half_ccd_factor; + } + /* 16 bit words, 2 words per color, 3 color channels */ offset=(strpixel-startx)*2*2*3; length=(endpixel-strpixel)*2*2*3; diff --git a/backend/genesys_gl843.h b/backend/genesys_gl843.h index 6d9da33b8..797c200b9 100644 --- a/backend/genesys_gl843.h +++ b/backend/genesys_gl843.h @@ -557,6 +557,9 @@ static Gpio_layout gpios[]={ { GPO_CS8400F, 0x00, 0x03, 0x00, 0x02 }, + { + GPO_CS8600F, 0x00, 0xff, 0x00, 0x00, + }, /* end marker */ { 0, 0, 0, 0, 0 @@ -569,23 +572,29 @@ static Gpio_layout gpios[]={ */ typedef struct { int sensor_type; /**> sensor id */ - int dpi; /**> maximum dpi for which data are valid */ - int exposure; /**> exposure */ + int dpi; /**> maximum dpi for which data are valid, used only to select the sensor */ + + // exposure. The value of LPERIOD register depend on it + int exposure; int ck1map; /**> CK1MAP */ int ck3map; /**> CK2MAP */ int ck4map; /**> CK3MAP */ - int segcnt; /**> SEGCNT */ - int tg0cnt; /**> TG0CNT */ - int expdummy; /**> exposure dummy */ - int expr; /**> initial red exposure */ - int expg; /**> initial green exposure */ - int expb; /**> initial blue exposure */ + int segcnt; /**> SEGCNT */ // FIXME: not used + int tg0cnt; /**> TG0CNT */ // FIXME: not used + int expdummy; /**> exposure dummy */ // FIXME: not used + int expr; /**> initial red exposure */ // FIXME: not used + int expg; /**> initial green exposure */ // FIXME: not used + int expb; /**> initial blue exposure */ // FIXME: not used uint8_t reg0c; /**> register 0x0c value */ uint8_t reg70; /**> register 0x70 value */ uint8_t reg71; /**> register 0x71 value */ uint8_t reg9e; /**> register 0x9e value */ uint8_t regaa; /**> either undocumented or mapping to somewhere else */ + + // 0x10-0x15 define the exposure and may be modified during calibration. uint8_t regs_0x10_0x1d[14]; + // 0x5b-0x5c defines download address and is later overwritten + // 0x5d is unused. uint8_t regs_0x52_0x5e[13]; } Sensor_Profile; @@ -597,6 +606,26 @@ static Sensor_Profile xpa_sensors[]={ {0x2c, 0x09, 0x22, 0xb8, 0x10, 0xf0, 0x33, 0x4c, 0x01, 0x2a, 0x30, 0x00, 0x00, 0x08} , {0x0e, 0x11, 0x02, 0x05, 0x08, 0x0b, 0x6b, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x6f}, }, + { + // sensor_type + CCD_CS8600F, + // dpi + 4800, + // exposure + 0x5dc0, + // ck1map, ck3map, ck4map + 0x03f0f0, 0x03fe00, 0x009249, + // segcnt, tg0cnt + 0, 0, + // expdummy, expr, expg, expb + 0, 0, 0, 0, + // reg0c, reg70, reg71, reg9e, regaa + 0x00, 0x00, 0x02, 0x2d, 0x00, + // regs_0x10_0x1d + { 0x9c, 0x40, 0x9c, 0x40, 0x9c, 0x40, 0x13, 0x0a, 0x10, 0x2a, 0x30, 0x00, 0x00, 0x6b }, + // regs_0x52_0x5e + { 0x0c, 0x0f, 0x00, 0x03, 0x06, 0x09, 0x6b, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1f }, + } }; static Sensor_Profile sensors[]={ /* 0c 70 71 9e aa*/ @@ -633,7 +662,27 @@ static Sensor_Profile sensors[]={ {CCD_CS8400F, 600, 7200, 0x0e3f, 0x0000, 0x1b6db, 5168, 0, 0x2a, 0x0, 0x0, 0x0, 0x00, 0x01, 0x02, 0x00, 0x00, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x0c, 0x13, 0x2a, 0x30, 0x00, 0x00, 0x84}, {0x0d, 0x10, 0x01, 0x04, 0x07, 0x0a, 0x6b, 0x00, 0x40, 0x00, 0x00, 0x00, 0x85}, - } + }, + { + // sensor_type + CCD_CS8600F, + // dpi + 4800, + // exposure + 0x5dc0, + // ck1map, ck3map, ck4map + 0x03f0f0, 0x03fe00, 0x009249, + // segcnt, tg0cnt + 0, 0, + // expdummy, expr, expg, expb + 0, 0, 0, 0, + // reg0c, reg70, reg71, reg9e, regaa + 0x00, 0x00, 0x02, 0x2d, 0x00, + // regs_0x10_0x1d + { 0x9c, 0x40, 0x9c, 0x40, 0x9c, 0x40, 0x13, 0x0a, 0x10, 0x2a, 0x30, 0x00, 0x00, 0x6b }, + // regs_0x52_0x5e + { 0x0c, 0x0f, 0x00, 0x03, 0x06, 0x09, 0x6b, 0x00, 0x40, 0x00, 0x00, 0x00, 0x1f }, + } }; static uint32_t kvss080[]={44444, 34188, 32520, 29630, 26666, 24242, 22222, 19048, 16666, 15686, 14814, 14034, 12402, 11110, 8888, 7618, 6666, 5926, 5228, 4678, 4172, 3682, 3336, 3074, 2866, 2702, 2566, 2450, 2352, 2266, 2188, 2118, 2056, 2002, 1950, 1904, 1860, 1820, 1784, 1748, 1716, 1684, 1656, 1628, 1600, 1576, 1552, 1528, 1506, 1486, 1466, 1446, 1428, 1410, 1394, 1376, 1360, 1346, 1330, 1316, 1302, 1288, 1276, 1264, 1250, 1238, 1228, 1216, 1206, 1194, 1184, 1174, 1164, 1154, 1146, 1136, 1128, 1120, 1110, 1102, 1094, 1088, 1080, 1072, 1064, 1058, 1050, 1044, 1038, 1030, 1024, 1018, 1012, 1006, 1000, 994, 988, 984, 978, 972, 968, 962, 958, 952, 948, 942, 938, 934, 928, 924, 920, 916, 912, 908, 904, 900, 896, 892, 888, 884, 882, 878, 874, 870, 868, 864, 860, 858, 854, 850, 848, 844, 842, 838, 836, 832, 830, 826, 824, 822, 820, 816, 814, 812, 808, 806, 804, 802, 800, 796, 794, 792, 790, 788, 786, 784, 782, 778, 776, 774, 772, 770, 768, 766, 764, 762, 760, 758, 756, 754, 752, 750, 750, 748, 746, 744, 742, 740, 738, 736, 734, 734, 732, 730, 728, 726, 724, 724, 722, 720, 718, 716, 716, 714, 712, 710, 710, 708, 706, 704, 704, 702, 700, 698, 698, 696, 694, 694, 692, 690, 690, 688, 686, 686, 684, 682, 682, 680, 678, 678, 676, 674, 674, 672, 672, 670, 668, 668, 666, 666, 664, 662, 662, 660, 660, 658, 656, 656, 654, 654, 652, 652, 650, 650, 648, 646, 646, 644, 644, 642, 642, 640, 640, 638, 638, 636, 636, 636, 634, 634, 632, 632, 630, 630, 628, 628, 626, 626, 624, 624, 624, 622, 622, 620, 620, 618, 618, 618, 616, 616, 614, 614, 612, 612, 612, 610, 610, 608, 608, 608, 606, 606, 606, 604, 604, 602, 602, 602, 600, 600, 600, 598, 598, 596, 596, 596, 594, 594, 594, 592, 592, 592, 590, 590, 590, 588, 588, 588, 586, 586, 586, 584, 584, 584, 582, 582, 582, 590, 590, 590, 588, 588, 588, 586, 586, 586, 584, 584, 584, 582, 582, 582, 580, 580, 580, 578, 578, 578, 576, 576, 576, 576, 574, 574, 574, 572, 572, 572, 570, 570, 570, 568, 568, 568, 568, 566, 566, 566, 564, 564, 564, 562, 562, 562, 562, 560, 560, 560, 558, 558, 558, 558, 556, 556, 556, 554, 554, 554, 552, 552, 552, 552, 550, 550, 550, 548, 548, 548, 548, 546, 546, 546, 546, 544, 544, 544, 542, 542, 542, 542, 540, 540, 540, 538, 538, 538, 538, 536, 536, 536, 536, 534, 534, 534, 534, 532, 532, 532, 530, 530, 530, 530, 528, 528, 528, 528, 526, 526, 526, 526, 524, 524, 524, 524, 522, 522, 522, 522, 520, 520, 520, 520, 518, 518, 518, 516, 516, 516, 516, 514, 514, 514, 514, 514, 512, 512, 512, 512, 510, 510, 510, 510, 508, 508, 508, 508, 506, 506, 506, 506, 504, 504, 504, 504, 502, 502, 502, 502, 500, 500, 500, 500, 0}; @@ -643,6 +692,30 @@ static uint32_t g4050_max[]={42752,42752,42752,42752,42752,42752,42752,42752, 41 static uint32_t g4050_xpa[]={9422,5978,4736,4028,3560,3220,2914,2756,2588,2448,2328,2224,2132,2052,1978,1914,1854,1800,1752,1706,1664,1626,1588,1554,1522,1492,1464,1438,1412,1388,1366,1344,1324,1304,1284,1268,1250,1232,1218,1202,1188,1172,1160,1146,1134,1120,1110,1098,1086,1076,1066,1056,1046,1036,1026,1018,1008,1000,992,984,976,968,960,952,946,938,932,924,918,912,906,898,892,888,882,876,870,864,860,854,848,844,838,834,828,824,820,814,810,806,802,798,794,790,786,782,778,774,770,766,762,758,754,752,748,744,740,738,734,730,728,724,722,718,716,712,710,706,704,700,698,696,692,690,686,684,682,678,676,674,672,668,666,664,662,660,656,654,652,650,648,646,644,642,638,636,634,632,630,628,626,624,622,620,618,616,614,612,612,610,608,606,604,602,600,598,596,594,594,592,590,588,586,584,584,582,580,578,576,576,574,572,570,570,568,566,564,564,562,560,560,558,556,554,554,552,550,550,548,546,546,544,542,542,540,540,538,536,536,534,532,532,530,530,528,526,526,524,524,522,522,520,518,518,516,516,514,514,512,512,510,508,508,506,506,504,504,502,502,500,500,498,498,496,496,494,494,492,492,492,490,490,488,488,486,486,484,484,482,482,480,480,480,478,478,476,476,474,474,474,472,472,470,470,468,468,468,466,466,464,464,464,462,462,462,460,460,458,458,458,456,456,454,454,454,452,452,452,450,450,450,448,448,446,446,446,444,444,444,442,442,442,440,440,440,438,438,438,436,436,436,434,434,434,432,432,432,430,430,430,430,428,428,428,426,426,426,424,424,424,424,422,422,422,420,420,420,418,418,418,418,416,416,416,414,414,414,414,412,412,412,412,410,410,410,408,408,408,408,406,406,406,406,404,404,404,404,402,402,402,402,400,400,400,400,398,398,398,398,396,396,396,396,394,394,394,394,392,392,392,392,392,390,390,390,390,388,388,388,388,386,386,386,386,386,384,384,384,384,384,382,382,382,382,380,380,380,380,380,378,378,378,378,378,376,376,376,376,376,374,374,374,374,374,372,372,372,372,372,370,370,370,370,370,368,368,368,368,368,366,366,366,366,366,364,364,364,364,364,364,362,362,362,362,362,360,360,360,360,360,360,358,358,358,358,358,358,356,356,356,356,356,354,354,354,354,354,354,352,352,352,352,352,352,350,350,350,350,350,350,350,348,348,348,348,348,348,346,346,346,346,346,346,344,344,344,344,344,344,344,342,342,342,342,342,342,340,340,340,340,340,340,340,338,338,338,338,338,338,338,336,336,336,336,336,336,336,334,334,334,334,334,334,334,332,332,332,332,332,332,332,330,330,330,330,330,330,330,330,328,328,328,328,328,328,328,326,326,326,326,326,326,326,326,324,324,324,324,324,324,324,324,322,322,322,322,322,322,322,322,320,320,320,320,320,320,320,320,318,318,318,318,318,318,318,318,318,316,316,316,316,316,316,316,316,314,314,314,314,314,314,314,314,314,312,312,312,312,312,312,312,312,312,310,310,310,310,310,310,310,310,310,308,308,308,308,308,308,308,308,308,306,306,306,306,306,306,306,306,306,306,304,304,304,304,304,304,304,304,304,302,302,302,302,302,302,302,302,302,302,300,300,300,300,300,300,300,300,300,300,298,298,298,298,298,298,298,298,298,298,298,296,296,296,296,296,296,296,296,296,296,294,294,294,294,294,294,294,294,294,294,294,292,292,292,292,292,292,292,292,292,292,292,290,290,290,290,290,290,290,290,290,290,290,288,288,288,288,288,288,288,288,288,288,288,288,286,286,286,286,286,286,286,286,286,286,286,286,284,284,284,284,284,284,284,284,284,284,284,284,282,282,282,282,282,282,282,282,282,282,282,282,280,280,280,280,280,280,280,280,280,280,280,280,280,278,278,278,278,278,278,278,278,278,278,278,278,278,276,276,276,276,276,276,276,276,276,276,276,276,276,274,274,274,274,274,274,274,274,274,274,274,274,274,274,272,272,272,272,272,272,272,272,272,272,272,272,272,272,270,270,270,270,270,270,270,270,270,270,270,270,270,270,268,268,268,268,268,268,268,268,268,268,268,268,268,268,268,266,266,266,266,266,266,266,266,266,266,266,266,266,266,266,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,260,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,258,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,0}; static uint32_t cs4400f_fast[]={49152, 49152, 31144, 23652, 19538, 16822, 14908, 13442, 12288, 11356, 10590, 9922, 9362, 8886, 8456, 8064, 7728, 7418, 7148, 6882, 6664, 6446, 6252, 6060, 5890, 5740, 5586, 5450, 5322, 5198, 5080, 4968, 4868, 4766, 4674, 4584, 4500, 4418, 4338, 4262, 4194, 4122, 4058, 3996, 3932, 3874, 3816, 3766, 3712, 3662, 3610, 3566, 3518, 3474, 3430, 3388, 3350, 3310, 3272, 3236, 3200, 3164, 3130, 3096, 3062, 3032, 3000, 2972, 2942, 2914, 2884, 2858, 2832, 2806, 2780, 2756, 2732, 2708, 2686, 2662, 2640, 2618, 2596, 2576, 2554, 2536, 2516, 2496, 2478, 2458, 2440, 2422, 2404, 2388, 2370, 2354, 2338, 2320, 2306, 2290, 2276, 2258, 2244, 2230, 2216, 2202, 2188, 2174, 2162, 2148, 2134, 2122, 2108, 2096, 2084, 2072, 2060, 2048, 2036, 2026, 2014, 2002, 1992, 1982, 1970, 1960, 1950, 1940, 1928, 1920, 1908, 1900, 1890, 1880, 1872, 1862, 1852, 1844, 1834, 1826, 1818, 1808, 1800, 1792, 1784, 1776, 1768, 1760, 1752, 1742, 1736, 1728, 1720, 1712, 1704, 1698, 1690, 1684, 1676, 1670, 1662, 1656, 1648, 1642, 1634, 1628, 1622, 1616, 1608, 1602, 1596, 1590, 1584, 1578, 1572, 1566, 1560, 1554, 1548, 1542, 1536, 1532, 1526, 1520, 1514, 1508, 1504, 1498, 1492, 1488, 1482, 1478, 1472, 1466, 1462, 1456, 1452, 1446, 1442, 1438, 1432, 1428, 1424, 1418, 1414, 1410, 1404, 1400, 1396, 1390, 1386, 1382, 1378, 1374, 1370, 1364, 1360, 1356, 1352, 1348, 1344, 1340, 1336, 1332, 1328, 1324, 1320, 1316, 1312, 1308, 1304, 1302, 1298, 1294, 1290, 1286, 1282, 1278, 1276, 1272, 1268, 1264, 1262, 1258, 1254, 1250, 1248, 1244, 1240, 1238, 1234, 1230, 1228, 1224, 1222, 1218, 1214, 1212, 1208, 1206, 1202, 1200, 1196, 1194, 1190, 1186, 1184, 1182, 1178, 1176, 1172, 1170, 1166, 1164, 1162, 1158, 1156, 1152, 1150, 1148, 1144, 1142, 1138, 1136, 1134, 1130, 1128, 1126, 1122, 1120, 1118, 1116, 1112, 1110, 1108, 1106, 1102, 1100, 1098, 1096, 1092, 1090, 1088, 1086, 1082, 1080, 1078, 1076, 1074, 1072, 1068, 1066, 1064, 1062, 1060, 1058, 1056, 1054, 1052, 1048, 1046, 1044, 1042, 1040, 1038, 1036, 1034, 1032, 1030, 1028, 1026, 1024, 1022, 1020, 1018, 1016, 1014, 1012, 1010, 1008, 1006, 1004, 1002, 1000, 998, 996, 994, 992, 990, 988, 986, 984, 982, 980, 978, 976, 974, 972, 972, 970, 968, 966, 964, 962, 960, 958, 956, 956, 954, 952, 950, 948, 946, 944, 944, 942, 940, 938, 936, 934, 934, 932, 930, 928, 926, 926, 924, 922, 920, 918, 918, 916, 914, 912, 912, 910, 908, 906, 904, 904, 902, 900, 898, 898, 896, 894, 892, 892, 890, 888, 888, 886, 884, 882, 882, 880, 878, 878, 876, 874, 874, 872, 870, 868, 868, 866, 864, 864, 862, 860, 860, 858, 856, 856, 854, 852, 852, 850, 848, 848, 846, 846, 844, 842, 842, 840, 838, 838, 836, 834, 834, 832, 832, 830, 828, 828, 826, 826, 824, 822, 822, 820, 820, 818, 816, 816, 814, 814, 812, 812, 810, 808, 808, 806, 806, 804, 802, 802, 800, 800, 798, 798, 796, 796, 794, 792, 792, 790, 790, 788, 788, 786, 786, 784, 784, 782, 782, 780, 780, 778, 778, 776, 774, 774, 772, 772, 770, 770, 768, 768, 766, 766, 764, 764, 762, 762, 760, 760, 758, 758, 758, 756, 756, 754, 754, 752, 752, 750, 750, 748, 748, 746, 746, 744, 744, 742, 742, 740, 740, 738, 738, 738, 736, 736, 734, 734, 732, 732, 730, 730, 730, 728, 728, 726, 726, 724, 724, 722, 722, 722, 720, 720, 718, 718, 718, 716, 716, 714, 714, 712, 712, 712, 710, 710, 708, 708, 708, 706, 706, 704, 704, 702, 702, 702, 700, 700, 698, 698, 698, 696, 696, 694, 694, 694, 692, 692, 692, 690, 690, 688, 688, 688, 686, 686, 684, 684, 684, 682, 682, 682, 680, 680, 680, 678, 678, 676, 676, 676, 674, 674, 674, 672, 672, 670, 670, 670, 668, 668, 668, 666, 666, 666, 664, 664, 664, 662, 662, 660, 660, 660, 658, 658, 658, 656, 656, 656, 654, 654, 654, 652, 652, 652, 650, 650, 650, 648, 648, 648, 646, 646, 646, 644, 644, 644, 642, 642, 642, 640, 640, 640, 640, 638, 638, 638, 636, 636, 636, 634, 634, 634, 632, 632, 632, 630, 630, 630, 630, 628, 628, 628, 626, 626, 626, 624, 624, 624, 624, 622, 622, 622, 620, 620, 620, 618, 618, 618, 618, 616, 616, 616, 614, 614, 614, 614, 612, 612, 612, 610, 610, 610, 610, 608, 608, 608, 606, 606, 606, 606, 604, 604, 604, 604, 602, 602, 602, 600, 600, 600, 600, 598, 598, 598, 598, 596, 596, 596, 594, 594, 594, 594, 592, 592, 592, 592, 590, 590, 590, 590, 588, 588, 588, 586, 586, 586, 586, 584, 584, 584, 584, 582, 582, 582, 582, 580, 580, 580, 580, 578, 578, 578, 578, 576, 576, 576, 576, 574, 574, 574, 574, 574, 572, 572, 572, 572, 570, 570, 570, 570, 568, 568, 568, 568, 566, 566, 566, 566, 564, 564, 564, 564, 564, 562, 562, 562, 562, 560, 560, 560, 560, 558, 558, 558, 558, 558, 556, 556, 556, 556, 554, 554, 554, 554, 554, 552, 552, 552, 552, 550, 550, 550, 550, 550, 548, 548, 548, 548, 546, 546, 546, 546, 546, 544, 544, 544, 544, 544, 542, 542, 542, 542, 540, 540, 540, 540, 540, 538, 538, 538, 538, 538, 536, 536, 536, 536, 536, 534, 534, 534, 534, 534, 532, 532, 532, 532, 532, 530, 530, 530, 530, 530, 528, 528, 528, 528, 528, 526, 526, 526, 526, 526, 524, 524, 524, 524, 524, 522, 522, 522, 522, 522, 520, 520, 520, 520, 520, 520, 518, 518, 518, 518, 518, 516, 516, 516, 516, 516, 514, 514, 514, 514, 514, 514, 512, 512, 512, 512, 512, 510, 510, 510, 510, 510, 510, 508, 508, 508, 508, 508, 506, 506, 506, 506, 506, 506, 504, 504, 504, 504, 504, 502, 502, 502, 502, 502, 502, 500, 500, 500, 500, 500, 500, 498, 498, 498, 498, 498, 498, 496, 496, 496, 496, 496, 496, 494, 494, 494, 494, 494, 494, 492, 492, 492, 492, 492, 492, 490, 490, 490, 490, 490, 490, 488, 488, 488, 488, 488, 488, 486, 486, 486, 486, 486, 486, 484, 484, 484, 484, 484, 484, 484, 0, 0, 0, 0, 0}; static uint32_t cs8400f_fast[]={8743, 8205, 7017, 6201, 4938, 4016, 3371, 2966, 2682, 2469, 2296, 2159, 2041, 1942, 1857, 1782, 1716, 1656, 1602, 1554, 1510, 1470, 1432, 1398, 1366, 1336, 1309, 1282, 1258, 1235, 1213, 1193, 1173, 1154, 1137, 1120, 1104, 1089, 1074, 1060, 1047, 1034, 1022, 1010, 998, 987, 976, 966, 956, 946, 937, 928, 919, 911, 902, 894, 887, 879, 872, 864, 858, 851, 844, 838, 832, 825, 819, 814, 808, 802, 797, 792, 786, 781, 776, 771, 766, 762, 757, 753, 748, 744, 740, 736, 731, 728, 724, 720, 716, 712, 709, 705, 701, 698, 695, 691, 688, 685, 682, 679, 675, 672, 669, 666, 664, 661, 658, 655, 652, 650, 647, 644, 642, 639, 637, 634, 632, 629, 627, 625, 622, 620, 618, 616, 613, 611, 609, 607, 605, 603, 601, 599, 597, 595, 593, 591, 589, 587, 585, 583, 581, 580, 578, 576, 574, 573, 571, 569, 567, 566, 564, 563, 561, 559, 558, 556, 555, 553, 552, 550, 549, 547, 546, 544, 543, 542, 540, 539, 537, 536, 535, 533, 532, 531, 529, 528, 527, 526, 524, 523, 522, 521, 519, 518, 517, 516, 515, 514, 512, 511, 510, 509, 508, 507, 506, 505, 504, 502, 501, 500, 499, 498, 497, 496, 495, 494, 493, 492, 491, 490, 489, 488, 488, 487, 486, 485, 484, 483, 482, 481, 480, 479, 478, 477, 477, 476, 475, 474, 473, 472, 472, 471, 470, 469, 468, 467, 467, 466, 465, 464, 464, 463, 462, 461, 460, 460, 459, 458, 457, 457, 456, 455, 454, 454, 453, 452, 452, 451, 450, 449, 449, 448, 448, 447, 446, 446, 445, 444, 444, 443, 442, 442, 441, 440, 440, 439, 438, 438, 437, 437, 436, 435, 435, 434, 434, 433, 432, 432, 431, 431, 430, 429, 429, 428, 428, 427, 427, 426, 425, 425, 424, 424, 423, 423, 422, 422, 421, 421, 420, 420, 419, 419, 418, 417, 417, 416, 416, 416, 415, 414, 414, 414, 413, 412, 412, 412, 411, 411, 410, 410, 409, 409, 408, 408, 407, 407, 406, 406, 406, 405, 405, 404, 404, 403, 403, 402, 402, 402, 401, 401, 400, 400, 399, 399, 398, 398, 398, 397, 397, 396, 396, 396, 395, 395, 394, 394, 394, 393, 393, 392, 392, 392, 391, 391, 391, 390, 390, 389, 389, 389, 388, 388, 387, 387, 387, 386, 386, 385, 385, 385, 384, 384, 384, 383, 383, 383, 382, 382, 382, 381, 381, 381, 380, 380, 380, 379, 379, 379, 378, 378, 378, 377, 377, 377, 376, 376, 376, 375, 375, 375, 374, 374, 374, 373, 373, 373, 372, 372, 372, 371, 371, 371, 370, 370, 370, 370, 369, 369, 369, 368, 368, 368, 368, 367, 367, 367, 367, 366, 366, 366, 365, 365, 365, 365, 364, 364, 364, 363, 363, 363, 363, 362, 362, 362, 362, 361, 361, 361, 360, 360, 360, 360, 359, 359, 359, 358, 358, 358, 358, 357, 357, 357, 356, 356, 356, 356, 355, 355, 355, 355, 354, 354, 354, 354, 354, 353, 353, 353, 353, 352, 352, 352, 352, 352, 351, 351, 351, 351, 350, 350, 350, 350, 350, 349, 349, 349, 349, 348, 348, 348, 348, 348, 347, 347, 347, 347, 346, 346, 346, 346, 346, 345, 345, 345, 345, 344, 344, 344, 344, 344, 343, 343, 343, 343, 342, 342, 342, 342, 342, 341, 341, 341, 341, 340, 340, 340, 340, 340, 339, 339, 339, 339, 338, 338, 338, 338, 338, 337, 337, 337, 337, 337, 337, 336, 336, 336, 336, 336, 336, 335, 335, 335, 335, 335, 335, 334, 334, 334, 334, 334, 334, 333, 333, 333, 333, 333, 333, 332, 332, 332, 332, 332, 332, 331, 331, 331, 331, 331, 331, 330, 330, 330, 330, 330, 330, 329, 329, 329, 329, 329, 329, 328, 328, 328, 328, 328, 328, 327, 327, 327, 327, 327, 327, 326, 326, 326, 326, 326, 326, 325, 325, 325, 325, 325, 325, 324, 324, 324, 324, 324, 324, 323, 323, 323, 323, 323, 323, 322, 322, 322, 322, 322, 322, 321, 321, 321, 321, 321, 321, 320, 320, 320, 320, 320, 320, 319, 319, 319, 319, 319, 319, 318, 318, 318, 318, 318, 318, 317, 317, 317, 317, 317, 317, 316, 316, 316, 316, 316, 316, 315, 315, 315, 315, 315, 315, 314, 314, 314, 314, 314, 314, 313, 313, 313, 313, 313, 313, 312, 312, 312, 312, 312, 312, 311, 311, 311, 311, 311, 311, 310, 310, 310, 310, 310, 310, 309, 309, 309, 309, 309, 309, 308, 308, 308, 308, 308, 308, 307, 307, 307, 307, 307, 307, 306, 306, 306, 306, 306, 306, 305, 305, 305, 305, 305, 305, 304, 304, 304, 304, 304, 304, 303, 303, 303, 303, 303, 303, 302, 302, 302, 302, 302, 302, 302, 301, 301, 301, 301, 301, 301, 301, 301, 301, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 0, 0, 0, 0, 0 }; +static uint32_t motor_speeds_cs8600f[] = { + 54612, 54612, 34604, 26280, 21708, 18688, 16564, 14936, 13652, 12616, + 11768, 11024, 10400, 9872, 9392, 8960, 8584, 8240, 7940, 7648, + 7404, 7160, 6948, 6732, 6544, 6376, 6208, 6056, 5912, 5776, + 5644, 5520, 5408, 5292, 5192, 5092, 5000, 4908, 4820, 4736, + 4660, 4580, 4508, 4440, 4368, 4304, 4240, 4184, 4124, 4068, + 4012, 3960, 3908, 3860, 3808, 3764, 3720, 3676, 3636, 3592, + 3552, 3516, 3476, 3440, 3400, 3368, 3332, 3300, 3268, 3236, + 3204, 3176, 3148, 3116, 3088, 3060, 3036, 3008, 2984, 2956, + 2932, 2908, 2884, 2860, 2836, 2816, 2796, 2772, 2752, 2732, + 2708, 2692, 2672, 2652, 2632, 2616, 2596, 2576, 2560, 2544, + 2528, 2508, 2492, 2476, 2460, 2444, 2432, 2416, 2400, 2384, + 2372, 2356, 2344, 2328, 2316, 2304, 2288, 2276, 2260, 2252, + 2236, 2224, 2212, 2200, 2188, 2176, 2164, 2156, 2144, 2132, + 2120, 2108, 2100, 2088, 2080, 2068, 2056, 2048, 2036, 2028, + 2020, 2008, 2000, 1988, 1980, 1972, 1964, 1952, 1944, 1936, + 1928, 1920, 1912, 1900, 1892, 1884, 1876, 1868, 1860, 1856, + 1848, 1840, 1832, 1824, 1816, 1808, 1800, 1796, 1788, 1780, + 1772, 1764, 1760, 1752, 1744, 1740, 1732, 1724, 1720, 1712, + 1708, 1700, 1692, 1688, 1680, 1676, 1668, 1664, 1656, 1652, + 1644, 1640, 1636, 1628, 1624, 1616, 1612, 1608, 1600, 1596, + 1592, 1584, 1580, 1576, 1568, 1564, 1560, 1556, 1548, 1544, + 1540, 1536, 1528, 1524, 1520, 1516, 1512, 1508, 1500, 0 +}; /** * database of motor profiles @@ -660,7 +733,8 @@ static Motor_Profile gl843_motors[]={ {MOTOR_G4050, 56064, 1, g4050_high}, /* CS8400F */ {MOTOR_CS8400F, 7200, 0, cs8400f_fast}, - {0, 0, 0, NULL}, + { MOTOR_CS8600F, 0x59d8, 2, motor_speeds_cs8600f }, // FIXME: if the exposure is lower then we'll select another motor + { 0, 0, 0, NULL }, }; /* *INDENT-ON* */ diff --git a/backend/genesys_gl846.cc b/backend/genesys_gl846.cc index a995fce89..b02e18715 100644 --- a/backend/genesys_gl846.cc +++ b/backend/genesys_gl846.cc @@ -2114,6 +2114,7 @@ gl846_init_regs_for_shading (Genesys_Device * dev) memcpy (dev->calib_reg, dev->reg, GENESYS_GL846_MAX_REGS * sizeof (Genesys_Register_Set)); dev->calib_resolution = sanei_genesys_compute_dpihw(dev,dev->settings.xres); + dev->calib_total_bytes_to_read = 0; dev->calib_lines = dev->model->shading_lines; if(dev->calib_resolution==4800) dev->calib_lines *= 2; diff --git a/backend/genesys_gl847.cc b/backend/genesys_gl847.cc index 4e72619ad..a8fd5ab7f 100644 --- a/backend/genesys_gl847.cc +++ b/backend/genesys_gl847.cc @@ -2178,6 +2178,7 @@ gl847_init_regs_for_shading (Genesys_Device * dev) memcpy (dev->calib_reg, dev->reg, GENESYS_GL847_MAX_REGS * sizeof (Genesys_Register_Set)); dev->calib_resolution = sanei_genesys_compute_dpihw(dev,dev->settings.xres); + dev->calib_total_bytes_to_read = 0; dev->calib_lines = dev->model->shading_lines; if(dev->calib_resolution==4800) dev->calib_lines *= 2; diff --git a/backend/genesys_low.cc b/backend/genesys_low.cc index 3a2739b1c..0b6266cc4 100644 --- a/backend/genesys_low.cc +++ b/backend/genesys_low.cc @@ -1765,7 +1765,7 @@ sanei_genesys_wait_for_home (Genesys_Device * dev) */ int sanei_genesys_compute_dpihw(Genesys_Device *dev, int xres) { - /* some scanners use alxways hardware dpi for sensor */ + /* some scanners use always hardware dpi for sensor */ if (dev->model->flags & GENESYS_FLAG_FULL_HWDPI_MODE) { return dev->sensor.optical_res; @@ -1787,6 +1787,29 @@ int sanei_genesys_compute_dpihw(Genesys_Device *dev, int xres) return dev->sensor.optical_res; } +// sanei_genesys_compute_dpihw returns the dpihw that is written to register. +// However the number of pixels depends on half_ccd mode +int sanei_genesys_compute_dpihw_calibration(Genesys_Device *dev, int xres) +{ + if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) + { + // real resolution is half of the "official" resolution - half_ccd mode + int hwres = dev->sensor.optical_res / 4; + + if (xres <= hwres / 4) + { + return hwres / 4; + } + if (xres <= hwres / 2) + { + return hwres / 2; + } + return hwres; + } + + return sanei_genesys_compute_dpihw(dev, xres); +} + /** @brief motor profile * search for the database of motor profiles and get the best one. Each * profile is at full step and at a reference exposure. Use first entry @@ -1954,7 +1977,7 @@ Motor_Profile *profile; i++; } - /* return used steps and acceleration sum */ + // return used steps and taken time *steps=i/factor; return sum; } diff --git a/backend/genesys_low.h b/backend/genesys_low.h index 2e2b84fcd..6ed4e6481 100644 --- a/backend/genesys_low.h +++ b/backend/genesys_low.h @@ -325,8 +325,14 @@ struct Genesys_Sensor { typedef struct { uint8_t gpo_id; /**< id of the gpo description */ - uint8_t value[2]; /**< registers 0x6c and 0x6d on gl843 */ - uint8_t enable[2]; /**< registers 0x6e and 0x6F on gl843 */ + + // registers 0x6c and 0x6d on GL841, GL842, GL843, GL846, GL848 and possibly + // others + uint8_t value[2]; + + // registers 0x6e and 0x6f on GL841, GL842, GL843, GL846, GL848 and possibly + // others + uint8_t enable[2]; } Genesys_Gpo; typedef struct @@ -384,6 +390,7 @@ enum Genesys_Model_Type MODEL_HP_SCANJET_G4050, MODEL_CANON_CANOSCAN_4400F, MODEL_CANON_CANOSCAN_8400F, + MODEL_CANON_CANOSCAN_8600F, MODEL_CANON_LIDE_100, MODEL_CANON_LIDE_110, MODEL_CANON_LIDE_120, @@ -440,6 +447,7 @@ enum Genesys_Dac_Type DAC_PLUSTEK_3600, DAC_CANONLIDE700, DAC_CS8400F, + DAC_CS8600F, DAC_IMG101, DAC_PLUSTEK3800, DAC_CANONLIDE80, @@ -472,6 +480,7 @@ enum Genesys_Sensor_Type CIS_CANONLIDE700, CCD_CS4400F, CCD_CS8400F, + CCD_CS8600F, CCD_IMG101, CCD_PLUSTEK3800, CIS_CANONLIDE210, @@ -504,6 +513,7 @@ enum Genesys_Gpo_Type GPO_CANONLIDE700, GPO_CS4400F, GPO_CS8400F, + GPO_CS8600F, GPO_IMG101, GPO_PLUSTEK3800, GPO_CANONLIDE80, @@ -532,6 +542,7 @@ enum Genesys_Motor_Type MOTOR_PLUSTEK_3600, MOTOR_CANONLIDE700, MOTOR_CS8400F, + MOTOR_CS8600F, MOTOR_IMG101, MOTOR_PLUSTEK3800, MOTOR_CANONLIDE210, @@ -753,6 +764,7 @@ typedef struct Genesys_Model SANE_Word buttons; /* Button flags, described existing buttons for the model */ /*@} */ SANE_Int shading_lines; /* how many lines are used for shading calibration */ + SANE_Int shading_ta_lines; // how many lines are used for shading calibration in TA mode SANE_Int search_lines; /* how many lines are used to search start position */ } Genesys_Model; @@ -928,6 +940,8 @@ struct Genesys_Device size_t calib_lines = 0; size_t calib_channels = 0; size_t calib_resolution = 0; + // bytes to read from USB when calibrating. If 0, this is not set + size_t calib_total_bytes_to_read = 0; std::vector white_average_data; std::vector dark_average_data; @@ -944,6 +958,8 @@ struct Genesys_Device // for sheetfed scanner's, is TRUE when there is a document in the scanner SANE_Bool document = 0; + SANE_Bool needs_home_ta = 0; + Genesys_Buffer read_buffer; Genesys_Buffer lines_buffer; Genesys_Buffer shrink_buffer; @@ -1025,7 +1041,7 @@ typedef struct { int motor_type; /**< motor id */ int exposure; /**< exposure for the slope table */ int step_type; /**< default step type for given exposure */ - uint32_t *table; /**< 0 terminated slope table at full step */ + uint32_t *table; // 0-terminated slope table at full step (i.e. step_type == 0) } Motor_Profile; #define FULL_STEP 0 @@ -1251,6 +1267,9 @@ sanei_genesys_asic_init(Genesys_Device *dev, SANE_Bool cold); extern int sanei_genesys_compute_dpihw(Genesys_Device *dev, int xres); +extern +int sanei_genesys_compute_dpihw_calibration(Genesys_Device *dev, int xres); + extern Motor_Profile *sanei_genesys_get_motor_profile(Motor_Profile *motors, int motor_type, int exposure); diff --git a/doc/descriptions/genesys.desc b/doc/descriptions/genesys.desc index f6fb8a3ed..77c1fd8c3 100644 --- a/doc/descriptions/genesys.desc +++ b/doc/descriptions/genesys.desc @@ -181,6 +181,13 @@ :status :unsupported :comment "GL847 based, to be added to the genesys backend" +:model "CanoScan 8600F" +:url "unsupported/canon-8600.html" +:interface "USB" +:usbid "0x04a9" "0x2229" +:status :basic +:comment "normal and transparency scans work up to 1200 dpi resolution" + :model "CanoScan 700F" :interface "USB" :usbid "0x04a9" "0x1907" diff --git a/doc/descriptions/unsupported.desc b/doc/descriptions/unsupported.desc index 01d0fea58..496ebea6b 100644 --- a/doc/descriptions/unsupported.desc +++ b/doc/descriptions/unsupported.desc @@ -340,14 +340,6 @@ :status :unsupported :comment "GL841 based, to be added to genesys backend" -:model "CanoScan 8600F" -:url "unsupported/canon-8600.html" -:interface "USB" -:usbid "0x04a9" "0x2229" -:status :unsupported -:comment "GL841 based, to be added to genesys backend" - - :model "CanoScan 9900F" :url "unsupported/canon-9900f.html" :interface "USB"