~ubuntu-branches/ubuntu/vivid/sane-backends/vivid

« back to all changes in this revision

Viewing changes to backend/genesys_gl124.c

  • Committer: Bazaar Package Importer
  • Author(s): Julien BLACHE
  • Date: 2011-02-16 19:00:55 UTC
  • mfrom: (1.2.2 upstream) (21.1.2 experimental)
  • Revision ID: james.westby@ubuntu.com-20110216190055-wz0c33eracchkxts
Tags: 1.0.22-1
* New upstream release.
  + epson2: reject scan area settings that would lead to a division by zero
    (closes: #581181).

* debian/control:
  + Bump Standards-Version to 3.9.1 (no changes).
  + Demote libsane-extras-* to Recommends again.
* debian/rules:
  + Add acl (>= 2.2.49-4) to udev substvar for ACL utilities in /bin.
  + Use sane-desc -m udev+acl (closes: #591767, #612815).
* debian/libsane.README.Debian:
  + Update; mention ConsoleKit and the udev rules now using ACLs.

* debian/patches/sane-desc_udev+acl.patch:
  + Added; compared to experimental, setfacl is now in /bin.
* debian/patches/fix_xerox_mfp_color_mode.patch,
  debian/patches/use_libsane_matched_for_scsi.patch,
  debian/patches/allow_dll.d_symlinks.patch,
  debian/patches/saned_exit_avahi_process.patch,
  debian/patches/xerox_mfp_new_ids.patch,
  debian/patches/scsi_perfection_2450.patch,
  debian/patches/scsi_scanjet_4c.patch,
  debian/patches/genesys_disable_raw_data_log.patch,
  debian/patches/fix_epson2_commands.patch,
  debian/patches/fix_epson2_cancel.patch:
  + Removed; merged upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* sane - Scanner Access Now Easy.
 
2
 
 
3
   Copyright (C) 2010 St�phane Voltz <stef.dev@free.fr>
 
4
   
 
5
    
 
6
   This file is part of the SANE package.
 
7
   
 
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.
 
12
   
 
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.
 
17
   
 
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,
 
21
   MA 02111-1307, USA.
 
22
   
 
23
   As a special exception, the authors of SANE give permission for
 
24
   additional uses of the libraries contained in this release of SANE.
 
25
   
 
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.
 
31
   
 
32
   This exception does not, however, invalidate any other reasons why
 
33
   the executable file might be covered by the GNU General Public
 
34
   License.
 
35
   
 
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.
 
39
   
 
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. 
 
43
*/
 
44
 
 
45
#include "genesys_gl124.h"
 
46
 
 
47
/****************************************************************************
 
48
 Low level function
 
49
 ****************************************************************************/
 
50
 
 
51
/* ------------------------------------------------------------------------ */
 
52
/*                  Read and write RAM, registers and AFE                   */
 
53
/* ------------------------------------------------------------------------ */
 
54
 
 
55
/**
 
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
 
62
 */
 
63
#ifndef UNIT_TESTING
 
64
static
 
65
#endif
 
66
  SANE_Status
 
67
gl124_bulk_write_register (Genesys_Device * dev, Genesys_Register_Set * reg,
 
68
                           size_t elems)
 
69
{
 
70
  SANE_Status status = SANE_STATUS_GOOD;
 
71
  size_t i;
 
72
 
 
73
  for (i = 0; i < elems && status == SANE_STATUS_GOOD; i++)
 
74
    {
 
75
      if (reg[i].address != 0)
 
76
        {
 
77
          status =
 
78
            sanei_genesys_write_register (dev, reg[i].address, reg[i].value);
 
79
        }
 
80
    }
 
81
 
 
82
  DBG (DBG_io, "gl124_bulk_write_register: wrote %lu registers\n",
 
83
       (u_long) elems);
 
84
  return status;
 
85
}
 
86
 
 
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
 
95
 */
 
96
static SANE_Status
 
97
gl124_bulk_read_data (Genesys_Device * dev, uint8_t addr,
 
98
                      uint8_t * data, size_t len)
 
99
{
 
100
  SANE_Status status;
 
101
  size_t size, target, read, done;
 
102
  uint8_t outdata[8];
 
103
 
 
104
  DBG (DBG_io, "gl124_bulk_read_data: requesting %lu bytes (unused addr=0x%02x)\n", (u_long) len,addr);
 
105
 
 
106
  if (len == 0)
 
107
    return SANE_STATUS_GOOD;
 
108
 
 
109
  target = len;
 
110
 
 
111
  /* loop until computed data size is read */
 
112
  while (target)
 
113
    {
 
114
      if (target > 0xeff0)
 
115
        {
 
116
          size = 0xeff0;
 
117
        }
 
118
      else
 
119
        {
 
120
          size = target;
 
121
        }
 
122
 
 
123
      /* hard coded 0x10000000 addr */
 
124
      outdata[0] = 0;
 
125
      outdata[1] = 0;
 
126
      outdata[2] = 0;
 
127
      outdata[3] = 0x10;
 
128
 
 
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);
 
134
 
 
135
      status =
 
136
        sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_BUFFER,
 
137
                               VALUE_BUFFER, 0x00, sizeof (outdata),
 
138
                               outdata);
 
139
      if (status != SANE_STATUS_GOOD)
 
140
        {
 
141
          DBG (DBG_error, "%s failed while writing command: %s\n",
 
142
               __FUNCTION__, sane_strstatus (status));
 
143
          return status;
 
144
        }
 
145
 
 
146
      /* blocks must be multiple of 512 but not last block */
 
147
      read = size;
 
148
      read /= 512;
 
149
      read *= 512;
 
150
    
 
151
      if(read>0)
 
152
        {
 
153
          DBG (DBG_io2,
 
154
               "gl124_bulk_read_data: trying to read %lu bytes of data\n",
 
155
               (u_long) read);
 
156
          status = sanei_usb_read_bulk (dev->dn, data, &read);
 
157
          if (status != SANE_STATUS_GOOD)
 
158
            {
 
159
              DBG (DBG_error,
 
160
                   "gl124_bulk_read_data failed while reading bulk data: %s\n",
 
161
                   sane_strstatus (status));
 
162
              return status;
 
163
            }
 
164
        }
 
165
 
 
166
      /* read less than 512 bytes remainder */
 
167
      if (read < size)
 
168
        {
 
169
          done = read;
 
170
          read = size - read;
 
171
          DBG (DBG_io2,
 
172
               "gl124_bulk_read_data: trying to read remaining %lu bytes of data\n",
 
173
               (u_long) read);
 
174
          status = sanei_usb_read_bulk (dev->dn, data+done, &read);
 
175
          if (status != SANE_STATUS_GOOD)
 
176
            {
 
177
              DBG (DBG_error,
 
178
                   "gl124_bulk_read_data failed while reading bulk data: %s\n",
 
179
                   sane_strstatus (status));
 
180
              return status;
 
181
            }
 
182
        }
 
183
 
 
184
      DBG (DBG_io2, "%s: read %lu bytes, %lu remaining\n", __FUNCTION__,
 
185
           (u_long) size, (u_long) (target - size));
 
186
 
 
187
      target -= size;
 
188
      data += size;
 
189
    }
 
190
 
 
191
  DBGCOMPLETED;
 
192
 
 
193
  return SANE_STATUS_GOOD;
 
194
}
 
195
 
 
196
/****************************************************************************
 
197
 Mid level functions 
 
198
 ****************************************************************************/
 
199
 
 
200
static SANE_Bool
 
201
gl124_get_fast_feed_bit (Genesys_Register_Set * regs)
 
202
{
 
203
  Genesys_Register_Set *r = NULL;
 
204
 
 
205
  r = sanei_genesys_get_address (regs, REG02);
 
206
  if (r && (r->value & REG02_FASTFED))
 
207
    return SANE_TRUE;
 
208
  return SANE_FALSE;
 
209
}
 
210
 
 
211
static SANE_Bool
 
212
gl124_get_filter_bit (Genesys_Register_Set * regs)
 
213
{
 
214
  Genesys_Register_Set *r = NULL;
 
215
 
 
216
  r = sanei_genesys_get_address (regs, REG04);
 
217
  if (r && (r->value & REG04_FILTER))
 
218
    return SANE_TRUE;
 
219
  return SANE_FALSE;
 
220
}
 
221
 
 
222
static SANE_Bool
 
223
gl124_get_lineart_bit (Genesys_Register_Set * regs)
 
224
{
 
225
  Genesys_Register_Set *r = NULL;
 
226
 
 
227
  r = sanei_genesys_get_address (regs, REG04);
 
228
  if (r && (r->value & REG04_LINEART))
 
229
    return SANE_TRUE;
 
230
  return SANE_FALSE;
 
231
}
 
232
 
 
233
static SANE_Bool
 
234
gl124_get_bitset_bit (Genesys_Register_Set * regs)
 
235
{
 
236
  Genesys_Register_Set *r = NULL;
 
237
 
 
238
  r = sanei_genesys_get_address (regs, REG04);
 
239
  if (r && (r->value & REG04_BITSET))
 
240
    return SANE_TRUE;
 
241
  return SANE_FALSE;
 
242
}
 
243
 
 
244
static SANE_Bool
 
245
gl124_get_gain4_bit (Genesys_Register_Set * regs)
 
246
{
 
247
  Genesys_Register_Set *r = NULL;
 
248
 
 
249
  r = sanei_genesys_get_address (regs, REG06);
 
250
  if (r && (r->value & REG06_GAIN4))
 
251
    return SANE_TRUE;
 
252
  return SANE_FALSE;
 
253
}
 
254
 
 
255
static SANE_Bool
 
256
gl124_test_buffer_empty_bit (SANE_Byte val)
 
257
{
 
258
  if (val & BUFEMPTY)
 
259
    return SANE_TRUE;
 
260
  return SANE_FALSE;
 
261
}
 
262
 
 
263
static SANE_Bool
 
264
gl124_test_motor_flag_bit (SANE_Byte val)
 
265
{
 
266
  if (val & MOTORENB)
 
267
    return SANE_TRUE;
 
268
  return SANE_FALSE;
 
269
}
 
270
 
 
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
 
277
 */
 
278
static Sensor_Profile *get_sensor_profile(int sensor_type, int dpi)
 
279
{
 
280
  unsigned int i;
 
281
  int idx;
 
282
 
 
283
  i=0;
 
284
  idx=-1;
 
285
  while(i<sizeof(sensors)/sizeof(Sensor_Profile))
 
286
    {
 
287
      /* exact match */
 
288
      if(sensors[i].sensor_type==sensor_type && sensors[i].dpi==dpi)
 
289
        {
 
290
          return &(sensors[i]);
 
291
        }
 
292
 
 
293
      /* closest match */
 
294
      if(sensors[i].sensor_type==sensor_type)
 
295
        {
 
296
          if(idx<0)
 
297
            {
 
298
              idx=i;
 
299
            }
 
300
          else
 
301
            {
 
302
              if(sensors[i].dpi>=dpi 
 
303
              && sensors[i].dpi<sensors[idx].dpi)
 
304
                {
 
305
                  idx=i;
 
306
                }
 
307
            }
 
308
        }
 
309
      i++;
 
310
    }
 
311
 
 
312
  /* default fallback */
 
313
  if(idx<0)
 
314
    {
 
315
      DBG (DBG_warn,"%s: using default sensor profile\n",__FUNCTION__);
 
316
      idx=0;
 
317
    }
 
318
 
 
319
  return &(sensors[idx]);
 
320
}
 
321
 
 
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
 
325
 * by default.
 
326
 * @param motor_type motor id
 
327
 * @param exposure exposure time
 
328
 * @return a pointer to a Motor_Profile struct
 
329
 */
 
330
static Motor_Profile *get_motor_profile(int motor_type, int exposure)
 
331
{
 
332
  unsigned int i;
 
333
  int idx;
 
334
 
 
335
  i=0;
 
336
  idx=-1;
 
337
  while(i<sizeof(motors)/sizeof(Motor_Profile))
 
338
    {
 
339
      /* exact match */
 
340
      if(motors[i].motor_type==motor_type && motors[i].exposure==exposure)
 
341
        {
 
342
          return &(motors[i]);
 
343
        }
 
344
 
 
345
      /* closest match */
 
346
      if(motors[i].motor_type==motor_type)
 
347
        {
 
348
          if(idx<0)
 
349
            {
 
350
              idx=i;
 
351
            }
 
352
          else
 
353
            {
 
354
              if(motors[i].exposure>=exposure 
 
355
              && motors[i].exposure<motors[idx].exposure)
 
356
                {
 
357
                  idx=i;
 
358
                }
 
359
            }
 
360
        }
 
361
      i++;
 
362
    }
 
363
 
 
364
  /* default fallback */
 
365
  if(idx<0)
 
366
    {
 
367
      DBG (DBG_warn,"%s: using default motor profile\n",__FUNCTION__);
 
368
      idx=0;
 
369
    }
 
370
 
 
371
  return &(motors[idx]);
 
372
}
 
373
 
 
374
 
 
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
 
379
 */
 
380
/*
 
381
static int gl124_get_lowest_ydpi(Genesys_Device *dev)
 
382
{
 
383
  int min=9600;
 
384
  int i=0;
 
385
 
 
386
  while(dev->model->ydpi_values[i]!=0)
 
387
    {
 
388
      if(dev->model->ydpi_values[i]<min)
 
389
        {
 
390
          min=dev->model->ydpi_values[i];
 
391
        }
 
392
      i++;
 
393
    }
 
394
  return min;
 
395
}
 
396
*/
 
397
 
 
398
/** @brief generate slope table
 
399
 * Generate the slope table to use for the scan using a reference slope
 
400
 * table.
 
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
 
409
 */
 
410
static int gl124_slope_table(uint16_t *slope,
 
411
                             int       *steps,
 
412
                             int       dpi,
 
413
                             int       exposure,
 
414
                             int       base_dpi,
 
415
                             int       step_type,
 
416
                             int       factor,
 
417
                             int       motor_type)
 
418
{
 
419
int sum, i;
 
420
uint16_t target,current;
 
421
Motor_Profile *profile;
 
422
 
 
423
        /* required speed */
 
424
        target=((exposure * dpi) / base_dpi)>>step_type;
 
425
        
 
426
        /* fill result with target speed */
 
427
        for(i=0;i<SLOPE_TABLE_SIZE;i++)
 
428
          slope[i]=target;
 
429
 
 
430
        profile=get_motor_profile(motor_type,exposure);
 
431
 
 
432
        /* use profile to build table */
 
433
        i=0;
 
434
        sum=0;
 
435
 
 
436
        /* first step is used unmodified */
 
437
        current=profile->table[0];
 
438
 
 
439
        /* loop on profile copying and apply step type */
 
440
        while(i<SLOPE_TABLE_SIZE && current>=target)
 
441
          {
 
442
            slope[i]=current;
 
443
            sum+=slope[i];
 
444
            i++;
 
445
            current=profile->table[i*factor]>>step_type;
 
446
          }
 
447
        if(i<3 && DBG_LEVEL >= DBG_warn)
 
448
          {
 
449
            DBG (DBG_warn,"%s: short slope table, failed to reach %d\n",__FUNCTION__,target);
 
450
          }
 
451
 
 
452
        /* ensure minimal slope size */
 
453
        while(i<8)
 
454
          {
 
455
            sum+=slope[i];
 
456
            i++;
 
457
          }
 
458
 
 
459
        /* return used steps and acceleration sum */
 
460
        *steps=i;
 
461
        return sum;
 
462
}
 
463
 
 
464
/* returns the max register bulk size */
 
465
static int
 
466
gl124_bulk_full_size (void)
 
467
{
 
468
  return GENESYS_GL124_MAX_REGS;
 
469
}
 
470
 
 
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
 
475
 * individually.
 
476
 * @param dev device structure holding register set to initialize
 
477
 */
 
478
static void
 
479
gl124_init_registers (Genesys_Device * dev)
 
480
{
 
481
  DBGSTART;
 
482
 
 
483
  memset (dev->reg, 0, GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set));
 
484
 
 
485
  /* default to LiDE 110 */
 
486
  SETREG (0x01,0xa2); /* + REG01_SHDAREA */
 
487
  SETREG (0x02,0x90);
 
488
  SETREG (0x03,0x50);
 
489
  SETREG (0x03,0x50 & ~REG03_AVEENB);
 
490
  SETREG (0x04,0x03);
 
491
  SETREG (0x05,0x00);
 
492
  SETREG (0x06,0x50 | REG06_GAIN4); /* causes calibration trouble */
 
493
  SETREG (0x06,0x50);
 
494
  /* SETREG (0x07,0x00); */
 
495
  /* SETREG (0x08,0x10); */
 
496
  SETREG (0x09,0x00);
 
497
  SETREG (0x0a,0xc0);
 
498
  SETREG (0x0b,0x2a);
 
499
  SETREG (0x0c,0x12);
 
500
  SETREG (0x11,0x00);
 
501
  SETREG (0x12,0x00);
 
502
  SETREG (0x13,0x0f);
 
503
  SETREG (0x14,0x00);
 
504
  SETREG (0x15,0x80);
 
505
  SETREG (0x16,0x10);
 
506
  SETREG (0x17,0x04);
 
507
  SETREG (0x18,0x00);
 
508
  SETREG (0x19,0x01);
 
509
  SETREG (0x1a,0x30);
 
510
  SETREG (0x1b,0x00);
 
511
  SETREG (0x1c,0x00);
 
512
  SETREG (0x1d,0x01);
 
513
  SETREG (0x1e,0x10);
 
514
  SETREG (0x1f,0x00);
 
515
  SETREG (0x20,0x15);
 
516
  SETREG (0x21,0x00);
 
517
  SETREG (0x22,0x02);
 
518
  SETREG (0x23,0x00);
 
519
  SETREG (0x24,0x00);
 
