1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy.
2141cc406Sopenharmony_ci
3141cc406Sopenharmony_ci   Copyright (C) 2000 Mustek.
4141cc406Sopenharmony_ci   Originally maintained by Tom Wang <tom.wang@mustek.com.tw>
5141cc406Sopenharmony_ci
6141cc406Sopenharmony_ci   Copyright (C) 2001 - 2004 by Henning Meier-Geinitz.
7141cc406Sopenharmony_ci
8141cc406Sopenharmony_ci   This file is part of the SANE package.
9141cc406Sopenharmony_ci
10141cc406Sopenharmony_ci   This program is free software; you can redistribute it and/or
11141cc406Sopenharmony_ci   modify it under the terms of the GNU General Public License as
12141cc406Sopenharmony_ci   published by the Free Software Foundation; either version 2 of the
13141cc406Sopenharmony_ci   License, or (at your option) any later version.
14141cc406Sopenharmony_ci
15141cc406Sopenharmony_ci   This program is distributed in the hope that it will be useful, but
16141cc406Sopenharmony_ci   WITHOUT ANY WARRANTY; without even the implied warranty of
17141cc406Sopenharmony_ci   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18141cc406Sopenharmony_ci   General Public License for more details.
19141cc406Sopenharmony_ci
20141cc406Sopenharmony_ci   You should have received a copy of the GNU General Public License
21141cc406Sopenharmony_ci   along with this program.  If not, see <https://www.gnu.org/licenses/>.
22141cc406Sopenharmony_ci
23141cc406Sopenharmony_ci   As a special exception, the authors of SANE give permission for
24141cc406Sopenharmony_ci   additional uses of the libraries contained in this release of SANE.
25141cc406Sopenharmony_ci
26141cc406Sopenharmony_ci   The exception is that, if you link a SANE library with other files
27141cc406Sopenharmony_ci   to produce an executable, this does not by itself cause the
28141cc406Sopenharmony_ci   resulting executable to be covered by the GNU General Public
29141cc406Sopenharmony_ci   License.  Your use of that executable is in no way restricted on
30141cc406Sopenharmony_ci   account of linking the SANE library code into it.
31141cc406Sopenharmony_ci
32141cc406Sopenharmony_ci   This exception does not, however, invalidate any other reasons why
33141cc406Sopenharmony_ci   the executable file might be covered by the GNU General Public
34141cc406Sopenharmony_ci   License.
35141cc406Sopenharmony_ci
36141cc406Sopenharmony_ci   If you submit changes to SANE to the maintainers to be included in
37141cc406Sopenharmony_ci   a subsequent release, you agree by submitting the changes that
38141cc406Sopenharmony_ci   those changes may be distributed with this exception intact.
39141cc406Sopenharmony_ci
40141cc406Sopenharmony_ci   If you write modifications of your own for SANE, it is your choice
41141cc406Sopenharmony_ci   whether to permit this exception to apply to your modifications.
42141cc406Sopenharmony_ci   If you do not wish that, delete this exception notice.
43141cc406Sopenharmony_ci
44141cc406Sopenharmony_ci   This file implements a SANE backend for Mustek 1200UB and similar
45141cc406Sopenharmony_ci   USB flatbed scanners.  */
46141cc406Sopenharmony_ci
47141cc406Sopenharmony_ci#include <unistd.h>
48141cc406Sopenharmony_ci
49141cc406Sopenharmony_ci#include "../include/sane/sane.h"
50141cc406Sopenharmony_ci#include "../include/sane/sanei_usb.h"
51141cc406Sopenharmony_ci#include "mustek_usb_low.h"
52141cc406Sopenharmony_ci
53141cc406Sopenharmony_ci
54141cc406Sopenharmony_ciSANE_Status
55141cc406Sopenharmony_ciusb_low_init (ma1017 ** chip_address)
56141cc406Sopenharmony_ci{
57141cc406Sopenharmony_ci  SANE_Int i;
58141cc406Sopenharmony_ci  ma1017 *chip;
59141cc406Sopenharmony_ci
60141cc406Sopenharmony_ci  DBG (7, "usb_low_init: start\n");
61141cc406Sopenharmony_ci  if (!chip_address)
62141cc406Sopenharmony_ci    return SANE_STATUS_INVAL;
63141cc406Sopenharmony_ci
64141cc406Sopenharmony_ci  chip = (ma1017 *) malloc (sizeof (ma1017));
65141cc406Sopenharmony_ci
66141cc406Sopenharmony_ci  if (!chip)
67141cc406Sopenharmony_ci    {
68141cc406Sopenharmony_ci      DBG (3, "usb_low_init: couldn't malloc %ld bytes for chip\n",
69141cc406Sopenharmony_ci	   (long int) sizeof (ma1017));
70141cc406Sopenharmony_ci      *chip_address = 0;
71141cc406Sopenharmony_ci      return SANE_STATUS_NO_MEM;
72141cc406Sopenharmony_ci    }
73141cc406Sopenharmony_ci  *chip_address = chip;
74141cc406Sopenharmony_ci
75141cc406Sopenharmony_ci  /* io */
76141cc406Sopenharmony_ci  chip->is_rowing = SANE_FALSE;
77141cc406Sopenharmony_ci  chip->is_opened = SANE_FALSE;
78141cc406Sopenharmony_ci  chip->fd = -1;
79141cc406Sopenharmony_ci
80141cc406Sopenharmony_ci  /* Construction/Destruction */
81141cc406Sopenharmony_ci  chip->is_opened = SANE_FALSE;
82141cc406Sopenharmony_ci  chip->is_rowing = SANE_FALSE;
83141cc406Sopenharmony_ci
84141cc406Sopenharmony_ci  /* A2 */
85141cc406Sopenharmony_ci  chip->append = 0x00;
86141cc406Sopenharmony_ci  chip->test_sram = 0x00;
87141cc406Sopenharmony_ci  chip->fix_pattern = 0x00;
88141cc406Sopenharmony_ci  /* A4 */
89141cc406Sopenharmony_ci  chip->select = 0x00;
90141cc406Sopenharmony_ci  chip->frontend = 0x00;
91141cc406Sopenharmony_ci  /* A6 */
92141cc406Sopenharmony_ci  chip->rgb_sel_pin = 0x02;
93141cc406Sopenharmony_ci  chip->asic_io_pins = 0x9c;
94141cc406Sopenharmony_ci  /* A7 */
95141cc406Sopenharmony_ci  chip->timing = 0xe8;
96141cc406Sopenharmony_ci  chip->sram_bank = 0x02;
97141cc406Sopenharmony_ci  /* A8 */
98141cc406Sopenharmony_ci  chip->dummy_msb = 0x00;
99141cc406Sopenharmony_ci  chip->ccd_width_msb = 0x00;
100141cc406Sopenharmony_ci  chip->cmt_table_length = 0x00;
101141cc406Sopenharmony_ci  /* A9 */
102141cc406Sopenharmony_ci  chip->cmt_second_pos = 0x00;
103141cc406Sopenharmony_ci  /* A10 + A8ID5 */
104141cc406Sopenharmony_ci  chip->ccd_width = 0x0c80;
105141cc406Sopenharmony_ci  /* A11 + A8ID6 */
106141cc406Sopenharmony_ci  chip->dummy = 0x0020;
107141cc406Sopenharmony_ci  /* A12 + A13 */
108141cc406Sopenharmony_ci  chip->byte_width = 0x09f6;
109141cc406Sopenharmony_ci  /* A14 + A30W */
110141cc406Sopenharmony_ci  chip->loop_count = 0x0db5;
111141cc406Sopenharmony_ci  /* A15 */
112141cc406Sopenharmony_ci  chip->motor_enable = 0x00;
113141cc406Sopenharmony_ci  chip->motor_movement = 0x60;
114141cc406Sopenharmony_ci  chip->motor_direction = 0x10;
115141cc406Sopenharmony_ci  chip->motor_signal = 0x00;
116141cc406Sopenharmony_ci  chip->motor_home = 0x00;
117141cc406Sopenharmony_ci  /* A16 */
118141cc406Sopenharmony_ci  chip->pixel_depth = 0x00;
119141cc406Sopenharmony_ci  chip->image_invert = 0x00;
120141cc406Sopenharmony_ci  chip->optical_600 = 0x00;
121141cc406Sopenharmony_ci  chip->sample_way = 0x06;
122141cc406Sopenharmony_ci  /* A17 + A18 + A19 */
123141cc406Sopenharmony_ci  chip->red_ref = 0xff;
124141cc406Sopenharmony_ci  chip->green_ref = 0xff;
125141cc406Sopenharmony_ci  chip->blue_ref = 0xff;
126141cc406Sopenharmony_ci  /* A20 + A21 + A22 */
127141cc406Sopenharmony_ci  chip->red_pd = 0x00;
128141cc406Sopenharmony_ci  chip->green_pd = 0x00;
129141cc406Sopenharmony_ci  chip->blue_pd = 0x00;
130141cc406Sopenharmony_ci  /* A23 */
131141cc406Sopenharmony_ci  chip->a23 = 0x80;
132141cc406Sopenharmony_ci  /* A24 */
133141cc406Sopenharmony_ci  chip->fy1_delay = 0x00;
134141cc406Sopenharmony_ci  chip->special_ad = 0x00;
135141cc406Sopenharmony_ci  /* A27 */
136141cc406Sopenharmony_ci  chip->sclk = 0x00;
137141cc406Sopenharmony_ci  chip->sen = 0x00;
138141cc406Sopenharmony_ci  chip->serial_length = 0x10;
139141cc406Sopenharmony_ci
140141cc406Sopenharmony_ci  /* Use for Rowing */
141141cc406Sopenharmony_ci  chip->get_row = NULL;
142141cc406Sopenharmony_ci
143141cc406Sopenharmony_ci  chip->cmt_table_length_word = 0x00000000;
144141cc406Sopenharmony_ci  chip->cmt_second_pos_word = 0x00000000;
145141cc406Sopenharmony_ci  chip->row_size = 0x00;
146141cc406Sopenharmony_ci  chip->soft_resample = 0x01;
147141cc406Sopenharmony_ci  chip->total_lines = 0x00;
148141cc406Sopenharmony_ci  chip->lines_left = 0x00;
149141cc406Sopenharmony_ci  for (i = 0; i < 32; i++)
150141cc406Sopenharmony_ci    chip->is_transfer_table[i] = SANE_FALSE;
151141cc406Sopenharmony_ci  chip->sensor = ST_CANON600;
152141cc406Sopenharmony_ci  chip->motor = MT_1200;
153141cc406Sopenharmony_ci
154141cc406Sopenharmony_ci  chip->total_read_urbs = 0;
155141cc406Sopenharmony_ci  chip->total_write_urbs = 0;
156141cc406Sopenharmony_ci  DBG (7, "usb_low_init: exit\n");
157141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
158141cc406Sopenharmony_ci}
159141cc406Sopenharmony_ci
160141cc406Sopenharmony_ciSANE_Status
161141cc406Sopenharmony_ciusb_low_exit (ma1017 * chip)
162141cc406Sopenharmony_ci{
163141cc406Sopenharmony_ci  DBG (7, "usb_low_exit: chip = %p\n", (void *) chip);
164141cc406Sopenharmony_ci  if (chip)
165141cc406Sopenharmony_ci    {
166141cc406Sopenharmony_ci      if (chip->fd >= 0 && chip->is_opened)
167141cc406Sopenharmony_ci	usb_low_close (chip);
168141cc406Sopenharmony_ci      DBG (7, "usb_low_exit: freeing chip\n");
169141cc406Sopenharmony_ci      free (chip);
170141cc406Sopenharmony_ci    }
171141cc406Sopenharmony_ci  DBG (5, "usb_low_exit: read %d URBs, wrote %d URBs\n",
172141cc406Sopenharmony_ci       chip->total_read_urbs, chip->total_write_urbs);
173141cc406Sopenharmony_ci  DBG (7, "usb_low_exit: exit\n");
174141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
175141cc406Sopenharmony_ci}
176141cc406Sopenharmony_ci
177141cc406Sopenharmony_ci/* A0 ~ A1 */
178141cc406Sopenharmony_ciSANE_Status
179141cc406Sopenharmony_ciusb_low_set_cmt_table (ma1017 * chip, SANE_Int index, Channel channel,
180141cc406Sopenharmony_ci		       SANE_Bool is_move_motor, SANE_Bool is_transfer)
181141cc406Sopenharmony_ci{
182141cc406Sopenharmony_ci  SANE_Byte pattern = ((SANE_Byte) index) << 4;
183141cc406Sopenharmony_ci  SANE_Byte reg_no = 0;
184141cc406Sopenharmony_ci  SANE_Status status;
185141cc406Sopenharmony_ci
186141cc406Sopenharmony_ci  DBG (7, "usb_low_set_cmt_table: start\n");
187141cc406Sopenharmony_ci
188141cc406Sopenharmony_ci  if (!chip->is_opened)
189141cc406Sopenharmony_ci    {
190141cc406Sopenharmony_ci      DBG (3, "usb_low_set_cmt_table: not opened yet\n");
191141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
192141cc406Sopenharmony_ci    }
193141cc406Sopenharmony_ci  if (chip->is_rowing)
194141cc406Sopenharmony_ci    {
195141cc406Sopenharmony_ci      DBG (3, "usb_low_set_cmt_table: stop rowing first\n");
196141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
197141cc406Sopenharmony_ci    }
198141cc406Sopenharmony_ci  if ((unsigned int) index > 31)
199141cc406Sopenharmony_ci    {
200141cc406Sopenharmony_ci      DBG (7, "usb_low_set_cmt_table: CMT index (%d) exceed 31", index);
201141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
202141cc406Sopenharmony_ci    }
203141cc406Sopenharmony_ci
204141cc406Sopenharmony_ci  switch (channel)
205141cc406Sopenharmony_ci    {
206141cc406Sopenharmony_ci    case CH_RED:
207141cc406Sopenharmony_ci      pattern |= 0x04;
208141cc406Sopenharmony_ci      break;
209141cc406Sopenharmony_ci    case CH_GREEN:
210141cc406Sopenharmony_ci      pattern |= 0x08;
211141cc406Sopenharmony_ci      break;
212141cc406Sopenharmony_ci    case CH_BLUE:
213141cc406Sopenharmony_ci      pattern |= 0x0c;
214141cc406Sopenharmony_ci      break;
215141cc406Sopenharmony_ci    default:
216141cc406Sopenharmony_ci      break;
217141cc406Sopenharmony_ci    }
218141cc406Sopenharmony_ci  if (is_move_motor)
219141cc406Sopenharmony_ci    pattern |= 0x02;
220141cc406Sopenharmony_ci  if (is_transfer)
221141cc406Sopenharmony_ci    pattern |= 0x01;
222141cc406Sopenharmony_ci  if (index > 15)
223141cc406Sopenharmony_ci    reg_no++;
224141cc406Sopenharmony_ci
225141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, pattern));
226141cc406Sopenharmony_ci
227141cc406Sopenharmony_ci  chip->is_transfer_table[index] = is_transfer;
228141cc406Sopenharmony_ci
229141cc406Sopenharmony_ci  DBG (7, "usb_low_set_cmt_table: exit\n");
230141cc406Sopenharmony_ci
231141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
232141cc406Sopenharmony_ci}
233141cc406Sopenharmony_ci
234141cc406Sopenharmony_ci/* A2 */
235141cc406Sopenharmony_ciSANE_Status
236141cc406Sopenharmony_ciusb_low_get_a2 (ma1017 * chip, SANE_Byte * value)
237141cc406Sopenharmony_ci{
238141cc406Sopenharmony_ci  SANE_Byte pattern;
239141cc406Sopenharmony_ci  SANE_Status status;
240141cc406Sopenharmony_ci
241141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a2: start\n");
242141cc406Sopenharmony_ci  if (!chip->is_opened)
243141cc406Sopenharmony_ci    {
244141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a2: not opened yet\n");
245141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
246141cc406Sopenharmony_ci    }
247141cc406Sopenharmony_ci  if (chip->is_rowing)
248141cc406Sopenharmony_ci    {
249141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a2: stop rowing first\n");
250141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
251141cc406Sopenharmony_ci    }
252141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 2, &pattern));
253141cc406Sopenharmony_ci
254141cc406Sopenharmony_ci  chip->append = pattern & 0x10;
255141cc406Sopenharmony_ci  chip->test_sram = pattern & 0x20;
256141cc406Sopenharmony_ci  chip->fix_pattern = pattern & 0x80;
257141cc406Sopenharmony_ci  if (value)
258141cc406Sopenharmony_ci    *value = pattern;
259141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a2: exit, value =%d\n", pattern);
260141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
261141cc406Sopenharmony_ci}
262141cc406Sopenharmony_ci
263141cc406Sopenharmony_ciSANE_Status
264141cc406Sopenharmony_ciusb_low_start_cmt_table (ma1017 * chip)
265141cc406Sopenharmony_ci{
266141cc406Sopenharmony_ci  SANE_Byte data_field[2];
267141cc406Sopenharmony_ci  SANE_Status status;
268141cc406Sopenharmony_ci  size_t n;
269141cc406Sopenharmony_ci
270141cc406Sopenharmony_ci  DBG (7, "usb_low_start_cmt_table: start\n");
271141cc406Sopenharmony_ci
272141cc406Sopenharmony_ci  data_field[0] = 0x02 | chip->append | chip->test_sram | chip->fix_pattern;
273141cc406Sopenharmony_ci  data_field[1] = 2;
274141cc406Sopenharmony_ci
275141cc406Sopenharmony_ci  if (!chip->is_opened)
276141cc406Sopenharmony_ci    {
277141cc406Sopenharmony_ci      DBG (3, "usb_low_start_cmt_table: not opened yet\n");
278141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
279141cc406Sopenharmony_ci    }
280141cc406Sopenharmony_ci  if (chip->is_rowing)
281141cc406Sopenharmony_ci    {
282141cc406Sopenharmony_ci      DBG (7, "usb_low_start_cmt_table: Already Rowing\n");
283141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
284141cc406Sopenharmony_ci    }
285141cc406Sopenharmony_ci
286141cc406Sopenharmony_ci  data_field[1] |= 0x60;
287141cc406Sopenharmony_ci  n = 2;
288141cc406Sopenharmony_ci  status = sanei_usb_write_bulk (chip->fd, data_field, &n);
289141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD || n != 2)
290141cc406Sopenharmony_ci    {
291141cc406Sopenharmony_ci      DBG (3, "usb_low_start_cmt_table: can't write, wanted 2 bytes, "
292141cc406Sopenharmony_ci	   "wrote %lu bytes\n", (unsigned long int) n);
293141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
294141cc406Sopenharmony_ci    }
295141cc406Sopenharmony_ci  chip->total_write_urbs++;
296141cc406Sopenharmony_ci  chip->is_rowing = SANE_TRUE;
297141cc406Sopenharmony_ci  DBG (7, "usb_low_start_cmt_table: exit\n");
298141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
299141cc406Sopenharmony_ci}
300141cc406Sopenharmony_ci
301141cc406Sopenharmony_ciSANE_Status
302141cc406Sopenharmony_ciusb_low_stop_cmt_table (ma1017 * chip)
303141cc406Sopenharmony_ci{
304141cc406Sopenharmony_ci  SANE_Byte data_field[2];
305141cc406Sopenharmony_ci  SANE_Byte read_byte;
306141cc406Sopenharmony_ci  size_t n;
307141cc406Sopenharmony_ci  SANE_Status status;
308141cc406Sopenharmony_ci
309141cc406Sopenharmony_ci  DBG (7, "usb_low_stop_cmt_table: start\n");
310141cc406Sopenharmony_ci
311141cc406Sopenharmony_ci  if (!chip->is_opened)
312141cc406Sopenharmony_ci    {
313141cc406Sopenharmony_ci      DBG (3, "usb_low_stop_cmt_table: not opened yet\n");
314141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
315141cc406Sopenharmony_ci    }
316141cc406Sopenharmony_ci  if (!chip->is_rowing)
317141cc406Sopenharmony_ci    {
318141cc406Sopenharmony_ci      DBG (7, "usb_low_stop_cmt_table: Not Rowing yet\n");
319141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
320141cc406Sopenharmony_ci    }
321141cc406Sopenharmony_ci
322141cc406Sopenharmony_ci  data_field[0] = 0x01 | chip->append | chip->test_sram | chip->fix_pattern;
323141cc406Sopenharmony_ci  data_field[1] = 2;
324141cc406Sopenharmony_ci  data_field[1] |= 0x80;
325141cc406Sopenharmony_ci  n = 2;
326141cc406Sopenharmony_ci  status = sanei_usb_write_bulk (chip->fd, data_field, &n);
327141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD || n != 2)
328141cc406Sopenharmony_ci    {
329141cc406Sopenharmony_ci      DBG (3, "usb_low_stop_cmt_table: couldn't write, wanted 2 bytes, wrote "
330141cc406Sopenharmony_ci	   "%lu bytes\n", (unsigned long int) n);
331141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
332141cc406Sopenharmony_ci    }
333141cc406Sopenharmony_ci  chip->total_write_urbs++;
334141cc406Sopenharmony_ci  n = 1;
335141cc406Sopenharmony_ci  status = sanei_usb_read_bulk (chip->fd, &read_byte, &n);
336141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD || n != 1)
337141cc406Sopenharmony_ci    {
338141cc406Sopenharmony_ci      DBG (3, "usb_low_stop_cmt_table: couldn't read, wanted 1 byte, got %lu "
339141cc406Sopenharmony_ci	   "bytes\n", (unsigned long int) n);
340141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
341141cc406Sopenharmony_ci    }
342141cc406Sopenharmony_ci  chip->total_read_urbs++;
343141cc406Sopenharmony_ci  chip->is_rowing = SANE_FALSE;
344141cc406Sopenharmony_ci
345141cc406Sopenharmony_ci  DBG (7, "usb_low_stop_cmt_table: exit\n");
346141cc406Sopenharmony_ci
347141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
348141cc406Sopenharmony_ci}
349141cc406Sopenharmony_ci
350141cc406Sopenharmony_ciSANE_Status
351141cc406Sopenharmony_ciusb_low_set_test_sram_mode (ma1017 * chip, SANE_Bool is_test)
352141cc406Sopenharmony_ci{
353141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
354141cc406Sopenharmony_ci  SANE_Status status;
355141cc406Sopenharmony_ci
356141cc406Sopenharmony_ci  DBG (7, "usb_low_set_test_sram_mode: start\n");
357141cc406Sopenharmony_ci
358141cc406Sopenharmony_ci  data = chip->append | chip->test_sram | chip->fix_pattern;
359141cc406Sopenharmony_ci  reg_no = 2;
360141cc406Sopenharmony_ci
361141cc406Sopenharmony_ci  if (!chip->is_opened)
362141cc406Sopenharmony_ci    {
363141cc406Sopenharmony_ci      DBG (3, "usb_low_set_test_sram_mode: not opened yet\n");
364141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
365141cc406Sopenharmony_ci    }
366141cc406Sopenharmony_ci  if (chip->is_rowing)
367141cc406Sopenharmony_ci    {
368141cc406Sopenharmony_ci      DBG (3, "usb_low_set_test_sram_mode: stop rowing first\n");
369141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
370141cc406Sopenharmony_ci    }
371141cc406Sopenharmony_ci
372141cc406Sopenharmony_ci  if (is_test)
373141cc406Sopenharmony_ci    chip->test_sram = 0x20;
374141cc406Sopenharmony_ci  else
375141cc406Sopenharmony_ci    chip->test_sram = 0x00;
376141cc406Sopenharmony_ci
377141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
378141cc406Sopenharmony_ci
379141cc406Sopenharmony_ci  DBG (7, "usb_low_set_test_sram_mode: exit\n");
380141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
381141cc406Sopenharmony_ci}
382141cc406Sopenharmony_ci
383141cc406Sopenharmony_ciSANE_Status
384141cc406Sopenharmony_ciusb_low_set_fix_pattern (ma1017 * chip, SANE_Bool is_fix)
385141cc406Sopenharmony_ci{
386141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
387141cc406Sopenharmony_ci  SANE_Status status;
388141cc406Sopenharmony_ci
389141cc406Sopenharmony_ci  DBG (7, "usb_low_set_fix_pattern: start\n");
390141cc406Sopenharmony_ci
391141cc406Sopenharmony_ci  data = chip->append | chip->test_sram | chip->fix_pattern;
392141cc406Sopenharmony_ci  reg_no = 2;
393141cc406Sopenharmony_ci
394141cc406Sopenharmony_ci  if (!chip->is_opened)
395141cc406Sopenharmony_ci    {
396141cc406Sopenharmony_ci      DBG (3, "usb_low_set_fix_pattern: not opened yet\n");
397141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
398141cc406Sopenharmony_ci    }
399141cc406Sopenharmony_ci  if (chip->is_rowing)
400141cc406Sopenharmony_ci    {
401141cc406Sopenharmony_ci      DBG (3, "usb_low_set_fix_pattern: stop rowing first\n");
402141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
403141cc406Sopenharmony_ci    }
404141cc406Sopenharmony_ci
405141cc406Sopenharmony_ci  if (is_fix)
406141cc406Sopenharmony_ci    chip->fix_pattern = 0x80;
407141cc406Sopenharmony_ci  else
408141cc406Sopenharmony_ci    chip->fix_pattern = 0x00;
409141cc406Sopenharmony_ci
410141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
411141cc406Sopenharmony_ci
412141cc406Sopenharmony_ci  DBG (7, "usb_low_set_fix_pattern: exit\n");
413141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
414141cc406Sopenharmony_ci}
415141cc406Sopenharmony_ci
416141cc406Sopenharmony_ciSANE_Status
417141cc406Sopenharmony_ciusb_low_adjust_timing (ma1017 * chip, SANE_Byte data)
418141cc406Sopenharmony_ci{
419141cc406Sopenharmony_ci  SANE_Status status;
420141cc406Sopenharmony_ci  SANE_Byte reg_no;
421141cc406Sopenharmony_ci
422141cc406Sopenharmony_ci  DBG (7, "usb_low_adjust_timing: start\n");
423141cc406Sopenharmony_ci
424141cc406Sopenharmony_ci  reg_no = 3;
425141cc406Sopenharmony_ci
426141cc406Sopenharmony_ci  if (!chip->is_opened)
427141cc406Sopenharmony_ci    {
428141cc406Sopenharmony_ci      DBG (3, "usb_low_adjust_timing: not opened yet\n");
429141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
430141cc406Sopenharmony_ci    }
431141cc406Sopenharmony_ci  if (chip->is_rowing)
432141cc406Sopenharmony_ci    {
433141cc406Sopenharmony_ci      DBG (3, "usb_low_adjust_timing: stop rowing first\n");
434141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
435141cc406Sopenharmony_ci    }
436141cc406Sopenharmony_ci
437141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
438141cc406Sopenharmony_ci
439141cc406Sopenharmony_ci  DBG (7, "usb_low_adjust_timing: exit\n");
440141cc406Sopenharmony_ci
441141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
442141cc406Sopenharmony_ci}
443141cc406Sopenharmony_ci
444141cc406Sopenharmony_ci/* A4 */
445141cc406Sopenharmony_ciSANE_Status
446141cc406Sopenharmony_ciusb_low_get_a4 (ma1017 * chip, SANE_Byte * value)
447141cc406Sopenharmony_ci{
448141cc406Sopenharmony_ci  SANE_Status status;
449141cc406Sopenharmony_ci  SANE_Byte pattern;
450141cc406Sopenharmony_ci
451141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a4: start\n");
452141cc406Sopenharmony_ci  if (!chip->is_opened)
453141cc406Sopenharmony_ci    {
454141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a4: not opened yet\n");
455141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
456141cc406Sopenharmony_ci    }
457141cc406Sopenharmony_ci  if (chip->is_rowing)
458141cc406Sopenharmony_ci    {
459141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a4: stop rowing first\n");
460141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
461141cc406Sopenharmony_ci    }
462141cc406Sopenharmony_ci
463141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 4, &pattern));
464141cc406Sopenharmony_ci
465141cc406Sopenharmony_ci  chip->select = pattern & 0xfe;
466141cc406Sopenharmony_ci  chip->frontend = pattern & 0x01;
467141cc406Sopenharmony_ci
468141cc406Sopenharmony_ci  if (value)
469141cc406Sopenharmony_ci    *value = pattern;
470141cc406Sopenharmony_ci
471141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a4: exit, value=%d\n", pattern);
472141cc406Sopenharmony_ci
473141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
474141cc406Sopenharmony_ci}
475141cc406Sopenharmony_ci
476141cc406Sopenharmony_ciSANE_Status
477141cc406Sopenharmony_ciusb_low_select_timing (ma1017 * chip, SANE_Byte data)
478141cc406Sopenharmony_ci{
479141cc406Sopenharmony_ci  SANE_Status status;
480141cc406Sopenharmony_ci  SANE_Byte reg_no;
481141cc406Sopenharmony_ci
482141cc406Sopenharmony_ci  DBG (7, "usb_low_select_timing: start\n");
483141cc406Sopenharmony_ci
484141cc406Sopenharmony_ci  reg_no = 4;
485141cc406Sopenharmony_ci
486141cc406Sopenharmony_ci  if (!chip->is_opened)
487141cc406Sopenharmony_ci    {
488141cc406Sopenharmony_ci      DBG (3, "usb_low_select_timing: not opened yet\n");
489141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
490141cc406Sopenharmony_ci    }
491141cc406Sopenharmony_ci  if (chip->is_rowing)
492141cc406Sopenharmony_ci    {
493141cc406Sopenharmony_ci      DBG (3, "usb_low_select_timing: stop rowing first\n");
494141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
495141cc406Sopenharmony_ci    }
496141cc406Sopenharmony_ci
497141cc406Sopenharmony_ci  chip->select = data & 0xfe;
498141cc406Sopenharmony_ci  chip->frontend = data & 0x01;
499141cc406Sopenharmony_ci
500141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
501141cc406Sopenharmony_ci
502141cc406Sopenharmony_ci  DBG (7, "usb_low_select_timing: exit\n");
503141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
504141cc406Sopenharmony_ci}
505141cc406Sopenharmony_ci
506141cc406Sopenharmony_ciSANE_Status
507141cc406Sopenharmony_ciusb_low_turn_frontend_mode (ma1017 * chip, SANE_Bool is_on)
508141cc406Sopenharmony_ci{
509141cc406Sopenharmony_ci  SANE_Status status;
510141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
511141cc406Sopenharmony_ci
512141cc406Sopenharmony_ci  DBG (7, "usb_low_turn_frontend_mode: start\n");
513141cc406Sopenharmony_ci  if (!chip->is_opened)
514141cc406Sopenharmony_ci    {
515141cc406Sopenharmony_ci      DBG (3, "usb_low_turn_frontend_mode: not opened yet\n");
516141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
517141cc406Sopenharmony_ci    }
518141cc406Sopenharmony_ci  if (chip->is_rowing)
519141cc406Sopenharmony_ci    {
520141cc406Sopenharmony_ci      DBG (3, "usb_low_turn_frontend_mode: stop rowing first\n");
521141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
522141cc406Sopenharmony_ci    }
523141cc406Sopenharmony_ci
524141cc406Sopenharmony_ci  if (is_on)
525141cc406Sopenharmony_ci    chip->frontend = 0x01;
526141cc406Sopenharmony_ci  else
527141cc406Sopenharmony_ci    chip->frontend = 0x00;
528141cc406Sopenharmony_ci
529141cc406Sopenharmony_ci  data = chip->select | chip->frontend;
530141cc406Sopenharmony_ci  reg_no = 4;
531141cc406Sopenharmony_ci
532141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
533141cc406Sopenharmony_ci
534141cc406Sopenharmony_ci  DBG (7, "usb_low_turn_frontend_mode: exit\n");
535141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
536141cc406Sopenharmony_ci}
537141cc406Sopenharmony_ci
538141cc406Sopenharmony_ci/* A6 */
539141cc406Sopenharmony_ciSANE_Status
540141cc406Sopenharmony_ciusb_low_get_a6 (ma1017 * chip, SANE_Byte * value)
541141cc406Sopenharmony_ci{
542141cc406Sopenharmony_ci  SANE_Byte pattern;
543141cc406Sopenharmony_ci  SANE_Status status;
544141cc406Sopenharmony_ci
545141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a6: start\n");
546141cc406Sopenharmony_ci
547141cc406Sopenharmony_ci  if (!chip->is_opened)
548141cc406Sopenharmony_ci    {
549141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a6: not opened yet\n");
550141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
551141cc406Sopenharmony_ci    }
552141cc406Sopenharmony_ci  if (chip->is_rowing)
553141cc406Sopenharmony_ci    {
554141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a6: stop rowing first\n");
555141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
556141cc406Sopenharmony_ci    }
557141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 6, &pattern));
558141cc406Sopenharmony_ci
559141cc406Sopenharmony_ci  chip->asic_io_pins = pattern & 0xdc;
560141cc406Sopenharmony_ci  chip->rgb_sel_pin = pattern & 0x03;
561141cc406Sopenharmony_ci
562141cc406Sopenharmony_ci  if (value)
563141cc406Sopenharmony_ci    *value = pattern;
564141cc406Sopenharmony_ci
565141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a6: exit\n");
566141cc406Sopenharmony_ci
567141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
568141cc406Sopenharmony_ci}
569141cc406Sopenharmony_ci
570141cc406Sopenharmony_ciSANE_Status
571141cc406Sopenharmony_ciusb_low_set_asic_io_pins (ma1017 * chip, SANE_Byte data)
572141cc406Sopenharmony_ci{
573141cc406Sopenharmony_ci  SANE_Status status;
574141cc406Sopenharmony_ci  SANE_Byte reg_no;
575141cc406Sopenharmony_ci
576141cc406Sopenharmony_ci  DBG (7, "usb_low_set_asic_io_pins: start\n");
577141cc406Sopenharmony_ci
578141cc406Sopenharmony_ci  if (!chip->is_opened)
579141cc406Sopenharmony_ci    {
580141cc406Sopenharmony_ci      DBG (3, "usb_low_set_asic_io_pins: not opened yet\n");
581141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
582141cc406Sopenharmony_ci    }
583141cc406Sopenharmony_ci  if (chip->is_rowing)
584141cc406Sopenharmony_ci    {
585141cc406Sopenharmony_ci      DBG (3, "usb_low_set_asic_io_pins: stop rowing first\n");
586141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
587141cc406Sopenharmony_ci    }
588141cc406Sopenharmony_ci
589141cc406Sopenharmony_ci  chip->asic_io_pins = data & 0xdc;
590141cc406Sopenharmony_ci
591141cc406Sopenharmony_ci  data = chip->asic_io_pins | chip->rgb_sel_pin;
592141cc406Sopenharmony_ci  reg_no = 6;
593141cc406Sopenharmony_ci
594141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
595141cc406Sopenharmony_ci
596141cc406Sopenharmony_ci  DBG (7, "usb_low_set_asic_io_pins: exit\n");
597141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
598141cc406Sopenharmony_ci}
599141cc406Sopenharmony_ci
600141cc406Sopenharmony_ciSANE_Status
601141cc406Sopenharmony_ciusb_low_set_rgb_sel_pins (ma1017 * chip, SANE_Byte data)
602141cc406Sopenharmony_ci{
603141cc406Sopenharmony_ci  SANE_Status status;
604141cc406Sopenharmony_ci  SANE_Byte reg_no;
605141cc406Sopenharmony_ci
606141cc406Sopenharmony_ci  DBG (7, "usb_low_set_rgb_sel_pins: start\n");
607141cc406Sopenharmony_ci
608141cc406Sopenharmony_ci  if (!chip->is_opened)
609141cc406Sopenharmony_ci    {
610141cc406Sopenharmony_ci      DBG (3, "usb_low_set_rgb_sel_pins: not opened yet\n");
611141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
612141cc406Sopenharmony_ci    }
613141cc406Sopenharmony_ci  if (chip->is_rowing)
614141cc406Sopenharmony_ci    {
615141cc406Sopenharmony_ci      DBG (3, "usb_low_set_rgb_sel_pins: stop rowing first\n");
616141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
617141cc406Sopenharmony_ci    }
618141cc406Sopenharmony_ci  chip->rgb_sel_pin = data & 0x03;
619141cc406Sopenharmony_ci  data = chip->asic_io_pins | chip->rgb_sel_pin;
620141cc406Sopenharmony_ci  reg_no = 6;
621141cc406Sopenharmony_ci
622141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
623141cc406Sopenharmony_ci
624141cc406Sopenharmony_ci  DBG (7, "usb_low_set_rgb_sel_pins: exit\n");
625141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;	/* was false? */
626141cc406Sopenharmony_ci}
627141cc406Sopenharmony_ci
628141cc406Sopenharmony_ci/* A7 */
629141cc406Sopenharmony_ciSANE_Status
630141cc406Sopenharmony_ciusb_low_get_a7 (ma1017 * chip, SANE_Byte * value)
631141cc406Sopenharmony_ci{
632141cc406Sopenharmony_ci  SANE_Byte pattern;
633141cc406Sopenharmony_ci  SANE_Status status;
634141cc406Sopenharmony_ci
635141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a7: start\n");
636141cc406Sopenharmony_ci  if (!chip->is_opened)
637141cc406Sopenharmony_ci    {
638141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a7: not opened yet\n");
639141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
640141cc406Sopenharmony_ci    }
641141cc406Sopenharmony_ci  if (chip->is_rowing)
642141cc406Sopenharmony_ci    {
643141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a7: stop rowing first\n");
644141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
645141cc406Sopenharmony_ci    }
646141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 7, &pattern));
647141cc406Sopenharmony_ci
648141cc406Sopenharmony_ci  if (value)
649141cc406Sopenharmony_ci    *value = pattern;
650141cc406Sopenharmony_ci
651141cc406Sopenharmony_ci  chip->timing = pattern & 0xfc;
652141cc406Sopenharmony_ci  chip->sram_bank = pattern & 0x03;
653141cc406Sopenharmony_ci
654141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a7: exit\n");
655141cc406Sopenharmony_ci
656141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
657141cc406Sopenharmony_ci}
658141cc406Sopenharmony_ci
659141cc406Sopenharmony_ciSANE_Status
660141cc406Sopenharmony_ciusb_low_set_timing (ma1017 * chip, SANE_Byte data)
661141cc406Sopenharmony_ci{
662141cc406Sopenharmony_ci  SANE_Status status;
663141cc406Sopenharmony_ci  SANE_Byte reg_no;
664141cc406Sopenharmony_ci
665141cc406Sopenharmony_ci  DBG (7, "usb_low_set_timing: start\n");
666141cc406Sopenharmony_ci  if (!chip->is_opened)
667141cc406Sopenharmony_ci    {
668141cc406Sopenharmony_ci      DBG (3, "usb_low_set_timing: not opened yet\n");
669141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
670141cc406Sopenharmony_ci    }
671141cc406Sopenharmony_ci  if (chip->is_rowing)
672141cc406Sopenharmony_ci    {
673141cc406Sopenharmony_ci      DBG (3, "usb_low_set_timing: stop rowing first\n");
674141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
675141cc406Sopenharmony_ci    }
676141cc406Sopenharmony_ci
677141cc406Sopenharmony_ci  chip->timing = data & 0xfc;
678141cc406Sopenharmony_ci  data = chip->timing | chip->sram_bank;
679141cc406Sopenharmony_ci  reg_no = 7;
680141cc406Sopenharmony_ci
681141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
682141cc406Sopenharmony_ci
683141cc406Sopenharmony_ci  DBG (7, "usb_low_set_timing: exit\n");
684141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
685141cc406Sopenharmony_ci}
686141cc406Sopenharmony_ci
687141cc406Sopenharmony_ciSANE_Status
688141cc406Sopenharmony_ciusb_low_set_sram_bank (ma1017 * chip, Banksize banksize)
689141cc406Sopenharmony_ci{
690141cc406Sopenharmony_ci  SANE_Status status;
691141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
692141cc406Sopenharmony_ci
693141cc406Sopenharmony_ci  DBG (7, "usb_low_set_sram_bank: start\n");
694141cc406Sopenharmony_ci  if (!chip->is_opened)
695141cc406Sopenharmony_ci    {
696141cc406Sopenharmony_ci      DBG (3, "usb_low_set_sram_bank: not opened yet\n");
697141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
698141cc406Sopenharmony_ci    }
699141cc406Sopenharmony_ci  if (chip->is_rowing)
700141cc406Sopenharmony_ci    {
701141cc406Sopenharmony_ci      DBG (3, "usb_low_set_sram_bank: stop rowing first\n");
702141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
703141cc406Sopenharmony_ci    }
704141cc406Sopenharmony_ci
705141cc406Sopenharmony_ci  switch (banksize)
706141cc406Sopenharmony_ci    {
707141cc406Sopenharmony_ci    case BS_4K:
708141cc406Sopenharmony_ci      chip->sram_bank = 0x00;
709141cc406Sopenharmony_ci      break;
710141cc406Sopenharmony_ci    case BS_8K:
711141cc406Sopenharmony_ci      chip->sram_bank = 0x01;
712141cc406Sopenharmony_ci      break;
713141cc406Sopenharmony_ci    case BS_16K:
714141cc406Sopenharmony_ci      chip->sram_bank = 0x02;
715141cc406Sopenharmony_ci      break;
716141cc406Sopenharmony_ci    default:
717141cc406Sopenharmony_ci      DBG (3, "usb_low_set_sram_bank: bsBankSize error\n");
718141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
719141cc406Sopenharmony_ci      break;
720141cc406Sopenharmony_ci    }
721141cc406Sopenharmony_ci  data = chip->timing | chip->sram_bank;
722141cc406Sopenharmony_ci  reg_no = 7;
723141cc406Sopenharmony_ci
724141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
725141cc406Sopenharmony_ci
726141cc406Sopenharmony_ci  DBG (7, "usb_low_set_sram_bank: exit\n");
727141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
728141cc406Sopenharmony_ci}
729141cc406Sopenharmony_ci
730141cc406Sopenharmony_ci/* A8 */
731141cc406Sopenharmony_ciSANE_Status
732141cc406Sopenharmony_ciusb_low_get_a8 (ma1017 * chip, SANE_Byte * value)
733141cc406Sopenharmony_ci{
734141cc406Sopenharmony_ci  SANE_Byte pattern;
735141cc406Sopenharmony_ci  SANE_Status status;
736141cc406Sopenharmony_ci
737141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a8: start\n");
738141cc406Sopenharmony_ci  if (!chip->is_opened)
739141cc406Sopenharmony_ci    {
740141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a8: not opened yet\n");
741141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
742141cc406Sopenharmony_ci    }
743141cc406Sopenharmony_ci  if (chip->is_rowing)
744141cc406Sopenharmony_ci    {
745141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a8: stop rowing first\n");
746141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
747141cc406Sopenharmony_ci    }
748141cc406Sopenharmony_ci
749141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 8, &pattern));
750141cc406Sopenharmony_ci
751141cc406Sopenharmony_ci  chip->dummy_msb = pattern & 0x40;
752141cc406Sopenharmony_ci  chip->ccd_width_msb = pattern & 0x20;
753141cc406Sopenharmony_ci  chip->cmt_table_length = pattern & 0x1f;
754141cc406Sopenharmony_ci  chip->ccd_width =
755141cc406Sopenharmony_ci    ((chip->ccd_width / 32) & 0x00ff) * 32 +
756141cc406Sopenharmony_ci    ((chip->ccd_width_msb == 0) ? 0 : 0x0100 * 32);
757141cc406Sopenharmony_ci  chip->dummy =
758141cc406Sopenharmony_ci    ((chip->dummy / 32) & 0x00ff) * 32 +
759141cc406Sopenharmony_ci    ((chip->dummy_msb == 0) ? 0 : 0x0100 * 32);
760141cc406Sopenharmony_ci
761141cc406Sopenharmony_ci  if (value)
762141cc406Sopenharmony_ci    *value = pattern;
763141cc406Sopenharmony_ci
764141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a8: exit\n");
765141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
766141cc406Sopenharmony_ci}
767141cc406Sopenharmony_ci
768141cc406Sopenharmony_ciSANE_Status
769141cc406Sopenharmony_ciusb_low_set_cmt_table_length (ma1017 * chip, SANE_Byte table_length)
770141cc406Sopenharmony_ci{
771141cc406Sopenharmony_ci  SANE_Status status;
772141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
773141cc406Sopenharmony_ci
774141cc406Sopenharmony_ci  DBG (7, "usb_low_set_cmt_table_length: start\n");
775141cc406Sopenharmony_ci  if (!chip->is_opened)
776141cc406Sopenharmony_ci    {
777141cc406Sopenharmony_ci      DBG (3, "usb_low_set_cmt_table_length: not opened yet\n");
778141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
779141cc406Sopenharmony_ci    }
780141cc406Sopenharmony_ci  if (chip->is_rowing)
781141cc406Sopenharmony_ci    {
782141cc406Sopenharmony_ci      DBG (3, "usb_low_set_cmt_table_length: stop rowing first\n");
783141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
784141cc406Sopenharmony_ci    }
785141cc406Sopenharmony_ci  if (table_length > 32)
786141cc406Sopenharmony_ci    {
787141cc406Sopenharmony_ci      DBG (3, "usb_low_set_cmt_table_length: length %d exceeds 32\n",
788141cc406Sopenharmony_ci	   (int) table_length);
789141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
790141cc406Sopenharmony_ci    }
791141cc406Sopenharmony_ci  if (table_length == 0)
792141cc406Sopenharmony_ci    {
793141cc406Sopenharmony_ci      DBG (3, "usb_low_set_cmt_table_length: length is 0\n");
794141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
795141cc406Sopenharmony_ci    }
796141cc406Sopenharmony_ci
797141cc406Sopenharmony_ci  chip->cmt_table_length = table_length - 1;
798141cc406Sopenharmony_ci  chip->cmt_table_length_word = (SANE_Word) table_length;
799141cc406Sopenharmony_ci  data = chip->cmt_table_length | chip->ccd_width_msb | chip->dummy_msb;
800141cc406Sopenharmony_ci  reg_no = 8;
801141cc406Sopenharmony_ci
802141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
803141cc406Sopenharmony_ci
804141cc406Sopenharmony_ci  DBG (7, "usb_low_set_cmt_table_length: exit\n");
805141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
806141cc406Sopenharmony_ci}
807141cc406Sopenharmony_ci
808141cc406Sopenharmony_ci/* A9 */
809141cc406Sopenharmony_ciSANE_Status
810141cc406Sopenharmony_ciusb_low_get_a9 (ma1017 * chip, SANE_Byte * value)
811141cc406Sopenharmony_ci{
812141cc406Sopenharmony_ci  SANE_Byte pattern;
813141cc406Sopenharmony_ci  SANE_Status status;
814141cc406Sopenharmony_ci
815141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a9: start\n");
816141cc406Sopenharmony_ci
817141cc406Sopenharmony_ci  if (!chip->is_opened)
818141cc406Sopenharmony_ci    {
819141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a9: not opened yet\n");
820141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
821141cc406Sopenharmony_ci    }
822141cc406Sopenharmony_ci  if (chip->is_rowing)
823141cc406Sopenharmony_ci    {
824141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a9: stop rowing first\n");
825141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
826141cc406Sopenharmony_ci    }
827141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 9, &pattern));
828141cc406Sopenharmony_ci
829141cc406Sopenharmony_ci  chip->cmt_second_pos = pattern & 0x1f;
830141cc406Sopenharmony_ci
831141cc406Sopenharmony_ci  if (value)
832141cc406Sopenharmony_ci    *value = pattern;
833141cc406Sopenharmony_ci
834141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a9: exit\n");
835141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
836141cc406Sopenharmony_ci}
837141cc406Sopenharmony_ci
838141cc406Sopenharmony_ciSANE_Status
839141cc406Sopenharmony_ciusb_low_set_cmt_second_position (ma1017 * chip, SANE_Byte position)
840141cc406Sopenharmony_ci{
841141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
842141cc406Sopenharmony_ci  SANE_Status status;
843141cc406Sopenharmony_ci
844141cc406Sopenharmony_ci  DBG (7, "usb_low_set_cmt_second_position: start\n");
845141cc406Sopenharmony_ci
846141cc406Sopenharmony_ci  if (!chip->is_opened)
847141cc406Sopenharmony_ci    {
848141cc406Sopenharmony_ci      DBG (3, "usb_low_set_cmt_second_position: not opened yet\n");
849141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
850141cc406Sopenharmony_ci    }
851141cc406Sopenharmony_ci  if (chip->is_rowing)
852141cc406Sopenharmony_ci    {
853141cc406Sopenharmony_ci      DBG (3, "usb_low_set_cmt_second_position: stop rowing first\n");
854141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
855141cc406Sopenharmony_ci    }
856141cc406Sopenharmony_ci  if (position > 31)
857141cc406Sopenharmony_ci    {
858141cc406Sopenharmony_ci      DBG (3, "usb_low_set_cmt_second_position: length: %d exceeds 31\n",
859141cc406Sopenharmony_ci	   (int) position);
860141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
861141cc406Sopenharmony_ci    }
862141cc406Sopenharmony_ci
863141cc406Sopenharmony_ci  chip->cmt_second_pos = position;
864141cc406Sopenharmony_ci  chip->cmt_second_pos_word = (SANE_Word) (position);
865141cc406Sopenharmony_ci  data = chip->cmt_second_pos;
866141cc406Sopenharmony_ci  reg_no = 9;
867141cc406Sopenharmony_ci
868141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
869141cc406Sopenharmony_ci
870141cc406Sopenharmony_ci  DBG (7, "usb_low_set_cmt_second_position: exit\n");
871141cc406Sopenharmony_ci
872141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
873141cc406Sopenharmony_ci}
874141cc406Sopenharmony_ci
875141cc406Sopenharmony_ci/* A10 + A8ID5 */
876141cc406Sopenharmony_ciSANE_Status
877141cc406Sopenharmony_ciusb_low_get_a10 (ma1017 * chip, SANE_Byte * value)
878141cc406Sopenharmony_ci{
879141cc406Sopenharmony_ci  SANE_Byte pattern;
880141cc406Sopenharmony_ci  SANE_Status status;
881141cc406Sopenharmony_ci
882141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a10: start\n");
883141cc406Sopenharmony_ci
884141cc406Sopenharmony_ci  if (!chip->is_opened)
885141cc406Sopenharmony_ci    {
886141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a10: not opened yet\n");
887141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
888141cc406Sopenharmony_ci    }
889141cc406Sopenharmony_ci  if (chip->is_rowing)
890141cc406Sopenharmony_ci    {
891141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a10: stop rowing first\n");
892141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
893141cc406Sopenharmony_ci    }
894141cc406Sopenharmony_ci
895141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 10, &pattern));
896141cc406Sopenharmony_ci
897141cc406Sopenharmony_ci  chip->ccd_width =
898141cc406Sopenharmony_ci    ((SANE_Word) (pattern)) * 32 +
899141cc406Sopenharmony_ci    ((chip->ccd_width_msb == 0) ? 0 : 0x0100 * 32);
900141cc406Sopenharmony_ci
901141cc406Sopenharmony_ci  if (value)
902141cc406Sopenharmony_ci    *value = pattern;
903141cc406Sopenharmony_ci
904141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a10: exit\n");
905141cc406Sopenharmony_ci
906141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
907141cc406Sopenharmony_ci}
908141cc406Sopenharmony_ci
909141cc406Sopenharmony_ciSANE_Status
910141cc406Sopenharmony_ciusb_low_set_ccd_width (ma1017 * chip, SANE_Word ccd_width)
911141cc406Sopenharmony_ci{
912141cc406Sopenharmony_ci  SANE_Status status;
913141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
914141cc406Sopenharmony_ci
915141cc406Sopenharmony_ci  DBG (7, "usb_low_set_ccd_width: start\n");
916141cc406Sopenharmony_ci
917141cc406Sopenharmony_ci  if (!chip->is_opened)
918141cc406Sopenharmony_ci    {
919141cc406Sopenharmony_ci      DBG (3, "usb_low_set_ccd_width: not opened yet\n");
920141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
921141cc406Sopenharmony_ci    }
922141cc406Sopenharmony_ci  if (chip->is_rowing)
923141cc406Sopenharmony_ci    {
924141cc406Sopenharmony_ci      DBG (3, "usb_low_set_ccd_width: stop rowing first\n");
925141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
926141cc406Sopenharmony_ci    }
927141cc406Sopenharmony_ci  if (ccd_width / 32 > 0x01ff)
928141cc406Sopenharmony_ci    {
929141cc406Sopenharmony_ci      DBG (3, "usb_low_set_ccd_width: width %d too high\n", (int) ccd_width);
930141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
931141cc406Sopenharmony_ci    }
932141cc406Sopenharmony_ci
933141cc406Sopenharmony_ci  chip->ccd_width = ccd_width;
934141cc406Sopenharmony_ci  ccd_width /= 32;
935141cc406Sopenharmony_ci  if (HIBYTE (ccd_width) == 0x01)
936141cc406Sopenharmony_ci    chip->ccd_width_msb = 0x20;
937141cc406Sopenharmony_ci  else
938141cc406Sopenharmony_ci    chip->ccd_width_msb = 0x00;
939141cc406Sopenharmony_ci
940141cc406Sopenharmony_ci  data = chip->cmt_table_length | chip->ccd_width_msb | chip->dummy_msb;
941141cc406Sopenharmony_ci  reg_no = 8;
942141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
943141cc406Sopenharmony_ci
944141cc406Sopenharmony_ci  data = LOBYTE (ccd_width);
945141cc406Sopenharmony_ci  reg_no = 10;
946141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
947141cc406Sopenharmony_ci
948141cc406Sopenharmony_ci  DBG (7, "usb_low_set_ccd_width: exit\n");
949141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
950141cc406Sopenharmony_ci}
951141cc406Sopenharmony_ci
952141cc406Sopenharmony_ci/* A11 + A8ID6 */
953141cc406Sopenharmony_ciSANE_Status
954141cc406Sopenharmony_ciusb_low_get_a11 (ma1017 * chip, SANE_Byte * value)
955141cc406Sopenharmony_ci{
956141cc406Sopenharmony_ci  SANE_Byte pattern;
957141cc406Sopenharmony_ci  SANE_Status status;
958141cc406Sopenharmony_ci
959141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a11: start\n");
960141cc406Sopenharmony_ci
961141cc406Sopenharmony_ci  if (!chip->is_opened)
962141cc406Sopenharmony_ci    {
963141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a11: not opened yet\n");
964141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
965141cc406Sopenharmony_ci    }
966141cc406Sopenharmony_ci  if (chip->is_rowing)
967141cc406Sopenharmony_ci    {
968141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a11: stop rowing first\n");
969141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
970141cc406Sopenharmony_ci    }
971141cc406Sopenharmony_ci
972141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 11, &pattern));
973141cc406Sopenharmony_ci
974141cc406Sopenharmony_ci  chip->dummy =
975141cc406Sopenharmony_ci    ((SANE_Word) (pattern)) * 32 + ((chip->dummy_msb == 0) ? 0 : 0x0100 * 32);
976141cc406Sopenharmony_ci
977141cc406Sopenharmony_ci  if (value)
978141cc406Sopenharmony_ci    *value = pattern;
979141cc406Sopenharmony_ci
980141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a11: exit\n");
981141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
982141cc406Sopenharmony_ci}
983141cc406Sopenharmony_ci
984141cc406Sopenharmony_ciSANE_Status
985141cc406Sopenharmony_ciusb_low_set_dummy (ma1017 * chip, SANE_Word dummy)
986141cc406Sopenharmony_ci{
987141cc406Sopenharmony_ci  SANE_Status status;
988141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
989141cc406Sopenharmony_ci
990141cc406Sopenharmony_ci  DBG (7, "usb_low_set_dummy: start\n");
991141cc406Sopenharmony_ci
992141cc406Sopenharmony_ci  if (!chip->is_opened)
993141cc406Sopenharmony_ci    {
994141cc406Sopenharmony_ci      DBG (3, "usb_low_set_dummy: not opened yet\n");
995141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
996141cc406Sopenharmony_ci    }
997141cc406Sopenharmony_ci  if (chip->is_rowing)
998141cc406Sopenharmony_ci    {
999141cc406Sopenharmony_ci      DBG (3, "usb_low_set_dummy: stop rowing first\n");
1000141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1001141cc406Sopenharmony_ci    }
1002141cc406Sopenharmony_ci  if (dummy / 32 > 0x01ff)
1003141cc406Sopenharmony_ci    {
1004141cc406Sopenharmony_ci      DBG (7, "usb_low_set_dummy: width %d exceeded\n", (int) dummy);
1005141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1006141cc406Sopenharmony_ci    }
1007141cc406Sopenharmony_ci
1008141cc406Sopenharmony_ci  chip->dummy = dummy;
1009141cc406Sopenharmony_ci  dummy /= 32;
1010141cc406Sopenharmony_ci  dummy++;
1011141cc406Sopenharmony_ci  if (HIBYTE (dummy) == 0x01)
1012141cc406Sopenharmony_ci    chip->dummy_msb = 0x40;
1013141cc406Sopenharmony_ci  else
1014141cc406Sopenharmony_ci    chip->dummy_msb = 0x00;
1015141cc406Sopenharmony_ci  data = chip->cmt_table_length | chip->ccd_width_msb | chip->dummy_msb;
1016141cc406Sopenharmony_ci  reg_no = 8;
1017141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1018141cc406Sopenharmony_ci
1019141cc406Sopenharmony_ci  data = LOBYTE (dummy);
1020141cc406Sopenharmony_ci  reg_no = 11;
1021141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1022141cc406Sopenharmony_ci
1023141cc406Sopenharmony_ci  DBG (7, "usb_low_set_dummy: exit\n");
1024141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1025141cc406Sopenharmony_ci}
1026141cc406Sopenharmony_ci
1027141cc406Sopenharmony_ci/* A12 + A13 */
1028141cc406Sopenharmony_ciSANE_Status
1029141cc406Sopenharmony_ciusb_low_get_a12 (ma1017 * chip, SANE_Byte * value)
1030141cc406Sopenharmony_ci{
1031141cc406Sopenharmony_ci  SANE_Byte pattern;
1032141cc406Sopenharmony_ci  SANE_Status status;
1033141cc406Sopenharmony_ci
1034141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a12: start\n");
1035141cc406Sopenharmony_ci
1036141cc406Sopenharmony_ci  if (!chip->is_opened)
1037141cc406Sopenharmony_ci    {
1038141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a12: not opened yet\n");
1039141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1040141cc406Sopenharmony_ci    }
1041141cc406Sopenharmony_ci  if (chip->is_rowing)
1042141cc406Sopenharmony_ci    {
1043141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a12: stop rowing first\n");
1044141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1045141cc406Sopenharmony_ci    }
1046141cc406Sopenharmony_ci
1047141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 12, &pattern));
1048141cc406Sopenharmony_ci
1049141cc406Sopenharmony_ci  chip->byte_width = (chip->byte_width & 0x3f00) + ((SANE_Word) pattern);
1050141cc406Sopenharmony_ci  chip->soft_resample = (chip->soft_resample == 0) ? 1 : chip->soft_resample;
1051141cc406Sopenharmony_ci  chip->get_row =
1052141cc406Sopenharmony_ci    (chip->soft_resample == 1)
1053141cc406Sopenharmony_ci    ? &usb_low_get_row_direct : &usb_low_get_row_resample;
1054141cc406Sopenharmony_ci  chip->row_size = chip->byte_width / chip->soft_resample;
1055141cc406Sopenharmony_ci
1056141cc406Sopenharmony_ci  if (value)
1057141cc406Sopenharmony_ci    *value = pattern;
1058141cc406Sopenharmony_ci
1059141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a12: exit\n");
1060141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1061141cc406Sopenharmony_ci}
1062141cc406Sopenharmony_ci
1063141cc406Sopenharmony_ciSANE_Status
1064141cc406Sopenharmony_ciusb_low_get_a13 (ma1017 * chip, SANE_Byte * value)
1065141cc406Sopenharmony_ci{
1066141cc406Sopenharmony_ci  SANE_Byte pattern;
1067141cc406Sopenharmony_ci  SANE_Status status;
1068141cc406Sopenharmony_ci
1069141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a13: start\n");
1070141cc406Sopenharmony_ci
1071141cc406Sopenharmony_ci  if (!chip->is_opened)
1072141cc406Sopenharmony_ci    {
1073141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a13: not opened yet\n");
1074141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1075141cc406Sopenharmony_ci    }
1076141cc406Sopenharmony_ci  if (chip->is_rowing)
1077141cc406Sopenharmony_ci    {
1078141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a13: stop rowing first\n");
1079141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1080141cc406Sopenharmony_ci    }
1081141cc406Sopenharmony_ci
1082141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 13, &pattern));
1083141cc406Sopenharmony_ci
1084141cc406Sopenharmony_ci  chip->byte_width =
1085141cc406Sopenharmony_ci    (chip->byte_width & 0x00ff) + (((SANE_Word) (pattern & 0x3f)) << 8);
1086141cc406Sopenharmony_ci  chip->soft_resample = (chip->soft_resample == 0) ? 1 : chip->soft_resample;
1087141cc406Sopenharmony_ci  chip->get_row =
1088141cc406Sopenharmony_ci    (chip->soft_resample ==
1089141cc406Sopenharmony_ci     1) ? &usb_low_get_row_direct : &usb_low_get_row_resample;
1090141cc406Sopenharmony_ci  chip->row_size = chip->byte_width / chip->soft_resample;
1091141cc406Sopenharmony_ci
1092141cc406Sopenharmony_ci  if (value)
1093141cc406Sopenharmony_ci    *value = pattern;
1094141cc406Sopenharmony_ci
1095141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a13: exit\n");
1096141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1097141cc406Sopenharmony_ci}
1098141cc406Sopenharmony_ci
1099141cc406Sopenharmony_ciSANE_Status
1100141cc406Sopenharmony_ciusb_low_set_image_byte_width (ma1017 * chip, SANE_Word row_size)
1101141cc406Sopenharmony_ci{
1102141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
1103141cc406Sopenharmony_ci  SANE_Status status;
1104141cc406Sopenharmony_ci
1105141cc406Sopenharmony_ci  DBG (7, "usb_low_set_image_byte_width: start\n");
1106141cc406Sopenharmony_ci
1107141cc406Sopenharmony_ci  if (!chip->is_opened)
1108141cc406Sopenharmony_ci    {
1109141cc406Sopenharmony_ci      DBG (3, "usb_low_set_image_byte_width: not opened yet\n");
1110141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1111141cc406Sopenharmony_ci    }
1112141cc406Sopenharmony_ci  if (chip->is_rowing)
1113141cc406Sopenharmony_ci    {
1114141cc406Sopenharmony_ci      DBG (3, "usb_low_set_image_byte_width: stop rowing first\n");
1115141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1116141cc406Sopenharmony_ci    }
1117141cc406Sopenharmony_ci
1118141cc406Sopenharmony_ci  chip->row_size = row_size;
1119141cc406Sopenharmony_ci  chip->soft_resample = (chip->soft_resample == 0) ? 1 : chip->soft_resample;
1120141cc406Sopenharmony_ci  chip->get_row = (chip->soft_resample == 1) ? &usb_low_get_row_direct
1121141cc406Sopenharmony_ci    : &usb_low_get_row_resample;
1122141cc406Sopenharmony_ci  chip->byte_width = chip->row_size * chip->soft_resample;
1123141cc406Sopenharmony_ci  if (chip->byte_width > 0x3fff)
1124141cc406Sopenharmony_ci    {
1125141cc406Sopenharmony_ci      DBG (3, "usb_low_set_image_byte_width: width %d exceeded\n",
1126141cc406Sopenharmony_ci	   (int) chip->byte_width);
1127141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1128141cc406Sopenharmony_ci    }
1129141cc406Sopenharmony_ci
1130141cc406Sopenharmony_ci  data = LOBYTE (chip->byte_width);
1131141cc406Sopenharmony_ci  reg_no = 12;
1132141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1133141cc406Sopenharmony_ci
1134141cc406Sopenharmony_ci  data = HIBYTE (chip->byte_width);
1135141cc406Sopenharmony_ci  reg_no = 13;
1136141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1137141cc406Sopenharmony_ci
1138141cc406Sopenharmony_ci  DBG (7, "usb_low_set_image_byte_width: exit\n");
1139141cc406Sopenharmony_ci
1140141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1141141cc406Sopenharmony_ci}
1142141cc406Sopenharmony_ci
1143141cc406Sopenharmony_ciSANE_Status
1144141cc406Sopenharmony_ciusb_low_set_soft_resample (ma1017 * chip, SANE_Word soft_resample)
1145141cc406Sopenharmony_ci{
1146141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
1147141cc406Sopenharmony_ci  SANE_Status status;
1148141cc406Sopenharmony_ci
1149141cc406Sopenharmony_ci  DBG (7, "usb_low_set_soft_resample: start\n");
1150141cc406Sopenharmony_ci
1151141cc406Sopenharmony_ci  if (!chip->is_opened)
1152141cc406Sopenharmony_ci    {
1153141cc406Sopenharmony_ci      DBG (3, "usb_low_set_soft_resample: not opened yet\n");
1154141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1155141cc406Sopenharmony_ci    }
1156141cc406Sopenharmony_ci  if (chip->is_rowing)
1157141cc406Sopenharmony_ci    {
1158141cc406Sopenharmony_ci      DBG (3, "usb_low_set_soft_resample: stop rowing first\n");
1159141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1160141cc406Sopenharmony_ci    }
1161141cc406Sopenharmony_ci  if (soft_resample == 0x00)
1162141cc406Sopenharmony_ci    {
1163141cc406Sopenharmony_ci      DBG (3, "usb_low_set_soft_resample: soft_resample==0\n");
1164141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1165141cc406Sopenharmony_ci    }
1166141cc406Sopenharmony_ci
1167141cc406Sopenharmony_ci  chip->soft_resample = soft_resample;
1168141cc406Sopenharmony_ci  chip->get_row = (chip->soft_resample == 1) ? &usb_low_get_row_direct
1169141cc406Sopenharmony_ci    : &usb_low_get_row_resample;
1170141cc406Sopenharmony_ci  chip->byte_width = chip->row_size * chip->soft_resample;
1171141cc406Sopenharmony_ci  if (chip->byte_width > 0x3fff)
1172141cc406Sopenharmony_ci    {
1173141cc406Sopenharmony_ci      DBG (3, "usb_low_set_soft_resample: width %d exceeded",
1174141cc406Sopenharmony_ci	   (int) chip->byte_width);
1175141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1176141cc406Sopenharmony_ci    }
1177141cc406Sopenharmony_ci
1178141cc406Sopenharmony_ci  data = LOBYTE (chip->byte_width);
1179141cc406Sopenharmony_ci  reg_no = 12;
1180141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1181141cc406Sopenharmony_ci
1182141cc406Sopenharmony_ci  data = HIBYTE (chip->byte_width);
1183141cc406Sopenharmony_ci  reg_no = 13;
1184141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1185141cc406Sopenharmony_ci
1186141cc406Sopenharmony_ci  DBG (7, "usb_low_set_soft_resample: exit\n");
1187141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1188141cc406Sopenharmony_ci}
1189141cc406Sopenharmony_ci
1190141cc406Sopenharmony_ci/* A14 + A30W */
1191141cc406Sopenharmony_ciSANE_Status
1192141cc406Sopenharmony_ciusb_low_set_cmt_loop_count (ma1017 * chip, SANE_Word loop_count)
1193141cc406Sopenharmony_ci{
1194141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
1195141cc406Sopenharmony_ci  SANE_Status status;
1196141cc406Sopenharmony_ci
1197141cc406Sopenharmony_ci  DBG (7, "usb_low_set_cmt_loop_count: start\n");
1198141cc406Sopenharmony_ci
1199141cc406Sopenharmony_ci  if (!chip->is_opened)
1200141cc406Sopenharmony_ci    {
1201141cc406Sopenharmony_ci      DBG (3, "usb_low_set_cmt_loop_count: not opened yet\n");
1202141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1203141cc406Sopenharmony_ci    }
1204141cc406Sopenharmony_ci  if (chip->is_rowing)
1205141cc406Sopenharmony_ci    {
1206141cc406Sopenharmony_ci      DBG (3, "usb_low_set_cmt_loop_count: stop rowing first\n");
1207141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1208141cc406Sopenharmony_ci    }
1209141cc406Sopenharmony_ci
1210141cc406Sopenharmony_ci  chip->loop_count = loop_count;
1211141cc406Sopenharmony_ci
1212141cc406Sopenharmony_ci  data = LOBYTE (loop_count);
1213141cc406Sopenharmony_ci  reg_no = 14;
1214141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1215141cc406Sopenharmony_ci
1216141cc406Sopenharmony_ci  data = HIBYTE (loop_count);
1217141cc406Sopenharmony_ci  reg_no = 30;
1218141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1219141cc406Sopenharmony_ci
1220141cc406Sopenharmony_ci  DBG (7, "usb_low_set_cmt_loop_count: exit\n");
1221141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1222141cc406Sopenharmony_ci}
1223141cc406Sopenharmony_ci
1224141cc406Sopenharmony_ci/* A15 */
1225141cc406Sopenharmony_ciSANE_Status
1226141cc406Sopenharmony_ciusb_low_get_a15 (ma1017 * chip, SANE_Byte * value)
1227141cc406Sopenharmony_ci{
1228141cc406Sopenharmony_ci  SANE_Byte pattern;
1229141cc406Sopenharmony_ci  SANE_Status status;
1230141cc406Sopenharmony_ci
1231141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a15: start\n");
1232141cc406Sopenharmony_ci
1233141cc406Sopenharmony_ci  if (!chip->is_opened)
1234141cc406Sopenharmony_ci    {
1235141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a15: not opened yet\n");
1236141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1237141cc406Sopenharmony_ci    }
1238141cc406Sopenharmony_ci  if (chip->is_rowing)
1239141cc406Sopenharmony_ci    {
1240141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a15: stop rowing first\n");
1241141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1242141cc406Sopenharmony_ci    }
1243141cc406Sopenharmony_ci
1244141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 15, &pattern));
1245141cc406Sopenharmony_ci
1246141cc406Sopenharmony_ci  chip->motor_enable = pattern & 0x80;
1247141cc406Sopenharmony_ci  chip->motor_movement = pattern & 0x68;
1248141cc406Sopenharmony_ci  chip->motor_direction = pattern & 10;
1249141cc406Sopenharmony_ci  chip->motor_signal = pattern & 0x06;
1250141cc406Sopenharmony_ci  chip->motor_home = pattern & 0x01;
1251141cc406Sopenharmony_ci
1252141cc406Sopenharmony_ci  if (value)
1253141cc406Sopenharmony_ci    *value = pattern;
1254141cc406Sopenharmony_ci
1255141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a15: exit\n");
1256141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1257141cc406Sopenharmony_ci}
1258141cc406Sopenharmony_ci
1259141cc406Sopenharmony_ciSANE_Status
1260141cc406Sopenharmony_ciusb_low_enable_motor (ma1017 * chip, SANE_Bool is_enable)
1261141cc406Sopenharmony_ci{
1262141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
1263141cc406Sopenharmony_ci  SANE_Status status;
1264141cc406Sopenharmony_ci
1265141cc406Sopenharmony_ci  DBG (7, "usb_low_enable_motor: start\n");
1266141cc406Sopenharmony_ci  if (!chip->is_opened)
1267141cc406Sopenharmony_ci    {
1268141cc406Sopenharmony_ci      DBG (3, "usb_low_enable_motor: not opened yet\n");
1269141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1270141cc406Sopenharmony_ci    }
1271141cc406Sopenharmony_ci  if (chip->is_rowing)
1272141cc406Sopenharmony_ci    {
1273141cc406Sopenharmony_ci      DBG (3, "usb_low_enable_motor: stop rowing first\n");
1274141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1275141cc406Sopenharmony_ci    }
1276141cc406Sopenharmony_ci
1277141cc406Sopenharmony_ci  chip->motor_enable = 0x00;
1278141cc406Sopenharmony_ci  if (is_enable)
1279141cc406Sopenharmony_ci    chip->motor_enable |= 0x80;
1280141cc406Sopenharmony_ci  data = chip->motor_enable | chip->motor_movement
1281141cc406Sopenharmony_ci    | chip->motor_direction | chip->motor_signal | chip->motor_home;
1282141cc406Sopenharmony_ci  reg_no = 15;
1283141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1284141cc406Sopenharmony_ci
1285141cc406Sopenharmony_ci  DBG (7, "usb_low_enable_motor: exit\n");
1286141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1287141cc406Sopenharmony_ci}
1288141cc406Sopenharmony_ci
1289141cc406Sopenharmony_ciSANE_Status
1290141cc406Sopenharmony_ciusb_low_set_motor_movement (ma1017 * chip, SANE_Bool is_full_step,
1291141cc406Sopenharmony_ci			    SANE_Bool is_double_phase, SANE_Bool is_two_step)
1292141cc406Sopenharmony_ci{
1293141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
1294141cc406Sopenharmony_ci  SANE_Status status;
1295141cc406Sopenharmony_ci
1296141cc406Sopenharmony_ci  DBG (7, "usb_low_set_motor_movement: start\n");
1297141cc406Sopenharmony_ci  if (!chip->is_opened)
1298141cc406Sopenharmony_ci    {
1299141cc406Sopenharmony_ci      DBG (3, "usb_low_set_motor_movement: not opened yet\n");
1300141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1301141cc406Sopenharmony_ci    }
1302141cc406Sopenharmony_ci  if (chip->is_rowing)
1303141cc406Sopenharmony_ci    {
1304141cc406Sopenharmony_ci      DBG (3, "usb_low_set_motor_movement: stop rowing first\n");
1305141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1306141cc406Sopenharmony_ci    }
1307141cc406Sopenharmony_ci
1308141cc406Sopenharmony_ci  chip->motor_movement = 0x00;
1309141cc406Sopenharmony_ci  if (is_full_step)
1310141cc406Sopenharmony_ci    chip->motor_movement |= 0x40;
1311141cc406Sopenharmony_ci  if (is_double_phase)
1312141cc406Sopenharmony_ci    chip->motor_movement |= 0x20;
1313141cc406Sopenharmony_ci  if (is_two_step)
1314141cc406Sopenharmony_ci    chip->motor_movement |= 0x08;
1315141cc406Sopenharmony_ci  data = chip->motor_enable | chip->motor_movement
1316141cc406Sopenharmony_ci    | chip->motor_direction | chip->motor_signal | chip->motor_home;
1317141cc406Sopenharmony_ci  reg_no = 15;
1318141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1319141cc406Sopenharmony_ci
1320141cc406Sopenharmony_ci  DBG (7, "usb_low_set_motor_movement:  exit\n");
1321141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1322141cc406Sopenharmony_ci}
1323141cc406Sopenharmony_ci
1324141cc406Sopenharmony_ciSANE_Status
1325141cc406Sopenharmony_ciusb_low_set_motor_direction (ma1017 * chip, SANE_Bool is_backward)
1326141cc406Sopenharmony_ci{
1327141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
1328141cc406Sopenharmony_ci  SANE_Status status;
1329141cc406Sopenharmony_ci
1330141cc406Sopenharmony_ci  DBG (7, "usb_low_set_motor_direction: start\n");
1331141cc406Sopenharmony_ci
1332141cc406Sopenharmony_ci  if (!chip->is_opened)
1333141cc406Sopenharmony_ci    {
1334141cc406Sopenharmony_ci      DBG (3, "usb_low_set_motor_direction: not opened yet\n");
1335141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1336141cc406Sopenharmony_ci    }
1337141cc406Sopenharmony_ci  if (chip->is_rowing)
1338141cc406Sopenharmony_ci    {
1339141cc406Sopenharmony_ci      DBG (3, "usb_low_set_motor_direction: stop rowing first\n");
1340141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1341141cc406Sopenharmony_ci    }
1342141cc406Sopenharmony_ci
1343141cc406Sopenharmony_ci  chip->motor_direction = 0x00;
1344141cc406Sopenharmony_ci  if (is_backward)
1345141cc406Sopenharmony_ci    chip->motor_direction |= 0x10;
1346141cc406Sopenharmony_ci  data = chip->motor_enable | chip->motor_movement
1347141cc406Sopenharmony_ci    | chip->motor_direction | chip->motor_signal | chip->motor_home;
1348141cc406Sopenharmony_ci  reg_no = 15;
1349141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1350141cc406Sopenharmony_ci
1351141cc406Sopenharmony_ci  DBG (7, "usb_low_set_motor_direction: exit\n");
1352141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1353141cc406Sopenharmony_ci}
1354141cc406Sopenharmony_ci
1355141cc406Sopenharmony_ciSANE_Status
1356141cc406Sopenharmony_ciusb_low_set_motor_signal (ma1017 * chip, SANE_Byte signal)
1357141cc406Sopenharmony_ci{
1358141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
1359141cc406Sopenharmony_ci  SANE_Status status;
1360141cc406Sopenharmony_ci
1361141cc406Sopenharmony_ci  DBG (7, "usb_low_set_motor_signal: start\n");
1362141cc406Sopenharmony_ci
1363141cc406Sopenharmony_ci  if (!chip->is_opened)
1364141cc406Sopenharmony_ci    {
1365141cc406Sopenharmony_ci      DBG (3, "usb_low_set_motor_signal: not opened yet\n");
1366141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1367141cc406Sopenharmony_ci    }
1368141cc406Sopenharmony_ci  if (chip->is_rowing)
1369141cc406Sopenharmony_ci    {
1370141cc406Sopenharmony_ci      DBG (3, "usb_low_set_motor_signal: stop rowing first\n");
1371141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1372141cc406Sopenharmony_ci    }
1373141cc406Sopenharmony_ci
1374141cc406Sopenharmony_ci  chip->motor_signal = signal & 0x06;
1375141cc406Sopenharmony_ci  data = chip->motor_enable | chip->motor_movement
1376141cc406Sopenharmony_ci    | chip->motor_direction | chip->motor_signal | chip->motor_home;
1377141cc406Sopenharmony_ci  reg_no = 15;
1378141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1379141cc406Sopenharmony_ci
1380141cc406Sopenharmony_ci  DBG (7, "usb_low_set_motor_signal: exit\n");
1381141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1382141cc406Sopenharmony_ci}
1383141cc406Sopenharmony_ci
1384141cc406Sopenharmony_ciSANE_Status
1385141cc406Sopenharmony_ciusb_low_move_motor_home (ma1017 * chip, SANE_Bool is_home,
1386141cc406Sopenharmony_ci			 SANE_Bool is_backward)
1387141cc406Sopenharmony_ci{
1388141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
1389141cc406Sopenharmony_ci  SANE_Status status;
1390141cc406Sopenharmony_ci
1391141cc406Sopenharmony_ci  DBG (7, "usb_low_move_motor_home: start\n");
1392141cc406Sopenharmony_ci
1393141cc406Sopenharmony_ci  if (!chip->is_opened)
1394141cc406Sopenharmony_ci    {
1395141cc406Sopenharmony_ci      DBG (3, "usb_low_move_motor_home: not opened yet\n");
1396141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1397141cc406Sopenharmony_ci    }
1398141cc406Sopenharmony_ci  if (chip->is_rowing)
1399141cc406Sopenharmony_ci    {
1400141cc406Sopenharmony_ci      DBG (3, "usb_low_move_motor_home: stop rowing first\n");
1401141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1402141cc406Sopenharmony_ci    }
1403141cc406Sopenharmony_ci
1404141cc406Sopenharmony_ci  chip->motor_enable = 0x00;
1405141cc406Sopenharmony_ci  chip->motor_direction = 0x00;
1406141cc406Sopenharmony_ci  chip->motor_home = 0x00;
1407141cc406Sopenharmony_ci  if (is_backward)
1408141cc406Sopenharmony_ci    chip->motor_direction |= 0x10;
1409141cc406Sopenharmony_ci  if (is_home)
1410141cc406Sopenharmony_ci    {
1411141cc406Sopenharmony_ci      chip->motor_enable |= 0x80;
1412141cc406Sopenharmony_ci      chip->motor_home |= 0x01;
1413141cc406Sopenharmony_ci    }
1414141cc406Sopenharmony_ci  data = chip->motor_enable | chip->motor_movement
1415141cc406Sopenharmony_ci    | chip->motor_direction | chip->motor_signal | chip->motor_home;
1416141cc406Sopenharmony_ci  reg_no = 15;
1417141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1418141cc406Sopenharmony_ci
1419141cc406Sopenharmony_ci  DBG (7, "usb_low_move_motor_home: exit\n");
1420141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1421141cc406Sopenharmony_ci}
1422141cc406Sopenharmony_ci
1423141cc406Sopenharmony_ci/* A16 */
1424141cc406Sopenharmony_ciSANE_Status
1425141cc406Sopenharmony_ciusb_low_get_a16 (ma1017 * chip, SANE_Byte * value)
1426141cc406Sopenharmony_ci{
1427141cc406Sopenharmony_ci  SANE_Byte pattern;
1428141cc406Sopenharmony_ci  SANE_Status status;
1429141cc406Sopenharmony_ci
1430141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a16: start\n");
1431141cc406Sopenharmony_ci
1432141cc406Sopenharmony_ci  if (!chip->is_opened)
1433141cc406Sopenharmony_ci    {
1434141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a16: not opened yet\n");
1435141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1436141cc406Sopenharmony_ci    }
1437141cc406Sopenharmony_ci  if (chip->is_rowing)
1438141cc406Sopenharmony_ci    {
1439141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a16: stop rowing first\n");
1440141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1441141cc406Sopenharmony_ci    }
1442141cc406Sopenharmony_ci
1443141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 16, &pattern));
1444141cc406Sopenharmony_ci
1445141cc406Sopenharmony_ci  chip->pixel_depth = pattern & 0xe0;
1446141cc406Sopenharmony_ci  chip->image_invert = pattern & 0x10;
1447141cc406Sopenharmony_ci  chip->optical_600 = pattern & 0x08;
1448141cc406Sopenharmony_ci  chip->sample_way = pattern & 0x07;
1449141cc406Sopenharmony_ci
1450141cc406Sopenharmony_ci  if (value)
1451141cc406Sopenharmony_ci    *value = pattern;
1452141cc406Sopenharmony_ci
1453141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a16: exit\n");
1454141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1455141cc406Sopenharmony_ci}
1456141cc406Sopenharmony_ci
1457141cc406Sopenharmony_ciSANE_Status
1458141cc406Sopenharmony_ciusb_low_set_image_dpi (ma1017 * chip, SANE_Bool is_optical600,
1459141cc406Sopenharmony_ci		       Sampleway sampleway)
1460141cc406Sopenharmony_ci{
1461141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
1462141cc406Sopenharmony_ci  SANE_Status status;
1463141cc406Sopenharmony_ci
1464141cc406Sopenharmony_ci  DBG (7, "usb_low_set_image_dpi: start\n");
1465141cc406Sopenharmony_ci
1466141cc406Sopenharmony_ci  if (!chip->is_opened)
1467141cc406Sopenharmony_ci    {
1468141cc406Sopenharmony_ci      DBG (3, "usb_low_set_image_dpi: not opened yet\n");
1469141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1470141cc406Sopenharmony_ci    }
1471141cc406Sopenharmony_ci  if (chip->is_rowing)
1472141cc406Sopenharmony_ci    {
1473141cc406Sopenharmony_ci      DBG (3, "usb_low_set_image_dpi: stop rowing first\n");
1474141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1475141cc406Sopenharmony_ci    }
1476141cc406Sopenharmony_ci
1477141cc406Sopenharmony_ci  chip->optical_600 = 0x00;
1478141cc406Sopenharmony_ci  chip->sample_way = 0x00;
1479141cc406Sopenharmony_ci  if (is_optical600)
1480141cc406Sopenharmony_ci    chip->optical_600 |= 0x08;
1481141cc406Sopenharmony_ci  switch (sampleway)
1482141cc406Sopenharmony_ci    {
1483141cc406Sopenharmony_ci    case SW_P1P6:
1484141cc406Sopenharmony_ci      chip->sample_way = 0x01;
1485141cc406Sopenharmony_ci      break;
1486141cc406Sopenharmony_ci    case SW_P2P6:
1487141cc406Sopenharmony_ci      chip->sample_way = 0x02;
1488141cc406Sopenharmony_ci      break;
1489141cc406Sopenharmony_ci    case SW_P3P6:
1490141cc406Sopenharmony_ci      chip->sample_way = 0x03;
1491141cc406Sopenharmony_ci      break;
1492141cc406Sopenharmony_ci    case SW_P4P6:
1493141cc406Sopenharmony_ci      chip->sample_way = 0x04;
1494141cc406Sopenharmony_ci      break;
1495141cc406Sopenharmony_ci    case SW_P5P6:
1496141cc406Sopenharmony_ci      chip->sample_way = 0x05;
1497141cc406Sopenharmony_ci      break;
1498141cc406Sopenharmony_ci    case SW_P6P6:
1499141cc406Sopenharmony_ci      chip->sample_way = 0x06;
1500141cc406Sopenharmony_ci      break;
1501141cc406Sopenharmony_ci    default:
1502141cc406Sopenharmony_ci      DBG (3, "usb_low_set_image_dpi: swsample_way error\n");
1503141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1504141cc406Sopenharmony_ci      break;
1505141cc406Sopenharmony_ci    }
1506141cc406Sopenharmony_ci  data = chip->pixel_depth | chip->image_invert | chip->optical_600
1507141cc406Sopenharmony_ci    | chip->sample_way;
1508141cc406Sopenharmony_ci  reg_no = 16;
1509141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1510141cc406Sopenharmony_ci
1511141cc406Sopenharmony_ci  DBG (7, "usb_low_set_image_dpi: exit\n");
1512141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1513141cc406Sopenharmony_ci}
1514141cc406Sopenharmony_ci
1515141cc406Sopenharmony_ciSANE_Status
1516141cc406Sopenharmony_ciusb_low_set_pixel_depth (ma1017 * chip, Pixeldepth pixeldepth)
1517141cc406Sopenharmony_ci{
1518141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
1519141cc406Sopenharmony_ci  SANE_Status status;
1520141cc406Sopenharmony_ci
1521141cc406Sopenharmony_ci  DBG (7, "usb_low_set_pixel_depth: start\n");
1522141cc406Sopenharmony_ci  if (!chip->is_opened)
1523141cc406Sopenharmony_ci    {
1524141cc406Sopenharmony_ci      DBG (3, "usb_low_set_pixel_depth: not opened yet\n");
1525141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1526141cc406Sopenharmony_ci    }
1527141cc406Sopenharmony_ci  if (chip->is_rowing)
1528141cc406Sopenharmony_ci    {
1529141cc406Sopenharmony_ci      DBG (3, "usb_low_set_pixel_depth: stop rowing first\n");
1530141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1531141cc406Sopenharmony_ci    }
1532141cc406Sopenharmony_ci
1533141cc406Sopenharmony_ci  chip->pixel_depth = 0x00;
1534141cc406Sopenharmony_ci  switch (pixeldepth)
1535141cc406Sopenharmony_ci    {
1536141cc406Sopenharmony_ci    case PD_1BIT:
1537141cc406Sopenharmony_ci      chip->pixel_depth = 0x80;
1538141cc406Sopenharmony_ci      break;
1539141cc406Sopenharmony_ci    case PD_4BIT:
1540141cc406Sopenharmony_ci      chip->pixel_depth = 0xc0;
1541141cc406Sopenharmony_ci      break;
1542141cc406Sopenharmony_ci    case PD_8BIT:
1543141cc406Sopenharmony_ci      chip->pixel_depth = 0x00;
1544141cc406Sopenharmony_ci      break;
1545141cc406Sopenharmony_ci    case PD_12BIT:
1546141cc406Sopenharmony_ci      chip->pixel_depth = 0x20;
1547141cc406Sopenharmony_ci      break;
1548141cc406Sopenharmony_ci    default:
1549141cc406Sopenharmony_ci      DBG (3, "usb_low_set_pixel_depth: pdPixelDepth error\n");
1550141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1551141cc406Sopenharmony_ci    }
1552141cc406Sopenharmony_ci  data = chip->pixel_depth | chip->image_invert | chip->optical_600
1553141cc406Sopenharmony_ci    | chip->sample_way;
1554141cc406Sopenharmony_ci  reg_no = 16;
1555141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1556141cc406Sopenharmony_ci
1557141cc406Sopenharmony_ci  DBG (7, "usb_low_SetPixelDeepth: exit\n");
1558141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1559141cc406Sopenharmony_ci}
1560141cc406Sopenharmony_ci
1561141cc406Sopenharmony_ciSANE_Status
1562141cc406Sopenharmony_ciusb_low_invert_image (ma1017 * chip, SANE_Bool is_invert)
1563141cc406Sopenharmony_ci{
1564141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
1565141cc406Sopenharmony_ci  SANE_Status status;
1566141cc406Sopenharmony_ci
1567141cc406Sopenharmony_ci  DBG (7, "usb_low_invert_image: start\n");
1568141cc406Sopenharmony_ci  if (!chip->is_opened)
1569141cc406Sopenharmony_ci    {
1570141cc406Sopenharmony_ci      DBG (3, "usb_low_invert_image: not opened yet\n");
1571141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1572141cc406Sopenharmony_ci    }
1573141cc406Sopenharmony_ci  if (chip->is_rowing)
1574141cc406Sopenharmony_ci    {
1575141cc406Sopenharmony_ci      DBG (3, "usb_low_invert_image: stop rowing first\n");
1576141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1577141cc406Sopenharmony_ci    }
1578141cc406Sopenharmony_ci
1579141cc406Sopenharmony_ci  chip->image_invert = 0x00;
1580141cc406Sopenharmony_ci  if (is_invert)
1581141cc406Sopenharmony_ci    chip->image_invert |= 0x10;
1582141cc406Sopenharmony_ci  data = chip->pixel_depth | chip->image_invert | chip->optical_600
1583141cc406Sopenharmony_ci    | chip->sample_way;
1584141cc406Sopenharmony_ci  reg_no = 16;
1585141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1586141cc406Sopenharmony_ci
1587141cc406Sopenharmony_ci  DBG (7, "usb_low_invert_image: exit\n");
1588141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1589141cc406Sopenharmony_ci}
1590141cc406Sopenharmony_ci
1591141cc406Sopenharmony_ci/* A17 + A18 + A19 */
1592141cc406Sopenharmony_ciSANE_Status
1593141cc406Sopenharmony_ciusb_low_get_a17 (ma1017 * chip, SANE_Byte * value)
1594141cc406Sopenharmony_ci{
1595141cc406Sopenharmony_ci  SANE_Byte pattern;
1596141cc406Sopenharmony_ci  SANE_Status status;
1597141cc406Sopenharmony_ci
1598141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a17: start\n");
1599141cc406Sopenharmony_ci  if (!chip->is_opened)
1600141cc406Sopenharmony_ci    {
1601141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a17: not opened yet\n");
1602141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1603141cc406Sopenharmony_ci    }
1604141cc406Sopenharmony_ci  if (chip->is_rowing)
1605141cc406Sopenharmony_ci    {
1606141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a17: stop rowing first\n");
1607141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1608141cc406Sopenharmony_ci    }
1609141cc406Sopenharmony_ci
1610141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 17, &pattern));
1611141cc406Sopenharmony_ci
1612141cc406Sopenharmony_ci  chip->red_ref = pattern;
1613141cc406Sopenharmony_ci
1614141cc406Sopenharmony_ci  if (value)
1615141cc406Sopenharmony_ci    *value = pattern;
1616141cc406Sopenharmony_ci
1617141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a17: exit\n");
1618141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1619141cc406Sopenharmony_ci}
1620141cc406Sopenharmony_ci
1621141cc406Sopenharmony_ciSANE_Status
1622141cc406Sopenharmony_ciusb_low_get_a18 (ma1017 * chip, SANE_Byte * value)
1623141cc406Sopenharmony_ci{
1624141cc406Sopenharmony_ci  SANE_Byte pattern;
1625141cc406Sopenharmony_ci  SANE_Status status;
1626141cc406Sopenharmony_ci
1627141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a18: start\n");
1628141cc406Sopenharmony_ci  if (!chip->is_opened)
1629141cc406Sopenharmony_ci    {
1630141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a18: not opened yet\n");
1631141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1632141cc406Sopenharmony_ci    }
1633141cc406Sopenharmony_ci  if (chip->is_rowing)
1634141cc406Sopenharmony_ci    {
1635141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a18: stop rowing first\n");
1636141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1637141cc406Sopenharmony_ci    }
1638141cc406Sopenharmony_ci
1639141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 18, &pattern));
1640141cc406Sopenharmony_ci
1641141cc406Sopenharmony_ci  chip->green_ref = pattern;
1642141cc406Sopenharmony_ci
1643141cc406Sopenharmony_ci  if (value)
1644141cc406Sopenharmony_ci    *value = pattern;
1645141cc406Sopenharmony_ci
1646141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a18: exit\n");
1647141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1648141cc406Sopenharmony_ci}
1649141cc406Sopenharmony_ci
1650141cc406Sopenharmony_ciSANE_Status
1651141cc406Sopenharmony_ciusb_low_get_a19 (ma1017 * chip, SANE_Byte * value)
1652141cc406Sopenharmony_ci{
1653141cc406Sopenharmony_ci  SANE_Byte pattern;
1654141cc406Sopenharmony_ci  SANE_Status status;
1655141cc406Sopenharmony_ci
1656141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a19: start\n");
1657141cc406Sopenharmony_ci  if (!chip->is_opened)
1658141cc406Sopenharmony_ci    {
1659141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a19: not opened yet\n");
1660141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1661141cc406Sopenharmony_ci    }
1662141cc406Sopenharmony_ci  if (chip->is_rowing)
1663141cc406Sopenharmony_ci    {
1664141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a19:stop rowing first\n");
1665141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1666141cc406Sopenharmony_ci    }
1667141cc406Sopenharmony_ci
1668141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 19, &pattern));
1669141cc406Sopenharmony_ci
1670141cc406Sopenharmony_ci  chip->blue_ref = pattern;
1671141cc406Sopenharmony_ci
1672141cc406Sopenharmony_ci  if (value)
1673141cc406Sopenharmony_ci    *value = pattern;
1674141cc406Sopenharmony_ci
1675141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a19: exit\n");
1676141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1677141cc406Sopenharmony_ci}
1678141cc406Sopenharmony_ci
1679141cc406Sopenharmony_ciSANE_Status
1680141cc406Sopenharmony_ciusb_low_set_red_ref (ma1017 * chip, SANE_Byte red_ref)
1681141cc406Sopenharmony_ci{
1682141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
1683141cc406Sopenharmony_ci  SANE_Status status;
1684141cc406Sopenharmony_ci
1685141cc406Sopenharmony_ci  DBG (7, "usb_low_set_red_ref: start\n");
1686141cc406Sopenharmony_ci
1687141cc406Sopenharmony_ci  if (!chip->is_opened)
1688141cc406Sopenharmony_ci    {
1689141cc406Sopenharmony_ci      DBG (3, "usb_low_set_red_ref: not opened yet\n");
1690141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1691141cc406Sopenharmony_ci    }
1692141cc406Sopenharmony_ci  if (chip->is_rowing)
1693141cc406Sopenharmony_ci    {
1694141cc406Sopenharmony_ci      DBG (3, "usb_low_set_red_ref: stop rowing first\n");
1695141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1696141cc406Sopenharmony_ci    }
1697141cc406Sopenharmony_ci
1698141cc406Sopenharmony_ci  chip->red_ref = red_ref;
1699141cc406Sopenharmony_ci  data = red_ref;
1700141cc406Sopenharmony_ci  reg_no = 17;
1701141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1702141cc406Sopenharmony_ci
1703141cc406Sopenharmony_ci  DBG (7, "usb_low_set_red_ref: stop\n");
1704141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1705141cc406Sopenharmony_ci}
1706141cc406Sopenharmony_ci
1707141cc406Sopenharmony_ciSANE_Status
1708141cc406Sopenharmony_ciusb_low_set_green_ref (ma1017 * chip, SANE_Byte green_ref)
1709141cc406Sopenharmony_ci{
1710141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
1711141cc406Sopenharmony_ci  SANE_Status status;
1712141cc406Sopenharmony_ci
1713141cc406Sopenharmony_ci  DBG (7, "usb_low_set_green_ref: start\n");
1714141cc406Sopenharmony_ci
1715141cc406Sopenharmony_ci
1716141cc406Sopenharmony_ci  if (!chip->is_opened)
1717141cc406Sopenharmony_ci    {
1718141cc406Sopenharmony_ci      DBG (3, "usb_low_set_green_ref: not opened yet\n");
1719141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1720141cc406Sopenharmony_ci    }
1721141cc406Sopenharmony_ci  if (chip->is_rowing)
1722141cc406Sopenharmony_ci    {
1723141cc406Sopenharmony_ci      DBG (3, "usb_low_set_green_ref: stop rowing first\n");
1724141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1725141cc406Sopenharmony_ci    }
1726141cc406Sopenharmony_ci
1727141cc406Sopenharmony_ci  chip->green_ref = green_ref;
1728141cc406Sopenharmony_ci
1729141cc406Sopenharmony_ci  data = green_ref;
1730141cc406Sopenharmony_ci  reg_no = 18;
1731141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1732141cc406Sopenharmony_ci
1733141cc406Sopenharmony_ci  DBG (7, "usb_low_set_green_ref: exit\n");
1734141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1735141cc406Sopenharmony_ci}
1736141cc406Sopenharmony_ci
1737141cc406Sopenharmony_ciSANE_Status
1738141cc406Sopenharmony_ciusb_low_set_blue_ref (ma1017 * chip, SANE_Byte blue_ref)
1739141cc406Sopenharmony_ci{
1740141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
1741141cc406Sopenharmony_ci  SANE_Status status;
1742141cc406Sopenharmony_ci
1743141cc406Sopenharmony_ci  DBG (7, "usb_low_set_blue_ref: start\n");
1744141cc406Sopenharmony_ci
1745141cc406Sopenharmony_ci  if (!chip->is_opened)
1746141cc406Sopenharmony_ci    {
1747141cc406Sopenharmony_ci      DBG (3, "usb_low_set_blue_ref: not opened yet\n");
1748141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1749141cc406Sopenharmony_ci    }
1750141cc406Sopenharmony_ci  if (chip->is_rowing)
1751141cc406Sopenharmony_ci    {
1752141cc406Sopenharmony_ci      DBG (3, "usb_low_set_blue_ref: stop rowing first\n");
1753141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1754141cc406Sopenharmony_ci    }
1755141cc406Sopenharmony_ci
1756141cc406Sopenharmony_ci  chip->blue_ref = blue_ref;
1757141cc406Sopenharmony_ci
1758141cc406Sopenharmony_ci  data = blue_ref;
1759141cc406Sopenharmony_ci  reg_no = 19;
1760141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1761141cc406Sopenharmony_ci
1762141cc406Sopenharmony_ci  DBG (7, "usb_low_set_blue_ref: stop\n");
1763141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1764141cc406Sopenharmony_ci}
1765141cc406Sopenharmony_ci
1766141cc406Sopenharmony_ci/* A20 + A21 + A22 */
1767141cc406Sopenharmony_ciSANE_Status
1768141cc406Sopenharmony_ciusb_low_get_a20 (ma1017 * chip, SANE_Byte * value)
1769141cc406Sopenharmony_ci{
1770141cc406Sopenharmony_ci  SANE_Byte pattern;
1771141cc406Sopenharmony_ci  SANE_Status status;
1772141cc406Sopenharmony_ci
1773141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a20: start\n");
1774141cc406Sopenharmony_ci
1775141cc406Sopenharmony_ci  if (!chip->is_opened)
1776141cc406Sopenharmony_ci    {
1777141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a20: not opened yet\n");
1778141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1779141cc406Sopenharmony_ci    }
1780141cc406Sopenharmony_ci  if (chip->is_rowing)
1781141cc406Sopenharmony_ci    {
1782141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a20: stop rowing first\n");
1783141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1784141cc406Sopenharmony_ci    }
1785141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 20, &pattern));
1786141cc406Sopenharmony_ci
1787141cc406Sopenharmony_ci  chip->red_pd = pattern;
1788141cc406Sopenharmony_ci
1789141cc406Sopenharmony_ci  if (value)
1790141cc406Sopenharmony_ci    *value = pattern;
1791141cc406Sopenharmony_ci
1792141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a20: stop\n");
1793141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1794141cc406Sopenharmony_ci}
1795141cc406Sopenharmony_ci
1796141cc406Sopenharmony_ciSANE_Status
1797141cc406Sopenharmony_ciusb_low_get_a21 (ma1017 * chip, SANE_Byte * value)
1798141cc406Sopenharmony_ci{
1799141cc406Sopenharmony_ci  SANE_Byte pattern;
1800141cc406Sopenharmony_ci  SANE_Status status;
1801141cc406Sopenharmony_ci
1802141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a21: start\n");
1803141cc406Sopenharmony_ci
1804141cc406Sopenharmony_ci  if (!chip->is_opened)
1805141cc406Sopenharmony_ci    {
1806141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a21: not opened yet\n");
1807141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1808141cc406Sopenharmony_ci    }
1809141cc406Sopenharmony_ci  if (chip->is_rowing)
1810141cc406Sopenharmony_ci    {
1811141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a21: stop rowing first\n");
1812141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1813141cc406Sopenharmony_ci    }
1814141cc406Sopenharmony_ci
1815141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 21, &pattern));
1816141cc406Sopenharmony_ci
1817141cc406Sopenharmony_ci  chip->green_pd = pattern;
1818141cc406Sopenharmony_ci
1819141cc406Sopenharmony_ci  if (value)
1820141cc406Sopenharmony_ci    *value = pattern;
1821141cc406Sopenharmony_ci
1822141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a21: exit\n");
1823141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1824141cc406Sopenharmony_ci}
1825141cc406Sopenharmony_ci
1826141cc406Sopenharmony_ciSANE_Status
1827141cc406Sopenharmony_ciusb_low_get_a22 (ma1017 * chip, SANE_Byte * value)
1828141cc406Sopenharmony_ci{
1829141cc406Sopenharmony_ci  SANE_Byte pattern;
1830141cc406Sopenharmony_ci  SANE_Status status;
1831141cc406Sopenharmony_ci
1832141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a22: start\n");
1833141cc406Sopenharmony_ci
1834141cc406Sopenharmony_ci  if (!chip->is_opened)
1835141cc406Sopenharmony_ci    {
1836141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a22: not opened yet\n");
1837141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1838141cc406Sopenharmony_ci    }
1839141cc406Sopenharmony_ci  if (chip->is_rowing)
1840141cc406Sopenharmony_ci    {
1841141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a22: stop rowing first\n");
1842141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1843141cc406Sopenharmony_ci    }
1844141cc406Sopenharmony_ci
1845141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 22, &pattern));
1846141cc406Sopenharmony_ci
1847141cc406Sopenharmony_ci  chip->blue_pd = pattern;
1848141cc406Sopenharmony_ci
1849141cc406Sopenharmony_ci  if (value)
1850141cc406Sopenharmony_ci    *value = pattern;
1851141cc406Sopenharmony_ci
1852141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a22: exit\n");
1853141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1854141cc406Sopenharmony_ci}
1855141cc406Sopenharmony_ci
1856141cc406Sopenharmony_ciSANE_Status
1857141cc406Sopenharmony_ciusb_low_set_red_pd (ma1017 * chip, SANE_Byte red_pd)
1858141cc406Sopenharmony_ci{
1859141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
1860141cc406Sopenharmony_ci  SANE_Status status;
1861141cc406Sopenharmony_ci
1862141cc406Sopenharmony_ci  DBG (7, "usb_low_set_red_pd: start\n");
1863141cc406Sopenharmony_ci
1864141cc406Sopenharmony_ci  if (!chip->is_opened)
1865141cc406Sopenharmony_ci    {
1866141cc406Sopenharmony_ci      DBG (3, "usb_low_set_red_pd: not opened yet\n");
1867141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1868141cc406Sopenharmony_ci    }
1869141cc406Sopenharmony_ci  if (chip->is_rowing)
1870141cc406Sopenharmony_ci    {
1871141cc406Sopenharmony_ci      DBG (3, "usb_low_set_red_pd: stop rowing first\n");
1872141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1873141cc406Sopenharmony_ci    }
1874141cc406Sopenharmony_ci
1875141cc406Sopenharmony_ci  chip->red_pd = red_pd;
1876141cc406Sopenharmony_ci
1877141cc406Sopenharmony_ci  data = chip->red_pd;
1878141cc406Sopenharmony_ci  reg_no = 20;
1879141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1880141cc406Sopenharmony_ci
1881141cc406Sopenharmony_ci  DBG (7, "usb_low_set_red_pd: exit\n");
1882141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1883141cc406Sopenharmony_ci}
1884141cc406Sopenharmony_ci
1885141cc406Sopenharmony_ciSANE_Status
1886141cc406Sopenharmony_ciusb_low_set_green_pd (ma1017 * chip, SANE_Byte green_pd)
1887141cc406Sopenharmony_ci{
1888141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
1889141cc406Sopenharmony_ci  SANE_Status status;
1890141cc406Sopenharmony_ci
1891141cc406Sopenharmony_ci  DBG (7, "usb_low_set_green_pd: start\n");
1892141cc406Sopenharmony_ci
1893141cc406Sopenharmony_ci  if (!chip->is_opened)
1894141cc406Sopenharmony_ci    {
1895141cc406Sopenharmony_ci      DBG (3, "usb_low_set_green_pd: not opened yet\n");
1896141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1897141cc406Sopenharmony_ci    }
1898141cc406Sopenharmony_ci  if (chip->is_rowing)
1899141cc406Sopenharmony_ci    {
1900141cc406Sopenharmony_ci      DBG (3, "usb_low_set_green_pd: stop rowing first\n");
1901141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1902141cc406Sopenharmony_ci    }
1903141cc406Sopenharmony_ci
1904141cc406Sopenharmony_ci  chip->green_pd = green_pd;
1905141cc406Sopenharmony_ci  data = chip->green_pd;
1906141cc406Sopenharmony_ci  reg_no = 21;
1907141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1908141cc406Sopenharmony_ci
1909141cc406Sopenharmony_ci  DBG (7, "usb_low_set_green_pd: exit\n");
1910141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1911141cc406Sopenharmony_ci}
1912141cc406Sopenharmony_ci
1913141cc406Sopenharmony_ciSANE_Status
1914141cc406Sopenharmony_ciusb_low_set_blue_pd (ma1017 * chip, SANE_Byte blue_pd)
1915141cc406Sopenharmony_ci{
1916141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
1917141cc406Sopenharmony_ci  SANE_Status status;
1918141cc406Sopenharmony_ci
1919141cc406Sopenharmony_ci  DBG (7, "usb_low_set_blue_pd: start\n");
1920141cc406Sopenharmony_ci
1921141cc406Sopenharmony_ci  if (!chip->is_opened)
1922141cc406Sopenharmony_ci    {
1923141cc406Sopenharmony_ci      DBG (3, "usb_low_set_blue_pd: not opened yet\n");
1924141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1925141cc406Sopenharmony_ci    }
1926141cc406Sopenharmony_ci  if (chip->is_rowing)
1927141cc406Sopenharmony_ci    {
1928141cc406Sopenharmony_ci      DBG (3, "usb_low_set_blue_pd: stop rowing first\n");
1929141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1930141cc406Sopenharmony_ci    }
1931141cc406Sopenharmony_ci
1932141cc406Sopenharmony_ci  chip->blue_pd = blue_pd;
1933141cc406Sopenharmony_ci
1934141cc406Sopenharmony_ci  data = chip->blue_pd;
1935141cc406Sopenharmony_ci  reg_no = 22;
1936141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1937141cc406Sopenharmony_ci
1938141cc406Sopenharmony_ci  DBG (7, "usb_low_set_blue_pd: exit\n");
1939141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1940141cc406Sopenharmony_ci}
1941141cc406Sopenharmony_ci
1942141cc406Sopenharmony_ci/* A23 */
1943141cc406Sopenharmony_ciSANE_Status
1944141cc406Sopenharmony_ciusb_low_get_a23 (ma1017 * chip, SANE_Byte * value)
1945141cc406Sopenharmony_ci{
1946141cc406Sopenharmony_ci  SANE_Byte pattern;
1947141cc406Sopenharmony_ci  SANE_Status status;
1948141cc406Sopenharmony_ci
1949141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a23: start\n");
1950141cc406Sopenharmony_ci  if (!chip->is_opened)
1951141cc406Sopenharmony_ci    {
1952141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a23: not opened yet\n");
1953141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1954141cc406Sopenharmony_ci    }
1955141cc406Sopenharmony_ci  if (chip->is_rowing)
1956141cc406Sopenharmony_ci    {
1957141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a23: stop rowing first\n");
1958141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1959141cc406Sopenharmony_ci    }
1960141cc406Sopenharmony_ci
1961141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 23, &pattern));
1962141cc406Sopenharmony_ci
1963141cc406Sopenharmony_ci  chip->a23 = pattern;
1964141cc406Sopenharmony_ci
1965141cc406Sopenharmony_ci  if (value)
1966141cc406Sopenharmony_ci    *value = pattern;
1967141cc406Sopenharmony_ci
1968141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a23: exit\n");
1969141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1970141cc406Sopenharmony_ci}
1971141cc406Sopenharmony_ci
1972141cc406Sopenharmony_ciSANE_Status
1973141cc406Sopenharmony_ciusb_low_turn_peripheral_power (ma1017 * chip, SANE_Bool is_on)
1974141cc406Sopenharmony_ci{
1975141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
1976141cc406Sopenharmony_ci  SANE_Status status;
1977141cc406Sopenharmony_ci
1978141cc406Sopenharmony_ci  DBG (7, "usb_low_turn_peripheral_power: start\n");
1979141cc406Sopenharmony_ci
1980141cc406Sopenharmony_ci  if (!chip->is_opened)
1981141cc406Sopenharmony_ci    {
1982141cc406Sopenharmony_ci      DBG (3, "usb_low_turn_peripheral_power: not opened yet\n");
1983141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1984141cc406Sopenharmony_ci    }
1985141cc406Sopenharmony_ci  if (chip->is_rowing)
1986141cc406Sopenharmony_ci    {
1987141cc406Sopenharmony_ci      DBG (3, "usb_low_turn_peripheral_power: stop rowing first\n");
1988141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
1989141cc406Sopenharmony_ci    }
1990141cc406Sopenharmony_ci
1991141cc406Sopenharmony_ci  chip->a23 &= 0x7f;
1992141cc406Sopenharmony_ci  if (is_on)
1993141cc406Sopenharmony_ci    chip->a23 |= 0x80;
1994141cc406Sopenharmony_ci  data = chip->a23;
1995141cc406Sopenharmony_ci  reg_no = 23;
1996141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
1997141cc406Sopenharmony_ci
1998141cc406Sopenharmony_ci  DBG (7, "usb_low_turn_peripheral_power: exit\n");
1999141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2000141cc406Sopenharmony_ci}
2001141cc406Sopenharmony_ci
2002141cc406Sopenharmony_ciSANE_Status
2003141cc406Sopenharmony_ciusb_low_turn_lamp_power (ma1017 * chip, SANE_Bool is_on)
2004141cc406Sopenharmony_ci{
2005141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
2006141cc406Sopenharmony_ci  SANE_Status status;
2007141cc406Sopenharmony_ci
2008141cc406Sopenharmony_ci  DBG (7, "usb_low_turn_lamp_power: start\n");
2009141cc406Sopenharmony_ci
2010141cc406Sopenharmony_ci  if (!chip->is_opened)
2011141cc406Sopenharmony_ci    {
2012141cc406Sopenharmony_ci      DBG (3, "usb_low_turn_lamp_power: not opened yet\n");
2013141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2014141cc406Sopenharmony_ci    }
2015141cc406Sopenharmony_ci  if (chip->is_rowing)
2016141cc406Sopenharmony_ci    {
2017141cc406Sopenharmony_ci      DBG (3, "usb_low_turn_lamp_power: stop rowing first\n");
2018141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2019141cc406Sopenharmony_ci    }
2020141cc406Sopenharmony_ci
2021141cc406Sopenharmony_ci  chip->a23 &= 0xbf;
2022141cc406Sopenharmony_ci  if (is_on)
2023141cc406Sopenharmony_ci    chip->a23 |= 0x40;
2024141cc406Sopenharmony_ci
2025141cc406Sopenharmony_ci  data = chip->a23;
2026141cc406Sopenharmony_ci  reg_no = 23;
2027141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
2028141cc406Sopenharmony_ci
2029141cc406Sopenharmony_ci  DBG (7, "usb_low_turn_lamp_power: exit\n");
2030141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2031141cc406Sopenharmony_ci}
2032141cc406Sopenharmony_ci
2033141cc406Sopenharmony_ciSANE_Status
2034141cc406Sopenharmony_ciusb_low_set_io_3 (ma1017 * chip, SANE_Bool is_high)
2035141cc406Sopenharmony_ci{
2036141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
2037141cc406Sopenharmony_ci  SANE_Status status;
2038141cc406Sopenharmony_ci
2039141cc406Sopenharmony_ci  DBG (7, "usb_low_set_io_3: start\n");
2040141cc406Sopenharmony_ci
2041141cc406Sopenharmony_ci  if (!chip->is_opened)
2042141cc406Sopenharmony_ci    {
2043141cc406Sopenharmony_ci      DBG (3, "usb_low_set_io_3: not opened yet\n");
2044141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2045141cc406Sopenharmony_ci    }
2046141cc406Sopenharmony_ci  if (chip->is_rowing)
2047141cc406Sopenharmony_ci    {
2048141cc406Sopenharmony_ci      DBG (3, "usb_low_set_io_3: stop rowing first\n");
2049141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2050141cc406Sopenharmony_ci    }
2051141cc406Sopenharmony_ci
2052141cc406Sopenharmony_ci  chip->a23 &= 0xf7;
2053141cc406Sopenharmony_ci  if (is_high)
2054141cc406Sopenharmony_ci    chip->a23 |= 0x08;
2055141cc406Sopenharmony_ci
2056141cc406Sopenharmony_ci  data = chip->a23;
2057141cc406Sopenharmony_ci  reg_no = 23;
2058141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
2059141cc406Sopenharmony_ci
2060141cc406Sopenharmony_ci  DBG (7, "usb_low_set_io_3: exit\n");
2061141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2062141cc406Sopenharmony_ci}
2063141cc406Sopenharmony_ci
2064141cc406Sopenharmony_ciSANE_Status
2065141cc406Sopenharmony_ciusb_low_set_led_light_all (ma1017 * chip, SANE_Bool is_light_all)
2066141cc406Sopenharmony_ci{
2067141cc406Sopenharmony_ci  SANE_Byte data, reg_no;
2068141cc406Sopenharmony_ci  SANE_Status status;
2069141cc406Sopenharmony_ci
2070141cc406Sopenharmony_ci  DBG (7, "usb_low_set_led_light_all: start\n");
2071141cc406Sopenharmony_ci
2072141cc406Sopenharmony_ci  if (!chip->is_opened)
2073141cc406Sopenharmony_ci    {
2074141cc406Sopenharmony_ci      DBG (3, "usb_low_set_led_light_all: not opened yet\n");
2075141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2076141cc406Sopenharmony_ci    }
2077141cc406Sopenharmony_ci  if (chip->is_rowing)
2078141cc406Sopenharmony_ci    {
2079141cc406Sopenharmony_ci      DBG (3, "usb_low_set_led_light_all: stop rowing first\n");
2080141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2081141cc406Sopenharmony_ci    }
2082141cc406Sopenharmony_ci
2083141cc406Sopenharmony_ci  chip->a23 &= 0xfe;
2084141cc406Sopenharmony_ci  if (is_light_all)
2085141cc406Sopenharmony_ci    chip->a23 |= 0x01;
2086141cc406Sopenharmony_ci
2087141cc406Sopenharmony_ci  data = chip->a23;
2088141cc406Sopenharmony_ci  reg_no = 23;
2089141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
2090141cc406Sopenharmony_ci
2091141cc406Sopenharmony_ci  DBG (7, "usb_low_set_led_light_all: exit\n");
2092141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2093141cc406Sopenharmony_ci}
2094141cc406Sopenharmony_ci
2095141cc406Sopenharmony_ci/* A24 */
2096141cc406Sopenharmony_ciSANE_Status
2097141cc406Sopenharmony_ciusb_low_get_a24 (ma1017 * chip, SANE_Byte * value)
2098141cc406Sopenharmony_ci{
2099141cc406Sopenharmony_ci  SANE_Byte pattern;
2100141cc406Sopenharmony_ci  SANE_Status status;
2101141cc406Sopenharmony_ci
2102141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a24: start\n");
2103141cc406Sopenharmony_ci
2104141cc406Sopenharmony_ci  if (!chip->is_opened)
2105141cc406Sopenharmony_ci    {
2106141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a24: not opened yet\n");
2107141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2108141cc406Sopenharmony_ci    }
2109141cc406Sopenharmony_ci  if (chip->is_rowing)
2110141cc406Sopenharmony_ci    {
2111141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a24: stop rowing first\n");
2112141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2113141cc406Sopenharmony_ci    }
2114141cc406Sopenharmony_ci
2115141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 24, &pattern));
2116141cc406Sopenharmony_ci
2117141cc406Sopenharmony_ci  chip->fy1_delay = pattern & 0x01;
2118141cc406Sopenharmony_ci  chip->special_ad = pattern & 0x02;
2119141cc406Sopenharmony_ci
2120141cc406Sopenharmony_ci  if (value)
2121141cc406Sopenharmony_ci    *value = pattern;
2122141cc406Sopenharmony_ci
2123141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a24: exit\n");
2124141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2125141cc406Sopenharmony_ci}
2126141cc406Sopenharmony_ci
2127141cc406Sopenharmony_ciSANE_Status
2128141cc406Sopenharmony_ciusb_low_set_ad_timing (ma1017 * chip, SANE_Byte data)
2129141cc406Sopenharmony_ci{
2130141cc406Sopenharmony_ci  SANE_Byte reg_no;
2131141cc406Sopenharmony_ci  SANE_Status status;
2132141cc406Sopenharmony_ci
2133141cc406Sopenharmony_ci  DBG (7, "usb_low_set_ad_timing: start\n");
2134141cc406Sopenharmony_ci
2135141cc406Sopenharmony_ci  if (!chip->is_opened)
2136141cc406Sopenharmony_ci    {
2137141cc406Sopenharmony_ci      DBG (3, "usb_low_set_ad_timing: not opened yet\n");
2138141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2139141cc406Sopenharmony_ci    }
2140141cc406Sopenharmony_ci  if (chip->is_rowing)
2141141cc406Sopenharmony_ci    {
2142141cc406Sopenharmony_ci      DBG (3, "usb_low_set_ad_timing: stop rowing first\n");
2143141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2144141cc406Sopenharmony_ci    }
2145141cc406Sopenharmony_ci
2146141cc406Sopenharmony_ci  chip->fy1_delay = data & 0x01;
2147141cc406Sopenharmony_ci  chip->special_ad = data & 0x02;
2148141cc406Sopenharmony_ci
2149141cc406Sopenharmony_ci  data = chip->special_ad | chip->fy1_delay;
2150141cc406Sopenharmony_ci  reg_no = 24;
2151141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
2152141cc406Sopenharmony_ci
2153141cc406Sopenharmony_ci  DBG (7, "usb_low_set_ad_timing: exit\n");
2154141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2155141cc406Sopenharmony_ci}
2156141cc406Sopenharmony_ci
2157141cc406Sopenharmony_ci/* A25 + A26 */
2158141cc406Sopenharmony_ciSANE_Status
2159141cc406Sopenharmony_ciusb_low_set_serial_byte1 (ma1017 * chip, SANE_Byte data)
2160141cc406Sopenharmony_ci{
2161141cc406Sopenharmony_ci  SANE_Byte reg_no;
2162141cc406Sopenharmony_ci  SANE_Status status;
2163141cc406Sopenharmony_ci
2164141cc406Sopenharmony_ci  DBG (7, "usb_low_set_serial_byte1: start\n");
2165141cc406Sopenharmony_ci
2166141cc406Sopenharmony_ci  if (!chip->is_opened)
2167141cc406Sopenharmony_ci    {
2168141cc406Sopenharmony_ci      DBG (3, "usb_low_set_serial_byte1: not opened\n");
2169141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2170141cc406Sopenharmony_ci    }
2171141cc406Sopenharmony_ci  if (chip->is_rowing)
2172141cc406Sopenharmony_ci    {
2173141cc406Sopenharmony_ci      DBG (3, "usb_low_set_serial_byte1: stop rowing first\n");
2174141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2175141cc406Sopenharmony_ci    }
2176141cc406Sopenharmony_ci
2177141cc406Sopenharmony_ci  reg_no = 25;
2178141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
2179141cc406Sopenharmony_ci
2180141cc406Sopenharmony_ci  DBG (7, "usb_low_set_serial_byte1: exit\n");
2181141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2182141cc406Sopenharmony_ci}
2183141cc406Sopenharmony_ci
2184141cc406Sopenharmony_ciSANE_Status
2185141cc406Sopenharmony_ciusb_low_set_serial_byte2 (ma1017 * chip, SANE_Byte data)
2186141cc406Sopenharmony_ci{
2187141cc406Sopenharmony_ci  SANE_Byte reg_no;
2188141cc406Sopenharmony_ci  SANE_Status status;
2189141cc406Sopenharmony_ci
2190141cc406Sopenharmony_ci  DBG (7, "usb_low_set_serial_byte2: start\n");
2191141cc406Sopenharmony_ci
2192141cc406Sopenharmony_ci  if (!chip->is_opened)
2193141cc406Sopenharmony_ci    {
2194141cc406Sopenharmony_ci      DBG (3, "usb_low_set_serial_byte2: not opened yet\n");
2195141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2196141cc406Sopenharmony_ci    }
2197141cc406Sopenharmony_ci  if (chip->is_rowing)
2198141cc406Sopenharmony_ci    {
2199141cc406Sopenharmony_ci      DBG (3, "usb_low_set_serial_byte2: stop rowing first\n");
2200141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2201141cc406Sopenharmony_ci    }
2202141cc406Sopenharmony_ci
2203141cc406Sopenharmony_ci  reg_no = 26;
2204141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
2205141cc406Sopenharmony_ci
2206141cc406Sopenharmony_ci  DBG (7, "usb_low_set_serial_byte2: exit\n");
2207141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2208141cc406Sopenharmony_ci}
2209141cc406Sopenharmony_ci
2210141cc406Sopenharmony_ci/* A27 */
2211141cc406Sopenharmony_ciSANE_Status
2212141cc406Sopenharmony_ciusb_low_get_a27 (ma1017 * chip, SANE_Byte * value)
2213141cc406Sopenharmony_ci{
2214141cc406Sopenharmony_ci  SANE_Byte pattern;
2215141cc406Sopenharmony_ci  SANE_Status status;
2216141cc406Sopenharmony_ci
2217141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a27: start\n");
2218141cc406Sopenharmony_ci
2219141cc406Sopenharmony_ci  if (!chip->is_opened)
2220141cc406Sopenharmony_ci    {
2221141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a27: not opened yet\n");
2222141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2223141cc406Sopenharmony_ci    }
2224141cc406Sopenharmony_ci  if (chip->is_rowing)
2225141cc406Sopenharmony_ci    {
2226141cc406Sopenharmony_ci      DBG (3, "usb_low_get_a27: stop rowing first\n");
2227141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2228141cc406Sopenharmony_ci    }
2229141cc406Sopenharmony_ci
2230141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 27, &pattern));
2231141cc406Sopenharmony_ci
2232141cc406Sopenharmony_ci  chip->sclk = pattern & 0x80;
2233141cc406Sopenharmony_ci  chip->sen = pattern & 0x40;
2234141cc406Sopenharmony_ci  chip->serial_length = pattern & 0x1f;
2235141cc406Sopenharmony_ci
2236141cc406Sopenharmony_ci  if (value)
2237141cc406Sopenharmony_ci    *value = pattern;
2238141cc406Sopenharmony_ci
2239141cc406Sopenharmony_ci  DBG (7, "usb_low_get_a27: exit\n");
2240141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2241141cc406Sopenharmony_ci}
2242141cc406Sopenharmony_ci
2243141cc406Sopenharmony_ciSANE_Status
2244141cc406Sopenharmony_ciusb_low_set_serial_format (ma1017 * chip, SANE_Byte data)
2245141cc406Sopenharmony_ci{
2246141cc406Sopenharmony_ci  SANE_Byte reg_no;
2247141cc406Sopenharmony_ci  SANE_Status status;
2248141cc406Sopenharmony_ci
2249141cc406Sopenharmony_ci  DBG (7, "usb_low_set_serial_format: start\n");
2250141cc406Sopenharmony_ci
2251141cc406Sopenharmony_ci  if (!chip->is_opened)
2252141cc406Sopenharmony_ci    {
2253141cc406Sopenharmony_ci      DBG (3, "usb_low_set_serial_format: not opened yet\n");
2254141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2255141cc406Sopenharmony_ci    }
2256141cc406Sopenharmony_ci  if (chip->is_rowing)
2257141cc406Sopenharmony_ci    {
2258141cc406Sopenharmony_ci      DBG (3, "usb_low_set_serial_format: stop rowing first\n");
2259141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2260141cc406Sopenharmony_ci    }
2261141cc406Sopenharmony_ci
2262141cc406Sopenharmony_ci
2263141cc406Sopenharmony_ci  chip->sclk = data & 0x80;
2264141cc406Sopenharmony_ci  chip->sen = data & 0x40;
2265141cc406Sopenharmony_ci  chip->serial_length = data & 0x1f;
2266141cc406Sopenharmony_ci
2267141cc406Sopenharmony_ci  reg_no = 27;
2268141cc406Sopenharmony_ci  RIE (usb_low_write_reg (chip, reg_no, data));
2269141cc406Sopenharmony_ci
2270141cc406Sopenharmony_ci  DBG (7, "usb_low_set_serial_format: exit\n");
2271141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2272141cc406Sopenharmony_ci}
2273141cc406Sopenharmony_ci
2274141cc406Sopenharmony_ciSANE_Status
2275141cc406Sopenharmony_ciusb_low_get_home_sensor (ma1017 * chip)
2276141cc406Sopenharmony_ci{
2277141cc406Sopenharmony_ci  SANE_Byte data;
2278141cc406Sopenharmony_ci  SANE_Status status;
2279141cc406Sopenharmony_ci
2280141cc406Sopenharmony_ci  DBG (7, "usb_low_get_home_sensor: start\n");
2281141cc406Sopenharmony_ci
2282141cc406Sopenharmony_ci  if (!chip->is_opened)
2283141cc406Sopenharmony_ci    {
2284141cc406Sopenharmony_ci      DBG (3, "usb_low_get_home_sensor: not opened yet\n");
2285141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2286141cc406Sopenharmony_ci    }
2287141cc406Sopenharmony_ci  if (chip->is_rowing)
2288141cc406Sopenharmony_ci    {
2289141cc406Sopenharmony_ci      DBG (3, "usb_low_get_home_sensor: stop rowing first\n");
2290141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2291141cc406Sopenharmony_ci    }
2292141cc406Sopenharmony_ci
2293141cc406Sopenharmony_ci  RIE (usb_low_read_reg (chip, 31, &data));
2294141cc406Sopenharmony_ci
2295141cc406Sopenharmony_ci  DBG (7, "usb_low_get_home_sensor: exit\n");
2296141cc406Sopenharmony_ci  if ((data & 0x80) != 0)
2297141cc406Sopenharmony_ci    return SANE_STATUS_GOOD;
2298141cc406Sopenharmony_ci  else
2299141cc406Sopenharmony_ci    return SANE_STATUS_IO_ERROR;
2300141cc406Sopenharmony_ci}
2301141cc406Sopenharmony_ci
2302141cc406Sopenharmony_ci/* Special Mode */
2303141cc406Sopenharmony_ciSANE_Status
2304141cc406Sopenharmony_ciusb_low_start_rowing (ma1017 * chip)
2305141cc406Sopenharmony_ci{
2306141cc406Sopenharmony_ci  SANE_Word line_of_first = 0;
2307141cc406Sopenharmony_ci  SANE_Word line_of_second = 0;
2308141cc406Sopenharmony_ci  SANE_Int i;
2309141cc406Sopenharmony_ci  SANE_Status status;
2310141cc406Sopenharmony_ci
2311141cc406Sopenharmony_ci  DBG (7, "usb_low_start_rowing: start\n");
2312141cc406Sopenharmony_ci
2313141cc406Sopenharmony_ci  if (chip->loop_count == 0)
2314141cc406Sopenharmony_ci    {
2315141cc406Sopenharmony_ci      DBG (3, "usb_low_start_rowing loop_count hasn't been set yet\n");
2316141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2317141cc406Sopenharmony_ci    }
2318141cc406Sopenharmony_ci  if (chip->cmt_table_length_word == 0)
2319141cc406Sopenharmony_ci    {
2320141cc406Sopenharmony_ci      DBG (3, "usb_low_start_rowing: cmt_table_length_word hasn't been set "
2321141cc406Sopenharmony_ci	   "yet\n");
2322141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2323141cc406Sopenharmony_ci    }
2324141cc406Sopenharmony_ci  if (chip->cmt_table_length_word <= chip->cmt_second_pos_word)
2325141cc406Sopenharmony_ci    {
2326141cc406Sopenharmony_ci      DBG (3, "usb_low_start_rowing: cmt_second_pos_word cannot be larger "
2327141cc406Sopenharmony_ci	   "than cmt_table_length_word\n");
2328141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2329141cc406Sopenharmony_ci    }
2330141cc406Sopenharmony_ci
2331141cc406Sopenharmony_ci  for (i = 0; i < (int) chip->cmt_second_pos_word; i++)
2332141cc406Sopenharmony_ci    {
2333141cc406Sopenharmony_ci      if (chip->is_transfer_table[i])
2334141cc406Sopenharmony_ci	line_of_first++;
2335141cc406Sopenharmony_ci    }
2336141cc406Sopenharmony_ci  for (; i < (int) chip->cmt_table_length_word; i++)
2337141cc406Sopenharmony_ci    {
2338141cc406Sopenharmony_ci      if (chip->is_transfer_table[i])
2339141cc406Sopenharmony_ci	{
2340141cc406Sopenharmony_ci	  line_of_first++;
2341141cc406Sopenharmony_ci	  line_of_second++;
2342141cc406Sopenharmony_ci	}
2343141cc406Sopenharmony_ci    }
2344141cc406Sopenharmony_ci
2345141cc406Sopenharmony_ci  chip->total_lines =
2346141cc406Sopenharmony_ci    ((SANE_Word) (chip->loop_count - 1)) * line_of_second + line_of_first;
2347141cc406Sopenharmony_ci  chip->lines_left = chip->total_lines;
2348141cc406Sopenharmony_ci
2349141cc406Sopenharmony_ci  RIE (usb_low_start_cmt_table (chip));
2350141cc406Sopenharmony_ci
2351141cc406Sopenharmony_ci  DBG (7, "usb_low_start_rowing: exit\n");
2352141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2353141cc406Sopenharmony_ci}
2354141cc406Sopenharmony_ci
2355141cc406Sopenharmony_ciSANE_Status
2356141cc406Sopenharmony_ciusb_low_stop_rowing (ma1017 * chip)
2357141cc406Sopenharmony_ci{
2358141cc406Sopenharmony_ci  SANE_Status status;
2359141cc406Sopenharmony_ci
2360141cc406Sopenharmony_ci  DBG (7, "usb_low_stop_rowing: start\n");
2361141cc406Sopenharmony_ci
2362141cc406Sopenharmony_ci  RIE (usb_low_stop_cmt_table (chip));
2363141cc406Sopenharmony_ci
2364141cc406Sopenharmony_ci  DBG (7, "usb_low_stop_rowing: exit\n");
2365141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2366141cc406Sopenharmony_ci
2367141cc406Sopenharmony_ci}
2368141cc406Sopenharmony_ci
2369141cc406Sopenharmony_ciSANE_Status
2370141cc406Sopenharmony_ciusb_low_wait_rowing_stop (ma1017 * chip)
2371141cc406Sopenharmony_ci{
2372141cc406Sopenharmony_ci  SANE_Status status;
2373141cc406Sopenharmony_ci
2374141cc406Sopenharmony_ci  DBG (7, "usb_low_wait_rowing_stop: start\n");
2375141cc406Sopenharmony_ci  if (chip->total_lines != 0)
2376141cc406Sopenharmony_ci    {
2377141cc406Sopenharmony_ci      DBG (3, "usb_low_wait_rowing_stop: total_lines must be 0\n");
2378141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2379141cc406Sopenharmony_ci    }
2380141cc406Sopenharmony_ci
2381141cc406Sopenharmony_ci  RIE (usb_low_wait_rowing (chip));
2382141cc406Sopenharmony_ci  chip->is_rowing = SANE_FALSE;
2383141cc406Sopenharmony_ci  DBG (7, "usb_low_wait_rowing_stop: exit\n");
2384141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2385141cc406Sopenharmony_ci}
2386141cc406Sopenharmony_ci
2387141cc406Sopenharmony_ciSANE_Status
2388141cc406Sopenharmony_ciusb_low_read_all_registers (ma1017 * chip)
2389141cc406Sopenharmony_ci{
2390141cc406Sopenharmony_ci  SANE_Status status;
2391141cc406Sopenharmony_ci
2392141cc406Sopenharmony_ci  DBG (7, "usb_low_read_all_registers: start\n");
2393141cc406Sopenharmony_ci
2394141cc406Sopenharmony_ci  RIE (usb_low_get_a2 (chip, 0));
2395141cc406Sopenharmony_ci  RIE (usb_low_get_a4 (chip, 0));
2396141cc406Sopenharmony_ci  RIE (usb_low_get_a6 (chip, 0));
2397141cc406Sopenharmony_ci  RIE (usb_low_get_a7 (chip, 0));
2398141cc406Sopenharmony_ci  RIE (usb_low_get_a8 (chip, 0));
2399141cc406Sopenharmony_ci  RIE (usb_low_get_a9 (chip, 0));
2400141cc406Sopenharmony_ci  RIE (usb_low_get_a10 (chip, 0));
2401141cc406Sopenharmony_ci  RIE (usb_low_get_a11 (chip, 0));
2402141cc406Sopenharmony_ci  RIE (usb_low_get_a12 (chip, 0));
2403141cc406Sopenharmony_ci  RIE (usb_low_get_a13 (chip, 0));
2404141cc406Sopenharmony_ci  RIE (usb_low_get_a15 (chip, 0));
2405141cc406Sopenharmony_ci  RIE (usb_low_get_a16 (chip, 0));
2406141cc406Sopenharmony_ci  RIE (usb_low_get_a17 (chip, 0));
2407141cc406Sopenharmony_ci  RIE (usb_low_get_a18 (chip, 0));
2408141cc406Sopenharmony_ci  RIE (usb_low_get_a19 (chip, 0));
2409141cc406Sopenharmony_ci  RIE (usb_low_get_a20 (chip, 0));
2410141cc406Sopenharmony_ci  RIE (usb_low_get_a21 (chip, 0));
2411141cc406Sopenharmony_ci  RIE (usb_low_get_a22 (chip, 0));
2412141cc406Sopenharmony_ci  RIE (usb_low_get_a23 (chip, 0));
2413141cc406Sopenharmony_ci  RIE (usb_low_get_a24 (chip, 0));
2414141cc406Sopenharmony_ci  RIE (usb_low_get_a27 (chip, 0));
2415141cc406Sopenharmony_ci
2416141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2417141cc406Sopenharmony_ci  DBG (7, "usb_low_read_all_registers: exit\n");
2418141cc406Sopenharmony_ci}
2419141cc406Sopenharmony_ci
2420141cc406Sopenharmony_ciSANE_Status
2421141cc406Sopenharmony_ciusb_low_get_row (ma1017 * chip, SANE_Byte * data, SANE_Word * lines_left)
2422141cc406Sopenharmony_ci{
2423141cc406Sopenharmony_ci  SANE_Status status;
2424141cc406Sopenharmony_ci
2425141cc406Sopenharmony_ci  DBG (7, "usb_low_get_row: start\n");
2426141cc406Sopenharmony_ci  RIE ((*chip->get_row) (chip, data, lines_left));
2427141cc406Sopenharmony_ci  DBG (7, "usb_low_get_row: exit\n");
2428141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;;
2429141cc406Sopenharmony_ci}
2430141cc406Sopenharmony_ci
2431141cc406Sopenharmony_ciSANE_Status
2432141cc406Sopenharmony_ciusb_low_get_row_direct (ma1017 * chip, SANE_Byte * data,
2433141cc406Sopenharmony_ci			SANE_Word * lines_left)
2434141cc406Sopenharmony_ci{
2435141cc406Sopenharmony_ci  SANE_Status status;
2436141cc406Sopenharmony_ci
2437141cc406Sopenharmony_ci  DBG (7, "usb_low_get_row_direct: start\n");
2438141cc406Sopenharmony_ci  if (chip->lines_left == 0)
2439141cc406Sopenharmony_ci    {
2440141cc406Sopenharmony_ci      DBG (3, "usb_low_get_row_direct: lines_left == 0\n");
2441141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2442141cc406Sopenharmony_ci    }
2443141cc406Sopenharmony_ci
2444141cc406Sopenharmony_ci  if (chip->lines_left <= 1)
2445141cc406Sopenharmony_ci    {
2446141cc406Sopenharmony_ci      RIE (usb_low_read_rows (chip, data, chip->byte_width));
2447141cc406Sopenharmony_ci      RIE (usb_low_wait_rowing (chip));
2448141cc406Sopenharmony_ci
2449141cc406Sopenharmony_ci      chip->lines_left = 0x00;
2450141cc406Sopenharmony_ci      chip->is_rowing = SANE_FALSE;
2451141cc406Sopenharmony_ci      *lines_left = 0;
2452141cc406Sopenharmony_ci    }
2453141cc406Sopenharmony_ci  else
2454141cc406Sopenharmony_ci    {
2455141cc406Sopenharmony_ci      RIE (usb_low_read_rows (chip, data, chip->byte_width));
2456141cc406Sopenharmony_ci      chip->lines_left--;
2457141cc406Sopenharmony_ci      *lines_left = chip->lines_left;
2458141cc406Sopenharmony_ci    }
2459141cc406Sopenharmony_ci  DBG (7, "usb_low_get_row_direct: exit\n");
2460141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2461141cc406Sopenharmony_ci}
2462141cc406Sopenharmony_ci
2463141cc406Sopenharmony_ciSANE_Status
2464141cc406Sopenharmony_ciusb_low_get_row_resample (ma1017 * chip, SANE_Byte * data,
2465141cc406Sopenharmony_ci			  SANE_Word * lines_left)
2466141cc406Sopenharmony_ci{
2467141cc406Sopenharmony_ci  static SANE_Byte resample_buffer[8 * 1024];
2468141cc406Sopenharmony_ci  SANE_Word *pixel_temp;
2469141cc406Sopenharmony_ci  SANE_Word i;
2470141cc406Sopenharmony_ci  SANE_Word j;
2471141cc406Sopenharmony_ci  SANE_Word k;
2472141cc406Sopenharmony_ci  SANE_Status status;
2473141cc406Sopenharmony_ci
2474141cc406Sopenharmony_ci  DBG (7, "usb_low_get_row_resample: start\n");
2475141cc406Sopenharmony_ci
2476141cc406Sopenharmony_ci  if (chip->lines_left == 0)
2477141cc406Sopenharmony_ci    {
2478141cc406Sopenharmony_ci      DBG (3, "usb_low_get_row_resample: lines_left == 0\n");
2479141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2480141cc406Sopenharmony_ci    }
2481141cc406Sopenharmony_ci
2482141cc406Sopenharmony_ci  if (chip->lines_left <= 1)
2483141cc406Sopenharmony_ci    {
2484141cc406Sopenharmony_ci      RIE (usb_low_read_rows (chip, resample_buffer, chip->byte_width));
2485141cc406Sopenharmony_ci
2486141cc406Sopenharmony_ci      if ((chip->sensor == ST_CANON600) && (chip->pixel_depth == 0x20))
2487141cc406Sopenharmony_ci	{
2488141cc406Sopenharmony_ci	  pixel_temp = (SANE_Word *) malloc (6 * 1024 * sizeof (SANE_Word));
2489141cc406Sopenharmony_ci	  if (!pixel_temp)
2490141cc406Sopenharmony_ci	    return SANE_STATUS_NO_MEM;
2491141cc406Sopenharmony_ci
2492141cc406Sopenharmony_ci	  j = 0;
2493141cc406Sopenharmony_ci	  for (i = 0; i < chip->byte_width; i += 3)
2494141cc406Sopenharmony_ci	    {
2495141cc406Sopenharmony_ci	      pixel_temp[j] = (SANE_Word) resample_buffer[i];
2496141cc406Sopenharmony_ci	      pixel_temp[j] |= ((SANE_Word)
2497141cc406Sopenharmony_ci				(resample_buffer[i + 1] & 0xf0)) << 4;
2498141cc406Sopenharmony_ci	      j++;
2499141cc406Sopenharmony_ci	      pixel_temp[j] = ((SANE_Word)
2500141cc406Sopenharmony_ci			       (resample_buffer[i + 1] & 0x0f)) << 8;
2501141cc406Sopenharmony_ci	      pixel_temp[j] |= (SANE_Word) resample_buffer[i + 2];
2502141cc406Sopenharmony_ci	      j++;
2503141cc406Sopenharmony_ci	    }
2504141cc406Sopenharmony_ci
2505141cc406Sopenharmony_ci	  k = 0;
2506141cc406Sopenharmony_ci	  for (i = 0; i < j; i += chip->soft_resample * 2)
2507141cc406Sopenharmony_ci	    {
2508141cc406Sopenharmony_ci	      data[k] = (SANE_Byte) (pixel_temp[i] & 0x00ff);
2509141cc406Sopenharmony_ci	      k++;
2510141cc406Sopenharmony_ci	      data[k] = (SANE_Byte) ((pixel_temp[i] & 0x0f00) >> 4);
2511141cc406Sopenharmony_ci	      data[k] |= (SANE_Byte) ((pixel_temp[i + 2] & 0x0f00) >> 8);
2512141cc406Sopenharmony_ci	      k++;
2513141cc406Sopenharmony_ci	      data[k] = (SANE_Byte) (pixel_temp[i + 2] & 0x00ff);
2514141cc406Sopenharmony_ci	      k++;
2515141cc406Sopenharmony_ci	    }
2516141cc406Sopenharmony_ci	  free (pixel_temp);
2517141cc406Sopenharmony_ci	}
2518141cc406Sopenharmony_ci      else			/* fixme ? */
2519141cc406Sopenharmony_ci	{
2520141cc406Sopenharmony_ci	  for (i = 0; i < chip->byte_width; i += chip->soft_resample)
2521141cc406Sopenharmony_ci	    *(data++) = resample_buffer[i];
2522141cc406Sopenharmony_ci	}
2523141cc406Sopenharmony_ci      RIE (usb_low_wait_rowing (chip));
2524141cc406Sopenharmony_ci
2525141cc406Sopenharmony_ci      chip->lines_left = 0x00;
2526141cc406Sopenharmony_ci      chip->is_rowing = SANE_FALSE;
2527141cc406Sopenharmony_ci      *lines_left = 0;
2528141cc406Sopenharmony_ci    }
2529141cc406Sopenharmony_ci  else
2530141cc406Sopenharmony_ci    {
2531141cc406Sopenharmony_ci      RIE (usb_low_read_rows (chip, resample_buffer, chip->byte_width));
2532141cc406Sopenharmony_ci
2533141cc406Sopenharmony_ci      if ((chip->sensor == ST_CANON600) && (chip->pixel_depth == 0x20))
2534141cc406Sopenharmony_ci	{
2535141cc406Sopenharmony_ci	  pixel_temp = (SANE_Word *) malloc (6 * 1024 * sizeof (SANE_Word));
2536141cc406Sopenharmony_ci	  if (!pixel_temp)
2537141cc406Sopenharmony_ci	    return SANE_STATUS_NO_MEM;
2538141cc406Sopenharmony_ci
2539141cc406Sopenharmony_ci	  j = 0;
2540141cc406Sopenharmony_ci	  for (i = 0; i < chip->byte_width; i += 3)
2541141cc406Sopenharmony_ci	    {
2542141cc406Sopenharmony_ci	      pixel_temp[j] = (SANE_Word) resample_buffer[i];
2543141cc406Sopenharmony_ci	      pixel_temp[j] |=
2544141cc406Sopenharmony_ci		((SANE_Word) (resample_buffer[i + 1] & 0xf0)) << 4;
2545141cc406Sopenharmony_ci	      j++;
2546141cc406Sopenharmony_ci	      pixel_temp[j] =
2547141cc406Sopenharmony_ci		((SANE_Word) (resample_buffer[i + 1] & 0x0f)) << 8;
2548141cc406Sopenharmony_ci	      pixel_temp[j] |= (SANE_Word) resample_buffer[i + 2];
2549141cc406Sopenharmony_ci	      j++;
2550141cc406Sopenharmony_ci	    }
2551141cc406Sopenharmony_ci
2552141cc406Sopenharmony_ci	  k = 0;
2553141cc406Sopenharmony_ci	  for (i = 0; i < j; i += chip->soft_resample * 2)
2554141cc406Sopenharmony_ci	    {
2555141cc406Sopenharmony_ci	      data[k] = (SANE_Byte) (pixel_temp[i] & 0x00ff);
2556141cc406Sopenharmony_ci	      k++;
2557141cc406Sopenharmony_ci	      data[k] = (SANE_Byte) ((pixel_temp[i] & 0x0f00) >> 4);
2558141cc406Sopenharmony_ci	      data[k] |= (SANE_Byte) ((pixel_temp[i + 2] & 0x0f00) >> 8);
2559141cc406Sopenharmony_ci	      k++;
2560141cc406Sopenharmony_ci	      data[k] = (SANE_Byte) (pixel_temp[i + 2] & 0x00ff);
2561141cc406Sopenharmony_ci	      k++;
2562141cc406Sopenharmony_ci	    }
2563141cc406Sopenharmony_ci	  free (pixel_temp);
2564141cc406Sopenharmony_ci	}
2565141cc406Sopenharmony_ci      else			/* fixme? */
2566141cc406Sopenharmony_ci	{
2567141cc406Sopenharmony_ci	  for (i = 0; i < chip->byte_width; i += chip->soft_resample)
2568141cc406Sopenharmony_ci	    *(data++) = resample_buffer[i];
2569141cc406Sopenharmony_ci	}
2570141cc406Sopenharmony_ci      chip->lines_left--;
2571141cc406Sopenharmony_ci      *lines_left = chip->lines_left;
2572141cc406Sopenharmony_ci    }
2573141cc406Sopenharmony_ci  DBG (7, "usb_low_get_row_resample: exit\n");
2574141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2575141cc406Sopenharmony_ci}
2576141cc406Sopenharmony_ci
2577141cc406Sopenharmony_ciSANE_Status
2578141cc406Sopenharmony_ciusb_low_wait_rowing (ma1017 * chip)
2579141cc406Sopenharmony_ci{
2580141cc406Sopenharmony_ci  SANE_Byte read_byte;
2581141cc406Sopenharmony_ci  size_t n;
2582141cc406Sopenharmony_ci  SANE_Status status;
2583141cc406Sopenharmony_ci
2584141cc406Sopenharmony_ci  DBG (7, "usb_low_wait_rowing: start\n");
2585141cc406Sopenharmony_ci
2586141cc406Sopenharmony_ci  if (!chip->is_opened)
2587141cc406Sopenharmony_ci    {
2588141cc406Sopenharmony_ci      DBG (3, "usb_low_wait_rowing: open first\n");
2589141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2590141cc406Sopenharmony_ci    }
2591141cc406Sopenharmony_ci  if (!chip->is_rowing)
2592141cc406Sopenharmony_ci    {
2593141cc406Sopenharmony_ci      DBG (3, "usb_low_wait_rowing: not rowing\n");
2594141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2595141cc406Sopenharmony_ci    }
2596141cc406Sopenharmony_ci  n = 1;
2597141cc406Sopenharmony_ci  status = sanei_usb_read_bulk (chip->fd, (SANE_Byte *) & read_byte, &n);
2598141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD || n != 1)
2599141cc406Sopenharmony_ci    {
2600141cc406Sopenharmony_ci      DBG (3, "usb_low_wait_rowing: couldn't read: %s\n",
2601141cc406Sopenharmony_ci	   sane_strstatus (status));
2602141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
2603141cc406Sopenharmony_ci    }
2604141cc406Sopenharmony_ci  chip->total_read_urbs++;
2605141cc406Sopenharmony_ci  chip->is_rowing = SANE_FALSE;
2606141cc406Sopenharmony_ci  DBG (7, "usb_low_wait_rowing: exit\n");
2607141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2608141cc406Sopenharmony_ci}
2609141cc406Sopenharmony_ci
2610141cc406Sopenharmony_ciSANE_Status
2611141cc406Sopenharmony_ciusb_low_read_rows (ma1017 * chip, SANE_Byte * data, SANE_Word byte_count)
2612141cc406Sopenharmony_ci{
2613141cc406Sopenharmony_ci  size_t n, bytes_total;
2614141cc406Sopenharmony_ci  SANE_Status status;
2615141cc406Sopenharmony_ci
2616141cc406Sopenharmony_ci  DBG (7, "usb_low_read_rows: start\n");
2617141cc406Sopenharmony_ci  if (!(chip->is_opened))
2618141cc406Sopenharmony_ci    {
2619141cc406Sopenharmony_ci      DBG (3, "usb_low_read_rows: is_opened==SANE_FALSE\n");
2620141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2621141cc406Sopenharmony_ci    }
2622141cc406Sopenharmony_ci  if (!(chip->is_rowing))
2623141cc406Sopenharmony_ci    {
2624141cc406Sopenharmony_ci      DBG (3, "usb_low_read_rows: is_rowing==SANE_FALSE\n");
2625141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2626141cc406Sopenharmony_ci    }
2627141cc406Sopenharmony_ci
2628141cc406Sopenharmony_ci  n = MIN (byte_count, chip->max_block_size);
2629141cc406Sopenharmony_ci  bytes_total = 0;
2630141cc406Sopenharmony_ci
2631141cc406Sopenharmony_ci  while ((SANE_Word) bytes_total < byte_count)
2632141cc406Sopenharmony_ci    {
2633141cc406Sopenharmony_ci      status =
2634141cc406Sopenharmony_ci	sanei_usb_read_bulk (chip->fd, (SANE_Byte *) (data + bytes_total),
2635141cc406Sopenharmony_ci			     &n);
2636141cc406Sopenharmony_ci      if (status != SANE_STATUS_GOOD)
2637141cc406Sopenharmony_ci	{
2638141cc406Sopenharmony_ci	  DBG (7, "usb_low_read_rows: problems during read: %s -- exiting\n",
2639141cc406Sopenharmony_ci	       sane_strstatus (status));
2640141cc406Sopenharmony_ci	  return status;
2641141cc406Sopenharmony_ci	}
2642141cc406Sopenharmony_ci      /* Count the number of URBs. This is a bit tricky, as we are reading
2643141cc406Sopenharmony_ci	 bigger chunks here but the scanner can only handle 64 bytes at once. */
2644141cc406Sopenharmony_ci      chip->total_read_urbs += ((n +  63) / 64);
2645141cc406Sopenharmony_ci      bytes_total += n;
2646141cc406Sopenharmony_ci      if ((SANE_Word) bytes_total != byte_count)
2647141cc406Sopenharmony_ci	{
2648141cc406Sopenharmony_ci	  DBG (7, "usb_low_read_rows:  wanted %d, got %d "
2649141cc406Sopenharmony_ci	       "bytes (%d in total) -- retrying\n", byte_count, (SANE_Word) n,
2650141cc406Sopenharmony_ci	       (SANE_Word) bytes_total);
2651141cc406Sopenharmony_ci	}
2652141cc406Sopenharmony_ci      n = MIN ((byte_count - (SANE_Word) bytes_total), chip->max_block_size);
2653141cc406Sopenharmony_ci    }
2654141cc406Sopenharmony_ci
2655141cc406Sopenharmony_ci  DBG (7, "usb_low_read_rows: exit, read %d bytes\n",
2656141cc406Sopenharmony_ci       (SANE_Word) bytes_total);
2657141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2658141cc406Sopenharmony_ci}
2659141cc406Sopenharmony_ci
2660141cc406Sopenharmony_ci
2661141cc406Sopenharmony_ciSANE_Status
2662141cc406Sopenharmony_ciusb_low_write_reg (ma1017 * chip, SANE_Byte reg_no, SANE_Byte data)
2663141cc406Sopenharmony_ci{
2664141cc406Sopenharmony_ci  size_t n;
2665141cc406Sopenharmony_ci  SANE_Status status;
2666141cc406Sopenharmony_ci  SANE_Byte data_field[2];
2667141cc406Sopenharmony_ci
2668141cc406Sopenharmony_ci  data_field[0] = data;
2669141cc406Sopenharmony_ci  data_field[1] = reg_no;
2670141cc406Sopenharmony_ci
2671141cc406Sopenharmony_ci  if (!chip->is_opened)
2672141cc406Sopenharmony_ci    {
2673141cc406Sopenharmony_ci      DBG (3, "usb_low_write_reg: open first\n");
2674141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2675141cc406Sopenharmony_ci    }
2676141cc406Sopenharmony_ci  if (chip->is_rowing)
2677141cc406Sopenharmony_ci    {
2678141cc406Sopenharmony_ci      DBG (3, "usb_low_write_reg: rowing, stop first\n");
2679141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2680141cc406Sopenharmony_ci    }
2681141cc406Sopenharmony_ci  if (reg_no > 0x20)
2682141cc406Sopenharmony_ci    {
2683141cc406Sopenharmony_ci      DBG (3, "usb_low_write_reg: reg_no out of range\n");
2684141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2685141cc406Sopenharmony_ci    }
2686141cc406Sopenharmony_ci  n = 2;
2687141cc406Sopenharmony_ci  status = sanei_usb_write_bulk (chip->fd, data_field, &n);
2688141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD || n != 2)
2689141cc406Sopenharmony_ci    {
2690141cc406Sopenharmony_ci      DBG (3, "usb_low_write_reg: couldn't write, tried to write %d, "
2691141cc406Sopenharmony_ci	   "wrote %lu: %s\n", 2, (unsigned long int) n,
2692141cc406Sopenharmony_ci	   sane_strstatus (status));
2693141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
2694141cc406Sopenharmony_ci    }
2695141cc406Sopenharmony_ci  chip->total_write_urbs++;
2696141cc406Sopenharmony_ci  DBG (7, "usb_low_write_reg: reg: 0x%02x, value: 0x%02x\n", reg_no, data);
2697141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2698141cc406Sopenharmony_ci}
2699141cc406Sopenharmony_ci
2700141cc406Sopenharmony_ciSANE_Status
2701141cc406Sopenharmony_ciusb_low_read_reg (ma1017 * chip, SANE_Byte reg_no, SANE_Byte * data)
2702141cc406Sopenharmony_ci{
2703141cc406Sopenharmony_ci  SANE_Byte data_field[2];
2704141cc406Sopenharmony_ci  SANE_Byte read_byte;
2705141cc406Sopenharmony_ci  size_t n;
2706141cc406Sopenharmony_ci  SANE_Status status;
2707141cc406Sopenharmony_ci
2708141cc406Sopenharmony_ci  data_field[0] = 0x00;
2709141cc406Sopenharmony_ci  data_field[1] = reg_no | 0x20;
2710141cc406Sopenharmony_ci
2711141cc406Sopenharmony_ci  if (!chip->is_opened)
2712141cc406Sopenharmony_ci    {
2713141cc406Sopenharmony_ci      DBG (3, "usb_low_read_reg: open first\n");
2714141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2715141cc406Sopenharmony_ci    }
2716141cc406Sopenharmony_ci  if (chip->is_rowing)
2717141cc406Sopenharmony_ci    {
2718141cc406Sopenharmony_ci      DBG (3, "usb_low_read_reg: rowing, stop first\n");
2719141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2720141cc406Sopenharmony_ci    }
2721141cc406Sopenharmony_ci  if (reg_no > 0x20)
2722141cc406Sopenharmony_ci    {
2723141cc406Sopenharmony_ci      DBG (3, "usb_low_read_reg: reg_no out of range\n");
2724141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2725141cc406Sopenharmony_ci    }
2726141cc406Sopenharmony_ci  n = 2;
2727141cc406Sopenharmony_ci  DBG (5, "usb_low_read_reg: trying to write %lu bytes\n", (unsigned long int) n);
2728141cc406Sopenharmony_ci
2729141cc406Sopenharmony_ci  status = sanei_usb_write_bulk (chip->fd, data_field, &n);
2730141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD || n != 2)
2731141cc406Sopenharmony_ci    {
2732141cc406Sopenharmony_ci      DBG (3, "usb_low_read_reg: couldn't write, tried to write %d, "
2733141cc406Sopenharmony_ci	   "wrote %lu: %s\n", 2, (unsigned long int) n,
2734141cc406Sopenharmony_ci	   sane_strstatus (status));
2735141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
2736141cc406Sopenharmony_ci    }
2737141cc406Sopenharmony_ci  chip->total_write_urbs++;
2738141cc406Sopenharmony_ci  n = 1;
2739141cc406Sopenharmony_ci  DBG (5, "usb_low_read_reg: trying to read %lu bytes\n", (unsigned long int) n);
2740141cc406Sopenharmony_ci  status = sanei_usb_read_bulk (chip->fd, (SANE_Byte *) & read_byte, &n);
2741141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD || n != 1)
2742141cc406Sopenharmony_ci    {
2743141cc406Sopenharmony_ci      DBG (3, "usb_low_read_reg: couldn't read, tried to read %lu, "
2744141cc406Sopenharmony_ci	   "read %lu: %s\n", (unsigned long int) 1,
2745141cc406Sopenharmony_ci	   (unsigned long int) n, sane_strstatus (status));
2746141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
2747141cc406Sopenharmony_ci    }
2748141cc406Sopenharmony_ci  chip->total_read_urbs++;
2749141cc406Sopenharmony_ci  if (data)
2750141cc406Sopenharmony_ci    *data = read_byte;
2751141cc406Sopenharmony_ci  DBG (7, "usb_low_read_reg: Reg: 0x%02x, Value: 0x%02x\n",
2752141cc406Sopenharmony_ci       reg_no, read_byte);
2753141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2754141cc406Sopenharmony_ci}
2755141cc406Sopenharmony_ci
2756141cc406Sopenharmony_ciSANE_Status
2757141cc406Sopenharmony_ciusb_low_identify_scanner (SANE_Int fd, Mustek_Type * scanner_type)
2758141cc406Sopenharmony_ci{
2759141cc406Sopenharmony_ci  SANE_Status status;
2760141cc406Sopenharmony_ci  SANE_Word devvendor, devproduct;
2761141cc406Sopenharmony_ci  Mustek_Type devtype;
2762141cc406Sopenharmony_ci
2763141cc406Sopenharmony_ci  DBG (7, "usb_low_identify_scanner: start\n");
2764141cc406Sopenharmony_ci
2765141cc406Sopenharmony_ci  status = sanei_usb_get_vendor_product (fd, &devvendor, &devproduct);
2766141cc406Sopenharmony_ci  devtype = MT_UNKNOWN;
2767141cc406Sopenharmony_ci  if (status == SANE_STATUS_GOOD)
2768141cc406Sopenharmony_ci    {
2769141cc406Sopenharmony_ci      if (devvendor == 0x055f)
2770141cc406Sopenharmony_ci	{
2771141cc406Sopenharmony_ci	  switch (devproduct)
2772141cc406Sopenharmony_ci	    {
2773141cc406Sopenharmony_ci	    case 0x0001:
2774141cc406Sopenharmony_ci	      devtype = MT_1200CU;
2775141cc406Sopenharmony_ci	      break;
2776141cc406Sopenharmony_ci	    case 0x0002:
2777141cc406Sopenharmony_ci	      devtype = MT_600CU;
2778141cc406Sopenharmony_ci	      break;
2779141cc406Sopenharmony_ci	    case 0x0003:
2780141cc406Sopenharmony_ci	      devtype = MT_1200USB;
2781141cc406Sopenharmony_ci	      break;
2782141cc406Sopenharmony_ci	    case 0x0006:
2783141cc406Sopenharmony_ci	      devtype = MT_1200UB;
2784141cc406Sopenharmony_ci	      break;
2785141cc406Sopenharmony_ci	    case 0x0008:
2786141cc406Sopenharmony_ci	      devtype = MT_1200CU_PLUS;
2787141cc406Sopenharmony_ci	      break;
2788141cc406Sopenharmony_ci	    case 0x0873:
2789141cc406Sopenharmony_ci	      devtype = MT_600USB;
2790141cc406Sopenharmony_ci	      break;
2791141cc406Sopenharmony_ci	    default:
2792141cc406Sopenharmony_ci	      if (scanner_type)
2793141cc406Sopenharmony_ci		*scanner_type = devtype;
2794141cc406Sopenharmony_ci	      DBG (3, "usb_low_identify_scanner: unknown product id: "
2795141cc406Sopenharmony_ci		   "0x%04x\n", devproduct);
2796141cc406Sopenharmony_ci	      return SANE_STATUS_INVAL;
2797141cc406Sopenharmony_ci	      break;
2798141cc406Sopenharmony_ci	    }
2799141cc406Sopenharmony_ci	}
2800141cc406Sopenharmony_ci      else
2801141cc406Sopenharmony_ci	{
2802141cc406Sopenharmony_ci	  if (scanner_type)
2803141cc406Sopenharmony_ci	    *scanner_type = devtype;
2804141cc406Sopenharmony_ci	  DBG (3, "usb_low_identify_scanner: unknown vendor id: 0x%04d\n",
2805141cc406Sopenharmony_ci	       devvendor);
2806141cc406Sopenharmony_ci	  return SANE_STATUS_INVAL;
2807141cc406Sopenharmony_ci	}
2808141cc406Sopenharmony_ci    }
2809141cc406Sopenharmony_ci  if (scanner_type)
2810141cc406Sopenharmony_ci    *scanner_type = devtype;
2811141cc406Sopenharmony_ci  DBG (7, "usb_low_identify_scanner: exit\n");
2812141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2813141cc406Sopenharmony_ci}
2814141cc406Sopenharmony_ci
2815141cc406Sopenharmony_ciSANE_Status
2816141cc406Sopenharmony_ciusb_low_open (ma1017 * chip, SANE_String_Const devname)
2817141cc406Sopenharmony_ci{
2818141cc406Sopenharmony_ci  SANE_Status status;
2819141cc406Sopenharmony_ci  Mustek_Type scanner_type;
2820141cc406Sopenharmony_ci
2821141cc406Sopenharmony_ci  DBG (7, "usb_low_open: start: chip = %p\n", (void *) chip);
2822141cc406Sopenharmony_ci
2823141cc406Sopenharmony_ci  if (chip->is_rowing)
2824141cc406Sopenharmony_ci    {
2825141cc406Sopenharmony_ci      DBG (3, "usb_low_open: already rowing\n");
2826141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2827141cc406Sopenharmony_ci    }
2828141cc406Sopenharmony_ci  if (chip->is_opened)
2829141cc406Sopenharmony_ci    {
2830141cc406Sopenharmony_ci      DBG (3, "usb_low_open: already opened\n");
2831141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2832141cc406Sopenharmony_ci    }
2833141cc406Sopenharmony_ci
2834141cc406Sopenharmony_ci  status = sanei_usb_open ((SANE_String_Const) devname, &chip->fd);
2835141cc406Sopenharmony_ci
2836141cc406Sopenharmony_ci  if (status == SANE_STATUS_GOOD)
2837141cc406Sopenharmony_ci    {
2838141cc406Sopenharmony_ci      DBG (7, "usb_low_open: device %s successfully opened\n", devname);
2839141cc406Sopenharmony_ci      chip->is_opened = SANE_TRUE;
2840141cc406Sopenharmony_ci      /* Try to get vendor and device ids */
2841141cc406Sopenharmony_ci      DBG (7, "usb_low_open: trying to identify device `%s'\n", devname);
2842141cc406Sopenharmony_ci      status = usb_low_identify_scanner (chip->fd, &scanner_type);
2843141cc406Sopenharmony_ci      if (status != SANE_STATUS_GOOD)
2844141cc406Sopenharmony_ci	{
2845141cc406Sopenharmony_ci	  DBG (3, "usb_low_open: device `%s' doesn't look like a supported "
2846141cc406Sopenharmony_ci	       "scanner\n", devname);
2847141cc406Sopenharmony_ci	  sanei_usb_close (chip->fd);
2848141cc406Sopenharmony_ci	  return status;
2849141cc406Sopenharmony_ci	}
2850141cc406Sopenharmony_ci      else
2851141cc406Sopenharmony_ci	{
2852141cc406Sopenharmony_ci	  if (scanner_type == MT_UNKNOWN)
2853141cc406Sopenharmony_ci	    {
2854141cc406Sopenharmony_ci	      DBG (3, "usb_low_open: device `%s' can't be identified\n",
2855141cc406Sopenharmony_ci		   devname);
2856141cc406Sopenharmony_ci	    }
2857141cc406Sopenharmony_ci	  else if (scanner_type != chip->scanner_type)
2858141cc406Sopenharmony_ci	    {
2859141cc406Sopenharmony_ci	      DBG (3, "usb_low_open: device `%s' is supported but"
2860141cc406Sopenharmony_ci		   "it's not the same as at the start\n", devname);
2861141cc406Sopenharmony_ci	      return SANE_STATUS_INVAL;
2862141cc406Sopenharmony_ci	    }
2863141cc406Sopenharmony_ci	}
2864141cc406Sopenharmony_ci    }
2865141cc406Sopenharmony_ci  else
2866141cc406Sopenharmony_ci    {
2867141cc406Sopenharmony_ci      DBG (1, "usb_low_open: device %s couldn't be opened: %s\n",
2868141cc406Sopenharmony_ci	   devname, sane_strstatus (status));
2869141cc406Sopenharmony_ci      return status;
2870141cc406Sopenharmony_ci    }
2871141cc406Sopenharmony_ci
2872141cc406Sopenharmony_ci  chip->is_opened = SANE_TRUE;
2873141cc406Sopenharmony_ci
2874141cc406Sopenharmony_ci  RIE (usb_low_read_all_registers (chip));
2875141cc406Sopenharmony_ci
2876141cc406Sopenharmony_ci  DBG (7, "usb_low_open: exit, type is %d\n", scanner_type);
2877141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2878141cc406Sopenharmony_ci}
2879141cc406Sopenharmony_ci
2880141cc406Sopenharmony_ciSANE_Status
2881141cc406Sopenharmony_ciusb_low_close (ma1017 * chip)
2882141cc406Sopenharmony_ci{
2883141cc406Sopenharmony_ci  DBG (7, "usb_low_close: start, chip=%p\n", (void *) chip);
2884141cc406Sopenharmony_ci  if (!chip->is_opened)
2885141cc406Sopenharmony_ci    {
2886141cc406Sopenharmony_ci      DBG (3, "usb_low_close: already close or never opened\n");
2887141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2888141cc406Sopenharmony_ci    }
2889141cc406Sopenharmony_ci
2890141cc406Sopenharmony_ci  if (chip->fd >= 0)
2891141cc406Sopenharmony_ci    {
2892141cc406Sopenharmony_ci      SANE_Byte dummy;
2893141cc406Sopenharmony_ci
2894141cc406Sopenharmony_ci      if (chip->is_rowing)
2895141cc406Sopenharmony_ci	usb_low_stop_rowing (chip);
2896141cc406Sopenharmony_ci      /* Now make sure that both the number of written and
2897141cc406Sopenharmony_ci	 read URBs is even. Use some dummy writes/reads. That's to avoid
2898141cc406Sopenharmony_ci	 a nasty bug in the MA 1017 chipset that causes timeouts when
2899141cc406Sopenharmony_ci	 the number of URBs is odd (toggle bug). */
2900141cc406Sopenharmony_ci      if ((chip->total_read_urbs % 2) == 1)
2901141cc406Sopenharmony_ci	usb_low_get_a4 (chip, &dummy);
2902141cc406Sopenharmony_ci      if ((chip->total_write_urbs % 2) == 1)
2903141cc406Sopenharmony_ci	usb_low_set_fix_pattern (chip, SANE_FALSE);
2904141cc406Sopenharmony_ci      sanei_usb_close (chip->fd);
2905141cc406Sopenharmony_ci      chip->fd = -1;
2906141cc406Sopenharmony_ci    }
2907141cc406Sopenharmony_ci  chip->is_opened = SANE_FALSE;
2908141cc406Sopenharmony_ci  chip->is_rowing = SANE_FALSE;
2909141cc406Sopenharmony_ci
2910141cc406Sopenharmony_ci  DBG (7, "usb_low_close: exit\n");
2911141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2912141cc406Sopenharmony_ci}
2913