kopia lustrzana https://gitlab.com/sane-project/backends
				
				
				
			
		
			
				
	
	
		
			2915 wiersze
		
	
	
		
			66 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			2915 wiersze
		
	
	
		
			66 KiB
		
	
	
	
		
			C
		
	
	
| /* sane - Scanner Access Now Easy.
 | |
| 
 | |
|    Copyright (C) 2000 Mustek.
 | |
|    Originally maintained by Tom Wang <tom.wang@mustek.com.tw>
 | |
| 
 | |
|    Copyright (C) 2001 - 2004 by Henning Meier-Geinitz.
 | |
| 
 | |
|    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.
 | |
| 
 | |
|    This file implements a SANE backend for Mustek 1200UB and similar 
 | |
|    USB flatbed scanners.  */
 | |
| 
 | |
| #include <unistd.h>
 | |
| 
 | |
| #include "../include/sane/sane.h"
 | |
| #include "../include/sane/sanei_usb.h"
 | |
| #include "mustek_usb_low.h"
 | |
| 
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_init (ma1017 ** chip_address)
 | |
| {
 | |
|   SANE_Int i;
 | |
|   ma1017 *chip;
 | |
| 
 | |
|   DBG (7, "usb_low_init: start\n");
 | |
|   if (!chip_address)
 | |
|     return SANE_STATUS_INVAL;
 | |
| 
 | |
|   chip = (ma1017 *) malloc (sizeof (ma1017));
 | |
| 
 | |
|   if (!chip)
 | |
|     {
 | |
|       DBG (3, "usb_low_init: couldn't malloc %ld bytes for chip\n",
 | |
| 	   (long int) sizeof (ma1017));
 | |
|       *chip_address = 0;
 | |
|       return SANE_STATUS_NO_MEM;
 | |
|     }
 | |
|   *chip_address = chip;
 | |
| 
 | |
|   /* io */
 | |
|   chip->is_rowing = SANE_FALSE;
 | |
|   chip->is_opened = SANE_FALSE;
 | |
|   chip->fd = -1;
 | |
| 
 | |
|   /* Construction/Destruction */
 | |
|   chip->is_opened = SANE_FALSE;
 | |
|   chip->is_rowing = SANE_FALSE;
 | |
| 
 | |
|   /* A2 */
 | |
|   chip->append = 0x00;
 | |
|   chip->test_sram = 0x00;
 | |
|   chip->fix_pattern = 0x00;
 | |
|   /* A4 */
 | |
|   chip->select = 0x00;
 | |
|   chip->frontend = 0x00;
 | |
|   /* A6 */
 | |
|   chip->rgb_sel_pin = 0x02;
 | |
|   chip->asic_io_pins = 0x9c;
 | |
|   /* A7 */
 | |
|   chip->timing = 0xe8;
 | |
|   chip->sram_bank = 0x02;
 | |
|   /* A8 */
 | |
|   chip->dummy_msb = 0x00;
 | |
|   chip->ccd_width_msb = 0x00;
 | |
|   chip->cmt_table_length = 0x00;
 | |
|   /* A9 */
 | |
|   chip->cmt_second_pos = 0x00;
 | |
|   /* A10 + A8ID5 */
 | |
|   chip->ccd_width = 0x0c80;
 | |
|   /* A11 + A8ID6 */
 | |
|   chip->dummy = 0x0020;
 | |
|   /* A12 + A13 */
 | |
|   chip->byte_width = 0x09f6;
 | |
|   /* A14 + A30W */
 | |
|   chip->loop_count = 0x0db5;
 | |
|   /* A15 */
 | |
|   chip->motor_enable = 0x00;
 | |
|   chip->motor_movement = 0x60;
 | |
|   chip->motor_direction = 0x10;
 | |
|   chip->motor_signal = 0x00;
 | |
|   chip->motor_home = 0x00;
 | |
|   /* A16 */
 | |
|   chip->pixel_depth = 0x00;
 | |
|   chip->image_invert = 0x00;
 | |
|   chip->optical_600 = 0x00;
 | |
|   chip->sample_way = 0x06;
 | |
|   /* A17 + A18 + A19 */
 | |
|   chip->red_ref = 0xff;
 | |
|   chip->green_ref = 0xff;
 | |
|   chip->blue_ref = 0xff;
 | |
|   /* A20 + A21 + A22 */
 | |
|   chip->red_pd = 0x00;
 | |
|   chip->green_pd = 0x00;
 | |
|   chip->blue_pd = 0x00;
 | |
|   /* A23 */
 | |
|   chip->a23 = 0x80;
 | |
|   /* A24 */
 | |
|   chip->fy1_delay = 0x00;
 | |
|   chip->special_ad = 0x00;
 | |
|   /* A27 */
 | |
|   chip->sclk = 0x00;
 | |
|   chip->sen = 0x00;
 | |
|   chip->serial_length = 0x10;
 | |
| 
 | |
|   /* Use for Rowing */
 | |
|   chip->get_row = NULL;
 | |
| 
 | |
|   chip->cmt_table_length_word = 0x00000000;
 | |
|   chip->cmt_second_pos_word = 0x00000000;
 | |
|   chip->row_size = 0x00;
 | |
|   chip->soft_resample = 0x01;
 | |
|   chip->total_lines = 0x00;
 | |
|   chip->lines_left = 0x00;
 | |
|   for (i = 0; i < 32; i++)
 | |
|     chip->is_transfer_table[i] = SANE_FALSE;
 | |
|   chip->sensor = ST_CANON600;
 | |
|   chip->motor = MT_1200;
 | |
| 
 | |
|   chip->total_read_urbs = 0;
 | |
|   chip->total_write_urbs = 0;
 | |
|   DBG (7, "usb_low_init: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_exit (ma1017 * chip)
 | |
| {
 | |
|   DBG (7, "usb_low_exit: chip = %p\n", (void *) chip);
 | |
|   if (chip)
 | |
|     {
 | |
|       if (chip->fd >= 0 && chip->is_opened)
 | |
| 	usb_low_close (chip);
 | |
|       DBG (7, "usb_low_exit: freeing chip\n");
 | |
|       free (chip);
 | |
|     }
 | |
|   DBG (5, "usb_low_exit: read %d URBs, wrote %d URBs\n", 
 | |
|        chip->total_read_urbs, chip->total_write_urbs);
 | |
|   DBG (7, "usb_low_exit: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| /* A0 ~ A1 */
 | |
| SANE_Status
 | |
| usb_low_set_cmt_table (ma1017 * chip, SANE_Int index, Channel channel,
 | |
| 		       SANE_Bool is_move_motor, SANE_Bool is_transfer)
 | |
| {
 | |
|   SANE_Byte pattern = ((SANE_Byte) index) << 4;
 | |
|   SANE_Byte reg_no = 0;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_cmt_table: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_cmt_table: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_cmt_table: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if ((unsigned int) index > 31)
 | |
|     {
 | |
|       DBG (7, "usb_low_set_cmt_table: CMT index (%d) exceed 31", index);
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   switch (channel)
 | |
|     {
 | |
|     case CH_RED:
 | |
|       pattern |= 0x04;
 | |
|       break;
 | |
|     case CH_GREEN:
 | |
|       pattern |= 0x08;
 | |
|       break;
 | |
|     case CH_BLUE:
 | |
|       pattern |= 0x0c;
 | |
|       break;
 | |
|     default:
 | |
|       break;
 | |
|     }
 | |
|   if (is_move_motor)
 | |
|     pattern |= 0x02;
 | |
|   if (is_transfer)
 | |
|     pattern |= 0x01;
 | |
|   if (index > 15)
 | |
|     reg_no++;
 | |
| 
 | |
|   RIE (usb_low_write_reg (chip, reg_no, pattern));
 | |
| 
 | |
|   chip->is_transfer_table[index] = is_transfer;
 | |
| 
 | |
|   DBG (7, "usb_low_set_cmt_table: exit\n");
 | |
| 
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| /* A2 */
 | |
| SANE_Status
 | |
| usb_low_get_a2 (ma1017 * chip, SANE_Byte * value)
 | |
| {
 | |
|   SANE_Byte pattern;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a2: start\n");
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a2: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a2: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   RIE (usb_low_read_reg (chip, 2, &pattern));
 | |
| 
 | |
|   chip->append = pattern & 0x10;
 | |
|   chip->test_sram = pattern & 0x20;
 | |
|   chip->fix_pattern = pattern & 0x80;
 | |
|   if (value)
 | |
|     *value = pattern;
 | |
|   DBG (7, "usb_low_get_a2: exit, value =%d\n", pattern);
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_start_cmt_table (ma1017 * chip)
 | |
| {
 | |
|   SANE_Byte data_field[2];
 | |
|   SANE_Status status;
 | |
|   size_t n;
 | |
| 
 | |
|   DBG (7, "usb_low_start_cmt_table: start\n");
 | |
| 
 | |
|   data_field[0] = 0x02 | chip->append | chip->test_sram | chip->fix_pattern;
 | |
|   data_field[1] = 2;
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_start_cmt_table: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (7, "usb_low_start_cmt_table: Already Rowing\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   data_field[1] |= 0x60;
 | |
|   n = 2;
 | |
|   status = sanei_usb_write_bulk (chip->fd, data_field, &n);
 | |
|   if (status != SANE_STATUS_GOOD || n != 2)
 | |
|     {
 | |
|       DBG (3, "usb_low_start_cmt_table: can't write, wanted 2 bytes, "
 | |
| 	   "wrote %lu bytes\n", (unsigned long int) n);
 | |
|       return SANE_STATUS_IO_ERROR;
 | |
|     }
 | |
|   chip->total_write_urbs++;
 | |
|   chip->is_rowing = SANE_TRUE;
 | |
|   DBG (7, "usb_low_start_cmt_table: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_stop_cmt_table (ma1017 * chip)
 | |
| {
 | |
|   SANE_Byte data_field[2];
 | |
|   SANE_Byte read_byte;
 | |
|   size_t n;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_stop_cmt_table: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_stop_cmt_table: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (!chip->is_rowing)
 | |
|     {
 | |
|       DBG (7, "usb_low_stop_cmt_table: Not Rowing yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   data_field[0] = 0x01 | chip->append | chip->test_sram | chip->fix_pattern;
 | |
|   data_field[1] = 2;
 | |
|   data_field[1] |= 0x80;
 | |
|   n = 2;
 | |
|   status = sanei_usb_write_bulk (chip->fd, data_field, &n);
 | |
|   if (status != SANE_STATUS_GOOD || n != 2)
 | |
|     {
 | |
|       DBG (3, "usb_low_stop_cmt_table: couldn't write, wanted 2 bytes, wrote "
 | |
| 	   "%lu bytes\n", (unsigned long int) n);
 | |
|       return SANE_STATUS_IO_ERROR;
 | |
|     }
 | |
|   chip->total_write_urbs++;
 | |
|   n = 1;
 | |
|   status = sanei_usb_read_bulk (chip->fd, &read_byte, &n);
 | |
|   if (status != SANE_STATUS_GOOD || n != 1)
 | |
|     {
 | |
|       DBG (3, "usb_low_stop_cmt_table: couldn't read, wanted 1 byte, got %lu "
 | |
| 	   "bytes\n", (unsigned long int) n);
 | |
|       return SANE_STATUS_IO_ERROR;
 | |
|     }
 | |
|   chip->total_read_urbs++;
 | |
|   chip->is_rowing = SANE_FALSE;
 | |
| 
 | |
|   DBG (7, "usb_low_stop_cmt_table: exit\n");
 | |
| 
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_test_sram_mode (ma1017 * chip, SANE_Bool is_test)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_test_sram_mode: start\n");
 | |
| 
 | |
|   data = chip->append | chip->test_sram | chip->fix_pattern;
 | |
|   reg_no = 2;
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_test_sram_mode: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_test_sram_mode: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   if (is_test)
 | |
|     chip->test_sram = 0x20;
 | |
|   else
 | |
|     chip->test_sram = 0x00;
 | |
| 
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_test_sram_mode: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_fix_pattern (ma1017 * chip, SANE_Bool is_fix)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_fix_pattern: start\n");
 | |
| 
 | |
|   data = chip->append | chip->test_sram | chip->fix_pattern;
 | |
|   reg_no = 2;
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_fix_pattern: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_fix_pattern: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   if (is_fix)
 | |
|     chip->fix_pattern = 0x80;
 | |
|   else
 | |
|     chip->fix_pattern = 0x00;
 | |
| 
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_fix_pattern: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_adjust_timing (ma1017 * chip, SANE_Byte data)
 | |
| {
 | |
|   SANE_Status status;
 | |
|   SANE_Byte reg_no;
 | |
| 
 | |
|   DBG (7, "usb_low_adjust_timing: start\n");
 | |
| 
 | |
|   reg_no = 3;
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_adjust_timing: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_adjust_timing: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_adjust_timing: exit\n");
 | |
| 
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| /* A4 */
 | |
| SANE_Status
 | |
| usb_low_get_a4 (ma1017 * chip, SANE_Byte * value)
 | |
| {
 | |
|   SANE_Status status;
 | |
|   SANE_Byte pattern;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a4: start\n");
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a4: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a4: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   RIE (usb_low_read_reg (chip, 4, &pattern));
 | |
| 
 | |
|   chip->select = pattern & 0xfe;
 | |
|   chip->frontend = pattern & 0x01;
 | |
| 
 | |
|   if (value)
 | |
|     *value = pattern;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a4: exit, value=%d\n", pattern);
 | |
| 
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_select_timing (ma1017 * chip, SANE_Byte data)
 | |
| {
 | |
|   SANE_Status status;
 | |
|   SANE_Byte reg_no;
 | |
| 
 | |
|   DBG (7, "usb_low_select_timing: start\n");
 | |
| 
 | |
|   reg_no = 4;
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_select_timing: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_select_timing: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->select = data & 0xfe;
 | |
|   chip->frontend = data & 0x01;
 | |
| 
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_select_timing: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_turn_frontend_mode (ma1017 * chip, SANE_Bool is_on)
 | |
| {
 | |
|   SANE_Status status;
 | |
|   SANE_Byte data, reg_no;
 | |
| 
 | |
|   DBG (7, "usb_low_turn_frontend_mode: start\n");
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_turn_frontend_mode: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_turn_frontend_mode: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   if (is_on)
 | |
|     chip->frontend = 0x01;
 | |
|   else
 | |
|     chip->frontend = 0x00;
 | |
| 
 | |
|   data = chip->select | chip->frontend;
 | |
|   reg_no = 4;
 | |
| 
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_turn_frontend_mode: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| /* A6 */
 | |
| SANE_Status
 | |
| usb_low_get_a6 (ma1017 * chip, SANE_Byte * value)
 | |
| {
 | |
|   SANE_Byte pattern;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a6: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a6: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a6: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   RIE (usb_low_read_reg (chip, 6, &pattern));
 | |
| 
 | |
|   chip->asic_io_pins = pattern & 0xdc;
 | |
|   chip->rgb_sel_pin = pattern & 0x03;
 | |
| 
 | |
|   if (value)
 | |
|     *value = pattern;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a6: exit\n");
 | |
| 
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_asic_io_pins (ma1017 * chip, SANE_Byte data)
 | |
| {
 | |
|   SANE_Status status;
 | |
|   SANE_Byte reg_no;
 | |
| 
 | |
|   DBG (7, "usb_low_set_asic_io_pins: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_asic_io_pins: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_asic_io_pins: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->asic_io_pins = data & 0xdc;
 | |
| 
 | |
|   data = chip->asic_io_pins | chip->rgb_sel_pin;
 | |
|   reg_no = 6;
 | |
| 
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_asic_io_pins: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_rgb_sel_pins (ma1017 * chip, SANE_Byte data)
 | |
| {
 | |
|   SANE_Status status;
 | |
|   SANE_Byte reg_no;
 | |
| 
 | |
|   DBG (7, "usb_low_set_rgb_sel_pins: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_rgb_sel_pins: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_rgb_sel_pins: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   chip->rgb_sel_pin = data & 0x03;
 | |
|   data = chip->asic_io_pins | chip->rgb_sel_pin;
 | |
|   reg_no = 6;
 | |
| 
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_rgb_sel_pins: exit\n");
 | |
|   return SANE_STATUS_GOOD;	/* was false? */
 | |
| }
 | |
| 
 | |
| /* A7 */
 | |
| SANE_Status
 | |
| usb_low_get_a7 (ma1017 * chip, SANE_Byte * value)
 | |
| {
 | |
|   SANE_Byte pattern;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a7: start\n");
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a7: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a7: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   RIE (usb_low_read_reg (chip, 7, &pattern));
 | |
| 
 | |
|   if (value)
 | |
|     *value = pattern;
 | |
| 
 | |
|   chip->timing = pattern & 0xfc;
 | |
|   chip->sram_bank = pattern & 0x03;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a7: exit\n");
 | |
| 
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_timing (ma1017 * chip, SANE_Byte data)
 | |
| {
 | |
|   SANE_Status status;
 | |
|   SANE_Byte reg_no;
 | |
| 
 | |
|   DBG (7, "usb_low_set_timing: start\n");
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_timing: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_timing: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->timing = data & 0xfc;
 | |
|   data = chip->timing | chip->sram_bank;
 | |
|   reg_no = 7;
 | |
| 
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_timing: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_sram_bank (ma1017 * chip, Banksize banksize)
 | |
| {
 | |
|   SANE_Status status;
 | |
|   SANE_Byte data, reg_no;
 | |
| 
 | |
|   DBG (7, "usb_low_set_sram_bank: start\n");
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_sram_bank: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_sram_bank: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   switch (banksize)
 | |
|     {
 | |
|     case BS_4K:
 | |
|       chip->sram_bank = 0x00;
 | |
|       break;
 | |
|     case BS_8K:
 | |
|       chip->sram_bank = 0x01;
 | |
|       break;
 | |
|     case BS_16K:
 | |
|       chip->sram_bank = 0x02;
 | |
|       break;
 | |
|     default:
 | |
|       DBG (3, "usb_low_set_sram_bank: bsBankSize error\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|       break;
 | |
|     }
 | |
|   data = chip->timing | chip->sram_bank;
 | |
|   reg_no = 7;
 | |
| 
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_sram_bank: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| /* A8 */
 | |
| SANE_Status
 | |
| usb_low_get_a8 (ma1017 * chip, SANE_Byte * value)
 | |
| {
 | |
|   SANE_Byte pattern;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a8: start\n");
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a8: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a8: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   RIE (usb_low_read_reg (chip, 8, &pattern));
 | |
| 
 | |
|   chip->dummy_msb = pattern & 0x40;
 | |
|   chip->ccd_width_msb = pattern & 0x20;
 | |
|   chip->cmt_table_length = pattern & 0x1f;
 | |
|   chip->ccd_width =
 | |
|     ((chip->ccd_width / 32) & 0x00ff) * 32 +
 | |
|     ((chip->ccd_width_msb == 0) ? 0 : 0x0100 * 32);
 | |
|   chip->dummy =
 | |
|     ((chip->dummy / 32) & 0x00ff) * 32 +
 | |
|     ((chip->dummy_msb == 0) ? 0 : 0x0100 * 32);
 | |
| 
 | |
|   if (value)
 | |
|     *value = pattern;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a8: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_cmt_table_length (ma1017 * chip, SANE_Byte table_length)
 | |
| {
 | |
|   SANE_Status status;
 | |
|   SANE_Byte data, reg_no;
 | |
| 
 | |
|   DBG (7, "usb_low_set_cmt_table_length: start\n");
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_cmt_table_length: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_cmt_table_length: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (table_length > 32)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_cmt_table_length: length %d exceeds 32\n",
 | |
| 	   (int) table_length);
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (table_length == 0)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_cmt_table_length: length is 0\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->cmt_table_length = table_length - 1;
 | |
|   chip->cmt_table_length_word = (SANE_Word) table_length;
 | |
|   data = chip->cmt_table_length | chip->ccd_width_msb | chip->dummy_msb;
 | |
|   reg_no = 8;
 | |
| 
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_cmt_table_length: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| /* A9 */
 | |
| SANE_Status
 | |
| usb_low_get_a9 (ma1017 * chip, SANE_Byte * value)
 | |
| {
 | |
|   SANE_Byte pattern;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a9: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a9: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a9: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   RIE (usb_low_read_reg (chip, 9, &pattern));
 | |
| 
 | |
|   chip->cmt_second_pos = pattern & 0x1f;
 | |
| 
 | |
|   if (value)
 | |
|     *value = pattern;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a9: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_cmt_second_position (ma1017 * chip, SANE_Byte position)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_cmt_second_position: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_cmt_second_position: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_cmt_second_position: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (position > 31)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_cmt_second_position: length: %d exceeds 31\n",
 | |
| 	   (int) position);
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->cmt_second_pos = position;
 | |
|   chip->cmt_second_pos_word = (SANE_Word) (position);
 | |
|   data = chip->cmt_second_pos;
 | |
|   reg_no = 9;
 | |
| 
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_cmt_second_position: exit\n");
 | |
| 
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| /* A10 + A8ID5 */
 | |
| SANE_Status
 | |
| usb_low_get_a10 (ma1017 * chip, SANE_Byte * value)
 | |
| {
 | |
|   SANE_Byte pattern;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a10: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a10: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a10: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   RIE (usb_low_read_reg (chip, 10, &pattern));
 | |
| 
 | |
|   chip->ccd_width =
 | |
|     ((SANE_Word) (pattern)) * 32 +
 | |
|     ((chip->ccd_width_msb == 0) ? 0 : 0x0100 * 32);
 | |
| 
 | |
|   if (value)
 | |
|     *value = pattern;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a10: exit\n");
 | |
| 
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_ccd_width (ma1017 * chip, SANE_Word ccd_width)
 | |
| {
 | |
|   SANE_Status status;
 | |
|   SANE_Byte data, reg_no;
 | |
| 
 | |
|   DBG (7, "usb_low_set_ccd_width: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_ccd_width: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_ccd_width: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (ccd_width / 32 > 0x01ff)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_ccd_width: width %d too high\n", (int) ccd_width);
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->ccd_width = ccd_width;
 | |
|   ccd_width /= 32;
 | |
|   if (HIBYTE (ccd_width) == 0x01)
 | |
|     chip->ccd_width_msb = 0x20;
 | |
|   else
 | |
|     chip->ccd_width_msb = 0x00;
 | |
| 
 | |
|   data = chip->cmt_table_length | chip->ccd_width_msb | chip->dummy_msb;
 | |
|   reg_no = 8;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   data = LOBYTE (ccd_width);
 | |
|   reg_no = 10;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_ccd_width: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| /* A11 + A8ID6 */
 | |
| SANE_Status
 | |
| usb_low_get_a11 (ma1017 * chip, SANE_Byte * value)
 | |
| {
 | |
|   SANE_Byte pattern;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a11: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a11: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a11: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   RIE (usb_low_read_reg (chip, 11, &pattern));
 | |
| 
 | |
|   chip->dummy =
 | |
|     ((SANE_Word) (pattern)) * 32 + ((chip->dummy_msb == 0) ? 0 : 0x0100 * 32);
 | |
| 
 | |
|   if (value)
 | |
|     *value = pattern;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a11: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_dummy (ma1017 * chip, SANE_Word dummy)
 | |
| {
 | |
|   SANE_Status status;
 | |
|   SANE_Byte data, reg_no;
 | |
| 
 | |
|   DBG (7, "usb_low_set_dummy: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_dummy: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_dummy: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (dummy / 32 > 0x01ff)
 | |
|     {
 | |
|       DBG (7, "usb_low_set_dummy: width %d exceeded\n", (int) dummy);
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->dummy = dummy;
 | |
|   dummy /= 32;
 | |
|   dummy++;
 | |
|   if (HIBYTE (dummy) == 0x01)
 | |
|     chip->dummy_msb = 0x40;
 | |
|   else
 | |
|     chip->dummy_msb = 0x00;
 | |
|   data = chip->cmt_table_length | chip->ccd_width_msb | chip->dummy_msb;
 | |
|   reg_no = 8;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   data = LOBYTE (dummy);
 | |
|   reg_no = 11;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_dummy: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| /* A12 + A13 */
 | |
| SANE_Status
 | |
| usb_low_get_a12 (ma1017 * chip, SANE_Byte * value)
 | |
| {
 | |
|   SANE_Byte pattern;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a12: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a12: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a12: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   RIE (usb_low_read_reg (chip, 12, &pattern));
 | |
| 
 | |
|   chip->byte_width = (chip->byte_width & 0x3f00) + ((SANE_Word) pattern);
 | |
|   chip->soft_resample = (chip->soft_resample == 0) ? 1 : chip->soft_resample;
 | |
|   chip->get_row =
 | |
|     (chip->soft_resample == 1)
 | |
|     ? &usb_low_get_row_direct : &usb_low_get_row_resample;
 | |
|   chip->row_size = chip->byte_width / chip->soft_resample;
 | |
| 
 | |
|   if (value)
 | |
|     *value = pattern;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a12: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_get_a13 (ma1017 * chip, SANE_Byte * value)
 | |
| {
 | |
|   SANE_Byte pattern;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a13: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a13: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a13: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   RIE (usb_low_read_reg (chip, 13, &pattern));
 | |
| 
 | |
|   chip->byte_width =
 | |
|     (chip->byte_width & 0x00ff) + (((SANE_Word) (pattern & 0x3f)) << 8);
 | |
|   chip->soft_resample = (chip->soft_resample == 0) ? 1 : chip->soft_resample;
 | |
|   chip->get_row =
 | |
|     (chip->soft_resample ==
 | |
|      1) ? &usb_low_get_row_direct : &usb_low_get_row_resample;
 | |
|   chip->row_size = chip->byte_width / chip->soft_resample;
 | |
| 
 | |
|   if (value)
 | |
|     *value = pattern;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a13: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_image_byte_width (ma1017 * chip, SANE_Word row_size)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_image_byte_width: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_image_byte_width: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_image_byte_width: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->row_size = row_size;
 | |
|   chip->soft_resample = (chip->soft_resample == 0) ? 1 : chip->soft_resample;
 | |
|   chip->get_row = (chip->soft_resample == 1) ? &usb_low_get_row_direct
 | |
|     : &usb_low_get_row_resample;
 | |
|   chip->byte_width = chip->row_size * chip->soft_resample;
 | |
|   if (chip->byte_width > 0x3fff)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_image_byte_width: width %d exceeded\n",
 | |
| 	   (int) chip->byte_width);
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   data = LOBYTE (chip->byte_width);
 | |
|   reg_no = 12;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   data = HIBYTE (chip->byte_width);
 | |
|   reg_no = 13;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_image_byte_width: exit\n");
 | |
| 
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_soft_resample (ma1017 * chip, SANE_Word soft_resample)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_soft_resample: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_soft_resample: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_soft_resample: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (soft_resample == 0x00)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_soft_resample: soft_resample==0\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->soft_resample = soft_resample;
 | |
|   chip->get_row = (chip->soft_resample == 1) ? &usb_low_get_row_direct
 | |
|     : &usb_low_get_row_resample;
 | |
|   chip->byte_width = chip->row_size * chip->soft_resample;
 | |
|   if (chip->byte_width > 0x3fff)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_soft_resample: width %d exceeded",
 | |
| 	   (int) chip->byte_width);
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   data = LOBYTE (chip->byte_width);
 | |
|   reg_no = 12;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   data = HIBYTE (chip->byte_width);
 | |
|   reg_no = 13;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_soft_resample: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| /* A14 + A30W */
 | |
| SANE_Status
 | |
| usb_low_set_cmt_loop_count (ma1017 * chip, SANE_Word loop_count)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_cmt_loop_count: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_cmt_loop_count: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_cmt_loop_count: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->loop_count = loop_count;
 | |
| 
 | |
|   data = LOBYTE (loop_count);
 | |
|   reg_no = 14;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   data = HIBYTE (loop_count);
 | |
|   reg_no = 30;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_cmt_loop_count: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| /* A15 */
 | |
| SANE_Status
 | |
| usb_low_get_a15 (ma1017 * chip, SANE_Byte * value)
 | |
| {
 | |
|   SANE_Byte pattern;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a15: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a15: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a15: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   RIE (usb_low_read_reg (chip, 15, &pattern));
 | |
| 
 | |
|   chip->motor_enable = pattern & 0x80;
 | |
|   chip->motor_movement = pattern & 0x68;
 | |
|   chip->motor_direction = pattern & 10;
 | |
|   chip->motor_signal = pattern & 0x06;
 | |
|   chip->motor_home = pattern & 0x01;
 | |
| 
 | |
|   if (value)
 | |
|     *value = pattern;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a15: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_enable_motor (ma1017 * chip, SANE_Bool is_enable)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_enable_motor: start\n");
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_enable_motor: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_enable_motor: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->motor_enable = 0x00;
 | |
|   if (is_enable)
 | |
|     chip->motor_enable |= 0x80;
 | |
|   data = chip->motor_enable | chip->motor_movement
 | |
|     | chip->motor_direction | chip->motor_signal | chip->motor_home;
 | |
|   reg_no = 15;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_enable_motor: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_motor_movement (ma1017 * chip, SANE_Bool is_full_step,
 | |
| 			    SANE_Bool is_double_phase, SANE_Bool is_two_step)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_motor_movement: start\n");
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_motor_movement: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_motor_movement: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->motor_movement = 0x00;
 | |
|   if (is_full_step)
 | |
|     chip->motor_movement |= 0x40;
 | |
|   if (is_double_phase)
 | |
|     chip->motor_movement |= 0x20;
 | |
|   if (is_two_step)
 | |
|     chip->motor_movement |= 0x08;
 | |
|   data = chip->motor_enable | chip->motor_movement
 | |
|     | chip->motor_direction | chip->motor_signal | chip->motor_home;
 | |
|   reg_no = 15;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_motor_movement:  exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_motor_direction (ma1017 * chip, SANE_Bool is_backward)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_motor_direction: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_motor_direction: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_motor_direction: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->motor_direction = 0x00;
 | |
|   if (is_backward)
 | |
|     chip->motor_direction |= 0x10;
 | |
|   data = chip->motor_enable | chip->motor_movement
 | |
|     | chip->motor_direction | chip->motor_signal | chip->motor_home;
 | |
|   reg_no = 15;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_motor_direction: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_motor_signal (ma1017 * chip, SANE_Byte signal)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_motor_signal: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_motor_signal: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_motor_signal: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->motor_signal = signal & 0x06;
 | |
|   data = chip->motor_enable | chip->motor_movement
 | |
|     | chip->motor_direction | chip->motor_signal | chip->motor_home;
 | |
|   reg_no = 15;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_motor_signal: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_move_motor_home (ma1017 * chip, SANE_Bool is_home,
 | |
| 			 SANE_Bool is_backward)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_move_motor_home: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_move_motor_home: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_move_motor_home: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->motor_enable = 0x00;
 | |
|   chip->motor_direction = 0x00;
 | |
|   chip->motor_home = 0x00;
 | |
|   if (is_backward)
 | |
|     chip->motor_direction |= 0x10;
 | |
|   if (is_home)
 | |
|     {
 | |
|       chip->motor_enable |= 0x80;
 | |
|       chip->motor_home |= 0x01;
 | |
|     }
 | |
|   data = chip->motor_enable | chip->motor_movement
 | |
|     | chip->motor_direction | chip->motor_signal | chip->motor_home;
 | |
|   reg_no = 15;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_move_motor_home: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| /* A16 */
 | |
| SANE_Status
 | |
| usb_low_get_a16 (ma1017 * chip, SANE_Byte * value)
 | |
| {
 | |
|   SANE_Byte pattern;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a16: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a16: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a16: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   RIE (usb_low_read_reg (chip, 16, &pattern));
 | |
| 
 | |
|   chip->pixel_depth = pattern & 0xe0;
 | |
|   chip->image_invert = pattern & 0x10;
 | |
|   chip->optical_600 = pattern & 0x08;
 | |
|   chip->sample_way = pattern & 0x07;
 | |
| 
 | |
|   if (value)
 | |
|     *value = pattern;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a16: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_image_dpi (ma1017 * chip, SANE_Bool is_optical600,
 | |
| 		       Sampleway sampleway)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_image_dpi: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_image_dpi: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_image_dpi: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->optical_600 = 0x00;
 | |
|   chip->sample_way = 0x00;
 | |
|   if (is_optical600)
 | |
|     chip->optical_600 |= 0x08;
 | |
|   switch (sampleway)
 | |
|     {
 | |
|     case SW_P1P6:
 | |
|       chip->sample_way = 0x01;
 | |
|       break;
 | |
|     case SW_P2P6:
 | |
|       chip->sample_way = 0x02;
 | |
|       break;
 | |
|     case SW_P3P6:
 | |
|       chip->sample_way = 0x03;
 | |
|       break;
 | |
|     case SW_P4P6:
 | |
|       chip->sample_way = 0x04;
 | |
|       break;
 | |
|     case SW_P5P6:
 | |
|       chip->sample_way = 0x05;
 | |
|       break;
 | |
|     case SW_P6P6:
 | |
|       chip->sample_way = 0x06;
 | |
|       break;
 | |
|     default:
 | |
|       DBG (3, "usb_low_set_image_dpi: swsample_way error\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|       break;
 | |
|     }
 | |
|   data = chip->pixel_depth | chip->image_invert | chip->optical_600
 | |
|     | chip->sample_way;
 | |
|   reg_no = 16;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_image_dpi: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_pixel_depth (ma1017 * chip, Pixeldepth pixeldepth)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_pixel_depth: start\n");
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_pixel_depth: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_pixel_depth: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->pixel_depth = 0x00;
 | |
|   switch (pixeldepth)
 | |
|     {
 | |
|     case PD_1BIT:
 | |
|       chip->pixel_depth = 0x80;
 | |
|       break;
 | |
|     case PD_4BIT:
 | |
|       chip->pixel_depth = 0xc0;
 | |
|       break;
 | |
|     case PD_8BIT:
 | |
|       chip->pixel_depth = 0x00;
 | |
|       break;
 | |
|     case PD_12BIT:
 | |
|       chip->pixel_depth = 0x20;
 | |
|       break;
 | |
|     default:
 | |
|       DBG (3, "usb_low_set_pixel_depth: pdPixelDepth error\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   data = chip->pixel_depth | chip->image_invert | chip->optical_600
 | |
|     | chip->sample_way;
 | |
|   reg_no = 16;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_SetPixelDeepth: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_invert_image (ma1017 * chip, SANE_Bool is_invert)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_invert_image: start\n");
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_invert_image: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_invert_image: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->image_invert = 0x00;
 | |
|   if (is_invert)
 | |
|     chip->image_invert |= 0x10;
 | |
|   data = chip->pixel_depth | chip->image_invert | chip->optical_600
 | |
|     | chip->sample_way;
 | |
|   reg_no = 16;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_invert_image: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| /* A17 + A18 + A19 */
 | |
| SANE_Status
 | |
| usb_low_get_a17 (ma1017 * chip, SANE_Byte * value)
 | |
| {
 | |
|   SANE_Byte pattern;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a17: start\n");
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a17: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a17: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   RIE (usb_low_read_reg (chip, 17, &pattern));
 | |
| 
 | |
|   chip->red_ref = pattern;
 | |
| 
 | |
|   if (value)
 | |
|     *value = pattern;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a17: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_get_a18 (ma1017 * chip, SANE_Byte * value)
 | |
| {
 | |
|   SANE_Byte pattern;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a18: start\n");
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a18: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a18: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   RIE (usb_low_read_reg (chip, 18, &pattern));
 | |
| 
 | |
|   chip->green_ref = pattern;
 | |
| 
 | |
|   if (value)
 | |
|     *value = pattern;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a18: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_get_a19 (ma1017 * chip, SANE_Byte * value)
 | |
| {
 | |
|   SANE_Byte pattern;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a19: start\n");
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a19: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a19:stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   RIE (usb_low_read_reg (chip, 19, &pattern));
 | |
| 
 | |
|   chip->blue_ref = pattern;
 | |
| 
 | |
|   if (value)
 | |
|     *value = pattern;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a19: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_red_ref (ma1017 * chip, SANE_Byte red_ref)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_red_ref: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_red_ref: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_red_ref: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->red_ref = red_ref;
 | |
|   data = red_ref;
 | |
|   reg_no = 17;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_red_ref: stop\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_green_ref (ma1017 * chip, SANE_Byte green_ref)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_green_ref: start\n");
 | |
| 
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_green_ref: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_green_ref: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->green_ref = green_ref;
 | |
| 
 | |
|   data = green_ref;
 | |
|   reg_no = 18;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_green_ref: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_blue_ref (ma1017 * chip, SANE_Byte blue_ref)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_blue_ref: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_blue_ref: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_blue_ref: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->blue_ref = blue_ref;
 | |
| 
 | |
|   data = blue_ref;
 | |
|   reg_no = 19;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_blue_ref: stop\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| /* A20 + A21 + A22 */
 | |
| SANE_Status
 | |
| usb_low_get_a20 (ma1017 * chip, SANE_Byte * value)
 | |
| {
 | |
|   SANE_Byte pattern;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a20: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a20: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a20: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   RIE (usb_low_read_reg (chip, 20, &pattern));
 | |
| 
 | |
|   chip->red_pd = pattern;
 | |
| 
 | |
|   if (value)
 | |
|     *value = pattern;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a20: stop\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_get_a21 (ma1017 * chip, SANE_Byte * value)
 | |
| {
 | |
|   SANE_Byte pattern;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a21: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a21: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a21: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   RIE (usb_low_read_reg (chip, 21, &pattern));
 | |
| 
 | |
|   chip->green_pd = pattern;
 | |
| 
 | |
|   if (value)
 | |
|     *value = pattern;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a21: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_get_a22 (ma1017 * chip, SANE_Byte * value)
 | |
| {
 | |
|   SANE_Byte pattern;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a22: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a22: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a22: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   RIE (usb_low_read_reg (chip, 22, &pattern));
 | |
| 
 | |
|   chip->blue_pd = pattern;
 | |
| 
 | |
|   if (value)
 | |
|     *value = pattern;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a22: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_red_pd (ma1017 * chip, SANE_Byte red_pd)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_red_pd: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_red_pd: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_red_pd: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->red_pd = red_pd;
 | |
| 
 | |
|   data = chip->red_pd;
 | |
|   reg_no = 20;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_red_pd: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_green_pd (ma1017 * chip, SANE_Byte green_pd)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_green_pd: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_green_pd: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_green_pd: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->green_pd = green_pd;
 | |
|   data = chip->green_pd;
 | |
|   reg_no = 21;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_green_pd: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_blue_pd (ma1017 * chip, SANE_Byte blue_pd)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_blue_pd: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_blue_pd: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_blue_pd: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->blue_pd = blue_pd;
 | |
| 
 | |
|   data = chip->blue_pd;
 | |
|   reg_no = 22;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_blue_pd: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| /* A23 */
 | |
| SANE_Status
 | |
| usb_low_get_a23 (ma1017 * chip, SANE_Byte * value)
 | |
| {
 | |
|   SANE_Byte pattern;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a23: start\n");
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a23: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a23: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   RIE (usb_low_read_reg (chip, 23, &pattern));
 | |
| 
 | |
|   chip->a23 = pattern;
 | |
| 
 | |
|   if (value)
 | |
|     *value = pattern;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a23: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_turn_peripheral_power (ma1017 * chip, SANE_Bool is_on)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_turn_peripheral_power: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_turn_peripheral_power: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_turn_peripheral_power: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->a23 &= 0x7f;
 | |
|   if (is_on)
 | |
|     chip->a23 |= 0x80;
 | |
|   data = chip->a23;
 | |
|   reg_no = 23;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_turn_peripheral_power: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_turn_lamp_power (ma1017 * chip, SANE_Bool is_on)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_turn_lamp_power: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_turn_lamp_power: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_turn_lamp_power: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->a23 &= 0xbf;
 | |
|   if (is_on)
 | |
|     chip->a23 |= 0x40;
 | |
| 
 | |
|   data = chip->a23;
 | |
|   reg_no = 23;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_turn_lamp_power: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_io_3 (ma1017 * chip, SANE_Bool is_high)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_io_3: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_io_3: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_io_3: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->a23 &= 0xf7;
 | |
|   if (is_high)
 | |
|     chip->a23 |= 0x08;
 | |
| 
 | |
|   data = chip->a23;
 | |
|   reg_no = 23;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_io_3: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_led_light_all (ma1017 * chip, SANE_Bool is_light_all)
 | |
| {
 | |
|   SANE_Byte data, reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_led_light_all: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_led_light_all: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_led_light_all: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->a23 &= 0xfe;
 | |
|   if (is_light_all)
 | |
|     chip->a23 |= 0x01;
 | |
| 
 | |
|   data = chip->a23;
 | |
|   reg_no = 23;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_led_light_all: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| /* A24 */
 | |
| SANE_Status
 | |
| usb_low_get_a24 (ma1017 * chip, SANE_Byte * value)
 | |
| {
 | |
|   SANE_Byte pattern;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a24: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a24: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a24: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   RIE (usb_low_read_reg (chip, 24, &pattern));
 | |
| 
 | |
|   chip->fy1_delay = pattern & 0x01;
 | |
|   chip->special_ad = pattern & 0x02;
 | |
| 
 | |
|   if (value)
 | |
|     *value = pattern;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a24: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_ad_timing (ma1017 * chip, SANE_Byte data)
 | |
| {
 | |
|   SANE_Byte reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_ad_timing: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_ad_timing: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_ad_timing: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   chip->fy1_delay = data & 0x01;
 | |
|   chip->special_ad = data & 0x02;
 | |
| 
 | |
|   data = chip->special_ad | chip->fy1_delay;
 | |
|   reg_no = 24;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_ad_timing: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| /* A25 + A26 */
 | |
| SANE_Status
 | |
| usb_low_set_serial_byte1 (ma1017 * chip, SANE_Byte data)
 | |
| {
 | |
|   SANE_Byte reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_serial_byte1: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_serial_byte1: not opened\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_serial_byte1: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   reg_no = 25;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_serial_byte1: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_serial_byte2 (ma1017 * chip, SANE_Byte data)
 | |
| {
 | |
|   SANE_Byte reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_serial_byte2: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_serial_byte2: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_serial_byte2: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   reg_no = 26;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_serial_byte2: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| /* A27 */
 | |
| SANE_Status
 | |
| usb_low_get_a27 (ma1017 * chip, SANE_Byte * value)
 | |
| {
 | |
|   SANE_Byte pattern;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a27: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a27: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_a27: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   RIE (usb_low_read_reg (chip, 27, &pattern));
 | |
| 
 | |
|   chip->sclk = pattern & 0x80;
 | |
|   chip->sen = pattern & 0x40;
 | |
|   chip->serial_length = pattern & 0x1f;
 | |
| 
 | |
|   if (value)
 | |
|     *value = pattern;
 | |
| 
 | |
|   DBG (7, "usb_low_get_a27: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_set_serial_format (ma1017 * chip, SANE_Byte data)
 | |
| {
 | |
|   SANE_Byte reg_no;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_set_serial_format: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_serial_format: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_set_serial_format: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
| 
 | |
|   chip->sclk = data & 0x80;
 | |
|   chip->sen = data & 0x40;
 | |
|   chip->serial_length = data & 0x1f;
 | |
| 
 | |
|   reg_no = 27;
 | |
|   RIE (usb_low_write_reg (chip, reg_no, data));
 | |
| 
 | |
|   DBG (7, "usb_low_set_serial_format: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_get_home_sensor (ma1017 * chip)
 | |
| {
 | |
|   SANE_Byte data;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_home_sensor: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_home_sensor: not opened yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_home_sensor: stop rowing first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   RIE (usb_low_read_reg (chip, 31, &data));
 | |
| 
 | |
|   DBG (7, "usb_low_get_home_sensor: exit\n");
 | |
|   if ((data & 0x80) != 0)
 | |
|     return SANE_STATUS_GOOD;
 | |
|   else
 | |
|     return SANE_STATUS_IO_ERROR;
 | |
| }
 | |
| 
 | |
| /* Special Mode */
 | |
| SANE_Status
 | |
| usb_low_start_rowing (ma1017 * chip)
 | |
| {
 | |
|   SANE_Word line_of_first = 0;
 | |
|   SANE_Word line_of_second = 0;
 | |
|   SANE_Int i;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_start_rowing: start\n");
 | |
| 
 | |
|   if (chip->loop_count == 0)
 | |
|     {
 | |
|       DBG (3, "usb_low_start_rowing loop_count hasn't been set yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->cmt_table_length_word == 0)
 | |
|     {
 | |
|       DBG (3, "usb_low_start_rowing: cmt_table_length_word hasn't been set "
 | |
| 	   "yet\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->cmt_table_length_word <= chip->cmt_second_pos_word)
 | |
|     {
 | |
|       DBG (3, "usb_low_start_rowing: cmt_second_pos_word cannot be larger "
 | |
| 	   "than cmt_table_length_word\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   for (i = 0; i < (int) chip->cmt_second_pos_word; i++)
 | |
|     {
 | |
|       if (chip->is_transfer_table[i])
 | |
| 	line_of_first++;
 | |
|     }
 | |
|   for (; i < (int) chip->cmt_table_length_word; i++)
 | |
|     {
 | |
|       if (chip->is_transfer_table[i])
 | |
| 	{
 | |
| 	  line_of_first++;
 | |
| 	  line_of_second++;
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|   chip->total_lines =
 | |
|     ((SANE_Word) (chip->loop_count - 1)) * line_of_second + line_of_first;
 | |
|   chip->lines_left = chip->total_lines;
 | |
| 
 | |
|   RIE (usb_low_start_cmt_table (chip));
 | |
| 
 | |
|   DBG (7, "usb_low_start_rowing: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_stop_rowing (ma1017 * chip)
 | |
| {
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_stop_rowing: start\n");
 | |
| 
 | |
|   RIE (usb_low_stop_cmt_table (chip));
 | |
| 
 | |
|   DBG (7, "usb_low_stop_rowing: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| 
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_wait_rowing_stop (ma1017 * chip)
 | |
| {
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_wait_rowing_stop: start\n");
 | |
|   if (chip->total_lines != 0)
 | |
|     {
 | |
|       DBG (3, "usb_low_wait_rowing_stop: total_lines must be 0\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   RIE (usb_low_wait_rowing (chip));
 | |
|   chip->is_rowing = SANE_FALSE;
 | |
|   DBG (7, "usb_low_wait_rowing_stop: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_read_all_registers (ma1017 * chip)
 | |
| {
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_read_all_registers: start\n");
 | |
| 
 | |
|   RIE (usb_low_get_a2 (chip, 0));
 | |
|   RIE (usb_low_get_a4 (chip, 0));
 | |
|   RIE (usb_low_get_a6 (chip, 0));
 | |
|   RIE (usb_low_get_a7 (chip, 0));
 | |
|   RIE (usb_low_get_a8 (chip, 0));
 | |
|   RIE (usb_low_get_a9 (chip, 0));
 | |
|   RIE (usb_low_get_a10 (chip, 0));
 | |
|   RIE (usb_low_get_a11 (chip, 0));
 | |
|   RIE (usb_low_get_a12 (chip, 0));
 | |
|   RIE (usb_low_get_a13 (chip, 0));
 | |
|   RIE (usb_low_get_a15 (chip, 0));
 | |
|   RIE (usb_low_get_a16 (chip, 0));
 | |
|   RIE (usb_low_get_a17 (chip, 0));
 | |
|   RIE (usb_low_get_a18 (chip, 0));
 | |
|   RIE (usb_low_get_a19 (chip, 0));
 | |
|   RIE (usb_low_get_a20 (chip, 0));
 | |
|   RIE (usb_low_get_a21 (chip, 0));
 | |
|   RIE (usb_low_get_a22 (chip, 0));
 | |
|   RIE (usb_low_get_a23 (chip, 0));
 | |
|   RIE (usb_low_get_a24 (chip, 0));
 | |
|   RIE (usb_low_get_a27 (chip, 0));
 | |
| 
 | |
|   return SANE_STATUS_GOOD;
 | |
|   DBG (7, "usb_low_read_all_registers: exit\n");
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_get_row (ma1017 * chip, SANE_Byte * data, SANE_Word * lines_left)
 | |
| {
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_row: start\n");
 | |
|   RIE ((*chip->get_row) (chip, data, lines_left));
 | |
|   DBG (7, "usb_low_get_row: exit\n");
 | |
|   return SANE_STATUS_GOOD;;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_get_row_direct (ma1017 * chip, SANE_Byte * data,
 | |
| 			SANE_Word * lines_left)
 | |
| {
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_row_direct: start\n");
 | |
|   if (chip->lines_left == 0)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_row_direct: lines_left == 0\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   if (chip->lines_left <= 1)
 | |
|     {
 | |
|       RIE (usb_low_read_rows (chip, data, chip->byte_width));
 | |
|       RIE (usb_low_wait_rowing (chip));
 | |
| 
 | |
|       chip->lines_left = 0x00;
 | |
|       chip->is_rowing = SANE_FALSE;
 | |
|       *lines_left = 0;
 | |
|     }
 | |
|   else
 | |
|     {
 | |
|       RIE (usb_low_read_rows (chip, data, chip->byte_width));
 | |
|       chip->lines_left--;
 | |
|       *lines_left = chip->lines_left;
 | |
|     }
 | |
|   DBG (7, "usb_low_get_row_direct: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_get_row_resample (ma1017 * chip, SANE_Byte * data,
 | |
| 			  SANE_Word * lines_left)
 | |
| {
 | |
|   static SANE_Byte resample_buffer[8 * 1024];
 | |
|   SANE_Word *pixel_temp;
 | |
|   SANE_Word i;
 | |
|   SANE_Word j;
 | |
|   SANE_Word k;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_get_row_resample: start\n");
 | |
| 
 | |
|   if (chip->lines_left == 0)
 | |
|     {
 | |
|       DBG (3, "usb_low_get_row_resample: lines_left == 0\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   if (chip->lines_left <= 1)
 | |
|     {
 | |
|       RIE (usb_low_read_rows (chip, resample_buffer, chip->byte_width));
 | |
| 
 | |
|       if ((chip->sensor == ST_CANON600) && (chip->pixel_depth == 0x20))
 | |
| 	{
 | |
| 	  pixel_temp = (SANE_Word *) malloc (6 * 1024 * sizeof (SANE_Word));
 | |
| 	  if (!pixel_temp)
 | |
| 	    return SANE_STATUS_NO_MEM;
 | |
| 
 | |
| 	  j = 0;
 | |
| 	  for (i = 0; i < chip->byte_width; i += 3)
 | |
| 	    {
 | |
| 	      pixel_temp[j] = (SANE_Word) resample_buffer[i];
 | |
| 	      pixel_temp[j] |= ((SANE_Word)
 | |
| 				(resample_buffer[i + 1] & 0xf0)) << 4;
 | |
| 	      j++;
 | |
| 	      pixel_temp[j] = ((SANE_Word)
 | |
| 			       (resample_buffer[i + 1] & 0x0f)) << 8;
 | |
| 	      pixel_temp[j] |= (SANE_Word) resample_buffer[i + 2];
 | |
| 	      j++;
 | |
| 	    }
 | |
| 
 | |
| 	  k = 0;
 | |
| 	  for (i = 0; i < j; i += chip->soft_resample * 2)
 | |
| 	    {
 | |
| 	      data[k] = (SANE_Byte) (pixel_temp[i] & 0x00ff);
 | |
| 	      k++;
 | |
| 	      data[k] = (SANE_Byte) ((pixel_temp[i] & 0x0f00) >> 4);
 | |
| 	      data[k] |= (SANE_Byte) ((pixel_temp[i + 2] & 0x0f00) >> 8);
 | |
| 	      k++;
 | |
| 	      data[k] = (SANE_Byte) (pixel_temp[i + 2] & 0x00ff);
 | |
| 	      k++;
 | |
| 	    }
 | |
| 	  free (pixel_temp);
 | |
| 	}
 | |
|       else			/* fixme ? */
 | |
| 	{
 | |
| 	  for (i = 0; i < chip->byte_width; i += chip->soft_resample)
 | |
| 	    *(data++) = resample_buffer[i];
 | |
| 	}
 | |
|       RIE (usb_low_wait_rowing (chip));
 | |
| 
 | |
|       chip->lines_left = 0x00;
 | |
|       chip->is_rowing = SANE_FALSE;
 | |
|       *lines_left = 0;
 | |
|     }
 | |
|   else
 | |
|     {
 | |
|       RIE (usb_low_read_rows (chip, resample_buffer, chip->byte_width));
 | |
| 
 | |
|       if ((chip->sensor == ST_CANON600) && (chip->pixel_depth == 0x20))
 | |
| 	{
 | |
| 	  pixel_temp = (SANE_Word *) malloc (6 * 1024 * sizeof (SANE_Word));
 | |
| 	  if (!pixel_temp)
 | |
| 	    return SANE_STATUS_NO_MEM;
 | |
| 
 | |
| 	  j = 0;
 | |
| 	  for (i = 0; i < chip->byte_width; i += 3)
 | |
| 	    {
 | |
| 	      pixel_temp[j] = (SANE_Word) resample_buffer[i];
 | |
| 	      pixel_temp[j] |=
 | |
| 		((SANE_Word) (resample_buffer[i + 1] & 0xf0)) << 4;
 | |
| 	      j++;
 | |
| 	      pixel_temp[j] =
 | |
| 		((SANE_Word) (resample_buffer[i + 1] & 0x0f)) << 8;
 | |
| 	      pixel_temp[j] |= (SANE_Word) resample_buffer[i + 2];
 | |
| 	      j++;
 | |
| 	    }
 | |
| 
 | |
| 	  k = 0;
 | |
| 	  for (i = 0; i < j; i += chip->soft_resample * 2)
 | |
| 	    {
 | |
| 	      data[k] = (SANE_Byte) (pixel_temp[i] & 0x00ff);
 | |
| 	      k++;
 | |
| 	      data[k] = (SANE_Byte) ((pixel_temp[i] & 0x0f00) >> 4);
 | |
| 	      data[k] |= (SANE_Byte) ((pixel_temp[i + 2] & 0x0f00) >> 8);
 | |
| 	      k++;
 | |
| 	      data[k] = (SANE_Byte) (pixel_temp[i + 2] & 0x00ff);
 | |
| 	      k++;
 | |
| 	    }
 | |
| 	  free (pixel_temp);
 | |
| 	}
 | |
|       else			/* fixme? */
 | |
| 	{
 | |
| 	  for (i = 0; i < chip->byte_width; i += chip->soft_resample)
 | |
| 	    *(data++) = resample_buffer[i];
 | |
| 	}
 | |
|       chip->lines_left--;
 | |
|       *lines_left = chip->lines_left;
 | |
|     }
 | |
|   DBG (7, "usb_low_get_row_resample: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_wait_rowing (ma1017 * chip)
 | |
| {
 | |
|   SANE_Byte read_byte;
 | |
|   size_t n;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_wait_rowing: start\n");
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_wait_rowing: open first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (!chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_wait_rowing: not rowing\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   n = 1;
 | |
|   status = sanei_usb_read_bulk (chip->fd, (SANE_Byte *) & read_byte, &n);
 | |
|   if (status != SANE_STATUS_GOOD || n != 1)
 | |
|     {
 | |
|       DBG (3, "usb_low_wait_rowing: couldn't read: %s\n",
 | |
| 	   sane_strstatus (status));
 | |
|       return SANE_STATUS_IO_ERROR;
 | |
|     }
 | |
|   chip->total_read_urbs++;
 | |
|   chip->is_rowing = SANE_FALSE;
 | |
|   DBG (7, "usb_low_wait_rowing: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_read_rows (ma1017 * chip, SANE_Byte * data, SANE_Word byte_count)
 | |
| {
 | |
|   size_t n, bytes_total;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   DBG (7, "usb_low_read_rows: start\n");
 | |
|   if (!(chip->is_opened))
 | |
|     {
 | |
|       DBG (3, "usb_low_read_rows: is_opened==SANE_FALSE\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (!(chip->is_rowing))
 | |
|     {
 | |
|       DBG (3, "usb_low_read_rows: is_rowing==SANE_FALSE\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   n = MIN (byte_count, chip->max_block_size);
 | |
|   bytes_total = 0;
 | |
| 
 | |
|   while ((SANE_Word) bytes_total < byte_count)
 | |
|     {
 | |
|       status =
 | |
| 	sanei_usb_read_bulk (chip->fd, (SANE_Byte *) (data + bytes_total),
 | |
| 			     &n);
 | |
|       if (status != SANE_STATUS_GOOD)
 | |
| 	{
 | |
| 	  DBG (7, "usb_low_read_rows: problems during read: %s -- exiting\n",
 | |
| 	       sane_strstatus (status));
 | |
| 	  return status;
 | |
| 	}
 | |
|       /* Count the number of URBs. This is a bit tricky, as we are reading
 | |
| 	 bigger chunks here but the scanner can only handle 64 bytes at once. */
 | |
|       chip->total_read_urbs += ((n +  63) / 64);
 | |
|       bytes_total += n;
 | |
|       if ((SANE_Word) bytes_total != byte_count)
 | |
| 	{
 | |
| 	  DBG (7, "usb_low_read_rows:  wanted %d, got %d "
 | |
| 	       "bytes (%d in total) -- retrying\n", byte_count, (SANE_Word) n,
 | |
| 	       (SANE_Word) bytes_total);
 | |
| 	}
 | |
|       n = MIN ((byte_count - (SANE_Word) bytes_total), chip->max_block_size);
 | |
|     }
 | |
| 
 | |
|   DBG (7, "usb_low_read_rows: exit, read %d bytes\n",
 | |
|        (SANE_Word) bytes_total);
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_write_reg (ma1017 * chip, SANE_Byte reg_no, SANE_Byte data)
 | |
| {
 | |
|   size_t n;
 | |
|   SANE_Status status;
 | |
|   SANE_Byte data_field[2];
 | |
| 
 | |
|   data_field[0] = data;
 | |
|   data_field[1] = reg_no;
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_write_reg: open first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_write_reg: rowing, stop first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (reg_no > 0x20)
 | |
|     {
 | |
|       DBG (3, "usb_low_write_reg: reg_no out of range\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   n = 2;
 | |
|   status = sanei_usb_write_bulk (chip->fd, data_field, &n);
 | |
|   if (status != SANE_STATUS_GOOD || n != 2)
 | |
|     {
 | |
|       DBG (3, "usb_low_write_reg: couldn't write, tried to write %d, "
 | |
| 	   "wrote %lu: %s\n", 2, (unsigned long int) n,
 | |
| 	   sane_strstatus (status));
 | |
|       return SANE_STATUS_IO_ERROR;
 | |
|     }
 | |
|   chip->total_write_urbs++;
 | |
|   DBG (7, "usb_low_write_reg: reg: 0x%02x, value: 0x%02x\n", reg_no, data);
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_read_reg (ma1017 * chip, SANE_Byte reg_no, SANE_Byte * data)
 | |
| {
 | |
|   SANE_Byte data_field[2];
 | |
|   SANE_Byte read_byte;
 | |
|   size_t n;
 | |
|   SANE_Status status;
 | |
| 
 | |
|   data_field[0] = 0x00;
 | |
|   data_field[1] = reg_no | 0x20;
 | |
| 
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_read_reg: open first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_read_reg: rowing, stop first\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (reg_no > 0x20)
 | |
|     {
 | |
|       DBG (3, "usb_low_read_reg: reg_no out of range\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   n = 2;
 | |
|   DBG (5, "usb_low_read_reg: trying to write %lu bytes\n", (unsigned long int) n);
 | |
| 
 | |
|   status = sanei_usb_write_bulk (chip->fd, data_field, &n);
 | |
|   if (status != SANE_STATUS_GOOD || n != 2)
 | |
|     {
 | |
|       DBG (3, "usb_low_read_reg: couldn't write, tried to write %d, "
 | |
| 	   "wrote %lu: %s\n", 2, (unsigned long int) n,
 | |
| 	   sane_strstatus (status));
 | |
|       return SANE_STATUS_IO_ERROR;
 | |
|     }
 | |
|   chip->total_write_urbs++;
 | |
|   n = 1;
 | |
|   DBG (5, "usb_low_read_reg: trying to read %lu bytes\n", (unsigned long int) n);
 | |
|   status = sanei_usb_read_bulk (chip->fd, (SANE_Byte *) & read_byte, &n);
 | |
|   if (status != SANE_STATUS_GOOD || n != 1)
 | |
|     {
 | |
|       DBG (3, "usb_low_read_reg: couldn't read, tried to read %lu, "
 | |
| 	   "read %lu: %s\n", (unsigned long int) 1,
 | |
| 	   (unsigned long int) n, sane_strstatus (status));
 | |
|       return SANE_STATUS_IO_ERROR;
 | |
|     }
 | |
|   chip->total_read_urbs++;
 | |
|   if (data)
 | |
|     *data = read_byte;
 | |
|   DBG (7, "usb_low_read_reg: Reg: 0x%02x, Value: 0x%02x\n",
 | |
|        reg_no, read_byte);
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_identify_scanner (SANE_Int fd, Mustek_Type * scanner_type)
 | |
| {
 | |
|   SANE_Status status;
 | |
|   SANE_Word devvendor, devproduct;
 | |
|   Mustek_Type devtype;
 | |
| 
 | |
|   DBG (7, "usb_low_identify_scanner: start\n");
 | |
| 
 | |
|   status = sanei_usb_get_vendor_product (fd, &devvendor, &devproduct);
 | |
|   devtype = MT_UNKNOWN;
 | |
|   if (status == SANE_STATUS_GOOD)
 | |
|     {
 | |
|       if (devvendor == 0x055f)
 | |
| 	{
 | |
| 	  switch (devproduct)
 | |
| 	    {
 | |
| 	    case 0x0001:
 | |
| 	      devtype = MT_1200CU;
 | |
| 	      break;
 | |
| 	    case 0x0002:
 | |
| 	      devtype = MT_600CU;
 | |
| 	      break;
 | |
| 	    case 0x0003:
 | |
| 	      devtype = MT_1200USB;
 | |
| 	      break;
 | |
| 	    case 0x0006:
 | |
| 	      devtype = MT_1200UB;
 | |
| 	      break;
 | |
| 	    case 0x0008:
 | |
| 	      devtype = MT_1200CU_PLUS;
 | |
| 	      break;
 | |
| 	    case 0x0873:
 | |
| 	      devtype = MT_600USB;
 | |
| 	      break;
 | |
| 	    default:
 | |
| 	      if (scanner_type)
 | |
| 		*scanner_type = devtype;
 | |
| 	      DBG (3, "usb_low_identify_scanner: unknown product id: "
 | |
| 		   "0x%04x\n", devproduct);
 | |
| 	      return SANE_STATUS_INVAL;
 | |
| 	      break;
 | |
| 	    }
 | |
| 	}
 | |
|       else
 | |
| 	{
 | |
| 	  if (scanner_type)
 | |
| 	    *scanner_type = devtype;
 | |
| 	  DBG (3, "usb_low_identify_scanner: unknown vendor id: 0x%04d\n",
 | |
| 	       devvendor);
 | |
| 	  return SANE_STATUS_INVAL;
 | |
| 	}
 | |
|     }
 | |
|   if (scanner_type)
 | |
|     *scanner_type = devtype;
 | |
|   DBG (7, "usb_low_identify_scanner: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_open (ma1017 * chip, SANE_String_Const devname)
 | |
| {
 | |
|   SANE_Status status;
 | |
|   Mustek_Type scanner_type;
 | |
| 
 | |
|   DBG (7, "usb_low_open: start: chip = %p\n", (void *) chip);
 | |
| 
 | |
|   if (chip->is_rowing)
 | |
|     {
 | |
|       DBG (3, "usb_low_open: already rowing\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
|   if (chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_open: already opened\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   status = sanei_usb_open ((SANE_String_Const) devname, &chip->fd);
 | |
| 
 | |
|   if (status == SANE_STATUS_GOOD)
 | |
|     {
 | |
|       DBG (7, "usb_low_open: device %s successfully opened\n", devname);
 | |
|       chip->is_opened = SANE_TRUE;
 | |
|       /* Try to get vendor and device ids */
 | |
|       DBG (7, "usb_low_open: trying to identify device `%s'\n", devname);
 | |
|       status = usb_low_identify_scanner (chip->fd, &scanner_type);
 | |
|       if (status != SANE_STATUS_GOOD)
 | |
| 	{
 | |
| 	  DBG (3, "usb_low_open: device `%s' doesn't look like a supported "
 | |
| 	       "scanner\n", devname);
 | |
| 	  sanei_usb_close (chip->fd);
 | |
| 	  return status;
 | |
| 	}
 | |
|       else
 | |
| 	{
 | |
| 	  if (scanner_type == MT_UNKNOWN)
 | |
| 	    {
 | |
| 	      DBG (3, "usb_low_open: device `%s' can't be identified\n",
 | |
| 		   devname);
 | |
| 	    }
 | |
| 	  else if (scanner_type != chip->scanner_type)
 | |
| 	    {
 | |
| 	      DBG (3, "usb_low_open: device `%s' is supported but"
 | |
| 		   "it's not the same as at the start\n", devname);
 | |
| 	      return SANE_STATUS_INVAL;
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
|   else
 | |
|     {
 | |
|       DBG (1, "usb_low_open: device %s couldn't be opened: %s\n",
 | |
| 	   devname, sane_strstatus (status));
 | |
|       return status;
 | |
|     }
 | |
| 
 | |
|   chip->is_opened = SANE_TRUE;
 | |
| 
 | |
|   RIE (usb_low_read_all_registers (chip));
 | |
| 
 | |
|   DBG (7, "usb_low_open: exit, type is %d\n", scanner_type);
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| usb_low_close (ma1017 * chip)
 | |
| {
 | |
|   DBG (7, "usb_low_close: start, chip=%p\n", (void *) chip);
 | |
|   if (!chip->is_opened)
 | |
|     {
 | |
|       DBG (3, "usb_low_close: already close or never opened\n");
 | |
|       return SANE_STATUS_INVAL;
 | |
|     }
 | |
| 
 | |
|   if (chip->fd >= 0)
 | |
|     {
 | |
|       SANE_Byte dummy;
 | |
| 
 | |
|       if (chip->is_rowing)
 | |
| 	usb_low_stop_rowing (chip);
 | |
|       /* Now make sure that both the number of written and
 | |
| 	 read URBs is even. Use some dummy writes/reads. That's to avoid
 | |
| 	 a nasty bug in the MA 1017 chipset that causes timeouts when
 | |
| 	 the number of URBs is odd (toggle bug). */
 | |
|       if ((chip->total_read_urbs % 2) == 1)
 | |
| 	usb_low_get_a4 (chip, &dummy);
 | |
|       if ((chip->total_write_urbs % 2) == 1)
 | |
| 	usb_low_set_fix_pattern (chip, SANE_FALSE);
 | |
|       sanei_usb_close (chip->fd);
 | |
|       chip->fd = -1;
 | |
|     }
 | |
|   chip->is_opened = SANE_FALSE;
 | |
|   chip->is_rowing = SANE_FALSE;
 | |
| 
 | |
|   DBG (7, "usb_low_close: exit\n");
 | |
|   return SANE_STATUS_GOOD;
 | |
| }
 |