520
  SETREG (0x25,0x00);
 
521
  SETREG (0x26,0x0d);
 
522
  SETREG (0x27,0x48);
 
523
  SETREG (0x28,0x00);
 
524
  SETREG (0x29,0x56);
 
525
  SETREG (0x2a,0x5e);
 
526
  SETREG (0x2b,0x02);
 
527
  SETREG (0x2c,0x02);
 
528
  SETREG (0x2d,0x58);
 
529
  SETREG (0x3b,0x00);
 
530
  SETREG (0x3c,0x00);
 
531
  SETREG (0x3d,0x00);
 
532
  SETREG (0x3e,0x00);
 
533
  SETREG (0x3f,0x02);
 
534
  SETREG (0x40,0x00);
 
535
  SETREG (0x41,0x00);
 
536
  SETREG (0x42,0x00);
 
537
  SETREG (0x43,0x00);
 
538
  SETREG (0x44,0x00);
 
539
  SETREG (0x45,0x00);
 
540
  SETREG (0x46,0x00);
 
541
  SETREG (0x47,0x00);
 
542
  SETREG (0x48,0x00);
 
543
  SETREG (0x49,0x00);
 
544
  SETREG (0x4f,0x00);
 
545
  SETREG (0x52,0x00);
 
546
  SETREG (0x53,0x02);
 
547
  SETREG (0x54,0x04);
 
548
  SETREG (0x55,0x06);
 
549
  SETREG (0x56,0x04);
 
550
  SETREG (0x57,0x04);
 
551
  SETREG (0x58,0x04);
 
552
  SETREG (0x59,0x04);
 
553
  SETREG (0x5a,0x1a);
 
554
  SETREG (0x5b,0x00);
 
555
  SETREG (0x5c,0xc0);
 
556
  SETREG (0x5f,0x00);
 
557
  SETREG (0x60,0x02);
 
558
  SETREG (0x61,0x00);
 
559
  SETREG (0x62,0x00);
 
560
  SETREG (0x63,0x00);
 
561
  SETREG (0x64,0x00);
 
562
  SETREG (0x65,0x00);
 
563
  SETREG (0x66,0x00);
 
564
  SETREG (0x67,0x00);
 
565
  SETREG (0x68,0x00);
 
566
  SETREG (0x69,0x00);
 
567
  SETREG (0x6a,0x00);
 
568
  SETREG (0x6b,0x00);
 
569
  SETREG (0x6c,0x00);
 
570
  SETREG (0x6d,0xd0);
 
571
  SETREG (0x6e,0x00);
 
572
  SETREG (0x6f,0x00);
 
573
  SETREG (0x70,0x06);
 
574
  SETREG (0x71,0x08);
 
575
  SETREG (0x72,0x08);
 
576
  SETREG (0x73,0x0a);
 
577
 
 
578
  /* CKxMAP */
 
579
  SETREG (0x74,0x00);
 
580
  SETREG (0x75,0x00);
 
581
  SETREG (0x76,0x3c);
 
582
  SETREG (0x77,0x00);
 
583
  SETREG (0x78,0x00);
 
584
  SETREG (0x79,0x9f);
 
585
  SETREG (0x7a,0x00);
 
586
  SETREG (0x7b,0x00);
 
587
  SETREG (0x7c,0x55);
 
588
 
 
589
  SETREG (0x7d,0x00);
 
590
  SETREG (0x7e,0x08);
 
591
  SETREG (0x7f,0x58);
 
592
  SETREG (0x80,0x00);
 
593
  SETREG (0x81,0x14);
 
594
 
 
595
  /* STRPIXEL */
 
596
  SETREG (0x82,0x00);
 
597
  SETREG (0x83,0x00);
 
598
  SETREG (0x84,0x00);
 
599
  /* ENDPIXEL */
 
600
  SETREG (0x85,0x00);
 
601
  SETREG (0x86,0x00);
 
602
  SETREG (0x87,0x00);
 
603
 
 
604
  SETREG (0x88,0x00);
 
605
  SETREG (0x89,0x65);
 
606
  SETREG (0x8a,0x00);
 
607
  SETREG (0x8b,0x00);
 
608
  SETREG (0x8c,0x00);
 
609
  SETREG (0x8d,0x00);
 
610
  SETREG (0x8e,0x00);
 
611
  SETREG (0x8f,0x00);
 
612
  SETREG (0x90,0x00);
 
613
  SETREG (0x91,0x00);
 
614
  SETREG (0x92,0x00);
 
615
  SETREG (0x93,0x00);
 
616
  SETREG (0x94,0x14);
 
617
  SETREG (0x95,0x30);
 
618
  SETREG (0x96,0x00);
 
619
  SETREG (0x97,0x90);
 
620
  SETREG (0x98,0x01);
 
621
  SETREG (0x99,0x1f);
 
622
  SETREG (0x9a,0x00);
 
623
  SETREG (0x9b,0x80);
 
624
  SETREG (0x9c,0x80);
 
625
  SETREG (0x9d,0x3f);
 
626
  SETREG (0x9e,0x00);
 
627
  SETREG (0x9f,0x00);
 
628
  SETREG (0xa0,0x20);
 
629
  SETREG (0xa1,0x30);
 
630
  SETREG (0xa2,0x00);
 
631
  SETREG (0xa3,0x20);
 
632
  SETREG (0xa4,0x01);
 
633
  SETREG (0xa5,0x00);
 
634
  SETREG (0xa6,0x00);
 
635
  SETREG (0xa7,0x08);
 
636
  SETREG (0xa8,0x00);
 
637
  SETREG (0xa9,0x08);
 
638
  SETREG (0xaa,0x01);
 
639
  SETREG (0xab,0x00);
 
640
  SETREG (0xac,0x00);
 
641
  SETREG (0xad,0x40);
 
642
  SETREG (0xae,0x01);
 
643
  SETREG (0xaf,0x00);
 
644
  SETREG (0xb0,0x00);
 
645
  SETREG (0xb1,0x40);
 
646
  SETREG (0xb2,0x00);
 
647
  SETREG (0xb3,0x09);
 
648
  SETREG (0xb4,0x5b);
 
649
  SETREG (0xb5,0x00);
 
650
  SETREG (0xb6,0x10);
 
651
  SETREG (0xb7,0x3f);
 
652
  SETREG (0xb8,0x00);
 
653
  SETREG (0xbb,0x00);
 
654
  SETREG (0xbc,0xff);
 
655
  SETREG (0xbd,0x00);
 
656
  SETREG (0xbe,0x07);
 
657
  SETREG (0xc3,0x00);
 
658
  SETREG (0xc4,0x00);
 
659
 
 
660
  /* gamma 
 
661
  SETREG (0xc5,0x00);
 
662
  SETREG (0xc6,0x00);
 
663
  SETREG (0xc7,0x00);
 
664
  SETREG (0xc8,0x00);
 
665
  SETREG (0xc9,0x00);
 
666
  SETREG (0xca,0x00);
 
667
  SETREG (0xcb,0x00);
 
668
  SETREG (0xcc,0x00);
 
669
  SETREG (0xcd,0x00);
 
670
  SETREG (0xce,0x00);
 
671
  */
 
672
 
 
673
  /* memory layout 
 
674
  SETREG (0xd0,0x0a);
 
675
  SETREG (0xd1,0x1f);
 
676
  SETREG (0xd2,0x34); */
 
677
  SETREG (0xd3,0x00);
 
678
  SETREG (0xd4,0x00);
 
679
  SETREG (0xd5,0x00);
 
680
  SETREG (0xd6,0x00);
 
681
  SETREG (0xd7,0x00);
 
682
  SETREG (0xd8,0x00);
 
683
  SETREG (0xd9,0x00);
 
684
 
 
685
  /* memory layout
 
686
  SETREG (0xe0,0x00);
 
687
  SETREG (0xe1,0x48);
 
688
  SETREG (0xe2,0x15);
 
689
  SETREG (0xe3,0x90);
 
690
  SETREG (0xe4,0x15);
 
691
  SETREG (0xe5,0x91);
 
692
  SETREG (0xe6,0x2a);
 
693
  SETREG (0xe7,0xd9);
 
694
  SETREG (0xe8,0x2a);
 
695
  SETREG (0xe9,0xad);
 
696
  SETREG (0xea,0x40);
 
697
  SETREG (0xeb,0x22);
 
698
  SETREG (0xec,0x40);
 
699
  SETREG (0xed,0x23);
 
700
  SETREG (0xee,0x55);
 
701
  SETREG (0xef,0x6b);
 
702
  SETREG (0xf0,0x55);
 
703
  SETREG (0xf1,0x6c);
 
704
  SETREG (0xf2,0x6a);
 
705
  SETREG (0xf3,0xb4);
 
706
  SETREG (0xf4,0x6a);
 
707
  SETREG (0xf5,0xb5);
 
708
  SETREG (0xf6,0x7f);
 
709
  SETREG (0xf7,0xfd);*/
 
710
 
 
711
  SETREG (0xf8,0x01);   /* other value is 0x05 */
 
712
  SETREG (0xf9,0x00);
 
713
  SETREG (0xfa,0x00);
 
714
  SETREG (0xfb,0x00);
 
715
  SETREG (0xfc,0x00);
 
716
  SETREG (0xff,0x00);
 
717
 
 
718
  /* fine tune upon device description */
 
719
  dev->reg[reg_0x05].value &= ~REG05_DPIHW;
 
720
  switch (dev->sensor.optical_res)
 
721
    {
 
722
    case 600:
 
723
      dev->reg[reg_0x05].value |= REG05_DPIHW_600;
 
724
      break;
 
725
    case 1200:
 
726
      dev->reg[reg_0x05].value |= REG05_DPIHW_1200;
 
727
      break;
 
728
    case 2400:
 
729
      dev->reg[reg_0x05].value |= REG05_DPIHW_2400;
 
730
      break;
 
731
    case 4800:
 
732
      dev->reg[reg_0x05].value |= REG05_DPIHW_4800;
 
733
      break;
 
734
    }
 
735
 
 
736
  /* initalize calibration reg */
 
737
  memcpy (dev->calib_reg, dev->reg,
 
738
          GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set));
 
739
 
 
740
  DBGCOMPLETED;
 
741
}
 
742
 
 
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
 
750
 */
 
751
static SANE_Status
 
752
gl124_send_slope_table (Genesys_Device * dev, int table_nr,
 
753
                        uint16_t * slope_table, int steps)
 
754
{
 
755
  SANE_Status status;
 
756
  uint8_t *table;
 
757
  int i;
 
758
  char msg[2048];
 
759
 
 
760
  DBG (DBG_proc, "%s (table_nr = %d, steps = %d)\n", __FUNCTION__,
 
761
       table_nr, steps);
 
762
 
 
763
  /* sanity check */
 
764
  if(table_nr<0 || table_nr>4)
 
765
    {
 
766
      DBG (DBG_error, "%s: invalid table number %d!\n", __FUNCTION__, table_nr);
 
767
      return SANE_STATUS_INVAL;
 
768
    }
 
769
 
 
770
  table = (uint8_t *) malloc (steps * 2);
 
771
  for (i = 0; i < steps; i++)
 
772
    {
 
773
      table[i * 2] = slope_table[i] & 0xff;
 
774
      table[i * 2 + 1] = slope_table[i] >> 8;
 
775
    }
 
776
 
 
777
  if (DBG_LEVEL >= DBG_io)
 
778
    {
 
779
      sprintf (msg, "write slope %d (%d)=", table_nr, steps);
 
780
      for (i = 0; i < steps; i++)
 
781
        {
 
782
          sprintf (msg, "%s,%d", msg, slope_table[i]);
 
783
        }
 
784
      DBG (DBG_io, "%s: %s\n", __FUNCTION__, msg);
 
785
    }
 
786
 
 
787
  /* slope table addresses are fixed */
 
788
  status =
 
789
    sanei_genesys_write_ahb (dev->dn, 0x10000000 + 0x4000 * table_nr, steps * 2, table);
 
790
  if (status != SANE_STATUS_GOOD)
 
791
    {
 
792
      DBG (DBG_error,
 
793
           "%s: write to AHB failed writing slope table %d (%s)\n",
 
794
           __FUNCTION__, table_nr, sane_strstatus (status));
 
795
    }
 
796
 
 
797
  free (table);
 
798
  DBGCOMPLETED;
 
799
  return status;
 
800
}
 
801
 
 
802
/**
 
803
 * Set register values of 'special' type frontend
 
804
 * */
 
805
static SANE_Status
 
806
gl124_set_ti_fe (Genesys_Device * dev, uint8_t set)
 
807
{
 
808
  SANE_Status status = SANE_STATUS_GOOD;
 
809
  int i;
 
810
  uint16_t val;
 
811
 
 
812
  DBGSTART;
 
813
  if (set == AFE_INIT)
 
814
    {
 
815
      DBG (DBG_proc, "%s: setting DAC %u\n", __FUNCTION__,
 
816
           dev->model->dac_type);
 
817
 
 
818
      /* sets to default values */
 
819
      sanei_genesys_init_fe (dev);
 
820
    }
 
821
 
 
822
  /* start writing to DAC */
 
823
  status = sanei_genesys_fe_write_data (dev, 0x00, 0x80);
 
824
  if (status != SANE_STATUS_GOOD)
 
825
    {
 
826
      DBG (DBG_error, "%s: failed to write reg0: %s\n", __FUNCTION__,
 
827
           sane_strstatus (status));
 
828
      return status;
 
829
    }
 
830
 
 
831
  /* write values to analog frontend */
 
832
  for (i = 1; i < 4; i++)
 
833
    {
 
834
      val = dev->frontend.reg[i];
 
835
      status = sanei_genesys_fe_write_data (dev, i, val);
 
836
      if (status != SANE_STATUS_GOOD)
 
837
        {
 
838
          DBG (DBG_error,
 
839
               "%s: failed to write reg %d: %s\n", __FUNCTION__, i,
 
840
               sane_strstatus (status));
 
841
          return status;
 
842
        }
 
843
    }
 
844
 
 
845
  status = sanei_genesys_fe_write_data (dev, 0x04, 0x00);
 
846
  if (status != SANE_STATUS_GOOD)
 
847
    {
 
848
      DBG (DBG_error, "%s: failed to write reg4: %s\n", __FUNCTION__,
 
849
           sane_strstatus (status));
 
850
      return status;
 
851
    }
 
852
 
 
853
  /* these are not really sign */
 
854
  for (i = 0; i < 3; i++)
 
855
    {
 
856
      val = dev->frontend.sign[i];
 
857
      status = sanei_genesys_fe_write_data (dev, 0x05 + i, val);
 
858
      if (status != SANE_STATUS_GOOD)
 
859
        {
 
860
          DBG (DBG_error,
 
861
               "%s: failed to write reg %d: %s\n", __FUNCTION__, i+5,
 
862
               sane_strstatus (status));
 
863
          return status;
 
864
        }
 
865
    }
 
866
 
 
867
  /* close writing to DAC */
 
868
  status = sanei_genesys_fe_write_data (dev, 0x00, 0x11);
 
869
  if (status != SANE_STATUS_GOOD)
 
870
    {
 
871
      DBG (DBG_error, "%s: failed to write reg0: %s\n", __FUNCTION__,
 
872
           sane_strstatus (status));
 
873
      return status;
 
874
    }
 
875
 
 
876
  DBGCOMPLETED;
 
877
 
 
878
  return status;
 
879
}
 
880
 
 
881
 
 
882
/* Set values of analog frontend */
 
883
static SANE_Status
 
884
gl124_set_fe (Genesys_Device * dev, uint8_t set)
 
885
{
 
886
  SANE_Status status;
 
887
  uint8_t val;
 
888
 
 
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?");
 
892
 
 
893
  if (set == AFE_INIT)
 
894
    {
 
895
      DBG (DBG_proc, "gl124_set_fe(): setting DAC %u\n",
 
896
           dev->model->dac_type);
 
897
      sanei_genesys_init_fe (dev);
 
898
    }
 
899
 
 
900
  RIE (sanei_genesys_read_register (dev, REG0A, &val));
 
901
 
 
902
  /* route to correct analog FE */
 
903
  switch ((val & REG0A_SIFSEL)>>REG0AS_SIFSEL)
 
904
    {
 
905
    case 3:
 
906
      status=gl124_set_ti_fe (dev, set);
 
907
      break;
 
908
    case 0:
 
909
    case 1:
 
910
    case 2:
 
911
    default:
 
912
      DBG (DBG_error, "%s: unsupported anlog FE 0x%02x\n",__FUNCTION__,val);
 
913
      status=SANE_STATUS_INVAL;
 
914
      break;
 
915
    }
 
916
 
 
917
  DBGCOMPLETED;
 
918
  return status;
 
919
}
 
920
 
 
921
 
 
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
 
928
 */
 
929
static int gl124_compute_dpihw(Genesys_Device *dev, int xres)
 
930
{
 
931
  switch(dev->model->ccd_type)
 
932
    {
 
933
    default:
 
934
      if(xres<=dev->sensor.optical_res/4)
 
935
        {
 
936
          return dev->sensor.optical_res/4;
 
937
        }
 
938
      if(xres<=dev->sensor.optical_res/2)
 
939
        {
 
940
          return dev->sensor.optical_res/2;
 
941
        }
 
942
      return dev->sensor.optical_res;
 
943
    }
 
944
}
 
945
 
 
946
/**@brief compute exposure to use
 
947
 * compute the sensor exposure based on target resolution
 
948
 */
 
949
static int gl124_compute_exposure(Genesys_Device *dev, int xres)
 
950
{
 
951
  Sensor_Profile *sensor;
 
952
 
 
953
  sensor=get_sensor_profile(dev->model->ccd_type, xres);
 
954
  return sensor->exposure;
 
955
}
 
956
 
 
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
 
963
 *         1 for half step
 
964
 *         2 for quarter step
 
