1 /* sane - Scanner Access Now Easy.
2
3 Copyright (C) 2019 Povilas Kanapickas <povilas@radix.lt>
4
5 This file is part of the SANE package.
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21 #define DEBUG_DECLARE_ONLY
22
23 #include "command_set_common.h"
24 #include "low.h"
25 #include "value_filter.h"
26
27 namespace genesys {
28
29 CommandSetCommon::~CommandSetCommon() = default;
30
is_head_home(Genesys_Device & dev,ScanHeadId scan_head) const31 bool CommandSetCommon::is_head_home(Genesys_Device& dev, ScanHeadId scan_head) const
32 {
33 struct HeadSettings {
34 ModelId model_id;
35 ScanHeadId scan_head;
36 GenesysRegisterSettingSet regs;
37 };
38
39 HeadSettings settings[] = {
40 { ModelId::CANON_8600F,
41 ScanHeadId::PRIMARY, {
42 { 0x6c, 0x20, 0x60 },
43 { 0xa6, 0x00, 0x01 },
44 }
45 },
46 { ModelId::CANON_8600F,
47 ScanHeadId::SECONDARY, {
48 { 0x6c, 0x00, 0x60 },
49 { 0xa6, 0x01, 0x01 },
50 }
51 },
52 };
53
54 for (const auto& setting : settings) {
55 if (setting.model_id == dev.model->model_id &&
56 setting.scan_head == scan_head)
57 {
58 auto reg_backup = apply_reg_settings_to_device_with_backup(dev, setting.regs);
59 auto status = scanner_read_status(dev);
60 apply_reg_settings_to_device(dev, reg_backup);
61 return status.is_at_home;
62 }
63 }
64
65 auto status = scanner_read_status(dev);
66 return status.is_at_home;
67 }
68
set_xpa_lamp_power(Genesys_Device & dev,bool set) const69 void CommandSetCommon::set_xpa_lamp_power(Genesys_Device& dev, bool set) const
70
71 {
72 DBG_HELPER(dbg);
73
74 struct LampSettings {
75 ModelId model_id;
76 ScanMethod scan_method;
77 GenesysRegisterSettingSet regs_on;
78 GenesysRegisterSettingSet regs_off;
79 };
80
81 // FIXME: BUG: we're not clearing the registers to the previous state when returning back when
82 // turning off the lamp
83 LampSettings settings[] = {
84 { ModelId::CANON_4400F, ScanMethod::TRANSPARENCY, {}, {} },
85 { ModelId::CANON_5600F, ScanMethod::TRANSPARENCY, {}, {} },
86 { ModelId::CANON_8400F, ScanMethod::TRANSPARENCY, {
87 { 0xa6, 0x34, 0xf4 },
88 }, {
89 { 0xa6, 0x40, 0x70 },
90 }
91 },
92 { ModelId::CANON_8400F, ScanMethod::TRANSPARENCY_INFRARED, {
93 { 0x6c, 0x40, 0x40 },
94 { 0xa6, 0x01, 0xff },
95 }, {
96 { 0x6c, 0x00, 0x40 },
97 { 0xa6, 0x00, 0xff },
98 }
99 },
100 { ModelId::CANON_8600F, ScanMethod::TRANSPARENCY, {
101 { 0xa6, 0x34, 0xf4 },
102 { 0xa7, 0xe0, 0xe0 },
103 }, {
104 { 0xa6, 0x40, 0x70 },
105 }
106 },
107 { ModelId::CANON_8600F, ScanMethod::TRANSPARENCY_INFRARED, {
108 { 0xa6, 0x00, 0xc0 },
109 { 0xa7, 0xe0, 0xe0 },
110 { 0x6c, 0x80, 0x80 },
111 }, {
112 { 0xa6, 0x00, 0xc0 },
113 { 0x6c, 0x00, 0x80 },
114 }
115 },
116 { ModelId::PLUSTEK_OPTICFILM_7200, ScanMethod::TRANSPARENCY, {}, {} },
117 { ModelId::PLUSTEK_OPTICFILM_7200I, ScanMethod::TRANSPARENCY, {}, {} },
118 { ModelId::PLUSTEK_OPTICFILM_7200I, ScanMethod::TRANSPARENCY_INFRARED, {
119 { 0xa8, 0x07, 0x07 },
120 }, {
121 { 0xa8, 0x00, 0x07 },
122 }
123 },
124 { ModelId::PLUSTEK_OPTICFILM_7300, ScanMethod::TRANSPARENCY, {}, {} },
125 { ModelId::PLUSTEK_OPTICFILM_7400, ScanMethod::TRANSPARENCY, {}, {} },
126 { ModelId::PLUSTEK_OPTICFILM_7500I, ScanMethod::TRANSPARENCY, {}, {} },
127 { ModelId::PLUSTEK_OPTICFILM_7500I, ScanMethod::TRANSPARENCY_INFRARED, {
128 { 0xa8, 0x07, 0x07 },
129 }, {
130 { 0xa8, 0x00, 0x07 },
131 }
132 },
133 { ModelId::PLUSTEK_OPTICFILM_8200I, ScanMethod::TRANSPARENCY, {}, {} },
134 { ModelId::PLUSTEK_OPTICFILM_8200I, ScanMethod::TRANSPARENCY_INFRARED, {
135 { 0xa8, 0x04, 0x04 },
136 }, {
137 { 0xa8, 0x00, 0x04 },
138 }
139 },
140 };
141
142 for (const auto& setting : settings) {
143 if (setting.model_id == dev.model->model_id &&
144 setting.scan_method == dev.settings.scan_method)
145 {
146 apply_reg_settings_to_device(dev, set ? setting.regs_on : setting.regs_off);
147 return;
148 }
149 }
150
151 throw SaneException("Could not find XPA lamp settings");
152 }
153
154
set_motor_mode(Genesys_Device & dev,Genesys_Register_Set & regs,MotorMode mode) const155 void CommandSetCommon::set_motor_mode(Genesys_Device& dev, Genesys_Register_Set& regs,
156 MotorMode mode) const
157 {
158 DBG_HELPER(dbg);
159
160 struct MotorSettings {
161 ModelId model_id;
162 ValueFilterAny<unsigned> resolutions;
163 GenesysRegisterSettingSet regs_primary_and_secondary;
164 GenesysRegisterSettingSet regs_primary;
165 GenesysRegisterSettingSet regs_secondary;
166 };
167
168 MotorSettings settings[] = {
169 { ModelId::CANON_8400F, { 400, 800, 1600, 3200 }, {
170 { 0x6c, 0x00, 0x90 },
171 { 0xa9, 0x04, 0x06 },
172 }, {
173 { 0x6c, 0x90, 0x90 },
174 { 0xa9, 0x02, 0x06 },
175 }, {}
176 },
177 { ModelId::CANON_8600F, { 300, 600, 1200 }, {
178 { 0x6c, 0x00, 0x60 },
179 { 0xa6, 0x01, 0x41 },
180 }, {
181 { 0x6c, 0x20, 0x62 },
182 { 0xa6, 0x00, 0x41 },
183 }, {
184 { 0x6c, 0x40, 0x62 },
185 { 0xa6, 0x01, 0x41 },
186 }
187 },
188 { ModelId::CANON_8600F, { 2400, 4800 }, {
189 { 0x6c, 0x02, 0x62 },
190 { 0xa6, 0x01, 0x41 },
191 }, {
192 { 0x6c, 0x20, 0x62 },
193 { 0xa6, 0x00, 0x41 },
194 }, {
195 { 0x6c, 0x40, 0x62 },
196 { 0xa6, 0x01, 0x41 },
197 }
198 },
199 { ModelId::HP_SCANJET_G4050, VALUE_FILTER_ANY, {
200 { 0x6b, 0x81, 0x81 }, // set MULTFILM and GPOADF
201 { 0x6c, 0x00, 0x40 }, // note that reverse change is not applied on off
202 // 0xa6 register 0x08 bit likely sets motor power. No move at all without that one
203 { 0xa6, 0x08, 0x08 }, // note that reverse change is not applied on off
204 { 0xa8, 0x00, 0x04 },
205 { 0xa9, 0x30, 0x30 },
206 }, {
207 { 0x6b, 0x00, 0x01 }, // BUG: note that only ADF is unset
208 { 0xa8, 0x04, 0x04 },
209 { 0xa9, 0x00, 0x10 }, // note that 0x20 bit is not reset
210 }, {}
211 },
212 { ModelId::PLUSTEK_OPTICFILM_7200, VALUE_FILTER_ANY, {}, {}, {} },
213 { ModelId::PLUSTEK_OPTICFILM_7200I, VALUE_FILTER_ANY, {}, {}, {} },
214 { ModelId::PLUSTEK_OPTICFILM_7300, VALUE_FILTER_ANY, {}, {}, {} },
215 { ModelId::PLUSTEK_OPTICFILM_7400, VALUE_FILTER_ANY, {}, {}, {} },
216 { ModelId::PLUSTEK_OPTICFILM_7500I, VALUE_FILTER_ANY, {}, {}, {} },
217 { ModelId::PLUSTEK_OPTICFILM_8200I, VALUE_FILTER_ANY, {}, {}, {} },
218 };
219
220 for (const auto& setting : settings) {
221 if (setting.model_id == dev.model->model_id &&
222 setting.resolutions.matches(dev.session.output_resolution))
223 {
224 switch (mode) {
225 case MotorMode::PRIMARY: {
226 apply_reg_settings_to_device(dev, setting.regs_primary);
227 break;
228 }
229 case MotorMode::PRIMARY_AND_SECONDARY: {
230 apply_reg_settings_to_device(dev, setting.regs_primary_and_secondary);
231 break;
232 }
233 case MotorMode::SECONDARY: {
234 apply_reg_settings_to_device(dev, setting.regs_secondary);
235 break;
236 }
237 }
238 regs.state.motor_mode = mode;
239 return;
240 }
241 }
242
243 throw SaneException("Motor settings have not been found");
244 }
245
246 } // namespace genesys
247