~ubuntu-branches/ubuntu/saucy/sane-backends/saucy

« back to all changes in this revision

Viewing changes to backend/genesys_gl843.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Ancell
  • Date: 2011-02-14 14:28:56 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20110214142856-6gxjetg88q9zctid
Tags: 1.0.22-0ubuntu1
* New upstream release
* debian/control:
  - Use standards version 3.9.1
* debian/patches/allow_dll.d_symlinks.patch:
* debian/patches/fix_epson2_cancel.patch:
* debian/patches/fix_epson2_commands.patch:
* debian/patches/fix_xerox_mfp_color_mode.patch:
* debian/patches/genesys_disable_raw_data_log.patch:
* debian/patches/no_translations.patch:
* debian/patches/saned_exit_avahi_process.patch:
* debian/patches/scsi_perfection_2450.patch:
* debian/patches/scsi_scanjet_4c.patch:
* debian/patches/xerox_mfp_new_ids.patch:
  - Applied upstream
* debian/watch:
  - Dropped, the URL is not consistent between releases

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_gl843.h"
 
46
 
 
47
/****************************************************************************
 
48
 Low level function
 
49
 ****************************************************************************/
 
50
 
 
51
/**
 
52
 * decodes and prints content of status (0x41) register
 
53
 * @param val value read from reg41
 
54
 */
 
55
#ifndef UNIT_TESTING
 
56
static
 
57
#endif
 
58
  void
 
59
print_status (uint8_t val)
 
60
{
 
61
  char msg[80];
 
62
 
 
63
  sprintf (msg, "%s%s%s%s%s%s%s%s",
 
64
           val & REG41_PWRBIT ? "PWRBIT " : "",
 
65
           val & REG41_BUFEMPTY ? "BUFEMPTY " : "",
 
66
           val & REG41_FEEDFSH ? "FEEDFSH " : "",
 
67
           val & REG41_SCANFSH ? "SCANFSH " : "",
 
68
           val & REG41_HOMESNR ? "HOMESNR " : "",
 
69
           val & REG41_LAMPSTS ? "LAMPSTS " : "",
 
70
           val & REG41_FEBUSY ? "FEBUSY " : "",
 
71
           val & REG41_MOTORENB ? "MOTORENB" : "");
 
72
  DBG (DBG_info, "status=%s\n", msg);
 
73
}
 
74
 
 
75
/* ------------------------------------------------------------------------ */
 
76
/*                  Read and write RAM, registers and AFE                   */
 
77
/* ------------------------------------------------------------------------ */
 
78
 
 
79
/**
 
80
 *
 
81
 */
 
82
static SANE_Status
 
83
write_end_access (Genesys_Device * dev, uint8_t index, uint8_t val)
 
84
{
 
85
  SANE_Status status;
 
86
 
 
87
  DBG (DBG_io, "write_end_access: 0x%02x,0x%02x\n", index, val);
 
88
 
 
89
  status =
 
90
    sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_REGISTER,
 
91
                           VALUE_BUF_ENDACCESS, index, 1, &val);
 
92
  if (status != SANE_STATUS_GOOD)
 
93
    {
 
94
      DBG (DBG_error,
 
95
           "write_end_access: failed %s\n", sane_strstatus (status));
 
96
    }
 
97
  return status;
 
98
}
 
99
 
 
100
/* Write bulk data (e.g. gamma) */
 
101
static SANE_Status
 
102
gl843_bulk_write_data (Genesys_Device * dev, uint8_t addr,
 
103
                       uint8_t * data, size_t len)
 
104
{
 
105
  SANE_Status status;
 
106
  size_t size;
 
107
  uint8_t outdata[8];
 
108
 
 
109
  DBGSTART;
 
110
  DBG (DBG_io, "gl843_bulk_write_data writing %lu bytes\n", (u_long) len);
 
111
 
 
112
  status =
 
113
    sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_REGISTER,
 
114
                           VALUE_SET_REGISTER, INDEX, 1, &addr);
 
115
  if (status != SANE_STATUS_GOOD)
 
116
    {
 
117
      DBG (DBG_error,
 
118
           "gl843_bulk_write_data failed while setting register: %s\n",
 
119
           sane_strstatus (status));
 
120
      return status;
 
121
    }
 
122
 
 
123
  /* TODO check with G4050 that we shouldn't loop at all */
 
124
  while (len)
 
125
    {
 
126
      size = len;
 
127
 
 
128
      outdata[0] = BULK_OUT;
 
129
      outdata[1] = BULK_RAM;
 
130
      outdata[2] = 0x00;
 
131
      outdata[3] = 0x00;
 
132
      outdata[4] = (size & 0xff);
 
133
      outdata[5] = ((size >> 8) & 0xff);
 
134
      outdata[6] = ((size >> 16) & 0xff);
 
135
      outdata[7] = ((size >> 24) & 0xff);
 
136
 
 
137
      status =
 
138
        sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_BUFFER,
 
139
                               VALUE_BUFFER, INDEX, sizeof (outdata),
 
140
                               outdata);
 
141
      if (status != SANE_STATUS_GOOD)
 
142
        {
 
143
          DBG (DBG_error,
 
144
               "gl843_bulk_write_data failed while writing command: %s\n",
 
145
               sane_strstatus (status));
 
146
          return status;
 
147
        }
 
148
 
 
149
      status = sanei_usb_write_bulk (dev->dn, data, &size);
 
150
      if (status != SANE_STATUS_GOOD)
 
151
        {
 
152
          DBG (DBG_error,
 
153
               "gl843_bulk_write_data failed while writing bulk data: %s\n",
 
154
               sane_strstatus (status));
 
155
          return status;
 
156
        }
 
157
 
 
158
      DBG (DBG_io2,
 
159
           "gl843_bulk_write_data: gamma wrote %lu bytes, %lu remaining\n",
 
160
           (u_long) size, (u_long) (len - size));
 
161
 
 
162
      len -= size;
 
163
      data += size;
 
164
    }
 
165
 
 
166
  DBGCOMPLETED;
 
167
  return status;
 
168
}
 
169
 
 
170
/* Set address for writing data */
 
171
static SANE_Status
 
172
gl843_set_buffer_address (Genesys_Device * dev, uint32_t addr)
 
173
{
 
174
  SANE_Status status;
 
175
 
 
176
  DBG (DBG_io, "gl843_set_buffer_address: setting address to 0x%05x\n",
 
177
       addr & 0xffff);
 
178
 
 
179
  status = sanei_genesys_write_register (dev, 0x5b, ((addr >> 8) & 0xff));
 
180
  if (status != SANE_STATUS_GOOD)
 
181
    {
 
182
      DBG (DBG_error,
 
183
           "gl843_set_buffer_address: failed while writing high byte: %s\n",
 
184
           sane_strstatus (status));
 
185
      return status;
 
186
    }
 
187
 
 
188
  status = sanei_genesys_write_register (dev, 0x5c, (addr & 0xff));
 
189
  if (status != SANE_STATUS_GOOD)
 
190
    {
 
191
      DBG (DBG_error,
 
192
           "gl843_set_buffer_address: failed while writing low byte: %s\n",
 
193
           sane_strstatus (status));
 
194
      return status;
 
195
    }
 
196
 
 
197
  DBG (DBG_io, "gl843_set_buffer_address: completed\n");
 
198
 
 
199
  return status;
 
200
}
 
201
 
 
202
/**
 
203
 * writes a block of data to RAM
 
204
 * @param dev USB device
 
205
 * @param addr RAM address to write to
 
206
 * @param size size of the chunk of data
 
207
 * @param data pointer to the data to write
 
208
 */
 
209
static SANE_Status
 
210
write_data (Genesys_Device * dev, uint32_t addr, uint32_t size,
 
211
            uint8_t * data)
 
212
{
 
213
  SANE_Status status = SANE_STATUS_GOOD;
 
214
 
 
215
  DBGSTART;
 
216
 
 
217
  status = gl843_set_buffer_address (dev, addr);
 
218
  if (status != SANE_STATUS_GOOD)
 
219
    {
 
220
      DBG (DBG_error,
 
221
           "write_data: failed while setting address for bulk write data: %s\n",
 
222
           sane_strstatus (status));
 
223
      return status;
 
224
    }
 
225
 
 
226
  /* write actual data */
 
227
  status = gl843_bulk_write_data (dev, 0x28, data, size);
 
228
  if (status != SANE_STATUS_GOOD)
 
229
    {
 
230
      DBG (DBG_error,
 
231
           "write_data: failed while writing bulk write data: %s\n",
 
232
           sane_strstatus (status));
 
233
      return status;
 
234
    }
 
235
 
 
236
  /* set back address to 0 */
 
237
  status = gl843_set_buffer_address (dev, 0);
 
238
  if (status != SANE_STATUS_GOOD)
 
239
    {
 
240
      DBG (DBG_error,
 
241
           "write_data: failed setting to default RAM address: %s\n",
 
242
           sane_strstatus (status));
 
243
      return status;
 
244
    }
 
245
  DBGCOMPLETED;
 
246
  return status;
 
247
}
 
248
 
 
249
/**
 
250
 * Write to many GL843 registers at once
 
251
 */
 
252
#ifndef UNIT_TESTING
 
253
static
 
254
#endif
 
255
  SANE_Status
 
256
gl843_bulk_write_register (Genesys_Device * dev, Genesys_Register_Set * reg,
 
257
                           size_t elems)
 
258
{
 
259
  SANE_Status status = SANE_STATUS_GOOD;
 
260
  size_t i;
 
261
 
 
262
  for (i = 0; i < elems && status == SANE_STATUS_GOOD; i++)
 
263
    {
 
264
      if (reg[i].address != 0)
 
265
        {
 
266
          status =
 
267
            sanei_genesys_write_register (dev, reg[i].address, reg[i].value);
 
268
        }
 
269
    }
 
270
 
 
271
  DBG (DBG_io, "gl843_bulk_write_register: wrote %lu registers\n",
 
272
       (u_long) elems);
 
273
  return status;
 
274
}
 
275
 
 
276
static SANE_Status
 
277
gl843_bulk_read_data (Genesys_Device * dev, uint8_t addr,
 
278
                      uint8_t * data, size_t len)
 
279
{
 
280
  SANE_Status status;
 
281
  size_t size;
 
282
  uint8_t outdata[8];
 
283
 
 
284
  DBGSTART;
 
285
  DBG (DBG_io,
 
286
       "gl843_bulk_read_data: requesting %lu bytes from 0x%02x addr\n",
 
287
       (u_long) len, addr);
 
288
 
 
289
  status =
 
290
    sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_REGISTER,
 
291
                           VALUE_SET_REGISTER, 0, 1, &addr);
 
292
  if (status != SANE_STATUS_GOOD)
 
293
    {
 
294
      DBG (DBG_error,
 
295
           "write_data: failed to set register address %s\n",
 
296
           sane_strstatus (status));
 
297
      return status;
 
298
    }
 
299
 
 
300
  if (len == 0)
 
301
    return SANE_STATUS_GOOD;
 
302
 
 
303
  outdata[0] = BULK_IN;
 
304
  outdata[1] = BULK_RAM;
 
305
  outdata[2] = VALUE_BUFFER;
 
306
  outdata[3] = 0;
 
307
  outdata[4] = (len & 0xff);
 
308
  outdata[5] = ((len >> 8) & 0xff);
 
309
  outdata[6] = ((len >> 16) & 0xff);
 
310
  outdata[7] = ((len >> 24) & 0xff);
 
311
 
 
312
  status =
 
313
    sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_BUFFER,
 
314
                           VALUE_BUFFER, INDEX, sizeof (outdata), outdata);
 
315
  if (status != SANE_STATUS_GOOD)
 
316
    {
 
317
      DBG (DBG_error,
 
318
           "gl843_bulk_read_data failed while writing command: %s\n",
 
319
           sane_strstatus (status));
 
320
      return status;
 
321
    }
 
322
 
 
323
  while (len)
 
324
    {
 
325
      if (len > 0xF000)
 
326
        size = 0xF000;
 
327
      else
 
328
        size = len;
 
329
      if (size >= 512)
 
330
        {
 
331
          size /= 512;
 
332
          size *= 512;
 
333
        }
 
334
 
 
335
      DBG (DBG_io2,
 
336
           "gl843_bulk_read_data: trying to read %lu bytes of data\n",
 
337
           (u_long) size);
 
338
 
 
339
      status = sanei_usb_read_bulk (dev->dn, data, &size);
 
340
      if (status != SANE_STATUS_GOOD)
 
341
        {
 
342
          DBG (DBG_error,
 
343
               "gl843_bulk_read_data failed while reading bulk data: %s\n",
 
344
               sane_strstatus (status));
 
345
          return status;
 
346
        }
 
347
 
 
348
      DBG (DBG_io2,
 
349
           "gl843_bulk_read_data read %lu bytes, %lu remaining\n",
 
350
           (u_long) size, (u_long) (len - size));
 
351
 
 
352
      len -= size;
 
353
      data += size;
 
354
    }
 
355
 
 
356
  DBGCOMPLETED;
 
357
  return SANE_STATUS_GOOD;
 
358
}
 
359
 
 
360
/****************************************************************************
 
361
 Mid level functions 
 
362
 ****************************************************************************/
 
363
 
 
364
static SANE_Bool
 
365
gl843_get_fast_feed_bit (Genesys_Register_Set * regs)
 
366
{
 
367
  Genesys_Register_Set *r = NULL;
 
368
 
 
369
  r = sanei_genesys_get_address (regs, REG02);
 
370
  if (r && (r->value & REG02_FASTFED))
 
371
    return SANE_TRUE;
 
372
  return SANE_FALSE;
 
373
}
 
374
 
 
375
static SANE_Bool
 
376
gl843_get_filter_bit (Genesys_Register_Set * regs)
 
377
{
 
378
  Genesys_Register_Set *r = NULL;
 
379
 
 
380
  r = sanei_genesys_get_address (regs, REG04);
 
381
  if (r && (r->value & REG04_FILTER))
 
382
    return SANE_TRUE;
 
383
  return SANE_FALSE;
 
384
}
 
385
 
 
386
static SANE_Bool
 
387
gl843_get_lineart_bit (Genesys_Register_Set * regs)
 
388
{
 
389
  Genesys_Register_Set *r = NULL;
 
390
 
 
391
  r = sanei_genesys_get_address (regs, REG04);
 
392
  if (r && (r->value & REG04_LINEART))
 
393
    return SANE_TRUE;
 
394
  return SANE_FALSE;
 
395
}
 
396
 
 
397
static SANE_Bool
 
398
gl843_get_bitset_bit (Genesys_Register_Set * regs)
 
399
{
 
400
  Genesys_Register_Set *r = NULL;
 
401
 
 
402
  r = sanei_genesys_get_address (regs, REG04);
 
403
  if (r && (r->value & REG04_BITSET))
 
404
    return SANE_TRUE;
 
405
  return SANE_FALSE;
 
406
}
 
407
 
 
408
static SANE_Bool
 
409
gl843_get_gain4_bit (Genesys_Register_Set * regs)
 
410
{
 
411
  Genesys_Register_Set *r = NULL;
 
412
 
 
413
  r = sanei_genesys_get_address (regs, REG06);
 
414
  if (r && (r->value & REG06_GAIN4))
 
415
    return SANE_TRUE;
 
416
  return SANE_FALSE;
 
417
}
 
418
 
 
419
/**
 
420
 * compute the step multiplier used
 
421
 */
 
422
static int
 
423
gl843_get_step_multiplier (Genesys_Register_Set * regs)
 
424
{
 
425
  Genesys_Register_Set *r = NULL;
 
426
  int value = 1;
 
427
 
 
428
  r = sanei_genesys_get_address (regs, 0x9d);
 
429
  if (r != NULL)
 
430
    {
 
431
      switch (r->value & 0x0c)
 
432
        {
 
433
        case 0x04:
 
434
          value = 2;
 
435
          break;
 
436
        case 0x08:
 
437
          value = 4;
 
438
          break;
 
439
        default:
 
440
          value = 1;
 
441
        }
 
442
    }
 
443
  DBG (DBG_io, "%s: step multiplier is %d\n", __FUNCTION__, value);
 
444
  return value;
 
445
}
 
446
 
 
447
static SANE_Bool
 
448
gl843_test_buffer_empty_bit (SANE_Byte val)
 
449
{
 
450
  if (val & REG41_BUFEMPTY)
 
451
    return SANE_TRUE;
 
452
  return SANE_FALSE;
 
453
}
 
454
 
 
455
static SANE_Bool
 
456
gl843_test_motor_flag_bit (SANE_Byte val)
 
457
{
 
458
  if (val & REG41_MOTORENB)
 
459
    return SANE_TRUE;
 
460
  return SANE_FALSE;
 
461
}
 
462
 
 
463
/** @get motor profile
 
464
 * search for the database of motor profiles and get the best one. Each
 
465
 * profile is at full step and at a reference exposure. Use KV-SS080 table
 
466
 * by default.
 
467
 * @param motor_type motor id
 
468
 * @param exposure exposure time
 
469
 * @return a pointer to a Motor_Profile struct
 
470
 */
 
471
static Motor_Profile *get_motor_profile(int motor_type, int exposure)
 
472
{
 
473
  unsigned int i;
 
474
  int idx;
 
475
 
 
476
  i=0;
 
477
  idx=-1;
 
478
  while(i<sizeof(motors)/sizeof(Motor_Profile))
 
479
    {
 
480
      /* exact match */
 
481
      if(motors[i].motor_type==motor_type && motors[i].exposure==exposure)
 
482
        {
 
483
          return &(motors[i]);
 
484
        }
 
485
 
 
486
      /* closest match */
 
487
      if(motors[i].motor_type==motor_type)
 
488
        {
 
489
          if(idx<0)
 
490
            {
 
491
              idx=i;
 
492
            }
 
493
          else
 
494
            {
 
495
              if(motors[i].exposure>=exposure 
 
496
              && motors[i].exposure<motors[idx].exposure)
 
497
                {
 
498
                  idx=i;
 
499
                }
 
500
            }
 
501
        }
 
502
      i++;
 
503
    }
 
504
 
 
505
  /* default fallback */
 
506
  if(idx<0)
 
507
    idx=0;
 
508
 
 
509
  return &(motors[idx]);
 
510
}
 
511
 
 
512
 
 
513
/** @brief returns the lowest possible ydpi for the device
 
514
 * Parses device entry to find lowest motor dpi.
 
515
 * @dev device description
 
516
 * @return lowest motor resolution
 
517
 */
 
518
static int gl843_get_lowest_ydpi(Genesys_Device *dev)
 
519
{
 
520
  int min=9600;
 
521
  int i=0;
 
522
 
 
523
  while(dev->model->ydpi_values[i]!=0)
 
524
    {
 
525
      if(dev->model->ydpi_values[i]<min)
 
526
        {
 
527
          min=dev->model->ydpi_values[i];
 
528
        }
 
529
      i++;
 
530
    }
 
531
  return min;
 
532
}
 
533
static int gl843_slope_table(uint16_t *slope,
 
534
                             int       *steps,
 
535
                             int       dpi,
 
536
                             int       exposure,
 
537
                             int       base_dpi,
 
538
                             int       step_type,
 
539
                             int       factor,
 
540
                             int       motor_type)
 
541
{
 
542
int sum, i;
 
543
uint16_t target,current;
 
544
Motor_Profile *profile;
 
545
 
 
546
        /* required speed */
 
547
        target=((exposure * dpi) / base_dpi)>>step_type;
 
548
        
 
549
        /* fill result with target speed */
 
550
        for(i=0;i<256*factor;i++)
 
551
          slope[i]=target;
 
552
 
 
553
        profile=get_motor_profile(motor_type,exposure);
 
554
 
 
555
        /* use profile to build table */
 
556
        sum=0;
 
557
        i=0;
 
558
        current=profile->table[0]>>step_type;
 
559
        while(i<(256*factor) && current>target)
 
560
          {
 
561
            slope[i]=current;
 
562
            sum+=slope[i];
 
563
            i++;
 
564
            current=profile->table[i]>>step_type;
 
565
          }
 
566
 
 
567
        /* align size on step time factor */
 
568
        while(i%factor!=0)
 
569
          {
 
570
            sum+=slope[i];
 
571
            i++;
 
572
          }
 
573
 
 
574
        /* return used steps and acceleration sum */
 
575
        *steps=i;
 
576
        return sum;
 
577
}
 
578
 
 
579
 
 
580
 
 
581
 
 
582
/** copy sensor specific settings */
 
583
static void
 
584
gl843_setup_sensor (Genesys_Device * dev, Genesys_Register_Set * regs, int dpi)
 
585
{
 
586
  Genesys_Register_Set *r;
 
587
  int i;
 
588
 
 
589
  DBGSTART;
 
590
 
 
591
  for (i = 0x06; i < 0x0e; i++)
 
592
    {
 
593
      r = sanei_genesys_get_address (regs, 0x10 + i);
 
594
      if (r)
 
595
        r->value = dev->sensor.regs_0x10_0x1d[i];
 
596
    }
 
597
 
 
598
  /* TODO we need to create another data struct
 
599
   * for CKxMAP and CKSEL */
 
600
  /* G4050/G4010 sensor */
 
601
  if (dev->model->ccd_type == CCD_G4050)
 
602
    {
 
603
      if(dpi<=300)
 
604
        {
 
605
          sanei_genesys_write_register (dev, 0x74, 0x00);
 
606
          sanei_genesys_write_register (dev, 0x75, 0x1c);
 
607
          sanei_genesys_write_register (dev, 0x76, 0x7f);
 
608
        }
 
609
      else if(dpi<=600)
 
610
        {
 
611
          sanei_genesys_write_register (dev, 0x74, 0x00);
 
612
          sanei_genesys_write_register (dev, 0x75, 0x01);
 
613
          sanei_genesys_write_register (dev, 0x76, 0xff);
 
614
        }
 
615
      else /* 800 to 2400 case */
 
616
        {
 
617
          sanei_genesys_write_register (dev, 0x5a, 0x40);
 
618
          sanei_genesys_write_register (dev, 0x74, 0x0f);
 
619
          sanei_genesys_write_register (dev, 0x75, 0xff);
 
620
          sanei_genesys_write_register (dev, 0x76, 0xff);
 
621
          sanei_genesys_write_register (dev, 0x77, 0x00);
 
622
          sanei_genesys_write_register (dev, 0x78, 0x01);
 
623
          sanei_genesys_write_register (dev, 0x7a, 0x00);
 
624
          sanei_genesys_write_register (dev, 0x7b, 0x01);
 
625
          sanei_genesys_write_register (dev, 0x7d, 0x90);
 
626
          sanei_genesys_write_register (dev, 0x80, 0x05);
 
627
          sanei_genesys_write_register (dev, 0x9e, 0xc0);
 
628
        }
 
629
    }
 
630
 
 
631
  for (i = 0; i < 9; i++)
 
632
    {
 
633
      r = sanei_genesys_get_address (regs, 0x52 + i);
 
634
      if (r)
 
635
        r->value = dev->sensor.regs_0x52_0x5e[i];
 
636
    }
 
637
 
 
638
  DBG (DBG_proc, "gl843_setup_sensor: completed \n");
 
639
}
 
640
 
 
641
 
 
642
/* returns the max register bulk size */
 
643
static int
 
644
gl843_bulk_full_size (void)
 
645
{
 
646
  return GENESYS_GL843_MAX_REGS;
 
647
}
 