965
 *         3 for eighth step
 
966
 */
 
967
static int gl124_compute_step_type(Genesys_Device *dev, int exposure)
 
968
{
 
969
Motor_Profile *profile;
 
970
 
 
971
    profile=get_motor_profile(dev->model->motor_type,exposure);
 
972
    return profile->step_type;
 
973
}
 
974
 
 
975
#define MOTOR_FLAG_AUTO_GO_HOME             1
 
976
#define MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE 2
 
977
#define MOTOR_FLAG_FEED                     4
 
978
 
 
979
 
 
980
static SANE_Status
 
981
gl124_init_motor_regs_scan (Genesys_Device * dev,
 
982
                            Genesys_Register_Set * reg,
 
983
                            unsigned int scan_exposure_time,
 
984
                            float scan_yres,
 
985
                            int scan_step_type,
 
986
                            unsigned int scan_lines,
 
987
                            unsigned int scan_dummy,
 
988
                            unsigned int feed_steps,
 
989
                            int scan_mode,
 
990
                            unsigned int flags)
 
991
{
 
992
  SANE_Status status;
 
993
  int use_fast_fed;
 
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;
 
1002
  uint32_t z1, z2;
 
1003
  float yres;
 
1004
 
 
1005
  DBGSTART;
 
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",
 
1009
       scan_exposure_time,
 
1010
       scan_yres,
 
1011
       scan_step_type,
 
1012
       scan_lines, scan_dummy, feed_steps, scan_mode, flags);
 
1013
 
 
1014
  /* we never use fast fed since we do manual feed for the scans */
 
1015
  use_fast_fed=0;
 
1016
  factor=1;
 
1017
 
 
1018
  if(dev->line_interp>0)
 
1019
    {
 
1020
      lincnt=scan_lines*dev->line_interp;
 
1021
    }
 
1022
  else
 
1023
    {
 
1024
      lincnt=scan_lines;
 
1025
    }
 
1026
      
 
1027
  yres=scan_yres;
 
1028
  if ((scan_mode == SCAN_MODE_COLOR) && (yres<900))
 
1029
    {
 
1030
      yres=900;
 
1031
    }
 
1032
  if ((scan_mode != SCAN_MODE_COLOR) && (yres<300))
 
1033
    {
 
1034
        yres=300;
 
1035
    }
 
1036
 
 
1037
  sanei_genesys_set_triple(reg,REG_LINCNT,lincnt);
 
1038
  DBG (DBG_io, "%s: lincnt=%d\n", __FUNCTION__, lincnt);
 
1039
 
 
1040
  /* compute register 02 value */
 
1041
  r = sanei_genesys_get_address (reg, REG02);
 
1042
  r->value = REG02_NOTHOME;
 
1043
  r->value |= REG02_MTRPWR;
 
1044
 
 
1045
  if (use_fast_fed)
 
1046
    r->value |= REG02_FASTFED;
 
1047
  else
 
1048
    r->value &= ~REG02_FASTFED;
 
1049
 
 
1050
  if (flags & MOTOR_FLAG_AUTO_GO_HOME)
 
1051
    r->value |= REG02_AGOHOME;
 
1052
 
 
1053
  if ((flags & MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE)
 
1054
    ||(yres>=dev->sensor.optical_res))
 
1055
    r->value |= REG02_ACDCDIS;
 
1056
 
 
1057
  /* SCANFED */
 
1058
  sanei_genesys_set_double(reg,REG_SCANFED,4);
 
1059
 
 
1060
  /* scan and backtracking slope table */
 
1061
  slow_time=gl124_slope_table(scan_table,
 
1062
                              &scan_steps,
 
1063
                              yres,
 
1064
                              scan_exposure_time,
 
1065
                              dev->motor.base_ydpi,
 
1066
                              scan_step_type,
 
1067
                              factor,
 
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));
 
1071
 
 
1072
  /* STEPNO */
 
1073
  sanei_genesys_set_double(reg,REG_STEPNO,scan_steps);
 
1074
 
 
1075
  /* fast table */
 
1076
  fast_dpi=yres;
 
1077
  if (scan_mode != SCAN_MODE_COLOR)
 
1078
    {
 
1079
      fast_dpi*=3;
 
1080
    }
 
1081
  fast_time=gl124_slope_table(fast_table,
 
1082
                              &fast_steps,
 
1083
                              fast_dpi,
 
1084
                              scan_exposure_time,
 
1085
                              dev->motor.base_ydpi,
 
1086
                              scan_step_type,
 
1087
                              factor,
 
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));
 
1091
 
 
1092
  /* FASTNO */
 
1093
  sanei_genesys_set_double(reg,REG_FASTNO,fast_steps);
 
1094
 
 
1095
  /* FSHDEC */
 
1096
  sanei_genesys_set_double(reg,REG_FSHDEC,fast_steps);
 
1097
 
 
1098
  /* FMOVNO */
 
1099
  sanei_genesys_set_double(reg,REG_FMOVNO,fast_steps);
 
1100
 
 
1101
  /* substract acceleration distance from feedl */
 
1102
  feedl=feed_steps;
 
1103
  feedl<<=scan_step_type;
 
1104
 
 
1105
  dist = scan_steps;
 
1106
  if (use_fast_fed) 
 
1107
    {
 
1108
        dist += fast_steps*2;
 
1109
    }
 
1110
  DBG (DBG_io2, "%s: acceleration distance=%d\n", __FUNCTION__, dist);
 
1111
 
 
1112
  /* get sure we don't use insane value */
 
1113
  if(dist<feedl)
 
1114
    feedl -= dist;
 
1115
  else
 
1116
    feedl = 1;
 
1117
 
 
1118
  sanei_genesys_set_triple(reg,REG_FEEDL,feedl);
 
1119
  DBG (DBG_io, "%s: feedl=%d\n", __FUNCTION__, feedl);
 
1120
 
 
1121
  /* doesn't seem to matter that much */
 
1122
  sanei_genesys_calculate_zmode2 (use_fast_fed,
 
1123
                                  scan_exposure_time,
 
1124
                                  scan_table,
 
1125
                                  scan_steps,
 
1126
                                  feedl,
 
1127
                                  scan_steps,
 
1128
                                  &z1,
 
1129
                                  &z2);
 
1130
 
 
1131
  sanei_genesys_set_triple(reg,REG_Z1MOD,z1);
 
1132
  DBG (DBG_info, "gl124_init_motor_regs_scan: z1 = %d\n", z1);
 
1133
 
 
1134
  sanei_genesys_set_triple(reg,REG_Z2MOD,z2);
 
1135
  DBG (DBG_info, "gl124_init_motor_regs_scan: z2 = %d\n", z2);
 
1136
 
 
1137
  /* LINESEL */
 
1138
  r = sanei_genesys_get_address (reg, REG1D);
 
1139
  r->value = (r->value & ~REG1D_LINESEL) | scan_dummy;
 
1140
 
 
1141
  r = sanei_genesys_get_address (reg, REGA0);
 
1142
  r->value = (scan_step_type << REGA0S_STEPSEL) | (scan_step_type << REGA0S_FSTPSEL);
 
1143
  
 
1144
  /* FMOVDEC */
 
1145
  sanei_genesys_set_double(reg,REG_FMOVDEC,fast_steps);
 
1146
 
 
1147
  DBGCOMPLETED;
 
1148
  return SANE_STATUS_GOOD;
 
1149
}
 
1150
 
 
1151
 
 
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
 
1157
 * */
 
1158
static void
 
1159
gl124_setup_sensor (Genesys_Device * dev, Genesys_Register_Set * regs, int dpi)
 
1160
{
 
1161
  Genesys_Register_Set *r;
 
1162
  int i;
 
1163
  Sensor_Profile *sensor;
 
1164
  int dpihw;
 
1165
  uint32_t exp;
 
1166
 
 
1167
  DBGSTART;
 
1168
 
 
1169
  /* we start at 6, 0-5 is a 16 bits cache for exposure */
 
1170
  for (i = 0x06; i < 0x0e; i++)
 
1171
    {
 
1172
      r = sanei_genesys_get_address (regs, 0x10 + i);
 
1173
      if (r)
 
1174
        r->value = dev->sensor.regs_0x10_0x1d[i];
 
1175
    }
 
1176
 
 
1177
  for (i = 0; i < 11; i++)
 
1178
    {
 
1179
      r = sanei_genesys_get_address (regs, 0x52 + i);
 
1180
      if (r)
 
1181
        r->value = dev->sensor.regs_0x52_0x5e[i];
 
1182
    }
 
1183
 
 
1184
  /* set EXPDUMMY and CKxMAP */
 
1185
  dpihw=gl124_compute_dpihw(dev,dpi);
 
1186
  sensor=get_sensor_profile(dev->model->ccd_type, dpihw);
 
1187
      
 
1188
  r = sanei_genesys_get_address (regs, 0x18);
 
1189
  if (r)
 
1190
    {
 
1191
      r->value = sensor->reg18;
 
1192
    }
 
1193
  r = sanei_genesys_get_address (regs, 0x20);
 
1194
  if (r)
 
1195
    {
 
1196
      r->value = sensor->reg20;
 
1197
    }
 
1198
  r = sanei_genesys_get_address (regs, 0x61);
 
1199
  if (r)
 
1200
    {
 
1201
      r->value = sensor->reg61;
 
1202
    }
 
1203
  r = sanei_genesys_get_address (regs, 0x98);
 
1204
  if (r)
 
1205
    {
 
1206
      r->value = sensor->reg98;
 
1207
    }
 
1208
 
 
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);
 
1212
 
 
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];
 
1215
  if(exp==0)
 
1216
    {
 
1217
      exp=sensor->expr;
 
1218
    }
 
1219
  sanei_genesys_set_triple(regs,REG_EXPR,exp);
 
1220
 
 
1221
  exp=dev->sensor.regs_0x10_0x1d[2]*256+dev->sensor.regs_0x10_0x1d[3];
 
1222
  if(exp==0)
 
1223
    {
 
1224
      exp=sensor->expg;
 
1225
    }
 
1226
  sanei_genesys_set_triple(regs,REG_EXPG,exp);
 
1227
 
 
1228
  exp=dev->sensor.regs_0x10_0x1d[4]*256+dev->sensor.regs_0x10_0x1d[5];
 
1229
  if(exp==0)
 
1230
    {
 
1231
      exp=sensor->expb;
 
1232
    }
 
1233
  sanei_genesys_set_triple(regs,REG_EXPB,exp);
 
1234
 
 
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);
 
1238
 
 
1239
  DBGCOMPLETED;
 
1240
}
 
1241
 
 
1242
 
 
1243
 
 
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
 
1249
 
 
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
 
1257
 */
 
1258
static SANE_Status
 
1259
gl124_init_optical_regs_scan (Genesys_Device * dev,
 
1260
                              Genesys_Register_Set * reg,
 
1261
                              unsigned int exposure_time,
 
1262
                              int used_res,
 
1263
                              unsigned int start,
 
1264
                              unsigned int pixels,
 
1265
                              int channels,
 
1266
                              int depth,
 
1267
                              SANE_Bool half_ccd, int color_filter, int flags)
 
1268
{
 
1269
  unsigned int words_per_line, segcnt;
 
1270
  unsigned int startx, endx, used_pixels, segnb;
 
1271
  unsigned int dpiset, cksel, dpihw, factor;
 
1272
  unsigned int bytes;
 
1273
  Genesys_Register_Set *r;
 
1274
  SANE_Status status;
 
1275
 
 
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);
 
1280
 
 
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);
 
1285
 
 
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);
 
1291
 
 
1292
  /* sensor parameters */
 
1293
  gl124_setup_sensor (dev, reg, dpihw);
 
1294
  dpiset = used_res * cksel;
 
1295
 
 
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;
 
1301
 
 
1302
  /* pixel coordinate factor correction when used dpihw is not maximal one */
 
1303
  startx/=factor;
 
1304
  endx/=factor;
 
1305
  used_pixels=endx-startx;
 
1306
 
 
1307
  status = gl124_set_fe (dev, AFE_SET);
 
1308
  if (status != SANE_STATUS_GOOD)
 
1309
    {
 
1310
      DBG (DBG_error, "%s: failed to set frontend: %s\n", __FUNCTION__,
 
1311
           sane_strstatus (status));
 
1312
      return status;
 
1313
    }
 
1314
 
 
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))
 
1320
    {
 
1321
      r->value &= ~REG01_DVDSET;
 
1322
    }
 
1323
  else
 
1324
    {
 
1325
      r->value |= REG01_DVDSET;
 
1326
    }
 
1327
  r->value &= ~REG01_SCAN;
 
1328
 
 
1329
  r = sanei_genesys_get_address (reg, REG03);
 
1330
  r->value &= ~REG03_AVEENB;
 
1331
 
 
1332
  if (flags & OPTICAL_FLAG_DISABLE_LAMP)
 
1333
    r->value &= ~REG03_LAMPPWR;
 
1334
  else
 
1335
    r->value |= REG03_LAMPPWR;
 
1336
 
 
1337
  /* BW threshold */
 
1338
  RIE (sanei_genesys_write_hregister (dev, REG114, dev->settings.threshold));
 
1339
  RIE (sanei_genesys_write_hregister (dev, REG115, dev->settings.threshold));
 
1340
 
 
1341
  /* monochrome / color scan */
 
1342
  r = sanei_genesys_get_address (reg, REG04);
 
1343
  switch (depth)
 
1344
    {
 
1345
    case 1:
 
1346
      r->value &= ~REG04_BITSET;
 
1347
      r->value |= REG04_LINEART;
 
1348
      break;
 
1349
    case 8:
 
1350
      r->value &= ~(REG04_LINEART | REG04_BITSET);
 
1351
      break;
 
1352
    case 16:
 
1353
      r->value &= ~REG04_LINEART;
 
1354
      r->value |= REG04_BITSET;
 
1355
      break;
 
1356
    }
 
1357
 
 
1358
  r->value &= ~REG04_FILTER;
 
1359
  if (channels == 1)
 
1360
    {
 
1361
      switch (color_filter)
 
1362
        {
 
1363
        case 0:
 
1364
          r->value |= 0x10;     /* red filter */
 
1365
          break;
 
1366
        case 2:
 
1367
          r->value |= 0x30;     /* blue filter */
 
1368
          break;
 
1369
        default:
 
1370
          r->value |= 0x20;     /* green filter */
 
1371
          break;
 
1372
        }
 
1373
    }
 
1374
 
 
1375
  /* register 05 */
 
1376
  r = sanei_genesys_get_address (reg, REG05);
 
1377
 
 
1378
  /* set up dpihw */
 
1379
  r->value &= ~REG05_DPIHW;
 
1380
  switch(dpihw)
 
1381
    {
 
1382
      case 600:
 
1383
        r->value |= REG05_DPIHW_600;
 
1384
        break;
 
1385
      case 1200:
 
1386
        r->value |= REG05_DPIHW_1200;
 
1387
        break;
 
1388
      case 2400:
 
1389
        r->value |= REG05_DPIHW_2400;
 
1390
        break;
 
1391
      case 4800:
 
1392
        r->value |= REG05_DPIHW_4800;
 
1393
        break;
 
1394
    }
 
1395
 
 
1396
  /* enable gamma tables */
 
1397
  if (flags & OPTICAL_FLAG_DISABLE_GAMMA)
 
1398
    r->value &= ~REG05_GMMENB;
 
1399
  else
 
1400
    r->value |= REG05_GMMENB;
 
1401
 
 
1402
  sanei_genesys_set_double(reg,REG_DPISET,dpiset);
 
1403
  DBG (DBG_io2, "%s: dpiset used=%d\n", __FUNCTION__, dpiset);
 
1404
 
 
1405
  /* segment number */
 
1406
  r = sanei_genesys_get_address (reg, 0x98);
 
1407
  segnb = r->value & 0x0f;
 
1408
 
 
1409
  sanei_genesys_set_triple(reg,REG_STRPIXEL,startx/segnb);
 
1410
  sanei_genesys_get_triple(reg,REG_SEGCNT,&segcnt);
 
1411
  if(endx/segnb==segcnt)
 
1412
    {
 
1413
      endx=0;
 
1414
    }
 
1415
  sanei_genesys_set_triple(reg,REG_ENDPIXEL,endx/segnb);
 
1416
  
 
1417
  /* words(16bit) before gamma, conversion to 8 bit or lineart */
 
1418
  words_per_line = (used_pixels * dpiset) / dpihw;
 
1419
  bytes = depth / 8;
 
1420
  if (depth == 1)
 
1421
    {
 
1422
      words_per_line = (words_per_line >> 3) + ((words_per_line & 7) ? 1 : 0);
 
1423
    }
 
1424
  else
 
1425
    {
 
1426
      words_per_line *= bytes;
 
1427
    }
 
1428
 
 
1429
  dev->bpl = words_per_line;
 
1430
  dev->cur = 0;
 
1431
  dev->len = dev->bpl/segnb;
 
1432
  dev->dist = dev->bpl/segnb;
 
1433
  dev->segnb = segnb;
 
1434
  dev->skip = 0;
 
1435
  dev->line_count = 0;
 
1436
  if(dpiset>=300)
 
1437
    {
 
1438
      dev->line_interp = 0;
 
1439
    }
 
1440
  else
 
1441
    {
 
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
 
1445
       */
 
1446
      dev->line_interp = 300/dpiset;
 
1447
    }
 
1448
 
 
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);
 
1456
 
 
1457
  words_per_line *= channels;
 
1458
  dev->wpl = words_per_line;
 
1459
 
 
1460
  /* allocate buffer for odd/even pixles handling */
 
1461
  if(dev->oe_buffer.buffer!=NULL)
 
1462
    {
 
1463
      sanei_genesys_buffer_free (&(dev->oe_buffer));
 
1464
    }
 
