1141cc406Sopenharmony_ci/* sane - Scanner Access Now Easy.
2141cc406Sopenharmony_ci   Copyright (C) 2001-2012 Stéphane Voltz <stef.dev@free.fr>
3141cc406Sopenharmony_ci   This file is part of the SANE package.
4141cc406Sopenharmony_ci
5141cc406Sopenharmony_ci   This program is free software; you can redistribute it and/or
6141cc406Sopenharmony_ci   modify it under the terms of the GNU General Public License as
7141cc406Sopenharmony_ci   published by the Free Software Foundation; either version 2 of the
8141cc406Sopenharmony_ci   License, or (at your option) any later version.
9141cc406Sopenharmony_ci
10141cc406Sopenharmony_ci   This program is distributed in the hope that it will be useful, but
11141cc406Sopenharmony_ci   WITHOUT ANY WARRANTY; without even the implied warranty of
12141cc406Sopenharmony_ci   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13141cc406Sopenharmony_ci   General Public License for more details.
14141cc406Sopenharmony_ci
15141cc406Sopenharmony_ci   You should have received a copy of the GNU General Public License
16141cc406Sopenharmony_ci   along with this program.  If not, see <https://www.gnu.org/licenses/>.
17141cc406Sopenharmony_ci
18141cc406Sopenharmony_ci   As a special exception, the authors of SANE give permission for
19141cc406Sopenharmony_ci   additional uses of the libraries contained in this release of SANE.
20141cc406Sopenharmony_ci
21141cc406Sopenharmony_ci   The exception is that, if you link a SANE library with other files
22141cc406Sopenharmony_ci   to produce an executable, this does not by itself cause the
23141cc406Sopenharmony_ci   resulting executable to be covered by the GNU General Public
24141cc406Sopenharmony_ci   License.  Your use of that executable is in no way restricted on
25141cc406Sopenharmony_ci   account of linking the SANE library code into it.
26141cc406Sopenharmony_ci
27141cc406Sopenharmony_ci   This exception does not, however, invalidate any other reasons why
28141cc406Sopenharmony_ci   the executable file might be covered by the GNU General Public
29141cc406Sopenharmony_ci   License.
30141cc406Sopenharmony_ci
31141cc406Sopenharmony_ci   If you submit changes to SANE to the maintainers to be included in
32141cc406Sopenharmony_ci   a subsequent release, you agree by submitting the changes that
33141cc406Sopenharmony_ci   those changes may be distributed with this exception intact.
34141cc406Sopenharmony_ci
35141cc406Sopenharmony_ci   If you write modifications of your own for SANE, it is your choice
36141cc406Sopenharmony_ci   whether to permit this exception to apply to your modifications.
37141cc406Sopenharmony_ci   If you do not wish that, delete this exception notice.
38141cc406Sopenharmony_ci
39141cc406Sopenharmony_ci   This file implements a SANE backend for Umax PP flatbed scanners.  */
40141cc406Sopenharmony_ci
41141cc406Sopenharmony_ci#define DEBUG_DECLARE_ONLY
42141cc406Sopenharmony_ci#undef BACKEND_NAME
43141cc406Sopenharmony_ci#define BACKEND_NAME umax_pp
44141cc406Sopenharmony_ci
45141cc406Sopenharmony_ci#include "../include/sane/config.h"
46141cc406Sopenharmony_ci#include <stdlib.h>
47141cc406Sopenharmony_ci#include <string.h>
48141cc406Sopenharmony_ci#ifdef HAVE_UNISTD_H
49141cc406Sopenharmony_ci#include <unistd.h>
50141cc406Sopenharmony_ci#endif
51141cc406Sopenharmony_ci#include <stdio.h>
52141cc406Sopenharmony_ci#include "../include/sane/sanei_debug.h"
53141cc406Sopenharmony_ci
54141cc406Sopenharmony_ci#define __MAIN__
55141cc406Sopenharmony_ci
56141cc406Sopenharmony_ci
57141cc406Sopenharmony_ci#include "umax_pp_mid.h"
58141cc406Sopenharmony_ci
59141cc406Sopenharmony_ci/* this function locks the parallel port so that other devices */
60141cc406Sopenharmony_ci/* won't interfere. Returns UMAX1220P_BUSY is port cannot be   */
61141cc406Sopenharmony_ci/* lock or UMAX1220P_OK if it is locked                        */
62141cc406Sopenharmony_cistatic int locked = 0;
63141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H
64141cc406Sopenharmony_cistatic int exmode = IEEE1284_MODE_COMPAT;
65141cc406Sopenharmony_cistatic int exflags = 0;
66141cc406Sopenharmony_ci#endif
67141cc406Sopenharmony_ci
68141cc406Sopenharmony_cistatic int
69141cc406Sopenharmony_cilock_parport (void)
70141cc406Sopenharmony_ci{
71141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H
72141cc406Sopenharmony_ci  int mode, fd;
73141cc406Sopenharmony_ci#endif
74141cc406Sopenharmony_ci
75141cc406Sopenharmony_ci  DBG_INIT ();
76141cc406Sopenharmony_ci  DBG (3, "lock_parport\n");
77141cc406Sopenharmony_ci
78141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H
79141cc406Sopenharmony_ci  fd = sanei_umax_pp_getparport ();
80141cc406Sopenharmony_ci  if ((fd > 0) && (!locked))
81141cc406Sopenharmony_ci    {
82141cc406Sopenharmony_ci      if (ioctl (sanei_umax_pp_getparport (), PPCLAIM))
83141cc406Sopenharmony_ci        {
84141cc406Sopenharmony_ci          return UMAX1220P_BUSY;
85141cc406Sopenharmony_ci        }
86141cc406Sopenharmony_ci#ifdef PPGETMODE
87141cc406Sopenharmony_ci      if (ioctl (fd, PPGETMODE, &exmode))
88141cc406Sopenharmony_ci        exmode = IEEE1284_MODE_COMPAT;
89141cc406Sopenharmony_ci      if (ioctl (fd, PPGETFLAGS, &exflags))
90141cc406Sopenharmony_ci        exflags = 0;
91141cc406Sopenharmony_ci#endif
92141cc406Sopenharmony_ci      mode = IEEE1284_MODE_EPP;
93141cc406Sopenharmony_ci      ioctl (fd, PPNEGOT, &mode);
94141cc406Sopenharmony_ci      ioctl (fd, PPSETMODE, &mode);
95141cc406Sopenharmony_ci      locked = 1;
96141cc406Sopenharmony_ci    }
97141cc406Sopenharmony_ci#else
98141cc406Sopenharmony_ci  locked = 1;
99141cc406Sopenharmony_ci#endif
100141cc406Sopenharmony_ci  return UMAX1220P_OK;
101141cc406Sopenharmony_ci}
102141cc406Sopenharmony_ci
103141cc406Sopenharmony_ci
104141cc406Sopenharmony_ci/* this function release parport */
105141cc406Sopenharmony_cistatic int
106141cc406Sopenharmony_ciunlock_parport (void)
107141cc406Sopenharmony_ci{
108141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H
109141cc406Sopenharmony_ci  int fd, mode;
110141cc406Sopenharmony_ci
111141cc406Sopenharmony_ci  fd = sanei_umax_pp_getparport ();
112141cc406Sopenharmony_ci  if ((fd > 0) && (locked))
113141cc406Sopenharmony_ci    {
114141cc406Sopenharmony_ci      mode = IEEE1284_MODE_COMPAT;
115141cc406Sopenharmony_ci      ioctl (fd, PPNEGOT, &mode);
116141cc406Sopenharmony_ci      ioctl (fd, PPSETMODE, &exmode);
117141cc406Sopenharmony_ci#ifdef PPSETFLAGS
118141cc406Sopenharmony_ci      ioctl (fd, PPSETFLAGS, &exflags);
119141cc406Sopenharmony_ci#endif
120141cc406Sopenharmony_ci      ioctl (fd, PPRELEASE);
121141cc406Sopenharmony_ci      locked = 1;
122141cc406Sopenharmony_ci    }
123141cc406Sopenharmony_ci#endif
124141cc406Sopenharmony_ci  DBG (3, "unlock_parport\n");
125141cc406Sopenharmony_ci  locked = 0;
126141cc406Sopenharmony_ci  return UMAX1220P_OK;
127141cc406Sopenharmony_ci}
128141cc406Sopenharmony_ci
129141cc406Sopenharmony_ci
130141cc406Sopenharmony_ci
131141cc406Sopenharmony_ci
132141cc406Sopenharmony_ci/*
133141cc406Sopenharmony_ci *
134141cc406Sopenharmony_ci *  This function recognize the scanner model by sending an image
135141cc406Sopenharmony_ci * filter command. 1220P will use it as is, but 2000P will return
136141cc406Sopenharmony_ci * it back modified.
137141cc406Sopenharmony_ci *
138141cc406Sopenharmony_ci */
139141cc406Sopenharmony_ciint
140141cc406Sopenharmony_cisanei_umax_pp_model (int port, int *model)
141141cc406Sopenharmony_ci{
142141cc406Sopenharmony_ci  int recover = 0, rc;
143141cc406Sopenharmony_ci
144141cc406Sopenharmony_ci  /* set up port */
145141cc406Sopenharmony_ci  DBG (3, "sanei_umax_pp_model\n");
146141cc406Sopenharmony_ci  sanei_umax_pp_setport (port);
147141cc406Sopenharmony_ci  if (lock_parport () == UMAX1220P_BUSY)
148141cc406Sopenharmony_ci    return UMAX1220P_BUSY;
149141cc406Sopenharmony_ci
150141cc406Sopenharmony_ci  /* init transport layer */
151141cc406Sopenharmony_ci  /* 0: failed
152141cc406Sopenharmony_ci     1: success
153141cc406Sopenharmony_ci     2: retry
154141cc406Sopenharmony_ci     3: busy
155141cc406Sopenharmony_ci   */
156141cc406Sopenharmony_ci  do
157141cc406Sopenharmony_ci    {
158141cc406Sopenharmony_ci      rc = sanei_umax_pp_initTransport (recover);
159141cc406Sopenharmony_ci    }
160141cc406Sopenharmony_ci  while (rc == 2);
161141cc406Sopenharmony_ci
162141cc406Sopenharmony_ci  if (rc == 3)
163141cc406Sopenharmony_ci    {
164141cc406Sopenharmony_ci      unlock_parport ();
165141cc406Sopenharmony_ci      return UMAX1220P_BUSY;
166141cc406Sopenharmony_ci    }
167141cc406Sopenharmony_ci  if (rc != 1)
168141cc406Sopenharmony_ci    {
169141cc406Sopenharmony_ci      DBG (0, "sanei_umax_pp_initTransport() failed (%s:%d)\n", __FILE__,
170141cc406Sopenharmony_ci           __LINE__);
171141cc406Sopenharmony_ci      unlock_parport ();
172141cc406Sopenharmony_ci      return UMAX1220P_TRANSPORT_FAILED;
173141cc406Sopenharmony_ci    }
174141cc406Sopenharmony_ci
175141cc406Sopenharmony_ci  /* check model only, and if only none given in conf file */
176141cc406Sopenharmony_ci  if (!sanei_umax_pp_getastra ())
177141cc406Sopenharmony_ci    {
178141cc406Sopenharmony_ci      rc = sanei_umax_pp_checkModel ();
179141cc406Sopenharmony_ci    }
180141cc406Sopenharmony_ci  else
181141cc406Sopenharmony_ci    {
182141cc406Sopenharmony_ci      rc = sanei_umax_pp_getastra ();
183141cc406Sopenharmony_ci    }
184141cc406Sopenharmony_ci  sanei_umax_pp_endSession ();
185141cc406Sopenharmony_ci  unlock_parport ();
186141cc406Sopenharmony_ci  if (rc < 600)
187141cc406Sopenharmony_ci    {
188141cc406Sopenharmony_ci      DBG (0, "sanei_umax_pp_CheckModel() failed (%s:%d)\n", __FILE__,
189141cc406Sopenharmony_ci           __LINE__);
190141cc406Sopenharmony_ci      return UMAX1220P_PROBE_FAILED;
191141cc406Sopenharmony_ci    }
192141cc406Sopenharmony_ci  *model = rc;
193141cc406Sopenharmony_ci
194141cc406Sopenharmony_ci
195141cc406Sopenharmony_ci  /* OK */
196141cc406Sopenharmony_ci  return UMAX1220P_OK;
197141cc406Sopenharmony_ci}
198141cc406Sopenharmony_ci
199141cc406Sopenharmony_ciint
200141cc406Sopenharmony_cisanei_umax_pp_attach (int port, const char *name)
201141cc406Sopenharmony_ci{
202141cc406Sopenharmony_ci  int recover = 0;
203141cc406Sopenharmony_ci
204141cc406Sopenharmony_ci  /* set up port */
205141cc406Sopenharmony_ci  if (name == NULL)
206141cc406Sopenharmony_ci    {
207141cc406Sopenharmony_ci      DBG (3, "sanei_umax_pp_attach(%d,NULL)\n", port);
208141cc406Sopenharmony_ci    }
209141cc406Sopenharmony_ci  else
210141cc406Sopenharmony_ci    {
211141cc406Sopenharmony_ci      DBG (3, "sanei_umax_pp_attach(%d,%s)\n", port, name);
212141cc406Sopenharmony_ci    }
213141cc406Sopenharmony_ci
214141cc406Sopenharmony_ci  sanei_umax_pp_setport (port);
215141cc406Sopenharmony_ci  if (sanei_umax_pp_initPort (port, name) != 1)
216141cc406Sopenharmony_ci    return UMAX1220P_PROBE_FAILED;
217141cc406Sopenharmony_ci
218141cc406Sopenharmony_ci  /* init port locks the port, so we flag that */
219141cc406Sopenharmony_ci  locked = 1;
220141cc406Sopenharmony_ci
221141cc406Sopenharmony_ci  if (sanei_umax_pp_probeScanner (recover) != 1)
222141cc406Sopenharmony_ci    {
223141cc406Sopenharmony_ci      if (recover)
224141cc406Sopenharmony_ci        {
225141cc406Sopenharmony_ci          sanei_umax_pp_initTransport (recover);
226141cc406Sopenharmony_ci          sanei_umax_pp_endSession ();
227141cc406Sopenharmony_ci          if (sanei_umax_pp_probeScanner (recover) != 1)
228141cc406Sopenharmony_ci            {
229141cc406Sopenharmony_ci              DBG (0, "Recover failed ....\n");
230141cc406Sopenharmony_ci              unlock_parport ();
231141cc406Sopenharmony_ci              return UMAX1220P_PROBE_FAILED;
232141cc406Sopenharmony_ci            }
233141cc406Sopenharmony_ci        }
234141cc406Sopenharmony_ci      else
235141cc406Sopenharmony_ci        {
236141cc406Sopenharmony_ci          unlock_parport ();
237141cc406Sopenharmony_ci          return UMAX1220P_PROBE_FAILED;
238141cc406Sopenharmony_ci        }
239141cc406Sopenharmony_ci    }
240141cc406Sopenharmony_ci  sanei_umax_pp_endSession ();
241141cc406Sopenharmony_ci  unlock_parport ();
242141cc406Sopenharmony_ci
243141cc406Sopenharmony_ci
244141cc406Sopenharmony_ci  /* OK */
245141cc406Sopenharmony_ci  return UMAX1220P_OK;
246141cc406Sopenharmony_ci}
247141cc406Sopenharmony_ci
248141cc406Sopenharmony_ci
249141cc406Sopenharmony_ciint
250141cc406Sopenharmony_cisanei_umax_pp_open (int port, char *name)
251141cc406Sopenharmony_ci{
252141cc406Sopenharmony_ci  int rc;
253141cc406Sopenharmony_ci  int recover = 0;
254141cc406Sopenharmony_ci
255141cc406Sopenharmony_ci  /* set up port */
256141cc406Sopenharmony_ci  DBG (3, "sanei_umax_pp_open\n");
257141cc406Sopenharmony_ci
258141cc406Sopenharmony_ci  if (name == NULL)
259141cc406Sopenharmony_ci    sanei_umax_pp_setport (port);
260141cc406Sopenharmony_ci
261141cc406Sopenharmony_ci  if (lock_parport () == UMAX1220P_BUSY)
262141cc406Sopenharmony_ci    return UMAX1220P_BUSY;
263141cc406Sopenharmony_ci
264141cc406Sopenharmony_ci  /* init transport layer */
265141cc406Sopenharmony_ci  /* 0: failed
266141cc406Sopenharmony_ci     1: success
267141cc406Sopenharmony_ci     2: retry
268141cc406Sopenharmony_ci     3: scanner busy
269141cc406Sopenharmony_ci   */
270141cc406Sopenharmony_ci  do
271141cc406Sopenharmony_ci    {
272141cc406Sopenharmony_ci      rc = sanei_umax_pp_initTransport (recover);
273141cc406Sopenharmony_ci    }
274141cc406Sopenharmony_ci  while (rc == 2);
275141cc406Sopenharmony_ci
276141cc406Sopenharmony_ci  if (rc == 3)
277141cc406Sopenharmony_ci    {
278141cc406Sopenharmony_ci      unlock_parport ();
279141cc406Sopenharmony_ci      return UMAX1220P_BUSY;
280141cc406Sopenharmony_ci    }
281141cc406Sopenharmony_ci
282141cc406Sopenharmony_ci  if (rc != 1)
283141cc406Sopenharmony_ci    {
284141cc406Sopenharmony_ci
285141cc406Sopenharmony_ci      DBG (0, "sanei_umax_pp_initTransport() failed (%s:%d)\n", __FILE__,
286141cc406Sopenharmony_ci           __LINE__);
287141cc406Sopenharmony_ci      unlock_parport ();
288141cc406Sopenharmony_ci      return UMAX1220P_TRANSPORT_FAILED;
289141cc406Sopenharmony_ci    }
290141cc406Sopenharmony_ci  /* init scanner */
291141cc406Sopenharmony_ci  if (sanei_umax_pp_initScanner (recover) == 0)
292141cc406Sopenharmony_ci    {
293141cc406Sopenharmony_ci      DBG (0, "sanei_umax_pp_initScanner() failed (%s:%d)\n", __FILE__,
294141cc406Sopenharmony_ci           __LINE__);
295141cc406Sopenharmony_ci      sanei_umax_pp_endSession ();
296141cc406Sopenharmony_ci      unlock_parport ();
297141cc406Sopenharmony_ci      return UMAX1220P_SCANNER_FAILED;
298141cc406Sopenharmony_ci    }
299141cc406Sopenharmony_ci
300141cc406Sopenharmony_ci  /* OK */
301141cc406Sopenharmony_ci  unlock_parport ();
302141cc406Sopenharmony_ci  return UMAX1220P_OK;
303141cc406Sopenharmony_ci}
304141cc406Sopenharmony_ci
305141cc406Sopenharmony_ci
306141cc406Sopenharmony_ciint
307141cc406Sopenharmony_cisanei_umax_pp_cancel (void)
308141cc406Sopenharmony_ci{
309141cc406Sopenharmony_ci  DBG (3, "sanei_umax_pp_cancel\n");
310141cc406Sopenharmony_ci  if (lock_parport () == UMAX1220P_BUSY)
311141cc406Sopenharmony_ci    return UMAX1220P_BUSY;
312141cc406Sopenharmony_ci
313141cc406Sopenharmony_ci  /* maybe EPAT reset here if exists */
314141cc406Sopenharmony_ci  sanei_umax_pp_cmdSync (0xC2);
315141cc406Sopenharmony_ci  sanei_umax_pp_cmdSync (0x00);
316141cc406Sopenharmony_ci  sanei_umax_pp_cmdSync (0x00);
317141cc406Sopenharmony_ci  if (sanei_umax_pp_park () == 0)
318141cc406Sopenharmony_ci    {
319141cc406Sopenharmony_ci      DBG (0, "sanei_umax_pp_park failed !!! (%s:%d)\n", __FILE__, __LINE__);
320141cc406Sopenharmony_ci      unlock_parport ();
321141cc406Sopenharmony_ci      return UMAX1220P_PARK_FAILED;
322141cc406Sopenharmony_ci    }
323141cc406Sopenharmony_ci  /* endSession() cancels any pending command  */
324141cc406Sopenharmony_ci  /* such as parking ...., so we only return   */
325141cc406Sopenharmony_ci  unlock_parport ();
326141cc406Sopenharmony_ci  return UMAX1220P_OK;
327141cc406Sopenharmony_ci}
328141cc406Sopenharmony_ci
329141cc406Sopenharmony_ci
330141cc406Sopenharmony_ci
331141cc406Sopenharmony_ciint
332141cc406Sopenharmony_cisanei_umax_pp_start (int x, int y, int width, int height, int dpi, int color,
333141cc406Sopenharmony_ci                     int autoset,
334141cc406Sopenharmony_ci                     int gain, int offset, int *rbpp, int *rtw,
335141cc406Sopenharmony_ci                     int *rth)
336141cc406Sopenharmony_ci{
337141cc406Sopenharmony_ci  int col = BW_MODE;
338141cc406Sopenharmony_ci
339141cc406Sopenharmony_ci  DBG (3, "sanei_umax_pp_start\n");
340141cc406Sopenharmony_ci  if (lock_parport () == UMAX1220P_BUSY)
341141cc406Sopenharmony_ci    return UMAX1220P_BUSY;
342141cc406Sopenharmony_ci  /* end session isn't done by cancel any more */
343141cc406Sopenharmony_ci  sanei_umax_pp_endSession ();
344141cc406Sopenharmony_ci
345141cc406Sopenharmony_ci  if (autoset)
346141cc406Sopenharmony_ci    sanei_umax_pp_setauto (1);
347141cc406Sopenharmony_ci  else
348141cc406Sopenharmony_ci    sanei_umax_pp_setauto (0);
349141cc406Sopenharmony_ci
350141cc406Sopenharmony_ci  switch (color)
351141cc406Sopenharmony_ci    {
352141cc406Sopenharmony_ci    case 0:
353141cc406Sopenharmony_ci      col = BW2_MODE;
354141cc406Sopenharmony_ci      break;
355141cc406Sopenharmony_ci    case 1:
356141cc406Sopenharmony_ci      col = BW_MODE;
357141cc406Sopenharmony_ci      break;
358141cc406Sopenharmony_ci    case 2:
359141cc406Sopenharmony_ci      col = RGB_MODE;
360141cc406Sopenharmony_ci      break;
361141cc406Sopenharmony_ci    }
362141cc406Sopenharmony_ci
363141cc406Sopenharmony_ci  if (sanei_umax_pp_startScan
364141cc406Sopenharmony_ci      (x + sanei_umax_pp_getLeft (), y, width, height, dpi, col, gain,
365141cc406Sopenharmony_ci       offset, rbpp, rtw, rth) != 1)
366141cc406Sopenharmony_ci    {
367141cc406Sopenharmony_ci      sanei_umax_pp_endSession ();
368141cc406Sopenharmony_ci      unlock_parport ();
369141cc406Sopenharmony_ci      return UMAX1220P_START_FAILED;
370141cc406Sopenharmony_ci    }
371141cc406Sopenharmony_ci  unlock_parport ();
372141cc406Sopenharmony_ci  return UMAX1220P_OK;
373141cc406Sopenharmony_ci}
374141cc406Sopenharmony_ci
375141cc406Sopenharmony_ciint
376141cc406Sopenharmony_cisanei_umax_pp_read (long len, int window, int dpi, int last,
377141cc406Sopenharmony_ci                    unsigned char *buffer)
378141cc406Sopenharmony_ci{
379141cc406Sopenharmony_ci  int read = 0;
380141cc406Sopenharmony_ci  int bytes;
381141cc406Sopenharmony_ci
382141cc406Sopenharmony_ci  DBG (3, "sanei_umax_pp_read\n");
383141cc406Sopenharmony_ci  if (lock_parport () == UMAX1220P_BUSY)
384141cc406Sopenharmony_ci    return UMAX1220P_BUSY;
385141cc406Sopenharmony_ci
386141cc406Sopenharmony_ci  /* since 610P may override len and last to meet its */
387141cc406Sopenharmony_ci  /* hardware requirements, we have to loop until we  */
388141cc406Sopenharmony_ci  /* have all the data                                */
389141cc406Sopenharmony_ci  while (read < len)
390141cc406Sopenharmony_ci    {
391141cc406Sopenharmony_ci      bytes =
392141cc406Sopenharmony_ci        sanei_umax_pp_readBlock (len - read, window, dpi, last,
393141cc406Sopenharmony_ci                                 buffer + read);
394141cc406Sopenharmony_ci      if (bytes == 0)
395141cc406Sopenharmony_ci        {
396141cc406Sopenharmony_ci          sanei_umax_pp_endSession ();
397141cc406Sopenharmony_ci          return UMAX1220P_READ_FAILED;
398141cc406Sopenharmony_ci        }
399141cc406Sopenharmony_ci      read += bytes;
400141cc406Sopenharmony_ci    }
401141cc406Sopenharmony_ci  unlock_parport ();
402141cc406Sopenharmony_ci  return UMAX1220P_OK;
403141cc406Sopenharmony_ci}
404141cc406Sopenharmony_ci
405141cc406Sopenharmony_ci
406141cc406Sopenharmony_ci
407141cc406Sopenharmony_ciint
408141cc406Sopenharmony_cisanei_umax_pp_lamp (int on)
409141cc406Sopenharmony_ci{
410141cc406Sopenharmony_ci  /* init transport layer */
411141cc406Sopenharmony_ci  DBG (3, "sanei_umax_pp_lamp\n");
412141cc406Sopenharmony_ci
413141cc406Sopenharmony_ci  /* no lamp support for 610P ... */
414141cc406Sopenharmony_ci  if (sanei_umax_pp_getastra () < 1210)
415141cc406Sopenharmony_ci    return UMAX1220P_OK;
416141cc406Sopenharmony_ci
417141cc406Sopenharmony_ci  if (lock_parport () == UMAX1220P_BUSY)
418141cc406Sopenharmony_ci    return UMAX1220P_BUSY;
419141cc406Sopenharmony_ci
420141cc406Sopenharmony_ci  if (sanei_umax_pp_setLamp (on) == 0)
421141cc406Sopenharmony_ci    {
422141cc406Sopenharmony_ci      DBG (0, "Setting lamp state failed!\n");
423141cc406Sopenharmony_ci    }
424141cc406Sopenharmony_ci
425141cc406Sopenharmony_ci  unlock_parport ();
426141cc406Sopenharmony_ci  return UMAX1220P_OK;
427141cc406Sopenharmony_ci}
428141cc406Sopenharmony_ci
429141cc406Sopenharmony_ci
430141cc406Sopenharmony_ci
431141cc406Sopenharmony_ci
432141cc406Sopenharmony_ciint
433141cc406Sopenharmony_cisanei_umax_pp_status (void)
434141cc406Sopenharmony_ci{
435141cc406Sopenharmony_ci  int status;
436141cc406Sopenharmony_ci
437141cc406Sopenharmony_ci  DBG (3, "sanei_umax_pp_status\n");
438141cc406Sopenharmony_ci  if (lock_parport () == UMAX1220P_BUSY)
439141cc406Sopenharmony_ci    return UMAX1220P_BUSY;
440141cc406Sopenharmony_ci  /* check if head is at home */
441141cc406Sopenharmony_ci  sanei_umax_pp_cmdSync (0x40);
442141cc406Sopenharmony_ci  status = sanei_umax_pp_scannerStatus ();
443141cc406Sopenharmony_ci  unlock_parport ();
444141cc406Sopenharmony_ci  DBG (8, "sanei_umax_pp_status=0x%02X\n", status);
445141cc406Sopenharmony_ci  if (((status & ASIC_BIT) != 0x00)||((status & MOTOR_BIT) == 0x00))
446141cc406Sopenharmony_ci    return UMAX1220P_BUSY;
447141cc406Sopenharmony_ci
448141cc406Sopenharmony_ci  return UMAX1220P_OK;
449141cc406Sopenharmony_ci}
450141cc406Sopenharmony_ci
451141cc406Sopenharmony_ciint
452141cc406Sopenharmony_cisanei_umax_pp_close ()
453141cc406Sopenharmony_ci{
454141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H
455141cc406Sopenharmony_ci  int fd;
456141cc406Sopenharmony_ci#endif
457141cc406Sopenharmony_ci
458141cc406Sopenharmony_ci  DBG (3, "sanei_umax_pp_close\n");
459141cc406Sopenharmony_ci
460141cc406Sopenharmony_ci  lock_parport ();
461141cc406Sopenharmony_ci  sanei_umax_pp_endSession ();
462141cc406Sopenharmony_ci  unlock_parport ();
463141cc406Sopenharmony_ci
464141cc406Sopenharmony_ci#ifdef HAVE_LINUX_PPDEV_H
465141cc406Sopenharmony_ci  fd = sanei_umax_pp_getparport ();
466141cc406Sopenharmony_ci  if (fd > 0)
467141cc406Sopenharmony_ci    {
468141cc406Sopenharmony_ci      close (fd);
469141cc406Sopenharmony_ci      sanei_umax_pp_setparport (0);
470141cc406Sopenharmony_ci    }
471141cc406Sopenharmony_ci#endif
472141cc406Sopenharmony_ci  return UMAX1220P_OK;
473141cc406Sopenharmony_ci}
474