xref: /third_party/backends/sanei/sanei_pv8630.c (revision 141cc406)
1/* sane - Scanner Access Now Easy.
2
3   Copyright (C) 2000 Adrian Perez Jorge
4   Copyright (C) 2001 Frank Zago
5   Copyright (C) 2001 Marcio Teixeira
6
7   This file is part of the SANE package.
8
9   This program is free software; you can redistribute it and/or
10   modify it under the terms of the GNU General Public License as
11   published by the Free Software Foundation; either version 2 of the
12   License, or (at your option) any later version.
13
14   This program is distributed in the hope that it will be useful, but
15   WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17   General Public License for more details.
18
19   You should have received a copy of the GNU General Public License
20   along with this program.  If not, see <https://www.gnu.org/licenses/>.
21
22   As a special exception, the authors of SANE give permission for
23   additional uses of the libraries contained in this release of SANE.
24
25   The exception is that, if you link a SANE library with other files
26   to produce an executable, this does not by itself cause the
27   resulting executable to be covered by the GNU General Public
28   License.  Your use of that executable is in no way restricted on
29   account of linking the SANE library code into it.
30
31   This exception does not, however, invalidate any other reasons why
32   the executable file might be covered by the GNU General Public
33   License.
34
35   If you submit changes to SANE to the maintainers to be included in
36   a subsequent release, you agree by submitting the changes that
37   those changes may be distributed with this exception intact.
38
39   If you write modifications of your own for SANE, it is your choice
40   whether to permit this exception to apply to your modifications.
41   If you do not wish that, delete this exception notice.
42
43   Interface files for the PowerVision 8630 chip, a USB to
44   parallel converter used in many scanners.
45
46 */
47
48#include "../include/sane/config.h"
49
50#include <stdlib.h>
51#include <unistd.h>
52
53#define BACKEND_NAME	sanei_pv8630
54#include "../include/sane/sane.h"
55#include "../include/sane/sanei_debug.h"
56#include "../include/sane/sanei_usb.h"
57#include "../include/sane/sanei_pv8630.h"
58
59#define DBG_error   1
60#define DBG_info    5
61
62void
63sanei_pv8630_init (void)
64{
65  DBG_INIT();
66}
67
68/* Write one control byte */
69SANE_Status
70sanei_pv8630_write_byte (int fd, SANEI_PV_Index index, SANE_Byte byte)
71{
72  SANE_Status status;
73
74  DBG(DBG_info, "sanei_pv8630_write_byte - index=%d, byte=%d\n", index, byte);
75  status =
76    sanei_usb_control_msg (fd, 0x40, PV8630_REQ_WRITEBYTE, byte, index, 0,
77			   NULL);
78
79  if (status != SANE_STATUS_GOOD)
80    DBG (DBG_error, "sanei_pv8630_write_byte error\n");
81  return status;
82}
83
84/* Read one control byte */
85SANE_Status
86sanei_pv8630_read_byte (int fd, SANEI_PV_Index index, SANE_Byte * byte)
87{
88  SANE_Status status;
89
90  DBG(DBG_info, "sanei_pv8630_read_byte - index=%d, byte=%p\n",
91      index, (void *) byte);
92
93  status =
94    sanei_usb_control_msg (fd, 0xc0, PV8630_REQ_READBYTE, 0, index, 1, byte);
95
96  if (status != SANE_STATUS_GOOD)
97    DBG (DBG_error, "sanei_pv8630_read_byte error\n");
98  return status;
99}
100
101/* Prepare a bulk read. len is the size of the data going to be
102 * read by pv8630_bulkread(). */
103SANE_Status
104sanei_pv8630_prep_bulkread (int fd, int len)
105{
106  SANE_Status status;
107
108  status =
109    sanei_usb_control_msg (fd, 0x40, PV8630_REQ_EPPBULKREAD, len & 0xffff,
110			   len >> 16, 0, NULL);
111
112  if (status != SANE_STATUS_GOOD)
113    DBG (DBG_error, "sanei_pv8630_prep_bulkread error\n");
114  return status;
115}
116
117/* Prepare a bulk write. len is the size of the data going to be
118 * written by pv8630_bulkwrite(). */
119SANE_Status
120sanei_pv8630_prep_bulkwrite (int fd, int len)
121{
122  SANE_Status status;
123
124  status =
125    sanei_usb_control_msg (fd, 0x40, PV8630_REQ_EPPBULKWRITE, len & 0xffff,
126			   len >> 16, 0, NULL);
127
128  if (status != SANE_STATUS_GOOD)
129      DBG (DBG_error, "sanei_pv8630_prep_bulkwrite error\n");
130  return status;
131}
132
133/* Flush the buffer. */
134SANE_Status
135sanei_pv8630_flush_buffer (int fd)
136{
137  SANE_Status status;
138
139  status =
140    sanei_usb_control_msg (fd, 0x40, PV8630_REQ_FLUSHBUFFER, 0, 0, 0, NULL);
141
142  if (status != SANE_STATUS_GOOD)
143    DBG (DBG_error, "sanei_pv8630_flush_buffer error\n");
144  return status;
145}
146
147/* Do a bulk write. The length must have previously been sent via
148 * pv8630_prep_bulkwrite(). */
149SANE_Status
150sanei_pv8630_bulkwrite (int fd, const void *data, size_t * len)
151{
152  SANE_Status status;
153
154  status = sanei_usb_write_bulk (fd, (const SANE_Byte *) data, len);
155
156  if (status != SANE_STATUS_GOOD)
157    DBG (DBG_error, "sanei_pv8630_bulkwrite error\n");
158  return status;
159}
160
161/* Do a bulk read. The length must have previously been sent via
162 * pv8630_prep_bulkread(). */
163SANE_Status
164sanei_pv8630_bulkread (int fd, void *data, size_t * len)
165{
166  SANE_Status status;
167
168  status = sanei_usb_read_bulk (fd, data, len);
169
170  if (status != SANE_STATUS_GOOD)
171    DBG (DBG_error, "sanei_pv8630_bulkread error\n");
172  return status;
173}
174
175/* Expects a specific byte in a register */
176SANE_Status
177sanei_pv8630_xpect_byte (int fd, SANEI_PV_Index index, SANE_Byte value,
178			 SANE_Byte mask)
179{
180  SANE_Status status;
181  SANE_Byte s;
182
183  status = sanei_pv8630_read_byte (fd, index, &s);
184  if (status != SANE_STATUS_GOOD)
185      return status;
186
187  if ((s & mask) != value)
188    {
189      DBG (DBG_error, "sanei_pv8630_xpect_byte: expected %x, got %x\n", value,
190	   s);
191      return SANE_STATUS_IO_ERROR;
192    }
193  return SANE_STATUS_GOOD;
194}
195
196/* Wait for the status register to present a given status. A timeout value
197   is given in tenths of a second. */
198SANE_Status
199sanei_pv8630_wait_byte (int fd, SANEI_PV_Index index, SANE_Byte value,
200			SANE_Byte mask, int timeout)
201{
202  SANE_Status status;
203  SANE_Byte s;
204  int n;
205
206  for (n = 0; n < timeout; n++)
207    {
208
209      status = sanei_pv8630_read_byte (fd, index, &s);
210      if (status != SANE_STATUS_GOOD)
211	return status;
212
213      if ((s & mask) == value)
214	return SANE_STATUS_GOOD;
215
216      usleep (100000);
217    }
218
219  DBG (DBG_error, "sanei_pv8630_wait_byte: timeout waiting for %x (got %x)\n",
220       value, s);
221  return SANE_STATUS_IO_ERROR;
222}
223