648
 
 
649
/** @brief set all registers to default values .
 
650
 * This function is called only once at the beginning and
 
651
 * fills register startup values for registers reused across scans.
 
652
 * Those that are rarely modified or not modified are written
 
653
 * individually.
 
654
 * @param dev device structure holding register set to initialize
 
655
 */
 
656
static void
 
657
gl843_init_registers (Genesys_Device * dev)
 
658
{
 
659
  DBGSTART;
 
660
 
 
661
  memset (dev->reg, 0,
 
662
          GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set));
 
663
 
 
664
  /* default to KV-SS080 */
 
665
  SETREG (0xa2, 0x0f);
 
666
  SETREG (0x01, 0x00);
 
667
  SETREG (0x02, 0x78);
 
668
  SETREG (0x03, 0x1f);
 
669
  SETREG (0x04, 0x10);
 
670
  SETREG (0x05, 0x80);
 
671
  SETREG (0x06, 0xd8); /* SCANMOD=110, PWRBIT and GAIN4 */
 
672
  SETREG (0x08, 0x00);
 
673
  SETREG (0x09, 0x00);
 
674
  SETREG (0x0a, 0x00);
 
675
  SETREG (0x0b, 0x6a);
 
676
  SETREG (0x0c, 0x00);
 
677
  SETREG (0x10, 0x00);
 
678
  SETREG (0x11, 0x00);
 
679
  SETREG (0x12, 0x00);
 
680
  SETREG (0x13, 0x00);
 
681
  SETREG (0x14, 0x00);
 
682
  SETREG (0x15, 0x00);
 
683
  SETREG (0x16, 0x33);
 
684
  SETREG (0x17, 0x1c);
 
685
  SETREG (0x18, 0x10);
 
686
  SETREG (0x19, 0x2a);
 
687
  SETREG (0x1a, 0x04);
 
688
  SETREG (0x1b, 0x00);
 
689
  SETREG (0x1c, 0x20);
 
690
  SETREG (0x1d, 0x04);
 
691
  SETREG (0x1e, 0x10);
 
692
  SETREG (0x1f, 0x01);
 
693
  SETREG (0x20, 0x10);
 
694
  SETREG (0x21, 0x04);
 
695
  SETREG (0x22, 0x01);
 
696
  SETREG (0x23, 0x01);
 
697
  SETREG (0x24, 0x04);
 
698
  SETREG (0x25, 0x00);
 
699
  SETREG (0x26, 0x00);
 
700
  SETREG (0x27, 0x00);
 
701
  SETREG (0x2c, 0x02);
 
702
  SETREG (0x2d, 0x58);
 
703
  SETREG (0x2e, 0x80);
 
704
  SETREG (0x2f, 0x80);
 
705
  SETREG (0x30, 0x00);
 
706
  SETREG (0x31, 0x14);
 
707
  SETREG (0x32, 0x27);
 
708
  SETREG (0x33, 0xec);
 
709
  SETREG (0x34, 0x24);
 
710
  SETREG (0x35, 0x00);
 
711
  SETREG (0x36, 0xff);
 
712
  SETREG (0x37, 0xff);
 
713
  SETREG (0x38, 0x55);
 
714
  SETREG (0x39, 0xf0);
 
715
  SETREG (0x3d, 0x00);
 
716
  SETREG (0x3e, 0x00);
 
717
  SETREG (0x3f, 0x01);
 
718
  SETREG (0x52, 0x01);
 
719
  SETREG (0x53, 0x04);
 
720
  SETREG (0x54, 0x07);
 
721
  SETREG (0x55, 0x0a);
 
722
  SETREG (0x56, 0x0d);
 
723
  SETREG (0x57, 0x10);
 
724
  SETREG (0x58, 0x1b);
 
725
  SETREG (0x59, 0x00);
 
726
  SETREG (0x5a, 0x40);
 
727
  SETREG (0x5e, 0x23);
 
728
  SETREG (0x5f, 0x01);
 
729
  SETREG (0x60, 0x00);
 
730
  SETREG (0x61, 0x00);
 
731
  SETREG (0x62, 0x00);
 
732
  SETREG (0x63, 0x00);
 
733
  SETREG (0x64, 0x00);
 
734
  SETREG (0x65, 0x00);
 
735
  SETREG (0x67, 0x7f);
 
736
  SETREG (0x68, 0x7f);
 
737
  SETREG (0x69, 0x01);
 
738
  SETREG (0x6a, 0x04);
 
739
  SETREG (0x6b, 0x30);
 
740
  SETREG (0x70, 0x01);
 
741
  SETREG (0x71, 0x03);
 
742
  SETREG (0x72, 0x04);
 
743
  SETREG (0x73, 0x05);
 
744
  SETREG (0x7d, 0x00);
 
745
  SETREG (0x7f, 0x00);
 
746
  SETREG (0x80, 0x00);
 
747
  SETREG (0x81, 0x00);
 
748
  SETREG (0x82, 0x00);
 
749
  SETREG (0x83, 0x00);
 
750
  SETREG (0x84, 0x00);
 
751
  SETREG (0x85, 0x00);
 
752
  SETREG (0x86, 0x00);
 
753
  SETREG (0x87, 0x00);
 
754
  SETREG (0x9d, 0x04);
 
755
  SETREG (0x94, 0xff);
 
756
  SETREG (0xab, 0x50);
 
757
 
 
758
  /* G4050 values */
 
759
  if ((strcmp (dev->model->name, "hewlett-packard-scanjet-g4050") == 0)
 
760
   || (strcmp (dev->model->name, "hewlett-packard-scanjet-g4010") == 0))
 
761
    {
 
762
      SETREG (0x03, 0x1d);
 
763
      SETREG (0x05, 0x08);
 
764
      SETREG (0x06, 0xd0); /* SCANMOD=110, PWRBIT and no GAIN4 */
 
765
      SETREG (0x0a, 0x18);
 
766
      SETREG (0x0b, 0x69);
 
767
      SETREG (0x5e, 0x6f);
 
768
      SETREG (0x6b, 0xf4);
 
769
 
 
770
      SETREG (0x70, 0x00);
 
771
      SETREG (0x71, 0x02);
 
772
      SETREG (0x72, 0x00);
 
773
      SETREG (0x73, 0x00);
 
774
      SETREG (0x7d, 0x90);
 
775
      
 
776
      SETREG (0x80, 0x50);
 
777
      SETREG (0x9d, 0x08);
 
778
      SETREG (0xab, 0x40);
 
779
 
 
780
      /* XXX STEF XXX TODO move to set for scan */
 
781
      SETREG (0x98, 0x03);
 
782
      SETREG (0x99, 0x30);
 
783
      SETREG (0x9a, 0x01);
 
784
      SETREG (0x9b, 0x80);
 
785
      
 
786
      SETREG (0xac, 0x00);
 
787
    }
 
788
 
 
789
  /* fine tune upon device description */
 
790
  dev->reg[reg_0x05].value &= ~REG05_DPIHW;
 
791
  switch (dev->sensor.optical_res)
 
792
    {
 
793
    case 600:
 
794
      dev->reg[reg_0x05].value |= REG05_DPIHW_600;
 
795
      break;
 
796
    case 1200:
 
797
      dev->reg[reg_0x05].value |= REG05_DPIHW_1200;
 
798
      break;
 
799
    case 2400:
 
800
      dev->reg[reg_0x05].value |= REG05_DPIHW_2400;
 
801
      break;
 
802
    case 4800:
 
803
      dev->reg[reg_0x05].value |= REG05_DPIHW_4800;
 
804
      break;
 
805
    }
 
806
 
 
807
  /* initalize calibration reg */
 
808
  memcpy (dev->calib_reg, dev->reg,
 
809
          GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set));
 
810
 
 
811
  DBGCOMPLETED;
 
812
}
 
813
 
 
814
/* Send slope table for motor movement 
 
815
   slope_table in machine byte order
 
816
 */
 
817
#ifndef UNIT_TESTING
 
818
static
 
819
#endif
 
820
  SANE_Status
 
821
gl843_send_slope_table (Genesys_Device * dev, int table_nr,
 
822
                        uint16_t * slope_table, int steps)
 
823
{
 
824
  SANE_Status status;
 
825
  uint8_t *table;
 
826
  int i;
 
827
  char msg[2048 * 4];
 
828
 
 
829
  DBG (DBG_proc, "%s (table_nr = %d, steps = %d)\n", __FUNCTION__,
 
830
       table_nr, steps);
 
831
 
 
832
  table = (uint8_t *) malloc (steps * 2);
 
833
  for (i = 0; i < steps; i++)
 
834
    {
 
835
      table[i * 2] = slope_table[i] & 0xff;
 
836
      table[i * 2 + 1] = slope_table[i] >> 8;
 
837
    }
 
838
 
 
839
  if (DBG_LEVEL >= DBG_io)
 
840
    {
 
841
      sprintf (msg, "write slope %d (%d)=", table_nr, steps);
 
842
      for (i = 0; i < steps; i++)
 
843
        {
 
844
          sprintf (msg, "%s,%d", msg, slope_table[i]);
 
845
        }
 
846
      DBG (DBG_io, "%s: %s\n", __FUNCTION__, msg);
 
847
    }
 
848
 
 
849
  /* slope table addresses are fixed : 0x4000,  0x4800,  0x5000,  0x5800,  0x6000 */
 
850
  /* XXX STEF XXX USB 1.1 ? write_end_access (dev, 0x0f, 0x14); */
 
851
  status = write_data (dev, 0x4000 + 0x800 * table_nr, steps * 2, table);
 
852
  if (status != SANE_STATUS_GOOD)
 
853
    {
 
854
      DBG (DBG_error,
 
855
           "%s: write data failed writing slope table %d (%s)\n",
 
856
           __FUNCTION__, table_nr, sane_strstatus (status));
 
857
    }
 
858
 
 
859
  free (table);
 
860
  DBG (DBG_proc, "%s: completed\n", __FUNCTION__);
 
861
  return status;
 
862
}
 
863
 
 
864
 
 
865
/* Set values of analog frontend */
 
866
static SANE_Status
 
867
gl843_set_fe (Genesys_Device * dev, uint8_t set)
 
868
{
 
869
  SANE_Status status;
 
870
  uint8_t val;
 
871
  int i;
 
872
 
 
873
  DBG (DBG_proc, "gl843_set_fe (%s)\n",
 
874
       set == AFE_INIT ? "init" : set == AFE_SET ? "set" : set ==
 
875
       AFE_POWER_SAVE ? "powersave" : "huh?");
 
876
 
 
877
  if (set == AFE_INIT)
 
878
    {
 
879
      DBG (DBG_proc, "gl843_set_fe(): setting DAC %u\n",
 
880
           dev->model->dac_type);
 
881
      sanei_genesys_init_fe (dev);
 
882
    }
 
883
 
 
884
  /* check analog frontend type */
 
885
  RIE (sanei_genesys_read_register (dev, REG04, &val));
 
886
  if ((val & REG04_FESET) != 0x00)
 
887
    {
 
888
      /* for now there is no support for AD fe */
 
889
      DBG (DBG_proc, "gl843_set_fe(): unsupported frontend type %d\n",
 
890
           dev->reg[reg_0x04].value & REG04_FESET);
 
891
      return SANE_STATUS_UNSUPPORTED;
 
892
    }
 
893
 
 
894
  DBG (DBG_proc, "gl843_set_fe(): frontend reset complete\n");
 
895
 
 
896
  for (i = 1; i <= 3; i++)
 
897
    {
 
898
      status = sanei_genesys_fe_write_data (dev, i, dev->frontend.reg[i]);
 
899
      if (status != SANE_STATUS_GOOD)
 
900
        {
 
901
          DBG (DBG_error,
 
902
               "gl843_set_fe: writing reg[%d] failed: %s\n", i,
 
903
               sane_strstatus (status));
 
904
          return status;
 
905
        }
 
906
    }
 
907
 
 
908
  for (i = 0; i < 3; i++)
 
909
    {
 
910
      status =
 
911
        sanei_genesys_fe_write_data (dev, 0x20 + i, dev->frontend.offset[i]);
 
912
      if (status != SANE_STATUS_GOOD)
 
913
        {
 
914
          DBG (DBG_error,
 
915
               "gl843_set_fe: writing offset[%d] failed: %s\n", i,
 
916
               sane_strstatus (status));
 
917
          return status;
 
918
        }
 
919
    }
 
920
 
 
921
  if (dev->model->ccd_type == CCD_KVSS080)
 
922
    {
 
923
      for (i = 0; i < 3; i++)
 
924
        {
 
925
          status =
 
926
            sanei_genesys_fe_write_data (dev, 0x24 + i,
 
927
                                         dev->frontend.sign[i]);
 
928
          if (status != SANE_STATUS_GOOD)
 
929
            {
 
930
              DBG (DBG_error,
 
931
                   "gl843_set_fe: writing sign[%d] failed: %s\n", i,
 
932
                   sane_strstatus (status));
 
933
              return status;
 
934
            }
 
935
        }
 
936
    }
 
937
 
 
938
  for (i = 0; i < 3; i++)
 
939
    {
 
940
      status =
 
941
        sanei_genesys_fe_write_data (dev, 0x28 + i, dev->frontend.gain[i]);
 
942
      if (status != SANE_STATUS_GOOD)
 
943
        {
 
944
          DBG (DBG_error,
 
945
               "gl843_set_fe: writing gain[%d] failed: %s\n", i,
 
946
               sane_strstatus (status));
 
947
          return status;
 
948
        }
 
949
    }
 
950
 
 
951
  DBGCOMPLETED;
 
952
  return SANE_STATUS_GOOD;
 
953
}
 
954
 
 
955
#define MOTOR_FLAG_AUTO_GO_HOME             1
 
956
#define MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE 2
 
957
 
 
958
#define MOTOR_ACTION_FEED       1
 
959
#define MOTOR_ACTION_GO_HOME    2
 
960
#define MOTOR_ACTION_HOME_FREE  3
 
961
 
 
962
 
 
963
static SANE_Status
 
964
gl843_init_motor_regs_scan (Genesys_Device * dev,
 
965
                            Genesys_Register_Set * reg,
 
966
                            unsigned int scan_exposure_time,
 
967
                            float scan_yres,
 
968
                            int scan_step_type,
 
969
                            unsigned int scan_lines,
 
970
                            unsigned int scan_dummy,
 
971
                            unsigned int feed_steps,
 
972
                            int scan_power_mode,
 
973
                            unsigned int flags)
 
974
{
 
975
  SANE_Status status;
 
976
  int use_fast_fed;
 
977
  unsigned int fast_time;
 
978
  unsigned int slow_time;
 
979
  unsigned int lincnt;
 
980
  uint16_t scan_table[1024];
 
981
  uint16_t fast_table[1024];
 
982
  int scan_steps,fast_steps;
 
983
  unsigned int feedl,factor,dist;
 
984
  Genesys_Register_Set *r;
 
985
  uint32_t z1, z2;
 
986
 
 
987
  DBGSTART;
 
988
  DBG (DBG_info, "gl843_init_motor_regs_scan : scan_exposure_time=%d, "
 
989
       "scan_yres=%g, scan_step_type=%d, scan_lines=%d, scan_dummy=%d, "
 
990
       "feed_steps=%d, scan_power_mode=%d, flags=%x\n",
 
991
       scan_exposure_time,
 
992
       scan_yres,
 
993
       scan_step_type,
 
994
       scan_lines, scan_dummy, feed_steps, scan_power_mode, flags);
 
995
 
 
996
  /* get step multiplier */
 
997
  factor = gl843_get_step_multiplier (reg);
 
998
 
 
999
  use_fast_fed = 0;
 
1000
 
 
1001
  if(scan_yres>=300 && feed_steps>900)
 
1002
    use_fast_fed=1;
 
1003
  lincnt=scan_lines;
 
1004
 
 
1005
  r = sanei_genesys_get_address (reg, 0x25);
 
1006
  r->value = (lincnt >> 16) & 0xf;
 
1007
  r = sanei_genesys_get_address (reg, 0x26);
 
1008
  r->value = (lincnt >> 8) & 0xff;
 
1009
  r = sanei_genesys_get_address (reg, 0x27);
 
1010
  r->value = lincnt & 0xff;
 
1011
  DBG (DBG_io, "%s: lincnt=%d\n", __FUNCTION__, lincnt);
 
1012
 
 
1013
  /* compute register 02 value */
 
1014
  r = sanei_genesys_get_address (reg, REG02);
 
1015
  r->value = 0x00;
 
1016
  r->value |= REG02_MTRPWR;
 
1017
 
 
1018
  if (use_fast_fed)
 
1019
    r->value |= REG02_FASTFED;
 
1020
  else
 
1021
    r->value &= ~REG02_FASTFED;
 
1022
 
 
1023
  if (flags & MOTOR_FLAG_AUTO_GO_HOME)
 
1024
    r->value |= REG02_AGOHOME;
 
1025
 
 
1026
  if (flags & MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE)
 
1027
    r->value |= REG02_ACDCDIS;
 
1028
 
 
1029
  /* scan and backtracking slope table */
 
1030
  slow_time=gl843_slope_table(scan_table,
 
1031
                              &scan_steps,
 
1032
                              scan_yres,
 
1033
                              scan_exposure_time,
 
1034
                              dev->motor.base_ydpi,
 
1035
                              scan_step_type,
 
1036
                              factor,
 
1037
                              dev->model->motor_type);
 
1038
  RIE(gl843_send_slope_table (dev, SCAN_TABLE, scan_table, scan_steps));
 
1039
  RIE(gl843_send_slope_table (dev, BACKTRACK_TABLE, scan_table, scan_steps));
 
1040
 
 
1041
  r = sanei_genesys_get_address (reg, 0x21);
 
1042
  r->value = scan_steps/factor;
 
1043
 
 
1044
  r = sanei_genesys_get_address (reg, 0x24);
 
1045
  r->value = scan_steps/factor;
 
1046
 
 
1047
  /* fast table */
 
1048
  fast_time=gl843_slope_table(fast_table,
 
1049
                              &fast_steps,
 
1050
                              gl843_get_lowest_ydpi(dev),
 
1051
                              scan_exposure_time,
 
1052
                              dev->motor.base_ydpi,
 
1053
                              scan_step_type,
 
1054
                              factor,
 
1055
                              dev->model->motor_type);
 
1056
  RIE(gl843_send_slope_table (dev, STOP_TABLE, fast_table, fast_steps));
 
1057
  RIE(gl843_send_slope_table (dev, FAST_TABLE, fast_table, fast_steps));
 
1058
 
 
1059
  r = sanei_genesys_get_address (reg, 0x69);
 
1060
  r->value = fast_steps / factor;
 
1061
  /* better stop time */
 
1062
  r->value = 1;
 
1063
 
 
1064
  r = sanei_genesys_get_address (reg, REG6A);
 
1065
  r->value = fast_steps / factor;
 
1066
 
 
1067
  /* substract acceleration distance from feedl */
 
1068
  feedl=feed_steps;
 
1069
  feedl<<=scan_step_type;
 
1070
 
 
1071
  dist = scan_steps;
 
1072
  if (use_fast_fed) 
 
1073
    {
 
1074
        dist += fast_steps*2;
 
1075
    }
 
1076
  DBG (DBG_io2, "%s: acceleration distance=%d\n", __FUNCTION__, dist);
 
1077
 
 
1078
  /* get sure when don't insane value */
 
1079
  if(dist<feedl)
 
1080
    feedl -= dist;
 
1081
  else
 
1082
    feedl = 1;
 
1083
 
 
1084
  r = sanei_genesys_get_address (reg, 0x3d);
 
1085
  r->value = (feedl >> 16) & 0xf;
 
1086
  r = sanei_genesys_get_address (reg, 0x3e);
 
1087
  r->value = (feedl >> 8) & 0xff;
 
1088
  r = sanei_genesys_get_address (reg, 0x3f);
 
1089
  r->value = feedl & 0xff;
 
1090
  DBG (DBG_io, "%s: feedl=%d\n", __FUNCTION__, feedl);
 
1091
 
 
1092
  /* doesn't seem to matter that much */
 
1093
  sanei_genesys_calculate_zmode2 (use_fast_fed,
 
1094
                                  scan_exposure_time,
 
1095
                                  scan_table,
 
1096
                                  scan_steps,
 
1097
                                  feedl,
 
1098
                                  scan_steps,
 
1099
                                  &z1,
 
1100
                                  &z2);
 
1101
 
 
1102
  DBG (DBG_info, "gl843_init_motor_regs_scan: z1 = %d\n", z1);
 
1103
  r = sanei_genesys_get_address (reg, REG60);
 
1104
  r->value = ((z1 >> 16) & REG60_Z1MOD);
 
1105
  r = sanei_genesys_get_address (reg, REG61);
 
1106
  r->value = ((z1 >> 8) & REG61_Z1MOD);
 
1107
  r = sanei_genesys_get_address (reg, REG62);
 
1108
  r->value = (z1 & REG62_Z1MOD);
 
1109
 
 
1110
  DBG (DBG_info, "gl843_init_motor_regs_scan: z2 = %d\n", z2);
 
1111
  r = sanei_genesys_get_address (reg, REG63);
 
1112
  r->value = ((z2 >> 16) & REG63_Z2MOD);
 
1113
  r = sanei_genesys_get_address (reg, REG64);
 
1114
  r->value = ((z2 >> 8) & REG64_Z2MOD);
 
1115
  r = sanei_genesys_get_address (reg, REG65);
 
1116
  r->value = (z2 & REG65_Z2MOD);
 
1117
 
 
1118
  r = sanei_genesys_get_address (reg, REG1E);
 
1119
  r->value &= 0xf0;             /* 0 dummy lines */
 
1120
  r->value |= scan_dummy;       /* dummy lines */
 
1121
 
 
1122
  r = sanei_genesys_get_address (reg, REG67);
 
1123
  r->value = 0x3f | (scan_step_type << REG67S_STEPSEL);
 
1124
 
 
1125
  r = sanei_genesys_get_address (reg, REG68);
 
1126
  r->value = 0x3f | (scan_step_type << REG68S_FSTPSEL);
 
1127
 
 
1128
  /* steps for STOP table */
 
1129
  r = sanei_genesys_get_address (reg, 0x5f);
 
1130
  r->value = 1;
 
1131
 
 
1132
  /* Vref */
 
1133
  r = sanei_genesys_get_address (reg, 0x80);
 
1134
  r->value = 0x05;              /* kv 75,150,300 dpi */
 
1135
 
 
1136
  DBGCOMPLETED;
 
1137
  return SANE_STATUS_GOOD;
 
1138
}
 
1139
 
 
1140
#if 0
 
1141
static int
 
1142
gl843_get_dpihw (Genesys_Device * dev)
 
1143
{
 
1144
  Genesys_Register_Set *r;
 
1145
  r = sanei_genesys_get_address (dev->reg, REG05);
 
1146
  if ((r->value & REG05_DPIHW) == REG05_DPIHW_600)
 
1147
    return 600;
 
1148
  if ((r->value & REG05_DPIHW) == REG05_DPIHW_1200)
 
1149
    return 1200;
 
1150
  if ((r->value & REG05_DPIHW) == REG05_DPIHW_2400)
 
1151
    return 2400;
 
1152
  if ((r->value & REG05_DPIHW) == REG05_DPIHW_4800)
 
1153
    return 4800;
 
1154
  return 0;
 
1155
}
 
1156
#endif
 
1157
 
 
1158
/**@brief compute hardware sensor dpi to use
 
1159
 * compute the sensor hardware dpi based on target resolution
 
1160
 */
 
1161
static int gl843_compute_dpihw(Genesys_Device *dev, int xres)
 
