1141cc406Sopenharmony_ci/* lexmark-low.c: scanner-interface file for low Lexmark scanners.
2141cc406Sopenharmony_ci
3141cc406Sopenharmony_ci   (C) 2005 Fred Odendaal
4141cc406Sopenharmony_ci   (C) 2006-2013 Stéphane Voltz	<stef.dev@free.fr>
5141cc406Sopenharmony_ci   (C) 2010 "Torsten Houwaart" <ToHo@gmx.de> X74 support
6141cc406Sopenharmony_ci
7141cc406Sopenharmony_ci   This file is part of the SANE package.
8141cc406Sopenharmony_ci
9141cc406Sopenharmony_ci   This program is free software; you can redistribute it and/or
10141cc406Sopenharmony_ci   modify it under the terms of the GNU General Public License as
11141cc406Sopenharmony_ci   published by the Free Software Foundation; either version 2 of the
12141cc406Sopenharmony_ci   License, or (at your option) any later version.
13141cc406Sopenharmony_ci
14141cc406Sopenharmony_ci   This program is distributed in the hope that it will be useful, but
15141cc406Sopenharmony_ci   WITHOUT ANY WARRANTY; without even the implied warranty of
16141cc406Sopenharmony_ci   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17141cc406Sopenharmony_ci   General Public License for more details.
18141cc406Sopenharmony_ci
19141cc406Sopenharmony_ci   You should have received a copy of the GNU General Public License
20141cc406Sopenharmony_ci   along with this program.  If not, see <https://www.gnu.org/licenses/>.
21141cc406Sopenharmony_ci
22141cc406Sopenharmony_ci   As a special exception, the authors of SANE give permission for
23141cc406Sopenharmony_ci   additional uses of the libraries contained in this release of SANE.
24141cc406Sopenharmony_ci
25141cc406Sopenharmony_ci   The exception is that, if you link a SANE library with other files
26141cc406Sopenharmony_ci   to produce an executable, this does not by itself cause the
27141cc406Sopenharmony_ci   resulting executable to be covered by the GNU General Public
28141cc406Sopenharmony_ci   License.  Your use of that executable is in no way restricted on
29141cc406Sopenharmony_ci   account of linking the SANE library code into it.
30141cc406Sopenharmony_ci
31141cc406Sopenharmony_ci   This exception does not, however, invalidate any other reasons why
32141cc406Sopenharmony_ci   the executable file might be covered by the GNU General Public
33141cc406Sopenharmony_ci   License.
34141cc406Sopenharmony_ci
35141cc406Sopenharmony_ci   If you submit changes to SANE to the maintainers to be included in
36141cc406Sopenharmony_ci   a subsequent release, you agree by submitting the changes that
37141cc406Sopenharmony_ci   those changes may be distributed with this exception intact.
38141cc406Sopenharmony_ci
39141cc406Sopenharmony_ci   If you write modifications of your own for SANE, it is your choice
40141cc406Sopenharmony_ci   whether to permit this exception to apply to your modifications.
41141cc406Sopenharmony_ci   If you do not wish that, delete this exception notice.
42141cc406Sopenharmony_ci
43141cc406Sopenharmony_ci   **************************************************************************/
44141cc406Sopenharmony_ci
45141cc406Sopenharmony_ci#undef BACKEND_NAME
46141cc406Sopenharmony_ci#define BACKEND_NAME lexmark_low
47141cc406Sopenharmony_ci
48141cc406Sopenharmony_ci#include "lexmark.h"
49141cc406Sopenharmony_ci
50141cc406Sopenharmony_ci#include "lexmark_sensors.c"
51141cc406Sopenharmony_ci#include "lexmark_models.c"
52141cc406Sopenharmony_ci
53141cc406Sopenharmony_ci/* numbre of ranges for offset */
54141cc406Sopenharmony_ci#define OFFSET_RANGES 5
55141cc406Sopenharmony_ci
56141cc406Sopenharmony_citypedef enum
57141cc406Sopenharmony_ci{
58141cc406Sopenharmony_ci  black = 0,
59141cc406Sopenharmony_ci  white
60141cc406Sopenharmony_ci}
61141cc406Sopenharmony_ciregion_type;
62141cc406Sopenharmony_ci
63141cc406Sopenharmony_ci#define HomeTolerance 32
64141cc406Sopenharmony_ci
65141cc406Sopenharmony_ci
66141cc406Sopenharmony_ci#define LOBYTE(x)  ((uint8_t)((x) & 0xFF))
67141cc406Sopenharmony_ci#define HIBYTE(x)  ((uint8_t)((x) >> 8))
68141cc406Sopenharmony_ci
69141cc406Sopenharmony_ci/* Static low function proto-types */
70141cc406Sopenharmony_cistatic SANE_Status low_usb_bulk_write (SANE_Int devnum,
71141cc406Sopenharmony_ci				       SANE_Byte * cmd, size_t * size);
72141cc406Sopenharmony_cistatic SANE_Status low_usb_bulk_read (SANE_Int devnum,
73141cc406Sopenharmony_ci				      SANE_Byte * buf, size_t * size);
74141cc406Sopenharmony_cistatic SANE_Status low_write_all_regs (SANE_Int devnum, SANE_Byte * regs);
75141cc406Sopenharmony_cistatic SANE_Bool low_is_home_line (Lexmark_Device * dev,
76141cc406Sopenharmony_ci				   unsigned char *buffer);
77141cc406Sopenharmony_cistatic SANE_Status low_get_start_loc (SANE_Int resolution,
78141cc406Sopenharmony_ci				      SANE_Int * vert_start,
79141cc406Sopenharmony_ci				      SANE_Int * hor_start, SANE_Int offset,
80141cc406Sopenharmony_ci				      Lexmark_Device * dev);
81141cc406Sopenharmony_cistatic void low_rewind (Lexmark_Device * dev, SANE_Byte * regs);
82141cc406Sopenharmony_cistatic SANE_Status low_start_mvmt (SANE_Int devnum);
83141cc406Sopenharmony_cistatic SANE_Status low_stop_mvmt (SANE_Int devnum);
84141cc406Sopenharmony_cistatic SANE_Status low_clr_c6 (SANE_Int devnum);
85141cc406Sopenharmony_cistatic SANE_Status low_simple_scan (Lexmark_Device * dev,
86141cc406Sopenharmony_ci				    SANE_Byte * regs,
87141cc406Sopenharmony_ci				    int xoffset,
88141cc406Sopenharmony_ci				    int pixels,
89141cc406Sopenharmony_ci				    int yoffset,
90141cc406Sopenharmony_ci				    int lines, SANE_Byte ** data);
91141cc406Sopenharmony_cistatic void low_set_scan_area (SANE_Int res,
92141cc406Sopenharmony_ci			       SANE_Int tlx,
93141cc406Sopenharmony_ci			       SANE_Int tly,
94141cc406Sopenharmony_ci			       SANE_Int brx,
95141cc406Sopenharmony_ci			       SANE_Int bry,
96141cc406Sopenharmony_ci			       SANE_Int offset,
97141cc406Sopenharmony_ci			       SANE_Bool half_step,
98141cc406Sopenharmony_ci			       SANE_Byte * regs, Lexmark_Device * dev);
99141cc406Sopenharmony_ci
100141cc406Sopenharmony_ci/* Static Read Buffer Proto-types */
101141cc406Sopenharmony_cistatic SANE_Status read_buffer_init (Lexmark_Device * dev, int bytesperline);
102141cc406Sopenharmony_cistatic SANE_Status read_buffer_free (Read_Buffer * rb);
103141cc406Sopenharmony_cistatic size_t read_buffer_bytes_available (Read_Buffer * rb);
104141cc406Sopenharmony_cistatic SANE_Status read_buffer_add_byte (Read_Buffer * rb,
105141cc406Sopenharmony_ci					 SANE_Byte * byte_pointer);
106141cc406Sopenharmony_cistatic SANE_Status read_buffer_add_byte_gray (Read_Buffer * rb,
107141cc406Sopenharmony_ci					      SANE_Byte * byte_pointer);
108141cc406Sopenharmony_cistatic SANE_Status read_buffer_add_bit_lineart (Read_Buffer * rb,
109141cc406Sopenharmony_ci						SANE_Byte * byte_pointer,
110141cc406Sopenharmony_ci						SANE_Byte threshold);
111141cc406Sopenharmony_cistatic size_t read_buffer_get_bytes (Read_Buffer * rb, SANE_Byte * buffer,
112141cc406Sopenharmony_ci				     size_t rqst_size);
113141cc406Sopenharmony_cistatic SANE_Bool read_buffer_is_empty (Read_Buffer * rb);
114141cc406Sopenharmony_ci
115141cc406Sopenharmony_ci
116141cc406Sopenharmony_ci/*
117141cc406Sopenharmony_ci *         RTS88XX	START
118141cc406Sopenharmony_ci *
119141cc406Sopenharmony_ci *         these rts88xx functions will be spin off in a separate lib
120141cc406Sopenharmony_ci *         so that they can be reused.
121141cc406Sopenharmony_ci */
122141cc406Sopenharmony_ci
123141cc406Sopenharmony_ci/*
124141cc406Sopenharmony_ci * registers helpers to avoid direct access
125141cc406Sopenharmony_ci */
126141cc406Sopenharmony_cistatic SANE_Bool
127141cc406Sopenharmony_cirts88xx_is_color (SANE_Byte * regs)
128141cc406Sopenharmony_ci{
129141cc406Sopenharmony_ci  if ((regs[0x2f] & 0x11) == 0x11)
130141cc406Sopenharmony_ci    return SANE_TRUE;
131141cc406Sopenharmony_ci  return SANE_FALSE;
132141cc406Sopenharmony_ci}
133141cc406Sopenharmony_ci
134141cc406Sopenharmony_cistatic void
135141cc406Sopenharmony_cirts88xx_set_gray_scan (SANE_Byte * regs)
136141cc406Sopenharmony_ci{
137141cc406Sopenharmony_ci  regs[0x2f] = (regs[0x2f] & 0x0f) | 0x20;
138141cc406Sopenharmony_ci}
139141cc406Sopenharmony_ci
140141cc406Sopenharmony_ci#if 0
141141cc406Sopenharmony_cistatic void
142141cc406Sopenharmony_cirts88xx_set_color_scan (SANE_Byte * regs)
143141cc406Sopenharmony_ci{
144141cc406Sopenharmony_ci  regs[0x2f] = (regs[0x2f] & 0x0f) | 0x10;
145141cc406Sopenharmony_ci}
146141cc406Sopenharmony_ci#endif
147141cc406Sopenharmony_ci
148141cc406Sopenharmony_cistatic void
149141cc406Sopenharmony_cirts88xx_set_offset (SANE_Byte * regs, SANE_Byte red, SANE_Byte green,
150141cc406Sopenharmony_ci		    SANE_Byte blue)
151141cc406Sopenharmony_ci{
152141cc406Sopenharmony_ci  /* offset for odd pixels */
153141cc406Sopenharmony_ci  regs[0x02] = red;
154141cc406Sopenharmony_ci  regs[0x03] = green;
155141cc406Sopenharmony_ci  regs[0x04] = blue;
156141cc406Sopenharmony_ci
157141cc406Sopenharmony_ci  /* offset for even pixels */
158141cc406Sopenharmony_ci  regs[0x05] = red;
159141cc406Sopenharmony_ci  regs[0x06] = green;
160141cc406Sopenharmony_ci  regs[0x07] = blue;
161141cc406Sopenharmony_ci}
162141cc406Sopenharmony_ci
163141cc406Sopenharmony_cistatic void
164141cc406Sopenharmony_cirts88xx_set_gain (SANE_Byte * regs, SANE_Byte red, SANE_Byte green,
165141cc406Sopenharmony_ci		  SANE_Byte blue)
166141cc406Sopenharmony_ci{
167141cc406Sopenharmony_ci  regs[0x08] = red;
168141cc406Sopenharmony_ci  regs[0x09] = green;
169141cc406Sopenharmony_ci  regs[0x0a] = blue;
170141cc406Sopenharmony_ci}
171141cc406Sopenharmony_ci
172141cc406Sopenharmony_ci/* set # of head moves per CIS read */
173141cc406Sopenharmony_cistatic int
174141cc406Sopenharmony_cirts88xx_set_scan_frequency (SANE_Byte * regs, int frequency)
175141cc406Sopenharmony_ci{
176141cc406Sopenharmony_ci  regs[0x64] = (regs[0x64] & 0xf0) | (frequency & 0x0f);
177141cc406Sopenharmony_ci  return 0;
178141cc406Sopenharmony_ci}
179141cc406Sopenharmony_ci
180141cc406Sopenharmony_ci/*
181141cc406Sopenharmony_ci * read one register at given index
182141cc406Sopenharmony_ci */
183141cc406Sopenharmony_cistatic SANE_Status
184141cc406Sopenharmony_cirts88xx_read_reg (SANE_Int devnum, SANE_Int index, SANE_Byte * reg)
185141cc406Sopenharmony_ci{
186141cc406Sopenharmony_ci  SANE_Status status = SANE_STATUS_GOOD;
187141cc406Sopenharmony_ci  unsigned char cmd[] = { 0x80, 0x00, 0x00, 0x01 };
188141cc406Sopenharmony_ci  size_t size;
189141cc406Sopenharmony_ci
190141cc406Sopenharmony_ci  cmd[1] = index;
191141cc406Sopenharmony_ci
192141cc406Sopenharmony_ci  size = 4;
193141cc406Sopenharmony_ci#ifdef FAKE_USB
194141cc406Sopenharmony_ci  status = SANE_STATUS_GOOD;
195141cc406Sopenharmony_ci#else
196141cc406Sopenharmony_ci  status = sanei_usb_write_bulk (devnum, cmd, &size);
197141cc406Sopenharmony_ci#endif
198141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
199141cc406Sopenharmony_ci    {
200141cc406Sopenharmony_ci      DBG (5, "rts88xx_read_reg: bulk write failed\n");
201141cc406Sopenharmony_ci      return status;
202141cc406Sopenharmony_ci    }
203141cc406Sopenharmony_ci  size = 1;
204141cc406Sopenharmony_ci#ifdef FAKE_USB
205141cc406Sopenharmony_ci  status = SANE_STATUS_GOOD;
206141cc406Sopenharmony_ci#else
207141cc406Sopenharmony_ci  status = sanei_usb_read_bulk (devnum, reg, &size);
208141cc406Sopenharmony_ci#endif
209141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
210141cc406Sopenharmony_ci    {
211141cc406Sopenharmony_ci      DBG (5, "rts88xx_read_reg: bulk read failed\n");
212141cc406Sopenharmony_ci      return status;
213141cc406Sopenharmony_ci    }
214141cc406Sopenharmony_ci  DBG (15, "rts88xx_read_reg: reg[0x%02x]=0x%02x\n", index, *reg);
215141cc406Sopenharmony_ci  return status;
216141cc406Sopenharmony_ci}
217141cc406Sopenharmony_ci
218141cc406Sopenharmony_ci/*
219141cc406Sopenharmony_ci * write one register at given index
220141cc406Sopenharmony_ci */
221141cc406Sopenharmony_cistatic SANE_Status
222141cc406Sopenharmony_cirts88xx_write_reg (SANE_Int devnum, SANE_Int index, SANE_Byte * reg)
223141cc406Sopenharmony_ci{
224141cc406Sopenharmony_ci  SANE_Status status = SANE_STATUS_GOOD;
225141cc406Sopenharmony_ci  unsigned char cmd[] = { 0x88, 0x00, 0x00, 0x01 };
226141cc406Sopenharmony_ci  size_t size;
227141cc406Sopenharmony_ci
228141cc406Sopenharmony_ci  cmd[1] = index;
229141cc406Sopenharmony_ci
230141cc406Sopenharmony_ci  size = 4;
231141cc406Sopenharmony_ci#ifdef FAKE_USB
232141cc406Sopenharmony_ci  status = SANE_STATUS_GOOD;
233141cc406Sopenharmony_ci#else
234141cc406Sopenharmony_ci  status = sanei_usb_write_bulk (devnum, cmd, &size);
235141cc406Sopenharmony_ci#endif
236141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
237141cc406Sopenharmony_ci    {
238141cc406Sopenharmony_ci      DBG (5, "rts88xx_write_reg: bulk write failed\n");
239141cc406Sopenharmony_ci      return status;
240141cc406Sopenharmony_ci    }
241141cc406Sopenharmony_ci  size = 1;
242141cc406Sopenharmony_ci#ifdef FAKE_USB
243141cc406Sopenharmony_ci  status = SANE_STATUS_GOOD;
244141cc406Sopenharmony_ci#else
245141cc406Sopenharmony_ci  status = sanei_usb_write_bulk (devnum, reg, &size);
246141cc406Sopenharmony_ci#endif
247141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
248141cc406Sopenharmony_ci    {
249141cc406Sopenharmony_ci      DBG (5, "rts88xx_write_reg: bulk write failed\n");
250141cc406Sopenharmony_ci      return status;
251141cc406Sopenharmony_ci    }
252141cc406Sopenharmony_ci  DBG (15, "rts88xx_write_reg: reg[0x%02x]=0x%02x\n", index, *reg);
253141cc406Sopenharmony_ci  return status;
254141cc406Sopenharmony_ci}
255141cc406Sopenharmony_ci
256141cc406Sopenharmony_ci/*
257141cc406Sopenharmony_ci * write length consecutive registers, starting at index
258141cc406Sopenharmony_ci * register 0xb3 is never wrote in bulk register write, so we split
259141cc406Sopenharmony_ci * write if it belongs to the register set sent
260141cc406Sopenharmony_ci */
261141cc406Sopenharmony_cistatic SANE_Status
262141cc406Sopenharmony_cirts88xx_write_regs (SANE_Int devnum, SANE_Int start, SANE_Byte * source,
263141cc406Sopenharmony_ci		    SANE_Int length)
264141cc406Sopenharmony_ci{
265141cc406Sopenharmony_ci  size_t size = 0;
266141cc406Sopenharmony_ci
267141cc406Sopenharmony_ci  /* when writing several registers at a time, we avoid writing 0xb3
268141cc406Sopenharmony_ci     register */
269141cc406Sopenharmony_ci  if ((start + length > 0xb3) && (length > 1))
270141cc406Sopenharmony_ci    {
271141cc406Sopenharmony_ci      size = 0xb3 - start;
272141cc406Sopenharmony_ci      if (low_usb_bulk_write (devnum, source, &size) != SANE_STATUS_GOOD)
273141cc406Sopenharmony_ci	{
274141cc406Sopenharmony_ci	  DBG (5, "rts88xx_write_regs : write registers part 1 failed ...\n");
275141cc406Sopenharmony_ci	  return SANE_STATUS_IO_ERROR;
276141cc406Sopenharmony_ci	}
277141cc406Sopenharmony_ci
278141cc406Sopenharmony_ci      /* skip 0xB3 register */
279141cc406Sopenharmony_ci      size++;
280141cc406Sopenharmony_ci      start = 0xb4;
281141cc406Sopenharmony_ci      source = source + size;
282141cc406Sopenharmony_ci    }
283141cc406Sopenharmony_ci  size = length - size;
284141cc406Sopenharmony_ci  if (low_usb_bulk_write (devnum, source, &size) != SANE_STATUS_GOOD)
285141cc406Sopenharmony_ci    {
286141cc406Sopenharmony_ci      DBG (5, "rts88xx_write_regs : write registers part 2 failed ...\n");
287141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
288141cc406Sopenharmony_ci    }
289141cc406Sopenharmony_ci
290141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
291141cc406Sopenharmony_ci
292141cc406Sopenharmony_ci}
293141cc406Sopenharmony_ci
294141cc406Sopenharmony_ci/*
295141cc406Sopenharmony_ci * reads 'needed' bytes of scanned data into 'data'. Actual number of bytes get
296141cc406Sopenharmony_ci * is returned in 'size'
297141cc406Sopenharmony_ci */
298141cc406Sopenharmony_cistatic SANE_Status
299141cc406Sopenharmony_cirts88xx_read_data (SANE_Int devnum, size_t needed, SANE_Byte * data,
300141cc406Sopenharmony_ci		   size_t * size)
301141cc406Sopenharmony_ci{
302141cc406Sopenharmony_ci  SANE_Byte read_cmd[] = { 0x91, 0x00, 0x00, 0x00 };
303141cc406Sopenharmony_ci  size_t cmd_size;
304141cc406Sopenharmony_ci  SANE_Status status = SANE_STATUS_GOOD;
305141cc406Sopenharmony_ci
306141cc406Sopenharmony_ci  /* this block would deserve to be a function */
307141cc406Sopenharmony_ci  if (needed > MAX_XFER_SIZE)
308141cc406Sopenharmony_ci    *size = MAX_XFER_SIZE;
309141cc406Sopenharmony_ci  else
310141cc406Sopenharmony_ci    *size = needed;
311141cc406Sopenharmony_ci  read_cmd[3] = (*size) & 0xff;
312141cc406Sopenharmony_ci  read_cmd[2] = (*size >> 8) & 0xff;
313141cc406Sopenharmony_ci  read_cmd[1] = (*size >> 16) & 0xff;
314141cc406Sopenharmony_ci
315141cc406Sopenharmony_ci  /* send header for 'get scanned data' */
316141cc406Sopenharmony_ci  cmd_size = 4;
317141cc406Sopenharmony_ci  status = low_usb_bulk_write (devnum, read_cmd, &cmd_size);
318141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
319141cc406Sopenharmony_ci    {
320141cc406Sopenharmony_ci      *size = 0;
321141cc406Sopenharmony_ci      DBG (5, "rts88xx_read_data : header sending failed ...\n");
322141cc406Sopenharmony_ci      return status;
323141cc406Sopenharmony_ci    }
324141cc406Sopenharmony_ci  /* get actual scanned data */
325141cc406Sopenharmony_ci  status = low_usb_bulk_read (devnum, data, size);
326141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
327141cc406Sopenharmony_ci    {
328141cc406Sopenharmony_ci      *size = 0;
329141cc406Sopenharmony_ci      DBG (5, "rts88xx_read_data : data reading failed ...\n");
330141cc406Sopenharmony_ci    }
331141cc406Sopenharmony_ci  return status;
332141cc406Sopenharmony_ci}
333141cc406Sopenharmony_ci
334141cc406Sopenharmony_ci/* starts scan by sending color depth, stopping head, the starting it */
335141cc406Sopenharmony_cistatic SANE_Status
336141cc406Sopenharmony_cirts88xx_commit (SANE_Int devnum, SANE_Byte depth)
337141cc406Sopenharmony_ci{
338141cc406Sopenharmony_ci  SANE_Status status;
339141cc406Sopenharmony_ci  SANE_Byte reg;
340141cc406Sopenharmony_ci
341141cc406Sopenharmony_ci  DBG (2, "rts88xx_commit: start\n");
342141cc406Sopenharmony_ci
343141cc406Sopenharmony_ci  /* send color depth depth ??
344141cc406Sopenharmony_ci   * X1100 -> 0x0f
345141cc406Sopenharmony_ci   * X1100/B2 -> 0x0d
346141cc406Sopenharmony_ci   * X1200 -> 0x01 */
347141cc406Sopenharmony_ci  reg = depth;
348141cc406Sopenharmony_ci  rts88xx_write_reg (devnum, 0x2c, &reg);
349141cc406Sopenharmony_ci
350141cc406Sopenharmony_ci  /* stop before starting */
351141cc406Sopenharmony_ci  low_stop_mvmt (devnum);
352141cc406Sopenharmony_ci
353141cc406Sopenharmony_ci  /* effective start */
354141cc406Sopenharmony_ci  status = low_start_mvmt (devnum);
355141cc406Sopenharmony_ci
356141cc406Sopenharmony_ci  DBG (2, "rts88xx_commit: end\n");
357141cc406Sopenharmony_ci
358141cc406Sopenharmony_ci  return status;
359141cc406Sopenharmony_ci}
360141cc406Sopenharmony_ci
361141cc406Sopenharmony_ci/*
362141cc406Sopenharmony_ci *         RTS88XX     END
363141cc406Sopenharmony_ci */
364141cc406Sopenharmony_ci
365141cc406Sopenharmony_ci
366141cc406Sopenharmony_ci
367141cc406Sopenharmony_ci/*
368141cc406Sopenharmony_ci * sets the scanner idle
369141cc406Sopenharmony_ci */
370141cc406Sopenharmony_cistatic SANE_Status
371141cc406Sopenharmony_cilexmark_low_set_idle (SANE_Int devnum)
372141cc406Sopenharmony_ci{
373141cc406Sopenharmony_ci  SANE_Byte regs[14] =
374141cc406Sopenharmony_ci    { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
375141cc406Sopenharmony_ci    0x00, 0x60
376141cc406Sopenharmony_ci  };
377141cc406Sopenharmony_ci  if (rts88xx_write_regs (devnum, 16, regs, 14) != SANE_STATUS_GOOD)
378141cc406Sopenharmony_ci    {
379141cc406Sopenharmony_ci      DBG (5, "lexmark_low_set_idle : register write failed ...\n");
380141cc406Sopenharmony_ci      return SANE_STATUS_IO_ERROR;
381141cc406Sopenharmony_ci    }
382141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
383141cc406Sopenharmony_ci}
384141cc406Sopenharmony_ci
385141cc406Sopenharmony_ci
386141cc406Sopenharmony_ci/* wake up scanner */
387141cc406Sopenharmony_ci#if 0
388141cc406Sopenharmony_cistatic SANE_Status
389141cc406Sopenharmony_cilexmark_low_wake_up (Lexmark_Device * dev)
390141cc406Sopenharmony_ci{
391141cc406Sopenharmony_ci  SANE_Byte regs[5] = { 0x12, 0x14, 0x16, 0x18, 0x1a };
392141cc406Sopenharmony_ci  SANE_Byte values[5] = { 0x0f, 0x00, 0x07, 0x00, 0x00 };
393141cc406Sopenharmony_ci  int i;
394141cc406Sopenharmony_ci
395141cc406Sopenharmony_ci  /* send the wake-up sequence, one reg at at time */
396141cc406Sopenharmony_ci  for (i = 0; i < 10; i++)
397141cc406Sopenharmony_ci    {
398141cc406Sopenharmony_ci      if (rts88xx_write_reg (dev->devnum, regs[i], values + i) !=
399141cc406Sopenharmony_ci	  SANE_STATUS_GOOD)
400141cc406Sopenharmony_ci	{
401141cc406Sopenharmony_ci	  DBG (5,
402141cc406Sopenharmony_ci	       "lexmark_low_wake_up : register write pass %d failed ...\n",
403141cc406Sopenharmony_ci	       i);
404141cc406Sopenharmony_ci	  return SANE_STATUS_IO_ERROR;
405141cc406Sopenharmony_ci	}
406141cc406Sopenharmony_ci    }
407141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
408141cc406Sopenharmony_ci}
409141cc406Sopenharmony_ci#endif
410141cc406Sopenharmony_ci
411141cc406Sopenharmony_ci
412141cc406Sopenharmony_ci/**
413141cc406Sopenharmony_ci *
414141cc406Sopenharmony_ci */
415141cc406Sopenharmony_ci#ifdef DEEP_DEBUG
416141cc406Sopenharmony_cistatic void
417141cc406Sopenharmony_ciwrite_pnm_file (char *title, int pixels, int lines, int color,
418141cc406Sopenharmony_ci		unsigned char *data)
419141cc406Sopenharmony_ci{
420141cc406Sopenharmony_ci  FILE *fdbg;
421141cc406Sopenharmony_ci  int x, y;
422141cc406Sopenharmony_ci
423141cc406Sopenharmony_ci  fdbg = fopen (title, "wb");
424141cc406Sopenharmony_ci  if (fdbg == NULL)
425141cc406Sopenharmony_ci    return;
426141cc406Sopenharmony_ci
427141cc406Sopenharmony_ci  if (color)
428141cc406Sopenharmony_ci    {
429141cc406Sopenharmony_ci      fprintf (fdbg, "P6\n%d %d\n255\n", pixels, lines);
430141cc406Sopenharmony_ci      for (y = 0; y < lines; y++)
431141cc406Sopenharmony_ci	{
432141cc406Sopenharmony_ci	  for (x = 0; x < pixels; x += 2)
433141cc406Sopenharmony_ci	    {
434141cc406Sopenharmony_ci	      fputc (data[y * pixels * 3 + x + 1], fdbg);
435141cc406Sopenharmony_ci	      fputc (data[y * pixels * 3 + x + 1 + pixels], fdbg);
436141cc406Sopenharmony_ci	      fputc (data[y * pixels * 3 + x + 1 + pixels * 2], fdbg);
437141cc406Sopenharmony_ci	      fputc (data[y * pixels * 3 + x], fdbg);
438141cc406Sopenharmony_ci	      fputc (data[y * pixels * 3 + x + pixels], fdbg);
439141cc406Sopenharmony_ci	      fputc (data[y * pixels * 3 + x + pixels * 2], fdbg);
440141cc406Sopenharmony_ci	    }
441141cc406Sopenharmony_ci	}
442141cc406Sopenharmony_ci    }
443141cc406Sopenharmony_ci  else
444141cc406Sopenharmony_ci    {
445141cc406Sopenharmony_ci      fprintf (fdbg, "P5\n%d %d\n255\n", pixels, lines);
446141cc406Sopenharmony_ci      fwrite (data, pixels, lines, fdbg);
447141cc406Sopenharmony_ci    }
448141cc406Sopenharmony_ci  fclose (fdbg);
449141cc406Sopenharmony_ci}
450141cc406Sopenharmony_ci#endif
451141cc406Sopenharmony_ci
452141cc406Sopenharmony_ci/*
453141cc406Sopenharmony_ci * mid level hardware functions
454141cc406Sopenharmony_ci */
455141cc406Sopenharmony_ci/*
456141cc406Sopenharmony_ci * model init
457141cc406Sopenharmony_ci */
458141cc406Sopenharmony_ciSANE_Status
459141cc406Sopenharmony_cisanei_lexmark_low_init (Lexmark_Device * dev)
460141cc406Sopenharmony_ci{
461141cc406Sopenharmony_ci  int i;
462141cc406Sopenharmony_ci  SANE_Status status;
463141cc406Sopenharmony_ci
464141cc406Sopenharmony_ci  DBG_INIT ();
465141cc406Sopenharmony_ci
466141cc406Sopenharmony_ci  status = SANE_STATUS_UNSUPPORTED;
467141cc406Sopenharmony_ci  DBG (2, "low_init: start\n");
468141cc406Sopenharmony_ci
469141cc406Sopenharmony_ci  /* clear all registers first */
470141cc406Sopenharmony_ci  for (i = 0; i < 255; i++)
471141cc406Sopenharmony_ci    {
472141cc406Sopenharmony_ci      dev->shadow_regs[i] = 0;
473141cc406Sopenharmony_ci    }
474141cc406Sopenharmony_ci
475141cc406Sopenharmony_ci  /* set up per model constant values */
476141cc406Sopenharmony_ci  dev->shadow_regs[0xf3] = 0xf8;
477141cc406Sopenharmony_ci  dev->shadow_regs[0xf4] = 0x7f;
478141cc406Sopenharmony_ci
479141cc406Sopenharmony_ci  switch (dev->model.sensor_type)
480141cc406Sopenharmony_ci    {
481141cc406Sopenharmony_ci    case X74_SENSOR:
482141cc406Sopenharmony_ci      dev->shadow_regs[0x00] = 0x04;
483141cc406Sopenharmony_ci      dev->shadow_regs[0x01] = 0x43;
484141cc406Sopenharmony_ci      dev->shadow_regs[0x0b] = 0x70;
485141cc406Sopenharmony_ci      dev->shadow_regs[0x12] = 0x0f;
486141cc406Sopenharmony_ci      dev->shadow_regs[0x16] = 0x07;
487141cc406Sopenharmony_ci      dev->shadow_regs[0x1d] = 0x20;
488141cc406Sopenharmony_ci      dev->shadow_regs[0x28] = 0xe0;
489141cc406Sopenharmony_ci      dev->shadow_regs[0x29] = 0xe3;
490141cc406Sopenharmony_ci      dev->shadow_regs[0x2a] = 0xeb;
491141cc406Sopenharmony_ci      dev->shadow_regs[0x2b] = 0x0d;
492141cc406Sopenharmony_ci      dev->shadow_regs[0x2e] = 0x40;
493141cc406Sopenharmony_ci      dev->shadow_regs[0x2e] = 0x86;
494141cc406Sopenharmony_ci      dev->shadow_regs[0x2f] = 0x01;
495141cc406Sopenharmony_ci      dev->shadow_regs[0x30] = 0x48;
496141cc406Sopenharmony_ci      dev->shadow_regs[0x31] = 0x06;
497141cc406Sopenharmony_ci      dev->shadow_regs[0x33] = 0x01;
498141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x50;
499141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x01;
500141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x50;
501141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x01;
502141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x50;
503141cc406Sopenharmony_ci      dev->shadow_regs[0x3a] = 0x20;
504141cc406Sopenharmony_ci      dev->shadow_regs[0x3c] = 0x88;
505141cc406Sopenharmony_ci      dev->shadow_regs[0x3d] = 0x08;
506141cc406Sopenharmony_ci      dev->shadow_regs[0x65] = 0x80;
507141cc406Sopenharmony_ci      dev->shadow_regs[0x66] = 0x64;
508141cc406Sopenharmony_ci      dev->shadow_regs[0x6c] = 0xc8;
509141cc406Sopenharmony_ci      dev->shadow_regs[0x72] = 0x1a;
510141cc406Sopenharmony_ci      dev->shadow_regs[0x74] = 0x23;
511141cc406Sopenharmony_ci      dev->shadow_regs[0x75] = 0x03;
512141cc406Sopenharmony_ci      dev->shadow_regs[0x79] = 0x40;
513141cc406Sopenharmony_ci      dev->shadow_regs[0x7A] = 0x01;
514141cc406Sopenharmony_ci      dev->shadow_regs[0x8d] = 0x01;
515141cc406Sopenharmony_ci      dev->shadow_regs[0x8e] = 0x60;
516141cc406Sopenharmony_ci      dev->shadow_regs[0x8f] = 0x80;
517141cc406Sopenharmony_ci      dev->shadow_regs[0x93] = 0x02;
518141cc406Sopenharmony_ci      dev->shadow_regs[0x94] = 0x0e;
519141cc406Sopenharmony_ci      dev->shadow_regs[0xa3] = 0xcc;
520141cc406Sopenharmony_ci      dev->shadow_regs[0xa4] = 0x27;
521141cc406Sopenharmony_ci      dev->shadow_regs[0xa5] = 0x24;
522141cc406Sopenharmony_ci      dev->shadow_regs[0xc2] = 0x80;
523141cc406Sopenharmony_ci      dev->shadow_regs[0xc3] = 0x01;
524141cc406Sopenharmony_ci      dev->shadow_regs[0xc4] = 0x20;
525141cc406Sopenharmony_ci      dev->shadow_regs[0xc5] = 0x0a;
526141cc406Sopenharmony_ci      dev->shadow_regs[0xc8] = 0x04;
527141cc406Sopenharmony_ci      dev->shadow_regs[0xc9] = 0x39;
528141cc406Sopenharmony_ci      dev->shadow_regs[0xca] = 0x0a;
529141cc406Sopenharmony_ci      dev->shadow_regs[0xe2] = 0x70;
530141cc406Sopenharmony_ci      dev->shadow_regs[0xe3] = 0x17;
531141cc406Sopenharmony_ci      dev->shadow_regs[0xf3] = 0xe0;
532141cc406Sopenharmony_ci      dev->shadow_regs[0xf4] = 0xff;
533141cc406Sopenharmony_ci      dev->shadow_regs[0xf5] = 0x01;
534141cc406Sopenharmony_ci      status = SANE_STATUS_GOOD;
535141cc406Sopenharmony_ci      break;
536141cc406Sopenharmony_ci    case X1100_B2_SENSOR:
537141cc406Sopenharmony_ci      dev->shadow_regs[0x01] = 0x43;
538141cc406Sopenharmony_ci      dev->shadow_regs[0x0b] = 0x70;
539141cc406Sopenharmony_ci      dev->shadow_regs[0x11] = 0x01;
540141cc406Sopenharmony_ci      dev->shadow_regs[0x12] = 0x0f;
541141cc406Sopenharmony_ci      dev->shadow_regs[0x13] = 0x01;
542141cc406Sopenharmony_ci      dev->shadow_regs[0x15] = 0x01;
543141cc406Sopenharmony_ci      dev->shadow_regs[0x16] = 0x0f;
544141cc406Sopenharmony_ci      dev->shadow_regs[0x1d] = 0x20;
545141cc406Sopenharmony_ci      dev->shadow_regs[0x28] = 0xeb;
546141cc406Sopenharmony_ci      dev->shadow_regs[0x29] = 0xee;
547141cc406Sopenharmony_ci      dev->shadow_regs[0x2a] = 0xf7;
548141cc406Sopenharmony_ci      dev->shadow_regs[0x2b] = 0x01;
549141cc406Sopenharmony_ci      dev->shadow_regs[0x2e] = 0x86;
550141cc406Sopenharmony_ci      dev->shadow_regs[0x30] = 0x48;
551141cc406Sopenharmony_ci      dev->shadow_regs[0x33] = 0x01;
552141cc406Sopenharmony_ci      dev->shadow_regs[0x3a] = 0x20;
553141cc406Sopenharmony_ci      dev->shadow_regs[0x3b] = 0x37;
554141cc406Sopenharmony_ci      dev->shadow_regs[0x3c] = 0x88;
555141cc406Sopenharmony_ci      dev->shadow_regs[0x3d] = 0x08;
556141cc406Sopenharmony_ci      dev->shadow_regs[0x40] = 0x80;
557141cc406Sopenharmony_ci      dev->shadow_regs[0x72] = 0x05;
558141cc406Sopenharmony_ci      dev->shadow_regs[0x74] = 0x0e;
559141cc406Sopenharmony_ci      dev->shadow_regs[0x8b] = 0xff;
560141cc406Sopenharmony_ci      dev->shadow_regs[0x8c] = 0x02;
561141cc406Sopenharmony_ci      dev->shadow_regs[0x8d] = 0x01;
562141cc406Sopenharmony_ci      dev->shadow_regs[0x8e] = 0x60;
563141cc406Sopenharmony_ci      dev->shadow_regs[0x8f] = 0x80;
564141cc406Sopenharmony_ci      dev->shadow_regs[0x94] = 0x0e;
565141cc406Sopenharmony_ci      dev->shadow_regs[0xa3] = 0xcc;
566141cc406Sopenharmony_ci      dev->shadow_regs[0xa4] = 0x27;
567141cc406Sopenharmony_ci      dev->shadow_regs[0xa5] = 0x24;
568141cc406Sopenharmony_ci      dev->shadow_regs[0xb0] = 0xb2;
569141cc406Sopenharmony_ci      dev->shadow_regs[0xb2] = 0x04;
570141cc406Sopenharmony_ci      dev->shadow_regs[0xc2] = 0x80;
571141cc406Sopenharmony_ci      dev->shadow_regs[0xc4] = 0x20;
572141cc406Sopenharmony_ci      dev->shadow_regs[0xc8] = 0x04;
573141cc406Sopenharmony_ci      dev->shadow_regs[0xc9] = 0x3b;
574141cc406Sopenharmony_ci      dev->shadow_regs[0xed] = 0xc2;
575141cc406Sopenharmony_ci      dev->shadow_regs[0xee] = 0x02;
576141cc406Sopenharmony_ci      status = SANE_STATUS_GOOD;
577141cc406Sopenharmony_ci      break;
578141cc406Sopenharmony_ci    case X1100_2C_SENSOR:
579141cc406Sopenharmony_ci      dev->shadow_regs[0x00] = 0x00;
580141cc406Sopenharmony_ci      dev->shadow_regs[0x01] = 0x43;
581141cc406Sopenharmony_ci      dev->shadow_regs[0x0b] = 0x70;
582141cc406Sopenharmony_ci      dev->shadow_regs[0x0c] = 0x28;
583141cc406Sopenharmony_ci      dev->shadow_regs[0x0d] = 0xa4;
584141cc406Sopenharmony_ci      dev->shadow_regs[0x11] = 0x01;
585141cc406Sopenharmony_ci      dev->shadow_regs[0x12] = 0x0f;
586141cc406Sopenharmony_ci      dev->shadow_regs[0x13] = 0x01;
587141cc406Sopenharmony_ci      dev->shadow_regs[0x15] = 0x01;
588141cc406Sopenharmony_ci      dev->shadow_regs[0x16] = 0x0f;
589141cc406Sopenharmony_ci      dev->shadow_regs[0x17] = 0x00;
590141cc406Sopenharmony_ci      dev->shadow_regs[0x1d] = 0x20;
591141cc406Sopenharmony_ci      dev->shadow_regs[0x28] = 0xf5;
592141cc406Sopenharmony_ci      dev->shadow_regs[0x29] = 0xf7;
593141cc406Sopenharmony_ci      dev->shadow_regs[0x2a] = 0xf5;
594141cc406Sopenharmony_ci      dev->shadow_regs[0x2b] = 0x17;
595141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x41;
596141cc406Sopenharmony_ci      dev->shadow_regs[0x2e] = 0x86;
597141cc406Sopenharmony_ci      dev->shadow_regs[0x2f] = 0x11;
598141cc406Sopenharmony_ci      dev->shadow_regs[0x30] = 0x48;
599141cc406Sopenharmony_ci      dev->shadow_regs[0x31] = 0x01;
600141cc406Sopenharmony_ci      dev->shadow_regs[0x33] = 0x01;
601141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x50;
602141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x01;
603141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x50;
604141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x01;
605141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x50;
606141cc406Sopenharmony_ci      dev->shadow_regs[0x3a] = 0x20;
607141cc406Sopenharmony_ci      dev->shadow_regs[0x3b] = 0x37;
608141cc406Sopenharmony_ci      dev->shadow_regs[0x3c] = 0x88;
609141cc406Sopenharmony_ci      dev->shadow_regs[0x3d] = 0x08;
610141cc406Sopenharmony_ci      dev->shadow_regs[0x40] = 0x80;
611141cc406Sopenharmony_ci      dev->shadow_regs[0x47] = 0x01;
612141cc406Sopenharmony_ci      dev->shadow_regs[0x48] = 0x1a;
613141cc406Sopenharmony_ci      dev->shadow_regs[0x49] = 0x5b;
614141cc406Sopenharmony_ci      dev->shadow_regs[0x4a] = 0x1b;
615141cc406Sopenharmony_ci      dev->shadow_regs[0x4b] = 0x5b;
616141cc406Sopenharmony_ci      dev->shadow_regs[0x4c] = 0x05;
617141cc406Sopenharmony_ci      dev->shadow_regs[0x4d] = 0x3f;
618141cc406Sopenharmony_ci      dev->shadow_regs[0x60] = 0x2f;
619141cc406Sopenharmony_ci      dev->shadow_regs[0x61] = 0x36;
620141cc406Sopenharmony_ci      dev->shadow_regs[0x62] = 0x30;
621141cc406Sopenharmony_ci      dev->shadow_regs[0x63] = 0x36;
622141cc406Sopenharmony_ci      dev->shadow_regs[0x65] = 0x80;
623141cc406Sopenharmony_ci      dev->shadow_regs[0x66] = 0x64;
624141cc406Sopenharmony_ci      dev->shadow_regs[0x6c] = 0xc8;
625141cc406Sopenharmony_ci      dev->shadow_regs[0x6d] = 0x00;
626141cc406Sopenharmony_ci      dev->shadow_regs[0x72] = 0x35;
627141cc406Sopenharmony_ci      dev->shadow_regs[0x74] = 0x4e;
628141cc406Sopenharmony_ci      dev->shadow_regs[0x75] = 0x03;
629141cc406Sopenharmony_ci      dev->shadow_regs[0x79] = 0x40;
630141cc406Sopenharmony_ci      dev->shadow_regs[0x7a] = 0x01;
631141cc406Sopenharmony_ci      dev->shadow_regs[0x85] = 0x02;
632141cc406Sopenharmony_ci      dev->shadow_regs[0x86] = 0x33;
633141cc406Sopenharmony_ci      dev->shadow_regs[0x87] = 0x0f;
634141cc406Sopenharmony_ci      dev->shadow_regs[0x88] = 0x24;
635141cc406Sopenharmony_ci      dev->shadow_regs[0x8b] = 0xff;
636141cc406Sopenharmony_ci      dev->shadow_regs[0x8c] = 0x02;
637141cc406Sopenharmony_ci      dev->shadow_regs[0x8d] = 0x01;
638141cc406Sopenharmony_ci      dev->shadow_regs[0x8e] = 0x60;
639141cc406Sopenharmony_ci      dev->shadow_regs[0x8f] = 0x80;
640141cc406Sopenharmony_ci      dev->shadow_regs[0x91] = 0x19;
641141cc406Sopenharmony_ci      dev->shadow_regs[0x92] = 0x20;
642141cc406Sopenharmony_ci      dev->shadow_regs[0x93] = 0x02;
643141cc406Sopenharmony_ci      dev->shadow_regs[0x94] = 0x0e;
644141cc406Sopenharmony_ci      dev->shadow_regs[0xa3] = 0x0d;
645141cc406Sopenharmony_ci      dev->shadow_regs[0xa4] = 0x5e;
646141cc406Sopenharmony_ci      dev->shadow_regs[0xa5] = 0x23;
647141cc406Sopenharmony_ci      dev->shadow_regs[0xb0] = 0x2c;
648141cc406Sopenharmony_ci      dev->shadow_regs[0xb1] = 0x07;
649141cc406Sopenharmony_ci      dev->shadow_regs[0xb2] = 0x04;
650141cc406Sopenharmony_ci      dev->shadow_regs[0xc2] = 0x80;
651141cc406Sopenharmony_ci      dev->shadow_regs[0xc3] = 0x01;
652141cc406Sopenharmony_ci      dev->shadow_regs[0xc4] = 0x20;
653141cc406Sopenharmony_ci      dev->shadow_regs[0xc5] = 0x0a;
654141cc406Sopenharmony_ci      dev->shadow_regs[0xc8] = 0x04;
655141cc406Sopenharmony_ci      dev->shadow_regs[0xc9] = 0x3b;
656141cc406Sopenharmony_ci      dev->shadow_regs[0xca] = 0x0a;
657141cc406Sopenharmony_ci      dev->shadow_regs[0xe2] = 0xf8;
658141cc406Sopenharmony_ci      dev->shadow_regs[0xe3] = 0x2a;
659141cc406Sopenharmony_ci      status = SANE_STATUS_GOOD;
660141cc406Sopenharmony_ci      break;
661141cc406Sopenharmony_ci    case X1200_USB2_SENSOR:
662141cc406Sopenharmony_ci      dev->shadow_regs[0x01] = 0x43;
663141cc406Sopenharmony_ci      dev->shadow_regs[0x11] = 0x01;
664141cc406Sopenharmony_ci      dev->shadow_regs[0x12] = 0x0f;
665141cc406Sopenharmony_ci      dev->shadow_regs[0x13] = 0x01;
666141cc406Sopenharmony_ci      dev->shadow_regs[0x15] = 0x01;
667141cc406Sopenharmony_ci      dev->shadow_regs[0x16] = 0x0f;
668141cc406Sopenharmony_ci      dev->shadow_regs[0x17] = 0x00;
669141cc406Sopenharmony_ci      dev->shadow_regs[0x1d] = 0x20;
670141cc406Sopenharmony_ci      dev->shadow_regs[0x28] = 0xf5;
671141cc406Sopenharmony_ci      dev->shadow_regs[0x29] = 0xf7;
672141cc406Sopenharmony_ci      dev->shadow_regs[0x2a] = 0xf5;
673141cc406Sopenharmony_ci      dev->shadow_regs[0x2b] = 0x17;
674141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x41;
675141cc406Sopenharmony_ci      dev->shadow_regs[0x2e] = 0x86;
676141cc406Sopenharmony_ci      dev->shadow_regs[0x30] = 0x48;
677141cc406Sopenharmony_ci      dev->shadow_regs[0x31] = 0x01;
678141cc406Sopenharmony_ci      dev->shadow_regs[0x33] = 0x01;
679141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x50;
680141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x01;
681141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x50;
682141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x01;
683141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x50;
684141cc406Sopenharmony_ci      dev->shadow_regs[0x3c] = 0x88;
685141cc406Sopenharmony_ci      dev->shadow_regs[0x3d] = 0x08;
686141cc406Sopenharmony_ci      dev->shadow_regs[0x66] = 0x64;
687141cc406Sopenharmony_ci      dev->shadow_regs[0x67] = 0x00;
688141cc406Sopenharmony_ci      dev->shadow_regs[0x6c] = 0xc8;
689141cc406Sopenharmony_ci      dev->shadow_regs[0x6d] = 0x00;
690141cc406Sopenharmony_ci      dev->shadow_regs[0x72] = 0x35;
691141cc406Sopenharmony_ci      dev->shadow_regs[0x74] = 0x4e;
692141cc406Sopenharmony_ci      dev->shadow_regs[0x75] = 0x03;
693141cc406Sopenharmony_ci      dev->shadow_regs[0x7a] = 0x01;
694141cc406Sopenharmony_ci      dev->shadow_regs[0x93] = 0x0a;
695141cc406Sopenharmony_ci      dev->shadow_regs[0x94] = 0x0e;
696141cc406Sopenharmony_ci
697141cc406Sopenharmony_ci      dev->shadow_regs[0xc3] = 0x01;
698141cc406Sopenharmony_ci      dev->shadow_regs[0xc4] = 0x20;
699141cc406Sopenharmony_ci      dev->shadow_regs[0xc5] = 0x0a;
700141cc406Sopenharmony_ci      dev->shadow_regs[0xc8] = 0x04;
701141cc406Sopenharmony_ci      dev->shadow_regs[0xc9] = 0x3b;
702141cc406Sopenharmony_ci      dev->shadow_regs[0xca] = 0x0a;
703141cc406Sopenharmony_ci      dev->shadow_regs[0xe2] = 0xf8;
704141cc406Sopenharmony_ci      dev->shadow_regs[0xe3] = 0x2a;
705141cc406Sopenharmony_ci      status = SANE_STATUS_GOOD;
706141cc406Sopenharmony_ci      break;
707141cc406Sopenharmony_ci    case A920_SENSOR:
708141cc406Sopenharmony_ci      dev->shadow_regs[0x01] = 0x43;
709141cc406Sopenharmony_ci      dev->shadow_regs[0x0b] = 0x70;
710141cc406Sopenharmony_ci      dev->shadow_regs[0x0c] = 0x28;
711141cc406Sopenharmony_ci      dev->shadow_regs[0x0d] = 0xa4;
712141cc406Sopenharmony_ci      dev->shadow_regs[0x11] = 0x01;
713141cc406Sopenharmony_ci      dev->shadow_regs[0x12] = 0x0f;
714141cc406Sopenharmony_ci      dev->shadow_regs[0x13] = 0x01;
715141cc406Sopenharmony_ci      dev->shadow_regs[0x15] = 0x01;
716141cc406Sopenharmony_ci      dev->shadow_regs[0x16] = 0x07;
717141cc406Sopenharmony_ci      dev->shadow_regs[0x1d] = 0x20;
718141cc406Sopenharmony_ci      dev->shadow_regs[0x28] = 0xf5;
719141cc406Sopenharmony_ci      dev->shadow_regs[0x29] = 0xf7;
720141cc406Sopenharmony_ci      dev->shadow_regs[0x2a] = 0xf5;
721141cc406Sopenharmony_ci      dev->shadow_regs[0x2b] = 0x17;
722141cc406Sopenharmony_ci      dev->shadow_regs[0x2e] = 0x86;
723141cc406Sopenharmony_ci      dev->shadow_regs[0x30] = 0x48;
724141cc406Sopenharmony_ci      dev->shadow_regs[0x31] = 0x01;
725141cc406Sopenharmony_ci      dev->shadow_regs[0x33] = 0x01;
726141cc406Sopenharmony_ci      dev->shadow_regs[0x3a] = 0x20;
727141cc406Sopenharmony_ci      dev->shadow_regs[0x3b] = 0x37;
728141cc406Sopenharmony_ci      dev->shadow_regs[0x3c] = 0x88;
729141cc406Sopenharmony_ci      dev->shadow_regs[0x3d] = 0x08;
730141cc406Sopenharmony_ci      dev->shadow_regs[0x47] = 0x21;
731141cc406Sopenharmony_ci      dev->shadow_regs[0x48] = 0x1a;
732141cc406Sopenharmony_ci      dev->shadow_regs[0x49] = 0x5b;
733141cc406Sopenharmony_ci      dev->shadow_regs[0x4a] = 0x1b;
734141cc406Sopenharmony_ci      dev->shadow_regs[0x4b] = 0x5b;
735141cc406Sopenharmony_ci      dev->shadow_regs[0x4c] = 0x05;
736141cc406Sopenharmony_ci      dev->shadow_regs[0x4d] = 0x3f;
737141cc406Sopenharmony_ci      dev->shadow_regs[0x65] = 0x80;
738141cc406Sopenharmony_ci      dev->shadow_regs[0x86] = 0x14;
739141cc406Sopenharmony_ci      dev->shadow_regs[0x87] = 0x06;
740141cc406Sopenharmony_ci      dev->shadow_regs[0x89] = 0xf5;
741141cc406Sopenharmony_ci      dev->shadow_regs[0x8d] = 0x01;
742141cc406Sopenharmony_ci      dev->shadow_regs[0x8e] = 0x60;
743141cc406Sopenharmony_ci      dev->shadow_regs[0x8f] = 0x80;
744141cc406Sopenharmony_ci      dev->shadow_regs[0x94] = 0x0e;
745141cc406Sopenharmony_ci      dev->shadow_regs[0xa3] = 0x0d;
746141cc406Sopenharmony_ci      dev->shadow_regs[0xa4] = 0x5e;
747141cc406Sopenharmony_ci      dev->shadow_regs[0xa5] = 0x23;
748141cc406Sopenharmony_ci      dev->shadow_regs[0xb0] = 0x2c;
749141cc406Sopenharmony_ci      dev->shadow_regs[0xb1] = 0x0f;
750141cc406Sopenharmony_ci      dev->shadow_regs[0xc2] = 0x80;
751141cc406Sopenharmony_ci      dev->shadow_regs[0xc4] = 0x20;
752141cc406Sopenharmony_ci      dev->shadow_regs[0xc8] = 0x04;
753141cc406Sopenharmony_ci      status = SANE_STATUS_GOOD;
754141cc406Sopenharmony_ci      break;
755141cc406Sopenharmony_ci    case X1200_SENSOR:
756141cc406Sopenharmony_ci      dev->shadow_regs[0x01] = 0x43;
757141cc406Sopenharmony_ci      dev->shadow_regs[0x0b] = 0x70;
758141cc406Sopenharmony_ci      dev->shadow_regs[0x0c] = 0x28;
759141cc406Sopenharmony_ci      dev->shadow_regs[0x0d] = 0xa4;
760141cc406Sopenharmony_ci      dev->shadow_regs[0x11] = 0x01;
761141cc406Sopenharmony_ci      dev->shadow_regs[0x12] = 0x0f;
762141cc406Sopenharmony_ci      dev->shadow_regs[0x13] = 0x01;
763141cc406Sopenharmony_ci      dev->shadow_regs[0x15] = 0x01;
764141cc406Sopenharmony_ci      dev->shadow_regs[0x16] = 0x0f;
765141cc406Sopenharmony_ci      dev->shadow_regs[0x1d] = 0x20;
766141cc406Sopenharmony_ci      dev->shadow_regs[0x28] = 0xe9;
767141cc406Sopenharmony_ci      dev->shadow_regs[0x29] = 0xeb;
768141cc406Sopenharmony_ci      dev->shadow_regs[0x2a] = 0xe9;
769141cc406Sopenharmony_ci      dev->shadow_regs[0x2b] = 0x0b;
770141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x01;
771141cc406Sopenharmony_ci      dev->shadow_regs[0x2e] = 0x86;
772141cc406Sopenharmony_ci      dev->shadow_regs[0x2f] = 0x11;
773141cc406Sopenharmony_ci      dev->shadow_regs[0x30] = 0x48;
774141cc406Sopenharmony_ci      dev->shadow_regs[0x33] = 0x01;
775141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x50;
776141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x01;
777141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x50;
778141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x01;
779141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x50;
780141cc406Sopenharmony_ci      dev->shadow_regs[0x3a] = 0x20;
781141cc406Sopenharmony_ci      dev->shadow_regs[0x3b] = 0x37;
782141cc406Sopenharmony_ci      dev->shadow_regs[0x3c] = 0x88;
783141cc406Sopenharmony_ci      dev->shadow_regs[0x3d] = 0x08;
784141cc406Sopenharmony_ci      dev->shadow_regs[0x40] = 0x80;
785141cc406Sopenharmony_ci      dev->shadow_regs[0x47] = 0x01;
786141cc406Sopenharmony_ci      dev->shadow_regs[0x48] = 0x1a;
787141cc406Sopenharmony_ci      dev->shadow_regs[0x49] = 0x5b;
788141cc406Sopenharmony_ci      dev->shadow_regs[0x4a] = 0x1b;
789141cc406Sopenharmony_ci      dev->shadow_regs[0x4b] = 0x5b;
790141cc406Sopenharmony_ci      dev->shadow_regs[0x4c] = 0x05;
791141cc406Sopenharmony_ci      dev->shadow_regs[0x4d] = 0x3f;
792141cc406Sopenharmony_ci      dev->shadow_regs[0x60] = 0x12;
793141cc406Sopenharmony_ci      dev->shadow_regs[0x62] = 0x81;
794141cc406Sopenharmony_ci      dev->shadow_regs[0x63] = 0x03;
795141cc406Sopenharmony_ci      dev->shadow_regs[0x65] = 0x80;
796141cc406Sopenharmony_ci      dev->shadow_regs[0x66] = 0x64;
797141cc406Sopenharmony_ci      dev->shadow_regs[0x6c] = 0xc8;
798141cc406Sopenharmony_ci      dev->shadow_regs[0x72] = 0x1e;
799141cc406Sopenharmony_ci      dev->shadow_regs[0x74] = 0x3c;
800141cc406Sopenharmony_ci      dev->shadow_regs[0x75] = 0x03;
801141cc406Sopenharmony_ci      dev->shadow_regs[0x79] = 0x40;
802141cc406Sopenharmony_ci      dev->shadow_regs[0x7a] = 0x01;
803141cc406Sopenharmony_ci      dev->shadow_regs[0x85] = 0x20;
804141cc406Sopenharmony_ci      dev->shadow_regs[0x86] = 0x1e;
805141cc406Sopenharmony_ci      dev->shadow_regs[0x87] = 0x39;
806141cc406Sopenharmony_ci      dev->shadow_regs[0x8b] = 0xff;
807141cc406Sopenharmony_ci      dev->shadow_regs[0x8c] = 0x02;
808141cc406Sopenharmony_ci      dev->shadow_regs[0x8d] = 0x01;
809141cc406Sopenharmony_ci      dev->shadow_regs[0x8e] = 0x60;
810141cc406Sopenharmony_ci      dev->shadow_regs[0x8f] = 0x80;
811141cc406Sopenharmony_ci      dev->shadow_regs[0x92] = 0x92;
812141cc406Sopenharmony_ci      dev->shadow_regs[0x93] = 0x02;
813141cc406Sopenharmony_ci      dev->shadow_regs[0x94] = 0x0e;
814141cc406Sopenharmony_ci      dev->shadow_regs[0xa3] = 0x0d;
815141cc406Sopenharmony_ci      dev->shadow_regs[0xa4] = 0x5e;
816141cc406Sopenharmony_ci      dev->shadow_regs[0xa5] = 0x23;
817141cc406Sopenharmony_ci      dev->shadow_regs[0xb0] = 0x2c;
818141cc406Sopenharmony_ci      dev->shadow_regs[0xb1] = 0x07;
819141cc406Sopenharmony_ci      dev->shadow_regs[0xb2] = 0x04;
820141cc406Sopenharmony_ci      dev->shadow_regs[0xc2] = 0x80;
821141cc406Sopenharmony_ci      dev->shadow_regs[0xc3] = 0x01;
822141cc406Sopenharmony_ci      dev->shadow_regs[0xc4] = 0x20;
823141cc406Sopenharmony_ci      dev->shadow_regs[0xc5] = 0x0a;
824141cc406Sopenharmony_ci      dev->shadow_regs[0xc8] = 0x04;
825141cc406Sopenharmony_ci      dev->shadow_regs[0xc9] = 0x3b;
826141cc406Sopenharmony_ci      dev->shadow_regs[0xca] = 0x0a;
827141cc406Sopenharmony_ci      dev->shadow_regs[0xe2] = 0xf8;
828141cc406Sopenharmony_ci      dev->shadow_regs[0xe3] = 0x2a;
829141cc406Sopenharmony_ci      dev->shadow_regs[0xf3] = 0xff;
830141cc406Sopenharmony_ci      dev->shadow_regs[0xf4] = 0x0f;
831141cc406Sopenharmony_ci      break;
832141cc406Sopenharmony_ci    }
833141cc406Sopenharmony_ci  DBG (5, "sanei_lexmark_low_init: init done for model %s/%s\n",
834141cc406Sopenharmony_ci       dev->model.model, dev->model.name);
835141cc406Sopenharmony_ci  DBG (2, "low_init: done\n");
836141cc406Sopenharmony_ci  return status;
837141cc406Sopenharmony_ci}
838141cc406Sopenharmony_ci
839141cc406Sopenharmony_civoid
840141cc406Sopenharmony_cisanei_lexmark_low_destroy (Lexmark_Device * dev)
841141cc406Sopenharmony_ci{
842141cc406Sopenharmony_ci  /* free the read buffer */
843141cc406Sopenharmony_ci  if (dev->read_buffer != NULL)
844141cc406Sopenharmony_ci    read_buffer_free (dev->read_buffer);
845141cc406Sopenharmony_ci}
846141cc406Sopenharmony_ci
847141cc406Sopenharmony_ci
848141cc406Sopenharmony_ciSANE_Status
849141cc406Sopenharmony_cilow_usb_bulk_write (SANE_Int devnum, SANE_Byte * cmd, size_t * size)
850141cc406Sopenharmony_ci{
851141cc406Sopenharmony_ci  SANE_Status status;
852141cc406Sopenharmony_ci  size_t cmd_size;
853141cc406Sopenharmony_ci
854141cc406Sopenharmony_ci  cmd_size = *size;
855141cc406Sopenharmony_ci#ifdef FAKE_USB
856141cc406Sopenharmony_ci  status = SANE_STATUS_GOOD;
857141cc406Sopenharmony_ci#else
858141cc406Sopenharmony_ci  status = sanei_usb_write_bulk (devnum, cmd, size);
859141cc406Sopenharmony_ci#endif
860141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
861141cc406Sopenharmony_ci    {
862141cc406Sopenharmony_ci      DBG (5,
863141cc406Sopenharmony_ci	   "low_usb_bulk_write: returned %s (size = %lu, expected %lu)\n",
864141cc406Sopenharmony_ci	   sane_strstatus (status), (u_long) * size, (u_long) cmd_size);
865141cc406Sopenharmony_ci      /* F.O. should reset the pipe here... */
866141cc406Sopenharmony_ci    }
867141cc406Sopenharmony_ci  return status;
868141cc406Sopenharmony_ci}
869141cc406Sopenharmony_ci
870141cc406Sopenharmony_ciSANE_Status
871141cc406Sopenharmony_cilow_usb_bulk_read (SANE_Int devnum, SANE_Byte * buf, size_t * size)
872141cc406Sopenharmony_ci{
873141cc406Sopenharmony_ci  SANE_Status status;
874141cc406Sopenharmony_ci  size_t exp_size;
875141cc406Sopenharmony_ci
876141cc406Sopenharmony_ci  exp_size = *size;
877141cc406Sopenharmony_ci#ifdef FAKE_USB
878141cc406Sopenharmony_ci  status = SANE_STATUS_GOOD;
879141cc406Sopenharmony_ci#else
880141cc406Sopenharmony_ci  status = sanei_usb_read_bulk (devnum, buf, size);
881141cc406Sopenharmony_ci#endif
882141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
883141cc406Sopenharmony_ci    {
884141cc406Sopenharmony_ci      DBG (5,
885141cc406Sopenharmony_ci	   "low_usb_bulk_read: returned %s (size = %lu, expected %lu)\n",
886141cc406Sopenharmony_ci	   sane_strstatus (status), (u_long) * size, (u_long) exp_size);
887141cc406Sopenharmony_ci      /* F.O. should reset the pipe here... */
888141cc406Sopenharmony_ci    }
889141cc406Sopenharmony_ci  DBG (7, "low_usb_bulk_read: returned size = %lu (required %lu)\n",
890141cc406Sopenharmony_ci       (u_long) * size, (u_long) exp_size);
891141cc406Sopenharmony_ci  return status;
892141cc406Sopenharmony_ci}
893141cc406Sopenharmony_ci
894141cc406Sopenharmony_ci
895141cc406Sopenharmony_ciSANE_Status
896141cc406Sopenharmony_cilow_start_mvmt (SANE_Int devnum)
897141cc406Sopenharmony_ci{
898141cc406Sopenharmony_ci  SANE_Status status;
899141cc406Sopenharmony_ci  SANE_Byte reg;
900141cc406Sopenharmony_ci
901141cc406Sopenharmony_ci  reg = 0x68;
902141cc406Sopenharmony_ci  rts88xx_write_reg (devnum, 0xb3, &reg);
903141cc406Sopenharmony_ci  status = rts88xx_write_reg (devnum, 0xb3, &reg);
904141cc406Sopenharmony_ci  return status;
905141cc406Sopenharmony_ci}
906141cc406Sopenharmony_ci
907141cc406Sopenharmony_ciSANE_Status
908141cc406Sopenharmony_cilow_stop_mvmt (SANE_Int devnum)
909141cc406Sopenharmony_ci{
910141cc406Sopenharmony_ci  SANE_Status status;
911141cc406Sopenharmony_ci  SANE_Byte reg;
912141cc406Sopenharmony_ci
913141cc406Sopenharmony_ci  /* Stop scanner - clear reg 0xb3: */
914141cc406Sopenharmony_ci  reg = 0x02;
915141cc406Sopenharmony_ci  rts88xx_write_reg (devnum, 0xb3, &reg);
916141cc406Sopenharmony_ci  rts88xx_write_reg (devnum, 0xb3, &reg);
917141cc406Sopenharmony_ci  reg = 0x00;
918141cc406Sopenharmony_ci  rts88xx_write_reg (devnum, 0xb3, &reg);
919141cc406Sopenharmony_ci  status = rts88xx_write_reg (devnum, 0xb3, &reg);
920141cc406Sopenharmony_ci  return status;
921141cc406Sopenharmony_ci}
922141cc406Sopenharmony_ci
923141cc406Sopenharmony_ciSANE_Status
924141cc406Sopenharmony_cilow_clr_c6 (SANE_Int devnum)
925141cc406Sopenharmony_ci{
926141cc406Sopenharmony_ci  SANE_Status status;
927141cc406Sopenharmony_ci  SANE_Byte reg;
928141cc406Sopenharmony_ci
929141cc406Sopenharmony_ci  /* Clear register 0xC6 */
930141cc406Sopenharmony_ci  /* cmd_size = 0x05;
931141cc406Sopenharmony_ci     return low_usb_bulk_write (devnum, clearC6_command_block, &cmd_size); */
932141cc406Sopenharmony_ci
933141cc406Sopenharmony_ci  reg = 0x00;
934141cc406Sopenharmony_ci  status = rts88xx_write_reg (devnum, 0xc6, &reg);
935141cc406Sopenharmony_ci  return status;
936141cc406Sopenharmony_ci}
937141cc406Sopenharmony_ci
938141cc406Sopenharmony_ci/* stops current scan */
939141cc406Sopenharmony_cistatic SANE_Status
940141cc406Sopenharmony_cilow_cancel (SANE_Int devnum)
941141cc406Sopenharmony_ci{
942141cc406Sopenharmony_ci  SANE_Status status;
943141cc406Sopenharmony_ci
944141cc406Sopenharmony_ci  DBG (2, "low_cancel: start\n");
945141cc406Sopenharmony_ci  status = low_stop_mvmt (devnum);
946141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
947141cc406Sopenharmony_ci    return status;
948141cc406Sopenharmony_ci  status = low_clr_c6 (devnum);
949141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
950141cc406Sopenharmony_ci    return status;
951141cc406Sopenharmony_ci  DBG (2, "low_cancel: end.\n");
952141cc406Sopenharmony_ci  return status;
953141cc406Sopenharmony_ci}
954141cc406Sopenharmony_ci
955141cc406Sopenharmony_cistatic SANE_Status
956141cc406Sopenharmony_cilow_start_scan (SANE_Int devnum, SANE_Byte * regs)
957141cc406Sopenharmony_ci{
958141cc406Sopenharmony_ci  SANE_Status status;
959141cc406Sopenharmony_ci
960141cc406Sopenharmony_ci  DBG (2, "low_start_scan: start\n");
961141cc406Sopenharmony_ci
962141cc406Sopenharmony_ci  /* writes registers to scanner */
963141cc406Sopenharmony_ci  regs[0x32] = 0x00;
964141cc406Sopenharmony_ci  status = low_write_all_regs (devnum, regs);
965141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
966141cc406Sopenharmony_ci    return status;
967141cc406Sopenharmony_ci  regs[0x32] = 0x40;
968141cc406Sopenharmony_ci  status = low_write_all_regs (devnum, regs);
969141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
970141cc406Sopenharmony_ci    return status;
971141cc406Sopenharmony_ci
972141cc406Sopenharmony_ci  /* Stop scanner - clear reg 0xb3: */
973141cc406Sopenharmony_ci  /* status = low_stop_mvmt (devnum);
974141cc406Sopenharmony_ci     if (status != SANE_STATUS_GOOD)
975141cc406Sopenharmony_ci     return status; */
976141cc406Sopenharmony_ci
977141cc406Sopenharmony_ci  /* then start */
978141cc406Sopenharmony_ci  status = rts88xx_commit (devnum, regs[0x2c]);
979141cc406Sopenharmony_ci  DBG (2, "low_start_scan: end.\n");
980141cc406Sopenharmony_ci  return status;
981141cc406Sopenharmony_ci}
982141cc406Sopenharmony_ci
983141cc406Sopenharmony_ci/* wait for scan data being available */
984141cc406Sopenharmony_cistatic SANE_Status
985141cc406Sopenharmony_cilow_poll_data (SANE_Int devnum)
986141cc406Sopenharmony_ci{
987141cc406Sopenharmony_ci  SANE_Status status;
988141cc406Sopenharmony_ci  int loops = 0;
989141cc406Sopenharmony_ci  size_t size;
990141cc406Sopenharmony_ci  static SANE_Byte command4_block[] = { 0x90, 0x00, 0x00, 0x03 };
991141cc406Sopenharmony_ci  SANE_Byte result[3];
992141cc406Sopenharmony_ci  SANE_Word count;
993141cc406Sopenharmony_ci
994141cc406Sopenharmony_ci  /* Poll the available byte count until not 0 */
995141cc406Sopenharmony_ci  while (loops < 1000)
996141cc406Sopenharmony_ci    {
997141cc406Sopenharmony_ci      /* 10 ms sleep */
998141cc406Sopenharmony_ci      usleep (10000);
999141cc406Sopenharmony_ci
1000141cc406Sopenharmony_ci      /* as stated in sanei_lexmark_low_search_home_bwd, we read
1001141cc406Sopenharmony_ci       * available data count twice */
1002141cc406Sopenharmony_ci      size = 4;
1003141cc406Sopenharmony_ci      status = low_usb_bulk_write (devnum, command4_block, &size);
1004141cc406Sopenharmony_ci      if (status != SANE_STATUS_GOOD)
1005141cc406Sopenharmony_ci	return status;
1006141cc406Sopenharmony_ci      size = 0x3;
1007141cc406Sopenharmony_ci      status = low_usb_bulk_read (devnum, result, &size);
1008141cc406Sopenharmony_ci      if (status != SANE_STATUS_GOOD)
1009141cc406Sopenharmony_ci	return status;
1010141cc406Sopenharmony_ci      size = 4;
1011141cc406Sopenharmony_ci      /* read available data size again */
1012141cc406Sopenharmony_ci      status = low_usb_bulk_write (devnum, command4_block, &size);
1013141cc406Sopenharmony_ci      if (status != SANE_STATUS_GOOD)
1014141cc406Sopenharmony_ci	return status;
1015141cc406Sopenharmony_ci      size = 0x3;
1016141cc406Sopenharmony_ci      status = low_usb_bulk_read (devnum, result, &size);
1017141cc406Sopenharmony_ci      if (status != SANE_STATUS_GOOD)
1018141cc406Sopenharmony_ci	return status;
1019141cc406Sopenharmony_ci      count = result[0] + (result[1] << 8) + (result[2] << 16);
1020141cc406Sopenharmony_ci      if (count != 0)
1021141cc406Sopenharmony_ci	{
1022141cc406Sopenharmony_ci	  DBG (15, "low_poll_data: %d bytes available\n", count);
1023141cc406Sopenharmony_ci	  return SANE_STATUS_GOOD;
1024141cc406Sopenharmony_ci	}
1025141cc406Sopenharmony_ci      loops++;
1026141cc406Sopenharmony_ci    }
1027141cc406Sopenharmony_ci  return SANE_STATUS_IO_ERROR;
1028141cc406Sopenharmony_ci}
1029141cc406Sopenharmony_ci
1030141cc406Sopenharmony_ci/**
1031141cc406Sopenharmony_ci * do a simple scan with the given registers. data buffer is allocated within
1032141cc406Sopenharmony_ci * the function
1033141cc406Sopenharmony_ci */
1034141cc406Sopenharmony_cistatic SANE_Status
1035141cc406Sopenharmony_cilow_simple_scan (Lexmark_Device * dev, SANE_Byte * regs, int xoffset,
1036141cc406Sopenharmony_ci		 int pixels, int yoffset, int lines, SANE_Byte ** data)
1037141cc406Sopenharmony_ci{
1038141cc406Sopenharmony_ci  SANE_Status status = SANE_STATUS_GOOD;
1039141cc406Sopenharmony_ci  static SANE_Byte reg;
1040141cc406Sopenharmony_ci  size_t size, read, needed;
1041141cc406Sopenharmony_ci  int i, bpl, yend;
1042141cc406Sopenharmony_ci
1043141cc406Sopenharmony_ci  DBG (2, "low_simple_scan: start\n");
1044141cc406Sopenharmony_ci  DBG (15, "low_simple_scan: x=%d, pixels=%d (ex=%d), y=%d, lines=%d\n",
1045141cc406Sopenharmony_ci       xoffset, pixels, xoffset + pixels * regs[0x7a], yoffset, lines);
1046141cc406Sopenharmony_ci
1047141cc406Sopenharmony_ci  /* set up registers */
1048141cc406Sopenharmony_ci  regs[0x60] = LOBYTE (yoffset);
1049141cc406Sopenharmony_ci  regs[0x61] = HIBYTE (yoffset);
1050141cc406Sopenharmony_ci  yend = yoffset + lines;
1051141cc406Sopenharmony_ci  if ((dev->model.motor_type == A920_MOTOR
1052141cc406Sopenharmony_ci       || dev->model.motor_type == X74_MOTOR) && rts88xx_is_color (regs)
1053141cc406Sopenharmony_ci      && dev->val[OPT_RESOLUTION].w == 600)
1054141cc406Sopenharmony_ci    yend *= 2;
1055141cc406Sopenharmony_ci  regs[0x62] = LOBYTE (yend);
1056141cc406Sopenharmony_ci  regs[0x63] = HIBYTE (yend);
1057141cc406Sopenharmony_ci
1058141cc406Sopenharmony_ci  regs[0x66] = LOBYTE (xoffset);
1059141cc406Sopenharmony_ci  regs[0x67] = HIBYTE (xoffset);
1060141cc406Sopenharmony_ci
1061141cc406Sopenharmony_ci  regs[0x6c] = LOBYTE (xoffset + pixels * regs[0x7a]);
1062141cc406Sopenharmony_ci  regs[0x6d] = HIBYTE (xoffset + pixels * regs[0x7a]);
1063141cc406Sopenharmony_ci
1064141cc406Sopenharmony_ci  /* allocate memory */
1065141cc406Sopenharmony_ci  if (rts88xx_is_color (regs))
1066141cc406Sopenharmony_ci    bpl = 3 * pixels;
1067141cc406Sopenharmony_ci  else
1068141cc406Sopenharmony_ci    bpl = pixels;
1069141cc406Sopenharmony_ci  *data = (SANE_Byte *) malloc (bpl * lines);
1070141cc406Sopenharmony_ci  if (*data == NULL)
1071141cc406Sopenharmony_ci    {
1072141cc406Sopenharmony_ci      DBG (2,
1073141cc406Sopenharmony_ci	   "low_simple_scan: failed to allocate %d bytes !\n", bpl * lines);
1074141cc406Sopenharmony_ci      return SANE_STATUS_NO_MEM;
1075141cc406Sopenharmony_ci    }
1076141cc406Sopenharmony_ci
1077141cc406Sopenharmony_ci  /* start scan */
1078141cc406Sopenharmony_ci  status = low_cancel (dev->devnum);
1079141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
1080141cc406Sopenharmony_ci    return status;
1081141cc406Sopenharmony_ci
1082141cc406Sopenharmony_ci
1083141cc406Sopenharmony_ci  status = low_start_scan (dev->devnum, regs);
1084141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
1085141cc406Sopenharmony_ci    return status;
1086141cc406Sopenharmony_ci
1087141cc406Sopenharmony_ci  /* wait for data */
1088141cc406Sopenharmony_ci  status = low_poll_data (dev->devnum);
1089141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
1090141cc406Sopenharmony_ci    {
1091141cc406Sopenharmony_ci      DBG (1, "low_simple_scan: time-out while waiting for data.\n");
1092141cc406Sopenharmony_ci      return status;
1093141cc406Sopenharmony_ci    }
1094141cc406Sopenharmony_ci
1095141cc406Sopenharmony_ci  /* data reading loop */
1096141cc406Sopenharmony_ci  needed = bpl * lines;
1097141cc406Sopenharmony_ci  DBG (1, "low_simple_scan: bpl=%d, lines=%d, needed=%lu.\n", bpl, lines,
1098141cc406Sopenharmony_ci       (u_long) needed);
1099141cc406Sopenharmony_ci  read = 0;
1100141cc406Sopenharmony_ci  do
1101141cc406Sopenharmony_ci    {
1102141cc406Sopenharmony_ci      /* this block would deserve to be a function */
1103141cc406Sopenharmony_ci      status =
1104141cc406Sopenharmony_ci	rts88xx_read_data (dev->devnum, needed - read, (*data) + read, &size);
1105141cc406Sopenharmony_ci      if (status != SANE_STATUS_GOOD)
1106141cc406Sopenharmony_ci	return status;
1107141cc406Sopenharmony_ci      read += size;
1108141cc406Sopenharmony_ci    }
1109141cc406Sopenharmony_ci  while (read < needed);
1110141cc406Sopenharmony_ci
1111141cc406Sopenharmony_ci  /* if needed, wait for motor to stop */
1112141cc406Sopenharmony_ci  if (regs[0xc3] & 0x80)
1113141cc406Sopenharmony_ci    {
1114141cc406Sopenharmony_ci      i = 0;
1115141cc406Sopenharmony_ci      do
1116141cc406Sopenharmony_ci	{
1117141cc406Sopenharmony_ci	  if (rts88xx_read_reg (dev->devnum, 0xb3, &reg) != SANE_STATUS_GOOD)
1118141cc406Sopenharmony_ci	    {
1119141cc406Sopenharmony_ci	      DBG (5, "low_simple_scan: register read failed ...\n");
1120141cc406Sopenharmony_ci	      return SANE_STATUS_IO_ERROR;
1121141cc406Sopenharmony_ci	    }
1122141cc406Sopenharmony_ci	  usleep (100000);
1123141cc406Sopenharmony_ci	  i++;
1124141cc406Sopenharmony_ci	}
1125141cc406Sopenharmony_ci      while ((reg & 0x08) && (i < 100));
1126141cc406Sopenharmony_ci      if (reg & 0x08)
1127141cc406Sopenharmony_ci	{
1128141cc406Sopenharmony_ci	  DBG (5,
1129141cc406Sopenharmony_ci	       "low_simple_scan : timeout waiting for motor to stop ...\n");
1130141cc406Sopenharmony_ci	  return SANE_STATUS_IO_ERROR;
1131141cc406Sopenharmony_ci	}
1132141cc406Sopenharmony_ci    }
1133141cc406Sopenharmony_ci
1134141cc406Sopenharmony_ci  /* stop scan */
1135141cc406Sopenharmony_ci  status = low_cancel (dev->devnum);
1136141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
1137141cc406Sopenharmony_ci    {
1138141cc406Sopenharmony_ci      DBG (1, "low_simple_scan: cancel failed.\n");
1139141cc406Sopenharmony_ci      return status;
1140141cc406Sopenharmony_ci    }
1141141cc406Sopenharmony_ci
1142141cc406Sopenharmony_ci  DBG (2, "low_simple_scan: end.\n");
1143141cc406Sopenharmony_ci  return status;
1144141cc406Sopenharmony_ci}
1145141cc406Sopenharmony_ci
1146141cc406Sopenharmony_ci/*
1147141cc406Sopenharmony_ci * open USB device ,read initial registers values and probe sensor
1148141cc406Sopenharmony_ci */
1149141cc406Sopenharmony_ciSANE_Status
1150141cc406Sopenharmony_cisanei_lexmark_low_open_device (Lexmark_Device * dev)
1151141cc406Sopenharmony_ci{
1152141cc406Sopenharmony_ci  /* This function calls the Sane Interface to open this usb device.
1153141cc406Sopenharmony_ci     It also needlessly does what the Windows driver does and reads
1154141cc406Sopenharmony_ci     the entire register set - this may be removed. */
1155141cc406Sopenharmony_ci
1156141cc406Sopenharmony_ci  SANE_Status result;
1157141cc406Sopenharmony_ci  static SANE_Byte command_block[] = { 0x80, 0, 0x00, 0xFF };
1158141cc406Sopenharmony_ci  size_t size;
1159141cc406Sopenharmony_ci  SANE_Byte variant = 0;
1160141cc406Sopenharmony_ci  SANE_Byte shadow_regs[255];
1161141cc406Sopenharmony_ci  int sx, ex;
1162141cc406Sopenharmony_ci  int sy, ey;
1163141cc406Sopenharmony_ci  int i;
1164141cc406Sopenharmony_ci  char msg[2048];
1165141cc406Sopenharmony_ci
1166141cc406Sopenharmony_ci
1167141cc406Sopenharmony_ci#ifdef FAKE_USB
1168141cc406Sopenharmony_ci  result = SANE_STATUS_GOOD;
1169141cc406Sopenharmony_ci  shadow_regs[0x00] = 0x91;
1170141cc406Sopenharmony_ci  shadow_regs[0xb0] = 0x2c;
1171141cc406Sopenharmony_ci  shadow_regs[0x10] = 0x97;
1172141cc406Sopenharmony_ci  shadow_regs[0x10] = 0x87;
1173141cc406Sopenharmony_ci  shadow_regs[0xf3] = 0xf8;
1174141cc406Sopenharmony_ci  shadow_regs[0xf4] = 0x7f;
1175141cc406Sopenharmony_ci#else
1176141cc406Sopenharmony_ci  result = sanei_usb_open (dev->sane.name, &(dev->devnum));
1177141cc406Sopenharmony_ci#endif
1178141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_open_device: devnum=%d\n", dev->devnum);
1179141cc406Sopenharmony_ci
1180141cc406Sopenharmony_ci  size = 4;
1181141cc406Sopenharmony_ci  low_usb_bulk_write (dev->devnum, command_block, &size);
1182141cc406Sopenharmony_ci  size = 0xFF;
1183141cc406Sopenharmony_ci  memset (shadow_regs, 0, sizeof (shadow_regs));
1184141cc406Sopenharmony_ci  low_usb_bulk_read (dev->devnum, shadow_regs, &size);
1185141cc406Sopenharmony_ci
1186141cc406Sopenharmony_ci  if (DBG_LEVEL > 2)
1187141cc406Sopenharmony_ci    {
1188141cc406Sopenharmony_ci      DBG (2, "sanei_lexmark_low_open_device: initial registers values\n");
1189141cc406Sopenharmony_ci      for (i = 0; i < 255; i++)
1190141cc406Sopenharmony_ci	{
1191141cc406Sopenharmony_ci	  sprintf (msg + i * 5, "0x%02x ", shadow_regs[i]);
1192141cc406Sopenharmony_ci	}
1193141cc406Sopenharmony_ci      DBG (3, "%s\n", msg);
1194141cc406Sopenharmony_ci    }
1195141cc406Sopenharmony_ci
1196141cc406Sopenharmony_ci  /* it seems that at first read after reset, registers hold information
1197141cc406Sopenharmony_ci   * about the scanner. Register 0x00 is overwritten with 0, so only first read
1198141cc406Sopenharmony_ci   * after USB plug-in gives this value */
1199141cc406Sopenharmony_ci  if (shadow_regs[0] == 0x91)
1200141cc406Sopenharmony_ci    {
1201141cc406Sopenharmony_ci      sx = shadow_regs[0x67] * 256 + shadow_regs[0x66];
1202141cc406Sopenharmony_ci      ex = shadow_regs[0x6d] * 256 + shadow_regs[0x6c];
1203141cc406Sopenharmony_ci      DBG (7, "startx=%d, endx=%d, pixels=%d, coef=%d, r2f=0x%02x\n", sx, ex,
1204141cc406Sopenharmony_ci	   ex - sx, dev->shadow_regs[0x7a], shadow_regs[0x2f]);
1205141cc406Sopenharmony_ci      sy = shadow_regs[0x61] * 256 + shadow_regs[0x60];
1206141cc406Sopenharmony_ci      ey = shadow_regs[0x63] * 256 + shadow_regs[0x62];
1207141cc406Sopenharmony_ci      DBG (7, "starty=%d, endy=%d, lines=%d\n", sy, ey, ey - sy);
1208141cc406Sopenharmony_ci    }
1209141cc406Sopenharmony_ci
1210141cc406Sopenharmony_ci  /* we use register 0xb0 to identify details about models   */
1211141cc406Sopenharmony_ci  /* this register isn't overwritten during normal operation */
1212141cc406Sopenharmony_ci  if (shadow_regs[0xb0] == 0x2c && dev->model.sensor_type == X1100_B2_SENSOR)
1213141cc406Sopenharmony_ci    {
1214141cc406Sopenharmony_ci      variant = shadow_regs[0xb0];
1215141cc406Sopenharmony_ci    }
1216141cc406Sopenharmony_ci  /* now the same with register 0x10 */
1217141cc406Sopenharmony_ci  /* which most likely signals USB2.0/USB1.1 */
1218141cc406Sopenharmony_ci  if ((dev->model.sensor_type == X1200_SENSOR) && (shadow_regs[0x10] == 0x97))
1219141cc406Sopenharmony_ci    {
1220141cc406Sopenharmony_ci      variant = shadow_regs[0x10];
1221141cc406Sopenharmony_ci    }
1222141cc406Sopenharmony_ci
1223141cc406Sopenharmony_ci  /* if find a case where default model given is inappropriate, reassign it
1224141cc406Sopenharmony_ci   * since we have now the information to get the real one.
1225141cc406Sopenharmony_ci   * We could avoid this if attach() did open and read registers, not init */
1226141cc406Sopenharmony_ci  if (variant != 0)
1227141cc406Sopenharmony_ci    {
1228141cc406Sopenharmony_ci      DBG (3,
1229141cc406Sopenharmony_ci	   "sanei_lexmark_low_open_device: reassign model/sensor for variant 0x%02x\n",
1230141cc406Sopenharmony_ci	   variant);
1231141cc406Sopenharmony_ci      sanei_lexmark_low_assign_model (dev, dev->sane.name,
1232141cc406Sopenharmony_ci				      dev->model.vendor_id,
1233141cc406Sopenharmony_ci				      dev->model.product_id, variant);
1234141cc406Sopenharmony_ci      /* since model has changed, run init again */
1235141cc406Sopenharmony_ci      sanei_lexmark_low_init (dev);
1236141cc406Sopenharmony_ci    }
1237141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_open_device: end\n");
1238141cc406Sopenharmony_ci  return result;
1239141cc406Sopenharmony_ci}
1240141cc406Sopenharmony_ci
1241141cc406Sopenharmony_civoid
1242141cc406Sopenharmony_cisanei_lexmark_low_close_device (Lexmark_Device * dev)
1243141cc406Sopenharmony_ci{
1244141cc406Sopenharmony_ci  /* put scanner in idle state */
1245141cc406Sopenharmony_ci  lexmark_low_set_idle (dev->devnum);
1246141cc406Sopenharmony_ci
1247141cc406Sopenharmony_ci  /* This function calls the Sane USB library to close this usb device */
1248141cc406Sopenharmony_ci#ifndef FAKE_USB
1249141cc406Sopenharmony_ci  sanei_usb_close (dev->devnum);
1250141cc406Sopenharmony_ci#endif
1251141cc406Sopenharmony_ci  return;
1252141cc406Sopenharmony_ci}
1253141cc406Sopenharmony_ci
1254141cc406Sopenharmony_ci
1255141cc406Sopenharmony_ci/* This function writes the contents of the given registers to the
1256141cc406Sopenharmony_ci     scanner. */
1257141cc406Sopenharmony_ciSANE_Status
1258141cc406Sopenharmony_cilow_write_all_regs (SANE_Int devnum, SANE_Byte * regs)
1259141cc406Sopenharmony_ci{
1260141cc406Sopenharmony_ci  int i;
1261141cc406Sopenharmony_ci  SANE_Status status;
1262141cc406Sopenharmony_ci  size_t size;
1263141cc406Sopenharmony_ci  static SANE_Byte command_block1[0xb7];
1264141cc406Sopenharmony_ci  static SANE_Byte command_block2[0x4f];
1265141cc406Sopenharmony_ci  command_block1[0] = 0x88;
1266141cc406Sopenharmony_ci  command_block1[1] = 0x00;
1267141cc406Sopenharmony_ci  command_block1[2] = 0x00;
1268141cc406Sopenharmony_ci  command_block1[3] = 0xb3;
1269141cc406Sopenharmony_ci  for (i = 0; i < 0xb3; i++)
1270141cc406Sopenharmony_ci    {
1271141cc406Sopenharmony_ci      command_block1[i + 4] = regs[i];
1272141cc406Sopenharmony_ci    }
1273141cc406Sopenharmony_ci  command_block2[0] = 0x88;
1274141cc406Sopenharmony_ci  command_block2[1] = 0xb4;
1275141cc406Sopenharmony_ci  command_block2[2] = 0x00;
1276141cc406Sopenharmony_ci  command_block2[3] = 0x4b;
1277141cc406Sopenharmony_ci  for (i = 0; i < 0x4b; i++)
1278141cc406Sopenharmony_ci    {
1279141cc406Sopenharmony_ci      command_block2[i + 4] = regs[i + 0xb4];
1280141cc406Sopenharmony_ci    }
1281141cc406Sopenharmony_ci  size = 0xb7;
1282141cc406Sopenharmony_ci
1283141cc406Sopenharmony_ci#ifdef DEEP_DEBUG
1284141cc406Sopenharmony_ci  fprintf (stderr, "write_all(0x00,255)=");
1285141cc406Sopenharmony_ci  for (i = 0; i < 255; i++)
1286141cc406Sopenharmony_ci    {
1287141cc406Sopenharmony_ci      fprintf (stderr, "0x%02x ", regs[i]);
1288141cc406Sopenharmony_ci    }
1289141cc406Sopenharmony_ci  fprintf (stderr, "\n");
1290141cc406Sopenharmony_ci#endif
1291141cc406Sopenharmony_ci
1292141cc406Sopenharmony_ci  status = low_usb_bulk_write (devnum, command_block1, &size);
1293141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
1294141cc406Sopenharmony_ci    return status;
1295141cc406Sopenharmony_ci  size = 0x4f;
1296141cc406Sopenharmony_ci  status = low_usb_bulk_write (devnum, command_block2, &size);
1297141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
1298141cc406Sopenharmony_ci    return status;
1299141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
1300141cc406Sopenharmony_ci}
1301141cc406Sopenharmony_ci
1302141cc406Sopenharmony_ci
1303141cc406Sopenharmony_ciSANE_Bool
1304141cc406Sopenharmony_cilow_is_home_line (Lexmark_Device * dev, unsigned char *buffer)
1305141cc406Sopenharmony_ci{
1306141cc406Sopenharmony_ci  /*
1307141cc406Sopenharmony_ci     This function assumes the buffer has a size of 2500 bytes.It is
1308141cc406Sopenharmony_ci     destructive to the buffer.
1309141cc406Sopenharmony_ci
1310141cc406Sopenharmony_ci     Here is what it does:
1311141cc406Sopenharmony_ci
1312141cc406Sopenharmony_ci     Go through the buffer finding low and high values, which are computed by
1313141cc406Sopenharmony_ci     comparing to the average:
1314141cc406Sopenharmony_ci     average = (lowest value + highest value)/2
1315141cc406Sopenharmony_ci     High bytes are changed to 0xFF (white), lower or equal bytes are changed
1316141cc406Sopenharmony_ci     to 0x00 (black),so that the buffer only contains white (0xFF) or black
1317141cc406Sopenharmony_ci     (0x00) values.
1318141cc406Sopenharmony_ci
1319141cc406Sopenharmony_ci     Next, we go through the buffer. We use a tolerance of 5 bytes on each end
1320141cc406Sopenharmony_ci     of the buffer and check a region from bytes 5 to 2495. We start assuming
1321141cc406Sopenharmony_ci     we are in a white region and look for the start of a black region. We save
1322141cc406Sopenharmony_ci     this index as the transition from white to black. We also save where we
1323141cc406Sopenharmony_ci     change from black back to white. We continue checking for transitions
1324141cc406Sopenharmony_ci     until the end of the check region. If we don't have exactly two
1325141cc406Sopenharmony_ci     transitions when we reach the end we return SANE_FALSE.
1326141cc406Sopenharmony_ci
1327141cc406Sopenharmony_ci     The final check compares the transition indices to the nominal values
1328141cc406Sopenharmony_ci     plus or minus the tolerance. For the first transition (white to black
1329141cc406Sopenharmony_ci     index) the value must lie in the range 1235-30 (1205) to 1235+30 (1265).
1330141cc406Sopenharmony_ci     For the second transition (black to white) the value must lie in the range
1331141cc406Sopenharmony_ci     1258-30 (1228) to 1258+30 (1288). If the indices are out of range we
1332141cc406Sopenharmony_ci     return SANE_FALSE. Otherwise, we return SANE_TRUE.
1333141cc406Sopenharmony_ci   */
1334141cc406Sopenharmony_ci
1335141cc406Sopenharmony_ci
1336141cc406Sopenharmony_ci  unsigned char max_byte = 0;
1337141cc406Sopenharmony_ci  unsigned char min_byte = 0xFF;
1338141cc406Sopenharmony_ci  unsigned char average;
1339141cc406Sopenharmony_ci  int i;
1340141cc406Sopenharmony_ci  int home_point1;
1341141cc406Sopenharmony_ci  int home_point2;
1342141cc406Sopenharmony_ci  region_type region;
1343141cc406Sopenharmony_ci  int transition_counter;
1344141cc406Sopenharmony_ci  int index1 = 0;
1345141cc406Sopenharmony_ci  int index2 = 0;
1346141cc406Sopenharmony_ci  int low_range, high_range;
1347141cc406Sopenharmony_ci
1348141cc406Sopenharmony_ci#ifdef DEEP_DEBUG
1349141cc406Sopenharmony_ci  static int numero = 0;
1350141cc406Sopenharmony_ci  char titre[80];
1351141cc406Sopenharmony_ci  FILE *trace = NULL;
1352141cc406Sopenharmony_ci  sprintf (titre, "lgn%03d.pnm", numero);
1353141cc406Sopenharmony_ci  trace = fopen (titre, "wb");
1354141cc406Sopenharmony_ci  if (trace)
1355141cc406Sopenharmony_ci    {
1356141cc406Sopenharmony_ci      fprintf (trace, "P5\n2500 1\n255\n");
1357141cc406Sopenharmony_ci      fwrite (buffer, 2500, 1, trace);
1358141cc406Sopenharmony_ci      fclose (trace);
1359141cc406Sopenharmony_ci    }
1360141cc406Sopenharmony_ci  numero++;
1361141cc406Sopenharmony_ci#endif
1362141cc406Sopenharmony_ci
1363141cc406Sopenharmony_ci  DBG (15, "low_is_home_line: start\n");
1364141cc406Sopenharmony_ci  /* Find the max and the min */
1365141cc406Sopenharmony_ci  for (i = 0; i < 2500; i++)
1366141cc406Sopenharmony_ci    {
1367141cc406Sopenharmony_ci      if (*(buffer + i) > max_byte)
1368141cc406Sopenharmony_ci	max_byte = *(buffer + i);
1369141cc406Sopenharmony_ci      if (*(buffer + i) < min_byte)
1370141cc406Sopenharmony_ci	min_byte = *(buffer + i);
1371141cc406Sopenharmony_ci    }
1372141cc406Sopenharmony_ci
1373141cc406Sopenharmony_ci  /* The average */
1374141cc406Sopenharmony_ci  average = ((max_byte + min_byte) / 2);
1375141cc406Sopenharmony_ci
1376141cc406Sopenharmony_ci  /* Set bytes as white (0xFF) or black (0x00) */
1377141cc406Sopenharmony_ci  for (i = 0; i < 2500; i++)
1378141cc406Sopenharmony_ci    {
1379141cc406Sopenharmony_ci      if (*(buffer + i) > average)
1380141cc406Sopenharmony_ci	*(buffer + i) = 0xFF;
1381141cc406Sopenharmony_ci      else
1382141cc406Sopenharmony_ci	*(buffer + i) = 0x00;
1383141cc406Sopenharmony_ci    }
1384141cc406Sopenharmony_ci
1385141cc406Sopenharmony_ci  region = white;
1386141cc406Sopenharmony_ci  transition_counter = 0;
1387141cc406Sopenharmony_ci
1388141cc406Sopenharmony_ci  /* Go through the check region - bytes 5 to 2495 */
1389141cc406Sopenharmony_ci  /* XXX STEF XXX shrink the area to where the dot should be
1390141cc406Sopenharmony_ci   * +-100 around the 1250 expected location */
1391141cc406Sopenharmony_ci  for (i = 1150; i <= 1350; i++)
1392141cc406Sopenharmony_ci    {
1393141cc406Sopenharmony_ci      /* Check for transition to black */
1394141cc406Sopenharmony_ci      if ((region == white) && (*(buffer + i) == 0))
1395141cc406Sopenharmony_ci	{
1396141cc406Sopenharmony_ci	  if (transition_counter < 2)
1397141cc406Sopenharmony_ci	    {
1398141cc406Sopenharmony_ci	      region = black;
1399141cc406Sopenharmony_ci	      index1 = i;
1400141cc406Sopenharmony_ci	      transition_counter++;
1401141cc406Sopenharmony_ci	    }
1402141cc406Sopenharmony_ci	  else
1403141cc406Sopenharmony_ci	    {
1404141cc406Sopenharmony_ci	      DBG (15, "low_is_home_line: no transition to black \n");
1405141cc406Sopenharmony_ci	      return SANE_FALSE;
1406141cc406Sopenharmony_ci	    }
1407141cc406Sopenharmony_ci	}
1408141cc406Sopenharmony_ci      /* Check for transition to white */
1409141cc406Sopenharmony_ci      else if ((region == black) && (*(buffer + i) == 0xFF))
1410141cc406Sopenharmony_ci	{
1411141cc406Sopenharmony_ci	  if (transition_counter < 2)
1412141cc406Sopenharmony_ci	    {
1413141cc406Sopenharmony_ci	      region = white;
1414141cc406Sopenharmony_ci	      index2 = i;
1415141cc406Sopenharmony_ci	      transition_counter++;
1416141cc406Sopenharmony_ci	    }
1417141cc406Sopenharmony_ci	  else
1418141cc406Sopenharmony_ci	    {
1419141cc406Sopenharmony_ci	      DBG (15, "low_is_home_line: no transition to white \n");
1420141cc406Sopenharmony_ci	      return SANE_FALSE;
1421141cc406Sopenharmony_ci	    }
1422141cc406Sopenharmony_ci	}
1423141cc406Sopenharmony_ci    }
1424141cc406Sopenharmony_ci
1425141cc406Sopenharmony_ci  /* Check that the number of transitions is 2 */
1426141cc406Sopenharmony_ci  if (transition_counter != 2)
1427141cc406Sopenharmony_ci    {
1428141cc406Sopenharmony_ci      DBG (15, "low_is_home_line: transitions!=2 (%d)\n", transition_counter);
1429141cc406Sopenharmony_ci      return SANE_FALSE;
1430141cc406Sopenharmony_ci    }
1431141cc406Sopenharmony_ci
1432141cc406Sopenharmony_ci
1433141cc406Sopenharmony_ci
1434141cc406Sopenharmony_ci
1435141cc406Sopenharmony_ci  /* Check that the 1st index is in range */
1436141cc406Sopenharmony_ci  home_point1 = dev->model.HomeEdgePoint1;
1437141cc406Sopenharmony_ci  low_range = home_point1 - HomeTolerance;
1438141cc406Sopenharmony_ci  high_range = home_point1 + HomeTolerance;
1439141cc406Sopenharmony_ci
1440141cc406Sopenharmony_ci  if ((index1 < low_range) || (index1 > high_range))
1441141cc406Sopenharmony_ci    {
1442141cc406Sopenharmony_ci      DBG (15, "low_is_home_line: index1=%d out of range\n", index1);
1443141cc406Sopenharmony_ci      return SANE_FALSE;
1444141cc406Sopenharmony_ci    }
1445141cc406Sopenharmony_ci
1446141cc406Sopenharmony_ci
1447141cc406Sopenharmony_ci  /* Check that the 2nd index is in range */
1448141cc406Sopenharmony_ci  home_point2 = dev->model.HomeEdgePoint2;
1449141cc406Sopenharmony_ci  low_range = home_point2 - HomeTolerance;
1450141cc406Sopenharmony_ci  high_range = home_point2 + HomeTolerance;
1451141cc406Sopenharmony_ci
1452141cc406Sopenharmony_ci  if ((index2 < low_range) || (index2 > high_range))
1453141cc406Sopenharmony_ci    {
1454141cc406Sopenharmony_ci      DBG (15, "low_is_home_line: index2=%d out of range.\n", index2);
1455141cc406Sopenharmony_ci      return SANE_FALSE;
1456141cc406Sopenharmony_ci    }
1457141cc406Sopenharmony_ci
1458141cc406Sopenharmony_ci  /* We made it this far, so its a good home line. Return True */
1459141cc406Sopenharmony_ci  DBG (15, "low_is_home_line: success\n");
1460141cc406Sopenharmony_ci  return SANE_TRUE;
1461141cc406Sopenharmony_ci}
1462141cc406Sopenharmony_ci
1463141cc406Sopenharmony_civoid
1464141cc406Sopenharmony_cisanei_lexmark_low_move_fwd (SANE_Int distance, Lexmark_Device * dev,
1465141cc406Sopenharmony_ci			    SANE_Byte * regs)
1466141cc406Sopenharmony_ci{
1467141cc406Sopenharmony_ci  /*
1468141cc406Sopenharmony_ci     This function moves the scan head forward with the highest vertical
1469141cc406Sopenharmony_ci     resolution of 1200dpi. The distance moved is given by the distance
1470141cc406Sopenharmony_ci     parameter.
1471141cc406Sopenharmony_ci
1472141cc406Sopenharmony_ci     As an example, given a distance parameter of 600, the scan head will
1473141cc406Sopenharmony_ci     move 600/1200", or 1/2" forward.
1474141cc406Sopenharmony_ci   */
1475141cc406Sopenharmony_ci
1476141cc406Sopenharmony_ci  static SANE_Byte pollstopmoving_command_block[] =
1477141cc406Sopenharmony_ci    { 0x80, 0xb3, 0x00, 0x01 };
1478141cc406Sopenharmony_ci
1479141cc406Sopenharmony_ci
1480141cc406Sopenharmony_ci  size_t cmd_size;
1481141cc406Sopenharmony_ci  SANE_Int devnum;
1482141cc406Sopenharmony_ci  SANE_Bool scan_head_moving;
1483141cc406Sopenharmony_ci  SANE_Byte read_result;
1484141cc406Sopenharmony_ci
1485141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_move_fwd: \n");
1486141cc406Sopenharmony_ci  devnum = dev->devnum;
1487141cc406Sopenharmony_ci
1488141cc406Sopenharmony_ci
1489141cc406Sopenharmony_ci  /* registers set-up */
1490141cc406Sopenharmony_ci  regs[0x2c] = 0x00;
1491141cc406Sopenharmony_ci  regs[0x2d] = 0x41;
1492141cc406Sopenharmony_ci  regs[0x65] = 0x80;
1493141cc406Sopenharmony_ci  switch (dev->model.sensor_type)
1494141cc406Sopenharmony_ci    {
1495141cc406Sopenharmony_ci    case X74_SENSOR:
1496141cc406Sopenharmony_ci      rts88xx_set_scan_frequency (regs, 0);
1497141cc406Sopenharmony_ci      regs[0x93] = 0x06;
1498141cc406Sopenharmony_ci      break;
1499141cc406Sopenharmony_ci    case X1100_B2_SENSOR:
1500141cc406Sopenharmony_ci      regs[0x8b] = 0x00;
1501141cc406Sopenharmony_ci      regs[0x8c] = 0x00;
1502141cc406Sopenharmony_ci      regs[0x93] = 0x06;
1503141cc406Sopenharmony_ci      break;
1504141cc406Sopenharmony_ci    case X1100_2C_SENSOR:
1505141cc406Sopenharmony_ci      rts88xx_set_scan_frequency (regs, 0);
1506141cc406Sopenharmony_ci      regs[0x93] = 0x06;
1507141cc406Sopenharmony_ci      break;
1508141cc406Sopenharmony_ci    case A920_SENSOR:
1509141cc406Sopenharmony_ci      rts88xx_set_scan_frequency (regs, 0);
1510141cc406Sopenharmony_ci      regs[0x8b] = 0xff;
1511141cc406Sopenharmony_ci      regs[0x8c] = 0x02;
1512141cc406Sopenharmony_ci      regs[0x93] = 0x0e;
1513141cc406Sopenharmony_ci      break;
1514141cc406Sopenharmony_ci    case X1200_SENSOR:
1515141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x01;
1516141cc406Sopenharmony_ci      rts88xx_set_scan_frequency (regs, 0);
1517141cc406Sopenharmony_ci      break;
1518141cc406Sopenharmony_ci    case X1200_USB2_SENSOR:
1519141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x4f;
1520141cc406Sopenharmony_ci      rts88xx_set_scan_frequency (regs, 0);
1521141cc406Sopenharmony_ci      break;
1522141cc406Sopenharmony_ci    }
1523141cc406Sopenharmony_ci
1524141cc406Sopenharmony_ci  /* set grayscale scan + nodata/nochannel?  */
1525141cc406Sopenharmony_ci  regs[0x2f] = 0xa1;
1526141cc406Sopenharmony_ci
1527141cc406Sopenharmony_ci  /* set ? */
1528141cc406Sopenharmony_ci  regs[0x34] = 0x50;
1529141cc406Sopenharmony_ci  regs[0x35] = 0x01;
1530141cc406Sopenharmony_ci  regs[0x36] = 0x50;
1531141cc406Sopenharmony_ci  regs[0x37] = 0x01;
1532141cc406Sopenharmony_ci  regs[0x38] = 0x50;
1533141cc406Sopenharmony_ci  /* set motor resolution divisor */
1534141cc406Sopenharmony_ci  regs[0x39] = 0x00;
1535141cc406Sopenharmony_ci  /* set vertical start/end positions */
1536141cc406Sopenharmony_ci  regs[0x60] = LOBYTE (distance - 1);
1537141cc406Sopenharmony_ci  regs[0x61] = HIBYTE (distance - 1);
1538141cc406Sopenharmony_ci  regs[0x62] = LOBYTE (distance);
1539141cc406Sopenharmony_ci  regs[0x63] = HIBYTE (distance);
1540141cc406Sopenharmony_ci  /* set horizontal start position */
1541141cc406Sopenharmony_ci  regs[0x66] = 0x64;
1542141cc406Sopenharmony_ci  regs[0x67] = 0x00;
1543141cc406Sopenharmony_ci  /* set horizontal end position */
1544141cc406Sopenharmony_ci  regs[0x6c] = 0xc8;
1545141cc406Sopenharmony_ci  regs[0x6d] = 0x00;
1546141cc406Sopenharmony_ci  /* set horizontal resolution */
1547141cc406Sopenharmony_ci  regs[0x79] = 0x40;
1548141cc406Sopenharmony_ci  regs[0x7a] = 0x01;
1549141cc406Sopenharmony_ci  /* don't buffer data for this scan */
1550141cc406Sopenharmony_ci  regs[0xb2] = 0x04;
1551141cc406Sopenharmony_ci  /* Motor enable & Coordinate space denominator */
1552141cc406Sopenharmony_ci  regs[0xc3] = 0x81;
1553141cc406Sopenharmony_ci  /* Movement direction & step size */
1554141cc406Sopenharmony_ci  regs[0xc6] = 0x09;
1555141cc406Sopenharmony_ci  /* ? */
1556141cc406Sopenharmony_ci  regs[0x80] = 0x00;
1557141cc406Sopenharmony_ci  regs[0x81] = 0x00;
1558141cc406Sopenharmony_ci  regs[0x82] = 0x00;
1559141cc406Sopenharmony_ci  regs[0xc5] = 0x0a;
1560141cc406Sopenharmony_ci
1561141cc406Sopenharmony_ci
1562141cc406Sopenharmony_ci  switch (dev->model.motor_type)
1563141cc406Sopenharmony_ci    {
1564141cc406Sopenharmony_ci    case X1100_MOTOR:
1565141cc406Sopenharmony_ci    case A920_MOTOR:
1566141cc406Sopenharmony_ci      /* step size range2 */
1567141cc406Sopenharmony_ci      regs[0xc9] = 0x3b;
1568141cc406Sopenharmony_ci      /* ? */
1569141cc406Sopenharmony_ci      regs[0xca] = 0x0a;
1570141cc406Sopenharmony_ci      /* motor curve stuff */
1571141cc406Sopenharmony_ci      regs[0xe0] = 0x00;
1572141cc406Sopenharmony_ci      regs[0xe1] = 0x00;
1573141cc406Sopenharmony_ci      regs[0xe4] = 0x00;
1574141cc406Sopenharmony_ci      regs[0xe5] = 0x00;
1575141cc406Sopenharmony_ci      regs[0xe7] = 0x00;
1576141cc406Sopenharmony_ci      regs[0xe8] = 0x00;
1577141cc406Sopenharmony_ci      regs[0xe2] = 0x09;
1578141cc406Sopenharmony_ci      regs[0xe3] = 0x1a;
1579141cc406Sopenharmony_ci      regs[0xe6] = 0xdc;
1580141cc406Sopenharmony_ci      regs[0xe9] = 0x1b;
1581141cc406Sopenharmony_ci      regs[0xec] = 0x07;
1582141cc406Sopenharmony_ci      regs[0xef] = 0x03;
1583141cc406Sopenharmony_ci      break;
1584141cc406Sopenharmony_ci    case X74_MOTOR:
1585141cc406Sopenharmony_ci      regs[0xc5] = 0x41;
1586141cc406Sopenharmony_ci      /* step size range2 */
1587141cc406Sopenharmony_ci      regs[0xc9] = 0x39;
1588141cc406Sopenharmony_ci      /* ? */
1589141cc406Sopenharmony_ci      regs[0xca] = 0x40;
1590141cc406Sopenharmony_ci      /* motor curve stuff */
1591141cc406Sopenharmony_ci      regs[0xe0] = 0x00;
1592141cc406Sopenharmony_ci      regs[0xe1] = 0x00;
1593141cc406Sopenharmony_ci      regs[0xe2] = 0x09;
1594141cc406Sopenharmony_ci      regs[0xe3] = 0x1a;
1595141cc406Sopenharmony_ci      regs[0xe4] = 0x00;
1596141cc406Sopenharmony_ci      regs[0xe5] = 0x00;
1597141cc406Sopenharmony_ci      regs[0xe6] = 0x64;
1598141cc406Sopenharmony_ci      regs[0xe7] = 0x00;
1599141cc406Sopenharmony_ci      regs[0xe8] = 0x00;
1600141cc406Sopenharmony_ci      regs[0xe9] = 0x32;
1601141cc406Sopenharmony_ci      regs[0xec] = 0x0c;
1602141cc406Sopenharmony_ci      regs[0xef] = 0x08;
1603141cc406Sopenharmony_ci      break;
1604141cc406Sopenharmony_ci    }
1605141cc406Sopenharmony_ci
1606141cc406Sopenharmony_ci
1607141cc406Sopenharmony_ci  /* prepare for register write */
1608141cc406Sopenharmony_ci  low_clr_c6 (devnum);
1609141cc406Sopenharmony_ci  low_stop_mvmt (devnum);
1610141cc406Sopenharmony_ci
1611141cc406Sopenharmony_ci/* Move Forward without scanning: */
1612141cc406Sopenharmony_ci  regs[0x32] = 0x00;
1613141cc406Sopenharmony_ci  low_write_all_regs (devnum, regs);
1614141cc406Sopenharmony_ci  regs[0x32] = 0x40;
1615141cc406Sopenharmony_ci  low_write_all_regs (devnum, regs);
1616141cc406Sopenharmony_ci
1617141cc406Sopenharmony_ci  /* Stop scanner - clear reg 0xb3: */
1618141cc406Sopenharmony_ci  /* low_stop_mvmt (devnum); */
1619141cc406Sopenharmony_ci
1620141cc406Sopenharmony_ci  rts88xx_commit (devnum, regs[0x2c]);
1621141cc406Sopenharmony_ci
1622141cc406Sopenharmony_ci  /* Poll for scanner stopped - return value(3:0) = 0: */
1623141cc406Sopenharmony_ci  scan_head_moving = SANE_TRUE;
1624141cc406Sopenharmony_ci  while (scan_head_moving)
1625141cc406Sopenharmony_ci    {
1626141cc406Sopenharmony_ci#ifdef FAKE_USB
1627141cc406Sopenharmony_ci      scan_head_moving = SANE_FALSE;
1628141cc406Sopenharmony_ci#else
1629141cc406Sopenharmony_ci      cmd_size = 0x04;
1630141cc406Sopenharmony_ci      low_usb_bulk_write (devnum, pollstopmoving_command_block, &cmd_size);
1631141cc406Sopenharmony_ci      cmd_size = 0x1;
1632141cc406Sopenharmony_ci      low_usb_bulk_read (devnum, &read_result, &cmd_size);
1633141cc406Sopenharmony_ci      if ((read_result & 0xF) == 0x0)
1634141cc406Sopenharmony_ci	{
1635141cc406Sopenharmony_ci	  scan_head_moving = SANE_FALSE;
1636141cc406Sopenharmony_ci	}
1637141cc406Sopenharmony_ci#endif
1638141cc406Sopenharmony_ci    }
1639141cc406Sopenharmony_ci
1640141cc406Sopenharmony_ci  /* this is needed to find the start line properly */
1641141cc406Sopenharmony_ci  if (dev->model.sensor_type == X74_SENSOR)
1642141cc406Sopenharmony_ci    low_stop_mvmt (devnum);
1643141cc406Sopenharmony_ci
1644141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_move_fwd: end.\n");
1645141cc406Sopenharmony_ci}
1646141cc406Sopenharmony_ci
1647141cc406Sopenharmony_ciSANE_Bool
1648141cc406Sopenharmony_cisanei_lexmark_low_search_home_fwd (Lexmark_Device * dev)
1649141cc406Sopenharmony_ci{
1650141cc406Sopenharmony_ci  /* This function actually searches backwards one line looking for home */
1651141cc406Sopenharmony_ci
1652141cc406Sopenharmony_ci  SANE_Int devnum;
1653141cc406Sopenharmony_ci  int i;
1654141cc406Sopenharmony_ci  SANE_Byte poll_result[3];
1655141cc406Sopenharmony_ci  SANE_Byte *buffer;
1656141cc406Sopenharmony_ci  SANE_Byte temp_byte;
1657141cc406Sopenharmony_ci
1658141cc406Sopenharmony_ci  static SANE_Byte command4_block[] = { 0x90, 0x00, 0x00, 0x03 };
1659141cc406Sopenharmony_ci
1660141cc406Sopenharmony_ci  static SANE_Byte command5_block[] = { 0x91, 0x00, 0x09, 0xc4 };
1661141cc406Sopenharmony_ci
1662141cc406Sopenharmony_ci  size_t cmd_size;
1663141cc406Sopenharmony_ci  SANE_Bool got_line;
1664141cc406Sopenharmony_ci  SANE_Bool ret_val;
1665141cc406Sopenharmony_ci
1666141cc406Sopenharmony_ci  devnum = dev->devnum;
1667141cc406Sopenharmony_ci
1668141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_search_home_fwd:\n");
1669141cc406Sopenharmony_ci
1670141cc406Sopenharmony_ci  /* set up registers according to the sensor type */
1671141cc406Sopenharmony_ci  switch (dev->model.sensor_type)
1672141cc406Sopenharmony_ci    {
1673141cc406Sopenharmony_ci    case X74_SENSOR:
1674141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x03;
1675141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x45;
1676141cc406Sopenharmony_ci      dev->shadow_regs[0x2f] = 0x21;
1677141cc406Sopenharmony_ci      dev->shadow_regs[0x30] = 0x48;
1678141cc406Sopenharmony_ci      dev->shadow_regs[0x31] = 0x06;
1679141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x05;
1680141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x05;
1681141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x09;
1682141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x09;
1683141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x0d;
1684141cc406Sopenharmony_ci      dev->shadow_regs[0x40] = 0x80;
1685141cc406Sopenharmony_ci      dev->shadow_regs[0x75] = 0x00;
1686141cc406Sopenharmony_ci      dev->shadow_regs[0x8b] = 0xff;
1687141cc406Sopenharmony_ci      dev->shadow_regs[0x93] = 0x06;
1688141cc406Sopenharmony_ci      break;
1689141cc406Sopenharmony_ci    case X1100_B2_SENSOR:
1690141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x0f;
1691141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x51;
1692141cc406Sopenharmony_ci      dev->shadow_regs[0x2f] = 0x21;
1693141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x04;
1694141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x04;
1695141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x08;
1696141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x08;
1697141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x0b;
1698141cc406Sopenharmony_ci      dev->shadow_regs[0x93] = 0x06;
1699141cc406Sopenharmony_ci      break;
1700141cc406Sopenharmony_ci    case X1100_2C_SENSOR:
1701141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x0d;
1702141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x4f;
1703141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x05;
1704141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x05;
1705141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x09;
1706141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x09;
1707141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x0d;
1708141cc406Sopenharmony_ci      dev->shadow_regs[0x40] = 0x80;
1709141cc406Sopenharmony_ci      dev->shadow_regs[0x72] = 0x35;
1710141cc406Sopenharmony_ci      dev->shadow_regs[0x74] = 0x4e;
1711141cc406Sopenharmony_ci
1712141cc406Sopenharmony_ci      dev->shadow_regs[0x85] = 0x20;	/* 05 */
1713141cc406Sopenharmony_ci      dev->shadow_regs[0x86] = 0x00;	/* 05 */
1714141cc406Sopenharmony_ci      dev->shadow_regs[0x87] = 0x00;	/* 05 */
1715141cc406Sopenharmony_ci      dev->shadow_regs[0x88] = 0x00;	/* 45 */
1716141cc406Sopenharmony_ci      dev->shadow_regs[0x89] = 0x00;
1717141cc406Sopenharmony_ci      dev->shadow_regs[0x8b] = 0xff;
1718141cc406Sopenharmony_ci
1719141cc406Sopenharmony_ci      dev->shadow_regs[0x93] = 0x06;	/* 0e */
1720141cc406Sopenharmony_ci
1721141cc406Sopenharmony_ci      dev->shadow_regs[0x75] = 0x00;	/*    */
1722141cc406Sopenharmony_ci      dev->shadow_regs[0x91] = 0x00;	/* 60 */
1723141cc406Sopenharmony_ci      dev->shadow_regs[0x92] = 0x00;	/* 8d */
1724141cc406Sopenharmony_ci      dev->shadow_regs[0xb1] = 0x00;	/*    */
1725141cc406Sopenharmony_ci      dev->shadow_regs[0xc5] = 0x00;	/*    */
1726141cc406Sopenharmony_ci      dev->shadow_regs[0xca] = 0x00;	/*    */
1727141cc406Sopenharmony_ci      dev->shadow_regs[0xc3] = 0x01;	/*    */
1728141cc406Sopenharmony_ci      break;
1729141cc406Sopenharmony_ci    case A920_SENSOR:
1730141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x0d;
1731141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x4f;
1732141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x05;
1733141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x05;
1734141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x09;
1735141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x09;
1736141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x0d;
1737141cc406Sopenharmony_ci      dev->shadow_regs[0x40] = 0x80;
1738141cc406Sopenharmony_ci      dev->shadow_regs[0x72] = 0x35;
1739141cc406Sopenharmony_ci      dev->shadow_regs[0x74] = 0x4e;
1740141cc406Sopenharmony_ci      dev->shadow_regs[0x85] = 0x05;
1741141cc406Sopenharmony_ci      dev->shadow_regs[0x88] = 0x45;
1742141cc406Sopenharmony_ci      dev->shadow_regs[0x89] = 0x00;
1743141cc406Sopenharmony_ci      dev->shadow_regs[0x8b] = 0xff;
1744141cc406Sopenharmony_ci      dev->shadow_regs[0x91] = 0x60;
1745141cc406Sopenharmony_ci      dev->shadow_regs[0x92] = 0x8d;
1746141cc406Sopenharmony_ci      dev->shadow_regs[0x93] = 0x0e;
1747141cc406Sopenharmony_ci      break;
1748141cc406Sopenharmony_ci    case X1200_SENSOR:
1749141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x01;
1750141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x03;
1751141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x04;
1752141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x04;
1753141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x08;
1754141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x08;
1755141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x0b;
1756141cc406Sopenharmony_ci      dev->shadow_regs[0x66] = 0x88;
1757141cc406Sopenharmony_ci      dev->shadow_regs[0x6c] = 0x10;
1758141cc406Sopenharmony_ci      dev->shadow_regs[0x6d] = 0x14;
1759141cc406Sopenharmony_ci      dev->shadow_regs[0x75] = 0x00;
1760141cc406Sopenharmony_ci      dev->shadow_regs[0x93] = 0x06;
1761141cc406Sopenharmony_ci      dev->shadow_regs[0xc5] = 0x00;
1762141cc406Sopenharmony_ci      dev->shadow_regs[0xca] = 0x00;
1763141cc406Sopenharmony_ci      break;
1764141cc406Sopenharmony_ci    case X1200_USB2_SENSOR:
1765141cc406Sopenharmony_ci      dev->shadow_regs[0x0b] = 0x70;
1766141cc406Sopenharmony_ci      dev->shadow_regs[0x0c] = 0x28;
1767141cc406Sopenharmony_ci      dev->shadow_regs[0x0d] = 0xa4;
1768141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x0d;
1769141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x4f;
1770141cc406Sopenharmony_ci      dev->shadow_regs[0x2f] = 0x21;
1771141cc406Sopenharmony_ci      dev->shadow_regs[0x32] = 0x40;
1772141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x05;
1773141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x05;
1774141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x09;
1775141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x09;
1776141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x0d;
1777141cc406Sopenharmony_ci      dev->shadow_regs[0x3a] = 0x20;
1778141cc406Sopenharmony_ci      dev->shadow_regs[0x3b] = 0x37;
1779141cc406Sopenharmony_ci      dev->shadow_regs[0x40] = 0x80;
1780141cc406Sopenharmony_ci      dev->shadow_regs[0x47] = 0x01;
1781141cc406Sopenharmony_ci      dev->shadow_regs[0x48] = 0x1a;
1782141cc406Sopenharmony_ci      dev->shadow_regs[0x49] = 0x5b;
1783141cc406Sopenharmony_ci      dev->shadow_regs[0x4a] = 0x1b;
1784141cc406Sopenharmony_ci      dev->shadow_regs[0x4b] = 0x5b;
1785141cc406Sopenharmony_ci      dev->shadow_regs[0x4c] = 0x05;
1786141cc406Sopenharmony_ci      dev->shadow_regs[0x4d] = 0x3f;
1787141cc406Sopenharmony_ci      dev->shadow_regs[0x75] = 0x00;
1788141cc406Sopenharmony_ci      dev->shadow_regs[0x85] = 0x03;
1789141cc406Sopenharmony_ci      dev->shadow_regs[0x86] = 0x33;
1790141cc406Sopenharmony_ci      dev->shadow_regs[0x87] = 0x8f;
1791141cc406Sopenharmony_ci      dev->shadow_regs[0x88] = 0x34;
1792141cc406Sopenharmony_ci      dev->shadow_regs[0x8b] = 0xff;
1793141cc406Sopenharmony_ci      dev->shadow_regs[0x8e] = 0x60;
1794141cc406Sopenharmony_ci      dev->shadow_regs[0x8f] = 0x80;
1795141cc406Sopenharmony_ci      dev->shadow_regs[0x91] = 0x59;
1796141cc406Sopenharmony_ci      dev->shadow_regs[0x92] = 0x10;
1797141cc406Sopenharmony_ci      dev->shadow_regs[0x93] = 0x06;
1798141cc406Sopenharmony_ci      dev->shadow_regs[0xa3] = 0x0d;
1799141cc406Sopenharmony_ci      dev->shadow_regs[0xa4] = 0x5e;
1800141cc406Sopenharmony_ci      dev->shadow_regs[0xa5] = 0x23;
1801141cc406Sopenharmony_ci      dev->shadow_regs[0xb1] = 0x07;
1802141cc406Sopenharmony_ci      dev->shadow_regs[0xc2] = 0x80;
1803141cc406Sopenharmony_ci      dev->shadow_regs[0xc5] = 0x00;
1804141cc406Sopenharmony_ci      dev->shadow_regs[0xca] = 0x00;
1805141cc406Sopenharmony_ci      break;
1806141cc406Sopenharmony_ci    }
1807141cc406Sopenharmony_ci  dev->shadow_regs[0x65] = 0x80;
1808141cc406Sopenharmony_ci  dev->shadow_regs[0x8c] = 0x02;
1809141cc406Sopenharmony_ci  dev->shadow_regs[0x8d] = 0x01;
1810141cc406Sopenharmony_ci  dev->shadow_regs[0xb2] = 0x00;
1811141cc406Sopenharmony_ci  dev->shadow_regs[0xed] = 0x00;
1812141cc406Sopenharmony_ci  dev->shadow_regs[0xee] = 0x00;
1813141cc406Sopenharmony_ci
1814141cc406Sopenharmony_ci  rts88xx_set_gain (dev->shadow_regs, dev->sensor->default_gain,
1815141cc406Sopenharmony_ci		    dev->sensor->default_gain, dev->sensor->default_gain);
1816141cc406Sopenharmony_ci  rts88xx_set_offset (dev->shadow_regs, 0x80, 0x80, 0x80);
1817141cc406Sopenharmony_ci
1818141cc406Sopenharmony_ci  /* set grayscale scan */
1819141cc406Sopenharmony_ci  rts88xx_set_gray_scan (dev->shadow_regs);
1820141cc406Sopenharmony_ci
1821141cc406Sopenharmony_ci  /* set motor resolution divisor */
1822141cc406Sopenharmony_ci  dev->shadow_regs[0x39] = 0x07;
1823141cc406Sopenharmony_ci
1824141cc406Sopenharmony_ci  /* set vertical start/end positions */
1825141cc406Sopenharmony_ci  dev->shadow_regs[0x60] = 0x01;
1826141cc406Sopenharmony_ci  dev->shadow_regs[0x61] = 0x00;
1827141cc406Sopenharmony_ci  dev->shadow_regs[0x62] = 0x02;
1828141cc406Sopenharmony_ci  dev->shadow_regs[0x63] = 0x00;
1829141cc406Sopenharmony_ci
1830141cc406Sopenharmony_ci  /* set # of head moves per CIS read */
1831141cc406Sopenharmony_ci  rts88xx_set_scan_frequency (dev->shadow_regs, 1);
1832141cc406Sopenharmony_ci
1833141cc406Sopenharmony_ci  /* set horizontal start position */
1834141cc406Sopenharmony_ci  dev->shadow_regs[0x66] = 0x6a;	/* 0x88 for X1200 */
1835141cc406Sopenharmony_ci  dev->shadow_regs[0x67] = 0x00;
1836141cc406Sopenharmony_ci  /* set horizontal end position */
1837141cc406Sopenharmony_ci  dev->shadow_regs[0x6c] = 0xf2;	/* 0x1410 for X1200 */
1838141cc406Sopenharmony_ci  dev->shadow_regs[0x6d] = 0x13;
1839141cc406Sopenharmony_ci  /* set horizontal resolution */
1840141cc406Sopenharmony_ci  dev->shadow_regs[0x79] = 0x40;
1841141cc406Sopenharmony_ci  dev->shadow_regs[0x7a] = 0x02;
1842141cc406Sopenharmony_ci  /* Motor disable & Coordinate space denominator */
1843141cc406Sopenharmony_ci  dev->shadow_regs[0xc3] = 0x01;
1844141cc406Sopenharmony_ci  /* Movement direction & step size */
1845141cc406Sopenharmony_ci  dev->shadow_regs[0xc6] = 0x01;
1846141cc406Sopenharmony_ci
1847141cc406Sopenharmony_ci  switch (dev->model.motor_type)
1848141cc406Sopenharmony_ci    {
1849141cc406Sopenharmony_ci    case A920_MOTOR:
1850141cc406Sopenharmony_ci    case X1100_MOTOR:
1851141cc406Sopenharmony_ci      /* step size range2 */
1852141cc406Sopenharmony_ci      dev->shadow_regs[0xc9] = 0x3b;
1853141cc406Sopenharmony_ci      /* step size range0 */
1854141cc406Sopenharmony_ci      dev->shadow_regs[0xe2] = 0x01;
1855141cc406Sopenharmony_ci      /* ? */
1856141cc406Sopenharmony_ci      dev->shadow_regs[0xe3] = 0x03;
1857141cc406Sopenharmony_ci      break;
1858141cc406Sopenharmony_ci    case X74_MOTOR:
1859141cc406Sopenharmony_ci      dev->shadow_regs[0xc4] = 0x20;
1860141cc406Sopenharmony_ci      dev->shadow_regs[0xc5] = 0x00;
1861141cc406Sopenharmony_ci      dev->shadow_regs[0xc8] = 0x04;
1862141cc406Sopenharmony_ci      /* step size range2 */
1863141cc406Sopenharmony_ci      dev->shadow_regs[0xc9] = 0x39;
1864141cc406Sopenharmony_ci      dev->shadow_regs[0xca] = 0x00;
1865141cc406Sopenharmony_ci      /* motor curve stuff */
1866141cc406Sopenharmony_ci      dev->shadow_regs[0xe0] = 0x29;
1867141cc406Sopenharmony_ci      dev->shadow_regs[0xe1] = 0x17;
1868141cc406Sopenharmony_ci      dev->shadow_regs[0xe2] = 0x8f;
1869141cc406Sopenharmony_ci      dev->shadow_regs[0xe3] = 0x06;
1870141cc406Sopenharmony_ci      dev->shadow_regs[0xe4] = 0x61;
1871141cc406Sopenharmony_ci      dev->shadow_regs[0xe5] = 0x16;
1872141cc406Sopenharmony_ci      dev->shadow_regs[0xe6] = 0x64;
1873141cc406Sopenharmony_ci      dev->shadow_regs[0xe7] = 0xb5;
1874141cc406Sopenharmony_ci      dev->shadow_regs[0xe8] = 0x08;
1875141cc406Sopenharmony_ci      dev->shadow_regs[0xe9] = 0x32;
1876141cc406Sopenharmony_ci      dev->shadow_regs[0xec] = 0x0c;
1877141cc406Sopenharmony_ci      dev->shadow_regs[0xef] = 0x08;
1878141cc406Sopenharmony_ci      break;
1879141cc406Sopenharmony_ci    }
1880141cc406Sopenharmony_ci
1881141cc406Sopenharmony_ci  /* Stop the scanner */
1882141cc406Sopenharmony_ci  low_stop_mvmt (devnum);
1883141cc406Sopenharmony_ci
1884141cc406Sopenharmony_ci  /* write regs out twice */
1885141cc406Sopenharmony_ci  dev->shadow_regs[0x32] = 0x00;
1886141cc406Sopenharmony_ci  low_write_all_regs (devnum, dev->shadow_regs);
1887141cc406Sopenharmony_ci  dev->shadow_regs[0x32] = 0x40;
1888141cc406Sopenharmony_ci  low_write_all_regs (devnum, dev->shadow_regs);
1889141cc406Sopenharmony_ci
1890141cc406Sopenharmony_ci  /* Start Scan */
1891141cc406Sopenharmony_ci  rts88xx_commit (devnum, dev->shadow_regs[0x2c]);
1892141cc406Sopenharmony_ci
1893141cc406Sopenharmony_ci  /* Poll the available byte count until not 0 */
1894141cc406Sopenharmony_ci  got_line = SANE_FALSE;
1895141cc406Sopenharmony_ci  while (!got_line)
1896141cc406Sopenharmony_ci    {
1897141cc406Sopenharmony_ci      cmd_size = 4;
1898141cc406Sopenharmony_ci      low_usb_bulk_write (devnum, command4_block, &cmd_size);
1899141cc406Sopenharmony_ci      cmd_size = 0x3;
1900141cc406Sopenharmony_ci      low_usb_bulk_read (devnum, poll_result, &cmd_size);
1901141cc406Sopenharmony_ci      if (!
1902141cc406Sopenharmony_ci	  (poll_result[0] == 0 && poll_result[1] == 0 && poll_result[2] == 0))
1903141cc406Sopenharmony_ci	{
1904141cc406Sopenharmony_ci	  /* if result != 00 00 00 we got data */
1905141cc406Sopenharmony_ci	  got_line = SANE_TRUE;
1906141cc406Sopenharmony_ci	}
1907141cc406Sopenharmony_ci    }
1908141cc406Sopenharmony_ci
1909141cc406Sopenharmony_ci  /* create buffer for scan data */
1910141cc406Sopenharmony_ci  buffer = calloc (2500, sizeof (char));
1911141cc406Sopenharmony_ci  if (buffer == NULL)
1912141cc406Sopenharmony_ci    {
1913141cc406Sopenharmony_ci      return SANE_FALSE;
1914141cc406Sopenharmony_ci    }
1915141cc406Sopenharmony_ci
1916141cc406Sopenharmony_ci  /* Tell the scanner to send the data */
1917141cc406Sopenharmony_ci  /* Write: 91 00 09 c4 */
1918141cc406Sopenharmony_ci  cmd_size = 4;
1919141cc406Sopenharmony_ci  low_usb_bulk_write (devnum, command5_block, &cmd_size);
1920141cc406Sopenharmony_ci  /* Read it */
1921141cc406Sopenharmony_ci  cmd_size = 0x09c4;
1922141cc406Sopenharmony_ci  low_usb_bulk_read (devnum, buffer, &cmd_size);
1923141cc406Sopenharmony_ci
1924141cc406Sopenharmony_ci  /* Reverse order of bytes in words of buffer */
1925141cc406Sopenharmony_ci  for (i = 0; i < 2500; i = i + 2)
1926141cc406Sopenharmony_ci    {
1927141cc406Sopenharmony_ci      temp_byte = *(buffer + i);
1928141cc406Sopenharmony_ci      *(buffer + i) = *(buffer + i + 1);
1929141cc406Sopenharmony_ci      *(buffer + i + 1) = temp_byte;
1930141cc406Sopenharmony_ci    }
1931141cc406Sopenharmony_ci
1932141cc406Sopenharmony_ci  /* check for home position */
1933141cc406Sopenharmony_ci  ret_val = low_is_home_line (dev, buffer);
1934141cc406Sopenharmony_ci
1935141cc406Sopenharmony_ci  if (ret_val)
1936141cc406Sopenharmony_ci    DBG (2, "sanei_lexmark_low_search_home_fwd: !!!HOME POSITION!!!\n");
1937141cc406Sopenharmony_ci
1938141cc406Sopenharmony_ci  /* free the buffer */
1939141cc406Sopenharmony_ci  free (buffer);
1940141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_search_home_fwd: end.\n");
1941141cc406Sopenharmony_ci
1942141cc406Sopenharmony_ci  return ret_val;
1943141cc406Sopenharmony_ci}
1944141cc406Sopenharmony_ci
1945141cc406Sopenharmony_ciSANE_Bool
1946141cc406Sopenharmony_cisanei_lexmark_low_search_home_bwd (Lexmark_Device * dev)
1947141cc406Sopenharmony_ci{
1948141cc406Sopenharmony_ci/* This function must only be called if the scan head is past the home dot.
1949141cc406Sopenharmony_ci   It could damage the scanner if not.
1950141cc406Sopenharmony_ci
1951141cc406Sopenharmony_ci   This function tells the scanner to do a grayscale scan backwards with a
1952141cc406Sopenharmony_ci   300dpi resolution. It reads 2500 bytes of data between horizontal
1953141cc406Sopenharmony_ci   coordinates 0x6a and 0x13f2.
1954141cc406Sopenharmony_ci
1955141cc406Sopenharmony_ci   The scan is set to read between vertical coordinates from 0x0a to 0x0f46,
1956141cc406Sopenharmony_ci   or 3900 lines. This equates to 13" at 300dpi, so we must stop the scan
1957141cc406Sopenharmony_ci   before it bangs against the end. A line limit is set so that a maximum of
1958141cc406Sopenharmony_ci   0x0F3C (13"*300dpi) lines can be read.
1959141cc406Sopenharmony_ci
1960141cc406Sopenharmony_ci   To read the scan data we create a buffer space large enough to hold 10
1961141cc406Sopenharmony_ci   lines of data. For each read we poll twice, ignoring the first poll. This
1962141cc406Sopenharmony_ci   is required for timing. We repeat the double poll until there is data
1963141cc406Sopenharmony_ci   available. The number of lines (or number of buffers in our buffer space)
1964141cc406Sopenharmony_ci   is calculated from the size of the data available from the scanner. The
1965141cc406Sopenharmony_ci   number of buffers is calculated as the space required to hold 1.5 times
1966141cc406Sopenharmony_ci   the size of the data available from the scanner.
1967141cc406Sopenharmony_ci
1968141cc406Sopenharmony_ci   After data is read from the scanner each line is checked if it is on the
1969141cc406Sopenharmony_ci   home dot. Lines are continued to be read until we are no longer on the home
1970141cc406Sopenharmony_ci   dot. */
1971141cc406Sopenharmony_ci
1972141cc406Sopenharmony_ci
1973141cc406Sopenharmony_ci  SANE_Int devnum;
1974141cc406Sopenharmony_ci  SANE_Status status;
1975141cc406Sopenharmony_ci  int i, j;
1976141cc406Sopenharmony_ci  SANE_Byte poll_result[3];
1977141cc406Sopenharmony_ci  SANE_Byte *buffer;
1978141cc406Sopenharmony_ci  SANE_Byte *buffer_start;
1979141cc406Sopenharmony_ci  SANE_Byte temp_byte;
1980141cc406Sopenharmony_ci
1981141cc406Sopenharmony_ci  SANE_Int buffer_count = 0;
1982141cc406Sopenharmony_ci  SANE_Int size_requested;
1983141cc406Sopenharmony_ci  SANE_Int size_returned;
1984141cc406Sopenharmony_ci  SANE_Int no_of_buffers;
1985141cc406Sopenharmony_ci  SANE_Int buffer_limit = 0xF3C;
1986141cc406Sopenharmony_ci
1987141cc406Sopenharmony_ci  SANE_Int high_byte, mid_byte, low_byte;
1988141cc406Sopenharmony_ci  SANE_Int home_line_count;
1989141cc406Sopenharmony_ci  SANE_Bool in_home_region;
1990141cc406Sopenharmony_ci
1991141cc406Sopenharmony_ci  static SANE_Byte command4_block[] = { 0x90, 0x00, 0x00, 0x03 };
1992141cc406Sopenharmony_ci
1993141cc406Sopenharmony_ci  static SANE_Byte command5_block[] = { 0x91, 0x00, 0xff, 0xc0 };
1994141cc406Sopenharmony_ci#ifdef DEEP_DEBUG
1995141cc406Sopenharmony_ci  FILE *img = NULL;
1996141cc406Sopenharmony_ci#endif
1997141cc406Sopenharmony_ci
1998141cc406Sopenharmony_ci  size_t cmd_size;
1999141cc406Sopenharmony_ci  SANE_Bool got_line;
2000141cc406Sopenharmony_ci
2001141cc406Sopenharmony_ci  devnum = dev->devnum;
2002141cc406Sopenharmony_ci
2003141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_search_home_bwd:\n");
2004141cc406Sopenharmony_ci
2005141cc406Sopenharmony_ci  /* set up registers */
2006141cc406Sopenharmony_ci  switch (dev->model.sensor_type)
2007141cc406Sopenharmony_ci    {
2008141cc406Sopenharmony_ci    case X74_SENSOR:
2009141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x03;
2010141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x45;
2011141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x09;
2012141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x09;
2013141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x11;
2014141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x11;
2015141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x19;
2016141cc406Sopenharmony_ci      dev->shadow_regs[0x85] = 0x00;
2017141cc406Sopenharmony_ci      dev->shadow_regs[0x93] = 0x06;
2018141cc406Sopenharmony_ci      dev->shadow_regs[0x40] = 0x80;
2019141cc406Sopenharmony_ci      /* important for detection of b/w transitions */
2020141cc406Sopenharmony_ci      dev->shadow_regs[0x75] = 0x00;
2021141cc406Sopenharmony_ci      dev->shadow_regs[0x8b] = 0xff;
2022141cc406Sopenharmony_ci      break;
2023141cc406Sopenharmony_ci    case X1100_B2_SENSOR:
2024141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x0f;
2025141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x51;
2026141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x07;
2027141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x07;
2028141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x0f;
2029141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x0f;
2030141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x15;
2031141cc406Sopenharmony_ci      dev->shadow_regs[0x85] = 0x20;
2032141cc406Sopenharmony_ci      dev->shadow_regs[0x93] = 0x06;
2033141cc406Sopenharmony_ci      break;
2034141cc406Sopenharmony_ci    case X1100_2C_SENSOR:
2035141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x0d;
2036141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x4f;
2037141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x09;
2038141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x09;
2039141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x11;
2040141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x11;
2041141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x19;
2042141cc406Sopenharmony_ci      dev->shadow_regs[0x85] = 0x20;
2043141cc406Sopenharmony_ci      dev->shadow_regs[0x93] = 0x06;
2044141cc406Sopenharmony_ci      break;
2045141cc406Sopenharmony_ci    case A920_SENSOR:
2046141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x0d;
2047141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x4f;
2048141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x09;
2049141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x09;
2050141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x11;
2051141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x11;
2052141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x19;
2053141cc406Sopenharmony_ci      dev->shadow_regs[0x85] = 0x05;
2054141cc406Sopenharmony_ci      dev->shadow_regs[0x93] = 0x0e;
2055141cc406Sopenharmony_ci      break;
2056141cc406Sopenharmony_ci    case X1200_SENSOR:
2057141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x01;
2058141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x03;
2059141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x07;
2060141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x07;
2061141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x0f;
2062141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x0f;
2063141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x15;
2064141cc406Sopenharmony_ci      break;
2065141cc406Sopenharmony_ci
2066141cc406Sopenharmony_ci    case X1200_USB2_SENSOR:
2067141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x0d;
2068141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x4f;
2069141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x09;
2070141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x09;
2071141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x11;
2072141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x11;
2073141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x19;
2074141cc406Sopenharmony_ci      dev->shadow_regs[0x85] = 0x03;
2075141cc406Sopenharmony_ci      dev->shadow_regs[0x93] = 0x06;
2076141cc406Sopenharmony_ci      break;
2077141cc406Sopenharmony_ci    }
2078141cc406Sopenharmony_ci  rts88xx_set_gain (dev->shadow_regs, dev->sensor->default_gain,
2079141cc406Sopenharmony_ci		    dev->sensor->default_gain, dev->sensor->default_gain);
2080141cc406Sopenharmony_ci  dev->shadow_regs[0x65] = 0x80;
2081141cc406Sopenharmony_ci  dev->shadow_regs[0x8b] = 0xff;
2082141cc406Sopenharmony_ci  dev->shadow_regs[0x8c] = 0x02;
2083141cc406Sopenharmony_ci  dev->shadow_regs[0xb2] = 0x00;
2084141cc406Sopenharmony_ci
2085141cc406Sopenharmony_ci  /* set calibration */
2086141cc406Sopenharmony_ci  rts88xx_set_offset (dev->shadow_regs, 0x80, 0x80, 0x80);
2087141cc406Sopenharmony_ci
2088141cc406Sopenharmony_ci  /* set grayscale  scan  */
2089141cc406Sopenharmony_ci  dev->shadow_regs[0x2f] = 0x21;
2090141cc406Sopenharmony_ci  /* set motor resolution divisor */
2091141cc406Sopenharmony_ci  dev->shadow_regs[0x39] = 0x03;
2092141cc406Sopenharmony_ci  /* set vertical start/end positions */
2093141cc406Sopenharmony_ci  dev->shadow_regs[0x60] = 0x0a;
2094141cc406Sopenharmony_ci  dev->shadow_regs[0x61] = 0x00;
2095141cc406Sopenharmony_ci  dev->shadow_regs[0x62] = 0x46;
2096141cc406Sopenharmony_ci  dev->shadow_regs[0x63] = 0x0f;
2097141cc406Sopenharmony_ci  /* set # of head moves per CIS read */
2098141cc406Sopenharmony_ci  rts88xx_set_scan_frequency (dev->shadow_regs, 2);
2099141cc406Sopenharmony_ci  /* set horizontal start position */
2100141cc406Sopenharmony_ci  dev->shadow_regs[0x66] = 0x6a;	/* 0x88 for X1200 */
2101141cc406Sopenharmony_ci  dev->shadow_regs[0x67] = 0x00;
2102141cc406Sopenharmony_ci  /* set horizontal end position */
2103141cc406Sopenharmony_ci  dev->shadow_regs[0x6c] = 0xf2;	/* 0x1410 for X1200, 13f2 for X1200/rev. 97 */
2104141cc406Sopenharmony_ci  dev->shadow_regs[0x6d] = 0x13;
2105141cc406Sopenharmony_ci  /* set horizontal resolution */
2106141cc406Sopenharmony_ci  dev->shadow_regs[0x79] = 0x40;
2107141cc406Sopenharmony_ci  dev->shadow_regs[0x7a] = 0x02;
2108141cc406Sopenharmony_ci
2109141cc406Sopenharmony_ci  /* Movement direction & step size */
2110141cc406Sopenharmony_ci  dev->shadow_regs[0xc6] = 0x01;
2111141cc406Sopenharmony_ci  /* Motor enable & Coordinate space denominator */
2112141cc406Sopenharmony_ci  dev->shadow_regs[0xc3] = 0x81;
2113141cc406Sopenharmony_ci
2114141cc406Sopenharmony_ci  switch (dev->model.motor_type)
2115141cc406Sopenharmony_ci    {
2116141cc406Sopenharmony_ci    case X74_MOTOR:
2117141cc406Sopenharmony_ci      dev->shadow_regs[0xc4] = 0x20;
2118141cc406Sopenharmony_ci      dev->shadow_regs[0xc5] = 0x00;
2119141cc406Sopenharmony_ci      dev->shadow_regs[0xc8] = 0x04;
2120141cc406Sopenharmony_ci      /* step size range2 */
2121141cc406Sopenharmony_ci      dev->shadow_regs[0xc9] = 0x39;
2122141cc406Sopenharmony_ci      dev->shadow_regs[0xca] = 0x00;
2123141cc406Sopenharmony_ci      /* motor curve stuff */
2124141cc406Sopenharmony_ci      dev->shadow_regs[0xe0] = 0x29;
2125141cc406Sopenharmony_ci      dev->shadow_regs[0xe1] = 0x17;
2126141cc406Sopenharmony_ci      dev->shadow_regs[0xe2] = 0x8f;
2127141cc406Sopenharmony_ci      dev->shadow_regs[0xe3] = 0x06;
2128141cc406Sopenharmony_ci      dev->shadow_regs[0xe4] = 0x61;
2129141cc406Sopenharmony_ci      dev->shadow_regs[0xe5] = 0x16;
2130141cc406Sopenharmony_ci      dev->shadow_regs[0xe6] = 0x64;
2131141cc406Sopenharmony_ci      dev->shadow_regs[0xe7] = 0xb5;
2132141cc406Sopenharmony_ci      dev->shadow_regs[0xe8] = 0x08;
2133141cc406Sopenharmony_ci      dev->shadow_regs[0xe9] = 0x32;
2134141cc406Sopenharmony_ci      dev->shadow_regs[0xec] = 0x0c;
2135141cc406Sopenharmony_ci      dev->shadow_regs[0xef] = 0x08;
2136141cc406Sopenharmony_ci      break;
2137141cc406Sopenharmony_ci    case A920_MOTOR:
2138141cc406Sopenharmony_ci    case X1100_MOTOR:
2139141cc406Sopenharmony_ci      /* ? */
2140141cc406Sopenharmony_ci      dev->shadow_regs[0xc5] = 0x19;
2141141cc406Sopenharmony_ci      /* step size range2 */
2142141cc406Sopenharmony_ci      dev->shadow_regs[0xc9] = 0x3a;
2143141cc406Sopenharmony_ci      /* ? */
2144141cc406Sopenharmony_ci      dev->shadow_regs[0xca] = 0x08;
2145141cc406Sopenharmony_ci      /* motor curve stuff */
2146141cc406Sopenharmony_ci      dev->shadow_regs[0xe0] = 0xe3;
2147141cc406Sopenharmony_ci      dev->shadow_regs[0xe1] = 0x18;
2148141cc406Sopenharmony_ci      dev->shadow_regs[0xe2] = 0x03;
2149141cc406Sopenharmony_ci      dev->shadow_regs[0xe3] = 0x06;
2150141cc406Sopenharmony_ci      dev->shadow_regs[0xe4] = 0x2b;
2151141cc406Sopenharmony_ci      dev->shadow_regs[0xe5] = 0x17;
2152141cc406Sopenharmony_ci      dev->shadow_regs[0xe6] = 0xdc;
2153141cc406Sopenharmony_ci      dev->shadow_regs[0xe7] = 0xb3;
2154141cc406Sopenharmony_ci      dev->shadow_regs[0xe8] = 0x07;
2155141cc406Sopenharmony_ci      dev->shadow_regs[0xe9] = 0x1b;
2156141cc406Sopenharmony_ci      dev->shadow_regs[0xec] = 0x07;
2157141cc406Sopenharmony_ci      dev->shadow_regs[0xef] = 0x03;
2158141cc406Sopenharmony_ci      break;
2159141cc406Sopenharmony_ci    }
2160141cc406Sopenharmony_ci
2161141cc406Sopenharmony_ci  /* Stop the scanner */
2162141cc406Sopenharmony_ci  low_stop_mvmt (devnum);
2163141cc406Sopenharmony_ci
2164141cc406Sopenharmony_ci  /* write regs out twice */
2165141cc406Sopenharmony_ci  dev->shadow_regs[0x32] = 0x00;
2166141cc406Sopenharmony_ci  low_write_all_regs (devnum, dev->shadow_regs);
2167141cc406Sopenharmony_ci  dev->shadow_regs[0x32] = 0x40;
2168141cc406Sopenharmony_ci  low_write_all_regs (devnum, dev->shadow_regs);
2169141cc406Sopenharmony_ci
2170141cc406Sopenharmony_ci  /* Start Scan */
2171141cc406Sopenharmony_ci  status = rts88xx_commit (devnum, dev->shadow_regs[0x2c]);
2172141cc406Sopenharmony_ci
2173141cc406Sopenharmony_ci  /* create buffer to hold up to 10 lines of  scan data */
2174141cc406Sopenharmony_ci  buffer = calloc (10 * 2500, sizeof (char));
2175141cc406Sopenharmony_ci  if (buffer == NULL)
2176141cc406Sopenharmony_ci    {
2177141cc406Sopenharmony_ci      return SANE_FALSE;
2178141cc406Sopenharmony_ci    }
2179141cc406Sopenharmony_ci
2180141cc406Sopenharmony_ci  home_line_count = 0;
2181141cc406Sopenharmony_ci  in_home_region = SANE_FALSE;
2182141cc406Sopenharmony_ci
2183141cc406Sopenharmony_ci#ifdef DEEP_DEBUG
2184141cc406Sopenharmony_ci  img = fopen ("find_bwd.pnm", "wb");
2185141cc406Sopenharmony_ci  fprintf (img, "P5\n2500 100\n255\n");
2186141cc406Sopenharmony_ci#endif
2187141cc406Sopenharmony_ci  while (buffer_count < buffer_limit)
2188141cc406Sopenharmony_ci    {
2189141cc406Sopenharmony_ci      size_returned = 0;
2190141cc406Sopenharmony_ci      got_line = SANE_FALSE;
2191141cc406Sopenharmony_ci      while (!got_line)
2192141cc406Sopenharmony_ci	{
2193141cc406Sopenharmony_ci	  /* always poll twice (needed for timing) - disregard 1st poll */
2194141cc406Sopenharmony_ci	  cmd_size = 4;
2195141cc406Sopenharmony_ci	  status = low_usb_bulk_write (devnum, command4_block, &cmd_size);
2196141cc406Sopenharmony_ci	  if (status != SANE_STATUS_GOOD)
2197141cc406Sopenharmony_ci	    return SANE_FALSE;
2198141cc406Sopenharmony_ci	  cmd_size = 0x3;
2199141cc406Sopenharmony_ci	  status = low_usb_bulk_read (devnum, poll_result, &cmd_size);
2200141cc406Sopenharmony_ci	  if (status != SANE_STATUS_GOOD)
2201141cc406Sopenharmony_ci	    return SANE_FALSE;
2202141cc406Sopenharmony_ci	  cmd_size = 4;
2203141cc406Sopenharmony_ci	  status = low_usb_bulk_write (devnum, command4_block, &cmd_size);
2204141cc406Sopenharmony_ci	  if (status != SANE_STATUS_GOOD)
2205141cc406Sopenharmony_ci	    return SANE_FALSE;
2206141cc406Sopenharmony_ci	  cmd_size = 0x3;
2207141cc406Sopenharmony_ci	  status = low_usb_bulk_read (devnum, poll_result, &cmd_size);
2208141cc406Sopenharmony_ci	  if (status != SANE_STATUS_GOOD)
2209141cc406Sopenharmony_ci	    return SANE_FALSE;
2210141cc406Sopenharmony_ci	  if (!
2211141cc406Sopenharmony_ci	      (poll_result[0] == 0 && poll_result[1] == 0
2212141cc406Sopenharmony_ci	       && poll_result[2] == 0))
2213141cc406Sopenharmony_ci	    {
2214141cc406Sopenharmony_ci	      /* if result != 00 00 00 we got data */
2215141cc406Sopenharmony_ci	      got_line = SANE_TRUE;
2216141cc406Sopenharmony_ci	      high_byte = poll_result[2] << 16;
2217141cc406Sopenharmony_ci	      mid_byte = poll_result[1] << 8;
2218141cc406Sopenharmony_ci	      low_byte = poll_result[0];
2219141cc406Sopenharmony_ci	      size_returned = high_byte + mid_byte + low_byte;
2220141cc406Sopenharmony_ci	    }
2221141cc406Sopenharmony_ci	}
2222141cc406Sopenharmony_ci
2223141cc406Sopenharmony_ci      /*size_requested = size_returned;*/
2224141cc406Sopenharmony_ci      size_requested = 2500;
2225141cc406Sopenharmony_ci      no_of_buffers = size_returned * 3;
2226141cc406Sopenharmony_ci      no_of_buffers = no_of_buffers / 2500;
2227141cc406Sopenharmony_ci      no_of_buffers = no_of_buffers >> 1;
2228141cc406Sopenharmony_ci      /* force 1 buffer at a time to improve accuracy, which slow downs search */
2229141cc406Sopenharmony_ci      no_of_buffers = 1;
2230141cc406Sopenharmony_ci
2231141cc406Sopenharmony_ci      if (no_of_buffers < 1)
2232141cc406Sopenharmony_ci	no_of_buffers = 1;
2233141cc406Sopenharmony_ci      else if (no_of_buffers > 10)
2234141cc406Sopenharmony_ci	no_of_buffers = 10;
2235141cc406Sopenharmony_ci      buffer_count = buffer_count + no_of_buffers;
2236141cc406Sopenharmony_ci
2237141cc406Sopenharmony_ci      size_requested = no_of_buffers * 2500;
2238141cc406Sopenharmony_ci
2239141cc406Sopenharmony_ci      /* Tell the scanner to send the data */
2240141cc406Sopenharmony_ci      /* Write: 91 <size_requested> */
2241141cc406Sopenharmony_ci      command5_block[1] = (SANE_Byte) (size_requested >> 16);
2242141cc406Sopenharmony_ci      command5_block[2] = (SANE_Byte) (size_requested >> 8);
2243141cc406Sopenharmony_ci      command5_block[3] = (SANE_Byte) (size_requested & 0xFF);
2244141cc406Sopenharmony_ci
2245141cc406Sopenharmony_ci      cmd_size = 4;
2246141cc406Sopenharmony_ci      status = low_usb_bulk_write (devnum, command5_block, &cmd_size);
2247141cc406Sopenharmony_ci      if (status != SANE_STATUS_GOOD)
2248141cc406Sopenharmony_ci	return SANE_FALSE;
2249141cc406Sopenharmony_ci      /* Read it */
2250141cc406Sopenharmony_ci      cmd_size = size_requested;
2251141cc406Sopenharmony_ci      status = low_usb_bulk_read (devnum, buffer, &cmd_size);
2252141cc406Sopenharmony_ci      if (status != SANE_STATUS_GOOD)
2253141cc406Sopenharmony_ci	return SANE_FALSE;
2254141cc406Sopenharmony_ci      for (i = 0; i < no_of_buffers; i++)
2255141cc406Sopenharmony_ci	{
2256141cc406Sopenharmony_ci	  buffer_start = buffer + (i * 2500);
2257141cc406Sopenharmony_ci	  /* Reverse order of bytes in words of buffer */
2258141cc406Sopenharmony_ci	  for (j = 0; j < 2500; j = j + 2)
2259141cc406Sopenharmony_ci	    {
2260141cc406Sopenharmony_ci	      temp_byte = *(buffer_start + j);
2261141cc406Sopenharmony_ci	      *(buffer_start + j) = *(buffer_start + j + 1);
2262141cc406Sopenharmony_ci	      *(buffer_start + j + 1) = temp_byte;
2263141cc406Sopenharmony_ci	    }
2264141cc406Sopenharmony_ci#ifdef DEEP_DEBUG
2265141cc406Sopenharmony_ci	  fwrite (buffer + (i * 2500), 2500, 1, img);
2266141cc406Sopenharmony_ci#endif
2267141cc406Sopenharmony_ci	  if (low_is_home_line (dev, buffer_start))
2268141cc406Sopenharmony_ci	    {
2269141cc406Sopenharmony_ci	      home_line_count++;
2270141cc406Sopenharmony_ci	      if (home_line_count > 7)
2271141cc406Sopenharmony_ci		in_home_region = SANE_TRUE;
2272141cc406Sopenharmony_ci	    }
2273141cc406Sopenharmony_ci	  if (in_home_region)
2274141cc406Sopenharmony_ci	    {
2275141cc406Sopenharmony_ci	      /* slow down scanning : on purpose backtracking */
2276141cc406Sopenharmony_ci	      if (home_line_count)
2277141cc406Sopenharmony_ci		sleep (1);
2278141cc406Sopenharmony_ci	      free (buffer);
2279141cc406Sopenharmony_ci#ifdef DEEP_DEBUG
2280141cc406Sopenharmony_ci	      fflush (img);
2281141cc406Sopenharmony_ci	      i = ftell (img) / 2500;
2282141cc406Sopenharmony_ci	      rewind (img);
2283141cc406Sopenharmony_ci	      DBG (2, "sanei_lexmark_low_search_home_bwd: offset=%d\n", i);
2284141cc406Sopenharmony_ci	      fprintf (img, "P5\n2500 %03d\n", i);
2285141cc406Sopenharmony_ci	      fclose (img);
2286141cc406Sopenharmony_ci#endif
2287141cc406Sopenharmony_ci	      low_stop_mvmt (devnum);
2288141cc406Sopenharmony_ci	      DBG (2,
2289141cc406Sopenharmony_ci		   "sanei_lexmark_low_search_home_bwd: in home region, end.\n");
2290141cc406Sopenharmony_ci	      return SANE_TRUE;
2291141cc406Sopenharmony_ci	    }
2292141cc406Sopenharmony_ci	}
2293141cc406Sopenharmony_ci    }				/*   end while (buffer_count > buffer_limit); */
2294141cc406Sopenharmony_ci  free (buffer);
2295141cc406Sopenharmony_ci#ifdef DEEP_DEBUG
2296141cc406Sopenharmony_ci  fflush (img);
2297141cc406Sopenharmony_ci  i = ftell (img) / 2500;
2298141cc406Sopenharmony_ci  rewind (img);
2299141cc406Sopenharmony_ci  fprintf (img, "P5\n2500 %03d\n", i);
2300141cc406Sopenharmony_ci  fclose (img);
2301141cc406Sopenharmony_ci#endif
2302141cc406Sopenharmony_ci  low_stop_mvmt (devnum);
2303141cc406Sopenharmony_ci
2304141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_search_home_bwd: end.\n");
2305141cc406Sopenharmony_ci
2306141cc406Sopenharmony_ci  return SANE_FALSE;
2307141cc406Sopenharmony_ci}
2308141cc406Sopenharmony_ci
2309141cc406Sopenharmony_ciSANE_Status
2310141cc406Sopenharmony_cilow_get_start_loc (SANE_Int resolution, SANE_Int * vert_start,
2311141cc406Sopenharmony_ci		   SANE_Int * hor_start, SANE_Int offset,
2312141cc406Sopenharmony_ci		   Lexmark_Device * dev)
2313141cc406Sopenharmony_ci{
2314141cc406Sopenharmony_ci  SANE_Int start_600;
2315141cc406Sopenharmony_ci
2316141cc406Sopenharmony_ci  switch (dev->model.sensor_type)
2317141cc406Sopenharmony_ci    {
2318141cc406Sopenharmony_ci    case X1100_2C_SENSOR:
2319141cc406Sopenharmony_ci    case X1200_USB2_SENSOR:
2320141cc406Sopenharmony_ci    case A920_SENSOR:
2321141cc406Sopenharmony_ci    case X1200_SENSOR:
2322141cc406Sopenharmony_ci      start_600 = 195 - offset;
2323141cc406Sopenharmony_ci      *hor_start = 0x68;
2324141cc406Sopenharmony_ci      break;
2325141cc406Sopenharmony_ci    case X1100_B2_SENSOR:
2326141cc406Sopenharmony_ci      start_600 = 195 - offset;
2327141cc406Sopenharmony_ci      switch (resolution)
2328141cc406Sopenharmony_ci	{
2329141cc406Sopenharmony_ci	case 75:
2330141cc406Sopenharmony_ci	  *hor_start = 0x68;
2331141cc406Sopenharmony_ci	  break;
2332141cc406Sopenharmony_ci	case 150:
2333141cc406Sopenharmony_ci	  *hor_start = 0x68;
2334141cc406Sopenharmony_ci	  break;
2335141cc406Sopenharmony_ci	case 300:
2336141cc406Sopenharmony_ci	  *hor_start = 0x6a;
2337141cc406Sopenharmony_ci	  break;
2338141cc406Sopenharmony_ci	case 600:
2339141cc406Sopenharmony_ci	  *hor_start = 0x6b;
2340141cc406Sopenharmony_ci	  break;
2341141cc406Sopenharmony_ci	case 1200:
2342141cc406Sopenharmony_ci	  *hor_start = 0x6b;
2343141cc406Sopenharmony_ci	  break;
2344141cc406Sopenharmony_ci	default:
2345141cc406Sopenharmony_ci	  /* If we're here we have an invalid resolution */
2346141cc406Sopenharmony_ci	  return SANE_STATUS_INVAL;
2347141cc406Sopenharmony_ci	}
2348141cc406Sopenharmony_ci      break;
2349141cc406Sopenharmony_ci    case X74_SENSOR:
2350141cc406Sopenharmony_ci      start_600 = 268 - offset;
2351141cc406Sopenharmony_ci      switch (resolution)
2352141cc406Sopenharmony_ci	{
2353141cc406Sopenharmony_ci	case 75:
2354141cc406Sopenharmony_ci	  *hor_start = 0x48;
2355141cc406Sopenharmony_ci	  break;
2356141cc406Sopenharmony_ci	case 150:
2357141cc406Sopenharmony_ci	  *hor_start = 0x48;
2358141cc406Sopenharmony_ci	  break;
2359141cc406Sopenharmony_ci	case 300:
2360141cc406Sopenharmony_ci	  *hor_start = 0x4a;
2361141cc406Sopenharmony_ci	  break;
2362141cc406Sopenharmony_ci	case 600:
2363141cc406Sopenharmony_ci	  *hor_start = 0x4b;
2364141cc406Sopenharmony_ci	  break;
2365141cc406Sopenharmony_ci	default:
2366141cc406Sopenharmony_ci	  /* If we're here we have an invalid resolution */
2367141cc406Sopenharmony_ci	  return SANE_STATUS_INVAL;
2368141cc406Sopenharmony_ci	}
2369141cc406Sopenharmony_ci      break;
2370141cc406Sopenharmony_ci    default:
2371141cc406Sopenharmony_ci      /* If we're here we have an unknown dev->model.sensor_type */
2372141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2373141cc406Sopenharmony_ci    }
2374141cc406Sopenharmony_ci  /* Calculate vertical start distance at 600dpi */
2375141cc406Sopenharmony_ci  switch (resolution)
2376141cc406Sopenharmony_ci    {
2377141cc406Sopenharmony_ci    case 75:
2378141cc406Sopenharmony_ci      *vert_start = start_600 / 8;
2379141cc406Sopenharmony_ci      break;
2380141cc406Sopenharmony_ci    case 150:
2381141cc406Sopenharmony_ci      *vert_start = start_600 / 4;
2382141cc406Sopenharmony_ci      break;
2383141cc406Sopenharmony_ci    case 300:
2384141cc406Sopenharmony_ci      *vert_start = start_600 / 2;
2385141cc406Sopenharmony_ci      break;
2386141cc406Sopenharmony_ci    case 600:
2387141cc406Sopenharmony_ci      *vert_start = start_600;
2388141cc406Sopenharmony_ci      break;
2389141cc406Sopenharmony_ci    case 1200:
2390141cc406Sopenharmony_ci      *vert_start = start_600 * 2;
2391141cc406Sopenharmony_ci      break;
2392141cc406Sopenharmony_ci    default:
2393141cc406Sopenharmony_ci      /* If we're here we have an invalid resolution */
2394141cc406Sopenharmony_ci      return SANE_STATUS_INVAL;
2395141cc406Sopenharmony_ci    }
2396141cc406Sopenharmony_ci
2397141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
2398141cc406Sopenharmony_ci}
2399141cc406Sopenharmony_ci
2400141cc406Sopenharmony_civoid
2401141cc406Sopenharmony_cilow_set_scan_area (SANE_Int res,
2402141cc406Sopenharmony_ci		   SANE_Int tlx,
2403141cc406Sopenharmony_ci		   SANE_Int tly,
2404141cc406Sopenharmony_ci		   SANE_Int brx,
2405141cc406Sopenharmony_ci		   SANE_Int bry,
2406141cc406Sopenharmony_ci		   SANE_Int offset,
2407141cc406Sopenharmony_ci		   SANE_Bool half_step,
2408141cc406Sopenharmony_ci		   SANE_Byte * regs, Lexmark_Device * dev)
2409141cc406Sopenharmony_ci{
2410141cc406Sopenharmony_ci
2411141cc406Sopenharmony_ci  SANE_Int vert_start = 0;
2412141cc406Sopenharmony_ci  SANE_Int hor_start = 0;
2413141cc406Sopenharmony_ci  SANE_Int vert_end;
2414141cc406Sopenharmony_ci  SANE_Int hor_end;
2415141cc406Sopenharmony_ci
2416141cc406Sopenharmony_ci  low_get_start_loc (res, &vert_start, &hor_start, offset, dev);
2417141cc406Sopenharmony_ci
2418141cc406Sopenharmony_ci  /* convert pixel height to vertical location coordinates */
2419141cc406Sopenharmony_ci  vert_end = vert_start + (bry * res) / 600;
2420141cc406Sopenharmony_ci  vert_start += (tly * res) / 600;
2421141cc406Sopenharmony_ci
2422141cc406Sopenharmony_ci  /* scan area size : for A920, 600 color scans are done at 1200 y dpi */
2423141cc406Sopenharmony_ci  /* this follow what was found in usb logs                            */
2424141cc406Sopenharmony_ci  if (half_step)
2425141cc406Sopenharmony_ci    {
2426141cc406Sopenharmony_ci      vert_end = vert_end * 2;
2427141cc406Sopenharmony_ci      vert_start = vert_start * 2;
2428141cc406Sopenharmony_ci    }
2429141cc406Sopenharmony_ci
2430141cc406Sopenharmony_ci  /* set vertical start position registers */
2431141cc406Sopenharmony_ci  regs[0x60] = LOBYTE (vert_start);
2432141cc406Sopenharmony_ci  regs[0x61] = HIBYTE (vert_start);
2433141cc406Sopenharmony_ci  /* set vertical end position registers */
2434141cc406Sopenharmony_ci  regs[0x62] = LOBYTE (vert_end);
2435141cc406Sopenharmony_ci  regs[0x63] = HIBYTE (vert_end);
2436141cc406Sopenharmony_ci
2437141cc406Sopenharmony_ci  /* convert pixel width to horizontal location coordinates */
2438141cc406Sopenharmony_ci
2439141cc406Sopenharmony_ci  hor_end = hor_start + brx;
2440141cc406Sopenharmony_ci  hor_start += tlx;
2441141cc406Sopenharmony_ci
2442141cc406Sopenharmony_ci  regs[0x66] = LOBYTE (hor_start);
2443141cc406Sopenharmony_ci  regs[0x67] = HIBYTE (hor_start);
2444141cc406Sopenharmony_ci  /* set horizontal end position registers */
2445141cc406Sopenharmony_ci  regs[0x6c] = LOBYTE (hor_end);
2446141cc406Sopenharmony_ci  regs[0x6d] = HIBYTE (hor_end);
2447141cc406Sopenharmony_ci
2448141cc406Sopenharmony_ci  /* Debug */
2449141cc406Sopenharmony_ci  DBG (2, "low_set_scan_area: vert_start: %d (tly=%d)\n", vert_start, tly);
2450141cc406Sopenharmony_ci  DBG (2, "low_set_scan_area: vert_end: %d\n", vert_end);
2451141cc406Sopenharmony_ci  DBG (2, "low_set_scan_area: hor_start: %d\n", hor_start);
2452141cc406Sopenharmony_ci  DBG (2, "low_set_scan_area: hor_end: %d\n", hor_end);
2453141cc406Sopenharmony_ci
2454141cc406Sopenharmony_ci}
2455141cc406Sopenharmony_ci
2456141cc406Sopenharmony_ciSANE_Int
2457141cc406Sopenharmony_cisanei_lexmark_low_find_start_line (Lexmark_Device * dev)
2458141cc406Sopenharmony_ci{
2459141cc406Sopenharmony_ci  /*
2460141cc406Sopenharmony_ci     This function scans forward 59 lines, reading 88 bytes per line from the
2461141cc406Sopenharmony_ci     middle of the horizontal line: pixel 0xa84 to pixel 0x9d4. It scans with
2462141cc406Sopenharmony_ci     the following parameters:
2463141cc406Sopenharmony_ci     dir=fwd
2464141cc406Sopenharmony_ci     mode=grayscale
2465141cc406Sopenharmony_ci     h.res=300 dpi
2466141cc406Sopenharmony_ci     v.res=600 dpi
2467141cc406Sopenharmony_ci     hor. pixels = (0xa84 - 0x9d4)/2 = 0x58 = 88
2468141cc406Sopenharmony_ci     vert. pixels = 0x3e - 0x03 = 0x3b = 59
2469141cc406Sopenharmony_ci     data = 88x59=5192=0x1448
2470141cc406Sopenharmony_ci
2471141cc406Sopenharmony_ci     It assumes we are in the start dot, or just before it. We are reading
2472141cc406Sopenharmony_ci     enough lines at 600dpi to read past the dot. We return the number of
2473141cc406Sopenharmony_ci     entirely white lines read consecutively, so we know how far past the
2474141cc406Sopenharmony_ci     dot we are.
2475141cc406Sopenharmony_ci
2476141cc406Sopenharmony_ci     To find the number of consecutive white lines we do the following:
2477141cc406Sopenharmony_ci
2478141cc406Sopenharmony_ci     Byte swap the order of the bytes in the buffer.
2479141cc406Sopenharmony_ci
2480141cc406Sopenharmony_ci     Go through the buffer finding low and high values, which are computed by
2481141cc406Sopenharmony_ci     comparing to the weighted average:
2482141cc406Sopenharmony_ci     weighted_average = (lowest value + (highest value - lowest value)/4)
2483141cc406Sopenharmony_ci     Low bytes are changed to 0xFF (white), higher of equal bytes are changed
2484141cc406Sopenharmony_ci     to 0x00 (black),so that the buffer only contains white (0xFF) or black
2485141cc406Sopenharmony_ci     (0x00) values.
2486141cc406Sopenharmony_ci
2487141cc406Sopenharmony_ci     Next, we go through the buffer a line (88 bytes) at a time for 59 lines
2488141cc406Sopenharmony_ci     to read the entire buffer. For each byte in a line we check if the
2489141cc406Sopenharmony_ci     byte is black. If it is we increment the black byte counter.
2490141cc406Sopenharmony_ci
2491141cc406Sopenharmony_ci     After each line we check the black byte counter. If it is greater than 0
2492141cc406Sopenharmony_ci     we increment the black line count and set the white line count to 0. If
2493141cc406Sopenharmony_ci     there were no black bytes in the line we set the black line count to 0
2494141cc406Sopenharmony_ci     and increment the white line count.
2495141cc406Sopenharmony_ci
2496141cc406Sopenharmony_ci     When all lines have been processed we return the white line count.
2497141cc406Sopenharmony_ci   */
2498141cc406Sopenharmony_ci
2499141cc406Sopenharmony_ci
2500141cc406Sopenharmony_ci  int blackLineCount = 0;
2501141cc406Sopenharmony_ci  int whiteLineCount = 0;
2502141cc406Sopenharmony_ci  int blackByteCounter = 0;
2503141cc406Sopenharmony_ci  unsigned char max_byte = 0;
2504141cc406Sopenharmony_ci  unsigned char min_byte = 0xFF;
2505141cc406Sopenharmony_ci  unsigned char weighted_average;
2506141cc406Sopenharmony_ci  int i, j;
2507141cc406Sopenharmony_ci#ifdef DEEP_DEBUG
2508141cc406Sopenharmony_ci  FILE *fdbg = NULL;
2509141cc406Sopenharmony_ci#endif
2510141cc406Sopenharmony_ci
2511141cc406Sopenharmony_ci  SANE_Byte poll_result[3];
2512141cc406Sopenharmony_ci  SANE_Byte *buffer;
2513141cc406Sopenharmony_ci  SANE_Byte temp_byte;
2514141cc406Sopenharmony_ci
2515141cc406Sopenharmony_ci  static SANE_Byte command4_block[] = { 0x90, 0x00, 0x00, 0x03 };
2516141cc406Sopenharmony_ci
2517141cc406Sopenharmony_ci  static SANE_Byte command5_block[] = { 0x91, 0x00, 0x14, 0x48 };
2518141cc406Sopenharmony_ci
2519141cc406Sopenharmony_ci  size_t cmd_size;
2520141cc406Sopenharmony_ci  SANE_Bool got_line;
2521141cc406Sopenharmony_ci
2522141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_find_start_line:\n");
2523141cc406Sopenharmony_ci
2524141cc406Sopenharmony_ci
2525141cc406Sopenharmony_ci  /* set up registers */
2526141cc406Sopenharmony_ci  switch (dev->model.sensor_type)
2527141cc406Sopenharmony_ci    {
2528141cc406Sopenharmony_ci    case X74_SENSOR:
2529141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x04;
2530141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x46;
2531141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x05;
2532141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x05;
2533141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x0b;
2534141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x0b;
2535141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x11;
2536141cc406Sopenharmony_ci      dev->shadow_regs[0x40] = 0x40;
2537141cc406Sopenharmony_ci      rts88xx_set_gain (dev->shadow_regs, 6, 6, 6);
2538141cc406Sopenharmony_ci      break;
2539141cc406Sopenharmony_ci    case X1100_B2_SENSOR:
2540141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x0f;
2541141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x51;
2542141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x0d;
2543141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x0d;
2544141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x1d;
2545141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x1d;
2546141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x29;
2547141cc406Sopenharmony_ci      dev->shadow_regs[0x65] = 0x80;
2548141cc406Sopenharmony_ci      dev->shadow_regs[0x85] = 0x00;
2549141cc406Sopenharmony_ci      dev->shadow_regs[0x93] = 0x06;
2550141cc406Sopenharmony_ci      rts88xx_set_gain (dev->shadow_regs, 6, 6, 6);
2551141cc406Sopenharmony_ci      break;
2552141cc406Sopenharmony_ci    case X1100_2C_SENSOR:
2553141cc406Sopenharmony_ci      rts88xx_set_gain (dev->shadow_regs, 10, 10, 10);
2554141cc406Sopenharmony_ci      dev->shadow_regs[0x28] = 0xf5;
2555141cc406Sopenharmony_ci      dev->shadow_regs[0x29] = 0xf7;
2556141cc406Sopenharmony_ci      dev->shadow_regs[0x2a] = 0xf5;
2557141cc406Sopenharmony_ci      dev->shadow_regs[0x2b] = 0x17;
2558141cc406Sopenharmony_ci
2559141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x0d;
2560141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x4f;
2561141cc406Sopenharmony_ci      dev->shadow_regs[0x31] = 0x01;
2562141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x11;
2563141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x11;
2564141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x21;
2565141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x21;
2566141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x31;
2567141cc406Sopenharmony_ci      dev->shadow_regs[0x72] = 0x35;
2568141cc406Sopenharmony_ci      dev->shadow_regs[0x74] = 0x4e;
2569141cc406Sopenharmony_ci      dev->shadow_regs[0x85] = 0x02;
2570141cc406Sopenharmony_ci      dev->shadow_regs[0x86] = 0x33;
2571141cc406Sopenharmony_ci      dev->shadow_regs[0x87] = 0x0f;
2572141cc406Sopenharmony_ci      dev->shadow_regs[0x88] = 0x24;
2573141cc406Sopenharmony_ci      dev->shadow_regs[0x91] = 0x19;
2574141cc406Sopenharmony_ci      dev->shadow_regs[0x92] = 0x20;
2575141cc406Sopenharmony_ci      dev->shadow_regs[0xea] = 0x00;
2576141cc406Sopenharmony_ci      dev->shadow_regs[0xeb] = 0x00;
2577141cc406Sopenharmony_ci      break;
2578141cc406Sopenharmony_ci    case A920_SENSOR:
2579141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x0d;
2580141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x4f;
2581141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x11;
2582141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x11;
2583141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x21;
2584141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x21;
2585141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x31;
2586141cc406Sopenharmony_ci      dev->shadow_regs[0x85] = 0x05;
2587141cc406Sopenharmony_ci      dev->shadow_regs[0x88] = 0x44;
2588141cc406Sopenharmony_ci      dev->shadow_regs[0x92] = 0x85;
2589141cc406Sopenharmony_ci      dev->shadow_regs[0x93] = 0x0e;
2590141cc406Sopenharmony_ci      rts88xx_set_gain (dev->shadow_regs, 6, 6, 6);
2591141cc406Sopenharmony_ci      break;
2592141cc406Sopenharmony_ci    case X1200_SENSOR:
2593141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x01;
2594141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x03;
2595141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x0d;
2596141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x0d;
2597141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x1d;
2598141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x1d;
2599141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x29;
2600141cc406Sopenharmony_ci      dev->shadow_regs[0xea] = 0x00;
2601141cc406Sopenharmony_ci      dev->shadow_regs[0xeb] = 0x00;
2602141cc406Sopenharmony_ci      dev->shadow_regs[0x40] = 0x80;
2603141cc406Sopenharmony_ci      dev->shadow_regs[0x50] = 0x00;
2604141cc406Sopenharmony_ci      dev->shadow_regs[0x81] = 0x00;
2605141cc406Sopenharmony_ci      dev->shadow_regs[0x82] = 0x00;
2606141cc406Sopenharmony_ci      dev->shadow_regs[0x85] = 0x00;
2607141cc406Sopenharmony_ci      dev->shadow_regs[0x86] = 0x00;
2608141cc406Sopenharmony_ci      dev->shadow_regs[0x87] = 0xff;
2609141cc406Sopenharmony_ci      dev->shadow_regs[0x88] = 0x02;
2610141cc406Sopenharmony_ci      dev->shadow_regs[0x92] = 0x00;
2611141cc406Sopenharmony_ci      rts88xx_set_gain (dev->shadow_regs, 10, 10, 10);
2612141cc406Sopenharmony_ci      break;
2613141cc406Sopenharmony_ci    case X1200_USB2_SENSOR:
2614141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x01;
2615141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x03;
2616141cc406Sopenharmony_ci      dev->shadow_regs[0x34] = 0x0d;
2617141cc406Sopenharmony_ci      dev->shadow_regs[0x35] = 0x0d;
2618141cc406Sopenharmony_ci      dev->shadow_regs[0x36] = 0x1d;
2619141cc406Sopenharmony_ci      dev->shadow_regs[0x37] = 0x1d;
2620141cc406Sopenharmony_ci      dev->shadow_regs[0x38] = 0x29;
2621141cc406Sopenharmony_ci      dev->shadow_regs[0xea] = 0x00;
2622141cc406Sopenharmony_ci      dev->shadow_regs[0xeb] = 0x00;
2623141cc406Sopenharmony_ci      rts88xx_set_gain (dev->shadow_regs, 10, 10, 10);
2624141cc406Sopenharmony_ci      break;
2625141cc406Sopenharmony_ci    }
2626141cc406Sopenharmony_ci
2627141cc406Sopenharmony_ci  /* set offset to a safe value */
2628141cc406Sopenharmony_ci  rts88xx_set_offset (dev->shadow_regs, 0x80, 0x80, 0x80);
2629141cc406Sopenharmony_ci  /* set grayscale  scan  */
2630141cc406Sopenharmony_ci  dev->shadow_regs[0x2f] = 0x21;
2631141cc406Sopenharmony_ci  /* set motor resolution divisor */
2632141cc406Sopenharmony_ci  dev->shadow_regs[0x39] = 0x01;
2633141cc406Sopenharmony_ci  /* set vertical start/end positions */
2634141cc406Sopenharmony_ci  dev->shadow_regs[0x60] = 0x03;
2635141cc406Sopenharmony_ci  dev->shadow_regs[0x61] = 0x00;
2636141cc406Sopenharmony_ci  dev->shadow_regs[0x62] = 0x3e;
2637141cc406Sopenharmony_ci  dev->shadow_regs[0x63] = 0x00;
2638141cc406Sopenharmony_ci  /* set # of head moves per CIS read */
2639141cc406Sopenharmony_ci  rts88xx_set_scan_frequency (dev->shadow_regs, 1);
2640141cc406Sopenharmony_ci  /* set horizontal start position */
2641141cc406Sopenharmony_ci  dev->shadow_regs[0x66] = 0xd4;	/* 0xf2 for X1200 */
2642141cc406Sopenharmony_ci  dev->shadow_regs[0x67] = 0x09;
2643141cc406Sopenharmony_ci  /* set horizontal end position */
2644141cc406Sopenharmony_ci  dev->shadow_regs[0x6c] = 0x84;	/* 0xa2 for X1200 */
2645141cc406Sopenharmony_ci  dev->shadow_regs[0x6d] = 0x0a;
2646141cc406Sopenharmony_ci  /* set horizontal resolution */
2647141cc406Sopenharmony_ci  dev->shadow_regs[0x79] = 0x40;
2648141cc406Sopenharmony_ci  dev->shadow_regs[0x7a] = 0x02;
2649141cc406Sopenharmony_ci  /* set for ? */
2650141cc406Sopenharmony_ci  /* Motor enable & Coordinate space denominator */
2651141cc406Sopenharmony_ci  dev->shadow_regs[0xc3] = 0x81;
2652141cc406Sopenharmony_ci
2653141cc406Sopenharmony_ci
2654141cc406Sopenharmony_ci
2655141cc406Sopenharmony_ci
2656141cc406Sopenharmony_ci
2657141cc406Sopenharmony_ci  switch (dev->model.motor_type)
2658141cc406Sopenharmony_ci    {
2659141cc406Sopenharmony_ci    case X1100_MOTOR:
2660141cc406Sopenharmony_ci    case A920_MOTOR:
2661141cc406Sopenharmony_ci      /* set for ? */
2662141cc406Sopenharmony_ci      dev->shadow_regs[0xc5] = 0x22;
2663141cc406Sopenharmony_ci      /* Movement direction & step size */
2664141cc406Sopenharmony_ci      dev->shadow_regs[0xc6] = 0x09;
2665141cc406Sopenharmony_ci      /* step size range2 */
2666141cc406Sopenharmony_ci      dev->shadow_regs[0xc9] = 0x3b;
2667141cc406Sopenharmony_ci      /* set for ? */
2668141cc406Sopenharmony_ci      dev->shadow_regs[0xca] = 0x1f;
2669141cc406Sopenharmony_ci      dev->shadow_regs[0xe0] = 0xf7;
2670141cc406Sopenharmony_ci      dev->shadow_regs[0xe1] = 0x16;
2671141cc406Sopenharmony_ci      /* step size range0 */
2672141cc406Sopenharmony_ci      dev->shadow_regs[0xe2] = 0x87;
2673141cc406Sopenharmony_ci      /* ? */
2674141cc406Sopenharmony_ci      dev->shadow_regs[0xe3] = 0x13;
2675141cc406Sopenharmony_ci      dev->shadow_regs[0xe4] = 0x1b;
2676141cc406Sopenharmony_ci      dev->shadow_regs[0xe5] = 0x16;
2677141cc406Sopenharmony_ci      dev->shadow_regs[0xe6] = 0xdc;
2678141cc406Sopenharmony_ci      dev->shadow_regs[0xe7] = 0x00;
2679141cc406Sopenharmony_ci      dev->shadow_regs[0xe8] = 0x00;
2680141cc406Sopenharmony_ci      dev->shadow_regs[0xe9] = 0x1b;
2681141cc406Sopenharmony_ci      dev->shadow_regs[0xec] = 0x07;
2682141cc406Sopenharmony_ci      dev->shadow_regs[0xef] = 0x03;
2683141cc406Sopenharmony_ci      break;
2684141cc406Sopenharmony_ci    case X74_MOTOR:
2685141cc406Sopenharmony_ci      dev->shadow_regs[0xc4] = 0x20;
2686141cc406Sopenharmony_ci      dev->shadow_regs[0xc5] = 0x22;
2687141cc406Sopenharmony_ci      /* Movement direction & step size */
2688141cc406Sopenharmony_ci      dev->shadow_regs[0xc6] = 0x0b;
2689141cc406Sopenharmony_ci
2690141cc406Sopenharmony_ci      dev->shadow_regs[0xc8] = 0x04;
2691141cc406Sopenharmony_ci      dev->shadow_regs[0xc9] = 0x39;
2692141cc406Sopenharmony_ci      dev->shadow_regs[0xca] = 0x1f;
2693141cc406Sopenharmony_ci
2694141cc406Sopenharmony_ci      /* bounds of movement range0 */
2695141cc406Sopenharmony_ci      dev->shadow_regs[0xe0] = 0x2f;
2696141cc406Sopenharmony_ci      dev->shadow_regs[0xe1] = 0x11;
2697141cc406Sopenharmony_ci      /* step size range0 */
2698141cc406Sopenharmony_ci      dev->shadow_regs[0xe2] = 0x9f;
2699141cc406Sopenharmony_ci      /* ? */
2700141cc406Sopenharmony_ci      dev->shadow_regs[0xe3] = 0x0f;
2701141cc406Sopenharmony_ci      /* bounds of movement range1 */
2702141cc406Sopenharmony_ci      dev->shadow_regs[0xe4] = 0xcb;
2703141cc406Sopenharmony_ci
2704141cc406Sopenharmony_ci      dev->shadow_regs[0xe5] = 0x10;
2705141cc406Sopenharmony_ci      /* step size range1 */
2706141cc406Sopenharmony_ci      dev->shadow_regs[0xe6] = 0x64;
2707141cc406Sopenharmony_ci      /* bounds of movement range2 */
2708141cc406Sopenharmony_ci      dev->shadow_regs[0xe7] = 0x00;
2709141cc406Sopenharmony_ci      dev->shadow_regs[0xe8] = 0x00;
2710141cc406Sopenharmony_ci      /* step size range2 */
2711141cc406Sopenharmony_ci      dev->shadow_regs[0xe9] = 0x32;
2712141cc406Sopenharmony_ci      /* bounds of movement range3 */
2713141cc406Sopenharmony_ci      dev->shadow_regs[0xea] = 0x00;
2714141cc406Sopenharmony_ci      dev->shadow_regs[0xeb] = 0x00;
2715141cc406Sopenharmony_ci      /* step size range3 */
2716141cc406Sopenharmony_ci      dev->shadow_regs[0xec] = 0x0c;
2717141cc406Sopenharmony_ci      /* bounds of movement range4 -only for 75dpi grayscale */
2718141cc406Sopenharmony_ci      dev->shadow_regs[0xed] = 0x00;
2719141cc406Sopenharmony_ci      dev->shadow_regs[0xee] = 0x00;
2720141cc406Sopenharmony_ci      /* step size range4 */
2721141cc406Sopenharmony_ci      dev->shadow_regs[0xef] = 0x08;
2722141cc406Sopenharmony_ci      break;
2723141cc406Sopenharmony_ci    }
2724141cc406Sopenharmony_ci
2725141cc406Sopenharmony_ci
2726141cc406Sopenharmony_ci  /* Stop the scanner */
2727141cc406Sopenharmony_ci  low_stop_mvmt (dev->devnum);
2728141cc406Sopenharmony_ci
2729141cc406Sopenharmony_ci  /* write regs out twice */
2730141cc406Sopenharmony_ci  dev->shadow_regs[0x32] = 0x00;
2731141cc406Sopenharmony_ci  low_write_all_regs (dev->devnum, dev->shadow_regs);
2732141cc406Sopenharmony_ci  dev->shadow_regs[0x32] = 0x40;
2733141cc406Sopenharmony_ci  low_write_all_regs (dev->devnum, dev->shadow_regs);
2734141cc406Sopenharmony_ci
2735141cc406Sopenharmony_ci  /* Start Scan */
2736141cc406Sopenharmony_ci  rts88xx_commit (dev->devnum, dev->shadow_regs[0x2c]);
2737141cc406Sopenharmony_ci
2738141cc406Sopenharmony_ci  /* Poll the available byte count until not 0 */
2739141cc406Sopenharmony_ci  got_line = SANE_FALSE;
2740141cc406Sopenharmony_ci  while (!got_line)
2741141cc406Sopenharmony_ci    {
2742141cc406Sopenharmony_ci      cmd_size = 4;
2743141cc406Sopenharmony_ci      low_usb_bulk_write (dev->devnum, command4_block, &cmd_size);
2744141cc406Sopenharmony_ci      cmd_size = 0x3;
2745141cc406Sopenharmony_ci      low_usb_bulk_read (dev->devnum, poll_result, &cmd_size);
2746141cc406Sopenharmony_ci      if (!
2747141cc406Sopenharmony_ci	  (poll_result[0] == 0 && poll_result[1] == 0 && poll_result[2] == 0))
2748141cc406Sopenharmony_ci	{
2749141cc406Sopenharmony_ci	  /* if result != 00 00 00 we got data */
2750141cc406Sopenharmony_ci	  got_line = SANE_TRUE;
2751141cc406Sopenharmony_ci	}
2752141cc406Sopenharmony_ci#ifdef FAKE_USB
2753141cc406Sopenharmony_ci      got_line = SANE_TRUE;
2754141cc406Sopenharmony_ci#endif
2755141cc406Sopenharmony_ci    }
2756141cc406Sopenharmony_ci
2757141cc406Sopenharmony_ci
2758141cc406Sopenharmony_ci  /* create buffer for scan data */
2759141cc406Sopenharmony_ci  buffer = calloc (5192, sizeof (char));
2760141cc406Sopenharmony_ci  if (buffer == NULL)
2761141cc406Sopenharmony_ci    {
2762141cc406Sopenharmony_ci      return -1;
2763141cc406Sopenharmony_ci    }
2764141cc406Sopenharmony_ci
2765141cc406Sopenharmony_ci  /* Tell the scanner to send the data */
2766141cc406Sopenharmony_ci  /* Write: 91 00 14 48 */
2767141cc406Sopenharmony_ci  cmd_size = 4;
2768141cc406Sopenharmony_ci  low_usb_bulk_write (dev->devnum, command5_block, &cmd_size);
2769141cc406Sopenharmony_ci  /* Read it */
2770141cc406Sopenharmony_ci  cmd_size = 0x1448;
2771141cc406Sopenharmony_ci  low_usb_bulk_read (dev->devnum, buffer, &cmd_size);
2772141cc406Sopenharmony_ci
2773141cc406Sopenharmony_ci  /* Stop the scanner */
2774141cc406Sopenharmony_ci  low_stop_mvmt (dev->devnum);
2775141cc406Sopenharmony_ci
2776141cc406Sopenharmony_ci
2777141cc406Sopenharmony_ci  /* Reverse order of bytes in words of buffer */
2778141cc406Sopenharmony_ci  for (i = 0; i < 5192; i = i + 2)
2779141cc406Sopenharmony_ci    {
2780141cc406Sopenharmony_ci      temp_byte = *(buffer + i);
2781141cc406Sopenharmony_ci      *(buffer + i) = *(buffer + i + 1);
2782141cc406Sopenharmony_ci      *(buffer + i + 1) = temp_byte;
2783141cc406Sopenharmony_ci    }
2784141cc406Sopenharmony_ci
2785141cc406Sopenharmony_ci#ifdef DEEP_DEBUG
2786141cc406Sopenharmony_ci  fdbg = fopen ("find_start.pnm", "wb");
2787141cc406Sopenharmony_ci  if (fdbg != NULL)
2788141cc406Sopenharmony_ci    {
2789141cc406Sopenharmony_ci      fprintf (fdbg, "P5\n%d %d\n255\n", 88, 59);
2790141cc406Sopenharmony_ci      fwrite (buffer, 5192, 1, fdbg);
2791141cc406Sopenharmony_ci      fclose (fdbg);
2792141cc406Sopenharmony_ci    }
2793141cc406Sopenharmony_ci#endif
2794141cc406Sopenharmony_ci
2795141cc406Sopenharmony_ci  /* Find the max and the min */
2796141cc406Sopenharmony_ci  for (i = 0; i < 5192; i++)
2797141cc406Sopenharmony_ci    {
2798141cc406Sopenharmony_ci      if (*(buffer + i) > max_byte)
2799141cc406Sopenharmony_ci	max_byte = *(buffer + i);
2800141cc406Sopenharmony_ci      if (*(buffer + i) < min_byte)
2801141cc406Sopenharmony_ci	min_byte = *(buffer + i);
2802141cc406Sopenharmony_ci    }
2803141cc406Sopenharmony_ci
2804141cc406Sopenharmony_ci  weighted_average = min_byte + ((max_byte - min_byte) / 4);
2805141cc406Sopenharmony_ci
2806141cc406Sopenharmony_ci  /* Set bytes as black (0x00) or white (0xFF) */
2807141cc406Sopenharmony_ci  for (i = 0; i < 5192; i++)
2808141cc406Sopenharmony_ci    {
2809141cc406Sopenharmony_ci      if (*(buffer + i) > weighted_average)
2810141cc406Sopenharmony_ci	*(buffer + i) = 0xFF;
2811141cc406Sopenharmony_ci      else
2812141cc406Sopenharmony_ci	*(buffer + i) = 0x00;
2813141cc406Sopenharmony_ci    }
2814141cc406Sopenharmony_ci
2815141cc406Sopenharmony_ci#ifdef DEEP_DEBUG
2816141cc406Sopenharmony_ci  fdbg = fopen ("find_start_after.pnm", "wb");
2817141cc406Sopenharmony_ci  if (fdbg != NULL)
2818141cc406Sopenharmony_ci    {
2819141cc406Sopenharmony_ci      fprintf (fdbg, "P5\n%d %d\n255\n", 88, 59);
2820141cc406Sopenharmony_ci      fwrite (buffer, 5192, 1, fdbg);
2821141cc406Sopenharmony_ci      fclose (fdbg);
2822141cc406Sopenharmony_ci    }
2823141cc406Sopenharmony_ci#endif
2824141cc406Sopenharmony_ci
2825141cc406Sopenharmony_ci  /* Go through 59 lines */
2826141cc406Sopenharmony_ci  for (j = 0; j < 59; j++)
2827141cc406Sopenharmony_ci    {
2828141cc406Sopenharmony_ci      blackByteCounter = 0;
2829141cc406Sopenharmony_ci      /* Go through 88 bytes per line */
2830141cc406Sopenharmony_ci      for (i = 0; i < 88; i++)
2831141cc406Sopenharmony_ci	{
2832141cc406Sopenharmony_ci	  /* Is byte black? */
2833141cc406Sopenharmony_ci	  if (*(buffer + (j * 88) + i) == 0)
2834141cc406Sopenharmony_ci	    {
2835141cc406Sopenharmony_ci	      blackByteCounter++;
2836141cc406Sopenharmony_ci	    }
2837141cc406Sopenharmony_ci	}			/* end for line */
2838141cc406Sopenharmony_ci      if (blackByteCounter > 0)
2839141cc406Sopenharmony_ci	{
2840141cc406Sopenharmony_ci	  /* This was a black line */
2841141cc406Sopenharmony_ci	  blackLineCount++;
2842141cc406Sopenharmony_ci	  whiteLineCount = 0;
2843141cc406Sopenharmony_ci	}
2844141cc406Sopenharmony_ci      else
2845141cc406Sopenharmony_ci	{
2846141cc406Sopenharmony_ci	  /* This is a white line */
2847141cc406Sopenharmony_ci	  whiteLineCount++;
2848141cc406Sopenharmony_ci	  blackLineCount = 0;
2849141cc406Sopenharmony_ci	}
2850141cc406Sopenharmony_ci    }				/* end for buffer */
2851141cc406Sopenharmony_ci
2852141cc406Sopenharmony_ci  free (buffer);
2853141cc406Sopenharmony_ci  /* Stop the scanner.
2854141cc406Sopenharmony_ci     This is needed to get the right distance to the scanning area */
2855141cc406Sopenharmony_ci  if (dev->model.sensor_type == X74_SENSOR)
2856141cc406Sopenharmony_ci    low_stop_mvmt (dev->devnum);
2857141cc406Sopenharmony_ci
2858141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_find_start_line: end.\n");
2859141cc406Sopenharmony_ci  return whiteLineCount;
2860141cc406Sopenharmony_ci}
2861141cc406Sopenharmony_ci
2862141cc406Sopenharmony_ci
2863141cc406Sopenharmony_ciSANE_Status
2864141cc406Sopenharmony_cisanei_lexmark_low_set_scan_regs (Lexmark_Device * dev, SANE_Int resolution,
2865141cc406Sopenharmony_ci				 SANE_Int offset, SANE_Bool calibrated)
2866141cc406Sopenharmony_ci{
2867141cc406Sopenharmony_ci  SANE_Bool isColourScan;
2868141cc406Sopenharmony_ci
2869141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_set_scan_regs:\n");
2870141cc406Sopenharmony_ci
2871141cc406Sopenharmony_ci  DBG (7, "sanei_lexmark_low_set_scan_regs: resolution=%d DPI\n", resolution);
2872141cc406Sopenharmony_ci
2873141cc406Sopenharmony_ci  /* colour mode */
2874141cc406Sopenharmony_ci  if (strcmp (dev->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_COLOR) == 0)
2875141cc406Sopenharmony_ci    isColourScan = SANE_TRUE;
2876141cc406Sopenharmony_ci  else
2877141cc406Sopenharmony_ci    isColourScan = SANE_FALSE;
2878141cc406Sopenharmony_ci
2879141cc406Sopenharmony_ci  /* set up registers */
2880141cc406Sopenharmony_ci  switch (dev->model.sensor_type)
2881141cc406Sopenharmony_ci    {
2882141cc406Sopenharmony_ci    case X74_SENSOR:
2883141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x03;
2884141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x45;
2885141cc406Sopenharmony_ci      break;
2886141cc406Sopenharmony_ci    case X1100_B2_SENSOR:
2887141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x0f;
2888141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x51;
2889141cc406Sopenharmony_ci      break;
2890141cc406Sopenharmony_ci    case X1100_2C_SENSOR:
2891141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x0d;
2892141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x4f;
2893141cc406Sopenharmony_ci      break;
2894141cc406Sopenharmony_ci    case A920_SENSOR:
2895141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x0d;
2896141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x4f;
2897141cc406Sopenharmony_ci      break;
2898141cc406Sopenharmony_ci    case X1200_SENSOR:
2899141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x01;
2900141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x03;
2901141cc406Sopenharmony_ci      break;
2902141cc406Sopenharmony_ci    case X1200_USB2_SENSOR:
2903141cc406Sopenharmony_ci      dev->shadow_regs[0x2c] = 0x01;
2904141cc406Sopenharmony_ci      dev->shadow_regs[0x2d] = 0x03;
2905141cc406Sopenharmony_ci      break;
2906141cc406Sopenharmony_ci    }
2907141cc406Sopenharmony_ci
2908141cc406Sopenharmony_ci  low_set_scan_area (resolution,
2909141cc406Sopenharmony_ci		     dev->val[OPT_TL_X].w,
2910141cc406Sopenharmony_ci		     dev->val[OPT_TL_Y].w,
2911141cc406Sopenharmony_ci		     dev->val[OPT_BR_X].w,
2912141cc406Sopenharmony_ci		     dev->val[OPT_BR_Y].w,
2913141cc406Sopenharmony_ci		     offset,
2914141cc406Sopenharmony_ci		     (dev->model.motor_type == A920_MOTOR
2915141cc406Sopenharmony_ci		      || dev->model.motor_type == X74_MOTOR) && isColourScan
2916141cc406Sopenharmony_ci		     && (resolution == 600), dev->shadow_regs, dev);
2917141cc406Sopenharmony_ci
2918141cc406Sopenharmony_ci  /* may be we could use a sensor descriptor that would held the max horiz dpi */
2919141cc406Sopenharmony_ci  if (dev->val[OPT_RESOLUTION].w < 600)
2920141cc406Sopenharmony_ci    dev->shadow_regs[0x7a] = 600 / dev->val[OPT_RESOLUTION].w;
2921141cc406Sopenharmony_ci  else
2922141cc406Sopenharmony_ci    dev->shadow_regs[0x7a] = 1;
2923141cc406Sopenharmony_ci
2924141cc406Sopenharmony_ci  /* 75dpi x 75dpi */
2925141cc406Sopenharmony_ci  if (resolution == 75)
2926141cc406Sopenharmony_ci    {
2927141cc406Sopenharmony_ci      DBG (5, "sanei_lexmark_low_set_scan_regs(): 75 DPI resolution\n");
2928141cc406Sopenharmony_ci
2929141cc406Sopenharmony_ci      if (isColourScan)
2930141cc406Sopenharmony_ci	{
2931141cc406Sopenharmony_ci	  switch (dev->model.sensor_type)
2932141cc406Sopenharmony_ci	    {
2933141cc406Sopenharmony_ci	    case X74_SENSOR:
2934141cc406Sopenharmony_ci
2935141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x04;
2936141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x03;
2937141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x03;
2938141cc406Sopenharmony_ci
2939141cc406Sopenharmony_ci	      dev->shadow_regs[0x79] = 0x08;
2940141cc406Sopenharmony_ci
2941141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x0d;
2942141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x0e;
2943141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x02;
2944141cc406Sopenharmony_ci
2945141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x00;
2946141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
2947141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x00;
2948141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
2949141cc406Sopenharmony_ci
2950141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x00;
2951141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
2952141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;;
2953141cc406Sopenharmony_ci
2954141cc406Sopenharmony_ci	      break;
2955141cc406Sopenharmony_ci
2956141cc406Sopenharmony_ci	    case X1100_B2_SENSOR:
2957141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x05;
2958141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x05;
2959141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x05;
2960141cc406Sopenharmony_ci
2961141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x0c;
2962141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x0c;
2963141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x09;
2964141cc406Sopenharmony_ci
2965141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x00;
2966141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
2967141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x00;
2968141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
2969141cc406Sopenharmony_ci
2970141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x8c;
2971141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x40;
2972141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;
2973141cc406Sopenharmony_ci	      break;
2974141cc406Sopenharmony_ci
2975141cc406Sopenharmony_ci	    case X1100_2C_SENSOR:
2976141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x03;
2977141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x04;
2978141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x03;
2979141cc406Sopenharmony_ci
2980141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x00;
2981141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x02;
2982141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x03;
2983141cc406Sopenharmony_ci
2984141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x20;
2985141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
2986141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x00;
2987141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
2988141cc406Sopenharmony_ci
2989141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x00;
2990141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
2991141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;
2992141cc406Sopenharmony_ci	      break;
2993141cc406Sopenharmony_ci
2994141cc406Sopenharmony_ci	    case A920_SENSOR:
2995141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x02;
2996141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x04;
2997141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x03;
2998141cc406Sopenharmony_ci
2999141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x07;
3000141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x0f;
3001141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x03;
3002141cc406Sopenharmony_ci
3003141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x05;
3004141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x14;
3005141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x06;
3006141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x44;
3007141cc406Sopenharmony_ci
3008141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x60;
3009141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x85;
3010141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x0e;
3011141cc406Sopenharmony_ci	      break;
3012141cc406Sopenharmony_ci
3013141cc406Sopenharmony_ci	    case X1200_SENSOR:
3014141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x02;
3015141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x03;
3016141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x01;
3017141cc406Sopenharmony_ci
3018141cc406Sopenharmony_ci	      dev->shadow_regs[0x79] = 0x20;
3019141cc406Sopenharmony_ci
3020141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x08;
3021141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x02;
3022141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x0d;
3023141cc406Sopenharmony_ci
3024141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x20;
3025141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x1e;
3026141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x39;
3027141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
3028141cc406Sopenharmony_ci
3029141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x00;
3030141cc406Sopenharmony_ci	      /* dev->shadow_regs[0x92] = 0x92; */
3031141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;
3032141cc406Sopenharmony_ci	      break;
3033141cc406Sopenharmony_ci
3034141cc406Sopenharmony_ci	    case X1200_USB2_SENSOR:
3035141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x04;
3036141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x05;
3037141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x04;
3038141cc406Sopenharmony_ci
3039141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x01;
3040141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x0a;
3041141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x0b;
3042141cc406Sopenharmony_ci	      break;
3043141cc406Sopenharmony_ci	    }
3044141cc406Sopenharmony_ci
3045141cc406Sopenharmony_ci	  switch (dev->model.motor_type)
3046141cc406Sopenharmony_ci	    {
3047141cc406Sopenharmony_ci	    case X74_MOTOR:
3048141cc406Sopenharmony_ci	      dev->shadow_regs[0xc2] = 0x80;
3049141cc406Sopenharmony_ci	      /*  ? */
3050141cc406Sopenharmony_ci	      dev->shadow_regs[0xc4] = 0x20;
3051141cc406Sopenharmony_ci	      dev->shadow_regs[0xc5] = 0x0c;
3052141cc406Sopenharmony_ci	      dev->shadow_regs[0xc6] = 0x0b;
3053141cc406Sopenharmony_ci
3054141cc406Sopenharmony_ci	      dev->shadow_regs[0xc8] = 0x04;
3055141cc406Sopenharmony_ci	      dev->shadow_regs[0xc9] = 0x39;
3056141cc406Sopenharmony_ci	      dev->shadow_regs[0xca] = 0x01;
3057141cc406Sopenharmony_ci
3058141cc406Sopenharmony_ci	      /* bounds of movement range0 */
3059141cc406Sopenharmony_ci	      dev->shadow_regs[0xe0] = 0x1b;
3060141cc406Sopenharmony_ci	      dev->shadow_regs[0xe1] = 0x0a;
3061141cc406Sopenharmony_ci	      /* step size range0 */
3062141cc406Sopenharmony_ci	      dev->shadow_regs[0xe2] = 0x4f;
3063141cc406Sopenharmony_ci	      /* ? */
3064141cc406Sopenharmony_ci	      dev->shadow_regs[0xe3] = 0x01;
3065141cc406Sopenharmony_ci	      /* bounds of movement range1 */
3066141cc406Sopenharmony_ci	      dev->shadow_regs[0xe4] = 0xb3;
3067141cc406Sopenharmony_ci
3068141cc406Sopenharmony_ci	      dev->shadow_regs[0xe5] = 0x09;
3069141cc406Sopenharmony_ci	      /* step size range1 */
3070141cc406Sopenharmony_ci	      dev->shadow_regs[0xe6] = 0x0d;
3071141cc406Sopenharmony_ci	      /* bounds of movement range2 */
3072141cc406Sopenharmony_ci	      dev->shadow_regs[0xe7] = 0xe5;
3073141cc406Sopenharmony_ci	      dev->shadow_regs[0xe8] = 0x02;
3074141cc406Sopenharmony_ci	      /* step size range2 */
3075141cc406Sopenharmony_ci	      dev->shadow_regs[0xe9] = 0x05;
3076141cc406Sopenharmony_ci	      /* bounds of movement range3 */
3077141cc406Sopenharmony_ci	      dev->shadow_regs[0xea] = 0xa0;
3078141cc406Sopenharmony_ci	      dev->shadow_regs[0xeb] = 0x01;
3079141cc406Sopenharmony_ci	      /* step size range3 */
3080141cc406Sopenharmony_ci	      dev->shadow_regs[0xec] = 0x01;
3081141cc406Sopenharmony_ci	      /* bounds of movement range4 */
3082141cc406Sopenharmony_ci	      dev->shadow_regs[0xed] = 0x00;
3083141cc406Sopenharmony_ci	      dev->shadow_regs[0xee] = 0x00;
3084141cc406Sopenharmony_ci	      /* step size range4 */
3085141cc406Sopenharmony_ci	      dev->shadow_regs[0xef] = 0x01;
3086141cc406Sopenharmony_ci	      break;
3087141cc406Sopenharmony_ci	    case A920_MOTOR:
3088141cc406Sopenharmony_ci	    case X1100_MOTOR:
3089141cc406Sopenharmony_ci	      /*  ? */
3090141cc406Sopenharmony_ci	      dev->shadow_regs[0xc5] = 0x0a;
3091141cc406Sopenharmony_ci	      /* bounds of movement range0 */
3092141cc406Sopenharmony_ci	      dev->shadow_regs[0xe0] = 0x2b;
3093141cc406Sopenharmony_ci	      dev->shadow_regs[0xe1] = 0x0a;
3094141cc406Sopenharmony_ci	      /* step size range0 */
3095141cc406Sopenharmony_ci	      dev->shadow_regs[0xe2] = 0x7f;
3096141cc406Sopenharmony_ci	      /* ? */
3097141cc406Sopenharmony_ci	      dev->shadow_regs[0xe3] = 0x01;
3098141cc406Sopenharmony_ci	      /* bounds of movement range1 */
3099141cc406Sopenharmony_ci	      dev->shadow_regs[0xe4] = 0xbb;
3100141cc406Sopenharmony_ci	      dev->shadow_regs[0xe5] = 0x09;
3101141cc406Sopenharmony_ci	      /* step size range1 */
3102141cc406Sopenharmony_ci	      dev->shadow_regs[0xe6] = 0x0e;
3103141cc406Sopenharmony_ci	      /* bounds of movement range2 */
3104141cc406Sopenharmony_ci	      dev->shadow_regs[0xe7] = 0x2b;
3105141cc406Sopenharmony_ci	      dev->shadow_regs[0xe8] = 0x03;
3106141cc406Sopenharmony_ci	      /* step size range2 */
3107141cc406Sopenharmony_ci	      dev->shadow_regs[0xe9] = 0x05;
3108141cc406Sopenharmony_ci	      /* bounds of movement range3 */
3109141cc406Sopenharmony_ci	      dev->shadow_regs[0xea] = 0xa0;
3110141cc406Sopenharmony_ci	      dev->shadow_regs[0xeb] = 0x01;
3111141cc406Sopenharmony_ci	      /* step size range3 */
3112141cc406Sopenharmony_ci	      dev->shadow_regs[0xec] = 0x01;
3113141cc406Sopenharmony_ci	      /* step size range4 */
3114141cc406Sopenharmony_ci	      dev->shadow_regs[0xef] = 0x01;
3115141cc406Sopenharmony_ci	      break;
3116141cc406Sopenharmony_ci	    }
3117141cc406Sopenharmony_ci
3118141cc406Sopenharmony_ci	  /* set colour scan */
3119141cc406Sopenharmony_ci	  dev->shadow_regs[0x2f] = 0x11;
3120141cc406Sopenharmony_ci
3121141cc406Sopenharmony_ci	  dev->shadow_regs[0x35] = 0x01;
3122141cc406Sopenharmony_ci	  dev->shadow_regs[0x37] = 0x01;
3123141cc406Sopenharmony_ci	  /* Motor enable & Coordinate space denominator */
3124141cc406Sopenharmony_ci	  dev->shadow_regs[0xc3] = 0x83;
3125141cc406Sopenharmony_ci	}
3126141cc406Sopenharmony_ci      else			/* 75 dpi gray */
3127141cc406Sopenharmony_ci	{
3128141cc406Sopenharmony_ci	  switch (dev->model.sensor_type)
3129141cc406Sopenharmony_ci	    {
3130141cc406Sopenharmony_ci	    case X74_SENSOR:
3131141cc406Sopenharmony_ci
3132141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x01;
3133141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x01;
3134141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x02;
3135141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x02;
3136141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x03;
3137141cc406Sopenharmony_ci	      dev->shadow_regs[0x39] = 0x0f;
3138141cc406Sopenharmony_ci
3139141cc406Sopenharmony_ci	      dev->shadow_regs[0x40] = 0x80;
3140141cc406Sopenharmony_ci
3141141cc406Sopenharmony_ci	      dev->shadow_regs[0x79] = 0x08;
3142141cc406Sopenharmony_ci
3143141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x00;
3144141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
3145141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x00;
3146141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
3147141cc406Sopenharmony_ci
3148141cc406Sopenharmony_ci	      dev->shadow_regs[0x8c] = 0x02;
3149141cc406Sopenharmony_ci	      dev->shadow_regs[0x8d] = 0x01;
3150141cc406Sopenharmony_ci	      dev->shadow_regs[0x8e] = 0x60;
3151141cc406Sopenharmony_ci	      dev->shadow_regs[0x8f] = 0x80;
3152141cc406Sopenharmony_ci
3153141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x00;
3154141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
3155141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;
3156141cc406Sopenharmony_ci
3157141cc406Sopenharmony_ci	      break;
3158141cc406Sopenharmony_ci
3159141cc406Sopenharmony_ci	    case X1100_B2_SENSOR:
3160141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x02;
3161141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x02;
3162141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x04;
3163141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x04;
3164141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x06;
3165141cc406Sopenharmony_ci
3166141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x20;
3167141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
3168141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x00;
3169141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
3170141cc406Sopenharmony_ci
3171141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x00;
3172141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
3173141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;
3174141cc406Sopenharmony_ci	      break;
3175141cc406Sopenharmony_ci	    case X1100_2C_SENSOR:
3176141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x01;
3177141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x01;
3178141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x02;
3179141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x02;
3180141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x03;	/* these are half of B2 sensor */
3181141cc406Sopenharmony_ci
3182141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x20;
3183141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
3184141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x00;
3185141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
3186141cc406Sopenharmony_ci
3187141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x00;
3188141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
3189141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
3190141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;
3191141cc406Sopenharmony_ci	      break;
3192141cc406Sopenharmony_ci	    case A920_SENSOR:
3193141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x01;
3194141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x01;
3195141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x02;
3196141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x02;
3197141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x03;
3198141cc406Sopenharmony_ci
3199141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x0d;
3200141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x14;
3201141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x06;
3202141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x45;
3203141cc406Sopenharmony_ci
3204141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x60;
3205141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x8d;
3206141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x0e;
3207141cc406Sopenharmony_ci	      break;
3208141cc406Sopenharmony_ci	    case X1200_SENSOR:
3209141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x01;
3210141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x01;
3211141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x02;
3212141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x02;
3213141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x02;
3214141cc406Sopenharmony_ci
3215141cc406Sopenharmony_ci	      dev->shadow_regs[0x79] = 0x20;
3216141cc406Sopenharmony_ci
3217141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x00;
3218141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
3219141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0xff;
3220141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x02;
3221141cc406Sopenharmony_ci
3222141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
3223141cc406Sopenharmony_ci	      break;
3224141cc406Sopenharmony_ci	    case X1200_USB2_SENSOR:
3225141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x01;
3226141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x01;
3227141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x02;
3228141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x02;
3229141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x02;
3230141cc406Sopenharmony_ci
3231141cc406Sopenharmony_ci	      dev->shadow_regs[0x79] = 0x20;
3232141cc406Sopenharmony_ci
3233141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x00;
3234141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
3235141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0xff;
3236141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x02;
3237141cc406Sopenharmony_ci
3238141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
3239141cc406Sopenharmony_ci	      break;
3240141cc406Sopenharmony_ci	    }
3241141cc406Sopenharmony_ci	  switch (dev->model.motor_type)
3242141cc406Sopenharmony_ci	    {
3243141cc406Sopenharmony_ci	    case X74_MOTOR:
3244141cc406Sopenharmony_ci	      /*  ? */
3245141cc406Sopenharmony_ci	      dev->shadow_regs[0xc4] = 0x20;
3246141cc406Sopenharmony_ci	      dev->shadow_regs[0xc5] = 0x0a;
3247141cc406Sopenharmony_ci	      dev->shadow_regs[0xc6] = 0x0b;
3248141cc406Sopenharmony_ci
3249141cc406Sopenharmony_ci	      dev->shadow_regs[0xc8] = 0x04;
3250141cc406Sopenharmony_ci	      dev->shadow_regs[0xc9] = 0x39;
3251141cc406Sopenharmony_ci	      dev->shadow_regs[0xca] = 0x01;
3252141cc406Sopenharmony_ci
3253141cc406Sopenharmony_ci	      /* bounds of movement range0 */
3254141cc406Sopenharmony_ci	      dev->shadow_regs[0xe0] = 0x07;
3255141cc406Sopenharmony_ci	      dev->shadow_regs[0xe1] = 0x18;
3256141cc406Sopenharmony_ci	      /* step size range0 */
3257141cc406Sopenharmony_ci	      dev->shadow_regs[0xe2] = 0xe7;
3258141cc406Sopenharmony_ci	      /* ? */
3259141cc406Sopenharmony_ci	      dev->shadow_regs[0xe3] = 0x03;
3260141cc406Sopenharmony_ci	      /* bounds of movement range1 */
3261141cc406Sopenharmony_ci	      dev->shadow_regs[0xe4] = 0xe7;
3262141cc406Sopenharmony_ci	      dev->shadow_regs[0xe5] = 0x14;
3263141cc406Sopenharmony_ci	      /* step size range1 */
3264141cc406Sopenharmony_ci	      dev->shadow_regs[0xe6] = 0x64;
3265141cc406Sopenharmony_ci	      /* bounds of movement range2 */
3266141cc406Sopenharmony_ci	      dev->shadow_regs[0xe7] = 0xcb;
3267141cc406Sopenharmony_ci	      dev->shadow_regs[0xe8] = 0x08;
3268141cc406Sopenharmony_ci	      /* step size range2 */
3269141cc406Sopenharmony_ci	      dev->shadow_regs[0xe9] = 0x32;
3270141cc406Sopenharmony_ci	      /* bounds of movement range3 */
3271141cc406Sopenharmony_ci	      dev->shadow_regs[0xea] = 0xe3;
3272141cc406Sopenharmony_ci	      dev->shadow_regs[0xeb] = 0x04;
3273141cc406Sopenharmony_ci	      /* step size range3 */
3274141cc406Sopenharmony_ci	      dev->shadow_regs[0xec] = 0x0c;
3275141cc406Sopenharmony_ci	      /* bounds of movement range4 */
3276141cc406Sopenharmony_ci	      dev->shadow_regs[0xed] = 0x00;
3277141cc406Sopenharmony_ci	      dev->shadow_regs[0xee] = 0x00;
3278141cc406Sopenharmony_ci	      /* step size range4 */
3279141cc406Sopenharmony_ci	      dev->shadow_regs[0xef] = 0x08;
3280141cc406Sopenharmony_ci	      break;
3281141cc406Sopenharmony_ci	    case A920_MOTOR:
3282141cc406Sopenharmony_ci	    case X1100_MOTOR:
3283141cc406Sopenharmony_ci	      /*  ? */
3284141cc406Sopenharmony_ci	      dev->shadow_regs[0xc5] = 0x10;
3285141cc406Sopenharmony_ci	      /* Movement direction & step size */
3286141cc406Sopenharmony_ci	      dev->shadow_regs[0xc6] = 0x09;
3287141cc406Sopenharmony_ci
3288141cc406Sopenharmony_ci	      dev->shadow_regs[0xc9] = 0x3b;
3289141cc406Sopenharmony_ci	      dev->shadow_regs[0xca] = 0x01;
3290141cc406Sopenharmony_ci	      /* bounds of movement range0 */
3291141cc406Sopenharmony_ci	      dev->shadow_regs[0xe0] = 0x4d;
3292141cc406Sopenharmony_ci	      dev->shadow_regs[0xe1] = 0x1c;
3293141cc406Sopenharmony_ci	      /* step size range0 */
3294141cc406Sopenharmony_ci	      dev->shadow_regs[0xe2] = 0x71;
3295141cc406Sopenharmony_ci	      /* ? */
3296141cc406Sopenharmony_ci	      dev->shadow_regs[0xe3] = 0x02;
3297141cc406Sopenharmony_ci	      /* bounds of movement range1 */
3298141cc406Sopenharmony_ci	      dev->shadow_regs[0xe4] = 0x6d;
3299141cc406Sopenharmony_ci	      dev->shadow_regs[0xe5] = 0x15;
3300141cc406Sopenharmony_ci	      /* step size range1 */
3301141cc406Sopenharmony_ci	      dev->shadow_regs[0xe6] = 0xdc;
3302141cc406Sopenharmony_ci	      /* bounds of movement range2 */
3303141cc406Sopenharmony_ci	      dev->shadow_regs[0xe7] = 0xad;
3304141cc406Sopenharmony_ci	      dev->shadow_regs[0xe8] = 0x07;
3305141cc406Sopenharmony_ci	      /* step size range2 */
3306141cc406Sopenharmony_ci	      dev->shadow_regs[0xe9] = 0x1b;
3307141cc406Sopenharmony_ci	      /* bounds of movement range3 */
3308141cc406Sopenharmony_ci	      dev->shadow_regs[0xea] = 0xe1;
3309141cc406Sopenharmony_ci	      dev->shadow_regs[0xeb] = 0x03;
3310141cc406Sopenharmony_ci	      /* step size range3 */
3311141cc406Sopenharmony_ci	      dev->shadow_regs[0xec] = 0x07;
3312141cc406Sopenharmony_ci	      /* bounds of movement range4 -only for 75dpi grayscale */
3313141cc406Sopenharmony_ci	      dev->shadow_regs[0xed] = 0xc2;
3314141cc406Sopenharmony_ci	      dev->shadow_regs[0xee] = 0x02;
3315141cc406Sopenharmony_ci	      /* step size range4 */
3316141cc406Sopenharmony_ci	      dev->shadow_regs[0xef] = 0x03;
3317141cc406Sopenharmony_ci	      break;
3318141cc406Sopenharmony_ci	    }
3319141cc406Sopenharmony_ci
3320141cc406Sopenharmony_ci	  /* set grayscale  scan  */
3321141cc406Sopenharmony_ci	  dev->shadow_regs[0x2f] = 0x21;
3322141cc406Sopenharmony_ci
3323141cc406Sopenharmony_ci	  /* set ? only for colour? */
3324141cc406Sopenharmony_ci	  dev->shadow_regs[0x80] = 0x00;
3325141cc406Sopenharmony_ci	  dev->shadow_regs[0x81] = 0x00;
3326141cc406Sopenharmony_ci	  dev->shadow_regs[0x82] = 0x00;
3327141cc406Sopenharmony_ci	  /* Motor enable & Coordinate space denominator */
3328141cc406Sopenharmony_ci	  dev->shadow_regs[0xc3] = 0x81;
3329141cc406Sopenharmony_ci
3330141cc406Sopenharmony_ci	}
3331141cc406Sopenharmony_ci
3332141cc406Sopenharmony_ci      /* set motor resolution divisor */
3333141cc406Sopenharmony_ci      dev->shadow_regs[0x39] = 0x0f;
3334141cc406Sopenharmony_ci
3335141cc406Sopenharmony_ci      /* set # of head moves per CIS read */
3336141cc406Sopenharmony_ci      rts88xx_set_scan_frequency (dev->shadow_regs, 1);
3337141cc406Sopenharmony_ci
3338141cc406Sopenharmony_ci      /* set horizontal resolution */
3339141cc406Sopenharmony_ci      if (dev->model.sensor_type != X1200_SENSOR)
3340141cc406Sopenharmony_ci	dev->shadow_regs[0x79] = 0x08;
3341141cc406Sopenharmony_ci
3342141cc406Sopenharmony_ci    }
3343141cc406Sopenharmony_ci
3344141cc406Sopenharmony_ci  /* 150dpi x 150dpi */
3345141cc406Sopenharmony_ci  if (resolution == 150)
3346141cc406Sopenharmony_ci    {
3347141cc406Sopenharmony_ci      DBG (5, "sanei_lexmark_low_set_scan_regs(): 150 DPI resolution\n");
3348141cc406Sopenharmony_ci
3349141cc406Sopenharmony_ci      if (isColourScan)
3350141cc406Sopenharmony_ci	{
3351141cc406Sopenharmony_ci
3352141cc406Sopenharmony_ci	  switch (dev->model.sensor_type)
3353141cc406Sopenharmony_ci	    {
3354141cc406Sopenharmony_ci	    case X74_SENSOR:
3355141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x08;
3356141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x06;
3357141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x05;
3358141cc406Sopenharmony_ci	      dev->shadow_regs[0x39] = 0x07;
3359141cc406Sopenharmony_ci
3360141cc406Sopenharmony_ci	      /* resolution divisor */
3361141cc406Sopenharmony_ci	      dev->shadow_regs[0x79] = 0x08;
3362141cc406Sopenharmony_ci
3363141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x0a;
3364141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x0c;
3365141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x04;
3366141cc406Sopenharmony_ci
3367141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x00;
3368141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
3369141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x00;
3370141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
3371141cc406Sopenharmony_ci
3372141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x00;
3373141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
3374141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;
3375141cc406Sopenharmony_ci	      break;
3376141cc406Sopenharmony_ci	    case X1100_B2_SENSOR:
3377141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x0b;
3378141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x0b;
3379141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x0a;
3380141cc406Sopenharmony_ci
3381141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x05;
3382141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x05;
3383141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x0a;
3384141cc406Sopenharmony_ci
3385141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x83;
3386141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x7e;
3387141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0xad;
3388141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x35;
3389141cc406Sopenharmony_ci
3390141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0xfe;
3391141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0xdf;
3392141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x0e;
3393141cc406Sopenharmony_ci	      break;
3394141cc406Sopenharmony_ci	    case X1100_2C_SENSOR:
3395141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x05;
3396141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x07;
3397141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x05;
3398141cc406Sopenharmony_ci
3399141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x00;
3400141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x02;
3401141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x06;
3402141cc406Sopenharmony_ci
3403141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x20;
3404141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
3405141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x00;
3406141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
3407141cc406Sopenharmony_ci
3408141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x00;
3409141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
3410141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;
3411141cc406Sopenharmony_ci	      break;
3412141cc406Sopenharmony_ci	    case A920_SENSOR:
3413141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x03;
3414141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x08;
3415141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x05;
3416141cc406Sopenharmony_ci
3417141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x0e;
3418141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x07;
3419141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x02;
3420141cc406Sopenharmony_ci
3421141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x05;
3422141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x14;
3423141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x06;
3424141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x04;
3425141cc406Sopenharmony_ci
3426141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0xe0;
3427141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x85;
3428141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x0e;
3429141cc406Sopenharmony_ci	      break;
3430141cc406Sopenharmony_ci	    case X1200_SENSOR:
3431141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x04;
3432141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x05;
3433141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x02;
3434141cc406Sopenharmony_ci	      /* data compression
3435141cc406Sopenharmony_ci	         dev->shadow_regs[0x40] = 0x90;
3436141cc406Sopenharmony_ci	         dev->shadow_regs[0x50] = 0x20; */
3437141cc406Sopenharmony_ci	      /* no data compression */
3438141cc406Sopenharmony_ci	      dev->shadow_regs[0x40] = 0x80;
3439141cc406Sopenharmony_ci	      dev->shadow_regs[0x50] = 0x00;
3440141cc406Sopenharmony_ci
3441141cc406Sopenharmony_ci	      dev->shadow_regs[0x79] = 0x20;
3442141cc406Sopenharmony_ci
3443141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x00;
3444141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x07;
3445141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x0b;
3446141cc406Sopenharmony_ci
3447141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x20;
3448141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x1e;
3449141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x39;
3450141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
3451141cc406Sopenharmony_ci
3452141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x92;
3453141cc406Sopenharmony_ci
3454141cc406Sopenharmony_ci	      break;
3455141cc406Sopenharmony_ci	    case X1200_USB2_SENSOR:
3456141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x04;
3457141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x05;
3458141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x02;
3459141cc406Sopenharmony_ci
3460141cc406Sopenharmony_ci	      dev->shadow_regs[0x40] = 0x80;
3461141cc406Sopenharmony_ci	      dev->shadow_regs[0x50] = 0x00;
3462141cc406Sopenharmony_ci
3463141cc406Sopenharmony_ci	      dev->shadow_regs[0x79] = 0x20;
3464141cc406Sopenharmony_ci
3465141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x00;
3466141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x07;
3467141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x0b;
3468141cc406Sopenharmony_ci
3469141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x20;
3470141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x1e;
3471141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x39;
3472141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
3473141cc406Sopenharmony_ci
3474141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x92;
3475141cc406Sopenharmony_ci	      break;
3476141cc406Sopenharmony_ci	    }			/* switch */
3477141cc406Sopenharmony_ci	  switch (dev->model.motor_type)
3478141cc406Sopenharmony_ci	    {
3479141cc406Sopenharmony_ci	    case X74_MOTOR:
3480141cc406Sopenharmony_ci	      dev->shadow_regs[0xc2] = 0x80;
3481141cc406Sopenharmony_ci	      /*  ? */
3482141cc406Sopenharmony_ci	      dev->shadow_regs[0xc4] = 0x20;
3483141cc406Sopenharmony_ci
3484141cc406Sopenharmony_ci	      dev->shadow_regs[0xc5] = 0x0e;
3485141cc406Sopenharmony_ci	      /* Movement direction & step size */
3486141cc406Sopenharmony_ci	      dev->shadow_regs[0xc6] = 0x0b;
3487141cc406Sopenharmony_ci	      dev->shadow_regs[0xc7] = 0x00;
3488141cc406Sopenharmony_ci	      dev->shadow_regs[0xc8] = 0x04;
3489141cc406Sopenharmony_ci	      dev->shadow_regs[0xc9] = 0x39;
3490141cc406Sopenharmony_ci	      dev->shadow_regs[0xca] = 0x03;
3491141cc406Sopenharmony_ci
3492141cc406Sopenharmony_ci	      /* bounds of movement range0 */
3493141cc406Sopenharmony_ci	      dev->shadow_regs[0xe0] = 0x41;
3494141cc406Sopenharmony_ci	      dev->shadow_regs[0xe1] = 0x09;
3495141cc406Sopenharmony_ci	      /* step size range0 */
3496141cc406Sopenharmony_ci	      dev->shadow_regs[0xe2] = 0x89;
3497141cc406Sopenharmony_ci	      /* ? */
3498141cc406Sopenharmony_ci	      dev->shadow_regs[0xe3] = 0x02;
3499141cc406Sopenharmony_ci	      /* bounds of movement range1 */
3500141cc406Sopenharmony_ci	      dev->shadow_regs[0xe4] = 0x0d;
3501141cc406Sopenharmony_ci
3502141cc406Sopenharmony_ci	      dev->shadow_regs[0xe5] = 0x09;
3503141cc406Sopenharmony_ci	      /* step size range1 */
3504141cc406Sopenharmony_ci	      dev->shadow_regs[0xe6] = 0x0d;
3505141cc406Sopenharmony_ci	      /* bounds of movement range2 */
3506141cc406Sopenharmony_ci	      dev->shadow_regs[0xe7] = 0xe8;
3507141cc406Sopenharmony_ci	      dev->shadow_regs[0xe8] = 0x02;
3508141cc406Sopenharmony_ci	      /* step size range2 */
3509141cc406Sopenharmony_ci	      dev->shadow_regs[0xe9] = 0x05;
3510141cc406Sopenharmony_ci	      /* bounds of movement range3 */
3511141cc406Sopenharmony_ci	      dev->shadow_regs[0xea] = 0x00;
3512141cc406Sopenharmony_ci	      dev->shadow_regs[0xeb] = 0x00;
3513141cc406Sopenharmony_ci	      /* step size range3 */
3514141cc406Sopenharmony_ci	      dev->shadow_regs[0xec] = 0x01;
3515141cc406Sopenharmony_ci	      /* bounds of movement range4 */
3516141cc406Sopenharmony_ci	      dev->shadow_regs[0xed] = 0x00;
3517141cc406Sopenharmony_ci	      dev->shadow_regs[0xee] = 0x00;
3518141cc406Sopenharmony_ci	      /* step size range4 */
3519141cc406Sopenharmony_ci	      dev->shadow_regs[0xef] = 0x01;
3520141cc406Sopenharmony_ci	      break;
3521141cc406Sopenharmony_ci	    case X1100_MOTOR:
3522141cc406Sopenharmony_ci	    case A920_MOTOR:
3523141cc406Sopenharmony_ci	      /*  ? */
3524141cc406Sopenharmony_ci	      dev->shadow_regs[0xc5] = 0x0e;
3525141cc406Sopenharmony_ci	      /*  ? */
3526141cc406Sopenharmony_ci	      dev->shadow_regs[0xc9] = 0x3a;
3527141cc406Sopenharmony_ci	      dev->shadow_regs[0xca] = 0x03;
3528141cc406Sopenharmony_ci	      /* bounds of movement range0 */
3529141cc406Sopenharmony_ci	      dev->shadow_regs[0xe0] = 0x61;
3530141cc406Sopenharmony_ci	      dev->shadow_regs[0xe1] = 0x0a;
3531141cc406Sopenharmony_ci	      /* step size range0 */
3532141cc406Sopenharmony_ci	      dev->shadow_regs[0xe2] = 0xed;
3533141cc406Sopenharmony_ci	      /* ? */
3534141cc406Sopenharmony_ci	      dev->shadow_regs[0xe3] = 0x02;
3535141cc406Sopenharmony_ci	      /* bounds of movement range1 */
3536141cc406Sopenharmony_ci	      dev->shadow_regs[0xe4] = 0x29;
3537141cc406Sopenharmony_ci	      dev->shadow_regs[0xe5] = 0x0a;
3538141cc406Sopenharmony_ci	      /* step size range1 */
3539141cc406Sopenharmony_ci	      dev->shadow_regs[0xe6] = 0x0e;
3540141cc406Sopenharmony_ci	      /* bounds of movement range2 */
3541141cc406Sopenharmony_ci	      dev->shadow_regs[0xe7] = 0x29;
3542141cc406Sopenharmony_ci	      dev->shadow_regs[0xe8] = 0x03;
3543141cc406Sopenharmony_ci	      /* step size range2 */
3544141cc406Sopenharmony_ci	      dev->shadow_regs[0xe9] = 0x05;
3545141cc406Sopenharmony_ci	      /* bounds of movement range3 */
3546141cc406Sopenharmony_ci	      dev->shadow_regs[0xea] = 0x00;
3547141cc406Sopenharmony_ci	      dev->shadow_regs[0xeb] = 0x00;
3548141cc406Sopenharmony_ci	      /* step size range3 */
3549141cc406Sopenharmony_ci	      dev->shadow_regs[0xec] = 0x01;
3550141cc406Sopenharmony_ci	      /* step size range4 */
3551141cc406Sopenharmony_ci	      dev->shadow_regs[0xef] = 0x01;
3552141cc406Sopenharmony_ci	      break;
3553141cc406Sopenharmony_ci	    }
3554141cc406Sopenharmony_ci	  /* set colour scan */
3555141cc406Sopenharmony_ci	  dev->shadow_regs[0x2f] = 0x11;
3556141cc406Sopenharmony_ci
3557141cc406Sopenharmony_ci	  dev->shadow_regs[0x35] = 0x01;
3558141cc406Sopenharmony_ci	  dev->shadow_regs[0x37] = 0x01;
3559141cc406Sopenharmony_ci	  /* Motor enable & Coordinate space denominator */
3560141cc406Sopenharmony_ci	  dev->shadow_regs[0xc3] = 0x83;
3561141cc406Sopenharmony_ci
3562141cc406Sopenharmony_ci	}			/* if (isColourScan) */
3563141cc406Sopenharmony_ci      else
3564141cc406Sopenharmony_ci	{
3565141cc406Sopenharmony_ci	  switch (dev->model.sensor_type)
3566141cc406Sopenharmony_ci	    {
3567141cc406Sopenharmony_ci	    case X74_SENSOR:
3568141cc406Sopenharmony_ci
3569141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x02;
3570141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x02;
3571141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x04;
3572141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x04;
3573141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x06;
3574141cc406Sopenharmony_ci	      dev->shadow_regs[0x39] = 0x07;
3575141cc406Sopenharmony_ci	      /* Motor enable & Coordinate space denominator */
3576141cc406Sopenharmony_ci	      dev->shadow_regs[0x40] = 0x40;
3577141cc406Sopenharmony_ci
3578141cc406Sopenharmony_ci	      /* resolution divisor */
3579141cc406Sopenharmony_ci	      dev->shadow_regs[0x79] = 0x08;
3580141cc406Sopenharmony_ci
3581141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x00;
3582141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
3583141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x00;
3584141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
3585141cc406Sopenharmony_ci
3586141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x00;
3587141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
3588141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;
3589141cc406Sopenharmony_ci	      break;
3590141cc406Sopenharmony_ci	    case X1100_B2_SENSOR:
3591141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x04;
3592141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x04;
3593141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x07;
3594141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x07;
3595141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x0a;
3596141cc406Sopenharmony_ci
3597141cc406Sopenharmony_ci
3598141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x00;
3599141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
3600141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x00;
3601141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
3602141cc406Sopenharmony_ci
3603141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x00;
3604141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
3605141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;
3606141cc406Sopenharmony_ci	      break;
3607141cc406Sopenharmony_ci	    case X1100_2C_SENSOR:
3608141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x02;
3609141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x02;
3610141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x04;
3611141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x04;
3612141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x05;
3613141cc406Sopenharmony_ci
3614141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x20;
3615141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
3616141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x00;
3617141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
3618141cc406Sopenharmony_ci
3619141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x00;
3620141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
3621141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;
3622141cc406Sopenharmony_ci	      break;
3623141cc406Sopenharmony_ci	    case A920_SENSOR:
3624141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x02;
3625141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x02;
3626141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x04;
3627141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x04;
3628141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x05;
3629141cc406Sopenharmony_ci
3630141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x0d;
3631141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x14;
3632141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x06;
3633141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x45;
3634141cc406Sopenharmony_ci
3635141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x60;
3636141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x8d;
3637141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x0e;
3638141cc406Sopenharmony_ci	      break;
3639141cc406Sopenharmony_ci	    case X1200_SENSOR:
3640141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x01;
3641141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x01;
3642141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x02;
3643141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x02;
3644141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x03;
3645141cc406Sopenharmony_ci
3646141cc406Sopenharmony_ci	      /* dev->shadow_regs[0x40] = 0x90;
3647141cc406Sopenharmony_ci	         dev->shadow_regs[0x50] = 0x20; */
3648141cc406Sopenharmony_ci	      /* no data compression */
3649141cc406Sopenharmony_ci	      dev->shadow_regs[0x40] = 0x80;
3650141cc406Sopenharmony_ci	      dev->shadow_regs[0x50] = 0x00;
3651141cc406Sopenharmony_ci
3652141cc406Sopenharmony_ci	      dev->shadow_regs[0x79] = 0x20;
3653141cc406Sopenharmony_ci
3654141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x00;
3655141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
3656141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0xff;
3657141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x02;
3658141cc406Sopenharmony_ci
3659141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x92;
3660141cc406Sopenharmony_ci	      break;
3661141cc406Sopenharmony_ci	    case X1200_USB2_SENSOR:
3662141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x01;
3663141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x01;
3664141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x02;
3665141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x02;
3666141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x03;
3667141cc406Sopenharmony_ci
3668141cc406Sopenharmony_ci	      dev->shadow_regs[0x40] = 0x80;
3669141cc406Sopenharmony_ci	      dev->shadow_regs[0x50] = 0x00;
3670141cc406Sopenharmony_ci
3671141cc406Sopenharmony_ci	      dev->shadow_regs[0x79] = 0x20;
3672141cc406Sopenharmony_ci
3673141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x00;
3674141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
3675141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0xff;
3676141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x02;
3677141cc406Sopenharmony_ci
3678141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x92;
3679141cc406Sopenharmony_ci	      break;
3680141cc406Sopenharmony_ci	    }			/* switch */
3681141cc406Sopenharmony_ci	  switch (dev->model.motor_type)
3682141cc406Sopenharmony_ci	    {
3683141cc406Sopenharmony_ci	    case X74_MOTOR:
3684141cc406Sopenharmony_ci	      /*  ? */
3685141cc406Sopenharmony_ci	      dev->shadow_regs[0xc4] = 0x20;
3686141cc406Sopenharmony_ci	      dev->shadow_regs[0xc5] = 0x14;
3687141cc406Sopenharmony_ci	      /* Movement direction & step size */
3688141cc406Sopenharmony_ci	      dev->shadow_regs[0xc6] = 0x0b;
3689141cc406Sopenharmony_ci
3690141cc406Sopenharmony_ci	      dev->shadow_regs[0xc8] = 0x04;
3691141cc406Sopenharmony_ci	      dev->shadow_regs[0xc9] = 0x39;
3692141cc406Sopenharmony_ci	      dev->shadow_regs[0xca] = 0x01;
3693141cc406Sopenharmony_ci
3694141cc406Sopenharmony_ci	      /* bounds of movement range0 */
3695141cc406Sopenharmony_ci	      dev->shadow_regs[0xe0] = 0x09;
3696141cc406Sopenharmony_ci	      dev->shadow_regs[0xe1] = 0x18;
3697141cc406Sopenharmony_ci	      /* step size range0 */
3698141cc406Sopenharmony_ci	      dev->shadow_regs[0xe2] = 0xe9;
3699141cc406Sopenharmony_ci	      /* ? */
3700141cc406Sopenharmony_ci	      dev->shadow_regs[0xe3] = 0x03;
3701141cc406Sopenharmony_ci	      /* bounds of movement range1 */
3702141cc406Sopenharmony_ci	      dev->shadow_regs[0xe4] = 0x79;
3703141cc406Sopenharmony_ci
3704141cc406Sopenharmony_ci	      dev->shadow_regs[0xe5] = 0x16;
3705141cc406Sopenharmony_ci	      /* step size range1 */
3706141cc406Sopenharmony_ci	      dev->shadow_regs[0xe6] = 0x64;
3707141cc406Sopenharmony_ci	      /* bounds of movement range2 */
3708141cc406Sopenharmony_ci	      dev->shadow_regs[0xe7] = 0xcd;
3709141cc406Sopenharmony_ci	      dev->shadow_regs[0xe8] = 0x08;
3710141cc406Sopenharmony_ci	      /* step size range2 */
3711141cc406Sopenharmony_ci	      dev->shadow_regs[0xe9] = 0x32;
3712141cc406Sopenharmony_ci	      /* bounds of movement range3 */
3713141cc406Sopenharmony_ci	      dev->shadow_regs[0xea] = 0xe5;
3714141cc406Sopenharmony_ci	      dev->shadow_regs[0xeb] = 0x04;
3715141cc406Sopenharmony_ci	      /* step size range3 */
3716141cc406Sopenharmony_ci	      dev->shadow_regs[0xec] = 0x0c;
3717141cc406Sopenharmony_ci	      /* bounds of movement range4 */
3718141cc406Sopenharmony_ci	      dev->shadow_regs[0xed] = 0x00;
3719141cc406Sopenharmony_ci	      dev->shadow_regs[0xee] = 0x00;
3720141cc406Sopenharmony_ci	      /* step size range4 */
3721141cc406Sopenharmony_ci	      dev->shadow_regs[0xef] = 0x08;
3722141cc406Sopenharmony_ci	      break;
3723141cc406Sopenharmony_ci	    case X1100_MOTOR:
3724141cc406Sopenharmony_ci	    case A920_MOTOR:
3725141cc406Sopenharmony_ci	      /*  ? */
3726141cc406Sopenharmony_ci	      dev->shadow_regs[0xc5] = 0x16;
3727141cc406Sopenharmony_ci	      /* Movement direction & step size */
3728141cc406Sopenharmony_ci	      dev->shadow_regs[0xc6] = 0x09;
3729141cc406Sopenharmony_ci	      /*  ? */
3730141cc406Sopenharmony_ci	      dev->shadow_regs[0xc9] = 0x3b;
3731141cc406Sopenharmony_ci	      dev->shadow_regs[0xca] = 0x01;
3732141cc406Sopenharmony_ci	      /* bounds of movement range0 */
3733141cc406Sopenharmony_ci	      dev->shadow_regs[0xe0] = 0xdd;
3734141cc406Sopenharmony_ci	      dev->shadow_regs[0xe1] = 0x18;
3735141cc406Sopenharmony_ci	      /* step size range0 */
3736141cc406Sopenharmony_ci	      dev->shadow_regs[0xe2] = 0x01;
3737141cc406Sopenharmony_ci	      /* ? */
3738141cc406Sopenharmony_ci	      dev->shadow_regs[0xe3] = 0x03;
3739141cc406Sopenharmony_ci	      /* bounds of movement range1 */
3740141cc406Sopenharmony_ci	      dev->shadow_regs[0xe4] = 0x6d;
3741141cc406Sopenharmony_ci	      dev->shadow_regs[0xe5] = 0x15;
3742141cc406Sopenharmony_ci	      /* step size range1 */
3743141cc406Sopenharmony_ci	      dev->shadow_regs[0xe6] = 0xdc;
3744141cc406Sopenharmony_ci	      /* bounds of movement range2 */
3745141cc406Sopenharmony_ci	      dev->shadow_regs[0xe7] = 0xad;
3746141cc406Sopenharmony_ci	      dev->shadow_regs[0xe8] = 0x07;
3747141cc406Sopenharmony_ci	      /* step size range2 */
3748141cc406Sopenharmony_ci	      dev->shadow_regs[0xe9] = 0x1b;
3749141cc406Sopenharmony_ci	      /* bounds of movement range3 */
3750141cc406Sopenharmony_ci	      dev->shadow_regs[0xea] = 0xe1;
3751141cc406Sopenharmony_ci	      dev->shadow_regs[0xeb] = 0x03;
3752141cc406Sopenharmony_ci	      /* step size range3 */
3753141cc406Sopenharmony_ci	      dev->shadow_regs[0xec] = 0x07;
3754141cc406Sopenharmony_ci	      /* step size range4 */
3755141cc406Sopenharmony_ci	      dev->shadow_regs[0xef] = 0x03;
3756141cc406Sopenharmony_ci	      break;
3757141cc406Sopenharmony_ci	    }
3758141cc406Sopenharmony_ci
3759141cc406Sopenharmony_ci	  /* set grayscale  scan */
3760141cc406Sopenharmony_ci	  dev->shadow_regs[0x2f] = 0x21;
3761141cc406Sopenharmony_ci	  /* set motor resolution divisor */
3762141cc406Sopenharmony_ci	  dev->shadow_regs[0x39] = 0x07;
3763141cc406Sopenharmony_ci	  /* set ? only for colour? */
3764141cc406Sopenharmony_ci	  dev->shadow_regs[0x80] = 0x00;
3765141cc406Sopenharmony_ci	  dev->shadow_regs[0x81] = 0x00;
3766141cc406Sopenharmony_ci	  dev->shadow_regs[0x82] = 0x00;
3767141cc406Sopenharmony_ci
3768141cc406Sopenharmony_ci	  /* Motor enable & Coordinate space denominator */
3769141cc406Sopenharmony_ci	  dev->shadow_regs[0xc3] = 0x81;
3770141cc406Sopenharmony_ci	}			/* else (greyscale) */
3771141cc406Sopenharmony_ci
3772141cc406Sopenharmony_ci
3773141cc406Sopenharmony_ci
3774141cc406Sopenharmony_ci
3775141cc406Sopenharmony_ci      /* set # of head moves per CIS read */
3776141cc406Sopenharmony_ci      rts88xx_set_scan_frequency (dev->shadow_regs, 1);
3777141cc406Sopenharmony_ci
3778141cc406Sopenharmony_ci      /* hum, horizontal resolution different for X1200 ? */
3779141cc406Sopenharmony_ci      /* if (dev->model.sensor_type != X1200_SENSOR)
3780141cc406Sopenharmony_ci         dev->shadow_regs[0x79] = 0x20; */
3781141cc406Sopenharmony_ci
3782141cc406Sopenharmony_ci    }
3783141cc406Sopenharmony_ci
3784141cc406Sopenharmony_ci  /*300dpi x 300dpi */
3785141cc406Sopenharmony_ci  if (resolution == 300)
3786141cc406Sopenharmony_ci    {
3787141cc406Sopenharmony_ci      DBG (5, "sanei_lexmark_low_set_scan_regs(): 300 DPI resolution\n");
3788141cc406Sopenharmony_ci
3789141cc406Sopenharmony_ci      if (isColourScan)
3790141cc406Sopenharmony_ci	{
3791141cc406Sopenharmony_ci
3792141cc406Sopenharmony_ci	  switch (dev->model.sensor_type)
3793141cc406Sopenharmony_ci	    {
3794141cc406Sopenharmony_ci	    case X74_SENSOR:
3795141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x08;
3796141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x06;
3797141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x05;
3798141cc406Sopenharmony_ci	      dev->shadow_regs[0x39] = 0x07;
3799141cc406Sopenharmony_ci
3800141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x08;
3801141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x0a;
3802141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x03;
3803141cc406Sopenharmony_ci
3804141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x00;
3805141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
3806141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x00;
3807141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
3808141cc406Sopenharmony_ci
3809141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x00;
3810141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
3811141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;
3812141cc406Sopenharmony_ci	      break;
3813141cc406Sopenharmony_ci	    case X1100_B2_SENSOR:
3814141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x15;
3815141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x15;
3816141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x14;
3817141cc406Sopenharmony_ci	      /* set motor resolution divisor */
3818141cc406Sopenharmony_ci	      dev->shadow_regs[0x39] = 0x03;
3819141cc406Sopenharmony_ci
3820141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x0a;
3821141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x0a;
3822141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x06;
3823141cc406Sopenharmony_ci
3824141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x83;
3825141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x7e;
3826141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0xad;
3827141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x35;
3828141cc406Sopenharmony_ci
3829141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0xfe;
3830141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0xdf;
3831141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x0e;
3832141cc406Sopenharmony_ci	      break;
3833141cc406Sopenharmony_ci	    case X1100_2C_SENSOR:
3834141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x08;
3835141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x0d;
3836141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x09;
3837141cc406Sopenharmony_ci	      /* set motor resolution divisor */
3838141cc406Sopenharmony_ci	      dev->shadow_regs[0x39] = 0x03;
3839141cc406Sopenharmony_ci
3840141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x0e;
3841141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x04;
3842141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x0a;
3843141cc406Sopenharmony_ci
3844141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x20;
3845141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
3846141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x00;
3847141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
3848141cc406Sopenharmony_ci
3849141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x00;
3850141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
3851141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;
3852141cc406Sopenharmony_ci	      break;
3853141cc406Sopenharmony_ci	    case A920_SENSOR:
3854141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x06;
3855141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x10;
3856141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x09;
3857141cc406Sopenharmony_ci	      /* set motor resolution divisor */
3858141cc406Sopenharmony_ci	      dev->shadow_regs[0x39] = 0x03;
3859141cc406Sopenharmony_ci
3860141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x0c;
3861141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x02;
3862141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x04;
3863141cc406Sopenharmony_ci
3864141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x05;
3865141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x14;
3866141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x06;
3867141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x04;
3868141cc406Sopenharmony_ci
3869141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0xe0;
3870141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x85;
3871141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x0e;
3872141cc406Sopenharmony_ci	      break;
3873141cc406Sopenharmony_ci	    case X1200_SENSOR:
3874141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x07;
3875141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x09;
3876141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x04;
3877141cc406Sopenharmony_ci	      /* set motor resolution divisor */
3878141cc406Sopenharmony_ci	      dev->shadow_regs[0x39] = 0x03;
3879141cc406Sopenharmony_ci
3880141cc406Sopenharmony_ci	      /* data compression
3881141cc406Sopenharmony_ci	         dev->shadow_regs[0x40] = 0x90;
3882141cc406Sopenharmony_ci	         dev->shadow_regs[0x50] = 0x20; */
3883141cc406Sopenharmony_ci	      /* no data compression */
3884141cc406Sopenharmony_ci	      dev->shadow_regs[0x40] = 0x80;
3885141cc406Sopenharmony_ci	      dev->shadow_regs[0x50] = 0x00;
3886141cc406Sopenharmony_ci
3887141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x00;
3888141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x0e;
3889141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x06;
3890141cc406Sopenharmony_ci	      break;
3891141cc406Sopenharmony_ci	    case X1200_USB2_SENSOR:
3892141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x07;
3893141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x09;
3894141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x04;
3895141cc406Sopenharmony_ci	      /* set motor resolution divisor */
3896141cc406Sopenharmony_ci	      dev->shadow_regs[0x39] = 0x03;
3897141cc406Sopenharmony_ci
3898141cc406Sopenharmony_ci	      dev->shadow_regs[0x40] = 0x80;
3899141cc406Sopenharmony_ci	      dev->shadow_regs[0x50] = 0x00;
3900141cc406Sopenharmony_ci
3901141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x00;
3902141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x0e;
3903141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x06;
3904141cc406Sopenharmony_ci	      break;
3905141cc406Sopenharmony_ci	    }
3906141cc406Sopenharmony_ci	  switch (dev->model.motor_type)
3907141cc406Sopenharmony_ci	    {
3908141cc406Sopenharmony_ci	    case X74_MOTOR:
3909141cc406Sopenharmony_ci	      /*  ? */
3910141cc406Sopenharmony_ci	      dev->shadow_regs[0xc4] = 0x20;
3911141cc406Sopenharmony_ci	      dev->shadow_regs[0xc5] = 0x12;
3912141cc406Sopenharmony_ci	      /* Movement direction & step size */
3913141cc406Sopenharmony_ci	      dev->shadow_regs[0xc6] = 0x09;
3914141cc406Sopenharmony_ci
3915141cc406Sopenharmony_ci	      dev->shadow_regs[0xc8] = 0x04;
3916141cc406Sopenharmony_ci	      dev->shadow_regs[0xc9] = 0x39;
3917141cc406Sopenharmony_ci	      dev->shadow_regs[0xca] = 0x0f;
3918141cc406Sopenharmony_ci
3919141cc406Sopenharmony_ci	      /* bounds of movement range0 */
3920141cc406Sopenharmony_ci	      dev->shadow_regs[0xe0] = 0x5d;
3921141cc406Sopenharmony_ci	      dev->shadow_regs[0xe1] = 0x05;
3922141cc406Sopenharmony_ci	      /* step size range0 */
3923141cc406Sopenharmony_ci	      dev->shadow_regs[0xe2] = 0xed;
3924141cc406Sopenharmony_ci	      /* ? */
3925141cc406Sopenharmony_ci	      dev->shadow_regs[0xe3] = 0x02;
3926141cc406Sopenharmony_ci	      /* bounds of movement range1 */
3927141cc406Sopenharmony_ci	      dev->shadow_regs[0xe4] = 0x29;
3928141cc406Sopenharmony_ci	      dev->shadow_regs[0xe5] = 0x05;
3929141cc406Sopenharmony_ci	      /* step size range1 */
3930141cc406Sopenharmony_ci	      dev->shadow_regs[0xe6] = 0x0d;
3931141cc406Sopenharmony_ci	      /* bounds of movement range2 */
3932141cc406Sopenharmony_ci	      dev->shadow_regs[0xe7] = 0x00;
3933141cc406Sopenharmony_ci	      dev->shadow_regs[0xe8] = 0x00;
3934141cc406Sopenharmony_ci	      /* step size range2 */
3935141cc406Sopenharmony_ci	      dev->shadow_regs[0xe9] = 0x05;
3936141cc406Sopenharmony_ci	      /* bounds of movement range3 */
3937141cc406Sopenharmony_ci	      dev->shadow_regs[0xea] = 0x00;
3938141cc406Sopenharmony_ci	      dev->shadow_regs[0xeb] = 0x00;
3939141cc406Sopenharmony_ci	      /* step size range3 */
3940141cc406Sopenharmony_ci	      dev->shadow_regs[0xec] = 0x01;
3941141cc406Sopenharmony_ci	      /* bounds of movement range4 -only for 75dpi grayscale */
3942141cc406Sopenharmony_ci	      dev->shadow_regs[0xed] = 0x00;
3943141cc406Sopenharmony_ci	      dev->shadow_regs[0xee] = 0x00;
3944141cc406Sopenharmony_ci	      /* step size range4 */
3945141cc406Sopenharmony_ci	      dev->shadow_regs[0xef] = 0x01;
3946141cc406Sopenharmony_ci	      break;
3947141cc406Sopenharmony_ci	    case A920_MOTOR:
3948141cc406Sopenharmony_ci	    case X1100_MOTOR:
3949141cc406Sopenharmony_ci	      /*  ? */
3950141cc406Sopenharmony_ci	      dev->shadow_regs[0xc5] = 0x17;
3951141cc406Sopenharmony_ci	      /* Movement direction & step size */
3952141cc406Sopenharmony_ci	      dev->shadow_regs[0xc6] = 0x09;
3953141cc406Sopenharmony_ci	      /*  ? */
3954141cc406Sopenharmony_ci	      dev->shadow_regs[0xc9] = 0x3a;
3955141cc406Sopenharmony_ci	      dev->shadow_regs[0xca] = 0x0a;
3956141cc406Sopenharmony_ci	      /* bounds of movement range0 */
3957141cc406Sopenharmony_ci	      dev->shadow_regs[0xe0] = 0x75;
3958141cc406Sopenharmony_ci	      dev->shadow_regs[0xe1] = 0x0a;
3959141cc406Sopenharmony_ci	      /* step size range0 */
3960141cc406Sopenharmony_ci	      dev->shadow_regs[0xe2] = 0xdd;
3961141cc406Sopenharmony_ci	      /* ? */
3962141cc406Sopenharmony_ci	      dev->shadow_regs[0xe3] = 0x05;
3963141cc406Sopenharmony_ci	      /* bounds of movement range1 */
3964141cc406Sopenharmony_ci	      dev->shadow_regs[0xe4] = 0x59;
3965141cc406Sopenharmony_ci	      dev->shadow_regs[0xe5] = 0x0a;
3966141cc406Sopenharmony_ci	      /* step size range1 */
3967141cc406Sopenharmony_ci	      dev->shadow_regs[0xe6] = 0x0e;
3968141cc406Sopenharmony_ci	      /* bounds of movement range2 */
3969141cc406Sopenharmony_ci	      dev->shadow_regs[0xe7] = 0x00;
3970141cc406Sopenharmony_ci	      dev->shadow_regs[0xe8] = 0x00;
3971141cc406Sopenharmony_ci	      /* step size range2 */
3972141cc406Sopenharmony_ci	      dev->shadow_regs[0xe9] = 0x05;
3973141cc406Sopenharmony_ci	      /* bounds of movement range3 */
3974141cc406Sopenharmony_ci	      dev->shadow_regs[0xea] = 0x00;
3975141cc406Sopenharmony_ci	      dev->shadow_regs[0xeb] = 0x00;
3976141cc406Sopenharmony_ci	      /* step size range3 */
3977141cc406Sopenharmony_ci	      dev->shadow_regs[0xec] = 0x01;
3978141cc406Sopenharmony_ci	      /* step size range4 */
3979141cc406Sopenharmony_ci	      dev->shadow_regs[0xef] = 0x01;
3980141cc406Sopenharmony_ci	      break;
3981141cc406Sopenharmony_ci	    }
3982141cc406Sopenharmony_ci
3983141cc406Sopenharmony_ci	  dev->shadow_regs[0x35] = 0x01;
3984141cc406Sopenharmony_ci	  dev->shadow_regs[0x37] = 0x01;
3985141cc406Sopenharmony_ci
3986141cc406Sopenharmony_ci	  /* set colour scan */
3987141cc406Sopenharmony_ci	  dev->shadow_regs[0x2f] = 0x11;
3988141cc406Sopenharmony_ci
3989141cc406Sopenharmony_ci	  /* Motor enable & Coordinate space denominator */
3990141cc406Sopenharmony_ci	  dev->shadow_regs[0xc3] = 0x83;
3991141cc406Sopenharmony_ci
3992141cc406Sopenharmony_ci	}
3993141cc406Sopenharmony_ci      else			/* greyscale */
3994141cc406Sopenharmony_ci	{
3995141cc406Sopenharmony_ci
3996141cc406Sopenharmony_ci	  switch (dev->model.sensor_type)
3997141cc406Sopenharmony_ci	    {
3998141cc406Sopenharmony_ci	    case X74_SENSOR:
3999141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x04;
4000141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x04;
4001141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x08;
4002141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x08;
4003141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x0c;
4004141cc406Sopenharmony_ci
4005141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x00;
4006141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
4007141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x00;
4008141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
4009141cc406Sopenharmony_ci
4010141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x00;
4011141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
4012141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;
4013141cc406Sopenharmony_ci	      break;
4014141cc406Sopenharmony_ci	    case X1100_B2_SENSOR:
4015141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x08;
4016141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x08;
4017141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x0f;
4018141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x0f;
4019141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x16;
4020141cc406Sopenharmony_ci
4021141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x00;
4022141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
4023141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x00;
4024141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
4025141cc406Sopenharmony_ci
4026141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x00;
4027141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
4028141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;
4029141cc406Sopenharmony_ci	      break;
4030141cc406Sopenharmony_ci	    case X1100_2C_SENSOR:
4031141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x04;
4032141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x04;
4033141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x07;
4034141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x07;
4035141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x0a;
4036141cc406Sopenharmony_ci
4037141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x20;
4038141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
4039141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x00;
4040141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
4041141cc406Sopenharmony_ci
4042141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x00;
4043141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
4044141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;
4045141cc406Sopenharmony_ci	      break;
4046141cc406Sopenharmony_ci	    case A920_SENSOR:
4047141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x03;
4048141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x03;
4049141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x06;
4050141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x06;
4051141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x09;
4052141cc406Sopenharmony_ci
4053141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x05;
4054141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x14;
4055141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x06;
4056141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x04;
4057141cc406Sopenharmony_ci
4058141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0xe0;
4059141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x85;
4060141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x0e;
4061141cc406Sopenharmony_ci	      break;
4062141cc406Sopenharmony_ci	    case X1200_SENSOR:
4063141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x02;
4064141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x02;
4065141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x04;
4066141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x04;
4067141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x06;
4068141cc406Sopenharmony_ci	      break;
4069141cc406Sopenharmony_ci	    case X1200_USB2_SENSOR:
4070141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x02;
4071141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x02;
4072141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x04;
4073141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x04;
4074141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x06;
4075141cc406Sopenharmony_ci	      break;
4076141cc406Sopenharmony_ci	    }
4077141cc406Sopenharmony_ci	  switch (dev->model.motor_type)
4078141cc406Sopenharmony_ci	    {
4079141cc406Sopenharmony_ci	    case X74_MOTOR:
4080141cc406Sopenharmony_ci	      /*  ? */
4081141cc406Sopenharmony_ci	      dev->shadow_regs[0xc4] = 0x20;
4082141cc406Sopenharmony_ci	      dev->shadow_regs[0xc5] = 0x1c;
4083141cc406Sopenharmony_ci	      /* Movement direction & step size */
4084141cc406Sopenharmony_ci	      dev->shadow_regs[0xc6] = 0x0b;
4085141cc406Sopenharmony_ci
4086141cc406Sopenharmony_ci	      dev->shadow_regs[0xc8] = 0x04;
4087141cc406Sopenharmony_ci	      dev->shadow_regs[0xc9] = 0x39;
4088141cc406Sopenharmony_ci	      dev->shadow_regs[0xca] = 0x05;
4089141cc406Sopenharmony_ci
4090141cc406Sopenharmony_ci	      /* bounds of movement range0 */
4091141cc406Sopenharmony_ci	      dev->shadow_regs[0xe0] = 0x29;
4092141cc406Sopenharmony_ci	      dev->shadow_regs[0xe1] = 0x17;
4093141cc406Sopenharmony_ci	      /* step size range0 */
4094141cc406Sopenharmony_ci	      dev->shadow_regs[0xe2] = 0x8f;
4095141cc406Sopenharmony_ci	      /* ? */
4096141cc406Sopenharmony_ci	      dev->shadow_regs[0xe3] = 0x06;
4097141cc406Sopenharmony_ci	      /* bounds of movement range1 */
4098141cc406Sopenharmony_ci	      dev->shadow_regs[0xe4] = 0x61;
4099141cc406Sopenharmony_ci
4100141cc406Sopenharmony_ci	      dev->shadow_regs[0xe5] = 0x16;
4101141cc406Sopenharmony_ci	      /* step size range1 */
4102141cc406Sopenharmony_ci	      dev->shadow_regs[0xe6] = 0x64;
4103141cc406Sopenharmony_ci	      /* bounds of movement range2 */
4104141cc406Sopenharmony_ci	      dev->shadow_regs[0xe7] = 0xb5;
4105141cc406Sopenharmony_ci	      dev->shadow_regs[0xe8] = 0x08;
4106141cc406Sopenharmony_ci	      /* step size range2 */
4107141cc406Sopenharmony_ci	      dev->shadow_regs[0xe9] = 0x32;
4108141cc406Sopenharmony_ci	      /* bounds of movement range3 */
4109141cc406Sopenharmony_ci	      dev->shadow_regs[0xea] = 0x00;
4110141cc406Sopenharmony_ci	      dev->shadow_regs[0xeb] = 0x00;
4111141cc406Sopenharmony_ci	      /* step size range3 */
4112141cc406Sopenharmony_ci	      dev->shadow_regs[0xec] = 0x0c;
4113141cc406Sopenharmony_ci	      /* bounds of movement range4 -only for 75dpi grayscale */
4114141cc406Sopenharmony_ci	      dev->shadow_regs[0xed] = 0x00;
4115141cc406Sopenharmony_ci	      dev->shadow_regs[0xee] = 0x00;
4116141cc406Sopenharmony_ci	      /* step size range4 */
4117141cc406Sopenharmony_ci	      dev->shadow_regs[0xef] = 0x08;
4118141cc406Sopenharmony_ci	      break;
4119141cc406Sopenharmony_ci	    case A920_MOTOR:
4120141cc406Sopenharmony_ci	    case X1100_MOTOR:
4121141cc406Sopenharmony_ci	      /*  ? */
4122141cc406Sopenharmony_ci	      dev->shadow_regs[0xc5] = 0x19;
4123141cc406Sopenharmony_ci	      /* Movement direction & step size */
4124141cc406Sopenharmony_ci	      dev->shadow_regs[0xc6] = 0x09;
4125141cc406Sopenharmony_ci	      /*  ? */
4126141cc406Sopenharmony_ci	      dev->shadow_regs[0xc9] = 0x3a;
4127141cc406Sopenharmony_ci	      dev->shadow_regs[0xca] = 0x08;
4128141cc406Sopenharmony_ci	      /* bounds of movement range0 */
4129141cc406Sopenharmony_ci	      dev->shadow_regs[0xe0] = 0xe3;
4130141cc406Sopenharmony_ci	      dev->shadow_regs[0xe1] = 0x18;
4131141cc406Sopenharmony_ci	      /* step size range0 */
4132141cc406Sopenharmony_ci	      dev->shadow_regs[0xe2] = 0x03;
4133141cc406Sopenharmony_ci	      /* ? */
4134141cc406Sopenharmony_ci	      dev->shadow_regs[0xe3] = 0x06;
4135141cc406Sopenharmony_ci	      /* bounds of movement range1 */
4136141cc406Sopenharmony_ci	      dev->shadow_regs[0xe4] = 0x2b;
4137141cc406Sopenharmony_ci	      dev->shadow_regs[0xe5] = 0x17;
4138141cc406Sopenharmony_ci	      /* step size range1 */
4139141cc406Sopenharmony_ci	      dev->shadow_regs[0xe6] = 0xdc;
4140141cc406Sopenharmony_ci	      /* bounds of movement range2 */
4141141cc406Sopenharmony_ci	      dev->shadow_regs[0xe7] = 0xb3;
4142141cc406Sopenharmony_ci	      dev->shadow_regs[0xe8] = 0x07;
4143141cc406Sopenharmony_ci	      /* step size range2 */
4144141cc406Sopenharmony_ci	      dev->shadow_regs[0xe9] = 0x1b;
4145141cc406Sopenharmony_ci	      /* bounds of movement range3 */
4146141cc406Sopenharmony_ci	      dev->shadow_regs[0xea] = 0x00;
4147141cc406Sopenharmony_ci	      dev->shadow_regs[0xeb] = 0x00;
4148141cc406Sopenharmony_ci	      /* step size range3 */
4149141cc406Sopenharmony_ci	      dev->shadow_regs[0xec] = 0x07;
4150141cc406Sopenharmony_ci	      /* step size range4 */
4151141cc406Sopenharmony_ci	      dev->shadow_regs[0xef] = 0x03;
4152141cc406Sopenharmony_ci	      break;
4153141cc406Sopenharmony_ci	    }			/* switch motortype */
4154141cc406Sopenharmony_ci	  /* set grayscale  scan */
4155141cc406Sopenharmony_ci	  dev->shadow_regs[0x2f] = 0x21;
4156141cc406Sopenharmony_ci	  /* set motor resolution divisor */
4157141cc406Sopenharmony_ci	  dev->shadow_regs[0x39] = 0x03;
4158141cc406Sopenharmony_ci
4159141cc406Sopenharmony_ci	  /* set ? only for colour? */
4160141cc406Sopenharmony_ci	  dev->shadow_regs[0x80] = 0x00;
4161141cc406Sopenharmony_ci	  dev->shadow_regs[0x81] = 0x00;
4162141cc406Sopenharmony_ci	  dev->shadow_regs[0x82] = 0x00;
4163141cc406Sopenharmony_ci	  /* Motor enable & Coordinate space denominator */
4164141cc406Sopenharmony_ci	  dev->shadow_regs[0xc3] = 0x81;
4165141cc406Sopenharmony_ci
4166141cc406Sopenharmony_ci
4167141cc406Sopenharmony_ci	}			/* else (gray) */
4168141cc406Sopenharmony_ci
4169141cc406Sopenharmony_ci      /* set # of head moves per CIS read */
4170141cc406Sopenharmony_ci      rts88xx_set_scan_frequency (dev->shadow_regs, 1);
4171141cc406Sopenharmony_ci      /* set horizontal resolution */
4172141cc406Sopenharmony_ci      dev->shadow_regs[0x79] = 0x20;
4173141cc406Sopenharmony_ci    }
4174141cc406Sopenharmony_ci
4175141cc406Sopenharmony_ci  /* 600dpi x 600dpi */
4176141cc406Sopenharmony_ci  if (resolution == 600)
4177141cc406Sopenharmony_ci    {
4178141cc406Sopenharmony_ci      DBG (5, "sanei_lexmark_low_set_scan_regs(): 600 DPI resolution\n");
4179141cc406Sopenharmony_ci
4180141cc406Sopenharmony_ci
4181141cc406Sopenharmony_ci
4182141cc406Sopenharmony_ci      if (isColourScan)
4183141cc406Sopenharmony_ci	{
4184141cc406Sopenharmony_ci	  /* 600 dpi color doesn't work for X74 yet */
4185141cc406Sopenharmony_ci	  if (dev->model.sensor_type == X74_SENSOR)
4186141cc406Sopenharmony_ci	    return SANE_STATUS_INVAL;
4187141cc406Sopenharmony_ci
4188141cc406Sopenharmony_ci	  switch (dev->model.sensor_type)
4189141cc406Sopenharmony_ci	    {
4190141cc406Sopenharmony_ci	    case X74_SENSOR:
4191141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x10;
4192141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x01;
4193141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x0c;
4194141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x01;
4195141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x09;
4196141cc406Sopenharmony_ci
4197141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x02;
4198141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x08;
4199141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x08;
4200141cc406Sopenharmony_ci
4201141cc406Sopenharmony_ci
4202141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x00;
4203141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
4204141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x00;
4205141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
4206141cc406Sopenharmony_ci
4207141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x00;
4208141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
4209141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;
4210141cc406Sopenharmony_ci	      break;
4211141cc406Sopenharmony_ci
4212141cc406Sopenharmony_ci	      /*dev->shadow_regs[0x34] = 0x08;
4213141cc406Sopenharmony_ci	         dev->shadow_regs[0x35] = 0x01;
4214141cc406Sopenharmony_ci	         dev->shadow_regs[0x36] = 0x06;
4215141cc406Sopenharmony_ci	         dev->shadow_regs[0x37] = 0x01;
4216141cc406Sopenharmony_ci	         dev->shadow_regs[0x38] = 0x05;
4217141cc406Sopenharmony_ci
4218141cc406Sopenharmony_ci
4219141cc406Sopenharmony_ci	         dev->shadow_regs[0x80] = 0x09;
4220141cc406Sopenharmony_ci	         dev->shadow_regs[0x81] = 0x0c;
4221141cc406Sopenharmony_ci	         dev->shadow_regs[0x82] = 0x04;
4222141cc406Sopenharmony_ci
4223141cc406Sopenharmony_ci
4224141cc406Sopenharmony_ci	         dev->shadow_regs[0x85] = 0x00;
4225141cc406Sopenharmony_ci	         dev->shadow_regs[0x86] = 0x00;
4226141cc406Sopenharmony_ci	         dev->shadow_regs[0x87] = 0x00;
4227141cc406Sopenharmony_ci	         dev->shadow_regs[0x88] = 0x00;
4228141cc406Sopenharmony_ci
4229141cc406Sopenharmony_ci	         dev->shadow_regs[0x91] = 0x00;
4230141cc406Sopenharmony_ci	         dev->shadow_regs[0x92] = 0x00;
4231141cc406Sopenharmony_ci	         dev->shadow_regs[0x93] = 0x06;
4232141cc406Sopenharmony_ci	         break; */
4233141cc406Sopenharmony_ci
4234141cc406Sopenharmony_ci
4235141cc406Sopenharmony_ci
4236141cc406Sopenharmony_ci	    case X1100_B2_SENSOR:
4237141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x15;
4238141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x15;
4239141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x14;
4240141cc406Sopenharmony_ci
4241141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x02;
4242141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x02;
4243141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x08;
4244141cc406Sopenharmony_ci
4245141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x83;
4246141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x7e;
4247141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0xad;
4248141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x35;
4249141cc406Sopenharmony_ci
4250141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0xfe;
4251141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0xdf;
4252141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x0e;
4253141cc406Sopenharmony_ci	      break;
4254141cc406Sopenharmony_ci	    case X1100_2C_SENSOR:
4255141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x08;
4256141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x0d;
4257141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x09;
4258141cc406Sopenharmony_ci
4259141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x0e;
4260141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x02;
4261141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x0a;
4262141cc406Sopenharmony_ci
4263141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x20;
4264141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
4265141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x00;
4266141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
4267141cc406Sopenharmony_ci
4268141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x00;
4269141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
4270141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;
4271141cc406Sopenharmony_ci	      break;
4272141cc406Sopenharmony_ci	    case A920_SENSOR:
4273141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x06;
4274141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x0f;
4275141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x09;
4276141cc406Sopenharmony_ci
4277141cc406Sopenharmony_ci	      dev->shadow_regs[0x79] = 0x40;
4278141cc406Sopenharmony_ci
4279141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x0e;
4280141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x0e;
4281141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x00;
4282141cc406Sopenharmony_ci
4283141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x05;
4284141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x14;
4285141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x06;
4286141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x04;
4287141cc406Sopenharmony_ci
4288141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x60;
4289141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x85;
4290141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x0e;
4291141cc406Sopenharmony_ci	      break;
4292141cc406Sopenharmony_ci	    case X1200_SENSOR:
4293141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x07;
4294141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x0a;
4295141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x04;
4296141cc406Sopenharmony_ci
4297141cc406Sopenharmony_ci	      /* data compression
4298141cc406Sopenharmony_ci	         dev->shadow_regs[0x40] = 0x90;
4299141cc406Sopenharmony_ci	         dev->shadow_regs[0x50] = 0x20; */
4300141cc406Sopenharmony_ci
4301141cc406Sopenharmony_ci	      /* no data compression */
4302141cc406Sopenharmony_ci	      dev->shadow_regs[0x40] = 0x80;
4303141cc406Sopenharmony_ci	      dev->shadow_regs[0x50] = 0x00;
4304141cc406Sopenharmony_ci
4305141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x02;
4306141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x00;
4307141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x06;
4308141cc406Sopenharmony_ci	      break;
4309141cc406Sopenharmony_ci	    case X1200_USB2_SENSOR:
4310141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x0d;
4311141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x13;
4312141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x10;
4313141cc406Sopenharmony_ci
4314141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x04;
4315141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x0e;
4316141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x08;
4317141cc406Sopenharmony_ci
4318141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x02;
4319141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x3b;
4320141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x0f;
4321141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x24;
4322141cc406Sopenharmony_ci
4323141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x19;
4324141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x30;
4325141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x0e;
4326141cc406Sopenharmony_ci	      dev->shadow_regs[0xc5] = 0x17;
4327141cc406Sopenharmony_ci	      dev->shadow_regs[0xc6] = 0x09;
4328141cc406Sopenharmony_ci	      dev->shadow_regs[0xca] = 0x0a;
4329141cc406Sopenharmony_ci	      break;
4330141cc406Sopenharmony_ci	    }
4331141cc406Sopenharmony_ci	  switch (dev->model.motor_type)
4332141cc406Sopenharmony_ci	    {
4333141cc406Sopenharmony_ci	    case X74_MOTOR:
4334141cc406Sopenharmony_ci	      /* Motor enable & Coordinate space denominator */
4335141cc406Sopenharmony_ci	      dev->shadow_regs[0xc3] = 0x81;
4336141cc406Sopenharmony_ci	      /*  ? */
4337141cc406Sopenharmony_ci	      dev->shadow_regs[0xc4] = 0x20;
4338141cc406Sopenharmony_ci	      dev->shadow_regs[0xc5] = 0x21;
4339141cc406Sopenharmony_ci	      /* Movement direction & step size */
4340141cc406Sopenharmony_ci	      dev->shadow_regs[0xc6] = 0x09;
4341141cc406Sopenharmony_ci	      dev->shadow_regs[0xc8] = 0x04;
4342141cc406Sopenharmony_ci	      dev->shadow_regs[0xc9] = 0x39;
4343141cc406Sopenharmony_ci	      dev->shadow_regs[0xca] = 0x20;
4344141cc406Sopenharmony_ci	      /* bounds of movement range0 */
4345141cc406Sopenharmony_ci	      dev->shadow_regs[0xe0] = 0x00;
4346141cc406Sopenharmony_ci	      dev->shadow_regs[0xe1] = 0x00;
4347141cc406Sopenharmony_ci	      /* step size range0 */
4348141cc406Sopenharmony_ci	      dev->shadow_regs[0xe2] = 0xbf;
4349141cc406Sopenharmony_ci	      /* ? */
4350141cc406Sopenharmony_ci	      dev->shadow_regs[0xe3] = 0x05;
4351141cc406Sopenharmony_ci	      /* bounds of movement range1 */
4352141cc406Sopenharmony_ci	      dev->shadow_regs[0xe4] = 0x00;
4353141cc406Sopenharmony_ci	      dev->shadow_regs[0xe5] = 0x00;
4354141cc406Sopenharmony_ci	      /* step size range1 */
4355141cc406Sopenharmony_ci	      dev->shadow_regs[0xe6] = 0x0d;
4356141cc406Sopenharmony_ci	      /* bounds of movement range2 */
4357141cc406Sopenharmony_ci	      dev->shadow_regs[0xe7] = 0x00;
4358141cc406Sopenharmony_ci	      dev->shadow_regs[0xe8] = 0x00;
4359141cc406Sopenharmony_ci	      /* step size range2 */
4360141cc406Sopenharmony_ci	      dev->shadow_regs[0xe9] = 0x05;
4361141cc406Sopenharmony_ci	      /* bounds of movement range3 */
4362141cc406Sopenharmony_ci	      dev->shadow_regs[0xea] = 0x00;
4363141cc406Sopenharmony_ci	      dev->shadow_regs[0xeb] = 0x00;
4364141cc406Sopenharmony_ci	      /* step size range3 */
4365141cc406Sopenharmony_ci	      dev->shadow_regs[0xec] = 0x01;
4366141cc406Sopenharmony_ci	      /* bounds of movement range4 -only for 75dpi grayscale */
4367141cc406Sopenharmony_ci	      dev->shadow_regs[0xed] = 0x00;
4368141cc406Sopenharmony_ci	      dev->shadow_regs[0xee] = 0x00;
4369141cc406Sopenharmony_ci	      /* step size range4 */
4370141cc406Sopenharmony_ci	      dev->shadow_regs[0xef] = 0x01;
4371141cc406Sopenharmony_ci	      break;
4372141cc406Sopenharmony_ci	    case A920_MOTOR:
4373141cc406Sopenharmony_ci	    case X1100_MOTOR:
4374141cc406Sopenharmony_ci	      /* Motor enable & Coordinate space denominator */
4375141cc406Sopenharmony_ci	      dev->shadow_regs[0xc3] = 0x86;
4376141cc406Sopenharmony_ci	      /*  ? */
4377141cc406Sopenharmony_ci	      dev->shadow_regs[0xc5] = 0x27;
4378141cc406Sopenharmony_ci	      /* Movement direction & step size */
4379141cc406Sopenharmony_ci	      dev->shadow_regs[0xc6] = 0x0c;
4380141cc406Sopenharmony_ci	      /*  ? */
4381141cc406Sopenharmony_ci	      dev->shadow_regs[0xc9] = 0x3a;
4382141cc406Sopenharmony_ci	      dev->shadow_regs[0xca] = 0x1a;
4383141cc406Sopenharmony_ci	      /* bounds of movement range0 */
4384141cc406Sopenharmony_ci	      dev->shadow_regs[0xe0] = 0x57;
4385141cc406Sopenharmony_ci	      dev->shadow_regs[0xe1] = 0x0a;
4386141cc406Sopenharmony_ci	      /* step size range0 */
4387141cc406Sopenharmony_ci	      dev->shadow_regs[0xe2] = 0xbf;
4388141cc406Sopenharmony_ci	      /* ? */
4389141cc406Sopenharmony_ci	      dev->shadow_regs[0xe3] = 0x05;
4390141cc406Sopenharmony_ci	      /* bounds of movement range1 */
4391141cc406Sopenharmony_ci	      dev->shadow_regs[0xe4] = 0x3b;
4392141cc406Sopenharmony_ci	      dev->shadow_regs[0xe5] = 0x0a;
4393141cc406Sopenharmony_ci	      /* step size range1 */
4394141cc406Sopenharmony_ci	      dev->shadow_regs[0xe6] = 0x0e;
4395141cc406Sopenharmony_ci	      /* bounds of movement range2 */
4396141cc406Sopenharmony_ci	      dev->shadow_regs[0xe7] = 0x00;
4397141cc406Sopenharmony_ci	      dev->shadow_regs[0xe8] = 0x00;
4398141cc406Sopenharmony_ci	      /* step size range2 */
4399141cc406Sopenharmony_ci	      dev->shadow_regs[0xe9] = 0x05;
4400141cc406Sopenharmony_ci	      /* bounds of movement range3 */
4401141cc406Sopenharmony_ci	      dev->shadow_regs[0xea] = 0x00;
4402141cc406Sopenharmony_ci	      dev->shadow_regs[0xeb] = 0x00;
4403141cc406Sopenharmony_ci	      /* step size range3 */
4404141cc406Sopenharmony_ci	      dev->shadow_regs[0xec] = 0x01;
4405141cc406Sopenharmony_ci	      /* step size range4 */
4406141cc406Sopenharmony_ci	      dev->shadow_regs[0xef] = 0x01;
4407141cc406Sopenharmony_ci	      break;
4408141cc406Sopenharmony_ci	    }
4409141cc406Sopenharmony_ci	  /* set colour scan */
4410141cc406Sopenharmony_ci	  dev->shadow_regs[0x2f] = 0x11;
4411141cc406Sopenharmony_ci
4412141cc406Sopenharmony_ci	  dev->shadow_regs[0x35] = 0x01;
4413141cc406Sopenharmony_ci	  dev->shadow_regs[0x37] = 0x01;
4414141cc406Sopenharmony_ci
4415141cc406Sopenharmony_ci	  /* set motor resolution divisor */
4416141cc406Sopenharmony_ci	  dev->shadow_regs[0x39] = 0x03;
4417141cc406Sopenharmony_ci	  /* set # of head moves per CIS read */
4418141cc406Sopenharmony_ci	  rts88xx_set_scan_frequency (dev->shadow_regs, 2);
4419141cc406Sopenharmony_ci
4420141cc406Sopenharmony_ci
4421141cc406Sopenharmony_ci	}
4422141cc406Sopenharmony_ci      else
4423141cc406Sopenharmony_ci	{
4424141cc406Sopenharmony_ci	  switch (dev->model.sensor_type)
4425141cc406Sopenharmony_ci	    {
4426141cc406Sopenharmony_ci	    case X74_SENSOR:
4427141cc406Sopenharmony_ci	      dev->shadow_regs[0x2c] = 0x04;
4428141cc406Sopenharmony_ci	      dev->shadow_regs[0x2d] = 0x46;
4429141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x05;
4430141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x05;
4431141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x0b;
4432141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x0b;
4433141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x11;
4434141cc406Sopenharmony_ci	      dev->shadow_regs[0x40] = 0x40;
4435141cc406Sopenharmony_ci
4436141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x00;
4437141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
4438141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x00;
4439141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
4440141cc406Sopenharmony_ci
4441141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x00;
4442141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
4443141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;
4444141cc406Sopenharmony_ci	      break;
4445141cc406Sopenharmony_ci	    case X1100_B2_SENSOR:
4446141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x11;
4447141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x11;
4448141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x21;
4449141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x21;
4450141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x31;
4451141cc406Sopenharmony_ci
4452141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x00;
4453141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
4454141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x00;
4455141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
4456141cc406Sopenharmony_ci
4457141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x00;
4458141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
4459141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;
4460141cc406Sopenharmony_ci	      break;
4461141cc406Sopenharmony_ci	    case X1100_2C_SENSOR:
4462141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x07;
4463141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x07;
4464141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x0d;
4465141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x0d;
4466141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x13;
4467141cc406Sopenharmony_ci
4468141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x20;
4469141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
4470141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x00;
4471141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x00;
4472141cc406Sopenharmony_ci
4473141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x00;
4474141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
4475141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x06;
4476141cc406Sopenharmony_ci	      break;
4477141cc406Sopenharmony_ci	    case A920_SENSOR:
4478141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x05;
4479141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x05;
4480141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x0b;
4481141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x0b;
4482141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x11;
4483141cc406Sopenharmony_ci
4484141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x05;
4485141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x14;
4486141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x06;
4487141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x04;
4488141cc406Sopenharmony_ci
4489141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0xe0;
4490141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x85;
4491141cc406Sopenharmony_ci	      dev->shadow_regs[0x93] = 0x0e;
4492141cc406Sopenharmony_ci	      break;
4493141cc406Sopenharmony_ci	    case X1200_SENSOR:
4494141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x03;
4495141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x03;
4496141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x07;
4497141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x07;
4498141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x0b;
4499141cc406Sopenharmony_ci
4500141cc406Sopenharmony_ci	      /* data compression
4501141cc406Sopenharmony_ci	         dev->shadow_regs[0x40] = 0x90;
4502141cc406Sopenharmony_ci	         dev->shadow_regs[0x50] = 0x20; */
4503141cc406Sopenharmony_ci	      /* no data compression */
4504141cc406Sopenharmony_ci	      dev->shadow_regs[0x40] = 0x80;
4505141cc406Sopenharmony_ci	      dev->shadow_regs[0x50] = 0x00;
4506141cc406Sopenharmony_ci
4507141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x00;
4508141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
4509141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0xff;
4510141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x02;
4511141cc406Sopenharmony_ci
4512141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
4513141cc406Sopenharmony_ci
4514141cc406Sopenharmony_ci	      break;
4515141cc406Sopenharmony_ci	    case X1200_USB2_SENSOR:
4516141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x03;
4517141cc406Sopenharmony_ci	      dev->shadow_regs[0x35] = 0x03;
4518141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x07;
4519141cc406Sopenharmony_ci	      dev->shadow_regs[0x37] = 0x07;
4520141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x0b;
4521141cc406Sopenharmony_ci
4522141cc406Sopenharmony_ci	      dev->shadow_regs[0x40] = 0x80;
4523141cc406Sopenharmony_ci	      dev->shadow_regs[0x50] = 0x00;
4524141cc406Sopenharmony_ci
4525141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x00;
4526141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x00;
4527141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0xff;
4528141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x02;
4529141cc406Sopenharmony_ci
4530141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x00;
4531141cc406Sopenharmony_ci	      break;
4532141cc406Sopenharmony_ci	    }
4533141cc406Sopenharmony_ci	  switch (dev->model.motor_type)
4534141cc406Sopenharmony_ci	    {
4535141cc406Sopenharmony_ci	    case X74_MOTOR:
4536141cc406Sopenharmony_ci	      /* set # of head moves per CIS read */
4537141cc406Sopenharmony_ci	      rts88xx_set_scan_frequency (dev->shadow_regs, 1);
4538141cc406Sopenharmony_ci	      /*  ? */
4539141cc406Sopenharmony_ci	      dev->shadow_regs[0xc4] = 0x20;
4540141cc406Sopenharmony_ci	      dev->shadow_regs[0xc5] = 0x22;
4541141cc406Sopenharmony_ci	      /* Movement direction & step size */
4542141cc406Sopenharmony_ci	      dev->shadow_regs[0xc6] = 0x0b;
4543141cc406Sopenharmony_ci
4544141cc406Sopenharmony_ci	      dev->shadow_regs[0xc8] = 0x04;
4545141cc406Sopenharmony_ci	      dev->shadow_regs[0xc9] = 0x39;
4546141cc406Sopenharmony_ci	      dev->shadow_regs[0xca] = 0x1f;
4547141cc406Sopenharmony_ci
4548141cc406Sopenharmony_ci	      /* bounds of movement range0 */
4549141cc406Sopenharmony_ci	      dev->shadow_regs[0xe0] = 0x2f;
4550141cc406Sopenharmony_ci	      dev->shadow_regs[0xe1] = 0x11;
4551141cc406Sopenharmony_ci	      /* step size range0 */
4552141cc406Sopenharmony_ci	      dev->shadow_regs[0xe2] = 0x9f;
4553141cc406Sopenharmony_ci	      /* ? */
4554141cc406Sopenharmony_ci	      dev->shadow_regs[0xe3] = 0x0f;
4555141cc406Sopenharmony_ci	      /* bounds of movement range1 */
4556141cc406Sopenharmony_ci	      dev->shadow_regs[0xe4] = 0xcb;
4557141cc406Sopenharmony_ci
4558141cc406Sopenharmony_ci	      dev->shadow_regs[0xe5] = 0x10;
4559141cc406Sopenharmony_ci	      /* step size range1 */
4560141cc406Sopenharmony_ci	      dev->shadow_regs[0xe6] = 0x64;
4561141cc406Sopenharmony_ci	      /* bounds of movement range2 */
4562141cc406Sopenharmony_ci	      dev->shadow_regs[0xe7] = 0x00;
4563141cc406Sopenharmony_ci	      dev->shadow_regs[0xe8] = 0x00;
4564141cc406Sopenharmony_ci	      /* step size range2 */
4565141cc406Sopenharmony_ci	      dev->shadow_regs[0xe9] = 0x32;
4566141cc406Sopenharmony_ci	      /* bounds of movement range3 */
4567141cc406Sopenharmony_ci	      dev->shadow_regs[0xea] = 0x00;
4568141cc406Sopenharmony_ci	      dev->shadow_regs[0xeb] = 0x00;
4569141cc406Sopenharmony_ci	      /* step size range3 */
4570141cc406Sopenharmony_ci	      dev->shadow_regs[0xec] = 0x0c;
4571141cc406Sopenharmony_ci	      /* bounds of movement range4 -only for 75dpi grayscale */
4572141cc406Sopenharmony_ci	      dev->shadow_regs[0xed] = 0x00;
4573141cc406Sopenharmony_ci	      dev->shadow_regs[0xee] = 0x00;
4574141cc406Sopenharmony_ci	      /* step size range4 */
4575141cc406Sopenharmony_ci	      dev->shadow_regs[0xef] = 0x08;
4576141cc406Sopenharmony_ci	      break;
4577141cc406Sopenharmony_ci	    case X1100_MOTOR:
4578141cc406Sopenharmony_ci	    case A920_MOTOR:
4579141cc406Sopenharmony_ci	      /* set ? only for colour? */
4580141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x00;
4581141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x00;
4582141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x00;
4583141cc406Sopenharmony_ci	      /*  ? */
4584141cc406Sopenharmony_ci	      dev->shadow_regs[0xc5] = 0x22;
4585141cc406Sopenharmony_ci	      /* Movement direction & step size */
4586141cc406Sopenharmony_ci	      dev->shadow_regs[0xc6] = 0x09;
4587141cc406Sopenharmony_ci	      /*  ? */
4588141cc406Sopenharmony_ci	      dev->shadow_regs[0xc9] = 0x3b;
4589141cc406Sopenharmony_ci	      dev->shadow_regs[0xca] = 0x1f;
4590141cc406Sopenharmony_ci	      /* bounds of movement range0 */
4591141cc406Sopenharmony_ci	      dev->shadow_regs[0xe0] = 0xf7;
4592141cc406Sopenharmony_ci	      dev->shadow_regs[0xe1] = 0x16;
4593141cc406Sopenharmony_ci	      /* step size range0 */
4594141cc406Sopenharmony_ci	      dev->shadow_regs[0xe2] = 0x87;
4595141cc406Sopenharmony_ci	      /* ? */
4596141cc406Sopenharmony_ci	      dev->shadow_regs[0xe3] = 0x13;
4597141cc406Sopenharmony_ci	      /* bounds of movement range1 */
4598141cc406Sopenharmony_ci	      dev->shadow_regs[0xe4] = 0x1b;
4599141cc406Sopenharmony_ci	      dev->shadow_regs[0xe5] = 0x16;
4600141cc406Sopenharmony_ci	      /* step size range1 */
4601141cc406Sopenharmony_ci	      dev->shadow_regs[0xe6] = 0xdc;
4602141cc406Sopenharmony_ci	      /* bounds of movement range2 */
4603141cc406Sopenharmony_ci	      dev->shadow_regs[0xe7] = 0x00;
4604141cc406Sopenharmony_ci	      dev->shadow_regs[0xe8] = 0x00;
4605141cc406Sopenharmony_ci	      /* step size range2 */
4606141cc406Sopenharmony_ci	      dev->shadow_regs[0xe9] = 0x1b;
4607141cc406Sopenharmony_ci	      /* bounds of movement range3 */
4608141cc406Sopenharmony_ci	      dev->shadow_regs[0xea] = 0x00;
4609141cc406Sopenharmony_ci	      dev->shadow_regs[0xeb] = 0x00;
4610141cc406Sopenharmony_ci	      /* step size range3 */
4611141cc406Sopenharmony_ci	      dev->shadow_regs[0xec] = 0x07;
4612141cc406Sopenharmony_ci	      /* step size range4 */
4613141cc406Sopenharmony_ci	      dev->shadow_regs[0xef] = 0x03;
4614141cc406Sopenharmony_ci	      break;
4615141cc406Sopenharmony_ci	    }
4616141cc406Sopenharmony_ci
4617141cc406Sopenharmony_ci	  /* set grayscale  scan */
4618141cc406Sopenharmony_ci	  dev->shadow_regs[0x2f] = 0x21;
4619141cc406Sopenharmony_ci
4620141cc406Sopenharmony_ci	  /* set motor resolution divisor */
4621141cc406Sopenharmony_ci	  dev->shadow_regs[0x39] = 0x01;
4622141cc406Sopenharmony_ci
4623141cc406Sopenharmony_ci	  /* set # of head moves per CIS read */
4624141cc406Sopenharmony_ci	  rts88xx_set_scan_frequency (dev->shadow_regs, 1);
4625141cc406Sopenharmony_ci
4626141cc406Sopenharmony_ci	  /* Motor enable & Coordinate space denominator */
4627141cc406Sopenharmony_ci	  dev->shadow_regs[0xc3] = 0x81;
4628141cc406Sopenharmony_ci	}			/* else (grayscale) */
4629141cc406Sopenharmony_ci
4630141cc406Sopenharmony_ci      /* set horizontal resolution */
4631141cc406Sopenharmony_ci      dev->shadow_regs[0x79] = 0x40;
4632141cc406Sopenharmony_ci
4633141cc406Sopenharmony_ci    }
4634141cc406Sopenharmony_ci  /*600dpi x 1200dpi */
4635141cc406Sopenharmony_ci  if (resolution == 1200)
4636141cc406Sopenharmony_ci    {
4637141cc406Sopenharmony_ci      DBG (5, "sanei_lexmark_low_set_scan_regs(): 1200 DPI resolution\n");
4638141cc406Sopenharmony_ci
4639141cc406Sopenharmony_ci      /* 1200 dpi doesn't work for X74 yet */
4640141cc406Sopenharmony_ci      if (dev->model.sensor_type == X74_SENSOR)
4641141cc406Sopenharmony_ci	return SANE_STATUS_INVAL;
4642141cc406Sopenharmony_ci
4643141cc406Sopenharmony_ci      if (isColourScan)
4644141cc406Sopenharmony_ci	{
4645141cc406Sopenharmony_ci	  /* set colour scan */
4646141cc406Sopenharmony_ci	  dev->shadow_regs[0x2f] = 0x11;
4647141cc406Sopenharmony_ci	  /* set motor resolution divisor */
4648141cc406Sopenharmony_ci	  dev->shadow_regs[0x39] = 0x01;
4649141cc406Sopenharmony_ci	  /* set # of head moves per CIS read */
4650141cc406Sopenharmony_ci	  rts88xx_set_scan_frequency (dev->shadow_regs, 2);
4651141cc406Sopenharmony_ci
4652141cc406Sopenharmony_ci	  if (dev->model.sensor_type == X1100_B2_SENSOR)
4653141cc406Sopenharmony_ci	    {
4654141cc406Sopenharmony_ci	      /* set ? */
4655141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x29;
4656141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x29;
4657141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x28;
4658141cc406Sopenharmony_ci	      /* set ? */
4659141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x04;
4660141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x04;
4661141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x08;
4662141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x83;
4663141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x7e;
4664141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0xad;
4665141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x35;
4666141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0xfe;
4667141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0xdf;
4668141cc406Sopenharmony_ci	    }
4669141cc406Sopenharmony_ci	  else
4670141cc406Sopenharmony_ci	    {			/* A920 case */
4671141cc406Sopenharmony_ci	      dev->shadow_regs[0x34] = 0x0c;
4672141cc406Sopenharmony_ci	      dev->shadow_regs[0x36] = 0x1e;
4673141cc406Sopenharmony_ci	      dev->shadow_regs[0x38] = 0x10;
4674141cc406Sopenharmony_ci
4675141cc406Sopenharmony_ci	      dev->shadow_regs[0x80] = 0x0c;
4676141cc406Sopenharmony_ci	      dev->shadow_regs[0x81] = 0x08;
4677141cc406Sopenharmony_ci	      dev->shadow_regs[0x82] = 0x0c;
4678141cc406Sopenharmony_ci
4679141cc406Sopenharmony_ci	      dev->shadow_regs[0x85] = 0x05;
4680141cc406Sopenharmony_ci	      dev->shadow_regs[0x86] = 0x14;
4681141cc406Sopenharmony_ci	      dev->shadow_regs[0x87] = 0x06;
4682141cc406Sopenharmony_ci	      dev->shadow_regs[0x88] = 0x04;
4683141cc406Sopenharmony_ci
4684141cc406Sopenharmony_ci	      dev->shadow_regs[0x91] = 0x60;
4685141cc406Sopenharmony_ci	      dev->shadow_regs[0x92] = 0x85;
4686141cc406Sopenharmony_ci	    }
4687141cc406Sopenharmony_ci
4688141cc406Sopenharmony_ci	  dev->shadow_regs[0x35] = 0x01;
4689141cc406Sopenharmony_ci	  dev->shadow_regs[0x37] = 0x01;
4690141cc406Sopenharmony_ci	  /* set motor resolution divisor */
4691141cc406Sopenharmony_ci	  dev->shadow_regs[0x39] = 0x01;
4692141cc406Sopenharmony_ci	  dev->shadow_regs[0x93] = 0x0e;
4693141cc406Sopenharmony_ci
4694141cc406Sopenharmony_ci	  /* Motor enable & Coordinate space denominator */
4695141cc406Sopenharmony_ci	  dev->shadow_regs[0xc3] = 0x86;
4696141cc406Sopenharmony_ci	  /*  ? */
4697141cc406Sopenharmony_ci	  dev->shadow_regs[0xc5] = 0x41;
4698141cc406Sopenharmony_ci	  /* Movement direction & step size */
4699141cc406Sopenharmony_ci	  dev->shadow_regs[0xc6] = 0x0c;
4700141cc406Sopenharmony_ci	  /*  ? */
4701141cc406Sopenharmony_ci	  dev->shadow_regs[0xc9] = 0x3a;
4702141cc406Sopenharmony_ci	  dev->shadow_regs[0xca] = 0x40;
4703141cc406Sopenharmony_ci	  /* bounds of movement range0 */
4704141cc406Sopenharmony_ci	  dev->shadow_regs[0xe0] = 0x00;
4705141cc406Sopenharmony_ci	  dev->shadow_regs[0xe1] = 0x00;
4706141cc406Sopenharmony_ci	  /* step size range0 */
4707141cc406Sopenharmony_ci	  dev->shadow_regs[0xe2] = 0x85;
4708141cc406Sopenharmony_ci	  /* ? */
4709141cc406Sopenharmony_ci	  dev->shadow_regs[0xe3] = 0x0b;
4710141cc406Sopenharmony_ci	  /* bounds of movement range1 */
4711141cc406Sopenharmony_ci	  dev->shadow_regs[0xe4] = 0x00;
4712141cc406Sopenharmony_ci	  dev->shadow_regs[0xe5] = 0x00;
4713141cc406Sopenharmony_ci	  /* step size range1 */
4714141cc406Sopenharmony_ci	  dev->shadow_regs[0xe6] = 0x0e;
4715141cc406Sopenharmony_ci	  /* bounds of movement range2 */
4716141cc406Sopenharmony_ci	  dev->shadow_regs[0xe7] = 0x00;
4717141cc406Sopenharmony_ci	  dev->shadow_regs[0xe8] = 0x00;
4718141cc406Sopenharmony_ci	  /* step size range2 */
4719141cc406Sopenharmony_ci	  dev->shadow_regs[0xe9] = 0x05;
4720141cc406Sopenharmony_ci	  /* bounds of movement range3 */
4721141cc406Sopenharmony_ci	  dev->shadow_regs[0xea] = 0x00;
4722141cc406Sopenharmony_ci	  dev->shadow_regs[0xeb] = 0x00;
4723141cc406Sopenharmony_ci	  /* step size range3 */
4724141cc406Sopenharmony_ci	  dev->shadow_regs[0xec] = 0x01;
4725141cc406Sopenharmony_ci	  /* step size range4 */
4726141cc406Sopenharmony_ci	  dev->shadow_regs[0xef] = 0x01;
4727141cc406Sopenharmony_ci	}
4728141cc406Sopenharmony_ci      else
4729141cc406Sopenharmony_ci	{
4730141cc406Sopenharmony_ci	  /* set grayscale  scan */
4731141cc406Sopenharmony_ci	  dev->shadow_regs[0x2f] = 0x21;
4732141cc406Sopenharmony_ci	  /* set ? */
4733141cc406Sopenharmony_ci	  dev->shadow_regs[0x34] = 0x22;
4734141cc406Sopenharmony_ci	  dev->shadow_regs[0x35] = 0x22;
4735141cc406Sopenharmony_ci	  dev->shadow_regs[0x36] = 0x42;
4736141cc406Sopenharmony_ci	  dev->shadow_regs[0x37] = 0x42;
4737141cc406Sopenharmony_ci	  dev->shadow_regs[0x38] = 0x62;
4738141cc406Sopenharmony_ci	  /* set motor resolution divisor */
4739141cc406Sopenharmony_ci	  dev->shadow_regs[0x39] = 0x01;
4740141cc406Sopenharmony_ci	  /* set # of head moves per CIS read */
4741141cc406Sopenharmony_ci	  rts88xx_set_scan_frequency (dev->shadow_regs, 0);
4742141cc406Sopenharmony_ci
4743141cc406Sopenharmony_ci	  /* set ? only for colour? */
4744141cc406Sopenharmony_ci	  dev->shadow_regs[0x80] = 0x00;
4745141cc406Sopenharmony_ci	  dev->shadow_regs[0x81] = 0x00;
4746141cc406Sopenharmony_ci	  dev->shadow_regs[0x82] = 0x00;
4747141cc406Sopenharmony_ci	  dev->shadow_regs[0x85] = 0x00;
4748141cc406Sopenharmony_ci	  dev->shadow_regs[0x86] = 0x00;
4749141cc406Sopenharmony_ci	  dev->shadow_regs[0x87] = 0x00;
4750141cc406Sopenharmony_ci	  dev->shadow_regs[0x88] = 0x00;
4751141cc406Sopenharmony_ci	  dev->shadow_regs[0x91] = 0x00;
4752141cc406Sopenharmony_ci	  dev->shadow_regs[0x92] = 0x00;
4753141cc406Sopenharmony_ci	  dev->shadow_regs[0x93] = 0x06;
4754141cc406Sopenharmony_ci	  /* Motor enable & Coordinate space denominator */
4755141cc406Sopenharmony_ci	  dev->shadow_regs[0xc3] = 0x81;
4756141cc406Sopenharmony_ci	  /*  ? */
4757141cc406Sopenharmony_ci	  dev->shadow_regs[0xc5] = 0x41;
4758141cc406Sopenharmony_ci	  /* Movement direction & step size */
4759141cc406Sopenharmony_ci	  dev->shadow_regs[0xc6] = 0x09;
4760141cc406Sopenharmony_ci	  /*  ? */
4761141cc406Sopenharmony_ci	  dev->shadow_regs[0xc9] = 0x3a;
4762141cc406Sopenharmony_ci	  dev->shadow_regs[0xca] = 0x40;
4763141cc406Sopenharmony_ci	  /* bounds of movement range0 */
4764141cc406Sopenharmony_ci	  dev->shadow_regs[0xe0] = 0x00;
4765141cc406Sopenharmony_ci	  dev->shadow_regs[0xe1] = 0x00;
4766141cc406Sopenharmony_ci	  /* step size range0 */
4767141cc406Sopenharmony_ci	  dev->shadow_regs[0xe2] = 0xc7;
4768141cc406Sopenharmony_ci	  /* ? */
4769141cc406Sopenharmony_ci	  dev->shadow_regs[0xe3] = 0x29;
4770141cc406Sopenharmony_ci	  /* bounds of movement range1 */
4771141cc406Sopenharmony_ci	  dev->shadow_regs[0xe4] = 0x00;
4772141cc406Sopenharmony_ci	  dev->shadow_regs[0xe5] = 0x00;
4773141cc406Sopenharmony_ci	  /* step size range1 */
4774141cc406Sopenharmony_ci	  dev->shadow_regs[0xe6] = 0xdc;
4775141cc406Sopenharmony_ci	  /* bounds of movement range2 */
4776141cc406Sopenharmony_ci	  dev->shadow_regs[0xe7] = 0x00;
4777141cc406Sopenharmony_ci	  dev->shadow_regs[0xe8] = 0x00;
4778141cc406Sopenharmony_ci	  /* step size range2 */
4779141cc406Sopenharmony_ci	  dev->shadow_regs[0xe9] = 0x1b;
4780141cc406Sopenharmony_ci	  /* bounds of movement range3 */
4781141cc406Sopenharmony_ci	  dev->shadow_regs[0xea] = 0x00;
4782141cc406Sopenharmony_ci	  dev->shadow_regs[0xeb] = 0x00;
4783141cc406Sopenharmony_ci	  /* step size range3 */
4784141cc406Sopenharmony_ci	  dev->shadow_regs[0xec] = 0x07;
4785141cc406Sopenharmony_ci	  /* step size range4 */
4786141cc406Sopenharmony_ci	  dev->shadow_regs[0xef] = 0x03;
4787141cc406Sopenharmony_ci	}
4788141cc406Sopenharmony_ci
4789141cc406Sopenharmony_ci      /* set horizontal resolution */
4790141cc406Sopenharmony_ci      dev->shadow_regs[0x79] = 0x40;
4791141cc406Sopenharmony_ci    }
4792141cc406Sopenharmony_ci
4793141cc406Sopenharmony_ci  /* is calibration has been done, we override fixed settings with detected ones */
4794141cc406Sopenharmony_ci  if (calibrated)
4795141cc406Sopenharmony_ci    {
4796141cc406Sopenharmony_ci      /* override fixed values with ones from calibration */
4797141cc406Sopenharmony_ci      if (rts88xx_is_color (dev->shadow_regs))
4798141cc406Sopenharmony_ci	{
4799141cc406Sopenharmony_ci	  rts88xx_set_offset (dev->shadow_regs,
4800141cc406Sopenharmony_ci			      dev->offset.red,
4801141cc406Sopenharmony_ci			      dev->offset.green, dev->offset.blue);
4802141cc406Sopenharmony_ci	  rts88xx_set_gain (dev->shadow_regs,
4803141cc406Sopenharmony_ci			    dev->gain.red, dev->gain.green, dev->gain.blue);
4804141cc406Sopenharmony_ci	}
4805141cc406Sopenharmony_ci      else
4806141cc406Sopenharmony_ci	{
4807141cc406Sopenharmony_ci	  rts88xx_set_offset (dev->shadow_regs,
4808141cc406Sopenharmony_ci			      dev->offset.gray,
4809141cc406Sopenharmony_ci			      dev->offset.gray, dev->offset.gray);
4810141cc406Sopenharmony_ci	  rts88xx_set_gain (dev->shadow_regs,
4811141cc406Sopenharmony_ci			    dev->gain.gray, dev->gain.gray, dev->gain.gray);
4812141cc406Sopenharmony_ci	}
4813141cc406Sopenharmony_ci    }
4814141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_set_scan_regs: end.\n");
4815141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
4816141cc406Sopenharmony_ci}
4817141cc406Sopenharmony_ci
4818141cc406Sopenharmony_ciSANE_Status
4819141cc406Sopenharmony_cisanei_lexmark_low_start_scan (Lexmark_Device * dev)
4820141cc406Sopenharmony_ci{
4821141cc406Sopenharmony_ci  SANE_Int devnum;
4822141cc406Sopenharmony_ci
4823141cc406Sopenharmony_ci  static SANE_Byte command4_block[] = { 0x90, 0x00, 0x00, 0x03 };
4824141cc406Sopenharmony_ci
4825141cc406Sopenharmony_ci  static SANE_Byte command5_block[] = { 0x80, 0xb3, 0x00, 0x01 };
4826141cc406Sopenharmony_ci
4827141cc406Sopenharmony_ci  SANE_Byte poll_result[3];
4828141cc406Sopenharmony_ci  SANE_Byte read_result;
4829141cc406Sopenharmony_ci  SANE_Bool scan_head_moving;
4830141cc406Sopenharmony_ci  size_t size;
4831141cc406Sopenharmony_ci
4832141cc406Sopenharmony_ci  devnum = dev->devnum;
4833141cc406Sopenharmony_ci
4834141cc406Sopenharmony_ci  dev->transfer_buffer = NULL;	/* No data xferred yet */
4835141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_start_scan:\n");
4836141cc406Sopenharmony_ci
4837141cc406Sopenharmony_ci
4838141cc406Sopenharmony_ci  /* 80 b3 00 01  - poll for scanner not moving */
4839141cc406Sopenharmony_ci  scan_head_moving = SANE_TRUE;
4840141cc406Sopenharmony_ci  while (scan_head_moving)
4841141cc406Sopenharmony_ci    {
4842141cc406Sopenharmony_ci      size = 4;
4843141cc406Sopenharmony_ci      low_usb_bulk_write (devnum, command5_block, &size);
4844141cc406Sopenharmony_ci      size = 0x1;
4845141cc406Sopenharmony_ci      low_usb_bulk_read (devnum, &read_result, &size);
4846141cc406Sopenharmony_ci      if ((read_result & 0xF) == 0x0)
4847141cc406Sopenharmony_ci	{
4848141cc406Sopenharmony_ci	  scan_head_moving = SANE_FALSE;
4849141cc406Sopenharmony_ci	}
4850141cc406Sopenharmony_ci      /* F.O. Should be a timeout here so we don't hang if something breaks */
4851141cc406Sopenharmony_ci#ifdef FAKE_USB
4852141cc406Sopenharmony_ci      scan_head_moving = SANE_FALSE;
4853141cc406Sopenharmony_ci#endif
4854141cc406Sopenharmony_ci    }
4855141cc406Sopenharmony_ci
4856141cc406Sopenharmony_ci  /* Clear C6 */
4857141cc406Sopenharmony_ci  low_clr_c6 (devnum);
4858141cc406Sopenharmony_ci  /* Stop the scanner */
4859141cc406Sopenharmony_ci  low_stop_mvmt (devnum);
4860141cc406Sopenharmony_ci
4861141cc406Sopenharmony_ci  /*Set regs x2 */
4862141cc406Sopenharmony_ci  dev->shadow_regs[0x32] = 0x00;
4863141cc406Sopenharmony_ci  low_write_all_regs (devnum, dev->shadow_regs);
4864141cc406Sopenharmony_ci  dev->shadow_regs[0x32] = 0x40;
4865141cc406Sopenharmony_ci  low_write_all_regs (devnum, dev->shadow_regs);
4866141cc406Sopenharmony_ci
4867141cc406Sopenharmony_ci  /* Start Scan */
4868141cc406Sopenharmony_ci  rts88xx_commit (devnum, dev->shadow_regs[0x2c]);
4869141cc406Sopenharmony_ci
4870141cc406Sopenharmony_ci  /* We start with 0 bytes remaining to be read */
4871141cc406Sopenharmony_ci  dev->bytes_remaining = 0;
4872141cc406Sopenharmony_ci  /* and 0 bytes in the transfer buffer */
4873141cc406Sopenharmony_ci  dev->bytes_in_buffer = 0;
4874141cc406Sopenharmony_ci  dev->bytes_read = 0;
4875141cc406Sopenharmony_ci
4876141cc406Sopenharmony_ci  /* Poll the available byte count until not 0 */
4877141cc406Sopenharmony_ci  while (1)
4878141cc406Sopenharmony_ci    {
4879141cc406Sopenharmony_ci      size = 4;
4880141cc406Sopenharmony_ci      low_usb_bulk_write (devnum, command4_block, &size);
4881141cc406Sopenharmony_ci      size = 0x3;
4882141cc406Sopenharmony_ci      low_usb_bulk_read (devnum, poll_result, &size);
4883141cc406Sopenharmony_ci      if (!
4884141cc406Sopenharmony_ci	  (poll_result[0] == 0 && poll_result[1] == 0 && poll_result[2] == 0))
4885141cc406Sopenharmony_ci	{
4886141cc406Sopenharmony_ci	  /* if result != 00 00 00 we got data */
4887141cc406Sopenharmony_ci
4888141cc406Sopenharmony_ci	  /* data_size should be used to set bytes_remaining */
4889141cc406Sopenharmony_ci	  /* data_size is set from sane_get_parameters () */
4890141cc406Sopenharmony_ci	  dev->bytes_remaining = dev->data_size;
4891141cc406Sopenharmony_ci	  /* Initialize the read buffer */
4892141cc406Sopenharmony_ci	  read_buffer_init (dev, dev->params.bytes_per_line);
4893141cc406Sopenharmony_ci	  return SANE_STATUS_GOOD;
4894141cc406Sopenharmony_ci
4895141cc406Sopenharmony_ci	}
4896141cc406Sopenharmony_ci      size = 4;
4897141cc406Sopenharmony_ci      /* I'm not sure why the Windows driver does this - probably a timeout? */
4898141cc406Sopenharmony_ci      low_usb_bulk_write (devnum, command5_block, &size);
4899141cc406Sopenharmony_ci      size = 0x1;
4900141cc406Sopenharmony_ci      low_usb_bulk_read (devnum, &read_result, &size);
4901141cc406Sopenharmony_ci      if (read_result != 0x68)
4902141cc406Sopenharmony_ci	{
4903141cc406Sopenharmony_ci	  dev->bytes_remaining = 0;
4904141cc406Sopenharmony_ci	  return SANE_STATUS_IO_ERROR;
4905141cc406Sopenharmony_ci	}
4906141cc406Sopenharmony_ci    }
4907141cc406Sopenharmony_ci
4908141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_start_scan: end.\n");
4909141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
4910141cc406Sopenharmony_ci}
4911141cc406Sopenharmony_ci
4912141cc406Sopenharmony_cilong
4913141cc406Sopenharmony_cisanei_lexmark_low_read_scan_data (SANE_Byte * data, SANE_Int size,
4914141cc406Sopenharmony_ci				  Lexmark_Device * dev)
4915141cc406Sopenharmony_ci{
4916141cc406Sopenharmony_ci  SANE_Bool isColourScan, isGrayScan;
4917141cc406Sopenharmony_ci  static SANE_Byte command1_block[] = { 0x91, 0x00, 0xff, 0xc0 };
4918141cc406Sopenharmony_ci  size_t cmd_size, xfer_request;
4919141cc406Sopenharmony_ci  long bytes_read;
4920141cc406Sopenharmony_ci  SANE_Bool even_byte;
4921141cc406Sopenharmony_ci  SANE_Status status;
4922141cc406Sopenharmony_ci  int i, k, val;
4923141cc406Sopenharmony_ci
4924141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_read_scan_data:\n");
4925141cc406Sopenharmony_ci
4926141cc406Sopenharmony_ci  /* colour mode */
4927141cc406Sopenharmony_ci  isGrayScan = SANE_FALSE;
4928141cc406Sopenharmony_ci  if (strcmp (dev->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_COLOR) == 0)
4929141cc406Sopenharmony_ci    isColourScan = SANE_TRUE;
4930141cc406Sopenharmony_ci  else
4931141cc406Sopenharmony_ci    {
4932141cc406Sopenharmony_ci      isColourScan = SANE_FALSE;
4933141cc406Sopenharmony_ci      /* grayscale  mode */
4934141cc406Sopenharmony_ci      if (strcmp (dev->val[OPT_MODE].s, SANE_VALUE_SCAN_MODE_GRAY) == 0)
4935141cc406Sopenharmony_ci	isGrayScan = SANE_TRUE;
4936141cc406Sopenharmony_ci    }
4937141cc406Sopenharmony_ci
4938141cc406Sopenharmony_ci  /* Check if we have a transfer buffer. Create one and fill it if we don't */
4939141cc406Sopenharmony_ci  if (dev->transfer_buffer == NULL)
4940141cc406Sopenharmony_ci    {
4941141cc406Sopenharmony_ci      if (dev->bytes_remaining > 0)
4942141cc406Sopenharmony_ci	{
4943141cc406Sopenharmony_ci	  if (dev->bytes_remaining > MAX_XFER_SIZE)
4944141cc406Sopenharmony_ci	    xfer_request = MAX_XFER_SIZE;
4945141cc406Sopenharmony_ci	  else
4946141cc406Sopenharmony_ci	    xfer_request = dev->bytes_remaining;
4947141cc406Sopenharmony_ci
4948141cc406Sopenharmony_ci	  command1_block[2] = (SANE_Byte) (xfer_request >> 8);
4949141cc406Sopenharmony_ci	  command1_block[3] = (SANE_Byte) (xfer_request & 0xFF);
4950141cc406Sopenharmony_ci
4951141cc406Sopenharmony_ci	  /* wait for data */
4952141cc406Sopenharmony_ci	  status = low_poll_data (dev->devnum);
4953141cc406Sopenharmony_ci	  if (status != SANE_STATUS_GOOD)
4954141cc406Sopenharmony_ci	    {
4955141cc406Sopenharmony_ci	      DBG (1,
4956141cc406Sopenharmony_ci		   "sanei_lexmark_low_read_scan_data: time-out while waiting for data.\n");
4957141cc406Sopenharmony_ci	      return status;
4958141cc406Sopenharmony_ci	    }
4959141cc406Sopenharmony_ci
4960141cc406Sopenharmony_ci	  /* Create buffer to hold the amount we will request */
4961141cc406Sopenharmony_ci	  dev->transfer_buffer = (SANE_Byte *) malloc (MAX_XFER_SIZE);
4962141cc406Sopenharmony_ci	  if (dev->transfer_buffer == NULL)
4963141cc406Sopenharmony_ci	    return SANE_STATUS_NO_MEM;
4964141cc406Sopenharmony_ci
4965141cc406Sopenharmony_ci	  /* Fill it */
4966141cc406Sopenharmony_ci	  /* Write: 91 00 (xfer_size) */
4967141cc406Sopenharmony_ci	  cmd_size = 4;
4968141cc406Sopenharmony_ci	  low_usb_bulk_write (dev->devnum, command1_block, &cmd_size);
4969141cc406Sopenharmony_ci
4970141cc406Sopenharmony_ci	  /* Read: xfer_size  bytes */
4971141cc406Sopenharmony_ci	  cmd_size = xfer_request;
4972141cc406Sopenharmony_ci	  low_usb_bulk_read (dev->devnum, dev->transfer_buffer, &cmd_size);
4973141cc406Sopenharmony_ci
4974141cc406Sopenharmony_ci	  /* apply shading coefficients */
4975141cc406Sopenharmony_ci	  k = dev->bytes_read % dev->read_buffer->linesize;
4976141cc406Sopenharmony_ci	  for (i = 0; i < (int) cmd_size; i++)
4977141cc406Sopenharmony_ci	    {
4978141cc406Sopenharmony_ci	      val = dev->transfer_buffer[i];
4979141cc406Sopenharmony_ci	      val = (int) ((float) val * dev->shading_coeff[k] + 0.5);
4980141cc406Sopenharmony_ci	      if (val > 255)
4981141cc406Sopenharmony_ci		val = 255;
4982141cc406Sopenharmony_ci	      dev->transfer_buffer[i] = val;
4983141cc406Sopenharmony_ci	      k++;
4984141cc406Sopenharmony_ci	      if ((size_t) k == dev->read_buffer->linesize)
4985141cc406Sopenharmony_ci		k = 0;
4986141cc406Sopenharmony_ci	    }
4987141cc406Sopenharmony_ci
4988141cc406Sopenharmony_ci	  /* advance by the amount actually read from device */
4989141cc406Sopenharmony_ci	  dev->bytes_read += cmd_size;
4990141cc406Sopenharmony_ci	  dev->bytes_remaining -= cmd_size;
4991141cc406Sopenharmony_ci	  dev->bytes_in_buffer = cmd_size;
4992141cc406Sopenharmony_ci	  dev->read_pointer = dev->transfer_buffer;
4993141cc406Sopenharmony_ci	  DBG (2, "sanei_lexmark_low_read_scan_data:\n");
4994141cc406Sopenharmony_ci	  DBG (2, "   Filled a buffer from the scanner\n");
4995141cc406Sopenharmony_ci	  DBG (2, "   bytes_remaining: %lu\n", (u_long) dev->bytes_remaining);
4996141cc406Sopenharmony_ci	  DBG (2, "   bytes_in_buffer: %lu\n", (u_long) dev->bytes_in_buffer);
4997141cc406Sopenharmony_ci	  DBG (2, "   read_pointer: %p\n", (void *) dev->read_pointer);
4998141cc406Sopenharmony_ci	}
4999141cc406Sopenharmony_ci    }
5000141cc406Sopenharmony_ci
5001141cc406Sopenharmony_ci  DBG (5, "READ BUFFER INFO: \n");
5002141cc406Sopenharmony_ci  DBG (5, "   write ptr:     %p\n", (void *) dev->read_buffer->writeptr);
5003141cc406Sopenharmony_ci  DBG (5, "   read ptr:      %p\n", (void *) dev->read_buffer->readptr);
5004141cc406Sopenharmony_ci  DBG (5, "   max write ptr: %p\n", (void *) dev->read_buffer->max_writeptr);
5005141cc406Sopenharmony_ci  DBG (5, "   buffer size:   %lu\n", (u_long) dev->read_buffer->size);
5006141cc406Sopenharmony_ci  DBG (5, "   line size:     %lu\n", (u_long) dev->read_buffer->linesize);
5007141cc406Sopenharmony_ci  DBG (5, "   empty:         %d\n", dev->read_buffer->empty);
5008141cc406Sopenharmony_ci  DBG (5, "   line no:       %d\n", dev->read_buffer->image_line_no);
5009141cc406Sopenharmony_ci
5010141cc406Sopenharmony_ci
5011141cc406Sopenharmony_ci  /* If there is space in the read buffer, copy the transfer buffer over */
5012141cc406Sopenharmony_ci  if (read_buffer_bytes_available (dev->read_buffer) >= dev->bytes_in_buffer)
5013141cc406Sopenharmony_ci    {
5014141cc406Sopenharmony_ci      even_byte = SANE_TRUE;
5015141cc406Sopenharmony_ci      while (dev->bytes_in_buffer)
5016141cc406Sopenharmony_ci	{
5017141cc406Sopenharmony_ci
5018141cc406Sopenharmony_ci	  /* Colour Scan */
5019141cc406Sopenharmony_ci	  if (isColourScan)
5020141cc406Sopenharmony_ci	    {
5021141cc406Sopenharmony_ci	      if (even_byte)
5022141cc406Sopenharmony_ci		read_buffer_add_byte (dev->read_buffer,
5023141cc406Sopenharmony_ci				      dev->read_pointer + 1);
5024141cc406Sopenharmony_ci	      else
5025141cc406Sopenharmony_ci		read_buffer_add_byte (dev->read_buffer,
5026141cc406Sopenharmony_ci				      dev->read_pointer - 1);
5027141cc406Sopenharmony_ci	      even_byte = !even_byte;
5028141cc406Sopenharmony_ci	    }
5029141cc406Sopenharmony_ci	  /* Gray Scan */
5030141cc406Sopenharmony_ci	  else if (isGrayScan)
5031141cc406Sopenharmony_ci	    {
5032141cc406Sopenharmony_ci	      if (even_byte)
5033141cc406Sopenharmony_ci		read_buffer_add_byte_gray (dev->read_buffer,
5034141cc406Sopenharmony_ci					   dev->read_pointer + 1);
5035141cc406Sopenharmony_ci	      else
5036141cc406Sopenharmony_ci		read_buffer_add_byte_gray (dev->read_buffer,
5037141cc406Sopenharmony_ci					   dev->read_pointer - 1);
5038141cc406Sopenharmony_ci	      even_byte = !even_byte;
5039141cc406Sopenharmony_ci	    }
5040141cc406Sopenharmony_ci	  /* Lineart Scan */
5041141cc406Sopenharmony_ci	  else
5042141cc406Sopenharmony_ci	    {
5043141cc406Sopenharmony_ci	      if (even_byte)
5044141cc406Sopenharmony_ci		read_buffer_add_bit_lineart (dev->read_buffer,
5045141cc406Sopenharmony_ci					     dev->read_pointer + 1,
5046141cc406Sopenharmony_ci					     dev->threshold);
5047141cc406Sopenharmony_ci	      else
5048141cc406Sopenharmony_ci		read_buffer_add_bit_lineart (dev->read_buffer,
5049141cc406Sopenharmony_ci					     dev->read_pointer - 1,
5050141cc406Sopenharmony_ci					     dev->threshold);
5051141cc406Sopenharmony_ci	      even_byte = !even_byte;
5052141cc406Sopenharmony_ci	    }
5053141cc406Sopenharmony_ci	  dev->read_pointer = dev->read_pointer + sizeof (SANE_Byte);
5054141cc406Sopenharmony_ci	  dev->bytes_in_buffer--;
5055141cc406Sopenharmony_ci	}
5056141cc406Sopenharmony_ci      /* free the transfer buffer */
5057141cc406Sopenharmony_ci      free (dev->transfer_buffer);
5058141cc406Sopenharmony_ci      dev->transfer_buffer = NULL;
5059141cc406Sopenharmony_ci    }
5060141cc406Sopenharmony_ci
5061141cc406Sopenharmony_ci  DBG (5, "READ BUFFER INFO: \n");
5062141cc406Sopenharmony_ci  DBG (5, "   write ptr:     %p\n", (void *) dev->read_buffer->writeptr);
5063141cc406Sopenharmony_ci  DBG (5, "   read ptr:      %p\n", (void *) dev->read_buffer->readptr);
5064141cc406Sopenharmony_ci  DBG (5, "   max write ptr: %p\n", (void *) dev->read_buffer->max_writeptr);
5065141cc406Sopenharmony_ci  DBG (5, "   buffer size:   %lu\n", (u_long) dev->read_buffer->size);
5066141cc406Sopenharmony_ci  DBG (5, "   line size:     %lu\n", (u_long) dev->read_buffer->linesize);
5067141cc406Sopenharmony_ci  DBG (5, "   empty:         %d\n", dev->read_buffer->empty);
5068141cc406Sopenharmony_ci  DBG (5, "   line no:       %d\n", dev->read_buffer->image_line_no);
5069141cc406Sopenharmony_ci
5070141cc406Sopenharmony_ci  /* Read blocks out of read buffer */
5071141cc406Sopenharmony_ci  bytes_read = read_buffer_get_bytes (dev->read_buffer, data, size);
5072141cc406Sopenharmony_ci
5073141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_read_scan_data:\n");
5074141cc406Sopenharmony_ci  DBG (2, "    Copying lines from buffer to data\n");
5075141cc406Sopenharmony_ci  DBG (2, "    bytes_remaining: %lu\n", (u_long) dev->bytes_remaining);
5076141cc406Sopenharmony_ci  DBG (2, "    bytes_in_buffer: %lu\n", (u_long) dev->bytes_in_buffer);
5077141cc406Sopenharmony_ci  DBG (2, "    read_pointer: %p\n", (void *) dev->read_buffer->readptr);
5078141cc406Sopenharmony_ci  DBG (2, "    bytes_read %lu\n", (u_long) bytes_read);
5079141cc406Sopenharmony_ci
5080141cc406Sopenharmony_ci  /* if no more bytes to xfer and read buffer empty we're at the end */
5081141cc406Sopenharmony_ci  if ((dev->bytes_remaining == 0) && read_buffer_is_empty (dev->read_buffer))
5082141cc406Sopenharmony_ci    {
5083141cc406Sopenharmony_ci      if (!dev->eof)
5084141cc406Sopenharmony_ci	{
5085141cc406Sopenharmony_ci	  DBG (2,
5086141cc406Sopenharmony_ci	       "sanei_lexmark_low_read_scan_data: EOF- parking the scanner\n");
5087141cc406Sopenharmony_ci	  dev->eof = SANE_TRUE;
5088141cc406Sopenharmony_ci	  low_rewind (dev, dev->shadow_regs);
5089141cc406Sopenharmony_ci	}
5090141cc406Sopenharmony_ci      else
5091141cc406Sopenharmony_ci	{
5092141cc406Sopenharmony_ci	  DBG (2, "ERROR: Why are we trying to set eof more than once?\n");
5093141cc406Sopenharmony_ci	}
5094141cc406Sopenharmony_ci    }
5095141cc406Sopenharmony_ci
5096141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_read_scan_data: end.\n");
5097141cc406Sopenharmony_ci  return bytes_read;
5098141cc406Sopenharmony_ci}
5099141cc406Sopenharmony_ci
5100141cc406Sopenharmony_civoid
5101141cc406Sopenharmony_cilow_rewind (Lexmark_Device * dev, SANE_Byte * regs)
5102141cc406Sopenharmony_ci{
5103141cc406Sopenharmony_ci  SANE_Int new_location;
5104141cc406Sopenharmony_ci  SANE_Int location;
5105141cc406Sopenharmony_ci  SANE_Int scale;
5106141cc406Sopenharmony_ci
5107141cc406Sopenharmony_ci  DBG (2, "low_rewind: \n");
5108141cc406Sopenharmony_ci
5109141cc406Sopenharmony_ci  /* We rewind at 1200dpi resolution. We rely on content of shadow registers
5110141cc406Sopenharmony_ci     to compute the number of lines at 1200 dpi to go back */
5111141cc406Sopenharmony_ci
5112141cc406Sopenharmony_ci  /* first move to start of scanning area */
5113141cc406Sopenharmony_ci  scale = 600 / dev->val[OPT_RESOLUTION].w;
5114141cc406Sopenharmony_ci  new_location = ((dev->val[OPT_BR_Y].w / scale) * scale) * 2;
5115141cc406Sopenharmony_ci
5116141cc406Sopenharmony_ci  /* then add distance to go to the "origin dot" */
5117141cc406Sopenharmony_ci  if (rts88xx_is_color (regs))
5118141cc406Sopenharmony_ci    new_location += 400;
5119141cc406Sopenharmony_ci  else
5120141cc406Sopenharmony_ci    new_location += 420;
5121141cc406Sopenharmony_ci
5122141cc406Sopenharmony_ci  if (dev->model.sensor_type == X74_SENSOR)
5123141cc406Sopenharmony_ci    new_location += 150;
5124141cc406Sopenharmony_ci
5125141cc406Sopenharmony_ci
5126141cc406Sopenharmony_ci  location = new_location - 1;
5127141cc406Sopenharmony_ci  DBG (2, "low_rewind: %d=>new_location=%d\n", dev->val[OPT_BR_Y].w,
5128141cc406Sopenharmony_ci       new_location);
5129141cc406Sopenharmony_ci
5130141cc406Sopenharmony_ci  /* stops any pending scan */
5131141cc406Sopenharmony_ci  low_clr_c6 (dev->devnum);
5132141cc406Sopenharmony_ci  low_cancel (dev->devnum);
5133141cc406Sopenharmony_ci
5134141cc406Sopenharmony_ci  /* set regs for rewind */
5135141cc406Sopenharmony_ci  regs[0x2f] = 0xa1;
5136141cc406Sopenharmony_ci  regs[0x32] = 0x00;
5137141cc406Sopenharmony_ci  regs[0x39] = 0x00;
5138141cc406Sopenharmony_ci
5139141cc406Sopenharmony_ci  /* all other regs are always the same. these ones change with parameters */
5140141cc406Sopenharmony_ci  /* the following 4 regs are the location 61,60 and the location+1 63,62 */
5141141cc406Sopenharmony_ci
5142141cc406Sopenharmony_ci  regs[0x60] = LOBYTE (location);
5143141cc406Sopenharmony_ci  regs[0x61] = HIBYTE (location);
5144141cc406Sopenharmony_ci  regs[0x62] = LOBYTE (new_location);
5145141cc406Sopenharmony_ci  regs[0x63] = HIBYTE (new_location);
5146141cc406Sopenharmony_ci
5147141cc406Sopenharmony_ci  switch (dev->model.motor_type)
5148141cc406Sopenharmony_ci    {
5149141cc406Sopenharmony_ci    case X74_MOTOR:
5150141cc406Sopenharmony_ci      regs[0xc3] = 0x81;
5151141cc406Sopenharmony_ci      regs[0xc6] = 0x03;
5152141cc406Sopenharmony_ci      regs[0xc9] = 0x39;
5153141cc406Sopenharmony_ci      regs[0xe0] = 0x81;
5154141cc406Sopenharmony_ci      regs[0xe1] = 0x16;
5155141cc406Sopenharmony_ci      regs[0xe2] = 0xe1;
5156141cc406Sopenharmony_ci      regs[0xe3] = 0x04;
5157141cc406Sopenharmony_ci      regs[0xe4] = 0xe7;
5158141cc406Sopenharmony_ci      regs[0xe5] = 0x14;
5159141cc406Sopenharmony_ci      regs[0xe6] = 0x64;
5160141cc406Sopenharmony_ci      regs[0xe7] = 0xd5;
5161141cc406Sopenharmony_ci      regs[0xe8] = 0x08;
5162141cc406Sopenharmony_ci      regs[0xe9] = 0x32;
5163141cc406Sopenharmony_ci      regs[0xea] = 0xed;
5164141cc406Sopenharmony_ci      regs[0xeb] = 0x04;
5165141cc406Sopenharmony_ci      regs[0xec] = 0x0c;
5166141cc406Sopenharmony_ci      regs[0xef] = 0x08;
5167141cc406Sopenharmony_ci      break;
5168141cc406Sopenharmony_ci    case X1100_MOTOR:
5169141cc406Sopenharmony_ci    case A920_MOTOR:
5170141cc406Sopenharmony_ci      /* set regs for rewind */
5171141cc406Sopenharmony_ci      regs[0x79] = 0x40;
5172141cc406Sopenharmony_ci      regs[0xb2] = 0x04;
5173141cc406Sopenharmony_ci      regs[0xc3] = 0x81;
5174141cc406Sopenharmony_ci      regs[0xc6] = 0x01;
5175141cc406Sopenharmony_ci      regs[0xc9] = 0x3b;
5176141cc406Sopenharmony_ci      regs[0xe0] = 0x2b;
5177141cc406Sopenharmony_ci      regs[0xe1] = 0x17;
5178141cc406Sopenharmony_ci      regs[0xe2] = 0xe7;
5179141cc406Sopenharmony_ci      regs[0xe3] = 0x03;
5180141cc406Sopenharmony_ci      regs[0xe6] = 0xdc;
5181141cc406Sopenharmony_ci      regs[0xe7] = 0xb3;
5182141cc406Sopenharmony_ci      regs[0xe8] = 0x07;
5183141cc406Sopenharmony_ci      regs[0xe9] = 0x1b;
5184141cc406Sopenharmony_ci      regs[0xea] = 0x00;
5185141cc406Sopenharmony_ci      regs[0xeb] = 0x00;
5186141cc406Sopenharmony_ci      regs[0xec] = 0x07;
5187141cc406Sopenharmony_ci      regs[0xef] = 0x03;
5188141cc406Sopenharmony_ci      break;
5189141cc406Sopenharmony_ci    }
5190141cc406Sopenharmony_ci
5191141cc406Sopenharmony_ci
5192141cc406Sopenharmony_ci  /* starts scan */
5193141cc406Sopenharmony_ci  low_start_scan (dev->devnum, regs);
5194141cc406Sopenharmony_ci  DBG (2, "low_rewind: end.\n");
5195141cc406Sopenharmony_ci}
5196141cc406Sopenharmony_ci
5197141cc406Sopenharmony_ci
5198141cc406Sopenharmony_ciSANE_Status
5199141cc406Sopenharmony_ciread_buffer_init (Lexmark_Device * dev, int bytesperline)
5200141cc406Sopenharmony_ci{
5201141cc406Sopenharmony_ci  size_t no_lines_in_buffer;
5202141cc406Sopenharmony_ci
5203141cc406Sopenharmony_ci  DBG (2, "read_buffer_init: Start\n");
5204141cc406Sopenharmony_ci
5205141cc406Sopenharmony_ci  dev->read_buffer = (Read_Buffer *) malloc (sizeof (Read_Buffer));
5206141cc406Sopenharmony_ci  if (dev->read_buffer == NULL)
5207141cc406Sopenharmony_ci    return SANE_STATUS_NO_MEM;
5208141cc406Sopenharmony_ci  dev->read_buffer->linesize = bytesperline;
5209141cc406Sopenharmony_ci  dev->read_buffer->gray_offset = 0;
5210141cc406Sopenharmony_ci  dev->read_buffer->max_gray_offset = bytesperline - 1;
5211141cc406Sopenharmony_ci  dev->read_buffer->region = RED;
5212141cc406Sopenharmony_ci  dev->read_buffer->red_offset = 0;
5213141cc406Sopenharmony_ci  dev->read_buffer->green_offset = 1;
5214141cc406Sopenharmony_ci  dev->read_buffer->blue_offset = 2;
5215141cc406Sopenharmony_ci  dev->read_buffer->max_red_offset = bytesperline - 3;
5216141cc406Sopenharmony_ci  dev->read_buffer->max_green_offset = bytesperline - 2;
5217141cc406Sopenharmony_ci  dev->read_buffer->max_blue_offset = bytesperline - 1;
5218141cc406Sopenharmony_ci  no_lines_in_buffer = 3 * MAX_XFER_SIZE / bytesperline;
5219141cc406Sopenharmony_ci  dev->read_buffer->size = bytesperline * no_lines_in_buffer;
5220141cc406Sopenharmony_ci  dev->read_buffer->data = (SANE_Byte *) malloc (dev->read_buffer->size);
5221141cc406Sopenharmony_ci  if (dev->read_buffer->data == NULL)
5222141cc406Sopenharmony_ci    return SANE_STATUS_NO_MEM;
5223141cc406Sopenharmony_ci  dev->read_buffer->readptr = dev->read_buffer->data;
5224141cc406Sopenharmony_ci  dev->read_buffer->writeptr = dev->read_buffer->data;
5225141cc406Sopenharmony_ci  dev->read_buffer->max_writeptr = dev->read_buffer->data +
5226141cc406Sopenharmony_ci    (no_lines_in_buffer - 1) * bytesperline;
5227141cc406Sopenharmony_ci  dev->read_buffer->empty = SANE_TRUE;
5228141cc406Sopenharmony_ci  dev->read_buffer->image_line_no = 0;
5229141cc406Sopenharmony_ci  dev->read_buffer->bit_counter = 0;
5230141cc406Sopenharmony_ci  dev->read_buffer->max_lineart_offset = dev->params.pixels_per_line - 1;
5231141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
5232141cc406Sopenharmony_ci}
5233141cc406Sopenharmony_ci
5234141cc406Sopenharmony_ciSANE_Status
5235141cc406Sopenharmony_ciread_buffer_free (Read_Buffer * read_buffer)
5236141cc406Sopenharmony_ci{
5237141cc406Sopenharmony_ci  DBG (2, "read_buffer_free:\n");
5238141cc406Sopenharmony_ci  if (read_buffer)
5239141cc406Sopenharmony_ci    {
5240141cc406Sopenharmony_ci      free (read_buffer->data);
5241141cc406Sopenharmony_ci      free (read_buffer);
5242141cc406Sopenharmony_ci      read_buffer = NULL;
5243141cc406Sopenharmony_ci    }
5244141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
5245141cc406Sopenharmony_ci}
5246141cc406Sopenharmony_ci
5247141cc406Sopenharmony_cisize_t
5248141cc406Sopenharmony_ciread_buffer_bytes_available (Read_Buffer * rb)
5249141cc406Sopenharmony_ci{
5250141cc406Sopenharmony_ci
5251141cc406Sopenharmony_ci  DBG (2, "read_buffer_bytes_available:\n");
5252141cc406Sopenharmony_ci
5253141cc406Sopenharmony_ci  if (rb->empty)
5254141cc406Sopenharmony_ci    return rb->size;
5255141cc406Sopenharmony_ci  else if (rb->writeptr < rb->readptr)
5256141cc406Sopenharmony_ci    return (size_t)(rb->readptr - rb->writeptr) < rb->linesize ? 0 :
5257141cc406Sopenharmony_ci           (size_t)(rb->readptr - rb->writeptr) - rb->linesize;
5258141cc406Sopenharmony_ci  else
5259141cc406Sopenharmony_ci    return (size_t)(rb->writeptr - rb->readptr) < rb->linesize ? 0 :
5260141cc406Sopenharmony_ci           rb->size - (size_t)(rb->writeptr - rb->readptr) - rb->linesize;
5261141cc406Sopenharmony_ci}
5262141cc406Sopenharmony_ci
5263141cc406Sopenharmony_ciSANE_Status
5264141cc406Sopenharmony_ciread_buffer_add_byte (Read_Buffer * rb, SANE_Byte * byte_pointer)
5265141cc406Sopenharmony_ci{
5266141cc406Sopenharmony_ci
5267141cc406Sopenharmony_ci  /* DBG(2, "read_buffer_add_byte:\n"); */
5268141cc406Sopenharmony_ci  /* F.O. Need to fix the endian byte ordering here */
5269141cc406Sopenharmony_ci
5270141cc406Sopenharmony_ci  switch (rb->region)
5271141cc406Sopenharmony_ci    {
5272141cc406Sopenharmony_ci    case RED:
5273141cc406Sopenharmony_ci      *(rb->writeptr + rb->red_offset) = *byte_pointer;
5274141cc406Sopenharmony_ci      if (rb->red_offset == rb->max_red_offset)
5275141cc406Sopenharmony_ci	{
5276141cc406Sopenharmony_ci	  rb->red_offset = 0;
5277141cc406Sopenharmony_ci	  rb->region = GREEN;
5278141cc406Sopenharmony_ci	}
5279141cc406Sopenharmony_ci      else
5280141cc406Sopenharmony_ci	rb->red_offset = rb->red_offset + (3 * sizeof (SANE_Byte));
5281141cc406Sopenharmony_ci      return SANE_STATUS_GOOD;
5282141cc406Sopenharmony_ci    case GREEN:
5283141cc406Sopenharmony_ci      *(rb->writeptr + rb->green_offset) = *byte_pointer;
5284141cc406Sopenharmony_ci      if (rb->green_offset == rb->max_green_offset)
5285141cc406Sopenharmony_ci	{
5286141cc406Sopenharmony_ci	  rb->green_offset = 1;
5287141cc406Sopenharmony_ci	  rb->region = BLUE;
5288141cc406Sopenharmony_ci	}
5289141cc406Sopenharmony_ci      else
5290141cc406Sopenharmony_ci	rb->green_offset = rb->green_offset + (3 * sizeof (SANE_Byte));
5291141cc406Sopenharmony_ci      return SANE_STATUS_GOOD;
5292141cc406Sopenharmony_ci    case BLUE:
5293141cc406Sopenharmony_ci      *(rb->writeptr + rb->blue_offset) = *byte_pointer;
5294141cc406Sopenharmony_ci      if (rb->blue_offset == rb->max_blue_offset)
5295141cc406Sopenharmony_ci	{
5296141cc406Sopenharmony_ci	  rb->image_line_no++;
5297141cc406Sopenharmony_ci	  /* finished a line. read_buffer no longer empty */
5298141cc406Sopenharmony_ci	  rb->empty = SANE_FALSE;
5299141cc406Sopenharmony_ci	  rb->blue_offset = 2;
5300141cc406Sopenharmony_ci	  rb->region = RED;
5301141cc406Sopenharmony_ci	  if (rb->writeptr == rb->max_writeptr)
5302141cc406Sopenharmony_ci	    rb->writeptr = rb->data;	/* back to beginning of buffer */
5303141cc406Sopenharmony_ci	  else
5304141cc406Sopenharmony_ci	    rb->writeptr = rb->writeptr + rb->linesize;	/* next line */
5305141cc406Sopenharmony_ci	}
5306141cc406Sopenharmony_ci      else
5307141cc406Sopenharmony_ci	rb->blue_offset = rb->blue_offset + (3 * sizeof (SANE_Byte));
5308141cc406Sopenharmony_ci      return SANE_STATUS_GOOD;
5309141cc406Sopenharmony_ci    }
5310141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
5311141cc406Sopenharmony_ci}
5312141cc406Sopenharmony_ci
5313141cc406Sopenharmony_ciSANE_Status
5314141cc406Sopenharmony_ciread_buffer_add_byte_gray (Read_Buffer * rb, SANE_Byte * byte_pointer)
5315141cc406Sopenharmony_ci{
5316141cc406Sopenharmony_ci
5317141cc406Sopenharmony_ci  /*  DBG(2, "read_buffer_add_byte_gray:\n"); */
5318141cc406Sopenharmony_ci
5319141cc406Sopenharmony_ci  *(rb->writeptr + rb->gray_offset) = *byte_pointer;
5320141cc406Sopenharmony_ci
5321141cc406Sopenharmony_ci  if (rb->gray_offset == rb->max_gray_offset)
5322141cc406Sopenharmony_ci    {
5323141cc406Sopenharmony_ci      rb->image_line_no++;
5324141cc406Sopenharmony_ci      /* finished a line. read_buffer no longer empty */
5325141cc406Sopenharmony_ci      rb->empty = SANE_FALSE;
5326141cc406Sopenharmony_ci      rb->gray_offset = 0;
5327141cc406Sopenharmony_ci
5328141cc406Sopenharmony_ci      if (rb->writeptr == rb->max_writeptr)
5329141cc406Sopenharmony_ci	rb->writeptr = rb->data;	/* back to beginning of buffer */
5330141cc406Sopenharmony_ci      else
5331141cc406Sopenharmony_ci	rb->writeptr = rb->writeptr + rb->linesize;	/* next line */
5332141cc406Sopenharmony_ci    }
5333141cc406Sopenharmony_ci  else
5334141cc406Sopenharmony_ci    rb->gray_offset = rb->gray_offset + (1 * sizeof (SANE_Byte));
5335141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
5336141cc406Sopenharmony_ci}
5337141cc406Sopenharmony_ci
5338141cc406Sopenharmony_ciSANE_Status
5339141cc406Sopenharmony_ciread_buffer_add_bit_lineart (Read_Buffer * rb, SANE_Byte * byte_pointer,
5340141cc406Sopenharmony_ci			     SANE_Byte threshold)
5341141cc406Sopenharmony_ci{
5342141cc406Sopenharmony_ci  SANE_Byte tmpByte;
5343141cc406Sopenharmony_ci  SANE_Byte *currentBytePtr;
5344141cc406Sopenharmony_ci  SANE_Int bitIndex;
5345141cc406Sopenharmony_ci
5346141cc406Sopenharmony_ci  /*  DBG(2, "read_buffer_add_bit_lineart:\n"); */
5347141cc406Sopenharmony_ci
5348141cc406Sopenharmony_ci  /* threshold = 0x80;  */
5349141cc406Sopenharmony_ci  tmpByte = 0;
5350141cc406Sopenharmony_ci  /* Create a bit by comparing incoming byte to threshold */
5351141cc406Sopenharmony_ci  if (*byte_pointer <= threshold)
5352141cc406Sopenharmony_ci    {
5353141cc406Sopenharmony_ci      tmpByte = 128;
5354141cc406Sopenharmony_ci    }
5355141cc406Sopenharmony_ci
5356141cc406Sopenharmony_ci  /* Calculate the bit index in the current byte */
5357141cc406Sopenharmony_ci  bitIndex = rb->bit_counter % 8;
5358141cc406Sopenharmony_ci  /* Move the bit to its correct position in the temporary byte */
5359141cc406Sopenharmony_ci  tmpByte = tmpByte >> bitIndex;
5360141cc406Sopenharmony_ci  /* Get the pointer to the current byte */
5361141cc406Sopenharmony_ci  currentBytePtr = rb->writeptr + rb->gray_offset;
5362141cc406Sopenharmony_ci
5363141cc406Sopenharmony_ci  /* If this is the first write to this byte, clear the byte */
5364141cc406Sopenharmony_ci  if (bitIndex == 0)
5365141cc406Sopenharmony_ci    *currentBytePtr = 0;
5366141cc406Sopenharmony_ci  /* Set the value of the bit in the current byte */
5367141cc406Sopenharmony_ci  *currentBytePtr = *currentBytePtr | tmpByte;
5368141cc406Sopenharmony_ci
5369141cc406Sopenharmony_ci  /* last bit in the line? */
5370141cc406Sopenharmony_ci  if (rb->bit_counter == rb->max_lineart_offset)
5371141cc406Sopenharmony_ci    {
5372141cc406Sopenharmony_ci      /* Check if we're at the last byte of the line - error if not */
5373141cc406Sopenharmony_ci      if (rb->gray_offset != rb->max_gray_offset)
5374141cc406Sopenharmony_ci	{
5375141cc406Sopenharmony_ci	  DBG (5, "read_buffer_add_bit_lineart:\n");
5376141cc406Sopenharmony_ci	  DBG (5, "  Last bit of line is not last byte.\n");
5377141cc406Sopenharmony_ci	  DBG (5, "  Bit Index: %d, Byte Index: %d. \n", rb->bit_counter,
5378141cc406Sopenharmony_ci	       rb->max_gray_offset);
5379141cc406Sopenharmony_ci	  return SANE_STATUS_INVAL;
5380141cc406Sopenharmony_ci	}
5381141cc406Sopenharmony_ci      rb->image_line_no++;
5382141cc406Sopenharmony_ci      /* line finished read_buffer no longer empty */
5383141cc406Sopenharmony_ci      rb->empty = SANE_FALSE;
5384141cc406Sopenharmony_ci      rb->gray_offset = 0;
5385141cc406Sopenharmony_ci      /* are we at the last line in the read buffer ? */
5386141cc406Sopenharmony_ci      if (rb->writeptr == rb->max_writeptr)
5387141cc406Sopenharmony_ci	rb->writeptr = rb->data;	/* back to beginning of buffer */
5388141cc406Sopenharmony_ci      else
5389141cc406Sopenharmony_ci	rb->writeptr = rb->writeptr + rb->linesize;	/* next line */
5390141cc406Sopenharmony_ci      /* clear the bit counter */
5391141cc406Sopenharmony_ci      rb->bit_counter = 0;
5392141cc406Sopenharmony_ci    }
5393141cc406Sopenharmony_ci  /* last bit in the byte? */
5394141cc406Sopenharmony_ci  else if (bitIndex == 7)
5395141cc406Sopenharmony_ci    {
5396141cc406Sopenharmony_ci      /* Not at the end of the line, but byte done. Increment byte offset */
5397141cc406Sopenharmony_ci      rb->gray_offset = rb->gray_offset + (1 * sizeof (SANE_Byte));
5398141cc406Sopenharmony_ci      /* increment bit counter */
5399141cc406Sopenharmony_ci      rb->bit_counter++;
5400141cc406Sopenharmony_ci    }
5401141cc406Sopenharmony_ci  else
5402141cc406Sopenharmony_ci    {
5403141cc406Sopenharmony_ci      /* else increment bit counter */
5404141cc406Sopenharmony_ci      rb->bit_counter++;
5405141cc406Sopenharmony_ci    }
5406141cc406Sopenharmony_ci
5407141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
5408141cc406Sopenharmony_ci}
5409141cc406Sopenharmony_ci
5410141cc406Sopenharmony_ci
5411141cc406Sopenharmony_cisize_t
5412141cc406Sopenharmony_ciread_buffer_get_bytes (Read_Buffer * rb, SANE_Byte * buffer, size_t rqst_size)
5413141cc406Sopenharmony_ci{
5414141cc406Sopenharmony_ci  /* Read_Buffer *rb; */
5415141cc406Sopenharmony_ci  size_t available_bytes;
5416141cc406Sopenharmony_ci
5417141cc406Sopenharmony_ci  /* rb = read_buffer; */
5418141cc406Sopenharmony_ci  if (rb->empty)
5419141cc406Sopenharmony_ci    return 0;
5420141cc406Sopenharmony_ci  else if (rb->writeptr > rb->readptr)
5421141cc406Sopenharmony_ci    {
5422141cc406Sopenharmony_ci      available_bytes = rb->writeptr - rb->readptr;
5423141cc406Sopenharmony_ci      if (available_bytes <= rqst_size)
5424141cc406Sopenharmony_ci	{
5425141cc406Sopenharmony_ci	  /* We can read from the read pointer up to the write pointer */
5426141cc406Sopenharmony_ci	  memcpy (buffer, rb->readptr, available_bytes);
5427141cc406Sopenharmony_ci	  rb->readptr = rb->writeptr;
5428141cc406Sopenharmony_ci	  rb->empty = SANE_TRUE;
5429141cc406Sopenharmony_ci	  return available_bytes;
5430141cc406Sopenharmony_ci	}
5431141cc406Sopenharmony_ci      else
5432141cc406Sopenharmony_ci	{
5433141cc406Sopenharmony_ci	  /* We can read from the full request size */
5434141cc406Sopenharmony_ci	  memcpy (buffer, rb->readptr, rqst_size);
5435141cc406Sopenharmony_ci	  rb->readptr = rb->readptr + rqst_size;
5436141cc406Sopenharmony_ci	  return rqst_size;
5437141cc406Sopenharmony_ci	}
5438141cc406Sopenharmony_ci    }
5439141cc406Sopenharmony_ci  else
5440141cc406Sopenharmony_ci    {
5441141cc406Sopenharmony_ci      /* The read pointer is ahead of the write pointer. Its wrapped around. */
5442141cc406Sopenharmony_ci      /* We can read to the end of the buffer and make a recursive call to */
5443141cc406Sopenharmony_ci      /* read any available lines at the beginning of the buffer */
5444141cc406Sopenharmony_ci      available_bytes = rb->data + rb->size - rb->readptr;
5445141cc406Sopenharmony_ci      if (available_bytes <= rqst_size)
5446141cc406Sopenharmony_ci	{
5447141cc406Sopenharmony_ci	  /* We can read from the read pointer up to the end of the buffer */
5448141cc406Sopenharmony_ci	  memcpy (buffer, rb->readptr, available_bytes);
5449141cc406Sopenharmony_ci	  rb->readptr = rb->data;
5450141cc406Sopenharmony_ci	  if (rb->writeptr == rb->readptr)
5451141cc406Sopenharmony_ci	    rb->empty = SANE_TRUE;
5452141cc406Sopenharmony_ci	  return available_bytes +
5453141cc406Sopenharmony_ci	    read_buffer_get_bytes (rb, buffer + available_bytes,
5454141cc406Sopenharmony_ci				   rqst_size - available_bytes);
5455141cc406Sopenharmony_ci	}
5456141cc406Sopenharmony_ci      else
5457141cc406Sopenharmony_ci	{
5458141cc406Sopenharmony_ci	  /* We can read from the full request size */
5459141cc406Sopenharmony_ci	  memcpy (buffer, rb->readptr, rqst_size);
5460141cc406Sopenharmony_ci	  rb->readptr = rb->readptr + rqst_size;
5461141cc406Sopenharmony_ci	  return rqst_size;
5462141cc406Sopenharmony_ci	}
5463141cc406Sopenharmony_ci    }
5464141cc406Sopenharmony_ci}
5465141cc406Sopenharmony_ci
5466141cc406Sopenharmony_ciSANE_Bool
5467141cc406Sopenharmony_ciread_buffer_is_empty (Read_Buffer * read_buffer)
5468141cc406Sopenharmony_ci{
5469141cc406Sopenharmony_ci  return read_buffer->empty;
5470141cc406Sopenharmony_ci}
5471141cc406Sopenharmony_ci
5472141cc406Sopenharmony_ci/*
5473141cc406Sopenharmony_ci * average a width*height rgb/monochrome area
5474141cc406Sopenharmony_ci * return values in given pointers
5475141cc406Sopenharmony_ci */
5476141cc406Sopenharmony_cistatic int
5477141cc406Sopenharmony_ciaverage_area (SANE_Byte * regs, SANE_Byte * data, int width, int height,
5478141cc406Sopenharmony_ci	      int *ra, int *ga, int *ba)
5479141cc406Sopenharmony_ci{
5480141cc406Sopenharmony_ci  int x, y;
5481141cc406Sopenharmony_ci  int global = 0;
5482141cc406Sopenharmony_ci  int rc, gc, bc;
5483141cc406Sopenharmony_ci
5484141cc406Sopenharmony_ci  *ra = 0;
5485141cc406Sopenharmony_ci  *ga = 0;
5486141cc406Sopenharmony_ci  *ba = 0;
5487141cc406Sopenharmony_ci  rc = 0;
5488141cc406Sopenharmony_ci  gc = 0;
5489141cc406Sopenharmony_ci  bc = 0;
5490141cc406Sopenharmony_ci  if (rts88xx_is_color (regs))
5491141cc406Sopenharmony_ci    {
5492141cc406Sopenharmony_ci      for (x = 0; x < width; x++)
5493141cc406Sopenharmony_ci	for (y = 0; y < height; y++)
5494141cc406Sopenharmony_ci	  {
5495141cc406Sopenharmony_ci	    rc += data[3 * width * y + x];
5496141cc406Sopenharmony_ci	    gc += data[3 * width * y + width + x];
5497141cc406Sopenharmony_ci	    bc += data[3 * width * y + 2 * width + x];
5498141cc406Sopenharmony_ci	  }
5499141cc406Sopenharmony_ci      global = (rc + gc + bc) / (3 * width * height);
5500141cc406Sopenharmony_ci      *ra = rc / (width * height);
5501141cc406Sopenharmony_ci      *ga = gc / (width * height);
5502141cc406Sopenharmony_ci      *ba = bc / (width * height);
5503141cc406Sopenharmony_ci    }
5504141cc406Sopenharmony_ci  else
5505141cc406Sopenharmony_ci    {
5506141cc406Sopenharmony_ci      for (x = 0; x < width; x++)
5507141cc406Sopenharmony_ci	for (y = 0; y < height; y++)
5508141cc406Sopenharmony_ci	  {
5509141cc406Sopenharmony_ci	    gc += data[width * y + x];
5510141cc406Sopenharmony_ci	  }
5511141cc406Sopenharmony_ci      global = gc / (width * height);
5512141cc406Sopenharmony_ci      *ga = gc / (width * height);
5513141cc406Sopenharmony_ci    }
5514141cc406Sopenharmony_ci  DBG (7, "average_area: global=%d, red=%d, green=%d, blue=%d\n", global, *ra,
5515141cc406Sopenharmony_ci       *ga, *ba);
5516141cc406Sopenharmony_ci  return global;
5517141cc406Sopenharmony_ci}
5518141cc406Sopenharmony_ci
5519141cc406Sopenharmony_ci/**
5520141cc406Sopenharmony_ci * we scan a dark area with gain minimum to detect offset
5521141cc406Sopenharmony_ci */
5522141cc406Sopenharmony_ciSANE_Status
5523141cc406Sopenharmony_cisanei_lexmark_low_offset_calibration (Lexmark_Device * dev)
5524141cc406Sopenharmony_ci{
5525141cc406Sopenharmony_ci  SANE_Byte regs[255];		/* we have our own copy of shadow registers */
5526141cc406Sopenharmony_ci  SANE_Status status = SANE_STATUS_GOOD;
5527141cc406Sopenharmony_ci  int i, lines = 8, yoffset = 2;
5528141cc406Sopenharmony_ci  int pixels;
5529141cc406Sopenharmony_ci  int failed = 0;
5530141cc406Sopenharmony_ci  /* offsets */
5531141cc406Sopenharmony_ci  int ro = 0, go = 0, bo = 0;
5532141cc406Sopenharmony_ci  /* averages */
5533141cc406Sopenharmony_ci  int ra, ga, ba, average;
5534141cc406Sopenharmony_ci  SANE_Byte *data = NULL;
5535141cc406Sopenharmony_ci  SANE_Byte top[OFFSET_RANGES] = { 0, 0x7f, 0x9f, 0xbf, 0xff };
5536141cc406Sopenharmony_ci#ifdef DEEP_DEBUG
5537141cc406Sopenharmony_ci  char title[20];
5538141cc406Sopenharmony_ci#endif
5539141cc406Sopenharmony_ci
5540141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_offset_calibration: start\n");
5541141cc406Sopenharmony_ci  /* copy registers */
5542141cc406Sopenharmony_ci  for (i = 0; i < 255; i++)
5543141cc406Sopenharmony_ci    regs[i] = dev->shadow_regs[i];
5544141cc406Sopenharmony_ci
5545141cc406Sopenharmony_ci  /* we clear movement bit */
5546141cc406Sopenharmony_ci  regs[0xc3] = regs[0xc3] & 0x7f;
5547141cc406Sopenharmony_ci
5548141cc406Sopenharmony_ci  pixels =
5549141cc406Sopenharmony_ci    (dev->sensor->offset_endx - dev->sensor->offset_startx) / regs[0x7a];
5550141cc406Sopenharmony_ci
5551141cc406Sopenharmony_ci  /* there are 4 ranges of offset:
5552141cc406Sopenharmony_ci     00-7F : almost no offset
5553141cc406Sopenharmony_ci     80-9F : high noise
5554141cc406Sopenharmony_ci     A0-BF : high noise
5555141cc406Sopenharmony_ci     C0-FF : high noise
5556141cc406Sopenharmony_ci     we start with the highest one and decrease until
5557141cc406Sopenharmony_ci     overall offset is ok
5558141cc406Sopenharmony_ci     First loop may have such an high offset that scanned data overflow
5559141cc406Sopenharmony_ci     and gives a low average. So we always skip its results
5560141cc406Sopenharmony_ci   */
5561141cc406Sopenharmony_ci
5562141cc406Sopenharmony_ci  /* minimal gains */
5563141cc406Sopenharmony_ci  DBG (3,
5564141cc406Sopenharmony_ci       "sanei_lexmark_low_offset_calibration: setting gains to (1,1,1).\n");
5565141cc406Sopenharmony_ci  rts88xx_set_gain (regs, 1, 1, 1);
5566141cc406Sopenharmony_ci
5567141cc406Sopenharmony_ci  i = OFFSET_RANGES;
5568141cc406Sopenharmony_ci  average = 255;
5569141cc406Sopenharmony_ci
5570141cc406Sopenharmony_ci  /* loop on ranges until one fits. Then adjust offset, first loop is
5571141cc406Sopenharmony_ci   * always done. TODO detect overflow by 'noise looking' data pattern */
5572141cc406Sopenharmony_ci  while (((i > 0) && (average > dev->sensor->offset_threshold))
5573141cc406Sopenharmony_ci	 || (i == OFFSET_RANGES))
5574141cc406Sopenharmony_ci    {
5575141cc406Sopenharmony_ci      /* next range  */
5576141cc406Sopenharmony_ci      i--;
5577141cc406Sopenharmony_ci
5578141cc406Sopenharmony_ci      /* sets to top of range */
5579141cc406Sopenharmony_ci      ro = top[i];
5580141cc406Sopenharmony_ci      go = top[i];
5581141cc406Sopenharmony_ci      bo = top[i];
5582141cc406Sopenharmony_ci      rts88xx_set_offset (regs, ro, ro, ro);
5583141cc406Sopenharmony_ci      DBG (3,
5584141cc406Sopenharmony_ci	   "sanei_lexmark_low_offset_calibration: setting offsets to (%d,%d,%d).\n",
5585141cc406Sopenharmony_ci	   ro, ro, ro);
5586141cc406Sopenharmony_ci
5587141cc406Sopenharmony_ci      status =
5588141cc406Sopenharmony_ci	low_simple_scan (dev, regs, dev->sensor->offset_startx, pixels,
5589141cc406Sopenharmony_ci			 yoffset, lines, &data);
5590141cc406Sopenharmony_ci      if (status != SANE_STATUS_GOOD)
5591141cc406Sopenharmony_ci	{
5592141cc406Sopenharmony_ci	  DBG (1,
5593141cc406Sopenharmony_ci	       "sanei_lexmark_low_offset_calibration: low_simple_scan failed!\n");
5594141cc406Sopenharmony_ci	  if (data != NULL)
5595141cc406Sopenharmony_ci	    free (data);
5596141cc406Sopenharmony_ci	  return status;
5597141cc406Sopenharmony_ci	}
5598141cc406Sopenharmony_ci#ifdef DEEP_DEBUG
5599141cc406Sopenharmony_ci      sprintf (title, "offset%02x.pnm", ro);
5600141cc406Sopenharmony_ci      write_pnm_file (title, pixels, lines, rts88xx_is_color (regs), data);
5601141cc406Sopenharmony_ci#endif
5602141cc406Sopenharmony_ci      average = average_area (regs, data, pixels, lines, &ra, &ga, &ba);
5603141cc406Sopenharmony_ci      free (data);
5604141cc406Sopenharmony_ci    }
5605141cc406Sopenharmony_ci  if (i == 0)
5606141cc406Sopenharmony_ci    {
5607141cc406Sopenharmony_ci      DBG (2, "sanei_lexmark_low_offset_calibration: failed !\n");
5608141cc406Sopenharmony_ci      failed = 1;
5609141cc406Sopenharmony_ci    }
5610141cc406Sopenharmony_ci
5611141cc406Sopenharmony_ci  /* increase gain and scan again */
5612141cc406Sopenharmony_ci  /* increase gain for fine offset tuning */
5613141cc406Sopenharmony_ci  rts88xx_set_gain (regs, 6, 6, 6);
5614141cc406Sopenharmony_ci  status =
5615141cc406Sopenharmony_ci    low_simple_scan (dev, regs, dev->sensor->offset_startx, pixels, yoffset,
5616141cc406Sopenharmony_ci		     lines, &data);
5617141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
5618141cc406Sopenharmony_ci    {
5619141cc406Sopenharmony_ci      DBG (1,
5620141cc406Sopenharmony_ci	   "sanei_lexmark_low_offset_calibration: low_simple_scan failed!\n");
5621141cc406Sopenharmony_ci      if (data != NULL)
5622141cc406Sopenharmony_ci	free (data);
5623141cc406Sopenharmony_ci      return status;
5624141cc406Sopenharmony_ci    }
5625141cc406Sopenharmony_ci  average_area (regs, data, pixels, lines, &ra, &ga, &ba);
5626141cc406Sopenharmony_ci#ifdef DEEP_DEBUG
5627141cc406Sopenharmony_ci  write_pnm_file ("offset-final.pnm", pixels, lines, rts88xx_is_color (regs),
5628141cc406Sopenharmony_ci		  data);
5629141cc406Sopenharmony_ci#endif
5630141cc406Sopenharmony_ci
5631141cc406Sopenharmony_ci  /* this "law" is a guess, may (should?) be changed ... */
5632141cc406Sopenharmony_ci  if (!failed)
5633141cc406Sopenharmony_ci    {
5634141cc406Sopenharmony_ci      if (ro > ra)
5635141cc406Sopenharmony_ci	dev->offset.red = ro - ra;
5636141cc406Sopenharmony_ci      if (go > ga)
5637141cc406Sopenharmony_ci	{
5638141cc406Sopenharmony_ci	  dev->offset.green = go - ga;
5639141cc406Sopenharmony_ci	  dev->offset.gray = go - ga;
5640141cc406Sopenharmony_ci	}
5641141cc406Sopenharmony_ci      if (bo > ba)
5642141cc406Sopenharmony_ci	dev->offset.blue = bo - ba;
5643141cc406Sopenharmony_ci    }
5644141cc406Sopenharmony_ci  else
5645141cc406Sopenharmony_ci    {
5646141cc406Sopenharmony_ci      dev->offset.red = dev->sensor->offset_fallback;
5647141cc406Sopenharmony_ci      dev->offset.green = dev->sensor->offset_fallback;
5648141cc406Sopenharmony_ci      dev->offset.blue = dev->sensor->offset_fallback;
5649141cc406Sopenharmony_ci    }
5650141cc406Sopenharmony_ci  DBG (7,
5651141cc406Sopenharmony_ci       "sanei_lexmark_low_offset_calibration: offset=(0x%02x,0x%02x,0x%02x).\n",
5652141cc406Sopenharmony_ci       dev->offset.red, dev->offset.green, dev->offset.blue);
5653141cc406Sopenharmony_ci
5654141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_offset_calibration: end.\n");
5655141cc406Sopenharmony_ci  free (data);
5656141cc406Sopenharmony_ci  return status;
5657141cc406Sopenharmony_ci}
5658141cc406Sopenharmony_ci
5659141cc406Sopenharmony_ci/*
5660141cc406Sopenharmony_ci * we scan a white area until average is good enough
5661141cc406Sopenharmony_ci * level is good enough when it maximize the range value of output:
5662141cc406Sopenharmony_ci * ie max-min is maximum
5663141cc406Sopenharmony_ci */
5664141cc406Sopenharmony_ciSANE_Status
5665141cc406Sopenharmony_cisanei_lexmark_low_gain_calibration (Lexmark_Device * dev)
5666141cc406Sopenharmony_ci{
5667141cc406Sopenharmony_ci  SANE_Byte regs[255];		/* we have our own copy of shadow registers */
5668141cc406Sopenharmony_ci  SANE_Status status = SANE_STATUS_GOOD;
5669141cc406Sopenharmony_ci  int i, lines = 4, yoffset = 1;
5670141cc406Sopenharmony_ci  int sx, ex;
5671141cc406Sopenharmony_ci  int pixels;
5672141cc406Sopenharmony_ci  /* averages */
5673141cc406Sopenharmony_ci  int ra, ga, ba;
5674141cc406Sopenharmony_ci  SANE_Byte *data = NULL;
5675141cc406Sopenharmony_ci  int red, green, blue;
5676141cc406Sopenharmony_ci#ifdef DEEP_DEBUG
5677141cc406Sopenharmony_ci  char title[20];
5678141cc406Sopenharmony_ci#endif
5679141cc406Sopenharmony_ci
5680141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_gain_calibration: start\n");
5681141cc406Sopenharmony_ci  /* copy registers */
5682141cc406Sopenharmony_ci  for (i = 0; i < 255; i++)
5683141cc406Sopenharmony_ci    regs[i] = dev->shadow_regs[i];
5684141cc406Sopenharmony_ci
5685141cc406Sopenharmony_ci  /* we clear movement bit */
5686141cc406Sopenharmony_ci  regs[0xc3] = regs[0xc3] & 0x7f;
5687141cc406Sopenharmony_ci  sx = regs[0x67] * 256 + regs[0x66];
5688141cc406Sopenharmony_ci  ex = regs[0x6d] * 256 + regs[0x6c];
5689141cc406Sopenharmony_ci  pixels = (ex - sx) / regs[0x7a];
5690141cc406Sopenharmony_ci
5691141cc406Sopenharmony_ci
5692141cc406Sopenharmony_ci  /* set up initial gains */
5693141cc406Sopenharmony_ci  red = 6;
5694141cc406Sopenharmony_ci  green = 6;
5695141cc406Sopenharmony_ci  blue = 6;
5696141cc406Sopenharmony_ci  rts88xx_set_gain (regs, red, green, blue);
5697141cc406Sopenharmony_ci
5698141cc406Sopenharmony_ci  /* init loop */
5699141cc406Sopenharmony_ci  i = 0;
5700141cc406Sopenharmony_ci  ra = 0;
5701141cc406Sopenharmony_ci  ba = 0;
5702141cc406Sopenharmony_ci  ga = 0;
5703141cc406Sopenharmony_ci
5704141cc406Sopenharmony_ci  status = low_cancel (dev->devnum);
5705141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
5706141cc406Sopenharmony_ci    return status;
5707141cc406Sopenharmony_ci
5708141cc406Sopenharmony_ci  /* we do a simple scan all 3 averages give the chosen level */
5709141cc406Sopenharmony_ci  while (((rts88xx_is_color (regs)
5710141cc406Sopenharmony_ci	   && ((ra < dev->sensor->red_gain_target)
5711141cc406Sopenharmony_ci	       || (ga < dev->sensor->green_gain_target)
5712141cc406Sopenharmony_ci	       || (ba < dev->sensor->blue_gain_target)))
5713141cc406Sopenharmony_ci	  || (!rts88xx_is_color (regs)
5714141cc406Sopenharmony_ci	      && (ga < dev->sensor->gray_gain_target))) && (i < 25))
5715141cc406Sopenharmony_ci    {
5716141cc406Sopenharmony_ci      status = low_simple_scan (dev, regs, sx, pixels, yoffset, lines, &data);
5717141cc406Sopenharmony_ci      if (status != SANE_STATUS_GOOD)
5718141cc406Sopenharmony_ci	{
5719141cc406Sopenharmony_ci	  DBG (1,
5720141cc406Sopenharmony_ci	       "sanei_lexmark_low_gain_calibration: low_simple_scan failed!\n");
5721141cc406Sopenharmony_ci	  if (data != NULL)
5722141cc406Sopenharmony_ci	    free (data);
5723141cc406Sopenharmony_ci	  return status;
5724141cc406Sopenharmony_ci	}
5725141cc406Sopenharmony_ci#ifdef DEEP_DEBUG
5726141cc406Sopenharmony_ci      sprintf (title, "gain%02d.pnm", i);
5727141cc406Sopenharmony_ci      write_pnm_file (title, pixels, lines, rts88xx_is_color (regs), data);
5728141cc406Sopenharmony_ci#endif
5729141cc406Sopenharmony_ci      average_area (regs, data, pixels, lines, &ra, &ga, &ba);
5730141cc406Sopenharmony_ci      free (data);
5731141cc406Sopenharmony_ci      if (ra < dev->sensor->red_gain_target)
5732141cc406Sopenharmony_ci	red++;
5733141cc406Sopenharmony_ci      if (ga < dev->sensor->green_gain_target
5734141cc406Sopenharmony_ci	  || (dev->sensor->gray_gain_target && !rts88xx_is_color (regs)))
5735141cc406Sopenharmony_ci	green++;
5736141cc406Sopenharmony_ci      if (ba < dev->sensor->blue_gain_target)
5737141cc406Sopenharmony_ci	blue++;
5738141cc406Sopenharmony_ci      rts88xx_set_gain (regs, red, green, blue);
5739141cc406Sopenharmony_ci      i++;
5740141cc406Sopenharmony_ci    }
5741141cc406Sopenharmony_ci  dev->gain.red = red;
5742141cc406Sopenharmony_ci  dev->gain.green = green;
5743141cc406Sopenharmony_ci  dev->gain.blue = blue;
5744141cc406Sopenharmony_ci  dev->gain.gray = green;
5745141cc406Sopenharmony_ci  DBG (7,
5746141cc406Sopenharmony_ci       "sanei_lexmark_low_gain_calibration: gain=(0x%02x,0x%02x,0x%02x).\n",
5747141cc406Sopenharmony_ci       dev->gain.red, dev->gain.green, dev->gain.blue);
5748141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_gain_calibration: end.\n");
5749141cc406Sopenharmony_ci  return status;
5750141cc406Sopenharmony_ci}
5751141cc406Sopenharmony_ci
5752141cc406Sopenharmony_ci/**
5753141cc406Sopenharmony_ci * there is no hardware shading correction. So we have to do it in software.
5754141cc406Sopenharmony_ci * We do it by scanning a pure white area which is before scanning area. Then
5755141cc406Sopenharmony_ci * we compute per pixel coefficient to move the scanned value to the target
5756141cc406Sopenharmony_ci * value. These coefficients are used later to correct scanned data.
5757141cc406Sopenharmony_ci * The scan is done with all the final scan settings but the height and vertical
5758141cc406Sopenharmony_ci * start position.
5759141cc406Sopenharmony_ci */
5760141cc406Sopenharmony_ciSANE_Status
5761141cc406Sopenharmony_cisanei_lexmark_low_shading_calibration (Lexmark_Device * dev)
5762141cc406Sopenharmony_ci{
5763141cc406Sopenharmony_ci  SANE_Byte regs[255];		/* we have our own copy of shadow registers */
5764141cc406Sopenharmony_ci  int i, j, pixels, bpl;
5765141cc406Sopenharmony_ci  int sx, ex;
5766141cc406Sopenharmony_ci  SANE_Byte *data = NULL;
5767141cc406Sopenharmony_ci  SANE_Status status;
5768141cc406Sopenharmony_ci  /* enough 75 dpi lines to "go off" home position dot,
5769141cc406Sopenharmony_ci     and include shading area */
5770141cc406Sopenharmony_ci  int lines = 4 + 4;
5771141cc406Sopenharmony_ci  int lineoffset = 1;
5772141cc406Sopenharmony_ci  int linetotal = lines + lineoffset;
5773141cc406Sopenharmony_ci  int yoffset;
5774141cc406Sopenharmony_ci  int x, y;
5775141cc406Sopenharmony_ci  float rtarget, btarget, gtarget;
5776141cc406Sopenharmony_ci
5777141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_shading_calibration: start\n");
5778141cc406Sopenharmony_ci  /* copy registers */
5779141cc406Sopenharmony_ci  for (i = 0; i < 255; i++)
5780141cc406Sopenharmony_ci    regs[i] = dev->shadow_regs[i];
5781141cc406Sopenharmony_ci
5782141cc406Sopenharmony_ci  /* allocate memory for scan */
5783141cc406Sopenharmony_ci  sx = regs[0x67] * 256 + regs[0x66];
5784141cc406Sopenharmony_ci  ex = regs[0x6d] * 256 + regs[0x6c];
5785141cc406Sopenharmony_ci
5786141cc406Sopenharmony_ci
5787141cc406Sopenharmony_ci  DBG (7, "startx=%d, endx=%d, coef=%d, r2f=0x%02x\n",
5788141cc406Sopenharmony_ci       sx, ex, regs[0x7a], regs[0x2f]);
5789141cc406Sopenharmony_ci
5790141cc406Sopenharmony_ci  pixels = (ex - sx) / regs[0x7a];
5791141cc406Sopenharmony_ci  if (rts88xx_is_color (regs))
5792141cc406Sopenharmony_ci    bpl = 3 * pixels;
5793141cc406Sopenharmony_ci  else
5794141cc406Sopenharmony_ci    bpl = pixels;
5795141cc406Sopenharmony_ci
5796141cc406Sopenharmony_ci  /* adjust the target area to the scanning resolution */
5797141cc406Sopenharmony_ci  lines = (8 * lines) / regs[0x7a];
5798141cc406Sopenharmony_ci  lineoffset = (8 * lineoffset) / regs[0x7a];
5799141cc406Sopenharmony_ci  linetotal = (8 * linetotal) / regs[0x7a];
5800141cc406Sopenharmony_ci
5801141cc406Sopenharmony_ci  data = (SANE_Byte *) malloc (bpl * lines);
5802141cc406Sopenharmony_ci  DBG (7, "pixels=%d, lines=%d, size=%d\n", pixels, lines, bpl * lines);
5803141cc406Sopenharmony_ci  if (data == NULL)
5804141cc406Sopenharmony_ci    {
5805141cc406Sopenharmony_ci      DBG (2,
5806141cc406Sopenharmony_ci	   "sanei_lexmark_low_shading_calibration: failed to allocate %d bytes !\n",
5807141cc406Sopenharmony_ci	   bpl * lines);
5808141cc406Sopenharmony_ci      return SANE_STATUS_NO_MEM;
5809141cc406Sopenharmony_ci    }
5810141cc406Sopenharmony_ci  if (dev->shading_coeff != NULL)
5811141cc406Sopenharmony_ci    free (dev->shading_coeff);
5812141cc406Sopenharmony_ci  dev->shading_coeff = (float *) malloc (bpl * sizeof (float));
5813141cc406Sopenharmony_ci  if (dev->shading_coeff == NULL)
5814141cc406Sopenharmony_ci    {
5815141cc406Sopenharmony_ci      DBG (2,
5816141cc406Sopenharmony_ci	   "sanei_lexmark_low_shading_calibration: failed to allocate %d floats !\n",
5817141cc406Sopenharmony_ci	   bpl);
5818141cc406Sopenharmony_ci      free (data);
5819141cc406Sopenharmony_ci      return SANE_STATUS_NO_MEM;
5820141cc406Sopenharmony_ci    }
5821141cc406Sopenharmony_ci
5822141cc406Sopenharmony_ci  /* we set movement bit this time */
5823141cc406Sopenharmony_ci  regs[0xc3] = regs[0xc3] | 0x80;
5824141cc406Sopenharmony_ci
5825141cc406Sopenharmony_ci  /* execute scan */
5826141cc406Sopenharmony_ci  status = low_simple_scan (dev, regs, sx, pixels, lineoffset, lines, &data);
5827141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
5828141cc406Sopenharmony_ci    {
5829141cc406Sopenharmony_ci      DBG (1,
5830141cc406Sopenharmony_ci	   "sanei_lexmark_low_shading_calibration: low_simple_scan failed!\n");
5831141cc406Sopenharmony_ci      if (data != NULL)
5832141cc406Sopenharmony_ci	free (data);
5833141cc406Sopenharmony_ci      return status;
5834141cc406Sopenharmony_ci    }
5835141cc406Sopenharmony_ci
5836141cc406Sopenharmony_ci  yoffset = -1;
5837141cc406Sopenharmony_ci  /* the very first lines of the scan may include the dark dot used
5838141cc406Sopenharmony_ci   * locate park position. We find the first line free of it in the scan.
5839141cc406Sopenharmony_ci   * We can't use is_home_line since it modifies data.
5840141cc406Sopenharmony_ci   */
5841141cc406Sopenharmony_ci  for (y = 0; (y < lines) && (yoffset == y - 1); y++)
5842141cc406Sopenharmony_ci    {
5843141cc406Sopenharmony_ci      if (rts88xx_is_color (regs))
5844141cc406Sopenharmony_ci	{
5845141cc406Sopenharmony_ci	  for (x = 0; x < 3 * pixels; x++)
5846141cc406Sopenharmony_ci	    {
5847141cc406Sopenharmony_ci	      if (data[x + y * 3 * pixels] < 30)
5848141cc406Sopenharmony_ci		yoffset = y;
5849141cc406Sopenharmony_ci	    }
5850141cc406Sopenharmony_ci	}
5851141cc406Sopenharmony_ci      else
5852141cc406Sopenharmony_ci	{
5853141cc406Sopenharmony_ci	  for (x = 0; x < pixels; x++)
5854141cc406Sopenharmony_ci	    {
5855141cc406Sopenharmony_ci	      if (data[x + y * pixels] < 30)
5856141cc406Sopenharmony_ci		yoffset = y;
5857141cc406Sopenharmony_ci	    }
5858141cc406Sopenharmony_ci	}
5859141cc406Sopenharmony_ci    }
5860141cc406Sopenharmony_ci  /* make sure we are really out of the dot */
5861141cc406Sopenharmony_ci  yoffset++;
5862141cc406Sopenharmony_ci
5863141cc406Sopenharmony_ci  /* yoffset is index of last dot line, go to first white line */
5864141cc406Sopenharmony_ci  if (yoffset >= lines - 1)
5865141cc406Sopenharmony_ci    {
5866141cc406Sopenharmony_ci      DBG (7,
5867141cc406Sopenharmony_ci	   "sanei_lexmark_low_shading_calibration: failed to detect yoffset.\n");
5868141cc406Sopenharmony_ci      /* fail safe fallback, picture will be altered at dot position,
5869141cc406Sopenharmony_ci         but scanner is safe */
5870141cc406Sopenharmony_ci      yoffset = lines - 2;
5871141cc406Sopenharmony_ci    }
5872141cc406Sopenharmony_ci  else
5873141cc406Sopenharmony_ci    yoffset++;
5874141cc406Sopenharmony_ci  DBG (7, "sanei_lexmark_low_shading_calibration: yoffset=%d.\n", yoffset);
5875141cc406Sopenharmony_ci
5876141cc406Sopenharmony_ci#ifdef DEEP_DEBUG
5877141cc406Sopenharmony_ci  write_pnm_file ("shading.pnm", pixels, lines, rts88xx_is_color (regs),
5878141cc406Sopenharmony_ci		  data);
5879141cc406Sopenharmony_ci#endif
5880141cc406Sopenharmony_ci
5881141cc406Sopenharmony_ci  /* computes coefficients */
5882141cc406Sopenharmony_ci  /* there are 8 lines usable for shading calibration at 150 dpi, between
5883141cc406Sopenharmony_ci     bottom of "home position" dot and the start of the scanner's window
5884141cc406Sopenharmony_ci     assembly, we only use 7 of them */
5885141cc406Sopenharmony_ci  if (yoffset + (8 * 4) / regs[0x7a] < lines)
5886141cc406Sopenharmony_ci    lines = yoffset + (8 * 4) / regs[0x7a];
5887141cc406Sopenharmony_ci  rtarget = dev->sensor->red_shading_target;
5888141cc406Sopenharmony_ci  gtarget = dev->sensor->green_shading_target;
5889141cc406Sopenharmony_ci  btarget = dev->sensor->blue_shading_target;
5890141cc406Sopenharmony_ci  for (i = 0; i < pixels; i++)
5891141cc406Sopenharmony_ci    {
5892141cc406Sopenharmony_ci      /* we computes the coefficient needed to move the scanned value to
5893141cc406Sopenharmony_ci         the target value */
5894141cc406Sopenharmony_ci      if (rts88xx_is_color (dev->shadow_regs))
5895141cc406Sopenharmony_ci	{
5896141cc406Sopenharmony_ci	  /* RED */
5897141cc406Sopenharmony_ci	  dev->shading_coeff[i] = 0;
5898141cc406Sopenharmony_ci	  for (j = yoffset; j < lines; j++)
5899141cc406Sopenharmony_ci	    dev->shading_coeff[i] += data[i + j * bpl];
5900141cc406Sopenharmony_ci	  dev->shading_coeff[i] =
5901141cc406Sopenharmony_ci	    (rtarget / (dev->shading_coeff[i] / (lines - yoffset)));
5902141cc406Sopenharmony_ci
5903141cc406Sopenharmony_ci	  /* GREEN */
5904141cc406Sopenharmony_ci	  dev->shading_coeff[i + pixels] = 0;
5905141cc406Sopenharmony_ci	  for (j = yoffset; j < lines; j++)
5906141cc406Sopenharmony_ci	    dev->shading_coeff[i + pixels] += data[i + j * bpl + pixels];
5907141cc406Sopenharmony_ci	  dev->shading_coeff[i + pixels] =
5908141cc406Sopenharmony_ci	    ((gtarget / dev->shading_coeff[i + pixels]) * (lines - yoffset));
5909141cc406Sopenharmony_ci
5910141cc406Sopenharmony_ci	  /* BLUE */
5911141cc406Sopenharmony_ci	  dev->shading_coeff[i + 2 * pixels] = 0;
5912141cc406Sopenharmony_ci	  for (j = yoffset; j < lines; j++)
5913141cc406Sopenharmony_ci	    dev->shading_coeff[i + 2 * pixels] +=
5914141cc406Sopenharmony_ci	      data[i + j * bpl + 2 * pixels];
5915141cc406Sopenharmony_ci	  dev->shading_coeff[i + 2 * pixels] =
5916141cc406Sopenharmony_ci	    ((btarget / dev->shading_coeff[i + 2 * pixels]) *
5917141cc406Sopenharmony_ci	     (lines - yoffset));
5918141cc406Sopenharmony_ci	}
5919141cc406Sopenharmony_ci      else
5920141cc406Sopenharmony_ci	{
5921141cc406Sopenharmony_ci	  dev->shading_coeff[i] = 0;
5922141cc406Sopenharmony_ci	  for (j = yoffset; j < lines; j++)
5923141cc406Sopenharmony_ci	    {
5924141cc406Sopenharmony_ci	      dev->shading_coeff[i] += data[i + j * bpl];
5925141cc406Sopenharmony_ci	    }
5926141cc406Sopenharmony_ci	  dev->shading_coeff[i] =
5927141cc406Sopenharmony_ci	    (rtarget / dev->shading_coeff[i]) * (lines - yoffset);
5928141cc406Sopenharmony_ci	}
5929141cc406Sopenharmony_ci    }
5930141cc406Sopenharmony_ci  free(data);
5931141cc406Sopenharmony_ci
5932141cc406Sopenharmony_ci  /* do the scan backward to go back to start position */
5933141cc406Sopenharmony_ci  regs[0xc6] &= 0xF7;
5934141cc406Sopenharmony_ci  lines = (8 * 8) / regs[0x7a];
5935141cc406Sopenharmony_ci  /* it should use linetotal to account for the lineoffset */
5936141cc406Sopenharmony_ci  if (dev->model.sensor_type == X74_SENSOR)
5937141cc406Sopenharmony_ci    lines = linetotal;
5938141cc406Sopenharmony_ci
5939141cc406Sopenharmony_ci  /* execute scan */
5940141cc406Sopenharmony_ci  status = low_simple_scan (dev, regs, sx, pixels, 1, lines, &data);
5941141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
5942141cc406Sopenharmony_ci    {
5943141cc406Sopenharmony_ci      DBG (1,
5944141cc406Sopenharmony_ci	   "sanei_lexmark_low_shading_calibration: low_simple_scan failed!\n");
5945141cc406Sopenharmony_ci      if(data!=NULL)
5946141cc406Sopenharmony_ci	free(data);
5947141cc406Sopenharmony_ci      return status;
5948141cc406Sopenharmony_ci    }
5949141cc406Sopenharmony_ci
5950141cc406Sopenharmony_ci#ifdef DEEP_DEBUG
5951141cc406Sopenharmony_ci  write_pnm_file ("shading_bwd.pnm", pixels, lines, rts88xx_is_color (regs),
5952141cc406Sopenharmony_ci		  data);
5953141cc406Sopenharmony_ci#endif
5954141cc406Sopenharmony_ci  free (data);
5955141cc406Sopenharmony_ci
5956141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_shading_calibration: end.\n");
5957141cc406Sopenharmony_ci  return status;
5958141cc406Sopenharmony_ci}
5959141cc406Sopenharmony_ci
5960141cc406Sopenharmony_ci
5961141cc406Sopenharmony_ciSANE_Status
5962141cc406Sopenharmony_cisanei_lexmark_low_calibration (Lexmark_Device * dev)
5963141cc406Sopenharmony_ci{
5964141cc406Sopenharmony_ci  SANE_Status status;
5965141cc406Sopenharmony_ci
5966141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_calibration: start.\n");
5967141cc406Sopenharmony_ci  status = sanei_lexmark_low_offset_calibration (dev);
5968141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
5969141cc406Sopenharmony_ci    return status;
5970141cc406Sopenharmony_ci
5971141cc406Sopenharmony_ci  /* we put the offset just computed in scanning regs */
5972141cc406Sopenharmony_ci  if (rts88xx_is_color (dev->shadow_regs))
5973141cc406Sopenharmony_ci    {
5974141cc406Sopenharmony_ci      rts88xx_set_offset (dev->shadow_regs,
5975141cc406Sopenharmony_ci			  dev->offset.red,
5976141cc406Sopenharmony_ci			  dev->offset.green, dev->offset.blue);
5977141cc406Sopenharmony_ci    }
5978141cc406Sopenharmony_ci  else
5979141cc406Sopenharmony_ci    {
5980141cc406Sopenharmony_ci      rts88xx_set_offset (dev->shadow_regs,
5981141cc406Sopenharmony_ci			  dev->offset.gray,
5982141cc406Sopenharmony_ci			  dev->offset.gray, dev->offset.gray);
5983141cc406Sopenharmony_ci    }
5984141cc406Sopenharmony_ci
5985141cc406Sopenharmony_ci  /* if manual gain settings, no gain calibration */
5986141cc406Sopenharmony_ci  if (dev->val[OPT_MANUAL_GAIN].w == SANE_TRUE)
5987141cc406Sopenharmony_ci    {
5988141cc406Sopenharmony_ci      if (rts88xx_is_color (dev->shadow_regs))
5989141cc406Sopenharmony_ci	{
5990141cc406Sopenharmony_ci	  dev->gain.red = dev->val[OPT_RED_GAIN].w;
5991141cc406Sopenharmony_ci	  dev->gain.green = dev->val[OPT_GREEN_GAIN].w;
5992141cc406Sopenharmony_ci	  dev->gain.blue = dev->val[OPT_BLUE_GAIN].w;
5993141cc406Sopenharmony_ci	}
5994141cc406Sopenharmony_ci      else
5995141cc406Sopenharmony_ci	dev->gain.gray = dev->val[OPT_GRAY_GAIN].w;
5996141cc406Sopenharmony_ci    }
5997141cc406Sopenharmony_ci  else
5998141cc406Sopenharmony_ci    {
5999141cc406Sopenharmony_ci      status = sanei_lexmark_low_gain_calibration (dev);
6000141cc406Sopenharmony_ci      if (status != SANE_STATUS_GOOD)
6001141cc406Sopenharmony_ci	return status;
6002141cc406Sopenharmony_ci    }
6003141cc406Sopenharmony_ci
6004141cc406Sopenharmony_ci  /* put the calibrated or manual settings before shading calibration
6005141cc406Sopenharmony_ci     which must be done with final setting values */
6006141cc406Sopenharmony_ci  if (rts88xx_is_color (dev->shadow_regs))
6007141cc406Sopenharmony_ci    {
6008141cc406Sopenharmony_ci      rts88xx_set_gain (dev->shadow_regs, dev->gain.red, dev->gain.green,
6009141cc406Sopenharmony_ci			dev->gain.blue);
6010141cc406Sopenharmony_ci    }
6011141cc406Sopenharmony_ci  else
6012141cc406Sopenharmony_ci    {
6013141cc406Sopenharmony_ci      rts88xx_set_gain (dev->shadow_regs, dev->gain.gray, dev->gain.gray,
6014141cc406Sopenharmony_ci			dev->gain.gray);
6015141cc406Sopenharmony_ci    }
6016141cc406Sopenharmony_ci
6017141cc406Sopenharmony_ci  status = sanei_lexmark_low_shading_calibration (dev);
6018141cc406Sopenharmony_ci
6019141cc406Sopenharmony_ci  if (status != SANE_STATUS_GOOD)
6020141cc406Sopenharmony_ci    return status;
6021141cc406Sopenharmony_ci
6022141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_calibration: end.\n");
6023141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
6024141cc406Sopenharmony_ci}
6025141cc406Sopenharmony_ci
6026141cc406Sopenharmony_ci/* assign sensor data */
6027141cc406Sopenharmony_cistatic SANE_Status
6028141cc406Sopenharmony_cisanei_lexmark_low_assign_sensor (Lexmark_Device * dev)
6029141cc406Sopenharmony_ci{
6030141cc406Sopenharmony_ci  int dn;
6031141cc406Sopenharmony_ci
6032141cc406Sopenharmony_ci  /* init sensor data */
6033141cc406Sopenharmony_ci  dn = 0;
6034141cc406Sopenharmony_ci  while (sensor_list[dn].id != 0
6035141cc406Sopenharmony_ci	 && sensor_list[dn].id != dev->model.sensor_type)
6036141cc406Sopenharmony_ci    dn++;
6037141cc406Sopenharmony_ci  if (sensor_list[dn].id == 0)
6038141cc406Sopenharmony_ci    {
6039141cc406Sopenharmony_ci      DBG (1,
6040141cc406Sopenharmony_ci	   "sanei_lexmark_low_assign_sensor: unknown sensor %d\n",
6041141cc406Sopenharmony_ci	   dev->model.sensor_type);
6042141cc406Sopenharmony_ci      return SANE_STATUS_UNSUPPORTED;
6043141cc406Sopenharmony_ci    }
6044141cc406Sopenharmony_ci  dev->sensor = &(sensor_list[dn]);
6045141cc406Sopenharmony_ci  DBG (1, "sanei_lexmark_low_assign_sensor: assigned sensor number %d\n",
6046141cc406Sopenharmony_ci       dev->model.sensor_type);
6047141cc406Sopenharmony_ci  return SANE_STATUS_GOOD;
6048141cc406Sopenharmony_ci}
6049141cc406Sopenharmony_ci
6050141cc406Sopenharmony_ci/* assign model description, based on USB id, and register content when
6051141cc406Sopenharmony_ci * available */
6052141cc406Sopenharmony_ciSANE_Status
6053141cc406Sopenharmony_cisanei_lexmark_low_assign_model (Lexmark_Device * dev,
6054141cc406Sopenharmony_ci				SANE_String_Const devname, SANE_Int vendor,
6055141cc406Sopenharmony_ci				SANE_Int product, SANE_Byte mainboard)
6056141cc406Sopenharmony_ci{
6057141cc406Sopenharmony_ci  int dn;
6058141cc406Sopenharmony_ci  SANE_Bool found = SANE_FALSE;
6059141cc406Sopenharmony_ci
6060141cc406Sopenharmony_ci  DBG_INIT ();
6061141cc406Sopenharmony_ci
6062141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_assign_model: start\n");
6063141cc406Sopenharmony_ci  DBG (3,
6064141cc406Sopenharmony_ci       "sanei_lexmark_low_assign_model: assigning %04x:%04x, variant %d\n",
6065141cc406Sopenharmony_ci       vendor, product, mainboard);
6066141cc406Sopenharmony_ci
6067141cc406Sopenharmony_ci  dn = 0;
6068141cc406Sopenharmony_ci  /* walk the list of known devices */
6069141cc406Sopenharmony_ci  while (!found && model_list[dn].vendor_id != 0)
6070141cc406Sopenharmony_ci    {
6071141cc406Sopenharmony_ci      /* no mainboard id given (at attach time) */
6072141cc406Sopenharmony_ci      if (mainboard == 0
6073141cc406Sopenharmony_ci	  && vendor == model_list[dn].vendor_id
6074141cc406Sopenharmony_ci	  && product == model_list[dn].product_id)
6075141cc406Sopenharmony_ci	found = SANE_TRUE;
6076141cc406Sopenharmony_ci      /* mainboard given (init time) */
6077141cc406Sopenharmony_ci      if (mainboard != 0
6078141cc406Sopenharmony_ci	  && mainboard == model_list[dn].mainboard_id
6079141cc406Sopenharmony_ci	  && vendor == model_list[dn].vendor_id
6080141cc406Sopenharmony_ci	  && product == model_list[dn].product_id)
6081141cc406Sopenharmony_ci	found = SANE_TRUE;
6082141cc406Sopenharmony_ci
6083141cc406Sopenharmony_ci      if (!found)
6084141cc406Sopenharmony_ci	dn++;
6085141cc406Sopenharmony_ci    }
6086141cc406Sopenharmony_ci
6087141cc406Sopenharmony_ci  /* we hit the end of list, so we don't know about the current model */
6088141cc406Sopenharmony_ci  if (!found)
6089141cc406Sopenharmony_ci    {
6090141cc406Sopenharmony_ci      DBG (1,
6091141cc406Sopenharmony_ci	   "sanei_lexmark_low_assign_model: unknown device 0x%04x:0x%04x\n",
6092141cc406Sopenharmony_ci	   vendor, product);
6093141cc406Sopenharmony_ci      return SANE_STATUS_UNSUPPORTED;
6094141cc406Sopenharmony_ci    }
6095141cc406Sopenharmony_ci
6096141cc406Sopenharmony_ci  dev->sane.name = strdup (devname);
6097141cc406Sopenharmony_ci  dev->sane.vendor = model_list[dn].vendor;
6098141cc406Sopenharmony_ci  dev->sane.model = model_list[dn].model;
6099141cc406Sopenharmony_ci  dev->model = model_list[dn];
6100141cc406Sopenharmony_ci  dev->sane.type = "flatbed scanner";
6101141cc406Sopenharmony_ci
6102141cc406Sopenharmony_ci  DBG (3, "sanei_lexmark_low_assign_model: assigned %s\n", dev->model.model);
6103141cc406Sopenharmony_ci
6104141cc406Sopenharmony_ci  /* init sensor data */
6105141cc406Sopenharmony_ci  DBG (2, "sanei_lexmark_low_assign_model: end.\n");
6106141cc406Sopenharmony_ci  return sanei_lexmark_low_assign_sensor (dev);
6107141cc406Sopenharmony_ci}
6108