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_gl843.h"
47
/****************************************************************************
49
****************************************************************************/
52
* decodes and prints content of status (0x41) register
53
* @param val value read from reg41
59
print_status (uint8_t val)
63
sprintf (msg, "%s%s%s%s%s%s%s%s",
64
val & REG41_PWRBIT ? "PWRBIT " : "",
65
val & REG41_BUFEMPTY ? "BUFEMPTY " : "",
66
val & REG41_FEEDFSH ? "FEEDFSH " : "",
67
val & REG41_SCANFSH ? "SCANFSH " : "",
68
val & REG41_HOMESNR ? "HOMESNR " : "",
69
val & REG41_LAMPSTS ? "LAMPSTS " : "",
70
val & REG41_FEBUSY ? "FEBUSY " : "",
71
val & REG41_MOTORENB ? "MOTORENB" : "");
72
DBG (DBG_info, "status=%s\n", msg);
75
/* ------------------------------------------------------------------------ */
76
/* Read and write RAM, registers and AFE */
77
/* ------------------------------------------------------------------------ */
83
write_end_access (Genesys_Device * dev, uint8_t index, uint8_t val)
87
DBG (DBG_io, "write_end_access: 0x%02x,0x%02x\n", index, val);
90
sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_REGISTER,
91
VALUE_BUF_ENDACCESS, index, 1, &val);
92
if (status != SANE_STATUS_GOOD)
95
"write_end_access: failed %s\n", sane_strstatus (status));
100
/* Write bulk data (e.g. gamma) */
102
gl843_bulk_write_data (Genesys_Device * dev, uint8_t addr,
103
uint8_t * data, size_t len)
110
DBG (DBG_io, "gl843_bulk_write_data writing %lu bytes\n", (u_long) len);
113
sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_REGISTER,
114
VALUE_SET_REGISTER, INDEX, 1, &addr);
115
if (status != SANE_STATUS_GOOD)
118
"gl843_bulk_write_data failed while setting register: %s\n",
119
sane_strstatus (status));
123
/* TODO check with G4050 that we shouldn't loop at all */
128
outdata[0] = BULK_OUT;
129
outdata[1] = BULK_RAM;
132
outdata[4] = (size & 0xff);
133
outdata[5] = ((size >> 8) & 0xff);
134
outdata[6] = ((size >> 16) & 0xff);
135
outdata[7] = ((size >> 24) & 0xff);
138
sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_BUFFER,
139
VALUE_BUFFER, INDEX, sizeof (outdata),
141
if (status != SANE_STATUS_GOOD)
144
"gl843_bulk_write_data failed while writing command: %s\n",
145
sane_strstatus (status));
149
status = sanei_usb_write_bulk (dev->dn, data, &size);
150
if (status != SANE_STATUS_GOOD)
153
"gl843_bulk_write_data failed while writing bulk data: %s\n",
154
sane_strstatus (status));
159
"gl843_bulk_write_data: gamma wrote %lu bytes, %lu remaining\n",
160
(u_long) size, (u_long) (len - size));
170
/* Set address for writing data */
172
gl843_set_buffer_address (Genesys_Device * dev, uint32_t addr)
176
DBG (DBG_io, "gl843_set_buffer_address: setting address to 0x%05x\n",
179
status = sanei_genesys_write_register (dev, 0x5b, ((addr >> 8) & 0xff));
180
if (status != SANE_STATUS_GOOD)
183
"gl843_set_buffer_address: failed while writing high byte: %s\n",
184
sane_strstatus (status));
188
status = sanei_genesys_write_register (dev, 0x5c, (addr & 0xff));
189
if (status != SANE_STATUS_GOOD)
192
"gl843_set_buffer_address: failed while writing low byte: %s\n",
193
sane_strstatus (status));
197
DBG (DBG_io, "gl843_set_buffer_address: completed\n");
203
* writes a block of data to RAM
204
* @param dev USB device
205
* @param addr RAM address to write to
206
* @param size size of the chunk of data
207
* @param data pointer to the data to write
210
write_data (Genesys_Device * dev, uint32_t addr, uint32_t size,
213
SANE_Status status = SANE_STATUS_GOOD;
217
status = gl843_set_buffer_address (dev, addr);
218
if (status != SANE_STATUS_GOOD)
221
"write_data: failed while setting address for bulk write data: %s\n",
222
sane_strstatus (status));
226
/* write actual data */
227
status = gl843_bulk_write_data (dev, 0x28, data, size);
228
if (status != SANE_STATUS_GOOD)
231
"write_data: failed while writing bulk write data: %s\n",
232
sane_strstatus (status));
236
/* set back address to 0 */
237
status = gl843_set_buffer_address (dev, 0);
238
if (status != SANE_STATUS_GOOD)
241
"write_data: failed setting to default RAM address: %s\n",
242
sane_strstatus (status));
250
* Write to many GL843 registers at once
256
gl843_bulk_write_register (Genesys_Device * dev, Genesys_Register_Set * reg,
259
SANE_Status status = SANE_STATUS_GOOD;
262
for (i = 0; i < elems && status == SANE_STATUS_GOOD; i++)
264
if (reg[i].address != 0)
267
sanei_genesys_write_register (dev, reg[i].address, reg[i].value);
271
DBG (DBG_io, "gl843_bulk_write_register: wrote %lu registers\n",
277
gl843_bulk_read_data (Genesys_Device * dev, uint8_t addr,
278
uint8_t * data, size_t len)
286
"gl843_bulk_read_data: requesting %lu bytes from 0x%02x addr\n",
290
sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_REGISTER,
291
VALUE_SET_REGISTER, 0, 1, &addr);
292
if (status != SANE_STATUS_GOOD)
295
"write_data: failed to set register address %s\n",
296
sane_strstatus (status));
301
return SANE_STATUS_GOOD;
303
outdata[0] = BULK_IN;
304
outdata[1] = BULK_RAM;
305
outdata[2] = VALUE_BUFFER;
307
outdata[4] = (len & 0xff);
308
outdata[5] = ((len >> 8) & 0xff);
309
outdata[6] = ((len >> 16) & 0xff);
310
outdata[7] = ((len >> 24) & 0xff);
313
sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_BUFFER,
314
VALUE_BUFFER, INDEX, sizeof (outdata), outdata);
315
if (status != SANE_STATUS_GOOD)
318
"gl843_bulk_read_data failed while writing command: %s\n",
319
sane_strstatus (status));
336
"gl843_bulk_read_data: trying to read %lu bytes of data\n",
339
status = sanei_usb_read_bulk (dev->dn, data, &size);
340
if (status != SANE_STATUS_GOOD)
343
"gl843_bulk_read_data failed while reading bulk data: %s\n",
344
sane_strstatus (status));
349
"gl843_bulk_read_data read %lu bytes, %lu remaining\n",
350
(u_long) size, (u_long) (len - size));
357
return SANE_STATUS_GOOD;
360
/****************************************************************************
362
****************************************************************************/
365
gl843_get_fast_feed_bit (Genesys_Register_Set * regs)
367
Genesys_Register_Set *r = NULL;
369
r = sanei_genesys_get_address (regs, REG02);
370
if (r && (r->value & REG02_FASTFED))
376
gl843_get_filter_bit (Genesys_Register_Set * regs)
378
Genesys_Register_Set *r = NULL;
380
r = sanei_genesys_get_address (regs, REG04);
381
if (r && (r->value & REG04_FILTER))
387
gl843_get_lineart_bit (Genesys_Register_Set * regs)
389
Genesys_Register_Set *r = NULL;
391
r = sanei_genesys_get_address (regs, REG04);
392
if (r && (r->value & REG04_LINEART))
398
gl843_get_bitset_bit (Genesys_Register_Set * regs)
400
Genesys_Register_Set *r = NULL;
402
r = sanei_genesys_get_address (regs, REG04);
403
if (r && (r->value & REG04_BITSET))
409
gl843_get_gain4_bit (Genesys_Register_Set * regs)
411
Genesys_Register_Set *r = NULL;
413
r = sanei_genesys_get_address (regs, REG06);
414
if (r && (r->value & REG06_GAIN4))
420
* compute the step multiplier used
423
gl843_get_step_multiplier (Genesys_Register_Set * regs)
425
Genesys_Register_Set *r = NULL;
428
r = sanei_genesys_get_address (regs, 0x9d);
431
switch (r->value & 0x0c)
443
DBG (DBG_io, "%s: step multiplier is %d\n", __FUNCTION__, value);
448
gl843_test_buffer_empty_bit (SANE_Byte val)
450
if (val & REG41_BUFEMPTY)
456
gl843_test_motor_flag_bit (SANE_Byte val)
458
if (val & REG41_MOTORENB)
463
/** @get motor profile
464
* search for the database of motor profiles and get the best one. Each
465
* profile is at full step and at a reference exposure. Use KV-SS080 table
467
* @param motor_type motor id
468
* @param exposure exposure time
469
* @return a pointer to a Motor_Profile struct
471
static Motor_Profile *get_motor_profile(int motor_type, int exposure)
478
while(i<sizeof(motors)/sizeof(Motor_Profile))
481
if(motors[i].motor_type==motor_type && motors[i].exposure==exposure)
487
if(motors[i].motor_type==motor_type)
495
if(motors[i].exposure>=exposure
496
&& motors[i].exposure<motors[idx].exposure)
505
/* default fallback */
509
return &(motors[idx]);
513
/** @brief returns the lowest possible ydpi for the device
514
* Parses device entry to find lowest motor dpi.
515
* @dev device description
516
* @return lowest motor resolution
518
static int gl843_get_lowest_ydpi(Genesys_Device *dev)
523
while(dev->model->ydpi_values[i]!=0)
525
if(dev->model->ydpi_values[i]<min)
527
min=dev->model->ydpi_values[i];
533
static int gl843_slope_table(uint16_t *slope,
543
uint16_t target,current;
544
Motor_Profile *profile;
547
target=((exposure * dpi) / base_dpi)>>step_type;
549
/* fill result with target speed */
550
for(i=0;i<256*factor;i++)
553
profile=get_motor_profile(motor_type,exposure);
555
/* use profile to build table */
558
current=profile->table[0]>>step_type;
559
while(i<(256*factor) && current>target)
564
current=profile->table[i]>>step_type;
567
/* align size on step time factor */
574
/* return used steps and acceleration sum */
582
/** copy sensor specific settings */
584
gl843_setup_sensor (Genesys_Device * dev, Genesys_Register_Set * regs, int dpi)
586
Genesys_Register_Set *r;
591
for (i = 0x06; i < 0x0e; i++)
593
r = sanei_genesys_get_address (regs, 0x10 + i);
595
r->value = dev->sensor.regs_0x10_0x1d[i];
598
/* TODO we need to create another data struct
599
* for CKxMAP and CKSEL */
600
/* G4050/G4010 sensor */
601
if (dev->model->ccd_type == CCD_G4050)
605
sanei_genesys_write_register (dev, 0x74, 0x00);
606
sanei_genesys_write_register (dev, 0x75, 0x1c);
607
sanei_genesys_write_register (dev, 0x76, 0x7f);
611
sanei_genesys_write_register (dev, 0x74, 0x00);
612
sanei_genesys_write_register (dev, 0x75, 0x01);
613
sanei_genesys_write_register (dev, 0x76, 0xff);
615
else /* 800 to 2400 case */
617
sanei_genesys_write_register (dev, 0x5a, 0x40);
618
sanei_genesys_write_register (dev, 0x74, 0x0f);
619
sanei_genesys_write_register (dev, 0x75, 0xff);
620
sanei_genesys_write_register (dev, 0x76, 0xff);
621
sanei_genesys_write_register (dev, 0x77, 0x00);
622
sanei_genesys_write_register (dev, 0x78, 0x01);
623
sanei_genesys_write_register (dev, 0x7a, 0x00);
624
sanei_genesys_write_register (dev, 0x7b, 0x01);
625
sanei_genesys_write_register (dev, 0x7d, 0x90);
626
sanei_genesys_write_register (dev, 0x80, 0x05);
627
sanei_genesys_write_register (dev, 0x9e, 0xc0);
631
for (i = 0; i < 9; i++)
633
r = sanei_genesys_get_address (regs, 0x52 + i);
635
r->value = dev->sensor.regs_0x52_0x5e[i];
638
DBG (DBG_proc, "gl843_setup_sensor: completed \n");
642
/* returns the max register bulk size */
644
gl843_bulk_full_size (void)
646
return GENESYS_GL843_MAX_REGS;
649
/** @brief set all registers to default values .
650
* This function is called only once at the beginning and
651
* fills register startup values for registers reused across scans.
652
* Those that are rarely modified or not modified are written
654
* @param dev device structure holding register set to initialize
657
gl843_init_registers (Genesys_Device * dev)
662
GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set));
664
/* default to KV-SS080 */
671
SETREG (0x06, 0xd8); /* SCANMOD=110, PWRBIT and GAIN4 */
759
if ((strcmp (dev->model->name, "hewlett-packard-scanjet-g4050") == 0)
760
|| (strcmp (dev->model->name, "hewlett-packard-scanjet-g4010") == 0))
764
SETREG (0x06, 0xd0); /* SCANMOD=110, PWRBIT and no GAIN4 */
780
/* XXX STEF XXX TODO move to set for scan */
789
/* fine tune upon device description */
790
dev->reg[reg_0x05].value &= ~REG05_DPIHW;
791
switch (dev->sensor.optical_res)
794
dev->reg[reg_0x05].value |= REG05_DPIHW_600;
797
dev->reg[reg_0x05].value |= REG05_DPIHW_1200;
800
dev->reg[reg_0x05].value |= REG05_DPIHW_2400;
803
dev->reg[reg_0x05].value |= REG05_DPIHW_4800;
807
/* initalize calibration reg */
808
memcpy (dev->calib_reg, dev->reg,
809
GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set));
814
/* Send slope table for motor movement
815
slope_table in machine byte order
821
gl843_send_slope_table (Genesys_Device * dev, int table_nr,
822
uint16_t * slope_table, int steps)
829
DBG (DBG_proc, "%s (table_nr = %d, steps = %d)\n", __FUNCTION__,
832
table = (uint8_t *) malloc (steps * 2);
833
for (i = 0; i < steps; i++)
835
table[i * 2] = slope_table[i] & 0xff;
836
table[i * 2 + 1] = slope_table[i] >> 8;
839
if (DBG_LEVEL >= DBG_io)
841
sprintf (msg, "write slope %d (%d)=", table_nr, steps);
842
for (i = 0; i < steps; i++)
844
sprintf (msg, "%s,%d", msg, slope_table[i]);
846
DBG (DBG_io, "%s: %s\n", __FUNCTION__, msg);
849
/* slope table addresses are fixed : 0x4000, 0x4800, 0x5000, 0x5800, 0x6000 */
850
/* XXX STEF XXX USB 1.1 ? write_end_access (dev, 0x0f, 0x14); */
851
status = write_data (dev, 0x4000 + 0x800 * table_nr, steps * 2, table);
852
if (status != SANE_STATUS_GOOD)
855
"%s: write data failed writing slope table %d (%s)\n",
856
__FUNCTION__, table_nr, sane_strstatus (status));
860
DBG (DBG_proc, "%s: completed\n", __FUNCTION__);
865
/* Set values of analog frontend */
867
gl843_set_fe (Genesys_Device * dev, uint8_t set)
873
DBG (DBG_proc, "gl843_set_fe (%s)\n",
874
set == AFE_INIT ? "init" : set == AFE_SET ? "set" : set ==
875
AFE_POWER_SAVE ? "powersave" : "huh?");
879
DBG (DBG_proc, "gl843_set_fe(): setting DAC %u\n",
880
dev->model->dac_type);
881
sanei_genesys_init_fe (dev);
884
/* check analog frontend type */
885
RIE (sanei_genesys_read_register (dev, REG04, &val));
886
if ((val & REG04_FESET) != 0x00)
888
/* for now there is no support for AD fe */
889
DBG (DBG_proc, "gl843_set_fe(): unsupported frontend type %d\n",
890
dev->reg[reg_0x04].value & REG04_FESET);
891
return SANE_STATUS_UNSUPPORTED;
894
DBG (DBG_proc, "gl843_set_fe(): frontend reset complete\n");
896
for (i = 1; i <= 3; i++)
898
status = sanei_genesys_fe_write_data (dev, i, dev->frontend.reg[i]);
899
if (status != SANE_STATUS_GOOD)
902
"gl843_set_fe: writing reg[%d] failed: %s\n", i,
903
sane_strstatus (status));
908
for (i = 0; i < 3; i++)
911
sanei_genesys_fe_write_data (dev, 0x20 + i, dev->frontend.offset[i]);
912
if (status != SANE_STATUS_GOOD)
915
"gl843_set_fe: writing offset[%d] failed: %s\n", i,
916
sane_strstatus (status));
921
if (dev->model->ccd_type == CCD_KVSS080)
923
for (i = 0; i < 3; i++)
926
sanei_genesys_fe_write_data (dev, 0x24 + i,
927
dev->frontend.sign[i]);
928
if (status != SANE_STATUS_GOOD)
931
"gl843_set_fe: writing sign[%d] failed: %s\n", i,
932
sane_strstatus (status));
938
for (i = 0; i < 3; i++)
941
sanei_genesys_fe_write_data (dev, 0x28 + i, dev->frontend.gain[i]);
942
if (status != SANE_STATUS_GOOD)
945
"gl843_set_fe: writing gain[%d] failed: %s\n", i,
946
sane_strstatus (status));
952
return SANE_STATUS_GOOD;
955
#define MOTOR_FLAG_AUTO_GO_HOME 1
956
#define MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE 2
958
#define MOTOR_ACTION_FEED 1
959
#define MOTOR_ACTION_GO_HOME 2
960
#define MOTOR_ACTION_HOME_FREE 3
964
gl843_init_motor_regs_scan (Genesys_Device * dev,
965
Genesys_Register_Set * reg,
966
unsigned int scan_exposure_time,
969
unsigned int scan_lines,
970
unsigned int scan_dummy,
971
unsigned int feed_steps,
977
unsigned int fast_time;
978
unsigned int slow_time;
980
uint16_t scan_table[1024];
981
uint16_t fast_table[1024];
982
int scan_steps,fast_steps;
983
unsigned int feedl,factor,dist;
984
Genesys_Register_Set *r;
988
DBG (DBG_info, "gl843_init_motor_regs_scan : scan_exposure_time=%d, "
989
"scan_yres=%g, scan_step_type=%d, scan_lines=%d, scan_dummy=%d, "
990
"feed_steps=%d, scan_power_mode=%d, flags=%x\n",
994
scan_lines, scan_dummy, feed_steps, scan_power_mode, flags);
996
/* get step multiplier */
997
factor = gl843_get_step_multiplier (reg);
1001
if(scan_yres>=300 && feed_steps>900)
1005
r = sanei_genesys_get_address (reg, 0x25);
1006
r->value = (lincnt >> 16) & 0xf;
1007
r = sanei_genesys_get_address (reg, 0x26);
1008
r->value = (lincnt >> 8) & 0xff;
1009
r = sanei_genesys_get_address (reg, 0x27);
1010
r->value = lincnt & 0xff;
1011
DBG (DBG_io, "%s: lincnt=%d\n", __FUNCTION__, lincnt);
1013
/* compute register 02 value */
1014
r = sanei_genesys_get_address (reg, REG02);
1016
r->value |= REG02_MTRPWR;
1019
r->value |= REG02_FASTFED;
1021
r->value &= ~REG02_FASTFED;
1023
if (flags & MOTOR_FLAG_AUTO_GO_HOME)
1024
r->value |= REG02_AGOHOME;
1026
if (flags & MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE)
1027
r->value |= REG02_ACDCDIS;
1029
/* scan and backtracking slope table */
1030
slow_time=gl843_slope_table(scan_table,
1034
dev->motor.base_ydpi,
1037
dev->model->motor_type);
1038
RIE(gl843_send_slope_table (dev, SCAN_TABLE, scan_table, scan_steps));
1039
RIE(gl843_send_slope_table (dev, BACKTRACK_TABLE, scan_table, scan_steps));
1041
r = sanei_genesys_get_address (reg, 0x21);
1042
r->value = scan_steps/factor;
1044
r = sanei_genesys_get_address (reg, 0x24);
1045
r->value = scan_steps/factor;
1048
fast_time=gl843_slope_table(fast_table,
1050
gl843_get_lowest_ydpi(dev),
1052
dev->motor.base_ydpi,
1055
dev->model->motor_type);
1056
RIE(gl843_send_slope_table (dev, STOP_TABLE, fast_table, fast_steps));
1057
RIE(gl843_send_slope_table (dev, FAST_TABLE, fast_table, fast_steps));
1059
r = sanei_genesys_get_address (reg, 0x69);
1060
r->value = fast_steps / factor;
1061
/* better stop time */
1064
r = sanei_genesys_get_address (reg, REG6A);
1065
r->value = fast_steps / factor;
1067
/* substract acceleration distance from feedl */
1069
feedl<<=scan_step_type;
1074
dist += fast_steps*2;
1076
DBG (DBG_io2, "%s: acceleration distance=%d\n", __FUNCTION__, dist);
1078
/* get sure when don't insane value */
1084
r = sanei_genesys_get_address (reg, 0x3d);
1085
r->value = (feedl >> 16) & 0xf;
1086
r = sanei_genesys_get_address (reg, 0x3e);
1087
r->value = (feedl >> 8) & 0xff;
1088
r = sanei_genesys_get_address (reg, 0x3f);
1089
r->value = feedl & 0xff;
1090
DBG (DBG_io, "%s: feedl=%d\n", __FUNCTION__, feedl);
1092
/* doesn't seem to matter that much */
1093
sanei_genesys_calculate_zmode2 (use_fast_fed,
1102
DBG (DBG_info, "gl843_init_motor_regs_scan: z1 = %d\n", z1);
1103
r = sanei_genesys_get_address (reg, REG60);
1104
r->value = ((z1 >> 16) & REG60_Z1MOD);
1105
r = sanei_genesys_get_address (reg, REG61);
1106
r->value = ((z1 >> 8) & REG61_Z1MOD);
1107
r = sanei_genesys_get_address (reg, REG62);
1108
r->value = (z1 & REG62_Z1MOD);
1110
DBG (DBG_info, "gl843_init_motor_regs_scan: z2 = %d\n", z2);
1111
r = sanei_genesys_get_address (reg, REG63);
1112
r->value = ((z2 >> 16) & REG63_Z2MOD);
1113
r = sanei_genesys_get_address (reg, REG64);
1114
r->value = ((z2 >> 8) & REG64_Z2MOD);
1115
r = sanei_genesys_get_address (reg, REG65);
1116
r->value = (z2 & REG65_Z2MOD);
1118
r = sanei_genesys_get_address (reg, REG1E);
1119
r->value &= 0xf0; /* 0 dummy lines */
1120
r->value |= scan_dummy; /* dummy lines */
1122
r = sanei_genesys_get_address (reg, REG67);
1123
r->value = 0x3f | (scan_step_type << REG67S_STEPSEL);
1125
r = sanei_genesys_get_address (reg, REG68);
1126
r->value = 0x3f | (scan_step_type << REG68S_FSTPSEL);
1128
/* steps for STOP table */
1129
r = sanei_genesys_get_address (reg, 0x5f);
1133
r = sanei_genesys_get_address (reg, 0x80);
1134
r->value = 0x05; /* kv 75,150,300 dpi */
1137
return SANE_STATUS_GOOD;
1142
gl843_get_dpihw (Genesys_Device * dev)
1144
Genesys_Register_Set *r;
1145
r = sanei_genesys_get_address (dev->reg, REG05);
1146
if ((r->value & REG05_DPIHW) == REG05_DPIHW_600)
1148
if ((r->value & REG05_DPIHW) == REG05_DPIHW_1200)
1150
if ((r->value & REG05_DPIHW) == REG05_DPIHW_2400)
1152
if ((r->value & REG05_DPIHW) == REG05_DPIHW_4800)
1158
/**@brief compute hardware sensor dpi to use
1159
* compute the sensor hardware dpi based on target resolution
1161
static int gl843_compute_dpihw(Genesys_Device *dev, int xres)
1163
switch(dev->model->ccd_type)
1178
return dev->sensor.optical_res;
1181
return dev->sensor.optical_res;
1185
/**@brief compute exposure to use
1186
* compute the sensor exposure based on target resolution
1188
static int gl843_compute_exposure(Genesys_Device *dev, int xres)
1190
switch(dev->model->ccd_type)
1197
return 56064 /* 21376 */;
1204
/**@brief compute motor step type to use
1205
* compute the step type (full, half, quarter, ...) to use based
1206
* on target resolution
1207
* @param dev device description
1208
* @param yres motor resolution
1209
* @return 0 for full step
1211
* 2 for quarter step
1214
static int gl843_compute_step_type(Genesys_Device *dev, int yres)
1216
switch(dev->model->motor_type)
1230
#define OPTICAL_FLAG_DISABLE_GAMMA 1
1231
#define OPTICAL_FLAG_DISABLE_SHADING 2
1232
#define OPTICAL_FLAG_DISABLE_LAMP 4
1233
#define OPTICAL_FLAG_ENABLE_LEDADD 8
1235
/** @brief setup optical related registers
1236
* start and pixels are expressed in optical sensor resolution coordinate
1237
* space. To handle odd/even case we double the resolution and
1238
* use only first logival half the sensor whic maps to effective CCD.
1239
* @param start logical start pixel coordinate
1240
* @param pixels logical number of pixels to use
1241
* @return SANE_STATUS_GOOD if OK
1244
gl843_init_optical_regs_scan (Genesys_Device * dev,
1245
Genesys_Register_Set * reg,
1246
unsigned int exposure_time,
1249
unsigned int pixels,
1252
SANE_Bool half_ccd, int color_filter, int flags)
1254
unsigned int words_per_line;
1255
unsigned int startx, endx, used_pixels;
1256
unsigned int dpiset, cksel,dpihw, factor;
1257
unsigned int i, bytes;
1258
Genesys_Register_Set *r;
1261
DBG (DBG_proc, "gl843_init_optical_regs_scan : exposure_time=%d, "
1262
"used_res=%d, start=%d, pixels=%d, channels=%d, depth=%d, "
1263
"half_ccd=%d, flags=%x\n",
1265
used_res, start, pixels, channels, depth, half_ccd, flags);
1267
/* sensor parameters */
1268
gl843_setup_sensor (dev, reg, used_res);
1270
/* to manage high resolution device while keeping good
1271
* low resolution scanning speed, we make hardware dpi vary */
1272
dpihw=gl843_compute_dpihw(dev, used_res);
1273
factor=dev->sensor.optical_res/dpihw;
1274
DBG (DBG_io2, "%s: dpihw=%d (factor=%d)\n", __FUNCTION__, dpihw, factor);
1276
r = sanei_genesys_get_address (reg, REG18);
1277
cksel= (r->value & REG18_CKSEL)+1;
1279
DBG (DBG_io2, "%s: cksel=%d\n", __FUNCTION__, cksel);
1280
dpiset = used_res * cksel;
1282
/* start and end coordinate in optical dpi coordinates */
1283
startx = start/cksel + dev->sensor.dummy_pixel;
1284
used_pixels=pixels/cksel;
1285
endx = startx + used_pixels;
1287
/* factor correction when used dpihw is not native one */
1292
used_pixels=endx-startx;
1295
status = gl843_set_fe (dev, AFE_SET);
1296
if (status != SANE_STATUS_GOOD)
1299
"gl843_init_optical_regs_scan: failed to set frontend: %s\n",
1300
sane_strstatus (status));
1304
/* enable shading */
1305
r = sanei_genesys_get_address (reg, REG01);
1306
r->value &= ~REG01_SCAN;
1307
if ((flags & OPTICAL_FLAG_DISABLE_SHADING) ||
1308
(dev->model->flags & GENESYS_FLAG_NO_CALIBRATION))
1310
r->value &= ~REG01_DVDSET;
1314
r->value |= REG01_DVDSET;
1317
r = sanei_genesys_get_address (reg, REG03);
1318
r->value &= ~REG03_AVEENB;
1319
if (flags & OPTICAL_FLAG_DISABLE_LAMP)
1320
r->value &= ~REG03_LAMPPWR;
1322
r->value |= REG03_LAMPPWR;
1324
/* exposure times */
1325
for (i = 0; i < 6; i++)
1327
r = sanei_genesys_get_address (reg, 0x10 + i);
1328
if (flags & OPTICAL_FLAG_DISABLE_LAMP)
1329
r->value = 0x01; /* 0x0101 is as off as possible */
1331
r->value = dev->sensor.regs_0x10_0x1d[i];
1335
r = sanei_genesys_get_address (reg, 0x2e);
1336
r->value = dev->settings.threshold;
1337
r = sanei_genesys_get_address (reg, 0x2f);
1338
r->value = dev->settings.threshold;
1340
/* monochrome / color scan */
1341
r = sanei_genesys_get_address (reg, REG04);
1345
r->value &= ~REG04_BITSET;
1346
r->value |= REG04_LINEART;
1349
r->value &= ~(REG04_LINEART | REG04_BITSET);
1352
r->value &= ~REG04_LINEART;
1353
r->value |= REG04_BITSET;
1357
r->value &= ~(REG04_FILTER | REG04_AFEMOD);
1360
switch (color_filter)
1363
r->value |= 0x14; /* red filter */
1366
r->value |= 0x1c; /* blue filter */
1369
r->value |= 0x18; /* green filter */
1374
r->value |= 0x10; /* mono */
1377
r = sanei_genesys_get_address (reg, REG05);
1380
r->value &= ~REG05_DPIHW;
1384
r->value |= REG05_DPIHW_600;
1387
r->value |= REG05_DPIHW_1200;
1390
r->value |= REG05_DPIHW_2400;
1393
r->value |= REG05_DPIHW_4800;
1397
/* enable gamma tables */
1398
if (flags & OPTICAL_FLAG_DISABLE_GAMMA)
1399
r->value &= ~REG05_GMMENB;
1401
r->value |= REG05_GMMENB;
1403
r = sanei_genesys_get_address (reg, 0x2c);
1404
r->value = HIBYTE (dpiset);
1405
r = sanei_genesys_get_address (reg, 0x2d);
1406
r->value = LOBYTE (dpiset);
1407
DBG (DBG_io2, "%s: dpiset used=%d\n", __FUNCTION__, dpiset);
1409
r = sanei_genesys_get_address (reg, 0x30);
1410
r->value = HIBYTE (startx);
1411
r = sanei_genesys_get_address (reg, 0x31);
1412
r->value = LOBYTE (startx);
1413
r = sanei_genesys_get_address (reg, 0x32);
1414
r->value = HIBYTE (endx);
1415
r = sanei_genesys_get_address (reg, 0x33);
1416
r->value = LOBYTE (endx);
1418
/* words(16bit) before gamma, conversion to 8 bit or lineart */
1419
words_per_line = (used_pixels * dpiset) / dpihw;
1423
words_per_line = (words_per_line >> 3) + ((words_per_line & 7) ? 1 : 0);
1427
words_per_line *= bytes;
1430
dev->bpl = words_per_line;
1432
DBG (DBG_io2, "%s: used_pixels=%d\n", __FUNCTION__, used_pixels);
1433
DBG (DBG_io2, "%s: pixels =%d\n", __FUNCTION__, pixels);
1434
DBG (DBG_io2, "%s: depth =%d\n", __FUNCTION__, depth);
1435
DBG (DBG_io2, "%s: dev->bpl =%lu\n", __FUNCTION__,
1436
(unsigned long) dev->bpl);
1438
words_per_line *= channels;
1439
dev->wpl = words_per_line;
1441
/* MAXWD is expressed in 2 words unit */
1442
/* nousedspace = (mem_bank_range * 1024 / 256 -1 ) * 4; */
1443
r = sanei_genesys_get_address (reg, 0x35);
1444
r->value = LOBYTE (HIWORD (words_per_line >> 2));
1445
r = sanei_genesys_get_address (reg, 0x36);
1446
r->value = HIBYTE (LOWORD (words_per_line >> 2));
1447
r = sanei_genesys_get_address (reg, 0x37);
1448
r->value = LOBYTE (LOWORD (words_per_line >> 2));
1449
DBG (DBG_io2, "%s: words_per_line used=%d\n", __FUNCTION__, words_per_line);
1451
r = sanei_genesys_get_address (reg, 0x38);
1452
r->value = HIBYTE (exposure_time);
1453
r = sanei_genesys_get_address (reg, 0x39);
1454
r->value = LOBYTE (exposure_time);
1455
DBG (DBG_io2, "%s: exposure_time used=%d\n", __FUNCTION__, exposure_time);
1457
r = sanei_genesys_get_address (reg, 0x34);
1458
r->value = dev->sensor.dummy_pixel;
1460
DBG (DBG_proc, "gl843_init_optical_regs_scan : completed. \n");
1461
return SANE_STATUS_GOOD;
1466
gl843_get_led_exposure (Genesys_Device * dev)
1469
if (!dev->model->is_cis)
1471
d = dev->reg[reg_0x19].value;
1472
r = dev->sensor.regs_0x10_0x1d[1] | (dev->sensor.regs_0x10_0x1d[0] << 8);
1473
g = dev->sensor.regs_0x10_0x1d[3] | (dev->sensor.regs_0x10_0x1d[2] << 8);
1474
b = dev->sensor.regs_0x10_0x1d[5] | (dev->sensor.regs_0x10_0x1d[4] << 8);
1486
/* set up registers for an actual scan
1488
* this function sets up the scanner to scan in normal or single line mode
1490
#ifndef UNIT_TESTING
1494
gl843_init_scan_regs (Genesys_Device * dev,
1495
Genesys_Register_Set * reg,
1496
float xres, /*dpi */
1497
float yres, /*dpi */
1498
float startx, /*optical_res, from dummy_pixel+1 */
1499
float starty, /*base_ydpi, from home! */
1503
unsigned int channels,
1504
int color_filter, unsigned int flags)
1507
int start, used_pixels;
1510
unsigned int lincnt;
1511
unsigned int oflags; /**> optical flags */
1517
int scan_step_type = 1;
1518
int scan_power_mode = 0;
1520
size_t requested_buffer_size, read_buffer_size;
1522
SANE_Bool half_ccd; /* false: full CCD res is used, true, half max CCD res is used */
1527
"gl843_init_scan_regs settings:\n"
1528
"Resolution : %gDPI/%gDPI\n"
1531
"Startpos : %g/%g\n"
1532
"Depth/Channels: %u/%u\n"
1534
xres, yres, lines, pixels, startx, starty, depth, channels, flags);
1552
dev->requested_buffer_size
1553
dev->read_buffer_size
1555
dev->read_bytes_in_buffer
1556
dev->read_bytes_left
1560
independent of our calculated values:
1561
dev->total_bytes_read
1566
/* we have 2 domains for ccd: xres below or above half ccd max dpi */
1567
if (dev->sensor.optical_res < 2 * xres ||
1568
!(dev->model->flags & GENESYS_FLAG_HALF_CCD_MODE))
1570
half_ccd = SANE_FALSE;
1574
half_ccd = SANE_TRUE;
1578
optical_res = dev->sensor.optical_res;
1583
if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE))
1584
stagger = (4 * yres) / dev->motor.base_ydpi;
1587
DBG (DBG_info, "gl843_init_scan_regs : stagger=%d lines\n", stagger);
1589
/** @brief compute used resolution
1590
* the sensor if mapped only to odd pixels. So we double the optical
1591
* resolution and use first half
1593
if (flags & SCAN_FLAG_USE_OPTICAL_RES)
1595
used_res = optical_res;
1599
/* resolution is choosen from a fixed list and can be used directly */
1600
if(xres>optical_res)
1601
used_res=optical_res;
1606
/* compute scan parameters values */
1607
/* pixels are allways given at full optical resolution */
1608
/* use detected left margin and fixed value */
1610
/* add x coordinates */
1616
/* compute correct pixels number */
1618
used_pixels = (pixels * optical_res) / xres;
1619
DBG (DBG_info, "%s: used_pixels=%d\n", __FUNCTION__, used_pixels);
1621
/* round up pixels number if needed */
1622
if (used_pixels * xres < pixels * optical_res)
1625
/* we want even number of pixels here */
1632
/* cis color scan is effectively a gray scan with 3 gray lines per color line and a FILTER of 0 */
1633
if (dev->model->is_cis)
1634
slope_dpi = yres * channels;
1638
/* scan_step_type */
1639
scan_step_type = gl843_compute_step_type(dev, slope_dpi);
1640
exposure_time = gl843_compute_exposure (dev, used_res);
1642
DBG (DBG_info, "gl843_init_scan_regs : exposure_time=%d pixels\n",
1644
DBG (DBG_info, "gl843_init_scan_regs : scan_step_type=%d\n",
1647
/*** optical parameters ***/
1648
/* in case of dynamic lineart, we use an internal 8 bit gray scan
1649
* to generate 1 lineart data */
1650
if ((flags & SCAN_FLAG_DYNAMIC_LINEART)
1651
&& (dev->settings.scan_mode == SCAN_MODE_LINEART))
1656
flags |= SCAN_FLAG_DISABLE_GAMMA;
1658
/* we enable true gray for cis scanners only, and just when doing
1659
* scan since color calibration is OK for this mode
1662
if (flags & SCAN_FLAG_DISABLE_SHADING)
1663
oflags |= OPTICAL_FLAG_DISABLE_SHADING;
1664
if (flags & SCAN_FLAG_DISABLE_GAMMA)
1665
oflags |= OPTICAL_FLAG_DISABLE_GAMMA;
1666
if (flags & SCAN_FLAG_DISABLE_LAMP)
1667
oflags |= OPTICAL_FLAG_DISABLE_LAMP;
1669
/* now _LOGICAL_ optical values used are known, setup registers */
1670
status = gl843_init_optical_regs_scan (dev,
1678
half_ccd, color_filter, oflags);
1680
if (status != SANE_STATUS_GOOD)
1683
/*** motor parameters ***/
1686
/* scanned area must be enlarged by max color shift needed */
1687
/* all values are assumed >= 0 */
1688
if (channels > 1 && !(flags & SCAN_FLAG_IGNORE_LINE_DISTANCE))
1690
max_shift = dev->model->ld_shift_r;
1691
if (dev->model->ld_shift_b > max_shift)
1692
max_shift = dev->model->ld_shift_b;
1693
if (dev->model->ld_shift_g > max_shift)
1694
max_shift = dev->model->ld_shift_g;
1695
max_shift = (max_shift * yres) / dev->motor.base_ydpi;
1703
lincnt = lines + max_shift + stagger;
1705
/* add tl_y to base movement */
1707
DBG (DBG_info, "gl843_init_scan_regs: move=%d steps\n", move);
1709
status = gl843_init_motor_regs_scan (dev,
1714
dev->model->is_cis ? lincnt * channels : lincnt,
1718
(flags & SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE) ? MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE : 0);
1719
if (status != SANE_STATUS_GOOD)
1722
/*** prepares data reordering ***/
1724
/* words_per_line */
1725
bytes_per_line = (used_pixels * used_res) / optical_res;
1726
bytes_per_line = (bytes_per_line * channels * depth) / 8;
1728
/* since we don't have sheetfed scanners to handle,
1729
* use huge read buffer */
1730
/* TODO find the best size according to settings */
1731
requested_buffer_size = 16 * bytes_per_line;
1734
2 * requested_buffer_size +
1735
((max_shift + stagger) * used_pixels * channels * depth) / 8;
1737
RIE (sanei_genesys_buffer_free (&(dev->read_buffer)));
1738
RIE (sanei_genesys_buffer_alloc (&(dev->read_buffer), read_buffer_size));
1740
RIE (sanei_genesys_buffer_free (&(dev->lines_buffer)));
1741
RIE (sanei_genesys_buffer_alloc (&(dev->lines_buffer), read_buffer_size));
1743
RIE (sanei_genesys_buffer_free (&(dev->shrink_buffer)));
1744
RIE (sanei_genesys_buffer_alloc (&(dev->shrink_buffer),
1745
requested_buffer_size));
1747
RIE (sanei_genesys_buffer_free (&(dev->out_buffer)));
1748
RIE (sanei_genesys_buffer_alloc (&(dev->out_buffer),
1749
(8 * dev->settings.pixels * channels *
1753
dev->read_bytes_left = bytes_per_line * lincnt;
1756
"gl843_init_scan_regs: physical bytes to read = %lu\n",
1757
(u_long) dev->read_bytes_left);
1758
dev->read_active = SANE_TRUE;
1761
dev->current_setup.pixels = (used_pixels * used_res) / optical_res;
1762
DBG (DBG_info, "%s: current_setup.pixels=%d\n", __FUNCTION__, dev->current_setup.pixels);
1763
dev->current_setup.lines = lincnt;
1764
dev->current_setup.depth = depth;
1765
dev->current_setup.channels = channels;
1766
dev->current_setup.exposure_time = exposure_time;
1767
dev->current_setup.xres = used_res;
1768
dev->current_setup.yres = yres;
1769
dev->current_setup.half_ccd = half_ccd;
1770
dev->current_setup.stagger = stagger;
1771
dev->current_setup.max_shift = max_shift + stagger;
1773
dev->total_bytes_read = 0;
1774
if (depth == 1 || dev->settings.scan_mode == SCAN_MODE_LINEART)
1775
dev->total_bytes_to_read =
1776
((dev->settings.pixels * dev->settings.lines) / 8 +
1777
(((dev->settings.pixels * dev->settings.lines) % 8) ? 1 : 0)) *
1780
dev->total_bytes_to_read =
1781
dev->settings.pixels * dev->settings.lines * channels * (depth / 8);
1783
DBG (DBG_info, "gl843_init_scan_regs: total bytes to send = %lu\n",
1784
(u_long) dev->total_bytes_to_read);
1786
DBG (DBG_proc, "gl843_init_scan_regs: completed\n");
1787
return SANE_STATUS_GOOD;
1791
gl843_calculate_current_setup (Genesys_Device * dev)
1797
float xres; /*dpi */
1798
float yres; /*dpi */
1799
float startx; /*optical_res, from dummy_pixel+1 */
1806
unsigned int lincnt;
1812
int scan_step_type = 1;
1813
int scan_power_mode = 0;
1816
SANE_Bool half_ccd; /* false: full CCD res is used, true, half max CCD res is used */
1820
"gl843_calculate_current_setup settings:\n"
1821
"Resolution: %ux%uDPI\n"
1824
"Startpos : %.3f/%.3f\n"
1825
"Scan mode : %d\n\n",
1827
dev->settings.yres, dev->settings.lines, dev->settings.pixels,
1828
dev->settings.tl_x, dev->settings.tl_y, dev->settings.scan_mode);
1831
if (dev->settings.scan_mode == 4) /* single pass color */
1837
depth = dev->settings.depth;
1838
if (dev->settings.scan_mode == 0)
1842
start = SANE_UNFIX (dev->model->x_offset);
1843
start += dev->settings.tl_x;
1844
start = (start * dev->sensor.optical_res) / MM_PER_INCH;
1847
xres = dev->settings.xres;
1848
yres = dev->settings.yres;
1850
pixels = dev->settings.pixels;
1851
lines = dev->settings.lines;
1852
color_filter = dev->settings.color_filter;
1856
"gl843_calculate_current_setup settings:\n"
1857
"Resolution : %gDPI/%gDPI\n"
1861
"Depth/Channels: %u/%u\n\n",
1862
xres, yres, lines, pixels, startx, depth, channels);
1865
/* we have 2 domains for ccd: xres below or above half ccd max dpi */
1866
if ((dev->sensor.optical_res < 2 * xres) ||
1867
!(dev->model->flags & GENESYS_FLAG_HALF_CCD_MODE))
1869
half_ccd = SANE_FALSE;
1873
half_ccd = SANE_TRUE;
1878
optical_res = dev->sensor.optical_res;
1883
if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE))
1884
stagger = (4 * yres) / dev->motor.base_ydpi;
1887
DBG (DBG_info, "%s: stagger=%d lines\n", __FUNCTION__, stagger);
1889
if(xres<=optical_res)
1892
used_res=optical_res;
1894
/* compute scan parameters values */
1895
/* pixels are allways given at half or full CCD optical resolution */
1896
/* use detected left margin and fixed value */
1898
/* compute correct pixels number */
1899
used_pixels = (pixels * optical_res) / xres;
1900
DBG (DBG_info, "%s: used_pixels=%d\n", __FUNCTION__, used_pixels);
1904
/* cis color scan is effectively a gray scan with 3 gray lines per color
1905
line and a FILTER of 0 */
1906
if (dev->model->is_cis)
1907
slope_dpi = yres * channels;
1911
/* scan_step_type */
1912
scan_step_type = gl843_compute_step_type(dev, yres);
1914
exposure_time = sanei_genesys_exposure_time2 (dev,
1917
start + used_pixels + 258,
1918
gl843_get_led_exposure (dev),
1921
DBG (DBG_info, "%s : exposure_time=%d pixels\n", __FUNCTION__, exposure_time);
1924
/* scanned area must be enlarged by max color shift needed */
1925
/* all values are assumed >= 0 */
1928
max_shift = dev->model->ld_shift_r;
1929
if (dev->model->ld_shift_b > max_shift)
1930
max_shift = dev->model->ld_shift_b;
1931
if (dev->model->ld_shift_g > max_shift)
1932
max_shift = dev->model->ld_shift_g;
1933
max_shift = (max_shift * yres) / dev->motor.base_ydpi;
1941
lincnt = lines + max_shift + stagger;
1943
dev->current_setup.pixels = (used_pixels * used_res) / optical_res;
1944
DBG (DBG_info, "%s: current_setup.pixels=%d\n", __FUNCTION__, dev->current_setup.pixels);
1945
dev->current_setup.lines = lincnt;
1946
dev->current_setup.depth = depth;
1947
dev->current_setup.channels = channels;
1948
dev->current_setup.exposure_time = exposure_time;
1949
dev->current_setup.xres = used_res;
1950
dev->current_setup.yres = yres;
1951
dev->current_setup.half_ccd = half_ccd;
1952
dev->current_setup.stagger = stagger;
1953
dev->current_setup.max_shift = max_shift + stagger;
1955
DBG (DBG_proc, "gl843_calculate_current_setup: completed\n");
1956
return SANE_STATUS_GOOD;
1960
gl843_set_motor_power (Genesys_Register_Set * regs, SANE_Bool set)
1963
DBG (DBG_proc, "gl843_set_motor_power\n");
1967
sanei_genesys_set_reg_from_set (regs, REG02,
1968
sanei_genesys_read_reg_from_set (regs,
1974
sanei_genesys_set_reg_from_set (regs, REG02,
1975
sanei_genesys_read_reg_from_set (regs,
1982
gl843_set_lamp_power (Genesys_Device * dev,
1983
Genesys_Register_Set * regs, SANE_Bool set)
1985
Genesys_Register_Set *r;
1990
sanei_genesys_set_reg_from_set (regs, 0x03,
1991
sanei_genesys_read_reg_from_set (regs,
1995
for (i = 0; i < 6; i++)
1997
r = sanei_genesys_get_address (dev->calib_reg, 0x10 + i);
1998
r->value = dev->sensor.regs_0x10_0x1d[i];
2003
sanei_genesys_set_reg_from_set (regs, 0x03,
2004
sanei_genesys_read_reg_from_set (regs,
2008
for (i = 0; i < 6; i++)
2010
r = sanei_genesys_get_address (dev->calib_reg, 0x10 + i);
2017
* for fast power saving methods only, like disabling certain amplifiers
2018
* @param device device to use
2019
* @param enable true to set inot powersaving
2022
gl843_save_power (Genesys_Device * dev, SANE_Bool enable)
2027
DBG (DBG_proc, "gl843_save_power: enable = %d\n", enable);
2029
return SANE_STATUS_INVAL;
2031
/* switch KV-SS080 lamp off */
2032
if (dev->model->gpo_type == GPO_KVSS080)
2034
RIE(sanei_genesys_read_register (dev, REG6C, &val));
2039
RIE(sanei_genesys_write_register(dev,REG6C,val));
2043
return SANE_STATUS_GOOD;
2047
gl843_set_powersaving (Genesys_Device * dev, int delay /* in minutes */ )
2049
SANE_Status status = SANE_STATUS_GOOD;
2051
DBG (DBG_proc, "gl843_set_powersaving (delay = %d)\n", delay);
2053
return SANE_STATUS_INVAL;
2059
#ifndef UNIT_TESTING
2063
gl843_start_action (Genesys_Device * dev)
2065
return sanei_genesys_write_register (dev, 0x0f, 0x01);
2069
gl843_stop_action (Genesys_Device * dev)
2075
DBG (DBG_proc, "%s\n", __FUNCTION__);
2077
status = sanei_genesys_get_status (dev, &val);
2078
if (DBG_LEVEL >= DBG_io)
2084
status = sanei_genesys_read_register (dev, REG40, &val40);
2085
if (status != SANE_STATUS_GOOD)
2088
"%s: failed to read home sensor: %s\n", __FUNCTION__,
2089
sane_strstatus (status));
2090
DBG (DBG_proc, "%s: completed\n", __FUNCTION__);
2094
/* only stop action if needed */
2095
if (!(val40 & REG40_DATAENB) && !(val40 & REG40_MOTMFLG))
2097
DBG (DBG_info, "%s: already stopped\n", __FUNCTION__);
2098
DBG (DBG_proc, "%s: completed\n", __FUNCTION__);
2099
return SANE_STATUS_GOOD;
2103
val = sanei_genesys_read_reg_from_set (dev->reg, REG01);
2105
sanei_genesys_set_reg_from_set (dev->reg, REG01, val);
2106
status = sanei_genesys_write_register (dev, REG01, val);
2107
if (status != SANE_STATUS_GOOD)
2110
"end_scan: failed to write register 01: %s\n",
2111
sane_strstatus (status));
2114
usleep (100 * 1000);
2119
status = sanei_genesys_get_status (dev, &val);
2120
if (DBG_LEVEL >= DBG_io)
2125
status = sanei_genesys_read_register (dev, 0x40, &val40);
2126
if (status != SANE_STATUS_GOOD)
2129
"%s: failed to read home sensor: %s\n", __FUNCTION__,
2130
sane_strstatus (status));
2135
/* if scanner is in command mode, we are done */
2136
if (!(val40 & REG40_DATAENB) && !(val40 & REG40_MOTMFLG)
2137
&& !(val & REG41_MOTORENB))
2140
return SANE_STATUS_GOOD;
2143
usleep (100 * 1000);
2148
return SANE_STATUS_IO_ERROR;
2152
gl843_get_paper_sensor (Genesys_Device * dev, SANE_Bool * paper_loaded)
2157
status = sanei_genesys_read_register (dev, REG6D, &val);
2158
if (status != SANE_STATUS_GOOD)
2161
"gl843_get_paper_sensor: failed to read gpio: %s\n",
2162
sane_strstatus (status));
2165
*paper_loaded = (val & 0x1) == 0;
2166
return SANE_STATUS_GOOD;
2168
return SANE_STATUS_INVAL;
2172
gl843_eject_document (Genesys_Device * dev)
2174
DBG (DBG_proc, "%s: not implemented \n", __FUNCTION__);
2176
return SANE_STATUS_INVAL;
2177
return SANE_STATUS_GOOD;
2182
gl843_load_document (Genesys_Device * dev)
2184
DBG (DBG_proc, "%s: not implemented \n", __FUNCTION__);
2186
return SANE_STATUS_INVAL;
2187
return SANE_STATUS_GOOD;
2191
* detects end of document and adjust current scan
2192
* to take it into account
2193
* used by sheetfed scanners
2196
gl843_detect_document_end (Genesys_Device * dev)
2198
SANE_Status status = SANE_STATUS_GOOD;
2199
SANE_Bool paper_loaded;
2200
unsigned int scancnt = 0;
2201
int flines, channels, depth, bytes_remain, sublines,
2202
bytes_to_flush, lines, sub_bytes, tmp, read_bytes_left;
2203
DBG (DBG_proc, "%s: begin\n", __FUNCTION__);
2205
RIE (gl843_get_paper_sensor (dev, &paper_loaded));
2207
/* sheetfed scanner uses home sensor as paper present */
2208
if ((dev->document == SANE_TRUE) && !paper_loaded)
2210
DBG (DBG_info, "%s: no more document\n", __FUNCTION__);
2211
dev->document = SANE_FALSE;
2213
channels = dev->current_setup.channels;
2214
depth = dev->current_setup.depth;
2215
read_bytes_left = (int) dev->read_bytes_left;
2216
DBG (DBG_io, "gl843_detect_document_end: read_bytes_left=%d\n",
2219
/* get lines read */
2220
status = sanei_genesys_read_scancnt (dev, &scancnt);
2221
if (status != SANE_STATUS_GOOD)
2227
/* compute number of line read */
2228
tmp = (int) dev->total_bytes_read;
2229
if (depth == 1 || dev->settings.scan_mode == SCAN_MODE_LINEART)
2230
flines = tmp * 8 / dev->settings.pixels / channels;
2232
flines = tmp / (depth / 8) / dev->settings.pixels / channels;
2234
/* number of scanned lines, but no read yet */
2235
flines = scancnt - flines;
2238
"gl843_detect_document_end: %d scanned but not read lines\n",
2242
/* adjust number of bytes to read
2243
* we need to read the final bytes which are word per line * number of last lines
2244
* to have doc leaving feeder */
2246
(SANE_UNFIX (dev->model->post_scan) * dev->current_setup.yres) /
2247
MM_PER_INCH + flines;
2248
DBG (DBG_io, "gl843_detect_document_end: adding %d line to flush\n",
2251
/* number of bytes to read from scanner to get document out of it after
2252
* end of document dectected by hardware sensor */
2253
bytes_to_flush = lines * dev->wpl;
2255
/* if we are already close to end of scan, flushing isn't needed */
2256
if (bytes_to_flush < read_bytes_left)
2258
/* we take all these step to work around an overflow on some plateforms */
2259
tmp = (int) dev->total_bytes_read;
2260
DBG (DBG_io, "gl843_detect_document_end: tmp=%d\n", tmp);
2261
bytes_remain = (int) dev->total_bytes_to_read;
2262
DBG (DBG_io, "gl843_detect_document_end: bytes_remain=%d\n",
2264
bytes_remain = bytes_remain - tmp;
2265
DBG (DBG_io, "gl843_detect_document_end: bytes_remain=%d\n",
2268
/* remaining lines to read by frontend for the current scan */
2269
if (depth == 1 || dev->settings.scan_mode == SCAN_MODE_LINEART)
2271
flines = bytes_remain * 8 / dev->settings.pixels / channels;
2274
flines = bytes_remain / (depth / 8)
2275
/ dev->settings.pixels / channels;
2276
DBG (DBG_io, "gl843_detect_document_end: flines=%d\n", flines);
2280
/* change the value controlling communication with the frontend :
2281
* total bytes to read is current value plus the number of remaining lines
2282
* multiplied by bytes per line */
2283
sublines = flines - lines;
2285
if (depth == 1 || dev->settings.scan_mode == SCAN_MODE_LINEART)
2287
((dev->settings.pixels * sublines) / 8 +
2288
(((dev->settings.pixels * sublines) % 8) ? 1 : 0)) *
2292
dev->settings.pixels * sublines * channels * (depth / 8);
2294
dev->total_bytes_to_read -= sub_bytes;
2296
/* then adjust the physical bytes to read */
2297
if (read_bytes_left > sub_bytes)
2299
dev->read_bytes_left -= sub_bytes;
2303
dev->total_bytes_to_read = dev->total_bytes_read;
2304
dev->read_bytes_left = 0;
2307
DBG (DBG_io, "gl843_detect_document_end: sublines=%d\n",
2309
DBG (DBG_io, "gl843_detect_document_end: subbytes=%d\n",
2312
"gl843_detect_document_end: total_bytes_to_read=%lu\n",
2313
(unsigned long) dev->total_bytes_to_read);
2315
"gl843_detect_document_end: read_bytes_left=%d\n",
2321
DBG (DBG_io, "gl843_detect_document_end: no flushing needed\n");
2325
DBG (DBG_proc, "%s: finished\n", __FUNCTION__);
2326
return SANE_STATUS_GOOD;
2329
/* Send the low-level scan command */
2330
/* todo : is this that useful ? */
2331
#ifndef UNIT_TESTING
2335
gl843_begin_scan (Genesys_Device * dev, Genesys_Register_Set * reg,
2336
SANE_Bool start_motor)
2343
return SANE_STATUS_INVAL;
2345
/* set up GPIO for scan */
2347
if (dev->model->gpo_type == GPO_KVSS080)
2349
RIE (sanei_genesys_write_register (dev, REGA9, 0x00));
2350
RIE (sanei_genesys_write_register (dev, REGA6, 0xf6));
2352
RIE(sanei_genesys_write_register(dev,0x7e,0x04));
2354
if (dev->model->gpo_type == GPO_G4050)
2356
RIE (sanei_genesys_write_register (dev, REGA6, 0x44));
2357
RIE (sanei_genesys_write_register (dev, REGA7, 0xfe));
2358
RIE (sanei_genesys_write_register (dev, REGA8, 0x3e));
2359
RIE (sanei_genesys_write_register (dev, REGA9, 0x06));
2361
RIE(sanei_genesys_write_register(dev,0x7e,0x01));
2364
/* clear scan and feed count */
2365
RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT | REG0D_CLRMCNT));
2367
/* enable scan and motor */
2368
RIE (sanei_genesys_read_register (dev, REG01, &val));
2370
RIE (sanei_genesys_write_register (dev, REG01, val));
2374
RIE (sanei_genesys_write_register (dev, REG0F, 1));
2378
RIE (sanei_genesys_write_register (dev, REG0F, 0));
2386
/* Send the stop scan command */
2387
#ifndef UNIT_TESTING
2391
gl843_end_scan (Genesys_Device * dev, Genesys_Register_Set * reg,
2392
SANE_Bool check_stop)
2396
DBG (DBG_proc, "gl843_end_scan (check_stop = %d)\n", check_stop);
2398
return SANE_STATUS_INVAL;
2400
/* post scan gpio */
2401
RIE(sanei_genesys_write_register(dev,0x7e,0x00));
2403
if (dev->model->is_sheetfed == SANE_TRUE)
2405
status = SANE_STATUS_GOOD;
2407
else /* flat bed scanners */
2409
status = gl843_stop_action (dev);
2410
if (status != SANE_STATUS_GOOD)
2413
"gl843_end_scan: failed to stop: %s\n",
2414
sane_strstatus (status));
2424
/** @brief Moves the slider to the home (top) position slowly
2426
#ifndef UNIT_TESTING
2430
gl843_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
2432
Genesys_Register_Set local_reg[GENESYS_GL843_MAX_REGS];
2434
Genesys_Register_Set *r;
2439
DBG (DBG_proc, "gl843_slow_back_home (wait_until_home = %d)\n",
2441
usleep (100000); /* sleep 100 ms */
2443
dev->scanhead_position_in_steps = 0;
2444
status = sanei_genesys_get_status (dev, &val);
2445
if (status != SANE_STATUS_GOOD)
2448
"gl843_slow_back_home: failed to read home sensor: %s\n",
2449
sane_strstatus (status));
2452
if (DBG_LEVEL >= DBG_io)
2456
if (val & REG41_HOMESNR) /* is sensor at home? */
2458
DBG (DBG_info, "gl843_slow_back_home: already at home, completed\n");
2459
return SANE_STATUS_GOOD;
2462
memset (local_reg, 0, sizeof (local_reg));
2464
memcpy (local_reg, dev->reg,
2465
GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set));
2466
resolution=gl843_get_lowest_ydpi(dev);
2468
gl843_init_scan_regs (dev,
2478
dev->settings.color_filter,
2479
SCAN_FLAG_DISABLE_SHADING |
2480
SCAN_FLAG_DISABLE_GAMMA |
2481
SCAN_FLAG_IGNORE_LINE_DISTANCE);
2482
gl843_init_motor_regs_scan (dev,
2484
gl843_compute_exposure (dev, resolution),
2486
gl843_compute_step_type(dev, resolution),
2489
30000, /* feed steps */
2493
/* clear scan and feed count */
2494
RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT | REG0D_CLRMCNT));
2496
/* set up for reverse and no scan */
2497
r = sanei_genesys_get_address (local_reg, REG02);
2498
r->value |= REG02_MTRREV;
2499
r = sanei_genesys_get_address (local_reg, REG01);
2500
r->value &= ~REG01_SCAN;
2502
RIE (gl843_bulk_write_register (dev, local_reg, GENESYS_GL843_MAX_REGS));
2504
status = gl843_start_action (dev);
2505
if (status != SANE_STATUS_GOOD)
2508
"gl843_slow_back_home: failed to start motor: %s\n",
2509
sane_strstatus (status));
2510
gl843_stop_action (dev);
2511
/* restore original registers */
2512
gl843_bulk_write_register (dev, dev->reg, GENESYS_GL843_MAX_REGS);
2516
if (wait_until_home)
2519
while (loop < 300) /* do not wait longer then 30 seconds */
2521
status = sanei_genesys_get_status (dev, &val);
2522
if (status != SANE_STATUS_GOOD)
2525
"gl843_slow_back_home: failed to read home sensor: %s\n",
2526
sane_strstatus (status));
2530
if (val & REG41_HOMESNR) /* home sensor */
2532
DBG (DBG_info, "gl843_slow_back_home: reached home position\n");
2533
DBG (DBG_proc, "gl843_slow_back_home: finished\n");
2534
return SANE_STATUS_GOOD;
2536
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
gl843_stop_action (dev);
2543
"gl843_slow_back_home: timeout while waiting for scanhead to go home\n");
2544
return SANE_STATUS_IO_ERROR;
2547
DBG (DBG_info, "gl843_slow_back_home: scanhead is still moving\n");
2548
DBG (DBG_proc, "gl843_slow_back_home: finished\n");
2549
return SANE_STATUS_GOOD;
2552
/* Automatically set top-left edge of the scan area by scanning a 200x200 pixels
2553
area at 600 dpi from very top of scanner */
2555
gl843_search_start_position (Genesys_Device * dev)
2560
Genesys_Register_Set local_reg[GENESYS_GL843_MAX_REGS];
2566
DBG (DBG_proc, "gl843_search_start_position\n");
2568
memset (local_reg, 0, sizeof (local_reg));
2569
memcpy (local_reg, dev->reg,
2570
GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set));
2572
/* sets for a 200 lines * 600 pixels */
2573
/* normal scan with no shading */
2575
status = gl843_init_scan_regs (dev, local_reg, dpi, dpi, 0, 0, /*we should give a small offset here~60 steps */
2576
600, dev->model->search_lines, 8, 1, 1, /*green */
2577
SCAN_FLAG_DISABLE_SHADING |
2578
SCAN_FLAG_DISABLE_GAMMA |
2579
SCAN_FLAG_IGNORE_LINE_DISTANCE |
2580
SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE);
2582
/* send to scanner */
2583
status = gl843_bulk_write_register (dev, local_reg, GENESYS_GL843_MAX_REGS);
2584
if (status != SANE_STATUS_GOOD)
2587
"gl843_search_start_position: failed to bulk write registers: %s\n",
2588
sane_strstatus (status));
2592
size = pixels * dev->model->search_lines;
2594
data = malloc (size);
2598
"gl843_search_start_position: failed to allocate memory\n");
2599
return SANE_STATUS_NO_MEM;
2602
status = gl843_begin_scan (dev, local_reg, SANE_TRUE);
2603
if (status != SANE_STATUS_GOOD)
2607
"gl843_search_start_position: failed to begin scan: %s\n",
2608
sane_strstatus (status));
2612
/* waits for valid data */
2614
sanei_genesys_test_buffer_empty (dev, &steps);
2617
/* now we're on target, we can read data */
2618
status = sanei_genesys_read_data_from_scanner (dev, data, size);
2619
if (status != SANE_STATUS_GOOD)
2623
"gl843_search_start_position: failed to read data: %s\n",
2624
sane_strstatus (status));
2628
if (DBG_LEVEL >= DBG_data)
2629
sanei_genesys_write_pnm_file ("search_position.pnm", data, 8, 1, pixels,
2630
dev->model->search_lines);
2632
status = gl843_end_scan (dev, local_reg, SANE_TRUE);
2633
if (status != SANE_STATUS_GOOD)
2637
"gl843_search_start_position: failed to end scan: %s\n",
2638
sane_strstatus (status));
2642
/* update regs to copy ASIC internal state */
2643
memcpy (dev->reg, local_reg,
2644
GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set));
2647
sanei_genesys_search_reference_point (dev, data, 0, dpi, pixels,
2648
dev->model->search_lines);
2649
if (status != SANE_STATUS_GOOD)
2653
"gl843_search_start_position: failed to set search reference point: %s\n",
2654
sane_strstatus (status));
2659
return SANE_STATUS_GOOD;
2663
* sets up register for coarse gain calibration
2664
* todo: check it for scanners using it */
2666
gl843_init_regs_for_coarse_calibration (Genesys_Device * dev)
2671
Genesys_Register_Set *r;
2674
cksel = (dev->calib_reg[reg_0x18].value & REG18_CKSEL) + 1; /* clock speed = 1..4 clocks */
2677
if (dev->settings.scan_mode == SCAN_MODE_COLOR) /* single pass color */
2682
status = gl843_init_scan_regs (dev,
2688
dev->sensor.optical_res / cksel,
2692
dev->settings.color_filter,
2693
SCAN_FLAG_DISABLE_SHADING |
2694
SCAN_FLAG_DISABLE_GAMMA |
2695
SCAN_FLAG_SINGLE_LINE |
2696
SCAN_FLAG_IGNORE_LINE_DISTANCE);
2697
if (status != SANE_STATUS_GOOD)
2700
"gl843_init_register_for_coarse_calibration: failed to setup scan: %s\n",
2701
sane_strstatus (status));
2704
r = sanei_genesys_get_address (dev->calib_reg, REG02);
2705
r->value &= ~REG02_MTRPWR;
2708
"gl843_init_register_for_coarse_calibration: optical sensor res: %d dpi, actual res: %d\n",
2709
dev->sensor.optical_res / cksel, dev->settings.xres);
2712
gl843_bulk_write_register (dev, dev->calib_reg, GENESYS_GL843_MAX_REGS);
2713
if (status != SANE_STATUS_GOOD)
2716
"gl843_init_register_for_coarse_calibration: failed to bulk write registers: %s\n",
2717
sane_strstatus (status));
2722
return SANE_STATUS_GOOD;
2726
/* init registers for shading calibration */
2728
gl843_init_regs_for_shading (Genesys_Device * dev)
2731
int move,resolution;
2735
/* initial calibration reg values */
2736
memcpy (dev->calib_reg, dev->reg,
2737
GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set));
2739
dev->calib_channels = 3;
2740
dev->calib_pixels = dev->sensor.sensor_pixels;
2741
resolution=gl843_compute_dpihw(dev,dev->settings.xres);
2743
/* distance to move to reach white target */
2744
move = SANE_UNFIX (dev->model->y_offset_calib);
2745
move = (move * resolution) / MM_PER_INCH;
2747
status = gl843_init_scan_regs (dev,
2754
dev->model->shading_lines,
2756
dev->calib_channels,
2757
dev->settings.color_filter,
2758
SCAN_FLAG_DISABLE_SHADING |
2759
SCAN_FLAG_DISABLE_GAMMA |
2760
SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE |
2761
SCAN_FLAG_IGNORE_LINE_DISTANCE);
2763
if (status != SANE_STATUS_GOOD)
2766
"gl843_init_registers_for_shading: failed to setup scan: %s\n",
2767
sane_strstatus (status));
2771
dev->scanhead_position_in_steps += dev->model->shading_lines + move;
2774
gl843_bulk_write_register (dev, dev->calib_reg, GENESYS_GL843_MAX_REGS);
2775
if (status != SANE_STATUS_GOOD)
2778
"gl843_init_registers_for_shading: failed to bulk write registers: %s\n",
2779
sane_strstatus (status));
2784
return SANE_STATUS_GOOD;
2787
/** @brief set up registers for the actual scan
2790
gl843_init_regs_for_scan (Genesys_Device * dev)
2802
"gl843_init_regs_for_scan settings:\nResolution: %ux%uDPI\n"
2803
"Lines : %u\npixels : %u\nStartpos : %.3f/%.3f\nScan mode : %d\n\n",
2806
dev->settings.lines,
2807
dev->settings.pixels,
2810
dev->settings.scan_mode);
2812
/* ensure head is parked in case of calibration */
2813
gl843_slow_back_home (dev, SANE_TRUE);
2816
if (dev->settings.scan_mode == SCAN_MODE_COLOR)
2822
depth = dev->settings.depth;
2823
if (dev->settings.scan_mode == SCAN_MODE_LINEART)
2826
move_dpi = dev->motor.base_ydpi;
2828
move = SANE_UNFIX (dev->model->y_offset);
2829
move += dev->settings.tl_y;
2830
move = (move * move_dpi) / MM_PER_INCH;
2831
DBG (DBG_info, "gl843_init_regs_for_scan: move=%f steps\n", move);
2834
start = SANE_UNFIX (dev->model->x_offset);
2835
start += dev->settings.tl_x;
2836
start = (start * dev->sensor.optical_res) / MM_PER_INCH;
2840
/* enable emulated lineart from gray data */
2841
if(dev->settings.scan_mode == SCAN_MODE_LINEART
2842
&& dev->settings.dynamic_lineart)
2844
flags |= SCAN_FLAG_DYNAMIC_LINEART;
2847
status = gl843_init_scan_regs (dev,
2853
dev->settings.pixels,
2854
dev->settings.lines,
2856
channels, dev->settings.color_filter, flags);
2858
if (status != SANE_STATUS_GOOD)
2862
return SANE_STATUS_GOOD;
2866
* this function sends generic gamma table (ie linear ones)
2867
* or the Sensor specific one if provided
2870
gl843_send_gamma_table (Genesys_Device * dev, SANE_Bool generic)
2877
DBG (DBG_proc, "gl843_send_gamma_table\n");
2879
/* don't send anything if no specific gamma table defined */
2881
&& (dev->sensor.red_gamma_table == NULL
2882
|| dev->sensor.green_gamma_table == NULL
2883
|| dev->sensor.blue_gamma_table == NULL))
2885
DBG (DBG_proc, "gl843_send_gamma_table: nothing to send, skipping\n");
2886
return SANE_STATUS_GOOD;
2891
/* allocate temporary gamma tables: 16 bits words, 3 channels */
2892
gamma = (uint8_t *) malloc (size * 2 * 3);
2894
return SANE_STATUS_NO_MEM;
2896
/* take care off generic/specific data */
2899
/* fill with default values */
2900
for (i = 0; i < size; i++)
2903
gamma[i * 2 + size * 0 + 0] = gmmval & 0xff;
2904
gamma[i * 2 + size * 0 + 1] = (gmmval >> 8) & 0xff;
2905
gamma[i * 2 + size * 2 + 0] = gmmval & 0xff;
2906
gamma[i * 2 + size * 2 + 1] = (gmmval >> 8) & 0xff;
2907
gamma[i * 2 + size * 4 + 0] = gmmval & 0xff;
2908
gamma[i * 2 + size * 4 + 1] = (gmmval >> 8) & 0xff;
2913
/* copy sensor specific's gamma tables */
2914
for (i = 0; i < size; i++)
2916
gamma[i * 2 + size * 0 + 0] = dev->sensor.red_gamma_table[i] & 0xff;
2917
gamma[i * 2 + size * 0 + 1] =
2918
(dev->sensor.red_gamma_table[i] >> 8) & 0xff;
2919
gamma[i * 2 + size * 2 + 0] =
2920
dev->sensor.green_gamma_table[i] & 0xff;
2921
gamma[i * 2 + size * 2 + 1] =
2922
(dev->sensor.green_gamma_table[i] >> 8) & 0xff;
2923
gamma[i * 2 + size * 4 + 0] =
2924
dev->sensor.blue_gamma_table[i] & 0xff;
2925
gamma[i * 2 + size * 4 + 1] =
2926
(dev->sensor.blue_gamma_table[i] >> 8) & 0xff;
2931
status = gl843_set_buffer_address (dev, 0x0000);
2932
if (status != SANE_STATUS_GOOD)
2936
"gl843_send_gamma_table: failed to set buffer address: %s\n",
2937
sane_strstatus (status));
2942
status = gl843_bulk_write_data (dev, 0x28, (uint8_t *) gamma, size * 2 * 3);
2943
if (status != SANE_STATUS_GOOD)
2947
"gl843_send_gamma_table: failed to send gamma table: %s\n",
2948
sane_strstatus (status));
2952
DBG (DBG_proc, "gl843_send_gamma_table: completed\n");
2954
return SANE_STATUS_GOOD;
2957
/* this function does the led calibration by scanning one line of the calibration
2958
area below scanner's top on white strip.
2960
-needs working coarse/gain
2963
gl843_led_calibration (Genesys_Device * dev)
2970
SANE_Status status = SANE_STATUS_GOOD;
2972
int channels, depth;
2973
int avg[3], avga, avge;
2976
uint16_t expr, expg, expb;
2977
Genesys_Register_Set *r;
2979
SANE_Bool acceptable = SANE_FALSE;
2981
DBG (DBG_proc, "gl843_led_calibration\n");
2983
/* offset calibration is always done in color mode */
2986
used_res = dev->sensor.optical_res;
2988
(dev->sensor.sensor_pixels * used_res) / dev->sensor.optical_res;
2990
/* initial calibration reg values */
2991
memcpy (dev->calib_reg, dev->reg,
2992
GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set));
2994
status = gl843_init_scan_regs (dev,
2997
dev->motor.base_ydpi,
3004
dev->settings.color_filter,
3005
SCAN_FLAG_DISABLE_SHADING |
3006
SCAN_FLAG_DISABLE_GAMMA |
3007
SCAN_FLAG_SINGLE_LINE |
3008
SCAN_FLAG_IGNORE_LINE_DISTANCE);
3010
if (status != SANE_STATUS_GOOD)
3013
"gl843_led_calibration: failed to setup scan: %s\n",
3014
sane_strstatus (status));
3018
RIE (gl843_bulk_write_register
3019
(dev, dev->calib_reg, GENESYS_GL843_MAX_REGS));
3022
total_size = num_pixels * channels * (depth / 8) * 1; /* colors * bytes_per_color * scan lines */
3024
line = malloc (total_size);
3026
return SANE_STATUS_NO_MEM;
3029
we try to get equal bright leds here:
3033
adjust exposure times
3036
expr = (dev->sensor.regs_0x10_0x1d[0] << 8) | dev->sensor.regs_0x10_0x1d[1];
3037
expg = (dev->sensor.regs_0x10_0x1d[2] << 8) | dev->sensor.regs_0x10_0x1d[3];
3038
expb = (dev->sensor.regs_0x10_0x1d[4] << 8) | dev->sensor.regs_0x10_0x1d[5];
3045
dev->sensor.regs_0x10_0x1d[0] = (expr >> 8) & 0xff;
3046
dev->sensor.regs_0x10_0x1d[1] = expr & 0xff;
3047
dev->sensor.regs_0x10_0x1d[2] = (expg >> 8) & 0xff;
3048
dev->sensor.regs_0x10_0x1d[3] = expg & 0xff;
3049
dev->sensor.regs_0x10_0x1d[4] = (expb >> 8) & 0xff;
3050
dev->sensor.regs_0x10_0x1d[5] = expb & 0xff;
3052
for (i = 0; i < 6; i++)
3054
r = sanei_genesys_get_address (dev->calib_reg, 0x10 + i);
3055
r->value = dev->sensor.regs_0x10_0x1d[i];
3058
RIE (gl843_bulk_write_register
3059
(dev, dev->calib_reg, GENESYS_GL843_MAX_REGS));
3061
DBG (DBG_info, "gl843_led_calibration: starting first line reading\n");
3062
RIE (gl843_begin_scan (dev, dev->calib_reg, SANE_TRUE));
3063
RIE (sanei_genesys_read_data_from_scanner (dev, line, total_size));
3065
if (DBG_LEVEL >= DBG_data)
3067
snprintf (fn, 20, "led_%02d.pnm", turn);
3068
sanei_genesys_write_pnm_file (fn,
3069
line, depth, channels, num_pixels, 1);
3072
acceptable = SANE_TRUE;
3074
for (j = 0; j < channels; j++)
3077
for (i = 0; i < num_pixels; i++)
3079
if (dev->model->is_cis)
3081
line[i * 2 + j * 2 * num_pixels + 1] * 256 +
3082
line[i * 2 + j * 2 * num_pixels];
3085
line[i * 2 * channels + 2 * j + 1] * 256 +
3086
line[i * 2 * channels + 2 * j];
3090
avg[j] /= num_pixels;
3093
DBG (DBG_info, "gl843_led_calibration: average: "
3094
"%d,%d,%d\n", avg[0], avg[1], avg[2]);
3096
acceptable = SANE_TRUE;
3098
if (avg[0] < avg[1] * 0.95 || avg[1] < avg[0] * 0.95 ||
3099
avg[0] < avg[2] * 0.95 || avg[2] < avg[0] * 0.95 ||
3100
avg[1] < avg[2] * 0.95 || avg[2] < avg[1] * 0.95)
3101
acceptable = SANE_FALSE;
3105
avga = (avg[0] + avg[1] + avg[2]) / 3;
3106
expr = (expr * avga) / avg[0];
3107
expg = (expg * avga) / avg[1];
3108
expb = (expb * avga) / avg[2];
3110
keep the resulting exposures below this value.
3111
too long exposure drives the ccd into saturation.
3112
we may fix this by relying on the fact that
3113
we get a striped scan without shading, by means of
3114
statistical calculation
3116
avge = (expr + expg + expb) / 3;
3118
/* don't overflow max exposure */
3121
expr = (expr * 2000) / avge;
3122
expg = (expg * 2000) / avge;
3123
expb = (expb * 2000) / avge;
3127
expr = (expr * 50) / avge;
3128
expg = (expg * 50) / avge;
3129
expb = (expb * 50) / avge;
3134
RIE (gl843_stop_action (dev));
3139
while (!acceptable && turn < 100);
3141
DBG (DBG_info, "gl843_led_calibration: acceptable exposure: %d,%d,%d\n",
3144
/* cleanup before return */
3147
gl843_slow_back_home (dev, SANE_TRUE);
3149
DBG (DBG_proc, "gl843_led_calibration: completed\n");
3155
* average dark pixels of a 8 bits scan
3158
dark_average (uint8_t * data, unsigned int pixels, unsigned int lines,
3159
unsigned int channels, unsigned int black)
3161
unsigned int i, j, k, average, count;
3162
unsigned int avg[3];
3165
/* computes average value on black margin */
3166
for (k = 0; k < channels; k++)
3170
for (i = 0; i < lines; i++)
3172
for (j = 0; j < black; j++)
3174
val = data[i * channels * pixels + j + k];
3181
DBG (DBG_info, "dark_average: avg[%d] = %d\n", k, avg[k]);
3184
for (i = 0; i < channels; i++)
3186
average /= channels;
3187
DBG (DBG_info, "dark_average: average = %d\n", average);
3193
gl843_offset_calibration (Genesys_Device * dev)
3195
Genesys_Register_Set *r;
3196
SANE_Status status = SANE_STATUS_GOOD;
3197
uint8_t *first_line, *second_line;
3198
unsigned int channels, bpp;
3200
int pass = 0, avg, total_size;
3201
int topavg, bottomavg, resolution, lines;
3202
int top, bottom, black_pixels, pixels;
3206
/* offset calibration is always done in color mode */
3208
resolution=dev->sensor.optical_res;
3209
dev->calib_pixels = dev->sensor.sensor_pixels;
3212
pixels= (dev->sensor.sensor_pixels*resolution) / dev->sensor.optical_res;
3213
black_pixels = (dev->sensor.black_pixels * resolution) / dev->sensor.optical_res;
3214
DBG (DBG_io2, "gl843_offset_calibration: black_pixels=%d\n", black_pixels);
3216
status = gl843_init_scan_regs (dev,
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
"gl843_offset_calibration: failed to setup scan: %s\n",
3235
sane_strstatus (status));
3238
r = sanei_genesys_get_address (dev->calib_reg, REG02);
3239
r->value &= ~REG02_MTRPWR;
3241
/* allocate memory for scans */
3242
total_size = pixels * channels * lines * (bpp/8); /* colors * bytes_per_color * scan lines */
3244
first_line = malloc (total_size);
3246
return SANE_STATUS_NO_MEM;
3248
second_line = malloc (total_size);
3252
return SANE_STATUS_NO_MEM;
3256
dev->frontend.gain[0] = 0;
3257
dev->frontend.gain[1] = 0;
3258
dev->frontend.gain[2] = 0;
3260
/* scan with no move */
3262
dev->frontend.offset[0] = bottom;
3263
dev->frontend.offset[1] = bottom;
3264
dev->frontend.offset[2] = bottom;
3266
RIE (gl843_set_fe(dev, AFE_SET));
3267
RIE (gl843_bulk_write_register (dev, dev->calib_reg, GENESYS_GL843_MAX_REGS));
3268
DBG (DBG_info, "gl843_offset_calibration: starting first line reading\n");
3269
RIE (gl843_begin_scan (dev, dev->calib_reg, SANE_TRUE));
3270
RIE (sanei_genesys_read_data_from_scanner (dev, first_line, total_size));
3271
if (DBG_LEVEL >= DBG_data)
3273
snprintf(title,20,"offset%03d.pnm",bottom);
3274
sanei_genesys_write_pnm_file (title, first_line, bpp, channels, pixels, lines);
3277
bottomavg = dark_average (first_line, pixels, lines, channels, black_pixels);
3278
DBG (DBG_io2, "gl843_offset_calibration: bottom avg=%d\n", bottomavg);
3282
dev->frontend.offset[0] = top;
3283
dev->frontend.offset[1] = top;
3284
dev->frontend.offset[2] = top;
3285
RIE (gl843_set_fe(dev, AFE_SET));
3286
RIE (gl843_bulk_write_register (dev, dev->calib_reg, GENESYS_GL843_MAX_REGS));
3287
DBG (DBG_info, "gl843_offset_calibration: starting second line reading\n");
3288
RIE (gl843_begin_scan (dev, dev->calib_reg, SANE_TRUE));
3289
RIE (sanei_genesys_read_data_from_scanner (dev, second_line, total_size));
3291
topavg = dark_average (second_line, pixels, lines, channels, black_pixels);
3292
DBG (DBG_io2, "gl843_offset_calibration: top avg=%d\n", topavg);
3294
/* loop until acceptable level */
3295
while ((pass < 32) && (top - bottom > 1))
3299
/* settings for new scan */
3300
dev->frontend.offset[0] = (top + bottom) / 2;
3301
dev->frontend.offset[1] = (top + bottom) / 2;
3302
dev->frontend.offset[2] = (top + bottom) / 2;
3304
/* scan with no move */
3305
RIE(gl843_set_fe(dev, AFE_SET));
3306
RIE (gl843_bulk_write_register (dev, dev->calib_reg, GENESYS_GL843_MAX_REGS));
3307
DBG (DBG_info, "gl843_offset_calibration: starting second line reading\n");
3308
RIE (gl843_begin_scan (dev, dev->calib_reg, SANE_TRUE));
3309
RIE (sanei_genesys_read_data_from_scanner (dev, second_line, total_size));
3311
if (DBG_LEVEL >= DBG_data)
3313
sprintf (title, "offset%03d.pnm", dev->frontend.offset[1]);
3314
sanei_genesys_write_pnm_file (title, second_line, bpp, channels, pixels, lines);
3317
avg = dark_average (second_line, pixels, lines, channels, black_pixels);
3318
DBG (DBG_info, "gl843_offset_calibration: avg=%d offset=%d\n", avg,
3319
dev->frontend.offset[1]);
3321
/* compute new boundaries */
3325
top = dev->frontend.offset[1];
3330
bottom = dev->frontend.offset[1];
3333
DBG (DBG_info, "gl843_offset_calibration: offset=(%d,%d,%d)\n", dev->frontend.offset[0], dev->frontend.offset[1], dev->frontend.offset[2]);
3335
/* cleanup before return */
3340
return SANE_STATUS_GOOD;
3344
/* alternative coarse gain calibration
3345
this on uses the settings from offset_calibration and
3346
uses only one scanline
3349
with offset and coarse calibration we only want to get our input range into
3350
a reasonable shape. the fine calibration of the upper and lower bounds will
3351
be done with shading.
3354
gl843_coarse_gain_calibration (Genesys_Device * dev, int dpi)
3360
SANE_Status status = SANE_STATUS_GOOD;
3362
float gain[3],coeff;
3363
int val, code, lines;
3365
Genesys_Register_Set *r;
3368
DBG (DBG_proc, "gl843_coarse_gain_calibration: dpi = %d\n", dpi);
3370
/* coarse gain calibration is always done in color mode */
3373
if(dev->settings.xres<dev->sensor.optical_res)
3376
resolution=dev->sensor.optical_res/2;
3377
resolution=dev->sensor.optical_res;
3381
resolution=dev->sensor.optical_res;
3386
pixels = (dev->sensor.sensor_pixels * resolution) / dev->sensor.optical_res,
3388
status = gl843_init_scan_regs (dev,
3398
dev->settings.color_filter,
3399
SCAN_FLAG_DISABLE_SHADING |
3400
SCAN_FLAG_DISABLE_GAMMA |
3401
SCAN_FLAG_SINGLE_LINE |
3402
SCAN_FLAG_IGNORE_LINE_DISTANCE);
3403
r = sanei_genesys_get_address (dev->calib_reg, REG02);
3404
r->value &= ~REG02_MTRPWR;
3406
if (status != SANE_STATUS_GOOD)
3409
"gl843_coarse_calibration: failed to setup scan: %s\n",
3410
sane_strstatus (status));
3414
RIE (gl843_bulk_write_register
3415
(dev, dev->calib_reg, GENESYS_GL843_MAX_REGS));
3417
total_size = pixels * channels * (16/bpp) * lines;
3419
line = malloc (total_size);
3421
return SANE_STATUS_NO_MEM;
3423
RIE (gl843_set_fe(dev, AFE_SET));
3424
RIE (gl843_begin_scan (dev, dev->calib_reg, SANE_TRUE));
3425
RIE (sanei_genesys_read_data_from_scanner (dev, line, total_size));
3427
if (DBG_LEVEL >= DBG_data)
3428
sanei_genesys_write_pnm_file ("coarse.pnm", line, bpp, channels, pixels, lines);
3430
/* average value on each channel */
3431
for (j = 0; j < channels; j++)
3434
for (i = pixels/4; i < (pixels*3/4); i++)
3438
if (dev->model->is_cis)
3440
line[i * 2 + j * 2 * pixels + 1] * 256 +
3441
line[i * 2 + j * 2 * pixels];
3444
line[i * 2 * channels + 2 * j + 1] * 256 +
3445
line[i * 2 * channels + 2 * j];
3449
if (dev->model->is_cis)
3450
val = line[i + j * pixels];
3452
val = line[i * channels + j];
3457
max[j] = max[j] / (pixels/2);
3459
gain[j] = ((float) dev->sensor.gain_white_ref*coeff) / max[j];
3461
/* turn logical gain value into gain code, checking for overflow */
3462
code = 283 - 208 / gain[j];
3467
dev->frontend.gain[j] = code;
3470
"gl843_coarse_gain_calibration: channel %d, max=%d, gain = %f, setting:%d\n",
3471
j, max[j], gain[j], dev->frontend.gain[j]);
3474
if (dev->model->is_cis)
3476
if (dev->frontend.gain[0] > dev->frontend.gain[1])
3477
dev->frontend.gain[0] = dev->frontend.gain[1];
3478
if (dev->frontend.gain[0] > dev->frontend.gain[2])
3479
dev->frontend.gain[0] = dev->frontend.gain[2];
3480
dev->frontend.gain[2] = dev->frontend.gain[1] = dev->frontend.gain[0];
3485
dev->frontend.gain[0] = dev->frontend.gain[1];
3486
dev->frontend.gain[2] = dev->frontend.gain[1];
3491
RIE (gl843_stop_action (dev));
3493
gl843_slow_back_home (dev, SANE_TRUE);
3496
return SANE_STATUS_GOOD;
3500
* wait for lamp warmup by scanning the same line until difference
3501
* between 2 scans is below a threshold
3504
gl843_init_regs_for_warmup (Genesys_Device * dev,
3505
Genesys_Register_Set * reg,
3506
int *channels, int *total_size)
3509
SANE_Status status = SANE_STATUS_GOOD;
3510
Genesys_Register_Set *r;
3513
if (dev == NULL || reg == NULL || channels == NULL || total_size == NULL)
3514
return SANE_STATUS_INVAL;
3518
memcpy (reg, dev->reg, (GENESYS_GL843_MAX_REGS + 1) * sizeof (Genesys_Register_Set));
3519
status = gl843_init_scan_regs (dev,
3521
dev->sensor.optical_res,
3522
dev->motor.base_ydpi,
3523
dev->sensor.sensor_pixels/4,
3525
dev->sensor.sensor_pixels/2,
3529
dev->settings.color_filter,
3530
SCAN_FLAG_DISABLE_SHADING |
3531
SCAN_FLAG_DISABLE_GAMMA |
3532
SCAN_FLAG_SINGLE_LINE |
3533
SCAN_FLAG_IGNORE_LINE_DISTANCE);
3535
if (status != SANE_STATUS_GOOD)
3538
"gl843_init_regs_for_warmup: failed to setup scan: %s\n",
3539
sane_strstatus (status));
3543
num_pixels = dev->current_setup.pixels;
3545
*total_size = num_pixels * 3 * 1; /* colors * bytes_per_color * scan lines */
3547
r = sanei_genesys_get_address (reg, REG02);
3548
r->value &= ~REG02_MTRPWR;
3549
RIE (gl843_bulk_write_register (dev, reg, GENESYS_GL843_MAX_REGS));
3552
return SANE_STATUS_GOOD;
3556
gl843_is_compatible_calibration (Genesys_Device * dev,
3557
Genesys_Calibration_Cache * cache,
3560
#ifdef HAVE_SYS_TIME_H
3561
struct timeval time;
3563
int compatible = 1, resolution;
3568
if (cache == NULL || for_overwrite)
3569
return SANE_STATUS_UNSUPPORTED;
3571
status = gl843_calculate_current_setup (dev);
3572
if (status != SANE_STATUS_GOOD)
3575
"gl843_is_compatible_calibration: failed to calculate current setup: %s\n",
3576
sane_strstatus (status));
3579
resolution=gl843_compute_dpihw(dev,dev->settings.xres);
3580
dev->current_setup.scan_method = dev->settings.scan_method;
3582
DBG (DBG_proc, "gl843_is_compatible_calibration: checking\n");
3584
/* a calibration cache is compatible if color mode and x dpi match the user
3585
* requested scan. In the case of CIS scanners, dpi isn't a criteria */
3586
if (dev->model->is_cis == SANE_FALSE)
3588
compatible = (resolution == ((int) cache->used_setup.xres));
3592
compatible = (dev->current_setup.channels == cache->used_setup.channels);
3594
if (dev->current_setup.scan_method != cache->used_setup.scan_method)
3597
"gl843_is_compatible_calibration: current method=%d, used=%d\n",
3598
dev->current_setup.scan_method, cache->used_setup.scan_method);
3604
"gl843_is_compatible_calibration: completed, non compatible cache\n");
3605
return SANE_STATUS_UNSUPPORTED;
3608
/* a cache entry expires after 30 minutes for non CIS scanners */
3609
#ifdef HAVE_SYS_TIME_H
3610
gettimeofday (&time, NULL);
3611
if ((time.tv_sec - cache->last_calibration > 30 * 60)
3612
&& (dev->model->is_cis == SANE_FALSE)
3613
&& (dev->settings.scan_method == SCAN_METHOD_FLATBED))
3616
"gl843_is_compatible_calibration: expired entry, non compatible cache\n");
3617
return SANE_STATUS_UNSUPPORTED;
3622
return SANE_STATUS_GOOD;
3626
* set up GPIO/GPOE for idle state
3627
WRITE GPIO[17-21]= GPIO19
3628
WRITE GPOE[17-21]= GPOE21 GPOE20 GPOE19 GPOE18
3629
genesys_write_register(0xa8,0x3e)
3633
gl843_init_gpio (Genesys_Device * dev)
3635
SANE_Status status = SANE_STATUS_GOOD;
3640
RIE (sanei_genesys_write_register (dev, REG6E, dev->gpo.enable[0]));
3641
RIE (sanei_genesys_write_register (dev, REG6F, dev->gpo.enable[1]));
3642
RIE (sanei_genesys_write_register (dev, REG6C, dev->gpo.value[0]));
3643
RIE (sanei_genesys_write_register (dev, REG6D, dev->gpo.value[1]));
3644
if ((strcmp (dev->model->name, "hewlett-packard-scanjet-g4010") == 0)
3645
|| (strcmp (dev->model->name, "hewlett-packard-scanjet-g4050") == 0))
3653
RIE (sanei_genesys_write_register (dev, 0xa6, gpios[i].ra6));
3654
RIE (sanei_genesys_write_register (dev, 0xa7, gpios[i].ra7));
3655
RIE (sanei_genesys_write_register (dev, 0xa8, gpios[i].ra8));
3656
RIE (sanei_genesys_write_register (dev, 0xa9, gpios[i].ra9));
3664
* initialize ASIC from power on condition
3667
gl843_cold_boot (Genesys_Device * dev)
3674
RIE (sanei_genesys_write_register (dev, 0x0e, 0x01));
3675
RIE (sanei_genesys_write_register (dev, 0x0e, 0x00));
3678
RIE (sanei_genesys_read_register (dev, REG40, &val));
3679
if (val & REG40_CHKVER)
3681
RIE (sanei_genesys_read_register (dev, 0x00, &val));
3683
"gl843_cold_boot: reported version for genesys chip is 0x%02x\n",
3687
/* Set default values for registers */
3688
gl843_init_registers (dev);
3690
RIE (sanei_genesys_write_register (dev, REG6B, 0x02));
3692
/* Write initial registers */
3693
RIE (gl843_bulk_write_register (dev, dev->reg, GENESYS_GL843_MAX_REGS));
3695
/* Enable DRAM by setting a rising edge on bit 3 of reg 0x0b */
3696
val = dev->reg[reg_0x0b].value & REG0B_DRAMSEL;
3697
val = (val | REG0B_ENBDRAM);
3698
RIE (sanei_genesys_write_register (dev, REG0B, val));
3699
dev->reg[reg_0x0b].value = val;
3700
/* URB 14 control 0x40 0x0c 0x8c 0x10 len 1 wrote 0xb4 */
3701
RIE (write_end_access (dev, 0x10, 0xb4));
3703
/* set up clock once for all TODO use sensor type for these sensor related registers */
3704
if (strncmp (dev->model->name, "hewlett-packard-scanjet-g40", 27) == 0)
3707
RIE (sanei_genesys_write_register (dev, 0x74, 0x00));
3708
RIE (sanei_genesys_write_register (dev, 0x75, 0x1c));
3709
RIE (sanei_genesys_write_register (dev, 0x76, 0x7f));
3711
RIE (sanei_genesys_write_register (dev, 0x77, 0x03));
3712
RIE (sanei_genesys_write_register (dev, 0x78, 0xff));
3713
RIE (sanei_genesys_write_register (dev, 0x79, 0xff));
3718
RIE (sanei_genesys_write_register (dev, 0x74, 0x00));
3719
RIE (sanei_genesys_write_register (dev, 0x75, 0x00));
3720
RIE (sanei_genesys_write_register (dev, 0x76, 0x00));
3722
RIE (sanei_genesys_write_register (dev, 0x77, 0x00));
3723
RIE (sanei_genesys_write_register (dev, 0x78, 0xff));
3724
RIE (sanei_genesys_write_register (dev, 0x79, 0xff));
3727
RIE (sanei_genesys_write_register (dev, 0x7a, 0x03));
3728
RIE (sanei_genesys_write_register (dev, 0x7b, 0xff));
3729
RIE (sanei_genesys_write_register (dev, 0x7c, 0xff));
3732
val = (dev->reg[reg_0x0b].value & ~REG0B_CLKSET) | REG0B_48MHZ;
3733
RIE (sanei_genesys_write_register (dev, REG0B, val));
3734
dev->reg[reg_0x0b].value = val;
3736
/* prevent further writings by bulk write register */
3737
dev->reg[reg_0x0b].address = 0x00;
3739
/* set up end access */
3740
sanei_genesys_write_register (dev, REGA7, 0x04);
3741
sanei_genesys_write_register (dev, REGA9, 0x00);
3743
/* set RAM read address */
3744
RIE (sanei_genesys_write_register (dev, REG29, 0x00));
3745
RIE (sanei_genesys_write_register (dev, REG2A, 0x00));
3746
RIE (sanei_genesys_write_register (dev, REG2B, 0x00));
3749
RIE (gl843_init_gpio (dev));
3752
return SANE_STATUS_GOOD;
3756
* initialize backend and ASIC : registers, motor tables, and gamma tables
3757
* then ensure scanner's head is at home
3759
#ifndef UNIT_TESTING
3763
gl843_init (Genesys_Device * dev)
3767
SANE_Bool cold = SANE_TRUE;
3773
/* URB 16 control 0xc0 0x0c 0x8e 0x0b len 1 read 0x00 */
3775
sanei_usb_control_msg (dev->dn, REQUEST_TYPE_IN, REQUEST_REGISTER,
3776
VALUE_GET_REGISTER, 0x0b, 1, &val);
3777
if (status != SANE_STATUS_GOOD)
3780
"gl843_init: request register failed %s\n",
3781
sane_strstatus (status));
3784
DBG (DBG_io2, "gl843_init: value=0x%02x\n", val);
3785
DBG (DBG_info, "%s: device is %s\n", __FUNCTION__,
3786
(val & 0x08) ? "USB 1.0" : "USB2.0");
3789
/* URB 17 control 0x40 0x0c 0x8c 0x0f len 1 wrote 0x14 */
3795
/* URB 17 control 0x40 0x0c 0x8c 0x0f len 1 wrote 0x11 */
3799
RIE (write_end_access (dev, 0x0f, val));
3801
/* check if the device has already been initialized and powered up
3802
* we read register 6 and check PWRBIT, if reset scanner has been
3803
* freshly powered up. This bit will be set to later so that following
3804
* reads can detect power down/up cycle*/
3805
RIE (sanei_genesys_read_register (dev, 0x06, &val));
3806
if (val & REG06_PWRBIT)
3810
DBG (DBG_info, "%s: device is %s\n", __FUNCTION__, cold ? "cold" : "warm");
3812
/* don't do anything if backend is initialized and hardware hasn't been
3814
if (dev->already_initialized && !cold)
3816
DBG (DBG_info, "gl843_init: already initialized, nothing to do\n");
3817
return SANE_STATUS_GOOD;
3820
/* set up hardware and registers */
3821
RIE (gl843_cold_boot (dev));
3823
/* now hardware part is OK, set up device struct */
3824
FREE_IFNOT_NULL (dev->white_average_data);
3825
FREE_IFNOT_NULL (dev->dark_average_data);
3826
FREE_IFNOT_NULL (dev->sensor.red_gamma_table);
3827
FREE_IFNOT_NULL (dev->sensor.green_gamma_table);
3828
FREE_IFNOT_NULL (dev->sensor.blue_gamma_table);
3830
dev->settings.color_filter = 0;
3832
memcpy (dev->calib_reg, dev->reg,
3833
GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set));
3835
/* Set analog frontend */
3836
RIE (gl843_set_fe (dev, AFE_INIT));
3838
/* init gamma tables */
3840
if (dev->sensor.red_gamma_table == NULL)
3842
dev->sensor.red_gamma_table = (uint16_t *) malloc (2 * size);
3843
if (dev->sensor.red_gamma_table == NULL)
3846
"gl843_init: could not allocate memory for gamma table\n");
3847
return SANE_STATUS_NO_MEM;
3849
sanei_genesys_create_gamma_table (dev->sensor.red_gamma_table, size,
3850
65535, 65535, dev->sensor.red_gamma);
3852
if (dev->sensor.green_gamma_table == NULL)
3854
dev->sensor.green_gamma_table = (uint16_t *) malloc (2 * size);
3855
if (dev->sensor.red_gamma_table == NULL)
3858
"gl843_init: could not allocate memory for gamma table\n");
3859
return SANE_STATUS_NO_MEM;
3861
sanei_genesys_create_gamma_table (dev->sensor.green_gamma_table, size,
3863
dev->sensor.green_gamma);
3865
if (dev->sensor.blue_gamma_table == NULL)
3867
dev->sensor.blue_gamma_table = (uint16_t *) malloc (2 * size);
3868
if (dev->sensor.red_gamma_table == NULL)
3871
"gl843_init: could not allocate memory for gamma table\n");
3872
return SANE_STATUS_NO_MEM;
3874
sanei_genesys_create_gamma_table (dev->sensor.blue_gamma_table, size,
3875
65535, 65535, dev->sensor.blue_gamma);
3878
dev->oe_buffer.buffer = NULL;
3879
dev->already_initialized = SANE_TRUE;
3881
/* Move home if needed */
3882
RIE (gl843_slow_back_home (dev, SANE_TRUE));
3883
dev->scanhead_position_in_steps = 0;
3885
/* Set powersaving (default = 15 minutes) */
3886
RIE (gl843_set_powersaving (dev, 15));
3893
gl843_update_hardware_sensors (Genesys_Scanner * s)
3895
/* do what is needed to get a new set of events, but try to not lose
3898
SANE_Status status = SANE_STATUS_GOOD;
3901
RIE (sanei_genesys_read_register (s->dev, REG6D, &val));
3903
if (s->dev->model->gpo_type == GPO_KVSS080)
3905
if (s->val[OPT_SCAN_SW].b == s->last_val[OPT_SCAN_SW].b)
3906
s->val[OPT_SCAN_SW].b = (val & 0x04) == 0;
3910
if (s->val[OPT_SCAN_SW].b == s->last_val[OPT_SCAN_SW].b)
3911
s->val[OPT_SCAN_SW].b = (val & 0x01) == 0;
3912
if (s->val[OPT_FILE_SW].b == s->last_val[OPT_FILE_SW].b)
3913
s->val[OPT_FILE_SW].b = (val & 0x02) == 0;
3914
if (s->val[OPT_EMAIL_SW].b == s->last_val[OPT_EMAIL_SW].b)
3915
s->val[OPT_EMAIL_SW].b = (val & 0x04) == 0;
3916
if (s->val[OPT_COPY_SW].b == s->last_val[OPT_COPY_SW].b)
3917
s->val[OPT_COPY_SW].b = (val & 0x08) == 0;
3923
/** @brief search for a full width black or white strip.
3924
* This function searches for a black or white stripe across the scanning area.
3925
* When searching backward, the searched area must completely be of the desired
3926
* color since this area will be used for calibration which scans forward.
3927
* @param dev scanner device
3928
* @param forward SANE_TRUE if searching forward, SANE_FALSE if searching backward
3929
* @param black SANE_TRUE if searching for a black strip, SANE_FALSE for a white strip
3930
* @return SANE_STATUS_GOOD if a matching strip is found, SANE_STATUS_UNSUPPORTED if not
3933
gl843_search_strip (Genesys_Device * dev, SANE_Bool forward, SANE_Bool black)
3935
unsigned int pixels, lines, channels;
3937
Genesys_Register_Set local_reg[GENESYS_GL843_MAX_REGS];
3940
int steps, depth, dpi;
3941
unsigned int pass, count, found, x, y;
3943
Genesys_Register_Set *r;
3945
DBG (DBG_proc, "gl843_search_strip %s %s\n", black ? "black" : "white",
3946
forward ? "forward" : "reverse");
3948
gl843_set_fe (dev, AFE_SET);
3949
status = gl843_stop_action (dev);
3950
if (status != SANE_STATUS_GOOD)
3953
"gl843_search_strip: failed to stop: %s\n",
3954
sane_strstatus (status));
3958
/* set up for a gray scan at lowest dpi */
3960
for (x = 0; x < MAX_RESOLUTIONS; x++)
3962
if (dev->model->xdpi_values[x] > 0 && dev->model->xdpi_values[x] < dpi)
3963
dpi = dev->model->xdpi_values[x];
3967
lines = (10 * dpi) / MM_PER_INCH;
3968
/* shading calibation is done with dev->motor.base_ydpi */
3969
lines = (dev->model->shading_lines * dpi) / dev->motor.base_ydpi;
3971
pixels = (dev->sensor.sensor_pixels * dpi) / dev->sensor.optical_res;
3972
size = pixels * channels * lines * (depth / 8);
3973
data = malloc (size);
3976
DBG (DBG_error, "gl843_search_strip: failed to allocate memory\n");
3977
return SANE_STATUS_NO_MEM;
3979
dev->scanhead_position_in_steps = 0;
3981
memcpy (local_reg, dev->reg,
3982
GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set));
3984
status = gl843_init_scan_regs (dev,
3995
SCAN_FLAG_DISABLE_SHADING |
3996
SCAN_FLAG_DISABLE_GAMMA);
3997
if (status != SANE_STATUS_GOOD)
4000
"gl843_search_strip: failed to setup for scan: %s\n",
4001
sane_strstatus (status));
4005
/* set up for reverse or forward */
4006
r = sanei_genesys_get_address (local_reg, REG02);
4008
r->value &= ~REG02_MTRREV;
4010
r->value |= REG02_MTRREV;
4013
status = gl843_bulk_write_register (dev, local_reg, GENESYS_GL843_MAX_REGS);
4014
if (status != SANE_STATUS_GOOD)
4017
"gl843_search_strip: failed to bulk write registers: %s\n",
4018
sane_strstatus (status));
4022
status = gl843_begin_scan (dev, local_reg, SANE_TRUE);
4023
if (status != SANE_STATUS_GOOD)
4027
"gl843_search_strip: failed to begin scan: %s\n",
4028
sane_strstatus (status));
4032
/* waits for valid data */
4034
sanei_genesys_test_buffer_empty (dev, &steps);
4037
/* now we're on target, we can read data */
4038
status = sanei_genesys_read_data_from_scanner (dev, data, size);
4039
if (status != SANE_STATUS_GOOD)
4043
"gl843_search_start_position: failed to read data: %s\n",
4044
sane_strstatus (status));
4048
status = gl843_stop_action (dev);
4049
if (status != SANE_STATUS_GOOD)
4052
DBG (DBG_error, "gl843_search_strip: gl843_stop_action failed\n");
4057
if (DBG_LEVEL >= DBG_data)
4059
sprintf (title, "search_strip_%s_%s%02d.pnm",
4060
black ? "black" : "white", forward ? "fwd" : "bwd", pass);
4061
sanei_genesys_write_pnm_file (title, data, depth, channels, pixels,
4065
/* loop until strip is found or maximum pass number done */
4067
while (pass < 20 && !found)
4070
gl843_bulk_write_register (dev, local_reg, GENESYS_GL843_MAX_REGS);
4071
if (status != SANE_STATUS_GOOD)
4074
"gl843_search_strip: failed to bulk write registers: %s\n",
4075
sane_strstatus (status));
4079
/* now start scan */
4080
status = gl843_begin_scan (dev, local_reg, SANE_TRUE);
4081
if (status != SANE_STATUS_GOOD)
4085
"gl843_search_strip: failed to begin scan: %s\n",
4086
sane_strstatus (status));
4090
/* waits for valid data */
4092
sanei_genesys_test_buffer_empty (dev, &steps);
4095
/* now we're on target, we can read data */
4096
status = sanei_genesys_read_data_from_scanner (dev, data, size);
4097
if (status != SANE_STATUS_GOOD)
4101
"gl843_search_start_position: failed to read data: %s\n",
4102
sane_strstatus (status));
4106
status = gl843_stop_action (dev);
4107
if (status != SANE_STATUS_GOOD)
4110
DBG (DBG_error, "gl843_search_strip: gl843_stop_action failed\n");
4114
if (DBG_LEVEL >= DBG_data)
4116
sprintf (title, "search_strip_%s_%s%02d.pnm",
4117
black ? "black" : "white", forward ? "fwd" : "bwd", pass);
4118
sanei_genesys_write_pnm_file (title, data, depth, channels,
4122
/* search data to find black strip */
4123
/* when searching forward, we only need one line of the searched color since we
4124
* will scan forward. But when doing backward search, we need all the area of the
4128
for (y = 0; y < lines && !found; y++)
4131
/* count of white/black pixels depending on the color searched */
4132
for (x = 0; x < pixels; x++)
4134
/* when searching for black, detect white pixels */
4135
if (black && data[y * pixels + x] > 90)
4139
/* when searching for white, detect black pixels */
4140
if (!black && data[y * pixels + x] < 60)
4146
/* at end of line, if count >= 3%, line is not fully of the desired color
4147
* so we must go to next line of the buffer */
4148
/* count*100/pixels < 3 */
4149
if ((count * 100) / pixels < 3)
4153
"gl843_search_strip: strip found forward during pass %d at line %d\n",
4159
"gl843_search_strip: pixels=%d, count=%d (%d%%)\n",
4160
pixels, count, (100 * count) / pixels);
4164
else /* since calibration scans are done forward, we need the whole area
4165
to be of the required color when searching backward */
4168
for (y = 0; y < lines; y++)
4170
/* count of white/black pixels depending on the color searched */
4171
for (x = 0; x < pixels; x++)
4173
/* when searching for black, detect white pixels */
4174
if (black && data[y * pixels + x] > 90)
4178
/* when searching for white, detect black pixels */
4179
if (!black && data[y * pixels + x] < 60)
4186
/* at end of area, if count >= 3%, area is not fully of the desired color
4187
* so we must go to next buffer */
4188
if ((count * 100) / (pixels * lines) < 3)
4192
"gl843_search_strip: strip found backward during pass %d \n",
4198
"gl843_search_strip: pixels=%d, count=%d (%d%%)\n",
4199
pixels, count, (100 * count) / pixels);
4207
status = SANE_STATUS_GOOD;
4208
DBG (DBG_info, "gl843_search_strip: %s strip found\n",
4209
black ? "black" : "white");
4213
status = SANE_STATUS_UNSUPPORTED;
4214
DBG (DBG_info, "gl843_search_strip: %s strip not found\n",
4215
black ? "black" : "white");
4218
DBG (DBG_proc, "gl843_search_strip: completed\n");
4222
/** the gl843 command set */
4223
static Genesys_Command_Set gl843_cmd_set = {
4224
"gl843-generic", /* the name of this set */
4227
gl843_init_regs_for_warmup,
4228
gl843_init_regs_for_coarse_calibration,
4229
gl843_init_regs_for_shading,
4230
gl843_init_regs_for_scan,
4232
gl843_get_filter_bit,
4233
gl843_get_lineart_bit,
4234
gl843_get_bitset_bit,
4235
gl843_get_gain4_bit,
4236
gl843_get_fast_feed_bit,
4237
gl843_test_buffer_empty_bit,
4238
gl843_test_motor_flag_bit,
4240
gl843_bulk_full_size,
4243
gl843_set_powersaving,
4246
gl843_set_motor_power,
4247
gl843_set_lamp_power,
4252
gl843_send_gamma_table,
4254
gl843_search_start_position,
4256
gl843_offset_calibration,
4257
gl843_coarse_gain_calibration,
4258
gl843_led_calibration,
4260
gl843_slow_back_home,
4262
gl843_bulk_write_register,
4263
gl843_bulk_write_data,
4264
gl843_bulk_read_data,
4266
gl843_update_hardware_sensors,
4268
gl843_load_document,
4269
gl843_detect_document_end,
4270
gl843_eject_document,
4273
gl843_is_compatible_calibration,
4275
NULL /* gl843_send_shading_data */
4279
sanei_gl843_init_cmd_set (Genesys_Device * dev)
4281
dev->model->cmd_set = &gl843_cmd_set;
4282
return SANE_STATUS_GOOD;
4285
/* vim: set sw=2 cino=>2se-1sn-1s{s^-1st0(0u0 smarttab expandtab: */