1162
{
 
1163
  switch(dev->model->ccd_type)
 
1164
    {
 
1165
    case CCD_G4050:
 
1166
      if(xres<=300)
 
1167
        {
 
1168
          return 600;
 
1169
        }
 
1170
      if(xres<=600)
 
1171
        {
 
1172
          return 1200;
 
1173
        }
 
1174
      if(xres<=1200)
 
1175
        {
 
1176
          return 2400;
 
1177
        }
 
1178
      return dev->sensor.optical_res;
 
1179
    case CCD_KVSS080:
 
1180
    default:
 
1181
      return dev->sensor.optical_res;
 
1182
    }
 
1183
}
 
1184
 
 
1185
/**@brief compute exposure to use
 
1186
 * compute the sensor exposure based on target resolution
 
1187
 */
 
1188
static int gl843_compute_exposure(Genesys_Device *dev, int xres)
 
1189
{
 
1190
  switch(dev->model->ccd_type)
 
1191
    {
 
1192
    case CCD_G4050:
 
1193
      if(xres<=600)
 
1194
        {
 
1195
          return 8016;
 
1196
        }
 
1197
      return 56064 /* 21376 */;
 
1198
    case CCD_KVSS080:
 
1199
    default:
 
1200
      return 8000;
 
1201
    }
 
1202
}
 
1203
 
 
1204
/**@brief compute motor step type to use
 
1205
 * compute the step type (full, half, quarter, ...) to use based
 
1206
 * on target resolution
 
1207
 * @param dev device description
 
1208
 * @param yres motor resolution
 
1209
 * @return 0 for full step
 
1210
 *         1 for half step
 
1211
 *         2 for quarter step
 
1212
 *         3 for eighth step
 
1213
 */
 
1214
static int gl843_compute_step_type(Genesys_Device *dev, int yres)
 
1215
{
 
1216
  switch(dev->model->motor_type)
 
1217
    {
 
1218
    case MOTOR_G4050:
 
1219
      if(yres<=1200)
 
1220
        {
 
1221
          return 1;
 
1222
        }
 
1223
      return 2;
 
1224
    case MOTOR_KVSS080:
 
1225
    default:
 
1226
      return 1;
 
1227
    }
 
1228
}
 
1229
 
 
1230
#define OPTICAL_FLAG_DISABLE_GAMMA   1
 
1231
#define OPTICAL_FLAG_DISABLE_SHADING 2
 
1232
#define OPTICAL_FLAG_DISABLE_LAMP    4
 
1233
#define OPTICAL_FLAG_ENABLE_LEDADD   8
 
1234
 
 
1235
/** @brief setup optical related registers
 
1236
 * start and pixels are expressed in optical sensor resolution coordinate
 
1237
 * space. To handle odd/even case we double the resolution and
 
1238
 * use only first logival half the sensor whic maps to effective CCD.
 
1239
 * @param start logical start pixel coordinate
 
1240
 * @param pixels logical number of pixels to use
 
1241
 * @return SANE_STATUS_GOOD if OK
 
1242
 */
 
1243
static SANE_Status
 
1244
gl843_init_optical_regs_scan (Genesys_Device * dev,
 
1245
                              Genesys_Register_Set * reg,
 
1246
                              unsigned int exposure_time,
 
1247
                              int used_res,
 
1248
                              unsigned int start,
 
1249
                              unsigned int pixels,
 
1250
                              int channels,
 
1251
                              int depth,
 
1252
                              SANE_Bool half_ccd, int color_filter, int flags)
 
1253
{
 
1254
  unsigned int words_per_line;
 
1255
  unsigned int startx, endx, used_pixels;
 
1256
  unsigned int dpiset, cksel,dpihw, factor;
 
1257
  unsigned int i, bytes;
 
1258
  Genesys_Register_Set *r;
 
1259
  SANE_Status status;
 
1260
 
 
1261
  DBG (DBG_proc, "gl843_init_optical_regs_scan :  exposure_time=%d, "
 
1262
       "used_res=%d, start=%d, pixels=%d, channels=%d, depth=%d, "
 
1263
       "half_ccd=%d, flags=%x\n",
 
1264
       exposure_time,
 
1265
       used_res, start, pixels, channels, depth, half_ccd, flags);
 
1266
 
 
1267
  /* sensor parameters */
 
1268
  gl843_setup_sensor (dev, reg, used_res);
 
1269
 
 
1270
  /* to manage high resolution device while keeping good
 
1271
   * low resolution scanning speed, we make hardware dpi vary */
 
1272
  dpihw=gl843_compute_dpihw(dev, used_res);
 
1273
  factor=dev->sensor.optical_res/dpihw;
 
1274
  DBG (DBG_io2, "%s: dpihw=%d (factor=%d)\n", __FUNCTION__, dpihw, factor);
 
1275
 
 
1276
  r = sanei_genesys_get_address (reg, REG18);
 
1277
  cksel= (r->value & REG18_CKSEL)+1;
 
1278
 
 
1279
  DBG (DBG_io2, "%s: cksel=%d\n", __FUNCTION__, cksel);
 
1280
  dpiset = used_res * cksel;
 
1281
 
 
1282
  /* start and end coordinate in optical dpi coordinates */
 
1283
  startx = start/cksel + dev->sensor.dummy_pixel;
 
1284
  used_pixels=pixels/cksel;
 
1285
  endx = startx + used_pixels;
 
1286
 
 
1287
  /* factor correction when used dpihw is not native one */
 
1288
  if(factor>1)
 
1289
    {
 
1290
      startx/=factor;
 
1291
      endx/=factor;
 
1292
      used_pixels=endx-startx;
 
1293
    }
 
1294
 
 
1295
  status = gl843_set_fe (dev, AFE_SET);
 
1296
  if (status != SANE_STATUS_GOOD)
 
1297
    {
 
1298
      DBG (DBG_error,
 
1299
           "gl843_init_optical_regs_scan: failed to set frontend: %s\n",
 
1300
           sane_strstatus (status));
 
1301
      return status;
 
1302
    }
 
1303
 
 
1304
  /* enable shading */
 
1305
  r = sanei_genesys_get_address (reg, REG01);
 
1306
  r->value &= ~REG01_SCAN;
 
1307
  if ((flags & OPTICAL_FLAG_DISABLE_SHADING) ||
 
1308
      (dev->model->flags & GENESYS_FLAG_NO_CALIBRATION))
 
1309
    {
 
1310
      r->value &= ~REG01_DVDSET;
 
1311
    }
 
1312
  else
 
1313
    {
 
1314
      r->value |= REG01_DVDSET;
 
1315
    }
 
1316
 
 
1317
  r = sanei_genesys_get_address (reg, REG03);
 
1318
  r->value &= ~REG03_AVEENB;
 
1319
  if (flags & OPTICAL_FLAG_DISABLE_LAMP)
 
1320
    r->value &= ~REG03_LAMPPWR;
 
1321
  else
 
1322
    r->value |= REG03_LAMPPWR;
 
1323
 
 
1324
  /* exposure times */
 
1325
  for (i = 0; i < 6; i++)
 
1326
    {
 
1327
      r = sanei_genesys_get_address (reg, 0x10 + i);
 
1328
      if (flags & OPTICAL_FLAG_DISABLE_LAMP)
 
1329
        r->value = 0x01;        /* 0x0101 is as off as possible */
 
1330
      else
 
1331
        r->value = dev->sensor.regs_0x10_0x1d[i];
 
1332
    }
 
1333
 
 
1334
  /* BW threshold */
 
1335
  r = sanei_genesys_get_address (reg, 0x2e);
 
1336
  r->value = dev->settings.threshold;
 
1337
  r = sanei_genesys_get_address (reg, 0x2f);
 
1338
  r->value = dev->settings.threshold;
 
1339
 
 
1340
  /* monochrome / color scan */
 
1341
  r = sanei_genesys_get_address (reg, REG04);
 
1342
  switch (depth)
 
1343
    {
 
1344
    case 1:
 
1345
      r->value &= ~REG04_BITSET;
 
1346
      r->value |= REG04_LINEART;
 
1347
      break;
 
1348
    case 8:
 
1349
      r->value &= ~(REG04_LINEART | REG04_BITSET);
 
1350
      break;
 
1351
    case 16:
 
1352
      r->value &= ~REG04_LINEART;
 
1353
      r->value |= REG04_BITSET;
 
1354
      break;
 
1355
    }
 
1356
 
 
1357
  r->value &= ~(REG04_FILTER | REG04_AFEMOD);
 
1358
  if (channels == 1)
 
1359
    {
 
1360
      switch (color_filter)
 
1361
        {
 
1362
        case 0:
 
1363
          r->value |= 0x14;     /* red filter */
 
1364
          break;
 
1365
        case 2:
 
1366
          r->value |= 0x1c;     /* blue filter */
 
1367
          break;
 
1368
        default:
 
1369
          r->value |= 0x18;     /* green filter */
 
1370
          break;
 
1371
        }
 
1372
    }
 
1373
  else
 
1374
    r->value |= 0x10;           /* mono */
 
1375
 
 
1376
  /* register 05 */
 
1377
  r = sanei_genesys_get_address (reg, REG05);
 
1378
 
 
1379
  /* set up dpihw */
 
1380
  r->value &= ~REG05_DPIHW;
 
1381
  switch(dpihw)
 
1382
    {
 
1383
      case 600:
 
1384
        r->value |= REG05_DPIHW_600;
 
1385
        break;
 
1386
      case 1200:
 
1387
        r->value |= REG05_DPIHW_1200;
 
1388
        break;
 
1389
      case 2400:
 
1390
        r->value |= REG05_DPIHW_2400;
 
1391
        break;
 
1392
      case 4800:
 
1393
        r->value |= REG05_DPIHW_4800;
 
1394
        break;
 
1395
    }
 
1396
 
 
1397
  /* enable gamma tables */
 
1398
  if (flags & OPTICAL_FLAG_DISABLE_GAMMA)
 
1399
    r->value &= ~REG05_GMMENB;
 
1400
  else
 
1401
    r->value |= REG05_GMMENB;
 
1402
 
 
1403
  r = sanei_genesys_get_address (reg, 0x2c);
 
1404
  r->value = HIBYTE (dpiset);
 
1405
  r = sanei_genesys_get_address (reg, 0x2d);
 
1406
  r->value = LOBYTE (dpiset);
 
1407
  DBG (DBG_io2, "%s: dpiset used=%d\n", __FUNCTION__, dpiset);
 
1408
 
 
1409
  r = sanei_genesys_get_address (reg, 0x30);
 
1410
  r->value = HIBYTE (startx);
 
1411
  r = sanei_genesys_get_address (reg, 0x31);
 
1412
  r->value = LOBYTE (startx);
 
1413
  r = sanei_genesys_get_address (reg, 0x32);
 
1414
  r->value = HIBYTE (endx);
 
1415
  r = sanei_genesys_get_address (reg, 0x33);
 
1416
  r->value = LOBYTE (endx);
 
1417
 
 
1418
  /* words(16bit) before gamma, conversion to 8 bit or lineart */
 
1419
  words_per_line = (used_pixels * dpiset) / dpihw;
 
1420
  bytes = depth / 8;
 
1421
  if (depth == 1)
 
1422
    {
 
1423
      words_per_line = (words_per_line >> 3) + ((words_per_line & 7) ? 1 : 0);
 
1424
    }
 
1425
  else
 
1426
    {
 
1427
      words_per_line *= bytes;
 
1428
    }
 
1429
 
 
1430
  dev->bpl = words_per_line;
 
1431
 
 
1432
  DBG (DBG_io2, "%s: used_pixels=%d\n", __FUNCTION__, used_pixels);
 
1433
  DBG (DBG_io2, "%s: pixels     =%d\n", __FUNCTION__, pixels);
 
1434
  DBG (DBG_io2, "%s: depth      =%d\n", __FUNCTION__, depth);
 
1435
  DBG (DBG_io2, "%s: dev->bpl   =%lu\n", __FUNCTION__,
 
1436
       (unsigned long) dev->bpl);
 
1437
 
 
1438
  words_per_line *= channels;
 
1439
  dev->wpl = words_per_line;
 
1440
 
 
1441
  /* MAXWD is expressed in 2 words unit */
 
1442
  /* nousedspace = (mem_bank_range * 1024 / 256 -1 ) * 4; */
 
1443
  r = sanei_genesys_get_address (reg, 0x35);
 
1444
  r->value = LOBYTE (HIWORD (words_per_line >> 2));
 
1445
  r = sanei_genesys_get_address (reg, 0x36);
 
1446
  r->value = HIBYTE (LOWORD (words_per_line >> 2));
 
1447
  r = sanei_genesys_get_address (reg, 0x37);
 
1448
  r->value = LOBYTE (LOWORD (words_per_line >> 2));
 
1449
  DBG (DBG_io2, "%s: words_per_line used=%d\n", __FUNCTION__, words_per_line);
 
1450
 
 
1451
  r = sanei_genesys_get_address (reg, 0x38);
 
1452
  r->value = HIBYTE (exposure_time);
 
1453
  r = sanei_genesys_get_address (reg, 0x39);
 
1454
  r->value = LOBYTE (exposure_time);
 
1455
  DBG (DBG_io2, "%s: exposure_time used=%d\n", __FUNCTION__, exposure_time);
 
1456
 
 
1457
  r = sanei_genesys_get_address (reg, 0x34);
 
1458
  r->value = dev->sensor.dummy_pixel;
 
1459
 
 
1460
  DBG (DBG_proc, "gl843_init_optical_regs_scan : completed. \n");
 
1461
  return SANE_STATUS_GOOD;
 
1462
}
 
1463
 
 
1464
 
 
1465
static int
 
1466
gl843_get_led_exposure (Genesys_Device * dev)
 
1467
{
 
1468
  int d, r, g, b, m;
 
1469
  if (!dev->model->is_cis)
 
1470
    return 0;
 
1471
  d = dev->reg[reg_0x19].value;
 
1472
  r = dev->sensor.regs_0x10_0x1d[1] | (dev->sensor.regs_0x10_0x1d[0] << 8);
 
1473
  g = dev->sensor.regs_0x10_0x1d[3] | (dev->sensor.regs_0x10_0x1d[2] << 8);
 
1474
  b = dev->sensor.regs_0x10_0x1d[5] | (dev->sensor.regs_0x10_0x1d[4] << 8);
 
1475
 
 
1476
  m = r;
 
1477
  if (m < g)
 
1478
    m = g;
 
1479
  if (m < b)
 
1480
    m = b;
 
1481
 
 
1482
  return m + d;
 
1483
}
 
1484
 
 
1485
 
 
1486
/* set up registers for an actual scan
 
1487
 *
 
1488
 * this function sets up the scanner to scan in normal or single line mode
 
1489
 */
 
1490
#ifndef UNIT_TESTING
 
1491
static
 
1492
#endif
 
1493
  SANE_Status
 
1494
gl843_init_scan_regs (Genesys_Device * dev,
 
1495
                      Genesys_Register_Set * reg,
 
1496
                      float xres,       /*dpi */
 
1497
                      float yres,       /*dpi */
 
1498
                      float startx,     /*optical_res, from dummy_pixel+1 */
 
1499
                      float starty,     /*base_ydpi, from home! */
 
1500
                      float pixels,
 
1501
                      float lines,
 
1502
                      unsigned int depth,
 
1503
                      unsigned int channels,
 
1504
                      int color_filter, unsigned int flags)
 
1505
{
 
1506
  int used_res;
 
1507
  int start, used_pixels;
 
1508
  int bytes_per_line;
 
1509
  int move;
 
1510
  unsigned int lincnt;
 
1511
  unsigned int oflags; /**> optical flags */
 
1512
  int exposure_time;
 
1513
  int stagger;
 
1514
 
 
1515
  int slope_dpi = 0;
 
1516
  int dummy = 0;
 
1517
  int scan_step_type = 1;
 
1518
  int scan_power_mode = 0;
 
1519
  int max_shift;
 
1520
  size_t requested_buffer_size, read_buffer_size;
 
1521
 
 
1522
  SANE_Bool half_ccd;           /* false: full CCD res is used, true, half max CCD res is used */
 
1523
  int optical_res;
 
1524
  SANE_Status status;
 
1525
 
 
1526
  DBG (DBG_info,
 
1527
       "gl843_init_scan_regs settings:\n"
 
1528
       "Resolution    : %gDPI/%gDPI\n"
 
1529
       "Lines         : %g\n"
 
1530
       "PPL           : %g\n"
 
1531
       "Startpos      : %g/%g\n"
 
1532
       "Depth/Channels: %u/%u\n"
 
1533
       "Flags         : %x\n\n",
 
1534
       xres, yres, lines, pixels, startx, starty, depth, channels, flags);
 
1535
 
 
1536
/*
 
1537
results:
 
1538
 
 
1539
for scanner:
 
1540
half_ccd
 
1541
start
 
1542
end
 
1543
dpiset
 
1544
exposure_time
 
1545
dummy
 
1546
z1
 
1547
z2
 
1548
 
 
1549
for ordered_read:
 
1550
  dev->words_per_line
 
1551
  dev->read_factor
 
1552
  dev->requested_buffer_size
 
1553
  dev->read_buffer_size
 
1554
  dev->read_pos
 
1555
  dev->read_bytes_in_buffer
 
1556
  dev->read_bytes_left
 
1557
  dev->max_shift
 
1558
  dev->stagger
 
1559
 
 
1560
independent of our calculated values:
 
1561
  dev->total_bytes_read
 
1562
  dev->bytes_to_read
 
1563
 */
 
1564
 
 
1565
/* half_ccd */
 
1566
  /* we have 2 domains for ccd: xres below or above half ccd max dpi */
 
1567
  if (dev->sensor.optical_res < 2 * xres ||
 
1568
      !(dev->model->flags & GENESYS_FLAG_HALF_CCD_MODE))
 
1569
    {
 
1570
      half_ccd = SANE_FALSE;
 
1571
    }
 
1572
  else
 
1573
    {
 
1574
      half_ccd = SANE_TRUE;
 
1575
    }
 
1576
 
 
1577
  /* optical_res */
 
1578
  optical_res = dev->sensor.optical_res;
 
1579
  if (half_ccd)
 
1580
    optical_res /= 2;
 
1581
 
 
1582
  /* stagger */
 
1583
  if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE))
 
1584
    stagger = (4 * yres) / dev->motor.base_ydpi;
 
1585
  else
 
1586
    stagger = 0;
 
1587
  DBG (DBG_info, "gl843_init_scan_regs : stagger=%d lines\n", stagger);
 
1588
 
 
1589
  /** @brief compute used resolution
 
1590
   * the sensor if mapped only to odd pixels. So we double the optical 
 
1591
   * resolution and use first half
 
1592
   * */
 
1593
  if (flags & SCAN_FLAG_USE_OPTICAL_RES)
 
1594
    {
 
1595
      used_res = optical_res;
 
1596
    }
 
1597
  else
 
1598
    {
 
1599
      /* resolution is choosen from a fixed list and can be used directly */
 
1600
      if(xres>optical_res)
 
1601
        used_res=optical_res;
 
1602
      else
 
1603
        used_res = xres;
 
1604
    }
 
1605
 
 
1606
  /* compute scan parameters values */
 
1607
  /* pixels are allways given at full optical resolution */
 
1608
  /* use detected left margin and fixed value */
 
1609
  /* start */
 
1610
  /* add x coordinates */
 
1611
  start = startx;
 
1612
 
 
1613
  if (stagger > 0)
 
1614
    start |= 1;
 
1615
 
 
1616
  /* compute correct pixels number */
 
1617
  /* pixels */
 
1618
  used_pixels = (pixels * optical_res) / xres;
 
1619
  DBG (DBG_info, "%s: used_pixels=%d\n", __FUNCTION__, used_pixels);
 
1620
 
 
1621
  /* round up pixels number if needed */
 
1622
  if (used_pixels * xres < pixels * optical_res)
 
1623
    used_pixels++;
 
1624
 
 
1625
  /* we want even number of pixels here */
 
1626
  if(used_pixels & 1)
 
1627
    used_pixels++;
 
1628
 
 
1629
  dummy = 0;
 
1630
 
 
1631
  /* slope_dpi */
 
1632
  /* cis color scan is effectively a gray scan with 3 gray lines per color line and a FILTER of 0 */
 
1633
  if (dev->model->is_cis)
 
1634
    slope_dpi = yres * channels;
 
1635
  else
 
1636
    slope_dpi = yres;
 
1637
 
 
1638
  /* scan_step_type */
 
1639
  scan_step_type = gl843_compute_step_type(dev, slope_dpi);
 
1640
  exposure_time = gl843_compute_exposure (dev, used_res);
 
1641
 
 
1642
  DBG (DBG_info, "gl843_init_scan_regs : exposure_time=%d pixels\n",
 
1643
       exposure_time);
 
1644
  DBG (DBG_info, "gl843_init_scan_regs : scan_step_type=%d\n",
 
1645
       scan_step_type);
 
1646
 
 
1647
/*** optical parameters ***/
 
1648
  /* in case of dynamic lineart, we use an internal 8 bit gray scan
 
1649
   * to generate 1 lineart data */
 
1650
  if ((flags & SCAN_FLAG_DYNAMIC_LINEART)
 
1651
      && (dev->settings.scan_mode == SCAN_MODE_LINEART))
 
1652
    {
 
1653
      depth = 8;
 
1654
    }
 
1655
  if (depth == 16)
 
1656
    flags |= SCAN_FLAG_DISABLE_GAMMA;
 
1657
 
 
1658
  /* we enable true gray for cis scanners only, and just when doing 
 
1659
   * scan since color calibration is OK for this mode
 
1660
   */
 
1661
  oflags = 0;
 
1662
  if (flags & SCAN_FLAG_DISABLE_SHADING)
 
1663
    oflags |= OPTICAL_FLAG_DISABLE_SHADING;
 
1664
  if (flags & SCAN_FLAG_DISABLE_GAMMA)
 
1665
    oflags |= OPTICAL_FLAG_DISABLE_GAMMA;
 
1666
  if (flags & SCAN_FLAG_DISABLE_LAMP)
 
1667
    oflags |= OPTICAL_FLAG_DISABLE_LAMP;
 
1668
 
 
1669
  /* now _LOGICAL_ optical values used are known, setup registers */
 
1670
  status = gl843_init_optical_regs_scan (dev,
 
1671
                                         reg,
 
1672
                                         exposure_time,
 
1673
                                         used_res,
 
1674
                                         start,
 
1675
                                         used_pixels,
 
1676
                                         channels,
 
1677
                                         depth,
 
1678
                                         half_ccd, color_filter, oflags);
 
1679
 
 
1680
  if (status != SANE_STATUS_GOOD)
 
1681
    return status;
 
1682
 
 
1683
/*** motor parameters ***/
 
1684
 
 
1685
/* max_shift */
 
1686
  /* scanned area must be enlarged by max color shift needed */
 
1687
  /* all values are assumed >= 0 */
 
1688
  if (channels > 1 && !(flags & SCAN_FLAG_IGNORE_LINE_DISTANCE))
 
1689
    {
 
1690
      max_shift = dev->model->ld_shift_r;
 
1691
      if (dev->model->ld_shift_b > max_shift)
 
1692
        max_shift = dev->model->ld_shift_b;
 
1693
      if (dev->model->ld_shift_g > max_shift)
 
1694
        max_shift = dev->model->ld_shift_g;
 
1695
      max_shift = (max_shift * yres) / dev->motor.base_ydpi;
 
1696
    }
 
1697
  else
 
