1 /* sane - Scanner Access Now Easy.
2 Copyright (C) 2007 Ilia Sotnikov <hostcc@gmail.com>
3 HP ScanJet 4570c support by Markham Thomas
4 ADF page detection and high DPI fixes by Bernard Badeer
5 scanbd integration by Damiano Scaramuzza and Bernard Badeer
6 This file is part of the SANE package.
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <https://www.gnu.org/licenses/>.
20
21 As a special exception, the authors of SANE give permission for
22 additional uses of the libraries contained in this release of SANE.
23
24 The exception is that, if you link a SANE library with other files
25 to produce an executable, this does not by itself cause the
26 resulting executable to be covered by the GNU General Public
27 License. Your use of that executable is in no way restricted on
28 account of linking the SANE library code into it.
29
30 This exception does not, however, invalidate any other reasons why
31 the executable file might be covered by the GNU General Public
32 License.
33
34 If you submit changes to SANE to the maintainers to be included in
35 a subsequent release, you agree by submitting the changes that
36 those changes may be distributed with this exception intact.
37
38 If you write modifications of your own for SANE, it is your choice
39 whether to permit this exception to apply to your modifications.
40 If you do not wish that, delete this exception notice.
41
42 This file is part of a SANE backend for
43 HP ScanJet 4500C/4570C/5500C/5550C/5590/7650 Scanners
44 */
45
46 #include "../include/sane/config.h"
47
48 #ifdef HAVE_UNISTD_H
49 # include <unistd.h>
50 #endif /* HAVE_UNISTD_H */
51 #ifdef HAVE_NETINET_IN_H
52 # include <netinet/in.h>
53 #endif /* HAVE_NETINET_IN_H */
54 #include <errno.h>
55 #include <string.h>
56
57 #include "../include/sane/sanei_debug.h"
58 #include "../include/_stdint.h"
59 #include "hp5590_low.h"
60 #include "hp5590_cmds.h"
61
62 static const struct hp5590_model
63 hp5590_models[] = {
64 {
65 SCANNER_HP4570,
66 0x03f0, 0x1305, "SILITEKIElwood",
67 "4570C/5500C", "Workgroup scanner",
68 PF_NONE
69 },
70 {
71 SCANNER_HP5550,
72 0x03f0, 0x1205, "SILITEKIPenguin",
73 "4500C/5550C", "Workgroup scanner",
74 PF_NO_USB_IN_USB_ACK /* These devices need no
75 * acknowledgment after USB-in-USB
76 * commands */
77 },
78 {
79 SCANNER_HP5590,
80 0x03f0, 0x1705, "SILITEKIPenguin",
81 "5590", "Workgroup scanner",
82 PF_NONE
83 },
84 {
85 SCANNER_HP7650,
86 0x03f0, 0x1805, "SILITEKIArnold",
87 "7650", "Document scanner",
88 PF_NONE
89 }
90 };
91
92 /* Debug levels */
93 #define DBG_err 0
94 #define DBG_proc 10
95 #define DBG_verbose 20
96 #define DBG_cmds 40
97
98 #define hp5590_cmds_assert(exp) if(!(exp)) { \
99 DBG (DBG_err, "Assertion '%s' failed at %s:%u\n", #exp, __FILE__, __LINE__);\
100 return SANE_STATUS_INVAL; \
101 }
102
103 #define WAKEUP_TIMEOUT 90
104
105 /* First byte of init (0x12 cmd) response */
106 #define INIT_FLAG_TMA 1 << 0
107 #define INIT_FLAG_ADF 1 << 1
108 #define INIT_FLAG_LCD 1 << 3
109
110 /* Power (0x24 cmd) */
111 #define POWER_FLAG_ON 1 << 1
112
113 /* ADF (0x03 cmd) */
114 #define FLAG_ADF_EMPTY 1 << 1
115
116 #define PART_NUMBER_LEN 10
117
118 #define REVERSE_MAP_LEN 128 * 1024 / sizeof(uint16_t)
119 #define FORWARD_MAP_LEN 128 * 1024 / sizeof(uint16_t)
120
121 /* Button flags */
122 /* From left to right */
123 /* 1: Power
124 * 1: Scan
125 * 2: Collect
126 * 3: File
127 * 4: Email
128 * 5: Copy
129 * 6,7: Up/down
130 * 8: Mode
131 * 9: Cancel
132 */
133 #define BUTTON_FLAG_EMAIL 1 << 15
134 #define BUTTON_FLAG_COPY 1 << 14
135 #define BUTTON_FLAG_DOWN 1 << 13
136 #define BUTTON_FLAG_MODE 1 << 12
137 #define BUTTON_FLAG_UP 1 << 11
138 #define BUTTON_FLAG_FILE 1 << 9
139 #define BUTTON_FLAG_POWER 1 << 5
140 #define BUTTON_FLAG_SCAN 1 << 2
141 #define BUTTON_FLAG_COLLECT 1 << 1
142 #define BUTTON_FLAG_CANCEL 1 << 0
143
144 #define CMD_INIT 0x0012
145 #define CMD_EEPROM_ADDR 0x00f2
146 #define CMD_EEPROM_READ 0x0bf0
147 #define CMD_EEPROM_WRITE 0x0bf1
148 #define CMD_DATA_STATUS 0x0001
149 #define CMD_STOP_SCAN 0x011b
150 #define CMD_CONTROL_LAMP 0x00c0
151 #define CMD_POWER_STATUS 0x0024
152 #define CMD_SELECT_SOURCE 0x00d6
153 #define CMD_MISC_STATUS 0x0003
154 #define CMD_LOCK_UNLOCK 0x0000
155 #define CMD_SET_BASE_DPI 0x0015
156 #define CMD_SET_COLOR_MAP 0x0240
157 #define CMD_SET_SCAN_PARAMS 0x0025
158 #define CMD_GET_IMAGE_PARAMS 0x0034
159 #define CMD_START_SCAN 0x051b
160 #define CMD_BUTTON_STATUS 0x0020
161 #define CMD_LCD_STATUS 0x0021
162
163 struct init_resp
164 {
165 uint8_t flags; /* bit 0 - TMA, bit 1 - ADF, bit 3 - LCD present */
166 uint8_t id[15]; /* SILITEKPenguin */
167 uint8_t pad1[9]; /* 00 00 00 00 00 00 00 00 00 */
168 uint8_t version[5]; /* 0.0.67 */
169 uint16_t max_dpi_x; /* 09 60 = 2400 */
170 uint16_t max_dpi_y; /* 09 60 = 2400 */
171 uint16_t max_pixels_x; /* 4F B0 = 20400 (20400 / 2400 = 8.5") */
172 uint16_t max_pixels_y; /* 6D E0 = 28128 (28128 / 2400 = 11.72") */
173 uint8_t pad2[8]; /* 00 00 00 00 00 00 00 00 */
174 uint16_t motor_param_normal; /* 00 64 = 100 */
175 uint16_t motor_param_max; /* 03 E8 = 1000 */
176 } __attribute__ ((packed));
177
178 struct power_resp
179 {
180 uint8_t flags;
181 uint16_t unk1;
182 } __attribute__ ((packed));
183
184 /*
185 * 215.9 mm x 297.2 mm
186 * 8.5" x 11.72"
187 *
188 * 50 : 425.00 x 586.00
189 * 75 : 637.50 x 879.50
190 * 100 : 850.00 x 1172.00
191 * 150 : 1275.00 x 1758.00 (base DPI)
192 * 200 : 1700.00 x 2344.00
193 * 300 : 2550.00 x 3516.00 (base DPI)
194 * 400 : 3400.00 x 4688.00
195 * 600 : 5100.00 x 7032.00 (base DPI)
196 */
197
198 #define SCAN_PARAMS_SOURCE_TMA_NEGATIVES 1 << 0
199 #define SCAN_PARAMS_SOURCE_TMA_SLIDES 1 << 1
200 #define SCAN_PARAMS_SOURCE_ADF 1 << 2
201 #define SCAN_PARAMS_SOURCE_FLATBED 1 << 3
202 #define SCAN_PARAMS_SOURCE_SIMPLEX 1 << 4
203 #define SCAN_PARAMS_SOURCE_DUPLEX 1 << 6
204
205 struct scan_params
206 {
207 uint8_t source; /*
208 * TMA Negatives : 11 = 17
209 * TMA Slides : 12 = 18
210 * ADF : 14 = 20
211 * Flatbed : 18 = 24
212 * ADF Duplex : 54 = 84
213 */
214
215 uint16_t dpi_x; /*
216 * 50 : 00 64 = 100
217 * 75 : 00 64 = 100
218 * 100 : 00 64 = 100
219 * 150 : 00 c8 = 200
220 * 200 : 00 c8 = 200
221 * 300 : 01 2c = 300
222 * 400 : 02 58 = 600
223 * 600 : 02 58 = 600
224 * 1200 : 04 b0 = 1200
225 */
226
227 uint16_t dpi_y; /*
228 * 50 : 00 64 = 100
229 * 75 : 00 64 = 100
230 * 100 : 00 64 = 100
231 * 150 : 00 c8 = 200
232 * 200 : 00 c8 = 200
233 * 300 : 01 2c = 300
234 * 400 : 02 58 = 600
235 * 600 : 02 58 = 600
236 * 1200 : 04 b0 = 1200
237 */
238
239 uint16_t top_x; /*
240 * pixels * (Base DPI / current DPI)
241 * 00 00, 01 6e = 366 (x = 425 - 302 = 123)
242 * 04 b0 = 1200 (x = 425 - 24 = 401)
243 */
244
245 uint16_t top_y; /*
246 * pixels * (Base DPI / current DPI)
247 * 00 00, 06 99 = 1689 (y = 585 - 21 = 564)
248 */
249
250 uint16_t size_x; /* X pixels in Base DPI (CMD 15)
251 * 50 : 04f8 = 1272 ; 150
252 * 75 : 04f8 = 1272 ; 150
253 * 100 : 04f8 = 1272 ; 150
254 * 100 TMA : 00fc = 252 ; 150
255 * 150 : 09f6 = 2550, 09f0 = 2544, 09f4 = 2548 ; 300
256 * 200 : 09f0 = 2544, 09f6 = 2550, 09f6 = 2550 ; 300
257 * 300 : 09f6 = 2550, 09f0 = 2544, 09f4 = 2548 ; 300
258 * 300 TMA : 01fc = 508 ; 300
259 * 400 : 13ec = 5100 ; 600
260 * 600 : 13e8 = 5096, 13ec = 5100 ,13ec = 5100 ; 600
261 * 1200 : 27a8 = 10152 ; 1200
262 */
263
264 uint16_t size_y; /* Y pixels in Base DPI (CMD 15)
265 * 50 : 06db = 1755 ; 150
266 * 75 : 06da = 1754 ; 150
267 * 100 : 06db = 1755 ; 150
268 * 100 TMA : 0384 = 900 ; 150
269 * 150 : 0db6 = 3510 ; 300
270 * 200 : 0db6 = 3510 ; 300
271 * 300 : 0db6 = 3510 ; 300
272 * 300 TMA : 0708 = 1800 ; 300
273 * 400 : 1b6c = 7020 ; 600
274 * 600 : 1b6c = 7020 ; 600
275 * 1200 : 36d8 = 14040 ; 1200
276 */
277
278 uint16_t unk1; /* 00 80 */
279
280 uint16_t bw_gray_flag; /*
281 * 00 40 - bw (ntsc gray)/gray,
282 * 00 20 - bw (by green band),
283 * 00 10 - bw (by red band),
284 * 00 30 - bw (by blue band),
285 * 00 00 - color
286 */
287
288 uint8_t pixel_bits; /*
289 * bw 50/75/150/400 : 08 = 8
290 * bw 100/200/300/600/1200 : 01 = 1
291 * gray 50/75/100/150/200/400/600 : 08 = 8
292 * color 24 bit 50/75/100/150/200/400/600 : 18 = 24
293 * color 48 bit 100/200 : 30 = 48
294 */
295
296 uint16_t flags; /*
297 * 50/75/100/150/200/300 : e8 40 = 59456
298 * 400/600/1200 : c8 40 = 51264
299 */
300
301 uint16_t motor_param1; /*
302 * 00 64 = 100
303 */
304 uint16_t motor_param2; /*
305 * 00 64 = 100 - ADF, Flatbed, TMA slides
306 * 00 c8 = 200 - TMA Negatives
307 */
308 uint16_t motor_param3; /*
309 * 00 64 = 100 - ADF, Flatbed, TMA slides
310 * 01 90 = 400 - TMA negatives
311 */
312 uint32_t pad1; /* 00 00 00 00 */
313 uint16_t pad2; /* 00 00 */
314 uint8_t mode; /* 00 - normal scan, 04 - preview scan */
315 uint16_t pad3; /* 00 00 */
316
317 uint16_t line_width; /* Based on current .dpi_x
318 * bw 50 : 03 50 = 848
319 * gray 50 : 03 50 = 848
320 * color 50 : 09 f0 = 2544 (3 * gray)
321 *
322 * bw 75 : 03 50 = 848
323 * gray 75 : 03 50 = 848
324 * color 75 : 09 f0 = 2544 (3 * gray)
325 *
326 * bw 100 : 00 6a = 106
327 * gray 100 : 03 50 = 848 (8 * bw)
328 * color 100(24) : 09 f0 = 2544 (3 * gray)
329 * color 100(48) : 13 e0 = 5088 (2 * color 24)
330 * color 100(48) TMA : 03 f0 = 1008
331 *
332 * bw 150 : 06 a4 = 1700
333 * gray 150 : 06 a4 = 1700
334 * color 150 : 13 ec = 5100 (3 * gray)
335 *
336 * bw 200 : 00 d4 = 212
337 * gray 200 : 06 a4 = 1700 (8 * bw)
338 * color 200(24) : 13 ec = 5100 (3 * gray)
339 * color 200(48) : 27 a8 = 10152
340 *
341 * bw 300 : 01 3e = 318
342 * gray 300 : 09 f4 = 2548 (8 * bw)
343 * color 300 : 1d dc = 7644 (3 * gray)
344 * color 300(48) TMA : 0b e8 = 3048
345 *
346 * bw 400 : 13 ec = 5100
347 * gray 400 : 13 ec = 5100
348 * color 400 : 3b c4 = 15300 (3 * gray)
349 *
350 * bw 600 : 02 7d = 637
351 * gray 600 : 13 ec = 5100 (8 * bw)
352 * color 600 : 3b c4 = 15300 (3 * gray)
353 *
354 * bw 1200 : 04 f5 = 1269
355 */
356 } __attribute__ ((packed));
357
358 struct image_params
359 {
360 uint8_t signature; /* c0 */
361 uint8_t pad1; /* 00 */
362 uint32_t image_size; /*
363 * bw 50 : 00 0f 23 a0 = 992 160
364 * gray 50 : 00 0f 23 a0 = 992 160
365 * color 50 : 00 2d 6a e0 = 2 976 480
366 *
367 * bw 75 : 00 0f 20 50 = 991 312
368 * gray 75 : 00 0f 20 50 = 991 312
369 * color 75 : 00 2d 60 f0 = 2 973 936
370 * color 75(48) : 00 5a 86 40 = 5 932 608
371 *
372 * bw 100 : 00 01 e4 74 = 124 020
373 * gray 100 : 00 0f 23 a0 = 992 160
374 * color 100 : 00 2d 6a e0 = 2 976 480
375 * color 100(48) : 00 5a 68 10 = 5 924 880
376 * color 100(48), preview: 00 5a d5 c0 = 5 952 960
377 *
378 * bw 150 : 00 3c b3 10 = 3 978 000
379 * gray 150 : 00 3c b3 10 = 3 978 000
380 * color 150 : 00 b6 19 30 = 11 934 000
381 * color 150(48) : 01 6a 7b a0 = 23 755 680
382 *
383 * bw 200 : 00 07 91 d0 = 496 080
384 * gray 200 : 00 3c b3 10 = 3 978 000
385 * color 200 : 00 b6 19 30 = 11 934 000
386 * color 200(48) : 01 6a f3 a0 = 23 786 400
387 *
388 * bw 300 : 00 11 08 14 = 1 116 180
389 * gray 300 : 00 88 77 78 = 8 943 480
390 * color 300 : 01 99 66 68 = 26 830 440
391 *
392 * bw 400 : 02 22 4b 90 = 35 802 000
393 * gray 400 : 02 22 4b 90 = 35 802 000
394 * color 400 : 06 66 e2 b0 = 107 406 000
395 *
396 * bw 600 : 00 44 3b bc = 4 471 740
397 * gray 600 : 02 22 4b 90 = 35 802 000
398 * color 600 : 06 66 e2 b0 = 107 406 000
399 */
400 uint16_t pad2; /* 00 00 */
401 uint16_t line_width;
402 uint16_t real_size_y;
403 uint32_t pad3; /* 00 00 00 00 */
404 } __attribute__ ((packed));
405
406 struct lamp_state
407 {
408 uint8_t unk1; /* 02 */
409 uint8_t flag; /* 01 on start, 02 - TMA, 03 - all other */
410 uint16_t turnoff_time; /* 0a 0a, 03 36, 0f 36 */
411 } __attribute__ ((packed));
412
413 struct color_map
414 {
415 uint8_t color1[6]; /* 00 00 00 00 01 00 */
416 uint8_t color2[6]; /* 00 00 00 00 01 00 */
417 uint8_t color3[6]; /* 00 00 00 00 01 00 */
418 } __attribute__ ((packed));
419
420 struct reg_03
421 {
422 uint8_t unk1; /* 0x0b - ADF ready, 0x03 - not */
423 uint8_t unk2; /* 0x80 */
424 uint8_t adf_flags; /* 0x01 - ADF ready when selected, 0x02 - not */
425 } __attribute__ ((packed));
426
427 /******************************************************************************/
428 static SANE_Status
hp5590_model_def(enum hp_scanner_types scanner_type, const struct hp5590_model ** model)429 hp5590_model_def (enum hp_scanner_types scanner_type,
430 const struct hp5590_model ** model)
431 {
432 unsigned int i;
433
434 hp5590_cmds_assert (model != NULL);
435
436 for (i = 0; i < sizeof (hp5590_models) / sizeof (struct hp5590_model); i++)
437 {
438 if (hp5590_models[i].scanner_type == scanner_type)
439 {
440 *model = &hp5590_models[i];
441 return SANE_STATUS_GOOD;
442 }
443 }
444
445 return SANE_STATUS_INVAL;
446 }
447
448 /******************************************************************************/
449 static SANE_Status
hp5590_vendor_product_id(enum hp_scanner_types scanner_type, SANE_Word * vendor_id, SANE_Word * product_id)450 hp5590_vendor_product_id (enum hp_scanner_types scanner_type,
451 SANE_Word * vendor_id,
452 SANE_Word * product_id)
453 {
454 const struct hp5590_model *model;
455 SANE_Status ret;
456
457 hp5590_cmds_assert (vendor_id != NULL);
458 hp5590_cmds_assert (product_id != NULL);
459
460 ret = hp5590_model_def (scanner_type, &model);
461 if (ret != SANE_STATUS_GOOD)
462 return ret;
463 *vendor_id = model->usb_vendor_id;
464 *product_id = model->usb_product_id;
465
466 return SANE_STATUS_GOOD;
467 }
468
469 /******************************************************************************/
470 static SANE_Status
hp5590_init_scanner(SANE_Int dn, enum proto_flags proto_flags, struct scanner_info ** info, enum hp_scanner_types scanner_type)471 hp5590_init_scanner (SANE_Int dn,
472 enum proto_flags proto_flags,
473 struct scanner_info ** info,
474 enum hp_scanner_types scanner_type)
475 {
476 struct init_resp init_resp;
477 char id_buf[sizeof (init_resp.id) + 1];
478 char ver_buf[sizeof (init_resp.version) + 1];
479 SANE_Status ret;
480 const struct hp5590_model *scanner_model;
481
482 /*
483 * 0A 53 49 4C 49 54 45 4B 49 50 65 6E 67 75 69 6E .SILITEKIPenguin
484 * 00 00 00 00 00 00 00 00 00 30 2E 30 36 37 09 60 .........0.067..
485 * 09 60 4F B0 6D E0 00 00 00 00 00 00 00 00 00 64 ..O.m..........d
486 * 03 E8 ..
487 */
488 DBG (DBG_proc, "%s\n", __func__);
489
490 hp5590_cmds_assert (sizeof (init_resp) == 50);
491
492 /* Init scanner */
493 ret = hp5590_cmd (dn,
494 proto_flags,
495 CMD_IN | CMD_VERIFY,
496 CMD_INIT,
497 (unsigned char *) &init_resp,
498 sizeof (init_resp), CORE_NONE);
499 if (ret != SANE_STATUS_GOOD)
500 return ret;
501
502 memset (id_buf, 0, sizeof (id_buf));
503 memcpy (id_buf, init_resp.id, sizeof (id_buf) - 1);
504 scanner_model = NULL;
505 if (scanner_type != SCANNER_NONE)
506 {
507 unsigned int i;
508 for (i = 0; i < sizeof (hp5590_models) / sizeof (struct hp5590_model);
509 i++)
510 {
511 if (hp5590_models[i].scanner_type == scanner_type)
512 {
513 if (strcmp (id_buf, hp5590_models[i].vendor_id) != 0)
514 {
515 DBG (DBG_err, "%s: Vendor id mismatch for scanner HP%s - "
516 "required '%s', got '%s'\n",
517 __func__,
518 hp5590_models[i].model,
519 hp5590_models[i].vendor_id, id_buf);
520 return SANE_STATUS_INVAL;
521 }
522 scanner_model = &hp5590_models[i];
523 break;
524 }
525 }
526 hp5590_cmds_assert (scanner_model != NULL);
527 }
528
529 if (scanner_model)
530 {
531 DBG (DBG_cmds, "HP%s flags (0x%02x)\n", scanner_model->model, init_resp.flags);
532
533 DBG (DBG_cmds, "HP%s flags: ADF %s, TMA %s, LCD %s\n",
534 scanner_model->model,
535 init_resp.flags & INIT_FLAG_ADF ? "yes" : "no",
536 init_resp.flags & INIT_FLAG_TMA ? "yes" : "no",
537 init_resp.flags & INIT_FLAG_LCD ? "yes" : "no");
538
539
540 memset (ver_buf, 0, sizeof (ver_buf));
541 memcpy (ver_buf, init_resp.version, sizeof (ver_buf) - 1);
542 DBG (DBG_cmds, "HP%s firmware version: %s\n", scanner_model->model, ver_buf);
543
544 DBG (DBG_cmds, "HP%s max resolution X: %u DPI\n",
545 scanner_model->model, ntohs (init_resp.max_dpi_x));
546 DBG (DBG_cmds, "HP%s max resolution Y: %u DPI\n",
547 scanner_model->model, ntohs (init_resp.max_dpi_y));
548 DBG (DBG_cmds, "HP%s max pixels X: %u\n",
549 scanner_model->model, ntohs (init_resp.max_pixels_x));
550 DBG (DBG_cmds, "HP%s max pixels Y: %u\n",
551 scanner_model->model, ntohs (init_resp.max_pixels_y));
552 DBG (DBG_cmds, "HP%s max size X: %.3f inches\n",
553 scanner_model->model,
554 ntohs (init_resp.max_pixels_x) * 1.0 /
555 ntohs (init_resp.max_dpi_x));
556 DBG (DBG_cmds, "HP%s max size Y: %.3f inches\n", scanner_model->model,
557 ntohs (init_resp.max_pixels_y) * 1.0 /
558 ntohs (init_resp.max_dpi_y));
559 DBG (DBG_cmds, "HP%s normal motor param: %u, max motor param: %u\n",
560 scanner_model->model, ntohs (init_resp.motor_param_normal),
561 ntohs (init_resp.motor_param_max));
562 }
563
564 if (info)
565 {
566 *info = malloc (sizeof (struct scanner_info));
567 if (!*info)
568 {
569 DBG (DBG_err, "Memory allocation failed\n");
570 return SANE_STATUS_NO_MEM;
571 }
572 memset (*info, 0, sizeof (struct scanner_info));
573
574 (*info)->max_dpi_x = ntohs (init_resp.max_dpi_x);
575 (*info)->max_dpi_y = ntohs (init_resp.max_dpi_y);
576 (*info)->max_pixels_x = ntohs (init_resp.max_pixels_x) - 1;
577 (*info)->max_pixels_y = ntohs (init_resp.max_pixels_y) + 1;
578 (*info)->max_size_x = (*info)->max_pixels_x * 1.0 / (*info)->max_dpi_x;
579 (*info)->max_size_y = (*info)->max_pixels_y * 1.0 / (*info)->max_dpi_y;
580 (*info)->features = FEATURE_NONE;
581 if (init_resp.flags & INIT_FLAG_LCD)
582 (*info)->features |= FEATURE_LCD;
583 if (init_resp.flags & INIT_FLAG_ADF)
584 (*info)->features |= FEATURE_ADF;
585 if (init_resp.flags & INIT_FLAG_TMA)
586 (*info)->features |= FEATURE_TMA;
587 if (scanner_model)
588 {
589 (*info)->model = scanner_model->model;
590 (*info)->kind = scanner_model->kind;
591 }
592 }
593
594 ret = hp5590_get_status (dn, proto_flags);
595 if (ret != SANE_STATUS_GOOD)
596 {
597 DBG (DBG_err, "%s: scanner reports non-zero status: %s\n",
598 __func__, sane_strstatus (ret));
599 return ret;
600 }
601 DBG (DBG_cmds, "%s: scanner status OK\n", __func__);
602
603 return SANE_STATUS_GOOD;
604 }
605
606 /******************************************************************************/
607 static SANE_Status
hp5590_read_eeprom(SANE_Int dn, enum proto_flags proto_flags, unsigned int addr, unsigned char *data, unsigned int size)608 hp5590_read_eeprom (SANE_Int dn,
609 enum proto_flags proto_flags,
610 unsigned int addr,
611 unsigned char *data, unsigned int size)
612 {
613 uint8_t eeprom_addr = addr;
614 SANE_Status ret;
615
616 hp5590_cmds_assert (data != NULL);
617 hp5590_cmds_assert (sizeof (eeprom_addr) == 1);
618
619 DBG (DBG_proc, "%s\n", __func__);
620 DBG (DBG_proc, "Reading EEPROM: addr %04x, size %u\n", addr, size);
621
622 ret = hp5590_cmd (dn,
623 proto_flags,
624 CMD_VERIFY,
625 CMD_EEPROM_ADDR,
626 (unsigned char *) &eeprom_addr,
627 sizeof (eeprom_addr), CORE_NONE);
628 if (ret != SANE_STATUS_GOOD)
629 return ret;
630
631 ret = hp5590_cmd (dn,
632 proto_flags,
633 CMD_IN | CMD_VERIFY,
634 CMD_EEPROM_READ, data, size, CORE_NONE);
635 if (ret != SANE_STATUS_GOOD)
636 return ret;
637
638 return SANE_STATUS_GOOD;
639 }
640
641 /******************************************************************************/
642 static SANE_Status
hp5590_write_eeprom(SANE_Int dn, enum proto_flags proto_flags, unsigned int addr, unsigned char *data, unsigned int size)643 hp5590_write_eeprom (SANE_Int dn,
644 enum proto_flags proto_flags,
645 unsigned int addr,
646 unsigned char *data, unsigned int size)
647 {
648 uint8_t eeprom_addr = addr;
649 SANE_Status ret;
650
651 hp5590_cmds_assert (data != NULL);
652 hp5590_cmds_assert (sizeof (eeprom_addr) == 1);
653
654 DBG (DBG_proc, "%s\n", __func__);
655 DBG (DBG_proc, "Writing EEPROM: addr %04x, size: %u\n", addr, size);
656
657 ret = hp5590_cmd (dn,
658 proto_flags,
659 CMD_VERIFY,
660 CMD_EEPROM_ADDR,
661 (unsigned char *) &eeprom_addr,
662 sizeof (eeprom_addr), CORE_NONE);
663 if (ret != SANE_STATUS_GOOD)
664 return ret;
665
666 ret = hp5590_cmd (dn,
667 proto_flags,
668 CMD_VERIFY,
669 CMD_EEPROM_WRITE, data, size, CORE_DATA);
670 if (ret != SANE_STATUS_GOOD)
671 return ret;
672
673 return SANE_STATUS_GOOD;
674 }
675
676 /******************************************************************************/
677 static SANE_Status
hp5590_read_scan_count(SANE_Int dn, enum proto_flags proto_flags, unsigned int *count)678 hp5590_read_scan_count (SANE_Int dn,
679 enum proto_flags proto_flags,
680 unsigned int *count)
681 {
682 uint32_t scan_count;
683 SANE_Status ret;
684
685 hp5590_cmds_assert (count != NULL);
686 hp5590_cmds_assert (sizeof (scan_count) == 4);
687
688 DBG (DBG_proc, "%s\n", __func__);
689 DBG (DBG_proc, "Reading scan count\n");
690
691 ret = hp5590_read_eeprom (dn,
692 proto_flags,
693 0x00,
694 (unsigned char *) &scan_count,
695 sizeof (scan_count));
696
697 if (ret != SANE_STATUS_GOOD)
698 return ret;
699
700 /* Host order */
701 *count = scan_count;
702
703 DBG (DBG_proc, "Scan count %u\n", *count);
704
705 return SANE_STATUS_GOOD;
706 }
707
708 /******************************************************************************/
709 static SANE_Status
hp5590_inc_scan_count(SANE_Int dn, enum proto_flags proto_flags)710 hp5590_inc_scan_count (SANE_Int dn,
711 enum proto_flags proto_flags)
712 {
713 uint32_t scan_count;
714 uint32_t count;
715 uint32_t new_count;
716 SANE_Status ret;
717
718 DBG (DBG_proc, "%s\n", __func__);
719 hp5590_cmds_assert (sizeof (scan_count) == 4);
720
721 ret = hp5590_read_scan_count (dn, proto_flags, &count);
722 if (ret != SANE_STATUS_GOOD)
723 return ret;
724
725 scan_count = ++count;
726 DBG (DBG_verbose, "Scan count = %u\n", scan_count);
727
728 ret = hp5590_write_eeprom (dn,
729 proto_flags,
730 0x00,
731 (unsigned char *) &scan_count,
732 sizeof (scan_count));
733 if (ret != SANE_STATUS_GOOD)
734 return ret;
735
736 /* Verify its setting */
737 ret = hp5590_read_scan_count (dn, proto_flags, &new_count);
738 if (ret != SANE_STATUS_GOOD)
739 return ret;
740
741 if (count != new_count)
742 {
743 DBG (DBG_err, "Scan count wasn't set\n");
744 return SANE_STATUS_IO_ERROR;
745 }
746
747 return SANE_STATUS_GOOD;
748 }
749
750 /******************************************************************************/
751 static SANE_Status
hp5590_read_max_scan_count(SANE_Int dn, enum proto_flags proto_flags, unsigned int *max_count)752 hp5590_read_max_scan_count (SANE_Int dn,
753 enum proto_flags proto_flags,
754 unsigned int *max_count)
755 {
756 uint8_t max_scan_count[3];
757 SANE_Status ret;
758
759 hp5590_cmds_assert (max_count != NULL);
760 hp5590_cmds_assert (sizeof (max_scan_count) == 3);
761
762 DBG (DBG_proc, "%s\n", __func__);
763 DBG (DBG_proc, "Reading max scan count\n");
764
765 ret = hp5590_read_eeprom (dn,
766 proto_flags,
767 0x10,
768 (unsigned char *) max_scan_count,
769 sizeof (max_scan_count));
770 if (ret != SANE_STATUS_GOOD)
771 return ret;
772
773 /* Host order */
774 *max_count = 0;
775 memcpy (max_count, max_scan_count, sizeof (max_scan_count));
776
777 DBG (DBG_proc, "Max scan count %u\n", *max_count);
778
779 return SANE_STATUS_GOOD;
780 }
781
782 /***************************************************************************
783 *
784 * EEPROM contents:
785 *
786 * 0000: 6A 11 00 00 FF FF FF FF FF FF FF FF 09 0E 0F 00 j...............
787 * 0010: 0C 13 0F 00 00 3A 00 FF FF FF 4E 35 39 45 54 52 ..........N59ETR
788 * 0020: 31 52 4D 00 FF FF 00 16 00 0A 00 0D 00 11 00 10 1RM.............
789 * 0030: FF FF FF FF FF FF FF FF FF 00 FF FF FF FF FF FF ................
790 * 0040: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
791 * 0050: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
792 * 0060: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
793 * 0070: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
794 * 0080: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
795 * 0090: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
796 * 00A0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
797 * 00B0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
798 * 00C0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
799 * 00D0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
800 * 00E0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
801 * 00F0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ...............
802 *
803 * Addr 0x00, len: 0x04 - scan count (little-endian)
804 * Addr 0x1A, len: 0x0A - part number (w/o first 'CN' letters)
805 * Addr 0x10, len: 0x03 - max scan count (little-endian) (0C 13 0F)
806 *
807 */
808
809 /******************************************************************************/
810 static __sane_unused__ SANE_Status
hp5590_read_eeprom_all_cmd(SANE_Int dn, enum proto_flags proto_flags)811 hp5590_read_eeprom_all_cmd (SANE_Int dn,
812 enum proto_flags proto_flags)
813 {
814 uint8_t eeprom[255];
815 SANE_Status ret;
816
817 DBG (DBG_proc, "%s\n", __func__);
818
819 ret = hp5590_read_eeprom (dn,
820 proto_flags,
821 0x00,
822 (unsigned char *) eeprom,
823 sizeof (eeprom));
824 if (ret != SANE_STATUS_GOOD)
825 return ret;
826
827 DBG (DBG_verbose, "hp5590_read_eeprom_all_cmd: rc = %d\n", ret);
828 {
829 const int LEN = 4096;
830 char buf[LEN];
831 char* p = buf;
832 for (size_t i = 0; i < sizeof(eeprom); ++i) {
833 if (i % 16 == 0) {
834 int n = sprintf(p, "\n%04x ", (int)i);
835 if (n < 0) {
836 break;
837 }
838 p += n;
839 }
840 int n = sprintf(p, " %02x", eeprom[i]);
841 if (n < 0 ) {
842 break;
843 }
844 p += n;
845 }
846 *p = '\0';
847 DBG (DBG_verbose, "dump:%s\n", buf);
848 }
849
850 return SANE_STATUS_GOOD;
851 }
852
853 /******************************************************************************/
854 static SANE_Status
hp5590_read_part_number(SANE_Int dn, enum proto_flags proto_flags)855 hp5590_read_part_number (SANE_Int dn,
856 enum proto_flags proto_flags)
857 {
858 unsigned int part_number_len = PART_NUMBER_LEN;
859 unsigned char part_number[PART_NUMBER_LEN + 1];
860 SANE_Status ret;
861
862 DBG (DBG_proc, "%s\n", __func__);
863
864 memset (part_number, 0, sizeof (part_number));
865 ret = hp5590_read_eeprom (dn,
866 proto_flags,
867 0x1a,
868 part_number, part_number_len);
869 if (ret != SANE_STATUS_GOOD)
870 return ret;
871
872 DBG (DBG_cmds, "Part number: '%s'\n", part_number);
873
874 return SANE_STATUS_GOOD;
875 }
876
877 /******************************************************************************/
878 static SANE_Status
hp5590_is_data_available(SANE_Int dn, enum proto_flags proto_flags)879 hp5590_is_data_available (SANE_Int dn,
880 enum proto_flags proto_flags)
881 {
882 uint8_t data_status;
883 SANE_Status ret;
884 SANE_Bool data_available;
885
886 DBG (DBG_proc, "%s\n", __func__);
887
888 hp5590_cmds_assert (sizeof (data_status) == 1);
889 data_available = SANE_FALSE;
890
891 ret = hp5590_cmd (dn,
892 proto_flags,
893 CMD_IN | CMD_VERIFY,
894 CMD_DATA_STATUS,
895 (unsigned char *) &data_status,
896 sizeof (data_status), CORE_DATA);
897 if (ret != SANE_STATUS_GOOD)
898 return ret;
899
900 DBG (DBG_cmds, "%s: Data status: %02x\n", __func__, data_status);
901
902 if (data_status == 0x40)
903 data_available = SANE_TRUE;
904
905 DBG (DBG_cmds, "%s: Data is %s\n",
906 __func__,
907 data_available == SANE_TRUE ? "available" : "not available");
908
909 return data_available == SANE_TRUE ? SANE_STATUS_GOOD : SANE_STATUS_NO_DOCS;
910 }
911
912 /******************************************************************************/
913 static SANE_Status
hp5590_stop_scan(SANE_Int dn, enum proto_flags proto_flags)914 hp5590_stop_scan (SANE_Int dn,
915 enum proto_flags proto_flags)
916 {
917 uint8_t reg_011b = 0x40;
918 SANE_Status ret;
919
920 DBG (DBG_proc, "%s\n", __func__);
921
922 hp5590_cmds_assert (sizeof (reg_011b) == 1);
923
924 ret = hp5590_cmd (dn,
925 proto_flags,
926 CMD_VERIFY,
927 CMD_STOP_SCAN,
928 (unsigned char *) ®_011b,
929 sizeof (reg_011b), CORE_NONE);
930 if (ret != SANE_STATUS_GOOD)
931 return ret;
932
933 /* FIXME */
934
935 return SANE_STATUS_GOOD;
936 }
937
938 /******************************************************************************/
939 static SANE_Status
hp5590_turnon_lamp(SANE_Int dn, enum proto_flags proto_flags, enum hp5590_lamp_state state)940 hp5590_turnon_lamp (SANE_Int dn,
941 enum proto_flags proto_flags,
942 enum hp5590_lamp_state state)
943 {
944 struct lamp_state lamp_state;
945 SANE_Status ret;
946
947 DBG (DBG_proc, "%s\n", __func__);
948
949 hp5590_cmds_assert (sizeof (lamp_state) == 4);
950
951 if (state == LAMP_STATE_TURNON)
952 {
953 /* Turn on lamp */
954 lamp_state.unk1 = 0x02;
955 lamp_state.flag = 0x01;
956 lamp_state.turnoff_time = htons (0x0a0a);
957 DBG (DBG_cmds, "%s: turning lamp on\n", __func__);
958 }
959
960 if (state == LAMP_STATE_TURNOFF)
961 {
962 /* Turn off lamp */
963 lamp_state.unk1 = 0x02;
964 lamp_state.flag = 0x02;
965 lamp_state.turnoff_time = htons (0x0a0a);
966 DBG (DBG_cmds, "%s: turning lamp off\n", __func__);
967 }
968
969 if (state == LAMP_STATE_SET_TURNOFF_TIME)
970 {
971 /* Turn on lamp */
972 lamp_state.unk1 = 0x02;
973 lamp_state.flag = 0x03;
974 lamp_state.turnoff_time = htons (0x0336);
975 DBG (DBG_cmds, "%s: setting turnoff time\n", __func__);
976 }
977
978 if (state == LAMP_STATE_SET_TURNOFF_TIME_LONG)
979 {
980 /* Turn on lamp */
981 lamp_state.unk1 = 0x02;
982 lamp_state.flag = 0x03;
983 lamp_state.turnoff_time = htons (0x0f36);
984 DBG (DBG_cmds, "%s: setting long turnoff time\n", __func__);
985 }
986
987 ret = hp5590_cmd (dn,
988 proto_flags,
989 CMD_VERIFY,
990 CMD_CONTROL_LAMP,
991 (unsigned char *) &lamp_state,
992 sizeof (lamp_state), CORE_DATA);
993 if (ret != SANE_STATUS_GOOD)
994 return ret;
995
996 if (state == LAMP_STATE_TURNON)
997 {
998 ret = hp5590_init_scanner (dn, proto_flags, NULL, SCANNER_NONE);
999 if (ret != SANE_STATUS_GOOD)
1000 return ret;
1001 }
1002
1003 return SANE_STATUS_GOOD;
1004 }
1005
1006 /******************************************************************************/
1007 static SANE_Status
hp5590_power_status(SANE_Int dn, enum proto_flags proto_flags)1008 hp5590_power_status (SANE_Int dn,
1009 enum proto_flags proto_flags)
1010 {
1011 struct power_resp power_resp;
1012 SANE_Status ret;
1013
1014 DBG (DBG_proc, "%s\n", __func__);
1015
1016 hp5590_cmds_assert (sizeof (power_resp) == 3);
1017
1018 ret = hp5590_cmd (dn,
1019 proto_flags,
1020 CMD_IN | CMD_VERIFY,
1021 CMD_POWER_STATUS,
1022 (unsigned char *) &power_resp,
1023 sizeof (power_resp), CORE_NONE);
1024 if (ret != SANE_STATUS_GOOD)
1025 return ret;
1026
1027 DBG (DBG_cmds, "Power status: %s (%02x)\n",
1028 power_resp.flags & POWER_FLAG_ON ? "on" : "off", power_resp.flags);
1029
1030 if (!(power_resp.flags & POWER_FLAG_ON))
1031 {
1032 DBG (DBG_cmds, "Turning lamp on\n");
1033 ret = hp5590_turnon_lamp (dn, proto_flags, LAMP_STATE_TURNON);
1034 if (ret != SANE_STATUS_GOOD)
1035 return ret;
1036 }
1037
1038 return SANE_STATUS_GOOD;
1039 }
1040
1041 /******************************************************************************/
1042 static SANE_Status
hp5590_read_error_code(SANE_Int dn, enum proto_flags proto_flags, unsigned int *adf_flags)1043 hp5590_read_error_code (SANE_Int dn,
1044 enum proto_flags proto_flags,
1045 unsigned int *adf_flags)
1046 {
1047 struct reg_03 reg_03;
1048 SANE_Status ret;
1049
1050 DBG (DBG_proc, "%s\n", __func__);
1051
1052 hp5590_cmds_assert (sizeof (reg_03) == 3);
1053 hp5590_cmds_assert (adf_flags != NULL);
1054
1055 memset (®_03, 0, sizeof (reg_03));
1056 *adf_flags = 0;
1057 ret = hp5590_cmd (dn,
1058 proto_flags,
1059 CMD_IN,
1060 CMD_MISC_STATUS,
1061 (unsigned char *) ®_03,
1062 sizeof (reg_03), CORE_NONE);
1063
1064 if (ret != SANE_STATUS_GOOD)
1065 return ret;
1066
1067 DBG (DBG_cmds, "%s: adf_flags: %04x\n", __func__, reg_03.adf_flags);
1068 DBG (DBG_cmds, "%s: unk1 : %04x\n", __func__, reg_03.unk1);
1069 DBG (DBG_cmds, "%s: unk2 : %04x\n", __func__, reg_03.unk2);
1070
1071 *adf_flags = reg_03.adf_flags;
1072
1073 return SANE_STATUS_GOOD;
1074 }
1075
1076 /******************************************************************************/
1077 static SANE_Status
hp5590_reset_scan_head(SANE_Int dn, enum proto_flags proto_flags)1078 hp5590_reset_scan_head (SANE_Int dn,
1079 enum proto_flags proto_flags)
1080 {
1081 SANE_Status ret;
1082
1083 DBG (DBG_proc, "%s\n", __func__);
1084
1085 ret = hp5590_turnon_lamp (dn, proto_flags, LAMP_STATE_TURNOFF);
1086 if (ret != SANE_STATUS_GOOD)
1087 return ret;
1088
1089 usleep (100 * 1000);
1090
1091 ret = hp5590_turnon_lamp (dn, proto_flags, LAMP_STATE_TURNON);
1092 if (ret != SANE_STATUS_GOOD)
1093 return ret;
1094
1095 return SANE_STATUS_GOOD;
1096 }
1097
1098 /******************************************************************************/
1099 static SANE_Status
hp5590_select_source_and_wakeup(SANE_Int dn, enum proto_flags proto_flags, enum scan_sources source, SANE_Bool extend_lamp_timeout)1100 hp5590_select_source_and_wakeup (SANE_Int dn,
1101 enum proto_flags proto_flags,
1102 enum scan_sources source,
1103 SANE_Bool extend_lamp_timeout)
1104 {
1105 uint8_t reg_d6 = 0x04;
1106 SANE_Status ret;
1107 unsigned int adf_flags;
1108
1109 DBG (DBG_proc, "%s\n", __func__);
1110
1111 hp5590_cmds_assert (sizeof (reg_d6) == 1);
1112
1113 if (source == SOURCE_TMA_SLIDES || source == SOURCE_TMA_NEGATIVES)
1114 {
1115 ret = hp5590_turnon_lamp (dn, proto_flags, LAMP_STATE_TURNOFF);
1116 if (ret != SANE_STATUS_GOOD)
1117 return ret;
1118 }
1119 else
1120 {
1121 ret = hp5590_turnon_lamp (dn,
1122 proto_flags,
1123 extend_lamp_timeout == SANE_TRUE ?
1124 LAMP_STATE_SET_TURNOFF_TIME_LONG :
1125 LAMP_STATE_SET_TURNOFF_TIME);
1126 if (ret != SANE_STATUS_GOOD)
1127 return ret;
1128 }
1129
1130 switch (source)
1131 {
1132 case SOURCE_ADF:
1133 case SOURCE_ADF_DUPLEX:
1134 reg_d6 = 0x03;
1135 break;
1136 case SOURCE_FLATBED:
1137 reg_d6 = 0x04;
1138 break;
1139 case SOURCE_TMA_SLIDES:
1140 reg_d6 = 0x02;
1141 break;
1142 case SOURCE_TMA_NEGATIVES:
1143 reg_d6 = 0x01;
1144 break;
1145 case SOURCE_NONE:
1146 DBG (DBG_err, "Scan source not selected\n");
1147 return SANE_STATUS_INVAL;
1148 default:
1149 DBG (DBG_err, "Unknown scan source: %u\n", source);
1150 return SANE_STATUS_INVAL;
1151 }
1152
1153 DBG (DBG_cmds, "Scan source: %u\n", reg_d6);
1154
1155 ret = hp5590_cmd (dn,
1156 proto_flags,
1157 CMD_VERIFY,
1158 CMD_SELECT_SOURCE,
1159 (unsigned char *) ®_d6,
1160 sizeof (reg_d6), CORE_NONE);
1161
1162 if (ret != SANE_STATUS_GOOD && ret != SANE_STATUS_DEVICE_BUSY)
1163 return ret;
1164
1165 ret = hp5590_read_error_code (dn, proto_flags, &adf_flags);
1166 if (ret != SANE_STATUS_GOOD)
1167 return ret;
1168
1169 if (adf_flags & FLAG_ADF_EMPTY)
1170 {
1171 DBG (DBG_cmds, "ADF empty\n");
1172 return SANE_STATUS_NO_DOCS;
1173 }
1174
1175 return SANE_STATUS_GOOD;
1176 }
1177
1178 /******************************************************************************/
1179 static SANE_Status
hp5590_lock_unlock_scanner(SANE_Int dn, enum proto_flags proto_flags)1180 hp5590_lock_unlock_scanner (SANE_Int dn,
1181 enum proto_flags proto_flags)
1182 {
1183 uint8_t reg_00 = 0x01;
1184 SANE_Status ret;
1185 unsigned int adf_flags;
1186 unsigned int waiting;
1187
1188 DBG (DBG_proc, "%s\n", __func__);
1189 hp5590_cmds_assert (sizeof (reg_00) == 1);
1190
1191 for (waiting = 0; waiting < WAKEUP_TIMEOUT; waiting++, sleep (1))
1192 {
1193 ret = hp5590_cmd (dn,
1194 proto_flags,
1195 CMD_VERIFY,
1196 CMD_LOCK_UNLOCK,
1197 (unsigned char *) ®_00,
1198 sizeof (reg_00), CORE_NONE);
1199 if (ret == SANE_STATUS_GOOD)
1200 break;
1201
1202 if (ret != SANE_STATUS_DEVICE_BUSY)
1203 return ret;
1204
1205 DBG (DBG_cmds, "Waiting for scanner...\n");
1206 ret = hp5590_read_error_code (dn, proto_flags, &adf_flags);
1207 if (ret != SANE_STATUS_GOOD)
1208 return ret;
1209
1210 if (adf_flags & FLAG_ADF_EMPTY)
1211 {
1212 DBG (DBG_cmds, "ADF empty\n");
1213 return SANE_STATUS_NO_DOCS;
1214 }
1215 }
1216
1217 if (waiting == WAKEUP_TIMEOUT)
1218 return SANE_STATUS_DEVICE_BUSY;
1219
1220 return SANE_STATUS_GOOD;
1221 }
1222
1223 /******************************************************************************/
1224 static SANE_Status
hp5590_set_base_dpi(SANE_Int dn, enum proto_flags proto_flags, struct scanner_info *scanner_info, unsigned int base_dpi)1225 hp5590_set_base_dpi (SANE_Int dn,
1226 enum proto_flags proto_flags,
1227 struct scanner_info *scanner_info,
1228 unsigned int base_dpi)
1229 {
1230 uint16_t _base_dpi;
1231 SANE_Status ret;
1232
1233 DBG (DBG_proc, "%s\n", __func__);
1234
1235 hp5590_cmds_assert (scanner_info != NULL);
1236 hp5590_cmds_assert (base_dpi != 0);
1237 hp5590_cmds_assert (sizeof (_base_dpi) == 2);
1238
1239 if (base_dpi > scanner_info->max_dpi_x
1240 || base_dpi > scanner_info->max_dpi_y)
1241 {
1242 DBG (DBG_err, "Base DPI too large "
1243 "(given: %u, max X DPI: %u, max Y DPI: %u)\n",
1244 base_dpi,
1245 scanner_info->max_dpi_x,
1246 scanner_info->max_dpi_y);
1247 return SANE_STATUS_INVAL;
1248 }
1249
1250 _base_dpi = htons (base_dpi);
1251
1252 ret = hp5590_cmd (dn,
1253 proto_flags,
1254 CMD_VERIFY,
1255 CMD_SET_BASE_DPI,
1256 (unsigned char *) &_base_dpi,
1257 sizeof (_base_dpi), CORE_DATA);
1258 if (ret != SANE_STATUS_GOOD)
1259 return ret;
1260
1261 return SANE_STATUS_GOOD;
1262 }
1263
1264 /******************************************************************************/
1265 static SANE_Status
hp5590_set_color_map(SANE_Int dn, enum proto_flags proto_flags, unsigned int base_dpi)1266 hp5590_set_color_map (SANE_Int dn,
1267 enum proto_flags proto_flags,
1268 unsigned int base_dpi)
1269 {
1270 struct color_map color_map;
1271 SANE_Status ret;
1272
1273 DBG (DBG_proc, "%s\n", __func__);
1274
1275 hp5590_cmds_assert (sizeof (color_map) == 18);
1276 hp5590_cmds_assert (base_dpi != 0);
1277
1278 memset (&color_map, 0, sizeof (color_map));
1279 if (base_dpi < 2400)
1280 {
1281 color_map.color1[4] = 0x01;
1282 color_map.color2[4] = 0x01;
1283 color_map.color3[4] = 0x01;
1284 }
1285 else
1286 {
1287 if (0) {
1288 /* Does not work with hp5590 and 2400 dpi. */
1289 color_map.color1[2] = 0xff;
1290 color_map.color1[3] = 0x01;
1291 color_map.color1[4] = 0x04;
1292 color_map.color1[5] = 0x02;
1293
1294 color_map.color2[2] = 0xff;
1295 color_map.color2[3] = 0x01;
1296 color_map.color2[4] = 0x04;
1297 color_map.color2[5] = 0x02;
1298
1299 color_map.color3[2] = 0xff;
1300 color_map.color3[3] = 0x01;
1301 color_map.color3[4] = 0x04;
1302 color_map.color3[5] = 0x02;
1303
1304 } else {
1305 /* Needs documentation. */
1306 color_map.color1[2] = 0x00;
1307 color_map.color1[3] = 0x00;
1308 color_map.color1[4] = 0x01;
1309 color_map.color1[5] = 0x00;
1310
1311 color_map.color2[2] = 0x00;
1312 color_map.color2[3] = 0x00;
1313 color_map.color2[4] = 0x01;
1314 color_map.color2[5] = 0x00;
1315
1316 color_map.color3[2] = 0x00;
1317 color_map.color3[3] = 0x00;
1318 color_map.color3[4] = 0x01;
1319 color_map.color3[5] = 0x00;
1320 }
1321 }
1322
1323 ret = hp5590_cmd (dn,
1324 proto_flags,
1325 CMD_VERIFY,
1326 CMD_SET_COLOR_MAP,
1327 (unsigned char *) &color_map,
1328 sizeof (color_map), CORE_DATA);
1329 if (ret != SANE_STATUS_GOOD)
1330 return ret;
1331
1332 return SANE_STATUS_GOOD;
1333 }
1334
1335 /******************************************************************************
1336 * Calculate base DPI
1337 * Base DPI is what image dimensions are calculated on (top X,Y; bottom X,Y)
1338 * Calculated according the following rules:
1339 * Base DPI is 150 when 0 < DPI < 150;
1340 * Base DPI is 300 when 150 <= DPI <= 300;
1341 * Base DPI is 600 when 300 < DPI <= 600;
1342 * Base DPI is 1200 when 600 < DPI;
1343 */
1344 static SANE_Status
calc_base_dpi(unsigned int dpi, unsigned int *base_dpi)1345 calc_base_dpi (unsigned int dpi, unsigned int *base_dpi)
1346 {
1347
1348 DBG (DBG_proc, "%s\n", __func__);
1349
1350 hp5590_cmds_assert (base_dpi != NULL);
1351 hp5590_cmds_assert (dpi != 0);
1352
1353 *base_dpi = 0;
1354
1355 if (dpi < 150)
1356 {
1357 *base_dpi = 150;
1358 return SANE_STATUS_GOOD;
1359 }
1360
1361 if (dpi >= 150 && dpi <= 300)
1362 {
1363 *base_dpi = 300;
1364 return SANE_STATUS_GOOD;
1365 }
1366
1367 if (dpi > 300 && dpi <= 600)
1368 {
1369 *base_dpi = 600;
1370 return SANE_STATUS_GOOD;
1371 }
1372
1373 if (dpi > 600 && dpi <= 1200)
1374 {
1375 *base_dpi = 1200;
1376 return SANE_STATUS_GOOD;
1377 }
1378
1379 if (dpi > 1200 && dpi <= 2400)
1380 {
1381 *base_dpi = 2400;
1382 return SANE_STATUS_GOOD;
1383 }
1384
1385 DBG (DBG_err, "Error calculating base DPI (given DPI: %u)\n", dpi);
1386 return SANE_STATUS_INVAL;
1387 }
1388
1389 /******************************************************************************/
1390 static SANE_Status
calc_scanner_dpi(unsigned int dpi, unsigned int *scanner_dpi)1391 calc_scanner_dpi (unsigned int dpi, unsigned int *scanner_dpi)
1392 {
1393 DBG (DBG_proc, "%s\n", __func__);
1394
1395 hp5590_cmds_assert (scanner_dpi != NULL);
1396 hp5590_cmds_assert (dpi != 0);
1397
1398 if (dpi <= 100)
1399 {
1400 *scanner_dpi = 100;
1401 return SANE_STATUS_GOOD;
1402 }
1403
1404 if (dpi > 100 && dpi <= 200)
1405 {
1406 *scanner_dpi = 200;
1407 return SANE_STATUS_GOOD;
1408 }
1409
1410 if (dpi == 300)
1411 {
1412 *scanner_dpi = 300;
1413 return SANE_STATUS_GOOD;
1414 }
1415
1416 if (dpi > 300 && dpi <= 600)
1417 {
1418 *scanner_dpi = 600;
1419 return SANE_STATUS_GOOD;
1420 }
1421
1422 if (dpi > 600 && dpi <= 1200)
1423 {
1424 *scanner_dpi = 1200;
1425 return SANE_STATUS_GOOD;
1426 }
1427
1428 if (dpi > 1200 && dpi <= 2400)
1429 {
1430 *scanner_dpi = 2400;
1431 return SANE_STATUS_GOOD;
1432 }
1433
1434 DBG (DBG_err, "Error calculating scanner DPI (given DPI: %u)\n", dpi);
1435 return SANE_STATUS_INVAL;
1436 }
1437
1438 /******************************************************************************/
1439 static SANE_Status
hp5590_calc_pixel_bits(unsigned int dpi, enum color_depths color_depth, unsigned int *pixel_bits)1440 hp5590_calc_pixel_bits (unsigned int dpi, enum color_depths color_depth,
1441 unsigned int *pixel_bits)
1442 {
1443 unsigned int scanner_dpi;
1444 SANE_Status ret;
1445
1446 DBG (DBG_proc, "%s\n", __func__);
1447
1448 hp5590_cmds_assert (pixel_bits != NULL);
1449 hp5590_cmds_assert (dpi != 0);
1450
1451 ret = calc_scanner_dpi (dpi, &scanner_dpi);
1452 if (ret != SANE_STATUS_GOOD)
1453 return ret;
1454
1455 if (color_depth == DEPTH_COLOR_48)
1456 {
1457 *pixel_bits = 48;
1458 return SANE_STATUS_GOOD;
1459 }
1460
1461 if (color_depth == DEPTH_COLOR_24)
1462 {
1463 *pixel_bits = 24;
1464 return SANE_STATUS_GOOD;
1465 }
1466
1467 if (color_depth == DEPTH_GRAY)
1468 {
1469 *pixel_bits = 8;
1470 return SANE_STATUS_GOOD;
1471 }
1472
1473 if (color_depth == DEPTH_BW)
1474 {
1475 if (dpi == scanner_dpi)
1476 *pixel_bits = 1;
1477 else
1478 *pixel_bits = 8;
1479 return SANE_STATUS_GOOD;
1480 }
1481
1482 DBG (DBG_err, "Error calculating pixel bits (given DPI: %u)\n", dpi);
1483 return SANE_STATUS_INVAL;
1484 }
1485
1486 /******************************************************************************/
1487 static SANE_Status
hp5590_set_scan_area(SANE_Int dn, enum proto_flags proto_flags, struct scanner_info *scanner_info, unsigned int top_x, unsigned int top_y, unsigned int width, unsigned int height, unsigned int dpi, enum color_depths color_depth, enum scan_modes scan_mode, enum scan_sources scan_source)1488 hp5590_set_scan_area (SANE_Int dn,
1489 enum proto_flags proto_flags,
1490 struct scanner_info *scanner_info,
1491 unsigned int top_x, unsigned int top_y,
1492 unsigned int width, unsigned int height,
1493 unsigned int dpi, enum color_depths color_depth,
1494 enum scan_modes scan_mode,
1495 enum scan_sources scan_source)
1496 {
1497 struct scan_params scan_params;
1498 unsigned int scanner_top_x;
1499 unsigned int scanner_top_y;
1500 unsigned int scanner_pixels_x;
1501 unsigned int scanner_pixels_y;
1502 unsigned int base_dpi;
1503 unsigned int scanner_dpi;
1504 unsigned int pixel_bits;
1505 unsigned int scanner_line_width;
1506 unsigned int max_pixels_x_current_dpi;
1507 unsigned int max_pixels_y_current_dpi;
1508 unsigned int pixels_x;
1509 unsigned int pixels_y;
1510 SANE_Status ret;
1511
1512 DBG (DBG_proc, "%s\n", __func__);
1513
1514 hp5590_cmds_assert (sizeof (scan_params) == 37);
1515 hp5590_cmds_assert (dpi != 0);
1516 hp5590_cmds_assert (scanner_info != NULL);
1517
1518 memset (&scan_params, 0, sizeof (scan_params));
1519
1520 scan_params.source = SCAN_PARAMS_SOURCE_SIMPLEX;
1521 if (scan_source == SOURCE_ADF)
1522 scan_params.source |= SCAN_PARAMS_SOURCE_ADF;
1523 if (scan_source == SOURCE_ADF_DUPLEX)
1524 scan_params.source |= SCAN_PARAMS_SOURCE_ADF | SCAN_PARAMS_SOURCE_DUPLEX;
1525 if (scan_source == SOURCE_FLATBED)
1526 scan_params.source |= SCAN_PARAMS_SOURCE_FLATBED;
1527 if (scan_source == SOURCE_TMA_SLIDES)
1528 scan_params.source |= SCAN_PARAMS_SOURCE_TMA_SLIDES;
1529 if (scan_source == SOURCE_TMA_NEGATIVES)
1530 scan_params.source |= SCAN_PARAMS_SOURCE_TMA_NEGATIVES;
1531
1532 DBG (DBG_cmds, "Scan params. source : 0x%04x\n", scan_params.source);
1533
1534 DBG (DBG_cmds, "DPI: %u\n", dpi);
1535 if (dpi > scanner_info->max_dpi_x || dpi > scanner_info->max_dpi_y)
1536 {
1537 DBG (DBG_err, "DPI too large "
1538 "(given: %u, max X DPI: %u, max Y DPI: %u)\n",
1539 dpi, scanner_info->max_dpi_x, scanner_info->max_dpi_y);
1540 return SANE_STATUS_INVAL;
1541 }
1542
1543 ret = calc_base_dpi (dpi, &base_dpi);
1544 if (ret != SANE_STATUS_GOOD)
1545 return ret;
1546 DBG (DBG_cmds, "Base DPI: %u\n", base_dpi);
1547
1548 ret = calc_scanner_dpi (dpi, &scanner_dpi);
1549 if (ret != SANE_STATUS_GOOD)
1550 return ret;
1551 DBG (DBG_cmds, "Scanner DPI: %u\n", scanner_dpi);
1552
1553 scan_params.dpi_x = htons (scanner_dpi);
1554 scan_params.dpi_y = htons (scanner_dpi);
1555
1556 DBG (DBG_cmds, "DPI X: 0x%04x\n", scanner_dpi);
1557 DBG (DBG_cmds, "DPI Y: 0x%04x\n", scanner_dpi);
1558
1559 ret = hp5590_calc_pixel_bits (dpi, color_depth, &pixel_bits);
1560 if (ret != SANE_STATUS_GOOD)
1561 return ret;
1562
1563 DBG (DBG_cmds, "Pixel bits: %u\n", pixel_bits);
1564
1565 scan_params.pixel_bits = pixel_bits;
1566
1567 scan_params.bw_gray_flag = 0;
1568 if (color_depth == DEPTH_BW || color_depth == DEPTH_GRAY)
1569 scan_params.bw_gray_flag = htons (0x40);
1570
1571 scan_params.flags = htons (0xe840);
1572 if (dpi > 300 && dpi <= 1200)
1573 scan_params.flags = htons (0xc840);
1574 if (dpi > 1200)
1575 scan_params.flags = htons (0xc040);
1576
1577 scan_params.motor_param1 = htons (100);
1578 scan_params.motor_param2 = htons (100);
1579 scan_params.motor_param3 = htons (100);
1580 if (scan_source == SOURCE_TMA_NEGATIVES)
1581 {
1582 scan_params.motor_param2 = htons (200);
1583 scan_params.motor_param3 = htons (400);
1584 }
1585
1586 scan_params.unk1 = htons (0x80);
1587
1588 scan_params.mode = 0;
1589 if (scan_mode == MODE_PREVIEW)
1590 scan_params.mode = 0x04;
1591
1592 max_pixels_x_current_dpi = (float) scanner_info->max_size_x * dpi;
1593 max_pixels_y_current_dpi = (float) scanner_info->max_size_y * dpi;
1594 if ( scan_source == SOURCE_TMA_NEGATIVES
1595 || scan_source == SOURCE_TMA_SLIDES)
1596 {
1597 max_pixels_x_current_dpi = (float) (TMA_MAX_X_INCHES * dpi);
1598 max_pixels_y_current_dpi = (float) (TMA_MAX_Y_INCHES * dpi);
1599 }
1600 /* In ADF mode the device can scan up to ADF_MAX_Y_INCHES, which is usually
1601 * bigger than what scanner reports back during initialization
1602 */
1603 if ( scan_source == SOURCE_ADF )
1604 max_pixels_y_current_dpi = (float) (ADF_MAX_Y_INCHES * dpi);
1605
1606 /* Allow two times of max pixels for ADF Duplex mode */
1607 if (scan_source == SOURCE_ADF_DUPLEX)
1608 max_pixels_y_current_dpi *= 2;
1609
1610 pixels_x = width;
1611 pixels_y = height;
1612
1613 scanner_top_x = (float) (top_x * (1.0 * base_dpi / dpi));
1614 scanner_top_y = (float) (top_y * (1.0 * base_dpi / dpi));
1615 scanner_pixels_x = (float) (pixels_x * (1.0 * base_dpi / dpi));
1616 scanner_pixels_y = (float) (pixels_y * (1.0 * base_dpi / dpi));
1617
1618 DBG (DBG_cmds, "Top X: %u, top Y: %u, size X: %u, size Y: %u\n",
1619 top_x, top_y, pixels_x, pixels_y);
1620 DBG (DBG_cmds, "Scanner top X: %u, top Y: %u, size X: %u, size Y: %u\n",
1621 scanner_top_x, scanner_top_y,
1622 scanner_pixels_x, scanner_pixels_y);
1623
1624 if (top_x + pixels_x > max_pixels_x_current_dpi)
1625 {
1626 DBG (DBG_err, "Top X (%u) + pixels X (%u) exceeds max X %u\n",
1627 top_x, pixels_x, max_pixels_x_current_dpi);
1628 return SANE_STATUS_INVAL;
1629 }
1630
1631 if (top_y + pixels_y > max_pixels_y_current_dpi)
1632 {
1633 DBG (DBG_err, "Top Y (%u) + pixels Y (%u) exceeds max Y %u\n",
1634 top_y, pixels_y, max_pixels_y_current_dpi);
1635 return SANE_STATUS_INVAL;
1636 }
1637
1638 scan_params.top_x = htons (scanner_top_x);
1639 scan_params.top_y = htons (scanner_top_y);
1640 scan_params.size_x = htons (scanner_pixels_x);
1641 scan_params.size_y = htons (scanner_pixels_y);
1642
1643 scanner_line_width = (float) (pixels_x
1644 * (1.0 * scanner_dpi / dpi) / 8 * pixel_bits);
1645
1646 /* Scanner hangs at scan command if line width less than 18 */
1647 if (scanner_line_width < 18)
1648 {
1649 DBG (DBG_err, "Line width too small, extending to minimum\n");
1650 scanner_line_width = 18;
1651 }
1652 scan_params.line_width = htons (scanner_line_width);
1653 DBG (DBG_cmds, "Line width: %u\n", scanner_line_width);
1654
1655 ret = hp5590_cmd (dn,
1656 proto_flags,
1657 CMD_VERIFY,
1658 CMD_SET_SCAN_PARAMS,
1659 (unsigned char *) &scan_params,
1660 sizeof (scan_params), CORE_DATA);
1661 if (ret != SANE_STATUS_GOOD)
1662 return ret;
1663
1664 return SANE_STATUS_GOOD;
1665 }
1666
1667 /******************************************************************************/
1668 static SANE_Status
hp5590_read_image_params(SANE_Int dn, enum proto_flags proto_flags)1669 hp5590_read_image_params (SANE_Int dn,
1670 enum proto_flags proto_flags)
1671 {
1672 struct image_params image_params;
1673 SANE_Status ret;
1674
1675 DBG (DBG_proc, "%s\n", __func__);
1676
1677 hp5590_cmds_assert (sizeof (image_params) == 16);
1678
1679 memset (&image_params, 0, sizeof (image_params));
1680
1681 ret = hp5590_cmd (dn,
1682 proto_flags,
1683 CMD_IN | CMD_VERIFY,
1684 CMD_GET_IMAGE_PARAMS,
1685 (unsigned char *) &image_params,
1686 sizeof (image_params), CORE_NONE);
1687 if (ret != SANE_STATUS_GOOD)
1688 return ret;
1689
1690 if (image_params.signature != 0xc0)
1691 {
1692 DBG (DBG_err, "Wrong signature for image parameters structure "
1693 "received (needed 0xc0, got %02x)\n", image_params.signature);
1694 return SANE_STATUS_IO_ERROR;
1695 }
1696 DBG (DBG_cmds, "Received image params:\n");
1697 DBG (DBG_cmds, "Signature %02x\n", image_params.signature);
1698 DBG (DBG_cmds, "Image size %lu (%04lx)\n",
1699 (unsigned long) ntohl (image_params.image_size),
1700 (unsigned long) ntohl (image_params.image_size));
1701 DBG (DBG_cmds, "Line width: %u (%02x)\n", ntohs (image_params.line_width),
1702 ntohs (image_params.line_width));
1703 DBG (DBG_cmds, "Actual size Y: %u (%02x)\n",
1704 ntohs (image_params.real_size_y), ntohs (image_params.real_size_y));
1705
1706 return SANE_STATUS_GOOD;
1707 }
1708
1709 /******************************************************************************/
1710 static SANE_Status
hp5590_set_scan_params(SANE_Int dn, enum proto_flags proto_flags, struct scanner_info * scanner_info, unsigned int top_x, unsigned int top_y, unsigned int width, unsigned int height, unsigned int dpi, enum color_depths color_depth, enum scan_modes scan_mode, enum scan_sources scan_source)1711 hp5590_set_scan_params (SANE_Int dn,
1712 enum proto_flags proto_flags,
1713 struct scanner_info * scanner_info,
1714 unsigned int top_x, unsigned int top_y,
1715 unsigned int width, unsigned int height,
1716 unsigned int dpi, enum color_depths color_depth,
1717 enum scan_modes scan_mode,
1718 enum scan_sources scan_source)
1719 {
1720 unsigned int base_dpi;
1721 SANE_Status ret;
1722
1723 DBG (DBG_proc, "%s\n", __func__);
1724
1725 hp5590_cmds_assert (scanner_info != NULL);
1726 hp5590_cmds_assert (dpi != 0);
1727
1728 /* Lock scanner */
1729 ret = hp5590_lock_unlock_scanner (dn, proto_flags);
1730 if (ret != SANE_STATUS_GOOD)
1731 return ret;
1732
1733 /* Set base DPI */
1734 ret = calc_base_dpi (dpi, &base_dpi);
1735 if (ret != SANE_STATUS_GOOD)
1736 {
1737 /* Unlock scanner */
1738 hp5590_lock_unlock_scanner (dn, proto_flags);
1739 return ret;
1740 }
1741
1742 DBG (DBG_cmds, "Set base DPI: %u\n", base_dpi);
1743 ret = hp5590_set_base_dpi (dn, proto_flags, scanner_info, base_dpi);
1744 if (ret != SANE_STATUS_GOOD)
1745 {
1746 /* Unlock scanner */
1747 hp5590_lock_unlock_scanner (dn, proto_flags);
1748 return ret;
1749 }
1750
1751 /* Set color map */
1752 ret = hp5590_set_color_map (dn, proto_flags, base_dpi);
1753 if (ret != SANE_STATUS_GOOD)
1754 {
1755 /* Unlock scanner */
1756 hp5590_lock_unlock_scanner (dn, proto_flags);
1757 return ret;
1758 }
1759
1760 ret = hp5590_set_scan_area (dn,
1761 proto_flags,
1762 scanner_info,
1763 top_x, top_y,
1764 width, height,
1765 dpi, color_depth, scan_mode, scan_source);
1766 if (ret != SANE_STATUS_GOOD)
1767 {
1768 /* Unlock scanner */
1769 hp5590_lock_unlock_scanner (dn, proto_flags);
1770 return ret;
1771 }
1772
1773 ret = hp5590_read_image_params (dn, proto_flags);
1774 if (ret != SANE_STATUS_GOOD)
1775 {
1776 /* Unlock scanner */
1777 hp5590_lock_unlock_scanner (dn, proto_flags);
1778 return ret;
1779 }
1780
1781 /* Unlock scanner */
1782 ret = hp5590_lock_unlock_scanner (dn, proto_flags);
1783 if (ret != SANE_STATUS_GOOD)
1784 return ret;
1785
1786 return SANE_STATUS_GOOD;
1787 }
1788
1789 /******************************************************************************/
1790 static SANE_Status
hp5590_send_reverse_calibration_map(SANE_Int dn, enum proto_flags proto_flags)1791 hp5590_send_reverse_calibration_map (SANE_Int dn,
1792 enum proto_flags proto_flags)
1793 {
1794 unsigned int reverse_map_size = REVERSE_MAP_LEN;
1795 uint16_t reverse_map[REVERSE_MAP_LEN];
1796 unsigned int i;
1797 uint16_t val;
1798 unsigned int len;
1799 SANE_Status ret;
1800
1801 DBG (DBG_proc, "%s\n", __func__);
1802 DBG (DBG_proc, "Preparing reverse calibration map\n");
1803 val = 0xffff;
1804 len = reverse_map_size / 4;
1805 for (i = 0; i < len; i++)
1806 {
1807 reverse_map[i] = htons (val);
1808 val -= 1;
1809 }
1810
1811 for (i = len; i < len * 2; i++)
1812 {
1813 reverse_map[i] = htons (val);
1814 val -= 1;
1815 }
1816
1817 for (i = len * 2; i < len * 3; i++)
1818 {
1819 reverse_map[i] = htons (val);
1820 val -= 1;
1821 }
1822
1823 for (i = len * 3; i < len * 4; i++)
1824 {
1825 if (1) {
1826 reverse_map[i] = htons (0xffff);
1827 } else {
1828 reverse_map[i] = htons (val);
1829 val -= 1;
1830 }
1831 }
1832
1833 DBG (DBG_proc, "Done preparing reverse calibration map. n=%u, bytes_per_entry=%zu\n", reverse_map_size, sizeof(uint16_t));
1834
1835 ret = hp5590_bulk_write (dn,
1836 proto_flags,
1837 0x2b,
1838 (unsigned char *) reverse_map,
1839 reverse_map_size * sizeof (uint16_t));
1840 if (ret != SANE_STATUS_GOOD)
1841 return ret;
1842
1843 return SANE_STATUS_GOOD;
1844 }
1845
1846 /******************************************************************************/
1847 static SANE_Status
hp5590_send_forward_calibration_maps(SANE_Int dn, enum proto_flags proto_flags)1848 hp5590_send_forward_calibration_maps (SANE_Int dn,
1849 enum proto_flags proto_flags)
1850 {
1851 unsigned int forward_map_size = FORWARD_MAP_LEN;
1852 uint16_t forward_map[FORWARD_MAP_LEN];
1853 SANE_Status ret;
1854 unsigned int i;
1855 uint16_t val;
1856
1857 DBG (DBG_proc, "%s\n", __func__);
1858 DBG (DBG_proc, "Preparing forward calibration map\n");
1859 val = 0x0000;
1860 for (i = 0; i < forward_map_size; i++)
1861 {
1862 forward_map[i] = htons (val);
1863 if (val < 0xffff)
1864 val += 1;
1865 }
1866 DBG (DBG_proc, "Done preparing forward calibration map. n=%u, bytes_per_entry=%zu\n", forward_map_size, sizeof(uint16_t));
1867
1868 ret = hp5590_bulk_write (dn,
1869 proto_flags,
1870 0x012a,
1871 (unsigned char *) forward_map,
1872 forward_map_size * sizeof (uint16_t));
1873 if (ret != SANE_STATUS_GOOD)
1874 return ret;
1875
1876 ret = hp5590_bulk_write (dn,
1877 proto_flags,
1878 0x022a,
1879 (unsigned char *) forward_map,
1880 forward_map_size * sizeof (uint16_t));
1881 if (ret != SANE_STATUS_GOOD)
1882 return ret;
1883
1884 ret = hp5590_bulk_write (dn,
1885 proto_flags,
1886 0x032a,
1887 (unsigned char *) forward_map,
1888 forward_map_size * sizeof (uint16_t));
1889 if (ret != SANE_STATUS_GOOD)
1890 return ret;
1891
1892 return SANE_STATUS_GOOD;
1893 }
1894
1895 /******************************************************************************/
1896 static SANE_Status
hp5590_read(SANE_Int dn, enum proto_flags proto_flags, unsigned char *bytes, unsigned int size, void *state)1897 hp5590_read (SANE_Int dn,
1898 enum proto_flags proto_flags,
1899 unsigned char *bytes, unsigned int size,
1900 void *state)
1901 {
1902 SANE_Status ret;
1903
1904 DBG (DBG_proc, "%s\n", __func__);
1905
1906 hp5590_cmds_assert (bytes != NULL);
1907 hp5590_cmds_assert (state != NULL);
1908
1909 ret = hp5590_bulk_read (dn, proto_flags, bytes, size, state);
1910 if (ret != SANE_STATUS_GOOD)
1911 return ret;
1912
1913 return SANE_STATUS_GOOD;
1914 }
1915
1916 /******************************************************************************/
1917 static SANE_Status
hp5590_start_scan(SANE_Int dn, enum proto_flags proto_flags)1918 hp5590_start_scan (SANE_Int dn,
1919 enum proto_flags proto_flags)
1920 {
1921 uint8_t reg_051b = 0x40;
1922 SANE_Status ret;
1923
1924 DBG (DBG_proc, "%s\n", __func__);
1925
1926 hp5590_cmds_assert (sizeof (reg_051b) == 1);
1927
1928 ret = hp5590_cmd (dn,
1929 proto_flags,
1930 CMD_VERIFY,
1931 CMD_START_SCAN,
1932 (unsigned char *) ®_051b,
1933 sizeof (reg_051b), CORE_NONE);
1934 if (ret != SANE_STATUS_GOOD)
1935 return ret;
1936
1937 return SANE_STATUS_GOOD;
1938 }
1939
1940 /******************************************************************************/
1941 static SANE_Status
hp5590_read_buttons(SANE_Int dn, enum proto_flags proto_flags, enum button_status * status)1942 hp5590_read_buttons (SANE_Int dn,
1943 enum proto_flags proto_flags,
1944 enum button_status * status)
1945 {
1946 uint16_t button_status;
1947 SANE_Status ret;
1948
1949 DBG (DBG_proc, "%s\n", __func__);
1950
1951 hp5590_cmds_assert (status != NULL);
1952 hp5590_cmds_assert (sizeof (button_status) == 2);
1953
1954 ret = hp5590_cmd (dn,
1955 proto_flags,
1956 CMD_IN | CMD_VERIFY,
1957 CMD_BUTTON_STATUS,
1958 (unsigned char *) &button_status,
1959 sizeof (button_status), CORE_NONE);
1960 if (ret != SANE_STATUS_GOOD)
1961 return ret;
1962
1963 *status = BUTTON_NONE;
1964
1965 /* Network order */
1966 button_status = ntohs (button_status);
1967 DBG (DBG_cmds, "Button status: %04x\n", button_status);
1968 DBG (DBG_cmds, "Power: %s, Scan: %s, Collect: %s, File: %s, Email: %s, Copy: %s, "
1969 "Up: %s, Down: %s, Mode: %s, Cancel: %s\n",
1970 button_status & BUTTON_FLAG_POWER ? " on" : "off",
1971 button_status & BUTTON_FLAG_SCAN ? " on" : "off",
1972 button_status & BUTTON_FLAG_COLLECT ? " on" : "off",
1973 button_status & BUTTON_FLAG_FILE ? " on" : "off",
1974 button_status & BUTTON_FLAG_EMAIL ? " on" : "off",
1975 button_status & BUTTON_FLAG_COPY ? " on" : "off",
1976 button_status & BUTTON_FLAG_UP ? " on" : "off",
1977 button_status & BUTTON_FLAG_DOWN ? " on" : "off",
1978 button_status & BUTTON_FLAG_MODE ? " on" : "off",
1979 button_status & BUTTON_FLAG_CANCEL ? " on" : "off");
1980
1981 if (button_status & BUTTON_FLAG_POWER)
1982 *status = BUTTON_POWER;
1983
1984 if (button_status & BUTTON_FLAG_SCAN)
1985 *status = BUTTON_SCAN;
1986
1987 if (button_status & BUTTON_FLAG_COLLECT)
1988 *status = BUTTON_COLLECT;
1989
1990 if (button_status & BUTTON_FLAG_FILE)
1991 *status = BUTTON_FILE;
1992
1993 if (button_status & BUTTON_FLAG_EMAIL)
1994 *status = BUTTON_EMAIL;
1995
1996 if (button_status & BUTTON_FLAG_COPY)
1997 *status = BUTTON_COPY;
1998
1999 if (button_status & BUTTON_FLAG_UP)
2000 *status = BUTTON_UP;
2001
2002 if (button_status & BUTTON_FLAG_DOWN)
2003 *status = BUTTON_DOWN;
2004
2005 if (button_status & BUTTON_FLAG_MODE)
2006 *status = BUTTON_MODE;
2007
2008 if (button_status & BUTTON_FLAG_CANCEL)
2009 *status = BUTTON_CANCEL;
2010
2011 return SANE_STATUS_GOOD;
2012 }
2013
2014 /******************************************************************************/
2015 static SANE_Status
hp5590_read_lcd_and_led(SANE_Int dn, enum proto_flags proto_flags, SANE_Int * lcd_counter, enum color_led_status * color_led)2016 hp5590_read_lcd_and_led (SANE_Int dn,
2017 enum proto_flags proto_flags,
2018 SANE_Int * lcd_counter,
2019 enum color_led_status * color_led)
2020 {
2021 SANE_Status ret;
2022
2023 DBG (DBG_proc, "%s\n", __func__);
2024
2025 hp5590_cmds_assert (lcd_counter != NULL);
2026 hp5590_cmds_assert (color_led != NULL);
2027
2028 /*
2029 * Read LCD status bytes and get current value of counter and
2030 * state of color/black_white LED.
2031 * data[0x29]: LCD counter value, data[0x2a]: 1=color / 2=black_white.
2032 */
2033 uint8_t data[0x30];
2034 ret = hp5590_cmd (dn,
2035 proto_flags,
2036 CMD_IN | CMD_VERIFY,
2037 CMD_LCD_STATUS,
2038 (unsigned char *) &data,
2039 sizeof (data), CORE_NONE);
2040 if (ret != SANE_STATUS_GOOD)
2041 return ret;
2042
2043 *lcd_counter = data[0x29];
2044 if (data[0x2a] == 2) {
2045 *color_led = LED_BLACKWHITE;
2046 } else {
2047 *color_led = LED_COLOR;
2048 }
2049 DBG (DBG_cmds, "LCD and LED values: lcd=%d, led=%s\n", *lcd_counter,
2050 *color_led == LED_BLACKWHITE ? "black_white" : "color");
2051
2052 return SANE_STATUS_GOOD;
2053 }
2054
2055 /* SET SCAN PARAMETERS
2056 ==================== 50 =======================
2057 BW 50 (425 x 585)
2058 18 00 64 00 64 00 00 00 00 04 f8 06 db 00 80 00
2059 40 08 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2060 00 00 00 03 50
2061
2062 BW 50 reduced top left (261 x 469)
2063 18 00 64 00 64 00 00 00 00 03 0c 05 7f 00 80 00
2064 40 08 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2065 00 00 00 02 08
2066
2067 BW 50 reduced top right (302 x 498)
2068 18 00 64 00 64 01 6e 00 00 03 8a 05 d6 00 80 00
2069 40 08 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2070 00 00 00 02 5c
2071
2072 BW 50 X 0, small width (16 x 585)
2073 18 00 64 00 64 00 00 00 00 00 30 06 db 00 80 00
2074 40 08 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2075 00 00 00 00 20
2076
2077 BW 50 X large, small width (24 x 585)
2078 18 00 64 00 64 04 b0 00 00 00 48 06 db 00 80 00
2079 40 08 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2080 00 00 00 00 30
2081
2082 BW 50 Y 0, small height (425 x 21)
2083 18 00 64 00 64 00 00 00 00 04 f8 00 3f 00 80 00
2084 40 08 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2085 00 00 00 03 50
2086
2087 BW 50 Y large, small height (425 x 21)
2088 18 00 64 00 64 00 00 06 99 04 f8 00 3f 00 80 00
2089 40 08 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2090 00 00 00 03 50
2091
2092 GRAY 50
2093 18 00 64 00 64 00 00 00 00 04 f8 06 db 00 80 00
2094 40 08 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2095 00 00 00 03 50
2096
2097 COLOR 50
2098 18 00 64 00 64 00 00 00 00 04 f8 06 db 00 80 00
2099 00 18 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2100 00 00 00 09 f0
2101
2102 ==================== 75 =======================
2103 BW 75
2104 18 00 64 00 64 00 00 00 00 04 f8 06 da 00 80 00
2105 40 08 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2106 00 00 00 03 50
2107
2108 GRAY 75
2109 18 00 64 00 64 00 00 00 00 04 f8 06 da 00 80 00
2110 40 08 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2111 00 00 00 03 50
2112
2113 COLOR 75
2114 18 00 64 00 64 00 00 00 00 04 f8 06 da 00 80 00
2115 00 18 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2116 00 00 00 09 f0
2117
2118 COLOR 75 48 bit
2119 18 00 64 00 64 00 00 00 00 04 f8 06 db 00 80 00
2120 00 30 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2121 04 00 00 13 e0
2122
2123 =================== 100 =======================
2124 BW 100
2125 18 00 64 00 64 00 00 00 00 04 f8 06 db 00 80 00
2126 40 01 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2127 00 00 00 00 6a
2128
2129 GRAY 100
2130 18 00 64 00 64 00 00 00 00 04 f8 06 db 00 80 00
2131 40 08 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2132 00 00 00 03 50
2133
2134 COLOR 100
2135 18 00 64 00 64 00 00 00 00 04 f8 06 db 00 80 00
2136 00 18 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2137 00 00 00 09 f0
2138
2139 COLOR 100 48bit, preview
2140 18 00 64 00 64 00 00 00 00 04 f8 06 db 00 80 00
2141 00 30 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2142 04 00 00 13 e0
2143
2144 COLOR 100 48bit
2145 18 00 64 00 64 00 00 00 00 04 f2 06 db 00 80 00
2146 00 30 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2147 00 00 00 13 c8
2148
2149 COLOR 100 48bit, TMA negatives
2150 11 00 64 00 64 00 00 00 00 00 fc 03 84 00 80 00
2151 00 30 e8 40 00 64 00 c8 01 90 00 00 00 00 00 00
2152 00 00 00 03 f0
2153
2154 COLOR 100 48bit, TMA slides
2155 12 00 64 00 64 00 00 00 00 00 fc 03 84 00 80 00
2156 00 30 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2157 00 00 00 03 f0
2158
2159 =================== 150 =======================
2160 BW 150
2161 18 00 c8 00 c8 00 00 00 00 09 f6 0d b6 00 80 00
2162 40 08 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2163 00 00 00 06 a4
2164
2165 GRAY 150
2166 18 00 c8 00 c8 00 00 00 00 09 f6 0d b6 00 80 00
2167 40 08 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2168 00 00 00 06 a4
2169
2170 COLOR 150
2171 18 00 c8 00 c8 00 00 00 00 09 f6 0d b6 00 80 00
2172 00 18 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2173 00 00 00 13 ec
2174
2175 COLOR 150 48 bit
2176 18 00 c8 00 c8 00 00 00 00 09 ea 0d b6 00 80 00
2177 00 30 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2178 00 00 00 27 a8
2179
2180 =================== 200 =======================
2181 BW 200
2182 18 00 c8 00 c8 00 00 00 00 09 f0 0d b6 00 80 00
2183 40 01 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2184 00 00 00 00 d4
2185
2186 GRAY 200
2187 18 00 c8 00 c8 00 00 00 00 09 f6 0d b6 00 80 00
2188 40 08 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2189 00 00 00 06 a4
2190
2191 COLOR 200
2192 18 00 c8 00 c8 00 00 00 00 09 f6 0d b6 00 80 00
2193 00 18 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2194 00 00 00 13 ec
2195
2196 COLOR 200 48 bit
2197 18 00 c8 00 c8 00 00 00 00 09 f6 0d aa 00 80 00
2198 00 30 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2199 00 00 00 27 d8
2200
2201 =================== 300 =======================
2202 BW 300
2203 18 01 2c 01 2c 00 00 00 00 09 f0 0d b6 00 80 00
2204 40 01 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2205 00 00 00 01 3e
2206
2207 GRAY 300
2208 18 01 2c 01 2c 00 00 00 00 09 f4 0d b6 00 80 00
2209 40 08 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2210 00 00 00 09 f4
2211
2212 COLOR 300
2213 18 01 2c 01 2c 00 00 00 00 09 f4 0d b6 00 80 00
2214 00 18 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2215 00 00 00 1d dc
2216
2217 COLOR 300 48bit, TMA negatives
2218 11 01 2c 01 2c 00 00 00 06 01 fc 07 02 00 80 00
2219 00 30 e8 40 00 64 00 c8 01 90 00 00 00 00 00 00
2220 00 00 00 0b e8
2221
2222 COLOR 300 48bit, TMA slides
2223 12 01 2c 01 2c 00 00 00 00 01 fc 07 08 00 80 00
2224 00 30 e8 40 00 64 00 64 00 64 00 00 00 00 00 00
2225 00 00 00 0b e8
2226
2227 ==================== 400 ======================
2228 BW 400
2229 18 02 58 02 58 00 00 00 00 13 ec 1b 6c 00 80 00
2230 40 08 c8 40 00 64 00 64 00 64 00 00 00 00 00 00
2231 00 00 00 13 ec
2232
2233 GRAY 400
2234 18 02 58 02 58 00 00 00 00 13 ec 1b 6c 00 80 00
2235 40 08 c8 40 00 64 00 64 00 64 00 00 00 00 00 00
2236 00 00 00 13 ec
2237
2238 COLOR 400
2239 18 02 58 02 58 00 00 00 00 13 ec 1b 6c 00 80 00
2240 00 18 c8 40 00 64 00 64 00 64 00 00 00 00 00 00
2241 00 00 00 3b c4
2242
2243 ==================== 600 ======================
2244 BW 600
2245 18 02 58 02 58 00 00 00 00 13 e8 1b 6c 00 80 00
2246 40 01 c8 40 00 64 00 64 00 64 00 00 00 00 00 00
2247 00 00 00 02 7d
2248
2249 GRAY 600
2250 18 02 58 02 58 00 00 00 00 13 ec 1b 6c 00 80 00
2251 40 08 c8 40 00 64 00 64 00 64 00 00 00 00 00 00
2252 00 00 00 13 ec
2253
2254 COLOR 600
2255 18 02 58 02 58 00 00 00 00 13 ec 1b 6c 00 80 00
2256 00 18 c8 40 00 64 00 64 00 64 00 00 00 00 00 00
2257 00 00 00 3b c4
2258
2259 ==================== 1200 =====================
2260 BW 1200
2261
2262 18 04 b0 04 b0 00 00 00 00 27 a8 36 d8 00 80 00
2263 40 01 c8 40 00 64 00 64 00 64 00 00 00 00 00 00
2264 00 00 00 04 f5
2265 */
2266
2267 /* READ SCAN PARAMETERS
2268 ====================== 50 =====================
2269 BW 50
2270 c0 00 00 0f 23 a0 00 00 03 50 04 92 00 00 00 00
2271
2272 GRAY 50
2273 c0 00 00 0f 23 a0 00 00 03 50 04 92 00 00 00 00
2274
2275 COLOR 50
2276 c0 00 00 2d 6a e0 00 00 09 f0 04 92 00 00 00 00
2277
2278 ====================== 75 =====================
2279 BW 75
2280 c0 00 00 0f 20 50 00 00 03 50 04 91 00 00 00 00
2281
2282 GRAY 75
2283 c0 00 00 0f 20 50 00 00 03 50 04 91 00 00 00 00
2284
2285 COLOR 75
2286 c0 00 00 2d 60 f0 00 00 09 f0 04 91 00 00 00 00
2287
2288 COLOR 75 48 bit
2289 c0 00 00 5a 86 40 00 00 13 e0 04 8e 00 00 00 00
2290
2291 ===================== 100 =====================
2292 BW 100
2293 c0 00 00 01 e4 74 00 00 00 6a 04 92 00 00 00 00
2294
2295 GRAY 100
2296 c0 00 00 0f 23 a0 00 00 03 50 04 92 00 00 00 00
2297
2298 COLOR 100
2299 c0 00 00 2d 6a e0 00 00 09 f0 04 92 00 00 00 00
2300
2301 COLOR 100, 48 bit preview
2302 c0 00 00 5a d5 c0 00 00 13 e0 04 92 00 00 00 00
2303
2304 COLOR 100, 48 bit
2305 c0 00 00 5a 68 10 00 00 13 c8 04 92 00 00 00 00
2306
2307 ===================== 150 =====================
2308 BW 150
2309 c0 00 00 3c b3 10 00 00 06 a4 09 24 00 00 00 00
2310
2311 GRAY 150
2312 c0 00 00 3c b3 10 00 00 06 a4 09 24 00 00 00 00
2313
2314 COLOR 150
2315 c0 00 00 b6 19 30 00 00 13 ec 09 24 00 00 00 00
2316
2317 COLOR 150 48bit
2318 c0 00 01 6a 7b a0 00 00 27 a8 09 24 00 00 00 00
2319
2320 ===================== 200 =====================
2321 BW 200
2322 c0 00 00 07 91 d0 00 00 00 d4 09 24 00 00 00 00
2323
2324 GRAY 200
2325 c0 00 00 3c b3 10 00 00 06 a4 09 24 00 00 00 00
2326
2327 COLOR 200
2328 c0 00 00 b6 19 30 00 00 13 ec 09 24 00 00 00 00
2329
2330 COLOR 200 48 bit
2331 c0 00 01 6a f3 a0 00 00 27 d8 09 1c 00 00 00 00
2332
2333 ===================== 300 =====================
2334 BW 300
2335 c0 00 00 11 08 14 00 00 01 3e 0d b6 00 00 00 00
2336
2337 GRAY 300
2338 c0 00 00 88 77 78 00 00 09 f4 0d b6 00 00 00 00
2339
2340 COLOR 300
2341 c0 00 01 99 66 68 00 00 1d dc 0d b6 00 00 00 00
2342
2343 ===================== 400 =====================
2344 BW 400
2345 c0 00 02 22 4b 90 00 00 13 ec 1b 6c 00 00 00 00
2346
2347 GRAY 400
2348 c0 00 02 22 4b 90 00 00 13 ec 1b 6c 00 00 00 00
2349
2350 COLOR 400
2351 c0 00 06 66 e2 b0 00 00 3b c4 1b 6c 00 00 00 00
2352
2353 ===================== 600 =====================
2354 BW 600
2355 c0 00 00 44 3b bc 00 00 02 7d 1b 6c 00 00 00 00
2356
2357 GRAY 600
2358 c0 00 02 22 4b 90 00 00 13 ec 1b 6c 00 00 00 00
2359
2360 COLOR 600
2361 c0 00 06 66 e2 b0 00 00 3b c4 1b 6c 00 00 00 00
2362 */
2363 /* vim: sw=2 ts=8
2364 */
2365