1465
  RIE (sanei_genesys_buffer_alloc (&(dev->oe_buffer), dev->wpl));
 
1466
 
 
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);
 
1470
 
 
1471
  sanei_genesys_set_triple(reg,REG_LPERIOD,exposure_time);
 
1472
  DBG (DBG_io2, "%s: exposure_time used=%d\n", __FUNCTION__, exposure_time);
 
1473
 
 
1474
  sanei_genesys_set_double(reg,REG_DUMMY,dev->sensor.dummy_pixel);
 
1475
 
 
1476
  DBGCOMPLETED;
 
1477
  return SANE_STATUS_GOOD;
 
1478
}
 
1479
 
 
1480
/* set up registers for an actual scan
 
1481
 *
 
1482
 * this function sets up the scanner to scan in normal or single line mode
 
1483
 */
 
1484
#ifndef UNIT_TESTING
 
1485
static
 
1486
#endif
 
1487
  SANE_Status
 
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! */
 
1494
                      float pixels,
 
1495
                      float lines,
 
1496
                      unsigned int depth,
 
1497
                      unsigned int channels,
 
1498
                      int color_filter, unsigned int flags)
 
1499
{
 
1500
  int used_res;
 
1501
  int start, used_pixels;
 
1502
  int bytes_per_line;
 
1503
  int move;
 
1504
  unsigned int lincnt;
 
1505
  unsigned int oflags, mflags; /**> optical and motor flags */
 
1506
  int exposure_time;
 
1507
  int stagger;
 
1508
 
 
1509
  int slope_dpi = 0;
 
1510
  int dummy = 0;
 
1511
  int scan_step_type = 1;
 
1512
  int max_shift;
 
1513
  size_t requested_buffer_size, read_buffer_size;
 
1514
 
 
1515
  SANE_Bool half_ccd;           /* false: full CCD res is used, true, half max CCD res is used */
 
1516
  int optical_res;
 
1517
  SANE_Status status;
 
1518
 
 
1519
  DBG (DBG_info,
 
1520
       "gl124_init_scan_regs settings:\n"
 
1521
       "Resolution    : %gDPI/%gDPI\n"
 
1522
       "Lines         : %g\n"
 
1523
       "PPL           : %g\n"
 
1524
       "Startpos      : %g/%g\n"
 
1525
       "Depth/Channels: %u/%u\n"
 
1526
       "Flags         : %x\n\n",
 
1527
       xres, yres, lines, pixels, startx, starty, depth, channels, flags);
 
1528
 
 
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))
 
1532
    {
 
1533
      half_ccd = SANE_FALSE;
 
1534
    }
 
1535
  else
 
1536
    {
 
1537
      half_ccd = SANE_TRUE;
 
1538
    }
 
1539
 
 
1540
  /* optical_res */
 
1541
  optical_res = dev->sensor.optical_res;
 
1542
  if (half_ccd)
 
1543
    optical_res /= 2;
 
1544
 
 
1545
  /* stagger */
 
1546
  if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE))
 
1547
    stagger = (4 * yres) / dev->motor.base_ydpi;
 
1548
  else
 
1549
    stagger = 0;
 
1550
  DBG (DBG_info, "gl124_init_scan_regs : stagger=%d lines\n", stagger);
 
1551
 
 
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
 
1555
   * */
 
1556
  if (flags & SCAN_FLAG_USE_OPTICAL_RES)
 
1557
    {
 
1558
      used_res = optical_res;
 
1559
    }
 
1560
  else
 
1561
    {
 
1562
      /* resolution is choosen from a fixed list and can be used directly */
 
1563
      if(xres>optical_res)
 
1564
        used_res=optical_res;
 
1565
      else
 
1566
        used_res = xres;
 
1567
    }
 
1568
 
 
1569
  /* compute scan parameters values */
 
1570
  /* pixels are allways given at full optical resolution */
 
1571
  /* use detected left margin and fixed value */
 
1572
  /* start */
 
1573
  /* add x coordinates */
 
1574
  start = startx;
 
1575
 
 
1576
  if (stagger > 0)
 
1577
    start |= 1;
 
1578
 
 
1579
  /* compute correct pixels number */
 
1580
  /* pixels */
 
1581
  used_pixels = (pixels * optical_res) / xres;
 
1582
  DBG (DBG_info, "%s: used_pixels=%d\n", __FUNCTION__, used_pixels);
 
1583
 
 
1584
  /* round up pixels number if needed */
 
1585
  if (used_pixels * xres < pixels * optical_res)
 
1586
    used_pixels++;
 
1587
 
 
1588
  /* we want even number of pixels here */
 
1589
  if(used_pixels & 1)
 
1590
    used_pixels++;
 
1591
 
 
1592
  dummy = 0;
 
1593
 
 
1594
  /* slope_dpi */
 
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;
 
1598
  else
 
1599
    slope_dpi = yres;
 
1600
 
 
1601
  /* scan_step_type */
 
1602
  if(flags & SCAN_FLAG_FEEDING)
 
1603
    {
 
1604
      scan_step_type=0;
 
1605
      exposure_time=MOVE_EXPOSURE;
 
1606
    }
 
1607
  else
 
1608
    {
 
1609
      exposure_time = gl124_compute_exposure (dev, used_res);
 
1610
      scan_step_type = gl124_compute_step_type(dev, exposure_time);
 
1611
    }
 
1612
 
 
1613
  DBG (DBG_info, "gl124_init_scan_regs : exposure_time=%d pixels\n",
 
1614
       exposure_time);
 
1615
  DBG (DBG_info, "gl124_init_scan_regs : scan_step_type=%d\n",
 
1616
       scan_step_type);
 
1617
 
 
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))
 
1623
    {
 
1624
      depth = 8;
 
1625
    }
 
1626
 
 
1627
  /* we enable true gray for cis scanners only, and just when doing 
 
1628
   * scan since color calibration is OK for this mode
 
1629
   */
 
1630
  oflags = 0;
 
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;
 
1639
 
 
1640
  /* now _LOGICAL_ optical values used are known, setup registers */
 
1641
  status = gl124_init_optical_regs_scan (dev,
 
1642
                                         reg,
 
1643
                                         exposure_time,
 
1644
                                         used_res,
 
1645
                                         start,
 
1646
                                         used_pixels,
 
1647
                                         channels,
 
1648
                                         depth,
 
1649
                                         half_ccd, color_filter, oflags);
 
1650
 
 
1651
  if (status != SANE_STATUS_GOOD)
 
1652
    return status;
 
1653
 
 
1654
/*** motor parameters ***/
 
1655
 
 
1656
/* max_shift */
 
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))
 
1660
    {
 
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;
 
1667
    }
 
1668
  else
 
1669
    {
 
1670
      max_shift = 0;
 
1671
    }
 
1672
 
 
1673
  /* lines to scan */
 
1674
  lincnt = lines + max_shift + stagger;
 
1675
 
 
1676
  /* add tl_y to base movement */
 
1677
  move = starty;
 
1678
  DBG (DBG_info, "gl124_init_scan_regs: move=%d steps\n", move);
 
1679
 
 
1680
  mflags=0;
 
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;
 
1685
 
 
1686
    status = gl124_init_motor_regs_scan (dev,
 
1687
                                         reg,
 
1688
                                         exposure_time,
 
1689
                                         slope_dpi,
 
1690
                                         scan_step_type,
 
1691
                                         dev->model->is_cis ? lincnt * channels : lincnt,
 
1692
                                         dummy,
 
1693
                                         move,
 
1694
                                         dev->settings.scan_mode,
 
1695
                                         mflags);
 
1696
  if (status != SANE_STATUS_GOOD)
 
1697
    return status;
 
1698
 
 
1699
  /*** prepares data reordering ***/
 
1700
 
 
1701
  /* words_per_line */
 
1702
  bytes_per_line = (used_pixels * used_res) / optical_res;
 
1703
  bytes_per_line = (bytes_per_line * channels * depth) / 8;
 
1704
 
 
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;
 
1709
 
 
1710
  read_buffer_size =
 
1711
    2 * requested_buffer_size +
 
1712
    ((max_shift + stagger) * used_pixels * channels * depth) / 8;
 
1713
 
 
1714
  RIE (sanei_genesys_buffer_free (&(dev->read_buffer)));
 
1715
  RIE (sanei_genesys_buffer_alloc (&(dev->read_buffer), read_buffer_size));
 
1716
 
 
1717
  RIE (sanei_genesys_buffer_free (&(dev->lines_buffer)));
 
1718
  RIE (sanei_genesys_buffer_alloc (&(dev->lines_buffer), read_buffer_size));
 
1719
 
 
1720
  RIE (sanei_genesys_buffer_free (&(dev->shrink_buffer)));
 
1721
  RIE (sanei_genesys_buffer_alloc (&(dev->shrink_buffer),
 
1722
                                   requested_buffer_size));
 
1723
 
 
1724
  RIE (sanei_genesys_buffer_free (&(dev->out_buffer)));
 
1725
  RIE (sanei_genesys_buffer_alloc (&(dev->out_buffer),
 
1726
                                   (8 * dev->settings.pixels * channels *
 
1727
                                    depth) / 8));
 
1728
 
 
1729
 
 
1730
  dev->read_bytes_left = bytes_per_line * lincnt;
 
1731
 
 
1732
  DBG (DBG_info,
 
1733
       "gl124_init_scan_regs: physical bytes to read = %lu\n",
 
1734
       (u_long) dev->read_bytes_left);
 
1735
  dev->read_active = SANE_TRUE;
 
1736
 
 
1737
 
 
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;
 
1749
 
 
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)) *
 
1755
      channels;
 
1756
  else
 
1757
    dev->total_bytes_to_read =
 
1758
      dev->settings.pixels * dev->settings.lines * channels * (depth / 8);
 
1759
 
 
1760
  DBG (DBG_info, "gl124_init_scan_regs: total bytes to send = %lu\n",
 
1761
       (u_long) dev->total_bytes_to_read);
 
1762
 
 
1763
  DBGCOMPLETED;
 
1764
  return SANE_STATUS_GOOD;
 
1765
}
 
1766
 
 
1767
static SANE_Status
 
1768
gl124_calculate_current_setup (Genesys_Device * dev)
 
1769
{
 
1770
  int channels;
 
1771
  int depth;
 
1772
  int start;
 
1773
 
 
1774
  float xres;                   /*dpi */
 
1775
  float yres;                   /*dpi */
 
1776
  float startx;                 /*optical_res, from dummy_pixel+1 */
 
1777
  float pixels;
 
1778
  float lines;
 
1779
  int color_filter;
 
1780
 
 
1781
  int used_res;
 
1782
  int used_pixels;
 
1783
  unsigned int lincnt;
 
1784
  int exposure_time;
 
1785
  int stagger;
 
1786
 
 
1787
  int slope_dpi = 0;
 
1788
  int dummy = 0;
 
1789
  int scan_step_type = 1;
 
1790
  int max_shift, dpihw;
 
1791
  Sensor_Profile *sensor;
 
1792
 
 
1793
  SANE_Bool half_ccd;           /* false: full CCD res is used, true, half max CCD res is used */
 
1794
  int optical_res;
 
1795
 
 
1796
  DBG (DBG_info,
 
1797
       "gl124_calculate_current_setup settings:\n"
 
1798
       "Resolution: %ux%uDPI\n"
 
1799
       "Lines     : %u\n"
 
1800
       "PPL       : %u\n"
 
1801
       "Startpos  : %.3f/%.3f\n"
 
1802
       "Scan mode : %d\n\n",
 
1803
       dev->settings.xres,
 
1804
       dev->settings.yres, dev->settings.lines, dev->settings.pixels,
 
1805
       dev->settings.tl_x, dev->settings.tl_y, dev->settings.scan_mode);
 
1806
 
 
1807
  /* channels */
 
1808
  if (dev->settings.scan_mode == 4)     /* single pass color */
 
1809
    channels = 3;
 
1810
  else
 
1811
    channels = 1;
 
1812
 
 
1813
  /* depth */
 
1814
  depth = dev->settings.depth;
 
1815
  if (dev->settings.scan_mode == 0)
 
1816
    depth = 1;
 
1817
 
 
1818
  /* start */
 
1819
  start = SANE_UNFIX (dev->model->x_offset);
 
1820
  start += dev->settings.tl_x;
 
1821
  start = (start * dev->sensor.optical_res) / MM_PER_INCH;
 
1822
 
 
1823
 
 
1824
  xres = dev->settings.xres;
 
1825
  yres = dev->settings.yres;
 
1826
  startx = start;
 
1827
  pixels = dev->settings.pixels;
 
1828
  lines = dev->settings.lines;
 
1829
  color_filter = dev->settings.color_filter;
 
1830
 
 
1831
 
 
1832
  DBG (DBG_info,
 
1833
       "gl124_calculate_current_setup settings:\n"
 
1834
       "Resolution    : %gDPI/%gDPI\n"
 
1835
       "Lines         : %g\n"
 
1836
       "PPL           : %g\n"
 
1837
       "Startpos      : %g\n"
 
1838
       "Depth/Channels: %u/%u\n\n",
 
1839
       xres, yres, lines, pixels, startx, depth, channels);
 
1840
 
 
1841
/* half_ccd */
 
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))
 
1845
    {
 
1846
      half_ccd = SANE_FALSE;
 
1847
    }
 
1848
  else
 
1849
    {
 
1850
      half_ccd = SANE_TRUE;
 
1851
    }
 
1852
 
 
1853
 
 
1854
  /* optical_res */
 
1855
  optical_res = dev->sensor.optical_res;
 
1856
  if (half_ccd)
 
1857
    optical_res /= 2;
 
1858
 
 
1859
  /* stagger */
 
1860
  if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE))
 
1861
    stagger = (4 * yres) / dev->motor.base_ydpi;
 
1862
  else
 
1863
    stagger = 0;
 
1864
  DBG (DBG_info, "%s: stagger=%d lines\n", __FUNCTION__, stagger);
 
1865
 
 
1866
  if(xres<=optical_res)
 
1867
    used_res = xres;
 
1868
  else
 
1869
    used_res=optical_res;
 
1870
 
 
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 */
 
1874
 
 
1875
  /* compute correct pixels number */
 
1876
  used_pixels = (pixels * optical_res) / xres;
 
1877
  DBG (DBG_info, "%s: used_pixels=%d\n", __FUNCTION__, used_pixels);
 
1878
  dummy = 0;
 
1879
 
 
1880
  /* slope_dpi */
 
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;
 
1885
  else
 
1886
    slope_dpi = yres;
 
1887
 
 
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);
 
1892
 
 
1893
/* max_shift */
 
1894
  /* scanned area must be enlarged by max color shift needed */
 
1895
  /* all values are assumed >= 0 */
 
1896
  if (channels > 1)
 
1897
    {
 
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;
 
1904
    }
 
1905
  else
 
1906
    {
 
1907
      max_shift = 0;
 
1908
    }
 
1909
  
 
1910
  dpihw=gl124_compute_dpihw(dev,used_res);
 
1911
  sensor=get_sensor_profile(dev->model->ccd_type, dpihw);
 
1912
  dev->segnb=sensor->reg98 & 0x0f;
 
1913
 
 
1914
  /* lincnt */
 
1915
  lincnt = lines + max_shift + stagger;
 
1916
 
 
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;
 
1928
 
 
1929
  DBGCOMPLETED;
 
1930
  return SANE_STATUS_GOOD;
 
1931
}
 
1932
 
 
1933
static void
 
1934
gl124_set_motor_power (Genesys_Register_Set * regs, SANE_Bool set)
 
1935
{
 
1936
 
 
1937
  DBG (DBG_proc, "gl124_set_motor_power\n");
 
1938
 
 
1939
  if (set)
 
1940
    {
 
1941
      sanei_genesys_set_reg_from_set (regs, REG02,
 
1942
                                      sanei_genesys_read_reg_from_set (regs,
 
1943
                                                                       REG02)
 
1944
                                      | REG02_MTRPWR);
 
1945
    }
 
1946
  else
 
1947
    {
 
1948
      sanei_genesys_set_reg_from_set (regs, REG02,
 
1949
                                      sanei_genesys_read_reg_from_set (regs,
 
1950
                                                                       REG02)
 
1951
                                      & ~REG02_MTRPWR);
 
1952
    }
 
1953
}
 
1954
 
 
1955
static void
 
1956
gl124_set_lamp_power (Genesys_Device * dev,
 
1957
                      Genesys_Register_Set * regs, SANE_Bool set)
 
1958
{
 
1959
  if (dev == NULL || regs==NULL)
 
1960
    return;
 
1961
 
 
1962
  if (set)
 
1963
    {
 
1964
      sanei_genesys_set_reg_from_set (regs, 0x03,
 
1965
                                      sanei_genesys_read_reg_from_set (regs,
 
1966
                                                                       0x03)
 
1967
                                      | REG03_LAMPPWR);
 
1968
    }
 
1969
  else
 
1970
    {
 
1971
      sanei_genesys_set_reg_from_set (regs, 0x03,
 
1972
                                      sanei_genesys_read_reg_from_set (regs,
 
1973
                                                                       0x03)
 
1974
                                      & ~REG03_LAMPPWR);
 
1975
    }
 
1976
}
 
1977
 
 
1978
/**
 
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
 
1982
 * */
 
1983
static SANE_Status
 
1984
gl124_save_power (Genesys_Device * dev, SANE_Bool enable)
 
1985
{
 
1986
  DBG (DBG_proc, "gl124_save_power: enable = %d\n", enable);
 
1987
  if (dev == NULL)
 
1988
    return SANE_STATUS_INVAL;
 
1989
 
 
1990
  DBGCOMPLETED;
 
1991
  return SANE_STATUS_GOOD;
 
1992
}
 
1993
 
 
1994
static SANE_Status
 
1995
gl124_set_powersaving (Genesys_Device * dev, int delay /* in minutes */ )
 