1698
    {
 
1699
      max_shift = 0;
 
1700
    }
 
1701
 
 
1702
  /* lines to scan */
 
1703
  lincnt = lines + max_shift + stagger;
 
1704
 
 
1705
  /* add tl_y to base movement */
 
1706
  move = starty;
 
1707
  DBG (DBG_info, "gl843_init_scan_regs: move=%d steps\n", move);
 
1708
 
 
1709
    status = gl843_init_motor_regs_scan (dev,
 
1710
                                         reg,
 
1711
                                         exposure_time,
 
1712
                                         slope_dpi,
 
1713
                                         scan_step_type,
 
1714
                                         dev->model->is_cis ? lincnt * channels : lincnt,
 
1715
                                         dummy,
 
1716
                                         move,
 
1717
                                         scan_power_mode,
 
1718
                                         (flags & SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE) ?  MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE : 0);
 
1719
  if (status != SANE_STATUS_GOOD)
 
1720
    return status;
 
1721
 
 
1722
  /*** prepares data reordering ***/
 
1723
 
 
1724
  /* words_per_line */
 
1725
  bytes_per_line = (used_pixels * used_res) / optical_res;
 
1726
  bytes_per_line = (bytes_per_line * channels * depth) / 8;
 
1727
 
 
1728
  /* since we don't have sheetfed scanners to handle,
 
1729
   * use huge read buffer */
 
1730
  /* TODO find the best size according to settings */
 
1731
  requested_buffer_size = 16 * bytes_per_line;
 
1732
 
 
1733
  read_buffer_size =
 
1734
    2 * requested_buffer_size +
 
1735
    ((max_shift + stagger) * used_pixels * channels * depth) / 8;
 
1736
 
 
1737
  RIE (sanei_genesys_buffer_free (&(dev->read_buffer)));
 
1738
  RIE (sanei_genesys_buffer_alloc (&(dev->read_buffer), read_buffer_size));
 
1739
 
 
1740
  RIE (sanei_genesys_buffer_free (&(dev->lines_buffer)));
 
1741
  RIE (sanei_genesys_buffer_alloc (&(dev->lines_buffer), read_buffer_size));
 
1742
 
 
1743
  RIE (sanei_genesys_buffer_free (&(dev->shrink_buffer)));
 
1744
  RIE (sanei_genesys_buffer_alloc (&(dev->shrink_buffer),
 
1745
                                   requested_buffer_size));
 
1746
 
 
1747
  RIE (sanei_genesys_buffer_free (&(dev->out_buffer)));
 
1748
  RIE (sanei_genesys_buffer_alloc (&(dev->out_buffer),
 
1749
                                   (8 * dev->settings.pixels * channels *
 
1750
                                    depth) / 8));
 
1751
 
 
1752
 
 
1753
  dev->read_bytes_left = bytes_per_line * lincnt;
 
1754
 
 
1755
  DBG (DBG_info,
 
1756
       "gl843_init_scan_regs: physical bytes to read = %lu\n",
 
1757
       (u_long) dev->read_bytes_left);
 
1758
  dev->read_active = SANE_TRUE;
 
1759
 
 
1760
 
 
1761
  dev->current_setup.pixels = (used_pixels * used_res) / optical_res;
 
1762
  DBG (DBG_info, "%s: current_setup.pixels=%d\n", __FUNCTION__, dev->current_setup.pixels);
 
1763
  dev->current_setup.lines = lincnt;
 
1764
  dev->current_setup.depth = depth;
 
1765
  dev->current_setup.channels = channels;
 
1766
  dev->current_setup.exposure_time = exposure_time;
 
1767
  dev->current_setup.xres = used_res;
 
1768
  dev->current_setup.yres = yres;
 
1769
  dev->current_setup.half_ccd = half_ccd;
 
1770
  dev->current_setup.stagger = stagger;
 
1771
  dev->current_setup.max_shift = max_shift + stagger;
 
1772
 
 
1773
  dev->total_bytes_read = 0;
 
1774
  if (depth == 1 || dev->settings.scan_mode == SCAN_MODE_LINEART)
 
1775
    dev->total_bytes_to_read =
 
1776
      ((dev->settings.pixels * dev->settings.lines) / 8 +
 
1777
       (((dev->settings.pixels * dev->settings.lines) % 8) ? 1 : 0)) *
 
1778
      channels;
 
1779
  else
 
1780
    dev->total_bytes_to_read =
 
1781
      dev->settings.pixels * dev->settings.lines * channels * (depth / 8);
 
1782
 
 
1783
  DBG (DBG_info, "gl843_init_scan_regs: total bytes to send = %lu\n",
 
1784
       (u_long) dev->total_bytes_to_read);
 
1785
 
 
1786
  DBG (DBG_proc, "gl843_init_scan_regs: completed\n");
 
1787
  return SANE_STATUS_GOOD;
 
1788
}
 
1789
 
 
1790
static SANE_Status
 
1791
gl843_calculate_current_setup (Genesys_Device * dev)
 
1792
{
 
1793
  int channels;
 
1794
  int depth;
 
1795
  int start;
 
1796
 
 
1797
  float xres;                   /*dpi */
 
1798
  float yres;                   /*dpi */
 
1799
  float startx;                 /*optical_res, from dummy_pixel+1 */
 
1800
  float pixels;
 
1801
  float lines;
 
1802
  int color_filter;
 
1803
 
 
1804
  int used_res;
 
1805
  int used_pixels;
 
1806
  unsigned int lincnt;
 
1807
  int exposure_time;
 
1808
  int stagger;
 
1809
 
 
1810
  int slope_dpi = 0;
 
1811
  int dummy = 0;
 
1812
  int scan_step_type = 1;
 
1813
  int scan_power_mode = 0;
 
1814
  int max_shift;
 
1815
 
 
1816
  SANE_Bool half_ccd;           /* false: full CCD res is used, true, half max CCD res is used */
 
1817
  int optical_res;
 
1818
 
 
1819
  DBG (DBG_info,
 
1820
       "gl843_calculate_current_setup settings:\n"
 
1821
       "Resolution: %ux%uDPI\n"
 
1822
       "Lines     : %u\n"
 
1823
       "PPL       : %u\n"
 
1824
       "Startpos  : %.3f/%.3f\n"
 
1825
       "Scan mode : %d\n\n",
 
1826
       dev->settings.xres,
 
1827
       dev->settings.yres, dev->settings.lines, dev->settings.pixels,
 
1828
       dev->settings.tl_x, dev->settings.tl_y, dev->settings.scan_mode);
 
1829
 
 
1830
  /* channels */
 
1831
  if (dev->settings.scan_mode == 4)     /* single pass color */
 
1832
    channels = 3;
 
1833
  else
 
1834
    channels = 1;
 
1835
 
 
1836
  /* depth */
 
1837
  depth = dev->settings.depth;
 
1838
  if (dev->settings.scan_mode == 0)
 
1839
    depth = 1;
 
1840
 
 
1841
  /* start */
 
1842
  start = SANE_UNFIX (dev->model->x_offset);
 
1843
  start += dev->settings.tl_x;
 
1844
  start = (start * dev->sensor.optical_res) / MM_PER_INCH;
 
1845
 
 
1846
 
 
1847
  xres = dev->settings.xres;
 
1848
  yres = dev->settings.yres;
 
1849
  startx = start;
 
1850
  pixels = dev->settings.pixels;
 
1851
  lines = dev->settings.lines;
 
1852
  color_filter = dev->settings.color_filter;
 
1853
 
 
1854
 
 
1855
  DBG (DBG_info,
 
1856
       "gl843_calculate_current_setup settings:\n"
 
1857
       "Resolution    : %gDPI/%gDPI\n"
 
1858
       "Lines         : %g\n"
 
1859
       "PPL           : %g\n"
 
1860
       "Startpos      : %g\n"
 
1861
       "Depth/Channels: %u/%u\n\n",
 
1862
       xres, yres, lines, pixels, startx, depth, channels);
 
1863
 
 
1864
/* half_ccd */
 
1865
  /* we have 2 domains for ccd: xres below or above half ccd max dpi */
 
1866
  if ((dev->sensor.optical_res < 2 * xres) ||
 
1867
      !(dev->model->flags & GENESYS_FLAG_HALF_CCD_MODE))
 
1868
    {
 
1869
      half_ccd = SANE_FALSE;
 
1870
    }
 
1871
  else
 
1872
    {
 
1873
      half_ccd = SANE_TRUE;
 
1874
    }
 
1875
 
 
1876
 
 
1877
  /* optical_res */
 
1878
  optical_res = dev->sensor.optical_res;
 
1879
  if (half_ccd)
 
1880
    optical_res /= 2;
 
1881
 
 
1882
  /* stagger */
 
1883
  if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE))
 
1884
    stagger = (4 * yres) / dev->motor.base_ydpi;
 
1885
  else
 
1886
    stagger = 0;
 
1887
  DBG (DBG_info, "%s: stagger=%d lines\n", __FUNCTION__, stagger);
 
1888
 
 
1889
  if(xres<=optical_res)
 
1890
    used_res = xres;
 
1891
  else
 
1892
    used_res=optical_res;
 
1893
 
 
1894
  /* compute scan parameters values */
 
1895
  /* pixels are allways given at half or full CCD optical resolution */
 
1896
  /* use detected left margin  and fixed value */
 
1897
 
 
1898
  /* compute correct pixels number */
 
1899
  used_pixels = (pixels * optical_res) / xres;
 
1900
  DBG (DBG_info, "%s: used_pixels=%d\n", __FUNCTION__, used_pixels);
 
1901
  dummy = 0;
 
1902
 
 
1903
  /* slope_dpi */
 
1904
  /* cis color scan is effectively a gray scan with 3 gray lines per color
 
1905
   line and a FILTER of 0 */
 
1906
  if (dev->model->is_cis)
 
1907
    slope_dpi = yres * channels;
 
1908
  else
 
1909
    slope_dpi = yres;
 
1910
 
 
1911
  /* scan_step_type */
 
1912
  scan_step_type = gl843_compute_step_type(dev, yres);
 
1913
 
 
1914
  exposure_time = sanei_genesys_exposure_time2 (dev,
 
1915
                                                slope_dpi,
 
1916
                                                scan_step_type,
 
1917
                                                start + used_pixels + 258,
 
1918
                                                gl843_get_led_exposure (dev),
 
1919
                                                scan_power_mode);
 
1920
 
 
1921
  DBG (DBG_info, "%s : exposure_time=%d pixels\n", __FUNCTION__, exposure_time);
 
1922
 
 
1923
/* max_shift */
 
1924
  /* scanned area must be enlarged by max color shift needed */
 
1925
  /* all values are assumed >= 0 */
 
1926
  if (channels > 1)
 
1927
    {
 
1928
      max_shift = dev->model->ld_shift_r;
 
1929
      if (dev->model->ld_shift_b > max_shift)
 
1930
        max_shift = dev->model->ld_shift_b;
 
1931
      if (dev->model->ld_shift_g > max_shift)
 
1932
        max_shift = dev->model->ld_shift_g;
 
1933
      max_shift = (max_shift * yres) / dev->motor.base_ydpi;
 
1934
    }
 
1935
  else
 
1936
    {
 
1937
      max_shift = 0;
 
1938
    }
 
1939
 
 
1940
  /* lincnt */
 
1941
  lincnt = lines + max_shift + stagger;
 
1942
 
 
1943
  dev->current_setup.pixels = (used_pixels * used_res) / optical_res;
 
1944
  DBG (DBG_info, "%s: current_setup.pixels=%d\n", __FUNCTION__, dev->current_setup.pixels);
 
1945
  dev->current_setup.lines = lincnt;
 
1946
  dev->current_setup.depth = depth;
 
1947
  dev->current_setup.channels = channels;
 
1948
  dev->current_setup.exposure_time = exposure_time;
 
1949
  dev->current_setup.xres = used_res;
 
1950
  dev->current_setup.yres = yres;
 
1951
  dev->current_setup.half_ccd = half_ccd;
 
1952
  dev->current_setup.stagger = stagger;
 
1953
  dev->current_setup.max_shift = max_shift + stagger;
 
1954
 
 
1955
  DBG (DBG_proc, "gl843_calculate_current_setup: completed\n");
 
1956
  return SANE_STATUS_GOOD;
 
1957
}
 
1958
 
 
1959
static void
 
1960
gl843_set_motor_power (Genesys_Register_Set * regs, SANE_Bool set)
 
1961
{
 
1962
 
 
1963
  DBG (DBG_proc, "gl843_set_motor_power\n");
 
1964
 
 
1965
  if (set)
 
1966
    {
 
1967
      sanei_genesys_set_reg_from_set (regs, REG02,
 
1968
                                      sanei_genesys_read_reg_from_set (regs,
 
1969
                                                                       REG02)
 
1970
                                      | REG02_MTRPWR);
 
1971
    }
 
1972
  else
 
1973
    {
 
1974
      sanei_genesys_set_reg_from_set (regs, REG02,
 
1975
                                      sanei_genesys_read_reg_from_set (regs,
 
1976
                                                                       REG02)
 
1977
                                      & ~REG02_MTRPWR);
 
1978
    }
 
1979
}
 
1980
 
 
1981
static void
 
1982
gl843_set_lamp_power (Genesys_Device * dev,
 
1983
                      Genesys_Register_Set * regs, SANE_Bool set)
 
1984
{
 
1985
  Genesys_Register_Set *r;
 
1986
  int i;
 
1987
 
 
1988
  if (set)
 
1989
    {
 
1990
      sanei_genesys_set_reg_from_set (regs, 0x03,
 
1991
                                      sanei_genesys_read_reg_from_set (regs,
 
1992
                                                                       0x03)
 
1993
                                      | REG03_LAMPPWR);
 
1994
 
 
1995
      for (i = 0; i < 6; i++)
 
1996
        {
 
1997
          r = sanei_genesys_get_address (dev->calib_reg, 0x10 + i);
 
1998
          r->value = dev->sensor.regs_0x10_0x1d[i];
 
1999
        }
 
2000
    }
 
2001
  else
 
2002
    {
 
2003
      sanei_genesys_set_reg_from_set (regs, 0x03,
 
2004
                                      sanei_genesys_read_reg_from_set (regs,
 
2005
                                                                       0x03)
 
2006
                                      & ~REG03_LAMPPWR);
 
2007
 
 
2008
      for (i = 0; i < 6; i++)
 
2009
        {
 
2010
          r = sanei_genesys_get_address (dev->calib_reg, 0x10 + i);
 
2011
          r->value = 0x00;
 
2012
        }
 
2013
    }
 
2014
}
 
2015
 
 
2016
/**
 
2017
 * for fast power saving methods only, like disabling certain amplifiers
 
2018
 * @param device device to use
 
2019
 * @param enable true to set inot powersaving
 
2020
 * */
 
2021
static SANE_Status
 
2022
gl843_save_power (Genesys_Device * dev, SANE_Bool enable)
 
2023
{
 
2024
  uint8_t val;
 
2025
  SANE_Status status;
 
2026
 
 
2027
  DBG (DBG_proc, "gl843_save_power: enable = %d\n", enable);
 
2028
  if (dev == NULL)
 
2029
    return SANE_STATUS_INVAL;
 
2030
 
 
2031
  /* switch KV-SS080 lamp off */
 
2032
  if (dev->model->gpo_type == GPO_KVSS080) 
 
2033
    {
 
2034
      RIE(sanei_genesys_read_register (dev, REG6C, &val));
 
2035
      if(enable)
 
2036
        val &= 0xef;
 
2037
      else
 
2038
        val |= 0x10;
 
2039
      RIE(sanei_genesys_write_register(dev,REG6C,val));
 
2040
    }
 
2041
 
 
2042
  DBGCOMPLETED;
 
2043
  return SANE_STATUS_GOOD;
 
2044
}
 
2045
 
 
2046
static SANE_Status
 
2047
gl843_set_powersaving (Genesys_Device * dev, int delay /* in minutes */ )
 
2048
{
 
2049
  SANE_Status status = SANE_STATUS_GOOD;
 
2050
 
 
2051
  DBG (DBG_proc, "gl843_set_powersaving (delay = %d)\n", delay);
 
2052
  if (dev == NULL)
 
2053
    return SANE_STATUS_INVAL;
 
2054
 
 
2055
  DBGCOMPLETED;
 
2056
  return status;
 
2057
}
 
2058
 
 
2059
#ifndef UNIT_TESTING
 
2060
static
 
2061
#endif
 
2062
  SANE_Status
 
2063
gl843_start_action (Genesys_Device * dev)
 
2064
{
 
2065
  return sanei_genesys_write_register (dev, 0x0f, 0x01);
 
2066
}
 
2067
 
 
2068
static SANE_Status
 
2069
gl843_stop_action (Genesys_Device * dev)
 
2070
{
 
2071
  SANE_Status status;
 
2072
  uint8_t val40, val;
 
2073
  unsigned int loop;
 
2074
 
 
2075
  DBG (DBG_proc, "%s\n", __FUNCTION__);
 
2076
 
 
2077
  status = sanei_genesys_get_status (dev, &val);
 
2078
  if (DBG_LEVEL >= DBG_io)
 
2079
    {
 
2080
      print_status (val);
 
2081
    }
 
2082
 
 
2083
  val40 = 0;
 
2084
  status = sanei_genesys_read_register (dev, REG40, &val40);
 
2085
  if (status != SANE_STATUS_GOOD)
 
2086
    {
 
2087
      DBG (DBG_error,
 
2088
           "%s: failed to read home sensor: %s\n", __FUNCTION__,
 
2089
           sane_strstatus (status));
 
2090
      DBG (DBG_proc, "%s: completed\n", __FUNCTION__);
 
2091
      return status;
 
2092
    }
 
2093
 
 
2094
  /* only stop action if needed */
 
2095
  if (!(val40 & REG40_DATAENB) && !(val40 & REG40_MOTMFLG))
 
2096
    {
 
2097
      DBG (DBG_info, "%s: already stopped\n", __FUNCTION__);
 
2098
      DBG (DBG_proc, "%s: completed\n", __FUNCTION__);
 
2099
      return SANE_STATUS_GOOD;
 
2100
    }
 
2101
 
 
2102
  /* ends scan 646  */
 
2103
  val = sanei_genesys_read_reg_from_set (dev->reg, REG01);
 
2104
  val &= ~REG01_SCAN;
 
2105
  sanei_genesys_set_reg_from_set (dev->reg, REG01, val);
 
2106
  status = sanei_genesys_write_register (dev, REG01, val);
 
2107
  if (status != SANE_STATUS_GOOD)
 
2108
    {
 
2109
      DBG (DBG_error,
 
2110
           "end_scan: failed to write register 01: %s\n",
 
2111
           sane_strstatus (status));
 
2112
      return status;
 
2113
    }
 
2114
  usleep (100 * 1000);
 
2115
 
 
2116
  loop = 10;
 
2117
  while (loop > 0)
 
2118
    {
 
2119
      status = sanei_genesys_get_status (dev, &val);
 
2120
      if (DBG_LEVEL >= DBG_io)
 
2121
        {
 
2122
          print_status (val);
 
2123
        }
 
2124
      val40 = 0;
 
2125
      status = sanei_genesys_read_register (dev, 0x40, &val40);
 
2126
      if (status != SANE_STATUS_GOOD)
 
2127
        {
 
2128
          DBG (DBG_error,
 
2129
               "%s: failed to read home sensor: %s\n", __FUNCTION__,
 
2130
               sane_strstatus (status));
 
2131
          DBGCOMPLETED;
 
2132
          return status;
 
2133
        }
 
2134
 
 
2135
      /* if scanner is in command mode, we are done */
 
2136
      if (!(val40 & REG40_DATAENB) && !(val40 & REG40_MOTMFLG)
 
2137
          && !(val & REG41_MOTORENB))
 
2138
        {
 
2139
          DBGCOMPLETED;
 
2140
          return SANE_STATUS_GOOD;
 
2141
        }
 
2142
 
 
2143
      usleep (100 * 1000);
 
2144
      loop--;
 
2145
    }
 
2146
 
 
2147
  DBGCOMPLETED;
 
2148
  return SANE_STATUS_IO_ERROR;
 
2149
}
 
2150
 
 
2151
static SANE_Status
 
2152
gl843_get_paper_sensor (Genesys_Device * dev, SANE_Bool * paper_loaded)
 
2153
{
 
2154
  SANE_Status status;
 
2155
  uint8_t val;
 
2156
 
 
2157
  status = sanei_genesys_read_register (dev, REG6D, &val);
 
2158
  if (status != SANE_STATUS_GOOD)
 
2159
    {
 
2160
      DBG (DBG_error,
 
2161
           "gl843_get_paper_sensor: failed to read gpio: %s\n",
 
2162
           sane_strstatus (status));
 
2163
      return status;
 
2164
    }
 
2165
  *paper_loaded = (val & 0x1) == 0;
 
2166
  return SANE_STATUS_GOOD;
 
2167
 
 
2168
  return SANE_STATUS_INVAL;
 
2169
}
 
2170
 
 
2171
static SANE_Status
 
2172
gl843_eject_document (Genesys_Device * dev)
 
2173
{
 
2174
  DBG (DBG_proc, "%s: not implemented \n", __FUNCTION__);
 
2175
  if (dev == NULL)
 
2176
    return SANE_STATUS_INVAL;
 
2177
  return SANE_STATUS_GOOD;
 
2178
}
 
2179
 
 
2180
 
 
2181
static SANE_Status
 
2182
gl843_load_document (Genesys_Device * dev)
 
2183
{
 
2184
  DBG (DBG_proc, "%s: not implemented \n", __FUNCTION__);
 
2185
  if (dev == NULL)
 
2186
    return SANE_STATUS_INVAL;
 
2187
  return SANE_STATUS_GOOD;
 
2188
}
 
2189
 
 
2190
/**
 
2191
 * detects end of document and adjust current scan
 
2192
 * to take it into account
 
2193
 * used by sheetfed scanners
 
2194
 */
 
2195
static SANE_Status
 
2196
gl843_detect_document_end (Genesys_Device * dev)
 
