diff --git a/backend/genesys.conf.in b/backend/genesys.conf.in index b14a19f62..8268da35a 100644 --- a/backend/genesys.conf.in +++ b/backend/genesys.conf.in @@ -39,6 +39,9 @@ usb 0x04a9 0x221c # Canon LiDE 80 usb 0x04a9 0x2214 +# Canon LiDE 90 +usb 0x04a9 0x1900 + # Canon 4400F usb 0x04a9 0x2228 diff --git a/backend/genesys/enums.cpp b/backend/genesys/enums.cpp index 464dfe0c1..cd4be7daa 100644 --- a/backend/genesys/enums.cpp +++ b/backend/genesys/enums.cpp @@ -121,6 +121,7 @@ std::ostream& operator<<(std::ostream& out, ModelId id) case ModelId::CANON_LIDE_50: out << "CANON_LIDE_50"; break; case ModelId::CANON_LIDE_60: out << "CANON_LIDE_60"; break; case ModelId::CANON_LIDE_80: out << "CANON_LIDE_80"; break; + case ModelId::CANON_LIDE_90: out << "CANON_LIDE_90"; break; case ModelId::CANON_LIDE_100: out << "CANON_LIDE_100"; break; case ModelId::CANON_LIDE_110: out << "CANON_LIDE_110"; break; case ModelId::CANON_LIDE_120: out << "CANON_LIDE_120"; break; @@ -205,6 +206,7 @@ std::ostream& operator<<(std::ostream& out, SensorId id) case SensorId::CIS_CANON_LIDE_35: out << "CIS_CANON_LIDE_35"; break; case SensorId::CIS_CANON_LIDE_60: out << "CIS_CANON_LIDE_60"; break; case SensorId::CIS_CANON_LIDE_80: out << "CIS_CANON_LIDE_80"; break; + case SensorId::CIS_CANON_LIDE_90: out << "CIS_CANON_LIDE_90"; break; case SensorId::CIS_CANON_LIDE_100: out << "CIS_CANON_LIDE_100"; break; case SensorId::CIS_CANON_LIDE_110: out << "CIS_CANON_LIDE_110"; break; case SensorId::CIS_CANON_LIDE_120: out << "CIS_CANON_LIDE_120"; break; @@ -226,6 +228,7 @@ std::ostream& operator<<(std::ostream& out, AdcId id) case AdcId::AD_XP200: out << "AD_XP200"; break; case AdcId::CANON_LIDE_35: out << "CANON_LIDE_35"; break; case AdcId::CANON_LIDE_80: out << "CANON_LIDE_80"; break; + case AdcId::CANON_LIDE_90: out << "CANON_LIDE_90"; break; case AdcId::CANON_LIDE_110: out << "CANON_LIDE_110"; break; case AdcId::CANON_LIDE_120: out << "CANON_LIDE_120"; break; case AdcId::CANON_LIDE_200: out << "CANON_LIDE_200"; break; @@ -266,6 +269,7 @@ std::ostream& operator<<(std::ostream& out, GpioId id) case GpioId::UNKNOWN: out << "UNKNOWN"; break; case GpioId::CANON_LIDE_35: out << "CANON_LIDE_35"; break; case GpioId::CANON_LIDE_80: out << "CANON_LIDE_80"; break; + case GpioId::CANON_LIDE_90: out << "CANON_LIDE_90"; break; case GpioId::CANON_LIDE_110: out << "CANON_LIDE_110"; break; case GpioId::CANON_LIDE_120: out << "CANON_LIDE_120"; break; case GpioId::CANON_LIDE_200: out << "CANON_LIDE_200"; break; @@ -306,6 +310,7 @@ std::ostream& operator<<(std::ostream& out, MotorId id) { switch (id) { case MotorId::UNKNOWN: out << "UNKNOWN"; break; + case MotorId::CANON_LIDE_90: out << "CANON_LIDE_90"; break; case MotorId::CANON_LIDE_100: out << "CANON_LIDE_100"; break; case MotorId::CANON_LIDE_110: out << "CANON_LIDE_110"; break; case MotorId::CANON_LIDE_120: out << "CANON_LIDE_120"; break; diff --git a/backend/genesys/enums.h b/backend/genesys/enums.h index f65f80f40..0e16ba477 100644 --- a/backend/genesys/enums.h +++ b/backend/genesys/enums.h @@ -182,6 +182,7 @@ enum class ModelId : unsigned CANON_LIDE_50, CANON_LIDE_60, CANON_LIDE_80, + CANON_LIDE_90, CANON_LIDE_100, CANON_LIDE_110, CANON_LIDE_120, @@ -276,6 +277,7 @@ enum class SensorId : unsigned CIS_CANON_LIDE_35, CIS_CANON_LIDE_60, CIS_CANON_LIDE_80, + CIS_CANON_LIDE_90, CIS_CANON_LIDE_100, CIS_CANON_LIDE_110, CIS_CANON_LIDE_120, @@ -308,6 +310,7 @@ enum class AdcId : unsigned AD_XP200, CANON_LIDE_35, CANON_LIDE_80, + CANON_LIDE_90, CANON_LIDE_110, CANON_LIDE_120, CANON_LIDE_200, @@ -358,6 +361,7 @@ enum class GpioId : unsigned UNKNOWN = 0, CANON_LIDE_35, CANON_LIDE_80, + CANON_LIDE_90, CANON_LIDE_110, CANON_LIDE_120, CANON_LIDE_200, @@ -406,6 +410,7 @@ enum class MotorId : unsigned CANON_LIDE_60, CANON_LIDE_700, CANON_LIDE_80, + CANON_LIDE_90, CANON_4400F, CANON_5600F, CANON_8400F, diff --git a/backend/genesys/genesys.cpp b/backend/genesys/genesys.cpp index 9a422ce82..9d80cfadf 100644 --- a/backend/genesys/genesys.cpp +++ b/backend/genesys/genesys.cpp @@ -544,9 +544,10 @@ void scanner_send_slope_table(Genesys_Device* dev, const Genesys_Sensor& sensor, table.push_back(slope_table[i] & 0xff); table.push_back(slope_table[i] >> 8); } - if (dev->model->asic_type == AsicType::GL841) { - // BUG: some motor setup setting is wrong on GL841 scanners, as they need full motor table - // to be written even though this is not observed in the official scanners. + if (dev->model->asic_type == AsicType::GL841 || + dev->model->model_id == ModelId::CANON_LIDE_90) + { + // BUG: do this on all gl842 scanners auto max_table_size = get_slope_table_max_size(dev->model->asic_type); table.reserve(max_table_size * 2); while (table.size() < max_table_size * 2) { @@ -3540,6 +3541,7 @@ static void genesys_send_shading_coefficient(Genesys_Device* dev, const Genesys_ break; case SensorId::CIS_CANON_LIDE_35: case SensorId::CIS_CANON_LIDE_60: + case SensorId::CIS_CANON_LIDE_90: compute_averaged_planar (dev, sensor, shading_data.data(), pixels_per_line, diff --git a/backend/genesys/gl842.cpp b/backend/genesys/gl842.cpp index 878a9b58c..d5bebe586 100644 --- a/backend/genesys/gl842.cpp +++ b/backend/genesys/gl842.cpp @@ -46,19 +46,35 @@ static void gl842_init_registers(Genesys_Device& dev) dev.reg.clear(); - dev.reg.init_reg(0x01, 0x00); - dev.reg.init_reg(0x02, 0x78); - dev.reg.init_reg(0x03, 0xbf); - dev.reg.init_reg(0x04, 0x22); - dev.reg.init_reg(0x05, 0x48); + if (dev.model->model_id == ModelId::PLUSTEK_OPTICFILM_7200) { + dev.reg.init_reg(0x01, 0x00); + dev.reg.init_reg(0x02, 0x78); + dev.reg.init_reg(0x03, 0xbf); + dev.reg.init_reg(0x04, 0x22); + dev.reg.init_reg(0x05, 0x48); - dev.reg.init_reg(0x06, 0xb8); + dev.reg.init_reg(0x06, 0xb8); - dev.reg.init_reg(0x07, 0x00); - dev.reg.init_reg(0x08, 0x00); - dev.reg.init_reg(0x09, 0x00); - dev.reg.init_reg(0x0a, 0x00); - dev.reg.init_reg(0x0d, 0x01); + dev.reg.init_reg(0x07, 0x00); + dev.reg.init_reg(0x08, 0x00); + dev.reg.init_reg(0x09, 0x00); + dev.reg.init_reg(0x0a, 0x00); + dev.reg.init_reg(0x0d, 0x01); + } else if (dev.model->model_id == ModelId::CANON_LIDE_90) { + dev.reg.init_reg(0x01, 0x82); + dev.reg.init_reg(0x02, 0x10); + dev.reg.init_reg(0x03, 0x60); + dev.reg.init_reg(0x04, 0x10); + dev.reg.init_reg(0x05, 0x8c); + + dev.reg.init_reg(0x06, 0x18); + + //dev.reg.init_reg(0x07, 0x00); + dev.reg.init_reg(0x08, 0x00); + dev.reg.init_reg(0x09, 0x21); + dev.reg.init_reg(0x0a, 0x00); + dev.reg.init_reg(0x0d, 0x00); + } dev.reg.init_reg(0x10, 0x00); // exposure, overwritten in scanner_setup_sensor() below dev.reg.init_reg(0x11, 0x00); // exposure, overwritten in scanner_setup_sensor() below @@ -77,14 +93,20 @@ static void gl842_init_registers(Genesys_Device& dev) // Various CCD clock settings. dev.reg.init_reg(0x1a, 0x00); // SENSOR_DEF - dev.reg.init_reg(0x1b, 0x00); // SENSOR_DEF + if (dev.model->model_id == ModelId::PLUSTEK_OPTICFILM_7200) { + dev.reg.init_reg(0x1b, 0x00); // SENSOR_DEF + } dev.reg.init_reg(0x1c, 0x00); // SENSOR_DEF dev.reg.init_reg(0x1d, 0x00); // SENSOR_DEF dev.reg.init_reg(0x1e, 0x10); // WDTIME, LINESEL: setup during sensor and motor setup - dev.reg.init_reg(0x1f, 0x01); - - dev.reg.init_reg(0x20, 0x27); // BUFSEL: buffer full condition + if (dev.model->model_id == ModelId::PLUSTEK_OPTICFILM_7200) { + dev.reg.init_reg(0x1f, 0x01); + dev.reg.init_reg(0x20, 0x27); // BUFSEL: buffer full condition + } else if (dev.model->model_id == ModelId::CANON_LIDE_90) { + dev.reg.init_reg(0x1f, 0x02); + dev.reg.init_reg(0x20, 0x02); // BUFSEL: buffer full condition + } dev.reg.init_reg(0x21, 0x10); // STEPNO: set during motor setup dev.reg.init_reg(0x22, 0x10); // FWDSTEP: set during motor setup @@ -127,7 +149,12 @@ static void gl842_init_registers(Genesys_Device& dev) dev.reg.init_reg(0x59, 0x00); // SENSOR_DEF dev.reg.init_reg(0x5a, 0x00); // SENSOR_DEF - dev.reg.init_reg(0x5e, 0x01); // DECSEL, STOPTIM + if (dev.model->model_id == ModelId::PLUSTEK_OPTICFILM_7200) { + dev.reg.init_reg(0x5e, 0x01); // DECSEL, STOPTIM + } else if (dev.model->model_id == ModelId::CANON_LIDE_90) { + dev.reg.init_reg(0x5e, 0x41); // DECSEL, STOPTIM + dev.reg.init_reg(0x5d, 0x20); + } dev.reg.init_reg(0x5f, 0x10); // FMOVDEC: set during motor setup dev.reg.init_reg(0x60, 0x00); // Z1MOD: overwritten during motor setup @@ -137,8 +164,14 @@ static void gl842_init_registers(Genesys_Device& dev) dev.reg.init_reg(0x64, 0x00); // Z2MOD: overwritten during motor setup dev.reg.init_reg(0x65, 0x00); // Z2MOD: overwritten during motor setup - dev.reg.init_reg(0x67, 0x7f); // STEPSEL, MTRPWM: overwritten during motor setup - dev.reg.init_reg(0x68, 0x7f); // FSTPSEL, FASTPWM: overwritten during motor setup + if (dev.model->model_id == ModelId::PLUSTEK_OPTICFILM_7200) { + dev.reg.init_reg(0x67, 0x7f); // STEPSEL, MTRPWM: partially overwritten during motor setup + dev.reg.init_reg(0x68, 0x7f); // FSTPSEL, FASTPWM: partially overwritten during motor setup + } else if (dev.model->model_id == ModelId::CANON_LIDE_90) { + dev.reg.init_reg(0x66, 0x00); // PHFREQ + dev.reg.init_reg(0x67, 0x40); // STEPSEL, MTRPWM: partially overwritten during motor setup + dev.reg.init_reg(0x68, 0x40); // FSTPSEL, FASTPWM: partially overwritten during motor setup + } dev.reg.init_reg(0x69, 0x10); // FSHDEC: overwritten during motor setup dev.reg.init_reg(0x6a, 0x10); // FMOVNO: overwritten during motor setup @@ -167,13 +200,26 @@ static void gl842_init_registers(Genesys_Device& dev) // moving in various situations. dev.reg.init_reg(0x80, 0x00); // MOTOR_PROFILE - dev.reg.init_reg(0x81, 0x00); - dev.reg.init_reg(0x82, 0x00); - dev.reg.init_reg(0x83, 0x00); - dev.reg.init_reg(0x84, 0x00); - dev.reg.init_reg(0x85, 0x00); - dev.reg.init_reg(0x86, 0x00); - dev.reg.init_reg(0x87, 0x00); + if (dev.model->model_id == ModelId::PLUSTEK_OPTICFILM_7200) { + dev.reg.init_reg(0x81, 0x00); + dev.reg.init_reg(0x82, 0x00); + dev.reg.init_reg(0x83, 0x00); + dev.reg.init_reg(0x84, 0x00); + dev.reg.init_reg(0x85, 0x00); + dev.reg.init_reg(0x86, 0x00); + dev.reg.init_reg(0x87, 0x00); + } else if (dev.model->model_id == ModelId::CANON_LIDE_90) { + dev.reg.init_reg(0x7e, 0x00); + dev.reg.init_reg(0x81, 0x00); + dev.reg.init_reg(0x82, 0x0f); + dev.reg.init_reg(0x83, 0x00); + dev.reg.init_reg(0x84, 0x0e); + dev.reg.init_reg(0x85, 0x00); + dev.reg.init_reg(0x86, 0x0d); + dev.reg.init_reg(0x87, 0x00); + dev.reg.init_reg(0x88, 0x00); + dev.reg.init_reg(0x89, 0x00); + } const auto& sensor = sanei_genesys_find_sensor_any(&dev); sanei_genesys_set_dpihw(dev.reg, sensor.register_dpihw); @@ -181,13 +227,6 @@ static void gl842_init_registers(Genesys_Device& dev) scanner_setup_sensor(dev, sensor, dev.reg); } -static void gl842_set_ad_fe(Genesys_Device* dev) -{ - for (const auto& reg : dev->frontend.regs) { - dev->interface->write_fe_register(reg.address, reg.value); - } -} - // Set values of analog frontend void CommandSetGl842::set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor, uint8_t set) const { @@ -203,8 +242,10 @@ void CommandSetGl842::set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor, // check analog frontend type // FIXME: looks like we write to that register with initial data uint8_t fe_type = dev->interface->read_register(REG_0x04) & REG_0x04_FESET; - if (fe_type == 2) { - gl842_set_ad_fe(dev); + if (fe_type == 2 || dev->model->model_id == ModelId::CANON_LIDE_90) { + for (const auto& reg : dev->frontend.regs) { + dev->interface->write_fe_register(reg.address, reg.value); + } return; } if (fe_type != 0) { @@ -222,12 +263,6 @@ void CommandSetGl842::set_fe(Genesys_Device* dev, const Genesys_Sensor& sensor, dev->interface->write_fe_register(0x20 + i, dev->frontend.get_offset(i)); } - if (dev->model->sensor_id == SensorId::CCD_KVSS080) { - for (unsigned i = 0; i < 3; i++) { - dev->interface->write_fe_register(0x24 + i, dev->frontend.regs.get_value(0x24 + i)); - } - } - for (unsigned i = 0; i < 3; i++) { dev->interface->write_fe_register(0x28 + i, dev->frontend.get_gain(i)); } @@ -482,7 +517,11 @@ static void gl842_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens reg->set16(REG_STRPIXEL, session.pixel_startx); reg->set16(REG_ENDPIXEL, session.pixel_endx); - reg->set24(REG_MAXWD, session.output_line_bytes_raw); + if (dev->model->is_cis) { + reg->set24(REG_MAXWD, session.output_line_bytes_raw * session.params.channels); + } else { + reg->set24(REG_MAXWD, session.output_line_bytes_raw); + } unsigned tgtime = exposure / 65536 + 1; reg->set16(REG_LPERIOD, exposure / tgtime); @@ -516,6 +555,9 @@ void CommandSetGl842::init_regs_for_scan_session(Genesys_Device* dev, const Gene if (exposure < 0) { throw std::runtime_error("Exposure not defined in sensor definition"); } + if (dev->model->model_id == ModelId::CANON_LIDE_90) { + exposure *= 2; + } const auto& motor_profile = get_motor_profile(dev->motor.profiles, exposure, session); // now _LOGICAL_ optical values used are known, setup registers @@ -643,6 +685,25 @@ void CommandSetGl842::begin_scan(Genesys_Device* dev, const Genesys_Sensor& sens dev->cmd_set->set_motor_mode(*dev, *reg, MotorMode::PRIMARY_AND_SECONDARY); } + if (dev->model->model_id == ModelId::CANON_LIDE_90) { + if (has_flag(dev->session.params.flags, ScanFlag::REVERSE)) { + dev->interface->write_register(REG_0x6B, 0x01); + dev->interface->write_register(REG_0x6C, 0x02); + } else { + dev->interface->write_register(REG_0x6B, 0x03); + switch (dev->session.params.xres) { + case 150: dev->interface->write_register(REG_0x6C, 0x74); break; + case 300: dev->interface->write_register(REG_0x6C, 0x38); break; + case 600: dev->interface->write_register(REG_0x6C, 0x1c); break; + case 1200: dev->interface->write_register(REG_0x6C, 0x2c); break; + case 2400: dev->interface->write_register(REG_0x6C, 0x0c); break; + default: + break; + } + } + dev->interface->sleep_ms(100); + } + scanner_clear_scan_and_feed_counts(*dev); // enable scan and motor @@ -902,6 +963,9 @@ void CommandSetGl842::asic_boot(Genesys_Device* dev, bool cold) const if (dev->model->model_id == ModelId::PLUSTEK_OPTICFILM_7200) { dev->interface->write_0x8c(0x10, 0x94); } + if (dev->model->model_id == ModelId::CANON_LIDE_90) { + dev->interface->write_0x8c(0x10, 0xd4); + } // set RAM read address dev->interface->write_register(REG_0x2A, 0x00); @@ -929,7 +993,11 @@ void CommandSetGl842::update_hardware_sensors(Genesys_Scanner* s) const void CommandSetGl842::update_home_sensor_gpio(Genesys_Device& dev) const { DBG_HELPER(dbg); - (void) dev; + if (dev.model->model_id == ModelId::CANON_LIDE_90) { + std::uint8_t val = dev.interface->read_register(REG_0x6C); + val |= 0x02; + dev.interface->write_register(REG_0x6C, val); + } } /** diff --git a/backend/genesys/low.cpp b/backend/genesys/low.cpp index b1589aa8e..05ef46bf2 100644 --- a/backend/genesys/low.cpp +++ b/backend/genesys/low.cpp @@ -791,7 +791,9 @@ void compute_session_pixel_offsets(const Genesys_Device* dev, ScanSession& s, dev->model->asic_type == AsicType::GL847) { unsigned startx_xres = s.optical_resolution; - if (dev->model->model_id == ModelId::CANON_5600F) { + if (dev->model->model_id == ModelId::CANON_5600F || + dev->model->model_id == ModelId::CANON_LIDE_90) + { if (s.output_resolution == 1200) { startx_xres /= 2; } @@ -1044,7 +1046,9 @@ void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Se } } - if (dev->model->asic_type == AsicType::GL841) { + if (dev->model->asic_type == AsicType::GL841 || + dev->model->asic_type == AsicType::GL842) + { if (dev->model->is_cis) { s.output_line_bytes_raw = s.output_channel_bytes; } @@ -1077,6 +1081,11 @@ void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Se s.output_segment_pixel_group_count = s.output_pixels / (s.full_resolution / s.optical_resolution * s.segment_count); } + + if (dev->model->model_id == ModelId::CANON_LIDE_90) { + s.output_segment_pixel_group_count = s.output_pixels / s.segment_count; + } + if (dev->model->asic_type == AsicType::GL845 || dev->model->asic_type == AsicType::GL846 || dev->model->asic_type == AsicType::GL847) @@ -1093,6 +1102,10 @@ void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Se s.output_total_bytes_raw = s.output_line_bytes_raw * s.output_line_count; s.output_total_bytes = s.output_line_bytes * s.output_line_count; + if (dev->model->model_id == ModelId::CANON_LIDE_90) { + s.output_total_bytes_raw *= s.params.channels; + s.output_total_bytes *= s.params.channels; + } s.buffer_size_read = s.output_line_bytes_raw * 64; compute_session_pixel_offsets(dev, s, sensor); diff --git a/backend/genesys/tables_frontend.cpp b/backend/genesys/tables_frontend.cpp index 5f4b206c8..5eb6e3cb6 100644 --- a/backend/genesys/tables_frontend.cpp +++ b/backend/genesys/tables_frontend.cpp @@ -219,6 +219,30 @@ void genesys_init_frontend_tables() s_frontends->push_back(fe); + fe = Genesys_Frontend(); + fe.id = AdcId::CANON_LIDE_90; + fe.layout = wolfson_layout; + fe.layout.type = FrontendType::WOLFSON; + fe.regs = { + { 0x01, 0x23 }, + { 0x02, 0x07 }, + { 0x03, 0x29 }, + { 0x06, 0x0d }, + { 0x08, 0x00 }, + { 0x09, 0x16 }, + { 0x20, 0x4d }, + { 0x21, 0x4d }, + { 0x22, 0x4d }, + { 0x23, 0x4d }, + { 0x28, 0x14 }, + { 0x29, 0x14 }, + { 0x2a, 0x14 }, + { 0x2b, 0x14 }, + }; + fe.reg2 = {0x00, 0x00, 0x00}; + s_frontends->push_back(fe); + + fe = Genesys_Frontend(); fe.id = AdcId::AD_XP200; fe.layout = wolfson_layout; diff --git a/backend/genesys/tables_gpo.cpp b/backend/genesys/tables_gpo.cpp index 40d927d10..5c1c54f39 100644 --- a/backend/genesys/tables_gpo.cpp +++ b/backend/genesys/tables_gpo.cpp @@ -130,6 +130,18 @@ void genesys_init_gpo_tables() s_gpo->push_back(gpo); + gpo = Genesys_Gpo(); + gpo.id = GpioId::CANON_LIDE_90; + gpo.regs = { + { 0x6b, 0x03 }, + { 0x6c, 0x74 }, + { 0x6d, 0x80 }, + { 0x6e, 0x7f }, + { 0x6f, 0xe0 }, + }; + s_gpo->push_back(gpo); + + gpo = Genesys_Gpo(); gpo.id = GpioId::XP200; gpo.regs = { diff --git a/backend/genesys/tables_model.cpp b/backend/genesys/tables_model.cpp index 50cd35969..2c5e6a385 100644 --- a/backend/genesys/tables_model.cpp +++ b/backend/genesys/tables_model.cpp @@ -1177,6 +1177,65 @@ void genesys_init_usb_device_tables() s_usb_devices->emplace_back(0x04a9, 0x2214, model); + model = Genesys_Model(); + model.name = "canon-lide-90"; + model.vendor = "Canon"; + model.model = "LiDE 90"; + model.model_id = ModelId::CANON_LIDE_90; + model.asic_type = AsicType::GL842; + + model.resolutions = { + { + { ScanMethod::FLATBED }, + { 2400, 1200, 600, 300 }, + { 2400, 1200, 600, 300 }, + } + }; + + model.bpp_gray_values = { 8, 16 }; + model.bpp_color_values = { 8, 16 }; + model.x_offset = 3.50; + model.y_offset = 9.0; + model.x_size = 219.0; + model.y_size = 299.0; + + model.y_offset_calib_white = 0.0; + model.y_size_calib_mm = 2.0; + model.y_offset_calib_dark_white_mm = 0.0; + model.y_size_calib_dark_white_mm = 0.0; + model.x_offset_calib_black = 0.0; + model.x_size_calib_mm = 221.5; + + model.post_scan = 0.0; + model.eject_feed = 0.0; + + model.ld_shift_r = 0; + model.ld_shift_g = 0; + model.ld_shift_b = 0; + + model.line_mode_color_order = ColorOrder::RGB; + + model.is_cis = true; + model.is_sheetfed = false; + model.sensor_id = SensorId::CIS_CANON_LIDE_90; + model.adc_id = AdcId::CANON_LIDE_90; + model.gpio_id = GpioId::CANON_LIDE_90; + model.motor_id = MotorId::CANON_LIDE_90; + model.flags = ModelFlag::DISABLE_ADC_CALIBRATION | + ModelFlag::HOST_SIDE_CALIBRATION_COMPLETE_SCAN | + ModelFlag::USE_CONSTANT_FOR_DARK_CALIBRATION | + ModelFlag::DISABLE_FAST_FEEDING | + ModelFlag::SHADING_REPARK | + ModelFlag::CUSTOM_GAMMA; + model.buttons = GENESYS_HAS_SCAN_SW | + GENESYS_HAS_FILE_SW | + GENESYS_HAS_EMAIL_SW | + GENESYS_HAS_COPY_SW; + model.search_lines = 400; + + s_usb_devices->emplace_back(0x04a9, 0x1900, model); + + model = Genesys_Model(); model.name = "hewlett-packard-scanjet-2300c"; model.vendor = "Hewlett Packard"; diff --git a/backend/genesys/tables_motor.cpp b/backend/genesys/tables_motor.cpp index b0b015876..a452fe575 100644 --- a/backend/genesys/tables_motor.cpp +++ b/backend/genesys/tables_motor.cpp @@ -144,6 +144,23 @@ void genesys_init_motor_tables() s_motors->push_back(std::move(motor)); + motor = Genesys_Motor(); + motor.id = MotorId::CANON_LIDE_90; + motor.base_ydpi = 1200; + profile = {MotorSlope::create_from_steps(8000, 3000, 200), StepType::FULL, 0}; + profile.resolutions = { 150, 300 }; + motor.profiles.push_back(profile); + + profile = {MotorSlope::create_from_steps(7000, 3000, 200), StepType::HALF, 0}; + profile.resolutions = { 600, 1200 }; + motor.profiles.push_back(profile); + + profile = {MotorSlope::create_from_steps(7000, 3000, 200), StepType::QUARTER, 0}; + profile.resolutions = { 2400 }; + motor.profiles.push_back(profile); + s_motors->push_back(std::move(motor)); + + motor = Genesys_Motor(); motor.id = MotorId::XP200; motor.base_ydpi = 600; diff --git a/backend/genesys/tables_sensor.cpp b/backend/genesys/tables_sensor.cpp index a9266d692..b90355c74 100644 --- a/backend/genesys/tables_sensor.cpp +++ b/backend/genesys/tables_sensor.cpp @@ -563,6 +563,69 @@ void genesys_init_sensor_tables() } + sensor = Genesys_Sensor(); + sensor.sensor_id = SensorId::CIS_CANON_LIDE_90; // gl842 + sensor.full_resolution = 2400; + sensor.black_pixels = 20; + sensor.dummy_pixel = 253; + sensor.fau_gain_white_ref = 150; + sensor.gain_white_ref = 150; + sensor.use_host_side_calib = true; + sensor.custom_regs = { + { 0x16, 0x20 }, { 0x17, 0x06 }, { 0x18, 0x00 }, { 0x19, 0xff }, + { 0x1a, 0x24 }, { 0x1c, 0x00 }, { 0x1d, 0x04 }, + { 0x52, 0x02 }, { 0x53, 0x04 }, { 0x54, 0x02 }, { 0x55, 0x04 }, + { 0x56, 0x02 }, { 0x57, 0x04 }, { 0x58, 0x0a }, { 0x59, 0x71 }, { 0x5a, 0x55 }, + { 0x70, 0x00 }, { 0x71, 0x05 }, { 0x72, 0x07 }, { 0x73, 0x09 }, + { 0x74, 0x00 }, { 0x75, 0x01 }, { 0x76, 0xff }, + { 0x77, 0x00 }, { 0x78, 0x00 }, { 0x79, 0x3f }, + { 0x7a, 0x00 }, { 0x7b, 0x00 }, { 0x7c, 0x1e }, { 0x7d, 0x11 }, { 0x7f, 0x50 } + }; + sensor.gamma = { 1.0f, 1.0f, 1.0f }; + { + struct CustomSensorSettings + { + ValueFilterAny resolutions; + unsigned optical_resolution; + unsigned register_dpihw; + unsigned register_dpiset; + unsigned shading_resolution; + unsigned shading_factor; + int output_pixel_offset; + SensorExposure exposure; + unsigned exposure_lperiod; + unsigned segment_size; + std::vector segment_order; + }; + + CustomSensorSettings custom_settings[] = { + { { 300 }, 300, 600, 600, 300, 2, 280, { 955, 1235, 675 }, 6500, 5152, + std::vector{} }, + { { 600 }, 600, 600, 600, 600, 1, 250, { 1655, 2075, 1095 }, 6536, 5152, + std::vector{} }, + { { 1200 }, 1200, 1200, 1200, 1200, 1, 500, { 3055, 4175, 1935 }, 12688, 5152, + {0, 1} }, + { { 2400 }, 2400, 2400, 2400, 2400, 1, 1000, { 5855, 7535, 3615 }, 21500, 5152, + {0, 1, 2, 3} }, + }; + + for (const CustomSensorSettings& setting : custom_settings) { + sensor.resolutions = setting.resolutions; + sensor.optical_resolution = setting.optical_resolution; + sensor.register_dpihw = setting.register_dpihw; + sensor.register_dpiset = setting.register_dpiset; + sensor.shading_resolution = setting.shading_resolution; + sensor.shading_factor = setting.shading_factor; + sensor.output_pixel_offset = setting.output_pixel_offset; + sensor.exposure = setting.exposure; + sensor.exposure_lperiod = setting.exposure_lperiod; + sensor.segment_size = setting.segment_size; + sensor.segment_order = setting.segment_order; + s_sensors->push_back(sensor); + } + } + + sensor = Genesys_Sensor(); sensor.sensor_id = SensorId::CIS_XP200; // gl646 sensor.full_resolution = 600; @@ -3803,7 +3866,7 @@ void verify_sensor_tables() if (asic_type == AsicType::GL842) { auto required_registers = { - 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1c, 0x1d, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7f diff --git a/doc/descriptions/genesys.desc b/doc/descriptions/genesys.desc index d16519456..e809d4be4 100644 --- a/doc/descriptions/genesys.desc +++ b/doc/descriptions/genesys.desc @@ -187,6 +187,12 @@ :status :basic :comment "No 2400 dpi support, slow speed at lower resolution" +:model "CanoScan LiDE 90" +:interface "USB" +:usbid "0x04a9" "0x1900" +:status :good +:comment "resolutions from 300 to 2400 dpi are supported" + :model "CanoScan LiDE 100" :interface "USB" :usbid "0x04a9" "0x1904" diff --git a/doc/descriptions/unsupported.desc b/doc/descriptions/unsupported.desc index aa392c54f..d6a11e799 100644 --- a/doc/descriptions/unsupported.desc +++ b/doc/descriptions/unsupported.desc @@ -395,13 +395,6 @@ :status :unsupported :comment "Not supported. However, a stand-alone program for FreeBSD is available." -:model "CanoScan LiDE 90" -:url "unsupported/canon-lide-90.html" -:interface "USB" -:usbid "0x04a9" "0x1900" -:status :unsupported -:comment "Unsupported. See link for details." - :model "CanoScan LiDE 500F" :url "unsupported/canon-canoscan-lide-500f.html" :interface "USB"