1996
{
 
1997
  Genesys_Register_Set *r;
 
1998
 
 
1999
  DBG (DBG_proc, "gl124_set_powersaving (delay = %d)\n", delay);
 
2000
  
 
2001
  r = sanei_genesys_get_address (dev->reg, REG03);
 
2002
  r->value &= ~0xf0;
 
2003
  if(delay<15)
 
2004
    {
 
2005
      r->value |= delay;
 
2006
    }
 
2007
  else
 
2008
    {
 
2009
      r->value |= 0x0f;
 
2010
    }
 
2011
 
 
2012
  DBGCOMPLETED;
 
2013
  return SANE_STATUS_GOOD;
 
2014
}
 
2015
 
 
2016
#ifndef UNIT_TESTING
 
2017
static
 
2018
#endif
 
2019
  SANE_Status
 
2020
gl124_start_action (Genesys_Device * dev)
 
2021
{
 
2022
  return sanei_genesys_write_register (dev, 0x0f, 0x01);
 
2023
}
 
2024
 
 
2025
static SANE_Status
 
2026
gl124_stop_action (Genesys_Device * dev)
 
2027
{
 
2028
  SANE_Status status;
 
2029
  uint8_t val40, val;
 
2030
  unsigned int loop;
 
2031
 
 
2032
  DBG (DBG_proc, "%s\n", __FUNCTION__);
 
2033
 
 
2034
  /* post scan gpio */
 
2035
  RIE (sanei_genesys_read_register (dev, REG32, &val));
 
2036
  val &= 0xf9;
 
2037
  RIE (sanei_genesys_write_register (dev, REG32, val));
 
2038
 
 
2039
  status = sanei_genesys_get_status (dev, &val);
 
2040
  if (DBG_LEVEL >= DBG_io)
 
2041
    {
 
2042
      sanei_genesys_print_status (val);
 
2043
    }
 
2044
 
 
2045
  status = sanei_genesys_read_hregister (dev, REG100, &val40);
 
2046
  if (status != SANE_STATUS_GOOD)
 
2047
    {
 
2048
      DBG (DBG_error,
 
2049
           "%s: failed to read reg100: %s\n", __FUNCTION__,
 
2050
           sane_strstatus (status));
 
2051
      DBGCOMPLETED;
 
2052
      return status;
 
2053
    }
 
2054
 
 
2055
  /* only stop action if needed */
 
2056
  if (!(val40 & REG100_DATAENB) && !(val40 & REG100_MOTMFLG))
 
2057
    {
 
2058
      DBG (DBG_info, "%s: already stopped\n", __FUNCTION__);
 
2059
      DBGCOMPLETED;
 
2060
      return SANE_STATUS_GOOD;
 
2061
    }
 
2062
 
 
2063
  /* ends scan */
 
2064
  val = sanei_genesys_read_reg_from_set (dev->reg, REG01);
 
2065
  val &= ~REG01_SCAN;
 
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)
 
2069
    {
 
2070
      DBG (DBG_error,
 
2071
           "%s: failed to write register 01: %s\n", __FUNCTION__,
 
2072
           sane_strstatus (status));
 
2073
      return status;
 
2074
    }
 
2075
  usleep (100 * 1000);
 
2076
 
 
2077
  loop = 10;
 
2078
  while (loop > 0)
 
2079
    {
 
2080
      status = sanei_genesys_get_status (dev, &val);
 
2081
      if (DBG_LEVEL >= DBG_io)
 
2082
        {
 
2083
          sanei_genesys_print_status (val);
 
2084
        }
 
2085
      val40 = 0;
 
2086
      status = sanei_genesys_read_hregister (dev, REG100, &val40);
 
2087
      if (status != SANE_STATUS_GOOD)
 
2088
        {
 
2089
          DBG (DBG_error,
 
2090
               "%s: failed to read home sensor: %s\n", __FUNCTION__,
 
2091
               sane_strstatus (status));
 
2092
          DBGCOMPLETED;
 
2093
          return status;
 
2094
        }
 
2095
 
 
2096
      /* if scanner is in command mode, we are done */
 
2097
      if (!(val40 & REG100_DATAENB) && !(val40 & REG100_MOTMFLG)
 
2098
          && !(val & MOTORENB))
 
2099
        {
 
2100
          DBGCOMPLETED;
 
2101
          return SANE_STATUS_GOOD;
 
2102
        }
 
2103
 
 
2104
      usleep (100 * 1000);
 
2105
      loop--;
 
2106
    }
 
2107
 
 
2108
  DBGCOMPLETED;
 
2109
  return SANE_STATUS_IO_ERROR;
 
2110
}
 
2111
 
 
2112
/* Send the low-level scan command */
 
2113
/* todo : is this that useful ? */
 
2114
#ifndef UNIT_TESTING
 
2115
static
 
2116
#endif
 
2117
  SANE_Status
 
2118
gl124_begin_scan (Genesys_Device * dev, Genesys_Register_Set * reg,
 
2119
                  SANE_Bool start_motor)
 
2120
{
 
2121
  SANE_Status status;
 
2122
  uint8_t val;
 
2123
 
 
2124
  DBGSTART;
 
2125
  if (reg == NULL)
 
2126
    return SANE_STATUS_INVAL;
 
2127
 
 
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)
 
2131
    {
 
2132
      val &= 0xf7;
 
2133
    }
 
2134
  else if(dev->settings.yres>=dev->motor.base_ydpi/4)
 
2135
    {
 
2136
      val &= 0xef;
 
2137
    }
 
2138
  else
 
2139
    {
 
2140
      val |= 0x10;
 
2141
    }
 
2142
  val |= 0x02;
 
2143
  RIE (sanei_genesys_write_register (dev, REG32, val));
 
2144
 
 
2145
  /* clear scan and feed count */
 
2146
  RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT | REG0D_CLRMCNT));
 
2147
 
 
2148
  /* enable scan and motor */
 
2149
  RIE (sanei_genesys_read_register (dev, REG01, &val));
 
2150
  val |= REG01_SCAN;
 
2151
  RIE (sanei_genesys_write_register (dev, REG01, val));
 
2152
 
 
2153
  if (start_motor)
 
2154
    {
 
2155
      RIE (sanei_genesys_write_register (dev, REG0F, 1));
 
2156
    }
 
2157
  else
 
2158
    {
 
2159
      RIE (sanei_genesys_write_register (dev, REG0F, 0));
 
2160
    }
 
2161
 
 
2162
  DBGCOMPLETED;
 
2163
  return status;
 
2164
}
 
2165
 
 
2166
 
 
2167
/* Send the stop scan command */
 
2168
#ifndef UNIT_TESTING
 
2169
static
 
2170
#endif
 
2171
  SANE_Status
 
2172
gl124_end_scan (Genesys_Device * dev, Genesys_Register_Set * reg,
 
2173
                SANE_Bool check_stop)
 
2174
{
 
2175
  SANE_Status status;
 
2176
 
 
2177
  DBG (DBG_proc, "gl124_end_scan (check_stop = %d)\n", check_stop);
 
2178
  if (reg == NULL)
 
2179
    return SANE_STATUS_INVAL;
 
2180
 
 
2181
  if (dev->model->is_sheetfed == SANE_TRUE)
 
2182
    {
 
2183
      status = SANE_STATUS_GOOD;
 
2184
    }
 
2185
  else                          /* flat bed scanners */
 
2186
    {
 
2187
      status = gl124_stop_action (dev);
 
2188
      if (status != SANE_STATUS_GOOD)
 
2189
        {
 
2190
          DBG (DBG_error,
 
2191
               "gl124_end_scan: failed to stop: %s\n",
 
2192
               sane_strstatus (status));
 
2193
          return status;
 
2194
        }
 
2195
    }
 
2196
 
 
2197
  DBGCOMPLETED;
 
2198
  return status;
 
2199
}
 
2200
 
 
2201
 
 
2202
/** @brief Moves the slider to the home (top) position slowly
 
2203
 * */
 
2204
#ifndef UNIT_TESTING
 
2205
static
 
2206
#endif
 
2207
  SANE_Status
 
2208
gl124_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
 
2209
{
 
2210
  Genesys_Register_Set local_reg[GENESYS_GL124_MAX_REGS];
 
2211
  SANE_Status status;
 
2212
  Genesys_Register_Set *r;
 
2213
  uint8_t val;
 
2214
  float resolution;
 
2215
  int loop = 0;
 
2216
 
 
2217
  DBG (DBG_proc, "gl124_slow_back_home (wait_until_home = %d)\n",
 
2218
       wait_until_home);
 
2219
 
 
2220
  dev->scanhead_position_in_steps = 0;
 
2221
 
 
2222
  /* first read gives HOME_SENSOR true */
 
2223
  status = sanei_genesys_get_status (dev, &val);
 
2224
  if (status != SANE_STATUS_GOOD)
 
2225
    {
 
2226
      DBG (DBG_error,
 
2227
           "gl124_slow_back_home: failed to read home sensor: %s\n",
 
2228
           sane_strstatus (status));
 
2229
      return status;
 
2230
    }
 
2231
  usleep (100000);              /* sleep 100 ms */
 
2232
 
 
2233
  /* second is reliable */
 
2234
  status = sanei_genesys_get_status (dev, &val);
 
2235
  if (status != SANE_STATUS_GOOD)
 
2236
    {
 
2237
      DBG (DBG_error,
 
2238
           "gl124_slow_back_home: failed to read home sensor: %s\n",
 
2239
           sane_strstatus (status));
 
2240
      return status;
 
2241
    }
 
2242
  if (DBG_LEVEL >= DBG_io)
 
2243
    {
 
2244
      sanei_genesys_print_status (val);
 
2245
    }
 
2246
  if (val & HOMESNR)    /* is sensor at home? */
 
2247
    {
 
2248
      DBGCOMPLETED;
 
2249
      return SANE_STATUS_GOOD;
 
2250
    }
 
2251
 
 
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;
 
2255
 
 
2256
  gl124_init_scan_regs (dev,
 
2257
                        local_reg,
 
2258
                        resolution,
 
2259
                        resolution,
 
2260
                        100,
 
2261
                        30000,
 
2262
                        100,
 
2263
                        100,
 
2264
                        8,
 
2265
                        3,
 
2266
                        dev->settings.color_filter,
 
2267
                        SCAN_FLAG_DISABLE_SHADING |
 
2268
                        SCAN_FLAG_DISABLE_GAMMA |
 
2269
                        SCAN_FLAG_FEEDING |
 
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);
 
2274
 
 
2275
  /* clear scan and feed count */
 
2276
  RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT | REG0D_CLRMCNT));
 
2277
  
 
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;
 
2283
 
 
2284
  RIE (gl124_bulk_write_register (dev, local_reg, GENESYS_GL124_MAX_REGS));
 
2285
 
 
2286
  status = gl124_start_action (dev);
 
2287
  if (status != SANE_STATUS_GOOD)
 
2288
    {
 
2289
      DBG (DBG_error,
 
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);
 
2295
      return status;
 
2296
    }
 
2297
 
 
2298
  if (wait_until_home)
 
2299
    {
 
2300
 
 
2301
      while (loop < 300)        /* do not wait longer then 30 seconds */
 
2302
        {
 
2303
          status = sanei_genesys_get_status (dev, &val);
 
2304
          if (status != SANE_STATUS_GOOD)
 
2305
            {
 
2306
              DBG (DBG_error,
 
2307
                   "gl124_slow_back_home: failed to read home sensor: %s\n",
 
2308
                   sane_strstatus (status));
 
2309
              return status;
 
2310
            }
 
2311
 
 
2312
          if (val & HOMESNR)    /* home sensor */
 
2313
            {
 
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;
 
2317
            }
 
2318
          usleep (100000);      /* sleep 100 ms */
 
2319
          ++loop;
 
2320
        }
 
2321
 
 
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);
 
2324
      DBG (DBG_error,
 
2325
           "gl124_slow_back_home: timeout while waiting for scanhead to go home\n");
 
2326
      return SANE_STATUS_IO_ERROR;
 
2327
    }
 
2328
 
 
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;
 
2332
}
 
2333
 
 
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
 
2337
 * */
 
2338
#ifndef UNIT_TESTING
 
2339
static
 
2340
#endif
 
2341
SANE_Status
 
2342
gl124_feed (Genesys_Device * dev, unsigned int steps)
 
2343
{
 
2344
  Genesys_Register_Set local_reg[GENESYS_GL124_MAX_REGS];
 
2345
  SANE_Status status;
 
2346
  Genesys_Register_Set *r;
 
2347
  float resolution;
 
2348
  uint8_t val;
 
2349
 
 
2350
  DBGSTART;
 
2351
 
 
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));
 
2355
 
 
2356
 
 
2357
  resolution=MOVE_DPI;
 
2358
  gl124_init_scan_regs (dev,
 
2359
                        local_reg,
 
2360
                        resolution,
 
2361
                        resolution,
 
2362
                        0,
 
2363
                        steps,
 
2364
                        100,
 
2365
                        3,
 
2366
                        8,
 
2367
                        3,
 
2368
                        dev->settings.color_filter,
 
2369
                        SCAN_FLAG_DISABLE_SHADING |
 
2370
                        SCAN_FLAG_DISABLE_GAMMA |
 
2371
                        SCAN_FLAG_FEEDING |
 
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);
 
2377
 
 
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));
 
2381
  
 
2382
  /* set up for no scan */
 
2383
  r = sanei_genesys_get_address (local_reg, REG01);
 
2384
  r->value &= ~REG01_SCAN;
 
2385
  
 
2386
  /* send registers */
 
2387
  RIE (gl124_bulk_write_register (dev, local_reg, GENESYS_GL124_MAX_REGS));
 
2388
 
 
2389
  status = gl124_start_action (dev);
 
2390
  if (status != SANE_STATUS_GOOD)
 
2391
    {
 
2392
      DBG (DBG_error, "%s: failed to start motor: %s\n", __FUNCTION__, sane_strstatus (status));
 
2393
      gl124_stop_action (dev);
 
2394
 
 
2395
      /* restore original registers */
 
2396
      gl124_bulk_write_register (dev, dev->reg, GENESYS_GL124_MAX_REGS);
 
2397
      return status;
 
2398
    }
 
2399
 
 
2400
  /* wait until feed count reaches the required value, but do not
 
2401
   * exceed 30s */
 
2402
  do
 
2403
    {
 
2404
          status = sanei_genesys_get_status (dev, &val);
 
2405
    }
 
2406
  while (status == SANE_STATUS_GOOD && !(val & FEEDFSH));
 
2407
  
 
2408
  DBGCOMPLETED;
 
2409
  return SANE_STATUS_GOOD;
 
2410
}
 
2411
 
 
2412
 
 
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 */
 
2415
static SANE_Status
 
2416
gl124_search_start_position (Genesys_Device * dev)
 
2417
{
 
2418
  int size;
 
2419
  SANE_Status status;
 
2420
  uint8_t *data;
 
2421
  Genesys_Register_Set local_reg[GENESYS_GL124_MAX_REGS];
 
2422
  int steps;
 
2423
 
 
2424
  int pixels = 600;
 
2425
  int dpi = 300;
 
2426
 
 
2427
  DBG (DBG_proc, "gl124_search_start_position\n");
 
2428
 
 
2429
  memset (local_reg, 0, sizeof (local_reg));
 
2430
  memcpy (local_reg, dev->reg,
 
2431
          GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set));
 
2432
 
 
2433
  /* sets for a 200 lines * 600 pixels */
 
2434
  /* normal scan with no shading */
 
2435
 
 
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);
 
2442
 
 
2443
  /* send to scanner */
 
2444
  status = gl124_bulk_write_register (dev, local_reg, GENESYS_GL124_MAX_REGS);
 
2445
  if (status != SANE_STATUS_GOOD)
 
2446
    {
 
2447
      DBG (DBG_error,
 
2448
           "gl124_search_start_position: failed to bulk write registers: %s\n",
 
2449
           sane_strstatus (status));
 
2450
      return status;
 
2451
    }
 
2452
 
 
2453
  size = pixels * dev->model->search_lines;
 
2454
 
 
2455
  data = malloc (size);
 
2456
  if (!data)
 
2457
    {
 
2458
      DBG (DBG_error,
 
2459
           "gl124_search_start_position: failed to allocate memory\n");
 
2460
      return SANE_STATUS_NO_MEM;
 
2461
    }
 
2462
 
 
2463
  status = gl124_begin_scan (dev, local_reg, SANE_TRUE);
 
2464
  if (status != SANE_STATUS_GOOD)
 
2465
    {
 
2466
      free (data);
 
2467
      DBG (DBG_error,
 
2468
           "gl124_search_start_position: failed to begin scan: %s\n",
 
2469
           sane_strstatus (status));
 
2470
      return status;
 
2471
    }
 
2472
 
 
2473
  /* waits for valid data */
 
2474
  do
 
2475
    sanei_genesys_test_buffer_empty (dev, &steps);
 
2476
  while (steps);
 
2477
 
 
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)
 
2481
    {
 
2482
      free (data);
 
2483
      DBG (DBG_error,
 
2484
           "gl124_search_start_position: failed to read data: %s\n",
 
2485
           sane_strstatus (status));
 
2486
      return status;
 
2487
    }
 
2488
 
 
2489
  if (DBG_LEVEL >= DBG_data)
 
2490
    sanei_genesys_write_pnm_file ("search_position.pnm", data, 8, 1, pixels,
 
2491
                                  dev->model->search_lines);
 
2492
 
 
2493
  status = gl124_end_scan (dev, local_reg, SANE_TRUE);
 
2494
  if (status != SANE_STATUS_GOOD)
 
2495
    {
 
2496
      free (data);
 
2497
      DBG (DBG_error,
 
2498
           "gl124_search_start_position: failed to end scan: %s\n",
 
2499
           sane_strstatus (status));
 
2500
      return status;
 
2501
    }
 