2197
{
 
2198
  SANE_Status status = SANE_STATUS_GOOD;
 
2199
  SANE_Bool paper_loaded;
 
2200
  unsigned int scancnt = 0;
 
2201
  int flines, channels, depth, bytes_remain, sublines,
 
2202
    bytes_to_flush, lines, sub_bytes, tmp, read_bytes_left;
 
2203
  DBG (DBG_proc, "%s: begin\n", __FUNCTION__);
 
2204
 
 
2205
  RIE (gl843_get_paper_sensor (dev, &paper_loaded));
 
2206
 
 
2207
  /* sheetfed scanner uses home sensor as paper present */
 
2208
  if ((dev->document == SANE_TRUE) && !paper_loaded)
 
2209
    {
 
2210
      DBG (DBG_info, "%s: no more document\n", __FUNCTION__);
 
2211
      dev->document = SANE_FALSE;
 
2212
 
 
2213
      channels = dev->current_setup.channels;
 
2214
      depth = dev->current_setup.depth;
 
2215
      read_bytes_left = (int) dev->read_bytes_left;
 
2216
      DBG (DBG_io, "gl843_detect_document_end: read_bytes_left=%d\n",
 
2217
           read_bytes_left);
 
2218
 
 
2219
      /* get lines read */
 
2220
      status = sanei_genesys_read_scancnt (dev, &scancnt);
 
2221
      if (status != SANE_STATUS_GOOD)
 
2222
        {
 
2223
          flines = 0;
 
2224
        }
 
2225
      else
 
2226
        {
 
2227
          /* compute number of line read */
 
2228
          tmp = (int) dev->total_bytes_read;
 
2229
          if (depth == 1 || dev->settings.scan_mode == SCAN_MODE_LINEART)
 
2230
            flines = tmp * 8 / dev->settings.pixels / channels;
 
2231
          else
 
2232
            flines = tmp / (depth / 8) / dev->settings.pixels / channels;
 
2233
 
 
2234
          /* number of scanned lines, but no read yet */
 
2235
          flines = scancnt - flines;
 
2236
 
 
2237
          DBG (DBG_io,
 
2238
               "gl843_detect_document_end: %d scanned but not read lines\n",
 
2239
               flines);
 
2240
        }
 
2241
 
 
2242
      /* adjust number of bytes to read 
 
2243
       * we need to read the final bytes which are word per line * number of last lines
 
2244
       * to have doc leaving feeder */
 
2245
      lines =
 
2246
        (SANE_UNFIX (dev->model->post_scan) * dev->current_setup.yres) /
 
2247
        MM_PER_INCH + flines;
 
2248
      DBG (DBG_io, "gl843_detect_document_end: adding %d line to flush\n",
 
2249
           lines);
 
2250
 
 
2251
      /* number of bytes to read from scanner to get document out of it after
 
2252
       * end of document dectected by hardware sensor */
 
2253
      bytes_to_flush = lines * dev->wpl;
 
2254
 
 
2255
      /* if we are already close to end of scan, flushing isn't needed */
 
2256
      if (bytes_to_flush < read_bytes_left)
 
2257
        {
 
2258
          /* we take all these step to work around an overflow on some plateforms */
 
2259
          tmp = (int) dev->total_bytes_read;
 
2260
          DBG (DBG_io, "gl843_detect_document_end: tmp=%d\n", tmp);
 
2261
          bytes_remain = (int) dev->total_bytes_to_read;
 
2262
          DBG (DBG_io, "gl843_detect_document_end: bytes_remain=%d\n",
 
2263
               bytes_remain);
 
2264
          bytes_remain = bytes_remain - tmp;
 
2265
          DBG (DBG_io, "gl843_detect_document_end: bytes_remain=%d\n",
 
2266
               bytes_remain);
 
2267
 
 
2268
          /* remaining lines to read by frontend for the current scan */
 
2269
          if (depth == 1 || dev->settings.scan_mode == SCAN_MODE_LINEART)
 
2270
            {
 
2271
              flines = bytes_remain * 8 / dev->settings.pixels / channels;
 
2272
            }
 
2273
          else
 
2274
            flines = bytes_remain / (depth / 8)
 
2275
              / dev->settings.pixels / channels;
 
2276
          DBG (DBG_io, "gl843_detect_document_end: flines=%d\n", flines);
 
2277
 
 
2278
          if (flines > lines)
 
2279
            {
 
2280
              /* change the value controlling communication with the frontend :
 
2281
               * total bytes to read is current value plus the number of remaining lines 
 
2282
               * multiplied by bytes per line */
 
2283
              sublines = flines - lines;
 
2284
 
 
2285
              if (depth == 1 || dev->settings.scan_mode == SCAN_MODE_LINEART)
 
2286
                sub_bytes =
 
2287
                  ((dev->settings.pixels * sublines) / 8 +
 
2288
                   (((dev->settings.pixels * sublines) % 8) ? 1 : 0)) *
 
2289
                  channels;
 
2290
              else
 
2291
                sub_bytes =
 
2292
                  dev->settings.pixels * sublines * channels * (depth / 8);
 
2293
 
 
2294
              dev->total_bytes_to_read -= sub_bytes;
 
2295
 
 
2296
              /* then adjust the physical bytes to read */
 
2297
              if (read_bytes_left > sub_bytes)
 
2298
                {
 
2299
                  dev->read_bytes_left -= sub_bytes;
 
2300
                }
 
2301
              else
 
2302
                {
 
2303
                  dev->total_bytes_to_read = dev->total_bytes_read;
 
2304
                  dev->read_bytes_left = 0;
 
2305
                }
 
2306
 
 
2307
              DBG (DBG_io, "gl843_detect_document_end: sublines=%d\n",
 
2308
                   sublines);
 
2309
              DBG (DBG_io, "gl843_detect_document_end: subbytes=%d\n",
 
2310
                   sub_bytes);
 
2311
              DBG (DBG_io,
 
2312
                   "gl843_detect_document_end: total_bytes_to_read=%lu\n",
 
2313
                   (unsigned long) dev->total_bytes_to_read);
 
2314
              DBG (DBG_io,
 
2315
                   "gl843_detect_document_end: read_bytes_left=%d\n",
 
2316
                   read_bytes_left);
 
2317
            }
 
2318
        }
 
2319
      else
 
2320
        {
 
2321
          DBG (DBG_io, "gl843_detect_document_end: no flushing needed\n");
 
2322
        }
 
2323
    }
 
2324
 
 
2325
  DBG (DBG_proc, "%s: finished\n", __FUNCTION__);
 
2326
  return SANE_STATUS_GOOD;
 
2327
}
 
2328
 
 
2329
/* Send the low-level scan command */
 
2330
/* todo : is this that useful ? */
 
2331
#ifndef UNIT_TESTING
 
2332
static
 
2333
#endif
 
2334
  SANE_Status
 
2335
gl843_begin_scan (Genesys_Device * dev, Genesys_Register_Set * reg,
 
2336
                  SANE_Bool start_motor)
 
2337
{
 
2338
  SANE_Status status;
 
2339
  uint8_t val;
 
2340
 
 
2341
  DBGSTART;
 
2342
  if (reg == NULL)
 
2343
    return SANE_STATUS_INVAL;
 
2344
 
 
2345
  /* set up GPIO for scan */
 
2346
  /* KV case */
 
2347
  if (dev->model->gpo_type == GPO_KVSS080)
 
2348
    {
 
2349
      RIE (sanei_genesys_write_register (dev, REGA9, 0x00));
 
2350
      RIE (sanei_genesys_write_register (dev, REGA6, 0xf6));
 
2351
      /* blinking led */
 
2352
      RIE(sanei_genesys_write_register(dev,0x7e,0x04)); 
 
2353
    }
 
2354
  if (dev->model->gpo_type == GPO_G4050)
 
2355
    {
 
2356
      RIE (sanei_genesys_write_register (dev, REGA6, 0x44));
 
2357
      RIE (sanei_genesys_write_register (dev, REGA7, 0xfe));
 
2358
      RIE (sanei_genesys_write_register (dev, REGA8, 0x3e));
 
2359
      RIE (sanei_genesys_write_register (dev, REGA9, 0x06));
 
2360
      /* blinking led */
 
2361
      RIE(sanei_genesys_write_register(dev,0x7e,0x01)); 
 
2362
    }
 
2363
 
 
2364
  /* clear scan and feed count */
 
2365
  RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT | REG0D_CLRMCNT));
 
2366
 
 
2367
  /* enable scan and motor */
 
2368
  RIE (sanei_genesys_read_register (dev, REG01, &val));
 
2369
  val |= REG01_SCAN;
 
2370
  RIE (sanei_genesys_write_register (dev, REG01, val));
 
2371
 
 
2372
  if (start_motor)
 
2373
    {
 
2374
      RIE (sanei_genesys_write_register (dev, REG0F, 1));
 
2375
    }
 
2376
  else
 
2377
    {
 
2378
      RIE (sanei_genesys_write_register (dev, REG0F, 0));
 
2379
    }
 
2380
 
 
2381
  DBGCOMPLETED;
 
2382
  return status;
 
2383
}
 
2384
 
 
2385
 
 
2386
/* Send the stop scan command */
 
2387
#ifndef UNIT_TESTING
 
2388
static
 
2389
#endif
 
2390
  SANE_Status
 
2391
gl843_end_scan (Genesys_Device * dev, Genesys_Register_Set * reg,
 
2392
                SANE_Bool check_stop)
 
2393
{
 
2394
  SANE_Status status;
 
2395
 
 
2396
  DBG (DBG_proc, "gl843_end_scan (check_stop = %d)\n", check_stop);
 
2397
  if (reg == NULL)
 
2398
    return SANE_STATUS_INVAL;
 
2399
 
 
2400
  /* post scan gpio */
 
2401
  RIE(sanei_genesys_write_register(dev,0x7e,0x00));
 
2402
 
 
2403
  if (dev->model->is_sheetfed == SANE_TRUE)
 
2404
    {
 
2405
      status = SANE_STATUS_GOOD;
 
2406
    }
 
2407
  else                          /* flat bed scanners */
 
2408
    {
 
2409
      status = gl843_stop_action (dev);
 
2410
      if (status != SANE_STATUS_GOOD)
 
2411
        {
 
2412
          DBG (DBG_error,
 
2413
               "gl843_end_scan: failed to stop: %s\n",
 
2414
               sane_strstatus (status));
 
2415
          return status;
 
2416
        }
 
2417
    }
 
2418
 
 
2419
  DBGCOMPLETED;
 
2420
  return status;
 
2421
}
 
2422
 
 
2423
 
 
2424
/** @brief Moves the slider to the home (top) position slowly
 
2425
 * */
 
2426
#ifndef UNIT_TESTING
 
2427
static
 
2428
#endif
 
2429
  SANE_Status
 
2430
gl843_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home)
 
2431
{
 
2432
  Genesys_Register_Set local_reg[GENESYS_GL843_MAX_REGS];
 
2433
  SANE_Status status;
 
2434
  Genesys_Register_Set *r;
 
2435
  uint8_t val;
 
2436
  float resolution;
 
2437
  int loop = 0;
 
2438
 
 
2439
  DBG (DBG_proc, "gl843_slow_back_home (wait_until_home = %d)\n",
 
2440
       wait_until_home);
 
2441
  usleep (100000);      /* sleep 100 ms */
 
2442
 
 
2443
  dev->scanhead_position_in_steps = 0;
 
2444
  status = sanei_genesys_get_status (dev, &val);
 
2445
  if (status != SANE_STATUS_GOOD)
 
2446
    {
 
2447
      DBG (DBG_error,
 
2448
           "gl843_slow_back_home: failed to read home sensor: %s\n",
 
2449
           sane_strstatus (status));
 
2450
      return status;
 
2451
    }
 
2452
  if (DBG_LEVEL >= DBG_io)
 
2453
    {
 
2454
      print_status (val);
 
2455
    }
 
2456
  if (val & REG41_HOMESNR)      /* is sensor at home? */
 
2457
    {
 
2458
      DBG (DBG_info, "gl843_slow_back_home: already at home, completed\n");
 
2459
      return SANE_STATUS_GOOD;
 
2460
    }
 
2461
 
 
2462
  memset (local_reg, 0, sizeof (local_reg));
 
2463
 
 
2464
  memcpy (local_reg, dev->reg,
 
2465
          GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set));
 
2466
  resolution=gl843_get_lowest_ydpi(dev);
 
2467
 
 
2468
  gl843_init_scan_regs (dev,
 
2469
                        local_reg,
 
2470
                        resolution,
 
2471
                        resolution,
 
2472
                        100,
 
2473
                        100,
 
2474
                        100,
 
2475
                        100,
 
2476
                        8,
 
2477
                        3,
 
2478
                        dev->settings.color_filter,
 
2479
                        SCAN_FLAG_DISABLE_SHADING |
 
2480
                        SCAN_FLAG_DISABLE_GAMMA |
 
2481
                        SCAN_FLAG_IGNORE_LINE_DISTANCE);
 
2482
  gl843_init_motor_regs_scan (dev,
 
2483
                              local_reg,
 
2484
                              gl843_compute_exposure (dev, resolution),
 
2485
                              resolution,
 
2486
                              gl843_compute_step_type(dev, resolution),
 
2487
                              1,
 
2488
                              1,
 
2489
                              30000, /* feed steps */
 
2490
                              0,
 
2491
                              0);
 
2492
 
 
2493
  /* clear scan and feed count */
 
2494
  RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT | REG0D_CLRMCNT));
 
2495
  
 
2496
  /* set up for reverse and no scan */
 
2497
  r = sanei_genesys_get_address (local_reg, REG02);
 
2498
  r->value |= REG02_MTRREV;
 
2499
  r = sanei_genesys_get_address (local_reg, REG01);
 
2500
  r->value &= ~REG01_SCAN;
 
2501
 
 
2502
  RIE (gl843_bulk_write_register (dev, local_reg, GENESYS_GL843_MAX_REGS));
 
2503
 
 
2504
  status = gl843_start_action (dev);
 
2505
  if (status != SANE_STATUS_GOOD)
 
2506
    {
 
2507
      DBG (DBG_error,
 
2508
           "gl843_slow_back_home: failed to start motor: %s\n",
 
2509
           sane_strstatus (status));
 
2510
      gl843_stop_action (dev);
 
2511
      /* restore original registers */
 
2512
      gl843_bulk_write_register (dev, dev->reg, GENESYS_GL843_MAX_REGS);
 
2513
      return status;
 
2514
    }
 
2515
 
 
2516
  if (wait_until_home)
 
2517
    {
 
2518
 
 
2519
      while (loop < 300)        /* do not wait longer then 30 seconds */
 
2520
        {
 
2521
          status = sanei_genesys_get_status (dev, &val);
 
2522
          if (status != SANE_STATUS_GOOD)
 
2523
            {
 
2524
              DBG (DBG_error,
 
2525
                   "gl843_slow_back_home: failed to read home sensor: %s\n",
 
2526
                   sane_strstatus (status));
 
2527
              return status;
 
2528
            }
 
2529
 
 
2530
          if (val & REG41_HOMESNR)      /* home sensor */
 
2531
            {
 
2532
              DBG (DBG_info, "gl843_slow_back_home: reached home position\n");
 
2533
              DBG (DBG_proc, "gl843_slow_back_home: finished\n");
 
2534
              return SANE_STATUS_GOOD;
 
2535
            }
 
2536
          usleep (100000);      /* sleep 100 ms */
 
2537
          ++loop;
 
2538
        }
 
2539
 
 
2540
      /* when we come here then the scanner needed too much time for this, so we better stop the motor */
 
2541
      gl843_stop_action (dev);
 
2542
      DBG (DBG_error,
 
2543
           "gl843_slow_back_home: timeout while waiting for scanhead to go home\n");
 
2544
      return SANE_STATUS_IO_ERROR;
 
2545
    }
 
2546
 
 
2547
  DBG (DBG_info, "gl843_slow_back_home: scanhead is still moving\n");
 
2548
  DBG (DBG_proc, "gl843_slow_back_home: finished\n");
 
2549
  return SANE_STATUS_GOOD;
 
2550
}
 
2551
 
 
2552
/* Automatically set top-left edge of the scan area by scanning a 200x200 pixels
 
2553
   area at 600 dpi from very top of scanner */
 
2554
static SANE_Status
 
2555
gl843_search_start_position (Genesys_Device * dev)
 
2556
{
 
2557
  int size;
 
2558
  SANE_Status status;
 
2559
  uint8_t *data;
 
2560
  Genesys_Register_Set local_reg[GENESYS_GL843_MAX_REGS];
 
2561
  int steps;
 
2562
 
 
2563
  int pixels = 600;
 
2564
  int dpi = 300;
 
2565
 
 
2566
  DBG (DBG_proc, "gl843_search_start_position\n");
 
2567
 
 
2568
  memset (local_reg, 0, sizeof (local_reg));
 
2569
  memcpy (local_reg, dev->reg,
 
2570
          GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set));
 
2571
 
 
2572
  /* sets for a 200 lines * 600 pixels */
 
2573
  /* normal scan with no shading */
 
2574
 
 
2575
  status = gl843_init_scan_regs (dev, local_reg, dpi, dpi, 0, 0,        /*we should give a small offset here~60 steps */
 
2576
                                 600, dev->model->search_lines, 8, 1, 1,        /*green */
 
2577
                                 SCAN_FLAG_DISABLE_SHADING |
 
2578
                                 SCAN_FLAG_DISABLE_GAMMA |
 
2579
                                 SCAN_FLAG_IGNORE_LINE_DISTANCE |
 
2580
                                 SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE);
 
2581
 
 
2582
  /* send to scanner */
 
2583
  status = gl843_bulk_write_register (dev, local_reg, GENESYS_GL843_MAX_REGS);
 
2584
  if (status != SANE_STATUS_GOOD)
 
2585
    {
 
2586
      DBG (DBG_error,
 
2587
           "gl843_search_start_position: failed to bulk write registers: %s\n",
 
2588
           sane_strstatus (status));
 
2589
      return status;
 
2590
    }
 
2591
 
 
2592
  size = pixels * dev->model->search_lines;
 
2593
 
 
2594
  data = malloc (size);
 
2595
  if (!data)
 
2596
    {
 
2597
      DBG (DBG_error,
 
2598
           "gl843_search_start_position: failed to allocate memory\n");
 
2599
      return SANE_STATUS_NO_MEM;
 
2600
    }
 
2601
 
 
2602
  status = gl843_begin_scan (dev, local_reg, SANE_TRUE);
 
2603
  if (status != SANE_STATUS_GOOD)
 
2604
    {
 
2605
      free (data);
 
2606
      DBG (DBG_error,
 
2607
           "gl843_search_start_position: failed to begin scan: %s\n",
 
2608
           sane_strstatus (status));
 
2609
      return status;
 
2610
    }
 
2611
 
 
2612
  /* waits for valid data */
 
2613
  do
 
2614
    sanei_genesys_test_buffer_empty (dev, &steps);
 
2615
  while (steps);
 
2616
 
 
2617
  /* now we're on target, we can read data */
 
2618
  status = sanei_genesys_read_data_from_scanner (dev, data, size);
 
2619
  if (status != SANE_STATUS_GOOD)
 
2620
    {
 
2621
      free (data);
 
2622
      DBG (DBG_error,
 
2623
           "gl843_search_start_position: failed to read data: %s\n",
 
2624
           sane_strstatus (status));
 
2625
      return status;
 
2626
    }
 
2627
 
 
2628
  if (DBG_LEVEL >= DBG_data)
 
2629
    sanei_genesys_write_pnm_file ("search_position.pnm", data, 8, 1, pixels,
 
2630
                                  dev->model->search_lines);
 
2631
 
 
2632
  status = gl843_end_scan (dev, local_reg, SANE_TRUE);
 
2633
  if (status != SANE_STATUS_GOOD)
 
2634
    {
 
2635
      free (data);
 
2636
      DBG (DBG_error,
 
2637
           "gl843_search_start_position: failed to end scan: %s\n",
 
2638
           sane_strstatus (status));
 
2639
      return status;
 
2640
    }
 
2641
 
 
2642
  /* update regs to copy ASIC internal state */
 
2643
  memcpy (dev->reg, local_reg,
 
2644
          GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set));
 
2645
 
 
2646
  status =
 
2647
    sanei_genesys_search_reference_point (dev, data, 0, dpi, pixels,
 
2648
                                          dev->model->search_lines);
 
2649
  if (status != SANE_STATUS_GOOD)
 
2650
    {
 
2651
      free (data);
 
2652
      DBG (DBG_error,
 
2653
           "gl843_search_start_position: failed to set search reference point: %s\n",
 
2654
           sane_strstatus (status));
 
2655
      return status;
 
2656
    }
 
2657
 
 
2658
  free (data);
 
2659
  return SANE_STATUS_GOOD;
 
2660
}
 
2661
 
 
2662
/* 
 
2663
 * sets up register for coarse gain calibration
 
2664
 * todo: check it for scanners using it */
 
2665
static SANE_Status
 
2666
gl843_init_regs_for_coarse_calibration (Genesys_Device * dev)
 
2667
{
 
2668
  SANE_Status status;
 
2669
  uint8_t channels;
 
2670
  uint8_t cksel;
 
2671
  Genesys_Register_Set *r;
 
2672
 
 
2673
  DBGSTART;
 
2674
  cksel = (dev->calib_reg[reg_0x18].value & REG18_CKSEL) + 1;   /* clock speed = 1..4 clocks */
 
2675
 
 
2676
  /* set line size */
 
2677
  if (dev->settings.scan_mode == SCAN_MODE_COLOR)       /* single pass color */
 
2678
    channels = 3;
 
2679
  else
 
2680
    channels = 1;
 
2681
 
 
2682
  status = gl843_init_scan_regs (dev,
 
2683
                                 dev->calib_reg,
 
2684
                                 dev->settings.xres,
 
2685
                                 dev->settings.yres,
 
2686
                                 0,
 
2687
                                 0,
 
2688
                                 dev->sensor.optical_res / cksel,
 
2689
                                 20,
 
2690
                                 16,
 
2691
                                 channels,
 
2692
                                 dev->settings.color_filter,
 
2693
                                 SCAN_FLAG_DISABLE_SHADING |
 
2694
                                 SCAN_FLAG_DISABLE_GAMMA |
 
2695
                                 SCAN_FLAG_SINGLE_LINE |
 
2696
                                 SCAN_FLAG_IGNORE_LINE_DISTANCE);
 
2697
  if (status != SANE_STATUS_GOOD)
 
2698
    {
 
2699
      DBG (DBG_error,
 
2700
           "gl843_init_register_for_coarse_calibration: failed to setup scan: %s\n",
 
2701
           sane_strstatus (status));
 
2702
      return status;
 
2703
    }
 
2704
  r = sanei_genesys_get_address (dev->calib_reg, REG02);
 
2705
  r->value &= ~REG02_MTRPWR;
 
2706
 
 
2707
  DBG (DBG_info,
 
2708
       "gl843_init_register_for_coarse_calibration: optical sensor res: %d dpi, actual res: %d\n",
 
2709
       dev->sensor.optical_res / cksel, dev->settings.xres);
 
2710
 
 
2711
  status =
 
2712
    gl843_bulk_write_register (dev, dev->calib_reg, GENESYS_GL843_MAX_REGS);
 
2713
  if (status != SANE_STATUS_GOOD)
 
2714
    {
 
2715
      DBG (DBG_error,
 
2716
           "gl843_init_register_for_coarse_calibration: failed to bulk write registers: %s\n",
 
2717
           sane_strstatus (status));
 
2718
      return status;
 
2719
    }
 
2720
 
 
2721
  DBGCOMPLETED;
 
2722
  return SANE_STATUS_GOOD;
 
2723
}
 
2724
 
 
2725
 
 
2726
/* init registers for shading calibration */
 
2727
static SANE_Status
 
2728
gl843_init_regs_for_shading (Genesys_Device * dev)
 
2729
{
 
2730
  SANE_Status status;
 
2731
  int move,resolution;
 
2732
 
 
2733
  DBGSTART;
 
2734
  
 
2735
  /* initial calibration reg values */
 
2736
  memcpy (dev->calib_reg, dev->reg,
 
2737
          GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set));
 
2738
 
 
2739
  dev->calib_channels = 3;
 
2740
  dev->calib_pixels = dev->sensor.sensor_pixels;
 
2741
  resolution=gl843_compute_dpihw(dev,dev->settings.xres);
 
2742
 
 
2743
  /* distance to move to reach white target */
 
2744
  move = SANE_UNFIX (dev->model->y_offset_calib);
 
2745
  move = (move * resolution) / MM_PER_INCH;
 
2746
 
 
2747
  status = gl843_init_scan_regs (dev,
 
2748
                                 dev->calib_reg,
 
2749
                                 resolution,
 
2750
                                 resolution,
 
2751
                                 0,
 
2752
                                 move,
 
2753
                                 dev->calib_pixels,
 
2754
                                 dev->model->shading_lines,
 
2755
                                 16,
 
2756
                                 dev->calib_channels,
 
2757
                                 dev->settings.color_filter,
 
2758
                                 SCAN_FLAG_DISABLE_SHADING |
 
2759
                                 SCAN_FLAG_DISABLE_GAMMA |
 
2760
                                 SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE |
 
2761
                                 SCAN_FLAG_IGNORE_LINE_DISTANCE);
 
