1 /* SANE - Scanner Access Now Easy.
2
3 Copyright (C) 2011-2020 Rolf Bensch <rolf at bensch hyphen online dot de>
4 Copyright (C) 2007-2008 Nicolas Martin, <nicols-guest at alioth dot debian dot org>
5 Copyright (C) 2006-2007 Wittawat Yamwong <wittawat@web.de>
6
7 This file is part of the SANE package.
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <https://www.gnu.org/licenses/>.
21
22 As a special exception, the authors of SANE give permission for
23 additional uses of the libraries contained in this release of SANE.
24
25 The exception is that, if you link a SANE library with other files
26 to produce an executable, this does not by itself cause the
27 resulting executable to be covered by the GNU General Public
28 License. Your use of that executable is in no way restricted on
29 account of linking the SANE library code into it.
30
31 This exception does not, however, invalidate any other reasons why
32 the executable file might be covered by the GNU General Public
33 License.
34
35 If you submit changes to SANE to the maintainers to be included in
36 a subsequent release, you agree by submitting the changes that
37 those changes may be distributed with this exception intact.
38
39 If you write modifications of your own for SANE, it is your choice
40 whether to permit this exception to apply to your modifications.
41 If you do not wish that, delete this exception notice.
42 */
43 #include "../include/sane/config.h"
44
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <time.h> /* localtime(C90) */
49
50 #include "pixma_rename.h"
51 #include "pixma_common.h"
52 #include "pixma_io.h"
53
54
55 #ifdef __GNUC__
56 # define UNUSED(v) (void) v
57 #else
58 # define UNUSED(v)
59 #endif
60
61 #define IMAGE_BLOCK_SIZE (0xc000)
62 #define CMDBUF_SIZE 512
63
64 #define MP10_PID 0x261f
65
66 #define MP730_PID 0x262f
67 #define MP700_PID 0x2630
68
69 #define MP5_PID 0x2635 /* untested */
70
71 #define MP360_PID 0x263c
72 #define MP370_PID 0x263d
73 #define MP390_PID 0x263e
74 #define MP375R_PID 0x263f /* untested */
75
76 #define MP740_PID 0x264c /* Untested */
77 #define MP710_PID 0x264d
78
79 #define MF5630_PID 0x264e /* Untested */
80 #define MF5650_PID 0x264f
81 #define MF5730_PID 0x265d /* Untested */
82 #define MF5750_PID 0x265e /* Untested */
83 #define MF5770_PID 0x265f
84 #define MF3110_PID 0x2660
85
86 #define IR1020_PID 0x26e6
87
88 enum mp730_state_t
89 {
90 state_idle,
91 state_warmup,
92 state_scanning,
93 state_transfering,
94 state_finished
95 };
96
97 enum mp730_cmd_t
98 {
99 cmd_start_session = 0xdb20,
100 cmd_select_source = 0xdd20,
101 cmd_gamma = 0xee20,
102 cmd_scan_param = 0xde20,
103 cmd_status = 0xf320,
104 cmd_abort_session = 0xef20,
105 cmd_time = 0xeb80,
106 cmd_read_image = 0xd420,
107 cmd_error_info = 0xff20,
108
109 cmd_activate = 0xcf60,
110 cmd_calibrate = 0xe920
111 };
112
113 typedef struct mp730_t
114 {
115 enum mp730_state_t state;
116 pixma_cmdbuf_t cb;
117 unsigned raw_width;
118 uint8_t current_status[12];
119
120 uint8_t *buf, *imgbuf, *lbuf;
121 unsigned imgbuf_len;
122
123 unsigned last_block:1;
124 } mp730_t;
125
126
127 static void mp730_finish_scan (pixma_t * s);
128
129 static int
has_paper(pixma_t * s)130 has_paper (pixma_t * s)
131 {
132 mp730_t *mp = (mp730_t *) s->subdriver;
133 return (mp->current_status[1] == 0);
134 }
135
136 static void
drain_bulk_in(pixma_t * s)137 drain_bulk_in (pixma_t * s)
138 {
139 mp730_t *mp = (mp730_t *) s->subdriver;
140 while (pixma_read (s->io, mp->imgbuf, IMAGE_BLOCK_SIZE) >= 0);
141 }
142
143 static int
abort_session(pixma_t * s)144 abort_session (pixma_t * s)
145 {
146 mp730_t *mp = (mp730_t *) s->subdriver;
147 return pixma_exec_short_cmd (s, &mp->cb, cmd_abort_session);
148 }
149
150 static int
query_status(pixma_t * s)151 query_status (pixma_t * s)
152 {
153 mp730_t *mp = (mp730_t *) s->subdriver;
154 uint8_t *data;
155 int error;
156
157 data = pixma_newcmd (&mp->cb, cmd_status, 0, 12);
158 error = pixma_exec (s, &mp->cb);
159 if (error >= 0)
160 {
161 memcpy (mp->current_status, data, 12);
162 PDBG (pixma_dbg (3, "Current status: paper=%u cal=%u lamp=%u\n",
163 data[1], data[8], data[7]));
164 }
165 return error;
166 }
167
168 static int
activate(pixma_t * s, uint8_t x)169 activate (pixma_t * s, uint8_t x)
170 {
171 mp730_t *mp = (mp730_t *) s->subdriver;
172 uint8_t *data = pixma_newcmd (&mp->cb, cmd_activate, 10, 0);
173 data[0] = 1;
174 data[3] = x;
175 return pixma_exec (s, &mp->cb);
176 }
177
178 static int
start_session(pixma_t * s)179 start_session (pixma_t * s)
180 {
181 mp730_t *mp = (mp730_t *) s->subdriver;
182 return pixma_exec_short_cmd (s, &mp->cb, cmd_start_session);
183 }
184
185 static int
select_source(pixma_t * s)186 select_source (pixma_t * s)
187 {
188 mp730_t *mp = (mp730_t *) s->subdriver;
189 uint8_t *data = pixma_newcmd (&mp->cb, cmd_select_source, 10, 0);
190 switch (s->param->source)
191 {
192 case PIXMA_SOURCE_ADF:
193 data[0] = 2;
194 break;
195
196 case PIXMA_SOURCE_ADFDUP:
197 data[0] = 2;
198 data[5] = 3;
199 break;
200
201 default:
202 data[0] = 1;
203 break;
204 }
205 return pixma_exec (s, &mp->cb);
206 }
207
208 static int
send_scan_param(pixma_t * s)209 send_scan_param (pixma_t * s)
210 {
211 mp730_t *mp = (mp730_t *) s->subdriver;
212 uint8_t *data;
213
214 data = pixma_newcmd (&mp->cb, cmd_scan_param, 0x2e, 0);
215 pixma_set_be16 (s->param->xdpi | 0x1000, data + 0x04);
216 pixma_set_be16 (s->param->ydpi | 0x1000, data + 0x06);
217 pixma_set_be32 (s->param->x, data + 0x08);
218 pixma_set_be32 (s->param->y, data + 0x0c);
219 pixma_set_be32 (mp->raw_width, data + 0x10);
220 pixma_set_be32 (s->param->h, data + 0x14);
221
222 if (s->param->channels == 1)
223 {
224 if (s->param->depth == 1)
225 data[0x18] = 0x01;
226 else
227 data[0x18] = 0x04;
228 }
229 else
230 data[0x18] = 0x08;
231
232 data[0x19] = s->param->channels * s->param->depth; /* bits per pixel, for lineart should be 0x01 */
233 data[0x1e] = (s->param->depth == 1) ? 0x80 : 0x00; /* modify for lineart: 0x80 NEW */
234 data[0x1f] = (s->param->depth == 1) ? 0x80 : 0x7f; /* modify for lineart: 0x80 */
235 data[0x20] = (s->param->depth == 1) ? 0x01 : 0xff; /* modify for lineart: 0x01 */
236 data[0x23] = 0x81;
237
238 return pixma_exec (s, &mp->cb);
239 }
240
241 static int
calibrate(pixma_t * s)242 calibrate (pixma_t * s)
243 {
244 mp730_t *mp = (mp730_t *) s->subdriver;
245 return pixma_exec_short_cmd (s, &mp->cb, cmd_calibrate);
246 }
247
248 static int
read_image_block(pixma_t * s, uint8_t * header, uint8_t * data)249 read_image_block (pixma_t * s, uint8_t * header, uint8_t * data)
250 {
251 static const uint8_t cmd[10] = /* 0xd420 cmd */
252 { 0xd4, 0x20, 0, 0, 0, 0, 0, IMAGE_BLOCK_SIZE / 256, 4, 0 };
253 mp730_t *mp = (mp730_t *) s->subdriver;
254 const int hlen = 2 + 4;
255 int error, datalen;
256
257 mp->state = state_transfering;
258 mp->cb.reslen =
259 pixma_cmd_transaction (s, cmd, sizeof (cmd), mp->cb.buf, 512);
260 datalen = mp->cb.reslen;
261 if (datalen < 0)
262 return datalen;
263
264 memcpy (header, mp->cb.buf, hlen);
265 if (datalen >= hlen)
266 {
267 datalen -= hlen;
268 memcpy (data, mp->cb.buf + hlen, datalen);
269 data += datalen;
270 if (mp->cb.reslen == 512)
271 {
272 error = pixma_read (s->io, data, IMAGE_BLOCK_SIZE - 512 + hlen);
273 if (error < 0)
274 return error;
275 datalen += error;
276 }
277 }
278
279 mp->state = state_scanning;
280 mp->cb.expected_reslen = 0;
281 error = pixma_check_result (&mp->cb);
282 if (error < 0)
283 return error;
284 if (mp->cb.reslen < hlen)
285 return PIXMA_EPROTO;
286 return datalen;
287 }
288
289 static int
send_time(pixma_t * s)290 send_time (pixma_t * s)
291 {
292 /* Why does a scanner need a time? */
293 time_t now;
294 struct tm *t;
295 uint8_t *data;
296 mp730_t *mp = (mp730_t *) s->subdriver;
297
298 data = pixma_newcmd (&mp->cb, cmd_time, 20, 0);
299 pixma_get_time (&now, NULL);
300 t = localtime (&now);
301 strftime ((char *) data, 16, "%y/%m/%d %H:%M", t);
302 PDBG (pixma_dbg (3, "Sending time: '%s'\n", (char *) data));
303 return pixma_exec (s, &mp->cb);
304 }
305
306 static int
handle_interrupt(pixma_t * s, int timeout)307 handle_interrupt (pixma_t * s, int timeout)
308 {
309 uint8_t buf[16];
310 int len;
311
312 len = pixma_wait_interrupt (s->io, buf, sizeof (buf), timeout);
313 if (len == PIXMA_ETIMEDOUT)
314 return 0;
315 if (len < 0)
316 return len;
317 switch (s->cfg->pid)
318 {
319 case MP360_PID:
320 case MP370_PID:
321 case MP375R_PID:
322 case MP390_PID:
323 case MF5630_PID:
324 case MF5650_PID:
325 case MF5730_PID:
326 case MF5750_PID:
327 case MF5770_PID:
328 case MF3110_PID:
329 case IR1020_PID:
330 if (len != 16)
331 {
332 PDBG (pixma_dbg
333 (1, "WARNING:unexpected interrupt packet length %d\n", len));
334 return PIXMA_EPROTO;
335 }
336 if (buf[12] & 0x40)
337 query_status (s);
338 if (buf[10] & 0x40)
339 send_time (s);
340 /* FIXME: following is unverified! */
341 if (buf[15] & 1)
342 s->events = PIXMA_EV_BUTTON2; /* b/w scan */
343 if (buf[15] & 2)
344 s->events = PIXMA_EV_BUTTON1; /* color scan */
345 break;
346
347 case MP5_PID:
348 case MP10_PID:
349 case MP700_PID:
350 case MP730_PID:
351 case MP710_PID:
352 case MP740_PID:
353 if (len != 8)
354 {
355 PDBG (pixma_dbg
356 (1, "WARNING:unexpected interrupt packet length %d\n", len));
357 return PIXMA_EPROTO;
358 }
359 if (buf[7] & 0x10)
360 s->events = PIXMA_EV_BUTTON1;
361 if (buf[5] & 8)
362 send_time (s);
363 break;
364
365 default:
366 PDBG (pixma_dbg (1, "WARNING:unknown interrupt, please report!\n"));
367 PDBG (pixma_hexdump (1, buf, len));
368 }
369 return 1;
370 }
371
372 static int
has_ccd_sensor(pixma_t * s)373 has_ccd_sensor (pixma_t * s)
374 {
375 return (s->cfg->pid == MP360_PID ||
376 s->cfg->pid == MP370_PID ||
377 s->cfg->pid == MP375R_PID ||
378 s->cfg->pid == MP390_PID ||
379 s->cfg->pid == MF5630_PID ||
380 s->cfg->pid == MF5650_PID ||
381 s->cfg->pid == MF5730_PID ||
382 s->cfg->pid == MF5750_PID ||
383 s->cfg->pid == MF5770_PID);
384 }
385
386 static int
read_error_info(pixma_t * s, void *buf, unsigned size)387 read_error_info (pixma_t * s, void *buf, unsigned size)
388 {
389 unsigned len = 16;
390 mp730_t *mp = (mp730_t *) s->subdriver;
391 uint8_t *data;
392 int error;
393
394 data = pixma_newcmd (&mp->cb, cmd_error_info, 0, len);
395 error = pixma_exec (s, &mp->cb);
396 if (error < 0)
397 return error;
398 if (buf && len < size)
399 {
400 size = len;
401 /* NOTE: I've absolutely no idea what the returned data mean. */
402 memcpy (buf, data, size);
403 error = len;
404 }
405 return error;
406 }
407
408 static int
step1(pixma_t * s)409 step1 (pixma_t * s)
410 {
411 int error;
412
413 error = query_status (s);
414 if (error < 0)
415 return error;
416 if ((s->param->source == PIXMA_SOURCE_ADF
417 || s->param->source == PIXMA_SOURCE_ADFDUP)
418 && !has_paper (s))
419 return PIXMA_ENO_PAPER;
420 if (has_ccd_sensor (s))
421 {
422 switch (s->cfg->pid)
423 {
424 case MF5630_PID:
425 case MF5650_PID:
426 case MF5730_PID:
427 case MF5750_PID:
428 case MF5770_PID:
429 /* MF57x0: Wait 10 sec before starting for 1st page only */
430 if (s->param->adf_pageid == 0)
431 {
432 int tmo = 10; /* like Windows driver, 10 sec CCD calibration ? */
433 while (--tmo >= 0)
434 {
435 error = handle_interrupt (s, 1000);
436 if (s->cancel)
437 return PIXMA_ECANCELED;
438 if (error != PIXMA_ECANCELED && error < 0)
439 return error;
440 PDBG (pixma_dbg (2, "CCD Calibration ends in %d sec.\n", tmo));
441 }
442 }
443 break;
444
445 default:
446 break;
447 }
448
449 activate (s, 0);
450 error = calibrate (s);
451
452 switch (s->cfg->pid)
453 {
454 case MF5630_PID:
455 case MF5650_PID:
456 case MF5730_PID:
457 case MF5750_PID:
458 case MF5770_PID:
459 /* MF57x0: calibration returns PIXMA_STATUS_FAILED */
460 if (error == PIXMA_ECANCELED)
461 error = read_error_info (s, NULL, 0);
462 break;
463
464 default:
465 break;
466 }
467
468 // ignore result from calibrate()
469 // don't interrupt @ PIXMA_STATUS_BUSY
470 error = 0;
471 }
472 if (error >= 0)
473 error = activate (s, 0);
474 if (error >= 0)
475 error = activate (s, 4);
476 return error;
477 }
478
479 static void
pack_rgb(const uint8_t * src, unsigned nlines, unsigned w, uint8_t * dst)480 pack_rgb (const uint8_t * src, unsigned nlines, unsigned w, uint8_t * dst)
481 {
482 unsigned w2, stride;
483
484 w2 = 2 * w;
485 stride = 3 * w;
486 for (; nlines != 0; nlines--)
487 {
488 unsigned x;
489 for (x = 0; x != w; x++)
490 {
491 *dst++ = src[x + 0];
492 *dst++ = src[x + w];
493 *dst++ = src[x + w2];
494 }
495 src += stride;
496 }
497 }
498
499 static int
mp730_open(pixma_t * s)500 mp730_open (pixma_t * s)
501 {
502 mp730_t *mp;
503 uint8_t *buf;
504
505 mp = (mp730_t *) calloc (1, sizeof (*mp));
506 if (!mp)
507 return PIXMA_ENOMEM;
508
509 buf = (uint8_t *) malloc (CMDBUF_SIZE);
510 if (!buf)
511 {
512 free (mp);
513 return PIXMA_ENOMEM;
514 }
515
516 s->subdriver = mp;
517 mp->state = state_idle;
518
519 mp->cb.buf = buf;
520 mp->cb.size = CMDBUF_SIZE;
521 mp->cb.res_header_len = 2;
522 mp->cb.cmd_header_len = 10;
523 mp->cb.cmd_len_field_ofs = 7;
524
525 PDBG (pixma_dbg (3, "Trying to clear the interrupt buffer...\n"));
526 if (handle_interrupt (s, 200) == 0)
527 {
528 PDBG (pixma_dbg (3, " no packets in buffer\n"));
529 }
530 return 0;
531 }
532
533 static void
mp730_close(pixma_t * s)534 mp730_close (pixma_t * s)
535 {
536 mp730_t *mp = (mp730_t *) s->subdriver;
537
538 mp730_finish_scan (s);
539 free (mp->cb.buf);
540 free (mp->buf);
541 free (mp);
542 s->subdriver = NULL;
543 }
544
545 static unsigned
calc_raw_width(pixma_t * s, const pixma_scan_param_t * sp)546 calc_raw_width (pixma_t * s, const pixma_scan_param_t * sp)
547 {
548 unsigned raw_width;
549 /* FIXME: Does MP730 need the alignment? */
550 /* TODO test: MP710/740 */
551 if (sp->channels == 1)
552 {
553 if (sp->depth == 8) /* grayscale */
554 {
555 if (s->cfg->pid == MP5_PID ||
556 s->cfg->pid == MP10_PID ||
557 s->cfg->pid == MP700_PID ||
558 s->cfg->pid == MP730_PID ||
559 s->cfg->pid == MP360_PID ||
560 s->cfg->pid == MP370_PID ||
561 s->cfg->pid == MP375R_PID ||
562 s->cfg->pid == MP390_PID ||
563 s->cfg->pid == IR1020_PID)
564 raw_width = ALIGN_SUP (sp->w, 4);
565 else
566 raw_width = ALIGN_SUP (sp->w, 12);
567 }
568 else /* depth = 1 : LINEART */
569 raw_width = ALIGN_SUP (sp->w, 16);
570 }
571 else
572 raw_width = ALIGN_SUP (sp->w, 4);
573 return raw_width;
574 }
575
576 static int
mp730_check_param(pixma_t * s, pixma_scan_param_t * sp)577 mp730_check_param (pixma_t * s, pixma_scan_param_t * sp)
578 {
579 uint8_t k = 1;
580
581 /* check if channels is 3, or if depth is 1 then channels also 1 else set depth to 8 */
582 if ((sp->channels==3) || !(sp->channels==1 && sp->depth==1))
583 {
584 sp->depth=8;
585 }
586 /* for MP5, MP10, MP360/370, MP700/730 in grayscale & lineart modes, max scan res is 600 dpi */
587 if (s->cfg->pid == MP5_PID ||
588 s->cfg->pid == MP10_PID ||
589 s->cfg->pid == MP700_PID ||
590 s->cfg->pid == MP730_PID ||
591 s->cfg->pid == MP360_PID ||
592 s->cfg->pid == MP370_PID ||
593 s->cfg->pid == MP375R_PID ||
594 s->cfg->pid == MP390_PID)
595 {
596 if (sp->channels == 1)
597 k = sp->xdpi / MIN (sp->xdpi, 600);
598 }
599
600 sp->x /= k;
601 sp->y /= k;
602 sp->h /= k;
603 sp->xdpi /= k;
604 sp->ydpi = sp->xdpi;
605
606 sp->w = calc_raw_width (s, sp);
607 sp->w /= k;
608 sp->line_size = (calc_raw_width (s, sp) * sp->channels * sp->depth) / 8;
609
610 return 0;
611 }
612
613 static int
mp730_scan(pixma_t * s)614 mp730_scan (pixma_t * s)
615 {
616 int error, n;
617 mp730_t *mp = (mp730_t *) s->subdriver;
618 uint8_t *buf;
619
620 if (mp->state != state_idle)
621 return PIXMA_EBUSY;
622
623 /* clear interrupt packets buffer */
624 while (handle_interrupt (s, 0) > 0)
625 {
626 }
627
628 mp->raw_width = calc_raw_width (s, s->param);
629 PDBG (pixma_dbg (3, "raw_width = %u\n", mp->raw_width));
630
631 n = IMAGE_BLOCK_SIZE / s->param->line_size + 1;
632 buf = (uint8_t *) malloc ((n + 1) * s->param->line_size + IMAGE_BLOCK_SIZE);
633 if (!buf)
634 return PIXMA_ENOMEM;
635 mp->buf = buf;
636 mp->lbuf = buf;
637 mp->imgbuf = buf + n * s->param->line_size;
638 mp->imgbuf_len = 0;
639
640 error = step1 (s);
641 if (error >= 0)
642 error = start_session (s);
643 if (error >= 0)
644 mp->state = state_scanning;
645 if (error >= 0)
646 error = select_source (s);
647 if (error >= 0)
648 error = send_scan_param (s);
649 if (error < 0)
650 {
651 mp730_finish_scan (s);
652 return error;
653 }
654 mp->last_block = 0;
655 return 0;
656 }
657
658 static int
mp730_fill_buffer(pixma_t * s, pixma_imagebuf_t * ib)659 mp730_fill_buffer (pixma_t * s, pixma_imagebuf_t * ib)
660 {
661 int error, n;
662 mp730_t *mp = (mp730_t *) s->subdriver;
663 unsigned block_size, bytes_received;
664 uint8_t header[16];
665
666 do
667 {
668 do
669 {
670 if (s->cancel)
671 return PIXMA_ECANCELED;
672 if (mp->last_block) /* end of image */
673 return 0;
674
675 error = read_image_block (s, header, mp->imgbuf + mp->imgbuf_len);
676 if (error < 0)
677 return error;
678
679 bytes_received = error;
680 block_size = pixma_get_be16 (header + 4);
681 mp->last_block = ((header[2] & 0x28) == 0x28);
682 if (mp->last_block)
683 { /* end of image */
684 mp->state = state_finished;
685 }
686 if ((header[2] & ~0x38) != 0)
687 {
688 PDBG (pixma_dbg (1, "WARNING: Unexpected result header\n"));
689 PDBG (pixma_hexdump (1, header, 16));
690 }
691 PASSERT (bytes_received == block_size);
692
693 if (block_size == 0)
694 {
695 /* no image data at this moment. */
696 /*pixma_sleep(100000); *//* FIXME: too short, too long? */
697 handle_interrupt (s, 100);
698 }
699 }
700 while (block_size == 0);
701
702 /* TODO: simplify! */
703 mp->imgbuf_len += bytes_received;
704 n = mp->imgbuf_len / s->param->line_size;
705 /* n = number of full lines (rows) we have in the buffer. */
706 if (n != 0)
707 {
708 if (s->param->channels != 1 &&
709 s->cfg->pid != MF5630_PID &&
710 s->cfg->pid != MF5650_PID &&
711 s->cfg->pid != MF5730_PID &&
712 s->cfg->pid != MF5750_PID &&
713 s->cfg->pid != MF5770_PID &&
714 s->cfg->pid != MF3110_PID &&
715 s->cfg->pid != IR1020_PID)
716 {
717 /* color, and not an MF57x0 nor MF3110 */
718 pack_rgb (mp->imgbuf, n, mp->raw_width, mp->lbuf);
719 }
720 else
721 /* grayscale/lineart or MF57x0 or MF3110 */
722 memcpy (mp->lbuf, mp->imgbuf, n * s->param->line_size);
723
724 block_size = n * s->param->line_size;
725 mp->imgbuf_len -= block_size;
726 memcpy (mp->imgbuf, mp->imgbuf + block_size, mp->imgbuf_len);
727 }
728 }
729 while (n == 0);
730
731 ib->rptr = mp->lbuf;
732 ib->rend = mp->lbuf + block_size;
733 return ib->rend - ib->rptr;
734 }
735
736 static void
mp730_finish_scan(pixma_t * s)737 mp730_finish_scan (pixma_t * s)
738 {
739 int error, aborted = 0;
740 mp730_t *mp = (mp730_t *) s->subdriver;
741
742 switch (mp->state)
743 {
744 case state_transfering:
745 drain_bulk_in (s);
746 /* fall through */
747 case state_scanning:
748 case state_warmup:
749 aborted = 1;
750 error = abort_session (s);
751 if (error < 0)
752 PDBG (pixma_dbg
753 (1, "WARNING:abort_session() failed %s\n",
754 pixma_strerror (error)));
755 /* fall through */
756 case state_finished:
757 query_status (s);
758 query_status (s);
759 activate (s, 0);
760
761 // MF57x0 devices don't require abort_session() after the last page
762 if (!aborted &&
763 (s->param->source == PIXMA_SOURCE_ADF ||
764 s->param->source == PIXMA_SOURCE_ADFDUP) &&
765 has_paper (s) &&
766 (s->cfg->pid == MF5630_PID ||
767 s->cfg->pid == MF5650_PID ||
768 s->cfg->pid == MF5730_PID ||
769 s->cfg->pid == MF5750_PID ||
770 s->cfg->pid == MF5770_PID ||
771 s->cfg->pid == IR1020_PID))
772 {
773 error = abort_session (s);
774 if (error < 0)
775 PDBG (pixma_dbg
776 (1, "WARNING:abort_session() failed %s\n",
777 pixma_strerror (error)));
778 }
779
780 mp->buf = mp->lbuf = mp->imgbuf = NULL;
781 mp->state = state_idle;
782 /* fall through */
783 case state_idle:
784 break;
785 }
786 }
787
788 static void
mp730_wait_event(pixma_t * s, int timeout)789 mp730_wait_event (pixma_t * s, int timeout)
790 {
791 /* FIXME: timeout is not correct. See usbGetCompleteUrbNoIntr() for
792 * instance. */
793 while (s->events == 0 && handle_interrupt (s, timeout) > 0)
794 {
795 }
796 }
797
798 static int
mp730_get_status(pixma_t * s, pixma_device_status_t * status)799 mp730_get_status (pixma_t * s, pixma_device_status_t * status)
800 {
801 int error;
802
803 error = query_status (s);
804 if (error < 0)
805 return error;
806 status->hardware = PIXMA_HARDWARE_OK;
807 status->adf = (has_paper (s)) ? PIXMA_ADF_OK : PIXMA_ADF_NO_PAPER;
808 return 0;
809 }
810
811
812 static const pixma_scan_ops_t pixma_mp730_ops = {
813 mp730_open,
814 mp730_close,
815 mp730_scan,
816 mp730_fill_buffer,
817 mp730_finish_scan,
818 mp730_wait_event,
819 mp730_check_param,
820 mp730_get_status
821 };
822
823 /* TODO: implement adftpu_min_dpi & adftpu_max_dpi for grayscale & lineart */
824 #define DEVICE(name, model, pid, dpi, w, h, cap) { \
825 name, /* name */ \
826 model, /* model */ \
827 0x04a9, pid, /* vid pid */ \
828 1, /* iface */ \
829 &pixma_mp730_ops, /* ops */ \
830 0, 0, /* min_xdpi & min_xdpi_16 not used in this subdriver */ \
831 dpi, dpi, /* xdpi, ydpi */ \
832 0, 0, /* adftpu_min_dpi & adftpu_max_dpi not used in this subdriver */ \
833 0, 0, /* tpuir_min_dpi & tpuir_max_dpi not used in this subdriver */ \
834 w, h, /* width, height */ \
835 PIXMA_CAP_GRAY|PIXMA_CAP_EVENTS|cap \
836 }
837 const pixma_config_t pixma_mp730_devices[] = {
838 /* TODO: check area limits */
839 DEVICE ("PIXUS MP5/SmartBase MPC190/imageCLASS MPC190","MP5", MP5_PID, 600, 636, 868, PIXMA_CAP_LINEART),/* color scan can do 600x1200 */
840 DEVICE ("PIXUS MP10/SmartBase MPC200/imageCLASS MPC200","MP10", MP10_PID, 600, 636, 868, PIXMA_CAP_LINEART),/* color scan can do 600x1200 */
841 DEVICE ("PIXMA MP360", "MP360", MP360_PID, 1200, 636, 868, PIXMA_CAP_LINEART),
842 DEVICE ("PIXMA MP370", "MP370", MP370_PID, 1200, 636, 868, PIXMA_CAP_LINEART),
843 DEVICE ("PIXMA MP375R", "MP375R", MP375R_PID, 1200, 636, 868, PIXMA_CAP_LINEART),
844 DEVICE ("PIXMA MP390", "MP390", MP390_PID, 1200, 636, 868, PIXMA_CAP_LINEART),
845 DEVICE ("PIXMA MP700", "MP700", MP700_PID, 1200, 638, 877 /*1035 */ , PIXMA_CAP_LINEART),
846 DEVICE ("PIXMA MP710", "MP710", MP710_PID, 1200, 637, 868, PIXMA_CAP_LINEART),
847 DEVICE ("PIXMA MP730", "MP730", MP730_PID, 1200, 637, 868, PIXMA_CAP_ADF | PIXMA_CAP_LINEART),
848 DEVICE ("PIXMA MP740", "MP740", MP740_PID, 1200, 637, 868, PIXMA_CAP_ADF | PIXMA_CAP_LINEART),
849
850 DEVICE ("Canon imageCLASS MF5630", "MF5630", MF5630_PID, 1200, 636, 868, PIXMA_CAP_ADF),
851 DEVICE ("Canon laserBase MF5650", "MF5650", MF5650_PID, 1200, 636, 868, PIXMA_CAP_ADF),
852 DEVICE ("Canon imageCLASS MF5730", "MF5730", MF5730_PID, 1200, 636, 868, PIXMA_CAP_ADF),
853 DEVICE ("Canon imageCLASS MF5750", "MF5750", MF5750_PID, 1200, 636, 868, PIXMA_CAP_ADF),
854 DEVICE ("Canon imageCLASS MF5770", "MF5770", MF5770_PID, 1200, 636, 868, PIXMA_CAP_ADF),
855 DEVICE ("Canon imageCLASS MF3110", "MF3110", MF3110_PID, 600, 636, 868, 0),
856
857 DEVICE ("Canon iR 1020/1024/1025", "iR1020", IR1020_PID, 600, 636, 868, PIXMA_CAP_ADFDUP),
858
859 DEVICE (NULL, NULL, 0, 0, 0, 0, 0)
860 };
861