2502
 
 
2503
  /* update regs to copy ASIC internal state */
 
2504
  memcpy (dev->reg, local_reg,
 
2505
          GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set));
 
2506
 
 
2507
  status =
 
2508
    sanei_genesys_search_reference_point (dev, data, 0, dpi, pixels,
 
2509
                                          dev->model->search_lines);
 
2510
  if (status != SANE_STATUS_GOOD)
 
2511
    {
 
2512
      free (data);
 
2513
      DBG (DBG_error,
 
2514
           "gl124_search_start_position: failed to set search reference point: %s\n",
 
2515
           sane_strstatus (status));
 
2516
      return status;
 
2517
    }
 
2518
 
 
2519
  free (data);
 
2520
  return SANE_STATUS_GOOD;
 
2521
}
 
2522
 
 
2523
/* 
 
2524
 * sets up register for coarse gain calibration
 
2525
 * todo: check it for scanners using it */
 
2526
static SANE_Status
 
2527
gl124_init_regs_for_coarse_calibration (Genesys_Device * dev)
 
2528
{
 
2529
  SANE_Status status;
 
2530
  uint8_t channels;
 
2531
  uint8_t cksel;
 
2532
  Genesys_Register_Set *r;
 
2533
 
 
2534
  DBGSTART;
 
2535
  cksel = (dev->calib_reg[reg_0x18].value & REG18_CKSEL) + 1;   /* clock speed = 1..4 clocks */
 
2536
 
 
2537
  /* set line size */
 
2538
  if (dev->settings.scan_mode == SCAN_MODE_COLOR)       /* single pass color */
 
2539
    channels = 3;
 
2540
  else
 
2541
    channels = 1;
 
2542
 
 
2543
  status = gl124_init_scan_regs (dev,
 
2544
                                 dev->calib_reg,
 
2545
                                 dev->settings.xres,
 
2546
                                 dev->settings.yres,
 
2547
                                 0,
 
2548
                                 0,
 
2549
                                 dev->sensor.optical_res / cksel,
 
2550
                                 20,
 
2551
                                 16,
 
2552
                                 channels,
 
2553
                                 dev->settings.color_filter,
 
2554
                                 SCAN_FLAG_DISABLE_SHADING |
 
2555
                                 SCAN_FLAG_DISABLE_GAMMA |
 
2556
                                 SCAN_FLAG_SINGLE_LINE |
 
2557
                                 SCAN_FLAG_FEEDING |
 
2558
                                 SCAN_FLAG_IGNORE_LINE_DISTANCE);
 
2559
  if (status != SANE_STATUS_GOOD)
 
2560
    {
 
2561
      DBG (DBG_error,
 
2562
           "gl124_init_register_for_coarse_calibration: failed to setup scan: %s\n",
 
2563
           sane_strstatus (status));
 
2564
      return status;
 
2565
    }
 
2566
  r = sanei_genesys_get_address (dev->calib_reg, REG02);
 
2567
  r->value &= ~REG02_MTRPWR;
 
2568
 
 
2569
  DBG (DBG_info,
 
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);
 
2572
 
 
2573
  status =
 
2574
    gl124_bulk_write_register (dev, dev->calib_reg, GENESYS_GL124_MAX_REGS);
 
2575
  if (status != SANE_STATUS_GOOD)
 
2576
    {
 
2577
      DBG (DBG_error,
 
2578
           "gl124_init_register_for_coarse_calibration: failed to bulk write registers: %s\n",
 
2579
           sane_strstatus (status));
 
2580
      return status;
 
2581
    }
 
2582
 
 
2583
  DBGCOMPLETED;
 
2584
  return SANE_STATUS_GOOD;
 
2585
}
 
2586
 
 
2587
 
 
2588
/* init registers for shading calibration */
 
2589
static SANE_Status
 
2590
gl124_init_regs_for_shading (Genesys_Device * dev)
 
2591
{
 
2592
  SANE_Status status;
 
2593
  int move,resolution;
 
2594
  Genesys_Register_Set *r;
 
2595
 
 
2596
  DBGSTART;
 
2597
  
 
2598
  /* initial calibration reg values */
 
2599
  memcpy (dev->calib_reg, dev->reg,
 
2600
          GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set));
 
2601
 
 
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;
 
2605
 
 
2606
  /* distance to move to reach white target at high resolution */
 
2607
  move=0;
 
2608
  if(dev->settings.yres>=1200)
 
2609
    {
 
2610
      move = SANE_UNFIX (dev->model->y_offset_calib);
 
2611
      move = (move * (dev->motor.base_ydpi/4)) / MM_PER_INCH;
 
2612
    }
 
2613
  DBG (DBG_io, "%s: move=%d steps\n", __FUNCTION__, move);
 
2614
 
 
2615
  status = gl124_init_scan_regs (dev,
 
2616
                                 dev->calib_reg,
 
2617
                                 resolution,
 
2618
                                 resolution,
 
2619
                                 0,
 
2620
                                 move,
 
2621
                                 dev->calib_pixels,
 
2622
                                 dev->model->shading_lines,
 
2623
                                 16,
 
2624
                                 dev->calib_channels,
 
2625
                                 0,
 
2626
                                 0);
 
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;
 
2633
 
 
2634
  if (status != SANE_STATUS_GOOD)
 
2635
    {
 
2636
      DBG (DBG_error, "%s: failed to setup scan: %s\n", __FUNCTION__, 
 
2637
           sane_strstatus (status));
 
2638
      return status;
 
2639
    }
 
2640
 
 
2641
  dev->scanhead_position_in_steps += dev->model->shading_lines + move;
 
2642
 
 
2643
  status =
 
2644
    gl124_bulk_write_register (dev, dev->calib_reg, GENESYS_GL124_MAX_REGS);
 
2645
  if (status != SANE_STATUS_GOOD)
 
2646
    {
 
2647
      DBG (DBG_error,
 
2648
           "%s: failed to bulk write registers: %s\n", __FUNCTION__, 
 
2649
           sane_strstatus (status));
 
2650
      return status;
 
2651
    }
 
2652
 
 
2653
  DBGCOMPLETED;
 
2654
  return SANE_STATUS_GOOD;
 
2655
}
 
2656
 
 
2657
/** @brief set up registers for the actual scan
 
2658
 */
 
2659
static SANE_Status
 
2660
gl124_init_regs_for_scan (Genesys_Device * dev)
 
2661
{
 
2662
  int channels;
 
2663
  int flags;
 
2664
  int depth;
 
2665
  float move;
 
2666
  int move_dpi;
 
2667
  float start;
 
2668
  uint8_t val40,val;
 
2669
 
 
2670
  SANE_Status status;
 
2671
 
 
2672
  DBG (DBG_info,
 
2673
       "gl124_init_regs_for_scan settings:\nResolution: %ux%uDPI\n"
 
2674
       "Lines     : %u\npixels    : %u\nStartpos  : %.3f/%.3f\nScan mode : %d\n\n",
 
2675
       dev->settings.xres,
 
2676
       dev->settings.yres,
 
2677
       dev->settings.lines,
 
2678
       dev->settings.pixels,
 
2679
       dev->settings.tl_x,
 
2680
       dev->settings.tl_y,
 
2681
       dev->settings.scan_mode);
 
2682
 
 
2683
  /* wait for motor to stop first */
 
2684
  status = sanei_genesys_get_status (dev, &val);
 
2685
  if (status != SANE_STATUS_GOOD)
 
2686
   {
 
2687
     DBG (DBG_error, "%s: failed to read status: %s\n", __FUNCTION__, sane_strstatus (status));
 
2688
     DBGCOMPLETED;
 
2689
     return status;
 
2690
   }
 
2691
  status = sanei_genesys_read_hregister (dev, REG100, &val40);
 
2692
  if (status != SANE_STATUS_GOOD)
 
2693
   {
 
2694
     DBG (DBG_error, "%s: failed to read reg100: %s\n", __FUNCTION__, sane_strstatus (status));
 
2695
     DBGCOMPLETED;
 
2696
     return status;
 
2697
   }
 
2698
  if((val & MOTORENB) || (val40 & REG100_MOTMFLG))
 
2699
    {
 
2700
      do
 
2701
        {
 
2702
          usleep(10000);
 
2703
          status = sanei_genesys_get_status (dev, &val);
 
2704
          if (status != SANE_STATUS_GOOD)
 
2705
           {
 
2706
             DBG (DBG_error, "%s: failed to read status: %s\n", __FUNCTION__, sane_strstatus (status));
 
2707
             DBGCOMPLETED;
 
2708
             return status;
 
2709
           }
 
2710
          status = sanei_genesys_read_hregister (dev, REG100, &val40);
 
2711
          if (status != SANE_STATUS_GOOD)
 
2712
           {
 
2713
             DBG (DBG_error, "%s: failed to read reg100: %s\n", __FUNCTION__, sane_strstatus (status));
 
2714
             DBGCOMPLETED;
 
2715
             return status;
 
2716
           }
 
2717
        } while ((val & MOTORENB) || (val40 & REG100_MOTMFLG));
 
2718
        usleep(50000);
 
2719
    }
 
2720
 
 
2721
  /* ensure head is parked in case of calibration */
 
2722
  RIE (gl124_slow_back_home (dev, SANE_TRUE));
 
2723
 
 
2724
  /* channels */
 
2725
  if (dev->settings.scan_mode == SCAN_MODE_COLOR)
 
2726
    channels = 3;
 
2727
  else
 
2728
    channels = 1;
 
2729
 
 
2730
  /* depth */
 
2731
  depth = dev->settings.depth;
 
2732
  if (dev->settings.scan_mode == SCAN_MODE_LINEART)
 
2733
    depth = 1;
 
2734
 
 
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);
 
2741
 
 
2742
  if(channels*dev->settings.yres>=1200 && move>3000)
 
2743
    {
 
2744
      move -= 180;
 
2745
      status = gl124_feed (dev, move);
 
2746
      if (status != SANE_STATUS_GOOD)
 
2747
        {
 
2748
          DBG (DBG_error, "%s: failed to move to scan area\n",__FUNCTION__);
 
2749
          return status;
 
2750
        }
 
2751
      move=0;
 
2752
    }
 
2753
  else
 
2754
    {
 
2755
      if(channels==1)
 
2756
        {
 
2757
          move-=0;
 
2758
        }
 
2759
    }
 
2760
  DBG (DBG_info, "gl124_init_regs_for_scan: move=%f steps\n", move);
 
2761
 
 
2762
  /* start */
 
2763
  start = SANE_UNFIX (dev->model->x_offset);
 
2764
  start += dev->settings.tl_x;
 
2765
  start = (start * dev->sensor.optical_res) / MM_PER_INCH;
 
2766
 
 
2767
  flags = 0;
 
2768
 
 
2769
  /* enable emulated lineart from gray data */
 
2770
  if(dev->settings.scan_mode == SCAN_MODE_LINEART 
 
2771
     && dev->settings.dynamic_lineart)
 
2772
    {
 
2773
      flags |= SCAN_FLAG_DYNAMIC_LINEART;
 
2774
    }
 
2775
 
 
2776
  status = gl124_init_scan_regs (dev,
 
2777
                                 dev->reg,
 
2778
                                 dev->settings.xres,
 
2779
                                 dev->settings.yres,
 
2780
                                 start,
 
2781
                                 move,
 
2782
                                 dev->settings.pixels,
 
2783
                                 dev->settings.lines,
 
2784
                                 depth,
 
2785
                                 channels, dev->settings.color_filter, flags);
 
2786
 
 
2787
  if (status != SANE_STATUS_GOOD)
 
2788
    return status;
 
2789
 
 
2790
  DBGCOMPLETED;
 
2791
  return SANE_STATUS_GOOD;
 
2792
}
 
2793
 
 
2794
/**
 
2795
 * Send shading calibration data. The buffer is considered to always hold values
 
2796
 * for all the channels.
 
2797
 */
 
2798
#ifndef UNIT_TESTING
 
2799
static
 
2800
#endif
 
2801
SANE_Status
 
2802
gl124_send_shading_data (Genesys_Device * dev, uint8_t * data, int size)
 
2803
{
 
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;
 
2808
 
 
2809
  DBGSTART;
 
2810
  DBG( DBG_io2, "%s: writing %d bytes of shading data\n",__FUNCTION__,size);
 
2811
 
 
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);
 
2817
  if(endpixel==0)
 
2818
    {
 
2819
      endpixel=segcnt;
 
2820
    }
 
2821
  DBG( DBG_io2, "%s: STRPIXEL=%d, ENDPIXEL=%d, PIXELS=%d, SEGCNT=%d\n",__FUNCTION__,strpixel,endpixel,endpixel-strpixel,segcnt);
 
2822
 
 
2823
  /* turn pixel value into bytes 2x16 bits words */
 
2824
  strpixel*=2*2; /* 2 words of 2 bytes */
 
2825
  endpixel*=2*2;
 
2826
  segcnt*=2*2;
 
2827
  pixels=endpixel-strpixel;
 
2828
 
 
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);
 
2832
 
 
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);
 
2838
 
 
2839
  /* write actual red data */
 
2840
  for(i=0;i<3;i++)
 
2841
    {
 
2842
      /* copy data to work buffer and process it */
 
2843
          /* coefficent destination */
 
2844
      ptr=buffer;
 
2845
 
 
2846
      /* iterate on both sensor segment */
 
2847
      for(x=0;x<pixels;x+=4*factor)
 
2848
        {
 
2849
          /* coefficient source */
 
2850
          src=data+x+strpixel+i*length;
 
2851
 
 
2852
          /* iterate over all the segments */
 
2853
          switch(dev->segnb)
 
2854
            {
 
2855
            case 1:
 
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];
 
2860
              break;
 
2861
            case 2:
 
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];
 
2870
              break;
 
2871
            case 4:
 
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];
 
2888
              break;
 
2889
            }
 
2890
 
 
2891
          /* next shading coefficients */
 
2892
          ptr+=4;
 
2893
        }
 
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)
 
2898
        {
 
2899
          DBG (DBG_error, "gl124_send_shading_data; write to AHB failed (%s)\n",
 
2900
               sane_strstatus (status));
 
2901
          return status;
 
2902
        }
 
2903
    }
 
2904
 
 
2905
  free(buffer);
 
2906
  DBGCOMPLETED;
 
2907
 
 
2908
  return status;
 
2909
}
 
2910
 
 
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 
 
2914
 * fontend.
 
2915
 * @param dev device to write to
 
2916
 * @param generic flag for using generic gamma tables
 
2917
 */
 
2918
static SANE_Status
 
2919
gl124_send_gamma_table (Genesys_Device * dev, SANE_Bool generic)
 
2920
{
 
2921
  int size;
 
2922
  int status;
 
2923
  uint8_t *gamma, val;
 
2924
  int i, gmmval;
 
2925
 
 
2926
  DBG (DBG_proc, "gl124_send_gamma_table\n");
 
2927
 
 
2928
  /* don't send anything if no specific gamma table defined */
 
2929
  if (!generic
 
2930
      && (dev->sensor.red_gamma_table == NULL
 
2931
          || dev->sensor.green_gamma_table == NULL
 
2932
          || dev->sensor.blue_gamma_table == NULL))
 
2933
    {
 
2934
      DBG (DBG_proc, "gl124_send_gamma_table: nothing to send, skipping\n");
 
2935
      return SANE_STATUS_GOOD;
 
2936
    }
 
2937
 
 
2938
  size = 256;
 
2939
 
 
2940
  /* allocate temporary gamma tables: 16 bits words, 3 channels */
 
2941
  gamma = (uint8_t *) malloc (size * 2 * 3);
 
2942
  if (!gamma)
 
2943
    return SANE_STATUS_NO_MEM;
 
2944
 
 
2945
  /* take care off generic/specific data */
 
2946
  if (generic)
 
2947
    {
 
2948
      /* fill with default values */
 
2949
      for (i = 0; i < size; i++)
 
2950
        {
 
2951
          gmmval = i * 256;
 
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;
 
2958
        }
 
2959
    }
 
2960
  else
 
2961
    {
 
2962
      /* copy sensor specific's gamma tables */
 
2963
      for (i = 0; i < size; i++)
 
2964
        {
 
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;
 
2976
        }
 
2977
    }
 
2978
 
 
2979
  /* loop sending gamma tables NOTE: 0x01000000 not 0x10000000 */
 
2980
  for (i = 0; i < 3; i++)
 
2981
    {
 
2982
      /* clear corresponding GMM_N bit */
 
2983
      RIE (sanei_genesys_read_register (dev, 0xbd, &val));
 
2984
      /* val &= ~(0x01 << i); */
 
2985
      val = 0x00;
 
2986
      RIE (sanei_genesys_write_register (dev, 0xbd, val));
 
2987
 
 
2988
      /* clear corresponding GMM_F bit */
 
2989
      RIE (sanei_genesys_read_register (dev, 0xbe, &val));
 
2990
      /* val &= ~(0x01 << i); */
 
2991
      val = 0x07;
 
2992
      RIE (sanei_genesys_write_register (dev, 0xbe, val));
 
2993
 
 
2994
      /* set GMM_Z */
 
2995
      RIE (sanei_genesys_write_register (dev, 0xc5+2*i, 0x00));
 
2996
      RIE (sanei_genesys_write_register (dev, 0xc6+2*i, 0x00));
 
2997
 
 
2998
      status =
 
2999
        sanei_genesys_write_ahb (dev->dn, 0x01000000 + 0x200 * i, size * 2,
 
3000
                   gamma + i * size * 2);
 
3001
      if (status != SANE_STATUS_GOOD)
 
3002
        {
 
3003
          DBG (DBG_error,
 
3004
               "gl124_send_gamma_table: write to AHB failed writing table %d (%s)\n",
 
3005
               i, sane_strstatus (status));
 
3006
        }
 
3007
    }
 
3008
 
 
3009
  free (gamma);
 
3010
  DBGCOMPLETED;
 
3011
  return status;
 
3012
}
 