2762
 
 
2763
  if (status != SANE_STATUS_GOOD)
 
2764
    {
 
2765
      DBG (DBG_error,
 
2766
           "gl843_init_registers_for_shading: failed to setup scan: %s\n",
 
2767
           sane_strstatus (status));
 
2768
      return status;
 
2769
    }
 
2770
 
 
2771
  dev->scanhead_position_in_steps += dev->model->shading_lines + move;
 
2772
 
 
2773
  status =
 
2774
    gl843_bulk_write_register (dev, dev->calib_reg, GENESYS_GL843_MAX_REGS);
 
2775
  if (status != SANE_STATUS_GOOD)
 
2776
    {
 
2777
      DBG (DBG_error,
 
2778
           "gl843_init_registers_for_shading: failed to bulk write registers: %s\n",
 
2779
           sane_strstatus (status));
 
2780
      return status;
 
2781
    }
 
2782
 
 
2783
  DBGCOMPLETED;
 
2784
  return SANE_STATUS_GOOD;
 
2785
}
 
2786
 
 
2787
/** @brief set up registers for the actual scan
 
2788
 */
 
2789
static SANE_Status
 
2790
gl843_init_regs_for_scan (Genesys_Device * dev)
 
2791
{
 
2792
  int channels;
 
2793
  int flags;
 
2794
  int depth;
 
2795
  float move;
 
2796
  int move_dpi;
 
2797
  float start;
 
2798
 
 
2799
  SANE_Status status;
 
2800
 
 
2801
  DBG (DBG_info,
 
2802
       "gl843_init_regs_for_scan settings:\nResolution: %ux%uDPI\n"
 
2803
       "Lines     : %u\npixels    : %u\nStartpos  : %.3f/%.3f\nScan mode : %d\n\n",
 
2804
       dev->settings.xres,
 
2805
       dev->settings.yres,
 
2806
       dev->settings.lines,
 
2807
       dev->settings.pixels,
 
2808
       dev->settings.tl_x,
 
2809
       dev->settings.tl_y,
 
2810
       dev->settings.scan_mode);
 
2811
 
 
2812
  /* ensure head is parked in case of calibration */
 
2813
  gl843_slow_back_home (dev, SANE_TRUE);
 
2814
 
 
2815
  /* channels */
 
2816
  if (dev->settings.scan_mode == SCAN_MODE_COLOR)
 
2817
    channels = 3;
 
2818
  else
 
2819
    channels = 1;
 
2820
 
 
2821
  /* depth */
 
2822
  depth = dev->settings.depth;
 
2823
  if (dev->settings.scan_mode == SCAN_MODE_LINEART)
 
2824
    depth = 1;
 
2825
 
 
2826
  move_dpi = dev->motor.base_ydpi;
 
2827
 
 
2828
  move = SANE_UNFIX (dev->model->y_offset);
 
2829
  move += dev->settings.tl_y;
 
2830
  move = (move * move_dpi) / MM_PER_INCH;
 
2831
  DBG (DBG_info, "gl843_init_regs_for_scan: move=%f steps\n", move);
 
2832
 
 
2833
  /* start */
 
2834
  start = SANE_UNFIX (dev->model->x_offset);
 
2835
  start += dev->settings.tl_x;
 
2836
  start = (start * dev->sensor.optical_res) / MM_PER_INCH;
 
2837
 
 
2838
  flags = 0;
 
2839
 
 
2840
  /* enable emulated lineart from gray data */
 
2841
  if(dev->settings.scan_mode == SCAN_MODE_LINEART 
 
2842
     && dev->settings.dynamic_lineart)
 
2843
    {
 
2844
      flags |= SCAN_FLAG_DYNAMIC_LINEART;
 
2845
    }
 
2846
 
 
2847
  status = gl843_init_scan_regs (dev,
 
2848
                                 dev->reg,
 
2849
                                 dev->settings.xres,
 
2850
                                 dev->settings.yres,
 
2851
                                 start,
 
2852
                                 move,
 
2853
                                 dev->settings.pixels,
 
2854
                                 dev->settings.lines,
 
2855
                                 depth,
 
2856
                                 channels, dev->settings.color_filter, flags);
 
2857
 
 
2858
  if (status != SANE_STATUS_GOOD)
 
2859
    return status;
 
2860
 
 
2861
  DBGCOMPLETED;
 
2862
  return SANE_STATUS_GOOD;
 
2863
}
 
2864
 
 
2865
/*
 
2866
 * this function sends generic gamma table (ie linear ones)
 
2867
 * or the Sensor specific one if provided
 
2868
 */
 
2869
static SANE_Status
 
2870
gl843_send_gamma_table (Genesys_Device * dev, SANE_Bool generic)
 
2871
{
 
2872
  int size;
 
2873
  int status;
 
2874
  uint8_t *gamma;
 
2875
  int i, gmmval;
 
2876
 
 
2877
  DBG (DBG_proc, "gl843_send_gamma_table\n");
 
2878
 
 
2879
  /* don't send anything if no specific gamma table defined */
 
2880
  if (!generic
 
2881
      && (dev->sensor.red_gamma_table == NULL
 
2882
          || dev->sensor.green_gamma_table == NULL
 
2883
          || dev->sensor.blue_gamma_table == NULL))
 
2884
    {
 
2885
      DBG (DBG_proc, "gl843_send_gamma_table: nothing to send, skipping\n");
 
2886
      return SANE_STATUS_GOOD;
 
2887
    }
 
2888
 
 
2889
  size = 256;
 
2890
 
 
2891
  /* allocate temporary gamma tables: 16 bits words, 3 channels */
 
2892
  gamma = (uint8_t *) malloc (size * 2 * 3);
 
2893
  if (!gamma)
 
2894
    return SANE_STATUS_NO_MEM;
 
2895
 
 
2896
  /* take care off generic/specific data */
 
2897
  if (generic)
 
2898
    {
 
2899
      /* fill with default values */
 
2900
      for (i = 0; i < size; i++)
 
2901
        {
 
2902
          gmmval = i * 256;
 
2903
          gamma[i * 2 + size * 0 + 0] = gmmval & 0xff;
 
2904
          gamma[i * 2 + size * 0 + 1] = (gmmval >> 8) & 0xff;
 
2905
          gamma[i * 2 + size * 2 + 0] = gmmval & 0xff;
 
2906
          gamma[i * 2 + size * 2 + 1] = (gmmval >> 8) & 0xff;
 
2907
          gamma[i * 2 + size * 4 + 0] = gmmval & 0xff;
 
2908
          gamma[i * 2 + size * 4 + 1] = (gmmval >> 8) & 0xff;
 
2909
        }
 
2910
    }
 
2911
  else
 
2912
    {
 
2913
      /* copy sensor specific's gamma tables */
 
2914
      for (i = 0; i < size; i++)
 
2915
        {
 
2916
          gamma[i * 2 + size * 0 + 0] = dev->sensor.red_gamma_table[i] & 0xff;
 
2917
          gamma[i * 2 + size * 0 + 1] =
 
2918
            (dev->sensor.red_gamma_table[i] >> 8) & 0xff;
 
2919
          gamma[i * 2 + size * 2 + 0] =
 
2920
            dev->sensor.green_gamma_table[i] & 0xff;
 
2921
          gamma[i * 2 + size * 2 + 1] =
 
2922
            (dev->sensor.green_gamma_table[i] >> 8) & 0xff;
 
2923
          gamma[i * 2 + size * 4 + 0] =
 
2924
            dev->sensor.blue_gamma_table[i] & 0xff;
 
2925
          gamma[i * 2 + size * 4 + 1] =
 
2926
            (dev->sensor.blue_gamma_table[i] >> 8) & 0xff;
 
2927
        }
 
2928
    }
 
2929
 
 
2930
  /* send address */
 
2931
  status = gl843_set_buffer_address (dev, 0x0000);
 
2932
  if (status != SANE_STATUS_GOOD)
 
2933
    {
 
2934
      free (gamma);
 
2935
      DBG (DBG_error,
 
2936
           "gl843_send_gamma_table: failed to set buffer address: %s\n",
 
2937
           sane_strstatus (status));
 
2938
      return status;
 
2939
    }
 
2940
 
 
2941
  /* send data */
 
2942
  status = gl843_bulk_write_data (dev, 0x28, (uint8_t *) gamma, size * 2 * 3);
 
2943
  if (status != SANE_STATUS_GOOD)
 
2944
    {
 
2945
      free (gamma);
 
2946
      DBG (DBG_error,
 
2947
           "gl843_send_gamma_table: failed to send gamma table: %s\n",
 
2948
           sane_strstatus (status));
 
2949
      return status;
 
2950
    }
 
2951
 
 
2952
  DBG (DBG_proc, "gl843_send_gamma_table: completed\n");
 
2953
  free (gamma);
 
2954
  return SANE_STATUS_GOOD;
 
2955
}
 
2956
 
 
2957
/* this function does the led calibration by scanning one line of the calibration
 
2958
   area below scanner's top on white strip.
 
2959
 
 
2960
-needs working coarse/gain
 
2961
*/
 
2962
static SANE_Status
 
2963
gl843_led_calibration (Genesys_Device * dev)
 
2964
{
 
2965
  int num_pixels;
 
2966
  int total_size;
 
2967
  int used_res;
 
2968
  uint8_t *line;
 
2969
  int i, j;
 
2970
  SANE_Status status = SANE_STATUS_GOOD;
 
2971
  int val;
 
2972
  int channels, depth;
 
2973
  int avg[3], avga, avge;
 
2974
  int turn;
 
2975
  char fn[20];
 
2976
  uint16_t expr, expg, expb;
 
2977
  Genesys_Register_Set *r;
 
2978
 
 
2979
  SANE_Bool acceptable = SANE_FALSE;
 
2980
 
 
2981
  DBG (DBG_proc, "gl843_led_calibration\n");
 
2982
 
 
2983
  /* offset calibration is always done in color mode */
 
2984
  channels = 3;
 
2985
  depth = 16;
 
2986
  used_res = dev->sensor.optical_res;
 
2987
  num_pixels =
 
2988
    (dev->sensor.sensor_pixels * used_res) / dev->sensor.optical_res;
 
2989
 
 
2990
  /* initial calibration reg values */
 
2991
  memcpy (dev->calib_reg, dev->reg,
 
2992
          GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set));
 
2993
 
 
2994
  status = gl843_init_scan_regs (dev,
 
2995
                                 dev->calib_reg,
 
2996
                                 used_res,
 
2997
                                 dev->motor.base_ydpi,
 
2998
                                 0,
 
2999
                                 0,
 
3000
                                 num_pixels,
 
3001
                                 1,
 
3002
                                 depth,
 
3003
                                 channels,
 
3004
                                 dev->settings.color_filter,
 
3005
                                 SCAN_FLAG_DISABLE_SHADING |
 
3006
                                 SCAN_FLAG_DISABLE_GAMMA |
 
3007
                                 SCAN_FLAG_SINGLE_LINE |
 
3008
                                 SCAN_FLAG_IGNORE_LINE_DISTANCE);
 
3009
 
 
3010
  if (status != SANE_STATUS_GOOD)
 
3011
    {
 
3012
      DBG (DBG_error,
 
3013
           "gl843_led_calibration: failed to setup scan: %s\n",
 
3014
           sane_strstatus (status));
 
3015
      return status;
 
3016
    }
 
3017
 
 
3018
  RIE (gl843_bulk_write_register
 
3019
       (dev, dev->calib_reg, GENESYS_GL843_MAX_REGS));
 
3020
 
 
3021
 
 
3022
  total_size = num_pixels * channels * (depth / 8) * 1; /* colors * bytes_per_color * scan lines */
 
3023
 
 
3024
  line = malloc (total_size);
 
3025
  if (!line)
 
3026
    return SANE_STATUS_NO_MEM;
 
3027
 
 
3028
/* 
 
3029
   we try to get equal bright leds here:
 
3030
 
 
3031
   loop:
 
3032
     average per color
 
3033
     adjust exposure times
 
3034
 */
 
3035
 
 
3036
  expr = (dev->sensor.regs_0x10_0x1d[0] << 8) | dev->sensor.regs_0x10_0x1d[1];
 
3037
  expg = (dev->sensor.regs_0x10_0x1d[2] << 8) | dev->sensor.regs_0x10_0x1d[3];
 
3038
  expb = (dev->sensor.regs_0x10_0x1d[4] << 8) | dev->sensor.regs_0x10_0x1d[5];
 
3039
 
 
3040
  turn = 0;
 
3041
 
 
3042
  do
 
3043
    {
 
3044
 
 
3045
      dev->sensor.regs_0x10_0x1d[0] = (expr >> 8) & 0xff;
 
3046
      dev->sensor.regs_0x10_0x1d[1] = expr & 0xff;
 
3047
      dev->sensor.regs_0x10_0x1d[2] = (expg >> 8) & 0xff;
 
3048
      dev->sensor.regs_0x10_0x1d[3] = expg & 0xff;
 
3049
      dev->sensor.regs_0x10_0x1d[4] = (expb >> 8) & 0xff;
 
3050
      dev->sensor.regs_0x10_0x1d[5] = expb & 0xff;
 
3051
 
 
3052
      for (i = 0; i < 6; i++)
 
3053
        {
 
3054
          r = sanei_genesys_get_address (dev->calib_reg, 0x10 + i);
 
3055
          r->value = dev->sensor.regs_0x10_0x1d[i];
 
3056
        }
 
3057
 
 
3058
      RIE (gl843_bulk_write_register
 
3059
           (dev, dev->calib_reg, GENESYS_GL843_MAX_REGS));
 
3060
 
 
3061
      DBG (DBG_info, "gl843_led_calibration: starting first line reading\n");
 
3062
      RIE (gl843_begin_scan (dev, dev->calib_reg, SANE_TRUE));
 
3063
      RIE (sanei_genesys_read_data_from_scanner (dev, line, total_size));
 
3064
 
 
3065
      if (DBG_LEVEL >= DBG_data)
 
3066
        {
 
3067
          snprintf (fn, 20, "led_%02d.pnm", turn);
 
3068
          sanei_genesys_write_pnm_file (fn,
 
3069
                                        line, depth, channels, num_pixels, 1);
 
3070
        }
 
3071
 
 
3072
      acceptable = SANE_TRUE;
 
3073
 
 
3074
      for (j = 0; j < channels; j++)
 
3075
        {
 
3076
          avg[j] = 0;
 
3077
          for (i = 0; i < num_pixels; i++)
 
3078
            {
 
3079
              if (dev->model->is_cis)
 
3080
                val =
 
3081
                  line[i * 2 + j * 2 * num_pixels + 1] * 256 +
 
3082
                  line[i * 2 + j * 2 * num_pixels];
 
3083
              else
 
3084
                val =
 
3085
                  line[i * 2 * channels + 2 * j + 1] * 256 +
 
3086
                  line[i * 2 * channels + 2 * j];
 
3087
              avg[j] += val;
 
3088
            }
 
3089
 
 
3090
          avg[j] /= num_pixels;
 
3091
        }
 
3092
 
 
3093
      DBG (DBG_info, "gl843_led_calibration: average: "
 
3094
           "%d,%d,%d\n", avg[0], avg[1], avg[2]);
 
3095
 
 
3096
      acceptable = SANE_TRUE;
 
3097
 
 
3098
      if (avg[0] < avg[1] * 0.95 || avg[1] < avg[0] * 0.95 ||
 
3099
          avg[0] < avg[2] * 0.95 || avg[2] < avg[0] * 0.95 ||
 
3100
          avg[1] < avg[2] * 0.95 || avg[2] < avg[1] * 0.95)
 
3101
        acceptable = SANE_FALSE;
 
3102
 
 
3103
      if (!acceptable)
 
3104
        {
 
3105
          avga = (avg[0] + avg[1] + avg[2]) / 3;
 
3106
          expr = (expr * avga) / avg[0];
 
3107
          expg = (expg * avga) / avg[1];
 
3108
          expb = (expb * avga) / avg[2];
 
3109
/*
 
3110
  keep the resulting exposures below this value.
 
3111
  too long exposure drives the ccd into saturation.
 
3112
  we may fix this by relying on the fact that 
 
3113
  we get a striped scan without shading, by means of
 
3114
  statistical calculation 
 
3115
*/
 
3116
          avge = (expr + expg + expb) / 3;
 
3117
 
 
3118
          /* don't overflow max exposure */
 
3119
          if (avge > 3000)
 
3120
            {
 
3121
              expr = (expr * 2000) / avge;
 
3122
              expg = (expg * 2000) / avge;
 
3123
              expb = (expb * 2000) / avge;
 
3124
            }
 
3125
          if (avge < 50)
 
3126
            {
 
3127
              expr = (expr * 50) / avge;
 
3128
              expg = (expg * 50) / avge;
 
3129
              expb = (expb * 50) / avge;
 
3130
            }
 
3131
 
 
3132
        }
 
3133
 
 
3134
      RIE (gl843_stop_action (dev));
 
3135
 
 
3136
      turn++;
 
3137
 
 
3138
    }
 
3139
  while (!acceptable && turn < 100);
 
3140
 
 
3141
  DBG (DBG_info, "gl843_led_calibration: acceptable exposure: %d,%d,%d\n",
 
3142
       expr, expg, expb);
 
3143
 
 
3144
  /* cleanup before return */
 
3145
  free (line);
 
3146
 
 
3147
  gl843_slow_back_home (dev, SANE_TRUE);
 
3148
 
 
3149
  DBG (DBG_proc, "gl843_led_calibration: completed\n");
 
3150
  return status;
 
3151
}
 
3152
 
 
3153
 
 
3154
/**
 
3155
 * average dark pixels of a 8 bits scan
 
3156
 */
 
3157
static int
 
3158
dark_average (uint8_t * data, unsigned int pixels, unsigned int lines,
 
3159
              unsigned int channels, unsigned int black)
 
3160
{
 
3161
  unsigned int i, j, k, average, count;
 
3162
  unsigned int avg[3];
 
3163
  uint8_t val;
 
3164
 
 
3165
  /* computes average value on black margin */
 
3166
  for (k = 0; k < channels; k++)
 
3167
    {
 
3168
      avg[k] = 0;
 
3169
      count = 0;
 
3170
      for (i = 0; i < lines; i++)
 
3171
        {
 
3172
          for (j = 0; j < black; j++)
 
3173
            {
 
3174
              val = data[i * channels * pixels + j + k];
 
3175
              avg[k] += val;
 
3176
              count++;
 
3177
            }
 
3178
        }
 
3179
      if (count)
 
3180
        avg[k] /= count;
 
3181
      DBG (DBG_info, "dark_average: avg[%d] = %d\n", k, avg[k]);
 
3182
    }
 
3183
  average = 0;
 
3184
  for (i = 0; i < channels; i++)
 
3185
    average += avg[i];
 
3186
  average /= channels;
 
3187
  DBG (DBG_info, "dark_average: average = %d\n", average);
 
3188
  return average;
 
3189
}
 
3190
 
 
3191
 
 
3192
static SANE_Status
 
3193
gl843_offset_calibration (Genesys_Device * dev)
 
3194
{
 
3195
  Genesys_Register_Set *r;
 
3196
  SANE_Status status = SANE_STATUS_GOOD;
 
3197
  uint8_t *first_line, *second_line;
 
3198
  unsigned int channels, bpp;
 
3199
  char title[32];
 
3200
  int pass = 0, avg, total_size;
 
3201
  int topavg, bottomavg, resolution, lines;
 
3202
  int top, bottom, black_pixels, pixels;
 
3203
 
 
3204
  DBGSTART;
 
3205
 
 
3206
  /* offset calibration is always done in color mode */
 
3207
  channels = 3;
 
3208
  resolution=dev->sensor.optical_res;
 
3209
  dev->calib_pixels = dev->sensor.sensor_pixels;
 
3210
  lines=1;
 
3211
  bpp=8;
 
3212
  pixels= (dev->sensor.sensor_pixels*resolution) / dev->sensor.optical_res;
 
3213
  black_pixels = (dev->sensor.black_pixels * resolution) / dev->sensor.optical_res;
 
3214
  DBG (DBG_io2, "gl843_offset_calibration: black_pixels=%d\n", black_pixels);
 
3215
 
 
3216
  status = gl843_init_scan_regs (dev,
 
3217
                                 dev->calib_reg,
 
3218
                                 resolution,
 
3219
                                 resolution,
 
3220
                                 0,
 
3221
                                 0,
 
3222
                                 pixels,
 
3223
                                 lines,
 
3224
                                 bpp,
 
3225
                                 channels,
 
3226
                                 dev->settings.color_filter,
 
3227
                                 SCAN_FLAG_DISABLE_SHADING |
 
3228
                                 SCAN_FLAG_DISABLE_GAMMA |
 
3229
                                 SCAN_FLAG_SINGLE_LINE |
 
3230
                                 SCAN_FLAG_IGNORE_LINE_DISTANCE);
 
3231
  if (status != SANE_STATUS_GOOD)
 
3232
    {
 
3233
      DBG (DBG_error,
 
3234
           "gl843_offset_calibration: failed to setup scan: %s\n",
 
3235
           sane_strstatus (status));
 
3236
      return status;
 
3237
    }
 
3238
  r = sanei_genesys_get_address (dev->calib_reg, REG02);
 
3239
  r->value &= ~REG02_MTRPWR;
 
3240
 
 
3241
  /* allocate memory for scans */
 
3242
  total_size = pixels * channels * lines * (bpp/8);     /* colors * bytes_per_color * scan lines */
 
3243
 
 
3244
  first_line = malloc (total_size);
 
3245
  if (!first_line)
 
3246
    return SANE_STATUS_NO_MEM;
 
3247
 
 
3248
  second_line = malloc (total_size);
 
3249
  if (!second_line)
 
3250
    {
 
3251
      free (first_line);
 
3252
      return SANE_STATUS_NO_MEM;
 
3253
    }
 
3254
 
 
3255
  /* init gain */
 
3256
  dev->frontend.gain[0] = 0;
 
3257
  dev->frontend.gain[1] = 0;
 
3258
  dev->frontend.gain[2] = 0;
 
3259
 
 
3260
  /* scan with no move */
 
3261
  bottom = 10;
 
3262
  dev->frontend.offset[0] = bottom;
 
3263
  dev->frontend.offset[1] = bottom;
 
3264
  dev->frontend.offset[2] = bottom;
 
3265
 
 
3266
  RIE (gl843_set_fe(dev, AFE_SET));
 
3267
  RIE (gl843_bulk_write_register (dev, dev->calib_reg, GENESYS_GL843_MAX_REGS));
 
3268
  DBG (DBG_info, "gl843_offset_calibration: starting first line reading\n");
 
3269
  RIE (gl843_begin_scan (dev, dev->calib_reg, SANE_TRUE));
 
3270
  RIE (sanei_genesys_read_data_from_scanner (dev, first_line, total_size));
 
3271
  if (DBG_LEVEL >= DBG_data)
 
3272
   {
 
3273
      snprintf(title,20,"offset%03d.pnm",bottom);
 
3274
      sanei_genesys_write_pnm_file (title, first_line, bpp, channels, pixels, lines);
 
3275
   }
 
3276
     
 
3277
  bottomavg = dark_average (first_line, pixels, lines, channels, black_pixels);
 
3278
  DBG (DBG_io2, "gl843_offset_calibration: bottom avg=%d\n", bottomavg);
 
3279
 
 
3280
  /* now top value */
 
3281
  top = 255;
 
3282
  dev->frontend.offset[0] = top;
 
3283
  dev->frontend.offset[1] = top;
 
3284
  dev->frontend.offset[2] = top;
 
3285
  RIE (gl843_set_fe(dev, AFE_SET));
 
3286
  RIE (gl843_bulk_write_register (dev, dev->calib_reg, GENESYS_GL843_MAX_REGS));
 
3287
  DBG (DBG_info, "gl843_offset_calibration: starting second line reading\n");
 
3288
  RIE (gl843_begin_scan (dev, dev->calib_reg, SANE_TRUE));
 
3289
  RIE (sanei_genesys_read_data_from_scanner (dev, second_line, total_size));
 
3290
      
 
3291
  topavg = dark_average (second_line, pixels, lines, channels, black_pixels);
 
3292
  DBG (DBG_io2, "gl843_offset_calibration: top avg=%d\n", topavg);
 
3293
 
 
3294
  /* loop until acceptable level */
 
3295
  while ((pass < 32) && (top - bottom > 1))
 
3296
    {
 
3297
      pass++;
 
3298
 
 
3299
      /* settings for new scan */
 
3300
      dev->frontend.offset[0] = (top + bottom) / 2;
 
3301
      dev->frontend.offset[1] = (top + bottom) / 2;
 
3302
      dev->frontend.offset[2] = (top + bottom) / 2;
 
3303
 
 
3304
      /* scan with no move */
 
3305
      RIE(gl843_set_fe(dev, AFE_SET));
 
3306
      RIE (gl843_bulk_write_register (dev, dev->calib_reg, GENESYS_GL843_MAX_REGS));
 
3307
      DBG (DBG_info, "gl843_offset_calibration: starting second line reading\n");
 
3308
      RIE (gl843_begin_scan (dev, dev->calib_reg, SANE_TRUE));
 
3309
      RIE (sanei_genesys_read_data_from_scanner (dev, second_line, total_size));
 
3310
 
 
3311
      if (DBG_LEVEL >= DBG_data)
 
3312
        {
 
3313
          sprintf (title, "offset%03d.pnm", dev->frontend.offset[1]);
 
3314
          sanei_genesys_write_pnm_file (title, second_line, bpp, channels, pixels, lines);
 
3315
        }
 
3316
 
 
3317
      avg = dark_average (second_line, pixels, lines, channels, black_pixels);
 
3318
      DBG (DBG_info, "gl843_offset_calibration: avg=%d offset=%d\n", avg,
 
3319
           dev->frontend.offset[1]);
 
3320
 
 
3321
      /* compute new boundaries */
 
3322
      if (topavg == avg)
 
3323
        {
 
3324
          topavg = avg;
 
3325
          top = dev->frontend.offset[1];
 
3326
        }
 
3327
      else
 
3328
        {
 
3329
          bottomavg = avg;
 
3330
          bottom = dev->frontend.offset[1];
 
3331
        }
 
3332
    }
 
3333
  DBG (DBG_info, "gl843_offset_calibration: offset=(%d,%d,%d)\n", dev->frontend.offset[0], dev->frontend.offset[1], dev->frontend.offset[2]);
 
3334
 
 
3335
  /* cleanup before return */
 
3336
  free (first_line);
 
3337
  free (second_line);
 
3338
 
 
3339
  DBGCOMPLETED;
 
3340
  return SANE_STATUS_GOOD;
 
3341
}
 
