1
/* sane - Scanner Access Now Easy.
3
Copyright (C) 2010 St�phane Voltz <stef.dev@free.fr>
6
This file is part of the SANE package.
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.
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.
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23
As a special exception, the authors of SANE give permission for
24
additional uses of the libraries contained in this release of SANE.
26
The exception is that, if you link a SANE library with other files
27
to produce an executable, this does not by itself cause the
28
resulting executable to be covered by the GNU General Public
29
License. Your use of that executable is in no way restricted on
30
account of linking the SANE library code into it.
32
This exception does not, however, invalidate any other reasons why
33
the executable file might be covered by the GNU General Public
36
If you submit changes to SANE to the maintainers to be included in
37
a subsequent release, you agree by submitting the changes that
38
those changes may be distributed with this exception intact.
40
If you write modifications of your own for SANE, it is your choice
41
whether to permit this exception to apply to your modifications.
42
If you do not wish that, delete this exception notice.
45
#include "genesys_gl847.h"
47
/****************************************************************************
49
****************************************************************************/
52
* decodes and prints content of status (0x41) register
53
* @param val value read from reg41
56
print_status (uint8_t val)
60
sprintf (msg, "%s%s%s%s%s%s%s%s",
61
val & REG41_PWRBIT ? "PWRBIT " : "",
62
val & REG41_BUFEMPTY ? "BUFEMPTY " : "",
63
val & REG41_FEEDFSH ? "FEEDFSH " : "",
64
val & REG41_SCANFSH ? "SCANFSH " : "",
65
val & REG41_HOMESNR ? "HOMESNR " : "",
66
val & REG41_LAMPSTS ? "LAMPSTS " : "",
67
val & REG41_FEBUSY ? "FEBUSY " : "",
68
val & REG41_MOTORENB ? "MOTORENB" : "");
69
DBG (DBG_info, "status=%s\n", msg);
72
/* ------------------------------------------------------------------------ */
73
/* Read and write RAM, registers and AFE */
74
/* ------------------------------------------------------------------------ */
77
* Write to many GL847 registers at once
78
* Note: sequential call to write register, no effective
79
* bulk write implemented.
80
* @param dev device to write to
81
* @param reg pointer to an array of registers
82
* @param elems size of the array
88
gl847_bulk_write_register (Genesys_Device * dev,
89
Genesys_Register_Set * reg, size_t elems)
91
SANE_Status status = SANE_STATUS_GOOD;
94
for (i = 0; i < elems && status == SANE_STATUS_GOOD; i++)
96
if (reg[i].address != 0)
99
sanei_genesys_write_register (dev, reg[i].address, reg[i].value);
103
DBG (DBG_io, "gl847_bulk_write_register: wrote %lu registers\n",
108
/** @brief read scanned data
109
* Read in 0xeff0 maximum sized blocks. This read is done in 2
110
* parts if not multple of 512. First read is rounded to a multiple of 512 bytes, last read fetches the
111
* remainder. Read addr is always 0x10000000 with the memory layout setup.
112
* @param dev device to read data from
113
* @param addr address within ASIC emory space
114
* @param data pointer where to store the read data
115
* @param len size to read
118
gl847_bulk_read_data (Genesys_Device * dev, uint8_t addr,
119
uint8_t * data, size_t len)
122
size_t size, target, read, done;
125
DBG (DBG_io, "gl847_bulk_read_data: requesting %lu bytes\n", (u_long) len);
128
return SANE_STATUS_GOOD;
132
/* loop until computed data size is read */
144
/* hard coded 0x10000000 addr */
150
/* data size to transfer */
151
outdata[4] = (size & 0xff);
152
outdata[5] = ((size >> 8) & 0xff);
153
outdata[6] = ((size >> 16) & 0xff);
154
outdata[7] = ((size >> 24) & 0xff);
157
sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_BUFFER,
158
VALUE_BUFFER, 0x00, sizeof (outdata),
160
if (status != SANE_STATUS_GOOD)
162
DBG (DBG_error, "%s failed while writing command: %s\n",
163
__FUNCTION__, sane_strstatus (status));
167
/* blocks must be multiple of 512 but not last block */
176
"gl847_bulk_read_data: trying to read %lu bytes of data\n",
178
status = sanei_usb_read_bulk (dev->dn, data, &read);
179
if (status != SANE_STATUS_GOOD)
182
"gl847_bulk_read_data failed while reading bulk data: %s\n",
183
sane_strstatus (status));
187
/* read less than 512 bytes remainder */
193
"gl847_bulk_read_data: trying to read %lu bytes of data\n",
195
status = sanei_usb_read_bulk (dev->dn, data+done, &read);
196
if (status != SANE_STATUS_GOOD)
199
"gl847_bulk_read_data failed while reading bulk data: %s\n",
200
sane_strstatus (status));
205
DBG (DBG_io2, "%s: read %lu bytes, %lu remaining\n", __FUNCTION__,
206
(u_long) size, (u_long) (target - size));
214
return SANE_STATUS_GOOD;
217
/****************************************************************************
219
****************************************************************************/
222
gl847_get_fast_feed_bit (Genesys_Register_Set * regs)
224
Genesys_Register_Set *r = NULL;
226
r = sanei_genesys_get_address (regs, REG02);
227
if (r && (r->value & REG02_FASTFED))
233
gl847_get_filter_bit (Genesys_Register_Set * regs)
235
Genesys_Register_Set *r = NULL;
237
r = sanei_genesys_get_address (regs, REG04);
238
if (r && (r->value & REG04_FILTER))
244
gl847_get_lineart_bit (Genesys_Register_Set * regs)
246
Genesys_Register_Set *r = NULL;
248
r = sanei_genesys_get_address (regs, REG04);
249
if (r && (r->value & REG04_LINEART))
255
gl847_get_bitset_bit (Genesys_Register_Set * regs)
257
Genesys_Register_Set *r = NULL;
259
r = sanei_genesys_get_address (regs, REG04);
260
if (r && (r->value & REG04_BITSET))
266
gl847_get_gain4_bit (Genesys_Register_Set * regs)
268
Genesys_Register_Set *r = NULL;
270
r = sanei_genesys_get_address (regs, 0x06);
271
if (r && (r->value & REG06_GAIN4))
277
gl847_test_buffer_empty_bit (SANE_Byte val)
279
if (val & REG41_BUFEMPTY)
285
gl847_test_motor_flag_bit (SANE_Byte val)
287
if (val & REG41_MOTORENB)
293
/** @brief sensor specific settings
296
gl847_setup_sensor (Genesys_Device * dev, Genesys_Register_Set * regs)
298
Genesys_Register_Set *r;
303
for (i = 0x06; i < 0x0e; i++)
305
r = sanei_genesys_get_address (regs, 0x10 + i);
307
r->value = dev->sensor.regs_0x10_0x1d[i];
310
for (i = 0; i < 9; i++)
312
r = sanei_genesys_get_address (regs, 0x52 + i);
314
r->value = dev->sensor.regs_0x52_0x5e[i];
321
/* returns the max register bulk size */
323
gl847_bulk_full_size (void)
325
return GENESYS_GL847_MAX_REGS;
328
/** @brief set all registers to default values .
329
* This function is called only once at the beginning and
330
* fills register startup values for registers reused across scans.
331
* Those that are rarely modified or not modified are written
333
* @param dev device structure holding register set to initialize
336
gl847_init_registers (Genesys_Device * dev)
341
GENESYS_GL847_MAX_REGS * sizeof (Genesys_Register_Set));
348
SETREG (0x06, 0x50); /* FASTMODE + POWERBIT */
354
/* SETREG (0x0d, REG0D_CLRMCNT); */
424
/* NOTE: autoconf is a non working option */
427
SETREG (0x9d, 0x00); /* 1x multiplier instead of 8x */
433
/* gamma[0] and gamma[256] values */
442
/* fine tune upon device description */
443
dev->reg[reg_0x05].value &= ~REG05_DPIHW;
444
switch (dev->sensor.optical_res)
447
dev->reg[reg_0x05].value |= REG05_DPIHW_600;
450
dev->reg[reg_0x05].value |= REG05_DPIHW_1200;
453
dev->reg[reg_0x05].value |= REG05_DPIHW_2400;
456
dev->reg[reg_0x05].value |= REG05_DPIHW_4800;
460
/* initalize calibration reg */
461
memcpy (dev->calib_reg, dev->reg,
462
GENESYS_GL847_MAX_REGS * sizeof (Genesys_Register_Set));
467
/**@brief send slope table for motor movement
468
* Send slope_table in machine byte order
469
* @param dev device to send slope table
470
* @param table_nr index of the slope table in ASIC memory
471
* Must be in the [0-4] range.
472
* @param slope_table pointer to 16 bit values array of the slope table
473
* @param steps number of elemnts in the slope table
476
gl847_send_slope_table (Genesys_Device * dev, int table_nr,
477
uint16_t * slope_table, int steps)
484
DBG (DBG_proc, "%s (table_nr = %d, steps = %d)\n", __FUNCTION__,
488
if(table_nr<0 || table_nr>4)
490
DBG (DBG_error, "%s: invalid table number %d!\n", __FUNCTION__, table_nr);
491
return SANE_STATUS_INVAL;
494
table = (uint8_t *) malloc (steps * 2);
495
for (i = 0; i < steps; i++)
497
table[i * 2] = slope_table[i] & 0xff;
498
table[i * 2 + 1] = slope_table[i] >> 8;
501
if (DBG_LEVEL >= DBG_io)
503
sprintf (msg, "write slope %d (%d)=", table_nr, steps);
504
for (i = 0; i < steps; i++)
506
sprintf (msg, "%s,%d", msg, slope_table[i]);
508
DBG (DBG_io, "%s: %s\n", __FUNCTION__, msg);
511
/* slope table addresses are fixed */
513
sanei_genesys_write_ahb (dev->dn, 0x10000000 + 0x4000 * table_nr, steps * 2, table);
514
if (status != SANE_STATUS_GOOD)
517
"%s: write to AHB failed writing slope table %d (%s)\n",
518
__FUNCTION__, table_nr, sane_strstatus (status));
527
* Set register values of Analog Device type frontend
530
gl847_set_ad_fe (Genesys_Device * dev, uint8_t set)
532
SANE_Status status = SANE_STATUS_GOOD;
536
DBG (DBG_proc, "gl847_set_ad_fe(): start\n");
539
DBG (DBG_proc, "gl847_set_ad_fe(): setting DAC %u\n",
540
dev->model->dac_type);
542
/* sets to default values */
543
sanei_genesys_init_fe (dev);
547
status = sanei_genesys_fe_write_data (dev, 0x00, 0x80);
548
if (status != SANE_STATUS_GOOD)
550
DBG (DBG_error, "gl847_set_ad_fe: failed to write reg0: %s\n",
551
sane_strstatus (status));
555
/* write them to analog frontend */
556
val = dev->frontend.reg[0];
557
status = sanei_genesys_fe_write_data (dev, 0x00, val);
558
if (status != SANE_STATUS_GOOD)
560
DBG (DBG_error, "gl847_set_ad_fe: failed to write reg0: %s\n",
561
sane_strstatus (status));
564
val = dev->frontend.reg[1];
565
status = sanei_genesys_fe_write_data (dev, 0x01, val);
566
if (status != SANE_STATUS_GOOD)
568
DBG (DBG_error, "gl847_set_ad_fe: failed to write reg1: %s\n",
569
sane_strstatus (status));
573
for (i = 0; i < 3; i++)
575
val = dev->frontend.gain[i];
576
status = sanei_genesys_fe_write_data (dev, 0x02 + i, val);
577
if (status != SANE_STATUS_GOOD)
580
"gl847_set_ad_fe: failed to write gain %d: %s\n", i,
581
sane_strstatus (status));
585
for (i = 0; i < 3; i++)
587
val = dev->frontend.offset[i];
588
status = sanei_genesys_fe_write_data (dev, 0x05 + i, val);
589
if (status != SANE_STATUS_GOOD)
592
"gl847_set_ad_fe: failed to write offset %d: %s\n", i,
593
sane_strstatus (status));
598
DBG (DBG_proc, "gl847_set_ad_fe(): end\n");
603
/* Set values of analog frontend */
605
gl847_set_fe (Genesys_Device * dev, uint8_t set)
610
DBG (DBG_proc, "gl847_set_fe (%s)\n",
611
set == AFE_INIT ? "init" : set == AFE_SET ? "set" : set ==
612
AFE_POWER_SAVE ? "powersave" : "huh?");
614
RIE (sanei_genesys_read_register (dev, REG04, &val));
616
/* route to AD devices */
617
if ((val & REG04_FESET) == 0x02)
619
return gl847_set_ad_fe (dev, set);
622
/* for now ther is no support for wolfson fe */
623
DBG (DBG_proc, "gl847_set_fe(): unsupported frontend type %d\n",
624
dev->reg[reg_0x04].value & REG04_FESET);
627
return SANE_STATUS_UNSUPPORTED;
630
#define MOTOR_FLAG_AUTO_GO_HOME 1
631
#define MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE 2
633
#define MOTOR_ACTION_FEED 1
634
#define MOTOR_ACTION_GO_HOME 2
635
#define MOTOR_ACTION_HOME_FREE 3
637
/** @brief setup motor for off mode
641
gl847_init_motor_regs_off (Genesys_Device * dev,
642
Genesys_Register_Set * reg,
643
unsigned int scan_lines)
646
Genesys_Register_Set *r;
648
DBG (DBG_proc, "gl847_init_motor_regs_off : scan_lines=%d\n", scan_lines);
652
/* all needed slopes available. we did even decide which mode to use.
656
flags \ use_fast_fed ! 0 1
657
------------------------\--------------------
659
MOTOR_FLAG_AUTO_GO_HOME ! 0,1,2,4 0,1,2,3,4
665
* slope specific registers (already done)
666
* DECSEL for HOME_FREE/GO_HOME/SCAN
681
r = sanei_genesys_get_address (reg, 0x3d);
682
r->value = (feedl >> 16) & 0xf;
683
r = sanei_genesys_get_address (reg, 0x3e);
684
r->value = (feedl >> 8) & 0xff;
685
r = sanei_genesys_get_address (reg, 0x3f);
686
r->value = feedl & 0xff;
687
DBG (DBG_io ,"%s: feedl=%d\n",__FUNCTION__,feedl);
689
r = sanei_genesys_get_address (reg, 0x25);
690
r->value = (scan_lines >> 16) & 0xf;
691
r = sanei_genesys_get_address (reg, 0x26);
692
r->value = (scan_lines >> 8) & 0xff;
693
r = sanei_genesys_get_address (reg, 0x27);
694
r->value = scan_lines & 0xff;
696
r = sanei_genesys_get_address (reg, REG02);
697
r->value &= ~0x01; /*LONGCURV OFF */
698
r->value &= ~0x80; /*NOT_HOME OFF */
710
r = sanei_genesys_get_address (reg, REG67);
711
r->value = REG67_MTRPWM;
713
r = sanei_genesys_get_address (reg, REG68);
714
r->value = REG68_FASTPWM;
716
r = sanei_genesys_get_address (reg, 0x21);
719
r = sanei_genesys_get_address (reg, 0x24);
722
r = sanei_genesys_get_address (reg, 0x69);
725
r = sanei_genesys_get_address (reg, 0x6a);
728
r = sanei_genesys_get_address (reg, 0x5f);
733
return SANE_STATUS_GOOD;
737
gl847_init_motor_regs (Genesys_Device * dev, Genesys_Register_Set * reg, unsigned int feed_steps, /*1/base_ydpi */
738
/*maybe float for half/quarter step resolution?*/
739
unsigned int action, unsigned int flags)
742
unsigned int fast_exposure;
743
int use_fast_fed = 0;
744
uint16_t fast_slope_table[256];
746
unsigned int fast_slope_time;
747
unsigned int fast_slope_steps = 32;
749
Genesys_Register_Set *r;
750
/*number of scan lines to add in a scan_lines line*/
753
"gl847_init_motor_regs : feed_steps=%d, action=%d, flags=%x\n",
754
feed_steps, action, flags);
756
if (action == MOTOR_ACTION_FEED || action == MOTOR_ACTION_GO_HOME || action == MOTOR_ACTION_HOME_FREE)
758
/* FEED and GO_HOME can use fastest slopes available */
759
fast_slope_steps = 256;
760
fast_exposure = sanei_genesys_exposure_time2 (dev,
761
dev->motor.base_ydpi / 4,
763
0, /*last used pixel */
767
DBG (DBG_info, "gl847_init_motor_regs : fast_exposure=%d pixels\n",
771
/* HOME_FREE must be able to stop in one step, so do not try to get faster */
773
if (action == MOTOR_ACTION_HOME_FREE)
775
fast_slope_steps = 256;
776
fast_exposure = dev->motor.slopes[0][0].maximum_start_speed;
780
fast_slope_time = sanei_genesys_create_slope_table3 (dev,
786
dev->motor.base_ydpi / 4,
791
feedl = feed_steps - fast_slope_steps * 2;
794
/* all needed slopes available. we did even decide which mode to use.
798
flags \ use_fast_fed ! 0 1
799
------------------------\--------------------
801
MOTOR_FLAG_AUTO_GO_HOME ! 0,1,2,4 0,1,2,3,4
807
* slope specific registers (already done)
808
* DECSEL for HOME_FREE/GO_HOME/SCAN
824
r = sanei_genesys_get_address (reg, 0x3d);
825
r->value = (feedl >> 16) & 0xf;
826
r = sanei_genesys_get_address (reg, 0x3e);
827
r->value = (feedl >> 8) & 0xff;
828
r = sanei_genesys_get_address (reg, 0x3f);
829
r->value = feedl & 0xff;
830
DBG (DBG_io ,"%s: feedl=%d\n",__FUNCTION__,feedl);
832
r = sanei_genesys_get_address (reg, 0x25);
834
r = sanei_genesys_get_address (reg, 0x26);
836
r = sanei_genesys_get_address (reg, 0x27);
840
r = sanei_genesys_get_address (reg, REG02);
841
r->value &= ~REG02_LONGCURV;
842
r->value &= ~REG02_HOMENEG;
843
r->value &= ~REG02_AGOHOME;
844
r->value &= ~REG02_ACDCDIS;
846
if (flags & MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE)
847
r->value |= REG02_ACDCDIS;
849
r->value |= REG02_MTRPWR;
851
if (action == MOTOR_ACTION_GO_HOME)
852
r->value |= (REG02_MTRREV | REG02_NOTHOME);
854
r->value &= ~(REG02_MTRREV | REG02_HOMENEG);
857
r->value |= REG02_FASTFED;
859
r->value &= ~REG02_FASTFED;
861
if (flags & MOTOR_FLAG_AUTO_GO_HOME)
862
r->value |= REG02_AGOHOME;
865
RIE (sanei_genesys_read_register (dev, REG6C, &val));
867
RIE (sanei_genesys_write_register (dev, REG6C, val));
868
RIE (sanei_genesys_read_register (dev, REG6C, &val));
870
RIE (sanei_genesys_write_register (dev, REG6C, val));
872
status = gl847_send_slope_table (dev, 0, fast_slope_table, 256);
873
status = gl847_send_slope_table (dev, 1, fast_slope_table, 256);
874
status = gl847_send_slope_table (dev, 2, fast_slope_table, 256);
875
status = gl847_send_slope_table (dev, 3, fast_slope_table, 256);
876
status = gl847_send_slope_table (dev, 4, fast_slope_table, 256);
878
if (status != SANE_STATUS_GOOD)
881
r = sanei_genesys_get_address (reg, REG67);
882
r->value = REG67_MTRPWM;
884
r = sanei_genesys_get_address (reg, REG68);
885
r->value = REG68_FASTPWM;
887
r = sanei_genesys_get_address (reg, 0x21);
890
r = sanei_genesys_get_address (reg, 0x24);
893
r = sanei_genesys_get_address (reg, REG60);
894
r->value = 0 << REG60S_STEPSEL;
896
r = sanei_genesys_get_address (reg, REG63);
897
r->value = 0 << REG63S_FSTPSEL;
899
r = sanei_genesys_get_address (reg, 0x69);
902
r = sanei_genesys_get_address (reg, 0x6a);
903
r->value = fast_slope_steps;
905
r = sanei_genesys_get_address (reg, 0x5f);
906
r->value = fast_slope_steps;
909
return SANE_STATUS_GOOD;
912
/** @brief set up motor related register for scan
913
* the following registers are modified:
918
flags \ use_fast_fed ! 0 1
919
------------------------\--------------------
921
MOTOR_FLAG_AUTO_GO_HOME ! 0,1,2,4 0,1,2,3,4
927
* slope specific registers (already done)
928
* DECSEL for HOME_FREE/GO_HOME/SCAN
944
gl847_init_motor_regs_scan (Genesys_Device * dev,
945
Genesys_Register_Set * reg,
946
unsigned int scan_exposure_time, /*pixel */
947
float scan_yres, /*dpi, motor resolution */
948
int scan_step_type, /*0: full, 1: half, 2: quarter */
949
unsigned int scan_lines, /*lines, scan resolution */
950
unsigned int scan_dummy,
951
/*number of scan lines to add in a scan_lines line*/
952
unsigned int feed_steps, /*1/base_ydpi */
953
/*maybe float for half/quarter step resolution?*/
954
int scan_power_mode, unsigned int flags)
957
unsigned int fast_exposure;
958
int use_fast_fed = 0;
959
unsigned int fast_time;
960
unsigned int slow_time;
961
uint16_t slow_slope_table[256];
962
uint16_t fast_slope_table[256];
963
uint16_t back_slope_table[256];
964
unsigned int slow_slope_time;
965
unsigned int fast_slope_time;
966
unsigned int back_slope_time;
967
unsigned int slow_slope_steps = 0;
968
unsigned int fast_slope_steps = 32;
969
unsigned int back_slope_steps = 0;
971
Genesys_Register_Set *r;
972
unsigned int min_restep = 0x20;
974
uint8_t val, effective;
977
DBG (DBG_proc, "gl847_init_motor_regs_scan : scan_exposure_time=%d, "
978
"scan_yres=%g, scan_step_type=%d, scan_lines=%d, scan_dummy=%d, "
979
"feed_steps=%d, scan_power_mode=%d, flags=%x\n",
983
scan_lines, scan_dummy, feed_steps, scan_power_mode, flags);
986
sanei_genesys_exposure_time2 (dev, dev->motor.base_ydpi / 4,
987
0, 0, 0, scan_power_mode);
989
DBG (DBG_info, "gl847_init_motor_regs_scan : fast_exposure=%d pixels\n",
993
we calculate both tables for SCAN. the fast slope step count depends on
994
how many steps we need for slow acceleration and how much steps we are
997
slow_slope_time = sanei_genesys_create_slope_table3 (dev,
1005
NULL, scan_power_mode);
1007
back_slope_time = sanei_genesys_create_slope_table3 (dev,
1015
NULL, scan_power_mode);
1017
if (feed_steps < (slow_slope_steps >> scan_step_type))
1019
/*TODO: what should we do here?? go back to exposure calculation? */
1020
feed_steps = slow_slope_steps >> scan_step_type;
1023
if (feed_steps > fast_slope_steps * 2 -
1024
(slow_slope_steps >> scan_step_type))
1025
fast_slope_steps = 256;
1028
/* we need to shorten fast_slope_steps here. */
1029
fast_slope_steps = (feed_steps - (slow_slope_steps >> scan_step_type)) / 2;
1031
if(fast_slope_steps>256)
1032
fast_slope_steps=256;
1035
"gl847_init_motor_regs_scan: Maximum allowed slope steps for fast slope: %d\n",
1038
fast_slope_time = sanei_genesys_create_slope_table3 (dev,
1044
dev->motor.base_ydpi / 4,
1050
fast_slope_steps * 2 + (slow_slope_steps >> scan_step_type))
1054
"gl847_init_motor_regs_scan: feed too short, slow move forced.\n");
1058
/* for deciding whether we should use fast mode we need to check how long we
1059
need for (fast)accelerating, moving, decelerating, (TODO: stopping?)
1060
(slow)accelerating again versus (slow)accelerating and moving. we need
1061
fast and slow tables here.
1063
/*NOTE: scan_exposure_time is per scan_yres*/
1064
/*NOTE: fast_exposure is per base_ydpi/4*/
1065
/*we use full steps as base unit here*/
1068
(feed_steps - fast_slope_steps * 2 -
1069
(slow_slope_steps >> scan_step_type))
1070
+ fast_slope_time * 2 + slow_slope_time;
1072
(scan_exposure_time * scan_yres) / dev->motor.base_ydpi *
1073
(feed_steps - (slow_slope_steps >> scan_step_type)) + slow_slope_time;
1075
DBG (DBG_info, "gl847_init_motor_regs_scan: Time for slow move: %d\n",
1077
DBG (DBG_info, "gl847_init_motor_regs_scan: Time for fast move: %d\n",
1080
use_fast_fed = fast_time < slow_time;
1083
DBG (DBG_info, "gl847_init_motor_regs_scan: decided to use %s mode\n",
1084
use_fast_fed ? "fast feed" : "slow feed");
1087
feedl = feed_steps - fast_slope_steps * 2 -
1088
(slow_slope_steps >> scan_step_type);
1089
else if ((feed_steps << scan_step_type) < slow_slope_steps)
1092
feedl = (feed_steps << scan_step_type) - slow_slope_steps;
1095
/* all needed slopes available. we did even decide which mode to use.
1097
r = sanei_genesys_get_address (reg, 0x3d);
1098
r->value = (feedl >> 16) & 0xf;
1099
r = sanei_genesys_get_address (reg, 0x3e);
1100
r->value = (feedl >> 8) & 0xff;
1101
r = sanei_genesys_get_address (reg, 0x3f);
1102
r->value = feedl & 0xff;
1103
DBG (DBG_io ,"%s: feedl=%d\n",__FUNCTION__,feedl);
1105
r = sanei_genesys_get_address (reg, 0x25);
1106
r->value = (scan_lines >> 16) & 0xf;
1107
r = sanei_genesys_get_address (reg, 0x26);
1108
r->value = (scan_lines >> 8) & 0xff;
1109
r = sanei_genesys_get_address (reg, 0x27);
1110
r->value = scan_lines & 0xff;
1112
/* compute register 02 value */
1113
r = sanei_genesys_get_address (reg, REG02);
1115
r->value |= REG02_NOTHOME | REG02_MTRPWR;
1118
r->value |= REG02_FASTFED;
1120
r->value &= ~REG02_FASTFED;
1122
if (flags & MOTOR_FLAG_AUTO_GO_HOME)
1123
r->value |= REG02_AGOHOME;
1125
if (flags & MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE)
1126
r->value |= REG02_ACDCDIS;
1128
/* hi res motor speed */
1129
RIE (sanei_genesys_read_register (dev, REG6C, &effective));
1131
/* if quarter step, bipolar Vref2 */
1132
if (scan_step_type > 1)
1134
val = effective & ~REG6C_GPIO13;
1140
RIE (sanei_genesys_write_register (dev, REG6C, val));
1142
/* effective scan */
1143
RIE (sanei_genesys_read_register (dev, REG6C, &effective));
1144
val = effective | REG6C_GPIO10;
1145
RIE (sanei_genesys_write_register (dev, REG6C, val));
1147
status = gl847_send_slope_table (dev, 0, slow_slope_table, 256);
1149
if (status != SANE_STATUS_GOOD)
1152
status = gl847_send_slope_table (dev, 1, back_slope_table, 256);
1154
if (status != SANE_STATUS_GOOD)
1157
status = gl847_send_slope_table (dev, 2, slow_slope_table, 256);
1159
if (status != SANE_STATUS_GOOD)
1164
status = gl847_send_slope_table (dev, 3, fast_slope_table, 256);
1166
if (status != SANE_STATUS_GOOD)
1170
if (flags & MOTOR_FLAG_AUTO_GO_HOME)
1172
status = gl847_send_slope_table (dev, 4, fast_slope_table, 256);
1174
if (status != SANE_STATUS_GOOD)
1179
/* now reg 0x21 and 0x24 are available, we can calculate reg 0x22 and 0x23,
1180
reg 0x60-0x62 and reg 0x63-0x65
1182
2*STEPNO+FWDSTEP=2*FASTNO+BWDSTEP
1184
/* steps of table 0*/
1185
if (min_restep < slow_slope_steps * 2 + 2)
1186
min_restep = slow_slope_steps * 2 + 2;
1187
/* steps of table 1*/
1188
if (min_restep < back_slope_steps * 2 + 2)
1189
min_restep = back_slope_steps * 2 + 2;
1190
/* steps of table 0*/
1191
r = sanei_genesys_get_address (reg, 0x22);
1192
r->value = min_restep - slow_slope_steps * 2;
1194
/* steps of table 1*/
1195
r = sanei_genesys_get_address (reg, 0x23);
1196
r->value = min_restep - back_slope_steps * 2;
1201
in documentation mentioned variables a-d:
1202
a = time needed for acceleration, table 1
1203
b = time needed for reg 0x1f... wouldn't that be reg0x1f*exposure_time?
1204
c = time needed for acceleration, table 1
1205
d = time needed for reg 0x22... wouldn't that be reg0x22*exposure_time?
1206
z1 = (c+d-1) % exposure_time
1207
z2 = (a+b-1) % exposure_time
1209
/* i don't see any effect of this. i can only guess that this will enhance
1211
z1 = (slope_0_time-1) % exposure_time;
1212
z2 = (slope_0_time-1) % exposure_time;
1215
sanei_genesys_calculate_zmode2 (use_fast_fed,
1224
DBG (DBG_info, "gl847_init_motor_regs_scan: z1 = %d\n", z1);
1225
r = sanei_genesys_get_address (reg, REG60);
1226
r->value = ((z1 >> 16) & REG60_Z1MOD) | (scan_step_type << REG60S_STEPSEL);
1227
r = sanei_genesys_get_address (reg, REG61);
1228
r->value = ((z1 >> 8) & REG61_Z1MOD);
1229
r = sanei_genesys_get_address (reg, REG62);
1230
r->value = (z1 & REG62_Z1MOD);
1232
DBG (DBG_info, "gl847_init_motor_regs_scan: z2 = %d\n", z2);
1233
r = sanei_genesys_get_address (reg, REG63);
1234
r->value = ((z2 >> 16) & REG63_Z2MOD) | (scan_step_type << REG63S_FSTPSEL);
1235
r = sanei_genesys_get_address (reg, REG64);
1236
r->value = ((z2 >> 8) & REG64_Z2MOD);
1237
r = sanei_genesys_get_address (reg, REG65);
1238
r->value = (z2 & REG65_Z2MOD);
1240
r = sanei_genesys_get_address (reg, 0x1e);
1241
r->value &= 0xf0; /* 0 dummy lines */
1242
r->value |= scan_dummy; /* dummy lines */
1244
r = sanei_genesys_get_address (reg, REG67);
1245
r->value = REG67_MTRPWM;
1247
r = sanei_genesys_get_address (reg, REG68);
1248
r->value = REG68_FASTPWM;
1250
r = sanei_genesys_get_address (reg, 0x21);
1251
r->value = slow_slope_steps;
1253
r = sanei_genesys_get_address (reg, 0x24);
1254
r->value = back_slope_steps;
1256
r = sanei_genesys_get_address (reg, 0x69);
1257
r->value = slow_slope_steps;
1259
r = sanei_genesys_get_address (reg, 0x6a);
1260
r->value = fast_slope_steps;
1262
r = sanei_genesys_get_address (reg, 0x5f);
1263
r->value = fast_slope_steps;
1267
return SANE_STATUS_GOOD;
1271
gl847_get_dpihw (Genesys_Device * dev)
1273
Genesys_Register_Set *r;
1274
r = sanei_genesys_get_address (dev->reg, REG05);
1275
if ((r->value & REG05_DPIHW) == REG05_DPIHW_600)
1277
if ((r->value & REG05_DPIHW) == REG05_DPIHW_1200)
1279
if ((r->value & REG05_DPIHW) == REG05_DPIHW_2400)
1281
if ((r->value & REG05_DPIHW) == REG05_DPIHW_4800)
1286
#define OPTICAL_FLAG_DISABLE_GAMMA 1
1287
#define OPTICAL_FLAG_DISABLE_SHADING 2
1288
#define OPTICAL_FLAG_DISABLE_LAMP 4
1289
#define OPTICAL_FLAG_ENABLE_LEDADD 8
1292
gl847_init_optical_regs_off (Genesys_Device * dev, Genesys_Register_Set * reg)
1294
Genesys_Register_Set *r;
1296
DBG (DBG_proc, "gl847_init_optical_regs_off : start\n");
1298
r = sanei_genesys_get_address (reg, REG01);
1299
r->value &= ~REG01_SCAN;
1302
return SANE_STATUS_GOOD;
1305
/** @brief set up registers related to sensor
1306
* Set up the following registers
1309
0x10-0x015 R/G/B exposures
1319
0x35,0x36,0x37 MAXWD [25:2] (>>2)
1324
gl847_init_optical_regs_scan (Genesys_Device * dev,
1325
Genesys_Register_Set * reg,
1326
unsigned int exposure_time,
1329
unsigned int pixels,
1332
SANE_Bool half_ccd, int color_filter, int flags)
1334
unsigned int words_per_line;
1335
unsigned int startx,endx, used_pixels,max_pixels;
1336
unsigned int dpiset;
1337
unsigned int i,bytes;
1338
Genesys_Register_Set *r;
1342
DBG (DBG_proc, "gl847_init_optical_regs_scan : exposure_time=%d, "
1343
"used_res=%d, start=%d, pixels=%d, channels=%d, depth=%d, "
1344
"half_ccd=%d, flags=%x\n",
1346
used_res, start, pixels, channels, depth, half_ccd, flags);
1348
/* during calibration , we don't want double xres */
1349
if(dev->settings.double_xres==SANE_TRUE && used_res<dev->sensor.optical_res)
1351
double_xres=SANE_TRUE;
1355
double_xres=SANE_FALSE;
1358
startx = dev->sensor.dummy_pixel + 1 + dev->sensor.CCD_start_xoffset;
1359
if(double_xres==SANE_TRUE)
1361
max_pixels = dev->sensor.sensor_pixels/2;
1365
max_pixels = dev->sensor.sensor_pixels;
1367
if(pixels<max_pixels)
1369
used_pixels = max_pixels;
1373
used_pixels = pixels;
1375
endx = startx + used_pixels;
1377
status = gl847_set_fe (dev, AFE_SET);
1378
if (status != SANE_STATUS_GOOD)
1381
"gl847_init_optical_regs_scan: failed to set frontend: %s\n",
1382
sane_strstatus (status));
1386
/* adjust used_res for chosen dpihw */
1387
used_res = used_res * gl847_get_dpihw (dev) / dev->sensor.optical_res;
1388
if(double_xres==SANE_TRUE)
1394
/* enable shading */
1395
r = sanei_genesys_get_address (reg, REG01);
1396
r->value &= ~REG01_SCAN;
1397
r->value |= REG01_SHDAREA;
1398
if ((flags & OPTICAL_FLAG_DISABLE_SHADING) ||
1399
(dev->model->flags & GENESYS_FLAG_NO_CALIBRATION))
1401
r->value &= ~REG01_DVDSET;
1405
r->value |= REG01_DVDSET;
1408
r = sanei_genesys_get_address (reg, REG03);
1409
r->value &= ~REG03_AVEENB;
1410
if (flags & OPTICAL_FLAG_DISABLE_LAMP)
1411
r->value &= ~REG03_LAMPPWR;
1413
r->value |= REG03_LAMPPWR;
1415
/* exposure times */
1416
for (i = 0; i < 6; i++)
1418
r = sanei_genesys_get_address (reg, 0x10 + i);
1419
if (flags & OPTICAL_FLAG_DISABLE_LAMP)
1420
r->value = 0x01; /* 0x0101 is as off as possible */
1422
r->value = dev->sensor.regs_0x10_0x1d[i];
1425
r = sanei_genesys_get_address (reg, 0x19);
1429
r = sanei_genesys_get_address (reg, 0x2e);
1430
r->value = dev->settings.threshold;
1431
r = sanei_genesys_get_address (reg, 0x2f);
1432
r->value = dev->settings.threshold;
1434
/* monochrome / color scan */
1435
r = sanei_genesys_get_address (reg, REG04);
1439
r->value &= ~REG04_BITSET;
1440
r->value |= REG04_LINEART;
1443
r->value &= ~(REG04_LINEART | REG04_BITSET);
1446
r->value &= ~REG04_LINEART;
1447
r->value |= REG04_BITSET;
1451
r->value &= ~(REG04_FILTER | REG04_AFEMOD);
1454
switch (color_filter)
1457
r->value |= 0x14; /* red filter */
1460
r->value |= 0x1c; /* blue filter */
1463
r->value |= 0x18; /* green filter */
1468
r->value |= 0x10; /* mono */
1470
/* CIS scanners can do true gray by setting LEDADD */
1471
/* we set up LEDADD only when asked */
1472
if (dev->model->is_cis == SANE_TRUE)
1474
r = sanei_genesys_get_address (reg, 0x87);
1475
r->value &= ~REG87_LEDADD;
1476
if (channels == 1 && (flags & OPTICAL_FLAG_ENABLE_LEDADD))
1478
r->value |= REG87_LEDADD;
1481
r = sanei_genesys_get_address (reg, 0x01);
1482
r->value &= ~REG01_TRUEGRAY;
1483
if (channels == 1 && (flags & OPTICAL_FLAG_ENABLE_LEDADD))
1485
r->value |= REG01_TRUEGRAY;
1489
/* enable gamma tables */
1490
r = sanei_genesys_get_address (reg, REG05);
1491
if (flags & OPTICAL_FLAG_DISABLE_GAMMA)
1492
r->value &= ~REG05_GMMENB;
1494
r->value |= REG05_GMMENB;
1496
/* sensor parameters */
1497
gl847_setup_sensor (dev, dev->reg);
1499
r = sanei_genesys_get_address (reg, 0x2c);
1500
r->value = HIBYTE (dpiset);
1501
r = sanei_genesys_get_address (reg, 0x2d);
1502
r->value = LOBYTE (dpiset);
1503
DBG (DBG_io2, "%s: dpiset used=%d\n", __FUNCTION__, dpiset);
1505
r = sanei_genesys_get_address (reg, 0x30);
1506
r->value = HIBYTE (startx);
1507
r = sanei_genesys_get_address (reg, 0x31);
1508
r->value = LOBYTE (startx);
1509
r = sanei_genesys_get_address (reg, 0x32);
1510
r->value = HIBYTE (endx);
1511
r = sanei_genesys_get_address (reg, 0x33);
1512
r->value = LOBYTE (endx);
1514
/* words(16bit) before gamma, conversion to 8 bit or lineart*/
1515
words_per_line = (used_pixels * dpiset) / gl847_get_dpihw (dev);
1519
words_per_line = (words_per_line >> 3) + ((words_per_line & 7) ? 1 : 0);
1523
words_per_line *= bytes;
1526
dev->bpl = words_per_line;
1528
dev->len=((pixels*dpiset)/gl847_get_dpihw (dev))/2*bytes;
1529
dev->dist=dev->bpl/2;
1530
dev->skip=((start*dpiset)/gl847_get_dpihw (dev))/2*bytes;
1531
if(dev->skip>=dev->dist && double_xres==SANE_FALSE)
1533
dev->skip-=dev->dist;
1536
DBG (DBG_io2, "%s: used_pixels=%d\n", __FUNCTION__, used_pixels);
1537
DBG (DBG_io2, "%s: pixels =%d\n", __FUNCTION__, pixels);
1538
DBG (DBG_io2, "%s: depth =%d\n", __FUNCTION__, depth);
1539
DBG (DBG_io2, "%s: dev->bpl =%lu\n", __FUNCTION__, (unsigned long)dev->bpl);
1540
DBG (DBG_io2, "%s: dev->len =%lu\n", __FUNCTION__, (unsigned long)dev->len);
1541
DBG (DBG_io2, "%s: dev->dist =%lu\n", __FUNCTION__, (unsigned long)dev->dist);
1542
DBG (DBG_io2, "%s: dev->skip =%lu\n", __FUNCTION__, (unsigned long)dev->skip);
1544
words_per_line *= channels;
1545
dev->wpl = words_per_line;
1547
if(dev->oe_buffer.buffer!=NULL)
1549
sanei_genesys_buffer_free (&(dev->oe_buffer));
1551
RIE (sanei_genesys_buffer_alloc (&(dev->oe_buffer), dev->wpl));
1554
/* MAXWD is expressed in 4 words unit */
1555
r = sanei_genesys_get_address (reg, 0x35);
1556
r->value = LOBYTE (HIWORD (words_per_line >> 2));
1557
r = sanei_genesys_get_address (reg, 0x36);
1558
r->value = HIBYTE (LOWORD (words_per_line >> 2));
1559
r = sanei_genesys_get_address (reg, 0x37);
1560
r->value = LOBYTE (LOWORD (words_per_line >> 2));
1561
DBG (DBG_io2, "%s: words_per_line used=%d\n", __FUNCTION__, words_per_line);
1563
r = sanei_genesys_get_address (reg, 0x38);
1564
r->value = HIBYTE (exposure_time);
1565
r = sanei_genesys_get_address (reg, 0x39);
1566
r->value = LOBYTE (exposure_time);
1567
DBG (DBG_io2, "%s: exposure_time used=%d\n", __FUNCTION__, exposure_time);
1569
r = sanei_genesys_get_address (reg, 0x34);
1570
r->value = dev->sensor.dummy_pixel;
1573
return SANE_STATUS_GOOD;
1578
gl847_get_led_exposure (Genesys_Device * dev)
1581
if (!dev->model->is_cis)
1583
d = dev->reg[reg_0x19].value;
1584
r = dev->sensor.regs_0x10_0x1d[1] | (dev->sensor.regs_0x10_0x1d[0] << 8);
1585
g = dev->sensor.regs_0x10_0x1d[3] | (dev->sensor.regs_0x10_0x1d[2] << 8);
1586
b = dev->sensor.regs_0x10_0x1d[5] | (dev->sensor.regs_0x10_0x1d[4] << 8);
1597
/* set up registers for an actual scan
1599
* this function sets up the scanner to scan in normal or single line mode
1601
#ifndef UNIT_TESTING
1605
gl847_init_scan_regs (Genesys_Device * dev,
1606
Genesys_Register_Set * reg,
1607
float xres, /*dpi */
1608
float yres, /*dpi */
1609
float startx, /*optical_res, from dummy_pixel+1 */
1610
float starty, /*base_ydpi, from home! */
1614
unsigned int channels,
1615
int color_filter, unsigned int flags)
1618
int start, used_pixels;
1621
unsigned int lincnt;
1622
unsigned int oflags; /**> optical flags */
1623
int exposure_time, exposure_time2, led_exposure;
1628
int pixels_exposure;
1630
int scan_step_type = 1;
1631
int scan_power_mode = 0;
1633
size_t requested_buffer_size, read_buffer_size;
1635
SANE_Bool half_ccd; /* false: full CCD res is used, true, half max CCD res is used */
1640
"gl847_init_scan_regs settings:\n"
1641
"Resolution : %gDPI/%gDPI\n"
1644
"Startpos : %g/%g\n"
1645
"Depth/Channels: %u/%u\n"
1647
xres, yres, lines, pixels, startx, starty, depth, channels, flags);
1665
dev->requested_buffer_size
1666
dev->read_buffer_size
1668
dev->read_bytes_in_buffer
1669
dev->read_bytes_left
1673
independent of our calculated values:
1674
dev->total_bytes_read
1679
/* we have 2 domains for ccd: xres below or above half ccd max dpi */
1680
if (dev->sensor.optical_res < 2 * xres ||
1681
!(dev->model->flags & GENESYS_FLAG_HALF_CCD_MODE))
1683
half_ccd = SANE_FALSE;
1687
half_ccd = SANE_TRUE;
1692
optical_res = dev->sensor.optical_res;
1698
if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE))
1699
stagger = (4 * yres) / dev->motor.base_ydpi;
1702
DBG (DBG_info, "gl847_init_scan_regs : stagger=%d lines\n", stagger);
1705
i = optical_res / xres;
1706
if (flags & SCAN_FLAG_USE_OPTICAL_RES)
1708
used_res = optical_res;
1712
/* resolution is choosen from a list */
1716
/* compute scan parameters values */
1717
/* pixels are allways given at full optical resolution */
1718
/* use detected left margin and fixed value */
1720
/* add x coordinates */
1726
/* compute correct pixels number */
1728
used_pixels = (pixels * optical_res) / xres;
1730
/* round up pixels number if needed */
1731
if (used_pixels * xres < pixels * optical_res)
1737
/* cis color scan is effectively a gray scan with 3 gray lines per color
1738
line and a FILTER of 0 */
1739
if (dev->model->is_cis)
1740
slope_dpi = yres * channels;
1744
slope_dpi = slope_dpi * (1 + dummy);
1746
/* scan_step_type */
1762
/* exposure_time , CCD case not handled */
1763
led_exposure = gl847_get_led_exposure (dev);
1765
pixels_exposure=dev->sensor.sensor_pixels+572;
1766
if(xres<dev->sensor.optical_res)
1767
pixels_exposure=(pixels_exposure*xres)/dev->sensor.optical_res-32;
1771
exposure_time = sanei_genesys_exposure_time2 (dev,
1778
while (scan_power_mode + 1 < dev->motor.power_mode_count)
1780
exposure_time2 = sanei_genesys_exposure_time2 (dev,
1785
scan_power_mode + 1);
1786
if (exposure_time < exposure_time2)
1788
exposure_time = exposure_time2;
1792
DBG (DBG_info, "gl847_init_scan_regs : exposure_time=%d pixels\n",
1794
DBG (DBG_info, "gl847_init_scan_regs : scan_step_type=%d\n",
1797
/*** optical parameters ***/
1798
/* in case of dynamic lineart, we use an internal 8 bit gray scan
1799
* to generate 1 lineart data */
1800
if ((flags & SCAN_FLAG_DYNAMIC_LINEART) && (dev->settings.scan_mode == SCAN_MODE_LINEART))
1805
/* we enable true gray for cis scanners only, and just when doing
1806
* scan since color calibration is OK for this mode
1809
if(flags & SCAN_FLAG_DISABLE_SHADING)
1810
oflags |= OPTICAL_FLAG_DISABLE_SHADING;
1811
if(flags & SCAN_FLAG_DISABLE_GAMMA)
1812
oflags |= OPTICAL_FLAG_DISABLE_GAMMA;
1813
if(flags & SCAN_FLAG_DISABLE_LAMP)
1814
oflags |= OPTICAL_FLAG_DISABLE_LAMP;
1816
if (dev->model->is_cis && dev->settings.true_gray)
1818
oflags |= OPTICAL_FLAG_ENABLE_LEDADD;
1821
status = gl847_init_optical_regs_scan (dev,
1833
if (status != SANE_STATUS_GOOD)
1836
/*** motor parameters ***/
1839
/* scanned area must be enlarged by max color shift needed */
1840
/* all values are assumed >= 0 */
1841
if (channels > 1 && !(flags & SCAN_FLAG_IGNORE_LINE_DISTANCE))
1843
max_shift = dev->model->ld_shift_r;
1844
if (dev->model->ld_shift_b > max_shift)
1845
max_shift = dev->model->ld_shift_b;
1846
if (dev->model->ld_shift_g > max_shift)
1847
max_shift = dev->model->ld_shift_g;
1848
max_shift = (max_shift * yres) / dev->motor.base_ydpi;
1856
lincnt = lines + max_shift + stagger;
1858
/* add tl_y to base movement */
1860
DBG (DBG_info, "gl847_init_scan_regs: move=%d steps\n", move);
1862
/* subtract current head position */
1864
move -= dev->scanhead_position_in_steps;
1865
DBG (DBG_info, "gl847_init_scan_regs: move=%d steps\n", move);
1871
/* the move is not affected by dummy -- pierre */
1872
/* move = ((move + dummy) / (dummy + 1)) * (dummy + 1);
1873
DBG (DBG_info, "gl847_init_scan_regs: move=%d steps\n", move);*/
1875
if (flags & SCAN_FLAG_SINGLE_LINE)
1876
status = gl847_init_motor_regs_off (dev,
1878
dev->model->is_cis ? lincnt *
1881
status = gl847_init_motor_regs_scan (dev,
1886
dev->model->is_cis ? lincnt *
1887
channels : lincnt, dummy, move,
1890
SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE)
1892
MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE
1895
if (status != SANE_STATUS_GOOD)
1899
/*** prepares data reordering ***/
1901
/* words_per_line */
1902
bytes_per_line = (used_pixels * used_res) / optical_res;
1903
bytes_per_line = (bytes_per_line * channels * depth) / 8;
1905
requested_buffer_size = 8 * bytes_per_line;
1906
/* we must use a round number of bytes_per_line */
1907
if (requested_buffer_size > BULKIN_MAXSIZE)
1908
requested_buffer_size =
1909
(BULKIN_MAXSIZE / bytes_per_line) * bytes_per_line;
1912
2 * requested_buffer_size +
1913
((max_shift + stagger) * used_pixels * channels * depth) / 8;
1915
RIE (sanei_genesys_buffer_free (&(dev->read_buffer)));
1916
RIE (sanei_genesys_buffer_alloc (&(dev->read_buffer), read_buffer_size));
1918
RIE (sanei_genesys_buffer_free (&(dev->lines_buffer)));
1919
RIE (sanei_genesys_buffer_alloc (&(dev->lines_buffer), read_buffer_size));
1921
RIE (sanei_genesys_buffer_free (&(dev->shrink_buffer)));
1922
RIE (sanei_genesys_buffer_alloc (&(dev->shrink_buffer),
1923
requested_buffer_size));
1925
RIE (sanei_genesys_buffer_free (&(dev->out_buffer)));
1926
RIE (sanei_genesys_buffer_alloc (&(dev->out_buffer),
1927
(8 * dev->settings.pixels * channels *
1931
dev->read_bytes_left = bytes_per_line * lincnt;
1934
"gl847_init_scan_regs: physical bytes to read = %lu\n",
1935
(u_long) dev->read_bytes_left);
1936
dev->read_active = SANE_TRUE;
1939
dev->current_setup.pixels = (used_pixels * used_res) / optical_res;
1940
dev->current_setup.lines = lincnt;
1941
dev->current_setup.depth = depth;
1942
dev->current_setup.channels = channels;
1943
dev->current_setup.exposure_time = exposure_time;
1944
dev->current_setup.xres = used_res;
1945
dev->current_setup.yres = yres;
1946
dev->current_setup.half_ccd = half_ccd;
1947
dev->current_setup.stagger = stagger;
1948
dev->current_setup.max_shift = max_shift + stagger;
1950
/* TODO: should this be done elsewhere? */
1951
/* scan bytes to send to the frontend */
1954
(dev->settings.pixels * dev->settings.lines * channels * depth) / 8;
1955
but it suffers from integer overflow so we do the following:
1957
1 bit color images store color data byte-wise, eg byte 0 contains
1958
8 bits of red data, byte 1 contains 8 bits of green, byte 2 contains
1960
This does not fix the overflow, though.
1961
644mp*16 = 10gp, leading to an overflow
1965
dev->total_bytes_read = 0;
1966
if (depth == 1 || dev->settings.scan_mode == SCAN_MODE_LINEART)
1967
dev->total_bytes_to_read =
1968
((dev->settings.pixels * dev->settings.lines) / 8 +
1969
(((dev->settings.pixels * dev->settings.lines) % 8) ? 1 : 0)) *
1972
dev->total_bytes_to_read =
1973
dev->settings.pixels * dev->settings.lines * channels * (depth / 8);
1975
DBG (DBG_info, "gl847_init_scan_regs: total bytes to send = %lu\n",
1976
(u_long) dev->total_bytes_to_read);
1980
return SANE_STATUS_GOOD;
1984
gl847_calculate_current_setup (Genesys_Device * dev)
1990
float xres; /*dpi */
1991
float yres; /*dpi */
1992
float startx; /*optical_res, from dummy_pixel+1 */
1999
unsigned int lincnt;
2000
int exposure_time, exposure_time2, led_exposure;
2006
int scan_step_type = 1;
2007
int scan_power_mode = 0;
2009
int pixels_exposure;
2011
SANE_Bool half_ccd; /* false: full CCD res is used, true, half max CCD res is used */
2015
"gl847_calculate_current_setup settings:\n"
2016
"Resolution: %uDPI\n"
2019
"Startpos : %.3f/%.3f\n"
2020
"Scan mode : %d\n\n",
2021
dev->settings.yres, dev->settings.lines, dev->settings.pixels,
2022
dev->settings.tl_x, dev->settings.tl_y, dev->settings.scan_mode);
2025
if (dev->settings.scan_mode == 4) /* single pass color */
2031
depth = dev->settings.depth;
2032
if (dev->settings.scan_mode == 0)
2036
start = SANE_UNFIX (dev->model->x_offset);
2037
start += dev->settings.tl_x;
2038
start = (start * dev->sensor.optical_res) / MM_PER_INCH;
2041
xres = dev->settings.xres; /*dpi */
2042
yres = dev->settings.yres; /*dpi */
2043
startx = start; /*optical_res, from dummy_pixel+1 */
2044
pixels = dev->settings.pixels;
2045
lines = dev->settings.lines;
2046
color_filter = dev->settings.color_filter;
2050
"gl847_calculate_current_setup settings:\n"
2051
"Resolution : %gDPI/%gDPI\n"
2055
"Depth/Channels: %u/%u\n\n",
2056
xres, yres, lines, pixels, startx, depth, channels);
2059
/* we have 2 domains for ccd: xres below or above half ccd max dpi */
2060
if ((dev->sensor.optical_res < 2 * xres) ||
2061
!(dev->model->flags & GENESYS_FLAG_HALF_CCD_MODE))
2063
half_ccd = SANE_FALSE;
2067
half_ccd = SANE_TRUE;
2072
optical_res = dev->sensor.optical_res;
2078
if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE))
2079
stagger = (4 * yres) / dev->motor.base_ydpi;
2082
DBG (DBG_info, "gl847_calculate_current_setup: stagger=%d lines\n",
2086
i = optical_res / xres;
2089
/* gl847 supports 1/1 1/2 1/3 1/4 1/5 1/6 1/8 1/10 1/12 1/15 averaging */
2090
if (i < 2) /* optical_res >= xres > optical_res/2 */
2091
used_res = optical_res;
2092
else if (i < 3) /* optical_res/2 >= xres > optical_res/3 */
2093
used_res = optical_res / 2;
2094
else if (i < 4) /* optical_res/3 >= xres > optical_res/4 */
2095
used_res = optical_res / 3;
2096
else if (i < 5) /* optical_res/4 >= xres > optical_res/5 */
2097
used_res = optical_res / 4;
2098
else if (i < 6) /* optical_res/5 >= xres > optical_res/6 */
2099
used_res = optical_res / 5;
2100
else if (i < 8) /* optical_res/6 >= xres > optical_res/8 */
2101
used_res = optical_res / 6;
2102
else if (i < 10) /* optical_res/8 >= xres > optical_res/10 */
2103
used_res = optical_res / 8;
2104
else if (i < 12) /* optical_res/10 >= xres > optical_res/12 */
2105
used_res = optical_res / 10;
2106
else if (i < 15) /* optical_res/12 >= xres > optical_res/15 */
2107
used_res = optical_res / 12;
2109
used_res = optical_res / 15;
2111
/* resolution is choosen from a fixed list */
2114
/* compute scan parameters values */
2115
/* pixels are allways given at half or full CCD optical resolution */
2116
/* use detected left margin and fixed value */
2118
/* compute correct pixels number */
2119
used_pixels = (pixels * optical_res) / used_res;
2122
/* dummy lines: may not be usefull, for instance 250 dpi works with 0 or 1
2123
dummy line. Maybe the dummy line adds correctness since the motor runs
2126
/* for cis this creates better aligned color lines:
2127
dummy \ scanned lines
2131
3: R G B - - - R ...
2132
4: R G B - - - - R ...
2133
5: R G B - - - - - R ...
2134
6: R G B - - - - - - R ...
2135
7: R G B - - - - - - - R ...
2136
8: R G B - - - - - - - - R ...
2137
9: R G B - - - - - - - - - R ...
2138
10: R G B - - - - - - - - - - R ...
2139
11: R G B - - - - - - - - - - - R ...
2140
12: R G B - - - - - - - - - - - - R ...
2141
13: R G B - - - - - - - - - - - - - R ...
2142
14: R G B - - - - - - - - - - - - - - R ...
2143
15: R G B - - - - - - - - - - - - - - - R ...
2149
/* cis color scan is effectively a gray scan with 3 gray lines per color
2150
line and a FILTER of 0 */
2151
if (dev->model->is_cis)
2152
slope_dpi = yres * channels;
2156
slope_dpi = slope_dpi * (1 + dummy);
2158
/* scan_step_type */
2174
led_exposure = gl847_get_led_exposure (dev);
2176
pixels_exposure=dev->sensor.sensor_pixels+572;
2177
if(xres<dev->sensor.optical_res)
2178
pixels_exposure=(pixels_exposure*xres)/dev->sensor.optical_res-32;
2183
exposure_time = sanei_genesys_exposure_time2 (dev,
2190
while (scan_power_mode + 1 < dev->motor.power_mode_count)
2192
exposure_time2 = sanei_genesys_exposure_time2 (dev,
2197
scan_power_mode + 1);
2198
if (exposure_time < exposure_time2)
2200
exposure_time = exposure_time2;
2205
"gl847_calculate_current_setup : exposure_time=%d pixels\n",
2209
/* scanned area must be enlarged by max color shift needed */
2210
/* all values are assumed >= 0 */
2213
max_shift = dev->model->ld_shift_r;
2214
if (dev->model->ld_shift_b > max_shift)
2215
max_shift = dev->model->ld_shift_b;
2216
if (dev->model->ld_shift_g > max_shift)
2217
max_shift = dev->model->ld_shift_g;
2218
max_shift = (max_shift * yres) / dev->motor.base_ydpi;
2226
lincnt = lines + max_shift + stagger;
2228
dev->current_setup.pixels = (used_pixels * used_res) / optical_res;
2229
dev->current_setup.lines = lincnt;
2230
dev->current_setup.depth = depth;
2231
dev->current_setup.channels = channels;
2232
dev->current_setup.exposure_time = exposure_time;
2233
dev->current_setup.xres = used_res;
2234
dev->current_setup.yres = yres;
2235
dev->current_setup.half_ccd = half_ccd;
2236
dev->current_setup.stagger = stagger;
2237
dev->current_setup.max_shift = max_shift + stagger;
2240
return SANE_STATUS_GOOD;
2244
gl847_set_motor_power (Genesys_Register_Set * regs, SANE_Bool set)
2247
DBG (DBG_proc, "gl847_set_motor_power\n");
2251
sanei_genesys_set_reg_from_set (regs, REG02,
2252
sanei_genesys_read_reg_from_set (regs,
2258
sanei_genesys_set_reg_from_set (regs, REG02,
2259
sanei_genesys_read_reg_from_set (regs,
2266
gl847_set_lamp_power (Genesys_Device * dev,
2267
Genesys_Register_Set * regs, SANE_Bool set)
2269
Genesys_Register_Set *r;
2274
sanei_genesys_set_reg_from_set (regs, 0x03,
2275
sanei_genesys_read_reg_from_set (regs,
2279
for (i = 0; i < 6; i++)
2281
r = sanei_genesys_get_address (dev->calib_reg, 0x10+i);
2282
r->value = dev->sensor.regs_0x10_0x1d[i];
2284
r = sanei_genesys_get_address (regs, 0x19);
2289
sanei_genesys_set_reg_from_set (regs, 0x03,
2290
sanei_genesys_read_reg_from_set (regs,
2294
for (i = 0; i < 6; i++)
2296
r = sanei_genesys_get_address (dev->calib_reg, 0x10+i);
2299
r = sanei_genesys_get_address (regs, 0x19);
2304
/*for fast power saving methods only, like disabling certain amplifiers*/
2306
gl847_save_power (Genesys_Device * dev, SANE_Bool enable)
2308
DBG (DBG_proc, "gl847_save_power: enable = %d\n", enable);
2310
return SANE_STATUS_INVAL;
2313
return SANE_STATUS_GOOD;
2317
gl847_set_powersaving (Genesys_Device * dev, int delay /* in minutes */ )
2319
DBG (DBG_proc, "gl847_set_powersaving (delay = %d)\n", delay);
2321
return SANE_STATUS_INVAL;
2324
return SANE_STATUS_GOOD;
2328
gl847_start_action (Genesys_Device * dev)
2330
return sanei_genesys_write_register (dev, 0x0f, 0x01);
2334
gl847_stop_action (Genesys_Device * dev)
2336
Genesys_Register_Set local_reg[GENESYS_GL847_MAX_REGS];
2341
DBG (DBG_proc, "%s\n", __FUNCTION__);
2343
status = sanei_genesys_get_status (dev, &val);
2344
if (DBG_LEVEL >= DBG_io)
2350
status = sanei_genesys_read_register (dev, REG40, &val40);
2351
if (status != SANE_STATUS_GOOD)
2354
"%s: failed to read home sensor: %s\n", __FUNCTION__,
2355
sane_strstatus (status));
2360
/* only stop action if needed */
2361
if (!(val40 & REG40_DATAENB) && !(val40 & REG40_MOTMFLG))
2363
DBG (DBG_info, "%s: already stopped\n", __FUNCTION__);
2365
return SANE_STATUS_GOOD;
2368
memset (local_reg, 0, sizeof (local_reg));
2370
memcpy (local_reg, dev->reg,
2371
GENESYS_GL847_MAX_REGS * sizeof (Genesys_Register_Set));
2373
gl847_init_optical_regs_off (dev, local_reg);
2375
gl847_init_motor_regs_off (dev, local_reg, 0);
2376
status = gl847_bulk_write_register (dev, local_reg, GENESYS_GL847_MAX_REGS);
2377
if (status != SANE_STATUS_GOOD)
2379
DBG (DBG_error, "%s: failed to bulk write registers: %s\n",
2380
__FUNCTION__, sane_strstatus (status));
2384
/* looks like writing the right registers to zero is enough to get the chip
2385
out of scan mode into command mode, actually triggering(writing to
2386
register 0x0f) seems to be unnecessary */
2391
status = sanei_genesys_get_status (dev, &val);
2392
if (DBG_LEVEL >= DBG_io)
2397
status = sanei_genesys_read_register (dev, 0x40, &val40);
2398
if (status != SANE_STATUS_GOOD)
2401
"%s: failed to read home sensor: %s\n", __FUNCTION__,
2402
sane_strstatus (status));
2407
/* if scanner is in command mode, we are done */
2408
if (!(val40 & REG40_DATAENB) && !(val40 & REG40_MOTMFLG)
2409
&& !(val & REG41_MOTORENB))
2412
return SANE_STATUS_GOOD;
2415
usleep (100 * 1000);
2420
return SANE_STATUS_IO_ERROR;
2424
gl847_get_paper_sensor (Genesys_Device * dev, SANE_Bool * paper_loaded)
2429
status = sanei_genesys_read_register (dev, REG6D, &val);
2430
if (status != SANE_STATUS_GOOD)
2433
"gl847_get_paper_sensor: failed to read gpio: %s\n",
2434
sane_strstatus (status));
2437
*paper_loaded = (val & 0x1) == 0;
2438
return SANE_STATUS_GOOD;
2440
return SANE_STATUS_INVAL;
2444
gl847_eject_document (Genesys_Device * dev)
2446
Genesys_Register_Set local_reg[GENESYS_GL847_MAX_REGS];
2449
SANE_Bool paper_loaded;
2450
unsigned int init_steps;
2454
DBG (DBG_proc, "gl847_eject_document\n");
2456
if (!dev->model->is_sheetfed == SANE_TRUE)
2459
"gl847_eject_document: there is no \"eject sheet\"-concept for non sheet fed\n");
2460
DBG (DBG_proc, "gl847_eject_document: finished\n");
2461
return SANE_STATUS_GOOD;
2465
memset (local_reg, 0, sizeof (local_reg));
2468
status = sanei_genesys_get_status (dev, &val);
2469
if (status != SANE_STATUS_GOOD)
2472
"gl847_eject_document: Failed to read status register: %s\n",
2473
sane_strstatus (status));
2477
status = gl847_stop_action (dev);
2478
if (status != SANE_STATUS_GOOD)
2481
"gl847_eject_document: failed to stop motor: %s\n",
2482
sane_strstatus (status));
2483
return SANE_STATUS_IO_ERROR;
2486
memcpy (local_reg, dev->reg,
2487
GENESYS_GL847_MAX_REGS * sizeof (Genesys_Register_Set));
2489
gl847_init_optical_regs_off (dev, local_reg);
2491
gl847_init_motor_regs (dev, local_reg, 65536, MOTOR_ACTION_FEED, 0);
2493
status = gl847_bulk_write_register (dev, local_reg, GENESYS_GL847_MAX_REGS);
2494
if (status != SANE_STATUS_GOOD)
2497
"gl847_eject_document: failed to bulk write registers: %s\n",
2498
sane_strstatus (status));
2502
status = gl847_start_action (dev);
2503
if (status != SANE_STATUS_GOOD)
2506
"gl847_eject_document: failed to start motor: %s\n",
2507
sane_strstatus (status));
2508
gl847_stop_action (dev);
2509
/* send original registers */
2510
gl847_bulk_write_register (dev, dev->reg, GENESYS_GL847_MAX_REGS);
2514
RIE (gl847_get_paper_sensor (dev, &paper_loaded));
2517
DBG (DBG_info, "gl847_eject_document: paper still loaded\n");
2518
/* force document TRUE, because it is definitely present */
2519
dev->document = SANE_TRUE;
2520
dev->scanhead_position_in_steps = 0;
2523
while (loop > 0) /* do not wait longer then 30 seconds */
2526
RIE (gl847_get_paper_sensor (dev, &paper_loaded));
2530
DBG (DBG_info, "gl847_eject_document: reached home position\n");
2531
DBG (DBG_proc, "gl847_eject_document: finished\n");
2534
usleep (100000); /* sleep 100 ms */
2540
/* when we come here then the scanner needed too much time for this, so we better stop the motor */
2541
gl847_stop_action (dev);
2543
"gl847_eject_document: timeout while waiting for scanhead to go home\n");
2544
return SANE_STATUS_IO_ERROR;
2548
feed_mm = SANE_UNFIX (dev->model->eject_feed);
2551
feed_mm += SANE_UNFIX (dev->model->post_scan);
2554
status = sanei_genesys_read_feed_steps (dev, &init_steps);
2555
if (status != SANE_STATUS_GOOD)
2558
"gl847_eject_document: Failed to read feed steps: %s\n",
2559
sane_strstatus (status));
2563
/* now feed for extra <number> steps */
2565
while (loop < 300) /* do not wait longer then 30 seconds */
2569
status = sanei_genesys_read_feed_steps (dev, &steps);
2570
if (status != SANE_STATUS_GOOD)
2573
"gl847_eject_document: Failed to read feed steps: %s\n",
2574
sane_strstatus (status));
2578
DBG (DBG_info, "gl847_eject_document: init_steps: %d, steps: %d\n",
2581
if (steps > init_steps + (feed_mm * dev->motor.base_ydpi) / MM_PER_INCH)
2586
usleep (100000); /* sleep 100 ms */
2590
status = gl847_stop_action (dev);
2591
if (status != SANE_STATUS_GOOD)
2594
"gl847_eject_document: Failed to stop motor: %s\n",
2595
sane_strstatus (status));
2599
dev->document = SANE_FALSE;
2601
DBG (DBG_proc, "gl847_eject_document: finished\n");
2602
return SANE_STATUS_GOOD;
2607
gl847_load_document (Genesys_Device * dev)
2610
SANE_Bool paper_loaded;
2612
DBG (DBG_proc, "gl847_load_document\n");
2613
while (loop > 0) /* do not wait longer then 30 seconds */
2616
RIE (gl847_get_paper_sensor (dev, &paper_loaded));
2620
DBG (DBG_info, "gl847_load_document: document inserted\n");
2622
/* when loading OK, document is here */
2623
dev->document = SANE_TRUE;
2625
usleep (1000000); /* give user 1000ms to place document correctly */
2628
usleep (100000); /* sleep 100 ms */
2634
/* when we come here then the user needed to much time for this */
2636
"gl847_load_document: timeout while waiting for document\n");
2637
return SANE_STATUS_IO_ERROR;
2640
DBG (DBG_proc, "gl847_load_document: finished\n");
2641
return SANE_STATUS_GOOD;
2645
* detects end of document and adjust current scan
2646
* to take it into account
2647
* used by sheetfed scanners
2650
gl847_detect_document_end (Genesys_Device * dev)
2652
SANE_Status status = SANE_STATUS_GOOD;
2653
SANE_Bool paper_loaded;
2654
unsigned int scancnt = 0;
2655
int flines, channels, depth, bytes_remain, sublines,
2656
bytes_to_flush, lines, sub_bytes, tmp, read_bytes_left;
2657
DBG (DBG_proc, "%s: begin\n", __FUNCTION__);
2659
RIE (gl847_get_paper_sensor (dev, &paper_loaded));
2661
/* sheetfed scanner uses home sensor as paper present */
2662
if ((dev->document == SANE_TRUE) && !paper_loaded)
2664
DBG (DBG_info, "%s: no more document\n", __FUNCTION__);
2665
dev->document = SANE_FALSE;
2667
channels = dev->current_setup.channels;
2668
depth = dev->current_setup.depth;
2669
read_bytes_left = (int) dev->read_bytes_left;
2670
DBG (DBG_io, "gl847_detect_document_end: read_bytes_left=%d\n",
2673
/* get lines read */
2674
status = sanei_genesys_read_scancnt (dev, &scancnt);
2675
if (status != SANE_STATUS_GOOD)
2681
/* compute number of line read */
2682
tmp = (int) dev->total_bytes_read;
2683
if (depth == 1 || dev->settings.scan_mode == SCAN_MODE_LINEART)
2684
flines = tmp * 8 / dev->settings.pixels / channels;
2686
flines = tmp / (depth / 8) / dev->settings.pixels / channels;
2688
/* number of scanned lines, but no read yet */
2689
flines = scancnt - flines;
2692
"gl847_detect_document_end: %d scanned but not read lines\n",
2696
/* adjust number of bytes to read
2697
* we need to read the final bytes which are word per line * number of last lines
2698
* to have doc leaving feeder */
2700
(SANE_UNFIX (dev->model->post_scan) * dev->current_setup.yres) /
2701
MM_PER_INCH + flines;
2702
DBG (DBG_io, "gl847_detect_document_end: adding %d line to flush\n",
2705
/* number of bytes to read from scanner to get document out of it after
2706
* end of document dectected by hardware sensor */
2707
bytes_to_flush = lines * dev->wpl;
2709
/* if we are already close to end of scan, flushing isn't needed */
2710
if (bytes_to_flush < read_bytes_left)
2712
/* we take all these step to work around an overflow on some plateforms */
2713
tmp = (int) dev->total_bytes_read;
2714
DBG (DBG_io, "gl847_detect_document_end: tmp=%d\n", tmp);
2715
bytes_remain = (int) dev->total_bytes_to_read;
2716
DBG (DBG_io, "gl847_detect_document_end: bytes_remain=%d\n",
2718
bytes_remain = bytes_remain - tmp;
2719
DBG (DBG_io, "gl847_detect_document_end: bytes_remain=%d\n",
2722
/* remaining lines to read by frontend for the current scan */
2723
if (depth == 1 || dev->settings.scan_mode == SCAN_MODE_LINEART)
2725
flines = bytes_remain * 8 / dev->settings.pixels / channels;
2728
flines = bytes_remain / (depth / 8)
2729
/ dev->settings.pixels / channels;
2730
DBG (DBG_io, "gl847_detect_document_end: flines=%d\n", flines);
2734
/* change the value controlling communication with the frontend :
2735
* total bytes to read is current value plus the number of remaining lines
2736
* multiplied by bytes per line */
2737
sublines = flines - lines;
2739
if (depth == 1 || dev->settings.scan_mode == SCAN_MODE_LINEART)
2741
((dev->settings.pixels * sublines) / 8 +
2742
(((dev->settings.pixels * sublines) % 8) ? 1 : 0)) *
2746
dev->settings.pixels * sublines * channels * (depth / 8);
2748
dev->total_bytes_to_read -= sub_bytes;
2750
/* then adjust the physical bytes to read */
2751
if (read_bytes_left > sub_bytes)
2753
dev->read_bytes_left -= sub_bytes;
2757
dev->total_bytes_to_read = dev->total_bytes_read;
2758
dev->read_bytes_left = 0;
2761
DBG (DBG_io, "gl847_detect_document_end: sublines=%d\n",
2763
DBG (DBG_io, "gl847_detect_document_end: subbytes=%d\n",
2766
"gl847_detect_document_end: total_bytes_to_read=%lu\n",
2767
(unsigned long)dev->total_bytes_to_read);
2769
"gl847_detect_document_end: read_bytes_left=%d\n",
2775
DBG (DBG_io, "gl847_detect_document_end: no flushing needed\n");
2779
DBG (DBG_proc, "%s: finished\n", __FUNCTION__);
2780
return SANE_STATUS_GOOD;
2783
/* Send the low-level scan command */
2784
/* todo : is this that useful ? */
2785
#ifndef UNIT_TESTING
2789
gl847_begin_scan (Genesys_Device * dev, Genesys_Register_Set * reg,
2790
SANE_Bool start_motor)
2798
RIE (sanei_genesys_read_register (dev, REG6C, &val));
2799
val &= ~REG6C_GPIO10;
2800
RIE (sanei_genesys_write_register (dev, REG6C, val));
2802
val = REG0D_CLRLNCNT;
2803
RIE (sanei_genesys_write_register (dev, REG0D, val));
2804
val = REG0D_CLRMCNT;
2805
RIE (sanei_genesys_write_register (dev, REG0D, val));
2807
RIE (sanei_genesys_read_register (dev, REG01, &val));
2809
RIE (sanei_genesys_write_register (dev, REG01, val));
2813
RIE (sanei_genesys_write_register (dev, REG0F, 1));
2817
RIE (sanei_genesys_write_register (dev, REG0F, 0));
2826
/* Send the stop scan command */
2827
#ifndef UNIT_TESTING
2831
gl847_end_scan (Genesys_Device * dev, Genesys_Register_Set * reg,
2832
SANE_Bool check_stop)
2836
DBG (DBG_proc, "gl847_end_scan (check_stop = %d)\n", check_stop);
2838
return SANE_STATUS_INVAL;
2840
if (dev->model->is_sheetfed == SANE_TRUE)
2842
status = SANE_STATUS_GOOD;
2844
else /* flat bed scanners */
2846
status = gl847_stop_action (dev);
2847
if (status != SANE_STATUS_GOOD)
2850
"gl847_end_scan: Failed to stop: %s\n",
2851
sane_strstatus (status));
2860
/* Moves the slider to steps */
2862
gl847_feed (Genesys_Device * dev, int steps)
2864
Genesys_Register_Set local_reg[GENESYS_GL847_MAX_REGS];
2869
DBG (DBG_proc, "gl847_feed (steps = %d)\n", steps);
2871
status = gl847_stop_action (dev);
2872
if (status != SANE_STATUS_GOOD)
2875
"gl847_feed: failed to stop action: %s\n",
2876
sane_strstatus (status));
2880
memset (local_reg, 0, sizeof (local_reg));
2882
memcpy (local_reg, dev->reg,
2883
GENESYS_GL847_MAX_REGS * sizeof (Genesys_Register_Set));
2885
gl847_init_optical_regs_off (dev, local_reg);
2887
gl847_init_motor_regs (dev, local_reg, steps, MOTOR_ACTION_FEED, 0);
2889
status = gl847_bulk_write_register (dev, local_reg, GENESYS_GL847_MAX_REGS);
2890
if (status != SANE_STATUS_GOOD)
2893
"gl847_feed: failed to bulk write registers: %s\n",
2894
sane_strstatus (status));
2898
status = gl847_start_action (dev);
2899
if (status != SANE_STATUS_GOOD)
2902
"gl847_feed: failed to start motor: %s\n",
2903
sane_strstatus (status));
2904
gl847_stop_action (dev);
2905
/* send original registers */
2906
gl847_bulk_write_register (dev, dev->reg, GENESYS_GL847_MAX_REGS);
2911
while (loop < 300) /* do not wait longer then 30 seconds */
2913
status = sanei_genesys_get_status (dev, &val);
2914
if (status != SANE_STATUS_GOOD)
2917
"gl847_feed: failed to read home sensor: %s\n",
2918
sane_strstatus (status));
2922
if (!(val & REG41_MOTORENB)) /* motor enabled */
2924
DBG (DBG_proc, "gl847_feed: finished\n");
2925
dev->scanhead_position_in_steps += steps;
2926
return SANE_STATUS_GOOD;
2928
usleep (100000); /* sleep 100 ms */
2932
/* when we come here then the scanner needed too much time for this, so we better stop the motor */
2933
gl847_stop_action (dev);
2936
"gl847_feed: timeout while feeding\n");
2937
return SANE_STATUS_IO_ERROR;
2940
/* Moves the slider to the home (top) postion slowly */
2942
gl847_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
2944
Genesys_Register_Set local_reg[GENESYS_GL847_MAX_REGS];
2948
DBG (DBG_proc, "gl847_slow_back_home (wait_until_home = %d)\n",
2951
if (dev->model->is_sheetfed == SANE_TRUE)
2954
"gl847_slow_back_home: there is no \"home\"-concept for sheet fed\n");
2955
DBG (DBG_proc, "gl847_slow_back_home: finished\n");
2956
return SANE_STATUS_GOOD;
2959
memset (local_reg, 0, sizeof (local_reg));
2961
/* reset gpio pin */
2962
RIE (sanei_genesys_read_register (dev, REG6C, &val));
2963
val = dev->gpo.value[0];
2964
RIE (sanei_genesys_write_register (dev, REG6C, val));
2966
/* first read gives HOME_SENSOR true */
2967
status = sanei_genesys_get_status (dev, &val);
2968
if (status != SANE_STATUS_GOOD)
2971
"gl847_slow_back_home: failed to read home sensor: %s\n",
2972
sane_strstatus (status));
2975
if (DBG_LEVEL >= DBG_io)
2979
usleep (100000); /* sleep 100 ms */
2981
/* second is reliable */
2982
status = sanei_genesys_get_status (dev, &val);
2983
if (status != SANE_STATUS_GOOD)
2986
"gl847_slow_back_home: failed to read home sensor: %s\n",
2987
sane_strstatus (status));
2990
if (DBG_LEVEL >= DBG_io)
2995
dev->scanhead_position_in_steps = 0;
2997
if (val & REG41_HOMESNR) /* is sensor at home? */
2999
DBG (DBG_info, "gl847_slow_back_home: already at home, completed\n");
3000
dev->scanhead_position_in_steps = 0;
3002
return SANE_STATUS_GOOD;
3005
/* if motor is on, stop current action */
3006
if (val & REG41_MOTORENB)
3008
status = gl847_stop_action (dev);
3009
if (status != SANE_STATUS_GOOD)
3012
"gl847_slow_back_home: failed to stop motor: %s\n",
3013
sane_strstatus (status));
3014
return SANE_STATUS_IO_ERROR;
3018
memcpy (local_reg, dev->reg,
3019
GENESYS_GL847_MAX_REGS * sizeof (Genesys_Register_Set));
3021
gl847_init_optical_regs_off (dev, local_reg);
3023
gl847_init_motor_regs (dev, local_reg, 65536, MOTOR_ACTION_GO_HOME, 0);
3025
status = gl847_bulk_write_register (dev, local_reg, GENESYS_GL847_MAX_REGS);
3026
if (status != SANE_STATUS_GOOD)
3029
"gl847_slow_back_home: failed to bulk write registers: %s\n",
3030
sane_strstatus (status));
3034
status = gl847_start_action (dev);
3035
if (status != SANE_STATUS_GOOD)
3038
"gl847_slow_back_home: failed to start motor: %s\n",
3039
sane_strstatus (status));
3040
gl847_stop_action (dev);
3041
/* send original registers */
3042
gl847_bulk_write_register (dev, dev->reg, GENESYS_GL847_MAX_REGS);
3046
if (wait_until_home)
3050
while (loop < 300) /* do not wait longer then 30 seconds */
3052
status = sanei_genesys_get_status (dev, &val);
3053
if (status != SANE_STATUS_GOOD)
3056
"gl847_slow_back_home: failed to read home sensor: %s\n",
3057
sane_strstatus (status));
3061
if (val & REG41_HOMESNR) /* home sensor */
3063
DBG (DBG_info, "gl847_slow_back_home: reached home position\n");
3064
DBG (DBG_proc, "gl847_slow_back_home: finished\n");
3065
return SANE_STATUS_GOOD;
3067
usleep (100000); /* sleep 100 ms */
3071
/* when we come here then the scanner needed too much time for this, so we better stop the motor */
3072
gl847_stop_action (dev);
3074
"gl847_slow_back_home: timeout while waiting for scanhead to go home\n");
3075
return SANE_STATUS_IO_ERROR;
3078
DBG (DBG_info, "gl847_slow_back_home: scanhead is still moving\n");
3079
DBG (DBG_proc, "gl847_slow_back_home: finished\n");
3080
return SANE_STATUS_GOOD;
3083
/* Automatically set top-left edge of the scan area by scanning a 200x200 pixels
3084
area at 600 dpi from very top of scanner */
3086
gl847_search_start_position (Genesys_Device * dev)
3091
Genesys_Register_Set local_reg[GENESYS_GL847_MAX_REGS];
3097
DBG (DBG_proc, "gl847_search_start_position\n");
3099
memset (local_reg, 0, sizeof (local_reg));
3100
memcpy (local_reg, dev->reg,
3101
GENESYS_GL847_MAX_REGS * sizeof (Genesys_Register_Set));
3103
/* sets for a 200 lines * 600 pixels */
3104
/* normal scan with no shading */
3106
status = gl847_init_scan_regs (dev, local_reg, dpi, dpi, 0, 0, /*we should give a small offset here~60 steps */
3107
600, dev->model->search_lines, 8, 1, 1, /*green */
3108
SCAN_FLAG_DISABLE_SHADING |
3109
SCAN_FLAG_DISABLE_GAMMA |
3110
SCAN_FLAG_IGNORE_LINE_DISTANCE |
3111
SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE);
3113
/* send to scanner */
3114
status = gl847_bulk_write_register (dev, local_reg, GENESYS_GL847_MAX_REGS);
3115
if (status != SANE_STATUS_GOOD)
3118
"gl847_search_start_position: failed to bulk write registers: %s\n",
3119
sane_strstatus (status));
3123
size = pixels * dev->model->search_lines;
3125
data = malloc (size);
3129
"gl847_search_start_position: failed to allocate memory\n");
3130
return SANE_STATUS_NO_MEM;
3133
status = gl847_begin_scan (dev, local_reg, SANE_TRUE);
3134
if (status != SANE_STATUS_GOOD)
3138
"gl847_search_start_position: failed to begin scan: %s\n",
3139
sane_strstatus (status));
3143
/* waits for valid data */
3145
sanei_genesys_test_buffer_empty (dev, &steps);
3148
/* now we're on target, we can read data */
3149
status = sanei_genesys_read_data_from_scanner (dev, data, size);
3150
if (status != SANE_STATUS_GOOD)
3154
"gl847_search_start_position: failed to read data: %s\n",
3155
sane_strstatus (status));
3159
if (DBG_LEVEL >= DBG_data)
3160
sanei_genesys_write_pnm_file ("search_position.pnm", data, 8, 1, pixels,
3161
dev->model->search_lines);
3163
status = gl847_end_scan (dev, local_reg, SANE_TRUE);
3164
if (status != SANE_STATUS_GOOD)
3168
"gl847_search_start_position: failed to end scan: %s\n",
3169
sane_strstatus (status));
3173
/* update regs to copy ASIC internal state */
3174
memcpy (dev->reg, local_reg,
3175
GENESYS_GL847_MAX_REGS * sizeof (Genesys_Register_Set));
3177
/*TODO: find out where sanei_genesys_search_reference_point
3178
stores information, and use that correctly*/
3180
sanei_genesys_search_reference_point (dev, data, 0, dpi, pixels,
3181
dev->model->search_lines);
3182
if (status != SANE_STATUS_GOOD)
3186
"gl847_search_start_position: failed to set search reference point: %s\n",
3187
sane_strstatus (status));
3192
return SANE_STATUS_GOOD;
3196
* sets up register for coarse gain calibration
3197
* todo: check it for scanners using it */
3199
gl847_init_regs_for_coarse_calibration (Genesys_Device * dev)
3205
DBG (DBG_proc, "gl847_init_regs_for_coarse_calibration\n");
3208
cksel = (dev->calib_reg[reg_0x18].value & REG18_CKSEL) + 1; /* clock speed = 1..4 clocks */
3211
if (dev->settings.scan_mode == SCAN_MODE_COLOR) /* single pass color */
3216
status = gl847_init_scan_regs (dev,
3222
dev->sensor.optical_res / cksel,
3226
dev->settings.color_filter,
3227
SCAN_FLAG_DISABLE_SHADING |
3228
SCAN_FLAG_DISABLE_GAMMA |
3229
SCAN_FLAG_SINGLE_LINE |
3230
SCAN_FLAG_IGNORE_LINE_DISTANCE);
3231
if (status != SANE_STATUS_GOOD)
3234
"gl847_init_register_for_coarse_calibration: Failed to setup scan: %s\n",
3235
sane_strstatus (status));
3240
"gl847_init_register_for_coarse_calibration: optical sensor res: %d dpi, actual res: %d\n",
3241
dev->sensor.optical_res / cksel, dev->settings.xres);
3244
gl847_bulk_write_register (dev, dev->calib_reg, GENESYS_GL847_MAX_REGS);
3245
if (status != SANE_STATUS_GOOD)
3248
"gl847_init_register_for_coarse_calibration: Failed to bulk write registers: %s\n",
3249
sane_strstatus (status));
3254
return SANE_STATUS_GOOD;
3258
/* init registers for shading calibration */
3260
gl847_init_regs_for_shading (Genesys_Device * dev)
3264
DBG (DBG_proc, "gl847_init_regs_for_shading: lines = %d\n",
3265
dev->model->shading_lines);
3267
dev->calib_channels = 3;
3269
/* initial calibration reg values */
3270
memcpy (dev->calib_reg, dev->reg,
3271
GENESYS_GL847_MAX_REGS * sizeof (Genesys_Register_Set));
3273
dev->calib_pixels = dev->sensor.sensor_pixels;
3275
status = gl847_init_scan_regs (dev,
3277
dev->sensor.optical_res,
3278
dev->motor.base_ydpi,
3282
dev->model->shading_lines,
3284
dev->calib_channels,
3285
dev->settings.color_filter,
3286
SCAN_FLAG_DISABLE_SHADING |
3287
SCAN_FLAG_DISABLE_GAMMA |
3288
SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE |
3289
SCAN_FLAG_IGNORE_LINE_DISTANCE |
3290
SCAN_FLAG_USE_OPTICAL_RES);
3293
if (status != SANE_STATUS_GOOD)
3296
"gl847_init_registers_for_shading: Failed to setup scan: %s\n",
3297
sane_strstatus (status));
3301
dev->scanhead_position_in_steps += dev->model->shading_lines;
3304
gl847_bulk_write_register (dev, dev->calib_reg, GENESYS_GL847_MAX_REGS);
3305
if (status != SANE_STATUS_GOOD)
3308
"gl847_init_registers_for_shading: Failed to bulk write registers: %s\n",
3309
sane_strstatus (status));
3314
return SANE_STATUS_GOOD;
3317
/** @brief set up registers for the actual scan
3320
gl847_init_regs_for_scan (Genesys_Device * dev)
3333
"gl847_init_regs_for_scan settings:\nResolution: %uDPI\n"
3334
"Lines : %u\nPPL : %u\nStartpos : %.3f/%.3f\nScan mode : %d\n\n",
3335
dev->settings.yres, dev->settings.lines, dev->settings.pixels,
3336
dev->settings.tl_x, dev->settings.tl_y, dev->settings.scan_mode);
3338
gl847_slow_back_home (dev, 1);
3341
if (dev->settings.scan_mode == SCAN_MODE_COLOR) /* single pass color */
3347
depth = dev->settings.depth;
3348
if (dev->settings.scan_mode == SCAN_MODE_LINEART)
3352
/* steps to move to reach scanning area:
3353
- first we move to physical start of scanning
3354
either by a fixed steps amount from the black strip
3355
or by a fixed amount from parking position,
3356
minus the steps done during shading calibration
3357
- then we move by the needed offset whitin physical
3360
assumption: steps are expressed at maximum motor resolution
3363
SANE_Fixed y_offset;
3365
SANE_Fixed y_offset_calib;
3366
mm_to_steps()=motor dpi / 2.54 / 10=motor dpi / MM_PER_INCH */
3368
/* if scanner uses GENESYS_FLAG_SEARCH_START y_offset is
3369
relative from origin, else, it is from parking position */
3371
move_dpi = dev->motor.base_ydpi;
3373
move = SANE_UNFIX (dev->model->y_offset);
3374
move += dev->settings.tl_y;
3375
move = (move * move_dpi) / MM_PER_INCH;
3376
DBG (DBG_info, "gl847_init_regs_for_scan: move=%f steps\n", move);
3378
/* at high res we do fast move to scan area */
3379
if(dev->settings.xres>150)
3381
status = gl847_feed (dev, move);
3382
if (status != SANE_STATUS_GOOD)
3384
DBG (DBG_error, "%s: failed to move to scan area\n",__FUNCTION__);
3390
/* clear scancnt and fedcnt */
3391
val = REG0D_CLRLNCNT;
3392
RIE (sanei_genesys_write_register (dev, REG0D, val));
3393
val = REG0D_CLRMCNT;
3394
RIE (sanei_genesys_write_register (dev, REG0D, val));
3397
start = SANE_UNFIX (dev->model->x_offset);
3398
start += dev->settings.tl_x;
3399
start = (start * dev->sensor.optical_res) / MM_PER_INCH;
3403
/* emulated lineart from gray data is required for now */
3404
flags |= SCAN_FLAG_DYNAMIC_LINEART;
3406
status = gl847_init_scan_regs (dev,
3412
dev->settings.pixels,
3413
dev->settings.lines,
3416
dev->settings.color_filter,
3419
if (status != SANE_STATUS_GOOD)
3423
return SANE_STATUS_GOOD;
3427
/** @brief send gmma table to scanner
3428
* This function sends generic gamma table (ie ones built with
3429
* provided gamma) or the user defined one if provided by
3431
* @param dev device to write to
3432
* @param generic flag for using generic gamma tables
3435
gl847_send_gamma_table (Genesys_Device * dev, SANE_Bool generic)
3439
uint8_t *gamma, val;
3442
DBG (DBG_proc, "gl847_send_gamma_table\n");
3444
/* don't send anything if no specific gamma table defined */
3446
&& (dev->sensor.red_gamma_table == NULL
3447
|| dev->sensor.green_gamma_table == NULL
3448
|| dev->sensor.blue_gamma_table == NULL))
3450
DBG (DBG_proc, "gl847_send_gamma_table: nothing to send, skipping\n");
3451
return SANE_STATUS_GOOD;
3456
/* allocate temporary gamma tables: 16 bits words, 3 channels */
3457
gamma = (uint8_t *) malloc (size * 2 * 3);
3459
return SANE_STATUS_NO_MEM;
3461
/* take care off generic/specific data */
3464
/* fill with default values */
3465
for (i = 0; i < size; i++)
3468
gamma[i * 2 + size * 0 + 0] = gmmval & 0xff;
3469
gamma[i * 2 + size * 0 + 1] = (gmmval >> 8) & 0xff;
3470
gamma[i * 2 + size * 2 + 0] = gmmval & 0xff;
3471
gamma[i * 2 + size * 2 + 1] = (gmmval >> 8) & 0xff;
3472
gamma[i * 2 + size * 4 + 0] = gmmval & 0xff;
3473
gamma[i * 2 + size * 4 + 1] = (gmmval >> 8) & 0xff;
3478
/* copy sensor specific's gamma tables */
3479
for (i = 0; i < size; i++)
3481
gamma[i * 2 + size * 0 + 0] = dev->sensor.red_gamma_table[i] & 0xff;
3482
gamma[i * 2 + size * 0 + 1] =
3483
(dev->sensor.red_gamma_table[i] >> 8) & 0xff;
3484
gamma[i * 2 + size * 2 + 0] =
3485
dev->sensor.green_gamma_table[i] & 0xff;
3486
gamma[i * 2 + size * 2 + 1] =
3487
(dev->sensor.green_gamma_table[i] >> 8) & 0xff;
3488
gamma[i * 2 + size * 4 + 0] =
3489
dev->sensor.blue_gamma_table[i] & 0xff;
3490
gamma[i * 2 + size * 4 + 1] =
3491
(dev->sensor.blue_gamma_table[i] >> 8) & 0xff;
3495
/* loop sending gamma tables NOTE: 0x01000000 not 0x10000000 */
3496
for (i = 0; i < 3; i++)
3498
/* clear corresponding GMM_N bit */
3499
RIE (sanei_genesys_read_register (dev, 0xbd, &val));
3500
val &= ~(0x01 << i);
3501
RIE (sanei_genesys_write_register (dev, 0xbd, val));
3503
/* clear corresponding GMM_F bit */
3504
RIE (sanei_genesys_read_register (dev, 0xbe, &val));
3505
val &= ~(0x01 << i);
3506
RIE (sanei_genesys_write_register (dev, 0xbe, val));
3509
RIE (sanei_genesys_write_register (dev, 0xc5+2*i, 0x00));
3510
RIE (sanei_genesys_write_register (dev, 0xc6+2*i, 0x00));
3513
sanei_genesys_write_ahb (dev->dn, 0x01000000 + 0x200 * i, size * 2,
3514
gamma + i * size * 2);
3515
if (status != SANE_STATUS_GOOD)
3518
"gl847_send_gamma_table: write to AHB failed writing table %d (%s)\n",
3519
i, sane_strstatus (status));
3529
* Send shading calibration data. The buffer is considered to always hold values
3530
* for all the channels.
3533
gl847_send_shading_data (Genesys_Device * dev, uint8_t * data, int size)
3535
SANE_Status status = SANE_STATUS_GOOD;
3536
uint32_t addr, length;
3540
DBG( DBG_io2, "%s: writing %d bytes of shading data\n",__FUNCTION__,size);
3542
/* shading data is plit in 3 (up to 5 with IR) areas
3543
write(0x10014000,0x00000dd8)
3544
URB 23429 bulk_out len 3544 wrote 0x33 0x10 0x....
3545
write(0x1003e000,0x00000dd8)
3546
write(0x10068000,0x00000dd8)
3548
length = (uint32_t) (size / 3);
3549
DBG( DBG_io2, "%s: using chunks of %d (0x%04x) bytes\n",__FUNCTION__,length,length);
3551
/* base addr of data has been written in reg D0-D4 in 4K word, so AHB address
3552
* is 8192*reg value */
3554
/* write actual red data */
3555
RIE (sanei_genesys_read_register (dev, 0xd0, &val));
3556
addr = val * 8192 + 0x10000000;
3557
status = sanei_genesys_write_ahb (dev->dn, addr, length, data);
3558
if (status != SANE_STATUS_GOOD)
3560
DBG (DBG_error, "gl847_send_shading_data; write to AHB failed (%s)\n",
3561
sane_strstatus (status));
3565
/* write actual green data */
3566
RIE (sanei_genesys_read_register (dev, 0xd1, &val));
3567
addr = val * 8192 + 0x10000000;
3568
status = sanei_genesys_write_ahb (dev->dn, addr, length, data + length);
3569
if (status != SANE_STATUS_GOOD)
3571
DBG (DBG_error, "gl847_send_shading_data; write to AHB failed (%s)\n",
3572
sane_strstatus (status));
3576
/* write actual blue data */
3577
RIE (sanei_genesys_read_register (dev, 0xd2, &val));
3578
addr = val * 8192 + 0x10000000;
3579
status = sanei_genesys_write_ahb (dev->dn, addr, length, data + 2 * length);
3580
if (status != SANE_STATUS_GOOD)
3582
DBG (DBG_error, "gl847_send_shading_data; write to AHB failed (%s)\n",
3583
sane_strstatus (status));
3592
/* this function does the led calibration by scanning one line of the calibration
3593
area below scanner's top on white strip.
3595
-needs working coarse/gain
3598
gl847_led_calibration (Genesys_Device * dev)
3605
SANE_Status status = SANE_STATUS_GOOD;
3607
int channels, depth;
3608
int avg[3], avga, avge;
3611
uint16_t expr, expg, expb;
3612
Genesys_Register_Set *r;
3614
SANE_Bool acceptable = SANE_FALSE;
3616
DBG (DBG_proc, "gl847_led_calibration\n");
3618
/* offset calibration is always done in color mode */
3621
used_res = dev->sensor.optical_res;
3622
num_pixels = (dev->sensor.sensor_pixels*used_res)/dev->sensor.optical_res;
3624
/* initial calibration reg values */
3625
memcpy (dev->calib_reg, dev->reg,
3626
GENESYS_GL847_MAX_REGS * sizeof (Genesys_Register_Set));
3628
status = gl847_init_scan_regs (dev,
3631
dev->motor.base_ydpi,
3638
dev->settings.color_filter,
3639
SCAN_FLAG_DISABLE_SHADING |
3640
SCAN_FLAG_DISABLE_GAMMA |
3641
SCAN_FLAG_SINGLE_LINE |
3642
SCAN_FLAG_IGNORE_LINE_DISTANCE |
3643
SCAN_FLAG_USE_OPTICAL_RES);
3645
if (status != SANE_STATUS_GOOD)
3648
"gl847_led_calibration: failed to setup scan: %s\n",
3649
sane_strstatus (status));
3653
RIE (gl847_bulk_write_register
3654
(dev, dev->calib_reg, GENESYS_GL847_MAX_REGS));
3657
total_size = num_pixels * channels * (depth/8) * 1; /* colors * bytes_per_color * scan lines */
3659
line = malloc (total_size);
3661
return SANE_STATUS_NO_MEM;
3664
we try to get equal bright leds here:
3668
adjust exposure times
3671
expr = (dev->sensor.regs_0x10_0x1d[0] << 8) | dev->sensor.regs_0x10_0x1d[1];
3672
expg = (dev->sensor.regs_0x10_0x1d[2] << 8) | dev->sensor.regs_0x10_0x1d[3];
3673
expb = (dev->sensor.regs_0x10_0x1d[4] << 8) | dev->sensor.regs_0x10_0x1d[5];
3680
dev->sensor.regs_0x10_0x1d[0] = (expr >> 8) & 0xff;
3681
dev->sensor.regs_0x10_0x1d[1] = expr & 0xff;
3682
dev->sensor.regs_0x10_0x1d[2] = (expg >> 8) & 0xff;
3683
dev->sensor.regs_0x10_0x1d[3] = expg & 0xff;
3684
dev->sensor.regs_0x10_0x1d[4] = (expb >> 8) & 0xff;
3685
dev->sensor.regs_0x10_0x1d[5] = expb & 0xff;
3687
for (i = 0; i < 6; i++)
3689
r = sanei_genesys_get_address (dev->calib_reg, 0x10+i);
3690
r->value = dev->sensor.regs_0x10_0x1d[i];
3693
RIE (gl847_bulk_write_register
3694
(dev, dev->calib_reg, GENESYS_GL847_MAX_REGS));
3696
DBG (DBG_info, "gl847_led_calibration: starting first line reading\n");
3697
RIE (gl847_begin_scan (dev, dev->calib_reg, SANE_TRUE));
3698
RIE (sanei_genesys_read_data_from_scanner (dev, line, total_size));
3700
if (DBG_LEVEL >= DBG_data)
3702
snprintf (fn, 20, "led_%02d.pnm", turn);
3703
sanei_genesys_write_pnm_file (fn,
3704
line, depth, channels, num_pixels, 1);
3707
acceptable = SANE_TRUE;
3709
for (j = 0; j < channels; j++)
3712
for (i = 0; i < num_pixels; i++)
3714
if (dev->model->is_cis)
3716
line[i * 2 + j * 2 * num_pixels + 1] * 256 +
3717
line[i * 2 + j * 2 * num_pixels];
3720
line[i * 2 * channels + 2 * j + 1] * 256 +
3721
line[i * 2 * channels + 2 * j];
3725
avg[j] /= num_pixels;
3728
DBG (DBG_info, "gl847_led_calibration: average: "
3729
"%d,%d,%d\n", avg[0], avg[1], avg[2]);
3731
acceptable = SANE_TRUE;
3733
if (avg[0] < avg[1] * 0.95 || avg[1] < avg[0] * 0.95 ||
3734
avg[0] < avg[2] * 0.95 || avg[2] < avg[0] * 0.95 ||
3735
avg[1] < avg[2] * 0.95 || avg[2] < avg[1] * 0.95)
3736
acceptable = SANE_FALSE;
3740
avga = (avg[0] + avg[1] + avg[2]) / 3;
3741
expr = (expr * avga) / avg[0];
3742
expg = (expg * avga) / avg[1];
3743
expb = (expb * avga) / avg[2];
3745
keep the resulting exposures below this value.
3746
too long exposure drives the ccd into saturation.
3747
we may fix this by relying on the fact that
3748
we get a striped scan without shading, by means of
3749
statistical calculation
3751
avge = (expr + expg + expb) / 3;
3753
/* don't overflow max exposure */
3756
expr = (expr * 2000) / avge;
3757
expg = (expg * 2000) / avge;
3758
expb = (expb * 2000) / avge;
3762
expr = (expr * 50) / avge;
3763
expg = (expg * 50) / avge;
3764
expb = (expb * 50) / avge;
3769
RIE (gl847_stop_action (dev));
3774
while (!acceptable && turn < 100);
3776
DBG (DBG_info, "gl847_led_calibration: acceptable exposure: %d,%d,%d\n",
3779
/* cleanup before return */
3782
gl847_slow_back_home (dev, SANE_TRUE);
3788
/* this function does the offset calibration by scanning one line of the calibration
3789
area below scanner's top. There is a black margin and the remaining is white.
3790
sanei_genesys_search_start() must have been called so that the offsets and margins
3793
this function expects the slider to be where?
3796
gl847_offset_calibration (Genesys_Device * dev)
3798
DBG (DBG_proc, "%s: not implemented \n", __FUNCTION__);
3799
return SANE_STATUS_GOOD;
3803
/* alternative coarse gain calibration
3804
this on uses the settings from offset_calibration and
3805
uses only one scanline
3808
with offset and coarse calibration we only want to get our input range into
3809
a reasonable shape. the fine calibration of the upper and lower bounds will
3810
be done with shading.
3813
gl847_coarse_gain_calibration (Genesys_Device * dev, int dpi)
3815
DBG (DBG_proc, "%s: not implemented \n", __FUNCTION__);
3816
return SANE_STATUS_GOOD;
3820
* wait for lamp warmup by scanning the same line until difference
3821
* between 2 scans is below a threshold
3824
gl847_init_regs_for_warmup (Genesys_Device * dev,
3825
Genesys_Register_Set * local_reg,
3826
int *channels, int *total_size)
3828
DBG (DBG_proc, "%s: not implemented \n", __FUNCTION__);
3829
return SANE_STATUS_GOOD;
3833
gl847_is_compatible_calibration (Genesys_Device * dev,
3834
Genesys_Calibration_Cache * cache,
3837
#ifdef HAVE_SYS_TIME_H
3838
struct timeval time;
3842
DBG (DBG_proc, "gl847_is_compatible_calibration\n");
3844
status = gl847_calculate_current_setup (dev);
3846
if (status != SANE_STATUS_GOOD)
3849
"gl847_is_compatible_calibration: failed to calculate current setup: %s\n",
3850
sane_strstatus (status));
3854
DBG (DBG_proc, "gl847_is_compatible_calibration: checking\n");
3856
if (dev->current_setup.half_ccd != cache->used_setup.half_ccd)
3857
return SANE_STATUS_UNSUPPORTED;
3859
/* a cache entry expires after 60 minutes for non sheetfed scanners */
3860
#ifdef HAVE_SYS_TIME_H
3861
gettimeofday (&time, NULL);
3862
if ((time.tv_sec - cache->last_calibration > 60 * 60)
3863
&& (dev->model->is_sheetfed == SANE_FALSE)
3864
&& (dev->settings.scan_method == SCAN_METHOD_FLATBED))
3867
"gl847_is_compatible_calibration: expired entry, non compatible cache\n");
3868
return SANE_STATUS_UNSUPPORTED;
3873
return SANE_STATUS_GOOD;
3877
* set up GPIO/GPOE for idle state
3880
gl847_init_gpio (Genesys_Device * dev)
3882
SANE_Status status = SANE_STATUS_GOOD;
3883
uint8_t val, effective;
3885
DBG (DBG_proc, "gl847_init_gpio: start\n");
3887
RIE (sanei_genesys_write_register (dev, 0x6e, dev->gpo.enable[0]));
3888
RIE (sanei_genesys_write_register (dev, 0x6f, dev->gpo.enable[1]));
3889
RIE (sanei_genesys_write_register (dev, 0xa7, 0x04));
3890
RIE (sanei_genesys_write_register (dev, 0xa8, 0x00));
3891
RIE (sanei_genesys_write_register (dev, 0xa9, 0x00));
3893
/* toggle needed bits one after all */
3894
/* TODO define a function for bit toggling */
3895
RIE (sanei_genesys_read_register (dev, REG6C, &effective));
3896
val = effective | 0x80;
3897
RIE (sanei_genesys_write_register (dev, REG6C, val));
3898
RIE (sanei_genesys_read_register (dev, REG6C, &effective));
3899
if (effective != val)
3902
"gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n",
3906
val = effective | 0x40;
3907
RIE (sanei_genesys_write_register (dev, REG6C, val));
3908
RIE (sanei_genesys_read_register (dev, REG6C, &effective));
3909
if (effective != val)
3912
"gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n",
3916
val = effective | 0x20;
3917
RIE (sanei_genesys_write_register (dev, REG6C, val));
3919
/* seems useless : memory or clock related ? */
3920
RIE (sanei_genesys_read_register (dev, REG0B, &effective));
3921
RIE (sanei_genesys_write_register (dev, REG0B, effective));
3923
RIE (sanei_genesys_read_register (dev, REG6C, &effective));
3924
if (effective != val)
3927
"gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n",
3931
/* not done yet for LiDE 100
3932
val = effective | 0x08;
3933
RIE (sanei_genesys_write_register (dev, REG6C, val));
3934
RIE (sanei_genesys_read_register (dev, REG6C, &effective));
3935
if (effective != val)
3937
DBG (DBG_warn, "gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n",
3941
val = effective | 0x02;
3942
RIE (sanei_genesys_write_register (dev, REG6C, val));
3943
RIE (sanei_genesys_read_register (dev, REG6C, &effective));
3944
if (effective != val)
3947
"gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n",
3951
val = effective | 0x01;
3952
RIE (sanei_genesys_write_register (dev, REG6C, val));
3953
RIE (sanei_genesys_read_register (dev, REG6C, &effective));
3954
if (effective != val)
3957
"gl847_init_gpio: effective!=needed (0x%02x!=0x%02x) \n",
3966
* set memory layout by filling values in dedicated registers
3969
gl847_init_memory_layout (Genesys_Device * dev)
3971
SANE_Status status = SANE_STATUS_GOOD;
3974
DBG (DBG_proc, "gl847_init_memory_layout\n");
3976
/* point to per model memory layout */
3978
if (strcmp (dev->model->name, "canon-lide-100") == 0)
3982
if (strcmp (dev->model->name, "canon-lide-200") == 0)
3986
if (strcmp (dev->model->name, "canon-5600f") == 0)
3990
if (strcmp (dev->model->name, "canon-lide-700f") == 0)
3995
/* setup base address for shading data. */
3996
/* values must be multiplied by 8192=0x4000 to give address on AHB */
3997
/* R-Channel shading bank0 address setting for CIS */
3998
sanei_genesys_write_register (dev, 0xd0, layouts[idx].rd0);
3999
/* G-Channel shading bank0 address setting for CIS */
4000
sanei_genesys_write_register (dev, 0xd1, layouts[idx].rd1);
4001
/* B-Channel shading bank0 address setting for CIS */
4002
sanei_genesys_write_register (dev, 0xd2, layouts[idx].rd2);
4004
/* setup base address for scanned data. */
4005
/* values must be multiplied by 1024*2=0x0800 to give address on AHB */
4006
/* R-Channel ODD image buffer 0x0124->0x92000 */
4007
/* size for each buffer is 0x16d*1k word */
4008
sanei_genesys_write_register (dev, 0xe0, layouts[idx].re0);
4009
sanei_genesys_write_register (dev, 0xe1, layouts[idx].re1);
4010
/* R-Channel ODD image buffer end-address 0x0291->0x148800 => size=0xB6800*/
4011
sanei_genesys_write_register (dev, 0xe2, layouts[idx].re2);
4012
sanei_genesys_write_register (dev, 0xe3, layouts[idx].re3);
4014
/* R-Channel EVEN image buffer 0x0292 */
4015
sanei_genesys_write_register (dev, 0xe4, layouts[idx].re4);
4016
sanei_genesys_write_register (dev, 0xe5, layouts[idx].re5);
4017
/* R-Channel EVEN image buffer end-address 0x03ff*/
4018
sanei_genesys_write_register (dev, 0xe6, layouts[idx].re6);
4019
sanei_genesys_write_register (dev, 0xe7, layouts[idx].re7);
4021
/* same for green, since CIS, same addresses */
4022
sanei_genesys_write_register (dev, 0xe8, layouts[idx].re0);
4023
sanei_genesys_write_register (dev, 0xe9, layouts[idx].re1);
4024
sanei_genesys_write_register (dev, 0xea, layouts[idx].re2);
4025
sanei_genesys_write_register (dev, 0xeb, layouts[idx].re3);
4026
sanei_genesys_write_register (dev, 0xec, layouts[idx].re4);
4027
sanei_genesys_write_register (dev, 0xed, layouts[idx].re5);
4028
sanei_genesys_write_register (dev, 0xee, layouts[idx].re6);
4029
sanei_genesys_write_register (dev, 0xef, layouts[idx].re7);
4031
/* same for blue, since CIS, same addresses */
4032
sanei_genesys_write_register (dev, 0xf0, layouts[idx].re0);
4033
sanei_genesys_write_register (dev, 0xf1, layouts[idx].re1);
4034
sanei_genesys_write_register (dev, 0xf2, layouts[idx].re2);
4035
sanei_genesys_write_register (dev, 0xf3, layouts[idx].re3);
4036
sanei_genesys_write_register (dev, 0xf4, layouts[idx].re4);
4037
sanei_genesys_write_register (dev, 0xf5, layouts[idx].re5);
4038
sanei_genesys_write_register (dev, 0xf6, layouts[idx].re6);
4039
sanei_genesys_write_register (dev, 0xf7, layouts[idx].re7);
4046
* initialize ASIC from power on condition
4049
gl847_cold_boot (Genesys_Device * dev)
4056
RIE (sanei_genesys_write_register (dev, 0x0e, 0x01));
4057
RIE (sanei_genesys_write_register (dev, 0x0e, 0x00));
4060
RIE (sanei_genesys_read_register (dev, REG40, &val));
4061
if (val & REG40_CHKVER)
4063
RIE (sanei_genesys_read_register (dev, 0x00, &val));
4064
DBG (DBG_info, "gl847_cold_boot: reported version for genesys chip is 0x%02x\n", val);
4068
sanei_genesys_read_register (dev, REGA6, &val);
4069
sanei_genesys_write_register (dev, REGA6, val | 0x04);
4070
sanei_genesys_write_register (dev, REGA7, 0x0f);
4071
sanei_genesys_write_register (dev, REGA9, 0x00);
4073
/* Set default values for registers */
4074
gl847_init_registers (dev);
4076
RIE (sanei_genesys_write_register (dev, REG6B, 0x02));
4077
RIE (sanei_genesys_write_register (dev, REG6C, 0x00));
4078
RIE (sanei_genesys_write_register (dev, REG6D, 0x20));
4079
RIE (sanei_genesys_write_register (dev, REG6E, 0x7e));
4080
RIE (sanei_genesys_write_register (dev, REG6F, 0x21));
4082
/* Write initial registers */
4083
RIE (gl847_bulk_write_register (dev, dev->reg, GENESYS_GL847_MAX_REGS));
4085
/* Enable DRAM by setting a rising edge on bit 3 of reg 0x0b */
4086
val = dev->reg[reg_0x0b].value & REG0B_DRAMSEL;
4087
val = (val | REG0B_ENBDRAM);
4088
RIE (sanei_genesys_write_register (dev, REG0B, val));
4089
dev->reg[reg_0x0b].value = val;
4091
/* read back GPIO TODO usefull ? */
4092
sanei_genesys_read_register (dev, REGA6, &val);
4095
DBG (DBG_warn, "gl847_cold_boot: GPIO is 0x%02d instead of 0x04\n", val);
4098
/* set up clock once for all */
4099
RIE (sanei_genesys_write_register (dev, 0x77, 0x00));
4100
RIE (sanei_genesys_write_register (dev, 0x78, 0x00));
4101
RIE (sanei_genesys_write_register (dev, 0x79, 0x9f));
4104
val = (dev->reg[reg_0x0b].value & ~REG0B_CLKSET) | REG0B_30MHZ;
4105
RIE (sanei_genesys_write_register (dev, REG0B, val));
4106
dev->reg[reg_0x0b].value = val;
4108
/* prevent further writings by bulk write register */
4109
dev->reg[reg_0x0b].address = 0x00;
4112
SETREG (0x08, REG08_CIS_LINE);
4113
RIE (sanei_genesys_write_register (dev, 0x08, dev->reg[reg_0x08].value));
4115
/* set up end access */
4116
RIE (sanei_genesys_write_0x8c (dev, 0x10, 0x0b));
4117
RIE (sanei_genesys_write_0x8c (dev, 0x13, 0x0e));
4119
sanei_genesys_write_register (dev, REGA7, 0x04);
4120
sanei_genesys_write_register (dev, REGA9, 0x00);
4123
RIE (gl847_init_gpio (dev));
4125
/* setup internal memory layout */
4126
RIE (gl847_init_memory_layout (dev));
4128
SETREG (0xf8, 0x01);
4129
RIE (sanei_genesys_write_register (dev, 0xf8, dev->reg[reg_0xf8].value));
4132
return SANE_STATUS_GOOD;
4135
/** @brief dummy scan at 150 to warm scanner
4139
gl847_warm_scan (Genesys_Device * dev)
4149
pixels = (dev->sensor.sensor_pixels * dpi) / dev->sensor.optical_res;
4150
status = gl847_init_scan_regs (dev,
4161
SCAN_FLAG_DISABLE_SHADING |
4162
SCAN_FLAG_DISABLE_GAMMA |
4163
SCAN_FLAG_IGNORE_LINE_DISTANCE |
4164
SCAN_FLAG_USE_OPTICAL_RES);
4166
RIE (gl847_bulk_write_register
4167
(dev, dev->reg, GENESYS_GL847_MAX_REGS));
4169
/* colors * bytes_per_color * scan lines */
4170
size = ((int) pixels) * 3 * 2 * 1;
4172
line = malloc (size);
4174
return SANE_STATUS_NO_MEM;
4176
DBG (DBG_info, "%s: starting dummy data reading\n", __FUNCTION__);
4178
RIE (gl847_begin_scan (dev, dev->reg, SANE_TRUE));
4179
sanei_genesys_read_data_from_scanner (dev, line, size);
4180
RIE (gl847_end_scan (dev, dev->reg, SANE_TRUE));
4183
RIE (gl847_slow_back_home (dev, SANE_TRUE));
4186
return SANE_STATUS_GOOD;
4190
* initialize backend and ASIC : registers, motor tables, and gamma tables
4191
* then ensure scanner's head is at home
4194
gl847_init (Genesys_Device * dev)
4198
SANE_Bool cold = SANE_TRUE;
4204
status = sanei_usb_control_msg (dev->dn, REQUEST_TYPE_IN, REQUEST_REGISTER, VALUE_GET_REGISTER, 0, 1, &val);
4205
if (status != SANE_STATUS_GOOD)
4208
"gl847_init: request register failed %s\n", sane_strstatus (status));
4211
DBG( DBG_io2, "gl847_init: value=0x%02x\n",val);
4213
/* check if the device has already been initialized and powered up
4214
* we read register 6 and check PWRBIT, if reset scanner has been
4215
* freshly powered up. This bit will be set to later so that following
4216
* reads can detect power down/up cycle*/
4217
RIE (sanei_genesys_read_register (dev, 0x06, &val));
4218
if (val & REG06_PWRBIT)
4222
DBG (DBG_info, "%s: device is %s\n", __FUNCTION__, cold ? "cold" : "warm");
4224
/* don't do anything is backend is initialized and hardware hasn't been
4226
if (dev->already_initialized && !cold)
4228
DBG (DBG_info, "gl847_init: already initialized, nothing to do\n");
4229
return SANE_STATUS_GOOD;
4232
/* set up hardware and registers */
4233
RIE (gl847_cold_boot (dev));
4235
/* now hardware part is OK, set up device struct */
4236
FREE_IFNOT_NULL (dev->white_average_data);
4237
FREE_IFNOT_NULL (dev->dark_average_data);
4238
FREE_IFNOT_NULL (dev->sensor.red_gamma_table);
4239
FREE_IFNOT_NULL (dev->sensor.green_gamma_table);
4240
FREE_IFNOT_NULL (dev->sensor.blue_gamma_table);
4242
dev->settings.color_filter = 0;
4244
memcpy (dev->calib_reg, dev->reg,
4245
GENESYS_GL847_MAX_REGS * sizeof (Genesys_Register_Set));
4247
/* Set analog frontend */
4248
RIE (gl847_set_fe (dev, AFE_INIT));
4250
/* init gamma tables */
4252
if (dev->sensor.red_gamma_table == NULL)
4254
dev->sensor.red_gamma_table = (uint16_t *) malloc (2 * size);
4255
if (dev->sensor.red_gamma_table == NULL)
4258
"gl847_init: could not allocate memory for gamma table\n");
4259
return SANE_STATUS_NO_MEM;
4261
sanei_genesys_create_gamma_table (dev->sensor.red_gamma_table, size,
4262
65535, 65535, dev->sensor.red_gamma);
4264
if (dev->sensor.green_gamma_table == NULL)
4266
dev->sensor.green_gamma_table = (uint16_t *) malloc (2 * size);
4267
if (dev->sensor.red_gamma_table == NULL)
4270
"gl847_init: could not allocate memory for gamma table\n");
4271
return SANE_STATUS_NO_MEM;
4273
sanei_genesys_create_gamma_table (dev->sensor.green_gamma_table, size,
4275
dev->sensor.green_gamma);
4277
if (dev->sensor.blue_gamma_table == NULL)
4279
dev->sensor.blue_gamma_table = (uint16_t *) malloc (2 * size);
4280
if (dev->sensor.red_gamma_table == NULL)
4283
"gl847_init: could not allocate memory for gamma table\n");
4284
return SANE_STATUS_NO_MEM;
4286
sanei_genesys_create_gamma_table (dev->sensor.blue_gamma_table, size,
4287
65535, 65535, dev->sensor.blue_gamma);
4290
dev->oe_buffer.buffer=NULL;
4291
dev->already_initialized = SANE_TRUE;
4293
/* Move home if needed */
4294
RIE (gl847_slow_back_home (dev, SANE_TRUE));
4295
RIE (gl847_warm_scan (dev));
4296
dev->scanhead_position_in_steps = 0;
4298
/* Set powersaving (default = 15 minutes) */
4299
RIE (gl847_set_powersaving (dev, 15));
4306
gl847_update_hardware_sensors (Genesys_Scanner * s)
4308
/* do what is needed to get a new set of events, but try to not lose
4311
SANE_Status status = SANE_STATUS_GOOD;
4314
RIE (sanei_genesys_read_register (s->dev, REG6D, &val));
4316
if (s->val[OPT_SCAN_SW].b == s->last_val[OPT_SCAN_SW].b)
4317
s->val[OPT_SCAN_SW].b = (val & 0x01) == 0;
4318
if (s->val[OPT_FILE_SW].b == s->last_val[OPT_FILE_SW].b)
4319
s->val[OPT_FILE_SW].b = (val & 0x02) == 0;
4320
if (s->val[OPT_EMAIL_SW].b == s->last_val[OPT_EMAIL_SW].b)
4321
s->val[OPT_EMAIL_SW].b = (val & 0x04) == 0;
4322
if (s->val[OPT_COPY_SW].b == s->last_val[OPT_COPY_SW].b)
4323
s->val[OPT_COPY_SW].b = (val & 0x08) == 0;
4328
/** @brief search for a full width black or white strip.
4329
* This function searches for a black or white stripe across the scanning area.
4330
* When searching backward, the searched area must completely be of the desired
4331
* color since this area will be used for calibration which scans forward.
4332
* @param dev scanner device
4333
* @param forward SANE_TRUE if searching forward, SANE_FALSE if searching backward
4334
* @param black SANE_TRUE if searching for a black strip, SANE_FALSE for a white strip
4335
* @return SANE_STATUS_GOOD if a matching strip is found, SANE_STATUS_UNSUPPORTED if not
4338
gl847_search_strip (Genesys_Device * dev, SANE_Bool forward, SANE_Bool black)
4340
unsigned int pixels, lines, channels;
4342
Genesys_Register_Set local_reg[GENESYS_GL847_MAX_REGS];
4345
int steps, depth, dpi;
4346
unsigned int pass, count, found, x, y;
4348
Genesys_Register_Set *r;
4350
DBG (DBG_proc, "gl847_search_strip %s %s\n", black ? "black" : "white",
4351
forward ? "forward" : "reverse");
4353
gl847_set_fe (dev, AFE_SET);
4354
status = gl847_stop_action (dev);
4355
if (status != SANE_STATUS_GOOD)
4358
"gl847_search_strip: failed to stop: %s\n",
4359
sane_strstatus (status));
4363
/* set up for a gray scan at lowest dpi */
4365
for (x = 0; x < MAX_RESOLUTIONS; x++)
4367
if (dev->model->xdpi_values[x] > 0 && dev->model->xdpi_values[x] < dpi)
4368
dpi = dev->model->xdpi_values[x];
4372
lines = (10 * dpi) / MM_PER_INCH;
4373
/* shading calibation is done with dev->motor.base_ydpi */
4374
lines = (dev->model->shading_lines * dpi) / dev->motor.base_ydpi;
4376
pixels = (dev->sensor.sensor_pixels * dpi) / dev->sensor.optical_res;
4377
size = pixels * channels * lines * (depth / 8);
4378
data = malloc (size);
4381
DBG (DBG_error, "gl847_search_strip: failed to allocate memory\n");
4382
return SANE_STATUS_NO_MEM;
4384
dev->scanhead_position_in_steps = 0;
4386
memcpy (local_reg, dev->reg,
4387
GENESYS_GL847_MAX_REGS * sizeof (Genesys_Register_Set));
4389
status = gl847_init_scan_regs (dev,
4400
SCAN_FLAG_DISABLE_SHADING |
4401
SCAN_FLAG_DISABLE_GAMMA);
4402
if (status != SANE_STATUS_GOOD)
4405
"gl847_search_strip: failed to setup for scan: %s\n",
4406
sane_strstatus (status));
4410
/* set up for reverse or forward */
4411
r = sanei_genesys_get_address (local_reg, REG02);
4413
r->value &= ~REG02_MTRREV;
4415
r->value |= REG02_MTRREV;
4418
status = gl847_bulk_write_register (dev, local_reg, GENESYS_GL847_MAX_REGS);
4419
if (status != SANE_STATUS_GOOD)
4422
"gl847_search_strip: Failed to bulk write registers: %s\n",
4423
sane_strstatus (status));
4427
status = gl847_begin_scan (dev, local_reg, SANE_TRUE);
4428
if (status != SANE_STATUS_GOOD)
4432
"gl847_search_strip: failed to begin scan: %s\n",
4433
sane_strstatus (status));
4437
/* waits for valid data */
4439
sanei_genesys_test_buffer_empty (dev, &steps);
4442
/* now we're on target, we can read data */
4443
status = sanei_genesys_read_data_from_scanner (dev, data, size);
4444
if (status != SANE_STATUS_GOOD)
4448
"gl847_search_start_position: failed to read data: %s\n",
4449
sane_strstatus (status));
4453
status = gl847_stop_action (dev);
4454
if (status != SANE_STATUS_GOOD)
4457
DBG (DBG_error, "gl847_search_strip: gl847_stop_action failed\n");
4462
if (DBG_LEVEL >= DBG_data)
4464
sprintf (title, "search_strip_%s_%s%02d.pnm",
4465
black ? "black" : "white", forward ? "fwd" : "bwd", pass);
4466
sanei_genesys_write_pnm_file (title, data, depth, channels, pixels,
4470
/* loop until strip is found or maximum pass number done */
4472
while (pass < 20 && !found)
4475
gl847_bulk_write_register (dev, local_reg, GENESYS_GL847_MAX_REGS);
4476
if (status != SANE_STATUS_GOOD)
4479
"gl847_search_strip: Failed to bulk write registers: %s\n",
4480
sane_strstatus (status));
4484
/* now start scan */
4485
status = gl847_begin_scan (dev, local_reg, SANE_TRUE);
4486
if (status != SANE_STATUS_GOOD)
4490
"gl847_search_strip: failed to begin scan: %s\n",
4491
sane_strstatus (status));
4495
/* waits for valid data */
4497
sanei_genesys_test_buffer_empty (dev, &steps);
4500
/* now we're on target, we can read data */
4501
status = sanei_genesys_read_data_from_scanner (dev, data, size);
4502
if (status != SANE_STATUS_GOOD)
4506
"gl847_search_start_position: failed to read data: %s\n",
4507
sane_strstatus (status));
4511
status = gl847_stop_action (dev);
4512
if (status != SANE_STATUS_GOOD)
4515
DBG (DBG_error, "gl847_search_strip: gl847_stop_action failed\n");
4519
if (DBG_LEVEL >= DBG_data)
4521
sprintf (title, "search_strip_%s_%s%02d.pnm",
4522
black ? "black" : "white", forward ? "fwd" : "bwd", pass);
4523
sanei_genesys_write_pnm_file (title, data, depth, channels,
4527
/* search data to find black strip */
4528
/* when searching forward, we only need one line of the searched color since we
4529
* will scan forward. But when doing backward search, we need all the area of the
4533
for (y = 0; y < lines && !found; y++)
4536
/* count of white/black pixels depending on the color searched */
4537
for (x = 0; x < pixels; x++)
4539
/* when searching for black, detect white pixels */
4540
if (black && data[y * pixels + x] > 90)
4544
/* when searching for white, detect black pixels */
4545
if (!black && data[y * pixels + x] < 60)
4551
/* at end of line, if count >= 3%, line is not fully of the desired color
4552
* so we must go to next line of the buffer */
4553
/* count*100/pixels < 3 */
4554
if ((count * 100) / pixels < 3)
4558
"gl847_search_strip: strip found forward during pass %d at line %d\n",
4564
"gl847_search_strip: pixels=%d, count=%d (%d%%)\n",
4565
pixels, count, (100 * count) / pixels);
4569
else /* since calibration scans are done forward, we need the whole area
4570
to be of the required color when searching backward */
4573
for (y = 0; y < lines; y++)
4575
/* count of white/black pixels depending on the color searched */
4576
for (x = 0; x < pixels; x++)
4578
/* when searching for black, detect white pixels */
4579
if (black && data[y * pixels + x] > 90)
4583
/* when searching for white, detect black pixels */
4584
if (!black && data[y * pixels + x] < 60)
4591
/* at end of area, if count >= 3%, area is not fully of the desired color
4592
* so we must go to next buffer */
4593
if ((count * 100) / (pixels * lines) < 3)
4597
"gl847_search_strip: strip found backward during pass %d \n",
4603
"gl847_search_strip: pixels=%d, count=%d (%d%%)\n",
4604
pixels, count, (100 * count) / pixels);
4612
status = SANE_STATUS_GOOD;
4613
DBG (DBG_info, "gl847_search_strip: %s strip found\n",
4614
black ? "black" : "white");
4618
status = SANE_STATUS_UNSUPPORTED;
4619
DBG (DBG_info, "gl847_search_strip: %s strip not found\n",
4620
black ? "black" : "white");
4627
/** the gl847 command set */
4628
static Genesys_Command_Set gl847_cmd_set = {
4629
"gl847-generic", /* the name of this set */
4632
gl847_init_regs_for_warmup,
4633
gl847_init_regs_for_coarse_calibration,
4634
gl847_init_regs_for_shading,
4635
gl847_init_regs_for_scan,
4637
gl847_get_filter_bit,
4638
gl847_get_lineart_bit,
4639
gl847_get_bitset_bit,
4640
gl847_get_gain4_bit,
4641
gl847_get_fast_feed_bit,
4642
gl847_test_buffer_empty_bit,
4643
gl847_test_motor_flag_bit,
4645
gl847_bulk_full_size,
4648
gl847_set_powersaving,
4651
gl847_set_motor_power,
4652
gl847_set_lamp_power,
4657
gl847_send_gamma_table,
4659
gl847_search_start_position,
4661
gl847_offset_calibration,
4662
gl847_coarse_gain_calibration,
4663
gl847_led_calibration,
4665
gl847_slow_back_home,
4667
gl847_bulk_write_register,
4669
gl847_bulk_read_data,
4671
gl847_update_hardware_sensors,
4673
gl847_load_document,
4674
gl847_detect_document_end,
4675
gl847_eject_document,
4678
gl847_is_compatible_calibration,
4680
gl847_send_shading_data
4684
sanei_gl847_init_cmd_set (Genesys_Device * dev)
4686
dev->model->cmd_set = &gl847_cmd_set;
4687
return SANE_STATUS_GOOD;
4690
/* vim: set sw=2 cino=>2se-1sn-1s{s^-1st0(0u0 smarttab expandtab: */