3013
 
 
3014
/* this function does the led calibration by scanning one line of the calibration
 
3015
   area below scanner's top on white strip.
 
3016
 
 
3017
-needs working coarse/gain
 
3018
*/
 
3019
static SANE_Status
 
3020
gl124_led_calibration (Genesys_Device * dev)
 
3021
{
 
3022
  int num_pixels;
 
3023
  int total_size;
 
3024
  int used_res;
 
3025
  uint8_t *line;
 
3026
  int i, j;
 
3027
  SANE_Status status = SANE_STATUS_GOOD;
 
3028
  int val;
 
3029
  int channels, depth;
 
3030
  int avg[3], avga, avge;
 
3031
  int turn;
 
3032
  char fn[20];
 
3033
  uint32_t expr, expg, expb;
 
3034
  Sensor_Profile *sensor;
 
3035
  Genesys_Register_Set *r;
 
3036
 
 
3037
  SANE_Bool acceptable = SANE_FALSE;
 
3038
 
 
3039
  DBGSTART;
 
3040
 
 
3041
  /* offset calibration is always done in color mode */
 
3042
  channels = 3;
 
3043
  depth = 16;
 
3044
  used_res=gl124_compute_dpihw(dev,dev->settings.xres);
 
3045
  sensor=get_sensor_profile(dev->model->ccd_type, used_res);
 
3046
  num_pixels =
 
3047
    (dev->sensor.sensor_pixels * used_res) / dev->sensor.optical_res;
 
3048
 
 
3049
  /* initial calibration reg values */
 
3050
  memcpy (dev->calib_reg, dev->reg,
 
3051
          GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set));
 
3052
 
 
3053
  status = gl124_init_scan_regs (dev,
 
3054
                                 dev->calib_reg,
 
3055
                                 used_res,
 
3056
                                 used_res,
 
3057
                                 0,
 
3058
                                 0,
 
3059
                                 num_pixels,
 
3060
                                 1,
 
3061
                                 depth,
 
3062
                                 channels,
 
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);
 
3069
 
 
3070
  if (status != SANE_STATUS_GOOD)
 
3071
    {
 
3072
      DBG (DBG_error,
 
3073
           "gl124_led_calibration: failed to setup scan: %s\n",
 
3074
           sane_strstatus (status));
 
3075
      return status;
 
3076
    }
 
3077
 
 
3078
  RIE (gl124_bulk_write_register
 
3079
       (dev, dev->calib_reg, GENESYS_GL124_MAX_REGS));
 
3080
 
 
3081
 
 
3082
  total_size = num_pixels * channels * (depth / 8) * 1; /* colors * bytes_per_color * scan lines */
 
3083
 
 
3084
  line = malloc (total_size);
 
3085
  if (!line)
 
3086
    return SANE_STATUS_NO_MEM;
 
3087
 
 
3088
/* 
 
3089
   we try to get equal bright leds here:
 
3090
 
 
3091
   loop:
 
3092
     average per color
 
3093
     adjust exposure times
 
3094
 */
 
3095
 
 
3096
  /* inital values */
 
3097
  expr=sensor->expr;
 
3098
  expg=sensor->expg;
 
3099
  expb=sensor->expb;
 
3100
  
 
3101
  turn = 0;
 
3102
 
 
3103
  /* no move during led calibration */
 
3104
  r = sanei_genesys_get_address (dev->calib_reg, REG02);
 
3105
  r->value &= ~REG02_MTRPWR;
 
3106
  do
 
3107
    {
 
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);
 
3111
 
 
3112
      RIE (gl124_bulk_write_register
 
3113
           (dev, dev->calib_reg, GENESYS_GL124_MAX_REGS));
 
3114
 
 
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));
 
3118
 
 
3119
      if (DBG_LEVEL >= DBG_data)
 
3120
        {
 
3121
          snprintf (fn, 20, "led_%02d.pnm", turn);
 
3122
          sanei_genesys_write_pnm_file (fn,
 
3123
                                        line, depth, channels, num_pixels, 1);
 
3124
        }
 
3125
 
 
3126
      acceptable = SANE_TRUE;
 
3127
 
 
3128
      for (j = 0; j < channels; j++)
 
3129
        {
 
3130
          avg[j] = 0;
 
3131
          for (i = 0; i < num_pixels; i++)
 
3132
            {
 
3133
              val = line[i * 2 + j * 2 * num_pixels + 1] * 256 +
 
3134
                  line[i * 2 + j * 2 * num_pixels];
 
3135
              avg[j] += val;
 
3136
            }
 
3137
          avg[j] /= num_pixels;
 
3138
        }
 
3139
      avga = (avg[0] + avg[1] + avg[2]) / 3;
 
3140
 
 
3141
      DBG (DBG_info, "gl124_led_calibration: average: "
 
3142
           "%d,%d,%d\n", avg[0], avg[1], avg[2]);
 
3143
 
 
3144
      acceptable = SANE_TRUE;
 
3145
 
 
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;
 
3151
 
 
3152
      if (!acceptable)
 
3153
        {
 
3154
          expr = (expr * avga) / avg[0];
 
3155
          expg = (expg * avga) / avg[1];
 
3156
          expb = (expb * avga) / avg[2];
 
3157
/*
 
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 
 
3163
*/
 
3164
          avge = (expr + expg + expb) / 3;
 
3165
 
 
3166
          /* XXX STEF XXX check limits: don't overflow max exposure */
 
3167
          if (avge > 40000)
 
3168
            {
 
3169
              expr = (expr * 40000) / avge;
 
3170
              expg = (expg * 40000) / avge;
 
3171
              expb = (expb * 40000) / avge;
 
3172
            }
 
3173
          if (avge < 200)
 
3174
            {
 
3175
              expr = (expr * 200) / avge;
 
3176
              expg = (expg * 200) / avge;
 
3177
              expb = (expb * 200) / avge;
 
3178
            }
 
3179
 
 
3180
        }
 
3181
 
 
3182
      RIE (gl124_stop_action (dev));
 
3183
 
 
3184
      turn++;
 
3185
 
 
3186
    }
 
3187
  while (!acceptable && turn < 100);
 
3188
 
 
3189
  DBG (DBG_info, "gl124_led_calibration: acceptable exposure: %d,%d,%d\n",
 
3190
       expr, expg, expb);
 
3191
 
 
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);
 
3196
 
 
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;
 
3205
 
 
3206
  /* cleanup before return */
 
3207
  free (line);
 
3208
 
 
3209
  /* repark head */
 
3210
  gl124_slow_back_home (dev, SANE_TRUE);
 
3211
 
 
3212
  DBGCOMPLETED;
 
3213
  return status;
 
3214
}
 
3215
 
 
3216
/**
 
3217
 * average dark pixels of a 8 bits scan
 
3218
 */
 
3219
static int
 
3220
dark_average (uint8_t * data, unsigned int pixels, unsigned int lines,
 
3221
              unsigned int channels, unsigned int black)
 
3222
{
 
3223
  unsigned int i, j, k, average, count;
 
3224
  unsigned int avg[3];
 
3225
  uint8_t val;
 
3226
 
 
3227
  /* computes average value on black margin */
 
3228
  for (k = 0; k < channels; k++)
 
3229
    {
 
3230
      avg[k] = 0;
 
3231
      count = 0;
 
3232
      for (i = 0; i < lines; i++)
 
3233
        {
 
3234
          for (j = 0; j < black; j++)
 
3235
            {
 
3236
              val = data[i * channels * pixels + j + k];
 
3237
              avg[k] += val;
 
3238
              count++;
 
3239
            }
 
3240
        }
 
3241
      if (count)
 
3242
        avg[k] /= count;
 
3243
      DBG (DBG_info, "dark_average: avg[%d] = %d\n", k, avg[k]);
 
3244
    }
 
3245
  average = 0;
 
3246
  for (i = 0; i < channels; i++)
 
3247
    average += avg[i];
 
3248
  average /= channels;
 
3249
  DBG (DBG_info, "dark_average: average = %d\n", average);
 
3250
  return average;
 
3251
}
 
3252
 
 
3253
 
 
3254
static SANE_Status
 
3255
gl124_offset_calibration (Genesys_Device * dev)
 
3256
{
 
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;
 
3261
  char title[32];
 
3262
  int pass = 0, avg, total_size;
 
3263
  int topavg, bottomavg, resolution, lines;
 
3264
  int top, bottom, black_pixels, pixels;
 
3265
 
 
3266
  DBGSTART;
 
3267
 
 
3268
  /* no gain nor offset for TI AFE */
 
3269
  RIE (sanei_genesys_read_register (dev, REG0A, &reg0a));
 
3270
  if(((reg0a & REG0A_SIFSEL)>>REG0AS_SIFSEL)==3)
 
3271
    {
 
3272
      DBGCOMPLETED;
 
3273
      return status;
 
3274
    }
 
3275
 
 
3276
  /* offset calibration is always done in color mode */
 
3277
  channels = 3;
 
3278
  resolution=dev->sensor.optical_res;
 
3279
  dev->calib_pixels = dev->sensor.sensor_pixels;
 
3280
  lines=1;
 
3281
  bpp=8;
 
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);
 
3285
 
 
3286
  status = gl124_init_scan_regs (dev,
 
3287
                                 dev->calib_reg,
 
3288
                                 resolution,
 
3289
                                 resolution,
 
3290
                                 0,
 
3291
                                 0,
 
3292
                                 pixels,
 
3293
                                 lines,
 
3294
                                 bpp,
 
3295
                                 channels,
 
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)
 
3302
    {
 
3303
      DBG (DBG_error,
 
3304
           "gl124_offset_calibration: failed to setup scan: %s\n",
 
3305
           sane_strstatus (status));
 
3306
      return status;
 
3307
    }
 
3308
  r = sanei_genesys_get_address (dev->calib_reg, REG02);
 
3309
  r->value &= ~REG02_MTRPWR;
 
3310
 
 
3311
  /* allocate memory for scans */
 
3312
  total_size = pixels * channels * lines * (bpp/8);     /* colors * bytes_per_color * scan lines */
 
3313
 
 
3314
  first_line = malloc (total_size);
 
3315
  if (!first_line)
 
3316
    return SANE_STATUS_NO_MEM;
 
3317
 
 
3318
  second_line = malloc (total_size);
 
3319
  if (!second_line)
 
3320
    {
 
3321
      free (first_line);
 
3322
      return SANE_STATUS_NO_MEM;
 
3323
    }
 
3324
 
 
3325
  /* init gain */
 
3326
  dev->frontend.gain[0] = 0;
 
3327
  dev->frontend.gain[1] = 0;
 
3328
  dev->frontend.gain[2] = 0;
 
3329
 
 
3330
  /* scan with no move */
 
3331
  bottom = 10;
 
3332
  dev->frontend.offset[0] = bottom;
 
3333
  dev->frontend.offset[1] = bottom;
 
3334
  dev->frontend.offset[2] = bottom;
 
3335
 
 
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)
 
3342
   {
 
3343
      snprintf(title,20,"offset%03d.pnm",bottom);
 
3344
      sanei_genesys_write_pnm_file (title, first_line, bpp, channels, pixels, lines);
 
3345
   }
 
3346
     
 
3347
  bottomavg = dark_average (first_line, pixels, lines, channels, black_pixels);
 
3348
  DBG (DBG_io2, "gl124_offset_calibration: bottom avg=%d\n", bottomavg);
 
3349
 
 
3350
  /* now top value */
 
3351
  top = 255;
 
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));
 
3360
      
 
3361
  topavg = dark_average (second_line, pixels, lines, channels, black_pixels);
 
3362
  DBG (DBG_io2, "gl124_offset_calibration: top avg=%d\n", topavg);
 
3363
 
 
3364
  /* loop until acceptable level */
 
3365
  while ((pass < 32) && (top - bottom > 1))
 
3366
    {
 
3367
      pass++;
 
3368
 
 
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;
 
3373
 
 
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));
 
3380
 
 
3381
      if (DBG_LEVEL >= DBG_data)
 
3382
        {
 
3383
          sprintf (title, "offset%03d.pnm", dev->frontend.offset[1]);
 
3384
          sanei_genesys_write_pnm_file (title, second_line, bpp, channels, pixels, lines);
 
3385
        }
 
3386
 
 
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]);
 
3390
 
 
3391
      /* compute new boundaries */
 
3392
      if (topavg == avg)
 
3393
        {
 
3394
          topavg = avg;
 
3395
          top = dev->frontend.offset[1];
 
3396
        }
 
3397
      else
 
3398
        {
 
3399
          bottomavg = avg;
 
3400
          bottom = dev->frontend.offset[1];
 
3401
        }
 
3402
    }
 
3403
  DBG (DBG_info, "gl124_offset_calibration: offset=(%d,%d,%d)\n", dev->frontend.offset[0], dev->frontend.offset[1], dev->frontend.offset[2]);
 
3404
 
 
3405
  /* cleanup before return */
 
3406
  free (first_line);
 
3407
  free (second_line);
 
3408
 
 
3409
  DBGCOMPLETED;
 
3410
  return SANE_STATUS_GOOD;
 
3411
}
 
3412
 
 
3413
 
 
3414
/* alternative coarse gain calibration 
 
3415
   this on uses the settings from offset_calibration and
 
3416
   uses only one scanline
 
3417
 */
 
3418
/*
 
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.
 
3422
 */
 
3423
static SANE_Status
 
3424
gl124_coarse_gain_calibration (Genesys_Device * dev, int dpi)
 
3425
{
 
3426
  int pixels;
 
3427
  int total_size;
 
3428
  uint8_t *line, reg0a;
 
3429
  int i, j, channels;
 
3430
  SANE_Status status = SANE_STATUS_GOOD;
 
3431
  int max[3];
 
3432
  float gain[3],coeff;
 
3433
  int val, code, lines;
 
3434
  int resolution;
 
3435
  Genesys_Register_Set *r;
 
3436
  int bpp;
 
3437
 
 
3438
  DBG (DBG_proc, "gl124_coarse_gain_calibration: dpi = %d\n", dpi);
 
3439
 
 
3440
  /* no gain nor offset for TI AFE */
 
3441
  RIE (sanei_genesys_read_register (dev, REG0A, &reg0a));
 
3442
  if(((reg0a & REG0A_SIFSEL)>>REG0AS_SIFSEL)==3)
 
3443
    {
 
3444
      DBGCOMPLETED;
 
3445
      return status;
 
3446
    }
 
3447
 
 
3448
  /* coarse gain calibration is always done in color mode */
 
3449
  channels = 3;
 
3450
 
 
3451
  /* follow CKSEL */
 
3452
  if(dev->settings.xres<dev->sensor.optical_res)
 
3453
    {
 
3454
      coeff=0.9;
 
3455
      resolution=dev->sensor.optical_res/2;
 
3456
      resolution=dev->sensor.optical_res;
 
3457
    }
 
3458
  else
 
3459
    {
 
3460
      resolution=dev->sensor.optical_res;
 
3461
      coeff=1.0;
 
3462
    }
 
3463
  lines=10;
 
3464
  bpp=8;
 
3465
  pixels = (dev->sensor.sensor_pixels * resolution) / dev->sensor.optical_res,
 
3466
 
 
3467
  status = gl124_init_scan_regs (dev,
 
3468
                                 dev->calib_reg,
 
3469
                                 resolution,
 
3470
                                 resolution,
 
3471
                                 0,
 
3472
                                 0,
 
3473
                                 pixels,
 
3474
                                 lines,
 
3475
                                 bpp,
 
3476
                                 channels,
 
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;
 
3484
 
 
3485
  if (status != SANE_STATUS_GOOD)
 
3486
    {
 
3487
      DBG (DBG_error,
 
3488
           "gl124_coarse_calibration: failed to setup scan: %s\n",
 
3489
           sane_strstatus (status));
 
3490
      return status;
 
3491
    }
 
3492
 
 
3493
  RIE (gl124_bulk_write_register
 
3494
       (dev, dev->calib_reg, GENESYS_GL124_MAX_REGS));
 
3495
 
 
3496
  total_size = pixels * channels * (16/bpp) * lines;
 
3497
 
 
3498
  line = malloc (total_size);
 
3499
  if (!line)
 
3500
    return SANE_STATUS_NO_MEM;
 
3501
 
 
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));
 
3505
 
 
3506
  if (DBG_LEVEL >= DBG_data)
 
3507
    sanei_genesys_write_pnm_file ("coarse.pnm", line, bpp, channels, pixels, lines);
 
3508
 
 
3509
  /* average value on each channel */
 
3510
  for (j = 0; j < channels; j++)
 
3511
    {
 
3512
      max[j] = 0;
 
3513
      for (i = pixels/4; i < (pixels*3/4); i++)
 
3514
        {
 
3515
          if(bpp==16)
 
3516
            {
 
3517
          if (dev->model->is_cis)
 
3518
            val =
 
3519
              line[i * 2 + j * 2 * pixels + 1] * 256 +
 
3520
              line[i * 2 + j * 2 * pixels];
 
3521
          else
 
3522
            val =
 
3523
              line[i * 2 * channels + 2 * j + 1] * 256 +
 
3524
              line[i * 2 * channels + 2 * j];
 
3525
            }
 
3526
          else
 
3527
            {
 
3528
          if (dev->model->is_cis)
 
3529
            val = line[i + j * pixels];
 
3530
          else
 
3531
            val = line[i * channels + j];
 
3532
            }
 
3533
 
 
3534
            max[j] += val;
 
3535
        }
 
3536
      max[j] = max[j] / (pixels/2);
 
3537
 
 
3538
      gain[j] = ((float) dev->sensor.gain_white_ref*coeff) / max[j];
 
3539
 
 
3540
      /* turn logical gain value into gain code, checking for overflow */
 
3541
      code = 283 - 208 / gain[j];
 
3542
      if (code > 255)
 
3543
        code = 255;
 
3544
      else if (code < 0)
 
3545
        code = 0;
 
3546
      dev->frontend.gain[j] = code;
 
3547
 
 
3548
      DBG (DBG_proc,
 
3549
           "gl124_coarse_gain_calibration: channel %d, max=%d, gain = %f, setting:%d\n",
 
3550
           j, max[j], gain[j], dev->frontend.gain[j]);
 
3551
    }
 