3342
 
 
3343
 
 
3344
/* alternative coarse gain calibration 
 
3345
   this on uses the settings from offset_calibration and
 
3346
   uses only one scanline
 
3347
 */
 
3348
/*
 
3349
  with offset and coarse calibration we only want to get our input range into
 
3350
  a reasonable shape. the fine calibration of the upper and lower bounds will 
 
3351
  be done with shading.
 
3352
 */
 
3353
static SANE_Status
 
3354
gl843_coarse_gain_calibration (Genesys_Device * dev, int dpi)
 
3355
{
 
3356
  int pixels;
 
3357
  int total_size;
 
3358
  uint8_t *line;
 
3359
  int i, j, channels;
 
3360
  SANE_Status status = SANE_STATUS_GOOD;
 
3361
  int max[3];
 
3362
  float gain[3],coeff;
 
3363
  int val, code, lines;
 
3364
  int resolution;
 
3365
  Genesys_Register_Set *r;
 
3366
  int bpp;
 
3367
 
 
3368
  DBG (DBG_proc, "gl843_coarse_gain_calibration: dpi = %d\n", dpi);
 
3369
 
 
3370
  /* coarse gain calibration is always done in color mode */
 
3371
  channels = 3;
 
3372
  /* follow CKSEL */
 
3373
  if(dev->settings.xres<dev->sensor.optical_res)
 
3374
    {
 
3375
      coeff=0.9;
 
3376
      resolution=dev->sensor.optical_res/2;
 
3377
      resolution=dev->sensor.optical_res;
 
3378
    }
 
3379
  else
 
3380
    {
 
3381
      resolution=dev->sensor.optical_res;
 
3382
      coeff=1.0;
 
3383
    }
 
3384
  lines=10;
 
3385
  bpp=8;
 
3386
  pixels = (dev->sensor.sensor_pixels * resolution) / dev->sensor.optical_res,
 
3387
 
 
3388
  status = gl843_init_scan_regs (dev,
 
3389
                                 dev->calib_reg,
 
3390
                                 resolution,
 
3391
                                 resolution,
 
3392
                                 0,
 
3393
                                 0,
 
3394
                                 pixels,
 
3395
                                 lines,
 
3396
                                 bpp,
 
3397
                                 channels,
 
3398
                                 dev->settings.color_filter,
 
3399
                                 SCAN_FLAG_DISABLE_SHADING |
 
3400
                                 SCAN_FLAG_DISABLE_GAMMA |
 
3401
                                 SCAN_FLAG_SINGLE_LINE |
 
3402
                                 SCAN_FLAG_IGNORE_LINE_DISTANCE);
 
3403
  r = sanei_genesys_get_address (dev->calib_reg, REG02);
 
3404
  r->value &= ~REG02_MTRPWR;
 
3405
 
 
3406
  if (status != SANE_STATUS_GOOD)
 
3407
    {
 
3408
      DBG (DBG_error,
 
3409
           "gl843_coarse_calibration: failed to setup scan: %s\n",
 
3410
           sane_strstatus (status));
 
3411
      return status;
 
3412
    }
 
3413
 
 
3414
  RIE (gl843_bulk_write_register
 
3415
       (dev, dev->calib_reg, GENESYS_GL843_MAX_REGS));
 
3416
 
 
3417
  total_size = pixels * channels * (16/bpp) * lines;
 
3418
 
 
3419
  line = malloc (total_size);
 
3420
  if (!line)
 
3421
    return SANE_STATUS_NO_MEM;
 
3422
 
 
3423
  RIE (gl843_set_fe(dev, AFE_SET));
 
3424
  RIE (gl843_begin_scan (dev, dev->calib_reg, SANE_TRUE));
 
3425
  RIE (sanei_genesys_read_data_from_scanner (dev, line, total_size));
 
3426
 
 
3427
  if (DBG_LEVEL >= DBG_data)
 
3428
    sanei_genesys_write_pnm_file ("coarse.pnm", line, bpp, channels, pixels, lines);
 
3429
 
 
3430
  /* average value on each channel */
 
3431
  for (j = 0; j < channels; j++)
 
3432
    {
 
3433
      max[j] = 0;
 
3434
      for (i = pixels/4; i < (pixels*3/4); i++)
 
3435
        {
 
3436
          if(bpp==16)
 
3437
            {
 
3438
          if (dev->model->is_cis)
 
3439
            val =
 
3440
              line[i * 2 + j * 2 * pixels + 1] * 256 +
 
3441
              line[i * 2 + j * 2 * pixels];
 
3442
          else
 
3443
            val =
 
3444
              line[i * 2 * channels + 2 * j + 1] * 256 +
 
3445
              line[i * 2 * channels + 2 * j];
 
3446
            }
 
3447
          else
 
3448
            {
 
3449
          if (dev->model->is_cis)
 
3450
            val = line[i + j * pixels];
 
3451
          else
 
3452
            val = line[i * channels + j];
 
3453
            }
 
3454
 
 
3455
            max[j] += val;
 
3456
        }
 
3457
      max[j] = max[j] / (pixels/2);
 
3458
 
 
3459
      gain[j] = ((float) dev->sensor.gain_white_ref*coeff) / max[j];
 
3460
 
 
3461
      /* turn logical gain value into gain code, checking for overflow */
 
3462
      code = 283 - 208 / gain[j];
 
3463
      if (code > 255)
 
3464
        code = 255;
 
3465
      else if (code < 0)
 
3466
        code = 0;
 
3467
      dev->frontend.gain[j] = code;
 
3468
 
 
3469
      DBG (DBG_proc,
 
3470
           "gl843_coarse_gain_calibration: channel %d, max=%d, gain = %f, setting:%d\n",
 
3471
           j, max[j], gain[j], dev->frontend.gain[j]);
 
3472
    }
 
3473
 
 
3474
  if (dev->model->is_cis)
 
3475
    {
 
3476
      if (dev->frontend.gain[0] > dev->frontend.gain[1])
 
3477
        dev->frontend.gain[0] = dev->frontend.gain[1];
 
3478
      if (dev->frontend.gain[0] > dev->frontend.gain[2])
 
3479
        dev->frontend.gain[0] = dev->frontend.gain[2];
 
3480
      dev->frontend.gain[2] = dev->frontend.gain[1] = dev->frontend.gain[0];
 
3481
    }
 
3482
 
 
3483
  if (channels == 1)
 
3484
    {
 
3485
      dev->frontend.gain[0] = dev->frontend.gain[1];
 
3486
      dev->frontend.gain[2] = dev->frontend.gain[1];
 
3487
    }
 
3488
 
 
3489
  free (line);
 
3490
 
 
3491
  RIE (gl843_stop_action (dev));
 
3492
 
 
3493
  gl843_slow_back_home (dev, SANE_TRUE);
 
3494
 
 
3495
  DBGCOMPLETED;
 
3496
  return SANE_STATUS_GOOD;
 
3497
}
 
3498
 
 
3499
/*
 
3500
 * wait for lamp warmup by scanning the same line until difference
 
3501
 * between 2 scans is below a threshold
 
3502
 */
 
3503
static SANE_Status
 
3504
gl843_init_regs_for_warmup (Genesys_Device * dev,
 
3505
                            Genesys_Register_Set * reg,
 
3506
                            int *channels, int *total_size)
 
3507
{
 
3508
  int num_pixels;
 
3509
  SANE_Status status = SANE_STATUS_GOOD;
 
3510
  Genesys_Register_Set *r;
 
3511
 
 
3512
  DBGSTART;
 
3513
  if (dev == NULL || reg == NULL || channels == NULL || total_size == NULL)
 
3514
    return SANE_STATUS_INVAL;
 
3515
  
 
3516
  *channels=3;
 
3517
 
 
3518
  memcpy (reg, dev->reg, (GENESYS_GL843_MAX_REGS + 1) * sizeof (Genesys_Register_Set));
 
3519
  status = gl843_init_scan_regs (dev,
 
3520
                                 reg,
 
3521
                                 dev->sensor.optical_res,
 
3522
                                 dev->motor.base_ydpi,
 
3523
                                 dev->sensor.sensor_pixels/4,
 
3524
                                 0,
 
3525
                                 dev->sensor.sensor_pixels/2,
 
3526
                                 1,
 
3527
                                 8,
 
3528
                                 *channels,
 
3529
                                 dev->settings.color_filter,
 
3530
                                 SCAN_FLAG_DISABLE_SHADING |
 
3531
                                 SCAN_FLAG_DISABLE_GAMMA |
 
3532
                                 SCAN_FLAG_SINGLE_LINE |
 
3533
                                 SCAN_FLAG_IGNORE_LINE_DISTANCE);
 
3534
 
 
3535
  if (status != SANE_STATUS_GOOD)
 
3536
    {
 
3537
      DBG (DBG_error,
 
3538
           "gl843_init_regs_for_warmup: failed to setup scan: %s\n",
 
3539
           sane_strstatus (status));
 
3540
      return status;
 
3541
    }
 
3542
 
 
3543
  num_pixels = dev->current_setup.pixels;
 
3544
 
 
3545
  *total_size = num_pixels * 3 * 1;     /* colors * bytes_per_color * scan lines */
 
3546
 
 
3547
  r = sanei_genesys_get_address (reg, REG02);
 
3548
  r->value &= ~REG02_MTRPWR;
 
3549
  RIE (gl843_bulk_write_register (dev, reg, GENESYS_GL843_MAX_REGS));
 
3550
 
 
3551
  DBGCOMPLETED;
 
3552
  return SANE_STATUS_GOOD;
 
3553
}
 
3554
 
 
3555
static SANE_Status
 
3556
gl843_is_compatible_calibration (Genesys_Device * dev,
 
3557
                                 Genesys_Calibration_Cache * cache,
 
3558
                                 int for_overwrite)
 
3559
{
 
3560
#ifdef HAVE_SYS_TIME_H
 
3561
  struct timeval time;
 
3562
#endif
 
3563
  int compatible = 1, resolution;
 
3564
  SANE_Status status;
 
3565
 
 
3566
  DBGSTART;
 
3567
  
 
3568
  if (cache == NULL || for_overwrite)
 
3569
    return SANE_STATUS_UNSUPPORTED;
 
3570
 
 
3571
  status = gl843_calculate_current_setup (dev);
 
3572
  if (status != SANE_STATUS_GOOD)
 
3573
    {
 
3574
      DBG (DBG_error,
 
3575
           "gl843_is_compatible_calibration: failed to calculate current setup: %s\n",
 
3576
           sane_strstatus (status));
 
3577
      return status;
 
3578
    }
 
3579
  resolution=gl843_compute_dpihw(dev,dev->settings.xres);
 
3580
  dev->current_setup.scan_method = dev->settings.scan_method;
 
3581
 
 
3582
  DBG (DBG_proc, "gl843_is_compatible_calibration: checking\n");
 
3583
  
 
3584
  /* a calibration cache is compatible if color mode and x dpi match the user 
 
3585
   * requested scan. In the case of CIS scanners, dpi isn't a criteria */
 
3586
  if (dev->model->is_cis == SANE_FALSE)
 
3587
    {
 
3588
      compatible = (resolution == ((int) cache->used_setup.xres));
 
3589
    }
 
3590
  else
 
3591
    {
 
3592
      compatible = (dev->current_setup.channels == cache->used_setup.channels);
 
3593
    }
 
3594
  if (dev->current_setup.scan_method != cache->used_setup.scan_method)
 
3595
    {
 
3596
      DBG (DBG_io,
 
3597
           "gl843_is_compatible_calibration: current method=%d, used=%d\n",
 
3598
           dev->current_setup.scan_method, cache->used_setup.scan_method);
 
3599
      compatible = 0;
 
3600
    }
 
3601
  if (!compatible)
 
3602
    {
 
3603
      DBG (DBG_proc,
 
3604
           "gl843_is_compatible_calibration: completed, non compatible cache\n");
 
3605
      return SANE_STATUS_UNSUPPORTED;
 
3606
    }
 
3607
 
 
3608
  /* a cache entry expires after 30 minutes for non CIS scanners */
 
3609
#ifdef HAVE_SYS_TIME_H
 
3610
  gettimeofday (&time, NULL);
 
3611
  if ((time.tv_sec - cache->last_calibration > 30 * 60)
 
3612
      && (dev->model->is_cis == SANE_FALSE)
 
3613
      && (dev->settings.scan_method == SCAN_METHOD_FLATBED))
 
3614
    {
 
3615
      DBG (DBG_proc,
 
3616
           "gl843_is_compatible_calibration: expired entry, non compatible cache\n");
 
3617
      return SANE_STATUS_UNSUPPORTED;
 
3618
    }
 
3619
#endif
 
3620
 
 
3621
  DBGCOMPLETED;
 
3622
  return SANE_STATUS_GOOD;
 
3623
}
 
3624
 
 
3625
/** 
 
3626
 * set up GPIO/GPOE for idle state
 
3627
WRITE GPIO[17-21]= GPIO19
 
3628
WRITE GPOE[17-21]= GPOE21 GPOE20 GPOE19 GPOE18
 
3629
genesys_write_register(0xa8,0x3e)
 
3630
GPIO(0xa8)=0x3e
 
3631
 */
 
3632
static SANE_Status
 
3633
gl843_init_gpio (Genesys_Device * dev)
 
3634
{
 
3635
  SANE_Status status = SANE_STATUS_GOOD;
 
3636
  int i;
 
3637
 
 
3638
  DBGSTART;
 
3639
 
 
3640
  RIE (sanei_genesys_write_register (dev, REG6E, dev->gpo.enable[0]));
 
3641
  RIE (sanei_genesys_write_register (dev, REG6F, dev->gpo.enable[1]));
 
3642
  RIE (sanei_genesys_write_register (dev, REG6C, dev->gpo.value[0]));
 
3643
  RIE (sanei_genesys_write_register (dev, REG6D, dev->gpo.value[1]));
 
3644
  if ((strcmp (dev->model->name, "hewlett-packard-scanjet-g4010") == 0)
 
3645
   || (strcmp (dev->model->name, "hewlett-packard-scanjet-g4050") == 0))
 
3646
    {
 
3647
      i = 0;
 
3648
    }
 
3649
  else
 
3650
    {
 
3651
      i = 1;
 
3652
    }
 
3653
  RIE (sanei_genesys_write_register (dev, 0xa6, gpios[i].ra6));
 
3654
  RIE (sanei_genesys_write_register (dev, 0xa7, gpios[i].ra7));
 
3655
  RIE (sanei_genesys_write_register (dev, 0xa8, gpios[i].ra8));
 
3656
  RIE (sanei_genesys_write_register (dev, 0xa9, gpios[i].ra9));
 
3657
 
 
3658
  DBGCOMPLETED;
 
3659
  return status;
 
3660
}
 
3661
 
 
3662
 
 
3663
/* *
 
3664
 * initialize ASIC from power on condition
 
3665
 */
 
3666
static SANE_Status
 
3667
gl843_cold_boot (Genesys_Device * dev)
 
3668
{
 
3669
  SANE_Status status;
 
3670
  uint8_t val;
 
3671
 
 
3672
  DBGSTART;
 
3673
 
 
3674
  RIE (sanei_genesys_write_register (dev, 0x0e, 0x01));
 
3675
  RIE (sanei_genesys_write_register (dev, 0x0e, 0x00));
 
3676
 
 
3677
  /* test CHKVER */
 
3678
  RIE (sanei_genesys_read_register (dev, REG40, &val));
 
3679
  if (val & REG40_CHKVER)
 
3680
    {
 
3681
      RIE (sanei_genesys_read_register (dev, 0x00, &val));
 
3682
      DBG (DBG_info,
 
3683
           "gl843_cold_boot: reported version for genesys chip is 0x%02x\n",
 
3684
           val);
 
3685
    }
 
3686
 
 
3687
  /* Set default values for registers */
 
3688
  gl843_init_registers (dev);
 
3689
 
 
3690
  RIE (sanei_genesys_write_register (dev, REG6B, 0x02));
 
3691
 
 
3692
  /* Write initial registers */
 
3693
  RIE (gl843_bulk_write_register (dev, dev->reg, GENESYS_GL843_MAX_REGS));
 
3694
 
 
3695
  /* Enable DRAM by setting a rising edge on bit 3 of reg 0x0b */
 
3696
  val = dev->reg[reg_0x0b].value & REG0B_DRAMSEL;
 
3697
  val = (val | REG0B_ENBDRAM);
 
3698
  RIE (sanei_genesys_write_register (dev, REG0B, val));
 
3699
  dev->reg[reg_0x0b].value = val;
 
3700
  /* URB    14  control  0x40 0x0c 0x8c 0x10 len     1 wrote 0xb4 */
 
3701
  RIE (write_end_access (dev, 0x10, 0xb4));
 
3702
 
 
3703
  /* set up clock once for all TODO use sensor type for these sensor related registers */
 
3704
  if (strncmp (dev->model->name, "hewlett-packard-scanjet-g40", 27) == 0)
 
3705
    {
 
3706
      /* CK1MAP */
 
3707
      RIE (sanei_genesys_write_register (dev, 0x74, 0x00));
 
3708
      RIE (sanei_genesys_write_register (dev, 0x75, 0x1c));
 
3709
      RIE (sanei_genesys_write_register (dev, 0x76, 0x7f));
 
3710
      /* CK3MAP */
 
3711
      RIE (sanei_genesys_write_register (dev, 0x77, 0x03));
 
3712
      RIE (sanei_genesys_write_register (dev, 0x78, 0xff));
 
3713
      RIE (sanei_genesys_write_register (dev, 0x79, 0xff));
 
3714
    }
 
3715
  else
 
3716
    {
 
3717
      /* CK1MAP */
 
3718
      RIE (sanei_genesys_write_register (dev, 0x74, 0x00));
 
3719
      RIE (sanei_genesys_write_register (dev, 0x75, 0x00));
 
3720
      RIE (sanei_genesys_write_register (dev, 0x76, 0x00));
 
3721
      /* CK3MAP */
 
3722
      RIE (sanei_genesys_write_register (dev, 0x77, 0x00));
 
3723
      RIE (sanei_genesys_write_register (dev, 0x78, 0xff));
 
3724
      RIE (sanei_genesys_write_register (dev, 0x79, 0xff));
 
3725
    }
 
3726
  /* CK4MAP */
 
3727
  RIE (sanei_genesys_write_register (dev, 0x7a, 0x03));
 
3728
  RIE (sanei_genesys_write_register (dev, 0x7b, 0xff));
 
3729
  RIE (sanei_genesys_write_register (dev, 0x7c, 0xff));
 
3730
 
 
3731
  /* CLKSET */
 
3732
  val = (dev->reg[reg_0x0b].value & ~REG0B_CLKSET) | REG0B_48MHZ;
 
3733
  RIE (sanei_genesys_write_register (dev, REG0B, val));
 
3734
  dev->reg[reg_0x0b].value = val;
 
3735
 
 
3736
  /* prevent further writings by bulk write register */
 
3737
  dev->reg[reg_0x0b].address = 0x00;
 
3738
 
 
3739
  /* set up end access */
 
3740
  sanei_genesys_write_register (dev, REGA7, 0x04);
 
3741
  sanei_genesys_write_register (dev, REGA9, 0x00);
 
3742
 
 
3743
  /* set RAM read address */
 
3744
  RIE (sanei_genesys_write_register (dev, REG29, 0x00));
 
3745
  RIE (sanei_genesys_write_register (dev, REG2A, 0x00));
 
3746
  RIE (sanei_genesys_write_register (dev, REG2B, 0x00));
 
3747
 
 
3748
  /* setup gpio */
 
3749
  RIE (gl843_init_gpio (dev));
 
3750
 
 
3751
  DBGCOMPLETED;
 
3752
  return SANE_STATUS_GOOD;
 
3753
}
 
3754
 
 
3755
/* *
 
3756
 * initialize backend and ASIC : registers, motor tables, and gamma tables
 
3757
 * then ensure scanner's head is at home
 
3758
 */
 
3759
#ifndef UNIT_TESTING
 
3760
static
 
3761
#endif
 
