Lines Matching defs:dev

5    Copyright (C) 2004-2016 Stéphane Voltz <stef.dev@free.fr>
158 const Genesys_Sensor& sanei_genesys_find_sensor_any(const Genesys_Device* dev)
162 if (dev->model->sensor_id == sensor.sensor_id) {
169 Genesys_Sensor* find_sensor_impl(const Genesys_Device* dev, unsigned dpi, unsigned channels,
175 if (dev->model->sensor_id == sensor.sensor_id && sensor.resolutions.matches(dpi) &&
184 bool sanei_genesys_has_sensor(const Genesys_Device* dev, unsigned dpi, unsigned channels,
189 return find_sensor_impl(dev, dpi, channels, scan_method) != nullptr;
192 const Genesys_Sensor& sanei_genesys_find_sensor(const Genesys_Device* dev, unsigned dpi,
197 const auto* sensor = find_sensor_impl(dev, dpi, channels, scan_method);
203 Genesys_Sensor& sanei_genesys_find_sensor_for_write(Genesys_Device* dev, unsigned dpi,
209 auto* sensor = find_sensor_impl(dev, dpi, channels, scan_method);
217 sanei_genesys_find_sensors_all(const Genesys_Device* dev, ScanMethod scan_method)
222 if (dev->model->sensor_id == sensor.sensor_id && sensor.method == scan_method) {
230 sanei_genesys_find_sensors_all_for_write(Genesys_Device* dev, ScanMethod scan_method)
235 if (dev->model->sensor_id == sensor.sensor_id && sensor.method == scan_method) {
242 void sanei_genesys_init_structs (Genesys_Device * dev)
252 if (dev->model->gpio_id == gpo.id) {
253 dev->gpo = gpo;
261 if (dev->model->motor_id == motor.id) {
262 dev->motor = motor;
269 if (dev->model->adc_id == frontend.id) {
270 dev->frontend_initial = frontend;
271 dev->frontend = frontend;
277 if (dev->model->asic_type == AsicType::GL845 ||
278 dev->model->asic_type == AsicType::GL846 ||
279 dev->model->asic_type == AsicType::GL847 ||
280 dev->model->asic_type == AsicType::GL124)
284 if (memory_layout.models.matches(dev->model->model_id)) {
285 dev->memory_layout = memory_layout;
297 static_cast<unsigned>(dev->model->sensor_id),
298 static_cast<unsigned>(dev->model->gpio_id),
299 static_cast<unsigned>(dev->model->motor_id));
335 void sanei_genesys_create_default_gamma_table(Genesys_Device* dev,
340 if (dev->model->asic_type == AsicType::GL646) {
341 if (has_flag(dev->model->flags, ModelFlag::GAMMA_14BIT)) {
347 } else if (dev->model->asic_type == AsicType::GL124 ||
348 dev->model->asic_type == AsicType::GL845 ||
349 dev->model->asic_type == AsicType::GL846 ||
350 dev->model->asic_type == AsicType::GL847) {
371 SANE_Int sanei_genesys_exposure_time2(Genesys_Device * dev, const MotorProfile& profile, float ydpi,
376 int exposure_by_motor = static_cast<int>((max_speed_motor_w * dev->motor.base_ydpi) / ydpi);
384 if (exposure < exposure_by_led && dev->model->is_cis) {
398 static void genesys_send_offset_and_shading(Genesys_Device* dev, const Genesys_Sensor& sensor,
407 if (dev->cmd_set->has_send_shading_data()) {
408 dev->cmd_set->send_shading_data(dev, sensor, data, size);
414 dev->interface->write_buffer(0x3c, start_address, data, size);
417 void sanei_genesys_init_shading_data(Genesys_Device* dev, const Genesys_Sensor& sensor,
422 if (dev->cmd_set->has_send_shading_data()) {
428 unsigned channels = dev->settings.get_channels();
442 genesys_send_offset_and_shading(dev, sensor, shading_data.data(),
447 void gl124_setup_scan_gpio(Genesys_Device* dev, int resolution);
450 void scanner_clear_scan_and_feed_counts(Genesys_Device& dev)
452 switch (dev.model->asic_type) {
454 dev.interface->write_register(gl841::REG_0x0D,
459 dev.interface->write_register(gl842::REG_0x0D,
464 dev.interface->write_register(gl843::REG_0x0D,
470 dev.interface->write_register(gl846::REG_0x0D,
475 dev.interface->write_register(gl847::REG_0x0D,
480 dev.interface->write_register(gl124::REG_0x0D,
489 void scanner_send_slope_table(Genesys_Device* dev, const Genesys_Sensor& sensor, unsigned table_nr,
495 switch (dev->model->asic_type) {
524 if (dev->model->asic_type == AsicType::GL841 ||
525 dev->model->model_id == ModelId::CANON_LIDE_90)
528 auto max_table_size = get_slope_table_max_size(dev->model->asic_type);
536 if (dev->interface->is_mock()) {
537 dev->interface->record_slope_table(table_nr, slope_table);
540 switch (dev->model->asic_type) {
542 unsigned dpihw = dev->reg.find_reg(0x05).value >> 6;
553 dev->interface->write_buffer(0x3c, start_address + table_nr * 0x100, table.data(),
566 dev->interface->write_buffer(0x3c, start_address + table_nr * 0x200, table.data(),
572 // XXX STEF XXX USB 1.1 ? sanei_genesys_write_0x8c (dev, 0x0f, 0x14);
573 dev->interface->write_gamma(0x28, 0x40000 + 0x8000 * table_nr, table.data(),
582 dev->interface->write_ahb(0x10000000 + 0x4000 * table_nr, table.size(),
592 bool scanner_is_motor_stopped(Genesys_Device& dev)
594 switch (dev.model->asic_type) {
596 auto status = scanner_read_status(dev);
600 auto status = scanner_read_status(dev);
601 auto reg = dev.interface->read_register(gl841::REG_0x40);
607 auto status = scanner_read_status(dev);
608 auto reg = dev.interface->read_register(gl842::REG_0x40);
614 auto status = scanner_read_status(dev);
615 auto reg = dev.interface->read_register(gl843::REG_0x40);
622 auto status = scanner_read_status(dev);
623 auto reg = dev.interface->read_register(gl846::REG_0x40);
629 auto status = scanner_read_status(dev);
630 auto reg = dev.interface->read_register(gl847::REG_0x40);
636 auto status = scanner_read_status(dev);
637 auto reg = dev.interface->read_register(gl124::REG_0x100);
647 void scanner_setup_sensor(Genesys_Device& dev, const Genesys_Sensor& sensor,
656 if (dev.model->asic_type != AsicType::GL843)
659 regs_set_exposure(dev.model->asic_type, regs, sensor.exposure);
662 dev.segment_order = sensor.segment_order;
665 void scanner_stop_action(Genesys_Device& dev)
669 switch (dev.model->asic_type) {
682 dev.cmd_set->update_home_sensor_gpio(dev);
684 if (scanner_is_motor_stopped(dev)) {
689 scanner_stop_action_no_move(dev, dev.reg);
696 if (scanner_is_motor_stopped(dev)) {
700 dev.interface->sleep_ms(100);
706 void scanner_stop_action_no_move(Genesys_Device& dev, genesys::Genesys_Register_Set& regs)
708 switch (dev.model->asic_type) {
722 regs_set_optical_off(dev.model->asic_type, regs);
724 dev.interface->write_register(0x01, regs.get8(0x01));
728 dev.interface->sleep_ms(100);
731 void scanner_move(Genesys_Device& dev, ScanMethod scan_method, unsigned steps, Direction direction)
735 auto local_reg = dev.reg;
737 unsigned resolution = dev.model->get_resolution_settings(scan_method).get_min_resolution_y();
739 const auto& sensor = sanei_genesys_find_sensor(&dev, resolution, 3, scan_method);
743 (!has_flag(dev.model->flags, ModelFlag::UTA_NO_SECONDARY_MOTOR));
746 dev.model->default_method == ScanMethod::FLATBED;
748 if (!dev.is_head_pos_known(ScanHeadId::PRIMARY)) {
751 if (uses_secondary_pos && !dev.is_head_pos_known(ScanHeadId::SECONDARY)) {
754 if (direction == Direction::BACKWARD && steps > dev.head_pos(ScanHeadId::PRIMARY)) {
756 steps, dev.head_pos(ScanHeadId::PRIMARY));
759 steps > dev.head_pos(ScanHeadId::SECONDARY))
762 steps, dev.head_pos(ScanHeadId::SECONDARY));
777 session.params.contrast_adjustment = dev.settings.contrast;
778 session.params.brightness_adjustment = dev.settings.brightness;
786 if (dev.model->asic_type == AsicType::GL124) {
794 compute_session(&dev, session, sensor);
796 dev.cmd_set->init_regs_for_scan_session(&dev, sensor, &local_reg, session);
798 if (dev.model->asic_type != AsicType::GL843) {
799 regs_set_exposure(dev.model->asic_type, local_reg,
802 scanner_clear_scan_and_feed_counts(dev);
804 dev.interface->write_registers(local_reg);
806 dev.cmd_set->set_motor_mode(dev, local_reg, MotorMode::PRIMARY_AND_SECONDARY);
810 scanner_start_action(dev, true);
813 dev.cmd_set->set_motor_mode(dev, local_reg, MotorMode::PRIMARY);
815 catch_all_exceptions(__func__, [&]() { scanner_stop_action(dev); });
817 catch_all_exceptions(__func__, [&]() { dev.interface->write_registers(dev.reg); });
822 dev.interface->test_checkpoint("feed");
824 dev.advance_head_pos_by_steps(ScanHeadId::PRIMARY, direction, steps);
826 dev.advance_head_pos_by_steps(ScanHeadId::SECONDARY, direction, steps);
829 scanner_stop_action(dev);
831 dev.cmd_set->set_motor_mode(dev, local_reg, MotorMode::PRIMARY);
837 if (dev.model->model_id == ModelId::CANON_LIDE_700F) {
838 dev.cmd_set->update_home_sensor_gpio(dev);
844 status = scanner_read_status(dev);
850 dev.interface->sleep_ms(10);
853 scanner_stop_action(dev);
855 dev.cmd_set->set_motor_mode(dev, local_reg, MotorMode::PRIMARY);
858 dev.advance_head_pos_by_steps(ScanHeadId::PRIMARY, direction, steps);
860 dev.advance_head_pos_by_steps(ScanHeadId::SECONDARY, direction, steps);
864 dev.interface->sleep_ms(100);
867 void scanner_move_to_ta(Genesys_Device& dev)
871 unsigned feed = static_cast<unsigned>((dev.model->y_offset_sensor_to_ta * dev.motor.base_ydpi) /
873 scanner_move(dev, dev.model->default_method, feed, Direction::FORWARD);
876 void scanner_move_back_home(Genesys_Device& dev, bool wait_until_home)
880 switch (dev.model->asic_type) {
893 if (dev.model->is_sheetfed) {
899 if ((!dev.is_head_pos_known(ScanHeadId::SECONDARY) ||
900 dev.head_pos(ScanHeadId::SECONDARY) > 0 ||
901 dev.settings.scan_method == ScanMethod::TRANSPARENCY ||
902 dev.settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) &&
903 (!has_flag(dev.model->flags, ModelFlag::UTA_NO_SECONDARY_MOTOR)))
905 scanner_move_back_home_ta(dev);
908 if (dev.is_head_pos_known(ScanHeadId::PRIMARY) &&
909 dev.head_pos(ScanHeadId::PRIMARY) > 1000)
912 scanner_move(dev, dev.model->default_method, dev.head_pos(ScanHeadId::PRIMARY) - 500,
916 dev.cmd_set->update_home_sensor_gpio(dev);
918 auto status = scanner_read_reliable_status(dev);
922 dev.set_head_pos_zero(ScanHeadId::PRIMARY);
926 Genesys_Register_Set local_reg = dev.reg;
927 unsigned resolution = sanei_genesys_get_lowest_ydpi(&dev);
929 const auto& sensor = sanei_genesys_find_sensor(&dev, resolution, 1, dev.model->default_method);
940 session.params.scan_method = dev.settings.scan_method;
943 session.params.contrast_adjustment = dev.settings.contrast;
944 session.params.brightness_adjustment = dev.settings.brightness;
952 if (dev.model->asic_type == AsicType::GL843) {
956 compute_session(&dev, session, sensor);
958 dev.cmd_set->init_regs_for_scan_session(&dev, sensor, &local_reg, session);
960 scanner_clear_scan_and_feed_counts(dev);
962 dev.interface->write_registers(local_reg);
964 if (dev.model->asic_type == AsicType::GL124) {
965 gl124::gl124_setup_scan_gpio(&dev, resolution);
969 scanner_start_action(dev, true);
971 catch_all_exceptions(__func__, [&]() { scanner_stop_action(dev); });
975 dev.interface->write_registers(dev.reg);
980 dev.cmd_set->update_home_sensor_gpio(dev);
983 dev.interface->test_checkpoint("move_back_home");
984 dev.set_head_pos_zero(ScanHeadId::PRIMARY);
990 auto status = scanner_read_status(dev);
994 if (dev.model->asic_type == AsicType::GL846 ||
995 dev.model->asic_type == AsicType::GL847)
997 scanner_stop_action(dev);
999 dev.set_head_pos_zero(ScanHeadId::PRIMARY);
1003 dev.interface->sleep_ms(100);
1008 catch_all_exceptions(__func__, [&](){ scanner_stop_action(dev); });
1009 dev.set_head_pos_unknown(ScanHeadId::PRIMARY | ScanHeadId::SECONDARY);
1016 bool should_use_secondary_motor_mode(Genesys_Device& dev)
1018 bool should_use = !dev.is_head_pos_known(ScanHeadId::SECONDARY) ||
1019 !dev.is_head_pos_known(ScanHeadId::PRIMARY) ||
1020 dev.head_pos(ScanHeadId::SECONDARY) > dev.head_pos(ScanHeadId::PRIMARY);
1021 bool supports = dev.model->model_id == ModelId::CANON_8600F;
1025 void handle_motor_position_after_move_back_home_ta(Genesys_Device& dev, MotorMode motor_mode)
1028 dev.set_head_pos_zero(ScanHeadId::SECONDARY);
1032 if (dev.is_head_pos_known(ScanHeadId::PRIMARY)) {
1033 if (dev.head_pos(ScanHeadId::PRIMARY) > dev.head_pos(ScanHeadId::SECONDARY)) {
1034 dev.advance_head_pos_by_steps(ScanHeadId::PRIMARY, Direction::BACKWARD,
1035 dev.head_pos(ScanHeadId::SECONDARY));
1037 dev.set_head_pos_zero(ScanHeadId::PRIMARY);
1039 dev.set_head_pos_zero(ScanHeadId::SECONDARY);
1044 void scanner_move_back_home_ta(Genesys_Device& dev)
1048 switch (dev.model->asic_type) {
1057 Genesys_Register_Set local_reg = dev.reg;
1060 unsigned resolution = dev.model->get_resolution_settings(scan_method).get_min_resolution_y();
1062 const auto& sensor = sanei_genesys_find_sensor(&dev, resolution, 1, scan_method);
1064 if (dev.is_head_pos_known(ScanHeadId::SECONDARY) &&
1065 dev.is_head_pos_known(ScanHeadId::PRIMARY) &&
1066 dev.head_pos(ScanHeadId::SECONDARY) > 1000 &&
1067 dev.head_pos(ScanHeadId::SECONDARY) <= dev.head_pos(ScanHeadId::PRIMARY))
1070 scanner_move(dev, scan_method, dev.head_pos(ScanHeadId::SECONDARY) - 500,
1086 session.params.contrast_adjustment = dev.settings.contrast;
1087 session.params.brightness_adjustment = dev.settings.brightness;
1095 compute_session(&dev, session, sensor);
1097 dev.cmd_set->init_regs_for_scan_session(&dev, sensor, &local_reg, session);
1099 scanner_clear_scan_and_feed_counts(dev);
1101 dev.interface->write_registers(local_reg);
1103 auto motor_mode = should_use_secondary_motor_mode(dev) ? MotorMode::SECONDARY
1106 dev.cmd_set->set_motor_mode(dev, local_reg, motor_mode);
1109 scanner_start_action(dev, true);
1111 catch_all_exceptions(__func__, [&]() { scanner_stop_action(dev); });
1113 catch_all_exceptions(__func__, [&]() { dev.interface->write_registers(dev.reg); });
1118 dev.interface->test_checkpoint("move_back_home_ta");
1120 handle_motor_position_after_move_back_home_ta(dev, motor_mode);
1122 scanner_stop_action(dev);
1123 dev.cmd_set->set_motor_mode(dev, local_reg, MotorMode::PRIMARY);
1129 auto status = scanner_read_status(dev);
1134 handle_motor_position_after_move_back_home_ta(dev, motor_mode);
1136 scanner_stop_action(dev);
1137 dev.cmd_set->set_motor_mode(dev, local_reg, MotorMode::PRIMARY);
1141 dev.interface->sleep_ms(100);
1147 void scanner_search_strip(Genesys_Device& dev, bool forward, bool black)
1151 if (dev.model->asic_type == AsicType::GL841 && !black && forward) {
1152 dev.frontend.set_gain(0, 0xff);
1153 dev.frontend.set_gain(1, 0xff);
1154 dev.frontend.set_gain(2, 0xff);
1158 const auto& resolution_settings = dev.model->get_resolution_settings(dev.settings.scan_method);
1162 auto& sensor = sanei_genesys_find_sensor(&dev, dpi, channels, dev.settings.scan_method);
1163 dev.cmd_set->set_fe(&dev, sensor, AFE_SET);
1164 scanner_stop_action(dev);
1167 // shading calibration is done with dev.motor.base_ydpi
1168 unsigned lines = static_cast<unsigned>(dev.model->y_size_calib_mm * dpi / MM_PER_INCH);
1169 if (dev.model->asic_type == AsicType::GL841) {
1170 lines = 10; // TODO: use dev.model->search_lines
1174 unsigned pixels = dev.model->x_size_calib_mm * dpi / MM_PER_INCH;
1176 dev.set_head_pos_zero(ScanHeadId::PRIMARY);
1179 if (dev.model->asic_type == AsicType::GL841) {
1184 auto local_reg = dev.reg;
1195 session.params.scan_method = dev.settings.scan_method;
1198 session.params.contrast_adjustment = dev.settings.contrast;
1199 session.params.brightness_adjustment = dev.settings.brightness;
1202 if (dev.model->asic_type != AsicType::GL841 && !forward) {
1205 compute_session(&dev, session, sensor);
1207 dev.cmd_set->init_regs_for_scan_session(&dev, sensor, &local_reg, session);
1209 dev.interface->write_registers(local_reg);
1211 dev.cmd_set->begin_scan(&dev, sensor, &local_reg, true);
1214 dev.interface->test_checkpoint("search_strip");
1215 scanner_stop_action(dev);
1219 wait_until_buffer_non_empty(&dev);
1222 auto image = read_unshuffled_image_from_scanner(&dev, session, session.output_total_bytes);
1224 scanner_stop_action(dev);
1237 dev.interface->write_registers(local_reg);
1240 dev.cmd_set->begin_scan(&dev, sensor, &local_reg, true);
1242 wait_until_buffer_non_empty(&dev);
1245 image = read_unshuffled_image_from_scanner(&dev, session, session.output_total_bytes);
1247 scanner_stop_action(dev);
1365 bool should_calibrate_only_active_area(const Genesys_Device& dev,
1371 if (dev.model->model_id == ModelId::CANON_4400F && settings.xres >= 4800) {
1374 if (dev.model->model_id == ModelId::CANON_8600F && settings.xres == 4800) {
1381 void scanner_offset_calibration(Genesys_Device& dev, const Genesys_Sensor& sensor,
1386 if (dev.model->asic_type == AsicType::GL842 &&
1387 dev.frontend.layout.type != FrontendType::WOLFSON)
1392 if (dev.model->asic_type == AsicType::GL843 &&
1393 dev.frontend.layout.type != FrontendType::WOLFSON)
1398 if (dev.model->asic_type == AsicType::GL845 ||
1399 dev.model->asic_type == AsicType::GL846)
1402 std::uint8_t reg04 = dev.interface->read_register(gl846::REG_0x04);
1407 if (dev.model->asic_type == AsicType::GL847) {
1409 std::uint8_t reg04 = dev.interface->read_register(gl847::REG_0x04);
1415 if (dev.model->asic_type == AsicType::GL124) {
1416 std::uint8_t reg0a = dev.interface->read_register(gl124::REG_0x0A);
1422 unsigned target_pixels = dev.model->x_size_calib_mm * sensor.full_resolution / MM_PER_INCH;
1431 if (dev.model->asic_type == AsicType::GL843) {
1435 const auto& dpihw_sensor = sanei_genesys_find_sensor(&dev, dev.settings.xres, channels,
1436 dev.settings.scan_method);
1440 calib_sensor = &sanei_genesys_find_sensor(&dev, resolution, channels,
1441 dev.settings.scan_method);
1443 target_pixels = dev.model->x_size_calib_mm * resolution / MM_PER_INCH;
1446 if (should_calibrate_only_active_area(dev, dev.settings)) {
1447 float offset = dev.model->x_offset_ta;
1450 float size = dev.model->x_size_ta;
1454 if (dev.model->model_id == ModelId::CANON_4400F &&
1455 dev.settings.scan_method == ScanMethod::FLATBED)
1461 if (dev.model->model_id == ModelId::CANON_5600F) {
1466 if (dev.model->asic_type == AsicType::GL847) {
1467 calib_sensor = &sanei_genesys_find_sensor(&dev, resolution, channels,
1468 dev.settings.scan_method);
1477 if (dev.settings.scan_method == ScanMethod::TRANSPARENCY ||
1478 dev.settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED)
1492 session.params.scan_method = dev.settings.scan_method;
1494 session.params.color_filter = dev.model->asic_type == AsicType::GL843 ? ColorFilter::RED
1495 : dev.settings.color_filter;
1496 session.params.contrast_adjustment = dev.settings.contrast;
1497 session.params.brightness_adjustment = dev.settings.brightness;
1499 compute_session(&dev, session, *calib_sensor);
1501 dev.cmd_set->init_regs_for_scan_session(&dev, *calib_sensor, &regs, session);
1514 dev.frontend.set_offset(ch, bottom[ch]);
1515 dev.frontend.set_gain(ch, 0);
1517 dev.cmd_set->set_fe(&dev, *calib_sensor, AFE_SET);
1520 dev.interface->write_registers(regs);
1523 dev.cmd_set->begin_scan(&dev, *calib_sensor, &regs, true);
1526 dev.interface->test_checkpoint("offset_calibration");
1527 if (dev.model->asic_type == AsicType::GL842 ||
1528 dev.model->asic_type == AsicType::GL843)
1530 scanner_stop_action_no_move(dev, regs);
1536 if (dev.model->asic_type == AsicType::GL842 ||
1537 dev.model->asic_type == AsicType::GL843)
1539 first_line = read_unshuffled_image_from_scanner(&dev, session,
1541 scanner_stop_action_no_move(dev, regs);
1543 first_line = read_unshuffled_image_from_scanner(&dev, session, session.output_total_bytes);
1545 if (dev.model->model_id == ModelId::CANON_5600F) {
1546 scanner_stop_action_no_move(dev, regs);
1565 dev.frontend.set_offset(ch, top[ch]);
1567 dev.cmd_set->set_fe(&dev, *calib_sensor, AFE_SET);
1570 dev.interface->write_registers(regs);
1573 dev.cmd_set->begin_scan(&dev, *calib_sensor, &regs, true);
1576 if (dev.model->asic_type == AsicType::GL842 ||
1577 dev.model->asic_type == AsicType::GL843)
1579 second_line = read_unshuffled_image_from_scanner(&dev, session,
1581 scanner_stop_action_no_move(dev, regs);
1583 second_line = read_unshuffled_image_from_scanner(&dev, session, session.output_total_bytes);
1585 if (dev.model->model_id == ModelId::CANON_5600F) {
1586 scanner_stop_action_no_move(dev, regs);
1610 dev.frontend.set_offset(ch, (top[ch] + bottom[ch]) / 2);
1613 dev.cmd_set->set_fe(&dev, *calib_sensor, AFE_SET);
1616 dev.interface->write_registers(regs);
1618 dev.cmd_set->begin_scan(&dev, *calib_sensor, &regs, true);
1620 if (dev.model->asic_type == AsicType::GL842 ||
1621 dev.model->asic_type == AsicType::GL843)
1623 second_line = read_unshuffled_image_from_scanner(&dev, session,
1625 scanner_stop_action_no_move(dev, regs);
1627 second_line = read_unshuffled_image_from_scanner(&dev, session, session.output_total_bytes);
1629 if (dev.model->model_id == ModelId::CANON_5600F) {
1630 scanner_stop_action_no_move(dev, regs);
1638 dev.frontend.get_offset(0),
1639 dev.frontend.get_offset(1),
1640 dev.frontend.get_offset(2));
1651 dev.frontend.get_offset(ch));
1658 top[ch] = dev.frontend.get_offset(ch);
1661 bottom[ch] = dev.frontend.get_offset(ch);
1675 dev.frontend.get_offset(0),
1676 dev.frontend.get_offset(1),
1677 dev.frontend.get_offset(2));
1684 void scanner_coarse_gain_calibration(Genesys_Device& dev, const Genesys_Sensor& sensor,
1689 if (dev.model->asic_type == AsicType::GL842 &&
1690 dev.frontend.layout.type != FrontendType::WOLFSON)
1695 if (dev.model->asic_type == AsicType::GL843 &&
1696 dev.frontend.layout.type != FrontendType::WOLFSON)
1701 if (dev.model->asic_type == AsicType::GL845 ||
1702 dev.model->asic_type == AsicType::GL846)
1705 std::uint8_t reg04 = dev.interface->read_register(gl846::REG_0x04);
1711 if (dev.model->asic_type == AsicType::GL847) {
1713 std::uint8_t reg04 = dev.interface->read_register(gl847::REG_0x04);
1719 if (dev.model->asic_type == AsicType::GL124) {
1721 std::uint8_t reg0a = dev.interface->read_register(gl124::REG_0x0A);
1727 if (dev.model->asic_type == AsicType::GL841) {
1729 if (dev.model->y_offset_calib_white > 0) {
1731 (dev.model->y_offset_calib_white * (dev.motor.base_ydpi)) / MM_PER_INCH);
1732 scanner_move(dev, dev.model->default_method, move, Direction::FORWARD);
1740 if (dev.model->asic_type == AsicType::GL841) {
1741 const auto& dpihw_sensor = sanei_genesys_find_sensor(&dev, dev.settings.xres, channels,
1742 dev.settings.scan_method);
1746 if (dev.model->asic_type == AsicType::GL842 ||
1747 dev.model->asic_type == AsicType::GL843)
1749 const auto& dpihw_sensor = sanei_genesys_find_sensor(&dev, dpi, channels,
1750 dev.settings.scan_method);
1757 if (dev.model->sensor_id == SensorId::CCD_KVSS080 ||
1758 dev.model->asic_type == AsicType::GL845 ||
1759 dev.model->asic_type == AsicType::GL846 ||
1760 dev.model->asic_type == AsicType::GL847 ||
1761 dev.model->asic_type == AsicType::GL124)
1763 if (dev.settings.xres < sensor.full_resolution) {
1769 if (dev.model->asic_type == AsicType::GL841) {
1774 if (dev.model->asic_type == AsicType::GL841 ||
1775 dev.model->asic_type == AsicType::GL842 ||
1776 dev.model->asic_type == AsicType::GL843 ||
1777 dev.model->asic_type == AsicType::GL847)
1779 calib_sensor = &sanei_genesys_find_sensor(&dev, resolution, channels,
1780 dev.settings.scan_method);
1789 if (dev.settings.scan_method == ScanMethod::TRANSPARENCY ||
1790 dev.settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED)
1797 session.params.yres = dev.model->asic_type == AsicType::GL841 ? dev.settings.yres : resolution;
1800 session.params.pixels = dev.model->x_size_calib_mm * resolution / MM_PER_INCH;
1802 session.params.depth = dev.model->asic_type == AsicType::GL841 ? 16 : 8;
1804 session.params.scan_method = dev.settings.scan_method;
1806 session.params.color_filter = dev.settings.color_filter;
1807 session.params.contrast_adjustment = dev.settings.contrast;
1808 session.params.brightness_adjustment = dev.settings.brightness;
1810 compute_session(&dev, session, *calib_sensor);
1815 dev.cmd_set->init_regs_for_scan_session(&dev, *calib_sensor, &regs, session);
1817 if (dev.model->asic_type != AsicType::GL841) {
1823 if (dev.model->asic_type != AsicType::GL841) {
1827 dev.interface->write_registers(regs);
1829 if (dev.model->asic_type != AsicType::GL841) {
1830 dev.cmd_set->set_fe(&dev, *calib_sensor, AFE_SET);
1832 dev.cmd_set->begin_scan(&dev, *calib_sensor, &regs, true);
1835 dev.interface->test_checkpoint("coarse_gain_calibration");
1836 scanner_stop_action(dev);
1837 dev.cmd_set->move_back_home(&dev, true);
1842 if (dev.model->asic_type == AsicType::GL842 ||
1843 dev.model->asic_type == AsicType::GL843)
1845 image = read_unshuffled_image_from_scanner(&dev, session, session.output_total_bytes_raw);
1846 } else if (dev.model->asic_type == AsicType::GL124) {
1848 image = read_unshuffled_image_from_scanner(&dev, session, session.output_line_bytes);
1850 image = read_unshuffled_image_from_scanner(&dev, session, session.output_total_bytes);
1853 if (dev.model->asic_type == AsicType::GL842 ||
1854 dev.model->asic_type == AsicType::GL843)
1856 scanner_stop_action_no_move(dev, regs);
1867 if (dev.model->asic_type == AsicType::GL841 ||
1868 dev.model->asic_type == AsicType::GL842 ||
1869 dev.model->asic_type == AsicType::GL843)
1898 dev.frontend.layout.type);
1899 dev.frontend.set_gain(ch, out_gain);
1904 if (dev.model->asic_type == AsicType::GL841 &&
1917 dbg.vlog(DBG_info, "gain=(%d, %d, %d)", dev.frontend.get_gain(0), dev.frontend.get_gain(1),
1918 dev.frontend.get_gain(2));
1921 if (dev.model->is_cis) {
1922 std::uint8_t min_gain = std::min({dev.frontend.get_gain(0),
1923 dev.frontend.get_gain(1),
1924 dev.frontend.get_gain(2)});
1926 dev.frontend.set_gain(0, min_gain);
1927 dev.frontend.set_gain(1, min_gain);
1928 dev.frontend.set_gain(2, min_gain);
1931 dbg.vlog(DBG_info, "final gain=(%d, %d, %d)", dev.frontend.get_gain(0),
1932 dev.frontend.get_gain(1), dev.frontend.get_gain(2));
1934 scanner_stop_action(dev);
1936 dev.cmd_set->move_back_home(&dev, true);
1940 void move_to_calibration_area(Genesys_Device* dev, const Genesys_Sensor& sensor,
1944 SensorExposure scanner_led_calibration(Genesys_Device& dev, const Genesys_Sensor& sensor,
1951 if (dev.model->asic_type == AsicType::GL841) {
1952 if (dev.model->y_offset_calib_white > 0) {
1953 move = (dev.model->y_offset_calib_white * (dev.motor.base_ydpi)) / MM_PER_INCH;
1954 scanner_move(dev, dev.model->default_method, static_cast<unsigned>(move),
1957 } else if (dev.model->asic_type == AsicType::GL842 ||
1958 dev.model->asic_type == AsicType::GL843)
1961 } else if (dev.model->asic_type == AsicType::GL845 ||
1962 dev.model->asic_type == AsicType::GL846 ||
1963 dev.model->asic_type == AsicType::GL847)
1965 move = dev.model->y_offset_calib_white;
1966 move = static_cast<float>((move * (dev.motor.base_ydpi / 4)) / MM_PER_INCH);
1968 scanner_move(dev, dev.model->default_method, static_cast<unsigned>(move),
1971 } else if (dev.model->asic_type == AsicType::GL124) {
1972 gl124::move_to_calibration_area(&dev, sensor, regs);
1978 const auto& calib_sensor = sanei_genesys_find_sensor(&dev, resolution, channels,
1979 dev.settings.scan_method);
1981 if (dev.model->asic_type == AsicType::GL841 ||
1982 dev.model->asic_type == AsicType::GL845 ||
1983 dev.model->asic_type == AsicType::GL846 ||
1984 dev.model->asic_type == AsicType::GL847 ||
1985 dev.model->asic_type == AsicType::GL124)
1987 regs = dev.reg; // FIXME: apply this to all ASICs
1995 session.params.pixels = dev.model->x_size_calib_mm * resolution / MM_PER_INCH;
1999 session.params.scan_method = dev.settings.scan_method;
2001 session.params.color_filter = dev.settings.color_filter;
2002 session.params.contrast_adjustment = dev.settings.contrast;
2003 session.params.brightness_adjustment = dev.settings.brightness;
2009 compute_session(&dev, session, calib_sensor);
2011 dev.cmd_set->init_regs_for_scan_session(&dev, calib_sensor, &regs, session);
2024 if (dev.model->asic_type == AsicType::GL845 ||
2025 dev.model->asic_type == AsicType::GL846)
2034 } else if (dev.model->asic_type == AsicType::GL847) {
2044 if (dev.model->asic_type == AsicType::GL845 ||
2045 dev.model->asic_type == AsicType::GL846 ||
2046 dev.model->asic_type == AsicType::GL847 ||
2047 dev.model->asic_type == AsicType::GL124)
2054 regs_set_exposure(dev.model->asic_type, regs, { exp[0], exp[1], exp[2] });
2056 dev.interface->write_registers(regs);
2059 dev.cmd_set->begin_scan(&dev, calib_sensor, &regs, true);
2062 dev.interface->test_checkpoint("led_calibration");
2063 if (dev.model->asic_type == AsicType::GL841) {
2064 scanner_stop_action(dev);
2065 dev.cmd_set->move_back_home(&dev, true);
2066 } else if (dev.model->asic_type == AsicType::GL124) {
2067 scanner_stop_action(dev);
2069 scanner_stop_action(dev);
2070 dev.cmd_set->move_back_home(&dev, true);
2075 auto image = read_unshuffled_image_from_scanner(&dev, session, session.output_line_bytes);
2077 scanner_stop_action(dev);
2098 if (dev.model->asic_type == AsicType::GL845 ||
2099 dev.model->asic_type == AsicType::GL846)
2119 } else if (dev.model->asic_type == AsicType::GL847) {
2132 } else if (dev.model->asic_type == AsicType::GL841 ||
2133 dev.model->asic_type == AsicType::GL124)
2150 if (dev.model->asic_type == AsicType::GL845 ||
2151 dev.model->asic_type == AsicType::GL846 ||
2152 dev.model->asic_type == AsicType::GL847 ||
2153 dev.model->asic_type == AsicType::GL124)
2156 regs_set_exposure(dev.model->asic_type, dev.reg, { exp[0], exp[1], exp[2] });
2159 if (dev.model->asic_type == AsicType::GL841 ||
2160 dev.model->asic_type == AsicType::GL842 ||
2161 dev.model->asic_type == AsicType::GL843)
2163 dev.cmd_set->move_back_home(&dev, true);
2166 if (dev.model->asic_type == AsicType::GL845 ||
2167 dev.model->asic_type == AsicType::GL846 ||
2168 dev.model->asic_type == AsicType::GL847)
2171 dev.cmd_set->move_back_home(&dev, true);
2215 * @param dev scanner's device
2217 static void genesys_shading_calibration_impl(Genesys_Device* dev, const Genesys_Sensor& sensor,
2224 if (dev->model->asic_type == AsicType::GL646) {
2225 dev->cmd_set->init_regs_for_shading(dev, sensor, local_reg);
2226 local_reg = dev->reg;
2228 local_reg = dev->reg;
2229 dev->cmd_set->init_regs_for_shading(dev, sensor, local_reg);
2230 dev->interface->write_registers(local_reg);
2233 debug_dump(DBG_info, dev->calib_session);
2238 if (dev->model->asic_type == AsicType::GL842 ||
2239 dev->model->asic_type == AsicType::GL843 ||
2240 dev->model->model_id == ModelId::CANON_5600F)
2242 pixels_per_line = dev->calib_session.output_pixels;
2245 pixels_per_line = dev->calib_session.params.pixels;
2247 unsigned channels = dev->calib_session.params.channels;
2251 dev->calib_session.params.startx * sensor.full_resolution / dev->calib_session.params.xres;
2256 dev->average_size = channels * out_pixels_per_line;
2259 out_average_data.resize(dev->average_size);
2261 if (is_dark && dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) {
2268 if (dev->model->asic_type == AsicType::GL842 ||
2269 dev->model->asic_type == AsicType::GL843 ||
2270 dev->model->model_id == ModelId::CANON_5600F)
2272 size = dev->calib_session.output_total_bytes_raw;
2274 size = channels * 2 * pixels_per_line * (dev->calib_session.params.lines + 1);
2281 if (is_dark && !dev->model->is_sheetfed) {
2282 sanei_genesys_set_lamp_power(dev, sensor, local_reg, false);
2284 sanei_genesys_set_lamp_power(dev, sensor, local_reg, true);
2288 dev->interface->write_registers(local_reg);
2292 dev->interface->sleep_ms(200);
2293 } else if (has_flag(dev->model->flags, ModelFlag::DARK_CALIBRATION)) {
2296 dev->interface->sleep_ms(500);
2300 dev->cmd_set->begin_scan(dev, sensor, &local_reg, start_motor);
2304 dev->interface->test_checkpoint(is_dark ? "dark_shading_calibration"
2306 dev->cmd_set->end_scan(dev, &local_reg, true);
2310 sanei_genesys_read_data_from_scanner(dev, reinterpret_cast<std::uint8_t*>(calibration_data.data()),
2313 dev->cmd_set->end_scan(dev, &local_reg, true);
2315 if (has_flag(dev->model->flags, ModelFlag::SWAP_16BIT_DATA)) {
2323 if (has_flag(dev->model->flags, ModelFlag::INVERT_PIXEL_DATA)) {
2335 dev->calib_session.params.lines, pixels_per_line * channels,
2340 channels, pixels_per_line, dev->calib_session.params.lines);
2353 static void genesys_dark_shading_by_dummy_pixel(Genesys_Device* dev, const Genesys_Sensor& sensor)
2360 if (dev->model->asic_type == AsicType::GL842 ||
2361 dev->model->asic_type == AsicType::GL843)
2363 pixels_per_line = dev->calib_session.output_pixels;
2365 pixels_per_line = dev->calib_session.params.pixels;
2368 unsigned channels = dev->calib_session.params.channels;
2372 dev->calib_session.params.startx * sensor.full_resolution / dev->calib_session.params.xres;
2376 dev->average_size = channels * out_pixels_per_line;
2377 dev->dark_average_data.clear();
2378 dev->dark_average_data.resize(dev->average_size, 0);
2382 if (dev->settings.xres <= sensor.full_resolution / 2) {
2391 if (dev->model->sensor_id==SensorId::CCD_G4050 ||
2392 dev->model->sensor_id==SensorId::CCD_HP_4850C
2393 || dev->model->sensor_id==SensorId::CCD_CANON_4400F
2394 || dev->model->sensor_id==SensorId::CCD_CANON_8400F
2395 || dev->model->sensor_id==SensorId::CCD_KVSS080)
2407 dummy1 += dev->white_average_data[channels * x];
2409 dummy2 += dev->white_average_data[channels * x + 1];
2410 dummy3 += dev->white_average_data[channels * x + 2];
2424 dev->dark_average_data[channels * x] = dummy1;
2426 dev->dark_average_data[channels * x + 1] = dummy2;
2427 dev->dark_average_data[channels * x + 2] = dummy3;
2432 static void genesys_dark_shading_by_constant(Genesys_Device& dev)
2434 dev.dark_average_data.clear();
2435 dev.dark_average_data.resize(dev.average_size, 0x0101);
2438 static void genesys_repark_sensor_before_shading(Genesys_Device* dev)
2441 if (has_flag(dev->model->flags, ModelFlag::SHADING_REPARK)) {
2442 dev->cmd_set->move_back_home(dev, true);
2444 if (dev->settings.scan_method == ScanMethod::TRANSPARENCY ||
2445 dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED)
2447 scanner_move_to_ta(*dev);
2452 static void genesys_repark_sensor_after_white_shading(Genesys_Device* dev)
2455 if (has_flag(dev->model->flags, ModelFlag::SHADING_REPARK)) {
2456 dev->cmd_set->move_back_home(dev, true);
2460 static void genesys_host_shading_calibration_impl(Genesys_Device& dev, const Genesys_Sensor& sensor,
2467 if (is_dark && dev.settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED) {
2472 auto local_reg = dev.reg;
2473 dev.cmd_set->init_regs_for_shading(&dev, sensor, local_reg);
2475 auto& session = dev.calib_session;
2480 if (is_dark && !dev.model->is_sheetfed) {
2481 sanei_genesys_set_lamp_power(&dev, sensor, local_reg, false);
2483 sanei_genesys_set_lamp_power(&dev, sensor, local_reg, true);
2487 dev.interface->write_registers(local_reg);
2491 dev.interface->sleep_ms(200);
2492 } else if (has_flag(dev.model->flags, ModelFlag::DARK_CALIBRATION)) {
2495 dev.interface->sleep_ms(500);
2499 dev.cmd_set->begin_scan(&dev, sensor, &local_reg, start_motor);
2502 dev.interface->test_checkpoint(is_dark ? "host_dark_shading_calibration"
2504 dev.cmd_set->end_scan(&dev, &local_reg, true);
2508 Image image = read_unshuffled_image_from_scanner(&dev, session, session.output_total_bytes_raw);
2509 scanner_stop_action(dev);
2516 dev.average_size = session.params.channels * out_pixels_per_line;
2519 out_average_data.resize(dev.average_size);
2538 static void genesys_dark_shading_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor,
2542 if (has_flag(dev->model->flags, ModelFlag::HOST_SIDE_CALIBRATION_COMPLETE_SCAN)) {
2543 genesys_host_shading_calibration_impl(*dev, sensor, dev->dark_average_data, true,
2546 genesys_shading_calibration_impl(dev, sensor, local_reg, dev->dark_average_data, true,
2551 static void genesys_white_shading_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor,
2555 if (has_flag(dev->model->flags, ModelFlag::HOST_SIDE_CALIBRATION_COMPLETE_SCAN)) {
2556 genesys_host_shading_calibration_impl(*dev, sensor, dev->white_average_data, false,
2559 genesys_shading_calibration_impl(dev, sensor, local_reg, dev->white_average_data, false,
2566 static void genesys_dark_white_shading_calibration(Genesys_Device* dev,
2572 if (dev->model->asic_type == AsicType::GL646) {
2573 dev->cmd_set->init_regs_for_shading(dev, sensor, local_reg);
2574 local_reg = dev->reg;
2576 local_reg = dev->reg;
2577 dev->cmd_set->init_regs_for_shading(dev, sensor, local_reg);
2578 dev->interface->write_registers(local_reg);
2585 if (dev->model->asic_type == AsicType::GL842 ||
2586 dev->model->asic_type == AsicType::GL843)
2588 pixels_per_line = dev->calib_session.output_pixels;
2590 pixels_per_line = dev->calib_session.params.pixels;
2593 unsigned channels = dev->calib_session.params.channels;
2597 dev->calib_session.params.startx * sensor.full_resolution / dev->calib_session.params.xres;
2601 dev->average_size = channels * out_pixels_per_line;
2603 dev->white_average_data.clear();
2604 dev->white_average_data.resize(dev->average_size);
2606 dev->dark_average_data.clear();
2607 dev->dark_average_data.resize(dev->average_size);
2609 if (dev->model->asic_type == AsicType::GL842 ||
2610 dev->model->asic_type == AsicType::GL843)
2612 size = dev->calib_session.output_total_bytes_raw;
2614 // FIXME: on GL841 this is different than dev->calib_session.output_total_bytes_raw,
2616 size = channels * 2 * pixels_per_line * dev->calib_session.params.lines;
2622 sanei_genesys_set_lamp_power(dev, sensor, local_reg, true);
2625 dev->interface->write_registers(local_reg);
2627 dev->cmd_set->begin_scan(dev, sensor, &local_reg, false);
2630 dev->interface->test_checkpoint("dark_white_shading_calibration");
2631 dev->cmd_set->end_scan(dev, &local_reg, true);
2635 sanei_genesys_read_data_from_scanner(dev, calibration_data.data(), size);
2637 dev->cmd_set->end_scan(dev, &local_reg, true);
2640 if (dev->model->is_cis) {
2643 dev->calib_session.params.lines);
2647 dev->calib_session.params.lines);
2652 std::fill(dev->dark_average_data.begin(),
2653 dev->dark_average_data.begin() + start_offset * channels, 0);
2654 std::fill(dev->white_average_data.begin(),
2655 dev->white_average_data.begin() + start_offset * channels, 0);
2657 std::uint16_t* average_white = dev->white_average_data.data() + start_offset * channels;
2658 std::uint16_t* average_dark = dev->dark_average_data.data() + start_offset * channels;
2665 for (std::size_t y = 0; y < dev->calib_session.params.lines; y++)
2689 for (std::size_t y = 0; y < dev->calib_session.params.lines; y++)
2717 write_tiff_file("gl_white_average.tiff", dev->white_average_data.data(), 16, channels,
2719 write_tiff_file("gl_dark_average.tiff", dev->dark_average_data.data(), 16, channels,
2769 * @param dev scanner's device
2779 static void compute_averaged_planar(Genesys_Device * dev, const Genesys_Sensor& sensor,
2824 res = dev->settings.xres;
2850 if (dev->model->sensor_id != SensorId::CIS_CANON_LIDE_80)
2878 dk += dev->dark_average_data[(x + i + pixels_per_line * j)];
2880 br += dev->white_average_data[(x + i + pixels_per_line * j)];
2950 * @param dev scanner's device
2959 static void compute_coefficients(Genesys_Device * dev,
2997 dk = dev->dark_average_data[x * channels + c];
3000 br = dev->white_average_data[x * channels + c];
3019 * @param dev scanner's device
3031 static void compute_planar_coefficients(Genesys_Device * dev,
3063 dk += dev->dark_average_data[((x+i) + pixels_per_line * c)];
3064 br += dev->white_average_data[((x+i) + pixels_per_line * c)];
3093 static void compute_shifted_coefficients(Genesys_Device * dev,
3112 x = dev->settings.xres;
3142 br_tmp[j] += dev->white_average_data[((x + i) * channels + j)];
3143 dk_tmp[i] += dev->dark_average_data[((x + i) * channels + j)];
3185 static void genesys_send_shading_coefficient(Genesys_Device* dev, const Genesys_Sensor& sensor)
3202 dev->calib_session.params.startx * sensor.full_resolution / dev->calib_session.params.xres;
3204 if (dev->model->asic_type == AsicType::GL842 ||
3205 dev->model->asic_type == AsicType::GL843)
3207 pixels_per_line = dev->calib_session.output_pixels + start_offset;
3209 pixels_per_line = dev->calib_session.params.pixels + start_offset;
3212 unsigned channels = dev->calib_session.params.channels;
3219 switch (dev->reg.get8(0x05) >> 6)
3242 if(dev->model->sensor_id==SensorId::CIS_CANON_LIDE_80)
3253 if (!dev->calib_session.computed) {
3254 genesys_send_offset_and_shading(dev, sensor, shading_data.data(), length);
3263 if (get_registers_gain4_bit(dev->model->asic_type, dev->reg)) {
3270 if (dev->settings.xres > sensor.full_resolution) {
3273 factor = sensor.full_resolution / dev->settings.xres;
3284 switch (dev->model->sensor_id)
3294 compute_planar_coefficients (dev,
3308 compute_planar_coefficients (dev,
3322 if (dev->settings.xres <= sensor.full_resolution / 2) {
3325 compute_coefficients (dev,
3337 if(dev->settings.xres<=sensor.full_resolution/2)
3341 compute_coefficients (dev,
3356 if(dev->settings.xres<=300)
3360 else if(dev->settings.xres<=600)
3368 compute_coefficients (dev,
3392 compute_coefficients (dev,
3411 switch(dev->model->sensor_id)
3427 compute_planar_coefficients (dev,
3441 compute_averaged_planar (dev, sensor,
3452 compute_averaged_planar (dev, sensor,
3463 compute_shifted_coefficients (dev, sensor,
3476 static_cast<unsigned>(dev->model->sensor_id));
3481 genesys_send_offset_and_shading(dev, sensor, shading_data.data(), length);
3488 * @param dev scanner's device
3493 genesys_restore_calibration(Genesys_Device * dev, Genesys_Sensor& sensor)
3498 if (dev->calibration_cache.empty()) {
3502 auto session = dev->cmd_set->calculate_scan_session(dev, sensor, dev->settings);
3506 for (auto& cache : dev->calibration_cache)
3508 if (sanei_genesys_is_compatible_calibration(dev, session, &cache, false)) {
3509 dev->frontend = cache.frontend;
3513 dev->calib_session = cache.session;
3514 dev->average_size = cache.average_size;
3516 dev->dark_average_data = cache.dark_average_data;
3517 dev->white_average_data = cache.white_average_data;
3519 if (!dev->cmd_set->has_send_shading_data()) {
3520 genesys_send_shading_coefficient(dev, sensor);
3532 static void genesys_save_calibration(Genesys_Device* dev, const Genesys_Sensor& sensor)
3539 auto session = dev->cmd_set->calculate_scan_session(dev, sensor, dev->settings);
3541 auto found_cache_it = dev->calibration_cache.end();
3542 for (auto cache_it = dev->calibration_cache.begin(); cache_it != dev->calibration_cache.end();
3545 if (sanei_genesys_is_compatible_calibration(dev, session, &*cache_it, true)) {
3552 if (found_cache_it == dev->calibration_cache.end())
3555 dev->calibration_cache.push_back(Genesys_Calibration_Cache());
3556 found_cache_it = std::prev(dev->calibration_cache.end());
3559 found_cache_it->average_size = dev->average_size;
3561 found_cache_it->dark_average_data = dev->dark_average_data;
3562 found_cache_it->white_average_data = dev->white_average_data;
3565 found_cache_it->frontend = dev->frontend;
3568 found_cache_it->session = dev->calib_session;
3576 static void genesys_flatbed_calibration(Genesys_Device* dev, Genesys_Sensor& sensor)
3582 if (dev->settings.yres <= sensor.full_resolution / 2) {
3586 if (dev->model->model_id == ModelId::CANON_8400F) {
3590 if (dev->model->model_id == ModelId::CANON_4400F ||
3591 dev->model->model_id == ModelId::CANON_8600F)
3596 auto local_reg = dev->initial_regs;
3598 if (!has_flag(dev->model->flags, ModelFlag::DISABLE_ADC_CALIBRATION)) {
3600 dev->interface->record_progress_message("offset_calibration");
3601 dev->cmd_set->offset_calibration(dev, sensor, local_reg);
3603 dev->interface->record_progress_message("coarse_gain_calibration");
3604 dev->cmd_set->coarse_gain_calibration(dev, sensor, local_reg, coarse_res);
3607 if (dev->model->is_cis &&
3608 !has_flag(dev->model->flags, ModelFlag::DISABLE_EXPOSURE_CALIBRATION))
3611 dev->interface->record_progress_message("led_calibration");
3612 switch (dev->model->asic_type) {
3618 auto calib_exposure = dev->cmd_set->led_calibration(dev, sensor, local_reg);
3620 sanei_genesys_find_sensors_all_for_write(dev, sensor.method)) {
3627 sensor.exposure = dev->cmd_set->led_calibration(dev, sensor, local_reg);
3631 if (!has_flag(dev->model->flags, ModelFlag::DISABLE_ADC_CALIBRATION)) {
3633 dev->interface->record_progress_message("offset_calibration");
3634 dev->cmd_set->offset_calibration(dev, sensor, local_reg);
3636 dev->interface->record_progress_message("coarse_gain_calibration");
3637 dev->cmd_set->coarse_gain_calibration(dev, sensor, local_reg, coarse_res);
3642 if (!has_flag(dev->model->flags, ModelFlag::SIS_SENSOR)) {
3643 pixels_per_line = static_cast<std::uint32_t>((dev->model->x_size * dev->settings.xres) /
3646 pixels_per_line = static_cast<std::uint32_t>((dev->model->x_size_calib_mm * dev->settings.xres)
3651 dev->interface->record_progress_message("sanei_genesys_init_shading_data");
3652 sanei_genesys_init_shading_data(dev, sensor, pixels_per_line);
3654 if (dev->settings.scan_method == ScanMethod::TRANSPARENCY ||
3655 dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED)
3657 scanner_move_to_ta(*dev);
3661 if (!has_flag(dev->model->flags, ModelFlag::DISABLE_SHADING_CALIBRATION)) {
3662 if (has_flag(dev->model->flags, ModelFlag::DARK_WHITE_CALIBRATION)) {
3663 dev->interface->record_progress_message("genesys_dark_white_shading_calibration");
3664 genesys_dark_white_shading_calibration(dev, sensor, local_reg);
3669 if (has_flag(dev->model->flags, ModelFlag::DARK_CALIBRATION)) {
3670 dev->interface->record_progress_message("genesys_dark_shading_calibration");
3671 genesys_dark_shading_calibration(dev, sensor, local_reg);
3672 genesys_repark_sensor_before_shading(dev);
3675 dev->interface->record_progress_message("genesys_white_shading_calibration");
3676 genesys_white_shading_calibration(dev, sensor, local_reg);
3678 genesys_repark_sensor_after_white_shading(dev);
3680 if (!has_flag(dev->model->flags, ModelFlag::DARK_CALIBRATION)) {
3681 if (has_flag(dev->model->flags, ModelFlag::USE_CONSTANT_FOR_DARK_CALIBRATION)) {
3682 genesys_dark_shading_by_constant(*dev);
3684 genesys_dark_shading_by_dummy_pixel(dev, sensor);
3690 if (!dev->cmd_set->has_send_shading_data()) {
3691 dev->interface->record_progress_message("genesys_send_shading_coefficient");
3692 genesys_send_shading_coefficient(dev, sensor);
3703 * @param dev device to calibrate
3705 static void genesys_sheetfed_calibration(Genesys_Device* dev, Genesys_Sensor& sensor)
3710 auto local_reg = dev->initial_regs;
3713 dev->cmd_set->load_document(dev);
3721 scanner_search_strip(*dev, forward, false);
3723 catch_all_exceptions(__func__, [&](){ dev->cmd_set->eject_document(dev); });
3727 if (!has_flag(dev->model->flags, ModelFlag::DISABLE_ADC_CALIBRATION)) {
3729 dev->interface->record_progress_message("offset_calibration");
3730 dev->cmd_set->offset_calibration(dev, sensor, local_reg);
3732 dev->interface->record_progress_message("coarse_gain_calibration");
3733 dev->cmd_set->coarse_gain_calibration(dev, sensor, local_reg, coarse_res);
3736 if (dev->model->is_cis &&
3737 !has_flag(dev->model->flags, ModelFlag::DISABLE_EXPOSURE_CALIBRATION))
3740 dev->interface->record_progress_message("led_calibration");
3741 dev->cmd_set->led_calibration(dev, sensor, local_reg);
3743 if (!has_flag(dev->model->flags, ModelFlag::DISABLE_ADC_CALIBRATION)) {
3745 dev->interface->record_progress_message("offset_calibration");
3746 dev->cmd_set->offset_calibration(dev, sensor, local_reg);
3748 dev->interface->record_progress_message("coarse_gain_calibration");
3749 dev->cmd_set->coarse_gain_calibration(dev, sensor, local_reg, coarse_res);
3755 if (has_flag(dev->model->flags, ModelFlag::DARK_CALIBRATION)) {
3758 scanner_search_strip(*dev, forward, true);
3760 catch_all_exceptions(__func__, [&](){ dev->cmd_set->eject_document(dev); });
3765 genesys_dark_shading_calibration(dev, sensor, local_reg);
3767 catch_all_exceptions(__func__, [&](){ dev->cmd_set->eject_document(dev); });
3776 scanner_search_strip(*dev, forward, false);
3778 catch_all_exceptions(__func__, [&](){ dev->cmd_set->eject_document(dev); });
3782 genesys_repark_sensor_before_shading(dev);
3785 genesys_white_shading_calibration(dev, sensor, local_reg);
3786 genesys_repark_sensor_after_white_shading(dev);
3788 catch_all_exceptions(__func__, [&](){ dev->cmd_set->eject_document(dev); });
3794 if (!has_flag(dev->model->flags, ModelFlag::DARK_CALIBRATION)) {
3795 genesys_dark_shading_by_constant(*dev);
3800 if (!dev->cmd_set->has_send_shading_data()) {
3801 genesys_send_shading_coefficient(dev, sensor);
3805 genesys_save_calibration(dev, sensor);
3808 dev->cmd_set->eject_document(dev);
3811 dev->settings.xres = sensor.full_resolution;
3816 * @param dev device to calibrate
3818 static void genesys_scanner_calibration(Genesys_Device* dev, Genesys_Sensor& sensor)
3821 if (!dev->model->is_sheetfed) {
3822 genesys_flatbed_calibration(dev, sensor);
3825 genesys_sheetfed_calibration(dev, sensor);
3837 static void genesys_warmup_lamp(Genesys_Device* dev)
3842 const auto& sensor = sanei_genesys_find_sensor_any(dev);
3844 dev->cmd_set->init_regs_for_warmup(dev, sensor, &dev->reg);
3845 dev->interface->write_registers(dev->reg);
3847 auto total_pixels = dev->session.output_pixels;
3848 auto total_size = dev->session.output_line_bytes;
3849 auto channels = dev->session.params.channels;
3850 auto lines = dev->session.output_line_count;
3858 dev->cmd_set->begin_scan(dev, sensor, &dev->reg, false);
3861 dev->interface->test_checkpoint("warmup_lamp");
3862 dev->cmd_set->end_scan(dev, &dev->reg, true);
3866 wait_until_buffer_non_empty(dev);
3868 sanei_genesys_read_data_from_scanner(dev, second_line.data(), total_size);
3869 dev->cmd_set->end_scan(dev, &dev->reg, true);
3876 if (dev->session.params.depth == 16) {
3890 write_tiff_file("gl_warmup1.tiff", first_line.data(), dev->session.params.depth,
3892 write_tiff_file("gl_warmup2.tiff", second_line.data(), dev->session.params.depth,
3906 dev->interface->sleep_ms(1000);
3921 static void init_regs_for_scan(Genesys_Device& dev, const Genesys_Sensor& sensor,
3925 debug_dump(DBG_info, dev.settings);
3927 auto session = dev.cmd_set->calculate_scan_session(&dev, sensor, dev.settings);
3929 if (dev.model->asic_type == AsicType::GL124 ||
3930 dev.model->asic_type == AsicType::GL845 ||
3931 dev.model->asic_type == AsicType::GL846 ||
3932 dev.model->asic_type == AsicType::GL847)
3941 if (dev.settings.get_channels() * dev.settings.yres >= 600 && session.params.starty > 700) {
3942 scanner_move(dev, dev.model->default_method,
3947 compute_session(&dev, session, sensor);
3950 dev.cmd_set->init_regs_for_scan_session(&dev, sensor, &regs, session);
3954 static void genesys_start_scan(Genesys_Device* dev, bool lamp_off)
3962 if (dev->parking) {
3963 sanei_genesys_wait_for_home(dev);
3967 dev->cmd_set->save_power(dev, false);
3971 if (has_flag(dev->model->flags, ModelFlag::WARMUP) &&
3972 (dev->settings.scan_method != ScanMethod::TRANSPARENCY_INFRARED))
3974 if (dev->settings.scan_method == ScanMethod::TRANSPARENCY ||
3975 dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED)
3977 scanner_move_to_ta(*dev);
3980 genesys_warmup_lamp(dev);
3984 if (!dev->model->is_sheetfed) {
3986 dev->parking = false;
3987 dev->cmd_set->move_back_home(dev, true);
3991 if (dev->settings.scan_method == ScanMethod::TRANSPARENCY ||
3992 dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED)
3994 scanner_move_to_ta(*dev);
3998 if (dev->model->is_sheetfed) {
3999 dev->cmd_set->load_document(dev);
4002 auto& sensor = sanei_genesys_find_sensor_for_write(dev, dev->settings.xres,
4003 dev->settings.get_channels(),
4004 dev->settings.scan_method);
4008 dev->cmd_set->send_gamma_table(dev, sensor);
4011 if (!genesys_restore_calibration (dev, sensor))
4016 has_flag(dev->model->flags, ModelFlag::DISABLE_ADC_CALIBRATION) &&
4017 has_flag(dev->model->flags, ModelFlag::DISABLE_EXPOSURE_CALIBRATION) &&
4018 has_flag(dev->model->flags, ModelFlag::DISABLE_SHADING_CALIBRATION);
4019 if (!shading_disabled && !dev->model->is_sheetfed) {
4020 genesys_scanner_calibration(dev, sensor);
4021 genesys_save_calibration(dev, sensor);
4027 dev->cmd_set->wait_for_motor_stop(dev);
4029 if (dev->cmd_set->needs_home_before_init_regs_for_scan(dev)) {
4030 dev->cmd_set->move_back_home(dev, true);
4033 if (dev->settings.scan_method == ScanMethod::TRANSPARENCY ||
4034 dev->settings.scan_method == ScanMethod::TRANSPARENCY_INFRARED)
4036 scanner_move_to_ta(*dev);
4039 init_regs_for_scan(*dev, sensor, dev->reg);
4043 sanei_genesys_set_lamp_power(dev, sensor, dev->reg, false);
4048 if (dev->cmd_set->has_send_shading_data() &&
4049 !has_flag(dev->model->flags, ModelFlag::DISABLE_SHADING_CALIBRATION))
4051 genesys_send_shading_coefficient(dev, sensor);
4055 dev->interface->write_registers(dev->reg);
4058 dev->cmd_set->begin_scan(dev, sensor, &dev->reg, true);
4061 dev->interface->test_checkpoint("start_scan");
4067 expected = dev->reg.get8(0x3d) * 65536
4068 + dev->reg.get8(0x3e) * 256
4069 + dev->reg.get8(0x3f);
4073 dev->interface->sleep_ms(100);
4074 sanei_genesys_read_feed_steps (dev, &steps);
4078 wait_until_buffer_non_empty(dev);
4082 if (!dev->model->is_sheetfed) {
4084 dev->interface->sleep_ms(100);
4085 sanei_genesys_read_valid_words(dev, &steps);
4096 static void genesys_read_ordered_data(Genesys_Device* dev, SANE_Byte* destination, size_t* len)
4101 if (!dev->read_active) {
4108 dev->total_bytes_to_read, dev->total_bytes_read);
4111 if (dev->total_bytes_read >= dev->total_bytes_to_read)
4115 if (!dev->model->is_sheetfed && !has_flag(dev->model->flags, ModelFlag::MUST_WAIT) &&
4116 !dev->parking)
4118 dev->cmd_set->move_back_home(dev, false);
4119 dev->parking = true;
4125 if (dev->total_bytes_read + *len > dev->total_bytes_to_read) {
4126 *len = dev->total_bytes_to_read - dev->total_bytes_read;
4128 dev->total_bytes_read += *len;
4130 if (dev->model->is_sheetfed) {
4131 dev->cmd_set->detect_document_end(dev);
4134 if (dev->total_bytes_read + *len > dev->total_bytes_to_read) {
4135 *len = dev->total_bytes_to_read - dev->total_bytes_read;
4138 dev->pipeline_buffer.get_data(*len, destination);
4139 dev->total_bytes_read += *len;
4143 if(dev->total_bytes_read >= dev->total_bytes_to_read)
4145 dev->cmd_set->end_scan(dev, &dev->reg, true);
4146 if (dev->model->is_sheetfed) {
4147 dev->cmd_set->eject_document (dev);
4217 const auto* dev = s->dev;
4230 const auto& resolutions = dev->model->get_resolution_settings(settings.scan_method);
4247 const auto& sensor = sanei_genesys_find_sensor(dev, settings.xres, settings.get_channels(),
4250 pixels_per_line = session_adjust_output_pixels(pixels_per_line, *dev, sensor,
4281 static SANE_Parameters calculate_scan_parameters(const Genesys_Device& dev,
4286 auto sensor = sanei_genesys_find_sensor(&dev, settings.xres, settings.get_channels(),
4288 auto session = dev.cmd_set->calculate_scan_session(&dev, sensor, settings);
4289 auto pipeline = build_image_pipeline(dev, session, 0, false);
4311 s->dev->settings = calculate_scan_settings(s);
4312 s->params = calculate_scan_parameters(*s->dev, s->dev->settings);
4338 if (scanner->dev->model->asic_type == AsicType::GL646) {
4339 if (has_flag(scanner->dev->model->flags, ModelFlag::GAMMA_14BIT)) {
4416 for (const auto& dev : *s_devices) {
4417 if (dev.vendorId == currdev->vendorId && dev.productId == currdev->productId) {
4466 auto resolutions = s.dev->model->get_resolutions(s.scan_method);
4483 s.opt_x_range = create_range(s.dev->model->x_size);
4484 s.opt_y_range = create_range(s.dev->model->y_size);
4488 s.opt_x_range = create_range(s.dev->model->x_size_ta);
4489 s.opt_y_range = create_range(s.dev->model->y_size_ta);
4507 const Genesys_Model* model = s->dev->model;
5062 Genesys_Device* dev = &s_devices->back();
5063 dev->file_name = devname;
5064 dev->vendorId = vendor_id;
5065 dev->productId = product_id;
5066 dev->model = &usb_dev.model();
5067 dev->usb_mode = 0; // i.e. unset
5068 dev->already_initialized = false;
5069 return dev;
5082 for (auto& dev : *s_devices) {
5083 if (dev.file_name == devname) {
5085 return &dev;
5117 Genesys_Device* dev = attach_usb_device(devname, vendor_id, product_id, bcd_device);
5120 dev->file_name.c_str());
5122 return dev;
5216 * from file defined in dev->calib_file
5394 Genesys_Device* dev = nullptr;
5403 dev = &d;
5408 if (dev) {
5409 DBG(DBG_info, "%s: found `%s' in devlist\n", __func__, dev->file_name.c_str());
5416 dev = attach_device_by_name(devicename, true);
5422 dev = &s_devices->front();
5423 DBG(DBG_info, "%s: empty devicename, trying `%s'\n", __func__, dev->file_name.c_str());
5427 if (!dev) {
5432 // during testing we need to initialize dev->model before test scanner interface is created
5438 dev->model = &get_matching_usb_dev(vendor_id, product_id, bcd_device).model();
5441 new TestScannerInterface{dev, vendor_id, product_id, bcd_device}};
5443 dev->interface = std::move(interface);
5445 dev->interface->get_usb_device().open(dev->file_name.c_str());
5447 dev->interface = std::unique_ptr<ScannerInterfaceUsb>{new ScannerInterfaceUsb{dev}};
5449 dbg.vstatus("open device '%s'", dev->file_name.c_str());
5450 dev->interface->get_usb_device().open(dev->file_name.c_str());
5453 auto bcd_device = dev->interface->get_usb_device().get_bcd_device();
5455 dev->model = &get_matching_usb_dev(dev->vendorId, dev->productId, bcd_device).model();
5458 dbg.vlog(DBG_info, "Opened device %s", dev->model->name);
5460 if (has_flag(dev->model->flags, ModelFlag::UNTESTED)) {
5472 s->dev = dev;
5474 dev->parking = false;
5475 dev->read_active = false;
5476 dev->force_calibration = 0;
5477 dev->line_count = 0;
5481 if (!dev->already_initialized) {
5482 sanei_genesys_init_structs (dev);
5485 dev->cmd_set = create_cmd_set(dev->model->asic_type);
5493 dev->cmd_set->init(dev);
5496 dev->cmd_set->update_hardware_sensors (s);
5528 auto* dev = it->dev;
5531 if (dev->model->is_sheetfed) {
5532 catch_all_exceptions(__func__, [&](){ dev->cmd_set->eject_document(dev); });
5535 if (dev->parking) {
5536 sanei_genesys_wait_for_home(dev);
5541 dev->cmd_set->save_power(dev, true);
5544 if (dev->force_calibration == 0 && !is_testing_mode()) {
5545 catch_all_exceptions(__func__, [&](){ write_calibration(dev->calibration_cache,
5546 dev->calib_file); });
5549 dev->already_initialized = false;
5550 dev->clear();
5553 dev->interface->write_register(0x03, 0x00);
5555 catch_all_exceptions(__func__, [&](){ dev->interface->get_usb_device().clear_halt(); });
5558 catch_all_exceptions(__func__, [&](){ dev->interface->get_usb_device().reset(); });
5560 // not freeing dev because it's in the dev list
5561 catch_all_exceptions(__func__, [&](){ dev->interface->get_usb_device().close(); });
5628 auto* dev = s->dev;
5635 if (sanei_genesys_has_sensor(dev, dev->settings.xres, dev->settings.get_channels(),
5636 dev->settings.scan_method))
5638 sensor = &sanei_genesys_find_sensor(dev, dev->settings.xres,
5639 dev->settings.get_channels(),
5640 dev->settings.scan_method);
5711 gamma_table = get_gamma_table(dev, *sensor, GENESYS_RED);
5713 gamma_table = get_gamma_table(dev, *sensor, GENESYS_BLUE);
5715 gamma_table = get_gamma_table(dev, *sensor, GENESYS_GREEN);
5730 gamma_table = get_gamma_table(dev, *sensor, GENESYS_RED);
5744 gamma_table = get_gamma_table(dev, *sensor, GENESYS_GREEN);
5758 gamma_table = get_gamma_table(dev, *sensor, GENESYS_BLUE);
5781 s->dev->cmd_set->update_hardware_sensors(s);
5795 auto session = dev->cmd_set->calculate_scan_session(dev, *sensor, dev->settings);
5797 for (auto& cache : dev->calibration_cache) {
5798 if (sanei_genesys_is_compatible_calibration(dev, session, &cache, false)) {
5817 auto dev = s->dev;
5832 dev->calibration_cache = std::move(new_calibration);
5833 dev->calib_file = new_calib_path;
5844 auto* dev = s->dev;
5926 if (dev->model->asic_type != AsicType::GL646 || !dev->model->is_cis) {
5929 create_bpp_list(s, dev->model->bpp_gray_values);
5930 s->bit_depth = dev->model->bpp_gray_values[0];
5933 create_bpp_list(s, dev->model->bpp_color_values);
5934 s->bit_depth = dev->model->bpp_color_values[0];
5966 if (dev->force_calibration == 0) {
5974 dev->cmd_set->set_powersaving(dev, s->lamp_off_time);
6010 for (auto& table : dev->gamma_override_tables) {
6021 dev->gamma_override_tables[GENESYS_RED].resize(option_size);
6022 dev->gamma_override_tables[GENESYS_GREEN].resize(option_size);
6023 dev->gamma_override_tables[GENESYS_BLUE].resize(option_size);
6025 dev->gamma_override_tables[GENESYS_RED][i] = table[i];
6026 dev->gamma_override_tables[GENESYS_GREEN][i] = table[i];
6027 dev->gamma_override_tables[GENESYS_BLUE][i] = table[i];
6034 dev->gamma_override_tables[GENESYS_RED].resize(option_size);
6036 dev->gamma_override_tables[GENESYS_RED][i] = table[i];
6043 dev->gamma_override_tables[GENESYS_GREEN].resize(option_size);
6045 dev->gamma_override_tables[GENESYS_GREEN][i] = table[i];
6052 dev->gamma_override_tables[GENESYS_BLUE].resize(option_size);
6054 dev->gamma_override_tables[GENESYS_BLUE][i] = table[i];
6059 auto& sensor = sanei_genesys_find_sensor_for_write(dev, dev->settings.xres,
6060 dev->settings.get_channels(),
6061 dev->settings.scan_method);
6064 dev->cmd_set->save_power(dev, false);
6065 genesys_scanner_calibration(dev, sensor);
6069 dev->cmd_set->save_power(dev, true);
6075 dev->calibration_cache.clear();
6078 unlink(dev->calib_file.c_str());
6084 dev->force_calibration = 1;
6085 dev->calibration_cache.clear();
6086 dev->calib_file.clear();
6094 dev->ignore_offsets = true;
6177 auto* dev = s->dev;
6180 if (!dev->read_active) {
6191 if (dev->model->is_sheetfed &&
6213 auto* dev = s->dev;
6223 if (dev->force_calibration == 0) {
6224 auto path = calibration_filename(dev);
6226 dev->calib_file = path;
6228 DBG(DBG_info, "%s: >%s<\n", __func__, dev->calib_file.c_str());
6232 sanei_genesys_read_calibration(dev->calibration_cache, dev->calib_file);
6240 genesys_start_scan(dev, s->lamp_off);
6265 auto* dev = s->dev;
6266 if (!dev) {
6267 throw SaneException("dev is nullptr");
6287 dev->total_bytes_to_read, dev->total_bytes_read);
6289 if(dev->total_bytes_read>=dev->total_bytes_to_read)
6295 if (!dev->model->is_sheetfed && !has_flag(dev->model->flags, ModelFlag::MUST_WAIT) &&
6296 !dev->parking)
6298 dev->cmd_set->move_back_home(dev, false);
6299 dev->parking = true;
6306 genesys_read_ordered_data(dev, buf, &local_len);
6329 auto* dev = s->dev;
6332 dev->read_active = false;
6335 if (!dev->parking) {
6336 dev->cmd_set->end_scan(dev, &dev->reg, true);
6340 if (!dev->model->is_sheetfed) {
6341 if (!dev->parking) {
6342 dev->cmd_set->move_back_home(dev, has_flag(dev->model->flags, ModelFlag::MUST_WAIT));
6343 dev->parking = !has_flag(dev->model->flags, ModelFlag::MUST_WAIT);
6347 dev->cmd_set->eject_document(dev);
6351 if (!dev->parking) {
6352 dev->cmd_set->save_power(dev, true);