3552
 
 
3553
  if (dev->model->is_cis)
 
3554
    {
 
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];
 
3560
    }
 
3561
 
 
3562
  if (channels == 1)
 
3563
    {
 
3564
      dev->frontend.gain[0] = dev->frontend.gain[1];
 
3565
      dev->frontend.gain[2] = dev->frontend.gain[1];
 
3566
    }
 
3567
 
 
3568
  free (line);
 
3569
 
 
3570
  RIE (gl124_stop_action (dev));
 
3571
 
 
3572
  gl124_slow_back_home (dev, SANE_TRUE);
 
3573
 
 
3574
  DBGCOMPLETED;
 
3575
  return SANE_STATUS_GOOD;
 
3576
}
 
3577
 
 
3578
/*
 
3579
 * wait for lamp warmup by scanning the same line until difference
 
3580
 * between 2 scans is below a threshold
 
3581
 */
 
3582
static SANE_Status
 
3583
gl124_init_regs_for_warmup (Genesys_Device * dev,
 
3584
                            Genesys_Register_Set * reg,
 
3585
                            int *channels, int *total_size)
 
3586
{
 
3587
  int num_pixels;
 
3588
  SANE_Status status = SANE_STATUS_GOOD;
 
3589
  Genesys_Register_Set *r;
 
3590
 
 
3591
  DBGSTART;
 
3592
  if (dev == NULL || reg == NULL || channels == NULL || total_size == NULL)
 
3593
    return SANE_STATUS_INVAL;
 
3594
  
 
3595
  *channels=3;
 
3596
 
 
3597
  memcpy (reg, dev->reg, (GENESYS_GL124_MAX_REGS + 1) * sizeof (Genesys_Register_Set));
 
3598
  status = gl124_init_scan_regs (dev,
 
3599
                                 reg,
 
3600
                                 dev->sensor.optical_res,
 
3601
                                 dev->motor.base_ydpi,
 
3602
                                 dev->sensor.sensor_pixels/4,
 
3603
                                 0,
 
3604
                                 dev->sensor.sensor_pixels/2,
 
3605
                                 1,
 
3606
                                 8,
 
3607
                                 *channels,
 
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);
 
3613
 
 
3614
  if (status != SANE_STATUS_GOOD)
 
3615
    {
 
3616
      DBG (DBG_error,
 
3617
           "gl124_init_regs_for_warmup: failed to setup scan: %s\n",
 
3618
           sane_strstatus (status));
 
3619
      return status;
 
3620
    }
 
3621
 
 
3622
  num_pixels = dev->current_setup.pixels;
 
3623
 
 
3624
  *total_size = num_pixels * 3 * 1;     /* colors * bytes_per_color * scan lines */
 
3625
 
 
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));
 
3629
 
 
3630
  DBGCOMPLETED;
 
3631
  return SANE_STATUS_GOOD;
 
3632
}
 
3633
 
 
3634
static SANE_Status
 
3635
gl124_is_compatible_calibration (Genesys_Device * dev,
 
3636
                                 Genesys_Calibration_Cache * cache,
 
3637
                                 int for_overwrite)
 
3638
{
 
3639
#ifdef HAVE_SYS_TIME_H
 
3640
  struct timeval time;
 
3641
#endif
 
3642
  int compatible = 1, resolution;
 
3643
  SANE_Status status;
 
3644
 
 
3645
  DBGSTART;
 
3646
  
 
3647
  if (cache == NULL || for_overwrite)
 
3648
    return SANE_STATUS_UNSUPPORTED;
 
3649
 
 
3650
  status = gl124_calculate_current_setup (dev);
 
3651
  if (status != SANE_STATUS_GOOD)
 
3652
    {
 
3653
      DBG (DBG_error,
 
3654
           "gl124_is_compatible_calibration: failed to calculate current setup: %s\n",
 
3655
           sane_strstatus (status));
 
3656
      return status;
 
3657
    }
 
3658
  resolution=gl124_compute_dpihw(dev,dev->settings.xres);
 
3659
  dev->current_setup.scan_method = dev->settings.scan_method;
 
3660
 
 
3661
  DBG (DBG_proc, "gl124_is_compatible_calibration: checking\n");
 
3662
  
 
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)
 
3667
    {
 
3668
      DBG (DBG_io,
 
3669
           "gl124_is_compatible_calibration: current method=%d, used=%d\n",
 
3670
           dev->current_setup.scan_method, cache->used_setup.scan_method);
 
3671
      compatible = 0;
 
3672
    }
 
3673
  if (!compatible)
 
3674
    {
 
3675
      DBG (DBG_proc,
 
3676
           "gl124_is_compatible_calibration: completed, non compatible cache\n");
 
3677
      return SANE_STATUS_UNSUPPORTED;
 
3678
    }
 
3679
 
 
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))
 
3686
    {
 
3687
      DBG (DBG_proc,
 
3688
           "gl124_is_compatible_calibration: expired entry, non compatible cache\n");
 
3689
      return SANE_STATUS_UNSUPPORTED;
 
3690
    }
 
3691
#endif
 
3692
 
 
3693
  DBGCOMPLETED;
 
3694
  return SANE_STATUS_GOOD;
 
3695
}
 
3696
 
 
3697
/** 
 
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)
 
3702
GPIO(0xa8)=0x3e
 
3703
 */
 
3704
static SANE_Status
 
3705
gl124_init_gpio (Genesys_Device * dev)
 
3706
{
 
3707
  SANE_Status status = SANE_STATUS_GOOD;
 
3708
  int idx;
 
3709
 
 
3710
  DBGSTART;
 
3711
 
 
3712
  /* per model GPIO layout */
 
3713
  if (strcmp (dev->model->name, "canon-lide-110") == 0)
 
3714
    {
 
3715
      idx = 0;
 
3716
    }
 
3717
  else
 
3718
    {                           /* canon LiDE 210 case */
 
3719
      idx = 1;
 
3720
    }
 
3721
 
 
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));
 
3729
 
 
3730
  DBGCOMPLETED;
 
3731
  return status;
 
3732
}
 
3733
 
 
3734
/** 
 
3735
 * set memory layout by filling values in dedicated registers
 
3736
 */
 
3737
static SANE_Status
 
3738
gl124_init_memory_layout (Genesys_Device * dev)
 
3739
{
 
3740
  SANE_Status status = SANE_STATUS_GOOD;
 
3741
  int idx = 0;
 
3742
 
 
3743
  DBGSTART;
 
3744
 
 
3745
  /* point to per model memory layout */
 
3746
  if (strcmp (dev->model->name, "canon-lide-110") == 0)
 
3747
    {
 
3748
      idx = 0;
 
3749
    }
 
3750
  else
 
3751
    {                           /* canon LiDE 210 case */
 
3752
      idx = 1;
 
3753
    }
 
3754
 
 
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);
 
3763
 
 
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);
 
3773
 
 
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);
 
3780
 
 
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);
 
3790
 
 
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);
 
3800
 
 
3801
  DBGCOMPLETED;
 
3802
  return status;
 
3803
}
 
3804
 
 
3805
 
 
3806
 
 
3807
/* *
 
3808
 * initialize ASIC from power on condition
 
3809
 */
 
3810
static SANE_Status
 
3811
gl124_cold_boot (Genesys_Device * dev)
 
3812
{
 
3813
  SANE_Status status;
 
3814
  uint8_t val;
 
3815
 
 
3816
  DBGSTART;
 
3817
 
 
3818
  RIE (sanei_genesys_write_register (dev, 0x0e, 0x01));
 
3819
  RIE (sanei_genesys_write_register (dev, 0x0e, 0x00));
 
3820
 
 
3821
  /* enable GPOE 17 */
 
3822
  RIE (sanei_genesys_write_register (dev, 0x36, 0x01));
 
3823
 
 
3824
  /* set GPIO 17 */
 
3825
  RIE (sanei_genesys_read_register (dev, 0x33, &val));
 
3826
  val |= 0x01;
 
3827
  RIE (sanei_genesys_write_register (dev, 0x33, val));
 
3828
 
 
3829
  /* test CHKVER */
 
3830
  RIE (sanei_genesys_read_hregister (dev, REG100, &val));
 
3831
  if (val & REG100_CHKVER)
 
3832
    {
 
3833
      RIE (sanei_genesys_read_register (dev, 0x00, &val));
 
3834
      DBG (DBG_info,
 
3835
           "gl124_cold_boot: reported version for genesys chip is 0x%02x\n",
 
3836
           val);
 
3837
    }
 
3838
 
 
3839
  /* Set default values for registers */
 
3840
  gl124_init_registers (dev);
 
3841
 
 
3842
  /* Write initial registers */
 
3843
  RIE (gl124_bulk_write_register (dev, dev->reg, GENESYS_GL124_MAX_REGS));
 
3844
 
 
3845
  /* tune reg 0B */
 
3846
  val = REG0B_30MHZ | REG0B_ENBDRAM | REG0B_64M;
 
3847
  RIE (sanei_genesys_write_register (dev, REG0B, val));
 
3848
  dev->reg[reg_0x0b].address = 0x00;
 
3849
 
 
3850
  /* set up end access */
 
3851
  RIE (sanei_genesys_write_0x8c (dev, 0x10, 0x0b));
 
3852
  RIE (sanei_genesys_write_0x8c (dev, 0x13, 0x0e));
 
3853
 
 
3854
  /* CIS_LINE */
 
3855
  SETREG (0x08, REG08_CIS_LINE);
 
3856
  RIE (sanei_genesys_write_register (dev, 0x08, dev->reg[reg_0x08].value));
 
3857
 
 
3858
  /* setup gpio */
 
3859
  RIE (gl124_init_gpio (dev));
 
3860
 
 
3861
  /* setup internal memory layout */
 
3862
  RIE (gl124_init_memory_layout (dev));
 
3863
 
 
3864
  DBGCOMPLETED;
 
3865
  return SANE_STATUS_GOOD;
 
3866
}
 
3867
 
 
3868
/* *
 
3869
 * initialize backend and ASIC : registers, motor tables, and gamma tables
 
3870
 * then ensure scanner's head is at home
 
3871
 */
 
3872
#ifndef UNIT_TESTING
 
3873
static
 
3874
#endif
 
3875
SANE_Status
 
3876
gl124_init (Genesys_Device * dev)
 
3877
{
 
3878
  SANE_Status status;
 
3879
  uint8_t val;
 
3880
  SANE_Bool cold = SANE_TRUE;
 
3881
  int size;
 
3882
 
 
3883
  DBG_INIT ();
 
3884
  DBGSTART;
 
3885
 
 
3886
  /* URB    16  control  0xc0 0x0c 0x8e 0x0b len     1 read  0x00 */
 
3887
  status =
 
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)
 
3891
    {
 
3892
      DBG (DBG_error,
 
3893
           "gl124_init: request register failed %s\n",
 
3894
           sane_strstatus (status));
 
3895
      return status;
 
3896
    }
 
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");
 
3900
  if (val & 0x08)
 
3901
    {
 
3902
      dev->usb_mode = 1;
 
3903
    }
 
3904
  else
 
3905
    {
 
3906
      dev->usb_mode = 2;
 
3907
    }
 
3908
 
 
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)
 
3915
    {
 
3916
      cold = SANE_FALSE;
 
3917
    }
 
3918
  DBG (DBG_info, "%s: device is %s\n", __FUNCTION__, cold ? "cold" : "warm");
 
3919
 
 
3920
  /* don't do anything if backend is initialized and hardware hasn't been
 
3921
   * replug */
 
3922
  if (dev->already_initialized && !cold)
 
3923
    {
 
3924
      DBG (DBG_info, "gl124_init: already initialized, nothing to do\n");
 
3925
      return SANE_STATUS_GOOD;
 
3926
    }
 
3927
 
 
3928
  /* set up hardware and registers */
 
3929
  RIE (gl124_cold_boot (dev));
 
3930
 
 
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);
 
3937
 
 
3938
  dev->settings.color_filter = 0;
 
3939
 
 
3940
  memcpy (dev->calib_reg, dev->reg,
 
3941
          GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set));
 
3942
 
 
3943
  /* Set analog frontend */
 
3944
  RIE (gl124_set_fe (dev, AFE_INIT));
 
3945
 
 
3946
  /* init gamma tables */
 
3947
  size = 256;
 
3948
  if (dev->sensor.red_gamma_table == NULL)
 
3949
    {
 
3950
      dev->sensor.red_gamma_table = (uint16_t *) malloc (2 * size);
 
3951
      if (dev->sensor.red_gamma_table == NULL)
 
3952
        {
 
3953
          DBG (DBG_error,
 
3954
               "gl124_init: could not allocate memory for gamma table\n");
 
3955
          return SANE_STATUS_NO_MEM;
 
3956
        }
 
3957
      sanei_genesys_create_gamma_table (dev->sensor.red_gamma_table, size,
 
3958
                                        65535, 65535, dev->sensor.red_gamma);
 
3959
    }
 
3960
  if (dev->sensor.green_gamma_table == NULL)
 
3961
    {
 
3962
      dev->sensor.green_gamma_table = (uint16_t *) malloc (2 * size);
 
3963
      if (dev->sensor.red_gamma_table == NULL)
 
3964
        {
 
3965
          DBG (DBG_error,
 
3966
               "gl124_init: could not allocate memory for gamma table\n");
 
3967
          return SANE_STATUS_NO_MEM;
 
3968
        }
 
3969
      sanei_genesys_create_gamma_table (dev->sensor.green_gamma_table, size,
 
3970
                                        65535, 65535,
 
3971
                                        dev->sensor.green_gamma);
 
3972
    }
 
3973
  if (dev->sensor.blue_gamma_table == NULL)
 
3974
    {
 
3975
      dev->sensor.blue_gamma_table = (uint16_t *) malloc (2 * size);
 
3976
      if (dev->sensor.red_gamma_table == NULL)
 
3977
        {
 
3978
          DBG (DBG_error,
 
3979
               "gl124_init: could not allocate memory for gamma table\n");
 
3980
          return SANE_STATUS_NO_MEM;
 
3981
        }
 
3982
      sanei_genesys_create_gamma_table (dev->sensor.blue_gamma_table, size,
 
3983
                                        65535, 65535, dev->sensor.blue_gamma);
 
3984
    }
 
3985
 
 
3986
  dev->oe_buffer.buffer = NULL;
 
3987
  dev->already_initialized = SANE_TRUE;
 
3988
 
 
3989
  /* Move home if needed */
 
3990
  RIE (gl124_slow_back_home (dev, SANE_TRUE));
 
3991
  dev->scanhead_position_in_steps = 0;
 
3992
 
 
3993
  /* Set powersaving (default = 15 minutes) */
 
3994
  RIE (gl124_set_powersaving (dev, 15));
 
3995
 
 
3996
  DBGCOMPLETED;
 
3997
  return status;
 
3998
}
 
3999
 
 
4000
static SANE_Status
 
4001
gl124_update_hardware_sensors (Genesys_Scanner * s)
 
4002
{
 
4003
  /* do what is needed to get a new set of events, but try to not lose
 
4004
     any of them.
 
4005
   */
 
4006
  SANE_Status status = SANE_STATUS_GOOD;
 
4007
  uint8_t val=0;
 
4008
 
 
4009
  RIE (sanei_genesys_read_register (s->dev, REG31, &val));
 
4010
 
 
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;
 
4019
  return status;
 
4020
}
 
4021
 
 
4022
 
 
4023
/** the gl124 command set */
 
4024
static Genesys_Command_Set gl124_cmd_set = {
 
4025
  "gl124-generic",              /* the name of this set */
 
4026
 
 
4027
  gl124_init,
 
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,
 
4032
 
 
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,
 
4040
 
 
4041
  gl124_bulk_full_size,
 
4042
 
 
4043
  gl124_set_fe,
 
4044
  gl124_set_powersaving,
 
4045
  gl124_save_power,
 
4046
 
 
4047
  gl124_set_motor_power,
 
4048
  gl124_set_lamp_power,
 
4049
 
 
4050
  gl124_begin_scan,
 
4051
  gl124_end_scan,
 
4052
 
 
4053
  gl124_send_gamma_table,
 
4054
 
 
4055
  gl124_search_start_position,
 
4056
 
 
4057
  gl124_offset_calibration,
 
4058
  gl124_coarse_gain_calibration,
 
4059
  gl124_led_calibration,
 
4060
 
 
4061
  gl124_slow_back_home,
 
4062
 
 
4063
  gl124_bulk_write_register,
 
4064
  NULL,
 
4065
  gl124_bulk_read_data,
 
4066
 
 
4067
  gl124_update_hardware_sensors,
 
4068
 
 
4069
  /* no sheetfed support for now */
 
4070
  NULL,
 
4071
  NULL,
 
4072
  NULL,
 
4073
  NULL,
 
4074
 
 
4075
  gl124_is_compatible_calibration,
 
4076
  NULL,
 
4077
  gl124_send_shading_data
 
4078
};
 
4079
 
 
4080
SANE_Status
 
4081
sanei_gl124_init_cmd_set (Genesys_Device * dev)
 
4082
{
 
4083
  dev->model->cmd_set = &gl124_cmd_set;
 
4084
  return SANE_STATUS_GOOD;
 
4085
}
 
4086
 
 
4087
/* vim: set sw=2 cino=>2se-1sn-1s{s^-1st0(0u0 smarttab expandtab: */