3762
SANE_Status
 
3763
gl843_init (Genesys_Device * dev)
 
3764
{
 
3765
  SANE_Status status;
 
3766
  uint8_t val;
 
3767
  SANE_Bool cold = SANE_TRUE;
 
3768
  int size;
 
3769
 
 
3770
  DBG_INIT ();
 
3771
  DBGSTART;
 
3772
 
 
3773
  /* URB    16  control  0xc0 0x0c 0x8e 0x0b len     1 read  0x00 */
 
3774
  status =
 
3775
    sanei_usb_control_msg (dev->dn, REQUEST_TYPE_IN, REQUEST_REGISTER,
 
3776
                           VALUE_GET_REGISTER, 0x0b, 1, &val);
 
3777
  if (status != SANE_STATUS_GOOD)
 
3778
    {
 
3779
      DBG (DBG_error,
 
3780
           "gl843_init: request register failed %s\n",
 
3781
           sane_strstatus (status));
 
3782
      return status;
 
3783
    }
 
3784
  DBG (DBG_io2, "gl843_init: value=0x%02x\n", val);
 
3785
  DBG (DBG_info, "%s: device is %s\n", __FUNCTION__,
 
3786
       (val & 0x08) ? "USB 1.0" : "USB2.0");
 
3787
  if (val & 0x08)
 
3788
    {
 
3789
      /* URB    17  control  0x40 0x0c 0x8c 0x0f len     1 wrote 0x14  */
 
3790
      dev->usb_mode = 1;
 
3791
      val = 0x14;
 
3792
    }
 
3793
  else
 
3794
    {
 
3795
      /* URB    17  control  0x40 0x0c 0x8c 0x0f len     1 wrote 0x11  */
 
3796
      dev->usb_mode = 2;
 
3797
      val = 0x11;
 
3798
    }
 
3799
  RIE (write_end_access (dev, 0x0f, val));
 
3800
 
 
3801
  /* check if the device has already been initialized and powered up 
 
3802
   * we read register 6 and check PWRBIT, if reset scanner has been
 
3803
   * freshly powered up. This bit will be set to later so that following
 
3804
   * reads can detect power down/up cycle*/
 
3805
  RIE (sanei_genesys_read_register (dev, 0x06, &val));
 
3806
  if (val & REG06_PWRBIT)
 
3807
    {
 
3808
      cold = SANE_FALSE;
 
3809
    }
 
3810
  DBG (DBG_info, "%s: device is %s\n", __FUNCTION__, cold ? "cold" : "warm");
 
3811
 
 
3812
  /* don't do anything if backend is initialized and hardware hasn't been
 
3813
   * replug */
 
3814
  if (dev->already_initialized && !cold)
 
3815
    {
 
3816
      DBG (DBG_info, "gl843_init: already initialized, nothing to do\n");
 
3817
      return SANE_STATUS_GOOD;
 
3818
    }
 
3819
 
 
3820
  /* set up hardware and registers */
 
3821
  RIE (gl843_cold_boot (dev));
 
3822
 
 
3823
  /* now hardware part is OK, set up device struct */
 
3824
  FREE_IFNOT_NULL (dev->white_average_data);
 
3825
  FREE_IFNOT_NULL (dev->dark_average_data);
 
3826
  FREE_IFNOT_NULL (dev->sensor.red_gamma_table);
 
3827
  FREE_IFNOT_NULL (dev->sensor.green_gamma_table);
 
3828
  FREE_IFNOT_NULL (dev->sensor.blue_gamma_table);
 
3829
 
 
3830
  dev->settings.color_filter = 0;
 
3831
 
 
3832
  memcpy (dev->calib_reg, dev->reg,
 
3833
          GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set));
 
3834
 
 
3835
  /* Set analog frontend */
 
3836
  RIE (gl843_set_fe (dev, AFE_INIT));
 
3837
 
 
3838
  /* init gamma tables */
 
3839
  size = 256;
 
3840
  if (dev->sensor.red_gamma_table == NULL)
 
3841
    {
 
3842
      dev->sensor.red_gamma_table = (uint16_t *) malloc (2 * size);
 
3843
      if (dev->sensor.red_gamma_table == NULL)
 
3844
        {
 
3845
          DBG (DBG_error,
 
3846
               "gl843_init: could not allocate memory for gamma table\n");
 
3847
          return SANE_STATUS_NO_MEM;
 
3848
        }
 
3849
      sanei_genesys_create_gamma_table (dev->sensor.red_gamma_table, size,
 
3850
                                        65535, 65535, dev->sensor.red_gamma);
 
3851
    }
 
3852
  if (dev->sensor.green_gamma_table == NULL)
 
3853
    {
 
3854
      dev->sensor.green_gamma_table = (uint16_t *) malloc (2 * size);
 
3855
      if (dev->sensor.red_gamma_table == NULL)
 
3856
        {
 
3857
          DBG (DBG_error,
 
3858
               "gl843_init: could not allocate memory for gamma table\n");
 
3859
          return SANE_STATUS_NO_MEM;
 
3860
        }
 
3861
      sanei_genesys_create_gamma_table (dev->sensor.green_gamma_table, size,
 
3862
                                        65535, 65535,
 
3863
                                        dev->sensor.green_gamma);
 
3864
    }
 
3865
  if (dev->sensor.blue_gamma_table == NULL)
 
3866
    {
 
3867
      dev->sensor.blue_gamma_table = (uint16_t *) malloc (2 * size);
 
3868
      if (dev->sensor.red_gamma_table == NULL)
 
3869
        {
 
3870
          DBG (DBG_error,
 
3871
               "gl843_init: could not allocate memory for gamma table\n");
 
3872
          return SANE_STATUS_NO_MEM;
 
3873
        }
 
3874
      sanei_genesys_create_gamma_table (dev->sensor.blue_gamma_table, size,
 
3875
                                        65535, 65535, dev->sensor.blue_gamma);
 
3876
    }
 
3877
 
 
3878
  dev->oe_buffer.buffer = NULL;
 
3879
  dev->already_initialized = SANE_TRUE;
 
3880
 
 
3881
  /* Move home if needed */
 
3882
  RIE (gl843_slow_back_home (dev, SANE_TRUE));
 
3883
  dev->scanhead_position_in_steps = 0;
 
3884
 
 
3885
  /* Set powersaving (default = 15 minutes) */
 
3886
  RIE (gl843_set_powersaving (dev, 15));
 
3887
 
 
3888
  DBGCOMPLETED;
 
3889
  return status;
 
3890
}
 
3891
 
 
3892
static SANE_Status
 
3893
gl843_update_hardware_sensors (Genesys_Scanner * s)
 
3894
{
 
3895
  /* do what is needed to get a new set of events, but try to not lose
 
3896
     any of them.
 
3897
   */
 
3898
  SANE_Status status = SANE_STATUS_GOOD;
 
3899
  uint8_t val;
 
3900
 
 
3901
  RIE (sanei_genesys_read_register (s->dev, REG6D, &val));
 
3902
 
 
3903
  if (s->dev->model->gpo_type == GPO_KVSS080) 
 
3904
    {
 
3905
      if (s->val[OPT_SCAN_SW].b == s->last_val[OPT_SCAN_SW].b)
 
3906
        s->val[OPT_SCAN_SW].b = (val & 0x04) == 0;
 
3907
    }
 
3908
  else
 
3909
    {
 
3910
      if (s->val[OPT_SCAN_SW].b == s->last_val[OPT_SCAN_SW].b)
 
3911
        s->val[OPT_SCAN_SW].b = (val & 0x01) == 0;
 
3912
      if (s->val[OPT_FILE_SW].b == s->last_val[OPT_FILE_SW].b)
 
3913
        s->val[OPT_FILE_SW].b = (val & 0x02) == 0;
 
3914
      if (s->val[OPT_EMAIL_SW].b == s->last_val[OPT_EMAIL_SW].b)
 
3915
        s->val[OPT_EMAIL_SW].b = (val & 0x04) == 0;
 
3916
      if (s->val[OPT_COPY_SW].b == s->last_val[OPT_COPY_SW].b)
 
3917
        s->val[OPT_COPY_SW].b = (val & 0x08) == 0;
 
3918
    }
 
3919
 
 
3920
  return status;
 
3921
}
 
3922
 
 
3923
/** @brief search for a full width black or white strip.
 
3924
 * This function searches for a black or white stripe across the scanning area.
 
3925
 * When searching backward, the searched area must completely be of the desired 
 
3926
 * color since this area will be used for calibration which scans forward.
 
3927
 * @param dev scanner device
 
3928
 * @param forward SANE_TRUE if searching forward, SANE_FALSE if searching backward
 
3929
 * @param black SANE_TRUE if searching for a black strip, SANE_FALSE for a white strip
 
3930
 * @return SANE_STATUS_GOOD if a matching strip is found, SANE_STATUS_UNSUPPORTED if not
 
3931
 */
 
3932
static SANE_Status
 
3933
gl843_search_strip (Genesys_Device * dev, SANE_Bool forward, SANE_Bool black)
 
3934
{
 
3935
  unsigned int pixels, lines, channels;
 
3936
  SANE_Status status;
 
3937
  Genesys_Register_Set local_reg[GENESYS_GL843_MAX_REGS];
 
3938
  size_t size;
 
3939
  uint8_t *data;
 
3940
  int steps, depth, dpi;
 
3941
  unsigned int pass, count, found, x, y;
 
3942
  char title[80];
 
3943
  Genesys_Register_Set *r;
 
3944
 
 
3945
  DBG (DBG_proc, "gl843_search_strip %s %s\n", black ? "black" : "white",
 
3946
       forward ? "forward" : "reverse");
 
3947
 
 
3948
  gl843_set_fe (dev, AFE_SET);
 
3949
  status = gl843_stop_action (dev);
 
3950
  if (status != SANE_STATUS_GOOD)
 
3951
    {
 
3952
      DBG (DBG_error,
 
3953
           "gl843_search_strip: failed to stop: %s\n",
 
3954
           sane_strstatus (status));
 
3955
      return status;
 
3956
    }
 
3957
 
 
3958
  /* set up for a gray scan at lowest dpi */
 
3959
  dpi = 9600;
 
3960
  for (x = 0; x < MAX_RESOLUTIONS; x++)
 
3961
    {
 
3962
      if (dev->model->xdpi_values[x] > 0 && dev->model->xdpi_values[x] < dpi)
 
3963
        dpi = dev->model->xdpi_values[x];
 
3964
    }
 
3965
  channels = 1;
 
3966
  /* 10 MM */
 
3967
  lines = (10 * dpi) / MM_PER_INCH;
 
3968
  /* shading calibation is done with dev->motor.base_ydpi */
 
3969
  lines = (dev->model->shading_lines * dpi) / dev->motor.base_ydpi;
 
3970
  depth = 8;
 
3971
  pixels = (dev->sensor.sensor_pixels * dpi) / dev->sensor.optical_res;
 
3972
  size = pixels * channels * lines * (depth / 8);
 
3973
  data = malloc (size);
 
3974
  if (!data)
 
3975
    {
 
3976
      DBG (DBG_error, "gl843_search_strip: failed to allocate memory\n");
 
3977
      return SANE_STATUS_NO_MEM;
 
3978
    }
 
3979
  dev->scanhead_position_in_steps = 0;
 
3980
 
 
3981
  memcpy (local_reg, dev->reg,
 
3982
          GENESYS_GL843_MAX_REGS * sizeof (Genesys_Register_Set));
 
3983
 
 
3984
  status = gl843_init_scan_regs (dev,
 
3985
                                 local_reg,
 
3986
                                 dpi,
 
3987
                                 dpi,
 
3988
                                 0,
 
3989
                                 0,
 
3990
                                 pixels,
 
3991
                                 lines,
 
3992
                                 depth,
 
3993
                                 channels,
 
3994
                                 0,
 
3995
                                 SCAN_FLAG_DISABLE_SHADING |
 
3996
                                 SCAN_FLAG_DISABLE_GAMMA);
 
3997
  if (status != SANE_STATUS_GOOD)
 
3998
    {
 
3999
      DBG (DBG_error,
 
4000
           "gl843_search_strip: failed to setup for scan: %s\n",
 
4001
           sane_strstatus (status));
 
4002
      return status;
 
4003
    }
 
4004
 
 
4005
  /* set up for reverse or forward */
 
4006
  r = sanei_genesys_get_address (local_reg, REG02);
 
4007
  if (forward)
 
4008
    r->value &= ~REG02_MTRREV;
 
4009
  else
 
4010
    r->value |= REG02_MTRREV;
 
4011
 
 
4012
 
 
4013
  status = gl843_bulk_write_register (dev, local_reg, GENESYS_GL843_MAX_REGS);
 
4014
  if (status != SANE_STATUS_GOOD)
 
4015
    {
 
4016
      DBG (DBG_error,
 
4017
           "gl843_search_strip: failed to bulk write registers: %s\n",
 
4018
           sane_strstatus (status));
 
4019
      return status;
 
4020
    }
 
4021
 
 
4022
  status = gl843_begin_scan (dev, local_reg, SANE_TRUE);
 
4023
  if (status != SANE_STATUS_GOOD)
 
4024
    {
 
4025
      free (data);
 
4026
      DBG (DBG_error,
 
4027
           "gl843_search_strip: failed to begin scan: %s\n",
 
4028
           sane_strstatus (status));
 
4029
      return status;
 
4030
    }
 
4031
 
 
4032
  /* waits for valid data */
 
4033
  do
 
4034
    sanei_genesys_test_buffer_empty (dev, &steps);
 
4035
  while (steps);
 
4036
 
 
4037
  /* now we're on target, we can read data */
 
4038
  status = sanei_genesys_read_data_from_scanner (dev, data, size);
 
4039
  if (status != SANE_STATUS_GOOD)
 
4040
    {
 
4041
      free (data);
 
4042
      DBG (DBG_error,
 
4043
           "gl843_search_start_position: failed to read data: %s\n",
 
4044
           sane_strstatus (status));
 
4045
      return status;
 
4046
    }
 
4047
 
 
4048
  status = gl843_stop_action (dev);
 
4049
  if (status != SANE_STATUS_GOOD)
 
4050
    {
 
4051
      free (data);
 
4052
      DBG (DBG_error, "gl843_search_strip: gl843_stop_action failed\n");
 
4053
      return status;
 
4054
    }
 
4055
 
 
4056
  pass = 0;
 
4057
  if (DBG_LEVEL >= DBG_data)
 
4058
    {
 
4059
      sprintf (title, "search_strip_%s_%s%02d.pnm",
 
4060
               black ? "black" : "white", forward ? "fwd" : "bwd", pass);
 
4061
      sanei_genesys_write_pnm_file (title, data, depth, channels, pixels,
 
4062
                                    lines);
 
4063
    }
 
4064
 
 
4065
  /* loop until strip is found or maximum pass number done */
 
4066
  found = 0;
 
4067
  while (pass < 20 && !found)
 
4068
    {
 
4069
      status =
 
4070
        gl843_bulk_write_register (dev, local_reg, GENESYS_GL843_MAX_REGS);
 
4071
      if (status != SANE_STATUS_GOOD)
 
4072
        {
 
4073
          DBG (DBG_error,
 
4074
               "gl843_search_strip: failed to bulk write registers: %s\n",
 
4075
               sane_strstatus (status));
 
4076
          return status;
 
4077
        }
 
4078
 
 
4079
      /* now start scan */
 
4080
      status = gl843_begin_scan (dev, local_reg, SANE_TRUE);
 
4081
      if (status != SANE_STATUS_GOOD)
 
4082
        {
 
4083
          free (data);
 
4084
          DBG (DBG_error,
 
4085
               "gl843_search_strip: failed to begin scan: %s\n",
 
4086
               sane_strstatus (status));
 
4087
          return status;
 
4088
        }
 
4089
 
 
4090
      /* waits for valid data */
 
4091
      do
 
4092
        sanei_genesys_test_buffer_empty (dev, &steps);
 
4093
      while (steps);
 
4094
 
 
4095
      /* now we're on target, we can read data */
 
4096
      status = sanei_genesys_read_data_from_scanner (dev, data, size);
 
4097
      if (status != SANE_STATUS_GOOD)
 
4098
        {
 
4099
          free (data);
 
4100
          DBG (DBG_error,
 
4101
               "gl843_search_start_position: failed to read data: %s\n",
 
4102
               sane_strstatus (status));
 
4103
          return status;
 
4104
        }
 
4105
 
 
4106
      status = gl843_stop_action (dev);
 
4107
      if (status != SANE_STATUS_GOOD)
 
4108
        {
 
4109
          free (data);
 
4110
          DBG (DBG_error, "gl843_search_strip: gl843_stop_action failed\n");
 
4111
          return status;
 
4112
        }
 
4113
 
 
4114
      if (DBG_LEVEL >= DBG_data)
 
4115
        {
 
4116
          sprintf (title, "search_strip_%s_%s%02d.pnm",
 
4117
                   black ? "black" : "white", forward ? "fwd" : "bwd", pass);
 
4118
          sanei_genesys_write_pnm_file (title, data, depth, channels,
 
4119
                                        pixels, lines);
 
4120
        }
 
4121
 
 
4122
      /* search data to find black strip */
 
4123
      /* when searching forward, we only need one line of the searched color since we
 
4124
       * will scan forward. But when doing backward search, we need all the area of the
 
4125
       * same color */
 
4126
      if (forward)
 
4127
        {
 
4128
          for (y = 0; y < lines && !found; y++)
 
4129
            {
 
4130
              count = 0;
 
4131
              /* count of white/black pixels depending on the color searched */
 
4132
              for (x = 0; x < pixels; x++)
 
4133
                {
 
4134
                  /* when searching for black, detect white pixels */
 
4135
                  if (black && data[y * pixels + x] > 90)
 
4136
                    {
 
4137
                      count++;
 
4138
                    }
 
4139
                  /* when searching for white, detect black pixels */
 
4140
                  if (!black && data[y * pixels + x] < 60)
 
4141
                    {
 
4142
                      count++;
 
4143
                    }
 
4144
                }
 
4145
 
 
4146
              /* at end of line, if count >= 3%, line is not fully of the desired color
 
4147
               * so we must go to next line of the buffer */
 
4148
              /* count*100/pixels < 3 */
 
4149
              if ((count * 100) / pixels < 3)
 
4150
                {
 
4151
                  found = 1;
 
4152
                  DBG (DBG_data,
 
4153
                       "gl843_search_strip: strip found forward during pass %d at line %d\n",
 
4154
                       pass, y);
 
4155
                }
 
4156
              else
 
4157
                {
 
4158
                  DBG (DBG_data,
 
4159
                       "gl843_search_strip: pixels=%d, count=%d (%d%%)\n",
 
4160
                       pixels, count, (100 * count) / pixels);
 
4161
                }
 
4162
            }
 
4163
        }
 
4164
      else                      /* since calibration scans are done forward, we need the whole area
 
4165
                                   to be of the required color when searching backward */
 
4166
        {
 
4167
          count = 0;
 
4168
          for (y = 0; y < lines; y++)
 
4169
            {
 
4170
              /* count of white/black pixels depending on the color searched */
 
4171
              for (x = 0; x < pixels; x++)
 
4172
                {
 
4173
                  /* when searching for black, detect white pixels */
 
4174
                  if (black && data[y * pixels + x] > 90)
 
4175
                    {
 
4176
                      count++;
 
4177
                    }
 
4178
                  /* when searching for white, detect black pixels */
 
4179
                  if (!black && data[y * pixels + x] < 60)
 
4180
                    {
 
4181
                      count++;
 
4182
                    }
 
4183
                }
 
4184
            }
 
4185
 
 
4186
          /* at end of area, if count >= 3%, area is not fully of the desired color
 
4187
           * so we must go to next buffer */
 
4188
          if ((count * 100) / (pixels * lines) < 3)
 
4189
            {
 
4190
              found = 1;
 
4191
              DBG (DBG_data,
 
4192
                   "gl843_search_strip: strip found backward during pass %d \n",
 
4193
                   pass);
 
4194
            }
 
4195
          else
 
4196
            {
 
4197
              DBG (DBG_data,
 
4198
                   "gl843_search_strip: pixels=%d, count=%d (%d%%)\n",
 
4199
                   pixels, count, (100 * count) / pixels);
 
4200
            }
 
4201
        }
 
4202
      pass++;
 
4203
    }
 
4204
  free (data);
 
4205
  if (found)
 
4206
    {
 
4207
      status = SANE_STATUS_GOOD;
 
4208
      DBG (DBG_info, "gl843_search_strip: %s strip found\n",
 
4209
           black ? "black" : "white");
 
4210
    }
 
4211
  else
 
4212
    {
 
4213
      status = SANE_STATUS_UNSUPPORTED;
 
4214
      DBG (DBG_info, "gl843_search_strip: %s strip not found\n",
 
4215
           black ? "black" : "white");
 
4216
    }
 
4217
 
 
4218
  DBG (DBG_proc, "gl843_search_strip: completed\n");
 
4219
  return status;
 
4220
}
 
4221
 
 
4222
/** the gl843 command set */
 
4223
static Genesys_Command_Set gl843_cmd_set = {
 
4224
  "gl843-generic",              /* the name of this set */
 
4225
 
 
4226
  gl843_init,
 
4227
  gl843_init_regs_for_warmup,
 
4228
  gl843_init_regs_for_coarse_calibration,
 
4229
  gl843_init_regs_for_shading,
 
4230
  gl843_init_regs_for_scan,
 
4231
 
 
4232
  gl843_get_filter_bit,
 
4233
  gl843_get_lineart_bit,
 
4234
  gl843_get_bitset_bit,
 
4235
  gl843_get_gain4_bit,
 
4236
  gl843_get_fast_feed_bit,
 
4237
  gl843_test_buffer_empty_bit,
 
4238
  gl843_test_motor_flag_bit,
 
4239
 
 
4240
  gl843_bulk_full_size,
 
4241
 
 
4242
  gl843_set_fe,
 
4243
  gl843_set_powersaving,
 
4244
  gl843_save_power,
 
4245
 
 
4246
  gl843_set_motor_power,
 
4247
  gl843_set_lamp_power,
 
4248
 
 
4249
  gl843_begin_scan,
 
4250
  gl843_end_scan,
 
4251
 
 
4252
  gl843_send_gamma_table,
 
4253
 
 
4254
  gl843_search_start_position,
 
4255
 
 
4256
  gl843_offset_calibration,
 
4257
  gl843_coarse_gain_calibration,
 
4258
  gl843_led_calibration,
 
4259
 
 
4260
  gl843_slow_back_home,
 
4261
 
 
4262
  gl843_bulk_write_register,
 
4263
  gl843_bulk_write_data,
 
4264
  gl843_bulk_read_data,
 
4265
 
 
4266
  gl843_update_hardware_sensors,
 
4267
 
 
4268
  gl843_load_document,
 
4269
  gl843_detect_document_end,
 
4270
  gl843_eject_document,
 
4271
  gl843_search_strip,
 
4272
 
 
4273
  gl843_is_compatible_calibration,
 
4274
  NULL,
 
4275
  NULL /* gl843_send_shading_data */
 
4276
};
 
4277
 
 
4278
SANE_Status
 
4279
sanei_gl843_init_cmd_set (Genesys_Device * dev)
 
4280
{
 
4281
  dev->model->cmd_set = &gl843_cmd_set;
 
4282
  return SANE_STATUS_GOOD;
 
4283
}
 
4284
 
 
4285
/* vim: set sw=2 cino=>2se-1sn-1s{s^-1st0(0u0 smarttab expandtab: */