1 /* sane - Scanner Access Now Easy.
2 Copyright (C) 2000-2003 Jochen Eisinger <jochen.eisinger@gmx.net>
3 This file is part of the SANE package.
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
17
18 As a special exception, the authors of SANE give permission for
19 additional uses of the libraries contained in this release of SANE.
20
21 The exception is that, if you link a SANE library with other files
22 to produce an executable, this does not by itself cause the
23 resulting executable to be covered by the GNU General Public
24 License. Your use of that executable is in no way restricted on
25 account of linking the SANE library code into it.
26
27 This exception does not, however, invalidate any other reasons why
28 the executable file might be covered by the GNU General Public
29 License.
30
31 If you submit changes to SANE to the maintainers to be included in
32 a subsequent release, you agree by submitting the changes that
33 those changes may be distributed with this exception intact.
34
35 If you write modifications of your own for SANE, it is your choice
36 whether to permit this exception to apply to your modifications.
37 If you do not wish that, delete this exception notice.
38
39 This file implements the hardware driver scanners using a 300dpi CCD */
40
41 #include "mustek_pp_ccd300.h"
42
43 #define MUSTEK_PP_CCD300 4
44
45 static void config_ccd_101x (Mustek_pp_Handle * dev);
46 static void config_ccd (Mustek_pp_Handle * dev);
47 static void lamp (Mustek_pp_Handle * dev, int lamp_on);
48
49 #define CCD300_ASIC1013 0xa8
50 #define CCD300_ASIC1015 0xa5
51
52 #define CCD300_CHANNEL_RED 0
53 #define CCD300_CHANNEL_GREEN 1
54 #define CCD300_CHANNEL_BLUE 2
55 #define CCD300_CHANNEL_GRAY 1
56
57 #define CCD300_MAXHSIZE 2600
58 #define CCD300_MAXVSIZE 3500
59
60 /*
61 * Here starts the driver code for the different chipsets
62 *
63 * The 1013 & 1015 chipsets share large portions of the code. This
64 * shared functions end with _101x.
65 */
66
67 static const u_char chan_codes_1013[] = { 0x82, 0x42, 0xC2 };
68 static const u_char chan_codes_1015[] = { 0x80, 0x40, 0xC0 };
69 static const u_char fullstep[] = { 0x09, 0x0C, 0x06, 0x03 };
70 static const u_char halfstep[] = { 0x02, 0x03, 0x01, 0x09,
71 0x08, 0x0C, 0x04, 0x06
72 };
73 static const u_char voltages[4][3] = { {0x5C, 0x5A, 0x63},
74 {0xE6, 0xB4, 0xBE},
75 {0xB4, 0xB4, 0xB4},
76 {0x64, 0x50, 0x64}
77 };
78
79 /* Forward declarations of 1013/1015 functions */
80 static void set_ccd_channel_1013 (Mustek_pp_Handle * dev, int channel);
81 static void motor_backward_1013 (Mustek_pp_Handle * dev);
82 static void return_home_1013 (Mustek_pp_Handle * dev);
83 static void motor_forward_1013 (Mustek_pp_Handle * dev);
84 static void config_ccd_1013 (Mustek_pp_Handle * dev);
85
86 static void set_ccd_channel_1015 (Mustek_pp_Handle * dev, int channel);
87 /* static void motor_backward_1015 (Mustek_pp_Handle * dev); */
88 static void return_home_1015 (Mustek_pp_Handle * dev, SANE_Bool nowait);
89 static void motor_forward_1015 (Mustek_pp_Handle * dev);
90 static void config_ccd_1015 (Mustek_pp_Handle * dev);
91
92
93 /* These functions are common to all 1013/1015 chipsets */
94
95 static void
set_led(Mustek_pp_Handle * dev)96 set_led (Mustek_pp_Handle * dev)
97 {
98 mustek_pp_ccd300_priv *priv = dev->priv;
99
100 sanei_pa4s2_writebyte (dev->fd, 6,
101 (priv->motor_step % 5 == 0 ? 0x03 : 0x13));
102
103 }
104
105 static void
set_sti(Mustek_pp_Handle * dev)106 set_sti (Mustek_pp_Handle * dev)
107 {
108 mustek_pp_ccd300_priv *priv = dev->priv;
109
110 sanei_pa4s2_writebyte (dev->fd, 3, 0);
111 priv->bank_count++;
112 priv->bank_count &= 7;
113
114 }
115
116 static void
get_bank_count(Mustek_pp_Handle * dev)117 get_bank_count (Mustek_pp_Handle * dev)
118 {
119 u_char val;
120 mustek_pp_ccd300_priv *priv = dev->priv;
121
122 sanei_pa4s2_readbegin (dev->fd, 3);
123 sanei_pa4s2_readbyte (dev->fd, &val);
124 sanei_pa4s2_readend (dev->fd);
125
126 priv->bank_count = (val & 0x07);
127
128 }
129
130 static void
reset_bank_count(Mustek_pp_Handle * dev)131 reset_bank_count (Mustek_pp_Handle * dev)
132 {
133 sanei_pa4s2_writebyte (dev->fd, 6, 7);
134 }
135
136 static void
wait_bank_change(Mustek_pp_Handle * dev, int bankcount, int niceload)137 wait_bank_change (Mustek_pp_Handle * dev, int bankcount, int niceload)
138 {
139 struct timeval start, end;
140 unsigned long diff;
141 mustek_pp_ccd300_priv *priv = dev->priv;
142 int first_time = 1;
143
144 gettimeofday (&start, NULL);
145
146 do
147 {
148 if ((niceload == 0) && (first_time == 0))
149 {
150 usleep (1); /* could be as well sched_yield */
151 first_time = 0;
152 }
153 get_bank_count (dev);
154
155 gettimeofday (&end, NULL);
156 diff = (end.tv_sec * 1000 + end.tv_usec / 1000) -
157 (start.tv_sec * 1000 + start.tv_usec / 1000);
158
159 }
160 while ((priv->bank_count != bankcount) && (diff < priv->wait_bank));
161
162 }
163
164 static void
set_dpi_value(Mustek_pp_Handle * dev)165 set_dpi_value (Mustek_pp_Handle * dev)
166 {
167 u_char val = 0;
168 mustek_pp_ccd300_priv *priv = dev->priv;
169
170 sanei_pa4s2_writebyte (dev->fd, 6, 0x80);
171
172 switch (priv->hwres)
173 {
174 case 100:
175 val = 0x00;
176 break;
177 case 200:
178 val = 0x10;
179 break;
180 case 300:
181 val = 0x20;
182 break;
183 }
184
185
186 if (priv->ccd_type == 1)
187 val |= 0x01;
188
189 sanei_pa4s2_writebyte (dev->fd, 5, val);
190
191 sanei_pa4s2_writebyte (dev->fd, 6, 0x00);
192
193 DBG (5, "set_dpi_value: value 0x%02x\n", val);
194
195 }
196
197 static void
set_line_adjust(Mustek_pp_Handle * dev)198 set_line_adjust (Mustek_pp_Handle * dev)
199 {
200 int adjustline;
201 mustek_pp_ccd300_priv *priv = dev->priv;
202
203 adjustline = (dev->bottomX - dev->topX) * priv->hwres / 300;
204 priv->adjustskip = priv->adjustskip * priv->hwres / 300;
205
206 DBG (5, "set_line_adjust: ppl %u (%u), adjust %u, skip %u\n",
207 dev->params.pixels_per_line, (dev->bottomX - dev->topX), adjustline,
208 priv->adjustskip);
209
210
211 sanei_pa4s2_writebyte (dev->fd, 6, 0x11);
212 sanei_pa4s2_writebyte (dev->fd, 5, (adjustline + priv->adjustskip) >> 8);
213 sanei_pa4s2_writebyte (dev->fd, 6, 0x21);
214 sanei_pa4s2_writebyte (dev->fd, 5, (adjustline + priv->adjustskip) & 0xFF);
215
216 sanei_pa4s2_writebyte (dev->fd, 6, 0x01);
217
218 }
219
220 static void
set_lamp(Mustek_pp_Handle * dev, int lamp_on)221 set_lamp (Mustek_pp_Handle * dev, int lamp_on)
222 {
223
224 int ctr;
225 mustek_pp_ccd300_priv *priv = dev->priv;
226
227 sanei_pa4s2_writebyte (dev->fd, 6, 0xC3);
228
229 for (ctr = 0; ctr < 3; ctr++)
230 {
231 sanei_pa4s2_writebyte (dev->fd, 6, (lamp_on ? 0x47 : 0x57));
232 sanei_pa4s2_writebyte (dev->fd, 6, 0x77);
233 }
234
235 priv->motor_step = lamp_on;
236
237 set_led (dev);
238
239 }
240
241 static void
send_voltages(Mustek_pp_Handle * dev)242 send_voltages (Mustek_pp_Handle * dev)
243 {
244
245 int voltage, sel = 8, ctr;
246 mustek_pp_ccd300_priv *priv = dev->priv;
247
248 switch (priv->ccd_type)
249 {
250 case 0:
251 voltage = 0;
252 break;
253 case 1:
254 voltage = 1;
255 break;
256 default:
257 voltage = 2;
258 break;
259 }
260
261 for (ctr = 0; ctr < 3; ctr++)
262 {
263
264 sel <<= 1;
265 sanei_pa4s2_writebyte (dev->fd, 6, sel);
266 sanei_pa4s2_writebyte (dev->fd, 5, voltages[voltage][ctr]);
267
268 }
269
270 sanei_pa4s2_writebyte (dev->fd, 6, 0x00);
271
272 }
273
274 static int
compar(const void *a, const void *b)275 compar (const void *a, const void *b)
276 {
277 return (signed int) (*(const SANE_Byte *) a) -
278 (signed int) (*(const SANE_Byte *) b);
279 }
280
281 static void
set_ccd_channel_101x(Mustek_pp_Handle * dev, int channel)282 set_ccd_channel_101x (Mustek_pp_Handle * dev, int channel)
283 {
284 mustek_pp_ccd300_priv *priv = dev->priv;
285 switch (priv->asic)
286 {
287 case CCD300_ASIC1013:
288 set_ccd_channel_1013 (dev, channel);
289 break;
290
291 case CCD300_ASIC1015:
292 set_ccd_channel_1015 (dev, channel);
293 break;
294 }
295 }
296
297 static void
motor_forward_101x(Mustek_pp_Handle * dev)298 motor_forward_101x (Mustek_pp_Handle * dev)
299 {
300 mustek_pp_ccd300_priv *priv = dev->priv;
301 switch (priv->asic)
302 {
303 case CCD300_ASIC1013:
304 motor_forward_1013 (dev);
305 break;
306
307 case CCD300_ASIC1015:
308 motor_forward_1015 (dev);
309 break;
310 }
311 }
312
313 static void
motor_backward_101x(Mustek_pp_Handle * dev)314 motor_backward_101x (Mustek_pp_Handle * dev)
315 {
316 mustek_pp_ccd300_priv *priv = dev->priv;
317 switch (priv->asic)
318 {
319 case CCD300_ASIC1013:
320 motor_backward_1013 (dev);
321 break;
322
323 case CCD300_ASIC1015:
324 /* motor_backward_1015 (dev); */
325 break;
326 }
327 }
328
329 static void
move_motor_101x(Mustek_pp_Handle * dev, int forward)330 move_motor_101x (Mustek_pp_Handle * dev, int forward)
331 {
332 mustek_pp_ccd300_priv *priv = dev->priv;
333 if (forward == SANE_TRUE)
334 motor_forward_101x (dev);
335 else
336 motor_backward_101x (dev);
337
338 wait_bank_change (dev, priv->bank_count, 1);
339 reset_bank_count (dev);
340 }
341
342
343 static void
config_ccd_101x(Mustek_pp_Handle * dev)344 config_ccd_101x (Mustek_pp_Handle * dev)
345 {
346 mustek_pp_ccd300_priv *priv = dev->priv;
347 switch (priv->asic)
348 {
349 case CCD300_ASIC1013:
350 config_ccd_1013 (dev);
351 break;
352
353 case CCD300_ASIC1015:
354 config_ccd_1015 (dev);
355 break;
356 }
357 }
358
359
360
361 static void
read_line_101x(Mustek_pp_Handle * dev, SANE_Byte * buf, SANE_Int pixel, SANE_Int RefBlack, SANE_Byte * calib, SANE_Int * gamma)362 read_line_101x (Mustek_pp_Handle * dev, SANE_Byte * buf, SANE_Int pixel,
363 SANE_Int RefBlack, SANE_Byte * calib, SANE_Int * gamma)
364 {
365
366 SANE_Byte *cal = calib;
367 u_char color;
368 mustek_pp_ccd300_priv *priv = dev->priv;
369 int ctr, skips = priv->adjustskip + 1, cval;
370
371 if (pixel <= 0)
372 return;
373
374 sanei_pa4s2_readbegin (dev->fd, 1);
375
376
377 if (priv->hwres == dev->res)
378 {
379
380 while (skips--)
381 sanei_pa4s2_readbyte (dev->fd, &color);
382
383 for (ctr = 0; ctr < pixel; ctr++)
384 {
385
386 sanei_pa4s2_readbyte (dev->fd, &color);
387
388 cval = color;
389
390 if (cval < RefBlack)
391 cval = 0;
392 else
393 cval -= RefBlack;
394
395 if (cal)
396 {
397 if (cval >= cal[ctr])
398 cval = 0xFF;
399 else
400 {
401 cval <<= 8;
402 cval /= (int) cal[ctr];
403 }
404 }
405
406 if (gamma)
407 cval = gamma[cval];
408
409 buf[ctr] = cval;
410
411 }
412
413 }
414 else
415 {
416
417 int pos = 0, bpos = 0;
418
419 while (skips--)
420 sanei_pa4s2_readbyte (dev->fd, &color);
421
422 ctr = 0;
423
424 do
425 {
426
427 sanei_pa4s2_readbyte (dev->fd, &color);
428
429 cval = color;
430
431 if (ctr < (pos >> SANE_FIXED_SCALE_SHIFT))
432 {
433 ctr++;
434 continue;
435 }
436
437 ctr++;
438 pos += priv->res_step;
439
440
441 if (cval < RefBlack)
442 cval = 0;
443 else
444 cval -= RefBlack;
445
446 if (cal)
447 {
448 if (cval >= cal[bpos])
449 cval = 0xFF;
450 else
451 {
452 cval <<= 8;
453 cval /= (int) cal[bpos];
454 }
455 }
456
457 if (gamma)
458 cval = gamma[cval];
459
460 buf[bpos++] = cval;
461
462 }
463 while (bpos < pixel);
464
465 }
466
467 sanei_pa4s2_readend (dev->fd);
468
469 }
470
471 static void
read_average_line_101x(Mustek_pp_Handle * dev, SANE_Byte * buf, int pixel, int RefBlack)472 read_average_line_101x (Mustek_pp_Handle * dev, SANE_Byte * buf, int pixel,
473 int RefBlack)
474 {
475
476 SANE_Byte lbuf[4][CCD300_MAXHSIZE * 2];
477 int ctr, sum;
478 mustek_pp_ccd300_priv *priv = dev->priv;
479
480 for (ctr = 0; ctr < 4; ctr++)
481 {
482
483 wait_bank_change (dev, priv->bank_count, 1);
484 read_line_101x (dev, lbuf[ctr], pixel, RefBlack, NULL, NULL);
485 reset_bank_count (dev);
486 if (ctr < 3)
487 set_sti (dev);
488
489 }
490
491 for (ctr = 0; ctr < pixel; ctr++)
492 {
493
494 sum = lbuf[0][ctr] + lbuf[1][ctr] + lbuf[2][ctr] + lbuf[3][ctr];
495
496 buf[ctr] = (sum / 4);
497
498 }
499
500 }
501
502 static void
find_black_side_edge_101x(Mustek_pp_Handle * dev)503 find_black_side_edge_101x (Mustek_pp_Handle * dev)
504 {
505 SANE_Byte buf[CCD300_MAXHSIZE * 2];
506 SANE_Byte blackposition[5];
507 int pos = 0, ctr, blackpos;
508 mustek_pp_ccd300_priv *priv = dev->priv;
509
510
511 for (ctr = 0; ctr < 20; ctr++)
512 {
513
514 motor_forward_101x (dev);
515 wait_bank_change (dev, priv->bank_count, 1);
516 read_line_101x (dev, buf, CCD300_MAXHSIZE, 0, NULL, NULL);
517 reset_bank_count (dev);
518
519 priv->ref_black = priv->ref_red = priv->ref_green = priv->ref_blue =
520 buf[0];
521
522 blackpos = CCD300_MAXHSIZE / 4;
523
524 while ((abs (buf[blackpos] - buf[0]) >= 15) && (blackpos > 0))
525 blackpos--;
526
527 if (blackpos > 1)
528 blackposition[pos++] = blackpos;
529
530 if (pos == 5)
531 break;
532
533 }
534
535 blackpos = 0;
536
537 for (ctr = 0; ctr < pos; ctr++)
538 if (blackposition[ctr] > blackpos)
539 blackpos = blackposition[ctr];
540
541 if (blackpos < 0x66)
542 blackpos = 0x6A;
543
544 priv->blackpos = blackpos;
545 priv->saved_skipcount = (blackpos + 12) & 0xFF;
546
547 }
548
549 static void
min_color_levels_101x(Mustek_pp_Handle * dev)550 min_color_levels_101x (Mustek_pp_Handle * dev)
551 {
552
553 SANE_Byte buf[CCD300_MAXHSIZE * 2];
554 int ctr, sum = 0;
555 mustek_pp_ccd300_priv *priv = dev->priv;
556
557 for (ctr = 0; ctr < 8; ctr++)
558 {
559
560 set_ccd_channel_101x (dev, CCD300_CHANNEL_RED);
561 set_sti (dev);
562 wait_bank_change (dev, priv->bank_count, 1);
563
564 read_line_101x (dev, buf, CCD300_MAXHSIZE, 0, NULL, NULL);
565
566 reset_bank_count (dev);
567
568 sum += buf[3];
569
570 }
571
572 priv->ref_red = sum / 8;
573
574 sum = 0;
575
576 for (ctr = 0; ctr < 8; ctr++)
577 {
578
579 set_ccd_channel_101x (dev, CCD300_CHANNEL_GREEN);
580 set_sti (dev);
581 wait_bank_change (dev, priv->bank_count, 1);
582
583 read_line_101x (dev, buf, CCD300_MAXHSIZE, 0, NULL, NULL);
584
585 reset_bank_count (dev);
586
587 sum += buf[3];
588
589 }
590
591 priv->ref_green = sum / 8;
592
593 sum = 0;
594
595 for (ctr = 0; ctr < 8; ctr++)
596 {
597
598 set_ccd_channel_101x (dev, CCD300_CHANNEL_BLUE);
599 set_sti (dev);
600 wait_bank_change (dev, priv->bank_count, 1);
601
602 read_line_101x (dev, buf, CCD300_MAXHSIZE, 0, NULL, NULL);
603
604 reset_bank_count (dev);
605
606 sum += buf[3];
607
608 }
609
610 priv->ref_blue = sum / 8;
611
612 }
613
614
615 static void
max_color_levels_101x(Mustek_pp_Handle * dev)616 max_color_levels_101x (Mustek_pp_Handle * dev)
617 {
618
619 int ctr, line, sum;
620 SANE_Byte rbuf[32][CCD300_MAXHSIZE * 2];
621 SANE_Byte gbuf[32][CCD300_MAXHSIZE * 2];
622 SANE_Byte bbuf[32][CCD300_MAXHSIZE * 2];
623 mustek_pp_ccd300_priv *priv = dev->priv;
624
625 SANE_Byte maxbuf[32];
626
627 for (ctr = 0; ctr < 32; ctr++)
628 {
629
630 if (dev->mode == MODE_COLOR)
631 {
632
633 set_ccd_channel_101x (dev, CCD300_CHANNEL_RED);
634 motor_forward_101x (dev);
635
636 read_average_line_101x (dev, rbuf[ctr], dev->params.pixels_per_line,
637 priv->ref_red);
638
639 set_ccd_channel_101x (dev, CCD300_CHANNEL_GREEN);
640 set_sti (dev);
641
642 read_average_line_101x (dev, gbuf[ctr], dev->params.pixels_per_line,
643 priv->ref_green);
644
645 set_ccd_channel_101x (dev, CCD300_CHANNEL_BLUE);
646 set_sti (dev);
647
648 read_average_line_101x (dev, bbuf[ctr], dev->params.pixels_per_line,
649 priv->ref_blue);
650
651 }
652 else
653 {
654
655 priv->channel = CCD300_CHANNEL_GRAY;
656
657 motor_forward_101x (dev);
658
659 read_average_line_101x (dev, gbuf[ctr], dev->params.pixels_per_line,
660 priv->ref_black);
661
662 }
663
664 }
665
666
667 for (ctr = 0; ctr < dev->params.pixels_per_line; ctr++)
668 {
669 for (line = 0; line < 32; line++)
670 maxbuf[line] = gbuf[line][ctr];
671
672 qsort (maxbuf, 32, sizeof (maxbuf[0]), compar);
673
674 sum = maxbuf[4] + maxbuf[5] + maxbuf[6] + maxbuf[7];
675
676 priv->calib_g[ctr] = sum / 4;
677
678 }
679
680 if (dev->mode == MODE_COLOR)
681 {
682
683 for (ctr = 0; ctr < dev->params.pixels_per_line; ctr++)
684 {
685 for (line = 0; line < 32; line++)
686 maxbuf[line] = rbuf[line][ctr];
687
688 qsort (maxbuf, 32, sizeof (maxbuf[0]), compar);
689
690 sum = maxbuf[4] + maxbuf[5] + maxbuf[6] + maxbuf[7];
691
692 priv->calib_r[ctr] = sum / 4;
693
694 }
695
696 for (ctr = 0; ctr < dev->params.pixels_per_line; ctr++)
697 {
698 for (line = 0; line < 32; line++)
699 maxbuf[line] = bbuf[line][ctr];
700
701 qsort (maxbuf, 32, sizeof (maxbuf[0]), compar);
702
703 sum = maxbuf[4] + maxbuf[5] + maxbuf[6] + maxbuf[7];
704
705 priv->calib_b[ctr] = sum / 4;
706
707 }
708
709 }
710
711 }
712
713 static void
find_black_top_edge_101x(Mustek_pp_Handle * dev)714 find_black_top_edge_101x (Mustek_pp_Handle * dev)
715 {
716
717 int lines = 0, ctr, pos;
718 SANE_Byte buf[CCD300_MAXHSIZE * 2];
719 mustek_pp_ccd300_priv *priv = dev->priv;
720
721 priv->channel = CCD300_CHANNEL_GRAY;
722
723 do
724 {
725
726 motor_forward_101x (dev);
727 wait_bank_change (dev, priv->bank_count, 1);
728
729 read_line_101x (dev, buf, CCD300_MAXHSIZE, priv->ref_black, NULL, NULL);
730
731 reset_bank_count (dev);
732
733 pos = 0;
734
735 for (ctr = priv->blackpos; ctr > priv->blackpos - 10; ctr--)
736 if (buf[ctr] <= 15)
737 pos++;
738
739 }
740 while ((pos >= 8) && (lines++ < 67));
741
742 }
743
744 static void
calibrate_device_101x(Mustek_pp_Handle * dev)745 calibrate_device_101x (Mustek_pp_Handle * dev)
746 {
747
748 int saved_ppl = dev->params.pixels_per_line, ctr;
749 mustek_pp_ccd300_priv *priv = dev->priv;
750
751 priv->saved_mode = dev->mode;
752 priv->saved_invert = dev->invert;
753 priv->saved_skipcount = priv->skipcount;
754 priv->saved_skipimagebyte = priv->skipimagebytes;
755 priv->saved_adjustskip = priv->adjustskip;
756 priv->saved_res = dev->res;
757 priv->saved_hwres = priv->hwres;
758 priv->saved_res_step = priv->res_step;
759 priv->saved_line_step = priv->line_step;
760 priv->saved_channel = priv->channel;
761
762 dev->params.pixels_per_line = CCD300_MAXHSIZE;
763 priv->hwres = dev->res = 300;
764 dev->mode = MODE_GRAYSCALE;
765 priv->skipcount = priv->skipimagebytes = 0;
766 dev->invert = SANE_FALSE;
767 priv->channel = CCD300_CHANNEL_GRAY;
768
769 config_ccd_101x (dev);
770 get_bank_count (dev);
771
772 find_black_side_edge_101x (dev);
773
774 for (ctr = 0; ctr < 4; ctr++)
775 move_motor_101x (dev, SANE_TRUE);
776
777 dev->mode = priv->saved_mode;
778 dev->invert = priv->saved_invert;
779 priv->skipcount = priv->saved_skipcount;
780 priv->skipimagebytes = priv->saved_skipimagebyte;
781 priv->adjustskip = priv->saved_adjustskip;
782 dev->res = priv->saved_res;
783 priv->hwres = priv->saved_hwres;
784 priv->res_step = priv->saved_res_step;
785 priv->line_step = priv->saved_line_step;
786 priv->channel = priv->saved_channel;
787
788 priv->hwres = dev->res = 300;
789 priv->skipcount = priv->skipimagebytes = 0;
790 dev->invert = SANE_FALSE;
791
792 config_ccd_101x (dev);
793 get_bank_count (dev);
794
795 if ((dev->mode == MODE_COLOR) && (priv->ccd_type != 0))
796 min_color_levels_101x (dev);
797
798 dev->mode = priv->saved_mode;
799 dev->invert = priv->saved_invert;
800 priv->skipcount = priv->saved_skipcount;
801 priv->skipimagebytes = priv->saved_skipimagebyte;
802 priv->adjustskip = priv->saved_adjustskip;
803 dev->res = priv->saved_res;
804 priv->hwres = priv->saved_hwres;
805 priv->res_step = priv->saved_res_step;
806 priv->line_step = priv->saved_line_step;
807 priv->channel = priv->saved_channel;
808
809 dev->params.pixels_per_line = saved_ppl;
810 dev->invert = SANE_FALSE;
811
812 config_ccd_101x (dev);
813 get_bank_count (dev);
814
815 max_color_levels_101x (dev);
816
817 dev->params.pixels_per_line = CCD300_MAXHSIZE;
818 dev->mode = MODE_GRAYSCALE;
819 priv->hwres = dev->res = 300;
820 priv->skipcount = priv->skipimagebytes = 0;
821 dev->invert = SANE_FALSE;
822
823 config_ccd_101x (dev);
824 get_bank_count (dev);
825
826 find_black_top_edge_101x (dev);
827
828 dev->mode = priv->saved_mode;
829 dev->invert = priv->saved_invert;
830 priv->skipcount = priv->saved_skipcount;
831 priv->skipimagebytes = priv->saved_skipimagebyte;
832 priv->adjustskip = priv->saved_adjustskip;
833 dev->res = priv->saved_res;
834 priv->hwres = priv->saved_hwres;
835 priv->res_step = priv->saved_res_step;
836 priv->line_step = priv->saved_line_step;
837 priv->channel = priv->saved_channel;
838
839 dev->params.pixels_per_line = saved_ppl;
840
841 config_ccd_101x (dev);
842 get_bank_count (dev);
843
844 }
845
846 static void
get_grayscale_line_101x(Mustek_pp_Handle * dev, SANE_Byte * buf)847 get_grayscale_line_101x (Mustek_pp_Handle * dev, SANE_Byte * buf)
848 {
849
850 int skips;
851 mustek_pp_ccd300_priv *priv = dev->priv;
852
853 priv->line_diff += SANE_FIX (300.0 / (float) dev->res);
854
855 skips = (priv->line_diff >> SANE_FIXED_SCALE_SHIFT);
856
857 while (--skips)
858 {
859 motor_forward_101x (dev);
860 wait_bank_change (dev, priv->bank_count, 1);
861 reset_bank_count (dev);
862 }
863
864 priv->line_diff &= 0xFFFF;
865
866 motor_forward_101x (dev);
867 wait_bank_change (dev, priv->bank_count, 1);
868
869 read_line_101x (dev, buf, dev->params.pixels_per_line, priv->ref_black,
870 priv->calib_g, NULL);
871
872 reset_bank_count (dev);
873
874 }
875
876 static void
get_lineart_line_101x(Mustek_pp_Handle * dev, SANE_Byte * buf)877 get_lineart_line_101x (Mustek_pp_Handle * dev, SANE_Byte * buf)
878 {
879
880 int ctr;
881 SANE_Byte gbuf[CCD300_MAXHSIZE * 2];
882 mustek_pp_ccd300_priv *priv = dev->priv;
883
884 get_grayscale_line_101x (dev, gbuf);
885
886 memset (buf, 0xFF, dev->params.bytes_per_line);
887
888 for (ctr = 0; ctr < dev->params.pixels_per_line; ctr++)
889 buf[ctr >> 3] ^= ((gbuf[ctr] > priv->bw) ? (1 << (7 - ctr % 8)) : 0);
890
891 }
892
893 static void
get_color_line_101x(Mustek_pp_Handle * dev, SANE_Byte * buf)894 get_color_line_101x (Mustek_pp_Handle * dev, SANE_Byte * buf)
895 {
896
897 SANE_Byte *red, *blue, *src, *dest;
898 int gotline = 0, ctr;
899 int gored, goblue, gogreen;
900 mustek_pp_ccd300_priv *priv = dev->priv;
901 int step = priv->line_step;
902
903 do
904 {
905
906 red = priv->red[priv->redline];
907 blue = priv->blue[priv->blueline];
908
909 priv->ccd_line++;
910
911 if ((priv->rdiff >> SANE_FIXED_SCALE_SHIFT) == priv->ccd_line)
912 {
913 gored = 1;
914 priv->rdiff += step;
915 }
916 else
917 gored = 0;
918
919 if ((priv->bdiff >> SANE_FIXED_SCALE_SHIFT) == priv->ccd_line)
920 {
921 goblue = 1;
922 priv->bdiff += step;
923 }
924 else
925 goblue = 0;
926
927 if ((priv->gdiff >> SANE_FIXED_SCALE_SHIFT) == priv->ccd_line)
928 {
929 gogreen = 1;
930 priv->gdiff += step;
931 }
932 else
933 gogreen = 0;
934
935 if (!gored && !goblue && !gogreen)
936 {
937 motor_forward_101x (dev);
938 wait_bank_change (dev, priv->bank_count, 1);
939 reset_bank_count (dev);
940 if (priv->ccd_line >= (priv->line_step >> SANE_FIXED_SCALE_SHIFT))
941 priv->redline = (priv->redline + 1) % priv->green_offs;
942 if (priv->ccd_line >=
943 priv->blue_offs + (priv->line_step >> SANE_FIXED_SCALE_SHIFT))
944 priv->blueline = (priv->blueline + 1) % priv->blue_offs;
945 continue;
946 }
947
948 if (gored)
949 priv->channel = CCD300_CHANNEL_RED;
950 else if (goblue)
951 priv->channel = CCD300_CHANNEL_BLUE;
952 else
953 priv->channel = CCD300_CHANNEL_GREEN;
954
955 motor_forward_101x (dev);
956 wait_bank_change (dev, priv->bank_count, 1);
957
958 if (priv->ccd_line >= priv->green_offs && gogreen)
959 {
960 src = red;
961 dest = buf;
962
963 for (ctr = 0; ctr < dev->params.pixels_per_line; ctr++)
964 {
965 *dest = *src++;
966 dest += 3;
967 }
968 }
969
970 if (gored)
971 {
972
973 read_line_101x (dev, red, dev->params.pixels_per_line,
974 priv->ref_red, priv->calib_r, NULL);
975
976 reset_bank_count (dev);
977
978 }
979
980 priv->redline = (priv->redline + 1) % priv->green_offs;
981
982 if (priv->ccd_line >= priv->green_offs && gogreen)
983 {
984 src = blue;
985 dest = buf + 2;
986
987
988 for (ctr = 0; ctr < dev->params.pixels_per_line; ctr++)
989 {
990 *dest = *src++;
991 dest += 3;
992 }
993
994 }
995
996 if (goblue)
997 {
998 if (gored)
999 {
1000 set_ccd_channel_101x (dev, CCD300_CHANNEL_BLUE);
1001 set_sti (dev);
1002 wait_bank_change (dev, priv->bank_count, 1);
1003 }
1004
1005 read_line_101x (dev, blue, dev->params.pixels_per_line,
1006 priv->ref_blue, priv->calib_b, NULL);
1007
1008 reset_bank_count (dev);
1009
1010 }
1011
1012 if (priv->ccd_line >=
1013 priv->blue_offs + (priv->line_step >> SANE_FIXED_SCALE_SHIFT))
1014 priv->blueline = (priv->blueline + 1) % priv->blue_offs;
1015
1016 if (gogreen)
1017 {
1018
1019 if (gored || goblue)
1020 {
1021 set_ccd_channel_101x (dev, CCD300_CHANNEL_GREEN);
1022 set_sti (dev);
1023 wait_bank_change (dev, priv->bank_count, 1);
1024 }
1025
1026 read_line_101x (dev, priv->green, dev->params.pixels_per_line,
1027 priv->ref_green, priv->calib_g, NULL);
1028
1029 reset_bank_count (dev);
1030
1031 src = priv->green;
1032 dest = buf + 1;
1033
1034 for (ctr = 0; ctr < dev->params.pixels_per_line; ctr++)
1035 {
1036 *dest = *src++;
1037 dest += 3;
1038 }
1039
1040 gotline = 1;
1041 }
1042
1043 }
1044 while (!gotline);
1045
1046 }
1047
1048
1049
1050 /* these functions are for the 1013 chipset */
1051
1052 static void
set_ccd_channel_1013(Mustek_pp_Handle * dev, int channel)1053 set_ccd_channel_1013 (Mustek_pp_Handle * dev, int channel)
1054 {
1055 mustek_pp_ccd300_priv *priv = dev->priv;
1056 priv->channel = channel;
1057 sanei_pa4s2_writebyte (dev->fd, 6, chan_codes_1013[channel]);
1058 }
1059
1060 static void
motor_backward_1013(Mustek_pp_Handle * dev)1061 motor_backward_1013 (Mustek_pp_Handle * dev)
1062 {
1063 mustek_pp_ccd300_priv *priv = dev->priv;
1064
1065 priv->motor_step++;
1066 set_led (dev);
1067
1068 if (priv->motor_phase > 3)
1069 priv->motor_phase = 3;
1070
1071 sanei_pa4s2_writebyte (dev->fd, 6, 0x62);
1072 sanei_pa4s2_writebyte (dev->fd, 5, fullstep[priv->motor_phase]);
1073
1074 priv->motor_phase = (priv->motor_phase == 0 ? 3 : priv->motor_phase - 1);
1075
1076 set_ccd_channel_1013 (dev, priv->channel);
1077 set_sti (dev);
1078
1079 }
1080
1081 static void
return_home_1013(Mustek_pp_Handle * dev)1082 return_home_1013 (Mustek_pp_Handle * dev)
1083 {
1084 u_char ishome;
1085 int ctr;
1086 mustek_pp_ccd300_priv *priv = dev->priv;
1087
1088 /* 1013 can't return home all alone, nowait ignored */
1089
1090 for (ctr = 0; ctr < 4500; ctr++)
1091 {
1092
1093 /* check_is_home_1013 */
1094 sanei_pa4s2_readbegin (dev->fd, 2);
1095 sanei_pa4s2_readbyte (dev->fd, &ishome);
1096 sanei_pa4s2_readend (dev->fd);
1097
1098 /* yes, it should be is_not_home */
1099 if ((ishome & 1) == 0)
1100 break;
1101
1102 motor_backward_1013 (dev);
1103 wait_bank_change (dev, priv->bank_count, 0);
1104 reset_bank_count (dev);
1105
1106 }
1107
1108 }
1109
1110 static void
motor_forward_1013(Mustek_pp_Handle * dev)1111 motor_forward_1013 (Mustek_pp_Handle * dev)
1112 {
1113
1114 int ctr;
1115 mustek_pp_ccd300_priv *priv = dev->priv;
1116
1117 priv->motor_step++;
1118 set_led (dev);
1119
1120 for (ctr = 0; ctr < 2; ctr++)
1121 {
1122
1123 sanei_pa4s2_writebyte (dev->fd, 6, 0x62);
1124 sanei_pa4s2_writebyte (dev->fd, 5, halfstep[priv->motor_phase]);
1125
1126 priv->motor_phase =
1127 (priv->motor_phase == 7 ? 0 : priv->motor_phase + 1);
1128
1129 }
1130
1131 set_ccd_channel_1013 (dev, priv->channel);
1132 set_sti (dev);
1133 }
1134
1135
1136
1137 static void
config_ccd_1013(Mustek_pp_Handle * dev)1138 config_ccd_1013 (Mustek_pp_Handle * dev)
1139 {
1140 mustek_pp_ccd300_priv *priv = dev->priv;
1141
1142 if (dev->res != 0)
1143 priv->res_step = SANE_FIX ((float) priv->hwres / (float) dev->res);
1144
1145 set_dpi_value (dev);
1146
1147 /* set_start_channel_1013 (dev); */
1148
1149 sanei_pa4s2_writebyte (dev->fd, 6, 0x05);
1150
1151 switch (dev->mode)
1152 {
1153 case MODE_BW:
1154 case MODE_GRAYSCALE:
1155 priv->channel = CCD300_CHANNEL_GRAY;
1156 break;
1157
1158 case MODE_COLOR:
1159 priv->channel = CCD300_CHANNEL_RED;
1160 break;
1161
1162 }
1163
1164 set_ccd_channel_1013 (dev, priv->channel);
1165
1166 /* set_invert_1013 (dev); */
1167
1168 sanei_pa4s2_writebyte (dev->fd, 6,
1169 (dev->invert == SANE_TRUE ? 0x04 : 0x14));
1170
1171 sanei_pa4s2_writebyte (dev->fd, 6, 0x37);
1172 reset_bank_count (dev);
1173
1174 sanei_pa4s2_writebyte (dev->fd, 6, 0x27);
1175 sanei_pa4s2_writebyte (dev->fd, 6, 0x67);
1176 sanei_pa4s2_writebyte (dev->fd, 6, 0x17);
1177 sanei_pa4s2_writebyte (dev->fd, 6, 0x77);
1178
1179 /* set_initial_skip_1013 (dev); */
1180
1181 sanei_pa4s2_writebyte (dev->fd, 6, 0x41);
1182
1183 priv->adjustskip = priv->skipcount + priv->skipimagebytes;
1184
1185 DBG (5, "config_ccd_1013: adjustskip %u\n", priv->adjustskip);
1186
1187 sanei_pa4s2_writebyte (dev->fd, 5, priv->adjustskip / 16 + 2);
1188
1189 priv->adjustskip %= 16;
1190
1191 sanei_pa4s2_writebyte (dev->fd, 6, 0x81);
1192 sanei_pa4s2_writebyte (dev->fd, 5, 0x70);
1193 sanei_pa4s2_writebyte (dev->fd, 6, 0x01);
1194
1195
1196 set_line_adjust (dev);
1197
1198 get_bank_count (dev);
1199
1200 }
1201
1202 /* these functions are for the 1015 chipset */
1203
1204
1205 static void
motor_control_1015(Mustek_pp_Handle * dev, u_char control)1206 motor_control_1015 (Mustek_pp_Handle * dev, u_char control)
1207 {
1208 u_char val;
1209
1210 DBG (5, "motor_controll_1015: control code 0x%02x\n",
1211 (unsigned int) control);
1212
1213 sanei_pa4s2_writebyte (dev->fd, 6, 0xF6);
1214 sanei_pa4s2_writebyte (dev->fd, 6, 0x22);
1215 sanei_pa4s2_writebyte (dev->fd, 5, control);
1216 sanei_pa4s2_writebyte (dev->fd, 6, 0x02);
1217
1218 do
1219 {
1220
1221 sanei_pa4s2_readbegin (dev->fd, 2);
1222 sanei_pa4s2_readbyte (dev->fd, &val);
1223 sanei_pa4s2_readend (dev->fd);
1224
1225 }
1226 while ((val & 0x08) != 0);
1227
1228 }
1229
1230 static void
return_home_1015(Mustek_pp_Handle * dev, SANE_Bool nowait)1231 return_home_1015 (Mustek_pp_Handle * dev, SANE_Bool nowait)
1232 {
1233
1234 u_char ishome, control = 0xC3;
1235
1236 motor_control_1015 (dev, control);
1237
1238 do
1239 {
1240
1241 /* check_is_home_1015 */
1242 sanei_pa4s2_readbegin (dev->fd, 2);
1243 sanei_pa4s2_readbyte (dev->fd, &ishome);
1244 sanei_pa4s2_readend (dev->fd);
1245
1246 if (nowait)
1247 break;
1248
1249 usleep (1000); /* much nicer load */
1250
1251 }
1252 while ((ishome & 2) == 0);
1253
1254 }
1255
1256 static void
motor_forward_1015(Mustek_pp_Handle * dev)1257 motor_forward_1015 (Mustek_pp_Handle * dev)
1258 {
1259 u_char control = 0x1B;
1260 mustek_pp_ccd300_priv *priv = dev->priv;
1261
1262 priv->motor_step++;
1263 set_led (dev);
1264
1265
1266 motor_control_1015 (dev, control);
1267
1268 set_ccd_channel_1015 (dev, priv->channel);
1269 set_sti (dev);
1270
1271 }
1272
1273 /*
1274 static void
1275 motor_backward_1015 (Mustek_pp_Handle * dev)
1276 {
1277 u_char control = 0x43;
1278 mustek_pp_ccd300_priv *priv = dev->priv;
1279
1280 priv->motor_step++;
1281
1282 set_led (dev);
1283
1284 switch (priv->ccd_type)
1285 {
1286 case 1:
1287 control = 0x1B;
1288 break;
1289
1290 default:
1291 control = 0x43;
1292 break;
1293 }
1294
1295 motor_control_1015 (dev, control);
1296
1297 set_ccd_channel_1015 (dev, priv->channel);
1298 set_sti (dev);
1299
1300 }
1301 */
1302
1303
1304 static void
set_ccd_channel_1015(Mustek_pp_Handle * dev, int channel)1305 set_ccd_channel_1015 (Mustek_pp_Handle * dev, int channel)
1306 {
1307
1308 u_char chancode = chan_codes_1015[channel];
1309 mustek_pp_ccd300_priv *priv = dev->priv;
1310
1311 priv->channel = channel;
1312
1313 priv->image_control &= 0x34;
1314 chancode |= priv->image_control;
1315
1316
1317 priv->image_control = chancode;
1318
1319 sanei_pa4s2_writebyte (dev->fd, 6, chancode);
1320
1321 }
1322
1323
1324 static void
config_ccd_1015(Mustek_pp_Handle * dev)1325 config_ccd_1015 (Mustek_pp_Handle * dev)
1326 {
1327
1328 u_char val;
1329 mustek_pp_ccd300_priv *priv = dev->priv;
1330
1331 if (dev->res != 0)
1332 priv->res_step = SANE_FIX ((float) priv->hwres / (float) dev->res);
1333
1334
1335 set_dpi_value (dev);
1336
1337 priv->image_control = 4;
1338
1339 /* set_start_channel_1015 (dev); */
1340
1341 switch (dev->mode)
1342 {
1343 case MODE_BW:
1344 case MODE_GRAYSCALE:
1345 priv->channel = CCD300_CHANNEL_GRAY;
1346 break;
1347
1348 case MODE_COLOR:
1349 priv->channel = CCD300_CHANNEL_RED;
1350 break;
1351
1352 }
1353
1354 set_ccd_channel_1015 (dev, priv->channel);
1355
1356
1357 /* set_invert_1015 (dev); */
1358
1359 priv->image_control &= 0xE4;
1360
1361 if (dev->invert == SANE_FALSE)
1362 priv->image_control |= 0x10;
1363
1364
1365 sanei_pa4s2_writebyte (dev->fd, 6, priv->image_control);
1366
1367 sanei_pa4s2_writebyte (dev->fd, 6, 0x23);
1368 sanei_pa4s2_writebyte (dev->fd, 5, 0x00);
1369
1370 sanei_pa4s2_writebyte (dev->fd, 6, 0x43);
1371
1372 switch (priv->ccd_type)
1373 {
1374 case 1:
1375 val = 0x6B;
1376 break;
1377 case 4:
1378 val = 0x9F;
1379 break;
1380 default:
1381 val = 0x92;
1382 break;
1383 }
1384
1385 sanei_pa4s2_writebyte (dev->fd, 5, val);
1386 sanei_pa4s2_writebyte (dev->fd, 6, 0x03);
1387
1388 sanei_pa4s2_writebyte (dev->fd, 6, 0x37);
1389 reset_bank_count (dev);
1390
1391 sanei_pa4s2_writebyte (dev->fd, 6, 0x27);
1392 sanei_pa4s2_writebyte (dev->fd, 6, 0x67);
1393 sanei_pa4s2_writebyte (dev->fd, 6, 0x17);
1394 sanei_pa4s2_writebyte (dev->fd, 6, 0x77);
1395
1396 /* set_initial_skip_1015 (dev); */
1397
1398 sanei_pa4s2_writebyte (dev->fd, 6, 0x41);
1399
1400 priv->adjustskip = priv->skipcount + priv->skipimagebytes;
1401
1402 /* if (dev->CCD.mode == MODE_COLOR)
1403 dev->CCD.adjustskip <<= 3; */
1404
1405
1406 sanei_pa4s2_writebyte (dev->fd, 5, priv->adjustskip / 32 + 1);
1407
1408 priv->adjustskip %= 32;
1409
1410
1411 sanei_pa4s2_writebyte (dev->fd, 6, 0x81);
1412
1413 /* expose time */
1414 switch (priv->ccd_type)
1415 {
1416 case 1:
1417
1418 val = 0xA8;
1419 break;
1420 case 0:
1421 val = 0x8A;
1422 break;
1423 default:
1424 val = 0xA8;
1425 break;
1426 }
1427
1428 sanei_pa4s2_writebyte (dev->fd, 5, val);
1429
1430 sanei_pa4s2_writebyte (dev->fd, 6, 0x01);
1431
1432
1433 set_line_adjust (dev);
1434
1435 get_bank_count (dev);
1436
1437 }
1438
1439
1440 /* these functions are interfaces only */
1441 static void
config_ccd(Mustek_pp_Handle * dev)1442 config_ccd (Mustek_pp_Handle * dev)
1443 {
1444 mustek_pp_ccd300_priv *priv = dev->priv;
1445
1446 DBG (5, "config_ccd: %d dpi, mode %d, invert %d, size %d\n",
1447 priv->hwres, dev->mode, dev->invert, dev->params.pixels_per_line);
1448
1449 switch (priv->asic)
1450 {
1451 case CCD300_ASIC1013:
1452 config_ccd_1013 (dev);
1453 break;
1454
1455 case CCD300_ASIC1015:
1456 config_ccd_1015 (dev);
1457 break;
1458 }
1459
1460 }
1461
1462 static void
return_home(Mustek_pp_Handle * dev, SANE_Bool nowait)1463 return_home (Mustek_pp_Handle * dev, SANE_Bool nowait)
1464 {
1465 mustek_pp_ccd300_priv *priv = dev->priv;
1466
1467 priv->saved_mode = dev->mode;
1468 priv->saved_invert = dev->invert;
1469 priv->saved_skipcount = priv->skipcount;
1470 priv->saved_skipimagebyte = priv->skipimagebytes;
1471 priv->saved_adjustskip = priv->adjustskip;
1472 priv->saved_res = dev->res;
1473 priv->saved_hwres = priv->hwres;
1474 priv->saved_res_step = priv->res_step;
1475 priv->saved_line_step = priv->line_step;
1476 priv->saved_channel = priv->channel;
1477
1478
1479 priv->hwres = dev->res = 100;
1480 dev->mode = MODE_GRAYSCALE;
1481
1482 priv->skipcount = priv->skipimagebytes = 0;
1483
1484 config_ccd (dev);
1485
1486 switch (priv->asic)
1487 {
1488 case CCD300_ASIC1013:
1489 return_home_1013 (dev);
1490 break;
1491
1492 case CCD300_ASIC1015:
1493 return_home_1015 (dev, nowait);
1494 break;
1495 }
1496
1497
1498 dev->mode = priv->saved_mode;
1499 dev->invert = priv->saved_invert;
1500 priv->skipcount = priv->saved_skipcount;
1501 priv->skipimagebytes = priv->saved_skipimagebyte;
1502 priv->adjustskip = priv->saved_adjustskip;
1503 dev->res = priv->saved_res;
1504 priv->hwres = priv->saved_hwres;
1505 priv->res_step = priv->saved_res_step;
1506 priv->line_step = priv->saved_line_step;
1507 priv->channel = priv->saved_channel;
1508 priv->motor_step = 0;
1509
1510 config_ccd (dev);
1511 }
1512
1513 static void
lamp(Mustek_pp_Handle * dev, int lamp_on)1514 lamp (Mustek_pp_Handle * dev, int lamp_on)
1515 {
1516
1517 set_lamp (dev, lamp_on);
1518
1519 }
1520
1521 static void
set_voltages(Mustek_pp_Handle * dev)1522 set_voltages (Mustek_pp_Handle * dev)
1523 {
1524 send_voltages (dev);
1525 }
1526
1527 static void
move_motor(Mustek_pp_Handle * dev, int count, int forward)1528 move_motor (Mustek_pp_Handle * dev, int count, int forward)
1529 {
1530
1531 int ctr;
1532
1533 DBG (5, "move_motor: %u steps (%s)\n", count,
1534 (forward == SANE_TRUE ? "forward" : "backward"));
1535
1536
1537 for (ctr = 0; ctr < count; ctr++)
1538 {
1539
1540 move_motor_101x (dev, forward);
1541
1542 }
1543
1544
1545 }
1546
1547 static void
calibrate(Mustek_pp_Handle * dev)1548 calibrate (Mustek_pp_Handle * dev)
1549 {
1550 mustek_pp_ccd300_priv *priv = dev->priv;
1551
1552 DBG (5, "calibrate entered (asic = 0x%02x)\n", priv->asic);
1553
1554 calibrate_device_101x (dev);
1555
1556 DBG (5, "calibrate: ref_black %d, blackpos %d\n",
1557 priv->ref_black, priv->blackpos);
1558
1559 }
1560
1561
1562 static void
get_lineart_line(Mustek_pp_Handle * dev, SANE_Byte * buf)1563 get_lineart_line (Mustek_pp_Handle * dev, SANE_Byte * buf)
1564 {
1565 get_lineart_line_101x (dev, buf);
1566 }
1567
1568 static void
get_grayscale_line(Mustek_pp_Handle * dev, SANE_Byte * buf)1569 get_grayscale_line (Mustek_pp_Handle * dev, SANE_Byte * buf)
1570 {
1571
1572 get_grayscale_line_101x (dev, buf);
1573 }
1574
1575 static void
get_color_line(Mustek_pp_Handle * dev, SANE_Byte * buf)1576 get_color_line (Mustek_pp_Handle * dev, SANE_Byte * buf)
1577 {
1578
1579 get_color_line_101x (dev, buf);
1580
1581 }
1582
1583
1584 static SANE_Status
ccd300_init(SANE_Int options, SANE_String_Const port, SANE_String_Const name, SANE_Attach_Callback attach)1585 ccd300_init (SANE_Int options, SANE_String_Const port,
1586 SANE_String_Const name, SANE_Attach_Callback attach)
1587 {
1588 SANE_Status status;
1589 unsigned char asic, ccd;
1590 int fd;
1591
1592 if (options != CAP_NOTHING)
1593 {
1594 DBG (1, "ccd300_init: called with unknown options (%#02x)\n", options);
1595 return SANE_STATUS_INVAL;
1596 }
1597
1598 /* try to attach to he supplied port */
1599 status = sanei_pa4s2_open (port, &fd);
1600
1601 if (status != SANE_STATUS_GOOD)
1602 {
1603 DBG (2, "ccd300_init: couldn't attach to port ``%s'' (%s)\n",
1604 port, sane_strstatus (status));
1605 return status;
1606 }
1607
1608 sanei_pa4s2_enable (fd, SANE_TRUE);
1609 sanei_pa4s2_readbegin (fd, 0);
1610 sanei_pa4s2_readbyte (fd, &asic);
1611 sanei_pa4s2_readend (fd);
1612 sanei_pa4s2_readbegin (fd, 2);
1613 sanei_pa4s2_readbyte (fd, &ccd);
1614 sanei_pa4s2_readend (fd);
1615 sanei_pa4s2_enable (fd, SANE_FALSE);
1616 sanei_pa4s2_close (fd);
1617
1618 if (asic != CCD300_ASIC1013 && asic != CCD300_ASIC1015)
1619 {
1620 DBG (2, "ccd300_init: scanner not recognized (unknown ASIC id %#02x)\n",
1621 asic);
1622 return SANE_STATUS_INVAL;
1623 }
1624
1625 ccd &= (asic == CCD300_ASIC1013 ? 0x04 : 0x05);
1626
1627 DBG (3, "ccd_init: found scanner on port ``%s'' (ASIC id %#02x, CCD %d)\n",
1628 port, asic, ccd);
1629
1630 return attach (port, name, MUSTEK_PP_CCD300, options);
1631
1632 }
1633
1634 static void
ccd300_capabilities(SANE_Int info, SANE_String * model, SANE_String * vendor, SANE_String * type, SANE_Int * maxres, SANE_Int * minres, SANE_Int * maxhsize, SANE_Int * maxvsize, SANE_Int * caps)1635 ccd300_capabilities (SANE_Int info, SANE_String * model,
1636 SANE_String * vendor, SANE_String * type,
1637 SANE_Int * maxres, SANE_Int * minres,
1638 SANE_Int * maxhsize, SANE_Int * maxvsize,
1639 SANE_Int * caps)
1640 {
1641 *model = strdup ("600 III EP Plus");
1642 *vendor = strdup ("Mustek");
1643 *type = strdup ("flatbed (CCD 300 dpi)");
1644 DBG (3,
1645 "ccd300_capabilities: 600 III EP Plus flatbed CCD (300 dpi) scanner\n");
1646
1647 *maxres = 300;
1648 *minres = 50;
1649 *maxhsize = CCD300_MAXHSIZE;
1650 *maxvsize = CCD300_MAXVSIZE;
1651 *caps = info | CAP_INVERT | CAP_LAMP_OFF;
1652 }
1653
1654 static SANE_Status
ccd300_open(SANE_String port, SANE_Int caps, SANE_Int * fd)1655 ccd300_open (SANE_String port, SANE_Int caps, SANE_Int * fd)
1656 {
1657 SANE_Status status;
1658
1659 if (caps & ~(CAP_NOTHING | CAP_INVERT | CAP_LAMP_OFF))
1660 {
1661 DBG (1, "ccd300_open: called with unknown capabilities (%#02x)\n",
1662 caps);
1663 return SANE_STATUS_INVAL;
1664 }
1665
1666 DBG (3, "ccd300_open: called for port ``%s''\n", port);
1667
1668 status = sanei_pa4s2_open (port, fd);
1669
1670 if (status != SANE_STATUS_GOOD)
1671 DBG (2, "ccd300_open: open failed (%s)\n", sane_strstatus (status));
1672
1673 return status;
1674 }
1675
1676 static void
ccd300_setup(SANE_Handle handle)1677 ccd300_setup (SANE_Handle handle)
1678 {
1679 Mustek_pp_Handle *dev = handle;
1680 mustek_pp_ccd300_priv *priv;
1681 unsigned char asic, ccd;
1682
1683 DBG (3, "ccd300_setup: called for port ``%s''\n", dev->dev->port);
1684
1685 if ((priv = malloc (sizeof (mustek_pp_ccd300_priv))) == NULL)
1686 {
1687 DBG (1, "ccd300_setup: not enough memory\n");
1688 return; /* can you here the shit hitting the fan? */
1689 }
1690
1691 dev->priv = priv;
1692 memset (priv, 0, sizeof (mustek_pp_ccd300_priv));
1693
1694 priv->bw = 128;
1695 priv->wait_bank = 700;
1696 priv->top = 47;
1697
1698 sanei_pa4s2_enable (dev->fd, SANE_TRUE);
1699
1700 sanei_pa4s2_readbegin (dev->fd, 0);
1701 sanei_pa4s2_readbyte (dev->fd, &asic);
1702 sanei_pa4s2_readend (dev->fd);
1703 sanei_pa4s2_readbegin (dev->fd, 2);
1704 sanei_pa4s2_readbyte (dev->fd, &ccd);
1705 sanei_pa4s2_readend (dev->fd);
1706 ccd &= (asic == CCD300_ASIC1013 ? 0x04 : 0x05);
1707 priv->asic = asic;
1708 priv->ccd_type = ccd;
1709
1710 return_home (dev, SANE_TRUE);
1711 lamp (dev, SANE_TRUE);
1712 sanei_pa4s2_enable (dev->fd, SANE_FALSE);
1713 dev->lamp_on = time (NULL);
1714 dev->res = priv->hwres = 300;
1715 dev->mode = MODE_COLOR;
1716 }
1717
1718 static void
ccd300_close(SANE_Handle handle)1719 ccd300_close (SANE_Handle handle)
1720 {
1721
1722 Mustek_pp_Handle *dev = handle;
1723 mustek_pp_ccd300_priv *priv = dev->priv;
1724
1725 DBG (3, "ccd300_close: called for port ``%s''\n", dev->dev->port);
1726
1727 sanei_pa4s2_enable (dev->fd, SANE_TRUE);
1728 lamp (dev, SANE_FALSE);
1729 return_home (dev, SANE_FALSE);
1730 sanei_pa4s2_enable (dev->fd, SANE_FALSE);
1731
1732 sanei_pa4s2_close (dev->fd);
1733 free (priv);
1734
1735 DBG (3, "ccd300_close: device shut down and all buffers freed\n");
1736 }
1737
1738 static SANE_Status
ccd300_config(SANE_Handle handle, SANE_String_Const optname, SANE_String_Const optval)1739 ccd300_config (SANE_Handle handle, SANE_String_Const optname,
1740 SANE_String_Const optval)
1741 {
1742 Mustek_pp_Handle *dev = handle;
1743 mustek_pp_ccd300_priv *priv = dev->priv;
1744 int value = -1;
1745
1746 DBG (3, "ccd300_config: called for port ``%s'' (%s%s%s)\n",
1747 dev->dev->port,
1748 optname, (optval ? " = " : ""), (optval ? optval : ""));
1749
1750 if (!strcmp (optname, "bw"))
1751 {
1752
1753 if (!optval)
1754 {
1755 DBG (1, "ccd300_config: missing value for option ``bw''\n");
1756 return SANE_STATUS_INVAL;
1757 }
1758
1759 /* ok, ok, should be strtol... know what? send me a patch. */
1760 value = atoi (optval);
1761
1762 if ((value < 0) || (value > 255))
1763 {
1764 DBG (1,
1765 "ccd300_config: value ``%s'' for option ``bw'' is out of range (0 <= bw <= 255)\n",
1766 optval);
1767 return SANE_STATUS_INVAL;
1768 }
1769
1770 priv->bw = value;
1771
1772 }
1773 else if (!strcmp (optname, "waitbank"))
1774 {
1775
1776 if (!optval)
1777 {
1778 DBG (1, "ccd300_config: missing value for option ``waitbank''\n");
1779 return SANE_STATUS_INVAL;
1780 }
1781
1782 value = atoi (optval);
1783
1784 if (value < 0)
1785 {
1786 DBG (1,
1787 "ccd300_config: value ``%s'' for option ``waitbank'' is out of range (>= 0)\n",
1788 optval);
1789 return SANE_STATUS_INVAL;
1790 }
1791
1792 priv->wait_bank = value;
1793 }
1794 else if (!strcmp (optname, "top"))
1795 {
1796
1797 if (!optval)
1798 {
1799 DBG (1, "ccd300_config: missing value for option ``top''\n");
1800 return SANE_STATUS_INVAL;
1801 }
1802
1803 value = atoi (optval);
1804
1805 if (value < 0)
1806 {
1807 DBG (1,
1808 "ccd300_config: value ``%s'' for option ``top'' is out of range (>= 0)\n",
1809 optval);
1810 return SANE_STATUS_INVAL;
1811 }
1812
1813 priv->top = value;
1814 }
1815 else
1816 {
1817 DBG (1, "ccd300_config: unknown option ``%s''", optname);
1818 return SANE_STATUS_INVAL;
1819 }
1820
1821 return SANE_STATUS_GOOD;
1822
1823 }
1824
1825 static void
ccd300_stop(SANE_Handle handle)1826 ccd300_stop (SANE_Handle handle)
1827 {
1828 Mustek_pp_Handle *dev = handle;
1829 mustek_pp_ccd300_priv *priv = dev->priv;
1830 int cnt;
1831
1832 DBG (3, "ccd300_stop: stopping scan operating on port ``%s''\n",
1833 dev->dev->port);
1834
1835 sanei_pa4s2_enable (dev->fd, SANE_TRUE);
1836 return_home (dev, SANE_TRUE);
1837 sanei_pa4s2_enable (dev->fd, SANE_FALSE);
1838
1839 free (priv->calib_r);
1840 free (priv->calib_g);
1841 free (priv->calib_b);
1842
1843 if (priv->red)
1844 {
1845 for (cnt = 0; cnt < priv->green_offs; cnt++)
1846 free (priv->red[cnt]);
1847 free (priv->red);
1848 }
1849 if (priv->blue)
1850 {
1851 for (cnt = 0; cnt < priv->blue_offs; cnt++)
1852 free (priv->blue[cnt]);
1853 free (priv->blue);
1854 }
1855 free (priv->green);
1856
1857 priv->calib_r = priv->calib_g = priv->calib_b = NULL;
1858 priv->red = priv->blue = NULL;
1859 priv->green = NULL;
1860
1861 }
1862
1863 static SANE_Status
ccd300_start(SANE_Handle handle)1864 ccd300_start (SANE_Handle handle)
1865 {
1866 Mustek_pp_Handle *dev = handle;
1867 mustek_pp_ccd300_priv *priv = dev->priv;
1868
1869 DBG (3, "ccd300_start: called for port ``%s''\n", dev->dev->port);
1870
1871 if (dev->res <= 100)
1872 priv->hwres = 100;
1873 else if (dev->res <= 200)
1874 priv->hwres = 200;
1875 else if (dev->res <= 300)
1876 priv->hwres = 300;
1877
1878 DBG (4, "ccd300_start: setting hardware resolution to %d dpi\n",
1879 priv->hwres);
1880
1881 priv->skipimagebytes = dev->topX;
1882
1883 sanei_pa4s2_enable (dev->fd, SANE_TRUE);
1884 config_ccd (dev);
1885 set_voltages (dev);
1886 get_bank_count (dev);
1887
1888 if (priv->bank_count != 0)
1889 {
1890 DBG (2, "ccd300_start: bank count is not zero...\n");
1891 }
1892
1893 return_home (dev, SANE_FALSE);
1894
1895 priv->motor_step = 0;
1896
1897 /* allocate memory for calibration */
1898 if ((priv->calib_g = malloc (dev->params.pixels_per_line)) == NULL)
1899 {
1900 sanei_pa4s2_enable (dev->fd, SANE_FALSE);
1901 DBG (1, "ccd300_start: not enough memory\n");
1902 return SANE_STATUS_NO_MEM;
1903 }
1904
1905 if (dev->mode == MODE_COLOR)
1906 {
1907 priv->calib_r = malloc (dev->params.pixels_per_line);
1908 priv->calib_b = malloc (dev->params.pixels_per_line);
1909
1910 if ((priv->calib_r == NULL) || (priv->calib_b == NULL))
1911 {
1912 free (priv->calib_g);
1913 free (priv->calib_r);
1914 free (priv->calib_b);
1915 priv->calib_r = priv->calib_g = priv->calib_b = NULL;
1916
1917 sanei_pa4s2_enable (dev->fd, SANE_FALSE);
1918 DBG (1, "ccd300_start: not enough memory\n");
1919 return SANE_STATUS_NO_MEM;
1920 }
1921 }
1922
1923 calibrate (dev);
1924
1925 if (priv->ccd_type == 1)
1926 {
1927 priv->blue_offs = 4;
1928 priv->green_offs = 8;
1929 }
1930 else
1931 {
1932 priv->blue_offs = 8;
1933 priv->green_offs = 16;
1934 }
1935
1936 move_motor (dev, priv->top + dev->topY -
1937 (dev->mode == MODE_COLOR ? priv->green_offs : 0), SANE_TRUE);
1938
1939 if (priv->ccd_type == 1)
1940 sanei_pa4s2_writebyte (dev->fd, 6, 0x15);
1941
1942 sanei_pa4s2_enable (dev->fd, SANE_FALSE);
1943
1944 if (dev->mode == MODE_COLOR)
1945 {
1946 int failed = SANE_FALSE, cnt;
1947
1948 priv->line_step = SANE_FIX (300.0 / (float) dev->res);
1949 priv->rdiff = priv->line_step;
1950 priv->bdiff = priv->rdiff + (priv->blue_offs << SANE_FIXED_SCALE_SHIFT);
1951 priv->gdiff =
1952 priv->rdiff + (priv->green_offs << SANE_FIXED_SCALE_SHIFT);
1953
1954 priv->red = malloc (sizeof (SANE_Byte *) * priv->green_offs);
1955 priv->blue = malloc (sizeof (SANE_Byte *) * priv->blue_offs);
1956 priv->green = malloc (dev->params.pixels_per_line);
1957
1958 if ((priv->red == NULL) || (priv->blue == NULL)
1959 || (priv->green == NULL))
1960 {
1961 free (priv->calib_r);
1962 free (priv->calib_g);
1963 free (priv->calib_b);
1964 priv->calib_r = priv->calib_g = priv->calib_b = NULL;
1965
1966 free (priv->red);
1967 free (priv->green);
1968 free (priv->blue);
1969 priv->red = priv->blue = NULL;
1970 priv->green = NULL;
1971
1972 DBG (1, "ccd300_start: not enough memory for ld buffers\n");
1973 return SANE_STATUS_NO_MEM;
1974 }
1975
1976 /* note to myself: better allocate one huge chunk of memory and set
1977 pointers */
1978 for (cnt = 0; cnt < priv->green_offs; cnt++)
1979 if ((priv->red[cnt] = malloc (dev->params.pixels_per_line)) == NULL)
1980 failed = SANE_TRUE;
1981
1982 for (cnt = 0; cnt < priv->blue_offs; cnt++)
1983 if ((priv->blue[cnt] = malloc (dev->params.pixels_per_line)) == NULL)
1984 failed = SANE_TRUE;
1985
1986 if (failed == SANE_TRUE)
1987 {
1988 free (priv->calib_r);
1989 free (priv->calib_g);
1990 free (priv->calib_b);
1991 priv->calib_r = priv->calib_g = priv->calib_b = NULL;
1992
1993 for (cnt = 0; cnt < priv->green_offs; cnt++)
1994 free (priv->red[cnt]);
1995 for (cnt = 0; cnt < priv->blue_offs; cnt++)
1996 free (priv->blue[cnt]);
1997
1998 free (priv->red);
1999 free (priv->green);
2000 free (priv->blue);
2001 priv->red = priv->blue = NULL;
2002 priv->green = NULL;
2003
2004 DBG (1, "ccd300_start: not enough memory for ld buffers\n");
2005 return SANE_STATUS_NO_MEM;
2006 }
2007
2008 priv->redline = priv->blueline = priv->ccd_line = 0;
2009 }
2010
2011 priv->lines = 0;
2012 priv->lines_left = dev->params.lines;
2013
2014 DBG (3, "ccd300_start: device ready for scanning\n");
2015
2016 return SANE_STATUS_GOOD;
2017 }
2018
2019 static void
ccd300_read(SANE_Handle handle, SANE_Byte * buffer)2020 ccd300_read (SANE_Handle handle, SANE_Byte * buffer)
2021 {
2022 Mustek_pp_Handle *dev = handle;
2023 mustek_pp_ccd300_priv *priv = dev->priv;
2024
2025 DBG (3, "ccd300_read: receiving one line from port ``%s''\n",
2026 dev->dev->port);
2027
2028 sanei_pa4s2_enable (dev->fd, SANE_TRUE);
2029
2030 switch (dev->mode)
2031 {
2032 case MODE_BW:
2033 get_lineart_line (dev, buffer);
2034 break;
2035
2036 case MODE_GRAYSCALE:
2037 get_grayscale_line (dev, buffer);
2038 break;
2039
2040 case MODE_COLOR:
2041 get_color_line (dev, buffer);
2042 break;
2043 }
2044
2045 priv->lines_left--;
2046 priv->lines++;
2047
2048 DBG (4, "ccd300_read: %d lines read (%d to go)\n", priv->lines,
2049 priv->lines_left);
2050
2051 if (priv->lines_left == 0)
2052 {
2053 DBG (3, "ccd300_read: scan finished\n");
2054 return_home (dev, SANE_TRUE);
2055 }
2056
2057 sanei_pa4s2_enable (dev->fd, SANE_FALSE);
2058
2059 }
2060