diff --git a/backend/genesys_devices.cc b/backend/genesys_devices.cc index 6d1665fd0..8bd308cba 100644 --- a/backend/genesys_devices.cc +++ b/backend/genesys_devices.cc @@ -1730,6 +1730,34 @@ void genesys_init_sensor_tables() { 0x03, 0x1f }, }, }, + { 1200, 1200, 28800, ScanMethod::TRANSPARENCY_INFRARED, { + { 0x16, 0x33 }, + { 0x17, 0x0c }, + { 0x18, 0x11 }, + { 0x19, 0x2a }, + { 0x1a, 0x30 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x84 }, + { 0x1e, 0xa0 }, + { 0x52, 0x0b }, + { 0x53, 0x0e }, + { 0x54, 0x11 }, + { 0x55, 0x02 }, + { 0x56, 0x05 }, + { 0x57, 0x08 }, + { 0x58, 0x63 }, + { 0x59, 0x00 }, + { 0x5a, 0x40 }, + { 0x70, 0x00 }, { 0x71, 0x01 }, { 0x72, 0x02 }, { 0x73, 0x03 }, + { 0x74, 0x00 }, { 0x75, 0x01 }, { 0x76, 0xff }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x00 }, + { 0x7a, 0x02 }, { 0x7b, 0x49 }, { 0x7c, 0x24 }, + { 0x80, 0x21 }, + }, { + { 0x03, 0x1f }, + }, + }, }; for (const CustomSensorSettings& setting : custom_settings) @@ -3335,6 +3363,7 @@ static Genesys_Model canon_8400f_model = { GPO_CS8400F, MOTOR_CS8400F, GENESYS_FLAG_HAS_UTA | + GENESYS_FLAG_HAS_UTA_INFRARED | GENESYS_FLAG_LAZY_INIT | GENESYS_FLAG_OFFSET_CALIBRATION | GENESYS_FLAG_STAGGERED_LINE | diff --git a/backend/genesys_gl843.cc b/backend/genesys_gl843.cc index b7f497977..58bc41163 100644 --- a/backend/genesys_gl843.cc +++ b/backend/genesys_gl843.cc @@ -1955,6 +1955,9 @@ static SANE_Status gl843_set_xpa_motor_power(Genesys_Device *dev, bool set) if (set) { sanei_genesys_read_register(dev, 0x6c, &val); val &= ~(REG6C_GPIO16 | REG6C_GPIO13); + if (dev->current_setup.xres >= 2400) { + val &= ~REG6C_GPIO10; + } sanei_genesys_write_register(dev, 0x6c, val); sanei_genesys_read_register(dev, 0xa9, &val); @@ -2043,57 +2046,75 @@ static SANE_Status gl843_set_xpa_motor_power(Genesys_Device *dev, bool set) * XPA light * @param dev device to set up */ -static SANE_Status gl843_set_xpa_lamp_power(Genesys_Device *dev, bool set) +static void gl843_set_xpa_lamp_power(Genesys_Device *dev, bool set) { DBG_HELPER(dbg); - SANE_Status status = SANE_STATUS_GOOD; - uint8_t val = 0; + struct LampSettings { + int model_id; + ScanMethod scan_method; + GenesysRegisterSettingSet regs_on; + GenesysRegisterSettingSet regs_off; + }; + + // FIXME: BUG: we're not clearing the registers to the previous state when returning back when + // turning off the lamp + LampSettings settings[] = { + { MODEL_CANON_CANOSCAN_8400F, ScanMethod::TRANSPARENCY, { + { 0xa6, 0x34, 0xf4 }, + { 0xa7, 0xe0, 0xe0 }, // BUG: should be 0x03 + }, { + { 0xa6, 0x40, 0x70 }, + } + }, + { MODEL_CANON_CANOSCAN_8400F, ScanMethod::TRANSPARENCY_INFRARED, { + { 0x6c, 0x40, 0x40 }, + { 0xa6, 0x01, 0xff }, + { 0xa7, 0x03, 0x07 }, + }, { + { 0x6c, 0x00, 0x40 }, + { 0xa6, 0x00, 0xff }, + { 0xa7, 0x07, 0x07 }, + } + }, + { MODEL_CANON_CANOSCAN_8600F, ScanMethod::TRANSPARENCY, { + { 0xa6, 0x34, 0xf4 }, + { 0xa7, 0xe0, 0xe0 }, + }, { + { 0xa6, 0x40, 0x70 }, + } + }, + { MODEL_CANON_CANOSCAN_8600F, ScanMethod::TRANSPARENCY_INFRARED, { + { 0xa6, 0x00, 0xc0 }, + { 0xa7, 0xe0, 0xe0 }, + { 0x6c, 0x80, 0x80 }, + }, { + { 0xa6, 0x00, 0xc0 }, + { 0x6c, 0x00, 0x80 }, + } + }, + }; + + for (const auto& setting : settings) { + if (setting.model_id == dev->model->model_id && + setting.scan_method == dev->settings.scan_method) + { + apply_reg_settings_to_device(*dev, set ? setting.regs_on : setting.regs_off); + return; + } + } + + // BUG: we're currently calling the function in shut down path of regular lamp if (set) { - sanei_genesys_read_register(dev, REGA6, &val); - - // cut regular lamp power - val &= ~(REGA6_GPIO24 | REGA6_GPIO23); - - // set XPA lamp power - if (dev->settings.scan_method != ScanMethod::TRANSPARENCY_INFRARED) { - val |= REGA6_GPIO22 | REGA6_GPIO21 | REGA6_GPIO19; - } - - sanei_genesys_write_register(dev, REGA6, val); - - sanei_genesys_read_register(dev, REGA7, &val); - val|=REGA7_GPOE24; /* lamp 1 off GPOE 24 */ - val|=REGA7_GPOE23; /* lamp 2 off GPOE 23 */ - val|=REGA7_GPOE22; /* full XPA lamp power */ - sanei_genesys_write_register(dev, REGA7, val); - } else { - sanei_genesys_read_register(dev, REGA6, &val); - - // switch on regular lamp - val |= REGA6_GPIO23; - - // no XPA lamp power (2 bits for level: __11 ____) - val &= ~(REGA6_GPIO22 | REGA6_GPIO21); - - sanei_genesys_write_register(dev, REGA6, val); + throw SaneException("Unexpected code path entered"); } - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F && - dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) - { - if (set) { - sanei_genesys_read_register(dev, REG6C, &val); - val |= REG6C_GPIO16; - sanei_genesys_write_register(dev, REG6C, val); - } else { - sanei_genesys_read_register(dev, REG6C, &val); - val &= ~REG6C_GPIO16; - sanei_genesys_write_register(dev, REG6C, val); - } - } - - return status; + GenesysRegisterSettingSet regs = { + { 0xa6, 0x40, 0x70 }, + }; + apply_reg_settings_to_device(*dev, regs); + // TODO: throw exception when we're only calling this function in error return path + // throw SaneException("Could not find XPA lamp settings"); } /* Send the low-level scan command */ @@ -2138,7 +2159,7 @@ gl843_begin_scan (Genesys_Device * dev, const Genesys_Sensor& sensor, Genesys_Re } if (reg->state.is_xpa_on && reg->state.is_lamp_on) { - RIE(gl843_set_xpa_lamp_power(dev, true)); + gl843_set_xpa_lamp_power(dev, true); } if (reg->state.is_xpa_on) { @@ -2152,7 +2173,7 @@ gl843_begin_scan (Genesys_Device * dev, const Genesys_Sensor& sensor, Genesys_Re case GPO_CS8400F: case GPO_CS8600F: if (reg->state.is_xpa_on && reg->state.is_lamp_on) { - RIE(gl843_set_xpa_lamp_power(dev, true)); + gl843_set_xpa_lamp_power(dev, true); } if (reg->state.is_xpa_on) { dev->needs_home_ta = SANE_TRUE; diff --git a/backend/genesys_low.cc b/backend/genesys_low.cc index 97eda3a53..3d82a0de0 100644 --- a/backend/genesys_low.cc +++ b/backend/genesys_low.cc @@ -75,6 +75,16 @@ void Genesys_Device::clear() dark_average_data.clear(); } +void apply_reg_settings_to_device(Genesys_Device& dev, const GenesysRegisterSettingSet& regs) +{ + for (const auto& reg : regs) { + uint8_t val; + sanei_genesys_read_register(&dev, reg.address, &val); + val = (val & ~reg.mask) | (reg.value & reg.mask); + sanei_genesys_write_register(&dev, reg.address, val); + } +} + /* ------------------------------------------------------------------------ */ /* functions calling ASIC specific functions */ /* ------------------------------------------------------------------------ */ @@ -890,7 +900,8 @@ void sanei_genesys_set_lamp_power(Genesys_Device* dev, const Genesys_Sensor& sen sanei_genesys_set_exposure(regs, sensor.exposure); // we don't actually turn on lamp on infrared scan - if (dev->model->model_id == MODEL_CANON_CANOSCAN_8600F && + if ((dev->model->model_id == MODEL_CANON_CANOSCAN_8400F || + dev->model->model_id == MODEL_CANON_CANOSCAN_8600F) && dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) { regs.find_reg(0x03).value &= ~REG03_LAMPPWR; diff --git a/backend/genesys_low.h b/backend/genesys_low.h index 8aea9566c..37b19927d 100644 --- a/backend/genesys_low.h +++ b/backend/genesys_low.h @@ -476,6 +476,8 @@ void serialize(Stream& str, GenesysRegisterSetting& reg) serialize(str, reg.mask); } +class Genesys_Device; + class GenesysRegisterSettingSet { public: using container = std::vector; @@ -551,6 +553,8 @@ inline void serialize(std::ostream& str, GenesysRegisterSettingSet& reg) serialize(str, reg.regs_); } +void apply_reg_settings_to_device(Genesys_Device& dev, const GenesysRegisterSettingSet& regs); + struct GenesysFrontendLayout { std::array offset_addr = {};