diff options
Diffstat (limited to 'backend/genesys_gl124.c')
| -rw-r--r-- | backend/genesys_gl124.c | 3997 | 
1 files changed, 0 insertions, 3997 deletions
diff --git a/backend/genesys_gl124.c b/backend/genesys_gl124.c deleted file mode 100644 index a98d3d4..0000000 --- a/backend/genesys_gl124.c +++ /dev/null @@ -1,3997 +0,0 @@ -/* sane - Scanner Access Now Easy. - -   Copyright (C) 2010-2016 Stéphane Voltz <stef.dev@free.fr> - - -   This file is part of the SANE package. - -   This program is free software; you can redistribute it and/or -   modify it under the terms of the GNU General Public License as -   published by the Free Software Foundation; either version 2 of the -   License, or (at your option) any later version. - -   This program is distributed in the hope that it will be useful, but -   WITHOUT ANY WARRANTY; without even the implied warranty of -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU -   General Public License for more details. - -   You should have received a copy of the GNU General Public License -   along with this program; if not, write to the Free Software -   Foundation, Inc., 59 Temple Place - Suite 330, Boston, -   MA 02111-1307, USA. - -   As a special exception, the authors of SANE give permission for -   additional uses of the libraries contained in this release of SANE. - -   The exception is that, if you link a SANE library with other files -   to produce an executable, this does not by itself cause the -   resulting executable to be covered by the GNU General Public -   License.  Your use of that executable is in no way restricted on -   account of linking the SANE library code into it. - -   This exception does not, however, invalidate any other reasons why -   the executable file might be covered by the GNU General Public -   License. - -   If you submit changes to SANE to the maintainers to be included in -   a subsequent release, you agree by submitting the changes that -   those changes may be distributed with this exception intact. - -   If you write modifications of your own for SANE, it is your choice -   whether to permit this exception to apply to your modifications. -   If you do not wish that, delete this exception notice. -*/ - -#undef BACKEND_NAME -#define BACKEND_NAME genesys_gl124 - -#include "genesys_gl124.h" - -/**************************************************************************** - Low level function - ****************************************************************************/ - -/* ------------------------------------------------------------------------ */ -/*                  Read and write RAM, registers and AFE                   */ -/* ------------------------------------------------------------------------ */ - - -/** @brief read scanned data - * Read in 0xeff0 maximum sized blocks. This read is done in 2 - * parts if not multple of 512. First read is rounded to a multiple of 512 bytes, last read fetches the - * remainder. Read addr is always 0x10000000 with the memory layout setup. - * @param dev device to read data from - * @param addr address within ASIC emory space - * @param data pointer where to store the read data - * @param len size to read - */ -static SANE_Status -gl124_bulk_read_data (Genesys_Device * dev, uint8_t addr, -		      uint8_t * data, size_t len) -{ -  SANE_Status status; -  size_t size, target, read, done; -  uint8_t outdata[8], *buffer; - -  DBG (DBG_io, "gl124_bulk_read_data: requesting %lu bytes (unused addr=0x%02x)\n", (u_long) len,addr); - -  if (len == 0) -    return SANE_STATUS_GOOD; - -  target = len; -  buffer = data; - -  /* loop until computed data size is read */ -  while (target) -    { -      if (target > 0xeff0) -	{ -	  size = 0xeff0; -	} -      else -	{ -	  size = target; -	} - -      /* hard coded 0x10000000 addr */ -      outdata[0] = 0; -      outdata[1] = 0; -      outdata[2] = 0; -      outdata[3] = 0x10; - -      /* data size to transfer */ -      outdata[4] = (size & 0xff); -      outdata[5] = ((size >> 8) & 0xff); -      outdata[6] = ((size >> 16) & 0xff); -      outdata[7] = ((size >> 24) & 0xff); - -      status = -	sanei_usb_control_msg (dev->dn, REQUEST_TYPE_OUT, REQUEST_BUFFER, -			       VALUE_BUFFER, 0x00, sizeof (outdata), -			       outdata); -      if (status != SANE_STATUS_GOOD) -	{ -	  DBG (DBG_error, "%s failed while writing command: %s\n", -	       __func__, sane_strstatus (status)); -	  return status; -	} - -      /* blocks must be multiple of 512 but not last block */ -      read = size; -      read /= 512; -      read *= 512; - -      if(read>0) -        { -          DBG (DBG_io2, -               "gl124_bulk_read_data: trying to read %lu bytes of data\n", -               (u_long) read); -          status = sanei_usb_read_bulk (dev->dn, data, &read); -          if (status != SANE_STATUS_GOOD) -            { -              DBG (DBG_error, -                   "gl124_bulk_read_data failed while reading bulk data: %s\n", -                   sane_strstatus (status)); -              return status; -            } -        } - -      /* read less than 512 bytes remainder */ -      if (read < size) -	{ -          done = read; -	  read = size - read; -	  DBG (DBG_io2, -	       "gl124_bulk_read_data: trying to read remaining %lu bytes of data\n", -	       (u_long) read); -	  status = sanei_usb_read_bulk (dev->dn, data+done, &read); -	  if (status != SANE_STATUS_GOOD) -	    { -	      DBG (DBG_error, -		   "gl124_bulk_read_data failed while reading bulk data: %s\n", -		   sane_strstatus (status)); -	      return status; -	    } -	} - -      DBG (DBG_io2, "%s: read %lu bytes, %lu remaining\n", __func__, -	   (u_long) size, (u_long) (target - size)); - -      target -= size; -      data += size; -    } - -  if (DBG_LEVEL >= DBG_data && dev->binary!=NULL) -    { -      fwrite(buffer, len, 1, dev->binary); -    } - -  DBGCOMPLETED; - -  return SANE_STATUS_GOOD; -} - -/**************************************************************************** - Mid level functions - ****************************************************************************/ - -static SANE_Bool -gl124_get_fast_feed_bit (Genesys_Register_Set * regs) -{ -  Genesys_Register_Set *r = NULL; - -  r = sanei_genesys_get_address (regs, REG02); -  if (r && (r->value & REG02_FASTFED)) -    return SANE_TRUE; -  return SANE_FALSE; -} - -static SANE_Bool -gl124_get_filter_bit (Genesys_Register_Set * regs) -{ -  Genesys_Register_Set *r = NULL; - -  r = sanei_genesys_get_address (regs, REG04); -  if (r && (r->value & REG04_FILTER)) -    return SANE_TRUE; -  return SANE_FALSE; -} - -static SANE_Bool -gl124_get_lineart_bit (Genesys_Register_Set * regs) -{ -  Genesys_Register_Set *r = NULL; - -  r = sanei_genesys_get_address (regs, REG04); -  if (r && (r->value & REG04_LINEART)) -    return SANE_TRUE; -  return SANE_FALSE; -} - -static SANE_Bool -gl124_get_bitset_bit (Genesys_Register_Set * regs) -{ -  Genesys_Register_Set *r = NULL; - -  r = sanei_genesys_get_address (regs, REG04); -  if (r && (r->value & REG04_BITSET)) -    return SANE_TRUE; -  return SANE_FALSE; -} - -static SANE_Bool -gl124_get_gain4_bit (Genesys_Register_Set * regs) -{ -  Genesys_Register_Set *r = NULL; - -  r = sanei_genesys_get_address (regs, REG06); -  if (r && (r->value & REG06_GAIN4)) -    return SANE_TRUE; -  return SANE_FALSE; -} - -static SANE_Bool -gl124_test_buffer_empty_bit (SANE_Byte val) -{ -  if (val & BUFEMPTY) -    return SANE_TRUE; -  return SANE_FALSE; -} - -static SANE_Bool -gl124_test_motor_flag_bit (SANE_Byte val) -{ -  if (val & MOTORENB) -    return SANE_TRUE; -  return SANE_FALSE; -} - -/** @brief sensor profile - * search for the database of motor profiles and get the best one. Each - * profile is at a specific dpihw. Use LiDE 110 table by default. - * @param sensor_type sensor id - * @param dpi hardware dpi for the scan - * @param half_ccd flag to signal half ccd mode - * @return a pointer to a Sensor_Profile struct - */ -static Sensor_Profile *get_sensor_profile(int sensor_type, int dpi, int half_ccd) -{ -  unsigned int i; -  int idx; - -  i=0; -  idx=-1; -  while(i<sizeof(sensors)/sizeof(Sensor_Profile)) -    { -      /* exact match */ -      if(sensors[i].sensor_type==sensor_type -         && sensors[i].dpi==dpi -         && sensors[i].half_ccd==half_ccd) -        { -          return &(sensors[i]); -        } - -      /* closest match */ -      if(sensors[i].sensor_type==sensor_type -        && sensors[i].half_ccd==half_ccd) -        { -          if(idx<0) -            { -              idx=i; -            } -          else -            { -              if(sensors[i].dpi>=dpi -              && sensors[i].dpi<sensors[idx].dpi) -                { -                  idx=i; -                } -            } -        } -      i++; -    } - -  /* default fallback */ -  if(idx<0) -    { -      DBG (DBG_warn,"%s: using default sensor profile\n",__func__); -      idx=0; -    } - -  return &(sensors[idx]); -} - - -/* returns the max register bulk size */ -static int -gl124_bulk_full_size (void) -{ -  return GENESYS_GL124_MAX_REGS; -} - -static SANE_Status -gl124_homsnr_gpio(Genesys_Device *dev) -{ -uint8_t val; -SANE_Status status=SANE_STATUS_GOOD; - -  RIE (sanei_genesys_read_register (dev, REG32, &val)); -  val &= ~REG32_GPIO10; -  RIE (sanei_genesys_write_register (dev, REG32, val)); -  return status; -} - -/**@brief compute half ccd mode - * Compute half CCD mode flag. Half CCD is on when dpiset it twice - * the actual scanning resolution. Used for fast scans. - * @param model pointer to device model - * @param xres required horizontal resolution - * @return SANE_TRUE if half CCD mode enabled - */ -static SANE_Bool compute_half_ccd(Genesys_Model *model, int xres) -{ -  /* we have 2 domains for ccd: xres below or above half ccd max dpi */ -  if (xres<=300 && (model->flags & GENESYS_FLAG_HALF_CCD_MODE)) -    { -      return SANE_TRUE; -    } -  return SANE_FALSE; -} - -/** @brief set all registers to default values . - * This function is called only once at the beginning and - * fills register startup values for registers reused across scans. - * Those that are rarely modified or not modified are written - * individually. - * @param dev device structure holding register set to initialize - */ -static void -gl124_init_registers (Genesys_Device * dev) -{ -  DBGSTART; - -  memset (dev->reg, 0, GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set)); - -  /* default to LiDE 110 */ -  SETREG (0x01,0xa2); /* + REG01_SHDAREA */ -  SETREG (0x02,0x90); -  SETREG (0x03,0x50); -  SETREG (0x04,0x03); -  SETREG (0x05,0x00); -  if(dev->model->ccd_type==CIS_CANONLIDE120) -    { -      SETREG (0x06,0x50); -      SETREG (0x07,0x00); -    } -  else -    { -      SETREG (0x03,0x50 & ~REG03_AVEENB); -      SETREG (0x06,0x50 | REG06_GAIN4); -    } -  SETREG (0x09,0x00); -  SETREG (0x0a,0xc0); -  SETREG (0x0b,0x2a); -  SETREG (0x0c,0x12); -  SETREG (0x11,0x00); -  SETREG (0x12,0x00); -  SETREG (0x13,0x0f); -  SETREG (0x14,0x00); -  SETREG (0x15,0x80); -  SETREG (0x16,0x10); -  SETREG (0x17,0x04); -  SETREG (0x18,0x00); -  SETREG (0x19,0x01); -  SETREG (0x1a,0x30); -  SETREG (0x1b,0x00); -  SETREG (0x1c,0x00); -  SETREG (0x1d,0x01); -  SETREG (0x1e,0x10); -  SETREG (0x1f,0x00); -  SETREG (0x20,0x15); -  SETREG (0x21,0x00); -  if(dev->model->ccd_type!=CIS_CANONLIDE120) -    { -      SETREG (0x22,0x02); -    } -  else -    { -      SETREG (0x22,0x14); -    } -  SETREG (0x23,0x00); -  SETREG (0x24,0x00); -  SETREG (0x25,0x00); -  SETREG (0x26,0x0d); -  SETREG (0x27,0x48); -  SETREG (0x28,0x00); -  SETREG (0x29,0x56); -  SETREG (0x2a,0x5e); -  SETREG (0x2b,0x02); -  SETREG (0x2c,0x02); -  SETREG (0x2d,0x58); -  SETREG (0x3b,0x00); -  SETREG (0x3c,0x00); -  SETREG (0x3d,0x00); -  SETREG (0x3e,0x00); -  SETREG (0x3f,0x02); -  SETREG (0x40,0x00); -  SETREG (0x41,0x00); -  SETREG (0x42,0x00); -  SETREG (0x43,0x00); -  SETREG (0x44,0x00); -  SETREG (0x45,0x00); -  SETREG (0x46,0x00); -  SETREG (0x47,0x00); -  SETREG (0x48,0x00); -  SETREG (0x49,0x00); -  SETREG (0x4f,0x00); -  SETREG (0x52,0x00); -  SETREG (0x53,0x02); -  SETREG (0x54,0x04); -  SETREG (0x55,0x06); -  SETREG (0x56,0x04); -  SETREG (0x57,0x04); -  SETREG (0x58,0x04); -  SETREG (0x59,0x04); -  SETREG (0x5a,0x1a); -  SETREG (0x5b,0x00); -  SETREG (0x5c,0xc0); -  SETREG (0x5f,0x00); -  SETREG (0x60,0x02); -  SETREG (0x61,0x00); -  SETREG (0x62,0x00); -  SETREG (0x63,0x00); -  SETREG (0x64,0x00); -  SETREG (0x65,0x00); -  SETREG (0x66,0x00); -  SETREG (0x67,0x00); -  SETREG (0x68,0x00); -  SETREG (0x69,0x00); -  SETREG (0x6a,0x00); -  SETREG (0x6b,0x00); -  SETREG (0x6c,0x00); -  SETREG (0x6e,0x00); -  SETREG (0x6f,0x00); -  if(dev->model->ccd_type!=CIS_CANONLIDE120) -    { -      SETREG (0x6d,0xd0); -      SETREG (0x71,0x08); -    } -  else -    { -      SETREG (0x6d,0x00); -      SETREG (0x71,0x1f); -    } -  SETREG (0x70,0x00); -  SETREG (0x72,0x08); -  SETREG (0x73,0x0a); - -  /* CKxMAP */ -  SETREG (0x74,0x00); -  SETREG (0x75,0x00); -  SETREG (0x76,0x3c); -  SETREG (0x77,0x00); -  SETREG (0x78,0x00); -  SETREG (0x79,0x9f); -  SETREG (0x7a,0x00); -  SETREG (0x7b,0x00); -  SETREG (0x7c,0x55); - -  SETREG (0x7d,0x00); -  SETREG (0x7e,0x08); -  SETREG (0x7f,0x58); -  if(dev->model->ccd_type!=CIS_CANONLIDE120) -    { -      SETREG (0x80,0x00); -      SETREG (0x81,0x14); -    } -  else -    { -      SETREG (0x80,0x00); -      SETREG (0x81,0x10); -    } - -  /* STRPIXEL */ -  SETREG (0x82,0x00); -  SETREG (0x83,0x00); -  SETREG (0x84,0x00); -  /* ENDPIXEL */ -  SETREG (0x85,0x00); -  SETREG (0x86,0x00); -  SETREG (0x87,0x00); - -  SETREG (0x88,0x00); -  SETREG (0x89,0x65); -  SETREG (0x8a,0x00); -  SETREG (0x8b,0x00); -  SETREG (0x8c,0x00); -  SETREG (0x8d,0x00); -  SETREG (0x8e,0x00); -  SETREG (0x8f,0x00); -  SETREG (0x90,0x00); -  SETREG (0x91,0x00); -  SETREG (0x92,0x00); -  SETREG (0x93,0x00); -  SETREG (0x94,0x14); -  SETREG (0x95,0x30); -  SETREG (0x96,0x00); -  SETREG (0x97,0x90); -  SETREG (0x98,0x01); -  SETREG (0x99,0x1f); -  SETREG (0x9a,0x00); -  SETREG (0x9b,0x80); -  SETREG (0x9c,0x80); -  SETREG (0x9d,0x3f); -  SETREG (0x9e,0x00); -  SETREG (0x9f,0x00); -  SETREG (0xa0,0x20); -  SETREG (0xa1,0x30); -  SETREG (0xa2,0x00); -  SETREG (0xa3,0x20); -  SETREG (0xa4,0x01); -  SETREG (0xa5,0x00); -  SETREG (0xa6,0x00); -  SETREG (0xa7,0x08); -  SETREG (0xa8,0x00); -  SETREG (0xa9,0x08); -  SETREG (0xaa,0x01); -  SETREG (0xab,0x00); -  SETREG (0xac,0x00); -  SETREG (0xad,0x40); -  SETREG (0xae,0x01); -  SETREG (0xaf,0x00); -  SETREG (0xb0,0x00); -  SETREG (0xb1,0x40); -  SETREG (0xb2,0x00); -  SETREG (0xb3,0x09); -  SETREG (0xb4,0x5b); -  SETREG (0xb5,0x00); -  SETREG (0xb6,0x10); -  SETREG (0xb7,0x3f); -  SETREG (0xb8,0x00); -  SETREG (0xbb,0x00); -  SETREG (0xbc,0xff); -  SETREG (0xbd,0x00); -  SETREG (0xbe,0x07); -  SETREG (0xc3,0x00); -  SETREG (0xc4,0x00); - -  /* gamma -  SETREG (0xc5,0x00); -  SETREG (0xc6,0x00); -  SETREG (0xc7,0x00); -  SETREG (0xc8,0x00); -  SETREG (0xc9,0x00); -  SETREG (0xca,0x00); -  SETREG (0xcb,0x00); -  SETREG (0xcc,0x00); -  SETREG (0xcd,0x00); -  SETREG (0xce,0x00); -  */ -  if(dev->model->ccd_type==CIS_CANONLIDE120) -    { -      SETREG (0xc5,0x20); -      SETREG (0xc6,0xeb); -      SETREG (0xc7,0x20); -      SETREG (0xc8,0xeb); -      SETREG (0xc9,0x20); -      SETREG (0xca,0xeb); -    } - -  /* memory layout -  SETREG (0xd0,0x0a); -  SETREG (0xd1,0x1f); -  SETREG (0xd2,0x34); */ -  SETREG (0xd3,0x00); -  SETREG (0xd4,0x00); -  SETREG (0xd5,0x00); -  SETREG (0xd6,0x00); -  SETREG (0xd7,0x00); -  SETREG (0xd8,0x00); -  SETREG (0xd9,0x00); - -  /* memory layout -  SETREG (0xe0,0x00); -  SETREG (0xe1,0x48); -  SETREG (0xe2,0x15); -  SETREG (0xe3,0x90); -  SETREG (0xe4,0x15); -  SETREG (0xe5,0x91); -  SETREG (0xe6,0x2a); -  SETREG (0xe7,0xd9); -  SETREG (0xe8,0x2a); -  SETREG (0xe9,0xad); -  SETREG (0xea,0x40); -  SETREG (0xeb,0x22); -  SETREG (0xec,0x40); -  SETREG (0xed,0x23); -  SETREG (0xee,0x55); -  SETREG (0xef,0x6b); -  SETREG (0xf0,0x55); -  SETREG (0xf1,0x6c); -  SETREG (0xf2,0x6a); -  SETREG (0xf3,0xb4); -  SETREG (0xf4,0x6a); -  SETREG (0xf5,0xb5); -  SETREG (0xf6,0x7f); -  SETREG (0xf7,0xfd);*/ - -  SETREG (0xf8,0x01);   /* other value is 0x05 */ -  SETREG (0xf9,0x00); -  SETREG (0xfa,0x00); -  SETREG (0xfb,0x00); -  SETREG (0xfc,0x00); -  SETREG (0xff,0x00); - -  /* fine tune upon device description */ -  dev->reg[reg_0x05].value &= ~REG05_DPIHW; -  switch (dev->sensor.optical_res) -    { -    case 600: -      dev->reg[reg_0x05].value |= REG05_DPIHW_600; -      break; -    case 1200: -      dev->reg[reg_0x05].value |= REG05_DPIHW_1200; -      break; -    case 2400: -      dev->reg[reg_0x05].value |= REG05_DPIHW_2400; -      break; -    case 4800: -      dev->reg[reg_0x05].value |= REG05_DPIHW_4800; -      break; -    } - -  /* initalize calibration reg */ -  memcpy (dev->calib_reg, dev->reg, -	  GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set)); - -  DBGCOMPLETED; -} - -/**@brief send slope table for motor movement - * Send slope_table in machine byte order - * @param dev device to send slope table - * @param table_nr index of the slope table in ASIC memory - * Must be in the [0-4] range. - * @param slope_table pointer to 16 bit values array of the slope table - * @param steps number of elemnts in the slope table - */ -GENESYS_STATIC SANE_Status -gl124_send_slope_table (Genesys_Device * dev, int table_nr, -			uint16_t * slope_table, int steps) -{ -  SANE_Status status; -  uint8_t *table; -  int i; -  char msg[10000]; - -  DBG (DBG_proc, "%s (table_nr = %d, steps = %d)\n", __func__, -       table_nr, steps); - -  /* sanity check */ -  if(table_nr<0 || table_nr>4) -    { -      DBG (DBG_error, "%s: invalid table number %d!\n", __func__, table_nr); -      return SANE_STATUS_INVAL; -    } - -  table = (uint8_t *) malloc (steps * 2); -  for (i = 0; i < steps; i++) -    { -      table[i * 2] = slope_table[i] & 0xff; -      table[i * 2 + 1] = slope_table[i] >> 8; -    } - -  if (DBG_LEVEL >= DBG_io) -    { -      sprintf (msg, "write slope %d (%d)=", table_nr, steps); -      for (i = 0; i < steps; i++) -	{ -	  sprintf (msg+strlen(msg), ",%d", slope_table[i]); -	} -      DBG (DBG_io, "%s: %s\n", __func__, msg); -    } - -  /* slope table addresses are fixed */ -  status = -    sanei_genesys_write_ahb (dev->dn, dev->usb_mode, 0x10000000 + 0x4000 * table_nr, steps * 2, table); -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, -	   "%s: write to AHB failed writing slope table %d (%s)\n", -	   __func__, table_nr, sane_strstatus (status)); -    } - -  free (table); -  DBGCOMPLETED; -  return status; -} - -/** @brief * Set register values of 'special' ti type frontend - * Registers value are taken from the frontend register data - * set. - * @param dev device owning the AFE - * @param set flag AFE_INIT to specify the AFE must be reset before writing data - * */ -static SANE_Status -gl124_set_ti_fe (Genesys_Device * dev, uint8_t set) -{ -  SANE_Status status = SANE_STATUS_GOOD; -  int i; -  uint16_t val; - -  DBGSTART; -  if (set == AFE_INIT) -    { -      DBG (DBG_proc, "%s: setting DAC %u\n", __func__, dev->model->dac_type); - -      /* sets to default values */ -      sanei_genesys_init_fe (dev); -    } - -  /* start writing to DAC */ -  status = sanei_genesys_fe_write_data (dev, 0x00, 0x80); -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, "%s: failed to write reg0: %s\n", __func__, -	   sane_strstatus (status)); -      return status; -    } - -  /* write values to analog frontend */ -  for (i = 1; i < 4; i++) -    { -      val = dev->frontend.reg[i]; -      status = sanei_genesys_fe_write_data (dev, i, val); -      if (status != SANE_STATUS_GOOD) -	{ -	  DBG (DBG_error, -	       "%s: failed to write reg %d: %s\n", __func__, i, -	       sane_strstatus (status)); -	  return status; -	} -    } - -  status = sanei_genesys_fe_write_data (dev, 0x04, 0x00); -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, "%s: failed to write reg4: %s\n", __func__, -	   sane_strstatus (status)); -      return status; -    } - -  /* these are not really sign for this AFE */ -  for (i = 0; i < 3; i++) -    { -      val = dev->frontend.sign[i]; -      status = sanei_genesys_fe_write_data (dev, 0x05 + i, val); -      if (status != SANE_STATUS_GOOD) -	{ -	  DBG (DBG_error, -	       "%s: failed to write reg %d: %s\n", __func__, i+5, -	       sane_strstatus (status)); -	  return status; -	} -    } - -  /* close writing to DAC */ -  if(dev->model->dac_type == DAC_CANONLIDE120) -    { -      status = sanei_genesys_fe_write_data (dev, 0x00, 0x01); -    } -  else -    { -      status = sanei_genesys_fe_write_data (dev, 0x00, 0x11); -    } -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, "%s: failed to write reg0: %s\n", __func__, -	   sane_strstatus (status)); -      return status; -    } - -  DBGCOMPLETED; - -  return status; -} - - -/* Set values of analog frontend */ -static SANE_Status -gl124_set_fe (Genesys_Device * dev, uint8_t set) -{ -  SANE_Status status; -  uint8_t val; - -  DBG (DBG_proc, "gl124_set_fe (%s)\n", -       set == AFE_INIT ? "init" : set == AFE_SET ? "set" : set == -       AFE_POWER_SAVE ? "powersave" : "huh?"); - -  if (set == AFE_INIT) -    { -      DBG (DBG_proc, "gl124_set_fe(): setting DAC %u\n", -	   dev->model->dac_type); -      sanei_genesys_init_fe (dev); -    } - -  RIE (sanei_genesys_read_register (dev, REG0A, &val)); - -  if(dev->usb_mode<0) -    { -      val=3<<REG0AS_SIFSEL; -    } - -  /* route to correct analog FE */ -  switch ((val & REG0A_SIFSEL)>>REG0AS_SIFSEL) -    { -    case 3: -      status=gl124_set_ti_fe (dev, set); -      break; -    case 0: -    case 1: -    case 2: -    default: -      DBG (DBG_error, "%s: unsupported analog FE 0x%02x\n",__func__,val); -      status=SANE_STATUS_INVAL; -      break; -    } - -  DBGCOMPLETED; -  return status; -} - - -/**@brief compute exposure to use - * compute the sensor exposure based on target resolution - * @param dev pointer to  device description - * @param xres sensor's required resolution - * @param half_ccd flag for half ccd mode - */ -static int gl124_compute_exposure(Genesys_Device *dev, int xres, int half_ccd) -{ -  Sensor_Profile *sensor; - -  sensor=get_sensor_profile(dev->model->ccd_type, xres, half_ccd); -  return sensor->exposure; -} - - -static SANE_Status -gl124_init_motor_regs_scan (Genesys_Device * dev, -                            Genesys_Register_Set * reg, -                            unsigned int scan_exposure_time, -			    float scan_yres, -			    int scan_step_type, -			    unsigned int scan_lines, -			    unsigned int scan_dummy, -			    unsigned int feed_steps, -			    int scan_mode, -                            unsigned int flags) -{ -  SANE_Status status; -  int use_fast_fed; -  unsigned int lincnt, fast_dpi; -  uint16_t scan_table[SLOPE_TABLE_SIZE]; -  uint16_t fast_table[SLOPE_TABLE_SIZE]; -  int scan_steps,fast_steps,factor; -  unsigned int feedl,dist; -  Genesys_Register_Set *r; -  uint32_t z1, z2; -  float yres; -  int min_speed; -  unsigned int linesel; - -  DBGSTART; -  DBG (DBG_info, "gl124_init_motor_regs_scan : scan_exposure_time=%d, " -       "scan_yres=%g, scan_step_type=%d, scan_lines=%d, scan_dummy=%d, " -       "feed_steps=%d, scan_mode=%d, flags=%x\n", -       scan_exposure_time, -       scan_yres, -       scan_step_type, -       scan_lines, scan_dummy, feed_steps, scan_mode, flags); - -  /* we never use fast fed since we do manual feed for the scans */ -  use_fast_fed=0; -  factor=1; - -  /* enforce motor minimal scan speed -   * @TODO extend motor struct for this value */ -  if (scan_mode == SCAN_MODE_COLOR) -    { -      min_speed = 900; -    } -  else -    { -      switch(dev->model->motor_type) -        { -          case MOTOR_CANONLIDE110: -	    min_speed = 600; -            break; -          case MOTOR_CANONLIDE120: -            min_speed = 900; -            break; -          default: -            min_speed = 900; -            break; -        } -    } - -  /* compute min_speed and linesel */ -  if(scan_yres<min_speed) -    { -      yres=min_speed; -      linesel=yres/scan_yres-1; -      /* limit case, we need a linesel > 0 */ -      if(linesel==0) -        { -          linesel=1; -          yres=scan_yres*2; -        } -    } -  else -    { -      yres=scan_yres; -      linesel=0; -    } - -  DBG (DBG_io2, "%s: final yres=%f, linesel=%d\n", __func__, yres, linesel); - -  lincnt=scan_lines*(linesel+1); -  sanei_genesys_set_triple(reg,REG_LINCNT,lincnt); -  DBG (DBG_io, "%s: lincnt=%d\n", __func__, lincnt); - -  /* compute register 02 value */ -  r = sanei_genesys_get_address (reg, REG02); -  r->value = REG02_NOTHOME; -  r->value |= REG02_MTRPWR; - -  if (use_fast_fed) -    r->value |= REG02_FASTFED; -  else -    r->value &= ~REG02_FASTFED; - -  if (flags & MOTOR_FLAG_AUTO_GO_HOME) -    r->value |= REG02_AGOHOME; - -  if ((flags & MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE) -    ||(yres>=dev->sensor.optical_res)) -    r->value |= REG02_ACDCDIS; - -  /* SCANFED */ -  sanei_genesys_set_double(reg,REG_SCANFED,4); - -  /* scan and backtracking slope table */ -  sanei_genesys_slope_table(scan_table, -                            &scan_steps, -                            yres, -                            scan_exposure_time, -                            dev->motor.base_ydpi, -                            scan_step_type, -                            factor, -                            dev->model->motor_type, -                            motors); -  RIE(gl124_send_slope_table (dev, SCAN_TABLE, scan_table, scan_steps)); -  RIE(gl124_send_slope_table (dev, BACKTRACK_TABLE, scan_table, scan_steps)); - -  /* STEPNO */ -  sanei_genesys_set_double(reg,REG_STEPNO,scan_steps); - -  /* fast table */ -  fast_dpi=yres; - -  /* -  if (scan_mode != SCAN_MODE_COLOR) -    { -      fast_dpi*=3; -    } -    */ -  sanei_genesys_slope_table(fast_table, -                            &fast_steps, -                            fast_dpi, -                            scan_exposure_time, -                            dev->motor.base_ydpi, -                            scan_step_type, -                            factor, -                            dev->model->motor_type, -                            motors); -  RIE(gl124_send_slope_table (dev, STOP_TABLE, fast_table, fast_steps)); -  RIE(gl124_send_slope_table (dev, FAST_TABLE, fast_table, fast_steps)); - -  /* FASTNO */ -  sanei_genesys_set_double(reg,REG_FASTNO,fast_steps); - -  /* FSHDEC */ -  sanei_genesys_set_double(reg,REG_FSHDEC,fast_steps); - -  /* FMOVNO */ -  sanei_genesys_set_double(reg,REG_FMOVNO,fast_steps); - -  /* substract acceleration distance from feedl */ -  feedl=feed_steps; -  feedl<<=scan_step_type; - -  dist = scan_steps; -  if (flags & MOTOR_FLAG_FEED) -    dist *=2; -  if (use_fast_fed) -    { -        dist += fast_steps*2; -    } -  DBG (DBG_io2, "%s: acceleration distance=%d\n", __func__, dist); - -  /* get sure we don't use insane value */ -  if(dist<feedl) -    feedl -= dist; -  else -    feedl = 0; - -  sanei_genesys_set_triple(reg,REG_FEEDL,feedl); -  DBG (DBG_io, "%s: feedl=%d\n", __func__, feedl); - -  /* doesn't seem to matter that much */ -  sanei_genesys_calculate_zmode2 (use_fast_fed, -				  scan_exposure_time, -				  scan_table, -				  scan_steps, -				  feedl, -                                  scan_steps, -                                  &z1, -                                  &z2); - -  sanei_genesys_set_triple(reg,REG_Z1MOD,z1); -  DBG (DBG_info, "gl124_init_motor_regs_scan: z1 = %d\n", z1); - -  sanei_genesys_set_triple(reg,REG_Z2MOD,z2); -  DBG (DBG_info, "gl124_init_motor_regs_scan: z2 = %d\n", z2); - -  /* LINESEL */ -  r = sanei_genesys_get_address (reg, REG1D); -  r->value = (r->value & ~REG1D_LINESEL) | linesel; - -  r = sanei_genesys_get_address (reg, REGA0); -  r->value = (scan_step_type << REGA0S_STEPSEL) | (scan_step_type << REGA0S_FSTPSEL); - -  /* FMOVDEC */ -  sanei_genesys_set_double(reg,REG_FMOVDEC,fast_steps); - -  DBGCOMPLETED; -  return SANE_STATUS_GOOD; -} - - -/** @brief copy sensor specific settings - * Set up register set for the given sensor resolution. Values are from the device table - * in genesys_devices.c for registers: - *       [0x16 ... 0x1d] - *       [0x52 ... 0x5e] - * Other come from the specific device sensor table in genesys_gl124.h: - *      0x18, 0x20, 0x61, 0x98 and - * @param dev device to set up - * @param regs register set to modify - * @param dpi resolution of the sensor during scan - * @param half_ccd flag for half ccd mode - * */ -static void -gl124_setup_sensor (Genesys_Device * dev, Genesys_Register_Set * regs, int dpi, int half_ccd) -{ -  Genesys_Register_Set *r; -  int i; -  Sensor_Profile *sensor; -  int dpihw; -  uint32_t exp; - -  DBGSTART; - -  /* we start at 6, 0-5 is a 16 bits cache for exposure */ -  for (i = 0x06; i < 0x0e; i++) -    { -      r = sanei_genesys_get_address (regs, 0x10 + i); -      if (r) -	{ -	  r->value = dev->sensor.regs_0x10_0x1d[i]; -	} -    } - -  /* skip writing 5d,5e which is AFE address because -   * they are not deifned in register set */ -  for (i = 0; i < 11; i++) -    { -      r = sanei_genesys_get_address (regs, 0x52 + i); -      if (r) -	{ -	  r->value = dev->sensor.regs_0x52_0x5e[i]; -	} -    } - -  /* set EXPDUMMY and CKxMAP */ -  dpihw=sanei_genesys_compute_dpihw(dev,dpi); -  sensor=get_sensor_profile(dev->model->ccd_type, dpihw, half_ccd); - -  r = sanei_genesys_get_address (regs, 0x18); -  if (r) -    { -      r->value = sensor->reg18; -    } -  r = sanei_genesys_get_address (regs, 0x20); -  if (r) -    { -      r->value = sensor->reg20; -    } -  r = sanei_genesys_get_address (regs, 0x61); -  if (r) -    { -      r->value = sensor->reg61; -    } -  r = sanei_genesys_get_address (regs, 0x98); -  if (r) -    { -      r->value = sensor->reg98; -    } - -  if(sensor->reg16!=0) -    { -      r = sanei_genesys_get_address (regs, 0x16); -      if (r) -	{ -	  r->value = sensor->reg16; -	} -    } -  if(sensor->reg70!=0) -    { -      r = sanei_genesys_get_address (regs, 0x70); -      if (r) -	{ -	  r->value = sensor->reg70; -	} -    } - -  sanei_genesys_set_triple(regs,REG_SEGCNT,sensor->segcnt); -  sanei_genesys_set_double(regs,REG_TG0CNT,sensor->tg0cnt); -  sanei_genesys_set_double(regs,REG_EXPDMY,sensor->expdummy); - -  /* if no calibration has been done, set default values for exposures */ -  exp=dev->sensor.regs_0x10_0x1d[0]*256+dev->sensor.regs_0x10_0x1d[1]; -  if(exp==0) -    { -      exp=sensor->expr; -    } -  sanei_genesys_set_triple(regs,REG_EXPR,exp); - -  exp=dev->sensor.regs_0x10_0x1d[2]*256+dev->sensor.regs_0x10_0x1d[3]; -  if(exp==0) -    { -      exp=sensor->expg; -    } -  sanei_genesys_set_triple(regs,REG_EXPG,exp); - -  exp=dev->sensor.regs_0x10_0x1d[4]*256+dev->sensor.regs_0x10_0x1d[5]; -  if(exp==0) -    { -      exp=sensor->expb; -    } -  sanei_genesys_set_triple(regs,REG_EXPB,exp); - -  sanei_genesys_set_triple(regs,REG_CK1MAP,sensor->ck1map); -  sanei_genesys_set_triple(regs,REG_CK3MAP,sensor->ck3map); -  sanei_genesys_set_triple(regs,REG_CK4MAP,sensor->ck4map); - -  /* order of the sub-segments */ -  dev->order=sensor->order; - -  DBGCOMPLETED; -} - -/** @brief setup optical related registers - * start and pixels are expressed in optical sensor resolution coordinate - * space. - * @param dev scanner device to use - * @param reg registers to set up - * @param exposure_time exposure time to use - * @param used_res scanning resolution used, may differ from - *        scan's one - * @param start logical start pixel coordinate - * @param pixels logical number of pixels to use - * @param channels number of color channels (currently 1 or 3) - * @param depth bit depth of the scan (1, 8 or 16) - * @param half_ccd SANE_TRUE if sensor's timings are such that x coordinates - *           must be halved - * @param color_filter color channel to use as gray data - * @param flags optical flags (@see ) - * @return SANE_STATUS_GOOD if OK - */ -static SANE_Status -gl124_init_optical_regs_scan (Genesys_Device * dev, -			      Genesys_Register_Set * reg, -			      unsigned int exposure_time, -			      int used_res, -			      unsigned int start, -			      unsigned int pixels, -			      int channels, -			      int depth, -			      SANE_Bool half_ccd, -                              int color_filter, -                              int flags) -{ -  unsigned int words_per_line, segcnt; -  unsigned int startx, endx, used_pixels, segnb; -  unsigned int dpiset, cksel, dpihw, factor; -  unsigned int bytes; -  Genesys_Register_Set *r; -  SANE_Status status; -  uint32_t expmax, exp; - -  DBG (DBG_proc, "%s :  exposure_time=%d, " -       "used_res=%d, start=%d, pixels=%d, channels=%d, depth=%d, " -       "half_ccd=%d, flags=%x\n", __func__, exposure_time, -       used_res, start, pixels, channels, depth, half_ccd, flags); - -  /* resolution is divided according to CKSEL */ -  r = sanei_genesys_get_address (reg, REG18); -  cksel= (r->value & REG18_CKSEL)+1; -  DBG (DBG_io2, "%s: cksel=%d\n", __func__, cksel); - -  /* to manage high resolution device while keeping good -   * low resolution scanning speed, we make hardware dpi vary */ -  dpihw=sanei_genesys_compute_dpihw(dev, used_res * cksel); -  factor=dev->sensor.optical_res/dpihw; -  DBG (DBG_io2, "%s: dpihw=%d (factor=%d)\n", __func__, dpihw, factor); - -  /* sensor parameters */ -  gl124_setup_sensor (dev, reg, dpihw, half_ccd); -  dpiset = used_res * cksel; - -  /* start and end coordinate in optical dpi coordinates */ -  /* startx = start/cksel + dev->sensor.dummy_pixel; XXX STEF XXX */ -  startx = start/cksel; -  used_pixels=pixels/cksel; -  endx = startx + used_pixels; - -  /* pixel coordinate factor correction when used dpihw is not maximal one */ -  startx/=factor; -  endx/=factor; -  used_pixels=endx-startx; - -  status = gl124_set_fe (dev, AFE_SET); -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, "%s: failed to set frontend: %s\n", __func__, -	   sane_strstatus (status)); -      return status; -    } - -  /* enable shading */ -  r = sanei_genesys_get_address (reg, REG01); -  r->value &= ~REG01_SCAN; -  if ((flags & OPTICAL_FLAG_DISABLE_SHADING) || -      (dev->model->flags & GENESYS_FLAG_NO_CALIBRATION)) -    { -      r->value &= ~REG01_DVDSET; -    } -  else -    { -      r->value |= REG01_DVDSET; -    } -  r->value &= ~REG01_SCAN; - -  r = sanei_genesys_get_address (reg, REG03); -  if((dev->model->ccd_type!=CIS_CANONLIDE120)&&(used_res>=600)) -    { -      r->value &= ~REG03_AVEENB; -      DBG (DBG_io, "%s: disabling AVEENB\n", __func__); -    } -  else -    { -      r->value |= ~REG03_AVEENB; -      DBG (DBG_io, "%s: enabling AVEENB\n", __func__); -    } - -  if (flags & OPTICAL_FLAG_DISABLE_LAMP) -    r->value &= ~REG03_LAMPPWR; -  else -    r->value |= REG03_LAMPPWR; - -  /* BW threshold */ -  RIE (sanei_genesys_write_register (dev, REG114, dev->settings.threshold)); -  RIE (sanei_genesys_write_register (dev, REG115, dev->settings.threshold)); - -  /* monochrome / color scan */ -  r = sanei_genesys_get_address (reg, REG04); -  switch (depth) -    { -    case 1: -      r->value &= ~REG04_BITSET; -      r->value |= REG04_LINEART; -      break; -    case 8: -      r->value &= ~(REG04_LINEART | REG04_BITSET); -      break; -    case 16: -      r->value &= ~REG04_LINEART; -      r->value |= REG04_BITSET; -      break; -    } - -  r->value &= ~REG04_FILTER; -  if (channels == 1) -    { -      switch (color_filter) -	{ -	case 0: -	  r->value |= 0x10;        /* red filter */ -	  break; -	case 2: -	  r->value |= 0x30;        /* blue filter */ -	  break; -	default: -	  r->value |= 0x20;        /* green filter */ -	  break; -	} -    } - -  /* register 05 */ -  r = sanei_genesys_get_address (reg, REG05); - -  /* set up dpihw */ -  r->value &= ~REG05_DPIHW; -  switch(dpihw) -    { -      case 600: -        r->value |= REG05_DPIHW_600; -        break; -      case 1200: -        r->value |= REG05_DPIHW_1200; -        break; -      case 2400: -        r->value |= REG05_DPIHW_2400; -        break; -      case 4800: -        r->value |= REG05_DPIHW_4800; -        break; -    } - -  /* enable gamma tables */ -  if (flags & OPTICAL_FLAG_DISABLE_GAMMA) -    r->value &= ~REG05_GMMENB; -  else -    r->value |= REG05_GMMENB; - -  if(half_ccd) -    { -      sanei_genesys_set_double(reg,REG_DPISET,dpiset*2); -      DBG (DBG_io2, "%s: dpiset used=%d\n", __func__, dpiset*2); -    } -  else -    { -      sanei_genesys_set_double(reg,REG_DPISET,dpiset); -      DBG (DBG_io2, "%s: dpiset used=%d\n", __func__, dpiset); -    } - -  r = sanei_genesys_get_address (reg, REG06); -  r->value |= REG06_GAIN4; - -  /* CIS scanners can do true gray by setting LEDADD */ -  /* we set up LEDADD only when asked */ -  if (dev->model->is_cis == SANE_TRUE) -    { -      r = sanei_genesys_get_address (reg, REG60); -      r->value &= ~REG60_LEDADD; -      if (channels == 1 && (flags & OPTICAL_FLAG_ENABLE_LEDADD)) -	{ -	  r->value |= REG60_LEDADD; -          sanei_genesys_get_triple(reg,REG_EXPR,&expmax); -          sanei_genesys_get_triple(reg,REG_EXPG,&exp); -          if(exp>expmax) -            { -              expmax=exp; -            } -          sanei_genesys_get_triple(reg,REG_EXPB,&exp); -          if(exp>expmax) -            { -              expmax=exp; -            } -          sanei_genesys_set_triple(dev->reg,REG_EXPR,expmax); -          sanei_genesys_set_triple(dev->reg,REG_EXPG,expmax); -          sanei_genesys_set_triple(dev->reg,REG_EXPB,expmax); -	} -      /* RGB weighting, REG_TRUER,G and B are to be set  */ -      r = sanei_genesys_get_address (reg, 0x01); -      r->value &= ~REG01_TRUEGRAY; -      if (channels == 1 && (flags & OPTICAL_FLAG_ENABLE_LEDADD)) -	{ -	  r->value |= REG01_TRUEGRAY; -          sanei_genesys_write_register (dev, REG_TRUER, 0x80); -          sanei_genesys_write_register (dev, REG_TRUEG, 0x80); -          sanei_genesys_write_register (dev, REG_TRUEB, 0x80); -	} -    } - -  /* segment number */ -  r = sanei_genesys_get_address (reg, 0x98); -  segnb = r->value & 0x0f; - -  sanei_genesys_set_triple(reg,REG_STRPIXEL,startx/segnb); -  DBG (DBG_io2, "%s: strpixel used=%d\n", __func__, startx/segnb); -  sanei_genesys_get_triple(reg,REG_SEGCNT,&segcnt); -  if(endx/segnb==segcnt) -    { -      endx=0; -    } -  sanei_genesys_set_triple(reg,REG_ENDPIXEL,endx/segnb); -  DBG (DBG_io2, "%s: endpixel used=%d\n", __func__, endx/segnb); - -  /* words(16bit) before gamma, conversion to 8 bit or lineart */ -  words_per_line = (used_pixels * dpiset) / dpihw; -  bytes = depth / 8; -  if (depth == 1) -    { -      words_per_line = (words_per_line >> 3) + ((words_per_line & 7) ? 1 : 0); -    } -  else -    { -      words_per_line *= bytes; -    } - -  dev->bpl = words_per_line; -  dev->cur = 0; -  dev->skip = 0; -  dev->len = dev->bpl/segnb; -  dev->dist = dev->bpl/segnb; -  dev->segnb = segnb; -  dev->line_count = 0; -  dev->line_interp = 0; - -  DBG (DBG_io2, "%s: used_pixels     =%d\n", __func__, used_pixels); -  DBG (DBG_io2, "%s: pixels          =%d\n", __func__, pixels); -  DBG (DBG_io2, "%s: depth           =%d\n", __func__, depth); -  DBG (DBG_io2, "%s: dev->bpl        =%lu\n", __func__, (unsigned long)dev->bpl); -  DBG (DBG_io2, "%s: dev->len        =%lu\n", __func__, (unsigned long)dev->len); -  DBG (DBG_io2, "%s: dev->dist       =%lu\n", __func__, (unsigned long)dev->dist); -  DBG (DBG_io2, "%s: dev->line_interp=%lu\n", __func__, (unsigned long)dev->line_interp); - -  words_per_line *= channels; -  dev->wpl = words_per_line; - -  /* allocate buffer for odd/even pixels handling */ -  if(dev->oe_buffer.buffer!=NULL) -    { -      sanei_genesys_buffer_free (&(dev->oe_buffer)); -    } -  RIE (sanei_genesys_buffer_alloc (&(dev->oe_buffer), dev->wpl)); - -  /* MAXWD is expressed in 2 words unit */ -  sanei_genesys_set_triple(reg,REG_MAXWD,(words_per_line)); -  DBG (DBG_io2, "%s: words_per_line used=%d\n", __func__, words_per_line); - -  sanei_genesys_set_triple(reg,REG_LPERIOD,exposure_time); -  DBG (DBG_io2, "%s: exposure_time used=%d\n", __func__, exposure_time); - -  sanei_genesys_set_double(reg,REG_DUMMY,dev->sensor.dummy_pixel); - -  DBGCOMPLETED; -  return SANE_STATUS_GOOD; -} - -/** set up registers for an actual scan - * - * this function sets up the scanner to scan in normal or single line mode - */ -GENESYS_STATIC -SANE_Status -gl124_init_scan_regs (Genesys_Device * dev, -                      Genesys_Register_Set * reg, -		      float xres,        /*dpi */ -		      float yres,        /*dpi */ -		      float startx,        /*optical_res, from dummy_pixel+1 */ -		      float starty,        /*base_ydpi, from home! */ -		      float pixels, -		      float lines, -		      unsigned int depth, -		      unsigned int channels, -		      __sane_unused__ int scan_method, -                      int scan_mode, -		      int color_filter, -                      unsigned int flags) -{ -  int used_res; -  int start, used_pixels; -  int bytes_per_line; -  int move; -  unsigned int lincnt; -  unsigned int oflags, mflags; /**> optical and motor flags */ -  int exposure_time; -  int stagger; - -  int dummy = 0; -  int slope_dpi = 0; -  int scan_step_type = 1; -  int max_shift; -  size_t requested_buffer_size, read_buffer_size; - -  SANE_Bool half_ccd;                /* false: full CCD res is used, true, half max CCD res is used */ -  int optical_res; -  SANE_Status status; - -  DBG (DBG_info, -       "gl124_init_scan_regs settings:\n" -       "Resolution    : %gDPI/%gDPI\n" -       "Lines         : %g\n" -       "PPL           : %g\n" -       "Startpos      : %g/%g\n" -       "Depth/Channels: %u/%u\n" -       "Flags         : %x\n\n", -       xres, yres, lines, pixels, startx, starty, depth, channels, flags); - -  half_ccd=compute_half_ccd(dev->model, xres); - -  /* optical_res */ -  optical_res = dev->sensor.optical_res; -  if (half_ccd) -    optical_res /= 2; -  DBG (DBG_info, "%s: optical_res=%d\n", __func__, optical_res); - -  /* stagger */ -  if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE)) -    stagger = (4 * yres) / dev->motor.base_ydpi; -  else -    stagger = 0; -  DBG (DBG_info, "gl124_init_scan_regs : stagger=%d lines\n", stagger); - -  /** @brief compute used resolution */ -  if (flags & SCAN_FLAG_USE_OPTICAL_RES) -    { -      used_res = optical_res; -    } -  else -    { -      /* resolution is choosen from a fixed list and can be used directly, -       * unless we have ydpi higher than sensor's maximum one */ -      if(xres>optical_res) -        used_res=optical_res; -      else -        used_res = xres; -    } - -  /* compute scan parameters values */ -  /* pixels are allways given at full optical resolution */ -  /* use detected left margin and fixed value */ -  /* start */ -  /* add x coordinates */ -  start = startx; - -  if (stagger > 0) -    start |= 1; - -  /* compute correct pixels number */ -  used_pixels = (pixels * optical_res) / xres; -  DBG (DBG_info, "%s: used_pixels=%d\n", __func__, used_pixels); - -  /* round up pixels number if needed */ -  if (used_pixels * xres < pixels * optical_res) -    used_pixels++; - -  /* we want even number of pixels here */ -  if(used_pixels & 1) -    used_pixels++; - -  /* slope_dpi */ -  /* cis color scan is effectively a gray scan with 3 gray lines per color line and a FILTER of 0 */ -  if (dev->model->is_cis) -    slope_dpi = yres * channels; -  else -    slope_dpi = yres; - -  /* scan_step_type */ -  if(flags & SCAN_FLAG_FEEDING) -    { -      scan_step_type=0; -      exposure_time=MOVE_EXPOSURE; -    } -  else -    { -      exposure_time = gl124_compute_exposure (dev, used_res, half_ccd); -      scan_step_type = sanei_genesys_compute_step_type(motors, dev->model->motor_type, exposure_time); -    } - -  DBG (DBG_info, "gl124_init_scan_regs : exposure_time=%d pixels\n", exposure_time); -  DBG (DBG_info, "gl124_init_scan_regs : scan_step_type=%d\n", scan_step_type); - -  /*** optical parameters ***/ -  /* in case of dynamic lineart, we use an internal 8 bit gray scan -   * to generate 1 lineart data */ -  if ((flags & SCAN_FLAG_DYNAMIC_LINEART) && (scan_mode == SCAN_MODE_LINEART)) -    { -      depth = 8; -    } - -  /* we enable true gray for cis scanners only, and just when doing -   * scan since color calibration is OK for this mode -   */ -  oflags = 0; -  if (flags & SCAN_FLAG_DISABLE_SHADING) -    oflags |= OPTICAL_FLAG_DISABLE_SHADING; -  if (flags & SCAN_FLAG_DISABLE_GAMMA) -    oflags |= OPTICAL_FLAG_DISABLE_GAMMA; -  if (flags & SCAN_FLAG_DISABLE_LAMP) -    oflags |= OPTICAL_FLAG_DISABLE_LAMP; -  if (flags & SCAN_FLAG_CALIBRATION) -    oflags |= OPTICAL_FLAG_DISABLE_DOUBLE; - -  if (dev->model->is_cis && dev->settings.true_gray) -    { -      oflags |= OPTICAL_FLAG_ENABLE_LEDADD; -    } - -  /* now _LOGICAL_ optical values used are known, setup registers */ -  status = gl124_init_optical_regs_scan (dev, -					 reg, -					 exposure_time, -					 used_res, -					 start, -					 used_pixels, -					 channels, -					 depth, -					 half_ccd, -                                         color_filter, -                                         oflags); -  if (status != SANE_STATUS_GOOD) -    return status; - -  /*** motor parameters ***/ - -  /* max_shift */ -  max_shift=sanei_genesys_compute_max_shift(dev,channels,yres,flags); - -  /* lines to scan */ -  lincnt = lines + max_shift + stagger; - -  /* add tl_y to base movement */ -  move = starty; -  DBG (DBG_info, "gl124_init_scan_regs: move=%d steps\n", move); - -  mflags=0; -  if(flags & SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE) -    mflags|=MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE; -  if(flags & SCAN_FLAG_FEEDING) -    mflags|=MOTOR_FLAG_FEED; - -    status = gl124_init_motor_regs_scan (dev, -					 reg, -					 exposure_time, -					 slope_dpi, -					 scan_step_type, -					 dev->model->is_cis ? lincnt * channels : lincnt, -					 dummy, -					 move, -					 scan_mode, -					 mflags); -  if (status != SANE_STATUS_GOOD) -    return status; - -  /*** prepares data reordering ***/ - -  /* words_per_line */ -  bytes_per_line = (used_pixels * used_res) / optical_res; -  bytes_per_line = (bytes_per_line * channels * depth) / 8; - -  /* since we don't have sheetfed scanners to handle, -   * use huge read buffer */ -  /* TODO find the best size according to settings */ -  requested_buffer_size = 16 * bytes_per_line; - -  read_buffer_size = -    2 * requested_buffer_size + -    ((max_shift + stagger) * used_pixels * channels * depth) / 8; - -  RIE (sanei_genesys_buffer_free (&(dev->read_buffer))); -  RIE (sanei_genesys_buffer_alloc (&(dev->read_buffer), read_buffer_size)); - -  RIE (sanei_genesys_buffer_free (&(dev->lines_buffer))); -  RIE (sanei_genesys_buffer_alloc (&(dev->lines_buffer), read_buffer_size)); - -  RIE (sanei_genesys_buffer_free (&(dev->shrink_buffer))); -  RIE (sanei_genesys_buffer_alloc (&(dev->shrink_buffer), -				   requested_buffer_size)); - -  RIE (sanei_genesys_buffer_free (&(dev->out_buffer))); -  RIE (sanei_genesys_buffer_alloc (&(dev->out_buffer), -				   (8 * dev->settings.pixels * channels * -				    depth) / 8)); - - -  dev->read_bytes_left = bytes_per_line * lincnt; - -  DBG (DBG_info, -       "gl124_init_scan_regs: physical bytes to read = %lu\n", -       (u_long) dev->read_bytes_left); -  dev->read_active = SANE_TRUE; - - -  dev->current_setup.pixels = (used_pixels * used_res) / optical_res; -  DBG (DBG_info, "%s: current_setup.pixels=%d\n", __func__, dev->current_setup.pixels); -  dev->current_setup.lines = lincnt; -  dev->current_setup.depth = depth; -  dev->current_setup.channels = channels; -  dev->current_setup.exposure_time = exposure_time; -  dev->current_setup.xres = used_res; -  dev->current_setup.yres = yres; -  dev->current_setup.half_ccd = half_ccd; -  dev->current_setup.stagger = stagger; -  dev->current_setup.max_shift = max_shift + stagger; - -  dev->total_bytes_read = 0; -  if (depth == 1) -    dev->total_bytes_to_read = -      ((dev->settings.pixels * dev->settings.lines) / 8 + -       (((dev->settings.pixels * dev->settings.lines) % 8) ? 1 : 0)) * -      channels; -  else -    dev->total_bytes_to_read = -      dev->settings.pixels * dev->settings.lines * channels * (depth / 8); - -  DBG (DBG_info, "gl124_init_scan_regs: total bytes to send = %lu\n", -       (u_long) dev->total_bytes_to_read); - -  DBGCOMPLETED; -  return SANE_STATUS_GOOD; -} - -static SANE_Status -gl124_calculate_current_setup (Genesys_Device * dev) -{ -  int channels; -  int depth; -  int start; - -  float xres;                        /*dpi */ -  float yres;                        /*dpi */ -  float startx;                        /*optical_res, from dummy_pixel+1 */ -  float pixels; -  float lines; - -  int used_res; -  int used_pixels; -  unsigned int lincnt; -  int exposure_time; -  int stagger; -  SANE_Bool half_ccd; - -  int max_shift, dpihw; -  Sensor_Profile *sensor; - -  int optical_res; - -  DBG (DBG_info, -       "gl124_calculate_current_setup settings:\n" -       "Resolution: %ux%uDPI\n" -       "Lines     : %u\n" -       "PPL       : %u\n" -       "Startpos  : %.3f/%.3f\n" -       "Scan mode : %d\n\n", -       dev->settings.xres, -       dev->settings.yres, dev->settings.lines, dev->settings.pixels, -       dev->settings.tl_x, dev->settings.tl_y, dev->settings.scan_mode); - -  /* channels */ -  if (dev->settings.scan_mode == 4)        /* single pass color */ -    channels = 3; -  else -    channels = 1; - -  /* depth */ -  depth = dev->settings.depth; -  if (dev->settings.scan_mode == 0) -    depth = 1; - -  /* start */ -  start = SANE_UNFIX (dev->model->x_offset); -  start += dev->settings.tl_x; -  start = (start * dev->sensor.optical_res) / MM_PER_INCH; - - -  xres = dev->settings.xres; -  yres = dev->settings.yres; -  startx = start; -  pixels = dev->settings.pixels; -  lines = dev->settings.lines; - -  half_ccd=compute_half_ccd(dev->model, xres); - -  DBG (DBG_info, -       "gl124_calculate_current_setup settings:\n" -       "Resolution    : %gDPI/%gDPI\n" -       "Lines         : %g\n" -       "PPL           : %g\n" -       "Startpos      : %g\n" -       "Half ccd      : %d\n" -       "Depth/Channels: %u/%u\n\n", -       xres, yres, lines, pixels, startx, depth, half_ccd, channels); - -  /* optical_res */ -  optical_res = dev->sensor.optical_res; - -  if(xres<=optical_res) -    used_res = xres; -  else -    used_res=optical_res; - -  /* compute scan parameters values */ -  /* pixels are allways given at half or full CCD optical resolution */ -  /* use detected left margin  and fixed value */ - -  /* compute correct pixels number */ -  used_pixels = (pixels * optical_res) / xres; -  DBG (DBG_info, "%s: used_pixels=%d\n", __func__, used_pixels); - -  /* exposure */ -  exposure_time = gl124_compute_exposure (dev, xres, half_ccd); -  DBG (DBG_info, "%s : exposure_time=%d pixels\n", __func__, exposure_time); - -  /* max_shift */ -  max_shift=sanei_genesys_compute_max_shift(dev,channels,yres,0); - -  /* compute hw dpi for sensor */ -  dpihw=sanei_genesys_compute_dpihw(dev,used_res); - -  sensor=get_sensor_profile(dev->model->ccd_type, dpihw, half_ccd); -  dev->segnb=sensor->reg98 & 0x0f; - -  /* stagger */ -  if ((!half_ccd) && (dev->model->flags & GENESYS_FLAG_STAGGERED_LINE)) -    stagger = (4 * yres) / dev->motor.base_ydpi; -  else -    stagger = 0; -  DBG (DBG_info, "%s: stagger=%d lines\n", __func__, stagger); - -  /* lincnt */ -  lincnt = lines + max_shift + stagger; - -  dev->current_setup.pixels = (used_pixels * used_res) / optical_res; -  DBG (DBG_info, "%s: current_setup.pixels=%d\n", __func__, dev->current_setup.pixels); -  dev->current_setup.lines = lincnt; -  dev->current_setup.depth = depth; -  dev->current_setup.channels = channels; -  dev->current_setup.exposure_time = exposure_time; -  dev->current_setup.xres = used_res; -  dev->current_setup.yres = yres; -  dev->current_setup.half_ccd = half_ccd; -  dev->current_setup.stagger = stagger; -  dev->current_setup.max_shift = max_shift + stagger; - -  DBGCOMPLETED; -  return SANE_STATUS_GOOD; -} - -static void -gl124_set_motor_power (Genesys_Register_Set * regs, SANE_Bool set) -{ - -  DBG (DBG_proc, "gl124_set_motor_power\n"); - -  if (set) -    { -      sanei_genesys_set_reg_from_set (regs, REG02, -				      sanei_genesys_read_reg_from_set (regs, -								       REG02) -				      | REG02_MTRPWR); -    } -  else -    { -      sanei_genesys_set_reg_from_set (regs, REG02, -				      sanei_genesys_read_reg_from_set (regs, -								       REG02) -				      & ~REG02_MTRPWR); -    } -} - -static void -gl124_set_lamp_power (Genesys_Device * dev, -		      Genesys_Register_Set * regs, SANE_Bool set) -{ -  if (dev == NULL || regs==NULL) -    return; - -  if (set) -    { -      sanei_genesys_set_reg_from_set (regs, 0x03, -				      sanei_genesys_read_reg_from_set (regs, -								       0x03) -				      | REG03_LAMPPWR); -    } -  else -    { -      sanei_genesys_set_reg_from_set (regs, 0x03, -				      sanei_genesys_read_reg_from_set (regs, -								       0x03) -				      & ~REG03_LAMPPWR); -    } -} - -/** - * for fast power saving methods only, like disabling certain amplifiers - * @param dev device to use - * @param enable true to set inot powersaving - * */ -static SANE_Status -gl124_save_power (Genesys_Device * dev, SANE_Bool enable) -{ -  DBG (DBG_proc, "gl124_save_power: enable = %d\n", enable); -  if (dev == NULL) -    return SANE_STATUS_INVAL; - -  DBGCOMPLETED; -  return SANE_STATUS_GOOD; -} - -static SANE_Status -gl124_set_powersaving (Genesys_Device * dev, int delay /* in minutes */ ) -{ -  Genesys_Register_Set *r; - -  DBG (DBG_proc, "gl124_set_powersaving (delay = %d)\n", delay); - -  r = sanei_genesys_get_address (dev->reg, REG03); -  r->value &= ~0xf0; -  if(delay<15) -    { -      r->value |= delay; -    } -  else -    { -      r->value |= 0x0f; -    } - -  DBGCOMPLETED; -  return SANE_STATUS_GOOD; -} - -#ifndef UNIT_TESTING -static -#endif -  SANE_Status -gl124_start_action (Genesys_Device * dev) -{ -  return sanei_genesys_write_register (dev, 0x0f, 0x01); -} - -#ifndef UNIT_TESTING -static -#endif -SANE_Status -gl124_stop_action (Genesys_Device * dev) -{ -  SANE_Status status; -  uint8_t val40, val; -  unsigned int loop; - -  DBGSTART; - -  /* post scan gpio : without that HOMSNR is unreliable */ -  gl124_homsnr_gpio(dev); - -  status = sanei_genesys_get_status (dev, &val); -  if (DBG_LEVEL >= DBG_io) -    { -      sanei_genesys_print_status (val); -    } - -  status = sanei_genesys_read_register (dev, REG100, &val40); -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, -	   "%s: failed to read reg100: %s\n", __func__, -	   sane_strstatus (status)); -      DBGCOMPLETED; -      return status; -    } - -  /* only stop action if needed */ -  if (!(val40 & REG100_DATAENB) && !(val40 & REG100_MOTMFLG)) -    { -      DBG (DBG_info, "%s: already stopped\n", __func__); -      DBGCOMPLETED; -      return SANE_STATUS_GOOD; -    } - -  /* ends scan */ -  val = sanei_genesys_read_reg_from_set (dev->reg, REG01); -  val &= ~REG01_SCAN; -  sanei_genesys_set_reg_from_set (dev->reg, REG01, val); -  status = sanei_genesys_write_register (dev, REG01, val); -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, -	   "%s: failed to write register 01: %s\n", __func__, -	   sane_strstatus (status)); -      return status; -    } -  usleep (100 * 1000); - -  loop = 10; -  while (loop > 0) -    { -      status = sanei_genesys_get_status (dev, &val); -      if (DBG_LEVEL >= DBG_io) -	{ -	  sanei_genesys_print_status (val); -	} -      status = sanei_genesys_read_register (dev, REG100, &val40); -      if (status != SANE_STATUS_GOOD) -	{ -	  DBG (DBG_error, -	       "%s: failed to read home sensor: %s\n", __func__, -	       sane_strstatus (status)); -	  DBGCOMPLETED; -	  return status; -	} - -      /* if scanner is in command mode, we are done */ -      if (!(val40 & REG100_DATAENB) && !(val40 & REG100_MOTMFLG) -	  && !(val & MOTORENB)) -	{ -	  DBGCOMPLETED; -	  return SANE_STATUS_GOOD; -	} - -      usleep (100 * 1000); -      loop--; -    } - -  DBGCOMPLETED; -  return SANE_STATUS_IO_ERROR; -} - - -/** @brief setup GPIOs for scan - * Setup GPIO values to drive motor (or light) needed for the - * target resolution - * @param *dev device to set up - * @param resolution dpi of the target scan - * @return SANE_STATUS_GOOD unless REG32 cannot be read - */ -static SANE_Status -gl124_setup_scan_gpio(Genesys_Device *dev, int resolution) -{ -SANE_Status status; -uint8_t val; - -  DBGSTART; -  RIE (sanei_genesys_read_register (dev, REG32, &val)); - -  /* LiDE 110, 210 and 220 cases */ -  if(dev->model->gpo_type != GPO_CANONLIDE120) -    { -      if(resolution>=dev->motor.base_ydpi/2) -	{ -	  val &= 0xf7; -	} -      else if(resolution>=dev->motor.base_ydpi/4) -	{ -	  val &= 0xef; -	} -      else -	{ -	  val |= 0x10; -	} -    } -  /* 120 : <=300 => 0x53 */ -  else -    { /* base_ydpi is 4800 */ -      if(resolution<=300) -	{ -	  val &= 0xf7; -	} -      else if(resolution<=600) -	{ -	  val |= 0x08; -	} -      else if(resolution<=1200) -	{ -	  val &= 0xef; -	  val |= 0x08; -	} -      else -	{ -	  val &= 0xf7; -	} -    } -  val |= 0x02; -  RIE (sanei_genesys_write_register (dev, REG32, val)); -  DBGCOMPLETED; -  return SANE_STATUS_GOOD; -} - -/* Send the low-level scan command */ -/* todo : is this that useful ? */ -#ifndef UNIT_TESTING -static -#endif -  SANE_Status -gl124_begin_scan (Genesys_Device * dev, Genesys_Register_Set * reg, -		  SANE_Bool start_motor) -{ -  SANE_Status status; -  uint8_t val; - -  DBGSTART; -  if (reg == NULL) -    return SANE_STATUS_INVAL; - -  /* set up GPIO for scan */ -  RIE(gl124_setup_scan_gpio(dev,dev->settings.yres)); - -  /* clear scan and feed count */ -  RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT | REG0D_CLRMCNT)); - -  /* enable scan and motor */ -  RIE (sanei_genesys_read_register (dev, REG01, &val)); -  val |= REG01_SCAN; -  RIE (sanei_genesys_write_register (dev, REG01, val)); - -  if (start_motor) -    { -      RIE (sanei_genesys_write_register (dev, REG0F, 1)); -    } -  else -    { -      RIE (sanei_genesys_write_register (dev, REG0F, 0)); -    } - -  DBGCOMPLETED; -  return status; -} - - -/* Send the stop scan command */ -#ifndef UNIT_TESTING -static -#endif -  SANE_Status -gl124_end_scan (Genesys_Device * dev, Genesys_Register_Set * reg, -		SANE_Bool check_stop) -{ -  SANE_Status status; - -  DBG (DBG_proc, "gl124_end_scan (check_stop = %d)\n", check_stop); -  if (reg == NULL) -    return SANE_STATUS_INVAL; - -  if (dev->model->is_sheetfed == SANE_TRUE) -    { -      status = SANE_STATUS_GOOD; -    } -  else                                /* flat bed scanners */ -    { -      status = gl124_stop_action (dev); -      if (status != SANE_STATUS_GOOD) -	{ -	  DBG (DBG_error, -	       "gl124_end_scan: failed to stop: %s\n", -	       sane_strstatus (status)); -	  return status; -	} -    } - -  DBGCOMPLETED; -  return status; -} - - -/** rewind scan - * Move back by the same amount of distance than previous scan. - * @param dev device to rewind - * @returns SANE_STATUS_GOOD on success - */ -GENESYS_STATIC -SANE_Status gl124_rewind(Genesys_Device * dev) -{ -  SANE_Status status; -  uint8_t byte; - -  DBGSTART; - -  /* set motor reverse */ -  RIE (sanei_genesys_read_register (dev, 0x02, &byte)); -  byte |= 0x04; -  RIE (sanei_genesys_write_register(dev, 0x02, byte)); - -  /* and start scan, then wait completion */ -  RIE (gl124_begin_scan (dev, dev->reg, SANE_TRUE)); -  do -    { -      usleep(100*1000); -      RIE (sanei_genesys_read_register (dev, REG100, &byte)); -    } -  while(byte & REG100_MOTMFLG); -  RIE (gl124_end_scan (dev, dev->reg, SANE_TRUE)); - -  /* restore direction */ -  RIE (sanei_genesys_read_register (dev, 0x02, &byte)); -  byte &= 0xfb; -  RIE (sanei_genesys_write_register(dev, 0x02, byte)); -  DBGCOMPLETED; -  return SANE_STATUS_GOOD; -} - - -/** Park head - * Moves the slider to the home (top) position slowly - * @param dev device to park - * @param wait_until_home true to make the function waiting for head - * to be home before returning, if fals returne immediately - * @returns SANE_STATUS_GOO on success */ -GENESYS_STATIC -SANE_Status -gl124_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home) -{ -  Genesys_Register_Set local_reg[GENESYS_GL124_MAX_REGS]; -  SANE_Status status; -  Genesys_Register_Set *r; -  uint8_t val; -  float resolution; -  int loop = 0; - -  DBG (DBG_proc, "gl124_slow_back_home (wait_until_home = %d)\n", -       wait_until_home); - -  if(dev->usb_mode<0) -    { -      DBGCOMPLETED; -      return SANE_STATUS_GOOD; -    } - -  /* post scan gpio : without that HOMSNR is unreliable */ -  gl124_homsnr_gpio(dev); - -  /* first read gives HOME_SENSOR true */ -  status = sanei_genesys_get_status (dev, &val); -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, -	   "gl124_slow_back_home: failed to read home sensor: %s\n", -	   sane_strstatus (status)); -      return status; -    } -  if (DBG_LEVEL >= DBG_io) -    { -      sanei_genesys_print_status (val); -    } -  usleep (100000);                /* sleep 100 ms */ - -  /* second is reliable */ -  status = sanei_genesys_get_status (dev, &val); -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, -	   "gl124_slow_back_home: failed to read home sensor: %s\n", -	   sane_strstatus (status)); -      return status; -    } -  if (DBG_LEVEL >= DBG_io) -    { -      sanei_genesys_print_status (val); -    } - -  /* is sensor at home? */ -  if (val & HOMESNR) -    { -      DBG (DBG_info, "%s: already at home, completed\n", __func__); -      dev->scanhead_position_in_steps = 0; -      DBGCOMPLETED; -      return SANE_STATUS_GOOD; -    } - -  /* feed a little first */ -  if (strcmp (dev->model->name, "canon-lide-210") == 0) -    { -      status = gl124_feed (dev, 20, SANE_TRUE); -      if (status != SANE_STATUS_GOOD) -        { -          DBG (DBG_error, "%s: failed to do initial feed: %s\n", __func__, sane_strstatus (status)); -          return status; -        } -    } - -  memcpy (local_reg, dev->reg, GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set)); -  resolution=sanei_genesys_get_lowest_dpi(dev); - -  status = gl124_init_scan_regs (dev, -                                 local_reg, -                                 resolution, -                                 resolution, -                                 100, -                                 30000, -                                 100, -                                 100, -                                 8, -                                 1, -                                 dev->settings.scan_method, -                                 SCAN_MODE_GRAY, -                                 0, -                                 SCAN_FLAG_DISABLE_SHADING | -                                 SCAN_FLAG_DISABLE_GAMMA | -                                 SCAN_FLAG_IGNORE_LINE_DISTANCE); -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, -           "gl124_slow_back_home: failed to set up registers: %s\n", -           sane_strstatus (status)); -      DBGCOMPLETED; -      return status; -    } - -  /* clear scan and feed count */ -  RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT | REG0D_CLRMCNT)); - -  /* set up for reverse and no scan */ -  r = sanei_genesys_get_address (local_reg, REG02); -  r->value |= REG02_MTRREV; - -  RIE (dev->model->cmd_set->bulk_write_register (dev, local_reg, GENESYS_GL124_MAX_REGS)); - -  RIE(gl124_setup_scan_gpio(dev,resolution)); - -  status = gl124_start_action (dev); -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, -	   "gl124_slow_back_home: failed to start motor: %s\n", -	   sane_strstatus (status)); -      gl124_stop_action (dev); -      /* restore original registers */ -      dev->model->cmd_set->bulk_write_register (dev, dev->reg, GENESYS_GL124_MAX_REGS); -      return status; -    } - -  /* post scan gpio : without that HOMSNR is unreliable */ -  gl124_homsnr_gpio(dev); - -  if (wait_until_home) -    { - -      while (loop < 300)        /* do not wait longer then 30 seconds */ -	{ -	  status = sanei_genesys_get_status (dev, &val); -	  if (status != SANE_STATUS_GOOD) -	    { -	      DBG (DBG_error, -		   "gl124_slow_back_home: failed to read home sensor: %s\n", -		   sane_strstatus (status)); -	      return status; -	    } - -	  if (val & HOMESNR)        /* home sensor */ -	    { -	      DBG (DBG_info, "gl124_slow_back_home: reached home position\n"); -	      DBGCOMPLETED; -              dev->scanhead_position_in_steps = 0; -	      return SANE_STATUS_GOOD; -	    } -	  usleep (100000);        /* sleep 100 ms */ -	  ++loop; -	} - -      /* when we come here then the scanner needed too much time for this, so we better stop the motor */ -      gl124_stop_action (dev); -      DBG (DBG_error, -	   "gl124_slow_back_home: timeout while waiting for scanhead to go home\n"); -      return SANE_STATUS_IO_ERROR; -    } - -  DBG (DBG_info, "gl124_slow_back_home: scanhead is still moving\n"); -  DBGCOMPLETED; -  return SANE_STATUS_GOOD; -} - -/** @brief moves the slider to steps at motor base dpi - * @param dev device to work on - * @param steps number of steps to move - * @param reverse true is moving backward - * */ -#ifndef UNIT_TESTING -static -#endif -SANE_Status -gl124_feed (Genesys_Device * dev, unsigned int steps, int reverse) -{ -  Genesys_Register_Set local_reg[GENESYS_GL124_MAX_REGS]; -  SANE_Status status; -  Genesys_Register_Set *r; -  float resolution; -  uint8_t val; - -  DBGSTART; -  DBG (DBG_io, "%s: steps=%d\n", __func__, steps); - -  /* prepare local registers */ -  memcpy (local_reg, dev->reg, GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set)); - -  resolution=sanei_genesys_get_lowest_ydpi(dev); -  status = gl124_init_scan_regs (dev, -                                 local_reg, -                                 resolution, -                                 resolution, -                                 0, -                                 steps, -                                 100, -                                 3, -                                 8, -                                 3, -                                 dev->settings.scan_method, -                                 SCAN_MODE_COLOR, -                                 dev->settings.color_filter, -                                 SCAN_FLAG_DISABLE_SHADING | -                                 SCAN_FLAG_DISABLE_GAMMA | -                                 SCAN_FLAG_FEEDING | -                                 SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE | -                                 SCAN_FLAG_IGNORE_LINE_DISTANCE); -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, "%s: failed to set up registers: %s\n", __func__, sane_strstatus (status)); -      DBGCOMPLETED; -      return status; -    } - -  /* set exposure to zero */ -  sanei_genesys_set_triple(local_reg,REG_EXPR,0); -  sanei_genesys_set_triple(local_reg,REG_EXPG,0); -  sanei_genesys_set_triple(local_reg,REG_EXPB,0); - -  /* clear scan and feed count */ -  RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRLNCNT)); -  RIE (sanei_genesys_write_register (dev, REG0D, REG0D_CLRMCNT)); - -  /* set up for no scan */ -  r = sanei_genesys_get_address (local_reg, REG01); -  r->value &= ~REG01_SCAN; - -  /* set up for reverse if needed */ -  if(reverse) -    { -      r = sanei_genesys_get_address (local_reg, REG02); -      r->value |= REG02_MTRREV; -    } - -  /* send registers */ -  RIE (dev->model->cmd_set->bulk_write_register (dev, local_reg, GENESYS_GL124_MAX_REGS)); - -  status = gl124_start_action (dev); -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, "%s: failed to start motor: %s\n", __func__, sane_strstatus (status)); -      gl124_stop_action (dev); - -      /* restore original registers */ -      dev->model->cmd_set->bulk_write_register (dev, dev->reg, GENESYS_GL124_MAX_REGS); -      return status; -    } - -  /* wait until feed count reaches the required value, but do not -   * exceed 30s */ -  do -    { -          status = sanei_genesys_get_status (dev, &val); -    } -  while (status == SANE_STATUS_GOOD && !(val & FEEDFSH)); - -  /* then stop scanning */ -  RIE(gl124_stop_action (dev)); - -  DBGCOMPLETED; -  return SANE_STATUS_GOOD; -} - - -/* Automatically set top-left edge of the scan area by scanning a 200x200 pixels -   area at 600 dpi from very top of scanner */ -static SANE_Status -gl124_search_start_position (Genesys_Device * dev) -{ -  int size; -  SANE_Status status; -  uint8_t *data; -  Genesys_Register_Set local_reg[GENESYS_GL124_MAX_REGS]; -  int steps; - -  int pixels = 600; -  int dpi = 300; - -  DBGSTART; - -  memcpy (local_reg, dev->reg, -	  GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set)); - -  /* sets for a 200 lines * 600 pixels */ -  /* normal scan with no shading */ - -  status = gl124_init_scan_regs (dev, -                                 local_reg, -                                 dpi, -                                 dpi, -                                 0, -				 0,        /*we should give a small offset here~60 steps */ -				 600, -                                 dev->model->search_lines, -                                 8, -                                 1, -                                 dev->settings.scan_method, -                                 SCAN_MODE_GRAY, -				 1,        /*green */ -				 SCAN_FLAG_DISABLE_SHADING | -				 SCAN_FLAG_DISABLE_GAMMA | -				 SCAN_FLAG_IGNORE_LINE_DISTANCE | -				 SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE); -  if (status!=SANE_STATUS_GOOD) -    { -      DBG (DBG_error, -	   "%s: failed to init scan registers: %s\n", __func__, -	   sane_strstatus (status)); -      return status; -    } - -  /* send to scanner */ -  status = dev->model->cmd_set->bulk_write_register (dev, local_reg, GENESYS_GL124_MAX_REGS); -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, -	   "gl124_search_start_position: failed to bulk write registers: %s\n", -	   sane_strstatus (status)); -      return status; -    } - -  size = pixels * dev->model->search_lines; - -  data = malloc (size); -  if (!data) -    { -      DBG (DBG_error, -	   "gl124_search_start_position: failed to allocate memory\n"); -      return SANE_STATUS_NO_MEM; -    } - -  status = gl124_begin_scan (dev, local_reg, SANE_TRUE); -  if (status != SANE_STATUS_GOOD) -    { -      free (data); -      DBG (DBG_error, -	   "gl124_search_start_position: failed to begin scan: %s\n", -	   sane_strstatus (status)); -      return status; -    } - -  /* waits for valid data */ -  do -    sanei_genesys_test_buffer_empty (dev, &steps); -  while (steps); - -  /* now we're on target, we can read data */ -  status = sanei_genesys_read_data_from_scanner (dev, data, size); -  if (status != SANE_STATUS_GOOD) -    { -      free (data); -      DBG (DBG_error, -	   "gl124_search_start_position: failed to read data: %s\n", -	   sane_strstatus (status)); -      return status; -    } - -  if (DBG_LEVEL >= DBG_data) -    sanei_genesys_write_pnm_file ("search_position.pnm", data, 8, 1, pixels, -				  dev->model->search_lines); - -  status = gl124_end_scan (dev, local_reg, SANE_TRUE); -  if (status != SANE_STATUS_GOOD) -    { -      free (data); -      DBG (DBG_error, -	   "gl124_search_start_position: failed to end scan: %s\n", -	   sane_strstatus (status)); -      return status; -    } - -  /* update regs to copy ASIC internal state */ -  memcpy (dev->reg, local_reg, -	  GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set)); - -  status = -    sanei_genesys_search_reference_point (dev, data, 0, dpi, pixels, -					  dev->model->search_lines); -  if (status != SANE_STATUS_GOOD) -    { -      free (data); -      DBG (DBG_error, -	   "gl124_search_start_position: failed to set search reference point: %s\n", -	   sane_strstatus (status)); -      return status; -    } - -  free (data); -  DBGCOMPLETED; -  return SANE_STATUS_GOOD; -} - -/* - * sets up register for coarse gain calibration - * todo: check it for scanners using it */ -static SANE_Status -gl124_init_regs_for_coarse_calibration (Genesys_Device * dev) -{ -  SANE_Status status; -  uint8_t channels; -  uint8_t cksel; - -  DBGSTART; -  cksel = (dev->calib_reg[reg_0x18].value & REG18_CKSEL) + 1;        /* clock speed = 1..4 clocks */ - -  /* set line size */ -  if (dev->settings.scan_mode == SCAN_MODE_COLOR)        /* single pass color */ -    channels = 3; -  else -    channels = 1; - -  status = gl124_init_scan_regs (dev, -				 dev->calib_reg, -				 dev->settings.xres, -				 dev->settings.yres, -				 0, -				 0, -				 dev->sensor.optical_res / cksel, -				 20, -				 16, -				 channels, -                                 dev->settings.scan_method, -                                 dev->settings.scan_mode, -				 dev->settings.color_filter, -				 SCAN_FLAG_DISABLE_SHADING | -				 SCAN_FLAG_DISABLE_GAMMA | -				 SCAN_FLAG_SINGLE_LINE | -				 SCAN_FLAG_FEEDING | -				 SCAN_FLAG_IGNORE_LINE_DISTANCE); -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, -	   "gl124_init_register_for_coarse_calibration: failed to setup scan: %s\n", -	   sane_strstatus (status)); -      return status; -    } -  gl124_set_motor_power (dev->calib_reg, SANE_FALSE); - -  DBG (DBG_info, -       "gl124_init_register_for_coarse_calibration: optical sensor res: %d dpi, actual res: %d\n", -       dev->sensor.optical_res / cksel, dev->settings.xres); - -  status = dev->model->cmd_set->bulk_write_register (dev, dev->calib_reg, GENESYS_GL124_MAX_REGS); -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, -	   "gl124_init_register_for_coarse_calibration: failed to bulk write registers: %s\n", -	   sane_strstatus (status)); -      return status; -    } - -  DBGCOMPLETED; -  return SANE_STATUS_GOOD; -} - - -/* init registers for shading calibration */ -/* shading calibration is done at dpihw */ -static SANE_Status -gl124_init_regs_for_shading (Genesys_Device * dev) -{ -  SANE_Status status; -  int move, resolution, dpihw, factor; - -  DBGSTART; - -  /* initial calibration reg values */ -  memcpy (dev->calib_reg, dev->reg, GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set)); - -  dev->calib_channels = 3; -  dev->calib_lines = dev->model->shading_lines; -  dpihw=sanei_genesys_compute_dpihw(dev,dev->settings.xres); -  if(dpihw>=2400) -    { -      dev->calib_lines *= 2; -    } -  resolution=dpihw; - -  /* if half CCD mode, use half resolution */ -  if(compute_half_ccd(dev->model, dev->settings.xres)==SANE_TRUE) -    { -      resolution /= 2; -      dev->calib_lines /= 2; -    } -  dev->calib_resolution = resolution; -  factor=dev->sensor.optical_res/resolution; -  dev->calib_pixels = dev->sensor.sensor_pixels/factor; - -  /* distance to move to reach white target at high resolution */ -  move=0; -  if(dev->settings.yres>=1200) -    { -      move = SANE_UNFIX (dev->model->y_offset_calib); -      move = (move * (dev->motor.base_ydpi/4)) / MM_PER_INCH; -    } -  DBG (DBG_io, "%s: move=%d steps\n", __func__, move); - -  status = gl124_init_scan_regs (dev, -				 dev->calib_reg, -				 resolution, -				 resolution, -				 0, -				 move, -				 dev->calib_pixels, -				 dev->calib_lines, -				 16, -				 dev->calib_channels, -                                 dev->settings.scan_method, -                                 SCAN_MODE_COLOR, -				 0, -				 SCAN_FLAG_DISABLE_SHADING | -				 SCAN_FLAG_DISABLE_GAMMA | -				 SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE | -				 SCAN_FLAG_IGNORE_LINE_DISTANCE); -  gl124_set_motor_power (dev->calib_reg, SANE_FALSE); - -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, "%s: failed to setup scan: %s\n", __func__, -	   sane_strstatus (status)); -      return status; -    } - -  dev->scanhead_position_in_steps += dev->calib_lines + move; - -  status = dev->model->cmd_set->bulk_write_register (dev, dev->calib_reg, GENESYS_GL124_MAX_REGS); -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, -	   "%s: failed to bulk write registers: %s\n", __func__, -	   sane_strstatus (status)); -      return status; -    } - -  DBGCOMPLETED; -  return SANE_STATUS_GOOD; -} - -/** @brief set up registers for the actual scan - */ -static SANE_Status -gl124_init_regs_for_scan (Genesys_Device * dev) -{ -  int channels; -  int flags; -  int depth; -  float move; -  int move_dpi; -  float start; -  uint8_t val40,val; - -  SANE_Status status; - -  DBG (DBG_info, -       "gl124_init_regs_for_scan settings:\nResolution: %ux%uDPI\n" -       "Lines     : %u\npixels    : %u\nStartpos  : %.3f/%.3f\nScan mode : %d\n\n", -       dev->settings.xres, -       dev->settings.yres, -       dev->settings.lines, -       dev->settings.pixels, -       dev->settings.tl_x, -       dev->settings.tl_y, -       dev->settings.scan_mode); - -  /* wait for motor to stop first */ -  status = sanei_genesys_get_status (dev, &val); -  if (status != SANE_STATUS_GOOD) -   { -     DBG (DBG_error, "%s: failed to read status: %s\n", __func__, sane_strstatus (status)); -     DBGCOMPLETED; -     return status; -   } -  status = sanei_genesys_read_register (dev, REG100, &val40); -  if (status != SANE_STATUS_GOOD) -   { -     DBG (DBG_error, "%s: failed to read reg100: %s\n", __func__, sane_strstatus (status)); -     DBGCOMPLETED; -     return status; -   } -  if((val & MOTORENB) || (val40 & REG100_MOTMFLG)) -    { -      do -        { -          usleep(10000); -          status = sanei_genesys_get_status (dev, &val); -          if (status != SANE_STATUS_GOOD) -           { -             DBG (DBG_error, "%s: failed to read status: %s\n", __func__, sane_strstatus (status)); -             DBGCOMPLETED; -             return status; -           } -          status = sanei_genesys_read_register (dev, REG100, &val40); -          if (status != SANE_STATUS_GOOD) -           { -             DBG (DBG_error, "%s: failed to read reg100: %s\n", __func__, sane_strstatus (status)); -             DBGCOMPLETED; -             return status; -           } -        } while ((val & MOTORENB) || (val40 & REG100_MOTMFLG)); -        usleep(50000); -    } - -  /* ensure head is parked in case of calibration */ -  RIE (gl124_slow_back_home (dev, SANE_TRUE)); - -  /* channels */ -  if (dev->settings.scan_mode == SCAN_MODE_COLOR) -    channels = 3; -  else -    channels = 1; - -  /* depth */ -  depth = dev->settings.depth; -  if (dev->settings.scan_mode == SCAN_MODE_LINEART) -    depth = 1; - -  /* y (motor) distance to move to reach scanned area */ -  move_dpi = dev->motor.base_ydpi/4; -  move = SANE_UNFIX (dev->model->y_offset); -  move += dev->settings.tl_y; -  move = (move * move_dpi) / MM_PER_INCH; -  DBG (DBG_info, "%s: move=%f steps\n", __func__, move); - -  if(channels*dev->settings.yres>=600 && move>700) -    { -      status = gl124_feed (dev, move-500, SANE_FALSE); -      if (status != SANE_STATUS_GOOD) -        { -          DBG (DBG_error, "%s: failed to move to scan area\n",__func__); -          return status; -        } -      move=500; -    } -  DBG (DBG_info, "gl124_init_regs_for_scan: move=%f steps\n", move); - -  /* start */ -  start = SANE_UNFIX (dev->model->x_offset); -  start += dev->settings.tl_x; -  if(compute_half_ccd(dev->model, dev->settings.xres)==SANE_TRUE) -    { -      start /=2; -    } -  start = (start * dev->sensor.optical_res) / MM_PER_INCH; - -  flags = 0; - -  /* enable emulated lineart from gray data */ -  if(dev->settings.scan_mode == SCAN_MODE_LINEART -     && dev->settings.dynamic_lineart) -    { -      flags |= SCAN_FLAG_DYNAMIC_LINEART; -    } - -  status = gl124_init_scan_regs (dev, -				 dev->reg, -				 dev->settings.xres, -				 dev->settings.yres, -				 start, -				 move, -				 dev->settings.pixels, -				 dev->settings.lines, -				 depth, -				 channels, -                                 dev->settings.scan_method, -                                 dev->settings.scan_mode, -                                 dev->settings.color_filter, -                                 flags); - -  if (status != SANE_STATUS_GOOD) -    return status; - -  DBGCOMPLETED; -  return SANE_STATUS_GOOD; -} - -/** - * Send shading calibration data. The buffer is considered to always hold values - * for all the channels. - */ -#ifndef UNIT_TESTING -static -#endif -SANE_Status -gl124_send_shading_data (Genesys_Device * dev, uint8_t * data, int size) -{ -  SANE_Status status = SANE_STATUS_GOOD; -  uint32_t addr, length, strpixel ,endpixel, x, factor, segcnt, pixels, i; -  uint32_t lines, channels; -  uint16_t dpiset,dpihw; -  uint8_t val,*buffer,*ptr,*src; - -  DBGSTART; -  DBG( DBG_io2, "%s: writing %d bytes of shading data\n",__func__,size); - -  /* logical size of a color as seen by generic code of the frontend */ -  length = (uint32_t) (size / 3); -  sanei_genesys_get_triple(dev->reg,REG_STRPIXEL,&strpixel); -  sanei_genesys_get_triple(dev->reg,REG_ENDPIXEL,&endpixel); -  sanei_genesys_get_triple(dev->reg,REG_SEGCNT,&segcnt); -  if(endpixel==0) -    { -      endpixel=segcnt; -    } -  DBG( DBG_io2, "%s: STRPIXEL=%d, ENDPIXEL=%d, PIXELS=%d, SEGCNT=%d\n",__func__,strpixel,endpixel,endpixel-strpixel,segcnt); - -  /* compute deletion factor */ -  sanei_genesys_get_double(dev->reg,REG_DPISET,&dpiset); -  dpihw=sanei_genesys_compute_dpihw(dev,dpiset); -  factor=dpihw/dpiset; -  DBG( DBG_io2, "%s: factor=%d\n",__func__,factor); - -  /* binary data logging */ -  if(DBG_LEVEL>=DBG_data) -    { -      dev->binary=fopen("binary.pnm","wb"); -      sanei_genesys_get_triple(dev->reg, REG_LINCNT, &lines); -      channels=dev->current_setup.channels; -      if(dev->binary!=NULL) -        { -          fprintf(dev->binary,"P5\n%d %d\n%d\n",(endpixel-strpixel)/factor*channels*dev->segnb,lines/channels,255); -        } -    } - -  /* turn pixel value into bytes 2x16 bits words */ -  strpixel*=2*2; /* 2 words of 2 bytes */ -  endpixel*=2*2; -  segcnt*=2*2; -  pixels=endpixel-strpixel; - -  DBG( DBG_io2, "%s: using chunks of %d bytes (%d shading data pixels)\n",__func__,length, length/4); -  buffer=(uint8_t *)malloc(pixels*dev->segnb); -  memset(buffer,0,pixels*dev->segnb); - -  /* write actual red data */ -  for(i=0;i<3;i++) -    { -      /* copy data to work buffer and process it */ -          /* coefficent destination */ -      ptr=buffer; - -      /* iterate on both sensor segment */ -      for(x=0;x<pixels;x+=4*factor) -        { -          /* coefficient source */ -          src=data+x+strpixel+i*length; - -          /* iterate over all the segments */ -          switch(dev->segnb) -            { -            case 1: -              ptr[0+pixels*0]=src[0+segcnt*0]; -              ptr[1+pixels*0]=src[1+segcnt*0]; -              ptr[2+pixels*0]=src[2+segcnt*0]; -              ptr[3+pixels*0]=src[3+segcnt*0]; -              break; -            case 2: -              ptr[0+pixels*0]=src[0+segcnt*0]; -              ptr[1+pixels*0]=src[1+segcnt*0]; -              ptr[2+pixels*0]=src[2+segcnt*0]; -              ptr[3+pixels*0]=src[3+segcnt*0]; -              ptr[0+pixels*1]=src[0+segcnt*1]; -              ptr[1+pixels*1]=src[1+segcnt*1]; -              ptr[2+pixels*1]=src[2+segcnt*1]; -              ptr[3+pixels*1]=src[3+segcnt*1]; -              break; -            case 4: -              ptr[0+pixels*0]=src[0+segcnt*0]; -              ptr[1+pixels*0]=src[1+segcnt*0]; -              ptr[2+pixels*0]=src[2+segcnt*0]; -              ptr[3+pixels*0]=src[3+segcnt*0]; -              ptr[0+pixels*1]=src[0+segcnt*2]; -              ptr[1+pixels*1]=src[1+segcnt*2]; -              ptr[2+pixels*1]=src[2+segcnt*2]; -              ptr[3+pixels*1]=src[3+segcnt*2]; -              ptr[0+pixels*2]=src[0+segcnt*1]; -              ptr[1+pixels*2]=src[1+segcnt*1]; -              ptr[2+pixels*2]=src[2+segcnt*1]; -              ptr[3+pixels*2]=src[3+segcnt*1]; -              ptr[0+pixels*3]=src[0+segcnt*3]; -              ptr[1+pixels*3]=src[1+segcnt*3]; -              ptr[2+pixels*3]=src[2+segcnt*3]; -              ptr[3+pixels*3]=src[3+segcnt*3]; -              break; -            } - -          /* next shading coefficient */ -          ptr+=4; -        } -      RIE (sanei_genesys_read_register (dev, 0xd0+i, &val)); -      addr = val * 8192 + 0x10000000; -      status = sanei_genesys_write_ahb (dev->dn, dev->usb_mode, addr, pixels*dev->segnb, buffer); -      if (status != SANE_STATUS_GOOD) -        { -          DBG (DBG_error, "gl124_send_shading_data; write to AHB failed (%s)\n", -               sane_strstatus (status)); -          return status; -        } -    } - -  free(buffer); -  DBGCOMPLETED; - -  return status; -} - - -/** @brief move to calibration area - * This functions moves scanning head to calibration area - * by doing a 600 dpi scan - * @param dev scanner device - * @return SANE_STATUS_GOOD on success, else the error code - */ -static SANE_Status -move_to_calibration_area (Genesys_Device * dev) -{ -  int pixels; -  int size; -  uint8_t *line; -  SANE_Status status = SANE_STATUS_GOOD; - -  DBGSTART; - -  pixels = (dev->sensor.sensor_pixels*600)/dev->sensor.optical_res; - -  /* initial calibration reg values */ -  memcpy (dev->calib_reg, dev->reg, GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set)); - -  /* set up for the calibration scan */ -  status = gl124_init_scan_regs (dev, -				 dev->calib_reg, -				 600, -				 600, -				 0, -				 0, -				 pixels, -                                 1, -                                 8, -                                 3, -                                 dev->settings.scan_method, -                                 SCAN_MODE_COLOR, -				 dev->settings.color_filter, -				 SCAN_FLAG_DISABLE_SHADING | -				 SCAN_FLAG_DISABLE_GAMMA | -				 SCAN_FLAG_SINGLE_LINE | -				 SCAN_FLAG_IGNORE_LINE_DISTANCE); -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus (status)); -      return status; -    } - -  size = pixels * 3; -  line = malloc (size); -  if (!line) -    return SANE_STATUS_NO_MEM; - -  /* write registers and scan data */ -  RIEF (dev->model->cmd_set->bulk_write_register (dev, dev->calib_reg, GENESYS_GL124_MAX_REGS), line); - -  DBG (DBG_info, "%s: starting line reading\n", __func__); -  RIEF (gl124_begin_scan (dev, dev->calib_reg, SANE_TRUE), line); -  RIEF (sanei_genesys_read_data_from_scanner (dev, line, size), line); - -  /* stop scanning */ -  RIE (gl124_stop_action (dev)); - -  if (DBG_LEVEL >= DBG_data) -    { -      sanei_genesys_write_pnm_file ("movetocalarea.pnm", line, 8, 3, pixels, 1); -    } - -  /* cleanup before return */ -  free (line); - -  DBGCOMPLETED; -  return status; -} - -/* this function does the led calibration by scanning one line of the calibration -   area below scanner's top on white strip. - --needs working coarse/gain -*/ -static SANE_Status -gl124_led_calibration (Genesys_Device * dev) -{ -  int num_pixels; -  int total_size; -  int resolution; -  int dpihw; -  uint8_t *line; -  int i, j; -  SANE_Status status = SANE_STATUS_GOOD; -  int val; -  int channels, depth; -  int avg[3]; -  int turn; -  char fn[20]; -  uint16_t exp[3],target; -  Sensor_Profile *sensor; -  SANE_Bool acceptable; -  SANE_Bool half_ccd; - -  DBGSTART; - -  /* move to calibration area */ -  move_to_calibration_area(dev); - -  /* offset calibration is always done in 16 bit depth color mode */ -  channels = 3; -  depth=16; -  dpihw=sanei_genesys_compute_dpihw(dev, dev->settings.xres); -  half_ccd=compute_half_ccd(dev->model, dev->settings.xres); -  if(half_ccd==SANE_TRUE) -    { -      resolution = dpihw/2; -    } -  else -    { -      resolution = dpihw; -    } -  sensor=get_sensor_profile(dev->model->ccd_type, dpihw, half_ccd); -  num_pixels = (dev->sensor.sensor_pixels*resolution)/dev->sensor.optical_res; - -  /* initial calibration reg values */ -  memcpy (dev->calib_reg, dev->reg, GENESYS_GL124_MAX_REGS * sizeof (Genesys_Register_Set)); - -  /* set up for the calibration scan */ -  status = gl124_init_scan_regs (dev, -				 dev->calib_reg, -				 resolution, -				 resolution, -				 0, -				 0, -				 num_pixels, -                                 1, -                                 depth, -                                 channels, -                                 dev->settings.scan_method, -                                 SCAN_MODE_COLOR, -				 dev->settings.color_filter, -				 SCAN_FLAG_DISABLE_SHADING | -				 SCAN_FLAG_DISABLE_GAMMA | -				 SCAN_FLAG_SINGLE_LINE | -				 SCAN_FLAG_IGNORE_LINE_DISTANCE); -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, "%s: failed to setup scan: %s\n", __func__, sane_strstatus (status)); -      return status; -    } - -  total_size = num_pixels * channels * (depth/8) * 1;        /* colors * bytes_per_color * scan lines */ -  line = malloc (total_size); -  if (!line) -    return SANE_STATUS_NO_MEM; - -  /* initial loop values and boundaries */ -  exp[0]=sensor->expr; -  exp[1]=sensor->expg; -  exp[2]=sensor->expb; -  target=dev->sensor.gain_white_ref*256; - -  turn = 0; - -  /* no move during led calibration */ -  gl124_set_motor_power (dev->calib_reg, SANE_FALSE); -  do -    { -      /* set up exposure */ -      sanei_genesys_set_triple(dev->calib_reg,REG_EXPR,exp[0]); -      sanei_genesys_set_triple(dev->calib_reg,REG_EXPG,exp[1]); -      sanei_genesys_set_triple(dev->calib_reg,REG_EXPB,exp[2]); - -      /* write registers and scan data */ -      RIEF (dev->model->cmd_set->bulk_write_register (dev, dev->calib_reg, GENESYS_GL124_MAX_REGS), line); - -      DBG (DBG_info, "gl124_led_calibration: starting line reading\n"); -      RIEF (gl124_begin_scan (dev, dev->calib_reg, SANE_TRUE), line); -      RIEF (sanei_genesys_read_data_from_scanner (dev, line, total_size), line); - -      /* stop scanning */ -      RIEF (gl124_stop_action (dev), line); - -      if (DBG_LEVEL >= DBG_data) -	{ -	  snprintf (fn, 20, "led_%02d.pnm", turn); -	  sanei_genesys_write_pnm_file (fn, line, depth, channels, num_pixels, 1); -	} - -      /* compute average */ -      for (j = 0; j < channels; j++) -	{ -	  avg[j] = 0; -	  for (i = 0; i < num_pixels; i++) -	    { -	      if (dev->model->is_cis) -		val = -		  line[i * 2 + j * 2 * num_pixels + 1] * 256 + -		  line[i * 2 + j * 2 * num_pixels]; -	      else -		val = -		  line[i * 2 * channels + 2 * j + 1] * 256 + -		  line[i * 2 * channels + 2 * j]; -	      avg[j] += val; -	    } - -	  avg[j] /= num_pixels; -	} - -      DBG (DBG_info, "gl124_led_calibration: average: %d,%d,%d\n", avg[0], avg[1], avg[2]); - -      /* check if exposure gives average within the boundaries */ -      acceptable = SANE_TRUE; -      for(i=0;i<3;i++) -        { -          /* we accept +- 2% delta from target */ -          if(abs(avg[i]-target)>target/50) -            { -              exp[i]=(exp[i]*target)/avg[i]; -              acceptable = SANE_FALSE; -            } -        } - -      turn++; -    } -  while (!acceptable && turn < 100); - -  DBG (DBG_info, "gl124_led_calibration: acceptable exposure: %d,%d,%d\n", exp[0], exp[1], exp[2]); - -  /* set these values as final ones for scan */ -  sanei_genesys_set_triple(dev->reg,REG_EXPR,exp[0]); -  sanei_genesys_set_triple(dev->reg,REG_EXPG,exp[1]); -  sanei_genesys_set_triple(dev->reg,REG_EXPB,exp[2]); - -  /* store in this struct since it is the one used by cache calibration */ -  dev->sensor.regs_0x10_0x1d[0] = (exp[0] >> 8) & 0xff; -  dev->sensor.regs_0x10_0x1d[1] = exp[0] & 0xff; -  dev->sensor.regs_0x10_0x1d[2] = (exp[1] >> 8) & 0xff; -  dev->sensor.regs_0x10_0x1d[3] = exp[1] & 0xff; -  dev->sensor.regs_0x10_0x1d[4] = (exp[2] >> 8) & 0xff; -  dev->sensor.regs_0x10_0x1d[5] = exp[2] & 0xff; - -  /* cleanup before return */ -  free (line); - -  DBGCOMPLETED; -  return status; -} - -/** - * average dark pixels of a 8 bits scan - */ -static int -dark_average (uint8_t * data, unsigned int pixels, unsigned int lines, -	      unsigned int channels, unsigned int black) -{ -  unsigned int i, j, k, average, count; -  unsigned int avg[3]; -  uint8_t val; - -  /* computes average value on black margin */ -  for (k = 0; k < channels; k++) -    { -      avg[k] = 0; -      count = 0; -      for (i = 0; i < lines; i++) -	{ -	  for (j = 0; j < black; j++) -	    { -	      val = data[i * channels * pixels + j + k]; -	      avg[k] += val; -	      count++; -	    } -	} -      if (count) -	avg[k] /= count; -      DBG (DBG_info, "dark_average: avg[%d] = %d\n", k, avg[k]); -    } -  average = 0; -  for (i = 0; i < channels; i++) -    average += avg[i]; -  average /= channels; -  DBG (DBG_info, "dark_average: average = %d\n", average); -  return average; -} - - -static SANE_Status -gl124_offset_calibration (Genesys_Device * dev) -{ -  SANE_Status status = SANE_STATUS_GOOD; -  uint8_t *first_line, *second_line, reg0a; -  unsigned int channels, bpp; -  char title[32]; -  int pass = 0, avg, total_size; -  int topavg, bottomavg, resolution, lines; -  int top, bottom, black_pixels, pixels; - -  DBGSTART; - -  /* no gain nor offset for TI AFE */ -  RIE (sanei_genesys_read_register (dev, REG0A, ®0a)); -  if(((reg0a & REG0A_SIFSEL)>>REG0AS_SIFSEL)==3) -    { -      DBGCOMPLETED; -      return status; -    } - -  /* offset calibration is always done in color mode */ -  channels = 3; -  resolution=dev->sensor.optical_res; -  dev->calib_pixels = dev->sensor.sensor_pixels; -  lines=1; -  bpp=8; -  pixels= (dev->sensor.sensor_pixels*resolution) / dev->sensor.optical_res; -  black_pixels = (dev->sensor.black_pixels * resolution) / dev->sensor.optical_res; -  DBG (DBG_io2, "gl124_offset_calibration: black_pixels=%d\n", black_pixels); - -  status = gl124_init_scan_regs (dev, -				 dev->calib_reg, -				 resolution, -				 resolution, -				 0, -				 0, -				 pixels, -				 lines, -				 bpp, -				 channels, -                                 dev->settings.scan_method, -                                 SCAN_MODE_COLOR, -				 dev->settings.color_filter, -				 SCAN_FLAG_DISABLE_SHADING | -				 SCAN_FLAG_DISABLE_GAMMA | -				 SCAN_FLAG_SINGLE_LINE | -				 SCAN_FLAG_IGNORE_LINE_DISTANCE); -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, -	   "gl124_offset_calibration: failed to setup scan: %s\n", -	   sane_strstatus (status)); -      return status; -    } -  gl124_set_motor_power (dev->calib_reg, SANE_FALSE); - -  /* allocate memory for scans */ -  total_size = pixels * channels * lines * (bpp/8);        /* colors * bytes_per_color * scan lines */ - -  first_line = malloc (total_size); -  if (!first_line) -    return SANE_STATUS_NO_MEM; - -  second_line = malloc (total_size); -  if (!second_line) -    { -      free (first_line); -      return SANE_STATUS_NO_MEM; -    } - -  /* init gain */ -  dev->frontend.gain[0] = 0; -  dev->frontend.gain[1] = 0; -  dev->frontend.gain[2] = 0; - -  /* scan with no move */ -  bottom = 10; -  dev->frontend.offset[0] = bottom; -  dev->frontend.offset[1] = bottom; -  dev->frontend.offset[2] = bottom; - -  RIEF2 (gl124_set_fe(dev, AFE_SET), first_line, second_line); -  RIEF2 (dev->model->cmd_set->bulk_write_register (dev, dev->calib_reg, GENESYS_GL124_MAX_REGS), first_line, second_line); -  DBG (DBG_info, "gl124_offset_calibration: starting first line reading\n"); -  RIEF2 (gl124_begin_scan (dev, dev->calib_reg, SANE_TRUE), first_line, second_line); -  RIEF2 (sanei_genesys_read_data_from_scanner (dev, first_line, total_size), first_line, second_line); -  if (DBG_LEVEL >= DBG_data) -   { -      snprintf(title,20,"offset%03d.pnm",bottom); -      sanei_genesys_write_pnm_file (title, first_line, bpp, channels, pixels, lines); -   } - -  bottomavg = dark_average (first_line, pixels, lines, channels, black_pixels); -  DBG (DBG_io2, "gl124_offset_calibration: bottom avg=%d\n", bottomavg); - -  /* now top value */ -  top = 255; -  dev->frontend.offset[0] = top; -  dev->frontend.offset[1] = top; -  dev->frontend.offset[2] = top; -  RIEF2 (gl124_set_fe(dev, AFE_SET), first_line, second_line); -  RIEF2 (dev->model->cmd_set->bulk_write_register (dev, dev->calib_reg, GENESYS_GL124_MAX_REGS), first_line, second_line); -  DBG (DBG_info, "gl124_offset_calibration: starting second line reading\n"); -  RIEF2 (gl124_begin_scan (dev, dev->calib_reg, SANE_TRUE), first_line, second_line); -  RIEF2 (sanei_genesys_read_data_from_scanner (dev, second_line, total_size), first_line, second_line); - -  topavg = dark_average (second_line, pixels, lines, channels, black_pixels); -  DBG (DBG_io2, "gl124_offset_calibration: top avg=%d\n", topavg); - -  /* loop until acceptable level */ -  while ((pass < 32) && (top - bottom > 1)) -    { -      pass++; - -      /* settings for new scan */ -      dev->frontend.offset[0] = (top + bottom) / 2; -      dev->frontend.offset[1] = (top + bottom) / 2; -      dev->frontend.offset[2] = (top + bottom) / 2; - -      /* scan with no move */ -      RIEF2 (gl124_set_fe(dev, AFE_SET), first_line, second_line); -      RIEF2 (dev->model->cmd_set->bulk_write_register (dev, dev->calib_reg, GENESYS_GL124_MAX_REGS), first_line, second_line); -      DBG (DBG_info, "gl124_offset_calibration: starting second line reading\n"); -      RIEF2 (gl124_begin_scan (dev, dev->calib_reg, SANE_TRUE), first_line, second_line); -      RIEF2 (sanei_genesys_read_data_from_scanner (dev, second_line, total_size), first_line, second_line); - -      if (DBG_LEVEL >= DBG_data) -	{ -	  sprintf (title, "offset%03d.pnm", dev->frontend.offset[1]); -	  sanei_genesys_write_pnm_file (title, second_line, bpp, channels, pixels, lines); -	} - -      avg = dark_average (second_line, pixels, lines, channels, black_pixels); -      DBG (DBG_info, "gl124_offset_calibration: avg=%d offset=%d\n", avg, -	   dev->frontend.offset[1]); - -      /* compute new boundaries */ -      if (topavg == avg) -	{ -	  topavg = avg; -	  top = dev->frontend.offset[1]; -	} -      else -	{ -	  bottomavg = avg; -	  bottom = dev->frontend.offset[1]; -	} -    } -  DBG (DBG_info, "gl124_offset_calibration: offset=(%d,%d,%d)\n", dev->frontend.offset[0], dev->frontend.offset[1], dev->frontend.offset[2]); - -  /* cleanup before return */ -  free (first_line); -  free (second_line); - -  DBGCOMPLETED; -  return SANE_STATUS_GOOD; -} - - -/* alternative coarse gain calibration -   this on uses the settings from offset_calibration and -   uses only one scanline - */ -/* -  with offset and coarse calibration we only want to get our input range into -  a reasonable shape. the fine calibration of the upper and lower bounds will -  be done with shading. - */ -static SANE_Status -gl124_coarse_gain_calibration (Genesys_Device * dev, int dpi) -{ -  int pixels; -  int total_size; -  uint8_t *line, reg0a; -  int i, j, channels; -  SANE_Status status = SANE_STATUS_GOOD; -  int max[3]; -  float gain[3],coeff; -  int val, code, lines; -  int resolution; -  int bpp; - -  DBG (DBG_proc, "gl124_coarse_gain_calibration: dpi = %d\n", dpi); - -  /* no gain nor offset for TI AFE */ -  RIE (sanei_genesys_read_register (dev, REG0A, ®0a)); -  if(((reg0a & REG0A_SIFSEL)>>REG0AS_SIFSEL)==3) -    { -      DBGCOMPLETED; -      return status; -    } - -  /* coarse gain calibration is always done in color mode */ -  channels = 3; - -  /* follow CKSEL */ -  if(dev->settings.xres<dev->sensor.optical_res) -    { -      coeff=0.9; -      /*resolution=dev->sensor.optical_res/2;*/ -      resolution=dev->sensor.optical_res; -    } -  else -    { -      resolution=dev->sensor.optical_res; -      coeff=1.0; -    } -  lines=10; -  bpp=8; -  pixels = (dev->sensor.sensor_pixels * resolution) / dev->sensor.optical_res; - -  status = gl124_init_scan_regs (dev, -				 dev->calib_reg, -				 resolution, -				 resolution, -				 0, -				 0, -				 pixels, -                                 lines, -                                 bpp, -                                 channels, -                                 dev->settings.scan_method, -                                 SCAN_MODE_COLOR, -				 dev->settings.color_filter, -				 SCAN_FLAG_DISABLE_SHADING | -				 SCAN_FLAG_DISABLE_GAMMA | -				 SCAN_FLAG_SINGLE_LINE | -				 SCAN_FLAG_IGNORE_LINE_DISTANCE); -  gl124_set_motor_power (dev->calib_reg, SANE_FALSE); - -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, -	   "gl124_coarse_calibration: failed to setup scan: %s\n", -	   sane_strstatus (status)); -      return status; -    } - -  RIE (dev->model->cmd_set->bulk_write_register -       (dev, dev->calib_reg, GENESYS_GL124_MAX_REGS)); - -  total_size = pixels * channels * (16/bpp) * lines; - -  line = malloc (total_size); -  if (!line) -    return SANE_STATUS_NO_MEM; - -  RIEF (gl124_set_fe(dev, AFE_SET), line); -  RIEF (gl124_begin_scan (dev, dev->calib_reg, SANE_TRUE), line); -  RIEF (sanei_genesys_read_data_from_scanner (dev, line, total_size), line); - -  if (DBG_LEVEL >= DBG_data) -    sanei_genesys_write_pnm_file ("coarse.pnm", line, bpp, channels, pixels, lines); - -  /* average value on each channel */ -  for (j = 0; j < channels; j++) -    { -      max[j] = 0; -      for (i = pixels/4; i < (pixels*3/4); i++) -	{ -          if(bpp==16) -            { -	  if (dev->model->is_cis) -	    val = -	      line[i * 2 + j * 2 * pixels + 1] * 256 + -	      line[i * 2 + j * 2 * pixels]; -	  else -	    val = -	      line[i * 2 * channels + 2 * j + 1] * 256 + -	      line[i * 2 * channels + 2 * j]; -            } -          else -            { -	  if (dev->model->is_cis) -	    val = line[i + j * pixels]; -	  else -	    val = line[i * channels + j]; -            } - -	    max[j] += val; -	} -      max[j] = max[j] / (pixels/2); - -      gain[j] = ((float) dev->sensor.gain_white_ref*coeff) / max[j]; - -      /* turn logical gain value into gain code, checking for overflow */ -      code = 283 - 208 / gain[j]; -      if (code > 255) -	code = 255; -      else if (code < 0) -	code = 0; -      dev->frontend.gain[j] = code; - -      DBG (DBG_proc, -	   "gl124_coarse_gain_calibration: channel %d, max=%d, gain = %f, setting:%d\n", -	   j, max[j], gain[j], dev->frontend.gain[j]); -    } - -  if (dev->model->is_cis) -    { -      if (dev->frontend.gain[0] > dev->frontend.gain[1]) -	dev->frontend.gain[0] = dev->frontend.gain[1]; -      if (dev->frontend.gain[0] > dev->frontend.gain[2]) -	dev->frontend.gain[0] = dev->frontend.gain[2]; -      dev->frontend.gain[2] = dev->frontend.gain[1] = dev->frontend.gain[0]; -    } - -  if (channels == 1) -    { -      dev->frontend.gain[0] = dev->frontend.gain[1]; -      dev->frontend.gain[2] = dev->frontend.gain[1]; -    } - -  free (line); - -  RIE (gl124_stop_action (dev)); - -  status = gl124_slow_back_home (dev, SANE_TRUE); - -  DBGCOMPLETED; -  return status; -} - -/* - * wait for lamp warmup by scanning the same line until difference - * between 2 scans is below a threshold - */ -static SANE_Status -gl124_init_regs_for_warmup (Genesys_Device * dev, -			    Genesys_Register_Set * reg, -			    int *channels, int *total_size) -{ -  int num_pixels; -  SANE_Status status = SANE_STATUS_GOOD; - -  DBGSTART; -  if (dev == NULL || reg == NULL || channels == NULL || total_size == NULL) -    return SANE_STATUS_INVAL; - -  *channels=3; - -  memcpy (reg, dev->reg, (GENESYS_GL124_MAX_REGS + 1) * sizeof (Genesys_Register_Set)); -  status = gl124_init_scan_regs (dev, -				 reg, -				 dev->sensor.optical_res, -				 dev->motor.base_ydpi, -				 dev->sensor.sensor_pixels/4, -				 0, -				 dev->sensor.sensor_pixels/2, -				 1, -				 8, -				 *channels, -                                 dev->settings.scan_method, -                                 SCAN_MODE_COLOR, -				 dev->settings.color_filter, -				 SCAN_FLAG_DISABLE_SHADING | -				 SCAN_FLAG_DISABLE_GAMMA | -				 SCAN_FLAG_SINGLE_LINE | -				 SCAN_FLAG_IGNORE_LINE_DISTANCE); - -  if (status != SANE_STATUS_GOOD) -    { -      DBG (DBG_error, -	   "gl124_init_regs_for_warmup: failed to setup scan: %s\n", -	   sane_strstatus (status)); -      return status; -    } - -  num_pixels = dev->current_setup.pixels; - -  *total_size = num_pixels * 3 * 1;        /* colors * bytes_per_color * scan lines */ - -  gl124_set_motor_power (reg, SANE_FALSE); -  RIE (dev->model->cmd_set->bulk_write_register (dev, reg, GENESYS_GL124_MAX_REGS)); - -  DBGCOMPLETED; -  return SANE_STATUS_GOOD; -} - -/** @brief default GPIO values - * set up GPIO/GPOE for idle state - * @param dev device to set up - * @return SANE_STATUS_GOOD unless a GPIO register cannot be written - */ -static SANE_Status -gl124_init_gpio (Genesys_Device * dev) -{ -  SANE_Status status = SANE_STATUS_GOOD; -  int idx; - -  DBGSTART; - -  /* per model GPIO layout */ -  if (strcmp (dev->model->name, "canon-lide-110") == 0) -    { -      idx = 0; -    } -  else if (strcmp (dev->model->name, "canon-lide-110") == 0) -    { -      idx = 2; -    } -  else -    {                                /* canon LiDE 210 and 220 case */ -      idx = 1; -    } - -  RIE (sanei_genesys_write_register (dev, REG31, gpios[idx].r31)); -  RIE (sanei_genesys_write_register (dev, REG32, gpios[idx].r32)); -  RIE (sanei_genesys_write_register (dev, REG33, gpios[idx].r33)); -  RIE (sanei_genesys_write_register (dev, REG34, gpios[idx].r34)); -  RIE (sanei_genesys_write_register (dev, REG35, gpios[idx].r35)); -  RIE (sanei_genesys_write_register (dev, REG36, gpios[idx].r36)); -  RIE (sanei_genesys_write_register (dev, REG38, gpios[idx].r38)); - -  DBGCOMPLETED; -  return status; -} - -/** - * set memory layout by filling values in dedicated registers - */ -static SANE_Status -gl124_init_memory_layout (Genesys_Device * dev) -{ -  SANE_Status status = SANE_STATUS_GOOD; -  int idx = 0; - -  DBGSTART; - -  /* point to per model memory layout */ -  if ((strcmp (dev->model->name, "canon-lide-110") == 0) -    ||(strcmp (dev->model->name, "canon-lide-120") == 0)) -    { -      idx = 0; -    } -  else -    {                                /* canon LiDE 210 and 220 case */ -      idx = 1; -    } - -  /* setup base address for shading data. */ -  /* values must be multiplied by 8192=0x4000 to give address on AHB */ -  /* R-Channel shading bank0 address setting for CIS */ -  sanei_genesys_write_register (dev, 0xd0, layouts[idx].rd0); -  /* G-Channel shading bank0 address setting for CIS */ -  sanei_genesys_write_register (dev, 0xd1, layouts[idx].rd1); -  /* B-Channel shading bank0 address setting for CIS */ -  sanei_genesys_write_register (dev, 0xd2, layouts[idx].rd2); - -  /* setup base address for scanned data. */ -  /* values must be multiplied by 1024*2=0x0800 to give address on AHB */ -  /* R-Channel ODD image buffer 0x0124->0x92000 */ -  /* size for each buffer is 0x16d*1k word */ -  sanei_genesys_write_register (dev, 0xe0, layouts[idx].re0); -  sanei_genesys_write_register (dev, 0xe1, layouts[idx].re1); -  /* R-Channel ODD image buffer end-address 0x0291->0x148800 => size=0xB6800*/ -  sanei_genesys_write_register (dev, 0xe2, layouts[idx].re2); -  sanei_genesys_write_register (dev, 0xe3, layouts[idx].re3); - -  /* R-Channel EVEN image buffer 0x0292 */ -  sanei_genesys_write_register (dev, 0xe4, layouts[idx].re4); -  sanei_genesys_write_register (dev, 0xe5, layouts[idx].re5); -  /* R-Channel EVEN image buffer end-address 0x03ff*/ -  sanei_genesys_write_register (dev, 0xe6, layouts[idx].re6); -  sanei_genesys_write_register (dev, 0xe7, layouts[idx].re7); - -  /* same for green, since CIS, same addresses */ -  sanei_genesys_write_register (dev, 0xe8, layouts[idx].re0); -  sanei_genesys_write_register (dev, 0xe9, layouts[idx].re1); -  sanei_genesys_write_register (dev, 0xea, layouts[idx].re2); -  sanei_genesys_write_register (dev, 0xeb, layouts[idx].re3); -  sanei_genesys_write_register (dev, 0xec, layouts[idx].re4); -  sanei_genesys_write_register (dev, 0xed, layouts[idx].re5); -  sanei_genesys_write_register (dev, 0xee, layouts[idx].re6); -  sanei_genesys_write_register (dev, 0xef, layouts[idx].re7); - -/* same for blue, since CIS, same addresses */ -  sanei_genesys_write_register (dev, 0xf0, layouts[idx].re0); -  sanei_genesys_write_register (dev, 0xf1, layouts[idx].re1); -  sanei_genesys_write_register (dev, 0xf2, layouts[idx].re2); -  sanei_genesys_write_register (dev, 0xf3, layouts[idx].re3); -  sanei_genesys_write_register (dev, 0xf4, layouts[idx].re4); -  sanei_genesys_write_register (dev, 0xf5, layouts[idx].re5); -  sanei_genesys_write_register (dev, 0xf6, layouts[idx].re6); -  sanei_genesys_write_register (dev, 0xf7, layouts[idx].re7); - -  DBGCOMPLETED; -  return status; -} - -/** - * initialize backend and ASIC : registers, motor tables, and gamma tables - * then ensure scanner's head is at home - */ -#ifndef UNIT_TESTING -static -#endif -SANE_Status -gl124_init (Genesys_Device * dev) -{ -  SANE_Status status; - -  DBG_INIT (); -  DBGSTART; - -  status=sanei_genesys_asic_init(dev, GENESYS_GL124_MAX_REGS); - -  DBGCOMPLETED; -  return status; -} - - -/* * - * initialize ASIC from power on condition - */ -static SANE_Status -gl124_boot (Genesys_Device * dev, SANE_Bool cold) -{ -  SANE_Status status; -  uint8_t val; - -  DBGSTART; - -  /* reset ASIC in case of cold boot */ -  if(cold) -    { -      RIE (sanei_genesys_write_register (dev, 0x0e, 0x01)); -      RIE (sanei_genesys_write_register (dev, 0x0e, 0x00)); -    } - -  /* enable GPOE 17 */ -  RIE (sanei_genesys_write_register (dev, 0x36, 0x01)); - -  /* set GPIO 17 */ -  RIE (sanei_genesys_read_register (dev, 0x33, &val)); -  val |= 0x01; -  RIE (sanei_genesys_write_register (dev, 0x33, val)); - -  /* test CHKVER */ -  RIE (sanei_genesys_read_register (dev, REG100, &val)); -  if (val & REG100_CHKVER) -    { -      RIE (sanei_genesys_read_register (dev, 0x00, &val)); -      DBG (DBG_info, -	   "gl124_cold_boot: reported version for genesys chip is 0x%02x\n", -	   val); -    } - -  /* Set default values for registers */ -  gl124_init_registers (dev); - -  /* Write initial registers */ -  RIE (dev->model->cmd_set->bulk_write_register (dev, dev->reg, GENESYS_GL124_MAX_REGS)); - -  /* tune reg 0B */ -  val = REG0B_30MHZ | REG0B_ENBDRAM | REG0B_64M; -  RIE (sanei_genesys_write_register (dev, REG0B, val)); -  dev->reg[reg_0x0b].address = 0x00; - -  /* set up end access */ -  RIE (sanei_genesys_write_0x8c (dev, 0x10, 0x0b)); -  RIE (sanei_genesys_write_0x8c (dev, 0x13, 0x0e)); - -  /* CIS_LINE */ -  SETREG (0x08, REG08_CIS_LINE); -  RIE (sanei_genesys_write_register (dev, 0x08, dev->reg[reg_0x08].value)); - -  /* setup gpio */ -  RIE (gl124_init_gpio (dev)); - -  /* setup internal memory layout */ -  RIE (gl124_init_memory_layout (dev)); - -  DBGCOMPLETED; -  return SANE_STATUS_GOOD; -} - - -static SANE_Status -gl124_update_hardware_sensors (Genesys_Scanner * s) -{ -  /* do what is needed to get a new set of events, but try to not loose -     any of them. -   */ -  SANE_Status status = SANE_STATUS_GOOD; -  uint8_t val=0; - -  RIE (sanei_genesys_read_register (s->dev, REG31, &val)); - -  /* TODO : for the next scanner special case, -   * add another per scanner button profile struct to avoid growing -   * hard-coded button mapping here. -   */ -  if((s->dev->model->gpo_type == GPO_CANONLIDE110) -    ||(s->dev->model->gpo_type == GPO_CANONLIDE120)) -    { -      if (s->val[OPT_SCAN_SW].b == s->last_val[OPT_SCAN_SW].b) -        s->val[OPT_SCAN_SW].b = (val & 0x01) == 0; -      if (s->val[OPT_FILE_SW].b == s->last_val[OPT_FILE_SW].b) -        s->val[OPT_FILE_SW].b = (val & 0x08) == 0; -      if (s->val[OPT_EMAIL_SW].b == s->last_val[OPT_EMAIL_SW].b) -        s->val[OPT_EMAIL_SW].b = (val & 0x04) == 0; -      if (s->val[OPT_COPY_SW].b == s->last_val[OPT_COPY_SW].b) -        s->val[OPT_COPY_SW].b = (val & 0x02) == 0; -    } -  else -    { /* LiDE 210 case */ -      if (s->val[OPT_EXTRA_SW].b == s->last_val[OPT_EXTRA_SW].b) -        s->val[OPT_EXTRA_SW].b = (val & 0x01) == 0; -      if (s->val[OPT_SCAN_SW].b == s->last_val[OPT_SCAN_SW].b) -        s->val[OPT_SCAN_SW].b = (val & 0x02) == 0; -      if (s->val[OPT_COPY_SW].b == s->last_val[OPT_COPY_SW].b) -        s->val[OPT_COPY_SW].b = (val & 0x04) == 0; -      if (s->val[OPT_EMAIL_SW].b == s->last_val[OPT_EMAIL_SW].b) -        s->val[OPT_EMAIL_SW].b = (val & 0x08) == 0; -      if (s->val[OPT_FILE_SW].b == s->last_val[OPT_FILE_SW].b) -        s->val[OPT_FILE_SW].b = (val & 0x10) == 0; -    } -  return status; -} - - -/** the gl124 command set */ -static Genesys_Command_Set gl124_cmd_set = { -  "gl124-generic",                /* the name of this set */ - -  gl124_init, -  gl124_init_regs_for_warmup, -  gl124_init_regs_for_coarse_calibration, -  gl124_init_regs_for_shading, -  gl124_init_regs_for_scan, - -  gl124_get_filter_bit, -  gl124_get_lineart_bit, -  gl124_get_bitset_bit, -  gl124_get_gain4_bit, -  gl124_get_fast_feed_bit, -  gl124_test_buffer_empty_bit, -  gl124_test_motor_flag_bit, - -  gl124_bulk_full_size, - -  gl124_set_fe, -  gl124_set_powersaving, -  gl124_save_power, - -  gl124_set_motor_power, -  gl124_set_lamp_power, - -  gl124_begin_scan, -  gl124_end_scan, - -  sanei_genesys_send_gamma_table, - -  gl124_search_start_position, - -  gl124_offset_calibration, -  gl124_coarse_gain_calibration, -  gl124_led_calibration, - -  gl124_slow_back_home, -  gl124_rewind, - -  sanei_genesys_bulk_write_register, -  NULL, -  gl124_bulk_read_data, - -  gl124_update_hardware_sensors, - -  /* no sheetfed support for now */ -  NULL, -  NULL, -  NULL, -  NULL, - -  sanei_genesys_is_compatible_calibration, -  NULL, -  gl124_send_shading_data, -  gl124_calculate_current_setup, -  gl124_boot, -  gl124_init_scan_regs -}; - -SANE_Status -sanei_gl124_init_cmd_set (Genesys_Device * dev) -{ -  dev->model->cmd_set = &gl124_cmd_set; -  return SANE_STATUS_GOOD; -} - -/* vim: set sw=2 cino=>2se-1sn-1s{s^-1st0(0u0 smarttab expandtab: */  | 
