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_gl124.h"
47
/****************************************************************************
49
****************************************************************************/
51
/* ------------------------------------------------------------------------ */
52
/* Read and write RAM, registers and AFE */
53
/* ------------------------------------------------------------------------ */
56
* Write to many GL124 registers at once
57
* Note: sequential call to write register, no effective
58
* bulk write implemented.
59
* @param dev device to write to
60
* @param reg pointer to an array of registers
61
* @param elems size of the array
67
gl124_bulk_write_register (Genesys_Device * dev, Genesys_Register_Set * reg,
70
SANE_Status status = SANE_STATUS_GOOD;
73
for (i = 0; i < elems && status == SANE_STATUS_GOOD; i++)
75
if (reg[i].address != 0)
78
sanei_genesys_write_register (dev, reg[i].address, reg[i].value);
82
DBG (DBG_io, "gl124_bulk_write_register: wrote %lu registers\n",
87
/** @brief read scanned data
88
* Read in 0xeff0 maximum sized blocks. This read is done in 2
89
* parts if not multple of 512. First read is rounded to a multiple of 512 bytes, last read fetches the
90
* remainder. Read addr is always 0x10000000 with the memory layout setup.
91
* @param dev device to read data from
92
* @param addr address within ASIC emory space
93
* @param data pointer where to store the read data
94
* @param len size to read
97
gl124_bulk_read_data (Genesys_Device * dev, uint8_t addr,
98
uint8_t * data, size_t len)
101
size_t size, target, read, done;
104
DBG (DBG_io, "gl124_bulk_read_data: requesting %lu bytes (unused addr=0x%02x)\n", (u_long) len,addr);
107
return SANE_STATUS_GOOD;
111
/* loop until computed data size is read */
123
/* hard coded 0x10000000 addr */
129
/* data size to transfer */
130
outdata[4] = (size & 0xff);
131
outdata[5] = ((size >> 8) & 0xff);
132
outdata[6] = ((size >> 16) & 0xff);
133
outdata[7] = ((size >> 24) & 0xff);
136
sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_BUFFER,
137
VALUE_BUFFER, 0x00, sizeof (outdata),
139
if (status != SANE_STATUS_GOOD)
141
DBG (DBG_error, "%s failed while writing command: %s\n",
142
__FUNCTION__, sane_strstatus (status));
146
/* blocks must be multiple of 512 but not last block */
154
"gl124_bulk_read_data: trying to read %lu bytes of data\n",
156
status = sanei_usb_read_bulk (dev->dn, data, &read);
157
if (status != SANE_STATUS_GOOD)
160
"gl124_bulk_read_data failed while reading bulk data: %s\n",
161
sane_strstatus (status));
166
/* read less than 512 bytes remainder */
172
"gl124_bulk_read_data: trying to read remaining %lu bytes of data\n",
174
status = sanei_usb_read_bulk (dev->dn, data+done, &read);
175
if (status != SANE_STATUS_GOOD)
178
"gl124_bulk_read_data failed while reading bulk data: %s\n",
179
sane_strstatus (status));
184
DBG (DBG_io2, "%s: read %lu bytes, %lu remaining\n", __FUNCTION__,
185
(u_long) size, (u_long) (target - size));
193
return SANE_STATUS_GOOD;
196
/****************************************************************************
198
****************************************************************************/
201
gl124_get_fast_feed_bit (Genesys_Register_Set * regs)
203
Genesys_Register_Set *r = NULL;
205
r = sanei_genesys_get_address (regs, REG02);
206
if (r && (r->value & REG02_FASTFED))
212
gl124_get_filter_bit (Genesys_Register_Set * regs)
214
Genesys_Register_Set *r = NULL;
216
r = sanei_genesys_get_address (regs, REG04);
217
if (r && (r->value & REG04_FILTER))
223
gl124_get_lineart_bit (Genesys_Register_Set * regs)
225
Genesys_Register_Set *r = NULL;
227
r = sanei_genesys_get_address (regs, REG04);
228
if (r && (r->value & REG04_LINEART))
234
gl124_get_bitset_bit (Genesys_Register_Set * regs)
236
Genesys_Register_Set *r = NULL;
238
r = sanei_genesys_get_address (regs, REG04);
239
if (r && (r->value & REG04_BITSET))
245
gl124_get_gain4_bit (Genesys_Register_Set * regs)
247
Genesys_Register_Set *r = NULL;
249
r = sanei_genesys_get_address (regs, REG06);
250
if (r && (r->value & REG06_GAIN4))
256
gl124_test_buffer_empty_bit (SANE_Byte val)
264
gl124_test_motor_flag_bit (SANE_Byte val)
271
/** @get sensor profile
272
* search for the database of motor profiles and get the best one. Each
273
* profile is at a specific dpihw. Use LiDE 110 table by default.
274
* @param sensor_type sensor id
275
* @param dpi hardware dpi for the scan
276
* @return a pointer to a Sensor_Profile struct
278
static Sensor_Profile *get_sensor_profile(int sensor_type, int dpi)
285
while(i<sizeof(sensors)/sizeof(Sensor_Profile))
288
if(sensors[i].sensor_type==sensor_type && sensors[i].dpi==dpi)
290
return &(sensors[i]);
294
if(sensors[i].sensor_type==sensor_type)
302
if(sensors[i].dpi>=dpi
303
&& sensors[i].dpi<sensors[idx].dpi)
312
/* default fallback */
315
DBG (DBG_warn,"%s: using default sensor profile\n",__FUNCTION__);
319
return &(sensors[idx]);
322
/** @get motor profile
323
* search for the database of motor profiles and get the best one. Each
324
* profile is at full step and at a reference exposure. Use LiDE 110 table
326
* @param motor_type motor id
327
* @param exposure exposure time
328
* @return a pointer to a Motor_Profile struct
330
static Motor_Profile *get_motor_profile(int motor_type, int exposure)
337
while(i<sizeof(motors)/sizeof(Motor_Profile))
340
if(motors[i].motor_type==motor_type && motors[i].exposure==exposure)
346
if(motors[i].motor_type==motor_type)
354
if(motors[i].exposure>=exposure
355
&& motors[i].exposure<motors[idx].exposure)
364
/* default fallback */
367
DBG (DBG_warn,"%s: using default motor profile\n",__FUNCTION__);
371
return &(motors[idx]);
375
/** @brief returns the lowest possible ydpi for the device
376
* Parses device entry to find lowest motor dpi.
377
* @dev device description
378
* @return lowest motor resolution
381
static int gl124_get_lowest_ydpi(Genesys_Device *dev)
386
while(dev->model->ydpi_values[i]!=0)
388
if(dev->model->ydpi_values[i]<min)
390
min=dev->model->ydpi_values[i];
398
/** @brief generate slope table
399
* Generate the slope table to use for the scan using a reference slope
401
* @param slope pointer to the slope table to fill
402
* @param steps pointer to return used step number
403
* @param dpi desired motor resolution
404
* @param exposure exposure used
405
* @param base_dpi base resolution of the motor
406
* @param step_type step type used for scan
407
* @param factor shrink factor for the slope
408
* @param motor_type motor id
410
static int gl124_slope_table(uint16_t *slope,
420
uint16_t target,current;
421
Motor_Profile *profile;
424
target=((exposure * dpi) / base_dpi)>>step_type;
426
/* fill result with target speed */
427
for(i=0;i<SLOPE_TABLE_SIZE;i++)
430
profile=get_motor_profile(motor_type,exposure);
432
/* use profile to build table */
436
/* first step is used unmodified */
437
current=profile->table[0];
439
/* loop on profile copying and apply step type */
440
while(i<SLOPE_TABLE_SIZE && current>=target)
445
current=profile->table[i*factor]>>step_type;
447
if(i<3 && DBG_LEVEL >= DBG_warn)
449
DBG (DBG_warn,"%s: short slope table, failed to reach %d\n",__FUNCTION__,target);
452
/* ensure minimal slope size */
459
/* return used steps and acceleration sum */
464
/* returns the max register bulk size */
466
gl124_bulk_full_size (void)
468
return GENESYS_GL124_MAX_REGS;
471
/** @brief set all registers to default values .
472
* This function is called only once at the beginning and
473
* fills register startup values for registers reused across scans.
474
* Those that are rarely modified or not modified are written
476
* @param dev device structure holding register set to initialize
479
gl124_init_registers (Genesys_Device * dev)
483
memset (dev->reg, 0, GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set));
485
/* default to LiDE 110 */
486
SETREG (0x01,0xa2); /* + REG01_SHDAREA */
489
SETREG (0x03,0x50 & ~REG03_AVEENB);
492
SETREG (0x06,0x50 | REG06_GAIN4); /* causes calibration trouble */
494
/* SETREG (0x07,0x00); */
495
/* SETREG (0x08,0x10); */
676
SETREG (0xd2,0x34); */
709
SETREG (0xf7,0xfd);*/
711
SETREG (0xf8,0x01); /* other value is 0x05 */
718
/* fine tune upon device description */
719
dev->reg[reg_0x05].value &= ~REG05_DPIHW;
720
switch (dev->sensor.optical_res)
723
dev->reg[reg_0x05].value |= REG05_DPIHW_600;
726
dev->reg[reg_0x05].value |= REG05_DPIHW_1200;
729
dev->reg[reg_0x05].value |= REG05_DPIHW_2400;
732
dev->reg[reg_0x05].value |= REG05_DPIHW_4800;
736
/* initalize calibration reg */
737
memcpy (dev->calib_reg, dev->reg,
738
GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set));
743
/**@brief send slope table for motor movement
744
* Send slope_table in machine byte order
745
* @param dev device to send slope table
746
* @param table_nr index of the slope table in ASIC memory
747
* Must be in the [0-4] range.
748
* @param slope_table pointer to 16 bit values array of the slope table
749
* @param steps number of elemnts in the slope table
752
gl124_send_slope_table (Genesys_Device * dev, int table_nr,
753
uint16_t * slope_table, int steps)
760
DBG (DBG_proc, "%s (table_nr = %d, steps = %d)\n", __FUNCTION__,
764
if(table_nr<0 || table_nr>4)
766
DBG (DBG_error, "%s: invalid table number %d!\n", __FUNCTION__, table_nr);
767
return SANE_STATUS_INVAL;
770
table = (uint8_t *) malloc (steps * 2);
771
for (i = 0; i < steps; i++)
773
table[i * 2] = slope_table[i] & 0xff;
774
table[i * 2 + 1] = slope_table[i] >> 8;
777
if (DBG_LEVEL >= DBG_io)
779
sprintf (msg, "write slope %d (%d)=", table_nr, steps);
780
for (i = 0; i < steps; i++)
782
sprintf (msg, "%s,%d", msg, slope_table[i]);
784
DBG (DBG_io, "%s: %s\n", __FUNCTION__, msg);
787
/* slope table addresses are fixed */
789
sanei_genesys_write_ahb (dev->dn, 0x10000000 + 0x4000 * table_nr, steps * 2, table);
790
if (status != SANE_STATUS_GOOD)
793
"%s: write to AHB failed writing slope table %d (%s)\n",
794
__FUNCTION__, table_nr, sane_strstatus (status));
803
* Set register values of 'special' type frontend
806
gl124_set_ti_fe (Genesys_Device * dev, uint8_t set)
808
SANE_Status status = SANE_STATUS_GOOD;
815
DBG (DBG_proc, "%s: setting DAC %u\n", __FUNCTION__,
816
dev->model->dac_type);
818
/* sets to default values */
819
sanei_genesys_init_fe (dev);
822
/* start writing to DAC */
823
status = sanei_genesys_fe_write_data (dev, 0x00, 0x80);
824
if (status != SANE_STATUS_GOOD)
826
DBG (DBG_error, "%s: failed to write reg0: %s\n", __FUNCTION__,
827
sane_strstatus (status));
831
/* write values to analog frontend */
832
for (i = 1; i < 4; i++)
834
val = dev->frontend.reg[i];
835
status = sanei_genesys_fe_write_data (dev, i, val);
836
if (status != SANE_STATUS_GOOD)
839
"%s: failed to write reg %d: %s\n", __FUNCTION__, i,
840
sane_strstatus (status));
845
status = sanei_genesys_fe_write_data (dev, 0x04, 0x00);
846
if (status != SANE_STATUS_GOOD)
848
DBG (DBG_error, "%s: failed to write reg4: %s\n", __FUNCTION__,
849
sane_strstatus (status));
853
/* these are not really sign */
854
for (i = 0; i < 3; i++)
856
val = dev->frontend.sign[i];
857
status = sanei_genesys_fe_write_data (dev, 0x05 + i, val);
858
if (status != SANE_STATUS_GOOD)
861
"%s: failed to write reg %d: %s\n", __FUNCTION__, i+5,
862
sane_strstatus (status));
867
/* close writing to DAC */
868
status = sanei_genesys_fe_write_data (dev, 0x00, 0x11);
869
if (status != SANE_STATUS_GOOD)
871
DBG (DBG_error, "%s: failed to write reg0: %s\n", __FUNCTION__,
872
sane_strstatus (status));
882
/* Set values of analog frontend */
884
gl124_set_fe (Genesys_Device * dev, uint8_t set)
889
DBG (DBG_proc, "gl124_set_fe (%s)\n",
890
set == AFE_INIT ? "init" : set == AFE_SET ? "set" : set ==
891
AFE_POWER_SAVE ? "powersave" : "huh?");
895
DBG (DBG_proc, "gl124_set_fe(): setting DAC %u\n",
896
dev->model->dac_type);
897
sanei_genesys_init_fe (dev);
900
RIE (sanei_genesys_read_register (dev, REG0A, &val));
902
/* route to correct analog FE */
903
switch ((val & REG0A_SIFSEL)>>REG0AS_SIFSEL)
906
status=gl124_set_ti_fe (dev, set);
912
DBG (DBG_error, "%s: unsupported anlog FE 0x%02x\n",__FUNCTION__,val);
913
status=SANE_STATUS_INVAL;
922
/**@brief compute hardware sensor dpi to use
923
* compute the sensor hardware dpi based on target resolution.
924
* A lower dpihw enable faster scans.
925
* @param dev device used for the scan
926
* @param xres x resolution of the scan
927
* @return the hardware dpi to use
929
static int gl124_compute_dpihw(Genesys_Device *dev, int xres)
931
switch(dev->model->ccd_type)
934
if(xres<=dev->sensor.optical_res/4)
936
return dev->sensor.optical_res/4;
938
if(xres<=dev->sensor.optical_res/2)
940
return dev->sensor.optical_res/2;
942
return dev->sensor.optical_res;
946
/**@brief compute exposure to use
947
* compute the sensor exposure based on target resolution
949
static int gl124_compute_exposure(Genesys_Device *dev, int xres)
951
Sensor_Profile *sensor;
953
sensor=get_sensor_profile(dev->model->ccd_type, xres);
954
return sensor->exposure;
957
/**@brief compute motor step type to use
958
* compute the step type (full, half, quarter, ...) to use based
959
* on target resolution
960
* @param dev device description
961
* @param exposure sensor exposure
962
* @return 0 for full step
967
static int gl124_compute_step_type(Genesys_Device *dev, int exposure)
969
Motor_Profile *profile;
971
profile=get_motor_profile(dev->model->motor_type,exposure);
972
return profile->step_type;
975
#define MOTOR_FLAG_AUTO_GO_HOME 1
976
#define MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE 2
977
#define MOTOR_FLAG_FEED 4
981
gl124_init_motor_regs_scan (Genesys_Device * dev,
982
Genesys_Register_Set * reg,
983
unsigned int scan_exposure_time,
986
unsigned int scan_lines,
987
unsigned int scan_dummy,
988
unsigned int feed_steps,
994
unsigned int fast_time;
995
unsigned int slow_time;
996
unsigned int lincnt, fast_dpi;
997
uint16_t scan_table[SLOPE_TABLE_SIZE];
998
uint16_t fast_table[SLOPE_TABLE_SIZE];
999
int scan_steps,fast_steps,factor;
1000
unsigned int feedl,dist;
1001
Genesys_Register_Set *r;
1006
DBG (DBG_info, "gl124_init_motor_regs_scan : scan_exposure_time=%d, "
1007
"scan_yres=%g, scan_step_type=%d, scan_lines=%d, scan_dummy=%d, "
1008
"feed_steps=%d, scan_mode=%d, flags=%x\n",
1012
scan_lines, scan_dummy, feed_steps, scan_mode, flags);
1014
/* we never use fast fed since we do manual feed for the scans */
1018
if(dev->line_interp>0)
1020
lincnt=scan_lines*dev->line_interp;
1028
if ((scan_mode == SCAN_MODE_COLOR) && (yres<900))
1032
if ((scan_mode != SCAN_MODE_COLOR) && (yres<300))
1037
sanei_genesys_set_triple(reg,REG_LINCNT,lincnt);
1038
DBG (DBG_io, "%s: lincnt=%d\n", __FUNCTION__, lincnt);
1040
/* compute register 02 value */
1041
r = sanei_genesys_get_address (reg, REG02);
1042
r->value = REG02_NOTHOME;
1043
r->value |= REG02_MTRPWR;
1046
r->value |= REG02_FASTFED;
1048
r->value &= ~REG02_FASTFED;
1050
if (flags & MOTOR_FLAG_AUTO_GO_HOME)
1051
r->value |= REG02_AGOHOME;
1053
if ((flags & MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE)
1054
||(yres>=dev->sensor.optical_res))
1055
r->value |= REG02_ACDCDIS;
1058
sanei_genesys_set_double(reg,REG_SCANFED,4);
1060
/* scan and backtracking slope table */
1061
slow_time=gl124_slope_table(scan_table,
1065
dev->motor.base_ydpi,
1068
dev->model->motor_type);
1069
RIE(gl124_send_slope_table (dev, SCAN_TABLE, scan_table, scan_steps));
1070
RIE(gl124_send_slope_table (dev, BACKTRACK_TABLE, scan_table, scan_steps));
1073
sanei_genesys_set_double(reg,REG_STEPNO,scan_steps);
1077
if (scan_mode != SCAN_MODE_COLOR)
1081
fast_time=gl124_slope_table(fast_table,
1085
dev->motor.base_ydpi,
1088
dev->model->motor_type);
1089
RIE(gl124_send_slope_table (dev, STOP_TABLE, fast_table, fast_steps));
1090
RIE(gl124_send_slope_table (dev, FAST_TABLE, fast_table, fast_steps));
1093
sanei_genesys_set_double(reg,REG_FASTNO,fast_steps);
1096
sanei_genesys_set_double(reg,REG_FSHDEC,fast_steps);
1099
sanei_genesys_set_double(reg,REG_FMOVNO,fast_steps);
1101
/* substract acceleration distance from feedl */
1103
feedl<<=scan_step_type;
1108
dist += fast_steps*2;
1110
DBG (DBG_io2, "%s: acceleration distance=%d\n", __FUNCTION__, dist);
1112
/* get sure we don't use insane value */
1118
sanei_genesys_set_triple(reg,REG_FEEDL,feedl);
1119
DBG (DBG_io, "%s: feedl=%d\n", __FUNCTION__, feedl);
1121
/* doesn't seem to matter that much */
1122
sanei_genesys_calculate_zmode2 (use_fast_fed,
1131
sanei_genesys_set_triple(reg,REG_Z1MOD,z1);
1132
DBG (DBG_info, "gl124_init_motor_regs_scan: z1 = %d\n", z1);
1134
sanei_genesys_set_triple(reg,REG_Z2MOD,z2);
1135
DBG (DBG_info, "gl124_init_motor_regs_scan: z2 = %d\n", z2);
1138
r = sanei_genesys_get_address (reg, REG1D);
1139
r->value = (r->value & ~REG1D_LINESEL) | scan_dummy;
1141
r = sanei_genesys_get_address (reg, REGA0);
1142
r->value = (scan_step_type << REGA0S_STEPSEL) | (scan_step_type << REGA0S_FSTPSEL);
1145
sanei_genesys_set_double(reg,REG_FMOVDEC,fast_steps);
1148
return SANE_STATUS_GOOD;
1152
/** @brief copy sensor specific settings
1153
* Set up register set for the given sensor resolution.
1154
* @param dev device to set up
1155
* @param regs register set to modify
1156
* @param dpi resolution of the sensor during scan
1159
gl124_setup_sensor (Genesys_Device * dev, Genesys_Register_Set * regs, int dpi)
1161
Genesys_Register_Set *r;
1163
Sensor_Profile *sensor;
1169
/* we start at 6, 0-5 is a 16 bits cache for exposure */
1170
for (i = 0x06; i < 0x0e; i++)
1172
r = sanei_genesys_get_address (regs, 0x10 + i);
1174
r->value = dev->sensor.regs_0x10_0x1d[i];
1177
for (i = 0; i < 11; i++)
1179
r = sanei_genesys_get_address (regs, 0x52 + i);
1181
r->value = dev->sensor.regs_0x52_0x5e[i];
1184
/* set EXPDUMMY and CKxMAP */
1185
dpihw=gl124_compute_dpihw(dev,dpi);
1186
sensor=get_sensor_profile(dev->model->ccd_type, dpihw);
1188
r = sanei_genesys_get_address (regs, 0x18);
1191
r->value = sensor->reg18;
1193
r = sanei_genesys_get_address (regs, 0x20);
1196
r->value = sensor->reg20;
1198
r = sanei_genesys_get_address (regs, 0x61);
1201
r->value = sensor->reg61;
1203
r = sanei_genesys_get_address (regs, 0x98);
1206
r->value = sensor->reg98;
1209
sanei_genesys_set_triple(regs,REG_SEGCNT,sensor->segcnt);
1210
sanei_genesys_set_double(regs,REG_TG0CNT,sensor->tg0cnt);
1211
sanei_genesys_set_double(regs,REG_EXPDMY,sensor->expdummy);
1213
/* if no calibration has been done, set default values for exposures */
1214
exp=dev->sensor.regs_0x10_0x1d[0]*256+dev->sensor.regs_0x10_0x1d[1];
1219
sanei_genesys_set_triple(regs,REG_EXPR,exp);
1221
exp=dev->sensor.regs_0x10_0x1d[2]*256+dev->sensor.regs_0x10_0x1d[3];
1226
sanei_genesys_set_triple(regs,REG_EXPG,exp);
1228
exp=dev->sensor.regs_0x10_0x1d[4]*256+dev->sensor.regs_0x10_0x1d[5];
1233
sanei_genesys_set_triple(regs,REG_EXPB,exp);
1235
sanei_genesys_set_triple(regs,REG_CK1MAP,sensor->ck1map);
1236
sanei_genesys_set_triple(regs,REG_CK3MAP,sensor->ck3map);
1237
sanei_genesys_set_triple(regs,REG_CK4MAP,sensor->ck4map);
1244
#define OPTICAL_FLAG_DISABLE_GAMMA 1
1245
#define OPTICAL_FLAG_DISABLE_SHADING 2
1246
#define OPTICAL_FLAG_DISABLE_LAMP 4
1247
#define OPTICAL_FLAG_ENABLE_LEDADD 8
1248
#define OPTICAL_FLAG_DISABLE_DOUBLE 16
1250
/** @brief setup optical related registers
1251
* start and pixels are expressed in optical sensor resolution coordinate
1252
* space. To handle odd/even case we double the resolution and
1253
* use only first logical half the sensor which maps to effective CCD.
1254
* @param start logical start pixel coordinate
1255
* @param pixels logical number of pixels to use
1256
* @return SANE_STATUS_GOOD if OK
1259
gl124_init_optical_regs_scan (Genesys_Device * dev,
1260
Genesys_Register_Set * reg,
1261
unsigned int exposure_time,
1264
unsigned int pixels,
1267
SANE_Bool half_ccd, int color_filter, int flags)
1269
unsigned int words_per_line, segcnt;
1270
unsigned int startx, endx, used_pixels, segnb;
1271
unsigned int dpiset, cksel, dpihw, factor;
1273
Genesys_Register_Set *r;
1276
DBG (DBG_proc, "%s : exposure_time=%d, "
1277
"used_res=%d, start=%d, pixels=%d, channels=%d, depth=%d, "
1278
"half_ccd=%d, flags=%x\n", __FUNCTION__, exposure_time,
1279
used_res, start, pixels, channels, depth, half_ccd, flags);
1281
/* resolution is divided according to CKSEL */
1282
r = sanei_genesys_get_address (reg, REG18);
1283
cksel= (r->value & REG18_CKSEL)+1;
1284
DBG (DBG_io2, "%s: cksel=%d\n", __FUNCTION__, cksel);
1286
/* to manage high resolution device while keeping good
1287
* low resolution scanning speed, we make hardware dpi vary */
1288
dpihw=gl124_compute_dpihw(dev, used_res * cksel);
1289
factor=dev->sensor.optical_res/dpihw;
1290
DBG (DBG_io2, "%s: dpihw=%d (factor=%d)\n", __FUNCTION__, dpihw, factor);
1292
/* sensor parameters */
1293
gl124_setup_sensor (dev, reg, dpihw);
1294
dpiset = used_res * cksel;
1296
/* start and end coordinate in optical dpi coordinates */
1297
/* startx = start/cksel + dev->sensor.dummy_pixel; XXX STEF XXX */
1298
startx = start/cksel;
1299
used_pixels=pixels/cksel;
1300
endx = startx + used_pixels;
1302
/* pixel coordinate factor correction when used dpihw is not maximal one */
1305
used_pixels=endx-startx;
1307
status = gl124_set_fe (dev, AFE_SET);
1308
if (status != SANE_STATUS_GOOD)
1310
DBG (DBG_error, "%s: failed to set frontend: %s\n", __FUNCTION__,
1311
sane_strstatus (status));
1315
/* enable shading */
1316
r = sanei_genesys_get_address (reg, REG01);
1317
r->value &= ~REG01_SCAN;
1318
if ((flags & OPTICAL_FLAG_DISABLE_SHADING) ||
1319
(dev->model->flags & GENESYS_FLAG_NO_CALIBRATION))
1321
r->value &= ~REG01_DVDSET;
1325
r->value |= REG01_DVDSET;
1327
r->value &= ~REG01_SCAN;
1329
r = sanei_genesys_get_address (reg, REG03);
1330
r->value &= ~REG03_AVEENB;
1332
if (flags & OPTICAL_FLAG_DISABLE_LAMP)
1333
r->value &= ~REG03_LAMPPWR;
1335
r->value |= REG03_LAMPPWR;
1338
RIE (sanei_genesys_write_hregister (dev, REG114, dev->settings.threshold));
1339
RIE (sanei_genesys_write_hregister (dev, REG115, dev->settings.threshold));
1341
/* monochrome / color scan */
1342
r = sanei_genesys_get_address (reg, REG04);
1346
r->value &= ~REG04_BITSET;
1347
r->value |= REG04_LINEART;
1350
r->value &= ~(REG04_LINEART | REG04_BITSET);
1353
r->value &= ~REG04_LINEART;
1354
r->value |= REG04_BITSET;
1358
r->value &= ~REG04_FILTER;
1361
switch (color_filter)
1364
r->value |= 0x10; /* red filter */
1367
r->value |= 0x30; /* blue filter */
1370
r->value |= 0x20; /* green filter */
1376
r = sanei_genesys_get_address (reg, REG05);
1379
r->value &= ~REG05_DPIHW;
1383
r->value |= REG05_DPIHW_600;
1386
r->value |= REG05_DPIHW_1200;
1389
r->value |= REG05_DPIHW_2400;
1392
r->value |= REG05_DPIHW_4800;
1396
/* enable gamma tables */
1397
if (flags & OPTICAL_FLAG_DISABLE_GAMMA)
1398
r->value &= ~REG05_GMMENB;
1400
r->value |= REG05_GMMENB;
1402
sanei_genesys_set_double(reg,REG_DPISET,dpiset);
1403
DBG (DBG_io2, "%s: dpiset used=%d\n", __FUNCTION__, dpiset);
1405
/* segment number */
1406
r = sanei_genesys_get_address (reg, 0x98);
1407
segnb = r->value & 0x0f;
1409
sanei_genesys_set_triple(reg,REG_STRPIXEL,startx/segnb);
1410
sanei_genesys_get_triple(reg,REG_SEGCNT,&segcnt);
1411
if(endx/segnb==segcnt)
1415
sanei_genesys_set_triple(reg,REG_ENDPIXEL,endx/segnb);
1417
/* words(16bit) before gamma, conversion to 8 bit or lineart */
1418
words_per_line = (used_pixels * dpiset) / dpihw;
1422
words_per_line = (words_per_line >> 3) + ((words_per_line & 7) ? 1 : 0);
1426
words_per_line *= bytes;
1429
dev->bpl = words_per_line;
1431
dev->len = dev->bpl/segnb;
1432
dev->dist = dev->bpl/segnb;
1435
dev->line_count = 0;
1438
dev->line_interp = 0;
1442
/* line interpolation, we are scanning at higher
1443
* motor dpi then discard lines to match taget
1444
* resolution, so lincnt has to be updated
1446
dev->line_interp = 300/dpiset;
1449
DBG (DBG_io2, "%s: used_pixels=%d\n", __FUNCTION__, used_pixels);
1450
DBG (DBG_io2, "%s: pixels =%d\n", __FUNCTION__, pixels);
1451
DBG (DBG_io2, "%s: depth =%d\n", __FUNCTION__, depth);
1452
DBG (DBG_io2, "%s: dev->bpl =%lu\n", __FUNCTION__, (unsigned long)dev->bpl);
1453
DBG (DBG_io2, "%s: dev->len =%lu\n", __FUNCTION__, (unsigned long)dev->len);
1454
DBG (DBG_io2, "%s: dev->dist =%lu\n", __FUNCTION__, (unsigned long)dev->dist);
1455
DBG (DBG_io2, "%s: dev->skip =%lu\n", __FUNCTION__, (unsigned long)dev->skip);
1457
words_per_line *= channels;
1458
dev->wpl = words_per_line;
1460
/* allocate buffer for odd/even pixles handling */
1461
if(dev->oe_buffer.buffer!=NULL)
1463
sanei_genesys_buffer_free (&(dev->oe_buffer));
1465
RIE (sanei_genesys_buffer_alloc (&(dev->oe_buffer), dev->wpl));
1467
/* MAXWD is expressed in 2 words unit */
1468
sanei_genesys_set_triple(reg,REG_MAXWD,(words_per_line));
1469
DBG (DBG_io2, "%s: words_per_line used=%d\n", __FUNCTION__, words_per_line);
1471
sanei_genesys_set_triple(reg,REG_LPERIOD,exposure_time);
1472
DBG (DBG_io2, "%s: exposure_time used=%d\n", __FUNCTION__, exposure_time);
1474
sanei_genesys_set_double(reg,REG_DUMMY,dev->sensor.dummy_pixel);
1477
return SANE_STATUS_GOOD;
1480
/* set up registers for an actual scan
1482
* this function sets up the scanner to scan in normal or single line mode
1484
#ifndef UNIT_TESTING
1488
gl124_init_scan_regs (Genesys_Device * dev,
1489
Genesys_Register_Set * reg,
1490
float xres, /*dpi */
1491
float yres, /*dpi */
1492
float startx, /*optical_res, from dummy_pixel+1 */
1493
float starty, /*base_ydpi, from home! */
1497
unsigned int channels,
1498
int color_filter, unsigned int flags)
1501
int start, used_pixels;
1504
unsigned int lincnt;
1505
unsigned int oflags, mflags; /**> optical and motor flags */
1511
int scan_step_type = 1;
1513
size_t requested_buffer_size, read_buffer_size;
1515
SANE_Bool half_ccd; /* false: full CCD res is used, true, half max CCD res is used */
1520
"gl124_init_scan_regs settings:\n"
1521
"Resolution : %gDPI/%gDPI\n"
1524
"Startpos : %g/%g\n"
1525
"Depth/Channels: %u/%u\n"
1527
xres, yres, lines, pixels, startx, starty, depth, channels, flags);
1529
/* we have 2 domains for ccd: xres below or above half ccd max dpi */
1530
if (dev->sensor.optical_res < 2 * xres ||
1531
!(dev->model->flags & GENESYS_FLAG_HALF_CCD_MODE))
1533
half_ccd = SANE_FALSE;
1537
half_ccd = SANE_TRUE;
1541
optical_res = dev->sensor.optical_res;
1546
if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE))
1547
stagger = (4 * yres) / dev->motor.base_ydpi;
1550
DBG (DBG_info, "gl124_init_scan_regs : stagger=%d lines\n", stagger);
1552
/** @brief compute used resolution
1553
* the sensor if mapped only to odd pixels. So we double the optical
1554
* resolution and use first half
1556
if (flags & SCAN_FLAG_USE_OPTICAL_RES)
1558
used_res = optical_res;
1562
/* resolution is choosen from a fixed list and can be used directly */
1563
if(xres>optical_res)
1564
used_res=optical_res;
1569
/* compute scan parameters values */
1570
/* pixels are allways given at full optical resolution */
1571
/* use detected left margin and fixed value */
1573
/* add x coordinates */
1579
/* compute correct pixels number */
1581
used_pixels = (pixels * optical_res) / xres;
1582
DBG (DBG_info, "%s: used_pixels=%d\n", __FUNCTION__, used_pixels);
1584
/* round up pixels number if needed */
1585
if (used_pixels * xres < pixels * optical_res)
1588
/* we want even number of pixels here */
1595
/* cis color scan is effectively a gray scan with 3 gray lines per color line and a FILTER of 0 */
1596
if (dev->model->is_cis)
1597
slope_dpi = yres * channels;
1601
/* scan_step_type */
1602
if(flags & SCAN_FLAG_FEEDING)
1605
exposure_time=MOVE_EXPOSURE;
1609
exposure_time = gl124_compute_exposure (dev, used_res);
1610
scan_step_type = gl124_compute_step_type(dev, exposure_time);
1613
DBG (DBG_info, "gl124_init_scan_regs : exposure_time=%d pixels\n",
1615
DBG (DBG_info, "gl124_init_scan_regs : scan_step_type=%d\n",
1618
/*** optical parameters ***/
1619
/* in case of dynamic lineart, we use an internal 8 bit gray scan
1620
* to generate 1 lineart data */
1621
if ((flags & SCAN_FLAG_DYNAMIC_LINEART)
1622
&& (dev->settings.scan_mode == SCAN_MODE_LINEART))
1627
/* we enable true gray for cis scanners only, and just when doing
1628
* scan since color calibration is OK for this mode
1631
if (flags & SCAN_FLAG_DISABLE_SHADING)
1632
oflags |= OPTICAL_FLAG_DISABLE_SHADING;
1633
if (flags & SCAN_FLAG_DISABLE_GAMMA)
1634
oflags |= OPTICAL_FLAG_DISABLE_GAMMA;
1635
if (flags & SCAN_FLAG_DISABLE_LAMP)
1636
oflags |= OPTICAL_FLAG_DISABLE_LAMP;
1637
if (flags & SCAN_FLAG_CALIBRATION)
1638
oflags |= OPTICAL_FLAG_DISABLE_DOUBLE;
1640
/* now _LOGICAL_ optical values used are known, setup registers */
1641
status = gl124_init_optical_regs_scan (dev,
1649
half_ccd, color_filter, oflags);
1651
if (status != SANE_STATUS_GOOD)
1654
/*** motor parameters ***/
1657
/* scanned area must be enlarged by max color shift needed */
1658
/* all values are assumed >= 0 */
1659
if (channels > 1 && !(flags & SCAN_FLAG_IGNORE_LINE_DISTANCE))
1661
max_shift = dev->model->ld_shift_r;
1662
if (dev->model->ld_shift_b > max_shift)
1663
max_shift = dev->model->ld_shift_b;
1664
if (dev->model->ld_shift_g > max_shift)
1665
max_shift = dev->model->ld_shift_g;
1666
max_shift = (max_shift * yres) / dev->motor.base_ydpi;
1674
lincnt = lines + max_shift + stagger;
1676
/* add tl_y to base movement */
1678
DBG (DBG_info, "gl124_init_scan_regs: move=%d steps\n", move);
1681
if(flags & SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE)
1682
mflags|=MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE;
1683
if(flags & SCAN_FLAG_FEEDING)
1684
mflags|=MOTOR_FLAG_FEED;
1686
status = gl124_init_motor_regs_scan (dev,
1691
dev->model->is_cis ? lincnt * channels : lincnt,
1694
dev->settings.scan_mode,
1696
if (status != SANE_STATUS_GOOD)
1699
/*** prepares data reordering ***/
1701
/* words_per_line */
1702
bytes_per_line = (used_pixels * used_res) / optical_res;
1703
bytes_per_line = (bytes_per_line * channels * depth) / 8;
1705
/* since we don't have sheetfed scanners to handle,
1706
* use huge read buffer */
1707
/* TODO find the best size according to settings */
1708
requested_buffer_size = 16 * bytes_per_line;
1711
2 * requested_buffer_size +
1712
((max_shift + stagger) * used_pixels * channels * depth) / 8;
1714
RIE (sanei_genesys_buffer_free (&(dev->read_buffer)));
1715
RIE (sanei_genesys_buffer_alloc (&(dev->read_buffer), read_buffer_size));
1717
RIE (sanei_genesys_buffer_free (&(dev->lines_buffer)));
1718
RIE (sanei_genesys_buffer_alloc (&(dev->lines_buffer), read_buffer_size));
1720
RIE (sanei_genesys_buffer_free (&(dev->shrink_buffer)));
1721
RIE (sanei_genesys_buffer_alloc (&(dev->shrink_buffer),
1722
requested_buffer_size));
1724
RIE (sanei_genesys_buffer_free (&(dev->out_buffer)));
1725
RIE (sanei_genesys_buffer_alloc (&(dev->out_buffer),
1726
(8 * dev->settings.pixels * channels *
1730
dev->read_bytes_left = bytes_per_line * lincnt;
1733
"gl124_init_scan_regs: physical bytes to read = %lu\n",
1734
(u_long) dev->read_bytes_left);
1735
dev->read_active = SANE_TRUE;
1738
dev->current_setup.pixels = (used_pixels * used_res) / optical_res;
1739
DBG (DBG_info, "%s: current_setup.pixels=%d\n", __FUNCTION__, dev->current_setup.pixels);
1740
dev->current_setup.lines = lincnt;
1741
dev->current_setup.depth = depth;
1742
dev->current_setup.channels = channels;
1743
dev->current_setup.exposure_time = exposure_time;
1744
dev->current_setup.xres = used_res;
1745
dev->current_setup.yres = yres;
1746
dev->current_setup.half_ccd = half_ccd;
1747
dev->current_setup.stagger = stagger;
1748
dev->current_setup.max_shift = max_shift + stagger;
1750
dev->total_bytes_read = 0;
1751
if (depth == 1 || dev->settings.scan_mode == SCAN_MODE_LINEART)
1752
dev->total_bytes_to_read =
1753
((dev->settings.pixels * dev->settings.lines) / 8 +
1754
(((dev->settings.pixels * dev->settings.lines) % 8) ? 1 : 0)) *
1757
dev->total_bytes_to_read =
1758
dev->settings.pixels * dev->settings.lines * channels * (depth / 8);
1760
DBG (DBG_info, "gl124_init_scan_regs: total bytes to send = %lu\n",
1761
(u_long) dev->total_bytes_to_read);
1764
return SANE_STATUS_GOOD;
1768
gl124_calculate_current_setup (Genesys_Device * dev)
1774
float xres; /*dpi */
1775
float yres; /*dpi */
1776
float startx; /*optical_res, from dummy_pixel+1 */
1783
unsigned int lincnt;
1789
int scan_step_type = 1;
1790
int max_shift, dpihw;
1791
Sensor_Profile *sensor;
1793
SANE_Bool half_ccd; /* false: full CCD res is used, true, half max CCD res is used */
1797
"gl124_calculate_current_setup settings:\n"
1798
"Resolution: %ux%uDPI\n"
1801
"Startpos : %.3f/%.3f\n"
1802
"Scan mode : %d\n\n",
1804
dev->settings.yres, dev->settings.lines, dev->settings.pixels,
1805
dev->settings.tl_x, dev->settings.tl_y, dev->settings.scan_mode);
1808
if (dev->settings.scan_mode == 4) /* single pass color */
1814
depth = dev->settings.depth;
1815
if (dev->settings.scan_mode == 0)
1819
start = SANE_UNFIX (dev->model->x_offset);
1820
start += dev->settings.tl_x;
1821
start = (start * dev->sensor.optical_res) / MM_PER_INCH;
1824
xres = dev->settings.xres;
1825
yres = dev->settings.yres;
1827
pixels = dev->settings.pixels;
1828
lines = dev->settings.lines;
1829
color_filter = dev->settings.color_filter;
1833
"gl124_calculate_current_setup settings:\n"
1834
"Resolution : %gDPI/%gDPI\n"
1838
"Depth/Channels: %u/%u\n\n",
1839
xres, yres, lines, pixels, startx, depth, channels);
1842
/* we have 2 domains for ccd: xres below or above half ccd max dpi */
1843
if ((dev->sensor.optical_res < 2 * xres) ||
1844
!(dev->model->flags & GENESYS_FLAG_HALF_CCD_MODE))
1846
half_ccd = SANE_FALSE;
1850
half_ccd = SANE_TRUE;
1855
optical_res = dev->sensor.optical_res;
1860
if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE))
1861
stagger = (4 * yres) / dev->motor.base_ydpi;
1864
DBG (DBG_info, "%s: stagger=%d lines\n", __FUNCTION__, stagger);
1866
if(xres<=optical_res)
1869
used_res=optical_res;
1871
/* compute scan parameters values */
1872
/* pixels are allways given at half or full CCD optical resolution */
1873
/* use detected left margin and fixed value */
1875
/* compute correct pixels number */
1876
used_pixels = (pixels * optical_res) / xres;
1877
DBG (DBG_info, "%s: used_pixels=%d\n", __FUNCTION__, used_pixels);
1881
/* cis color scan is effectively a gray scan with 3 gray lines per color
1882
line and a FILTER of 0 */
1883
if (dev->model->is_cis)
1884
slope_dpi = yres * channels;
1888
/* scan_step_type and exposure */
1889
exposure_time = gl124_compute_exposure (dev, xres);
1890
scan_step_type = gl124_compute_step_type(dev, exposure_time);
1891
DBG (DBG_info, "%s : exposure_time=%d pixels\n", __FUNCTION__, exposure_time);
1894
/* scanned area must be enlarged by max color shift needed */
1895
/* all values are assumed >= 0 */
1898
max_shift = dev->model->ld_shift_r;
1899
if (dev->model->ld_shift_b > max_shift)
1900
max_shift = dev->model->ld_shift_b;
1901
if (dev->model->ld_shift_g > max_shift)
1902
max_shift = dev->model->ld_shift_g;
1903
max_shift = (max_shift * yres) / dev->motor.base_ydpi;
1910
dpihw=gl124_compute_dpihw(dev,used_res);
1911
sensor=get_sensor_profile(dev->model->ccd_type, dpihw);
1912
dev->segnb=sensor->reg98 & 0x0f;
1915
lincnt = lines + max_shift + stagger;
1917
dev->current_setup.pixels = (used_pixels * used_res) / optical_res;
1918
DBG (DBG_info, "%s: current_setup.pixels=%d\n", __FUNCTION__, dev->current_setup.pixels);
1919
dev->current_setup.lines = lincnt;
1920
dev->current_setup.depth = depth;
1921
dev->current_setup.channels = channels;
1922
dev->current_setup.exposure_time = exposure_time;
1923
dev->current_setup.xres = used_res;
1924
dev->current_setup.yres = yres;
1925
dev->current_setup.half_ccd = half_ccd;
1926
dev->current_setup.stagger = stagger;
1927
dev->current_setup.max_shift = max_shift + stagger;
1930
return SANE_STATUS_GOOD;
1934
gl124_set_motor_power (Genesys_Register_Set * regs, SANE_Bool set)
1937
DBG (DBG_proc, "gl124_set_motor_power\n");
1941
sanei_genesys_set_reg_from_set (regs, REG02,
1942
sanei_genesys_read_reg_from_set (regs,
1948
sanei_genesys_set_reg_from_set (regs, REG02,
1949
sanei_genesys_read_reg_from_set (regs,
1956
gl124_set_lamp_power (Genesys_Device * dev,
1957
Genesys_Register_Set * regs, SANE_Bool set)
1959
if (dev == NULL || regs==NULL)
1964
sanei_genesys_set_reg_from_set (regs, 0x03,
1965
sanei_genesys_read_reg_from_set (regs,
1971
sanei_genesys_set_reg_from_set (regs, 0x03,
1972
sanei_genesys_read_reg_from_set (regs,
1979
* for fast power saving methods only, like disabling certain amplifiers
1980
* @param device device to use
1981
* @param enable true to set inot powersaving
1984
gl124_save_power (Genesys_Device * dev, SANE_Bool enable)
1986
DBG (DBG_proc, "gl124_save_power: enable = %d\n", enable);
1988
return SANE_STATUS_INVAL;
1991
return SANE_STATUS_GOOD;
1995
gl124_set_powersaving (Genesys_Device * dev, int delay /* in minutes */ )
1997
Genesys_Register_Set *r;
1999
DBG (DBG_proc, "gl124_set_powersaving (delay = %d)\n", delay);
2001
r = sanei_genesys_get_address (dev->reg, REG03);
2013
return SANE_STATUS_GOOD;
2016
#ifndef UNIT_TESTING
2020
gl124_start_action (Genesys_Device * dev)
2022
return sanei_genesys_write_register (dev, 0x0f, 0x01);
2026
gl124_stop_action (Genesys_Device * dev)
2032
DBG (DBG_proc, "%s\n", __FUNCTION__);
2034
/* post scan gpio */
2035
RIE (sanei_genesys_read_register (dev, REG32, &val));
2037
RIE (sanei_genesys_write_register (dev, REG32, val));
2039
status = sanei_genesys_get_status (dev, &val);
2040
if (DBG_LEVEL >= DBG_io)
2042
sanei_genesys_print_status (val);
2045
status = sanei_genesys_read_hregister (dev, REG100, &val40);
2046
if (status != SANE_STATUS_GOOD)
2049
"%s: failed to read reg100: %s\n", __FUNCTION__,
2050
sane_strstatus (status));
2055
/* only stop action if needed */
2056
if (!(val40 & REG100_DATAENB) && !(val40 & REG100_MOTMFLG))
2058
DBG (DBG_info, "%s: already stopped\n", __FUNCTION__);
2060
return SANE_STATUS_GOOD;
2064
val = sanei_genesys_read_reg_from_set (dev->reg, REG01);
2066
sanei_genesys_set_reg_from_set (dev->reg, REG01, val);
2067
status = sanei_genesys_write_register (dev, REG01, val);
2068
if (status != SANE_STATUS_GOOD)
2071
"%s: failed to write register 01: %s\n", __FUNCTION__,
2072
sane_strstatus (status));
2075
usleep (100 * 1000);
2080
status = sanei_genesys_get_status (dev, &val);
2081
if (DBG_LEVEL >= DBG_io)
2083
sanei_genesys_print_status (val);
2086
status = sanei_genesys_read_hregister (dev, REG100, &val40);
2087
if (status != SANE_STATUS_GOOD)
2090
"%s: failed to read home sensor: %s\n", __FUNCTION__,
2091
sane_strstatus (status));
2096
/* if scanner is in command mode, we are done */
2097
if (!(val40 & REG100_DATAENB) && !(val40 & REG100_MOTMFLG)
2098
&& !(val & MOTORENB))
2101
return SANE_STATUS_GOOD;
2104
usleep (100 * 1000);
2109
return SANE_STATUS_IO_ERROR;
2112
/* Send the low-level scan command */
2113
/* todo : is this that useful ? */
2114
#ifndef UNIT_TESTING
2118
gl124_begin_scan (Genesys_Device * dev, Genesys_Register_Set * reg,
2119
SANE_Bool start_motor)
2126
return SANE_STATUS_INVAL;
2128
/* set up GPIO for scan */
2129
RIE (sanei_genesys_read_register (dev, REG32, &val));
2130
if(dev->settings.yres>=dev->motor.base_ydpi/2)
2134
else if(dev->settings.yres>=dev->motor.base_ydpi/4)
2143
RIE (sanei_genesys_write_register (dev, REG32, val));
2145
/* clear scan and feed count */
2146
RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT | REG0D_CLRMCNT));
2148
/* enable scan and motor */
2149
RIE (sanei_genesys_read_register (dev, REG01, &val));
2151
RIE (sanei_genesys_write_register (dev, REG01, val));
2155
RIE (sanei_genesys_write_register (dev, REG0F, 1));
2159
RIE (sanei_genesys_write_register (dev, REG0F, 0));
2167
/* Send the stop scan command */
2168
#ifndef UNIT_TESTING
2172
gl124_end_scan (Genesys_Device * dev, Genesys_Register_Set * reg,
2173
SANE_Bool check_stop)
2177
DBG (DBG_proc, "gl124_end_scan (check_stop = %d)\n", check_stop);
2179
return SANE_STATUS_INVAL;
2181
if (dev->model->is_sheetfed == SANE_TRUE)
2183
status = SANE_STATUS_GOOD;
2185
else /* flat bed scanners */
2187
status = gl124_stop_action (dev);
2188
if (status != SANE_STATUS_GOOD)
2191
"gl124_end_scan: failed to stop: %s\n",
2192
sane_strstatus (status));
2202
/** @brief Moves the slider to the home (top) position slowly
2204
#ifndef UNIT_TESTING
2208
gl124_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
2210
Genesys_Register_Set local_reg[GENESYS_GL124_MAX_REGS];
2212
Genesys_Register_Set *r;
2217
DBG (DBG_proc, "gl124_slow_back_home (wait_until_home = %d)\n",
2220
dev->scanhead_position_in_steps = 0;
2222
/* first read gives HOME_SENSOR true */
2223
status = sanei_genesys_get_status (dev, &val);
2224
if (status != SANE_STATUS_GOOD)
2227
"gl124_slow_back_home: failed to read home sensor: %s\n",
2228
sane_strstatus (status));
2231
usleep (100000); /* sleep 100 ms */
2233
/* second is reliable */
2234
status = sanei_genesys_get_status (dev, &val);
2235
if (status != SANE_STATUS_GOOD)
2238
"gl124_slow_back_home: failed to read home sensor: %s\n",
2239
sane_strstatus (status));
2242
if (DBG_LEVEL >= DBG_io)
2244
sanei_genesys_print_status (val);
2246
if (val & HOMESNR) /* is sensor at home? */
2249
return SANE_STATUS_GOOD;
2252
memset (local_reg, 0, sizeof (local_reg));
2253
memcpy (local_reg, dev->reg, GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set));
2254
resolution=MOVE_DPI;
2256
gl124_init_scan_regs (dev,
2266
dev->settings.color_filter,
2267
SCAN_FLAG_DISABLE_SHADING |
2268
SCAN_FLAG_DISABLE_GAMMA |
2270
SCAN_FLAG_IGNORE_LINE_DISTANCE);
2271
sanei_genesys_set_triple(local_reg,REG_EXPR,0);
2272
sanei_genesys_set_triple(local_reg,REG_EXPG,0);
2273
sanei_genesys_set_triple(local_reg,REG_EXPB,0);
2275
/* clear scan and feed count */
2276
RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT | REG0D_CLRMCNT));
2278
/* set up for reverse and no scan */
2279
r = sanei_genesys_get_address (local_reg, REG02);
2280
r->value |= REG02_MTRREV;
2281
r = sanei_genesys_get_address (local_reg, REG01);
2282
r->value &= ~REG01_SCAN;
2284
RIE (gl124_bulk_write_register (dev, local_reg, GENESYS_GL124_MAX_REGS));
2286
status = gl124_start_action (dev);
2287
if (status != SANE_STATUS_GOOD)
2290
"gl124_slow_back_home: failed to start motor: %s\n",
2291
sane_strstatus (status));
2292
gl124_stop_action (dev);
2293
/* restore original registers */
2294
gl124_bulk_write_register (dev, dev->reg, GENESYS_GL124_MAX_REGS);
2298
if (wait_until_home)
2301
while (loop < 300) /* do not wait longer then 30 seconds */
2303
status = sanei_genesys_get_status (dev, &val);
2304
if (status != SANE_STATUS_GOOD)
2307
"gl124_slow_back_home: failed to read home sensor: %s\n",
2308
sane_strstatus (status));
2312
if (val & HOMESNR) /* home sensor */
2314
DBG (DBG_info, "gl124_slow_back_home: reached home position\n");
2315
DBG (DBG_proc, "gl124_slow_back_home: finished\n");
2316
return SANE_STATUS_GOOD;
2318
usleep (100000); /* sleep 100 ms */
2322
/* when we come here then the scanner needed too much time for this, so we better stop the motor */
2323
gl124_stop_action (dev);
2325
"gl124_slow_back_home: timeout while waiting for scanhead to go home\n");
2326
return SANE_STATUS_IO_ERROR;
2329
DBG (DBG_info, "gl124_slow_back_home: scanhead is still moving\n");
2330
DBG (DBG_proc, "gl124_slow_back_home: finished\n");
2331
return SANE_STATUS_GOOD;
2334
/** @brief moves the slider to steps at motor base dpi
2335
* @param dev device to work on
2336
* @param steps number of steps to move
2338
#ifndef UNIT_TESTING
2342
gl124_feed (Genesys_Device * dev, unsigned int steps)
2344
Genesys_Register_Set local_reg[GENESYS_GL124_MAX_REGS];
2346
Genesys_Register_Set *r;
2352
/* prepare local registers */
2353
memset (local_reg, 0, sizeof (local_reg));
2354
memcpy (local_reg, dev->reg, GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set));
2357
resolution=MOVE_DPI;
2358
gl124_init_scan_regs (dev,
2368
dev->settings.color_filter,
2369
SCAN_FLAG_DISABLE_SHADING |
2370
SCAN_FLAG_DISABLE_GAMMA |
2372
SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE |
2373
SCAN_FLAG_IGNORE_LINE_DISTANCE);
2374
sanei_genesys_set_triple(local_reg,REG_EXPR,0);
2375
sanei_genesys_set_triple(local_reg,REG_EXPG,0);
2376
sanei_genesys_set_triple(local_reg,REG_EXPB,0);
2378
/* clear scan and feed count */
2379
RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT));
2380
RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRMCNT));
2382
/* set up for no scan */
2383
r = sanei_genesys_get_address (local_reg, REG01);
2384
r->value &= ~REG01_SCAN;
2386
/* send registers */
2387
RIE (gl124_bulk_write_register (dev, local_reg, GENESYS_GL124_MAX_REGS));
2389
status = gl124_start_action (dev);
2390
if (status != SANE_STATUS_GOOD)
2392
DBG (DBG_error, "%s: failed to start motor: %s\n", __FUNCTION__, sane_strstatus (status));
2393
gl124_stop_action (dev);
2395
/* restore original registers */
2396
gl124_bulk_write_register (dev, dev->reg, GENESYS_GL124_MAX_REGS);
2400
/* wait until feed count reaches the required value, but do not
2404
status = sanei_genesys_get_status (dev, &val);
2406
while (status == SANE_STATUS_GOOD && !(val & FEEDFSH));
2409
return SANE_STATUS_GOOD;
2413
/* Automatically set top-left edge of the scan area by scanning a 200x200 pixels
2414
area at 600 dpi from very top of scanner */
2416
gl124_search_start_position (Genesys_Device * dev)
2421
Genesys_Register_Set local_reg[GENESYS_GL124_MAX_REGS];
2427
DBG (DBG_proc, "gl124_search_start_position\n");
2429
memset (local_reg, 0, sizeof (local_reg));
2430
memcpy (local_reg, dev->reg,
2431
GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set));
2433
/* sets for a 200 lines * 600 pixels */
2434
/* normal scan with no shading */
2436
status = gl124_init_scan_regs (dev, local_reg, dpi, dpi, 0, 0, /*we should give a small offset here~60 steps */
2437
600, dev->model->search_lines, 8, 1, 1, /*green */
2438
SCAN_FLAG_DISABLE_SHADING |
2439
SCAN_FLAG_DISABLE_GAMMA |
2440
SCAN_FLAG_IGNORE_LINE_DISTANCE |
2441
SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE);
2443
/* send to scanner */
2444
status = gl124_bulk_write_register (dev, local_reg, GENESYS_GL124_MAX_REGS);
2445
if (status != SANE_STATUS_GOOD)
2448
"gl124_search_start_position: failed to bulk write registers: %s\n",
2449
sane_strstatus (status));
2453
size = pixels * dev->model->search_lines;
2455
data = malloc (size);
2459
"gl124_search_start_position: failed to allocate memory\n");
2460
return SANE_STATUS_NO_MEM;
2463
status = gl124_begin_scan (dev, local_reg, SANE_TRUE);
2464
if (status != SANE_STATUS_GOOD)
2468
"gl124_search_start_position: failed to begin scan: %s\n",
2469
sane_strstatus (status));
2473
/* waits for valid data */
2475
sanei_genesys_test_buffer_empty (dev, &steps);
2478
/* now we're on target, we can read data */
2479
status = sanei_genesys_read_data_from_scanner (dev, data, size);
2480
if (status != SANE_STATUS_GOOD)
2484
"gl124_search_start_position: failed to read data: %s\n",
2485
sane_strstatus (status));
2489
if (DBG_LEVEL >= DBG_data)
2490
sanei_genesys_write_pnm_file ("search_position.pnm", data, 8, 1, pixels,
2491
dev->model->search_lines);
2493
status = gl124_end_scan (dev, local_reg, SANE_TRUE);
2494
if (status != SANE_STATUS_GOOD)
2498
"gl124_search_start_position: failed to end scan: %s\n",
2499
sane_strstatus (status));
2503
/* update regs to copy ASIC internal state */
2504
memcpy (dev->reg, local_reg,
2505
GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set));
2508
sanei_genesys_search_reference_point (dev, data, 0, dpi, pixels,
2509
dev->model->search_lines);
2510
if (status != SANE_STATUS_GOOD)
2514
"gl124_search_start_position: failed to set search reference point: %s\n",
2515
sane_strstatus (status));
2520
return SANE_STATUS_GOOD;
2524
* sets up register for coarse gain calibration
2525
* todo: check it for scanners using it */
2527
gl124_init_regs_for_coarse_calibration (Genesys_Device * dev)
2532
Genesys_Register_Set *r;
2535
cksel = (dev->calib_reg[reg_0x18].value & REG18_CKSEL) + 1; /* clock speed = 1..4 clocks */
2538
if (dev->settings.scan_mode == SCAN_MODE_COLOR) /* single pass color */
2543
status = gl124_init_scan_regs (dev,
2549
dev->sensor.optical_res / cksel,
2553
dev->settings.color_filter,
2554
SCAN_FLAG_DISABLE_SHADING |
2555
SCAN_FLAG_DISABLE_GAMMA |
2556
SCAN_FLAG_SINGLE_LINE |
2558
SCAN_FLAG_IGNORE_LINE_DISTANCE);
2559
if (status != SANE_STATUS_GOOD)
2562
"gl124_init_register_for_coarse_calibration: failed to setup scan: %s\n",
2563
sane_strstatus (status));
2566
r = sanei_genesys_get_address (dev->calib_reg, REG02);
2567
r->value &= ~REG02_MTRPWR;
2570
"gl124_init_register_for_coarse_calibration: optical sensor res: %d dpi, actual res: %d\n",
2571
dev->sensor.optical_res / cksel, dev->settings.xres);
2574
gl124_bulk_write_register (dev, dev->calib_reg, GENESYS_GL124_MAX_REGS);
2575
if (status != SANE_STATUS_GOOD)
2578
"gl124_init_register_for_coarse_calibration: failed to bulk write registers: %s\n",
2579
sane_strstatus (status));
2584
return SANE_STATUS_GOOD;
2588
/* init registers for shading calibration */
2590
gl124_init_regs_for_shading (Genesys_Device * dev)
2593
int move,resolution;
2594
Genesys_Register_Set *r;
2598
/* initial calibration reg values */
2599
memcpy (dev->calib_reg, dev->reg,
2600
GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set));
2602
dev->calib_channels = 3;
2603
resolution=gl124_compute_dpihw(dev,dev->settings.xres);
2604
dev->calib_pixels = (dev->sensor.sensor_pixels*resolution)/dev->sensor.optical_res;
2606
/* distance to move to reach white target at high resolution */
2608
if(dev->settings.yres>=1200)
2610
move = SANE_UNFIX (dev->model->y_offset_calib);
2611
move = (move * (dev->motor.base_ydpi/4)) / MM_PER_INCH;
2613
DBG (DBG_io, "%s: move=%d steps\n", __FUNCTION__, move);
2615
status = gl124_init_scan_regs (dev,
2622
dev->model->shading_lines,
2624
dev->calib_channels,
2627
r = sanei_genesys_get_address (dev->calib_reg, REG01);
2628
r->value &= ~REG01_DVDSET;
2629
r = sanei_genesys_get_address (dev->calib_reg, REG02);
2630
r->value &= ~REG02_MTRPWR;
2631
r = sanei_genesys_get_address (dev->calib_reg, REG05);
2632
r->value &= ~REG05_GMMENB;
2634
if (status != SANE_STATUS_GOOD)
2636
DBG (DBG_error, "%s: failed to setup scan: %s\n", __FUNCTION__,
2637
sane_strstatus (status));
2641
dev->scanhead_position_in_steps += dev->model->shading_lines + move;
2644
gl124_bulk_write_register (dev, dev->calib_reg, GENESYS_GL124_MAX_REGS);
2645
if (status != SANE_STATUS_GOOD)
2648
"%s: failed to bulk write registers: %s\n", __FUNCTION__,
2649
sane_strstatus (status));
2654
return SANE_STATUS_GOOD;
2657
/** @brief set up registers for the actual scan
2660
gl124_init_regs_for_scan (Genesys_Device * dev)
2673
"gl124_init_regs_for_scan settings:\nResolution: %ux%uDPI\n"
2674
"Lines : %u\npixels : %u\nStartpos : %.3f/%.3f\nScan mode : %d\n\n",
2677
dev->settings.lines,
2678
dev->settings.pixels,
2681
dev->settings.scan_mode);
2683
/* wait for motor to stop first */
2684
status = sanei_genesys_get_status (dev, &val);
2685
if (status != SANE_STATUS_GOOD)
2687
DBG (DBG_error, "%s: failed to read status: %s\n", __FUNCTION__, sane_strstatus (status));
2691
status = sanei_genesys_read_hregister (dev, REG100, &val40);
2692
if (status != SANE_STATUS_GOOD)
2694
DBG (DBG_error, "%s: failed to read reg100: %s\n", __FUNCTION__, sane_strstatus (status));
2698
if((val & MOTORENB) || (val40 & REG100_MOTMFLG))
2703
status = sanei_genesys_get_status (dev, &val);
2704
if (status != SANE_STATUS_GOOD)
2706
DBG (DBG_error, "%s: failed to read status: %s\n", __FUNCTION__, sane_strstatus (status));
2710
status = sanei_genesys_read_hregister (dev, REG100, &val40);
2711
if (status != SANE_STATUS_GOOD)
2713
DBG (DBG_error, "%s: failed to read reg100: %s\n", __FUNCTION__, sane_strstatus (status));
2717
} while ((val & MOTORENB) || (val40 & REG100_MOTMFLG));
2721
/* ensure head is parked in case of calibration */
2722
RIE (gl124_slow_back_home (dev, SANE_TRUE));
2725
if (dev->settings.scan_mode == SCAN_MODE_COLOR)
2731
depth = dev->settings.depth;
2732
if (dev->settings.scan_mode == SCAN_MODE_LINEART)
2735
/* y (motor) distance to move to reach scanned area */
2736
move_dpi = dev->motor.base_ydpi/4;
2737
move = SANE_UNFIX (dev->model->y_offset);
2738
move += dev->settings.tl_y;
2739
move = (move * move_dpi) / MM_PER_INCH;
2740
DBG (DBG_info, "%s: move=%f steps\n", __FUNCTION__, move);
2742
if(channels*dev->settings.yres>=1200 && move>3000)
2745
status = gl124_feed (dev, move);
2746
if (status != SANE_STATUS_GOOD)
2748
DBG (DBG_error, "%s: failed to move to scan area\n",__FUNCTION__);
2760
DBG (DBG_info, "gl124_init_regs_for_scan: move=%f steps\n", move);
2763
start = SANE_UNFIX (dev->model->x_offset);
2764
start += dev->settings.tl_x;
2765
start = (start * dev->sensor.optical_res) / MM_PER_INCH;
2769
/* enable emulated lineart from gray data */
2770
if(dev->settings.scan_mode == SCAN_MODE_LINEART
2771
&& dev->settings.dynamic_lineart)
2773
flags |= SCAN_FLAG_DYNAMIC_LINEART;
2776
status = gl124_init_scan_regs (dev,
2782
dev->settings.pixels,
2783
dev->settings.lines,
2785
channels, dev->settings.color_filter, flags);
2787
if (status != SANE_STATUS_GOOD)
2791
return SANE_STATUS_GOOD;
2795
* Send shading calibration data. The buffer is considered to always hold values
2796
* for all the channels.
2798
#ifndef UNIT_TESTING
2802
gl124_send_shading_data (Genesys_Device * dev, uint8_t * data, int size)
2804
SANE_Status status = SANE_STATUS_GOOD;
2805
uint32_t addr, length, strpixel ,endpixel, x, factor, segcnt, pixels, i;
2806
uint16_t dpiset,dpihw;
2807
uint8_t val,*buffer,*ptr,*src;
2810
DBG( DBG_io2, "%s: writing %d bytes of shading data\n",__FUNCTION__,size);
2812
/* logical size of a color as seen by generic code of the frontend */
2813
length = (uint32_t) (size / 3);
2814
sanei_genesys_get_triple(dev->reg,REG_STRPIXEL,&strpixel);
2815
sanei_genesys_get_triple(dev->reg,REG_ENDPIXEL,&endpixel);
2816
sanei_genesys_get_triple(dev->reg,REG_SEGCNT,&segcnt);
2821
DBG( DBG_io2, "%s: STRPIXEL=%d, ENDPIXEL=%d, PIXELS=%d, SEGCNT=%d\n",__FUNCTION__,strpixel,endpixel,endpixel-strpixel,segcnt);
2823
/* turn pixel value into bytes 2x16 bits words */
2824
strpixel*=2*2; /* 2 words of 2 bytes */
2827
pixels=endpixel-strpixel;
2829
DBG( DBG_io2, "%s: using chunks of %d bytes (%d shading data pixels)\n",__FUNCTION__,length, length/4);
2830
buffer=(uint8_t *)malloc(pixels*dev->segnb);
2831
memset(buffer,0,pixels*dev->segnb);
2833
/* compute deletion factor */
2834
sanei_genesys_get_double(dev->reg,REG_DPISET,&dpiset);
2835
dpihw=gl124_compute_dpihw(dev,dpiset);
2836
factor=dpihw/dpiset;
2837
DBG( DBG_io2, "%s: factor=%d\n",__FUNCTION__,factor);
2839
/* write actual red data */
2842
/* copy data to work buffer and process it */
2843
/* coefficent destination */
2846
/* iterate on both sensor segment */
2847
for(x=0;x<pixels;x+=4*factor)
2849
/* coefficient source */
2850
src=data+x+strpixel+i*length;
2852
/* iterate over all the segments */
2856
ptr[0+pixels*0]=src[0+segcnt*0];
2857
ptr[1+pixels*0]=src[1+segcnt*0];
2858
ptr[2+pixels*0]=src[2+segcnt*0];
2859
ptr[3+pixels*0]=src[3+segcnt*0];
2862
ptr[0+pixels*0]=src[0+segcnt*0];
2863
ptr[1+pixels*0]=src[1+segcnt*0];
2864
ptr[2+pixels*0]=src[2+segcnt*0];
2865
ptr[3+pixels*0]=src[3+segcnt*0];
2866
ptr[0+pixels*1]=src[0+segcnt*1];
2867
ptr[1+pixels*1]=src[1+segcnt*1];
2868
ptr[2+pixels*1]=src[2+segcnt*1];
2869
ptr[3+pixels*1]=src[3+segcnt*1];
2872
ptr[0+pixels*0]=src[0+segcnt*0];
2873
ptr[1+pixels*0]=src[1+segcnt*0];
2874
ptr[2+pixels*0]=src[2+segcnt*0];
2875
ptr[3+pixels*0]=src[3+segcnt*0];
2876
ptr[0+pixels*1]=src[0+segcnt*2];
2877
ptr[1+pixels*1]=src[1+segcnt*2];
2878
ptr[2+pixels*1]=src[2+segcnt*2];
2879
ptr[3+pixels*1]=src[3+segcnt*2];
2880
ptr[0+pixels*2]=src[0+segcnt*1];
2881
ptr[1+pixels*2]=src[1+segcnt*1];
2882
ptr[2+pixels*2]=src[2+segcnt*1];
2883
ptr[3+pixels*2]=src[3+segcnt*1];
2884
ptr[0+pixels*3]=src[0+segcnt*3];
2885
ptr[1+pixels*3]=src[1+segcnt*3];
2886
ptr[2+pixels*3]=src[2+segcnt*3];
2887
ptr[3+pixels*3]=src[3+segcnt*3];
2891
/* next shading coefficients */
2894
RIE (sanei_genesys_read_register (dev, 0xd0+i, &val));
2895
addr = val * 8192 + 0x10000000;
2896
status = sanei_genesys_write_ahb (dev->dn, addr, pixels*dev->segnb, buffer);
2897
if (status != SANE_STATUS_GOOD)
2899
DBG (DBG_error, "gl124_send_shading_data; write to AHB failed (%s)\n",
2900
sane_strstatus (status));
2911
/** @brief send gmma table to scanner
2912
* This function sends generic gamma table (ie ones built with
2913
* provided gamma) or the user defined one if provided by
2915
* @param dev device to write to
2916
* @param generic flag for using generic gamma tables
2919
gl124_send_gamma_table (Genesys_Device * dev, SANE_Bool generic)
2923
uint8_t *gamma, val;
2926
DBG (DBG_proc, "gl124_send_gamma_table\n");
2928
/* don't send anything if no specific gamma table defined */
2930
&& (dev->sensor.red_gamma_table == NULL
2931
|| dev->sensor.green_gamma_table == NULL
2932
|| dev->sensor.blue_gamma_table == NULL))
2934
DBG (DBG_proc, "gl124_send_gamma_table: nothing to send, skipping\n");
2935
return SANE_STATUS_GOOD;
2940
/* allocate temporary gamma tables: 16 bits words, 3 channels */
2941
gamma = (uint8_t *) malloc (size * 2 * 3);
2943
return SANE_STATUS_NO_MEM;
2945
/* take care off generic/specific data */
2948
/* fill with default values */
2949
for (i = 0; i < size; i++)
2952
gamma[i * 2 + size * 0 + 0] = gmmval & 0xff;
2953
gamma[i * 2 + size * 0 + 1] = (gmmval >> 8) & 0xff;
2954
gamma[i * 2 + size * 2 + 0] = gmmval & 0xff;
2955
gamma[i * 2 + size * 2 + 1] = (gmmval >> 8) & 0xff;
2956
gamma[i * 2 + size * 4 + 0] = gmmval & 0xff;
2957
gamma[i * 2 + size * 4 + 1] = (gmmval >> 8) & 0xff;
2962
/* copy sensor specific's gamma tables */
2963
for (i = 0; i < size; i++)
2965
gamma[i * 2 + size * 0 + 0] = dev->sensor.red_gamma_table[i] & 0xff;
2966
gamma[i * 2 + size * 0 + 1] =
2967
(dev->sensor.red_gamma_table[i] >> 8) & 0xff;
2968
gamma[i * 2 + size * 2 + 0] =
2969
dev->sensor.green_gamma_table[i] & 0xff;
2970
gamma[i * 2 + size * 2 + 1] =
2971
(dev->sensor.green_gamma_table[i] >> 8) & 0xff;
2972
gamma[i * 2 + size * 4 + 0] =
2973
dev->sensor.blue_gamma_table[i] & 0xff;
2974
gamma[i * 2 + size * 4 + 1] =
2975
(dev->sensor.blue_gamma_table[i] >> 8) & 0xff;
2979
/* loop sending gamma tables NOTE: 0x01000000 not 0x10000000 */
2980
for (i = 0; i < 3; i++)
2982
/* clear corresponding GMM_N bit */
2983
RIE (sanei_genesys_read_register (dev, 0xbd, &val));
2984
/* val &= ~(0x01 << i); */
2986
RIE (sanei_genesys_write_register (dev, 0xbd, val));
2988
/* clear corresponding GMM_F bit */
2989
RIE (sanei_genesys_read_register (dev, 0xbe, &val));
2990
/* val &= ~(0x01 << i); */
2992
RIE (sanei_genesys_write_register (dev, 0xbe, val));
2995
RIE (sanei_genesys_write_register (dev, 0xc5+2*i, 0x00));
2996
RIE (sanei_genesys_write_register (dev, 0xc6+2*i, 0x00));
2999
sanei_genesys_write_ahb (dev->dn, 0x01000000 + 0x200 * i, size * 2,
3000
gamma + i * size * 2);
3001
if (status != SANE_STATUS_GOOD)
3004
"gl124_send_gamma_table: write to AHB failed writing table %d (%s)\n",
3005
i, sane_strstatus (status));
3014
/* this function does the led calibration by scanning one line of the calibration
3015
area below scanner's top on white strip.
3017
-needs working coarse/gain
3020
gl124_led_calibration (Genesys_Device * dev)
3027
SANE_Status status = SANE_STATUS_GOOD;
3029
int channels, depth;
3030
int avg[3], avga, avge;
3033
uint32_t expr, expg, expb;
3034
Sensor_Profile *sensor;
3035
Genesys_Register_Set *r;
3037
SANE_Bool acceptable = SANE_FALSE;
3041
/* offset calibration is always done in color mode */
3044
used_res=gl124_compute_dpihw(dev,dev->settings.xres);
3045
sensor=get_sensor_profile(dev->model->ccd_type, used_res);
3047
(dev->sensor.sensor_pixels * used_res) / dev->sensor.optical_res;
3049
/* initial calibration reg values */
3050
memcpy (dev->calib_reg, dev->reg,
3051
GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set));
3053
status = gl124_init_scan_regs (dev,
3063
dev->settings.color_filter,
3064
SCAN_FLAG_CALIBRATION |
3065
SCAN_FLAG_DISABLE_SHADING |
3066
SCAN_FLAG_DISABLE_GAMMA |
3067
SCAN_FLAG_SINGLE_LINE |
3068
SCAN_FLAG_IGNORE_LINE_DISTANCE);
3070
if (status != SANE_STATUS_GOOD)
3073
"gl124_led_calibration: failed to setup scan: %s\n",
3074
sane_strstatus (status));
3078
RIE (gl124_bulk_write_register
3079
(dev, dev->calib_reg, GENESYS_GL124_MAX_REGS));
3082
total_size = num_pixels * channels * (depth / 8) * 1; /* colors * bytes_per_color * scan lines */
3084
line = malloc (total_size);
3086
return SANE_STATUS_NO_MEM;
3089
we try to get equal bright leds here:
3093
adjust exposure times
3103
/* no move during led calibration */
3104
r = sanei_genesys_get_address (dev->calib_reg, REG02);
3105
r->value &= ~REG02_MTRPWR;
3108
sanei_genesys_set_triple(dev->calib_reg,REG_EXPR,expr);
3109
sanei_genesys_set_triple(dev->calib_reg,REG_EXPG,expg);
3110
sanei_genesys_set_triple(dev->calib_reg,REG_EXPB,expb);
3112
RIE (gl124_bulk_write_register
3113
(dev, dev->calib_reg, GENESYS_GL124_MAX_REGS));
3115
DBG (DBG_info, "gl124_led_calibration: starting first line reading\n");
3116
RIE (gl124_begin_scan (dev, dev->calib_reg, SANE_TRUE));
3117
RIE (sanei_genesys_read_data_from_scanner (dev, line, total_size));
3119
if (DBG_LEVEL >= DBG_data)
3121
snprintf (fn, 20, "led_%02d.pnm", turn);
3122
sanei_genesys_write_pnm_file (fn,
3123
line, depth, channels, num_pixels, 1);
3126
acceptable = SANE_TRUE;
3128
for (j = 0; j < channels; j++)
3131
for (i = 0; i < num_pixels; i++)
3133
val = line[i * 2 + j * 2 * num_pixels + 1] * 256 +
3134
line[i * 2 + j * 2 * num_pixels];
3137
avg[j] /= num_pixels;
3139
avga = (avg[0] + avg[1] + avg[2]) / 3;
3141
DBG (DBG_info, "gl124_led_calibration: average: "
3142
"%d,%d,%d\n", avg[0], avg[1], avg[2]);
3144
acceptable = SANE_TRUE;
3146
/* averages must be in a %5 range from each other */
3147
if (avg[0] < avg[1] * 0.95 || avg[1] < avg[0] * 0.95 ||
3148
avg[0] < avg[2] * 0.95 || avg[2] < avg[0] * 0.95 ||
3149
avg[1] < avg[2] * 0.95 || avg[2] < avg[1] * 0.95)
3150
acceptable = SANE_FALSE;
3154
expr = (expr * avga) / avg[0];
3155
expg = (expg * avga) / avg[1];
3156
expb = (expb * avga) / avg[2];
3158
keep the resulting exposures below this value.
3159
too long exposure drives the ccd into saturation.
3160
we may fix this by relying on the fact that
3161
we get a striped scan without shading, by means of
3162
statistical calculation
3164
avge = (expr + expg + expb) / 3;
3166
/* XXX STEF XXX check limits: don't overflow max exposure */
3169
expr = (expr * 40000) / avge;
3170
expg = (expg * 40000) / avge;
3171
expb = (expb * 40000) / avge;
3175
expr = (expr * 200) / avge;
3176
expg = (expg * 200) / avge;
3177
expb = (expb * 200) / avge;
3182
RIE (gl124_stop_action (dev));
3187
while (!acceptable && turn < 100);
3189
DBG (DBG_info, "gl124_led_calibration: acceptable exposure: %d,%d,%d\n",
3192
/* set these values as final ones for scan */
3193
sanei_genesys_set_triple(dev->reg,REG_EXPR,expr);
3194
sanei_genesys_set_triple(dev->reg,REG_EXPG,expg);
3195
sanei_genesys_set_triple(dev->reg,REG_EXPB,expb);
3197
/* we're hoping that the values are 16bits so we can have them
3198
* persist in cache */
3199
dev->sensor.regs_0x10_0x1d[0] = (expr >> 8) & 0xff;
3200
dev->sensor.regs_0x10_0x1d[1] = expr & 0xff;
3201
dev->sensor.regs_0x10_0x1d[2] = (expg >> 8) & 0xff;
3202
dev->sensor.regs_0x10_0x1d[3] = expg & 0xff;
3203
dev->sensor.regs_0x10_0x1d[4] = (expb >> 8) & 0xff;
3204
dev->sensor.regs_0x10_0x1d[5] = expb & 0xff;
3206
/* cleanup before return */
3210
gl124_slow_back_home (dev, SANE_TRUE);
3217
* average dark pixels of a 8 bits scan
3220
dark_average (uint8_t * data, unsigned int pixels, unsigned int lines,
3221
unsigned int channels, unsigned int black)
3223
unsigned int i, j, k, average, count;
3224
unsigned int avg[3];
3227
/* computes average value on black margin */
3228
for (k = 0; k < channels; k++)
3232
for (i = 0; i < lines; i++)
3234
for (j = 0; j < black; j++)
3236
val = data[i * channels * pixels + j + k];
3243
DBG (DBG_info, "dark_average: avg[%d] = %d\n", k, avg[k]);
3246
for (i = 0; i < channels; i++)
3248
average /= channels;
3249
DBG (DBG_info, "dark_average: average = %d\n", average);
3255
gl124_offset_calibration (Genesys_Device * dev)
3257
Genesys_Register_Set *r;
3258
SANE_Status status = SANE_STATUS_GOOD;
3259
uint8_t *first_line, *second_line, reg0a;
3260
unsigned int channels, bpp;
3262
int pass = 0, avg, total_size;
3263
int topavg, bottomavg, resolution, lines;
3264
int top, bottom, black_pixels, pixels;
3268
/* no gain nor offset for TI AFE */
3269
RIE (sanei_genesys_read_register (dev, REG0A, ®0a));
3270
if(((reg0a & REG0A_SIFSEL)>>REG0AS_SIFSEL)==3)
3276
/* offset calibration is always done in color mode */
3278
resolution=dev->sensor.optical_res;
3279
dev->calib_pixels = dev->sensor.sensor_pixels;
3282
pixels= (dev->sensor.sensor_pixels*resolution) / dev->sensor.optical_res;
3283
black_pixels = (dev->sensor.black_pixels * resolution) / dev->sensor.optical_res;
3284
DBG (DBG_io2, "gl124_offset_calibration: black_pixels=%d\n", black_pixels);
3286
status = gl124_init_scan_regs (dev,
3296
dev->settings.color_filter,
3297
SCAN_FLAG_DISABLE_SHADING |
3298
SCAN_FLAG_DISABLE_GAMMA |
3299
SCAN_FLAG_SINGLE_LINE |
3300
SCAN_FLAG_IGNORE_LINE_DISTANCE);
3301
if (status != SANE_STATUS_GOOD)
3304
"gl124_offset_calibration: failed to setup scan: %s\n",
3305
sane_strstatus (status));
3308
r = sanei_genesys_get_address (dev->calib_reg, REG02);
3309
r->value &= ~REG02_MTRPWR;
3311
/* allocate memory for scans */
3312
total_size = pixels * channels * lines * (bpp/8); /* colors * bytes_per_color * scan lines */
3314
first_line = malloc (total_size);
3316
return SANE_STATUS_NO_MEM;
3318
second_line = malloc (total_size);
3322
return SANE_STATUS_NO_MEM;
3326
dev->frontend.gain[0] = 0;
3327
dev->frontend.gain[1] = 0;
3328
dev->frontend.gain[2] = 0;
3330
/* scan with no move */
3332
dev->frontend.offset[0] = bottom;
3333
dev->frontend.offset[1] = bottom;
3334
dev->frontend.offset[2] = bottom;
3336
RIE (gl124_set_fe(dev, AFE_SET));
3337
RIE (gl124_bulk_write_register (dev, dev->calib_reg, GENESYS_GL124_MAX_REGS));
3338
DBG (DBG_info, "gl124_offset_calibration: starting first line reading\n");
3339
RIE (gl124_begin_scan (dev, dev->calib_reg, SANE_TRUE));
3340
RIE (sanei_genesys_read_data_from_scanner (dev, first_line, total_size));
3341
if (DBG_LEVEL >= DBG_data)
3343
snprintf(title,20,"offset%03d.pnm",bottom);
3344
sanei_genesys_write_pnm_file (title, first_line, bpp, channels, pixels, lines);
3347
bottomavg = dark_average (first_line, pixels, lines, channels, black_pixels);
3348
DBG (DBG_io2, "gl124_offset_calibration: bottom avg=%d\n", bottomavg);
3352
dev->frontend.offset[0] = top;
3353
dev->frontend.offset[1] = top;
3354
dev->frontend.offset[2] = top;
3355
RIE (gl124_set_fe(dev, AFE_SET));
3356
RIE (gl124_bulk_write_register (dev, dev->calib_reg, GENESYS_GL124_MAX_REGS));
3357
DBG (DBG_info, "gl124_offset_calibration: starting second line reading\n");
3358
RIE (gl124_begin_scan (dev, dev->calib_reg, SANE_TRUE));
3359
RIE (sanei_genesys_read_data_from_scanner (dev, second_line, total_size));
3361
topavg = dark_average (second_line, pixels, lines, channels, black_pixels);
3362
DBG (DBG_io2, "gl124_offset_calibration: top avg=%d\n", topavg);
3364
/* loop until acceptable level */
3365
while ((pass < 32) && (top - bottom > 1))
3369
/* settings for new scan */
3370
dev->frontend.offset[0] = (top + bottom) / 2;
3371
dev->frontend.offset[1] = (top + bottom) / 2;
3372
dev->frontend.offset[2] = (top + bottom) / 2;
3374
/* scan with no move */
3375
RIE(gl124_set_fe(dev, AFE_SET));
3376
RIE (gl124_bulk_write_register (dev, dev->calib_reg, GENESYS_GL124_MAX_REGS));
3377
DBG (DBG_info, "gl124_offset_calibration: starting second line reading\n");
3378
RIE (gl124_begin_scan (dev, dev->calib_reg, SANE_TRUE));
3379
RIE (sanei_genesys_read_data_from_scanner (dev, second_line, total_size));
3381
if (DBG_LEVEL >= DBG_data)
3383
sprintf (title, "offset%03d.pnm", dev->frontend.offset[1]);
3384
sanei_genesys_write_pnm_file (title, second_line, bpp, channels, pixels, lines);
3387
avg = dark_average (second_line, pixels, lines, channels, black_pixels);
3388
DBG (DBG_info, "gl124_offset_calibration: avg=%d offset=%d\n", avg,
3389
dev->frontend.offset[1]);
3391
/* compute new boundaries */
3395
top = dev->frontend.offset[1];
3400
bottom = dev->frontend.offset[1];
3403
DBG (DBG_info, "gl124_offset_calibration: offset=(%d,%d,%d)\n", dev->frontend.offset[0], dev->frontend.offset[1], dev->frontend.offset[2]);
3405
/* cleanup before return */
3410
return SANE_STATUS_GOOD;
3414
/* alternative coarse gain calibration
3415
this on uses the settings from offset_calibration and
3416
uses only one scanline
3419
with offset and coarse calibration we only want to get our input range into
3420
a reasonable shape. the fine calibration of the upper and lower bounds will
3421
be done with shading.
3424
gl124_coarse_gain_calibration (Genesys_Device * dev, int dpi)
3428
uint8_t *line, reg0a;
3430
SANE_Status status = SANE_STATUS_GOOD;
3432
float gain[3],coeff;
3433
int val, code, lines;
3435
Genesys_Register_Set *r;
3438
DBG (DBG_proc, "gl124_coarse_gain_calibration: dpi = %d\n", dpi);
3440
/* no gain nor offset for TI AFE */
3441
RIE (sanei_genesys_read_register (dev, REG0A, ®0a));
3442
if(((reg0a & REG0A_SIFSEL)>>REG0AS_SIFSEL)==3)
3448
/* coarse gain calibration is always done in color mode */
3452
if(dev->settings.xres<dev->sensor.optical_res)
3455
resolution=dev->sensor.optical_res/2;
3456
resolution=dev->sensor.optical_res;
3460
resolution=dev->sensor.optical_res;
3465
pixels = (dev->sensor.sensor_pixels * resolution) / dev->sensor.optical_res,
3467
status = gl124_init_scan_regs (dev,
3477
dev->settings.color_filter,
3478
SCAN_FLAG_DISABLE_SHADING |
3479
SCAN_FLAG_DISABLE_GAMMA |
3480
SCAN_FLAG_SINGLE_LINE |
3481
SCAN_FLAG_IGNORE_LINE_DISTANCE);
3482
r = sanei_genesys_get_address (dev->calib_reg, REG02);
3483
r->value &= ~REG02_MTRPWR;
3485
if (status != SANE_STATUS_GOOD)
3488
"gl124_coarse_calibration: failed to setup scan: %s\n",
3489
sane_strstatus (status));
3493
RIE (gl124_bulk_write_register
3494
(dev, dev->calib_reg, GENESYS_GL124_MAX_REGS));
3496
total_size = pixels * channels * (16/bpp) * lines;
3498
line = malloc (total_size);
3500
return SANE_STATUS_NO_MEM;
3502
RIE (gl124_set_fe(dev, AFE_SET));
3503
RIE (gl124_begin_scan (dev, dev->calib_reg, SANE_TRUE));
3504
RIE (sanei_genesys_read_data_from_scanner (dev, line, total_size));
3506
if (DBG_LEVEL >= DBG_data)
3507
sanei_genesys_write_pnm_file ("coarse.pnm", line, bpp, channels, pixels, lines);
3509
/* average value on each channel */
3510
for (j = 0; j < channels; j++)
3513
for (i = pixels/4; i < (pixels*3/4); i++)
3517
if (dev->model->is_cis)
3519
line[i * 2 + j * 2 * pixels + 1] * 256 +
3520
line[i * 2 + j * 2 * pixels];
3523
line[i * 2 * channels + 2 * j + 1] * 256 +
3524
line[i * 2 * channels + 2 * j];
3528
if (dev->model->is_cis)
3529
val = line[i + j * pixels];
3531
val = line[i * channels + j];
3536
max[j] = max[j] / (pixels/2);
3538
gain[j] = ((float) dev->sensor.gain_white_ref*coeff) / max[j];
3540
/* turn logical gain value into gain code, checking for overflow */
3541
code = 283 - 208 / gain[j];
3546
dev->frontend.gain[j] = code;
3549
"gl124_coarse_gain_calibration: channel %d, max=%d, gain = %f, setting:%d\n",
3550
j, max[j], gain[j], dev->frontend.gain[j]);
3553
if (dev->model->is_cis)
3555
if (dev->frontend.gain[0] > dev->frontend.gain[1])
3556
dev->frontend.gain[0] = dev->frontend.gain[1];
3557
if (dev->frontend.gain[0] > dev->frontend.gain[2])
3558
dev->frontend.gain[0] = dev->frontend.gain[2];
3559
dev->frontend.gain[2] = dev->frontend.gain[1] = dev->frontend.gain[0];
3564
dev->frontend.gain[0] = dev->frontend.gain[1];
3565
dev->frontend.gain[2] = dev->frontend.gain[1];
3570
RIE (gl124_stop_action (dev));
3572
gl124_slow_back_home (dev, SANE_TRUE);
3575
return SANE_STATUS_GOOD;
3579
* wait for lamp warmup by scanning the same line until difference
3580
* between 2 scans is below a threshold
3583
gl124_init_regs_for_warmup (Genesys_Device * dev,
3584
Genesys_Register_Set * reg,
3585
int *channels, int *total_size)
3588
SANE_Status status = SANE_STATUS_GOOD;
3589
Genesys_Register_Set *r;
3592
if (dev == NULL || reg == NULL || channels == NULL || total_size == NULL)
3593
return SANE_STATUS_INVAL;
3597
memcpy (reg, dev->reg, (GENESYS_GL124_MAX_REGS + 1) * sizeof (Genesys_Register_Set));
3598
status = gl124_init_scan_regs (dev,
3600
dev->sensor.optical_res,
3601
dev->motor.base_ydpi,
3602
dev->sensor.sensor_pixels/4,
3604
dev->sensor.sensor_pixels/2,
3608
dev->settings.color_filter,
3609
SCAN_FLAG_DISABLE_SHADING |
3610
SCAN_FLAG_DISABLE_GAMMA |
3611
SCAN_FLAG_SINGLE_LINE |
3612
SCAN_FLAG_IGNORE_LINE_DISTANCE);
3614
if (status != SANE_STATUS_GOOD)
3617
"gl124_init_regs_for_warmup: failed to setup scan: %s\n",
3618
sane_strstatus (status));
3622
num_pixels = dev->current_setup.pixels;
3624
*total_size = num_pixels * 3 * 1; /* colors * bytes_per_color * scan lines */
3626
r = sanei_genesys_get_address (reg, REG02);
3627
r->value &= ~REG02_MTRPWR;
3628
RIE (gl124_bulk_write_register (dev, reg, GENESYS_GL124_MAX_REGS));
3631
return SANE_STATUS_GOOD;
3635
gl124_is_compatible_calibration (Genesys_Device * dev,
3636
Genesys_Calibration_Cache * cache,
3639
#ifdef HAVE_SYS_TIME_H
3640
struct timeval time;
3642
int compatible = 1, resolution;
3647
if (cache == NULL || for_overwrite)
3648
return SANE_STATUS_UNSUPPORTED;
3650
status = gl124_calculate_current_setup (dev);
3651
if (status != SANE_STATUS_GOOD)
3654
"gl124_is_compatible_calibration: failed to calculate current setup: %s\n",
3655
sane_strstatus (status));
3658
resolution=gl124_compute_dpihw(dev,dev->settings.xres);
3659
dev->current_setup.scan_method = dev->settings.scan_method;
3661
DBG (DBG_proc, "gl124_is_compatible_calibration: checking\n");
3663
/* a calibration cache is compatible if color mode and x dpi match the user
3664
* requested scan. In the case of CIS scanners, dpi isn't a criteria */
3665
compatible = (resolution == ((int) gl124_compute_dpihw(dev,cache->used_setup.xres)));
3666
if (dev->current_setup.scan_method != cache->used_setup.scan_method)
3669
"gl124_is_compatible_calibration: current method=%d, used=%d\n",
3670
dev->current_setup.scan_method, cache->used_setup.scan_method);
3676
"gl124_is_compatible_calibration: completed, non compatible cache\n");
3677
return SANE_STATUS_UNSUPPORTED;
3680
/* a cache entry expires after 60 minutes for non sheetfed scanners */
3681
#ifdef HAVE_SYS_TIME_H
3682
gettimeofday (&time, NULL);
3683
if ((time.tv_sec - cache->last_calibration > 60 * 60)
3684
&& (dev->model->is_sheetfed == SANE_FALSE)
3685
&& (dev->settings.scan_method == SCAN_METHOD_FLATBED))
3688
"gl124_is_compatible_calibration: expired entry, non compatible cache\n");
3689
return SANE_STATUS_UNSUPPORTED;
3694
return SANE_STATUS_GOOD;
3698
* set up GPIO/GPOE for idle state
3699
WRITE GPIO[17-21]= GPIO19
3700
WRITE GPOE[17-21]= GPOE21 GPOE20 GPOE19 GPOE18
3701
genesys_write_register(0xa8,0x3e)
3705
gl124_init_gpio (Genesys_Device * dev)
3707
SANE_Status status = SANE_STATUS_GOOD;
3712
/* per model GPIO layout */
3713
if (strcmp (dev->model->name, "canon-lide-110") == 0)
3718
{ /* canon LiDE 210 case */
3722
RIE (sanei_genesys_write_register (dev, REG31, gpios[idx].r31));
3723
RIE (sanei_genesys_write_register (dev, REG32, gpios[idx].r32));
3724
RIE (sanei_genesys_write_register (dev, REG33, gpios[idx].r33));
3725
RIE (sanei_genesys_write_register (dev, REG34, gpios[idx].r34));
3726
RIE (sanei_genesys_write_register (dev, REG35, gpios[idx].r35));
3727
RIE (sanei_genesys_write_register (dev, REG36, gpios[idx].r36));
3728
RIE (sanei_genesys_write_register (dev, REG38, gpios[idx].r38));
3735
* set memory layout by filling values in dedicated registers
3738
gl124_init_memory_layout (Genesys_Device * dev)
3740
SANE_Status status = SANE_STATUS_GOOD;
3745
/* point to per model memory layout */
3746
if (strcmp (dev->model->name, "canon-lide-110") == 0)
3751
{ /* canon LiDE 210 case */
3755
/* setup base address for shading data. */
3756
/* values must be multiplied by 8192=0x4000 to give address on AHB */
3757
/* R-Channel shading bank0 address setting for CIS */
3758
sanei_genesys_write_register (dev, 0xd0, layouts[idx].rd0);
3759
/* G-Channel shading bank0 address setting for CIS */
3760
sanei_genesys_write_register (dev, 0xd1, layouts[idx].rd1);
3761
/* B-Channel shading bank0 address setting for CIS */
3762
sanei_genesys_write_register (dev, 0xd2, layouts[idx].rd2);
3764
/* setup base address for scanned data. */
3765
/* values must be multiplied by 1024*2=0x0800 to give address on AHB */
3766
/* R-Channel ODD image buffer 0x0124->0x92000 */
3767
/* size for each buffer is 0x16d*1k word */
3768
sanei_genesys_write_register (dev, 0xe0, layouts[idx].re0);
3769
sanei_genesys_write_register (dev, 0xe1, layouts[idx].re1);
3770
/* R-Channel ODD image buffer end-address 0x0291->0x148800 => size=0xB6800*/
3771
sanei_genesys_write_register (dev, 0xe2, layouts[idx].re2);
3772
sanei_genesys_write_register (dev, 0xe3, layouts[idx].re3);
3774
/* R-Channel EVEN image buffer 0x0292 */
3775
sanei_genesys_write_register (dev, 0xe4, layouts[idx].re4);
3776
sanei_genesys_write_register (dev, 0xe5, layouts[idx].re5);
3777
/* R-Channel EVEN image buffer end-address 0x03ff*/
3778
sanei_genesys_write_register (dev, 0xe6, layouts[idx].re6);
3779
sanei_genesys_write_register (dev, 0xe7, layouts[idx].re7);
3781
/* same for green, since CIS, same addresses */
3782
sanei_genesys_write_register (dev, 0xe8, layouts[idx].re0);
3783
sanei_genesys_write_register (dev, 0xe9, layouts[idx].re1);
3784
sanei_genesys_write_register (dev, 0xea, layouts[idx].re2);
3785
sanei_genesys_write_register (dev, 0xeb, layouts[idx].re3);
3786
sanei_genesys_write_register (dev, 0xec, layouts[idx].re4);
3787
sanei_genesys_write_register (dev, 0xed, layouts[idx].re5);
3788
sanei_genesys_write_register (dev, 0xee, layouts[idx].re6);
3789
sanei_genesys_write_register (dev, 0xef, layouts[idx].re7);
3791
/* same for blue, since CIS, same addresses */
3792
sanei_genesys_write_register (dev, 0xf0, layouts[idx].re0);
3793
sanei_genesys_write_register (dev, 0xf1, layouts[idx].re1);
3794
sanei_genesys_write_register (dev, 0xf2, layouts[idx].re2);
3795
sanei_genesys_write_register (dev, 0xf3, layouts[idx].re3);
3796
sanei_genesys_write_register (dev, 0xf4, layouts[idx].re4);
3797
sanei_genesys_write_register (dev, 0xf5, layouts[idx].re5);
3798
sanei_genesys_write_register (dev, 0xf6, layouts[idx].re6);
3799
sanei_genesys_write_register (dev, 0xf7, layouts[idx].re7);
3808
* initialize ASIC from power on condition
3811
gl124_cold_boot (Genesys_Device * dev)
3818
RIE (sanei_genesys_write_register (dev, 0x0e, 0x01));
3819
RIE (sanei_genesys_write_register (dev, 0x0e, 0x00));
3821
/* enable GPOE 17 */
3822
RIE (sanei_genesys_write_register (dev, 0x36, 0x01));
3825
RIE (sanei_genesys_read_register (dev, 0x33, &val));
3827
RIE (sanei_genesys_write_register (dev, 0x33, val));
3830
RIE (sanei_genesys_read_hregister (dev, REG100, &val));
3831
if (val & REG100_CHKVER)
3833
RIE (sanei_genesys_read_register (dev, 0x00, &val));
3835
"gl124_cold_boot: reported version for genesys chip is 0x%02x\n",
3839
/* Set default values for registers */
3840
gl124_init_registers (dev);
3842
/* Write initial registers */
3843
RIE (gl124_bulk_write_register (dev, dev->reg, GENESYS_GL124_MAX_REGS));
3846
val = REG0B_30MHZ | REG0B_ENBDRAM | REG0B_64M;
3847
RIE (sanei_genesys_write_register (dev, REG0B, val));
3848
dev->reg[reg_0x0b].address = 0x00;
3850
/* set up end access */
3851
RIE (sanei_genesys_write_0x8c (dev, 0x10, 0x0b));
3852
RIE (sanei_genesys_write_0x8c (dev, 0x13, 0x0e));
3855
SETREG (0x08, REG08_CIS_LINE);
3856
RIE (sanei_genesys_write_register (dev, 0x08, dev->reg[reg_0x08].value));
3859
RIE (gl124_init_gpio (dev));
3861
/* setup internal memory layout */
3862
RIE (gl124_init_memory_layout (dev));
3865
return SANE_STATUS_GOOD;
3869
* initialize backend and ASIC : registers, motor tables, and gamma tables
3870
* then ensure scanner's head is at home
3872
#ifndef UNIT_TESTING
3876
gl124_init (Genesys_Device * dev)
3880
SANE_Bool cold = SANE_TRUE;
3886
/* URB 16 control 0xc0 0x0c 0x8e 0x0b len 1 read 0x00 */
3888
sanei_usb_control_msg (dev->dn, REQUEST_TYPE_IN, REQUEST_REGISTER,
3889
VALUE_GET_REGISTER, 0x00, 1, &val);
3890
if (status != SANE_STATUS_GOOD)
3893
"gl124_init: request register failed %s\n",
3894
sane_strstatus (status));
3897
DBG (DBG_io2, "gl124_init: value=0x%02x\n", val);
3898
DBG (DBG_info, "%s: device is %s\n", __FUNCTION__,
3899
(val & 0x08) ? "USB 1.0" : "USB2.0");
3909
/* check if the device has already been initialized and powered up
3910
* we read register 6 and check PWRBIT, if reset scanner has been
3911
* freshly powered up. This bit will be set to later so that following
3912
* reads can detect power down/up cycle*/
3913
RIE (sanei_genesys_read_register (dev, 0x06, &val));
3914
if (val & REG06_PWRBIT)
3918
DBG (DBG_info, "%s: device is %s\n", __FUNCTION__, cold ? "cold" : "warm");
3920
/* don't do anything if backend is initialized and hardware hasn't been
3922
if (dev->already_initialized && !cold)
3924
DBG (DBG_info, "gl124_init: already initialized, nothing to do\n");
3925
return SANE_STATUS_GOOD;
3928
/* set up hardware and registers */
3929
RIE (gl124_cold_boot (dev));
3931
/* now hardware part is OK, set up device struct */
3932
FREE_IFNOT_NULL (dev->white_average_data);
3933
FREE_IFNOT_NULL (dev->dark_average_data);
3934
FREE_IFNOT_NULL (dev->sensor.red_gamma_table);
3935
FREE_IFNOT_NULL (dev->sensor.green_gamma_table);
3936
FREE_IFNOT_NULL (dev->sensor.blue_gamma_table);
3938
dev->settings.color_filter = 0;
3940
memcpy (dev->calib_reg, dev->reg,
3941
GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set));
3943
/* Set analog frontend */
3944
RIE (gl124_set_fe (dev, AFE_INIT));
3946
/* init gamma tables */
3948
if (dev->sensor.red_gamma_table == NULL)
3950
dev->sensor.red_gamma_table = (uint16_t *) malloc (2 * size);
3951
if (dev->sensor.red_gamma_table == NULL)
3954
"gl124_init: could not allocate memory for gamma table\n");
3955
return SANE_STATUS_NO_MEM;
3957
sanei_genesys_create_gamma_table (dev->sensor.red_gamma_table, size,
3958
65535, 65535, dev->sensor.red_gamma);
3960
if (dev->sensor.green_gamma_table == NULL)
3962
dev->sensor.green_gamma_table = (uint16_t *) malloc (2 * size);
3963
if (dev->sensor.red_gamma_table == NULL)
3966
"gl124_init: could not allocate memory for gamma table\n");
3967
return SANE_STATUS_NO_MEM;
3969
sanei_genesys_create_gamma_table (dev->sensor.green_gamma_table, size,
3971
dev->sensor.green_gamma);
3973
if (dev->sensor.blue_gamma_table == NULL)
3975
dev->sensor.blue_gamma_table = (uint16_t *) malloc (2 * size);
3976
if (dev->sensor.red_gamma_table == NULL)
3979
"gl124_init: could not allocate memory for gamma table\n");
3980
return SANE_STATUS_NO_MEM;
3982
sanei_genesys_create_gamma_table (dev->sensor.blue_gamma_table, size,
3983
65535, 65535, dev->sensor.blue_gamma);
3986
dev->oe_buffer.buffer = NULL;
3987
dev->already_initialized = SANE_TRUE;
3989
/* Move home if needed */
3990
RIE (gl124_slow_back_home (dev, SANE_TRUE));
3991
dev->scanhead_position_in_steps = 0;
3993
/* Set powersaving (default = 15 minutes) */
3994
RIE (gl124_set_powersaving (dev, 15));
4001
gl124_update_hardware_sensors (Genesys_Scanner * s)
4003
/* do what is needed to get a new set of events, but try to not lose
4006
SANE_Status status = SANE_STATUS_GOOD;
4009
RIE (sanei_genesys_read_register (s->dev, REG31, &val));
4011
if (s->val[OPT_SCAN_SW].b == s->last_val[OPT_SCAN_SW].b)
4012
s->val[OPT_SCAN_SW].b = (val & 0x01) == 0;
4013
if (s->val[OPT_FILE_SW].b == s->last_val[OPT_FILE_SW].b)
4014
s->val[OPT_FILE_SW].b = (val & 0x08) == 0;
4015
if (s->val[OPT_EMAIL_SW].b == s->last_val[OPT_EMAIL_SW].b)
4016
s->val[OPT_EMAIL_SW].b = (val & 0x04) == 0;
4017
if (s->val[OPT_COPY_SW].b == s->last_val[OPT_COPY_SW].b)
4018
s->val[OPT_COPY_SW].b = (val & 0x02) == 0;
4023
/** the gl124 command set */
4024
static Genesys_Command_Set gl124_cmd_set = {
4025
"gl124-generic", /* the name of this set */
4028
gl124_init_regs_for_warmup,
4029
gl124_init_regs_for_coarse_calibration,
4030
gl124_init_regs_for_shading,
4031
gl124_init_regs_for_scan,
4033
gl124_get_filter_bit,
4034
gl124_get_lineart_bit,
4035
gl124_get_bitset_bit,
4036
gl124_get_gain4_bit,
4037
gl124_get_fast_feed_bit,
4038
gl124_test_buffer_empty_bit,
4039
gl124_test_motor_flag_bit,
4041
gl124_bulk_full_size,
4044
gl124_set_powersaving,
4047
gl124_set_motor_power,
4048
gl124_set_lamp_power,
4053
gl124_send_gamma_table,
4055
gl124_search_start_position,
4057
gl124_offset_calibration,
4058
gl124_coarse_gain_calibration,
4059
gl124_led_calibration,
4061
gl124_slow_back_home,
4063
gl124_bulk_write_register,
4065
gl124_bulk_read_data,
4067
gl124_update_hardware_sensors,
4069
/* no sheetfed support for now */
4075
gl124_is_compatible_calibration,
4077
gl124_send_shading_data
4081
sanei_gl124_init_cmd_set (Genesys_Device * dev)
4083
dev->model->cmd_set = &gl124_cmd_set;
4084
return SANE_STATUS_GOOD;
4087
/* vim: set sw=2 cino=>2se-1sn-1s{s^-1st0(0u0 smarttab expandtab: */